Vikivojaĝo eowikivoyage https://eo.wikivoyage.org/wiki/Vikivoja%C4%9Do:%C4%88efpa%C4%9Do MediaWiki 1.47.0-wmf.21 first-letter Aŭdvidaĵo Specialaĵo Diskuto Uzanto Uzanto-Diskuto Vikivojaĝo Vikivojaĝo-Diskuto Dosiero Dosiero-Diskuto MediaWiki MediaWiki-Diskuto Ŝablono Ŝablono-Diskuto Helpo Helpo-Diskuto Kategorio Kategorio-Diskuto TimedText TimedText talk Modulo Modulo-Diskuto Event Event talk Modulo:VCard 828 4800 73250 72508 2026-09-24T10:48:20Z RolandUnger 168 Update 73250 Scribunto text/plain -- module variable and administration local vc = { moduleInterface = { suite = 'vCard', serial = '2026-09-23', item = 58187507 }, -- table containing parameters fetched from Wikidata fromWD = {}, -- Wikidata to subtype table subtypeIds = nil, -- complete subtype table including Wikidata subtypes subtypes = {} } -- module import -- require( 'strict' ) local mi = require( 'Module:Marker utilities/i18n' ) local mu = require( 'Module:Marker utilities' ) local vp = require( 'Module:VCard/Params' ) -- parameter lists local vi = require( 'Module:VCard/i18n' ) -- parameter translations local vq = mw.loadData( 'Module:VCard/Qualifiers' ) -- comment tables local cm = require( 'Module:CountryData' ) local er -- modules will be loaded later if needed local hi local hr local lg local lp = require( 'Module:LinkPhone' ) local vs local wu = require( 'Module:Wikidata utilities' ) local function addWdClass( key ) return mu.addWdClass( vc.fromWD[ key ] ) end local function forceFetchFromWikidata( tab ) for key, value in pairs( tab ) do vp.ParMap[ key ] = true end end -- copying frameArgs parameters to args = vp.ParMap parameters local function copyParameters( args, show ) -- force getting data from Wikidata for missing parameters show.inlineDescription = true -- description with div or span tag if vp.ParMap.auto == true then forceFetchFromWikidata( vp.ParWD ) forceFetchFromWikidata( vp.ParWDAdd ) end -- copying args parameters to vp.ParMap parameters local t, value local exclude = { auto = 1, show = 1, wikidata = 1 } for key, v in pairs( vi.p ) do value = args[ key ] if value then value, t = mu.removeCtrls( value, show.inline or key ~= 'description' ) if t then show.inlineDescription = false end if vp.ParWD[ key ] then if value == '' then value = 'y' end t = mu.yesno( value ) if t then if vp.ParMap.wikidata ~= '' then vp.ParMap[ key ] = t == 'y' else vp.ParMap[ key ] = '' end else vp.ParMap[ key ] = value end elseif not exclude[ key ] then vp.ParMap[ key ] = value end end end return vp.ParMap end -- checking subtypes local function checkSubtypes( args, subtypesTable ) if not mu.isSet( args.subtype ) then return {} end local function aliasToSubtype( alias ) if not vc.subtypeAliases then -- alias to subtype table vc.subtypeAliases = mu.getAliases( subtypesTable, 'alias' ) end return vc.subtypeAliases[ alias ] end local function subtypeExists( subtype ) return subtypesTable[ subtype ] and subtype or aliasToSubtype( subtype ) end local subtypes = {} local invalidSubtypes = {} for subtype, v in pairs( mu.split( args.subtype ) ) do local count = '' local invalidCount = false local item = subtype -- split item from count local at = item:find( ':', 1, true ) if at then count = tonumber( item:sub( at + 1, #item ) ) or '' item = mw.text.trim( item:sub( 1, at - 1 ) ) if count == '' then invalidCount = true -- ':' without count or not a number else count = math.floor( count ) if count < 2 then count = '' end end end item = subtypeExists( item ) or mu.typeExists( item ) if item then subtypes[ item ] = count end if invalidCount or not item then table.insert( invalidSubtypes, subtype ) end end if #invalidSubtypes > 0 then mu.addMaintenance( 'unknownSubtype', table.concat( invalidSubtypes, mu.commaSeparator ) ) end return subtypes end local function initialParametersCheck( frame, page ) local country, email, entity, show, t, v, web, wrongQualifier local frameArgs = mu.checkArguments( frame:getParent().args, vi.p ) -- Using wu.getEntity instead of wu.getEntityId brings a better overall performance vp.ParMap.wikidata, entity, wrongQualifier = wu.getEntity( frameArgs.wikidata or '' ) if wrongQualifier then mu.addMaintenance( 'wrongQualifier' ) end vp.ParMap.auto = false if mu.isSet( vp.ParMap.wikidata ) then vp.ParMap.auto = vi.options.defaultAuto v = mu.yesno( frameArgs.auto or '' ) if v then vp.ParMap.auto = v == 'y' end mu.addMaintenance( 'wikidata' ) end -- making phone number table t = {} for i, key in ipairs( vp.phones ) do mu.tableInsert( t, frameArgs[ key ] ) end -- making web addresses table web = {} mu.tableInsert( web, frameArgs.url ) email = ( frameArgs.email or '' ):gsub( ',.*$', '' ) -- first email mu.tableInsert( web, email ) -- getting country-specific technical parameters country = cm.getCountryData( entity, t, frameArgs.country, vp.ParMap.wikidata, web ) if country.fromWD then mu.addMaintenance( 'countryFromWD' ) end if country.unknownCountry then mu.addMaintenance( 'unknownCountry' ) end if country.cc ~= '' then country.trunkPrefix = lp.getTrunkPrefix( country.cc ) end -- for map support country.extra = mi.map.defaultSiteType if mu.isSet( country.iso_3166 ) then country.extra = country.extra .. '_region:' .. country.iso_3166 end -- country-specific default show if mu.isSet( country.show ) then vp.ParMap.show = vp.ParMap.show .. ',' .. country.show end show = mu.getShow( vp.ParMap.show, frameArgs, vp.show ) -- copying frameArgs parameters to args = vp.ParMap parameters local args = copyParameters( frameArgs, show ) -- alternate local language if mu.isSet( args.localLang ) then args.localLang = args.localLang:lower() if args.localLang ~= country.lang then lg = lg or require( 'Module:Languages' ) if lg.lngProps[ args.localLang ] then cm.setLanguageParams( args.localLang, page.lang, country ) else args.localLang = '' mu.addMaintenance( 'unknownLanguage' ) end end end mu.checkStatus( args ) mu.checkStyles( args ) -- checking coordinates and converting DMS to decimal coordinates if necessary mu.checkCoordinates( args ) mu.checkZoom( args ) -- remove namespace from category mu.checkCommonsCategory( args ) mu.checkId( args ) for i, param in ipairs( mi.options.parameters ) do if mu.isSet( args[ param ] ) then mu.addMaintenance( 'parameterUsed', param ) end end args.subtypeAdd = mu.isSet( args.wikidata ) and args.auto -- getting features manually entered if mu.isSet( args.subtype ) then vs = require( 'Module:VCard/Subtypes' ) vc.subtypes = checkSubtypes( args, vs.f ) if mu.isSet( args.wikidata ) then -- y = fetch additional features from Wikidata if vc.subtypes.y then args.subtypeAdd = true -- n = do not show subtypes fetched from Wikidata elseif vc.subtypes.n then args.subtypeAdd = false end end end if type( args.lastedit ) == 'string' and args.lastedit ~= '' and not args.lastedit:match( mi.dates.yyyymmdd.p ) then mu.addMaintenance( 'wrongDate' ) args.lastedit = '' end -- check Google Maps customer id if type( args.googlemaps ) == 'string' and mu.isSet( args.googlemaps ) and not ( mu.checkLength( args.googlemaps, 14, 20 ) and args.googlemaps:match( '^[1-9]%d+$' ) ) then mu.addMaintenance( 'wrongGoogleCid' ) args.googlemaps = '' end if type( args.googlemaps ) == 'string' and mu.isSet( args.googlemaps ) then mu.addMaintenance( 'parameterUsed', 'google-maps' ) if mu.isSet( args.wikidata ) then mu.addMaintenance( 'wdWithGoogleCid' ) end end return args, entity, show, country end local function getQuantity( value, page ) if type( value ) == 'number' then return tostring( value ) elseif value.amount == '0' then return '0' else local a = mu.formatNumber( value.amount ) local u = '' local unitId = value.unit local unit = cm.getCurrency( unitId ) if mu.isSet( unit ) then if unit.mul then a = mu.formatNumber( string.format( '%.2f', -- 2 decimal places tonumber( value.amount ) * unit.mul ) ) end if mi.noCurrencyConversion.all or mi.noCurrencyConversion[ unit.iso ] then unit = mu.makeSpan( cm.getCurrencyFormatter( unitId ), 'voy-currency voy-currency-' .. unit.iso:lower() ) else er = er or require( 'Module:Exchange rate' ) unit = er.getWrapper( a, unit.iso, '', 2, cm.getCurrencyFormatter ) mu.addMaintenance( 'currencyTooltip' ) end else unit = vq.labels[ unitId ] end if unit and unit:find( '%s', 1, true ) then a = mw.ustring.format( unit, a ) elseif unit then u = unit elseif mw.wikibase.isValidEntityId( unitId ) then -- currency code u = wu.getValue( unitId, mi.properties.iso4217 ) if u == '' then -- unit symbol u = wu.getValuesByLang( unitId, mi.properties.unitSymbol, 1, page.lang ) u = u[ 1 ] or '' end if u ~= '' then mu.addMaintenance( 'unitFromWD' ) else u = unitId mu.addMaintenance( 'unknownUnit' ) end end return ( u ~= '' ) and a .. '&#x202F;' .. u or a end end local function getHourModules() if not hr then hi = require( 'Module:Hours/i18n' ) hr = require( 'Module:Hours' ) end end local function getLabel( id ) local label = id local tables = { vq.labels } if hi then table.insert( tables, hi.dateIds ) end if type( id ) == 'string' and id:match( '^Q%d+$' ) then for i, tab in ipairs( tables ) do if type( tab[ id ] ) == 'string' then label = tab[ id ] break end end if label == '' then return label elseif label == id then label = mu.getTypeLabel( id ) end if label == '' or label == id then label = wu.getLabel( id ) or '' if label == '' then mu.addMaintenance( 'unknownLabel' ) else mu.addMaintenance( 'labelFromWD' ) end end end return label end local function removeStringDuplicates( ar ) local hash = {} local result = {} local val for i = 1, #ar do val = ar[ i ] if not hash[ val ] then table.insert( result, val ) hash[ val ] = 1 end end return result end -- getting comments for contacts and prizes from Wikidata using tables local function getComments( statement, properties, args, page ) local comments = {} local isMobilephone = false local minAge, maxAge for i, property in ipairs( properties ) do local pType = property .. '-type' if statement[ property ] then if property == mi.properties.minimumAge then minAge = getQuantity( statement[ property ][ 1 ], page ) elseif property == mi.properties.maximumAge then maxAge = getQuantity( statement[ property ][ 1 ], page ) end for j, id in ipairs( statement[ property ] ) do if statement[ pType ] == 'monolingualtext' then id = id.text elseif statement[ pType ] == 'time' then -- getting last date in case of price/fees id = wu.getDateFromTime( id ) if not mu.isSet( args.asOf ) or args.asOf < id then args.asOf = id end id = '' elseif type( id ) == 'table' then id = '' end if id == mi.qualifiers.mobilePhone then isMobilephone = true else mu.tableInsert( comments, getLabel( id ) ) end end end end comments = removeStringDuplicates( comments ) if minAge and maxAge then mu.tableInsert( comments, mw.ustring.format( mi.texts.fromTo, minAge:gsub( '(%d+).*', '%1' ), maxAge ) ) elseif minAge then mu.tableInsert( comments, mw.ustring.format( mi.texts.from, minAge ) ) elseif maxAge then mu.tableInsert( comments, mw.ustring.format( mi.texts.to, maxAge ) ) end return table.concat( comments, mu.commaSeparator ), isMobilephone end local function getLngProperty( lng, p ) if not mu.isSet( lng ) then return '' end lg = lg or require( 'Module:Languages' ) local item = lg.lngProps[ lng ] if not item then local hyphen = lng:find( '-', 1, true ) if hyphen and hyphen > 1 then item = lg.lngProps[ lng:sub( 1, hyphen - 1 ) ] end end if item then item = item[ p ] end return item or ( p == 'c' and 0 or '' ) end local function removeTableDuplicates( ar ) local hash = {} local result = {} local hashVal for i, tab in ipairs( ar ) do hashVal = tab.value .. '#' .. tab.comment if not hash[ hashVal ] then table.insert( result, tab ) hash[ hashVal ] = 1 end end return result end local function mergeComments( ar ) if #ar > 1 then for i = #ar, 2, -1 do for j = 1, i - 1, 1 do if ar[ i ].value == ar[ j ].value and ar[ i ].comment ~= '' and ar[ j ].comment ~= '' then ar[ j ].comment = ar[ j ].comment .. '; ' .. ar[ i ].comment table.remove( ar, i ) break end end end end end local function convertTableWithComment( ar ) for i = 1, #ar, 1 do if ar[ i ].comment == '' then ar[ i ] = ar[ i ].value else ar[ i ] = ar[ i ].value .. mu.parentheses( ar[ i ].comment ) end end end --[[ properties are defined in Module:vCard/Params p property or set of properties f formatter string c maximum count of results, default = 1 m concat mode (if c > 1), default concat with ', ' v value type, empty: string value (i.e. default type), id: string value of an id like Q1234567 idl: string value of the label of an id like Q1234567 il: language-dependent string value iq: string value with qualifier ids au: quantity consisting of amount and unit pau: quantity consisting of amount (for P8733) vq: string or table value with qualifiers ids and references l = lang: language dependent wiki / local: monolingual text by wiki or local language le = true: use date for lastedit parameter --]] -- function returns an array in any case local function getWikidataValues( args, propDef, entity, page, country ) local ar = {} local a, isMobilephone, item, id, langs, q, u -- setting defaults propDef.v = propDef.v or '' propDef.f = propDef.f or '' propDef.c = propDef.c or 1 -- getting value arrays if propDef.l == 'wiki' then ar = wu.getValuesByLang( entity, propDef.p, propDef.c, page.lang ) elseif propDef.l == 'local' then ar = wu.getValuesByLang( entity, propDef.p, propDef.c, country.lang ) elseif propDef.l == 'lang' and propDef.c == 1 then id = getLngProperty( country.lang, 'q' ) if id == '' then country.unknownLanguage = true else -- using language of work or name ( page.lang, mi.langs, country.lang ) a = wu.getValuesByQualifier( entity, propDef.p, mi.properties.languageOfName, id ) if next( a ) then langs = mu.getLangTable( page.lang, country.lang ) for i, lang in ipairs( langs ) do item = a[ getLngProperty( lang, 'q' ) ] if item then break end end ar = { item or a[ next( a, nil ) ] } -- fallback: first item end end elseif propDef.v == 'iq' or propDef.v == 'iqa' or propDef.v == 'iqp' or propDef.v == 'iqu' then q = mi.propTable.quantity if propDef.v == 'iqa' then q = mi.propTable.accessQuantity elseif propDef.v == 'iqp' then q = mi.propTable.policyComments elseif propDef.v == 'iqu' then q = mi.propTable.unescoPartOf end ar = wu.getValuesWithQualifiers( entity, propDef.p, propDef.q, q, { mi.properties.retrieved }, propDef.c ) if propDef.le then args.lastedit = wu.getLastedit( args.lastedit, ar ) end elseif propDef.v == 'au' or propDef.v == 'vq' then q = propDef.v == 'au' and mi.propTable.feeComments or mi.propTable.contactComments ar = wu.getValuesWithQualifiers( entity, propDef.p, nil, q, { mi.properties.retrieved }, propDef.c ) -- maybe a change of nil to a properties table is useful if propDef.le then args.lastedit = wu.getLastedit( args.lastedit, ar ) end else ar = wu.getValues( entity, propDef.p, propDef.c ) end if #ar == 0 and propDef.p ~= mi.properties.instanceOf then return ar end for i = #ar, 1, -1 do -- amount with unit (for fees) if propDef.v == 'au' then a = getQuantity( ar[ i ].value, page ) if a == '0' then a = vq.labels.gratis end u = getComments( ar[ i ], mi.propTable.feeComments, args, page ) ar[ i ] = { value = a, comment = u } -- for number of rooms P8733 elseif propDef.v == 'pau' then if ar[ i ].unit == '1' then a = tonumber( ar[ i ].amount ) or 0 else a = 0 end ar[ i ] = {} ar[ i ][ mi.properties.quantity ] = { a } ar[ i ][ mi.properties.quantity .. '-type' ] = 'quantity' ar[ i ].value = mi.qualifiers.roomNumber ar[ i ]['value-type'] = 'wikibase-entityid' -- qualifier ids (for subtypes) elseif propDef.v == 'iq' or propDef.v == 'iqa' or propDef.v == 'iqp' or propDef.v == 'iqu' then if ar[ i ][ 'value-type' ] ~= 'wikibase-entityid' then table.remove( ar, i ) end if propDef.v == 'iqu' then if ar[ i ][ mi.properties.partOf ] then ar[ i ] = ar[ i ][ mi.properties.partOf ][ 1 ] else ar[ i ] = mi.qualifiers.unescoHeritage end end if propDef.v == 'iqa' then ar[ i ].policyComment = getComments( ar[ i ], mi.propTable.accessibility, args, page ) end if propDef.v == 'iqp' then ar[ i ].policyComment = getComments( ar[ i ], mi.propTable.policyComments, args, page ) end -- strings with qualifiers (for contacts) elseif propDef.v == 'vq' then if ar[ i ][ 'value-type' ] ~= 'string' then table.remove( ar, i ) else u, isMobilephone = getComments( ar[ i ], mi.propTable.contactComments, args, page ) if vi.options.useMobile and propDef.t then if ( isMobilephone and propDef.t == 'mobile' ) or ( not isMobilephone and propDef.t == 'landline' ) then ar[ i ] = { value = ar[ i ].value, comment = u } else table.remove( ar, i ) end else ar[ i ] = { value = ar[ i ].value, comment = u } end end -- value, monolingual text, identifier else if propDef.v == 'id' then ar[ i ] = ar[ i ].id elseif propDef.v == 'idl' then getHourModules() ar[ i ] = hr.formatTime( getLabel( ar[ i ].id ) ) end if ar[ i ] ~= '' and propDef.f ~= '' then ar[ i ] = mw.ustring.format( propDef.f, ar[ i ] ) end end if propDef.v == 'au' or propDef.v == 'vq' then if ar[ i ] and ar[ i ].value == '' then table.remove( ar, i ) end else if ar[ i ] == '' then table.remove( ar, i ) end end end -- cleanup if propDef.v == 'au' or propDef.v == 'vq' then ar = removeTableDuplicates( ar ) mergeComments( ar ) convertTableWithComment( ar ) else ar = removeStringDuplicates( ar ) end return ar end local function getWikidataItem( args, parWDitem, entity, page, country ) local arr = {} local function singleProperty( propDef ) if #arr == 0 then arr = getWikidataValues( args, propDef, entity, page, country ) else for i, value in ipairs( getWikidataValues( args, propDef, entity, page, country ) ) do table.insert( arr, value ) -- copy to arr end end end local p = parWDitem if not p or not p.p then return '' end p.c = p.c or 1 -- count local tp = type( p.p ) if tp == 'string' then singleProperty( p ) elseif tp == 'table' then for i, sngl in ipairs( p.p ) do if type( sngl ) == 'table' then singleProperty( sngl ) if p.c == 1 and #arr > 0 then break end end end end if #arr > p.c then for i = #arr, p.c + 1, -1 do -- delete supernumerary values table.remove( arr, i ) end end if p.m == 'no' then return arr else return table.concat( arr, p.m or mu.commaSeparator ) end end local function getAddressesFromWikidata( args, page, country, entity ) local addresses -- getting addresses from Wikidata but only if necessary if args.address == true or type( args.addressLocal ) == 'boolean' then -- P6375: address addresses = wu.getMonolingualValues( entity, mi.properties.streetAddress ) if next( addresses ) then -- sometimes addresses contain <br> tag(s) for key, value in pairs( addresses ) do addresses[ key ] = value:gsub( '</*br%s*/*>', mi.texts.space ) end else return end else return end local t, w if args.address == true then args.address = addresses[ page.lang ] -- select address if the same writing system is used if not args.address then local weight = -1 local u = getLngProperty( page.lang, 'w' ) -- writing entity id for key, value in pairs( addresses ) do -- same writing entity id as page.lang w = getLngProperty( key, 'w' ) if w == '' then country.unknownPropertyLanguage = true else if key and w == u then -- same writing entity id w = getLngProperty( key, 'c' ) -- getting language weight if w > weight then -- compare language weight args.address = value args.addressLang = key weight = w end end end end end if not args.address then for i, lng in ipairs( mi.langs ) do if addresses[ lng ] then args.address = addresses[ lng ] args.addressLang = lng break end end end if not args.address then args.address = '' args.addressLang = '' end vc.fromWD.address = args.address ~= '' end -- removing county name from the end of address -- same with county name in county language and English if type( args.address ) == 'string' then args.address = mw.ustring.gsub( args.address, '[.,;]*%s*' .. country.country .. '$', '' ) end t = true for i, lng in ipairs( mi.langs ) do if country.lang == lng then t = false end end -- keeping local address in any case for html data args.addAddressLocal = addresses[ country.lang ] or '' if t and args.addressLocal == true and country.lang ~= page.lang then if country.lang ~= '' then args.addressLocal = addresses[ country.lang ] or '' else -- unknown language, maybe missing in Module:Languages args.addressLocal = addresses.unknown or '' end vc.fromWD.addressLocal = args.addressLocal ~= '' end end local function getDataFromWikidata( args, page, country, entity ) if args.wikidata == '' then return end mu.getTypeFromWikidata( args, entity ) -- prevent local data if wiki language == country language if country.lang == page.lang then for i, value in ipairs( vp.localData ) do if type( args[ value ] ) == 'boolean' then args[ value ] = '' end end end mu.getNamesFromWikidata( args, vc.fromWD, page, country, entity ) getAddressesFromWikidata( args, page, country, entity ) if args.hours == true then local lastEdit getHourModules() if not mu.typeIds then mu.idToType( 'Q1' ) -- dummy call to create mu.typeIds end args.hours, lastEdit = hr.getHoursFromWikidata( entity, page.lang, mi.langs[ 1 ] or '', mi.formats.wikidata, nil, args.lastedit, vq.labels, { typeTable = mu.types, idTable = mu.typeIds } ) vc.fromWD.hours = args.hours ~= '' if vi.options.lasteditHours then args.lastedit = lastEdit end end for key, value in pairs( vp.ParWD ) do if args[ key ] == true then args[ key ] = getWikidataItem( args, vp.ParWD[ key ], entity, page, country ) vc.fromWD[ key ] = args[ key ] ~= '' end end mu.getArticleLink( args, entity, page ) mu.getCommonsCategory( args, entity ) mu.getCoordinatesFromWikidata( args, vc.fromWD, entity ) end local function checkAddresses( args ) local s for i, key in ipairs( { 'address', 'addressLocal', 'directions', 'directionsLocal' } ) do if mu.isSet( args[ key ] ) then s = args[ key ] args[ key ] = args[ key ]:gsub( "'''?", '' ) -- addresses shall not contain tags if key == 'address' or key == 'addressLocal' then args[ key ] = args[ key ]:gsub( '<[^<>]*>', '' ) :gsub( '[<>]+', '' ) end if s ~= args[ key ] then args[ key ] = mw.text.trim( args[ key ] ) mu.addMaintenance( 'malformedAddress' ) end end end end local function finalParametersCheck( args, show, page, country, defaultType, entity ) -- remove boolean values from parameters to have only strings for key, value in pairs( args ) do if type( args[ key ] ) == 'boolean' then args[ key ] = '' end end -- create givenName, displayName tables args.langIsWikiLang = country.lang == page.lang mu.prepareNames( args ) if args.langIsWikiLang and ( mu.isSet( args.addressLocal ) or mu.isSet( args.directionsLocal ) ) then args.addressLocal = '' args.directionsLocal = '' mu.addMaintenance( 'noLocalParams' ) end checkAddresses( args ) -- analysing addressLocal vs address if args.addressLang and args.addressLang == country.lang then args.addressLocal = '' args.addAddressLocal = '' end if args.addressLocal ~= '' and args.address == '' then args.address = mu.languageSpan( args.addressLocal, mi.texts.hintAddress, page, country ) args.addressLocal = '' args.addAddressLocal = '' vc.fromWD.address = vc.fromWD.addressLocal end show.noCoord = args.lat == '' or args.long == '' if show.noCoord then show.coord = nil show.poi = nil mu.addMaintenance( 'missingCoordVc' ) else mu.prepareCoordinates( args ) end -- getting Marker type, group, and color if not mu.isSet( args.type ) and mu.isSet( defaultType ) then args.type = defaultType end mu.checkTypeAndGroup( args ) -- image check if not vc.fromWD.image or mi.options.WDmediaCheck then mu.checkImage( args, entity ) end mu.checkUrl( args ) args.commonscat = args.commonscat:gsub( ' ', '_' ) -- add final period if not yet exists if mu.isSet( args.description ) then if mw.ustring.match( args.description, '[%w_€$]$' ) then args.description = args.description .. mi.texts.period end if mw.ustring.len( args.description ) > mi.options.contentLimit and mi.options.groupsWithLimit[ args.group ] then args.description = mw.ustring.sub( args.description, 1, mi.options.contentLimit ) .. '…' mu.addMaintenance( 'contentTooLong' ) end end end local function formatText( args, results, key, class ) if not mu.isSet( args[ key ] ) then return end local r local textKey = key local period = mi.texts.period if key == 'hours' then args[ key ], r = mw.ustring.gsub( args[ key ], mi.texts.closedPattern, '' ) textKey = ( r > 0 ) and 'closed' or key end r = mw.ustring.format( mi.texts[ textKey ], args[ key ] ) r = mw.ustring.gsub( r, '^%a', mw.ustring.upper ) -- add period if not yet exists r = r .. ( mw.ustring.sub( r, -1 ) == period and '' or period ) table.insert( results, mu.makeSpan( r, class .. addWdClass( key ) ) ) end local function formatPhone( args, key, country ) if not mu.isSet( args[ key ] ) then return '' end local class local pArgs = { phone = args[ key ], cc = country.cc, isFax = false, isTollfree = false, format = false } if vc.fromWD[ key ] then pArgs.format = true pArgs.size = country.phoneDigits or 2 end if key == 'fax' then class = 'voy-listing-fax p-tel-fax fax' .. addWdClass( key ) pArgs.isFax = true else class = 'p-tel tel' .. addWdClass( key ) if key == 'tollfree' then class = 'voy-listing-tollfree ' .. class pArgs.isTollfree = true elseif key == 'mobile' then class = 'voy-listing-mobile ' .. class else class = 'voy-listing-phone ' .. class end end return mw.ustring.format( mi.texts[ key ], mu.makeSpan( lp.linkPhoneNumbers( pArgs ), class ) ) end local function formatDate( aDate, aFormat ) return mw.getContentLanguage():formatDate( aFormat, aDate, true ) end local function removePeriods( s ) local period = mi.texts.period local _period = '%' .. period -- closing (span) tags between full stops return s:gsub( _period .. '+(</[%l<>/]+>)' .. _period .. '+', '%1' .. period ) :gsub( _period .. _period .. '+', period ) end local function makeMarkerAndName( args, show, page, country, frame ) local result = {} -- adding status icons mu.tableInsert( result, mu.makeStatusIcons( args ) ) -- adding POI marker if show.poi or mu.isSet( args.copyMarker ) then table.insert( result, mu.makeMarkerSymbol( args, show, frame ) ) end mu.makeName( result, args, show, page, country, addWdClass( 'name' ), addWdClass( 'nameLocal' ) ) if #result > 0 then result = { table.concat( result, mi.texts.space ) } end if args.before ~= '' then table.insert( result, 1, mu.makeSpan( args.before, 'voy-listing-before' ) ) end return table.concat( result, mi.texts.space ) end local function makeEvent( args, page ) local isEvent = false local s = {} local count = 0 -- counts from-to statements local startMonth -- month of start date local today = page.langObj:formatDate( 'Y-m-d', 'now', true ) local todayYear = today:sub( 1, 4 ) -- yyyy local todayMonth = today:sub( 6, 7 ) -- mm local lastDate = '' local lastYear = '' local useYMD -- both dates are yyyy-mm-dd local function makePeriod( beginP, endP ) if beginP == endP then endP = '' end if mu.isSet( beginP ) and mu.isSet( endP ) then count = count + 1 return mw.ustring.format( mi.texts.fromTo2, beginP, endP ) elseif mu.isSet( beginP ) then return beginP else return endP end end local function analyseDate( d, m, y ) local success, c, t if useYMD then success, t = pcall( formatDate, d, mi.dates.yyyymmdd.f ) if success then success, c = pcall( formatDate, d, 'Y-m-d' ) end if success then lastDate = c > lastDate and c or lastDate d = t end return d, nil end if d:match( mi.dates.yyyymmdd.p ) then y = d:sub( 1, 4 ) d = d:sub( 6 ) end if mu.isSet( y ) then if y:match( mi.dates.yy.p ) then y = ( '2000' ):sub( -#y ) .. y elseif not y:match( mi.dates.yyyy.p ) then y = nil end lastYear = y > lastYear and y or lastYear end if mu.isSet( d ) and mu.isSet( m ) and d:match( mi.dates.dd.p ) and not m:match( mi.dates.mm.p ) then -- try to convert month to number string success, t = pcall( formatDate, m, 'm' ) if success then m = t else for i = 1, 12, 1 do if m == mi.months[ i ] or mw.ustring.match( m, mi.monthAbbr[ i ] ) then m = '' .. i break end end end end if mu.isSet( d ) and mu.isSet( m ) and d:match( mi.dates.dd.p ) and m:match( mi.dates.mm.p ) then d = m:gsub( '%.+$', '' ) .. '-' .. d:gsub( '%.+$', '' ) m = nil elseif mu.isSet( d ) and not mu.isSet( m ) and d:match( mi.dates.dd.p ) then d = ( startMonth or todayMonth ) .. '-' .. d:gsub( '%.+$', '' ) end if mu.isSet( d ) then if d:match( mi.dates.mmdd.p ) then startMonth = d:gsub( '%-%d+', '' ) m = nil c = ( y or todayYear ) .. '-' .. d success, t = pcall( formatDate, c, mi.dates.mmdd.f ) if success then d = t end elseif d:match( mi.dates.dd.p ) and not mu.isSet( m ) and startMonth then c = ( y or todayYear ) .. '-' .. startMonth .. '-' .. d success, t = pcall( formatDate, c, mi.dates.mmdd.f ) if success then d = t end end end if mu.isSet( m ) then d = ( mu.isSet( d ) and ( d .. mi.texts.space ) or '' ) .. m end return d, y end if not mu.groupWithEvents( args.group ) then return '' end -- check if vCard is an event for i, param in ipairs( vp.checkEvent ) do if mu.isSet( args[ param ] ) then isEvent = true break end end if not isEvent then return '' end if mu.isSet( args.frequency ) then table.insert( s, mu.makeSpan( args.frequency, 'voy-listing-frequency' ) ) else if args.date:match( mi.dates.yyyymmdd.p ) and args.endDate:match( mi.dates.yyyymmdd.p ) then useYMD = true if args.date > args.endDate then args.date, args.endDate = args.endDate, args.date end end args.date, args.year = analyseDate( args.date, args.month, args.year ) args.endDate, args.endYear = analyseDate( args.endDate, args.endMonth, args.endYear ) local d = {} mu.tableInsert( d, makePeriod( args.date, args.endDate ) ) mu.tableInsert( d, makePeriod( args.year, args.endYear ) ) mu.tableInsert( s, mu.makeSpan( table.concat( d, count > 1 and mu.commaSeparator or mi.texts.space ), 'voy-listing-date' ) ) if ( lastYear ~= '' and lastYear < todayYear ) or ( lastDate ~= '' and lastDate < today ) then mu.addMaintenance( 'outdated' ) end end if mu.isSet( args.location ) then local locations = mu.textSplit( args.location, ',' ) for i, location in ipairs( locations ) do if location ~= page.subpageText and location ~= page.text and mw.title.new( location, '' ).exists then location = mu.makeSpan( '[[' .. location .. ']]', 'voy-listing-location' ) end table.insert( s, location ) end end s = table.concat( s, mu.commaSeparator ) return ( s ~= '' and ': ' or '' ) .. s end local function makeAddressAndDirections( args, page, country ) local r = '' local p, t if mu.isSet( args.address ) then p = {} if mu.isSet( args.addressLang ) then p.lang = args.addressLang t = mw.language.fetchLanguageName( args.addressLang, page.lang ) if mu.isSet( t ) then p.title = mw.ustring.format( mi.texts.hintAddress, t ) else country.unknownPropertyLanguage = true end end r = mu.commaSeparator .. mu.makeSpan( args.address, 'voy-listing-address p-adr adr' .. addWdClass( 'address' ), true, p ) end if mi.options.showLocalData and mu.isSet( args.addressLocal ) then r = r .. mu.comma .. mu.languageSpan( args.addressLocal, mi.texts.hintAddress, page, country, 'voy-listing-address-local' .. addWdClass( 'addressLocal' ) ) end t = {} if mu.isSet( args.directions ) then table.insert( t, mu.makeSpan( args.directions, 'voy-listing-directions' .. addWdClass( 'directions' ) ) ) end if mi.options.showLocalData and mu.isSet( args.directionsLocal ) then table.insert( t, mu.languageSpan( args.directionsLocal, mi.texts.hintDirections, page, country, 'voy-listing-directions-local' .. addWdClass( 'directionsLocal' ) ) ) end if #t == 0 then return r end return r .. mi.texts.space .. mu.makeSpan( mu.parentheses( table.concat( t, mu.comma ), true ), 'voy-listing-add-address' ) end local function makeContacts( args, country ) local t = {} local s mu.tableInsert( t, formatPhone( args, 'phone', country ) ) mu.tableInsert( t, formatPhone( args, 'tollfree', country ) ) mu.tableInsert( t, formatPhone( args, 'mobile', country ) ) mu.tableInsert( t, formatPhone( args, 'fax', country ) ) if args.email ~= '' then local lm = require( 'Module:LinkMail' ) s = mu.makeSpan( lm.linkMailSet( { email = args.email, ignoreUnicode = 1 } ), 'voy-listing-email u-email email' .. addWdClass( 'email' ) ) mu.tableInsert( t, mw.ustring.format( mi.texts.email, s ) ) end s = table.concat( t, mu.commaSeparator ) if s ~= '' then -- mi.texts.periodSeparator = '. ' s = mi.texts.periodSeparator .. mw.ustring.gsub( s, '^%a', mw.ustring.upper ) end return s end -- making subtypes string local function makeFeatures( args, tab ) vs = vs or require( 'Module:VCard/Subtypes' ) local function getSubtypeParams( subtype ) local r = vs.f[ subtype ] or mu.getTypeParams( subtype ) if not r.n then r.n = r.label or subtype end r.g = r.g or vs.fromTypesGroupNumber return r end vc.fromWD.subtypeAdd = type( args.subtypeAdd ) == 'table' and #args.subtypeAdd > 0 -- merging subtypeAdd (from Wikidata) to manually entered subtypes local unknowWDfeatures = false local label, p, t if vc.fromWD.subtypeAdd then -- making translation table from Wikidata ids to feature types if not vc.subtypeIds then vc.subtypeIds = mu.getAliases( vs.f, 'wd' ) end -- adding type if Wikidata id (wd.value) is known -- indexed array prevents multiple identical types for i, wd in ipairs( args.subtypeAdd ) do t = vc.subtypeIds[ wd.value ] or mu.idToType( wd.value ) if not t then -- maybe instance or subclass of wd.value are known local p31ids = wu.getIds( wd.value, mi.properties.instanceOf ) local p279ids = wu.getIds( wd.value, mi.properties.subclassOf ) -- merging both arrays for j = 1, #p279ids, 1 do table.insert( p31ids, p279ids[ j ] ) end for j = 1, #p31ids, 1 do t = vc.subtypeIds[ p31ids[ j ] ] or mu.idToType( p31ids[ j ] ) if t then break end end end -- subtype from WD is not known if not t and not vs.exclude[ wd.value ] then unknowWDfeatures = true -- try to add a new subtype Q... to vs.f subtypes table label = wu.getLabel( wd.value ) if label then vs.f[ wd.value ] = { n = label, wd = wd.value, g = vs.fromWDGroupNumber } t = wd.value end end -- add known subtype if t then vc.subtypes[ t ] = { c = ( wd[ mi.properties.quantity ] and wd[ mi.properties.quantity ][ 1 ] ) or ( wd[ mi.properties.capacity ] and wd[ mi.properties.capacity ][ 1 ] ) or '', p = wd.policyComment } end end end if unknowWDfeatures then mu.addMaintenance( 'unknowWDfeatures' ) end if next( vc.subtypes ) == nil and #args.subtypeTable == 0 then return end -- replace selected subtypes for subtype, count in pairs( vc.subtypes ) do if vs.convert[ subtype ] then if type( count ) == 'table' then p = count.p count = count.c end t = vs.convert[ subtype ][ count ] or vs.convert[ subtype ][ 1 ] vc.subtypes[ t ] = { p = p } vc.subtypes[ subtype ] = nil end end -- make subtypes table sortable local s = {}; for subtype, count in pairs( vc.subtypes ) do if type( count ) == 'table' then table.insert( s, { t = subtype, c = count.c, p = count.p } ) else table.insert( s, { t = subtype, c = count } ) end end -- add subtypes from types table if args.subtypeTable then for i, subtype in ipairs( args.subtypeTable ) do table.insert( s, { t = subtype, c = 1 } ) end end -- sorting subtypes -- by subtype group and then alphabetically by name table.sort( s, function( a, b ) local at = getSubtypeParams( a.t ) local bt = getSubtypeParams( b.t ) local na = mu.convertForSort( at.n ) local nb = mu.convertForSort( bt.n ) return ( at.g < bt.g ) or ( at.g == bt.g and na < nb ) end ) -- make text and data output local data = {} -- for data-subtype attribute in wrapper tag if #s > 0 then local r = {}; local subtype, f, u, u_n, v for i = 1, #s do subtype = s[ i ] -- for data-subtype="..." in wrapper tag u = subtype.t .. ',' .. tostring( i ) if type( subtype.c ) == 'number' and subtype.c > 1 then u = u .. ',' .. subtype.c end table.insert( data, u ) u = getSubtypeParams( subtype.t ) if u.g >= vs.firstGroup then u_n = u.n if not mu.isSet( u_n ) then u_n = subtype.t end u_n = u_n:gsub( '[,;/].*$', '' ) local count = ( type( subtype.c ) == 'number' ) and subtype.c or 1 if count > 1 and u_n:find( '%[[^%[%]]*%]' ) then v = mw.ustring.format( mi.texts.subtypeWithCount, subtype.c, u_n:gsub( '%[([^%[%]]*)|([^%[%]]*)%]', '%1' ) :gsub( '%[([^%[%]]*)%]', '%1' ) ) else v = u_n:gsub( '%[([^%[%]]*)|([^%[%]]*)%]', '%2' ) :gsub( '%[([^%[%]]*)%]', '' ) end if mu.isSet( u.t ) then -- string tooltip v = mw.ustring.format( mi.texts.subtypeSpan, u.t, v ) elseif mu.isSet( u.f ) then -- icons f = mw.ustring.format( mi.texts.subtypeFile, u.f, v ) if u.c then f = mw.ustring.rep( f, u.c ) end v = mw.ustring.format( mi.texts.subtypeAbbr, v, f ) end -- adding policy comment if subtype.p and subtype.p ~= '' then v = v .. mu.parentheses( subtype.p ) end end table.insert( r, v ) end if #r > 0 then r = #r == 1 and mw.ustring.format( mi.texts.subtype, r[ 1 ] ) or mw.ustring.format( mi.texts.subtypes, table.concat( r, mu.commaSeparator ) ) if r ~= '' then table.insert( tab, mu.makeSpan( r, 'voy-listing-subtype' .. addWdClass( 'subtypeAdd' ) ) ) end end end -- subtype contains now the value for wrapper tag args.subtype = table.concat( data, ';' ) end local function makePayment( args, results ) if not mu.isSet( args.payment ) then return end local t local class = 'voy-listing-payment p-note note' if type( args.payment ) == 'table' then local vr = mw.loadData( 'Module:VCard/Cards') for i = #args.payment, 1, -1 do -- remove unknown items t = args.payment[ i ] if vr.cards[ t ] then args.payment[ i ] = vr.cards[ t ] else table.remove( args.payment, i ) end end class = class .. mu.addWdClass( #args.payment > 0 ) args.payment = table.concat( args.payment, mu.commaSeparator ) else mu.addMaintenance( 'paymentUsed' ) end formatText( args, results, 'payment', class ) end local function wrapDescription( args, tab, isInline, addText ) if args.description ~= '' then table.insert( tab, tostring( mw.html.create( isInline and 'span' or 'div' ) :addClass( 'voy-listing-content p-note note' ) :wikitext( args.description .. ( addText or '' ) ) ) ) end end local function makeMetadata( args, page ) local outdated = false local t = args.lastedit if t ~= '' then local s, success, u success, t = pcall( formatDate, t, mi.dates.lastedit.f ) if not success then mu.addMaintenance( 'wrongDate' ) t = '' else success, s = pcall( formatDate, args.lastedit, 'U' ) -- UNIX seconds if success then success, u = pcall( formatDate, mi.texts.expirationPeriod, 'U' ) end if success and s < u then t = t .. mi.texts.space .. mi.texts.maybeOutdated outdated = true end end end local tag = mw.html.create( 'span' ) :attr( 'class', 'voy-listing-metadata' ) -- add node to save the parent tag :node( mw.html.create( 'span' ) :addClass( 'voy-listing-metadata-item voy-listing-lastedit' ) :addClass( outdated and 'voy-listing-outdated' or nil ) :addClass( t == '' and 'voy-listing-item-dummy' or nil ) :wikitext( mw.ustring.format( mi.texts.lastedit, t == '' and mi.texts.lasteditNone or t ) ) ) if mu.isSet( args.sectionFrom ) then local from = args.sectionFrom:gsub( '_', ' ' ) if from ~= page.subpageText and from ~= page.text then if mu.isSet( args.wikidata ) then from = mw.ustring.format( '%s#' .. mi.texts.anchor, from, args.wikidata ) end tag:node( mw.html.create( 'span' ) :addClass( 'voy-listing-metadata-item voy-listing-toSourcePage' ) :wikitext( mw.ustring.format( '[[%s|%s]]', from, mi.texts.editInSource ) ) ) end end return tostring( tag ) end -- making description, coordinates, and meta data local function makeDescription( args, show, page, country, entity ) local results = {} -- inline description if show.inlineDescription then wrapDescription( args, results, true ) end -- adding features makeFeatures( args, results ) -- practicalities formatText( args, results, 'hours', 'voy-listing-hours p-note note' ) formatText( args, results, 'checkin', 'voy-listing-checkin' ) formatText( args, results, 'checkout', 'voy-listing-checkout' ) if mu.isSet( args.asOf ) and mu.isSet( args.price ) then local success success, args.asOf = pcall( formatDate, args.asOf, mi.dates.asOf.f ) if success then args.price = args.price .. mw.ustring.format( mi.texts.asOf, args.asOf ) end end formatText( args, results, 'price', 'voy-listing-price p-note note' ) makePayment( args, results ) -- adding Unesco symbol if args.unesco ~= '' and vi.options.showUnesco then local uLink, uTitle = require( 'Module:VCard/Unesco' ).getUnescoInfo( country ) table.insert( results, mu.addLinkIcon( 'voy-listing-unesco', uLink, uTitle, 'unesco' ) ) end local noContent = #results == 0 -- adding DMS coordinates if show.coord then table.insert( results, mu.dmsCoordinates( args, page, country, vc.fromWD.lat ) ) end if mi.options.showSisters == 'atEnd' then table.insert( results, mu.makeIcons( args, page, country, entity, show, vc.fromWD ) ) end local description local space = mi.texts.space -- adding description in block mode if args.description ~= '' and not show.inlineDescription then -- last edit will be inserted at the end of the div tag wrapDescription( args, results, false, makeMetadata( args, page ) ) noContent = false description = table.concat( results, space ) if description ~= '' then description = space .. description end -- adding description in inline mode else description = table.concat( results, space ) if description ~= '' then description = space .. description end end return removePeriods( description ), noContent end -- vCard main function function vc.vCard( frame ) mu.initMaintenance() local page = mu.getPageData() -- getting location (vCard/listing) entity, show options and country data local args, vcEntity, show, country = initialParametersCheck( frame, page ) -- associated Wikivoyage page of the location in current Wikivoyage branch -- possibly modified by mu.getArticleLink() args.wikiPage = '' args.officialName = '' -- getting data from Wikidata getDataFromWikidata( args, page, country, vcEntity ) -- final check local defaultType = frame.args.type finalParametersCheck( args, show, page, country, defaultType, vcEntity ) -- making output -- leading part for marker mode: only location names and comment -- saving address args.addressOrig = args.address -- creating text parts -- leading part (marker and names) local leading = makeMarkerAndName( args, show, page, country, frame ) .. makeEvent( args, page ) -- additional parts for vCard mode -- get address and directions local address = makeAddressAndDirections( args, page, country ) -- get all contact information local contacts = makeContacts( args, country ) -- all contacts contacts = removePeriods( address .. contacts ) -- making description, coordinates, and meta data local description, noContent = makeDescription( args, show, page, country, vcEntity ) local r = leading local icons = '' if contacts == '' and noContent then show.inline = true r = r .. mu.makeIcons( args, page, country, vcEntity, show, vc.fromWD ) .. description else if type( mi.options.showSisters ) == 'boolean' then -- could also be 'atEnd', then part of body icons = mu.makeIcons( args, page, country, vcEntity, show, vc.fromWD ) end -- mi.texts.periodSeparator = '. ' r = removePeriods( r .. contacts .. icons .. ( show.noperiod and '' or mi.texts.periodSeparator ) .. description ) :gsub( '%)(</span>)%s*(<span [^>]*>)%s*%(', '%1; %2' ) end -- prevents line break before punctuation mark r = r:gsub( '</span>([,;.:!?])', '%1</span>' ) -- remove space(s) before punctuation marks :gsub( '%s+(<span [^>]*>[,;.:!?])', '%1' ) if show.inlineDescription then r = r:gsub( '%s+$', '' ) .. makeMetadata( args, page ) end -- error handling and maintenance, not in template and module namespaces if country.unknownLanguage then mu.addMaintenance( 'unknownLanguage' ) end if country.unknownPropertyLanguage then mu.addMaintenance( 'unknownPropertyLanguage' ) end r = r .. mu.makeMaintenance( page, { wu, mu, cm, hr } ) -- wrapping tag args.address = args.addressOrig args.template = 'vCard' return mu.makeWrapper( r, args, page, country, show, vp.vcardData, frame ) end return vc capbzxso4856qlp2fujjwky0am17f0k Modulo:VCard/Params 828 4802 73247 72148 2026-09-24T10:44:40Z RolandUnger 168 Update 73247 Scribunto text/plain --[[ This module contains the parameter tables and definitions. Do not modify this module. The translated values are stored in Module:vCard/i18n. Not all parameters given in the ParMap table can be used by authors. They are only for internal usage and will not be shown in the output (for instance booking). Parameters for internal usage will be generated by the program or fetched from Wikidata. --]] -- module import local vi = require( 'Module:VCard/i18n' ) -- additional vCard options return { -- administration moduleInterface = { suite = 'vCard', sub = 'Params', serial = '2026-09-17', item = 65455743 }, -- complete table of parameters -- true: get it from Wikidata in any case -- for parameter translations see Module:VCard/i18n ParMap = { address = '', addressLang = '', addressLocal = '', agoda = true, -- Agoda.com alt = '', applemaps = true, -- Maps.Apple.com auto = '', before = '', booking = true, -- Booking.com checkin = '', checkout = '', color = '', -- internal use comment = '', commonscat = '', content = '', copyMarker = '', country = '', dav = true, -- Alpenverein.de description = '', directions = '', directionsLocal = '', email = '', expedia = true, -- Expedia.com facebook = '', fax = '', flickr = '', foursquare = true, -- Foursquare.com geonames = true, -- Geonames.org googlemaps = '', -- Maps.Google.com group = '', histhotelsAm = true, -- HistoricHotels.org histhotelsEu = true, -- HistoricHotelsOfEurope.com histhotelsWw = true, -- HistoricHotelsWorldwide.com hostelworld = true, -- Hostelworld.com hotels = true, -- Hotels.com hours = '', iata = vi.options.showIata, icao = vi.options.showIcao, id = '', -- used if wikidata is missing image = true, instagram = '', kayak = true, -- Kayak.com lastedit = '', lat = '', leadingHotels = true, -- LHW.com localLang = '', long = '', mapGroup = '', mobile = '', name = true, nameExtra = '', nameLatin = '', nameLocal = '', nameMap = '', oeav = true, -- Alpenverein.at osmNodeId = true, osmRelationId = true, osmWayId = true, payment = '', phone = '', preferredHotels = true, -- PreferredHotels.com price = '', pzs = true, -- PZS.si (Slovenia) recreation = true, -- Recreation.gov relaisChateaux = true, -- RelaisChateaux.com rss = true, -- web feed sac = true, -- SAC-CAS.ch sectionFrom = '', show = vi.options.defaultShow, skyscanner = true, -- Skyscanner.com stationNumber = true, -- Intl. station number status = '', styles = '', subtype = '', subtypeAdd = true, -- internal use symbol = '', -- internal use text = '', -- internal use tiktok = '', tollfree = '', trip = true, -- Trip.com tripadvisor = true, -- Tripadvisor.com type = '', unesco = vi.options.showUnesco, url = '', urlMap = true, -- official map URL urlTimetable = true, -- timetable/schedule URL useIcon = '', -- internal use wikidata = '', wikipedia = '', -- deprecated x = '', youtube = '', zoom = '', date = '', -- for events month = '', year = '', endDate = '', endMonth = '', endYear = '', frequency = '', location = '' }, --[[ Wikidata properties and definitions for vCard parameters p property or set of properties f formatter string c maximum count of results, default = 1 m concat mode (if c > 1), default concat with ', ' v value type, empty: string value (i.e. default type), id: string value of an id like Q1234567 idl: string value of the label of an id like Q1234567 il: language-dependent string value iq: string value with qualifier ids iqa: string value with qualifier ids, for comments in accessibility iqp: string value with qualifier ids, for comments in policies iqu: string value with qualifier ids, for UNESCO parts au: quantity consisting of amount and unit pau: quantity consisting of amount (for P8733) vq: string or table value with qualifiers ids and references q table of qualifiers allowed, for value type id l = lang: language dependent wiki / local: monolingual text by wiki or local language le = true: use date for lastedit parameter t = phone type (landline, mobile) --]] ParWD = { address = {}, addressLocal = {}, agoda = { p = 'P6008' }, applemaps = { p = 'P10046' }, booking = { p = 'P3607' }, checkin = { p = 'P8745', v = 'idl' }, checkout = { p = 'P8746', v = 'idl' }, dav = { p = 'P5757' }, directions = { p = 'P2795', v = 'il', l = 'wiki' }, directionsLocal = { p = 'P2795', v = 'il', l = 'local' }, email = { p = 'P968', v = 'vq', c = 5 }, expedia = { p = 'P5651' }, facebook = { p = { { p = 'P2013', f = 'https://www.facebook.com/%s' }, -- Facebook username { p = 'P1997', f = 'https://www.facebook.com/%s' }, -- Facebook places ID { p = 'P11705', f = 'https://www.facebook.com/pages/%s' } } }, -- Facebook numeric ID fax = { p = 'P2900', v = 'vq', c = 3 }, flickr = { p = 'P3267', f = 'https://www.flickr.com/photos/%s' }, foursquare = { p = 'P1968' }, geonames = { p = 'P1566' }, googlemaps = { p = 'P3749' }, histhotelsAm = { p = 'P5734' }, histhotelsEu = { p = 'P5774' }, histhotelsWw = { p = 'P5735' }, hostelworld = { p = 'P10442' }, hotels = { p = 'P3898' }, iata = { p = 'P238', c = 3 }, icao = { p = 'P239' }, image = { p = { { p = 'P18' }, { p = 'P3451' }, -- nighttime view { p = 'P8592' }, -- aerial view { p = 'P5775' } } }, -- interior image instagram = { p = { { p = 'P2003', f = 'https://www.instagram.com/%s/' }, { p = 'P4173', f = 'https://www.instagram.com/explore/locations/%s/' } } }, kayak = { p = 'P10547' }, leadingHotels = { p = 'P5834' }, mobile = { p = 'P1329', v = 'vq', c = 5, t = 'mobile' }, nameLocal = {}, oeav = { p = 'P5759' }, osmNodeId = { p = 'P11693' }, osmRelationId = { p = 'P402' }, osmWayId = { p = 'P10689' }, payment = { p = 'P2851', v = 'id', c = 50, m = 'no' }, phone = { p = 'P1329', v = 'vq', c = 5, t = 'landline' }, preferredHotels = { p = 'P5890' }, price = { p = 'P2555', v = 'au', c = 10, le = true }, -- fee pzs = { p = 'P5758' }, recreation = { p = 'P3714' }, relaisChateaux = { p = 'P5836' }, rss = { p = 'P1019' }, sac = { p = 'P5761' }, skyscanner = { p = 'P10487' }, stationNumber = { p = 'P954' }, -- intl station number subtypeAdd = { p = { { p = 'P912', v = 'iqa', c = 50 }, -- has facility { p = 'P166', v = 'iq', c = 5, q = { 'Q2976556', 'Q20824563', 'Q104135230' } }, -- awards received (hotel rating, Michelin etc.) { p = 'P10290', v = 'iq', c = 3 }, -- hotel rating { p = 'P8733', v = 'pau' }, -- number of rooms { p = 'P2012', v = 'iq', c = 50 }, -- cuisine { p = 'P2846', v = 'iq' }, -- wheelchair { p = 'P2848', v = 'iq' }, -- WLAN { p = 'P5023', v = 'iqp', c = 10 } }, c = 100, m = 'no' }, -- activity policies tiktok = { p = { { p = 'P7085', f = 'https://www.tiktok.com/@%s' }, -- TikTok username { p = 'P11559', f = 'https://www.tiktok.com/place/_-%s' } } }, -- TikTok place ID trip = { p = 'P10425' }, tripadvisor = { p = 'P3134' }, x = { p = 'P2002', f = 'https://x.com/%s' }, unesco = { p = { { p = 'P757' }, { p = 'P1435', v = 'iqu', q = { 'Q43113623', 'Q9259' } } } }, url = { p = { { p = 'P856', l = 'lang' }, -- URL { p = 'P973', l = 'lang' } } }, -- described at URL urlMap = { p = 'P9601' }, urlTimetable = { p = 'P12677' }, youtube = { p = { { p = 'P11245', f = 'https://www.youtube.com/@%s' }, -- Youtube channel @ alias { p = 'P2397', f = 'https://www.youtube.com/channel/%s' } } } -- Youtube channel }, -- additional parameters for auto = y ParWDAdd = { address = 1, addressLocal = 1, directions = 1, directionsLocal = 1, hours = 1, nameLocal = 1 }, -- parameters to save in vCard wrapper tag vcardData = { addressLang = 'data-address-lang', -- language of address addressLocal = 'data-address-local', color = 'data-color', commonscat = 'data-commonscat', directionsLocal = 'data-directions-local', group = 'data-group', image = 'data-image', mapGroup = 'data-map-group', nameLocal = 'data-name-local', rss = 'data-rss', subtype = 'data-subtype', symbol = 'data-symbol', type = 'data-type', url = 'data-url', wikidata = 'data-wikidata', agoda = 'data-agoda-com', applemaps = 'data-apple-maps-id', booking = 'data-booking-com', dav = 'data-alpenverein-de', expedia = 'data-expedia-com', foursquare = 'data-foursquare-id', geonames = 'data-geonames-id', googlemaps = 'data-google-maps-cid', histhotelsAm = 'data-historic-hotels-america', histhotelsEu = 'data-historic-hotels-europe', histhotelsWw = 'data-historic-hotels-worldwide', hostelworld = 'data-hostelworld-com', hotels = 'data-hotels-com', kayak = 'data-kayak-com', leadingHotels = 'data-leading-hotels', oeav = 'data-alpenverein-at', osmNodeId = 'data-osm-node-id', osmRelationId = 'data-osm-relation-id', osmWayId = 'data-osm-way-id', preferredHotels = 'data-preferred-hotels', pzs = 'data-pzs-si', recreation = 'data-recreation-gov', relaisChateaux = 'data-relais-chateaux', sac = 'data-sac-cas-ch', sectionFrom = 'data-section-from', skyscanner = 'data-skyscanner-com', stationNumber = 'data-station-number', trip = 'data-trip-com', tripadvisor = 'data-tripadvisor-com', urlMap = 'data-map-url', urlTimetable = 'data-timetable-url' }, -- check if event checkEvent = { 'date', 'month', 'year', 'endDate', 'endMonth', 'endYear', 'frequency', 'location' }, -- prevent local data if wiki language == country language localData = { 'nameLocal', 'addressLocal', 'directionsLocal' }, -- phone numbers for fetching country data phones = { 'phone', 'fax', 'mobile', 'tollfree' }, -- possible values for show parameter show = { all = 1, coord = 1, copy = 1, inline = 1, noairport = 1, none = 1, noperiod = 1, nositelinks = 1, nosocialmedia = 1, outdent = 1, poi = 1, symbol = 1, wikilink = 1 } } 8w7v8nbgxdv54xpuzx7f9mgjq8ymb1p Modulo:VCard/Qualifiers 828 4803 73241 72146 2026-09-24T10:44:16Z RolandUnger 168 Update 73241 Scribunto text/plain -- Qualifier to label table -- please use only quotation marks instead of apostrophs for JSON export return { -- documentation moduleInterface = { suite = "VCard", sub = "VCard/Qualifiers", serial = "2026-09-23", item = 99929816 }, labels = { -- unuoj / units gratis = "senkosta", Q1543615 = "senkosta", Q1092296 = "Aĝojaro", Q24564698 = "Aĝojaro", -- uzado / use (P366) -- parto rilatanta / applies to part (P518) etc. Q5070802 = "Krizostato", Q11028 = "Informo", Q58897583 = "Informo", Q1482145 = "Telefonhelpo", Q256132 = "Telefoncentralo", Q1261521 = "Telefoncentralo", Q589666 = "Telefoncentralo", Q2794937 = "Akceptejo", Q31948 = "Vestiblo", Q862212 = "Fojero", Q4096995 = "Rezervo", Q1029698 = "Gvidata rondiro", Q7673285 = "Seĝa rezervo", Q1162163 = "Direktisto", Q267936 = "Direktisto", Q25713832 = "Estro", Q11964531 = "Manaĝero", Q22132694 = "Muzedirektoro", Q80687 = "Sekretariato", Q859482 = "Sekretariato", Q182060 = "Oficejo", Q5283295 = "Administracio", Q50412353 = "Administracio", Q39809 = "Merkatiko", Q133080 = "Publikrilatoj", Q111148864 = "Kultura oficejo", Q674426 = "Kuratoro", Q2108946 = "Gazetara oficejo", Q1193236 = "Novaĵa amaskomunikilo", Q5196479 = "Klienta subteno", Q1060653 = "Klienta servo", Q955464 = "Pastro", Q7406919 = "Servo", Q918324 = "Flughavena turo", Q51073356 = "Havenestro", Q11735065 = "Havenestro", Q12407563 = "Devigo de parkumejoj", Q1049511 = "WhatsApp", Q15616276 = "Telegram", Q17517 = "Poŝtelefono", Q738621 = "Fiksa telefono", Q2664461 = "Pordisto", Q1735282 = "Kassisto", Q1463565 = "Kassisto", Q551800 = "Biletoj", Q187456 = "Trinkejo", Q777754 = "Manĝlivera servo", Q41958 = "Manĝlivera servo", Q171141 = "Gastronomio", Q43164 = "Kuirejo", Q213441 = "Vendejo", Q11707 = "Restoracio", Q547762 = "Amuzumado", Q133215 = "Kazino", Q1065656 = "Gimnastikejo", Q55187 = "Tondisto", Q31374404 = "Butikcentro", Q179415 = "Masaĝo", Q33506 = "Muzeo", Q2772772 = "Milita muzeo", Q1824143 = "Liverado", Q2048970 = "Ĉambra servo", Q15983979 = "Oficejo pri perditaj posedaĵoj", Q60616546 = "Urba turismo", Q112726458 = "Vizoficejo", Q862761 = "Interne", Q1322786 = "Eksteraĵo", Q121298623 = "Subĉiela areo", Q115156410 = "Montra kolekto", Q464980 = "Ekspozicio", Q5402268 = "Daŭra ekspozicio", Q10426913 = "Daŭra ekspozicio", Q29023906 = "Portempa ekspozicio", -- por homoj / applies to people (P6001) Q5 = "Persono", Q1340307 = "Malgranda infano", Q11370581 = "Beboj kaj infanetoj", Q7569 = "Infano", Q29514218 = "Filo", Q1076052 = "Infanĝardenano", Q11519472 = "Infanĝardenano", Q1902344 = "Infanĝardenano", Q190007 = "Junaĝulo", Q131774 = "Junaĝulo", Q170079 = "Neplenaĝulo", Q1492760 = "Dekkelkjarulo", Q17156455 = "Juna plenkreskulo", Q80994 = "Plenkreskulo", Q18000 = "Plenkreskulo", Q16003605 = "Bazlernejaj studentoj", Q98021727 = "Bazlernejaj studentoj", Q16003532 = "Gimnaziano", Q15360275 = "Mezlernejaj studentoj", Q48942 = "Lernanto", Q68131879 = "Lernanto", Q73229462 = "Lernanto", Q98033936 = "Mezlernejaj studentoj", Q37226 = "Instruisto", Q48282 = "Studento", Q315247 = "Universitata studento", Q110207241 = "Eksterlanda studento", Q253567 = "Metilernanto", Q59263364 = "Metilernanto", Q28790169 = "Senlaborulo", Q59308743 = "Ricevulo de registara asistado", Q109710549 = "Volontulo", Q136806547 = "Volontulo", Q136806565 = "Volontulo", Q24716636 = "Volontulo", Q1454927 = "Soldatservanto", Q47228496 = "Soldatservanto", Q1930187 = "Ĵurnalisto", Q1749879 = "Emerito", Q1358789 = "Maljunuloj", Q191089 = "Maljunuloj", Q2191986 = "Maljunuloj", Q111524907 = "Maljunuloj ekde 60", Q117131136 = "Maljunuloj ekde 65", Q108427775 = "Maljunuloj super 65", Q12131 = "Malkapablo", Q10857933 = "Malkapablo", Q1250414 = "Grave handikapita", Q136806121 = "Grave handikapita (50% aŭ pli)", Q8436 = "Familio", Q1422286 = "Kompaniulo", Q874405 = "Grupo", Q16334295 = "Grupo", Q1605672 = "Junulara gvidanto", Q113191894 = "Egipta studento", Q113191817 = "Araba studento", Q221488 = "Piediranto", Q11442 = "Biciklo", Q42889 = "Rimedo de transporto", Q1420 = "Aŭtomobilo", Q1144312 = "Persona aŭto", Q190578 = "Persona aŭto", Q43193 = "Kamiono", Q5638 = "Buso", Q1373492 = "Buso", Q193234 = "Skotero", Q34493 = "Motorciklo", Q23901795 = "plena kotizo", Q100157294 = "malpliigita kotizo", Q23901802 = "malpliigita kotizo", Q10328277 = "malpliigita enirkotizo", Q10585806 = "Minimumo", Q10578722 = "Maksimumo", Q30079877 = "Monata bileto", Q2024421 = "Enreta bileto", Q59582212 = "Semajna bileto", Q819073 = "Labortago", Q211391 = "Semajnfino", Q22947 = "Loĝanto", Q1020994 = "Civitano", Q70237645 = "Hejmlando", Q473741 = "Eksterlandano", Q1072012 = "Eksterlandano", Q56508363 = "Civitano de Eŭropa Unio aŭ Eŭropa Ekonomia Areo", Q56508358 = "Ne-EU-civitanoj", Q1061510 = "Egipta", Q35323 = "Araba", Q31 = "Belgio", Q4200853 = "Indonezianoj", Q15731961 = "Indonezianoj", Q19840821 = "Singapuranoj", Q126003079 = "Singapuranoj", Q2408569 = "Tajlandanoj", Q7901501 = "Urugvajanoj", Q39201 = "dorlotbesto", Q144 = "hundo", Q62966720 = "parkumeja kotizo", Q1039099 = "ĉiĉerono", Q758877 = "aŭdogvidilo", Q15328 = "kamerao", Q313600 = "fotilo", Q313614 = "filmilo", Q335234 = "filmilo", Q335095 = "filmilo", Q683906 = "stativo", Q24192067 = "atingebla per rulseĝo", Q24192068 = "rulseĝo alirebla kun helpo", Q63731120 = "rulseĝo parte alirebla", Q63731151 = "rulseĝo parte alirebla kun helpo" -- es fehlen Übernachtung, ÜF, EZ, DZ u. ä. (in Wikidata anlegen) } } 1tyx3fxeskdkm12oboq3900z68jvm7u Modulo:VCard/Subtypes 828 4804 73242 72958 2026-09-24T10:44:19Z RolandUnger 168 Update 73242 Scribunto text/plain -- empty strings should be filled with icons -- please use only quotation marks instead of apostrophs for JSON export return { -- administration moduleInterface = { suite = 'vCard', sub = 'Subtypes', serial = '2026-08-20', item = 65455756 }, firstGroup = 2, -- first group to display fromWDGroupNumber = 98, -- group number for Q... types from Wikidata fromTypesGroupNumber = 99, -- group number for types from types table -- subtype conversion convert = { hotelstars = { "1", "2", "3", "4", "5" }, -- hotel stars codes michelin = { "michelin1", "michelin2", "michelin3" } }, -- type list f = { -- classification, rating, y & n. Group 1 is usually not displayed budget = { g = 1, wd = "", n = "günstig" }, midrange = { g = 1, wd = "", n = "mittel" }, upmarket = { g = 1, wd = "", n = "gehoben" }, -- fetching features from Wikidata n = { g = 1, wd = "", alias = { "no", "none", "nein" }, n = "ohne Wikidata-Merkmale" }, y = { g = 1, wd = "", alias = { "yes", "j", "ja" }, n = "mit Wikidata-Merkmalen" }, -- hotel rating hotelstars = { g = 2, wd = "Q2976556", n = "Hotel-Stern[e]" }, -- see: convert -- Upto now it seems that there is no font containing the left black half star -- (u+2BE8): ⯨. That's why now the ½ workaround. ["1"] = { g = 2, wd ="Q110772650", sortkey = "01*", n = "★", t = "1-Stern-Bewertung" }, -- tourist ["1h"] = { g = 2, wd ="Q110932985", sortkey = "01*5", n = "★½", t = "1,5-Sterne-Bewertung" }, -- superior tourist (tourist plus) ["1s"] = { g = 2, wd ="Q109726413", sortkey = "01*S", n = "★S", t = "1-Stern-Superior-Bewertung" }, -- superior tourist (tourist plus) ["2"] = { g = 2, wd ="Q110772651", sortkey = "02*", n = "★★", t = "2-Sterne-Bewertung" }, -- standard ["2h"] = { g = 2, wd ="Q110932986", sortkey = "02*5", n = "★★½", t = "2,5-Sterne-Bewertung" }, -- superior standard ["2s"] = { g = 2, wd ="Q109726348", sortkey = "02*S", n = "★★S", t = "2-Sterne-Superior-Bewertung" }, -- superior standard ["3"] = { g = 2, wd ="Q110772652", sortkey = "03*", n = "★★★", t = "3-Sterne-Bewertung" }, -- comfort ["3h"] = { g = 2, wd ="Q110932987", sortkey = "03*5", n = "★★★½", t = "3,5-Sterne-Bewertung" }, -- superior comfort ["3s"] = { g = 2, wd ="Q109726284", sortkey = "03*S", n = "★★★S", t = "3-Sterne-Superior-Bewertung" }, -- superior comfort ["4"] = { g = 2, wd ={ "Q110772653", "Q99309708" }, sortkey = "04*", n = "★★★★", t = "4-Sterne-Bewertung" }, -- first class ["4h"] = { g = 2, wd ="Q110932988", sortkey = "04*5", n = "★★★★½", t = "4,5-Sterne-Bewertung" }, -- superior first class ["4s"] = { g = 2, wd ="Q109726210", sortkey = "04*S", n = "★★★★S", t = "4-Sterne-Superior-Bewertung" }, -- superior first class ["5"] = { g = 2, wd ={ "Q109248725", "Q109248724" }, sortkey = "05*", n = "★★★★★", t = "5-Sterne-Bewertung" }, -- luxury ["5s"] = { g = 2, wd ="Q109726138", sortkey = "05*S", n = "★★★★★S", t = "5-Sterne-Superior-Bewertung" }, -- superior luxury -- Michelin awards to restaurant chefs bib_gourmand = { g = 2, wd ="Q104135230", n = "Bib Gourmand" }, michelin = { g = 2, wd = "Q20824563", n = "Michelin-Stern[e]" }, michelin1 = { g = 2, wd = "", n = "Michelin 1*", f = "Etoile Michelin-1.svg", c = 1 }, michelin2 = { g = 2, wd = "", n = "Michelin 2*", f = "Etoile Michelin-1.svg", c = 2 }, michelin3 = { g = 2, wd = "", n = "Michelin 3*", f = "Etoile Michelin-1.svg", c = 3 }, -- subtypes from subtype parameter in types table bnb = { g = 3, wd = "Q367914", n = "Bed & Breakfast" }, boarding_house = { g = 3, wd = { "Q1558858", "Q1065252" }, n = "Pension" }, hotel_garni= { g = 3, wd = "Q1631103", n = "Garni" }, -- general facilities accessible = { g = 4, wd = "Q808926", n = "barrierefrei" }, -- barrier-free, for handicapped people ai = { g = 4, wd = "Q1281666", n = "All inclusive" }, basement_garage = { g = 4, wd = "Q2431970", n = "Tiefgarage[]" }, car_park = { g = 4, wd = "Q13218805", n = "Parkhaus" }, free_wlan = { g = 4, wd = "Q1543615", n = "freies WLAN" }, garage = { g = 4, wd = "Q22733", n = "Garage[n]" }, induction_loop = { g = 4, wd = "Q2163913", n = "Induktionsschleife[n]" }, internet_access = { g = 4, wd = "Q1472399", n = "Internetzugang" }, -- unknown type or both lan and wlan lan = { g = 4, wd = "Q11381", n = "LAN" }, lgbt = { g = 4, wd = "Q17884", n = "LGBT", f = "Gay flag.svg" }, -- including gay nobreakfast= { g = 4, wd ="Q106041208", n = "kein Frühstück" }, nowheelchair = { g = 4, wd = "Q24192069", n = "nicht rollstuhlzugänglich", f = "Wheelchair-red3.png" }, nowlan = { g = 4, wd = "Q1814990", n = "kein WLAN" }, -- no paid_wlan = { g = 4, wd = "Q24202480", n = "kostenpflichtiges WLAN" }, parking = { g = 4, wd = "Q6501349", n = "Parkpl[ä|a]tz[e]" }, tactile_graphic = { g = 4, wd = "Q7674130", n = "Blindengrafik[en]" }, valet_parking = { g = 4, wd = "Q1423019", n = "Valet-Parken" }, withbreakfast = { g = 4, wd ="Q106041297", n = "mit Frühstück" }, wheelchair = { g = 4, wd = "Q24192067", n = "rollstuhlzugänglich", f = "Wheelchair-green3.png" }, wheelchair_available = { g = 4, wd = "Q191931", n = "Rollstuhl verfügbar" }, wheelchair_with_help = { g = 4, wd = "Q24192068", n = "rollstuhlzugänglich mit Hilfe", f = "Wheelchair-yellow3.png" }, wheelchair_partially = { g = 4, wd = "Q63731120", n = "teilweise rollstuhlzugänglich" }, wheelchair_partially_with_help = { g = 4, wd = "Q63731151", n = "teilweise rollstuhlzugänglich mit Hilfe" }, wlan = { g = 4, wd = { "Q6452715", "Q29643" }, n = "WLAN" }, -- yes -- hotel facilities adult_pool = { g = 5, wd = "", n = "Pool[s] für Erwachsene" }, airport_transfer_service = { g = 5, wd ="Q110012299", n = "Flughafentransfer-Service" }, atm = { g = 5, wd = { "Q81235", "Q6554231"}, n = "Geldautomat[en], Bankomat[en]" }, ballroom = { g = 5, wd = "Q805353", n = "Balls[ä|aa]l[e]" }, babysitter = { g = 5, wd = "Q45181247", n = "Babysitter[]" }, bank = { g = 5, wd = "Q22687", n = "Bank[en]" }, banquet_room = { g = 5, wd = "Q85833489", n = "Banketts[ä|aa]l[e]" }, bar = { g = 5, wd = "Q187456", n = "Bar[s]" }, beach = { g = 5, wd = "Q40080", n = "Str[ä|a]nd[e]" }, bed = { g = 5, wd = "Q42177", n = "Bett[en]" }, bicycle_stand = { g = 5, wd = "Q1392526", n = "Fahrradstellpl[ä|a]tz[e]" }, bike_rental= { g = 5, wd = "Q10611118", n = "Fahrradverleih[e]" }, business = { g = 5, wd = "Q203180", n = "Geschäftsbereich[e]" }, buy = { g = 5, wd = "Q1369832", n = "Einkaufen" }, cabana = { g = 5, wd = "Q3649129", n = "Cabana[s], Hütte[n], Umkleidehäuschen" }, cafe = { g = 5, wd = "Q30022", n = "Café[s]" }, cafeteria = { g = 5, wd = "Q8463304", n = "Cafeteria[s]" }, casino = { g = 5, wd = "Q133215", n = "Casino[s]" }, cell = { g = 5, wd = "Q2555640", n = "Zelle[n]" }, change_machine = { g = 5, wd = "Q5071849", n = "Geldwechselautomat[en]" }, cinema = { g = 5, wd = "Q41253", n = "Kino[s]" }, cloakroom = { g = 5, wd = "Q965173", n = "Garderobe[n]" }, conference = { g = 5, wd = { "Q625994", "Q1207465" }, n = "Konferenzr[ä|a]um[e]" }, currency_exchange = { g = 5, wd = "Q2002539", n = "Geldwechsel" }, dance_hall = { g = 5, wd ="Q121085156", n = "Tanzs[ä|aa]l[e]" }, dining_room= { g = 5, wd = "Q661199", n = "Esszimmer" }, diving = { g = 5, wd = "Q179643", n = "Tauchbas[en|is]" }, dormitory = { g = 5, wd = "Q3037266", n = "Schlafs[ä|aa]l[e]" }, family_room= { g = 5, wd = "Q5433389", n = "Familienzimmer[]" }, fitness_center = { g = 5, wd = { "Q1065656", "Q30750411", "Q56298769" }, n = "Fitnessstudio[s]" }, -- including gym, healthclub games_room = { g = 5, wd = "", n = "Spielzimmer[]" }, garden = { g = 5, wd = "Q1107656", n = "G[ä|a]rten" }, golf = { g = 5, wd = { "Q5377", "Q1048525", "Q3177122", "Q3177122" }, n = "Golf, Golfpl[ä|a]tz[e]" }, gym = { g = 5, wd = { "Q14092", "Q203609", "Q121085159" }, n = "Turnhalle[n]" }, indoorpool = { g = 5, wd = "Q357380", n = "Hallenschwimmb[ä|a]d[er]" }, kidsclub = { g = 5, wd = "Q16255832", n = "Kinderclub[s]" }, kiting = { g = 5, wd = "Q219554", n = "Kiten" }, library = { g = 5, wd = "Q7075", n = "Bibliothek[en]" }, lift = { g = 5, wd = "Q132911", n = "Fahrst[ü|u]hl[e], Lift[e]" }, lobby = { g = 5, wd = "Q31948", n = "Lobby[s]" }, luggage_storage = { g = 5, wd = { "Q1195470", "Q21996814" }, n = "Gepäckaufbewahrung[en]" }, money_exchange_machine = { g = 5, wd = "Q25632829", n = "Geldwechselautomat[en]" }, meeting = { g = 5, wd = "Q3469909", n = "Besprechungszimmer[]" }, -- meeting rooms minigolf = { g = 5, wd = "Q754796", n = "Minigolf" }, nightclub = { g = 5, wd = "Q622425", n = "Nachtclub[s]" }, playground = { g = 5, wd = "Q11875349", n = "Spielpl[ä|a]tz[e]" }, playground_tunnel = { g = 5, wd = "Q130308900", n = "Spielplatz-Tunnel[], Kriechtunnel[]" }, pool = { g = 5, wd = { "Q1501", "Q118559330" }, n = "Schwimmbecken[]" }, reception = { g = 5, wd = "Q2794937", alias = "service_counter", n = "Rezeption[en], Empfangsschalter" }, restaurant = { g = 5, wd = "Q11707", n = "Restaurant[s]" }, roof_garden= { g = 5, wd = "Q1156696", n = "Dachg[ä|a]rten" }, roof_terrace= { g = 5, wd = "Q1081213", n = "Dachterrasse[n]" }, room = { g = 5, wd = { "Q180516", "Q105582722" }, n = "Zimmer[]" }, sauna = { g = 5, wd = "Q57036", n = "Sauna[s]" }, slide = { g = 5, wd = "Q334747", n = "Rutsche[n]" }, socket_near_bed = { g = 5, wd ="Q110073378", n = "Steckdose[n] in Bettnähe" }, shop = { g = 5, wd = "Q213441", n = "Geschäft[e]" }, souvenir_shop = { g = 5, wd = "Q865693", n = "Souvenirgeschäft[e]" }, spa = { g = 5, wd = "Q1341387", alias = "wellness_center", n = "Wellness-Center[], Spa[s]" }, sports = { g = 5, wd = "Q349", n = "Sport" }, suite = { g = 5, wd = "Q1367530", n = "Suite[n]" }, surfing = { g = 5, wd = "Q1324499", n = "Surfen" }, tennis = { g = 5, wd = "Q847", n = "Tennis" }, tennis_court = { g = 5, wd = "Q741118", n = "Tennispl[ä|a]tz[e]" }, theater = { g = 5, wd = "Q24354", n = "Theater[]" }, wading_pool= { g = 5, wd = "Q2098314", n = "Planschbecken[]" }, warm_water = { g = 5, wd = "Q1419245", n = "Warmwasser" }, water_slide= { g = 5, wd = "Q1163166", n = "Wasserrutsche[n]" }, wave_pool = { g = 5, wd = "Q827349", n = "Wellenb[ä|a]d[er]" }, -- non-hotel facilities audioguide = { g = 5, wd = "Q758877", n = "Audioguide[s]" }, cctv = { g = 5, wd = { "Q242256", "Q334415" }, n = "Videoüberwachungsanlage[n]" }, communal_bunks = { g = 5, wd = "Q1628935", n = "Pl[ä|a]tz[e] im Matratzenlager" }, educational_workshop = { g = 5, wd ="Q113484895", n = "pädagogische[n] Werkst[ä|a]tt[en]" }, guidebook = { g = 5, wd = "Q223638", n = "gedruckte Reiseführer[]" }, lecture_hall = { g = 5, wd = "Q253275", n = "Hörs[ä|aa]l[e]" }, lighting = { g = 5, wd = "Q210064", n = "Beleuchtung" }, museum_shop= { g = 5, wd = "Q2922607", n = "Museumsgeschäft[e]" }, organ = { g = 5, wd = "Q1444", n = "Orgel[n]" }, public_clock = { g = 5, wd ="Q129165885", n = "öffentliche Uhr[en]" }, rest_area = { g = 5, wd = { "Q47520603", "Q785979" }, alias = "picnic_site", n = "Rastpl[ä|a]tz[e], Picknickplatz" }, reading_room = { g = 5, wd = "Q1753764", n = "Leses[ä|aa]l[e]" }, shakedown = { g = 5, wd = "Q40415224", n = "Pl[ä|a]tz[e] im Notlager" }, school_meal= { g = 5, wd = "Q1195832", n = "Schulspeisung" }, winter_room= { g = 5, wd = "Q382899", n = "Pl[ä|a]tz[e] im Winterraum" }, -- services in hotels etc. ["24-hour_reception"] = { g = 6, wd = "", n = "24-Stunden-Rezeption" }, accessible_toilet = { g = 6, wd = "Q2775009", n = "Behinderten-WC[s]" }, airport_shuttle = { g = 6, wd = "", n = "Flughafenshuttle" }, airport_terminal = { g = 6, wd = "Q849706", n = "Flughafenterminal[s]" }, airport_transportation = { g = 6, wd = "", n = "Flughafentransport" }, animation = { g = 6, wd = "Q547762", n = "Animation" }, baby_change = { g = 6, wd = "Q2567605", n = "Wickelr[ä|a]um[e]" }, babysitting = { g = 6, wd = "Q797990", n = "Babysitten" }, bahnhofsmission = { g = 6, wd = "Q801713", n = "Bahnhofsmission" }, beauty_service = { g = 6, wd = "Q30303305", n = "Schönheitsservice" }, bicycle = { g = 6, wd = "Q11442", n = "Fahrrad" }, breakfast = { g = 6, wd = "Q80973", n = "Frühstück" }, breakfast_buffet = { g = 6, wd = "", n = "Frühstücksbuffet" }, breakfast_included= { g = 6, wd = "", n = "inklusive Frühstück" }, bus_stop = { g = 6, wd = "Q953806", n = "Bushaltestelle[n]" }, car_hire = { g = 6, wd = "Q291240", n = "Autovermietung[en]" }, changing_table = { g = 6, wd = "Q1780834", n = "Wickeltisch[e]" }, concierge = { g = 6, wd = "Q2664461", n = "Concierge" }, discotheque = { g = 6, wd = "Q1228895", n = "Discothek[en]" }, dry_cleaning = { g = 6, wd = "Q878156", n = "chemische Reinigung[en]" }, entertainment = { g = 6, wd = "Q173799", n = "Unterhaltung" }, federal_police = { g = 6, wd = "Q56026", n = "Bundespolizei" }, free_parking = { g = 6, wd ="Q108759647", n = "kostenlose[|r] Parkpl[ä|a]tz[e]" }, gate = { g = 6, wd = "Q247739", n = "Flugsteig[e]" }, hairdresser = { g = 6, wd = { "Q55187", "Q95856773", "Q3062512" }, n = "Friseur[e]" }, laundry = { g = 6, wd = { "Q267734", "Q7223085", "Q12893467", "Q57261433" }, n = "Wäscherei[en]" }, live_music = { g = 6, wd ="Q100348587", n = "Livemusik" }, massage = { g = 6, wd = "Q179415", n = "Massage[n]" }, multilingual_staff= { g = 6, wd = "Q30081", n = "mehrsprachiges Personal" }, newspaper = { g = 6, wd = "Q11032", n = "Tageszeitung" }, paid_parking = { g = 6, wd ="Q128800991", n = "kostenpflichtige[|r] Parkpl[ä|a]tz[e]" }, post_office = { g = 6, wd = "Q35054", n = "Postfiliale[n]" }, public_toilet = { g = 6, wd = { "Q813966", "Q3472280" }, n = "öffentliche Toilette[n]" }, railroad_police = { g = 6, wd = "Q1930355", n = "Bahnpolizei" }, room_service = { g = 6, wd = "Q2048970", n = "Zimmerservice" }, selflaundry = { g = 6, wd = "Q1143034", n = "Waschsalon[s]" }, shuttle_bus = { g = 6, wd = "Q1368498", n = "Shuttlebus" }, taxicab_stand = { g = 6, wd = { "Q82650", "Q1395196" }, n = "Taxist[ä|a]nd[e]" }, ticket_machine = { g = 6, wd = "Q657345", n = "Fahrkartenautomat[en]" }, ticket_office = { g = 6, wd = { "Q56845288", "Q15842100" }, n = "Fahrkartenschalter[]" }, toilet = { g = 6, wd = { "Q7857", "Q97657740" }, n = "Toilette[n]" }, urinal = { g = 6, wd = { "Q152285", "Q97657738" }, n = "Urinal[e]" }, wc = { g = 6, wd = "Q7813355", n = "WC[s]" }, workshop = { g = 6, wd = "Q656720", n = "Werkst[ä|a]tt[en]" }, -- room facilities ac = { g = 7, wd = "Q173725", n = "Klimaanlage[n]" }, air_condition = { g = 5, wd = "Q1265533", n = "Klimaanlage[n]" }, balcony = { g = 7, wd = "Q170552", n = "Balkon[e]" }, bathroom = { g = 7, wd = "Q190771", n = "Badezimmer[]" }, bathtub = { g = 7, wd = "Q152095", n = "Badewanne[n]" }, bottle_warmer = { g = 7, wd = "Q56711128", n = "Flaschenwärmer[]" }, coffeemaker= { g = 7, wd = "Q211841", n = "Kaffeemaschine[n]" }, commonbath = { g = 7, wd = "", n = "Gemeinschaftsb[ä|a]d[er]" }, -- Gemeinschaftsbad fan = { g = 7, wd = "Q6498398", n = "Ventilator[en]" }, fridge = { g = 7, wd = "Q37828", n = "Kühlschr[ä|a]nk[e]" }, grab_rail = { g = 7, wd = "", n = "Haltegriff[e]" }, hairdryer = { g = 7, wd = "Q15004", n = "Fön[e]" }, jacuzzi = { g = 7, wd = "Q1936429", n = "Whirlpool[s]" }, -- incl. hot tub kitchen = { g = 7, wd = "Q43164", n = "Küche[n]" }, -- usable for guest, usually in the room minibar = { g = 7, wd = "Q1191522", n = "Minibar[s]" }, phone = { g = 7, wd = "Q11035", n = "Telefon[e]" }, safe = { g = 7, wd = "Q471898", n = "Safe[s]" }, shower = { g = 7, wd = "Q7863", n = "Dusche[n]" }, terrace = { g = 7, wd = "Q641406", n = "Terrasse[n]" }, tv = { g = 7, wd = "Q8075", n = "Fernseher[], TV" }, -- cuisine by ethnicity african = { g = 8, wd = "Q386284", n = "afrikanische Küche" }, alsatian = { g = 8, wd = "Q3006870", n = "elsässische Küche" }, american = { g = 8, wd = "Q40578", n = "amerikanische Küche" }, arab = { g = 8, wd = "Q623970", n = "arabische Küche" }, argentinian= { g = 8, wd = "Q579500", n = "argentische Küche" }, asian = { g = 8, wd = "Q728206", n = "asiatische Küche" }, australian = { g = 8, wd = "Q783010", n = "australische Küche" }, austrian = { g = 8, wd = "Q42029", n = "österreichische Küche" }, baden = { g = 8, wd = "Q799087", n = "badische Küche" }, balkan = { g = 8, wd = "Q805060", n = "Balkan-Küche" }, basque = { g = 8, wd = "Q521179", n = "baskische Küche" }, bavarian = { g = 8, wd = "Q458851", n = "bayerische Küche" }, bolivian = { g = 8, wd = "Q3006895", n = "bolivianische Küche" }, brazilian = { g = 8, wd = "Q614394", n = "brasilianische Küche" }, burmese = { g = 8, wd = "Q1187275", n = "burmesische Küche" }, californian= { g = 8, wd = "Q1026802", n = "kalifornische Küche" }, cambodian = { g = 8, wd = "Q139430", n = "kambodschanische Küche" }, cantonese = { g = 8, wd = "Q1154790", n = "kantonesische Küche" }, caribbean = { g = 8, wd = "Q1729345", n = "karibische Küche" }, chinese = { g = 8, wd = "Q10876842", n = "chinesische Küche" }, creole = { g = 8, wd = { "Q85430164", "Q1645076" }, n = "kreolische Küche" }, croatian = { g = 8, wd = "Q1789628", n = "kroatische Küche" }, cypriot = { g = 8, wd = "Q245932", n = "zyprische Küche" }, czech = { g = 8, wd = "Q871595", n = "tschechische Küche" }, danish = { g = 8, wd = "Q1196267", n = "dänische Küche" }, egyptian = { g = 8, wd = "Q1346230", n = "ägyptische Küche" }, english = { g = 8, wd = "Q1261477", n = "englische Küche" }, ethiopian = { g = 8, wd = "Q257508", n = "äthiopische Küche" }, european = { g = 8, wd = "Q579316", n = "europäische Küche" }, franconian = { g = 8, wd = "Q1471192", n = "fränkische Küche" }, french = { g = 8, wd = "Q6661", n = "französische Küche" }, fucha_ryori= { g = 8, wd = "Q10286142", n = "Fucha Ryōri" }, georgian = { g = 8, wd = "Q1199026", n = "georgische Küche" }, german = { g = 8, wd = "Q47629", n = "deutsche Küche" }, greek = { g = 8, wd = "Q744027", n = "griechische Küche" }, home_style = { g = 8, wd = "Q881929", n = "gutbürgerliche Küche" }, hunan = { g = 8, wd = "Q1156889", n = "Hunan-Küche" }, hungarian = { g = 8, wd = "Q264327", n = "ungarische Küche" }, indian = { g = 8, wd = "Q192087", n = "indische Küche" }, indonesian = { g = 8, wd = "Q787497", n = "indonesische Küche" }, international = { g = 8, wd = "Q99522230", n = "internationale Küche" }, iranian = { g = 8, wd = "Q1342397", n = "iranische Küche" }, irish = { g = 8, wd = "Q1068545", n = "irische Küche" }, italian = { g = 8, wd = "Q192786", n = "italienische Küche" }, japanese = { g = 8, wd = "Q234138", n = "japanische Küche" }, jewish = { g = 8, wd = "Q284288", n = "jüdische Küche" }, korean = { g = 8, wd = "Q647500", n = "koreanische Küche" }, latin_american = { g = 8, wd = "Q2707196", n = "lateinamerikanische Küche" }, lebanese = { g = 8, wd = "Q929239", n = "libanesische Küche" }, levantine = { g = 8, wd = "Q765174", n = "levantinische Küche" }, malaysian = { g = 8, wd = "Q772247", n = "malaysische Küche" }, medieval = { g = 8, wd = "Q10886", n = "Mittelalterküche" }, mediterranean = { g = 8, wd = "Q934309", n = "Mittelmeerküche" }, mexican = { g = 8, wd = "Q207965", n = "mexikanische Küche" }, modern = { g = 8, wd = "", n = "moderne Küche" }, national = { g = 8, wd = "Q1968435", n = "Nationalküche" }, nepalese = { g = 8, wd = "Q1194855", n = "nepalesische Küche" }, new_nordic = { g = 8, wd = "Q3345199", n = "New Nordic Cuisine" }, nubian = { g = 8, wd ="Q113827054", n = "nubische Küche" }, oriental = { g = 8, wd = "Q1547037", n = "orientalische Küche" }, pakistani = { g = 8, wd = "Q1089120", n = "pakistanische Küche" }, palestinian= { g = 8, wd = "Q1154594", n = "palästinensische Küche" }, peruvian = { g = 8, wd = "Q749847", n = "peruanische Küche" }, polish = { g = 8, wd = "Q756020", n = "polnische Küche" }, portuguese = { g = 8, wd = "Q180817", n = "portugiesische Küche" }, regional = { g = 8, wd = "Q94951", n = "Regionalküche" }, rhenish = { g = 8, wd = "Q2147761", n = "rheinische Küche" }, russian = { g = 8, wd = "Q12505", n = "russische Küche" }, savoy = { g = 8, wd = "Q3006988", n = "Savoyer Küche" }, shandong = { g = 8, wd = "Q1038209", n = "Shandong-Küche" }, sichuan = { g = 8, wd = "Q691365", n = "Sichuan-Küche" }, south_indian= { g = 8, wd = "Q3595152", n = "südindische Küche" }, spanish = { g = 8, wd = "Q622512", n = "spanische Küche" }, swedish = { g = 8, wd = "Q35623", n = "schwedische Küche" }, swiss = { g = 8, wd = "Q13497", n = "schweizerische Küche" }, swabian = { g = 8, wd = "Q880365", n = "schwäbische Küche" }, syrian = { g = 8, wd = "Q4119264", n = "syrische Küche" }, thai = { g = 8, wd = "Q841984", n = "thailändische Küche" }, thuringian = { g = 8, wd = "Q187477", n = "Thüringer Küche" }, turkish = { g = 8, wd = "Q654493", n = "türkische Küche" }, ukranian = { g = 8, wd = "Q1503789", n = "ukrainische Küche" }, vietnamese = { g = 8, wd = "Q826059", n = "vietnamesische Küche" }, western = { g = 8, wd = "Q16143746", n = "westliche Küche" }, westphalian= { g = 8, wd = "Q2565249", n = "westfälische Küche" }, -- cuisine by type of food bagel = { g = 9, wd = "Q272502", n = "Bagel" }, barbecue = { g = 9, wd = "Q461696", n = "Barbecue, BBQ" }, bougatsa = { g = 9, wd = "Q895009", n = "Bougatsa" }, buffet = { g = 9, wd = "Q847462", n = "Büffet" }, burger = { g = 9, wd = "Q6663", n = "Burger" }, cake = { g = 9, wd = "Q13276", n = "Kuchen" }, casserole = { g = 9, wd = "Q7724780", n = "Kasserolle" }, chicken = { g = 9, wd = "Q864693", n = "Hühnchen" }, crepe = { g = 9, wd = "Q12200", n = "Crêpe" }, couscous = { g = 9, wd = "Q76605", n = "Couscous" }, curry = { g = 9, wd = "Q164606", n = "Curry" }, dessert = { g = 9, wd = "Q182940", n = "Dessert, Nachspeise" }, donut = { g = 9, wd = "Q192783", n = "Donut" }, empanada = { g = 9, wd = "Q747457", n = "Empanada" }, fish = { g = 9, wd = "Q152", n = "Fisch" }, fish_and_chips = { g = 9, wd = "Q203925", n = "Fish and Chips" }, fried_food = { g = 9, wd = "Q300472", n = "Braten" }, friture = { g = 9, wd = "Q854618", n = "Frittieren" }, grill = { g = 9, wd = "Q853185", n = "Grill" }, gyros = { g = 9, wd = "Q681596", n = "Gyros" }, halal = { g = 9, wd = "Q85536643", n = "halal" }, ice_cream = { g = 9, wd = "Q13233", n = "Eis, Speiseeis" }, kebab = { g = 9, wd = "Q179010", n = "Kebab" }, noodle = { g = 9, wd = "Q192874", n = "Nudeln" }, pancake = { g = 9, wd = "Q44541", n = "Pfannkuchen, Eierkuchen" }, pasta = { g = 9, wd = "Q178", n = "Pasta" }, pie = { g = 9, wd = "Q13360264", n = "Pie" }, pizza = { g = 9, wd = "Q177", n = "Pizza" }, salad = { g = 9, wd = "Q9266", n = "Salat" }, sandwich = { g = 9, wd = "Q28803", n = "Sandwich" }, sausage = { g = 9, wd = "Q131419", n = "Wurst, Würstchen" }, seafood = { g = 9, wd = "Q192935", n = "Meeresfrüchte" }, soba = { g = 9, wd = "Q753910", n = "Soba" }, soup = { g = 9, wd = "Q41415", n = "Suppe" }, steakhouse = { g = 9, wd = "Q3109696", n = "Steakhaus" }, sushi = { g = 9, wd = "Q46383", n = "Sushi" }, tapas = { g = 9, wd = "Q220964", n = "Tapa, Tapas" }, vegan = { g = 9, wd = { "Q181138", "Q20669090" }, n = "vegan" }, vegetarian = { g = 9, wd = { "Q83364", "Q638022" }, n = "vegetarisch" }, wild_game = { g = 9, wd = "Q223930", n = "Wild" }, yakitori = { g = 9, wd = "Q483163", n = "Yakitori" }, -- drinks alcoholic = { g = 10, wd = "Q154", n = "alkoholische Getränke" }, beer = { g = 10, wd = "Q44", n = "Bier" }, cocktails = { g = 10, wd = "Q134768", n = "Cocktails" }, ["non-alcoholic"] = { g = 10, wd = "Q2647467", n = "alkoholfreie Getränke" }, noalcoholic= { g = 10, wd = "Q67426650", n = "keine alkoholischen Getränke" }, wine = { g = 10, wd = "Q282", n = "Wein" }, -- services in restaurants beer_garden = { g = 11, wd = "Q857909", n = "Biergarten" }, bowling_alley = { g = 11, wd = "Q27106471", n = "Bowlingbahn[en]" }, delivery = { g = 11, wd = { "Q2334804", "Q1824143" }, n = "Lieferung, Freihauslieferung" }, drive_in = { g = 11, wd = "Q14253958", n = "Drive-in" }, drive_through = { g = 11, wd = "Q14253958", n = "Drive-through" }, -- including drive-thru outdoor_seating = { g = 11, wd = "Q98642678", n = "Sitzplätze im Freien" }, reservation = { g = 11, wd = { "Q2145615", "Q7673285" }, n = "Reservierung" }, self_service = { g = 11, wd = "Q1369310", n = "Selbstbedienung" }, table_service = { g = 11, wd ="Q100805023", n = "mit Bedienung" }, takeaway = { g = 11, wd = "Q154383", n = "zum Mitnehmen" }, -- including "take-out", "to-go", and "carry-out" -- activity policies (P5023) -- photography noflash = { g = 12, wd = "Q51728726", n = "ohne Blitz" }, nophotos = { g = 12, wd = "Q51728721", n = "Fotografieren verboten" }, nosticks = { g = 12, wd = "Q53540617", n = "Selfie-Sticks verboten" }, notripod = { g = 12, wd ="Q108583523", n = "ohne Stativ" }, novideo = { g = 12, wd = "Q66361451", n = "Videografieren verboten" }, permit_for_commercial_photography = { g = 12, wd ="Q113756144", n = "Erlaubnis für gewerbsmäßige Fotografie erforderlich" }, photos_allowed= { g = 12, wd = "Q51728733", n = "Fotografieren erlaubt" }, -- general policies adults_only = { g = 13, wd ="Q132174927", n = "Adults Only, Erwachsenenhotel" }, animals = { g = 13, wd ="Q105100898", n = "Tiere erlaubt" }, bags_prohibited = { g = 13, wd ="Q113773766", n = "große Taschen verboten" }, cats = { g = 13, wd ="Q105100905", n = "Katzen erlaubt" }, companion_dogs= { g = 13, wd ="Q116343464", n = "Begleithunde erlaubt" }, couples_and_families = { g = 13, wd ="Q136175147", n = "Couples and Families Only" }, couples_only = { g = 13, wd ="Q136175105", n = "Couples Only" }, dogs = { g = 13, wd ="Q105100922", n = "Hunde erlaubt" }, drinking_ban = { g = 13, wd ="Q111986775", n = "Trinkverbot" }, eating_ban = { g = 13, wd ="Q116343890", n = "Essensverbot" }, face_mask_mandatory = { g = 13, wd = "Q97933005", n = "Gesichtsmaske vorgeschrieben" }, families_only = { g = 13, wd ="Q136175123", n = "Families Only, Familienhotel" }, leashed_dogs = { g = 13, wd = "Q66361287", n = "Hunde an der Leine" }, noanimals = { g = 13, wd ="Q105094093", n = "Tiere verboten" }, nobarefoot = { g = 13, wd ="Q135522352", n = "keine Barfüßigkeit" }, nobikes = { g = 13, wd = "Q66361472", n = "Fahrräder verboten" }, nocamping = { g = 13, wd = "Q66361437", n = "Campingverbot" }, nocats = { g = 13, wd ="Q105094244", n = "Katzen verboten" }, nodogs = { g = 13, wd ="Q105094236", n = "Hunde verboten" }, nodrones = { g = 13, wd = "Q66361435", n = "Drohnen verboten" }, nofeeding = { g = 13, wd = "Q5286412", n = "Tiere füttern verboten" }, nohighheels = { g = 13, wd ="Q123013492", n = "Stöckelschuhe verboten" }, nokids = { g = 13, wd = "Q24861437", n = "keine Kinder" }, nolittering = { g = 13, wd = "Q66361444", n = "Müllabladen verboten" }, noloudly = { g = 13, wd ="Q111986810", n = "lautes Sprechen verboten" }, nonsmoking = { g = 13, wd = "", n = "Nichtraucher" }, nopets = { g = 13, wd = "Q66361297", n = "Haustiere verboten" }, notouch = { g = 13, wd = "Q66361307", n = "Berühren verboten" }, pets = { g = 13, wd = "Q66361299", n = "Haustiere erlaubt" }, smoking = { g = 13, wd = "Q18809854", n = "Raucher" }, smoking_ban = { g = 13, wd = "Q751734", n = "Rauchverbot" }, smoking_separated= { g = 13, wd ="Q110090224", n = "Rauchen an abgetrennten Plätzen" }, water_mandatory= { g = 13, wd = "Q66361375", n = "eigenes Wasser zwingend erforderlich" }, -- dress codes: dress_code = { g = 13, wd = "Q286300", n = "Kleiderordnung" }, smart_casual = { g = 13, wd = "Q7544032", n = "Smart casual" }, decent_clothing = { g = 13, wd = "Q66361332", n = "Angemessene Kleidung erforderlich" }, -- difficulties (routes etc.) novice = { g = 14, wd = "", n = "Anfänger" }, easy = { g = 14, wd = "", n = "geringe Schwierigkeit" }, intermediate = { g = 14, wd = "", n = "mittlere Schwierigkeit" }, advanced = { g = 14, wd = "", n = "Fortgeschrittene" }, expert = { g = 14, wd = "", n = "Erfahrener" }, freeride = { g = 14, wd = "", n = "Freeride" }, extreme = { g = 14, wd = "", n = "extreme Schwierigkeit" }, }, -- group meanings g = { ["1"] = "Preisklasse", ["2"] = "Klassifikation", ["3"] = "Hoteltyp", ["4"] = "allgemeine Ausstattung", ["5"] = "Hotelausstattung", ["6"] = "Hoteldienstleistungen", ["7"] = "Raumausstattung", ["8"] = "Speisen nach Herkunft", ["9"] = "Speisen nach Art", ["10"] = "Getränke", ["11"] = "Restaurantdienstleistungen", ["12"] = "Verhaltensanweisungen Fotografie", ["13"] = "Verhaltensanweisungen", ["14"] = "Schwierigkeitsgrade" }, exclude = { -- do not translate Q116168276 = "10. Superior Deluxe", Q1031873 = "aircraft catapult", Q573970 = "apron", Q104123038 = "bilingual street name sign", Q918324 = "control tower", Q192375 = "hangar", Q464020 = "instrument landing system", Q1061299 = "jet bridge", Q184590 = "runway", Q774583 = "solar panel", Q5191724 = "steeple", Q35473 = "window" } } 8rcv59xqb41zhk04l7i6fkmiqko3zy6 Modulo:Marker utilities 828 4807 73249 72507 2026-09-24T10:48:18Z RolandUnger 168 Update 73249 Scribunto text/plain --[[ Functions library for Marker and vCard modules In non-Wikivoyage projects, sister-project links functions have to be adapted. ]]-- -- require( 'strict' ) local cd = require( 'Module:Coordinates' ) local mg = require( 'Module:Marker utilities/Groups' ) local mi = require( 'Module:Marker utilities/i18n' ) local mm -- MAKI icons local mt = require( 'Module:Marker utilities/Types' ) -- types to groups like drink, eat, go, see, sleep, ... local uc -- URL check local wu = require( 'Module:Wikidata utilities' ) -- module variable and administration local mu = { moduleInterface = { serial = '2026-09-23', item = 58187612 }, comma = mi.texts.comma, commaSeparator = mi.texts.commaSeparator } -- to keep background color in print local colorAdjust = { ['-webkit-print-color-adjust'] = 'exact', ['color-adjust'] = 'exact', ['print-color-adjust'] = 'exact' } -- maintenance tools function mu.initMaintenance() mu.invalidParams = {} -- table of unknown parameters mu.duplicateAliases = {} -- table of duplicate parameter aliases mu.maintenance = {} -- table of error strings mu.hints = {} -- table of hint strings mu.types = mt.types mu.groups = mg.groups mu.typeAliases = nil -- table for type aliases. Create on demand mu.groupAliases = nil -- table for group aliases end local function contains( new, ar ) for i = 1, #ar do if ar[ i ] == new then return true end end return false end function mu.addMaintenance( key, value ) local s = key -- fallback local tab = mi.maintenance[ key ] if tab then s = mi.formats.category:format( tab.category ) .. ( tab.err and mi.formats.error:format( tab.err ) or '' ) if not mi.options.noRecommendations then s = s .. ( tab.hint and mi.formats.hint:format( tab.hint ) or '' ) end end s = value and mw.ustring.format( s, value ) or s if not contains( s, mu.maintenance ) then table.insert( mu.maintenance, s ) end if mi.options.noRecommendations and tab and tab.hint then s = value and mw.ustring.format( tab.hint, value ) or tab.hint if not contains( s, mu.hints ) then table.insert( mu.hints, s ) end end end function mu.getCategories( formatStr ) return wu.getCategories( formatStr ) end local function getMaintenance() if #mu.invalidParams == 1 then mu.addMaintenance( 'unknownParam', mu.invalidParams[ 1 ] ) elseif #mu.invalidParams > 1 then mu.addMaintenance( 'unknownParams', table.concat( mu.invalidParams, mu.commaSeparator ) ) end if #mu.duplicateAliases > 0 then mu.addMaintenance( 'duplicateAliases', table.concat( mu.duplicateAliases, mu.commaSeparator ) ) end return table.concat( mu.maintenance, '' ) end function mu.makeMaintenance( page, modules ) local r = getMaintenance() if mi.options.usePropertyCateg then local m = mi.formats.wikidata -- format string for i, aModule in ipairs( modules ) do if aModule then r = r .. aModule.getCategories( m, mu.hints ) end end end if page.namespace ~= 0 then -- remove maintenance categories r = r:gsub( '%[%[[^%]]+%]%]', '' ) end return r end -- general-use functions function mu.isSet( arg ) return arg and arg ~= '' end function mu.convertForSort( s ) s = s:ulower() for i, obj in ipairs( mi.substitutes ) do s = mw.ustring.gsub( s, obj.l, obj.as ) end return s end -- replacing decimal separator and inserting group separators function mu.formatNumber( num ) if mu.isSet( mi.texts.decimalPoint ) and mi.texts.decimalPoint ~= '.' then num = num:gsub( '%.', mi.texts.decimalPoint ) end if mu.isSet( mi.texts.groupSeparator ) then local count repeat num, count = num:gsub( '^([-+]?%d+)(%d%d%d)', '%1%' .. mi.texts.groupSeparator .. '%2' ) until count == 0 end return num end function mu.tableInsert( tab, value ) if mu.isSet( value ) then table.insert( tab, value ) end end -- splitting string s at sep, removing empty substrings -- sep is a single character separator but no magic pattern character function mu.textSplit( s, sep ) local result = {} if type( s ) ~= 'string' then return result end for str in s:gmatch( '([^' .. sep .. ']+)' ) do mu.tableInsert( result, mw.text.trim( str ) ) end return result end local function encodeSpaces( s ) s = s:gsub( '[_%s]+', '_' ) return s end local function removeChars( s, pattern ) s = s:find( pattern ) and s:gsub( pattern, '' ) or s return s end local function replaceWithSpace( s, pattern ) s = s:find( pattern ) and s:gsub( pattern, ' ' ) or s return s end -- Splitting comma separated lists to a table and converting items function mu.split( s ) local arr = {} if not mu.isSet( s ) then return arr end for i, str in ipairs( mu.textSplit( s, ',' ) ) do arr[ encodeSpaces( str ) ] = 1 end return arr end function mu.makeSpan( s, class, isBdi, attr, css ) return tostring( mw.html.create( isBdi and 'bdi' or 'span' ) :addClass( class ) :attr( attr or {} ) :css( css or {} ) :wikitext( s ) ) end -- bdi and bdo tags are not working properly on all browsers. Adding marks -- (lrm, rlm) is maybe the only way for a correct output function mu.languageSpan( s, titleHint, page, country, addClass ) if not mu.isSet( s ) then return '' end local bdi = mw.html.create( 'bdi' ) :addClass( addClass ) :wikitext( s ) local c = country.lang if c == '' or c == page.lang then return tostring( bdi ) end local dir local fStr = '%s' if country.isRTL and not page.isRTL then dir = 'rtl' fStr = '&rlm;%s&lrm;' elseif not country.isRTL and page.isRTL then dir = 'ltr' fStr = '&lrm;%s&rlm;' end return fStr:format( tostring( bdi :addClass( 'voy-lang voy-lang-' .. c ) :attr( { title = mw.ustring.format( titleHint , country.langName ), lang = c, dir = dir } ) ) ) end function mu.addWdClass( isFromWikidata ) return isFromWikidata and ' voy-wikidata-content' or '' end function mu.getAliases( tab, key ) local result = {} if not tab then return result end local v for k, tb in pairs( tab ) do v = tb[ key ] if v then if type( v ) == 'table' then for i = 1, #v do result[ v[ i ] ] = k end else result[ v ] = k end end end return result end function mu.yesno( val ) return mi.yesno[ val:ulower() ] end -- check functions local function emphasize( s ) return mw.ustring.format( mi.texts.emph, s ) end -- args: template arguments consisting of argument name as key and a value -- validKeys: table with argument name as key used by the script and -- a string or a table of strings for argument names used by the local wiki function mu.checkArguments( templateArgs, validKeys ) local args = {} if not templateArgs or not validKeys or not next( validKeys ) then return args end local keys = {} -- list of wiki-dependent parameter names for key, params in pairs( validKeys ) do if type( params ) == 'string' then keys[ params ] = key else for i = 1, #params do keys[ params[ i ] ] = key end end end local targetKey for key, arg in pairs( templateArgs ) do targetKey = keys[ key ] if targetKey then if args[ targetKey ] then -- prevents duplicates table.insert( mu.duplicateAliases, emphasize( key ) ) else args[ targetKey ] = arg end else table.insert( mu.invalidParams, emphasize( key ) ) end end -- normalize values for i, param in ipairs( mi.options.normalizeValues ) do if mu.isSet( args[ param ] ) then args[ param ] = replaceWithSpace( args[ param ]:ulower(), '[_%s]+' ) end end return args end local function removeNS( s, nsTable ) if not s:find( ':', 1, true ) then return s end local t = s for i = 1, #nsTable do t = mw.ustring.gsub( t, '^' .. nsTable[ i ] .. ':', '' ) if s ~= t then return t end end return t end function mu.checkCommonsCategory( args ) -- remove namespace from category if mu.isSet( args.commonscat ) then args.commonscat = removeNS( args.commonscat, mi.texts.CategoryNS ) end end -- checking coordinates function mu.checkCoordinates( args ) local function clearCoordinates() args.lat, args.long = '', '' end local t if type( args.lat ) == 'boolean' or type( args.long ) == 'boolean' then clearCoordinates() end if args.lat == '' and args.long == '' then return elseif args.lat ~= '' and args.long == '' then t = args.lat:find( ',', 1, true ) if t then args.long = mw.text.trim( args.lat:sub( t + 1, #args.lat ) ) args.lat = mw.text.trim( args.lat:sub( 1, t - 1 ) ) end end if args.lat == '' or args.long == '' then clearCoordinates() mu.addMaintenance( 'wrongCoord' ) return end local dms = false t = tonumber( args.lat ) if t then args.lat = math.abs( t ) <= 90 and t or '' else t = cd.toDec( args.lat, 'lat', 6 ) args.lat = t.error == 0 and t.dec or '' dms = args.lat ~= '' end if args.lat ~= '' then t = tonumber( args.long ) if t then args.long = ( t > -180 and t <= 180 ) and t or '' else t = cd.toDec( args.long, 'long', 6 ) args.long = t.error == 0 and t.dec or '' dms = dms or args.long ~= '' end end if args.lat == '' or args.long == '' then clearCoordinates() mu.addMaintenance( 'wrongCoord' ) elseif dms then mu.addMaintenance( 'dmsCoordinate' ) end end -- check zoom level function mu.checkZoom( args ) args.zoom = math.floor( tonumber( args.zoom ) or mi.map.defaultZoomLevel ) if args.zoom < 0 or args.zoom > mi.map.maxZoomLevel then args.zoom = mi.map.defaultZoomLevel end end -- image check function mu.checkImage( args, entity ) if type( args.image ) == 'boolean' or args.image == '' then return end -- formal checks if args.image:find( '^https?:' ) then args.image = '' else -- remove namespace args.image = removeNS( args.image, mi.texts.FileNS ) local extensionExists = false local im = args.image:lower() for i = 1, #mi.fileExtensions do if im:find( '%.' .. mi.fileExtensions[ i ] .. '$' ) then extensionExists = true break end end if not extensionExists then args.image = '' end end if args.image == '' then mu.addMaintenance( 'wrongImgName' ) return end local alreadyChecked = false if mi.options.mediaCheck and args.image ~= '' then if not mi.options.WDmediaCheck and entity then -- check if image is stored in Wikidata local imgs = wu.getValues( entity, mi.properties.image, nil ) for i = 1, #imgs do if imgs[ i ] == args.image then alreadyChecked = true break end end end if not alreadyChecked then -- expensive function call local title = mw.title.new( 'Media:' .. args.image ) if not title or not title.exists then mu.addMaintenance( 'missingImg', args.image ) args.image = '' end end end end function mu.checkStatus( args ) args.statusTable = {} local hash = {} if mu.isSet( args.status ) then local statusAliases = mu.getAliases( mi.statuses, 'alias' ) for i, t in ipairs( mu.textSplit( args.status, ',' ) ) do t = encodeSpaces( t ) t = statusAliases[ t ] or t if mi.statuses[ t ] then if not hash[ t ] then table.insert( args.statusTable, t ) hash[ t ] = 'x' end else mu.addMaintenance( 'unknownStatus' ) end end if #args.statusTable > 1 then table.sort( args.statusTable, function( a, b ) local at = mi.statuses[ a ] local bt = mi.statuses[ b ] return ( at.g < bt.g ) or ( at.g == bt.g and a < b ) end ) end end end function mu.checkStyles( args ) if mu.isSet( args.styles ) then if mi.nameStyles[ args.styles:lower() ] then args.styles = args.styles:lower() args.styleClass = ' voy-listing-name-style-' .. args.styles args.styles = mi.nameStyles[ args.styles ] end else args.styles = nil end end function mu.checkId( args ) if mu.isSet( args.id ) and mu.isSet( args.wikidata ) then mu.addMaintenance( 'wikidataWithId' ) args.id = '' end if mu.isSet( args.id ) and args.id:find( '[!-,.-/:-?[-^{-\127%z\1-\31]' ) then mu.addMaintenance( 'wrongId' ) args.id = '' end end function mu.checkLength( s, min, max ) return #s >= ( min or 0 ) and #s <= ( max or 1000 ) end -- groups translation for map legend into Wiki language local function translateGroup( group ) if not mu.isSet( group ) then group = mt.types.error.group end local t = mg.groups[ group ] if t then t = t.map or t.label or t.alias or group if type( t ) == 'table' then t = t[ 1 ] end return t end return group end local function getTypeFromTypeAliases( aType ) if not mu.typeAliases then mu.typeAliases = mu.getAliases( mt.types, 'alias' ) end return mu.typeAliases[ aType ] end local function getGroupFromGroupAliases( group ) if not mu.groupAliases then mu.groupAliases = mu.getAliases( mg.groups, 'alias' ) end return mu.groupAliases[ group ] end -- getting marker type and group function mu.checkTypeAndGroup( args ) local s args.typeTable = {} args.subtypeTable = {} -- check group if mu.isSet( args.group ) then mu.addMaintenance( 'parameterUsed', 'group' ) s = mg.groups[ args.group ] if not s then s = getGroupFromGroupAliases( args.group ) if s then args.group = s s = mg.groups[ args.group ] end end if not s then mu.addMaintenance( 'unknownGroup' ) args.group = '' elseif s.is and s.is == 'color' and mi.options.useTypeCateg then mu.addMaintenance( 'group', args.group ) end end -- check type if not mu.isSet( args.type ) then args.type = mt.types.error.group mu.addMaintenance( 'missingType' ) elseif args.type == mt.types.error.group then mu.addMaintenance( 'unknownType', args.type ) end if args.type == mt.types.error.group then args.group = mt.types.error.group else -- split seperate types and analyse them for i, t in ipairs( mu.textSplit( args.type, ',' ) ) do -- try to find the type t in types or groups t = encodeSpaces( t ) if not mt.types[ t ] then t = getTypeFromTypeAliases( t ) or getGroupFromGroupAliases( t ) or t end s = mg.groups[ t ] if s then -- type is a group itself if s.is and s.is == 'color' then if mi.options.excludeColorTypes then args.group = mt.types.error.group mu.addMaintenance( 'unknownType', t ) else mu.addMaintenance( 'typeIsColor' ) end elseif not mi.options.noTypeMsgs then mu.addMaintenance( 'typeIsGroup' ) end if args.group == '' then args.group = t end else s = mt.types[ t ] if s then if args.group == '' then args.group = s.group end if mu.isSet( s.subtype ) then table.insert( args.subtypeTable, t ) end else args.group = mt.types.error.group mu.addMaintenance( 'unknownType', t ) end end table.insert( args.typeTable, t ) if mi.options.useTypeCateg then mu.addMaintenance( 'type', t ) end end args.type = table.concat( args.typeTable, ',' ) end args.groupTranslated = translateGroup( args.group ) mu.getColor( args ) end local function isUrl( url ) uc = uc or require( 'Module:UrlCheck' ) return uc.isUrl( url, mi.options.skipPathCheck ) end -- url check in args function mu.checkUrl( args ) if not mu.isSet( args.url ) then return end local c = isUrl( args.url ) -- getting result code if c > 2 then mu.addMaintenance( 'wrongUrl' ) args.url = '' elseif c == 2 then -- URL contains IP address mu.addMaintenance( 'urlWithIP' ) else if args.url:find( 'twitter.com', 1, true ) then -- old X url mu.addMaintenance( 'urlIsSocialMedia' ) args.url = '' else for i = 1, #mi.services do if args.url:find( '[./]' .. mi.services[ i ].key .. '.com' ) then mu.addMaintenance( 'urlIsSocialMedia' ) args.url = '' break end end end end end -- type and group functions -- getting a set of parameters for a given type function mu.getTypeParams( aType ) return mt.types[ aType ] end function mu.idToType( id ) if not mu.typeIds then mu.typeIds = mu.getAliases( mt.types, 'wd' ) -- Q id to type table end return mu.typeIds[ id ] end function mu.getTypeLabel( id ) if not mu.isSet( id ) then return '' end if id:match( '^Q%d+$' ) then id = mu.idToType( id ) if not id then return '' end else id = encodeSpaces( id ) end local at, t t = mt.types[ id ] if not t then t = getTypeFromTypeAliases( id ) t = t and mt.types[ t ] end if t then t = t.label or id at = t:find( ',', 1, true ) if at then t = t:sub( 1, at - 1 ) end else t = replaceWithSpace( id, '_' ) end return t end function mu.typeExists( aType ) return mt.types[ aType ] and aType or getTypeFromTypeAliases( aType ) end -- check if the specified group can have events function mu.groupWithEvents( group ) return mg.groups[ group ] and mg.groups[ group ].withEvents end -- see: https://www.w3.org/TR/WCAG20/#relativeluminancedef local function hexToLinear( hex ) hex = tonumber( hex, 16 ) / 255.0 if hex <= 0.03928 then return hex / 12.92 else return ( ( hex + 0.055 ) / 1.055 ) ^ 2.4 end end -- relative luminance of a color -- 6 digit hex color local function hexToLuminance( color ) local r = hexToLinear( color:sub( 1, 2 ) ) local g = hexToLinear( color:sub( 3, 4 ) ) local b = hexToLinear( color:sub( 5, 6 ) ) return 0.2126 * r + 0.7152 * g + 0.0722 * b end local function isInverse( backgroundColor ) -- the luminance threshold should be greater than 0.2848 (i.e. magenta, -- error, #FF00FF) and smaller than 0.4 -- the value chosen of 0.386 corresponds to a light magenta (#FF69FF) which -- seems to be used for Wikimedia's map server -- see: https://github.com/wikimedia/makizushi/blob/master/lib/color.js local luminanceThreshold = 0.386 backgroundColor = backgroundColor:sub( 2 ) -- remove # :gsub( '^(%x)(%x)(%x)$', '%1%1%2%2%3%3' ) return hexToLuminance( backgroundColor ) > luminanceThreshold end -- getting color from group in args function mu.getColor( args ) local c = mg.groups[ args.group ] or mg.groups[ 'error' ] args.color = c.color args.inverse = isInverse( c.color ) end -- Splitting comma separated lists to a table of key items -- checking items with allowed key values of validValues table local function splitAndCheck( s, validValues ) local values = {} if not validValues then return values, '' end local errors = {} for item, v in pairs( mu.split( s ) ) do -- value check if validValues[ item ] then values[ item ] = 1 else table.insert( errors, item ) end end return values, table.concat( errors, mu.commaSeparator ) end local function setCopyMarker( args, show ) if show.copy and ( mu.isSet( args.copyMarker ) or not mu.isSet( args.wikidata ) ) then show.copy = nil mu.addMaintenance( 'deleteShowCopy' ) end if show.copy then args.copyMarker = args.wikidata end if mu.isSet( args.copyMarker ) then show.symbol = nil end end -- treatment of social media services if Wikidata is available local function setSocialMedia( args, value ) for i, service in ipairs( mi.services ) do args[ service.key ] = value end end function mu.getShow( default, args, validValues ) local show = mu.split( default ) local add, err = splitAndCheck( args.show, validValues ) if err ~= '' then mu.addMaintenance( 'unknownShow', err ) end -- maintenance if add.inline then show.inlineSelected = true mu.addMaintenance( 'showInlineUsed' ) end if add.poi then mu.addMaintenance( 'showPoiUsed' ) -- is default end -- overwriting defaults if add.none or add.coord or add.poi or add.all then show.all, show.coord, show.poi = nil, nil, nil end -- merge show with add values for key, value in pairs( add ) do show[ key ] = value end if show.none then show.none, show.all, show.coord, show.poi = nil, nil, nil, nil end if show.all then show.all = nil show.coord, show.poi = 1, 1 end if show.noname then show.noname, show.name = nil, nil else show.name = 1 end setCopyMarker( args, show ) if args.wikidata ~= '' then if show.socialmedia then setSocialMedia( args, 'y' ) elseif show.nosocialmedia then setSocialMedia( args, 'n' ) end end if not show.nosocialmedia then show.socialmedia = 1 end return show end -- removing line breaks and controls from parameter strings function mu.removeCtrls( s, onlyInline ) local descrDiv = false -- div tag instead of span tag for description needed? -- remove controls from tags s = s:gsub( '(<[^>]+>)', function( t ) return replaceWithSpace( t, '[%z\1-\31]' ) end ) local t = removeChars( s, '[%z\1-\8\11\12\14-\31]' ) -- ctrl chars t = replaceWithSpace( t, '[\9]' ) -- horizontal tab t = replaceWithSpace( t, '</br%s*>' ) if onlyInline then t = replaceWithSpace( t, '<br[^/>]*/*>' ) -- no line breaks t = replaceWithSpace( t, '</*p[^/>]*/*>' ) -- no paragraphs t = replaceWithSpace( t, '</*div[^/>]*/*>' ) -- no divs t = mw.text.trim( replaceWithSpace( t, '[\10\13]' ) ) -- no line breaks -- not %c because \127 is used for Mediawiki tags (strip markers `UNIQ) else descrDiv = t:find( '[\10\13]' ) or t:find( '<br[^/>]*/*>' ) or t:find( '<p[^/>]*>' ) or t:find( '<div[^/>]*>' ) end -- remove LTR and RTL marks t = mw.ustring.gsub( t, '[‎‏]+', '' ) if descrDiv then -- unify line breaks to Linux mode t = t:gsub( '\13\10', '\10' ):gsub( '\13', '\10' ) -- replace line breaks by <br> in block mode t = t:gsub( '([^>%]\10])\10+([^<%[\10])', '%1<br class="voy-listing-next-paragraph" />%2' ) end return replaceWithSpace( t, '%s%s+' ), descrDiv end -- fetch data from Wikidata function mu.getCoordinatesFromWikidata( args, fromWikidata, entity ) if not entity or ( args.lat ~= '' and args.long ~= '' ) then return end -- center coordinates from Wikidata local c = wu.getValue( entity, mi.properties.centerCoordinates ) if c == '' then -- coordinates from Wikidata c = wu.getValue( entity, mi.properties.coordinates ) end -- search for headquarters location if c == '' then local tab = wu.getValuesWithQualifiers( entity, mi.properties.headquartersLoc, nil, mi.properties.coordinates ) if #tab > 0 then tab = tab[ 1 ][ mi.properties.coordinates ] if tab and #tab > 0 then c = tab[ 1 ] mu.addMaintenance( 'headquarters' ) args.coordFrom = 'headquarters' end end end if c ~= '' then args.lat, args.long = c.latitude, c.longitude fromWikidata.lat = true end end local function typeSearch( p31 ) -- p31: array of Wikidata values if not p31 or #p31 == 0 then return '' end local firstStep = true local function compareLabels( ar ) if not ar then return nil elseif type( ar ) == 'string' then ar = { ar } end for i, value in ipairs( ar ) do if mu.isSet( value ) then value = ( encodeSpaces( value ) ) if mt.types[ value ] then return value end end end return nil end local function compareIds( ar ) local id, t for i = 1, #ar do id = ar[ i ].id -- md: indexed array of q id - types relations t = mu.idToType( id ) if t then return t end -- checking English label and aliases t = compareLabels( mw.wikibase.getLabelByLang( id, 'en' ) ) or compareLabels( wu.getAliases( id, 'en' ) ) if t then if firstStep and not mi.options.noTypeMsgs then firstStep = false mu.addMaintenance( 'typeFromWDchain' ) end return t end end return nil end local aType = compareIds( p31 ) -- check p31 ids first, maybe step 2 is not nessary if aType then return aType end -- now functions becomes expensive because of multiple wu.getValues calls local id, ids firstStep = false for i = 1, #p31 do -- step 2: analyse P279 chains of first ids id = p31[ i ].id -- start id local j = 0 repeat ids = wu.getValues( id, mi.properties.subclassOf, nil ) if #ids > 0 then aType = compareIds( ids ) if aType then if not mi.options.noTypeMsgs then mu.addMaintenance( 'typeFromWDchain' ) end return aType end id = ids[ 1 ].id end j = j + 1 -- limit: maximum levels to analyse until j >= mi.options.searchLimit or #ids == 0 end return '' end function mu.getTypeFromWikidata( args, entity ) if mu.isSet( args.type ) then return end local p31 = wu.getValues( entity, mi.properties.instanceOf ) if #p31 == 0 then p31 = wu.getValues( entity, mi.properties.subclassOf ) end args.type = typeSearch( p31 ) end function mu.getCommonsCategory( args, entity ) -- getting commonscat from commonswiki sitelink before P373 -- because sitelink is checked by Wikidata if type( args.commonscat ) == 'boolean' then args.commonscat = '' end local t = wu.getSitelink( entity, 'commonswiki' ) or '' if t:match( '^Category:.+$' ) then t = t:gsub( '^[Cc]ategory:', '' ) else t = wu.getValue( entity, mi.properties.commonsCategory ) if t == '' then local id = wu.getId( entity, mi.properties.mainCategory ) if id ~= '' then t = wu.getSitelink( id, 'commonswiki' ) or '' t = t:gsub( '^[Cc]ategory:', '' ) end end end if t ~= '' and args.commonscat ~= '' then mu.addMaintenance( 'commonscatWD' ) end if args.commonscat == '' then args.commonscat = t end end function mu.getLangTable( wikiLang, localLang ) local langs = { wikiLang } for i, lang in ipairs( mi.langs ) do table.insert( langs, lang ) end if mu.isSet( localLang ) and localLang ~= wikiLang then table.insert( langs, localLang ) end return langs end -- getting names from Wikidata function mu.getNamesFromWikidata( args, fromWikidata, page, country, entity ) -- getting official names local officialNames = wu.getMonolingualValues( entity, mi.properties.officialName ) args.officialName = officialNames[ country.lang ] or wu.getLabel( entity, country.lang, true ) or '' if type( args.name ) == 'boolean' or args.name == '' then args.name = '' local langs = mu.getLangTable( page.lang ) for i, lang in ipairs( langs ) do args.name = officialNames[ lang ] if args.name then break end end -- if failed then get labels if not mu.isSet( args.name ) then for i, lang in ipairs( langs ) do args.name = wu.getLabel( entity, lang, true ) -- no fallback if args.name then break end end args.name = args.name or '' end if args.name ~= '' then -- remove brackets at the end args.name = args.name:gsub( '%s*%([^%(%)]*%)$', '' ) mu.addMaintenance( 'nameFromWD' ) fromWikidata.name = true end end -- get local name if no name is available if args.name == '' and not ( type( args.nameLocal ) == 'string' and args.nameLocal ~= '' ) then args.nameLocal = true -- no local name if country and wiki language are identical elseif args.nameLocal == true and page.lang == country.lang then args.nameLocal = '' end if type( args.nameLocal ) == 'string' and args.nameLocal ~= '' then -- keeping local name in any case for html data args.addNameLocal = args.nameLocal return end local nameLocal = officialNames[ country.lang ] or '' if nameLocal == '' then nameLocal = wu.getLabel( entity, country.lang, true ) or '' end nameLocal = nameLocal:gsub( '%s*%([^%(%)]*%)$', '' ) if args.nameLocal == true then args.nameLocal = '' if args.name == '' and nameLocal ~= '' then args.name = nameLocal nameLocal = '' mu.addMaintenance( 'nameFromWD' ) fromWikidata.name = true end -- prevent local data if wiki language == country language if page.lang ~= country.lang and nameLocal ~= '' then args.nameLocal = nameLocal if args.name:ulower() == args.nameLocal:ulower() then args.nameLocal = '' else fromWikidata.nameLocal = true end end elseif page.lang ~= country.lang and args.name ~= nameLocal then args.addNameLocal = nameLocal end end -- getting link to Wikivoyage function mu.getArticleLink( args, entity, page ) local title, isRedirect = wu.getCheckedSitelink( entity, page.lang .. page.globalProject ) if title and title ~= page.text then args.wikiPage = title if isRedirect == true then args.linkIsRedirect = true end end end -- marker functions -- returns a single data set from Module:Marker utilities/Maki icons local function getMaki( key ) mm = mm or require( 'Module:Marker utilities/Maki icons' ) key = key:lower():gsub( '[_%s]+', '-' ) return mm.icons[ key ] end local function getMakiIconId( key ) if not mu.isSet( key ) then return nil end key = key:lower():gsub( '[_%s]+', '-' ) if getMaki( key ) then return key end key = mt.types[ key ] and mt.types[ key ].icon if key and getMaki( key ) then return key end return nil end local function addIconToMarker( args ) args.text = ( '[[File:Maki7-%s.svg|x14px|link=|class=noviewer]]' ):format( args.symbol ) args.isIcon = true end -- distinguishing marker symbols, default: number local function makeMarkerProperties( args, show ) args.symbol = args.symbol or '' local noSymbol = args.symbol == '' if args.symbol == '' and show.poi and show.symbol then args.symbol = getMakiIconId( args.typeTable[ 1 ] ) or '' end local isIcon = getMaki( args.symbol ) if args.symbol == '' or args.symbol == 'number' then args.symbol = '-number-' .. args.group elseif args.symbol == 'letter' then args.symbol = '-letter-' .. args.group elseif args.symbol:len() == 1 and args.symbol:match( '%w' ) then args.text = args.symbol:upper() mu.addMaintenance( 'numberUsed' ) elseif args.symbol ~= '' and args.text == '' and isIcon then addIconToMarker( args ) elseif args.symbol ~= '' and not isIcon then args.text = mi.texts.closeX args.isIcon = true args.group = 'error' mu.getColor( args ) mu.addMaintenance( noSymbol and 'unknownMAKI' or 'unknownIcon' ) end end -- making marker symbol function mu.makeMarkerSymbol( args, show, frame ) local title = args.givenName.all local extraClasses = args.group == 'error' and ' voy-listing-map-is-error' or '' if mu.isSet( args.copyMarker ) then local copyClass = 'voy-listing-map voy-copy-marker plainlinks printNoLink' .. extraClasses return tostring( mw.html.create( 'span' ) :addClass( copyClass ) :css( colorAdjust ) -- display will be replaced by [[MediaWiki:Gadget-GeneralChanges.js]] script :css( { display = 'none' } ) :attr( { ['data-copy-marker-attribute'] = args.copyMarker:match( 'Q%d+' ) and 'data-wikidata' or 'data-name', title = mi.texts.tooltip, ['data-copy-marker-content'] = args.copyMarker } ) ) end makeMarkerProperties( args, show ) if args.isIcon then extraClasses = extraClasses .. ' voy-listing-map-is-symbol' .. -- set image color to white ( args.inverse and '' or ' voy-listing-map-inverse-img' ) end local lon = tonumber( args.long ) local lat = tonumber( args.lat ) local tagArgs = { zoom = tonumber( args.zoom ), latitude = lat, longitude = lon, show = mg.showAll, } if mu.isSet( args.text ) then tagArgs.text = args.text tagArgs.class = 'no-icon' end if mu.isSet( args.mapGroup ) then tagArgs.group, tagArgs.show = args.mapGroup, args.mapGroup else tagArgs.group = args.groupTranslated end if mu.isSet( args.image ) then tagArgs.description = '[[File:' .. args.image .. '|100x100px|' .. title .. ']]' end local geoJson = { type = 'Feature', geometry = { type = 'Point', coordinates = { lon, lat } }, properties = { title = title, description = tagArgs.description, ['marker-symbol'] = args.symbol, ['marker-color'] = args.color, ['marker-size'] = 'medium', } } return tostring( mw.html.create( 'span' ) :addClass( 'voy-listing-map plainlinks printNoLink' .. extraClasses ) :attr( 'title', mi.texts.tooltip ) :css( colorAdjust ) -- color for print mode :css( { ['background-color'] = args.color, color = args.inverse and '#000' or '#fff' } ) -- frame:extensionTag is expensive :wikitext( frame:extensionTag( 'maplink', mw.text.jsonEncode( geoJson ), tagArgs ) ) ) end -- icon functions function mu.makeStatusIcons( args ) local result = '' for i, v in ipairs( args.statusTable ) do result = result .. mu.makeSpan( ' ', 'voy-listing-status voy-listing-status-' .. v, false, { title = mi.statuses[ v ].label }, colorAdjust ) if mi.statuses[ v ].category then result = result .. ( '[[Category:%s]]' ):format( mi.statuses[ v ].label ) end end return result end function mu.addLinkIcon( classes, link, title, text, mainClass ) local span = mu.makeSpan( ' ', nil, false, { title = title, ['data-icon'] = text }, colorAdjust ) -- space to keep the span tag local lFormat = ( link:find( '^https?://' ) or link:find( '^//' ) ) and '[%s %s]' or '[[%s|%s]]' local iconLink = mw.ustring.format( lFormat, link, span ) -- add leading space for wikidata icon which is necessary if visible if text == 'wikidata' then iconLink = mu.makeSpan( '​ ', 'voy-listing-icon-with-space', true ) .. iconLink end mainClass = mainClass or 'voy-listing-icon' return mu.makeSpan( iconLink, mainClass .. ' ' .. classes ) end -- adding linked sister icons local function addSisterIcons( icons, sisters, name, id ) local icon for i, key in ipairs( { 'wikivoyage', 'wikipedia', 'commons', 'maps', 'wikidata' } ) do if mu.isSet( sisters[ key ] ) then icon = mu.addLinkIcon( 'voy-listing-sister-' .. key, sisters[ key ], mw.ustring.format( mi.iconTitles[ key ], name, id ), key ) table.insert( icons, icon ) end end -- return true if only Wikidata icon return mu.isSet( sisters.wikidata ) and #icons == 1 end -- getting sister project links local function getWikiLink( langArray, wiki, entity, wikilang ) local prefix = wiki == 'wiki' and 'w:' or 'voy:' local link for i, lang in ipairs( langArray ) do if lang ~= '' then link = wu.getFilteredSitelink( entity, lang .. wiki ) if link then prefix = prefix .. ( lang ~= wikilang and ( lang .. ':' ) or '' ) return prefix .. link end end end return '' end -- adding Wikimedia sister project icons local function makeSisterIcons( icons, args, page, country, entity, show ) local sisters = { commons = '', -- link to Commons category maps = '', -- link to Map Sources wikidata = '', -- link to Wikidata wikipedia = '', -- link to Wikipedia wikivoyage = '', -- link to another branch, usually en, as a sister link } if not show.nositelinks then if mu.isSet( args.wikipedia ) then sisters.wikipedia = 'w:' .. args.wikipedia end if mu.isSet( args.wikidata ) then local langs = mu.getLangTable( page.lang, country.lang ) if sisters.wikipedia == '' then sisters.wikipedia = getWikiLink( langs, 'wiki', entity, page.lang ) end if args.wikiPage == '' then table.remove( langs, 1 ) -- exclude page.lang sisters.wikivoyage = getWikiLink( langs, page.globalProject, entity, page.lang ) if sisters.wikivoyage ~= '' then mu.addMaintenance( 'linkToOtherWV' ) end end end if args.commonscat ~= '' then sisters.commons = 'c:Category:' .. args.commonscat end end if mu.isSet( args.wikidata ) then sisters.wikidata = 'd:' .. args.wikidata end if args.lat ~= '' and args.long ~= '' then sisters.maps = mw.ustring.format( mi.map.coordURLformat, page.lang, args.latMs, args.longMs, mw.uri.encode( country.extra ), mw.uri.encode( args.givenName.name ) ) end return addSisterIcons( icons, sisters, args.givenName.name, args.wikidata ) end -- creating social media icons including value check local function makeSocial( icons, args, fromWikidata, name ) local domain, span, t, which for i, service in ipairs( mi.services ) do -- check values first t = args[ service.key ] or '' domain = type( service.url ) == 'string' and service.url or service.url[ 1 ] domain = domain:gsub( 'com/.*', 'com/' ) if t ~= '' then if t:match( '^http' ) then if not t:find( 'https', 1, true ) then t = t:gsub( '^http', 'https' ) mu.addMaintenance( 'wrongSocialUrl', service.key ) end if isUrl( t ) > 1 or not t:match( '^' .. domain .. '.+$' ) then t = '' mu.addMaintenance( 'wrongSocialUrl', service.key ) end if t ~= '' and not fromWikidata[ service.key ] then mu.addMaintenance( 'socialUrlUsed', service.key ) end else local match = false local sp = service.pattern if type( sp ) == 'string' then sp = { sp } end for j = 1, #sp do if mw.ustring.match( t, sp[ j ] ) then match = true which = j break end end if not match then t = '' mu.addMaintenance( 'wrongSocialId', service.key ) end end end args[ service.key ] = t -- create symbol link if t ~= '' then if not t:find( domain, 1, true ) then -- multiple service urls local formatStr = type( service.url ) == 'string' and service.url or service.url[ which ] t = mw.ustring.format( formatStr, t ) end span = mu.addLinkIcon( 'voy-listing-social-media-' .. service.key .. mu.addWdClass( fromWikidata[ service.key ] ), t, mw.ustring.format( mi.iconTitles[ service.key ], name ), service.key, 'voy-listing-social-media' ) table.insert( icons, span ) end end end function mu.makeIcons( args, page, country, entity, show, fromWikidata ) local icons = {} if mi.options.showSisters then makeSisterIcons( icons, args, page, country, entity, show ) end if show.socialmedia then makeSocial( icons, args, fromWikidata, args.givenName.name ) end return table.concat( icons, '' ) end -- analyzing names for invalid parts local function checkMalformedNames( args ) local s for i, key in ipairs( { 'name', 'nameMap', 'nameLocal' } ) do if mu.isSet( args[ key ] ) then s = args[ key ] -- remove italic and bold args[ key ] = args[ key ]:gsub( "'''?", '' ) -- names shall not contain tags :gsub( '<[^<>]*>', '' ) :gsub( '[<>]+', '' ) -- remove links :gsub( '%[%s*http[^%s%]]+%s*%]', '' ) :gsub( '%[%s*http[^%s%]]+%s+([^%]]*)%]', '%1' ) :gsub( 'http%S+', '' ) -- remove images for j = 1, #mi.texts.FileNS do args[ key ] = mw.ustring.gsub( args[ key ], '%[%[%s*' .. mi.texts.FileNS[ j ] .. '%s*:[^%[%]]*%]%]', '') end if s ~= args[ key ] then args[ key ] = mw.text.trim( args[ key ] ) mu.addMaintenance( 'malformedName' ) end args[ key ] = args[ key ]:gsub( '%s%s+', ' ' ) if key ~= 'name' and args[ key ]:find( '[%(%)%[%]{}]' ) and args.officialName ~= args[ key ] then mu.addMaintenance( 'nameWithBrackets' ) end end end end local function removeStars( args ) for i, key in ipairs( mi.options.noStarParams ) do if mu.isSet( args[ key ] ) and args[ key ]:find( '*', 1, true ) then args[ key ] = args[ key ]:gsub( '%*+', '' ) args[ key ] = mw.text.trim( args[ key ] ) mu.addMaintenance( 'nameWithStar' ) end end end -- getting name table with linked and unlinked names local function getName( name, pageTitle ) local r = { all = '', -- name or linked name name = '', -- only name pageTitle = '', -- if pageTitle ~= '' name is already linked } if name == '' then return r end local c, s, t t, c = name:gsub( '^.*%[%[([^%[%]]*)%]%].*$', '%1' ) if c > 0 then -- is or contains wikilink [[...]] -- name shall not contain characters outside the wikilink if ( '[[' .. t .. ']]' ) ~= name then mu.addMaintenance( 'malformedName' ) end -- analyze wikilink t = mw.text.trim( t ) r.all = '[[' .. t .. ']]' s, c = t:gsub( '^.*|(.*)$', '%1' ) if c > 0 then -- is [[...|...]] r.name = mw.text.trim( s ) r.pageTitle = t:gsub( '^(.*)|.*$', '%1' ) r.pageTitle = mw.text.trim( r.pageTitle ) else r.name = t r.pageTitle = t end else r.name = name r.all = name if mu.isSet( pageTitle ) then r.pageTitle = pageTitle r.all = '[[' .. pageTitle .. '|' .. name .. ']]' r.fromWD = true end end return r end -- create givenName, displayName tables function mu.prepareNames( args ) local function simplifyString( s, length ) s = mw.ustring.sub( s, 1, length ) s = mw.ustring.gsub( s, "[%.'" .. '"“”„‟«»‘’‚‛‹›]', '' ) s = mw.ustring.gsub( s, '[-‐‑‒–—―]', ' ' ) return s:ulower():gsub( '%s%s+', ' ' ) end local function removeDuplicate( value1, key2 ) if not mu.isSet( value1 ) or not mu.isSet( args[ key2 ] ) then return end local minLen = math.min( mw.ustring.len( value1 ), mw.ustring.len( args[ key2 ] ) ) if simplifyString( value1, minLen ) == simplifyString( args[ key2 ], minLen ) then args[ key2 ] = '' end end -- use local name if name is not given if args.name == '' and args.nameLocal ~= '' then args.name = args.nameLocal args.nameLocal = '' end if args.name == args.nameMap then args.nameMap = '' end -- missing name if args.name == '' then args.name = mi.texts.missingName mu.addMaintenance( 'missingNameMsg' ) end if args.langIsWikiLang and mu.isSet( args.nameLocal ) then args.nameLocal = '' mu.addMaintenance( 'noLocalParams' ) end checkMalformedNames( args ) removeStars( args ) -- handling linked names like [[article|text]] args.displayName = getName( args.name, args.wikiPage ) if mu.isSet( args.nameMap ) then args.givenName = getName( args.nameMap, args.wikiPage ) else -- real copy args.givenName = {} args.givenName.all = args.displayName.all args.givenName.name = args.displayName.name args.givenName.pageTitle = args.displayName.pageTitle end -- reset args.linkIsRedirect if Wikidata link is not used -- args.linkIsRedirect is set by mu.getArticleLink() if not args.displayName.fromWD then args.linkIsRedirect = nil end if args.givenName.name:find( '[%(%)%[%]{}]' ) and args.officialName ~= args.givenName.name then mu.addMaintenance( 'nameWithBrackets' ) end -- remove identical names removeDuplicate( args.givenName.name, 'nameLocal' ) removeDuplicate( args.givenName.name, 'alt' ) removeDuplicate( args.givenName.name, 'comment' ) removeDuplicate( args.nameLocal, 'alt' ) removeDuplicate( args.alt, 'comment' ) removeDuplicate( args.directions, 'directionsLocal' ) removeDuplicate( args.address, 'addressLocal' ) end function mu.prepareCoordinates( args ) args.latDMS, args.latMs = cd.getDMSString( args.lat, 4, 'lat', '', '', mi.map.defaultDmsFormat ) args.longDMS, args.longMs = cd.getDMSString( args.long, 4, 'long', '', '', mi.map.defaultDmsFormat ) end local function _makeAirport( code, args ) local span = mu.makeSpan( args[ code ], 'voy-listing-' .. code .. '-code' .. mu.addWdClass( true ) ) return mu.makeSpan( mw.ustring.format( mi.texts[ code ], span ), 'voy-listing-airport voy-listing-' .. code ) end local function makeAirport( args, show ) if show.noairport then return '' else local t = args.type:gsub( ',.*$', '' ) -- only first type if mt.types[ t ] and not mt.types[ t ].useIATA then return '' end end if mu.isSet( args.iata ) then return _makeAirport( 'iata', args ) elseif mu.isSet( args.icao ) then return _makeAirport( 'icao', args ) else return '' end end -- creating a list of nick names etc. local function makeNameAffix( args, page, country, addClass, show ) local result = {} if mi.options.showLocalData then if mu.isSet( args.nameLocal ) then table.insert( result, mu.languageSpan( args.nameLocal, mi.texts.hintName, page, country, 'voy-listing-name-local' .. addClass ) ) end if mu.isSet( args.nameLatin ) then table.insert( result, mu.makeSpan( args.nameLatin, 'voy-listing-name-latin', false, { title = mi.texts.hintLatin, lang = mu.isSet( country.lang ) and ( country.lang .. '-Latn' ) or nil } ) ) end end for i, key in ipairs( { 'alt', 'comment' } ) do if mu.isSet( args[ key ] ) then table.insert( result, mu.makeSpan( args[ key ], 'voy-listing-' .. key ) ) end end mu.tableInsert( result, makeAirport( args, show ) ) if #result == 0 then return '' end return mu.makeSpan( mu.parentheses( table.concat( result, mu.comma ) ), 'voy-listing-add-names p-nickname nickname' ) end -- replace brackets in names local function replaceBrackets( s ) s = s:gsub( '%[', '&#x005B;' ):gsub( '%]', '&#x005D;' ) return s end -- creating (linked) name and its affix function mu.makeName( result, args, show, page, country, nameClass, localClass ) local c, s local r = {} nameClass = nameClass .. ( args.displayName.fromWD and ' voy-listing-link-from-wd' or '' ) -- clear redirect wiki link if required if args.linkIsRedirect and not show.wikilink then args.displayName.pageTitle = '' args.displayName.all = args.displayName.name args.linkIsRedirect = nil nameClass = nameClass .. ' voy-listing-unused-redirect' mu.addMaintenance( 'unusedRedirect' ) end if args.linkIsRedirect then nameClass = nameClass .. ' mw-redirect voy-listing-link-is-redirect' mu.addMaintenance( 'linkIsRedirect' ) end if mu.isSet( args.url ) and args.displayName.pageTitle == '' then s = '[' .. args.url .. ' ' .. replaceBrackets( args.displayName.name ) .. ']' else s = args.displayName.all end if mu.isSet( args.nameExtra ) then args.nameExtra, c = args.nameExtra:gsub( "'''?", '' ) if c > 0 then mu.addMaintenance( 'malformedName' ) end end if mu.isSet( args.nameExtra ) then s = s .. ' ' .. args.nameExtra end -- insert name if s ~= '' then local attr = { style = args.styles } s = mu.makeSpan( s, 'voy-listing-name p-name fn org' .. nameClass .. ( args.styleClass and args.styleClass or '' ), true, attr ) table.insert( r, s ) end -- insert separate url icon if mu.isSet( args.url ) and args.displayName.pageTitle ~= '' then -- both article and web links table.insert( r, mu.addLinkIcon( 'voy-listing-url', args.url, mi.iconTitles.internet, 'internet' ) ) end -- insert name affix mu.tableInsert( r, makeNameAffix( args, page, country, localClass, show ) ) if #r > 0 then table.insert( result, table.concat( r, mi.texts.space ) ) end end function mu.parentheses( s, trim ) if not mu.isSet( s ) then return '' end local formatter = mi.texts.parentheses if trim then formatter = mw.text.trim( formatter ) end return mw.ustring.format( formatter, s ) end -- getting DMS coordinates function mu.dmsCoordinates( args, page, country, fromWD, noBrackets ) local function coordSpan( title, text ) return mu.makeSpan( text, 'coordStyle', false, { title = title } ) end local r = '[' .. mw.ustring.format( mi.map.coordURLformat, page.lang, args.latMs, args.longMs, mw.uri.encode( country.extra ), mw.uri.encode( args.givenName.name ) ) .. ' ' .. coordSpan( mi.texts.latitude, args.latDMS ) .. ' ' .. coordSpan( mi.texts.longitude, args.longDMS ) .. ']' r = noBrackets and r or mu.parentheses( r ) return mu.makeSpan( r, 'voy-listing-dms-coordinates printNoLink plainlinks' .. mu.addWdClass( fromWD ) ) end -- prepare value s for data attribute and replace all entities by characters local function data( s ) return mu.isSet( s ) and mw.text.decode( s, true ) or nil end -- output functions local function makeAnchorId( name ) if name and not name:match( '^Q%d+$' ) then name = mw.uri.anchorEncode( name ) end return mw.ustring.format( mi.texts.anchor, name ) end -- adding wrapper and microformats function mu.makeWrapper( result, args, page, country, show, list, frame ) if not mu.isSet( args.nameLocal ) and mu.isSet( args.addNameLocal ) then args.nameLocal = args.addNameLocal end if not mu.isSet( args.addressLocal ) and mu.isSet( args.addAddressLocal ) then args.addressLocal = args.addAddressLocal end local wrapper = mw.html.create( show.inline and 'span' or 'div' ) :addClass( string.format( 'voy-%s vcard h-card', args.template ) ) if args.noGpx then wrapper:addClass( 'voy-listing-no-gpx' ) end if show.outdent and not show.inline then wrapper:addClass( 'voy-listing-outdent' ) end if show.inlineSelected or args.template == 'Marker' then wrapper:addClass( 'voy-listing-inline' ) end if mu.isSet( args.copyMarker ) or not show.poi then wrapper:addClass( 'voy-without-marker' ) end if #args.statusTable > 0 then wrapper:addClass( 'voy-listing-with-status' ) end if not show.inline and mi.options.groupsWithLimit[ args.group ] then wrapper:addClass( 'voy-listing-shrinkable' ) end if args.givenName.name ~= mi.texts.missingName then wrapper:attr( 'data-name', data( args.givenName.name ) ) end if #mu.hints > 0 then wrapper:attr( 'data-hints', table.concat( mu.hints, '; ' ) ) end -- no Marker id if no marker is shown if not( args.template == 'Marker' and not show.poi and not mu.isSet( args.id ) ) then if not ( mu.isSet( args.copyMarker ) and args.copyMarker == args.wikidata ) then local id = mu.isSet( args.wikidata ) and args.wikidata or args.id if mu.isSet( id ) then wrapper:attr( 'id', makeAnchorId( id ) ) end end end local editClass = 'voy-listing-edit' if mu.isSet( args.sectionFrom ) then args.sectionFrom = replaceWithSpace( args.sectionFrom, '[_]+' ) if args.sectionFrom ~= page.text then editClass = 'voy-listing-no-edit' end end wrapper:addClass( editClass ) wrapper:attr( 'data-location', data( page.subpageText ) ) :attr( 'data-location-qid', page.entityId ) :attr( 'data-country', data( country.iso_3166 ) ) :attr( 'data-lang', data( country.lang ) ) :attr( 'data-country-calling-code', data( country.cc ) ) :attr( 'data-trunk-prefix', data( country.trunkPrefix ) ) :attr( 'data-currency', data( country.addCurrency ) ) :attr( 'data-coord-from', args.coordFrom ) local arg for key, value in pairs( list ) do if mu.isSet( args[ key ] ) then arg = args[ key ]:gsub( '<[^<>]*>', '' ) -- remove html tags wrapper:attr( value, data( arg ) ) end end if not show.name then wrapper:node( mw.html.create( 'span' ) :addClass( 'voy-listing-name p-name fn org' ) :css( 'display', 'none' ) :wikitext( args.givenName.name ) ) end wrapper:wikitext( result ) if not show.noCoord then wrapper:node( mw.html.create( 'span' ) :addClass( 'voy-listing-coordinates p-geo geo' ) :css( 'display', 'none' ) :node( mw.html.create( 'span' ) :addClass( 'p-latitude latitude' ) :wikitext( args.lat ) ) :node( mw.html.create( 'span' ) :addClass( 'p-longitude longitude' ) :wikitext( args.long ) ) ) end wrapper = tostring( wrapper ) -- adding coordinates to Mediawiki database -- frame:callParserFunction is expensive if not show.noCoord and mi.options.secondaryCoords then wrapper = wrapper .. frame:callParserFunction{ name = '#coordinates', args = { args.lat, args.long, country.extra, name = args.givenName.name } } end return wrapper end function mu.getPageData() local page = mw.title.getCurrentTitle() page.langObj = mw.getContentLanguage() page.lang = page.langObj:getCode() page.langName = mw.language.fetchLanguageName( page.lang, page.lang ) page.isRTL = page.langObj:isRTL() page.entityId = mw.wikibase.getEntityIdForCurrentPage() -- can be nil page.siteName = mw.site.siteName page.globalProject = page.siteName:lower() if page.globalProject == 'wikipedia' then page.globalProject = 'wiki' end return page end return mu 02pcbtiscgfrgcp8c6ii32191f0g8ob Modulo:Marker utilities/i18n 828 4808 73248 72147 2026-09-24T10:48:15Z RolandUnger 168 Update 73248 Scribunto text/plain -- Separating code from internationalization return { -- module administration moduleInterface = { suite = 'Marker utilities', sub = 'i18n', serial = '2026-09-23', item = 65441686 }, dates = { yyyymmdd = { p = '^20[0-5]%d%-[01]?%d%-[0-3]?%d$', f = 'j. M Y' }, yyyy = { p = '^20[0-5]%d$', f = 'Y' }, yy = { p = '^[0-5]%d$', f = 'Y' }, mmdd = { p = '^[01]?%d%-[0-3]?%d$', f = 'j. M' }, dd = { p = '^[0-3]?%d%.?$', f = 'j.' }, mm = { p = '^[01]?%d%.?$', f = 'M' }, lastedit = { f = 'M Y' }, asOf = { f = 'n/Y' } }, fileExtensions = { 'tif', 'tiff', 'gif', 'png', 'jpg', 'jpeg', 'jpe', 'webp', 'xcf', 'ogg', 'ogv', 'svg', 'pdf', 'stl', 'djvu', 'webm', 'mpg', 'mpeg' }, months = { 'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember' }, monthAbbr = { 'Jan%.?', 'Feb%.?', 'Mär%.?', 'Apr%.?', 'Mai%.?', 'Jun%.?', 'Jul%.?', 'Aug%.?', 'Sep%.?', 'Okt%.?', 'Nov%.?', 'Dez%.?' }, -- Map related constants map = { coordURLformat = '//%s.wikivoyage.org/w/index.php?title=Special%%3AMapsources&params=%s_%s_%s&locname=%s', defaultDmsFormat = 'f1', -- see: Module:Coordinates/i18n defaultSiteType = 'type:landmark_globe:earth', defaultZoomLevel = 17, maxZoomLevel = 19, -- also to set in Module:GeoData, Module:Mapshape utilities/i18n }, -- Wikidata properties properties = { appliesToJurisdiction = 'P1001', appliesToPart = 'P518', appliesToPeople = 'P6001', capacity = 'P1083', centerCoordinates = 'P5140', commonsCategory = 'P373', coordinates = 'P625', endTime = 'P582', -- time headquartersLoc = 'P159', image = 'P18', instanceOf = 'P31', iso4217 = 'P498', languageOfName = 'P407', mainCategory = 'P910', maximumAge = 'P4135', minimumAge = 'P2899', nameInNativeLang = 'P1559', occupation = 'P106', of = 'P642', officialName = 'P1448', partOf = 'P361', pointInTime = 'P585', propertyScope = 'P5314', -- for fees quantity = 'P1114', retrieved = 'P813', roomNumber = 'P8733', startTime = 'P580', -- time, for fees streetAddress = 'P6375', subclassOf = 'P279', unitSymbol = 'P5061', use = 'P366', validInPeriod = 'P1264' }, -- Groups of Wikidata properties propTable = { accessibility = { 'P2846' }, contactComments = { 'P366', 'P518', 'P642', 'P1001', 'P1559', 'P106' }, feeComments = { 'P5314', 'P518', 'P6001', 'P1264', 'P585', 'P2899', 'P4135', 'P642', 'P580' }, policyComments = { 'P518', 'P1001', 'P6001' }, quantity = { 'P1114', 'P1083' }, accessQuantity = { 'P1114', 'P1083', 'P2846' }, unescoPartOf = { 'P361' } }, -- Wikidata properties representing a qualifier qualifiers = { mobilePhone = 'Q17517', P8733 = 'Q180516', roomNumber = 'Q180516', unescoHeritage = 'Q9259' }, -- Languages for fallbacks, except wiki language langs = { 'en', 'fr' }, -- array can be empty -- Display and performance options for vCard / Listing and Marker modules -- additional options in Module:VCard/i18n options = { excludeColorTypes = true, normalizeValues = { 'type', 'subtype', 'show', 'status', 'symbol' }, noStarParams = { 'name', 'nameExtra', 'nameLocal', 'nameMap', 'alt', 'comment' }, noTypeMsgs = false, -- prevents display of maintenance( typeFromWD, typeIsGroup ) noRecommendations = true, -- prevents display of recommendation hints parameters = { 'commonscat', 'country', 'id', 'localLang', 'nameExtra', 'wikipedia' }, -- parameter is used showLocalData = true, -- names, addresses, directions showSisters = true, -- possible values true, false, 'atEnd' usePropertyCateg = true, -- create maintenance categories for Wikidata properties useTypeCateg = true, -- create maintenance categories for marker types markerMetadata = true, -- add metadata at marker templates -- text limit of content/description parameter contentLimit = 1000, groupsWithLimit = { buy = 1, drink = 1, eat = 1, sleep = 1 }, -- Wikidata related constants searchLimit = 4, -- count of levels for P31-P279 search -- useful but not necessary function calls WDmediaCheck = false, -- check file names retrieved from Wikidata mediaCheck = false, -- for better performance, otherwise expensive -- mw.title.new( 'Media:' .. image ) call is used secondaryCoords = false, -- adding listing coordinates to article database -- using #coordinates parser function skipPathCheck = false -- for URL check, see Module:UrlCheck }, -- strings texts = { asOf = '; Stand %s', -- with semicolon separator from = 'ab %s', fromTo = '%s–%s', to = 'bis %s', fromTo2 = '%s bis %s', -- General, i18n -- black x-like cross closeX = '[[File:Close x - black.png|15px|link=|class=noviewer|Unbekanntes Marker-Symbol]]', missingName = 'Name fehlt', -- In case of CJK languages no spaces are used with punctuation -- Enumeration commas. voy-listing-comma is used for alt names only comma = '<span class="voy-listing-comma">, ​</span>', -- with zero-width space commaSeparator = ', ', period = '.', periodSeparator= '. ', -- Space following a punctuation mark space = ' ', nbSpace = '&nbsp;', parentheses = ' (%s)', emph = "''%s''", -- Formatting numbers: replacement patterns decimalPoint = ',', groupSeparator = '.', -- Anchor id anchor = 'vCard_%s', -- Marker CategoryNS = { '[Cc]ategory', '[Kk]ategorie' }, FileNS = { '[Ff]ile', '[Ii]mage', '[Dd]atei', '[Bb]ild' }, latitude = 'Breitengrad', longitude = 'Längengrad', tooltip = 'Click auf den Marker öffnet die Karte direkt.', -- vCard / Listing module checkin = 'Check-in: %s', checkout = 'Check-out: %s', closed = 'Geschlossen: %s', closedPattern = '^[Gg]eschlossen:?%s*', editInSource = 'im Quellartikel bearbeiten', email = 'E-Mail: %s', expirationPeriod = 'now - 3 years', fax = 'Fax: %s', hintName = 'Name in %s', hintLatin = 'Name in lateinischer Umschrift', hintAddress = 'Anschrift in %s', hintDirections = 'Wegbeschreibung in %s', hours = 'Geöffnet: %s', iata = '[[International Air Transport Association|IATA]]: %s', icao = '[[Internationale Zivilluftfahrt-Organisation|ICAO]]: %s', lastedit = 'letzte Änderung: %s', lasteditNone = 'keine Angabe', maybeOutdated = '(Angaben möglicherweise veraltet)[[Category:VCard: Angaben veraltet]]', mobile = 'Mobil: %s', payment = 'Akzeptierte Zahlungsarten: %s', phone = '<abbr title="Telefon">Tel.</abbr>: %s', price = 'Preis: %s', subtype = 'Merkmal: %s.', subtypes = 'Merkmale: %s.', subtypeAbbr = '<abbr title="%s">%s</abbr>', subtypeFile = '[[File:%s|x14px|link=|class=noviewer voy-listing-subtype-icon|%s]]', -- for subtype icons like Michelin stars subtypeSpan = '<span title="%s">%s</span>', subtypeWithCount = '%d %s', tollfree = '<abbr title="Telefon">Tel.</abbr> gebührenfrei: %s' }, -- format strings for mu.addMaintenance formats = { category = '[[Category:%s]]', error = ' <span class="error">%s</span>', hint = ' <span class="voy-check-recommended" style="display: none;">%s</span>', wikidata = '[[Category:Seiten, die die Wikidata-Eigenschaft %s benutzen]]' }, -- maintenance maintenance = { -- general type = { category = 'Seiten mit dem Markertyp %s' }, group = { category = 'Seiten mit der Markergruppe %s' }, urlWithIP = { category = 'URL enthält IP-Adresse', hint = 'URL enthält IP-Adresse' }, wrongUrl = { category = 'URL ist ungültig', err = 'URL ist ungültig' }, commonscatWD = { category = 'VCard: Parameter commonscat zusammen mit wikidata benutzt' }, contentTooLong = { category = 'VCard: Beschreibung ist zu lang', err = 'Beschreibung ist zu lang' }, currencyTooltip= { category = 'VCard: Währungstooltips eingesetzt' }, dmsCoordinate = { category = 'VCard: DMS-Koordinate', hint = 'DMS-Koordinate' }, duplicateAliases = { category = 'VCard: Doppelte Aliase', err = 'Doppelte Aliase: %s' }, headquarters = { category = 'VCard: Koordinate der Hauptverwaltung' }, labelFromWD = { category = 'VCard: Label aus Wikidata', hint = 'Label aus Wikidata' }, linkIsRedirect = { category = 'VCard: Artikellink ist Weiterleitung' }, linkToOtherWV = { category = 'VCard: Anderes Wikivoyage verlinkt' }, malformedName = { category = 'VCard: Fehlerhafter Name', err = 'Fehlerhafter Name' }, malformedAddress = { category = 'VCard: Fehlerhafte Adresse oder Wegbeschreibung', err = 'Fehlerhafte Adresse oder Wegbeschreibung' }, missingImg = { category = 'VCard: Datei existiert nicht', err = 'Nicht vorhandenes Bild: %s' }, missingNameMsg = { category = 'VCard: Ohne Namen', err = 'Name fehlt' }, missingType = { category = 'VCard: Typ fehlt', err = 'Fehlender Typ' }, nameFromWD = { category = 'VCard: Name aus Wikidata bezogen', err = 'Name aus Wikidata bezogen' }, nameWithBrackets = { category = 'VCard: Name mit Klammern', hint = 'Name mit Klammern' }, nameWithStar = { category = 'VCard: Name enthält Stern', err = 'Name enthält Stern' }, noLocalParams = { category = 'VCard: Lokale Parameter nicht verwendbar', err = 'Lokale Parameter nicht verwendbar' }, outdated = { category = 'VCard: Ereignis veraltet', err = 'Ereignis veraltet' }, parameterUsed = { category = 'VCard: Parameter %s benutzt' }, deleteShowCopy = { category = 'VCard: show=copy gelöscht', hint = 'show=copy gelöscht' }, showInlineUsed = { category = 'VCard: show=inline gesetzt' }, showNoneUsed = { category = 'Marker: show=none gesetzt' }, showPoiUsed = { category = 'VCard: show=poi gesetzt' }, typeFromWDchain= { category = 'VCard: Typ aus Wikidata-Kette bezogen', hint = 'Typ aus Wikidata bezogen' }, typeIsGroup = { category = 'VCard: Typ ist Gruppenbezeichnung', hint = 'Typ ist Gruppenbezeichnung' }, typeIsColor = { category = 'VCard: Typ ist Farbbezeichnung', hint = 'Typ ist Farbbezeichnung' }, -- typeIsColor is not used if excludeColorTypes = true unknownCountry = { category = 'VCard: Unbekannter Ländercode', err = 'Unbekannter Ländercode' }, unknownGroup = { category = 'VCard: Unbekannte Gruppe', err = 'Unbekannte Gruppe' }, unknownLanguage= { category = 'VCard: Unbekannter Sprachcode', hint = 'Unbekannter Sprachcode' }, unknownParam = { category = 'VCard: Unbekannte Parameter', err = 'Unbekannter Parameter: %s' }, unknownParams = { category = 'VCard: Unbekannte Parameter', err = 'Unbekannte Parameter: %s' }, unknownPropertyLanguage= { category = 'VCard: Unbekannter Sprachcode für Eigenschaft', hint = 'Unbekannter Sprachcode für Eigenschaft' }, unknownStatus = { category = 'VCard: Unbekannter Status', err = 'Unbekannter Status' }, unknownType = { category = 'VCard: Unbekannter Typ', err = 'Unbekannter Typ: %s' }, unusedRedirect = { category = 'VCard: Unbenutzter Weiterleitungs-Sitelink' }, urlIsSocialMedia = { category = 'VCard: URL stammt von Social-Media-Dienst', err = 'URL stammt von Social-Media-Dienst' }, wikidata = { category = 'VCard: Einsatz von Wikidata' }, wrongCoord = { category = 'VCard: Fehlerhafte Koordinate', err = 'Fehlerhafte Koordinate' }, wrongImgName = { category = 'VCard: Fehlerhafter Mediendateiname', err = 'Fehlerhafter Mediendateiname' }, wrongQualifier = { category = 'VCard: Fehlerhafter Wikidata-Qualifikator', err = 'Fehlerhafter Wikidata-Qualifikator' }, -- Marker module missingCoord = { category = 'Marker: Ohne Koordinaten', err = 'Länge und/oder Breite fehlt' }, numberUsed = { category = 'Marker: Nummer manuell vergeben' }, unknownIcon = { category = 'Marker: Unbekanntes Symbol' }, -- vCard / Listing module countryFromWD = { category = 'VCard: Länderdaten aus Wikidata' }, missingCoordVc = { category = 'VCard: Ohne Koordinaten' }, paymentUsed = { category = 'VCard: Zahlungsarten spezifiziert' }, socialUrlUsed = { category = 'VCard: Social-Media-URL verwendet', hint = '%s-URL verwendet' }, unitFromWD = { category = 'VCard: Einheit aus Wikidata', hint = 'Einheit aus Wikidata' }, unknownLabel = { category = 'VCard: Unbekanntes Label oder Id' }, unknownMAKI = { category = 'VCard: Unbekanntes MAKI-Symbol', hint = 'Unbekanntes MAKI-Symbol' }, unknownShow = { category = 'VCard: Unbekannter Wert für show', err = 'Wert(e) für show unbekannt: %s' }, unknownSubtype = { category = 'VCard: Unbekannter Wert für subtype', err = 'Wert(e) für subtype unbekannt: %s' }, unknownUnit = { category = 'VCard: Unbekannte Einheit', hint = 'Unbekannte Einheit' }, unknowWDfeatures = { category = 'VCard: Unbekannte Wikidata-Merkmale', hint = 'Unbekannte Wikidata-Merkmale' }, wdWithGoogleCid = { category = 'VCard: Parameter google-maps zusammen mit wikidata benutzt', hint = 'google-maps mit wikidata benutzt' }, wikidataWithId = { category = 'VCard: Parameter id zusammen mit wikidata benutzt', hint = 'id mit wikidata benutzt' }, wrongDate = { category = 'VCard: Fehlerhaftes Datum', err = 'Fehlerhaftes Datum' }, wrongGoogleCid = { category = 'VCard: Fehlerhafte Google-Maps-Kundenkennung', err = 'Fehlerhafte Google-Maps-Kundenkennung' }, wrongId = { category = 'VCard: Fehlerhafte id', err = 'Fehlerhafte id' }, wrongSocialId = { category = 'VCard: Fehlerhafte Social-Media-Id', err = 'Fehlerhafte %s-Id' }, wrongSocialUrl = { category = 'VCard: Fehlerhafte Social-Media-URL', err = 'Fehlerhafte %s-URL' } }, iconTitles = { commons = '%s im Medienverzeichnis Wikimedia Commons', facebook = '%s auf Facebook', flickr = '%s auf Flickr', instagram = '%s auf Instagram', internet = 'Website dieser Einrichtung', maps = '%s auf Karten und Routenplanern', rss = 'RSS-Web-Feed dieser Einrichtung', tiktok = '%s auf TikTok', wikidata = '%s (%s) in der Datenbank Wikidata', wikipedia = '%s in der Enzyklopädie Wikipedia', wikivoyage = '%s im Reiseführer Wikivoyage in einer anderen Sprache', x = '%s auf X', youtube = '%s auf YouTube' }, -- social media services services = { { key = 'facebook', url = 'https://www.facebook.com/%s', pattern = { '^[-.%d%w][-_.%d%w]+$', '^[^%z\1-,/:-?\91-\94{-~]+/[1-9]%d+$' } }, { key = 'flickr', url = 'https://www.flickr.com/photos/%s', pattern = '^%d%d%d%d%d+@N%d%d$' }, { key = 'instagram', url = 'https://www.instagram.com/%s/', pattern = { '^[0-9a-z_][0-9a-z._]+[0-9a-z_]$', '^explore/locations/%d+$' } }, { key = 'tiktok', url = 'https://www.tiktok.com/@%s', pattern = '^[0-9A-Za-z_][0-9A-Za-z_.]+$' }, { key = 'x', url = 'https://x.com/%s', pattern = '^[0-9A-Za-z_]+$' }, { key = 'youtube', url = { 'https://www.youtube.com/channel/%s', 'https://www.youtube.com/%s' }, pattern = { '^UC[-_0-9A-Za-z]+[AQgw]$', '^@[-0-9A-Za-z_.][-0-9A-Za-z_.][-0-9A-Za-z_.]+$' } } }, --[[ status symbols g: successive symbol group number alias: status alias label: image tag title category = 1: add maintenance category --]] statuses = { ['top-hotel'] = { g = 1, label = 'Top-Hotel', category = 1 }, ['top-restaurant'] = { g = 1, label = 'Top-Restaurant', category = 1 }, ['top-sight'] = { g = 1, label = 'Top-Sehenswürdigkeit', category = 1 }, recommendation = { g = 1, label = 'Empfehlung' }, none = { g = 2, alias = 'class-0', label = 'Ohne Einstufung' }, stub = { g = 2, alias = 'class-1', label = 'Stub' }, outline = { g = 2, alias = 'class-2', label = 'Artikelentwurf' }, usable = { g = 2, alias = 'class-3', label = 'Brauchbarer Artikel' }, guide = { g = 2, alias = 'class-4', label = 'Vollständiger Artikel' }, star = { g = 2, alias = 'class-5', label = 'Empfehlenswerter Artikel' } }, -- Marker name styles -- Colors in Template:VCard/styles.css nameStyles = { inherit = 'font-weight: inherit; font-style: inherit;', italic = 'font-weight: normal; font-style: italic;', kursiv = 'font-weight: normal; font-style: italic;', -- de: kursiv = italic normal = 'font-weight: normal; font-style: normal;', station = 'font-weight: normal; white-space: nowrap; padding-left: 2px; padding-right: 2px;' }, -- yes/no variants yesno = { y = 'y', yes = 'y', j = 'y', ja = 'y', n = 'n', no = 'n', nein = 'n' }, -- List of currencies without conversion tooltips noCurrencyConversion = { -- all = 1, -- no rate conversion tooltips are shown -- there is no confusion with (uppercase) ALL = "Q125999" EUR = 1 -- local currency }, -- Language-dependent sorting substitutes substitutes = { { l = 'ä', as = 'a' }, { l = 'ö', as = 'o' }, { l = 'ü', as = 'u' }, { l = 'ß', as = 'ss' } } } hoztqhqpg1422ts5cyydh9m9i7ilc3v Modulo:Marker utilities/Types 828 4814 73243 72959 2026-09-24T10:44:22Z RolandUnger 168 Update 73243 Scribunto text/plain --[[ Please use only quotation marks instead of apostrophs for JSON export. Do not change this modul without need. A change causes the parsing of the majority of articles. Wishes for new types should be discussed and collected on Module talk:Marker utilities/Types. Types should conform to tags in Openstreetmap, if possible. New types must be entered in Template:Marker/XML and Template:vCard/XML, too. --]] return { -- administration moduleInterface = { suite = "Marker utilities", sub = "types", serial = "2026-09-24", item = 65444106 }, types = { -- do not remove the following line -- ##start -- journey and mobility aerialway = { group = "go", wd = "Q1054650", label = "Seilbahn" }, airline = { group = "go", wd = "Q46970", label = "Fluggesellschaft" }, airport = { group = "go", wd = { "Q1248784", "Q62447", "Q644371" }, useIATA = "1", label = "Flughafen" }, airport_service = { group = "go", label = "Flughafendienst" }, bicycle_parking = { group = "go", wd = "Q16243822", label = "Fahrradparkplatz" }, bicycle_rental = { alias = "bicycle_share", group = "go", wd = { "Q10611118", "Q1358919", "Q61663696" }, label = "Fahrradverleih", icon = "bicycle-share" }, bicycle_repair = { group = "go", wd = { "Q96983545", "Q112663579" }, label = "Fahrradreparatur" }, boat_sharing = { group = "go", wd = "Q4931514", label = "Boot-Sharing, Boot-Charter" }, boat_trip = { group = "go", wd = "Q25040412", label = "Bootsfahrt, Schiffstour" }, border_control = { group = "go", wd = "Q218719", label = "Grenzkontrolle" }, bus = { alias = "bus_stop", group = "go", wd = { "Q953806", "Q494829" }, label = "Bushaltestelle" }, car_rental = { group = "go", wd = "Q291240", label = "Autoverleih, Autovermietung" }, car_repair = { group = "go", wd = "Q1310967", label = "Autowerkstatt" }, car_sharing = { group = "go", wd = "Q847201", label = "Carsharing" }, charging_station = { group = "go", wd = { "Q2140665", "Q55956304" }, label = "Ladestation, Stromtankstelle" }, cycle_track = { alias = "cycle_path", group = "go", wd = { "Q25037910", "Q221722" }, label = "Radweg" }, draisine = { group = "go", wd = "Q209658", label = "Draisine, Eisenbahn-Draisine" }, entrance = { group = "go", wd = "Q1137365", label = "Eingang" }, ferry = { group = "go", wd = { "Q100355757", "Q25653", "Q1478783" }, label = "Fähranleger" }, ford = { group = "go", wd = "Q12743", label = "Furt" }, fuel = { alias = "filling_station", group = "go", wd = "Q205495", label = "Tankstelle" }, funicular = { group = "go", wd = "Q142031", label = "Standseilbahnstation" }, harbor = { alias = "port", group = "go", wd = { "Q44782", "Q283202" }, label = "Hafen" }, heliport = { group = "go", wd = "Q502074", label = "Hubschrauberlandeplatz, Heliport" }, junction = { alias = { "road_junction", "intersection" }, group = "go", wd = { "Q1788454", "Q285783" }, label = "Kreuzung" }, landing_site = { group = "go", wd = "Q3631092", label = "Landeplatz" }, left_luggage = { group = "go", wd = "Q21996814", label = "Gepäckaufbewahrung" }, light_railway = { alias = "lrt", group = "go", wd = "Q32680449", label = "Light-Railway-Station" }, marina = { group = "go", wd = "Q721207", label = "Yachthafen, Marina" }, monorail = { group = "go", wd = "Q187934", label = "Monorail-Station" }, motorbike_rental = { group = "go", label = "Motorradverleih" }, motorway_junction = { group = "go", label = "Ausfahrt, Auffahrt, Anschlussstelle, Autobahnkreuz" }, parking = { group = "go", wd = "Q6501349", label = "Parkplatz" }, parking_garage = { group = "go", wd = "Q13218805", label = "Parkhaus" }, pier = { group = "go", wd = "Q863454", label = "Pier, Schiffsanleger" }, -- also jetty public_transport = { group = "go", wd = "Q178512", label = "Öffentliche Verkehrsmittel" }, quay = { alias = "wharf", group = "go", wd = "Q828909", label = "Kai, Schiffsanleger, Kaje" }, rail = { alias = { "train", "railway", "railway_station" }, group = "go", wd = { "Q55488", "Q55678" }, label = "Bahnhof, Haltepunkt" }, scooter = { group = "go", wd = { "Q193234", "Q502057" }, label = "Scooter, Motorroller, Tretroller" }, service_area = { group = "go", wd = "Q786014", label = "Raststätte, Autohof" }, ship = { group = "go", wd = "Q11446", label = "Schiff" }, shipping_company = { group = "go", label = "Schifffahrtsgesellschaft, Reederei" }, shuttle_bus_service = { group = "go", label = "Shuttlebus-Service" }, station = { group = "go", wd = "Q12819564", label = "Station" }, suburban_rail = { alias = { "suburban_railway", "commuter_rail", "s-bahn" }, group = "go", wd = { "Q1412403", "Q95723" }, label = "S-Bahn-Station, Vorortbahnstation" }, subway = { alias = "metro", group = "go", wd = "Q928830", label = "U-Bahn-Station", icon = "rail-metro" }, taxi = { group = "go", wd = "Q1395196", label = "Taxistand" }, terminal = { group = "go", wd = "Q849706", label = "Terminal" }, toll_station = { group = "go", wd = "Q1364150", label = "Mautstation" }, tram = { group = "go", wd = "Q2175765", label = "Straßenbahnhaltestelle, Tramhaltestelle", icon = "rail-light" }, tunnel = { group = "go", wd = "Q44377", label = "Tunnel" }, waiting_room = { group = "go", wd = "Q674251", label = "Warteraum, Wartesaal" }, waypoint = { group = "go", wd = "Q138081", label = "Wegpunkt" }, -- group types go = { group = "go", wd = { "Q334166", "Q740752" }, label = "Anreise" }, -- sights: religious sites and monuments altar = { group = "religion", wd = "Q101687", label = "Altar" }, bahai_temple = { group = "religion", wd = "Q1568313", label = "Bahai-Tempel" }, basilica = { group = "religion", wd = { "Q163687", "Q4846867" }, label = "Basilika" }, buddharupa = { group = "religion", wd = "Q1000809", label = "Buddha-Statue", icon = "religious-buddhist" }, cathedral = { group = "religion", wd = "Q2977", label = "Kathedrale", icon = "religious-christian" }, chapel = { group = "religion", wd = "Q108325", label = "Kapelle", icon = "religious-christian" }, chapel_shrine = { group = "religion", wd = "Q14552192", label = "Heiligenhäuschen" }, church = { group = "religion", wd = { "Q16970", "Q580499" }, label = "Kirche", icon = "religious-christian" }, fire_temple = { group = "religion", wd = "Q115278", label = "Feuertempel" }, gurdwara = { group = "religion", wd = "Q337986", label = "Gurdwara" }, hindu_temple = { group = "religion", wd = "Q842402", label = "Hindutempel" }, lak_mueang = { group = "religion", wd = "Q974127", label = "Lak Müang" }, lourdes_grotto = { group = "religion", wd = "Q1433032", label = "Lourdesgrotte, Mariengrotte" }, mikveh = { group = "religion", wd = "Q211351", label = "Mikwe" }, minaret = { group = "religion", wd = "Q48356", label = "Minarett" }, monastery = { group = "religion", wd = { "Q44613", "Q160742" }, label = "Kloster, Abtei" }, mosque = { group = "religion", wd = "Q32815", label = "Moschee", icon = "religious-muslim" }, nunnery = { group = "religion", wd = "Q6021560", label = "Nonnenkloster" }, pagoda = { group = "religion", wd = "Q199451", label = "Pagode" }, pilgrimage_site = { group = "religion", wd = "Q15135589", label = "Wallfahrtsort" }, sanctuary = { group = "religion", wd = "Q29553", label = "Heiligtum" }, shinto_shrine = { group = "religion", wd = "Q845945", label = "Shintō-Schrein", icon = "religious-shinto" }, shrine = { group = "religion", wd = "Q697295", label = "Schrein" }, stupa = { group = "religion", wd = "Q180987", label = "Stupa" }, summit_cross = { group = "religion", wd = "Q361665", label = "Gipfelkreuz" }, synagogue = { group = "religion", wd = "Q34627", label = "Synagoge", icon = "religious-jewish" }, temple = { group = "religion", wd = { "Q44539", "Q927825", "Q58621988" }, label = "Tempel" }, wat = { group = "religion", wd = "Q427287", label = "Wat" }, wayside_cross = { group = "religion", wd = "Q2309609", label = "Flurkreuz, Wegkreuz" }, wayside_shrine = { group = "religion", wd = { "Q3395121", "Q12661150" }, label = "Bildstock" }, religion = { alias = "religious_site", group = "religion", wd = "Q1370598", label = "Religiöse Stätte" }, -- sights: natural animal_shelter = { group = "nature", wd = "Q1411287", label = "Tierheim" }, animal_stable = { alias = "stable", group = "nature", wd = { "Q214252", "Q1207909" }, label = "Stall" }, aquarium = { group = "nature", wd = "Q2281788", label = "Aquarium" }, bay = { group = "nature", wd = { "Q39594", "Q17018380" }, label = "Bucht" }, botanical_garden = { group = "nature", wd = "Q167346", label = "Botanischer Garten" }, canal = { group = "nature", wd = "Q12284", label = "Kanal" }, canyon = { group = "nature", wd = "Q150784", label = "Canyon, Schlucht" }, cape = { group = "nature", wd = "Q185113", label = "Kap" }, cave = { group = "nature", wd = "Q35509", label = "Höhle" }, cliff = { group = "nature", wd = "Q107679", label = "Klippe" }, coast = { group = "nature", wd = "Q93352", label = "Küste" }, crater = { group = "nature", wd = "Q3240715", label = "Krater" }, crocodile_farm = { group = "nature", wd = "Q25691", label = "Krokodilfarm" }, depression = { group = "nature", wd = "Q190429", label = "Senke" }, desert = { group = "nature", wd = "Q8514", label = "Wüste" }, dive_site = { group = "nature", wd = "Q2141554", label = "Tauchplatz, Tauchgebiet" }, dog_park = { group = "nature", wd = "Q38516", label = "Hundezone, Hundewiese" }, dolphinarium = { group = "nature", wd = "Q491675", label = "Delfinarium" }, dune = { group = "nature", wd = "Q25391", label = "Düne" }, dyke = { group = "nature", wd = "Q105190", label = "Deich" }, farm = { group = "nature", wd = "Q131596", label = "Bauernhof, Gut" }, fish_pond = { group = "nature", wd = "Q1265665", label = "Fischteich" }, fjord = { group = "nature", wd = "Q45776", label = "Fjord" }, forest = { group = "nature", wd = "Q4421", label = "Wald" }, garden = { group = "nature", wd = "Q1107656", label = "Garten" }, geyser = { group = "nature", wd = "Q83471", label = "Geysir" }, glacier = { group = "nature", wd = "Q35666", label = "Gletscher" }, greenhouse = { group = "nature", wd = "Q165044", label = "Gewächshaus, Treibhaus" }, gulf = { group = "nature", wd = "Q1322134", label = "Golf (Bucht)" }, habitat = { group = "nature", label = "Habitat" }, heath = { group = "nature", wd = "Q27590", label = "Heide" }, hill = { group = "nature", wd = "Q54050", label = "Hügel" }, horticulture = { group = "nature", wd = "Q48803", label = "Gartenbau, Gärtnerei" }, hot_spring = { group = "nature", wd = "Q177380", label = "Thermalquelle" }, island = { group = "nature", wd = "Q23442", label = "Insel" }, lagoon = { group = "nature", wd = "Q187223", label = "Lagune" }, lake = { group = "nature", wd = "Q23397", label = "See, Teich" }, landscape = { group = "nature", wd = "Q107425", label = "Landschaft" }, mangrove = { group = "nature", wd = "Q19756", label = "Mangrove" }, meadow = { group = "nature", wd = "Q7777019", label = "Wiese" }, mountain = { group = "nature", wd = "Q8502", label = "Berg" }, mountain_chain = { group = "nature", wd = "Q2624046", label = "Gebirgszug" }, mountain_pass = { group = "nature", wd = "Q133056", label = "Gebirgspass" }, mountain_pasture = { alias = "alm", group = "nature", wd = "Q2082774", label = "Alm" }, mountain_range = { group = "nature", wd = "Q46831", label = "Gebirge" }, national_park = { group = "nature", wd = "Q46169", label = "Nationalpark" }, natural_heritage = { group = "nature", wd = "Q386426", label = "Naturerbe" }, natural_monument = { group = "nature", wd = "Q23790", label = "Naturdenkmal" }, nature_reserve = { group = "nature", wd = { "Q158454", "Q179049", "Q473972", "Q759421", "Q20268756" }, label = "Naturschutzgebiet" }, oasis = { group = "nature", wd = "Q43742", label = "Oase" }, palaeontological_site = { group = "nature", wd = "Q9096832", label = "Paläontologische Stätte" }, park = { group = "nature", wd = { "Q22698", "Q728904" }, label = "Park" }, peninsula = { group = "nature", wd = "Q34763", label = "Halbinsel" }, plantation = { group = "nature", wd = "Q188913", label = "Plantage" }, plateau = { group = "nature", wd = "Q75520", label = "Hochebene, Plateau" }, protected_area = { alias = "protectorate", group = "nature", wd = "Q473972", label = "Schutzgebiet" }, reef = { group = "nature", wd = "Q184358", label = "Riff" }, reservoir = { group = "nature", wd = "Q131681", label = "Stausee" }, river = { group = "nature", wd = "Q4022", label = "Fluss" }, river_mouth = { group = "nature", wd = "Q1233637", label = "Flussmündung" }, rock = { group = "nature", wd = { "Q1404150", "Q8063" }, label = "Felsen, Gestein" }, sea = { group = "nature", wd = "Q165", label = "Meer, Ozean" }, spring = { group = "nature", wd = "Q124714", label = "Quelle" }, steppe = { group = "nature", wd = "Q123991", label = "Steppe" }, strait = { group = "nature", wd = "Q37901", label = "Meerenge" }, stream = { group = "nature", wd = "Q47521", label = "Bach" }, stud = { group = "nature", wd = "Q108696", label = "Gestüt" }, summit = { group = "nature", wd = "Q207326", label = "Gipfel" }, tree = { group = "nature", wd = "Q10884", label = "Baum" }, valley = { group = "nature", wd = "Q39816", label = "Tal" }, volcano = { group = "nature", wd = "Q8072", label = "Vulkan" }, waterfall = { group = "nature", wd = "Q34038", label = "Wasserfall, Katarakt" }, wetland = { group = "nature", wd = "Q170321", label = "Feuchtgebiet" }, zoo = { group = "nature", wd = "Q43501", label = "Zoo, Tierpark" }, nature = { group = "nature", wd = "Q7860", label = "Natur" }, -- sights: arts, historic amphitheater = { group = "see", wd = "Q54831", label = "Amphitheater" }, aqueduct = { group = "see", wd = "Q474", label = "Aquädukt" }, archaeological_site = { group = "see", wd = "Q839954", label = "Archäologische Stätte" }, architecture = { group = "see", wd = "Q12271", label = "Architektur" }, archive = { group = "see", wd = { "Q166118", "Q635719", "Q27032363" }, label = "Archiv" }, artwork = { group = "see", wd = "Q838948", label = "Kunstwerk" }, bakehouse = { group = "see", wd = "Q798436", label = "Backhaus" }, barracks = { group = "see", wd = "Q131263", label = "Kaserne" }, boat_lift = { group = "see", wd = "Q14908", label = "Schiffshebewerk" }, bridge = { group = "see", wd = "Q12280", label = "Brücke" }, building = { group = "see", wd = { "Q41176", "Q811979" }, label = "Gebäude" }, building_complex = { group = "see", wd = { "Q1497364", "Q18247357" }, label = "Gebäudekomplex, Bauwerkgruppe" }, bunker = { group = "see", wd = "Q91122", label = "Bunker" }, cannon = { group = "see", wd = "Q81103", label = "Kanone" }, castle = { group = "see", wd = "Q23413", label = "Burg" }, cellar = { group = "see", wd = "Q234852", label = "Keller" }, cemetery = { alias = "necropolis", group = "see", wd = "Q39614", label = "Friedhof, Nekropole" }, cenotaph = { group = "see", wd = "Q321053", label = "Kenotaph, Scheingrab" }, chateau = { alias = "château", group = "see", wd = "Q751876", label = "Schloss" }, city_center = { group = "see", wd = "Q1468524", label = "Stadtzentrum, Stadtkern" }, city_wall = { group = "see", wd = "Q16748868", label = "Stadtmauer" }, collection = { group = "see", wd = { "Q2668072", "Q7328910" }, label = "Sammlung" }, column = { group = "see", wd = { "Q4817", "Q51845395", "Q1930585" }, label = "Säule, Gedenksäule" }, communication_tower = { group = "see", wd = { "Q11166728", "Q1798641" }, label = "Fernsehturm, Fernmeldeturm" }, crematorium = { group = "see", wd = "Q157570", label = "Krematorium" }, cultural_heritage = { group = "see", wd = "Q210272", label = "Kulturerbe" }, dam = { group = "see", wd = "Q12323", label = "Talsperre" }, domain = { group = "see", wd = "Q155231", label = "Landgut, Domäne, Rittergut" }, embankment_dam = { group = "see", wd = "Q1244922", label = "Staudamm" }, exhibition = { group = "see", wd = "Q464980", label = "Ausstellung" }, exhibition_hall = { group = "see", wd = { "Q57659484", "Q3364296" }, label = "Ausstellungshalle" }, factory = { group = "see", wd = "Q83405", label = "Fabrik" }, fort = { group = "see", wd = "Q57831", label = "Festung, Fort" }, fountain = { group = "see", wd = "Q483453", label = "Springbrunnen" }, gallery = { group = "see", wd = "Q1007870", label = "Galerie", icon = "art-gallery" }, gate = { group = "see", wd = "Q53060", label = "Tor" }, ghost_town = { group = "see", wd = "Q74047", label = "Geisterstadt" }, glassmaker = { group = "see", wd = { "Q12184432", "Q110135697", "Q137431541" }, label = "Glasmacher, Glasmacherwerkstatt" }, graduation_tower = { group = "see", wd = "Q1541226", label = "Gradierwerk" }, grave = { group = "see", wd = "Q173387", label = "Grab" }, hall = { group = "see", wd = "Q240854", label = "Halle" }, handicraft = { group = "see", wd = "Q52105", label = "Handwerk, Kunsthandwerk" }, high_rise = { alias = "skyscraper", group = "see", wd = { "Q18142", "Q11303" }, label = "Hochhaus, Wolkenkratzer" }, historic_district = { group = "see", wd = "Q15243209", label = "historisches Gebiet", icon = "historic" }, house = { group = "see", wd = "Q3947", label = "Haus" }, hydraulic_structure = { group = "see", wd = "Q2466889", label = "Wasserbauwerk" }, landmark = { group = "see", wd = "Q2319498", label = "Wahrzeichen" }, lighthouse = { group = "see", wd = "Q39715", label = "Leuchtturm, Bake, Seezeichen" }, lock = { group = "see", wd = "Q105731", label = "Schiffsschleuse, Schleuse" }, mausoleum = { group = "see", wd = "Q162875", label = "Mausoleum" }, megalithic_tomb = { group = "see", wd = { "Q10521078", "Q101659" }, label = "Großsteingrab, Hünengrab, Dolmen" }, memorial = { group = "see", wd = "Q5003624", label = "Gedenkstätte" }, mill = { group = "see", wd = "Q44494", label = "Mühle" }, mine = { group = "see", wd = "Q820477", label = "Bergwerk, Mine" }, -- including surface mining mining_museum = { group = "see", wd = "Q819426", label = "Bergbaumuseum" }, monument = { group = "see", wd = "Q4989906", label = "Denkmal, Monument" }, museum = { group = "see", wd = "Q33506", label = "Museum" }, museum_ship = { group = "see", wd = "Q575727", label = "Museumsschiff" }, national_monument = { group = "see", wd = "Q893745", label = "Nationaldenkmal" }, obelisk = { group = "see", wd = "Q170980", label = "Obelisk" }, observatory = { group = "see", wd = { "Q1254933", "Q62832" }, label = "Sternwarte" }, old_town = { group = "see", wd = "Q676050", label = "Altstadt", icon = "historic" }, open_air_museum = { group = "see", wd = "Q756102", label = "Freilichtmuseum" }, palace = { group = "see", wd = "Q16560", label = "Palast" }, pavilion = { alias = "arbor", group = "see", wd = { "Q276173", "Q23457088", "Q961082" }, label = "Pavillon, Gartenlaube" }, pedestrian = { group = "see", wd = "Q369730", label = "Fußgängerzone" }, planetarium = { group = "see", wd = "Q148319", label = "Planetarium" }, power = { group = "see", wd = "Q159719", label = "Kraftwerk, Energie" }, -- power station, transformers, towers etc. promenade = { group = "see", wd = "Q787113", label = "Promenade" }, pyramid = { group = "see", wd = "Q12516", label = "Pyramide" }, quarry = { group = "see", wd = "Q15115254", label = "Steinbruch" }, road = { group = "see", wd = { "Q34442", "Q83620" }, label = "Straße" }, -- including street and lane rock_art = { group = "see", wd = "Q1211146", label = "Felsbild" }, ruins = { group = "see", wd = "Q109607", label = "Ruine" }, shipyard = { group = "see", wd = "Q190928", label = "Werft" }, spaceport = { group = "see", wd = "Q194188", label = "Weltraumbahnhof" }, square = { group = "see", wd = "Q174782", label = "Platz" }, statue = { group = "see", wd = "Q179700", label = "Statue, Skulptur" }, stele = { group = "see", wd = "Q178743", label = "Stele" }, stolperstein = { group = "see", wd = "Q314003", label = "Stolperstein" }, technical_monument = { group = "see", wd = "Q1516537", label = "technisches Denkmal" }, tomb = { group = "see", wd = { "Q381885", "Q6023295" }, label = "Grabkammer" }, tower = { group = "see", wd = "Q12518", label = "Turm" }, town_hall = { group = "see", wd = "Q543654", label = "Rathaus" }, treasure_hall = { group = "see", wd = "Q133269026", label = "Schatzkammer" }, tumulus = { group = "see", wd = "Q34023", label = "Tumulus, Hügelgrab" }, viaduct = { group = "see", wd = "Q181348", label = "Viadukt" }, wall = { group = "see", wd = "Q42948", label = "Mauer" }, war_grave = { group = "see", wd = "Q90717531", label = "Kriegsgrab" }, war_memorial = { group = "see", wd = "Q575759", label = "Kriegsgedenkstätte, Kriegerdenkmal" }, watermill = { group = "see", wd = "Q185187", label = "Wassermühle" }, weather_station = { group = "see", wd = "Q190107", label = "Wetterstation" }, weir = { group = "see", wd = "Q1066997", label = "Stauwehr" }, well = { group = "see", wd = "Q43483", label = "Brunnen" }, windmill = { group = "see", wd = "Q38720", label = "Windmühle" }, wreck = { group = "see", wd = "Q852190", label = "Wrack" }, -- group types see = { group = "see", wd = "Q570116", label = "Sehenswürdigkeit" }, -- culture arena = { group = "do", wd = "Q641226", label = "Arena" }, arts_center = { group = "do", wd = "Q2190251", label = "Kunstzentrum" }, bird_watching = { group = "do", wd = "Q685629", label = "Vogelbeobachtung" }, bullring = { group = "do", wd = "Q1193438", label = "Stierkampfarena" }, cabaret = { group = "do", wd = "Q131183", label = "Cabaret, Kabarett, Musiktheater" }, cinema = { group = "do", wd = "Q41253", label = "Kino, Filmtheater" }, circus = { group = "do", wd = "Q47928", label = "Zirkus" }, concert_hall = { group = "do", wd = "Q1060829", label = "Konzerthaus" }, conference_center = { group = "do", wd = "Q1378975", label = "Tagungs- oder Konferenzzentrum" }, cultural_center = { group = "do", wd = "Q1329623", label = "Kulturzentrum" }, edutainment = { group = "do", wd = "Q1153173", label = "Edutainment" }, event = { group = "do", wd = "Q1190554", label = "Ereignis, Veranstaltung" }, event_venue = { group = "do", wd = "Q18674739", label = "Veranstaltungszentrum" }, fair = { group = "do", wd = { "Q57305", "Q2948561" }, label = "Messe, Handelsmesse" }, festival = { group = "do", wd = "Q132241", label = "Festspiele" }, heritage_railway = { group = "do", wd = "Q420962", label = "Museumsbahn, Museumseisenbahn" }, karaoke = { group = "do", wd = "Q229345", label = "Karaoke" }, labyrinth = { group = "do", wd = "Q48963", label = "Labyrinth" }, lazy_river = { group = "do", wd = "Q3220071", label = "Lazy River" }, [ "multi-purpose_hall" ] = { group = "do", wd = { "Q1763828", "Q2400020" }, label = "Mehrzweckhalle" }, music = { group = "do", wd = "Q638", label = "Musikdarbietung" }, -- different types of music theaters opera_house = { group = "do", wd = "Q153562", label = "Opernhaus" }, puppet_theater = { group = "do", wd = "Q3982337", label = "Puppentheater" }, recording_studio = { group = "do", wd = "Q746369", label = "Tonstudio" }, sightseeing_flight = { alias = "pleasure_flight", group = "do", wd = "Q1425541", label = "Rundflug" }, theater = { group = "do", wd = { "Q11635", "Q24354" }, label = "Theater", icon = "theatre" }, -- speech theater, theater in general themed_travel = { group = "do", label = "Themenreisen" }, wildlife_observation = { group = "do", wd = { "Q28455557", "Q241741" }, label = "Tierbeobachtung" }, -- recreation amusement_park = { group = "do", wd = "Q194195", label = "Freizeitpark" }, attraction = { group = "do", wd = "Q2800000", label = "Attraktion" }, ballooning = { group = "do", wd = "Q805325", label = "Ballonfahren" }, brine_bath = { group = "do", wd = "Q1316853", label = "Solbad" }, canopy_walkway = { group = "do", wd = "Q811593", label = "Baumkronenpfad" }, casino = { group = "do", wd = "Q133215", label = "Spielbank, Casino" }, entertainment = { group = "do", wd = "Q173799", label = "Unterhaltung" }, escape_game = { group = "do", wd = "Q1201679", label = "Fluchtspiel, Escape Game" }, falconry_display = { group = "do", wd = "Q1169958", label = "Greifvogelschau, Freiflugvorführung" }, game = { group = "do", wd = "Q11410", label = "Spiel" }, massage = { group = "do", wd = "Q179415", label = "Massagesalon" }, onsen = { group = "do", wd = "Q655311", label = "Onsen" }, picnic = { group = "do", wd = "Q506294", label = "Picknick", icon = "picnic-site" }, playground = { group = "do", wd = "Q11875349", label = "Spielplatz" }, public_bath = { group = "do", wd = "Q785952", label = "Badehaus, Hammam" }, ropes_course = { group = "do", wd = "Q1939700", label = "Seilgarten, Kletterpark" }, sauna = { group = "do", wd = "Q57036", label = "Sauna, Dampfbad" }, spa = { alias = "wellness", group = "do", wd = "Q6882870", label = "Heilbad, Spa, Wellnesscenter" }, theme_park = { group = "do", wd = "Q2416723", label = "Themenpark" }, thermal_bath = { group = "do", wd = "Q1004887", label = "Thermalbad" }, water_park = { group = "do", wd = { "Q740326", "Q118559331" }, label = "Wasserpark, Aquapark, Freizeitbad, Spaßbad" }, water_playground = { group = "do", wd = "Q19984194", label = "Wasserspielplatz" }, youth_center = { group = "do", wd = "Q1302299", label = "Jugendzentrum" }, -- sports and fitness ["9pin"] = { group = "do", wd = "Q706199", label = "Kegeln" }, ["10pin"] = { alias = "bowling", group = "do", wd = "Q172809", label = "Bowling", icon = "bowling-alley" }, athletics_track = { group = "do", wd = { "Q1004435", "Q37025296", "Q121072018" }, label = "Leichtathletikanlage" }, archery = { group = "do", wd = "Q108429", label = "Bogenschießen" }, badminton = { group = "do", wd = "Q7291", label = "Badminton" }, barefoot_path = { group = "do", wd = "Q2143241", label = "Barfußpfad" }, baseball = { group = "do", wd = { "Q5369", "Q701629" }, label = "Baseball" }, basketball_court = { group = "do", wd = "Q2341939", label = "Basketballfeld" }, beach = { group = "do", wd = "Q40080", label = "Strand" }, beachvolleyball = { group = "do", wd = "Q4543", label = "Beachvolleyball" }, bicycle_route = { group = "do", wd = { "Q353027", "Q102307360" }, label = "Radwanderweg" }, billiards = { group = "do", wd = "Q3341285", label = "Billard" }, bmx = { group = "do", wd = "Q215184", label = "BMX" }, boat_rental = { group = "do", wd = "Q25384001", label = "Bootsverleih" }, bobsleigh = { group = "do", wd = "Q177275", label = "Bobsport" }, bouldering = { group = "do", wd = "Q852989", label = "Bouldern, Klettern" }, boules = { group = "do", wd = "Q895060", label = "Boules" }, bungee_jumping = { group = "do", wd = "Q193847", label = "Bungeespringen" }, canoe = { group = "do", wd = "Q171529", label = "Bootssport" }, -- Kanu, Kayak canyoning = { group = "do", wd = "Q206091", label = "Canyoning" }, city_beach = { group = "do", wd = "Q7900097", label = "Stadtstrand" }, -- incl. beach club court = { group = "do", wd = { "Q41487", "Q136804782" }, label = "Gericht, Tribunal" }, cricket = { group = "do", wd = "Q5375", label = "Cricket" }, cycling = { group = "do", wd = "Q53121", label = "Radfahren" }, dive_center = { alias = { "dive_centre", "diving center" }, group = "do", wd = "Q3664857", label = "Tauchbasis" }, downhill = { group = "do", wd = { "Q319899", "Q121071424" }, label = "Ski Alpin, Abfahrt", icon = "skiing" }, -- alpine/downhill ski route extreme_sports = { group = "do", wd = "Q309162", label = "Extremsport" }, fishing = { group = "do", wd = "Q14373", label = "Fischen, Angeln" }, fitness_center = { alias = "gym", group = "do", wd = { "Q1065656", "Q30750411" }, label = "Fitnessstudio", icon = "fitness-centre" }, football_pitch = { group = "do", wd = "Q105755419", label = "Fußballfeld" }, gliding = { group = "do", wd = "Q624161", label = "Segelflug" }, golf = { group = "do", wd = { "Q5377", "Q3177122" }, label = "Golf (Sport)" }, hiking = { alias = "trekking", group = "do", wd = "Q12014035", label = "Wandern" }, horse_racing = { group = "do", wd = "Q187916", label = "Pferderennen" }, horse_riding = { alias = "equestrian", group = "do", wd = { "Q179226", "Q902378" }, label = "Reiten" }, hunting = { group = "do", wd = "Q36963", label = "Jagd" }, ice_hockey = { group = "do", wd = "Q41466", label = "Eishockey" }, ice_rink = { group = "do", wd = "Q1282870", label = "Eisbahn" }, ice_skating = { group = "do", wd = "Q779272", label = "Eislaufen" }, ice_stadium = { group = "do", wd = "Q12019965", label = "Eissporthalle" }, indoor_pool = { group = "do", wd = "Q357380", label = "Hallenbad" }, karting = { group = "do", wd = "Q192420", label = "Kartsport" }, kitesurfing = { group = "do", wd = "Q219554", label = "Kitesurfen" }, laser_tag = { group = "do", wd = "Q998303", label = "Laser Tag" }, leisure_center = { group = "do", wd = "Q30313989", label = "Freizeitzentrum" }, minigolf = { group = "do", wd = "Q754796", label = "Minigolf" }, mountain_biking = { group = "do", wd = { "Q520611", "Q223705" }, label = "Mountainbikesport" }, mountain_hiking = { alias = "hillwalking", group = "do", wd = "Q1762646", label = "Bergwandern" }, mountaineering = { alias = "mountain_climbing", group = "do", wd = "Q22857", label = "Bergsteigen" }, motocross = { group = "do", wd = "Q215862", label = "Motocross" }, nordic = { group = "do", wd = "Q216613", label = "Ski Nordisch" }, -- nordic/cross country ski trail orienteering = { group = "do", wd = "Q29358", label = "Orientierungslauf" }, outdoor_chess = { group = "do", wd = { "Q115997054", "Q110079" }, label = "Freiluftschach, Gartenschach" }, outdoor_pool = { group = "do", wd = "Q13586493", label = "Freibad" }, paintball = { group = "do", wd = "Q192832", label = "Paintball" }, parachuting = { alias = "skydiving", group = "do", wd = "Q193210", label = "Fallschirmspringen" }, paragliding = { group = "do", wd = "Q178380", label = "Paragliding" }, pedalo = { group = "do", wd = "Q1335189", label = "Tretboot" }, petanque = { group = "do", wd = { "Q189317", "Q114646415" }, label = "Pétanque" }, polo = { group = "do", wd = "Q134211", label = "Polo" }, quad_bike = { group = "do", wd = "Q3926537", label = "Quad-Bike" }, racetrack = { group = "do", wd = "Q1777138", label = "Rennbahn" }, rafting = { group = "do", wd = "Q207238", label = "Rafting" }, -- including whitewater rafting roller_skating = { group = "do", wd = "Q1707432", label = "Rollsport" }, -- including inline roller skating rowing = { group = "do", wd = "Q159354", label = "Rudern" }, running = { group = "do", wd = "Q3694569", label = "Laufsport" }, sailing = { group = "do", wd = "Q192520", label = "Segeln" }, sandboarding = { group = "do", wd = "Q570459", label = "Sandboarding" }, scuba_diving = { group = "do", wd = "Q1096878", label = "Tauchen" }, shooting_range = { group = "do", wd = "Q521839", label = "Schießstand, Schießplatz" }, skatepark = { group = "do", wd = "Q909906", label = "Skatepark" }, ski_jumping = { group = "do", wd = "Q7718", label = "Skispringen" }, ski_school = { group = "do", wd = "Q2292514", label = "Skischule" }, skitour = { group = "do", wd = "Q1075998", label = "Skitour" }, sledding = { group = "do", wd = "Q3266340", label = "Rodeln" }, snorkeling = { group = "do", wd = "Q2471422", label = "Schnorcheln" }, snow_park = { group = "do", wd = "Q3141488", label = "Snowpark" }, soccer = { group = "do", wd = "Q2736", label = "Fußball" }, summer_toboggan = { group = "do", wd = "Q3266345", label = "Sommerrodelbahn" }, sports = { group = "do", wd = "Q349", label = "Sport" }, sports_venue = { group = "do", wd = { "Q1076486", "Q121071543", "Q120169931" }, label = "Sportstätte" }, squash = { group = "do", wd = { "Q121072153", "Q121085278" }, label = "Squash" }, stadium = { group = "do", wd = { "Q483110", "Q37025296" }, label = "Stadion" }, standup_paddle_boarding = { alias = "sup", group = "do", wd = "Q2035123", label = "Stehpaddeln, Stand-up-Paddling" }, surfing = { group = "do", wd = "Q159992", label = "Surfen" }, swimming = { group = "do", wd = "Q6388", label = "Schwimmen" }, swimming_pool = { group = "do", wd = "Q200023", label = "Schwimmbad" }, table_tennis = { group = "do", wd = "Q3930", label = "Tischtennis" }, tennis = { alias = "tennis_court", group = "do", wd = { "Q847", "Q741118" }, label = "Tennisplatz" }, toboggan = { group = "do", wd = "Q56611604", label = "Rodelbahn" }, tour = { group = "do", label = "Tour, Rundfahrt" }, trail = { alias = "hiking_trail", group = "do", wd = { "Q2143825", "Q628179" }, label = "Wanderweg" }, trampoline_park = { group = "do", wd = "Q107338221", label = "Trampolinpark" }, triathlon = { group = "do", wd = "Q10980", label = "Triathlon" }, velodrome = { group = "do", wd = "Q830528", label = "Radrennbahn", icon = "racetrack-cycling" }, wakeboarding = { group = "do", wd = "Q376040", label = "Wakeboarding" }, water_skiing = { group = "do", wd = "Q472827", label = "Wasserski" }, water_sports = { group = "do", wd = "Q61065", label = "Wassersport" }, winter_sports = { group = "do", wd = "Q204686", label = "Wintersport" }, -- group types ["do"] = { group = "do", label = "Aktivität" }, -- shopping alcohol_shop = { group = "buy", wd = "Q2632011", label = "Spirituosengeschäft" }, antiquarian = { group = "buy", wd = "Q582794", label = "Antiquariat" }, atm = { group = "buy", wd = "Q81235", label = "Geldautomat, Bankomat" }, bakery = { group = "buy", wd = "Q274393", label = "Bäckerei" }, bank = { group = "buy", wd = "Q22687", label = "Bank, Geldwesen" }, beauty_salon = { group = "buy", wd = "Q1195245", label = "Schönheitssalon" }, beverages = { group = "buy", wd = "Q47504516", label = "Getränkegeschäft" }, bike_shop = { group = "buy", wd = "Q26721034", label = "Fahrradladen" }, book_seller = { alias = "book_shop", group = "buy", wd = "Q200764", label = "Buchhandlung" }, boutique = { group = "buy", wd = "Q1068824", label = "Boutique" }, business_park = { group = "buy", wd = "Q338313", label = "Gewerbegebiet" }, butchery = { group = "buy", wd = "Q13164546", label = "Metzgerei, Fleischerei" }, carpet_shop = { group = "buy", wd = "Q47516346", label = "Teppichgeschäft" }, cheesery = { group = "buy", wd = "Q3088348", label = "Käserei" }, chemist = { alias = "drugstore", group = "buy", wd = "Q1260046", label = "Drogerie" }, collector_shop = { group = "buy", label = "Sammlergeschäft" }, computer_shop = { alias = "computer", wd = "Q43182520", group = "buy", label = "Computergeschäft" }, cosmetics_shop = { group = "buy", wd = "Q47508166", label = "Kosmetik" }, crafts_shop = { group = "buy", wd = "Q101061294", label = "Handwerksgeschäft" }, currency_exchange = { group = "buy", wd = "Q2002539", label = "Wechselstube" }, delicatessen = { group = "buy", wd = { "Q3231410", "Q48635101" }, label = "Feinkostladen" }, department_store = { group = "buy", wd = "Q216107", label = "Warenhaus, Kaufhaus" }, ["duty-free_shop"] = { group = "buy", wd = "Q545609", label = "Duty-Free-Geschäft" }, fashion_store = { alias = "clothing_store", group = "buy", wd = "Q2090555", label = "Modeladen, Bekleidungsgeschäft", icon = "clothing-store" }, farm_shop = { group = "buy", wd = "Q1371823", label = "Hofladen" }, flea_market = { group = "buy", wd = "Q385870", label = "Flohmarkt" }, florist = { group = "buy", wd = "Q10431511", label = "Blumenladen" }, grocery = { group = "buy", wd = "Q1295201", label = "Lebensmittelladen" }, hairdresser = { group = "buy", wd = "Q95856773", label = "Friseur" }, industrial_park = { group = "buy", wd = "Q1662100", label = "Industriepark" }, jewellery = { group = "buy", wd = "Q20708021", label = "Juwelier", icon = "jewelry-store" }, kiosk = { group = "buy", wd = "Q693369", label = "Kiosk" }, livestock_market = { group = "buy", wd = "Q13592976", label = "Viehmarkt, Tiermarkt" }, mall = { group = "buy", wd = { "Q11315", "Q31374404" }, label = "Einkaufszentrum, Mall" }, market = { group = "buy", wd = "Q37654", label = "Markt" }, market_hall = { group = "buy", wd = "Q2080521", label = "Markthalle" }, music_shop = { group = "buy", wd = "Q24284215", label = "Musikgeschäft" }, optician = { group = "buy", wd = "Q80144507", label = "Optiker" }, outdoor_retailer = { group = "buy", label = "Outdoor-Händler" }, outlet = { group = "buy", wd = "Q76470", label = "Outlet, Fabrikverkauf" }, pastry_shop = { alias = "confectionery", group = "buy", wd = "Q47505416", label = "Konditorei, Feinbäckerei" }, photo_store = { group = "buy", wd = "Q57262241", label = "Fotogeschäft" }, second_hand = { group = "buy", wd = "Q2925872", label = "Gebrauchtwarenladen" }, shoe_shop = { group = "buy", wd = "Q7500021", label = "Schuhladen", icon = "shoe" }, shop = { group = "buy", wd = "Q213441", label = "Geschäft, Laden, Shop" }, shopping_arcade = { alias = "shopping_passage", group = "buy", wd = "Q97495053", label = "Ladenpassage, Einkaufspassage" }, shopping_district = { group = "buy", wd = "Q27095213", label = "Einkaufsviertel" }, shopping_street = { group = "buy", wd = "Q21000333", label = "Einkaufsstraße" }, souvenir_shop = { group = "buy", wd = "Q865693", label = "Souvenirgeschäft, Andenkenladen" }, sports_shop = { group = "buy", wd = "Q47516567", label = "Sportgeschäft" }, supermarket = { group = "buy", wd = "Q180846", label = "Supermarkt" }, ticket_shop = { alias = { "box_office", "ticket_sales", "ticket_office" }, group = "buy", wd = { "Q47519615", "Q877435", "Q100681367" }, label = "Ticketverkauf" }, vending_machine = { group = "buy", wd = "Q211584", label = "Verkaufsautomat" }, watersports_shop = { group = "buy", label = "Wassersportgeschäft" }, -- group types buy = { group = "buy", label = "Einkaufen" }, -- cuisine, eating agriculture = { group = "eat", wd = "Q11451", label = "Landwirtschaft" }, bistro = { group = "eat", wd = "Q866742", label = "Bistro" }, brasserie = { group = "eat", wd = "Q1581509", label = "Brasserie" }, cafe = { group = "eat", wd = "Q30022", label = "Café, Kaffeehaus" }, cafeteria = { group = "eat", wd = "Q8463304", label = "Cafeteria" }, canteen = { group = "eat", wd = "Q54957790", label = "Kantine, Mensa" }, community_kitchen = { group = "eat", wd = "Q28854744", label = "Gemeinschaftsküche, Langar" }, fast_food = { group = "eat", wd = "Q1751429", label = "Fastfood, Schnellrestaurant" }, fish_restaurant = { group = "eat", wd = "Q125216847", label = "Fischrestaurant" }, food = { group = "eat", wd = { "Q2095", "Q736427" }, label = "Lebensmittel" }, grill_site = { group = "eat", wd = "Q1546788", label = "Grillplatz" }, ice_cream = { group = "eat", wd = "Q1311064", label = "Eisdiele" }, izakaya = { group = "eat", wd = "Q1193068", label = "Izakaya-Restaurant" }, pizzeria = { group = "eat", wd = "Q1501212", label = "Pizzeria", icon = "restaurant-pizza" }, restaurant = { group = "eat", wd = "Q11707", label = "Restaurant, Gaststätte, Lokal" }, seafood_restaurant = { alias = "seafood", group = "eat", wd = "Q17102985", label = "Seefisch-Restaurant, Meeresfrüchte-Restaurant", icon = "restaurant-seafood" }, snack_bar = { group = "eat", wd = "Q1318768", label = "Imbissstand, Food-counter, Würstelstand" }, steak_house = { group = "eat", wd = "Q3109696", label = "Steakhaus" }, street_food = { group = "eat", wd = "Q1316209", label = "Street Food" }, takeaway = { group = "eat", wd = { "Q154383", "Q506946" }, label = "Take-away" }, tavern = { group = "eat", wd = { "Q154250", "Q2387565" }, label = "Taverne" }, teahouse = { group = "eat", wd = "Q1072166", label = "Teehaus" }, wine_tavern = { group = "eat", wd = { "Q2556304", "Q1922416" }, label = "Weinstube, Weinlokal, Bodega" }, -- group types eat = { group = "eat", wd = { "Q27038993", "Q27077054" }, label = "Küche, Essen" }, -- drinking, going out bar = { group = "drink", wd = "Q187456", label = "Bar" }, beer_garden = { group = "drink", wd = "Q857909", label = "Biergarten", icon = "beer" }, brewery = { group = "drink", wd = "Q131734", label = "Brauerei" }, club = { group = "drink", label = "Club" }, discotheque = { group = "drink", wd = "Q1228895", label = "Diskothek" }, distillery = { group = "drink", wd = "Q1251750", label = "Brennerei" }, drinking_hall = { group = "drink", wd = "Q4101440", label = "Trinkhalle" }, drinking_water = { group = "drink", wd = "Q7892", label = "Trinkwasser" }, nightclub = { group = "drink", wd = "Q622425", label = "Nachtclub" }, pub = { group = "drink", wd = { "Q19754932", "Q12341378" }, label = "Kneipe" }, vineyard = { group = "drink", wd = "Q22715", label = "Weingut, Weinberg" }, wine_cellar = { group = "drink", wd = "Q22995", label = "Weinkeller" }, winery = { group = "drink", wd = "Q20181766", label = "Kellerei" }, -- group types drink = { group = "drink", wd = "Q5307737", label = "Trinken" }, -- accommodation appartment = { group = "sleep", wd = "Q617839", label = "Appartement-Hotel" }, alpine_hut = { group = "sleep", wd = "Q182676", label = "Berghütte" }, bed_and_bike = { group = "sleep", label = "Bett und Bike" }, bnb = { group = "sleep", subtype = "y", wd = "Q367914", label = "Bed & Breakfast", icon = "lodging" }, boarding_house = { group = "sleep", subtype = "y", wd = { "Q1558858", "Q1065252" }, label = "Pension" }, boutique_hotel = { group = "sleep", wd = "Q259618", label = "Boutique-Hotel" }, campsite = { group = "sleep", wd = "Q832778", label = "Campingplatz, Zeltplatz" }, caravan_site = { group = "sleep", label = "Caravan-Campingplatz" }, chalet = { group = "sleep", label = "Chalet, Ferienhaus" }, ecolodge = { group = "sleep", wd = "Q3577646", label = "Ecolodge" }, group_accomodation = { group = "sleep", label = "Gruppenunterkunft" }, guest_house = { group = "sleep", wd = "Q2460422", label = "Gästehaus" }, holiday_flat = { group = "sleep", wd = "Q336532", label = "Ferienwohnung" }, hostel = { group = "sleep", wd = "Q654772", label = "Herberge, Hostel", icon = "lodging" }, hotel = { group = "sleep", wd = { "Q27686", "Q63099748" }, label = "Hotel", icon = "lodging" }, hotel_garni = { group = "sleep", subtype = "y", wd = "Q1631103", label = "Hotel garni", icon = "lodging" }, hut = { group = "sleep", wd = "Q5784097", label = "Hütte" }, lodge = { group = "sleep", wd = "Q56439882", label = "Lodge" }, motel = { group = "sleep", wd = "Q216212", label = "Motel", icon = "lodging" }, resort = { group = "sleep", wd = "Q875157", label = "Resort" }, wilderness_hut = { group = "sleep", wd = "Q17087359", label = "Wildnishütte" }, youth_hostel = { group = "sleep", wd = "Q1589077", label = "Jugendherberge" }, -- group types sleep = { group = "sleep", wd = "Q5056668", label = "Unterkunft" }, -- people children = { group = "other", wd = "Q7569", label = "Kinder" }, -- health animal_hospital = { group = "health", wd = "Q1706476", label = "Tierklinikum" }, defibrillator = { group = "health", wd = "Q1450682", label = "Defibrillator" }, dental_emergency_service = { group = "health", label = "Zahnärztlicher Notdienst" }, dentist = { group = "health", wd = "Q2979300", label = "Zahnarzt" }, diving_chamber = { alias = "", group = "health", wd = "Q549046", label = "Dekompressionskammer" }, doctor = { alias ="surgery", group = "health", wd = "Q718966", label = "Arztpraxis" }, emergency = { alias = "emergency_department", group = "health", wd = "Q1295316", label = "Notaufnahme, Notfallstation" }, emergency_medical_services = { group = "health", wd = "Q860447", label = "Rettungsdienst, Notfallrettung" }, first_aid = { group = "health", wd = "Q133981", label = "Erste Hilfe" }, health = { group = "health", wd = "Q12147", label = "Gesundheit" }, health_center = { alias = "clinic", group = "health", wd = { "Q569500", "Q1774898" }, label = "Ärztehaus, Poliklinik" }, hospital = { group = "health", wd = { "Q16917", "Q180370" }, label = "Krankenhaus, Spital" }, kneipp_facility = { group = "health", wd = "Q66425029", label = "Kneipp-Anlage" }, laboratory = { group = "health", wd = { "Q483242", "Q112203425" }, label = "Labor" }, ["medical_on-call_service"] = { group = "health", label = "Ärztlicher Bereitschaftsdienst" }, naturopathy = { group = "health", wd = "Q213403", label = "Naturheilkunde" }, nursing_home = { group = "health", wd = "Q837142", label = "Pflegeheim" }, pharmacy = { group = "health", wd = "Q13107184", label = "Apotheke" }, pharmacy_on_standby_duty = { group = "health", label = "Apotheken-Notdienst" }, rehabilitation = { group = "health", wd = "Q2795791", label = "Rehabilitation, Rehaklinik, Kurklinik" }, rescue_center = { group = "health", label = "Rettungsstation" }, veterinary = { group = "health", wd = "Q15850915", label = "Tierarzt" }, -- teaching & learning academy = { group = "other", wd = "Q162633", label = "Akademie" }, boarding_school = { group = "other", wd = { "Q269770", "Q125783335" }, label = "Internatsschule" }, bookcase = { group = "other", wd = "Q215857", label = "Bücherschrank" }, college = { group = "other", wd = "Q189004", label = "Hochschule, College" }, community_center = { group = "other", wd = "Q77115", label = "Gemeindezentrum" }, cooking_class = { group = "other", label = "Kochkurs" }, education = { alias = "learn", group = "other", wd = "Q8434", label = "Ausbildung" }, folk_high_school = { group = "other", wd = "Q170087", label = "Volkshochschule" }, gymnasium = { group = "other", wd = "Q55043", label = "Gymnasium" }, institute = { group = "other", wd = "Q1664720", label = "Institut" }, kindergarten = { group = "other", wd = "Q126807", label = "Kindergarten" }, language_school = { group = "other", wd = "Q897403", label = "Sprachschule" }, library = { group = "other", wd = { "Q7075", "Q6503358", "Q2061246", "Q50984122" }, label = "Bücherei, Bibliothek" }, nursery = { group = "other", wd = "Q20174673", label = "Kinderkrippe" }, school = { group = "other", wd = "Q3914", label = "Schule" }, university = { group = "other", wd = "Q3918", label = "Universität" }, -- administration and uncategorized administration = { group = "other", wd = { "Q327333", "Q5283295" }, label = "Verwaltung, Behörde, Amt" }, association = { alias = "society", group = "other", wd = { "Q48204", "Q15911314" }, label = "Verein" }, business_development_agency = { group = "other", label = "Wirtschaftsförderungsgesellschaft" }, checkpoint = { group = "other", wd = "Q88871664", label = "Kontrollpunkt" }, company = { group = "other", wd = "Q6881511", label = "Unternehmen" }, consulate = { group = "other", wd = "Q7843791", label = "Konsulat" }, coworking_space = { group = "other", wd = "Q97307779", label = "Coworking Space" }, customs = { group = "other", wd = "Q182290", label = "Zoll" }, cultural_organisation = { group = "other", wd = "Q29918292", label = "Kulturorganisation" }, embassy = { group = "other", wd = "Q3917681", label = "Botschaft" }, emergency_call = { group = "other", wd = "Q694554", label = "Notruf", icon = "emergency-phone" }, fire_brigade = { group = "other", wd = "Q6498663", label = "Feuerwehr", icon = "fire-station" }, government = { group = "other", wd = "Q16831714", label = "Regierungsgebäude" }, guide = { group = "other", wd = "Q14290559", label = "Fremdenführer" }, hotline = { group = "other", wd = "Q1482145", label = "Hotline" }, internet_cafe = { group = "other", wd = "Q272399", label = "Internetcafé" }, laundry = { group = "other", wd = "Q12893467", label = "Wäscherei" }, list = { group = "other", wd = { "Q12139612", "Q13406463" }, label = "Liste" }, lost_and_found = { group = "other", wd = "Q15983979", label = "Fundbüro" }, military = { group = "other", wd = "Q8473", label = "Militär" }, mobile_telephony = { group = "other", wd = "Q47516435", label = "Mobilfunkgeschäft" }, newspaper = { group = "other", wd = "Q11032", label = "Zeitung, Zeitungsverlag" }, office = { group = "other", wd = "Q182060", label = "Büro" }, organisation = { group = "other", wd = "Q43229", label = "Organisation" }, passport_office = { group = "other", label = "Passstelle" }, payphone = { group = "other", wd = "Q900977", label = "Münzfernsprecher", icon = "telephone" }, phone = { group = "other", wd = "Q11035", label = "Telefon", icon = "telephone" }, police = { group = "other", wd = "Q35535", label = "Polizei" }, post = { group = "other", wd = "Q35054", label = "Postamt" }, register_office = { alias = { "standesamt", "registry_office" }, group = "other", wd = { "Q745221", "Q29127138", "Q206946" }, label = "Standesamt" }, relief_organisation = { group = "other", wd = "Q708676", label = "Wohltätigkeitsorganisation" }, roadside_assistance = { group = "other", wd = "Q337810", label = "Pannenhilfe, Unfallhilfe" }, shelter = { group = "other", wd = { "Q7493941", "Q989946" }, label = "Unterstand" }, toilet = { group = "other", wd = "Q7857", label = "Toiletten" }, tour_operator = { group = "other", wd = "Q133744", label = "Reiseveranstalter" }, tourism_authority = { group = "other", label = "Tourismusbehörde" }, tourist_information = { alias = "visitor_center", group = "other", wd = { "Q1587716", "Q18411786", "Q6031029" }, label = "Touristinformation, Besucherzentrum, Fremdenverkehrsamt", icon = "information" }, travel_agency = { group = "other", wd = "Q217107", label = "Reisebüro" }, weblink = { group = "other", wd = "Q102014", label = "Weblink" }, wlan = { group = "other", wd = "Q334765", label = "WLAN-Hotspot" }, work = { group = "other", wd = "Q6958747", label = "Arbeit" }, -- group types other = { group = "other", label = "Anderes" }, listing = { group = "other", label = "Listung" }, -- populated areas city = { group = "populated", wd = "Q515", label = "Stadt" }, fraction = { group = "populated", label = "Ortsteil einer Gemeinde" }, holiday_resort = { group = "populated", wd = "Q3077815", label = "Feriensiedlung" }, municipality = { group = "populated", wd = { "Q15284", "Q17376095", "Q562061" }, label = "Gemeinde" }, quarter = { alias = "neighborhood", group = "populated", wd = { "Q2983893", "Q253019" }, label = "Stadtteil" }, refugee_camp = { group = "populated", wd = "Q622499", label = "Flüchtlingscamp" }, settlement = { group = "populated", wd = "Q486972", label = "Siedlung" }, town = { group = "populated", wd = "Q3957", label = "Kleinstadt" }, village = { group = "populated", wd = "Q532", label = "Dorf" }, -- views observation_tower = { group = "view", wd = "Q1440300", label = "Aussichtsturm" }, scenic_view = { group = "view", label = "Bildmotiv", icon = "attraction" }, viewpoint = { group = "view", wd = "Q6017969", label = "Aussichtspunkt" }, -- areas adm1st = { group = "area", wd = "Q10864048", label = "Verwaltungseinheit 1. Ebene" }, adm2nd = { group = "area", wd = "Q13220204", label = "Verwaltungseinheit 2. Ebene" }, adm3rd = { group = "area", wd = "Q13221722", label = "Verwaltungseinheit 3. Ebene" }, country = { group = "area", wd = "Q6256", label = "Land, Staat" }, district = { group = "area", wd = "Q149621", label = "Distrikt" }, region = { group = "area", wd = "Q82794", label = "Region" }, surroundings = { group = "area", wd = "Q2920644", label = "Umgebung" }, vicinity = { group = "area", wd = "Q16968816", label = "Nähe, nahe Umgebung" }, -- error error = { group = "error", wd = "Q29485", label = "Fehler" } -- do not remove the following line -- ##end } } nodf05clh2le0d9awt8uygmptz7wf6e Modulo:CountryData/Geography 828 4821 73244 71057 2026-09-24T10:44:25Z RolandUnger 168 Update 73244 Scribunto text/plain -- Preventing expensive Wikidata calls return { -- administration moduleInterface = { suite = 'CountryData', sub = 'Geography', serial = '2026-08-19', item = 65433242 }, -- wiki-specific exceptions for articles with many vCard calls or topic articles -- to prevent data retrieval on the base of article's Wikidata qualifier id articles = { _default = "Q183", -- DE Q24879 = "Q183", -- Bremen Q2814 = "Q183", -- Halle (Saale) Q452401 = "Q183", -- Deutsche Fachwerkstraße Q1741 = "Q40", -- Wien -> AT Q19386 = "Q25227", -- ABC-Inseln -> AN Q5604 = "Q30", -- Arizona/Frank Lloyd Wright -> US Q15112104= "Q79", -- Hamada -> EG Q214077 = "Q801", -- Via Dolorosa -> IL -- historic regions Q564882 = "Q36", -- Dobriner Land -> PL Q661110 = "Q36", -- Glatzer Ländchen Q178813 = "Q38", -- Herculaneum -> IT Q283680 = "Q43", -- Karkemisch -> TR Q672344 = "Q36", -- Kulmer Land Q22880 = "Q183", -- Kurpfalz Q1801987 = "Q36", -- Lande Lauenburg und Bütow Q158445 = "Q183", -- Mecklenburg-Schwerin Q819411 = "Q36", -- Neumark -> PL Q767089 = "Q23681", -- Salamis -> Nordzypern Q1294629 = "Q407199", -- Samaria -> PS Q151005 = "Q183", -- Völkerschlacht Q159626 = "Q183", -- Württemberg }, -- continent list continents = { Q15 = "af", Q51 = "an", Q48 = "as", Q3960 = "au", Q46 = "eu", Q49 = "na", Q538 = "oc", Q18 = "sa" }, -- countries list sorted by ISO 3166 code -- add contains additional show parameters link all, inline -- de-wiki: exceptions: at, ch, de, it: show = "inline" countries = { Q244165 = { cont = "as", iso_3166 = "", cc = "+37447", lang = "hy", currency = "Q130498", country = "Arzach" }, -- Bergkarabach Q228 = { cont = "eu", iso_3166 = "AD", cc = "+376", lang = "ca", currency = "Q4916", country = "Andorra" }, Q878 = { cont = "as", iso_3166 = "AE", cc = "+971", lang = "ar", currency = "Q200294", country = "Vereinigte Arabische Emirate" }, Q889 = { cont = "as", iso_3166 = "AF", cc = "+93", lang = "ps", currency = "Q199471", country = "Afghanistan" }, Q781 = { cont = "na", iso_3166 = "AG", cc = "+1-268", lang = "en", currency = "Q26365", country = "Antigua und Barbuda" }, Q222 = { cont = "eu", iso_3166 = "AL", cc = "+355", lang = "sq", currency = "Q125999", country = "Albanien" }, Q399 = { cont = "as", iso_3166 = "AM", cc = "+374", lang = "hy", currency = "Q130498", country = "Armenien" }, Q916 = { cont = "af", iso_3166 = "AO", cc = "+244", lang = "pt", currency = "Q200337", country = "Angola" }, Q1555938 = { cont = "an", iso_3166 = "AQ", cc = "", lang = "en", currency = "", country = "Antarktis" }, Q21590062= { id = "Q1555938" }, Q414 = { cont = "sa", iso_3166 = "AR", cc = "+54", lang = "es", currency = "Q199578", country = "Argentinien" }, Q40 = { cont = "eu", iso_3166 = "AT", cc = "+43", lang = "de", currency = "Q4916", show = "inline", country = "Österreich" }, Q408 = { cont = "au", iso_3166 = "AU", cc = "+61", lang = "en", currency = "Q259502", country = "Australien" }, Q227 = { cont = "as", iso_3166 = "AZ", cc = "+994", lang = "az", currency = "Q483725", country = "Aserbaidschan" }, Q225 = { cont = "eu", iso_3166 = "BA", cc = "+387", lang = "bs", currency = "Q179620", country = "Bosnien und Herzegowina" }, Q244 = { cont = "na", iso_3166 = "BB", cc = "+1-246", lang = "en", currency = "Q194351", country = "Barbados" }, Q902 = { cont = "as", iso_3166 = "BD", cc = "+880", lang = "bn", currency = "Q194453", country = "Bangladesch" }, Q31 = { cont = "eu", iso_3166 = "BE", cc = "+32", lang = "nl", currency = "Q4916", country = "Belgien" }, Q29999 = { id = "Q31" }, Q965 = { cont = "af", iso_3166 = "BF", cc = "+226", lang = "fr", currency = "Q861690", country = "Burkina Faso" }, Q219 = { cont = "eu", iso_3166 = "BG", cc = "+359", lang = "bg", currency = "Q172540", country = "Bulgarien" }, Q398 = { cont = "as", iso_3166 = "BH", cc = "+973", lang = "ar", currency = "Q201871", country = "Bahrain" }, Q967 = { cont = "af", iso_3166 = "BI", cc = "+257", lang = "fr", currency = "Q238007", country = "Burundi" }, Q962 = { cont = "af", iso_3166 = "BJ", cc = "+229", lang = "fr", currency = "Q861690", country = "Benin" }, Q921 = { cont = "as", iso_3166 = "BN", cc = "+673", lang = "ms", currency = "Q206319", country = "Brunei" }, Q750 = { cont = "sa", iso_3166 = "BO", cc = "+591", lang = "es", currency = "Q200737", country = "Bolivien" }, Q155 = { cont = "sa", iso_3166 = "BR", cc = "+55", lang = "pt", currency = "Q173117", country = "Brasilien" }, Q778 = { cont = "na", iso_3166 = "BS", cc = "+1-242", lang = "en", currency = "Q194339", country = "Bahamas" }, Q917 = { cont = "as", iso_3166 = "BT", cc = "+975", lang = "dz", currency = "Q201799", country = "Bhutan" }, Q963 = { cont = "af", iso_3166 = "BW", cc = "+267", lang = "en", currency = "Q186794", country = "Botsuana" }, Q184 = { cont = "eu", iso_3166 = "BY", cc = "+375", lang = "be", currency = "Q160680", country = "Belarus" }, Q242 = { cont = "na", iso_3166 = "BZ", cc = "+501", lang = "en", currency = "Q275112", country = "Belize" }, Q16 = { cont = "na", iso_3166 = "CA", cc = "+1", lang = "en", currency = "Q1104069", country = "Kanada" }, Q974 = { cont = "af", iso_3166 = "CD", cc = "+243", lang = "fr", currency = "Q4734", country = "Demokratische Republik Kongo" }, Q929 = { cont = "af", iso_3166 = "CF", cc = "+236", lang = "fr", currency = "Q847739", country = "Zentralafrikanische Republik" }, Q971 = { cont = "af", iso_3166 = "CG", cc = "+242", lang = "fr", currency = "Q847739", country = "Republik Kongo" }, Q39 = { cont = "eu", iso_3166 = "CH", cc = "+41", lang = "de", currency = "Q25344", show = "inline", country = "Schweiz" }, Q1008 = { cont = "af", iso_3166 = "CI", cc = "+225", lang = "fr", currency = "Q861690", country = "Elfenbeinküste" }, Q26988 = { cont = "oc", iso_3166 = "CK", cc = "+682", lang = "en", currency = "Q1472704", country = "Cookinseln" }, Q298 = { cont = "sa", iso_3166 = "CL", cc = "+56", lang = "es", currency = "Q200050", country = "Chile" }, Q1009 = { cont = "af", iso_3166 = "CM", cc = "+237", lang = "fr", currency = "Q847739", country = "Kamerun" }, Q148 = { cont = "as", iso_3166 = "CN", cc = "+86", lang = "zh", currency = "Q39099", country = "China" }, Q739 = { cont = "sa", iso_3166 = "CO", cc = "+57", lang = "es", currency = "Q244819", country = "Kolumbien" }, Q800 = { cont = "na", iso_3166 = "CR", cc = "+506", lang = "es", currency = "Q242915", country = "Costa Rica" }, Q241 = { cont = "na", iso_3166 = "CU", cc = "+53", lang = "es", currency = "Q201505", country = "Kuba" }, Q1011 = { cont = "af", iso_3166 = "CV", cc = "+238", lang = "pt", currency = "Q4591", country = "Kap Verde" }, Q229 = { cont = "eu", iso_3166 = "CY", cc = "+357", lang = "el", currency = "Q4916", country = "Zypern" }, Q213 = { cont = "eu", iso_3166 = "CZ", cc = "+420", lang = "cs", currency = "Q131016", country = "Tschechien" }, Q183 = { cont = "eu", iso_3166 = "DE", cc = "+49", lang = "de", currency = "Q4916", show = "inline", country = "Deutschland" }, Q977 = { cont = "af", iso_3166 = "DJ", cc = "+253", lang = "fr", currency = "Q4594", country = "Dschibuti" }, Q35 = { cont = "eu", iso_3166 = "DK", cc = "+45", lang = "da", currency = "Q25417", country = "Dänemark" }, Q756617 = { id = "Q35" }, Q784 = { cont = "na", iso_3166 = "DM", cc = "+1-767", lang = "en", currency = "Q26365", country = "Dominica" }, Q786 = { cont = "na", iso_3166 = "DO", cc = "+1-809", lang = "es", currency = "Q242922", country = "Dominikanische Republik" }, Q262 = { cont = "af", iso_3166 = "DZ", cc = "+213", lang = "fr", currency = "Q199674", country = "Algerien" }, Q736 = { cont = "sa", iso_3166 = "EC", cc = "+593", lang = "es", currency = "Q4917", country = "Ecuador" }, Q191 = { cont = "eu", iso_3166 = "EE", cc = "+372", lang = "et", currency = "Q4916", country = "Estland" }, Q79 = { cont = "af", iso_3166 = "EG", cc = "+20", lang = "ar", currency = "Q199462", phoneDigits = 4, show = "all", country = "Ägypten" }, Q6250 = { cont = "af", iso_3166 = "EH", cc = "+212", lang = "ar", currency = "Q200192", country = "Westsahara" }, Q40362 = { id = "Q6250" }, Q986 = { cont = "af", iso_3166 = "ER", cc = "+291", lang = "ti", currency = "Q171503", country = "Eritrea" }, Q29 = { cont = "eu", iso_3166 = "ES", cc = "+34", lang = "es", currency = "Q4916", country = "Spanien" }, Q115 = { cont = "af", iso_3166 = "ET", cc = "+251", lang = "am", currency = "Q206243", show = "all", country = "Äthiopien" }, Q33 = { cont = "eu", iso_3166 = "FI", cc = "+358", lang = "fi", currency = "Q4916", country = "Finnland" }, Q712 = { cont = "oc", iso_3166 = "FJ", cc = "+679", lang = "fj", currency = "Q4592", country = "Fidschi" }, Q702 = { cont = "oc", iso_3166 = "FM", cc = "+691", lang = "en", currency = "Q4917", country = "Mikronesien" }, Q4628 = { cont = "eu", iso_3166 = "FO", cc = "+298", lang = "da", currency = "Q191068", country = "Färöer" }, Q142 = { cont = "eu", iso_3166 = "FR", cc = "+33", lang = "fr", currency = "Q4916", country = "Frankreich" }, Q1000 = { cont = "af", iso_3166 = "GA", cc = "+241", lang = "fr", currency = "Q847739", country = "Gabun" }, Q145 = { cont = "eu", iso_3166 = "GB", cc = "+44", lang = "en-gb", currency = "Q25224", country = "Vereinigtes Königreich" }, Q124653007 = { id = "Q145" }, Q769 = { cont = "na", iso_3166 = "GD", cc = "+1-473", lang = "en", currency = "Q26365", country = "Grenada" }, Q230 = { cont = "as", iso_3166 = "GE", cc = "+995", lang = "ka", currency = "Q4608", country = "Georgien" }, Q31354462= { cont = "as", iso_3166 = "GE-AB", cc ="+7", lang = "ab", currency = "Q41044", country = "Abchasien" }, Q117 = { cont = "af", iso_3166 = "GH", cc = "+233", lang = "en", currency = "Q183530", country = "Ghana" }, Q1005 = { cont = "af", iso_3166 = "GM", cc = "+220", lang = "en", currency = "Q202885", country = "Gambia" }, Q1006 = { cont = "af", iso_3166 = "GN", cc = "+224", lang = "fr", currency = "Q213311", country = "Guinea" }, Q983 = { cont = "af", iso_3166 = "GQ", cc = "+240", lang = "es", currency = "Q847739", country = "Äquatorialguinea" }, Q41 = { cont = "eu", iso_3166 = "GR", cc = "+30", lang = "el", currency = "Q4916", country = "Griechenland" }, Q774 = { cont = "na", iso_3166 = "GT", cc = "+502", lang = "es", currency = "Q207396", country = "Guatemala" }, Q1007 = { cont = "af", iso_3166 = "GW", cc = "+245", lang = "pt", currency = "Q861690", country = "Guinea-Bissau" }, Q734 = { cont = "sa", iso_3166 = "GY", cc = "+592", lang = "en", currency = "Q213005", country = "Guyana" }, Q783 = { cont = "na", iso_3166 = "HN", cc = "+504", lang = "es", currency = "Q4719", phoneDigits = 4, country = "Honduras" }, Q224 = { cont = "eu", iso_3166 = "HR", cc = "+385", lang = "hr", currency = "Q4916", country = "Kroatien" }, Q790 = { cont = "na", iso_3166 = "HT", cc = "+509", lang = "fr", currency = "Q203955", country = "Haiti" }, Q28 = { cont = "eu", iso_3166 = "HU", cc = "+36", lang = "hu", currency = "Q47190", country = "Ungarn" }, Q252 = { cont = "as", iso_3166 = "ID", cc = "+62", lang = "id", currency = "Q41588", country = "Indonesien" }, Q27 = { cont = "eu", iso_3166 = "IE", cc = "+353", lang = "ga", currency = "Q4916", country = "Irland" }, Q801 = { cont = "as", iso_3166 = "IL", cc = "+972", lang = "he", currency = "Q131309", country = "Israel" }, Q575187 = { id = "Q801" }, Q668 = { cont = "as", iso_3166 = "IN", cc = "+91", lang = "hi", currency = "Q80524", country = "Indien" }, Q796 = { cont = "as", iso_3166 = "IQ", cc = "+964", lang = "ar", currency = "Q193094", country = "Irak" }, Q794 = { cont = "as", iso_3166 = "IR", cc = "+98", lang = "fa", currency = "Q188608", country = "Iran" }, Q189 = { cont = "eu", iso_3166 = "IS", cc = "+354", lang = "is", currency = "Q131473", country = "Island" }, Q38 = { cont = "eu", iso_3166 = "IT", cc = "+39", lang = "it", currency = "Q4916", show = "inline", country = "Italien" }, Q766 = { cont = "na", iso_3166 = "JM", cc = "+1-876", lang = "en", currency = "Q209792", country = "Jamaika" }, Q810 = { cont = "as", iso_3166 = "JO", cc = "+962", lang = "ar", currency = "Q203722", country = "Jordanien" }, Q17 = { cont = "as", iso_3166 = "JP", cc = "+81", lang = "ja", currency = "Q8146", country = "Japan" }, Q114 = { cont = "af", iso_3166 = "KE", cc = "+254", lang = "sw", currency = "Q202882", country = "Kenia" }, Q813 = { cont = "as", iso_3166 = "KG", cc = "+996", lang = "ky", currency = "Q35881", country = "Kirgisistan" }, Q424 = { cont = "as", iso_3166 = "KH", cc = "+855", lang = "km", currency = "Q204737", country = "Kambodscha" }, Q710 = { cont = "oc", iso_3166 = "KI", cc = "+686", lang = "en", currency = "Q1049963", country = "Kiribati" }, Q970 = { cont = "af", iso_3166 = "KM", cc = "+269", lang = "ar", currency = "Q267264", country = "Komoren" }, Q763 = { cont = "na", iso_3166 = "KN", cc = "+1-869", lang = "en", currency = "Q26365", country = "Saint Kitts und Nevis" }, Q423 = { cont = "as", iso_3166 = "KP", cc = "+850", lang = "ko", currency = "Q106720", country = "Nordkorea" }, Q884 = { cont = "as", iso_3166 = "KR", cc = "+82", lang = "ko", currency = "Q202040", country = "Südkorea" }, Q817 = { cont = "as", iso_3166 = "KW", cc = "+965", lang = "ar", currency = "Q193098", country = "Kuwait" }, Q232 = { cont = "as", iso_3166 = "KZ", cc = "+7", lang = "kk", currency = "Q173751", country = "Kasachstan" }, Q819 = { cont = "as", iso_3166 = "LA", cc = "+856", lang = "lo", currency = "Q200055", country = "Laos" }, Q822 = { cont = "as", iso_3166 = "LB", cc = "+961", lang = "ar", currency = "Q201880", country = "Libanon" }, Q760 = { cont = "na", iso_3166 = "LC", cc = "+1-758", lang = "en", currency = "Q26365", country = "Saint Lucia" }, Q347 = { cont = "eu", iso_3166 = "LI", cc = "+423", lang = "de", currency = "Q25344", country = "Liechtenstein" }, Q854 = { cont = "as", iso_3166 = "LK", cc = "+94", lang = "si", currency = "Q4596", country = "Sri Lanka" }, Q1014 = { cont = "af", iso_3166 = "LR", cc = "+231", lang = "en", currency = "Q242988", country = "Liberia" }, Q1013 = { cont = "af", iso_3166 = "LS", cc = "+266", lang = "en", currency = "Q208039", country = "Lesotho" }, Q37 = { cont = "eu", iso_3166 = "LT", cc = "+370", lang = "lt", currency = "Q4916", country = "Litauen" }, Q32 = { cont = "eu", iso_3166 = "LU", cc = "+352", lang = "lb", currency = "Q4916", country = "Luxemburg" }, Q211 = { cont = "eu", iso_3166 = "LV", cc = "+371", lang = "lv", currency = "Q4916", country = "Lettland" }, Q1016 = { cont = "af", iso_3166 = "LY", cc = "+218", lang = "ar", currency = "Q190699", country = "Libyen" }, Q1028 = { cont = "af", iso_3166 = "MA", cc = "+212", lang = "ar", currency = "Q200192", country = "Marokko" }, Q235 = { cont = "eu", iso_3166 = "MC", cc = "+377", lang = "fr", currency = "Q4916", country = "Monaco" }, Q217 = { cont = "eu", iso_3166 = "MD", cc = "+373", lang = "mo", currency = "Q181129", country = "Moldau" }, Q236 = { cont = "eu", iso_3166 = "ME", cc = "+382", lang = "sr-me", currency = "Q4916", country = "Montenegro" }, Q1019 = { cont = "af", iso_3166 = "MG", cc = "+261", lang = "mg", currency = "Q4584", country = "Madagaskar" }, Q709 = { cont = "oc", iso_3166 = "MH", cc = "+692", lang = "en", currency = "Q4917", country = "Marshallinseln" }, Q221 = { cont = "eu", iso_3166 = "MK", cc = "+389", lang = "mk", currency = "Q177875", country = "Nordmazedonien" }, Q912 = { cont = "af", iso_3166 = "ML", cc = "+223", lang = "fr", currency = "Q861690", country = "Mali" }, Q836 = { cont = "as", iso_3166 = "MM", cc = "+95", lang = "my", currency = "Q201875", country = "Myanmar" }, Q711 = { cont = "as", iso_3166 = "MN", cc = "+976", lang = "mn", currency = "Q183435", country = "Mongolei" }, Q16644 = { cont = "oc", iso_3166 = "MP", cc ="+1-670", lang = "en", currency = "Q4917", country = "Nördliche Marianen" }, Q1025 = { cont = "af", iso_3166 = "MR", cc = "+222", lang = "ar", currency = "Q207024", country = "Mauretanien" }, Q233 = { cont = "eu", iso_3166 = "MT", cc = "+356", lang = "mt", currency = "Q4916", country = "Malta" }, Q1027 = { cont = "af", iso_3166 = "MU", cc = "+230", lang = "en", currency = "Q212967", country = "Mauritius" }, Q826 = { cont = "as", iso_3166 = "MV", cc = "+960", lang = "dv", currency = "Q206600", country = "Malediven" }, Q1020 = { cont = "af", iso_3166 = "MW", cc = "+265", lang = "en", currency = "Q211694", country = "Malawi" }, Q96 = { cont = "na", iso_3166 = "MX", cc = "+52", lang = "es", currency = "Q4730", country = "Mexiko" }, Q833 = { cont = "as", iso_3166 = "MY", cc = "+60", lang = "ms", currency = "Q163712", country = "Malaysia" }, Q1029 = { cont = "af", iso_3166 = "MZ", cc = "+222", lang = "pt", currency = "Q200753", country = "Mosambik" }, Q1030 = { cont = "af", iso_3166 = "NA", cc = "+264", lang = "en", currency = "Q202462", country = "Namibia" }, Q1032 = { cont = "af", iso_3166 = "NE", cc = "+227", lang = "fr", currency = "Q861690", country = "Niger" }, Q1033 = { cont = "af", iso_3166 = "NG", cc = "+234", lang = "en", currency = "Q203567", country = "Nigeria" }, Q811 = { cont = "na", iso_3166 = "NI", cc = "+505", lang = "es", currency = "Q207312", country = "Nicaragua" }, Q55 = { cont = "eu", iso_3166 = "NL", cc = "+31", lang = "nl", currency = "Q4916", country = "Niederlande" }, Q20 = { cont = "eu", iso_3166 = "NO", cc = "+47", lang = "no", currency = "Q132643", country = "Norwegen" }, Q837 = { cont = "as", iso_3166 = "NP", cc = "+977", lang = "ne", currency = "Q202895", country = "Nepal" }, Q697 = { cont = "oc", iso_3166 = "NR", cc = "+674", lang = "na", currency = "Q259502", country = "Nauru" }, Q34020 = { cont = "oc", iso_3166 = "NU", cc = "+683", lang ="niu", currency = "Q1472704", country = "Niue" }, Q664 = { cont = "oc", iso_3166 = "NZ", cc = "+64", lang = "en", currency = "Q1472704", country = "Neuseeland" }, Q23681 = { cont = "eu", iso_3166 = "", cc = "+90-392", lang = "tr", currency = "Q172872", country = "Nordzypern" }, Q842 = { cont = "as", iso_3166 = "OM", cc = "+968", lang = "ar", currency = "Q272290", country = "Oman" }, Q804 = { cont = "na", iso_3166 = "PA", cc = "+507", lang = "es", currency = "Q210472", country = "Panama" }, Q419 = { cont = "sa", iso_3166 = "PE", cc = "+51", lang = "es", currency = "Q204656", country = "Peru" }, Q691 = { cont = "oc", iso_3166 = "PG", cc = "+675", lang = "ho", currency = "Q200759", country = "Papua-Neuguinea" }, Q928 = { cont = "as", iso_3166 = "PH", cc = "+63", lang = "fil", currency = "Q17193", country = "Philippinen" }, Q843 = { cont = "as", iso_3166 = "PK", cc = "+92", lang = "ur", currency = "Q188289", country = "Pakistan" }, Q36 = { cont = "eu", iso_3166 = "PL", cc = "+48", lang = "pl", currency = "Q123213", country = "Polen" }, Q407199 = { cont = "as", iso_3166 = "PS", cc = "+970", lang = "ar", currency = "Q203722", country = "Palästina" }, Q23792 = { id = "Q407199" }, Q42620 = { id = "Q407199" }, Q219060 = { id = "Q407199" }, Q45 = { cont = "eu", iso_3166 = "PT", cc = "+351", lang = "pt", currency = "Q4916", country = "Portugal" }, Q695 = { cont = "oc", iso_3166 = "PW", cc = "+680", lang = "en", currency = "Q4917", country = "Palau" }, Q733 = { cont = "sa", iso_3166 = "PY", cc = "+595", lang = "es", currency = "Q207514", country = "Paraguay" }, Q846 = { cont = "as", iso_3166 = "QA", cc = "+974", lang = "ar", currency = "Q206386", country = "Katar" }, Q218 = { cont = "eu", iso_3166 = "RO", cc = "+40", lang = "ro", currency = "Q131645", country = "Rumänien" }, Q403 = { cont = "eu", iso_3166 = "RS", cc = "+381", lang = "sr", currency = "Q172524", country = "Serbien" }, Q159 = { cont = "eu", iso_3166 = "RU", cc = "+7", lang = "ru", currency = "Q41044", country = "Russland" }, Q1037 = { cont = "af", iso_3166 = "RW", cc = "+250", lang = "rw", currency = "Q4741", country = "Ruanda" }, Q851 = { cont = "as", iso_3166 = "SA", cc = "+966", lang = "ar", currency = "Q199857", country = "Saudi-Arabien" }, Q685 = { cont = "oc", iso_3166 = "SB", cc = "+677", lang = "en", currency = "Q4597", country = "Salomonen" }, Q1042 = { cont = "af", iso_3166 = "SC", cc = "+248", lang = "en", currency = "Q4595", country = "Seychellen" }, Q1049 = { cont = "af", iso_3166 = "SD", cc = "+249", lang = "ar", currency = "Q271206", show = "all", country = "Sudan" }, Q34 = { cont = "eu", iso_3166 = "SE", cc = "+46", lang = "sv", currency = "Q122922", country = "Schweden" }, Q334 = { cont = "as", iso_3166 = "SG", cc = "+65", lang = "en", currency = "Q190951", country = "Singapur" }, Q215 = { cont = "eu", iso_3166 = "SI", cc = "+386", lang = "sl", currency = "Q4916", country = "Slowenien" }, Q214 = { cont = "eu", iso_3166 = "SK", cc = "+421", lang = "sk", currency = "Q4916", country = "Slowakei" }, Q1044 = { cont = "af", iso_3166 = "SL", cc = "+232", lang = "en", currency = "Q122922", country = "Sierra Leone" }, Q238 = { cont = "eu", iso_3166 = "SM", cc = "+378", lang = "it", currency = "Q4916", country = "San Marino" }, Q1041 = { cont = "af", iso_3166 = "SN", cc = "+221", lang = "fr", currency = "Q861690", country = "Senegal" }, Q1045 = { cont = "af", iso_3166 = "SO", cc = "+252", lang = "so", currency = "Q4603", country = "Somalia" }, Q730 = { cont = "sa", iso_3166 = "SR", cc = "+597", lang = "nl", currency = "Q202036", country = "Suriname" }, Q958 = { cont = "af", iso_3166 = "SS", cc = "+211", lang = "en", currency = "Q244366", country = "Südsudan" }, Q1039 = { cont = "af", iso_3166 = "ST", cc = "+239", lang = "pt", currency = "Q193712", country = "São Tomé und Príncipe" }, Q792 = { cont = "na", iso_3166 = "SV", cc = "+503", lang = "es", currency = "Q4917", country = "El Salvador" }, Q858 = { cont = "as", iso_3166 = "SY", cc = "+963", lang = "ar", currency = "Q240468", country = "Syrien" }, Q1050 = { cont = "af", iso_3166 = "SZ", cc = "+268", lang = "en", currency = "Q4823", country = "Eswatini" }, Q657 = { cont = "af", iso_3166 = "TD", cc = "+235", lang = "ar", currency = "Q847739", country = "Tschad" }, Q945 = { cont = "af", iso_3166 = "TG", cc = "+228", lang = "fr", currency = "Q861690", country = "Togo" }, Q869 = { cont = "as", iso_3166 = "TH", cc = "+66", lang = "th", currency = "Q177882", country = "Thailand" }, Q863 = { cont = "as", iso_3166 = "TJ", cc = "+992", lang = "tg", currency = "Q199886", country = "Tadschikistan" }, Q574 = { cont = "as", iso_3166 = "TL", cc = "+670", lang = "pt", currency = "Q4917", country = "Osttimor" }, Q874 = { cont = "as", iso_3166 = "TM", cc = "+993", lang = "tk", currency = "Q486637", country = "Turkmenistan" }, Q948 = { cont = "af", iso_3166 = "TN", cc = "+216", lang = "ar", currency = "Q4602", country = "Tunesien" }, Q678 = { cont = "oc", iso_3166 = "TO", cc = "+676", lang = "to", currency = "Q4613", country = "Tonga" }, Q43 = { cont = "eu", iso_3166 = "TR", cc = "+90", lang = "tr", currency = "Q172872", country = "Türkei" }, Q754 = { cont = "na", iso_3166 = "TT", cc = "+1-868", lang = "en", currency = "Q242890", country = "Trinidad und Tobago" }, Q672 = { cont = "oc", iso_3166 = "TV", cc = "+688", lang = "tvl", currency = "Q4406", country = "Tuvalu" }, Q865 = { cont = "as", iso_3166 = "TW", cc = "+886", lang = "zh", currency = "Q208526", country = "Taiwan" }, Q924 = { cont = "af", iso_3166 = "TZ", cc = "+255", lang = "sw", currency = "Q4589", country = "Tansania" }, Q907112 = { cont = "eu", iso_3166 = "", cc = "+373", lang = "ru", currency = "Q200979", country = "Transnistrien" }, -- auch Pridnestrowien Q212 = { cont = "eu", iso_3166 = "UA", cc = "+380", lang = "uk", currency = "Q81893", country = "Ukraine" }, Q1036 = { cont = "af", iso_3166 = "UG", cc = "+256", lang = "sw", currency = "Q4598", country = "Uganda" }, Q30 = { cont = "na", iso_3166 = "US", cc = "+1", lang = "en-us", currency = "Q4917", phoneDigits = 4, country = "Vereinigte Staaten" }, Q77 = { cont = "sa", iso_3166 = "UY", cc = "+598", lang = "es", currency = "Q209272", country = "Uruguay" }, Q265 = { cont = "as", iso_3166 = "UZ", cc = "+998", lang = "uz", currency = "Q487888", country = "Usbekistan" }, Q237 = { cont = "eu", iso_3166 = "VA", cc = "+39", lang = "it", currency = "Q4916", country = "Vatikanstadt" }, Q757 = { cont = "na", iso_3166 = "VC", cc = "+1-784", lang = "en", currency = "Q26365", country = "Saint Vincent und die Grenadinen" }, Q717 = { cont = "sa", iso_3166 = "VE", cc = "+58", lang = "es", currency = "Q56349362", country = "Venezuela" }, Q881 = { cont = "as", iso_3166 = "VN", cc = "+84", lang = "vi", currency = "Q192090", country = "Vietnam" }, Q686 = { cont = "oc", iso_3166 = "VU", cc = "+678", lang = "en", currency = "Q207523", country = "Vanuatu" }, Q683 = { cont = "oc", iso_3166 = "WS", cc = "+685", lang = "sm", currency = "Q4588", country = "Samoa" }, Q1246 = { cont = "eu", iso_3166 = "XK", cc = "+383", lang = "sq", currency = "Q4916", country = "Kosovo" }, Q805 = { cont = "as", iso_3166 = "YE", cc = "+967", lang = "ar", currency = "Q240512", country = "Jemen" }, Q258 = { cont = "af", iso_3166 = "ZA", cc = "+27", lang = "en", currency = "Q181907", country = "Südafrika" }, Q953 = { cont = "af", iso_3166 = "ZM", cc = "+260", lang = "en", currency = "Q21596813", country = "Sambia" }, Q954 = { cont = "af", iso_3166 = "ZW", cc = "+263", lang = "en", currency = "Q4917", country = "Simbabwe" } }, -- list of administrative entities usually outside of their home countries. -- These entities are favored over its home countries. adminEntities = { -- extraterritorial areas Q25228 = { cont = "na", iso_3166 = "AI", cc = "+1-264", lang = "en", currency = "Q26365", country = "Anguilla" }, Q25227 = { cont = "na", iso_3166 = "AN", cc = "+599", lang = "nl", currency = "Q4917", country = "Niederländische Antillen" }, Q16641 = { cont = "oc", iso_3166 = "AS", cc = "+1-684", lang = "en", currency = "Q4917", country = "Amerikanisch-Samoa" }, Q21203 = { cont = "na", iso_3166 = "AW", cc = "+297", lang = "nl", currency = "Q232270", country = "Aruba" }, Q5689 = { cont = "eu", iso_3166 = "AX", cc ="+358-18", lang = "sv", currency = "Q4916", country = "Åland" }, Q25362 = { cont = "na", iso_3166 = "BL", cc = "+590", lang = "fr", currency = "Q4916", country = "Saint-Barthélemy" }, Q23635 = { cont = "na", iso_3166 = "BM", cc = "+1-441", lang = "en", currency = "Q210478", country = "Bermuda" }, Q26180 = { cont = "na", iso_3166 = "BQ-SE", cc = "+599", lang = "nl", currency = "Q4917", country = "Niederländische Antillen" }, -- Sint Eustatius, +599-3 Q25528 = { cont = "na", iso_3166 = "BQ-SA", cc = "+599", lang = "nl", currency = "Q4917", country = "Niederländische Antillen" }, -- Saba, +599-4 Q25396 = { cont = "na", iso_3166 = "BQ-BO", cc = "+599", lang = "nl", currency = "Q4917", country = "Niederländische Antillen" }, -- Bonaire, +599-7 Q23408 = { cont = "an", iso_3166 = "BV", cc = "", lang = "", currency = "", country = "Bouvetinsel" }, Q36004 = { cont = "oc", iso_3166 = "CC", cc = "+61891", lang = "en", currency = "Q259502", country = "Kokosinseln" }, Q25279 = { cont = "na", iso_3166 = "CW", cc = "+599-9", lang = "nl", currency = "Q522701", country = "Curaçao" }, Q31063 = { cont = "oc", iso_3166 = "CX", cc = "+61", lang = "en", currency = "Q259502", country = "Weihnachtsinsel" }, Q9648 = { cont = "sa", iso_3166 = "FK", cc = "+500", lang = "en", currency = "Q330044", country = "Falklandinseln" }, Q3769 = { cont = "sa", iso_3166 = "GF", cc = "+594", lang = "fr", currency = "Q4916", country = "Französisch-Guayana" }, Q25230 = { cont = "eu", iso_3166 = "GG", cc = "+44", lang = "en-gb", currency = "Q25224", country = "Guernsey" }, Q1410 = { cont = "eu", iso_3166 = "GI", cc = "+350", lang = "en", currency = "Q41429", country = "Gibraltar" }, Q223 = { cont = "na", iso_3166 = "GL", cc = "+299", lang = "kl", currency = "Q25417", country = "Grönland" }, Q695387 = { id = "Q223" }, -- Kommuneqarfik Sermersooq Q478813 = { id = "Q223" }, -- Kommune Kujalleq Q17012 = { cont = "na", iso_3166 = "GP", cc = "+590", lang = "fr", currency = "Q4916", country = "Guadeloupe" }, Q35086 = { cont = "an", iso_3166 = "GS", cc = "+500", lang = "en", currency = "Q25224", country = "Südgeorgien und die Südlichen Sandwichinseln" }, Q16635 = { cont = "oc", iso_3166 = "GU", cc = "+1-671", lang = "en", currency = "Q4917", country = "Guam" }, Q8646 = { cont = "as", iso_3166 = "HK", cc = "+852", lang = "zh", currency = "Q31015", country = "Hongkong" }, Q131198 = { cont = "oc", iso_3166 = "HM", cc = "", lang = "en", currency = "", country = "Heard und McDonaldinseln" }, Q9676 = { cont = "eu", iso_3166 = "IM", cc = "+44", lang = "en-gb", currency = "Q25224", country = "Isle of Man" }, Q43448 = { cont = "af", iso_3166 = "IO", cc = "+246", lang = "en", currency = "Q25224", country = "Britisches Territorium im Indischen Ozean" }, Q785 = { cont = "eu", iso_3166 = "JE", cc = "+44", lang = "en-gb", currency = "Q25224", country = "Jersey" }, Q5785 = { cont = "na", iso_3166 = "KY", cc = "+1-345", lang = "en", currency = "Q319885", country = "Kaymaninseln" }, Q737765 = { id = "Q5785" }, -- Grand Cayman Q4936407 = { id = "Q5785" }, -- Bodden Town District, Grand Cayman Q126125 = { cont = "na", iso_3166 = "MF", cc = "+590", lang = "fr", currency = "Q4916", country = "Saint-Martin" }, -- French overseas collectivity Q14773 = { cont = "as", iso_3166 = "MO", cc = "+853", lang = "zh", currency = "Q241214", country = "Macau" }, Q17054 = { cont = "na", iso_3166 = "MQ", cc = "+596", lang = "fr", currency = "Q4916", country = "Martinique" }, Q13353 = { cont = "na", iso_3166 = "MS", cc = "+1-664", lang = "en", currency = "Q26365", country = "Montserrat" }, Q33788 = { cont = "oc", iso_3166 = "NC", cc = "+687", lang = "fr", currency = "Q214393", country = "Neukaledonien" }, Q31057 = { cont = "oc", iso_3166 = "NF", cc = "+6723", lang = "en", currency = "Q259502", country = "Norfolkinsel" }, Q30971 = { cont = "oc", iso_3166 = "PF", cc = "+689", lang = "fr", currency = "Q214393", country = "Französisch-Polynesien" }, Q34617 = { cont = "na", iso_3166 = "PM", cc = "+508", lang = "fr", currency = "Q4916", country = "Saint Pierre und Miquelon" }, Q35672 = { cont = "oc", iso_3166 = "PN", cc = " +649", lang = "en", currency = "Q1472704", country = "Pitcairninseln" }, Q1183 = { cont = "na", iso_3166 = "PR", cc = "+1-787", lang = "es", currency = "Q4917", country = "Puerto Rico" }, Q485112 = { cont = "af", iso_3166 = "SO", cc = "+252", lang = "so", currency = "Q4603", country = "Puntland" }, Q17070 = { cont = "af", iso_3166 = "RE", cc = "+262", lang = "fr", currency = "Q4916", country = "Réunion" }, Q653514 = { id = "Q17070" }, -- Arrondissement Saint-Denis Q47045 = { id = "Q17070" }, -- Saint-Denis Q316887 = { id = "Q17070" }, -- Saint-Paul Q612189 = { id = "Q17070" }, -- Arrondissement Saint-Paul Q702426 = { id = "Q17070" }, -- Arrondissement Saint-Pierre Q192184 = { cont = "af", iso_3166 = "SH", cc = "+290", lang = "en", currency = "Q374453", country = "St. Helena, Ascension und Tristan da Cunha" }, -- Sonderbehandlung Tristan da Cunha, Ascension, Gough-Insel Q842829 = { cont = "eu", iso_3166 = "SJ", cc = "+47", lang = "no", currency = "Q4916", country = "Svalbard und Jan Mayen" }, Q34754 = { cont = "af", iso_3166 = "SO", cc = "+252", lang = "so", currency = "Q737384", country = "Somaliland" }, Q26273 = { cont = "na", iso_3166 = "SX", cc = "+1-721", lang = "nl", currency = "Q522701", country = "Niederländische Antillen" }, -- Sint Maarten Q18221 = { cont = "na", iso_3166 = "TC", cc = "+1-649", lang = "en", currency = "Q4917", country = "Turks- und Caicosinseln" }, Q129003 = { cont = "an", iso_3166 = "TF", cc = "+262", lang = "fr", currency = "Q4916", country = "Französische Süd- und Antarktisgebiete" }, Q36823 = { cont = "oc", iso_3166 = "TK", cc = "+690", lang ="tkl", currency = "Q1472704", country = "Tokelau" }, Q16645 = { cont = "oc", iso_3166 = "UM", cc = "", lang = "en", currency = "", country = "United States Minor Outlying Islands" }, Q25305 = { cont = "na", iso_3166 = "VG", cc = "+1-284", lang = "en", currency = "Q4917", country = "Britische Jungferninseln" }, Q11703 = { cont = "na", iso_3166 = "VI", cc = "+1-340", lang = "en", currency = "Q4917", country = "Amerikanische Jungferninseln" }, Q642481 = { id = "Q11703" }, -- Saint Croix Q849441 = { id = "Q11703" }, -- Saint John Q463937 = { id = "Q11703" }, -- Saint Thomas Q35555 = { cont = "oc", iso_3166 = "WF", cc = "+681", lang = "fr", currency = "Q214393", country = "Wallis und Futuna" }, Q17063 = { cont = "af", iso_3166 = "YT", cc = "+262", lang = "fr", currency = "Q4916", country = "Mayotte" }, -- terrae nullius Q620634 = { cont = "af", iso_3166 = "", cc = "", lang = "ar", currency = "", country = "Bir Tawil" }, -- Antarctica Q140948 = { cont = "an", iso_3166 = "", cc = "", lang = "en", currency = "", country = "Südliche Shetlandinseln" }, } } jqnhna2eyfoje2wd86cwixqlptfa1jh Modulo:Hours 828 4824 73246 72502 2026-09-24T10:44:37Z RolandUnger 168 Update 73246 Scribunto text/plain -- getting opening hours from Wikidata -- module variable and administration local hr = { moduleInterface = { suite = 'Hours', serial = '2026-09-23', item = 99600452 }, labelTable = nil, typeTables = nil } -- module import -- require( 'strict' ) local hi = require( 'Module:Hours/i18n' ) local wu = require( 'Module:Wikidata utilities' ) -- local variables local categIds = {} local showOptions = {} local function isSet( s ) return s and s ~= '' end -- insert a value into a table only if it is set local function tableInsert( tab, value ) if isSet( value ) then table.insert( tab, value ) end end -- value count for any variable local function getCount( tab ) return type( tab ) == 'table' and #tab or 0 end local function getLabelFromTables( id ) local label = hi.dateIds[ id ] if not label and hr.labelTable then label = hr.labelTable[ id ] end if not label and hr.typeTables and hr.typeTables.idTable then local item = hr.typeTables.typeTable[ hr.typeTables.idTable[ id ] ] if item then item = item.label or item.n or item local at = mw.ustring.find( item, ',' ) if at then item = mw.ustring.sub( item, 1, at - 1 ) end label = mw.text.trim( item ) end end return label end -- getting normalized time hh:dd local function getNormalizedTime( s ) local count s, count = mw.ustring.gsub( s, hi.texts.timePattern, '%1:%2' ) return ( count > 0 ) and s or nil end function hr.formatTime( s ) local t = getNormalizedTime( s ) if not t then return s end local formatStr = hi.texts.formatTime t = mw.text.split( t, ':', true ) if #t == 1 then t[ 2 ] = '00' end if hi.options.hour12 then local isAM = true local n = tonumber( t[ 1 ] ) if n > 12 then isAM = false t[ 1 ] = '' .. ( n - 12 ) end formatStr = isAM and hi.texts.formatAM or hi.texts.formatPM end s = mw.ustring.format( formatStr, mw.text.trim( t[ 1 ] ), mw.text.trim( t[ 2 ] ) ) if hi.options.leadingZero then s = s:gsub( '^(%d):', '0%1:' ) else s = s:gsub( '^0(%d):', '%1:' ) end if hi.options.removeZeros then s = s:gsub( '^(%d%d?):00', '%1' ) end return s end -- getting label for a qualifier id -- to save computing time firstly the id will fetched from Hours/i18n table -- if available, otherwise from Wikidata local function getLabelFromId( id, wikilang, fallbackLang ) if not isSet( id ) then return '' end -- from table local label = getLabelFromTables( id ) -- from Wikidata if not label and mw.wikibase.isValidEntityId( id ) then label = wu.getLabel( id, wikilang ) if not label and isSet( fallbackLang ) then label = wu.getLabel( id, fallbackLang ) if label then categIds.fallbackLabel = 1 end end if label then categIds.hoursLabelFromWikidata = 1 end end -- abbreviate labels if isSet( label ) then for i, abbr in ipairs( hi.abbr ) do label = mw.ustring.gsub( label, abbr.f, abbr.a ) end label = mw.ustring.gsub( label, '​', '' ) -- zero-width space end -- additional time formatting if isSet( label ) then if hi.months then for full, short in pairs( hi.months ) do label = mw.ustring.gsub( label, full, short ) end end label = hr.formatTime( label ) end return label or '' end local function abbreviateTimeStr( s, all, pattern, repl ) if not isSet( s ) or not isSet( pattern ) or not repl then return s or '' end if all then s = mw.ustring.gsub( s, pattern, repl ) else local matchPattern = mw.ustring.gsub( pattern, '%(%%d%)', '' ) local first, stop = mw.ustring.find( s, pattern ) if first then local second = mw.ustring.find( s, pattern, stop + 1 ) if second and mw.ustring.match( s, matchPattern ) == mw.ustring.match( s, matchPattern, stop + 1 ) then s = mw.ustring.gsub( s, pattern, repl, 1 ) end end end return s end -- getting time period string -- i: position in from and to arrays -- id: label for P3035 value local function getTimePeriod( from, to, i, id ) local result = '' if id and ( id == getLabelFromTables( hi.times.daily ) or id == getLabelFromTables( hi.times.is24_7 ) ) and from and to and from[ i ] == getLabelFromTables( hi.times.Jan1 ) and to[ i ] == getLabelFromTables( hi.times.Dec31 ) then return '' end if from and isSet( from[ i ] ) and to and isSet( to[ i ] ) then result = mw.ustring.format( hi.texts.fromTo, from[ i ], to[ i ] ) if isSet( hi.texts.hourPattern ) then result = abbreviateTimeStr( result, hi.texts.hourReplAll, hi.texts.hourPattern, hi.texts.hourRepl ) end elseif from and isSet( from[ i ] ) then result = mw.ustring.format( hi.texts.from, from[ i ] ) elseif to and isSet( to[ i ] ) then result = mw.ustring.format( hi.texts.to, to[ i ] ) end return result end local function contains( new, ar ) for i = 1, #ar do if ar[ i ] == new then return true end end return false end -- collecting all maintenance categories function hr.getCategories( formatStr, hintsTable ) local result = wu.getCategories( formatStr ) local s, tab for k, v in pairs( categIds ) do tab = hi.maintenance[ k ] or hi.maintenance.unknownError s = hi.formats.category:format( tab.category ) if hi.options.noRecommendations and hintsTable then if tab.hint and not contains( tab.hint, hintsTable ) then table.insert( hintsTable, tab.hint ) end elseif not hi.options.noRecommendations then s = s .. ( tab.hint and hi.formats.hint:format( tab.hint ) or '' ) end result = result .. s end if showOptions.demo then -- remove category links result = result:gsub( '%[%[[^%[]*%]%]', '' ) end return result end -- getting a string with listed days at which an establishment is closed local function getClosed( arr ) return ( arr and #arr > 0 ) and mw.ustring.format( hi.texts.closed or '%s', table.concat( arr, hi.texts.comma ) ) or '' end -- converting day range from Mo, Tu, We to Mo–We, and so on local function getRange( arr, minPos, maxPos ) if maxPos > 0 and minPos > 0 and maxPos > minPos then arr[ minPos ] = mw.ustring.format( hi.texts.fromTo, arr[ minPos ], arr[ maxPos ] ) for i = maxPos, minPos + 1, -1 do table.remove( arr, i ) end end end -- looking for day ranges like Mo, Tu, We and so on and converting them local function convertDayRange( arr ) local count = #arr local minPos = 0 local maxPos = 0 local value, valueMin while count > 0 do value = hi.weekdays[ arr[ count ] ] if not value then getRange( arr, minPos, maxPos ) maxPos = 0 elseif maxPos == 0 then maxPos = count valueMin = value elseif maxPos > 0 and value == valueMin - 1 then minPos = count valueMin = value else getRange( arr, minPos, maxPos ) maxPos = 0 end count = count - 1 end getRange( arr, minPos, maxPos ) end -- concating non-empty strings local function concatStrings( sep, str1, str2 ) local tab = {} tableInsert( tab, str1 ) tableInsert( tab, str2 ) return table.concat( tab, sep ) end -- add comment if not yet exists local function addComment( tab, value ) if not isSet( value ) then return elseif #tab == 0 then table.insert( tab, value ) else for i = 1, #tab, 1 do if tab[ i ] == value then break end if i == #tab then table.insert( tab, value ) end end end end -- main function for usage in Lua modules -- entity: entity id or entity table -- wikilang: content language of the wiki -- fallbackLang: optional additional language for fallback -- formatStr: optional format string for property categories -- show: table of show options (addCategories, msg, nomsg) or nil -- lastedit: dat of last edit. If false no date will be fetched -- labelTabel: additional table with Q-id label pairs function hr.getHoursFromWikidata( entity, wikilang, fallbackLang, formatStr, show, lastEdit, labelTable, typeTables ) -- collecting days at which an establishment is closed local closeDays = {} local closeDaysHelper = {} local withStateOfUse = false local function mergeDays( days ) if not days or #days == 0 then return end for i, day in ipairs( days ) do if not closeDaysHelper[ day ] then table.insert( closeDays, day ) closeDaysHelper[ day ] = '' end end end local function clearDays() closeDays = {} closeDaysHelper = {} end -- adding additional properties if an additional Q-id table is given hr.labelTable = labelTable hr.typeTables = typeTables -- preparing show options showOptions = show or {} showOptions.addCategories = hi.options.addCategories if showOptions.msg then showOptions.addCategories = true elseif showOptions.nomsg then showOptions.addCategories = false end -- format string for property categories if not isSet( formatStr ) then formatStr = hi.formats.wikidata end -- 1st step: getting statements for P3025: open days local statements = wu.getValuesWithQualifiers( entity, hi.wd.opened, nil, hi.wd.all, hi.wd.retrieved, nil, getLabelFromId, wikilang, fallbackLang ) lastEdit = wu.getLastedit( lastEdit, statements ) -- converting statements to human-readable strings local result = {} local comments, s local is24_7 = getLabelFromTables( hi.times.is24_7 ) for i, statement in ipairs( statements ) do -- opening times local times = {} local count = math.max( getCount( statement[ hi.wd.hourOpenFrom ] ), getCount( statement[ hi.wd.hourOpenTo ] ) ) if count > 0 then for j = 1, count, 1 do s = getTimePeriod( statement[ hi.wd.hourOpenFrom ], statement[ hi.wd.hourOpenTo ], j ) if isSet( s ) then table.insert( times, s ) elseif statement.value ~= is24_7 then categIds.withoutTime = 1 end end elseif statement.value ~= is24_7 then categIds.withoutTime = 1 end s = table.concat( times, hi.texts.comma ) -- comments comments = {} count = math.max( getCount( statement[ hi.wd.dayOpenFrom ] ), getCount( statement[ hi.wd.dayOpenTo ] ) ) for j = 1, count, 1 do addComment( comments, getTimePeriod( statement[ hi.wd.dayOpenFrom ], statement[ hi.wd.dayOpenTo ], j, statement.value ) ) end for j, key in ipairs( hi.wd.comments ) do if statement[ key ] then addComment( comments, table.concat( statement[ key ], hi.texts.comma ) ) end end -- concating times and comments times = {} tableInsert( times, s ) s = table.concat( comments, hi.texts.comma ) if isSet( s ) then table.insert( times, mw.ustring.format( hi.texts.parentheses, s ) ) end local item = {} tableInsert( item, table.concat( times, hi.texts.space ) ) -- close statements (P3026) as qualifiers for open days property (P3025) mergeDays( statement[ hi.wd.closed ] ) if not hi.options.clusterClosed and ( i == #statements or statements[ i ].value ~= statements[ i + 1 ].value ) then convertDayRange( closeDays ) tableInsert( item, getClosed( closeDays ) ) clearDays() end s = table.concat( item, hi.texts.comma ) -- copying each statement to result table if statement.sort2 == 1 then tableInsert( result, { value = { statement.value }, times = s } ) elseif s ~= '' then result[ #result ].times = concatStrings( hi.texts.comma, result[ #result ].times, s ) end end -- checking for duplicates for i = #result, 2, -1 do if result[ i ].times == result[ i - 1 ].times then for j, value in ipairs( result[ i ].value ) do table.insert( result[ i - 1 ].value, value ) end table.remove( result, i ) end end -- converting day range for i = 1, #result, 1 do local arr = result[ i ].value convertDayRange( arr ) result[ i ] = concatStrings( hi.texts.space, table.concat( arr, hi.texts.comma ), result[ i ].times ) end -- 2nd step: getting separated close statements (P3026) statements = wu.getValuesWithQualifiers( entity, hi.wd.closed, nil, hi.wd.commentsForClosed, hi.wd.retrieved, nil, getLabelFromId, wikilang, fallbackLang ) if #statements > 0 then lastEdit = wu.getLastedit( lastEdit, statements ) -- getting closed values local closed = {} for i, statement in ipairs( statements ) do local closedDate = {} table.insert( closedDate, statement.value ) -- getting comments comments = {} for j, key in ipairs( hi.wd.commentsForClosed ) do if statement[ key ] then addComment( comments, table.concat( statement[ key ], hi.texts.comma ) ) end end s = table.concat( comments, hi.texts.comma ) if isSet( s ) then table.insert( closedDate, mw.ustring.format( hi.texts.parentheses, s ) ) end table.insert( closed, table.concat( closedDate, hi.texts.space ) ) end mergeDays( closed ) end convertDayRange( closeDays ) tableInsert( result, getClosed( closeDays ) ) -- 3rd step: adding additional statements statements = wu.getValuesWithQualifiers( entity, hi.wd.stateOfUse, nil, {}, hi.wd.retrieved, nil, getLabelFromId, wikilang, fallbackLang ) if #statements > 0 then lastEdit = wu.getLastedit( lastEdit, statements ) for i, statement in ipairs( statements ) do if statement.value ~= '' then withStateOfUse = true table.insert( result, statement.value ) end end end -- merging all statements result = table.concat( result, hi.texts.semicolon ) -- adding maintenance categories if result ~= '' then categIds.hoursFromWikidata = 1 if withStateOfUse then categIds.isClosed = 1 end if showOptions.addCategories then result = result .. hr.getCategories( formatStr ) end end return result, lastEdit end -- invoke helper functions -- splitting show parameters local function splitAndCheck( s ) local arr = {} local err = {} if isSet( s ) then for i, v in ipairs( mw.text.split( s, ',', true ) ) do v = mw.text.trim( v ) if not hi.show[ v ] then table.insert( err, v ) else arr[ v ] = '' end end end return arr, err end -- check if pareameters are valid local function checkParameters( args ) local err = {} if not args and type( args ) ~= 'table' then return err end for k, v in pairs( args ) do if not hi.params[ k ] then table.insert( err, k ) end end return err end -- formating and concating error strings local function getErrorStr( arr, key ) if #arr == 0 then return '' end local tab = hi.maintenance[ key ] if tab then local s = hi.formats.category:format( tab.category ) .. ( tab.err and hi.formats.error:format( tab.err ) or '' ) return mw.ustring.format( s, table.concat( arr, hi.texts.comma ) ) end return key end -- main function for template #invoke calls -- id: Q id of an establishment -- format: output format like 'opened at %s' -- fallback: fallback language if labels are not available in content language function hr.getHours( frame ) local args = frame.args args.id = mw.text.trim( args.id or '' ) if not isSet( args.id ) or not mw.wikibase.isValidEntityId( args.id ) then return getErrorStr( { args.id }, 'invalidId' ) end if not isSet( args.format ) then args.format = hi.texts.format else local count args.format, count = args.format:gsub( '%%s', '%%s' ) if count ~= 1 then args.format = hi.texts.format end end args.fallback = args.fallback or '' local wikilang = mw.getContentLanguage():getCode() local paramErr = checkParameters( args ) local show, showErr = splitAndCheck( args.show ) local result = hr.getHoursFromWikidata( args.id, wikilang, args.fallback, '', show, false, nil ) if result ~= '' then result = mw.ustring.format( args.format, result ) end return result .. getErrorStr( paramErr, 'unknownParams' ) .. getErrorStr( showErr, 'unknownShowOptions' ) end return hr tke67ekooj93psdirvq231h89cf1713 Modulo:Hours/i18n 828 4825 73245 72062 2026-09-24T10:44:32Z RolandUnger 168 Update 73245 Scribunto text/plain -- This module contains wiki-language specific strings to translate. return { -- administration moduleInterface = { suite = "Hours", sub = "Hours/i18n", serial = "2026-09-23", item = 99744685 }, -- invoke call parameters params = { fallback = "", format = "", id = "", show = "" }, -- invoke-call show options show = { demo = "", msg = "", nomsg = "" }, -- Wikidata property identifiers wd = { retrieved = "P813", validInPeriod = "P1264", opened = "P3025", closed = "P3026", dayOpenFrom = "P3027", dayOpenTo = "P3028", natureOfStatement = "P5102", stateOfUse = "P5817", hourOpenFrom = "P8626", hourOpenTo = "P8627", appliesToJurisdiction = "P1001", appliesToPart = "P518", appliesToPeople = "P6001", occupation = "P106", of = "P642", use = "P366", all = { "P3026", "P3027", "P3028", "P8626", "P8627", "P1264", "P5102", "P5817", "P366", "P518", "P642", "P1001", "P6001", "P106" }, comments = { "P1264", "P5102", "P5817", "P366", "P518", "P642", "P1001", "P6001", "P106" }, commentsForClosed = { "P5102", "P5817", "P366", "P518", "P642", "P1001", "P6001", "P106" } }, -- abbreviations for month names months = { Januar = "Jan.", Februar = "Feb.", [ "März" ] = "Mär.", April = "Apr.", Mai = "Mai", Juni = "Jun.", Juli = "Jul.", August = "Aug.", September = "Sep.", Oktober = "Okt.", November = "Nov.", Dezember = "Dez." }, weekdays = { Mo = 1, Di = 2, Mi = 3, Do = 4, Fr = 5, Sa = 6, So = 7 }, -- several strings texts = { closed = "geschlossen: %s", format = "Geöffnet: %s", -- punctuation parentheses = "(%s)", space = " ", -- for instance between days and times comma = ", ", -- several dates semicolon = "; ", -- several statesments from = "ab %s", fromTo = "%s–%s", to = "bis %s", -- formatting of a single time timePattern = "^(%d%d?)[.:](%d%d?)%s*Uhr$", -- for German wiki formatTime = "%s:%s", -- or "%s:%s Uhr" etc. formatDate = "j. M Y", formatAM = "%s:%s AM", formatPM = "%s:%s PM", -- formatting of a time range hourReplAll = true, -- (formally) replace all occurrences hourPattern = "", -- empty if no replacement is requested hourRepl = "", -- hourReplAll = false, -- replace only first occurrence -- hourPattern = "(%d)%s+[aApP][mM]", -- empty if no replacement is requested -- hourRepl = "%1", }, options = { addCategories = false, clusterClosed = true, -- cluster all closing dates at the end hour12 = false, -- 12 or 24 hours mode leadingZero = false, -- add or remove zero for hours noRecommendations = true, -- prevents display of recommendation hints removeZeros = false -- remove zeros :00 for full hours }, -- format strings for mu.addMaintenance formats = { category = '[[Category:%s]]', error = ' <span class="error">%s</span>', hint = ' <span class="voy-check-recommended" style="display: none;">%s</span>', wikidata = '[[Category:Seiten, die die Wikidata-Eigenschaft %s benutzen]]' }, -- Category names maintenance = { fallbackLabel = { category = 'VCard: Öffnungszeit-Label in Englisch', hint = 'Öffnungszeit-Label in Englisch' }, hoursFromWikidata = { category = 'VCard: Öffnungszeit aus Wikidata' }, isClosed = { category = 'VCard: Einrichtung ist geschlossen', hint = 'Einrichtung ist geschlossen' }, hoursLabelFromWikidata = { category = 'VCard: Öffnungszeit-Label aus Wikidata', hint = 'Öffnungszeit-Label aus Wikidata' }, unknownError = { category = 'VCard: Öffnungszeit mit Fehler', hint = 'Öffnungszeit mit Fehler' }, withoutTime = { category = 'VCard: Öffnungszeit ohne Uhrzeit', hint = 'Öffnungszeit ohne Uhrzeit' }, -- #invoke error messages invalidId = { category = 'Hours: Ungültige Wikidata-Id', err = 'Ungültige Wikidata-Id: %s' }, unknownParams = { category = 'Hours: Unbekannter Parameter', err = 'Parameter unbekannt: %s' }, unknownShowOptions = { category = 'Hours: Unbekannter Wert für show', err = 'Wert(e) für show unbekannt: %s' } }, -- time to id conversion times = { daily = "Q26214163", Dec31 = "Q2912", is24_7 = "Q1571749", Jan1 = "Q2150" }, -- several abbreviations abbr = { { f = "[Mm]ontags?", a = "Mo" }, { f = "[Dd]ienstags?", a = "Di" }, { f = "[Mm]ittwochs?", a = "Mi" }, { f = "[Dd]onnerstags?", a = "Do" }, { f = "[Ff]reitags?", a = "Fr" }, { f = "[Ss]amstags?", a = "Sa" }, { f = "[Ss]onnabends?", a = "Sa" }, { f = "[Ss]onntags?", a = "So" }, { f = "[Ee]rste[rs]?", a = "1." }, { f = "[Zz]weite[rs]?", a = "2." }, { f = "[Dd]ritte[rs]?", a = "3." }, { f = "[Vv]ierte[rs]?", a = "4." }, { f = "[Ff]ünfte[rs]?", a = "5." } }, -- selections of date labels to prevent fetching from Wikidata dateIds = { -- Table contains common values only and is used for reduction of -- computing time. Others will be taken from Wikidata labels. -- days Q105 = "Mo", Q127 = "Di", Q128 = "Mi", Q129 = "Do", Q130 = "Fr", Q131 = "Sa", Q132 = "So", Q211391 = "Wochenende", -- use Q99528581 instead of Q211391 because it is culturally dependent Q26214163 = "täglich", -- do not remove this item because it is used in Lua script Q100274304 = "Mo–Di", Q116445783 = "Mo–Di, Do", Q118773943 = "Mo–Di, Do–Fr", Q104786164 = "Mo–Mi", Q104057082 = "Mo–Do", Q97120402 = "Mo–Fr", Q21282379 = "Mo–Sa", Q101072294 = "Di–Mi", Q100320771 = "Di–Do", Q100157387 = "Di–Fr", Q100148056 = "Di–Sa", Q99731947 = "Di–So", Q100427721 = "Mi–Do", Q99714084 = "Mi–Fr", Q100148065 = "Mi–Fr", Q118773278 = "Mi, Fr", Q31689308 = "Mi–Sa", Q116328326 = "Mi, Sa", Q65681627 = "Mi–So", Q100332183 = "Mi–So", Q99731117 = "Mi–Mo", Q106714964 = "Do–Di", Q106538987 = "Do–Fr", Q106541052 = "Do–Sa", Q100274433 = "Do–So", Q100427930 = "Fr–Sa", Q100451849 = "Fr–So", Q138501313 = "Fr, So", Q111977440 = "Fr–Mi", Q102268431 = "Sa–Mi", Q101766385 = "Sa–Do", Q99528581 = "Sa–So", Q106538981 = "So–Mo", Q111127796 = "So–Mi", Q100587968 = "So–Do", Q112703547 = "So–Fr", Q1571749 = "24/7", -- do not remove this item because it is used in Lua script Q819073 = "Werktag", Q1445650 = "Feiertag", Q1197685 = "Feiertag", Q2174956 = "Ruhetag", Q12779928 = "Arbeitstag", Q116213 = "Ferien", -- Zero-width spaces are used to keep the week-day terms and to -- prevent abbreviation Q14915111 = "Weiberfastnacht", Q15834118 = "Weiberfastnacht", Q2245828 = "Nelkensams​tag", Q1241858 = "Tulpensonn​tag", Q2085192 = "Tulpensonn​tag", Q153134 = "Rosenmon​tag", Q4845365 = "Fastnachtsdiens​tag", Q123542 = "Aschermitt​woch", Q153308 = "Laetare", Q2033651 = "Judika", Q42236 = "Palmsonn​tag", Q106333 = "Gründonners​tag", Q40317 = "Karfrei​tag", Q186206 = "Karsams​tag", Q21196 = "Ostern", Q1512337 = "Ostersonn​tag", Q209663 = "Ostermon​tag", Q14795170 = "Ostermon​tag", Q14916781 = "Osterdiens​tag", Q51638 = "Christi Himmelfahrt", Q39864 = "Pfingsten", Q2512993 = "Pfingstmon​tag", Q14795386 = "Pfingstdiens​tag", Q152395 = "Fronleichnam", Q2304773 = "Erntedankfest", Q2913791 = "Thanksgiving", Q59833 = "Totensonn​tag", Q19809 = "Weihnachten", Q10901070 = "Tag der Arbeit", Q10274 = "Dashahara", Q464458 = "Fest des Fastenbrechens", Q10259 = "Holi", Q131772 = "Chinesisches Neujahrsfest", Q718778 = "Qingming-Fest", Q1145566 = "Chinesischer Nationalfeiertag", Q1622041 = "Hochsaison", Q99932986 = "Nebensaison", Q1777301 = "Normalzeit", Q36669 = "Sommerzeit", Q107376657 = "Januar bis März", Q107376740 = "März bis Oktober", Q121914265 = "März bis November", Q100157218 = "April bis Oktober", Q107376636 = "April bis Dezember", Q107359921 = "Mai bis Oktober", Q107376754 = "November bis Februar", Q100157227 = "November bis März", Q1312 = "Frühling", Q1313 = "Sommer", Q1314 = "Herbst", Q1311 = "Winter", Q100320775 = "erstes Wochenende im Monat", Q23034736 = "erster Montag im Monat", Q51119351 = "zweiter Montag im Monat", Q51119371 = "dritter Montag im Monat", Q51119385 = "vierter Montag im Monat", Q51119411 = "fünfter Montag im Monat", Q51120546 = "letzter Montag im Monat", Q51119341 = "erster Donnerstag im Monat", Q51119361 = "zweiter Donnerstag im Monat", Q51119378 = "dritter Donnerstag im Monat", Q51119395 = "vierter Donnerstag im Monat", Q51119421 = "fünfter Donnerstag im Monat", Q51120559 = "letzter Donnerstag im Monat", Q51119344 = "erster Freitag im Monat", Q51119363 = "zweiter Freitag im Monat", Q51119381 = "dritter Freitag im Monat", Q51119398 = "vierter Freitag im Monat", Q51119425 = "fünfter Freitag im Monat", Q51120563 = "letzter Freitag im Monat", Q51119345 = "erster Samstag im Monat", Q51119367 = "zweiter Samstag im Monat", Q51119382 = "dritter Samstag im Monat", Q51119402 = "vierter Samstag im Monat", Q51119427 = "fünfter Samstag im Monat", Q51120565 = "letzter Samstag im Monat", Q51119350 = "erster Sonntag im Monat", Q51119369 = "zweiter Sonntag im Monat", Q51119383 = "dritter Sonntag im Monat", Q51119404 = "vierter Sonntag im Monat", Q51119429 = "fünfter Sonntag im Monat", Q51120567 = "letzter Sonntag im Monat", Q108 = "Jan.", Q2150 = "1. Jan.", -- do not remove this item because it is used in Lua script Q196627 = "1. Jan.", Q2151 = "2. Jan.", Q2156 = "3. Jan.", Q2221 = "6. Jan.", Q1139536 = "26. Jan.", -- India Republic Day Q2289 = "31. Jan.", Q109 = "Feb.", Q2312 = "1. Feb.", Q2332 = "14. Feb.", Q2334 = "15. Feb.", Q2362 = "28. Feb.", Q2364 = "29. Feb.", Q110 = "Mär.", Q2393 = "1. Mär.", Q2404 = "14. Mär.", Q2403 = "15. Mär.", Q2457 = "27. Mär.", Q2458 = "28. Mär.", Q2461 = "31. Mär.", Q118 = "Apr.", Q2510 = "1. Apr.", Q2505 = "7. Apr.", Q2504 = "9. Apr.", Q2500 = "14. Apr.", Q2497 = "15. Apr.", Q2536 = "30. Apr.", Q119 = "Mai", Q2544 = "1. Mai", Q47499 = "1. Mai", Q2574 = "16. Mai", Q2591 = "31. Mai", Q120 = "Jun.", Q2625 = "1. Jun.", Q2657 = "30. Jun.", Q121 = "Jul.", Q2700 = "1. Jul.", Q2715 = "31. Jul.", Q122 = "Aug.", Q2788 = "1. Aug.", Q2774 = "15. Aug.", Q162691 = "15. Aug.", -- Assumption of Mary Q56106 = "15. Aug.", -- Independence Day, India Q2830 = "31. Aug.", Q123 = "Sep.", Q2859 = "1. Sep.", Q2846 = "15. Sep.", Q2881 = "30. Sep.", Q124 = "Okt.", Q2913 = "1. Okt.", Q2932 = "2. Okt.", Q2931 = "3. Okt.", Q157582 = "3. Okt.", -- German Unity Day Q2919 = "15. Okt.", Q2963 = "16. Okt.", Q2949 = "31. Okt.", Q153093 = "31. Okt.", -- Reformation Day Q125 = "Nov.", Q2997 = "1. Nov.", Q2996 = "2. Nov.", Q2995 = "3. Nov.", Q2982 = "15. Nov.", Q3029 = "16. Nov.", Q3015 = "30. Nov.", Q126 = "Dez.", Q2297 = "1. Dez.", Q2451 = "19. Dez.", Q2705 = "24. Dez.", Q106010 = "24. Dez.", Q2745 = "25. Dez.", Q2703710 = "25. Dez.", -- Christmas Day Q2761 = "26. Dez.", Q15113728 = "26. Dez.", Q2800 = "27. Dez.", Q2832 = "28. Dez.", Q2862 = "29. Dez.", Q2901 = "30. Dez.", Q2912 = "31. Dez.", -- do not remove this item because it is used in Lua script Q11269 = "31. Dez.", -- points of time Q573 = "Tag", Q575 = "Nacht", Q7722 = "Morgen", Q986787 = "Vormittag", Q283102 = "Nachmittag", Q7725 = "Abend", Q193294 = "Sonnenaufgang", Q166564 = "Sonnenuntergang", Q36402 = "0:00 Uhr", Q55812411 = "0:00 Uhr", Q55449532 = "0:30 Uhr", Q41618001 = "1:00 Uhr", Q55517345 = "1:00 Uhr", Q55518450 = "1:30 Uhr", Q41618006 = "2:00 Uhr", Q55521280 = "2:00 Uhr", Q55524996 = "2:30 Uhr", Q41618076 = "3:00 Uhr", Q55527754 = "3:00 Uhr", Q55560170 = "3:30 Uhr", Q41618081 = "4:00 Uhr", Q55810628 = "4:00 Uhr", Q55810646 = "4:15 Uhr", Q55811293 = "4:30 Uhr", Q55811308 = "4:45 Uhr", Q41618165 = "5:00 Uhr", Q55810695 = "5:00 Uhr", Q55810711 = "5:15 Uhr", Q55811314 = "5:30 Uhr", Q55811331 = "5:45 Uhr", Q41618168 = "6:00 Uhr", Q55810762 = "6:00 Uhr", Q55810778 = "6:15 Uhr", Q55810795 = "6:30 Uhr", Q55811354 = "6:45 Uhr", Q41618172 = "7:00 Uhr", Q55811431 = "7:00 Uhr", Q55810845 = "7:15 Uhr", Q55810863 = "7:30 Uhr", Q55811437 = "7:45 Uhr", Q41618176 = "8:00 Uhr", Q55811455 = "8:00 Uhr", Q55810913 = "8:15 Uhr", Q55810929 = "8:30 Uhr", Q55810940 = "8:40 Uhr", Q55812499 = "8:45 Uhr", Q41618181 = "9:00 Uhr", Q55811413 = "9:00 Uhr", Q55811478 = "9:15 Uhr", Q55810994 = "9:30 Uhr", Q55811012 = "9:45 Uhr", Q41618185 = "10:00 Uhr", Q55811483 = "10:00 Uhr", Q55811062 = "10:30 Uhr", Q41618189 = "11:00 Uhr", Q55811097 = "11:00 Uhr", Q55811133 = "11:30 Uhr", Q168182 = "12:00 Uhr", Q55812521 = "12:00 Uhr", Q55811197 = "12:30 Uhr", Q47454201 = "12:30 Uhr", Q55811213 = "12:45 Uhr", Q41618345 = "13:00 Uhr", Q55811230 = "13:00 Uhr", Q55812556 = "13:15 Uhr", Q55811580 = "13:30 Uhr", Q55811277 = "13:45 Uhr", Q41620570 = "14:00 Uhr", Q55811610 = "14:00 Uhr", Q55811657 = "14:15 Uhr", Q55811674 = "14:30 Uhr", Q55811761 = "14:45 Uhr", Q41620574 = "15:00 Uhr", Q55811778 = "15:00 Uhr", Q55811726 = "15:15 Uhr", Q55811745 = "15:30 Uhr", Q55811798 = "15:45 Uhr", Q41620578 = "16:00 Uhr", Q55812393 = "16:00 Uhr", Q55812563 = "16:15 Uhr", Q55811847 = "16:30 Uhr", Q55811864 = "16:45 Uhr", Q41620582 = "17:00 Uhr", Q55811883 = "17:00 Uhr", Q55812585 = "17:15 Uhr", Q55812595 = "17:25 Uhr", Q55813015 = "17:30 Uhr", Q55811932 = "17:45 Uhr", Q41620584 = "18:00 Uhr", Q55811949 = "18:00 Uhr", Q55813021 = "18:15 Uhr", Q55813038 = "18:30 Uhr", Q55812002 = "18:45 Uhr", Q41620587 = "19:00 Uhr", Q55812019 = "19:00 Uhr", Q55812659 = "19:30 Uhr", Q41620591 = "20:00 Uhr", Q55812694 = "20:00 Uhr", Q55812122 = "20:30 Uhr", Q41620593 = "21:00 Uhr", Q55812716 = "21:00 Uhr", Q55812732 = "21:15 Uhr", Q55812192 = "21:30 Uhr", Q55812210 = "21:45 Uhr", Q41620595 = "22:00 Uhr", Q55813122 = "22:00 Uhr", Q55812769 = "22:30 Uhr", Q44529925 = "23:00 Uhr", Q55812301 = "23:00 Uhr", Q55813170 = "23:30 Uhr", Q55812370 = "24:00 Uhr", -- for P1264 Q41662 = "Ramadan", -- for P5102 Q29509043 = "offiziell", Q29509080 = "inoffiziell", Q132555 = "de jure", Q712144 = "de facto", Q28962310 = "kaum", Q28962312 = "häufig", Q18603603 = "möglich", Q30230067 = "möglich", Q53737447 = "ursprünglich", Q18912752 = "umstritten", Q28831311 = "unbestätigt", Q24025284 = "ändert sich gelegentlich", Q4895105 = "Interim", Q18122778 = "vermutlich", Q32188232 = "angeblich", Q1520777 = "gewiss", Q5727902 = "ungefähr", Q56644435 = "wahrscheinlich", -- for P5817 -- empty strings are not displayed Q29415466 = "", -- "aktiv" Q29933838 = "außer Betrieb", Q56651571 = "außer Betrieb", Q111802839 = "außer Betrieb", Q104664889 = "dauerhaft geschlossen", Q55570821 = "", -- "für die Öffentlichkeit zugänglich" Q55570340 = "für die Öffentlichkeit geschlossen", Q55654238 = "", -- "in Benutzung" Q811683 = "im Bau befindlich", Q12377751 = "im Bau befindlich", Q109551035 = "", -- "in eingeschränkter Benutzung" Q63065035 = "", -- "nicht erhalten" Q11639308 = "stillgelegt", Q55653430 = "zeitweilig geschlossen", Q63187954 = "laufende Sanierung", Q4989906 = "", -- "Denkmal" Q2086116 = "", -- "Nachnutzung" Q110713763 = "noch nicht in Benutzung" } } 2g5epjtqvwj96gbl2mad56g4yd8f93n Orienta Riviero 0 5538 73251 71324 2026-09-24T11:39:27Z Tiguliano 53 73251 wikitext text/x-wiki {{Informkesto subregiono | nomo = Orienta Riviero | flago = | flagograndeco = | lando = Italio | regiono = Ligurio | bildo = Dosiero:Liguria 5Terre1 tango7174.jpg | bildotitolo = La vilaĝo Porto Venere | situo = | ĉefurbo = | areo = | loĝantaro = | horzono = }} [[File:Costa da Camogli a Genova.jpg|thumb|Marbordo de la Orienta Riviero inter Camogli kaj Ĝenovo, vidita de la monteto malantaŭ Camogli]] La '''Orienta Riviero''' de Ligurio, (itale: Riviera di Levante; "Rivêa de Levante" en la liguria) estas la marborda parto de Ligurio, kiu, etendiĝas de la urbo Ĝenovo ĝis la regiona limo kun Toskanio. [[File:Moneglia costa rocciosa.jpg|thumb|La roka marbordo en la proksimaĵoj de [[Moneglia]]]] [[File:Baia del silenzio panorama-Sestri Levante.JPG|thumb|[[Sestri Levante]] kaj la golfo de Tigulio]] Turismo sendube reprezentas la ĉefan ekonomian agadon de la Riviero, danke al la milda klimato kaj la natura beleco de la lokoj. Krom somera turismo, dediĉita ĉefe al la uzo de strandoj kaj marbordoj, estas ankaŭ ekskursa kaj kultura turismo distribuata tra la monatoj de la jaro, precipe en lokoj kiel [[Cinque Terre]], [[Porto Venere]] kaj [[Portofino]]. [[Framura]], [[Moneglia]], [[Montemarcello]], [[Vernazza]] kaj [[Tellaro (Lerici) | Tellaro]] estas la marbordaj vilaĝoj de la orienta marbordo kiuj estas parto de la listo de [[La plej belaj vilaĝoj en Italio | plej belaj vilaĝoj en Italio]]. Ankaŭ la turismo de familioj kun infanoj gravegas. La travideblaj akvoj de Ligurio, tiel plenaj de vivo, estas idealaj por sperti aventurojn kun masko kaj spirtubo: infanoj povas ĝui naĝi observante malgrandajn fiŝojn, krabojn, stelojn, mar-erinacojn kaj polpojn. La "Riviera di Levante" povas esti dividita en malsamajn distriktojn, de okcidento ĝis oriento: * Golfo Paradiso, de [[Bogliasco]] al [[Monte di Portofino]] * Golfo de Tigullio, de Monte di Portofino al [[Sestri Levante]] * Golfetoj de "Levante", de Sestri Levante ĝis Punta Mesco * [[Cinque Terre]], de Punta Mesco ĝis la Insulo [[Palmaria]] * Golfo de la Poetoj * Sarzana marbordo, de la enfluejo de la rivero Magra ĝis la limo kun [[Toskanio]] === Urboj === *[[Genova]] - Ĉefurbo de la regiono kaj elstara mara urbo, iama mara respubliko. *[[Camogli]] - Tipa ĉemara vilaĝo, turisma centro konata pro sia ja marinatejo kaj buntaj konstruaĵoj ĉe la marbordo. Ĝi estas parto de la Regiona Natura Parko Portofino. *[[Chiavari]] - Mezepoka vilaĝo *[[La Spezia]] - Turisma urbo, sed ankaŭ ŝipkonstruaĵoj kaj grava mararmea haveno. *[[Porto Venere]] - Malgranda ĉemara vilaĝo fronte al la insuloj [[Palmaria]], Tino kaj Tinetto *[[Portofino]] - Fama famul-feriejo kun bela haveneto. *[[Rapallo]] - Turisma urbo ĉe la maro kun longa tradicio de gastamo, (iam precipe de reĝoj kaj nobeloj, kiuj pasigis siajn feriojn tie). *[[Santa Margherita Ligure]] - Je Kelkaj kilometroj de Imperia kaj Sanremo. *[[Sestri Levante]] - === Aliaj vizitindaj lokoj === [[File:Palmaria and Tino.jpg|thumb|la insuloj [[Palmaria]] kaj [[Isola del Tino|Tino]], viditaj de la plaĝo de [[San Terenzo]]]] *[[Area marina protetta Cinque Terre]] *[[Parco nazionale delle Cinque Terre]] *[[Area naturale marina protetta Portofino]] *[[Parco naturale regionale di Portofino]] *[[Parco naturale regionale di Montemarcello-Magra-Vara]] *[[Parco naturale regionale di Porto Venere]] - Komprenas la komunumoj de Porto Venere kaj la insuloj [[Palmaria]], [[Isola del Tino|Tino]] kaj [[Tinetto]] == Kiel alveni == Grava turisma regiono en norda Italio, la Rivera di Ponente estas facile atingebla plurmaniere. === Aŭte === Estas du aŭtovojoj sur la teritorio de la Orienta Bordo. * Aŭtovojo A12, trairas la marbordon konektante [[Ĝenovo]]n al [[Livorno]]. * Aŭtovojo A15, ligas [[Parmo]] al [[La Spezia]] transirante la malaltan Taro-valon, la [[Lunigiana]] areo kaj alvenante en la malalta valo de rivero Magra. La ŝtata vojo 1 Aurelia laŭiras la tutan Riviera. En la sekcio inter Ĝenovo kaj [[Sestri Levante]] ĝi fluas sur marnivelo aŭ, por mallongaj streĉoj, duonvoje laŭ la marbordo. De [[Riva Trigoso]] al La Spezia la vojo foriras de la marbordo kaj grimpas supren tra la montetoj sekvante la naturajn levojn kaj mallevojn de la areo. De La Spezia al la toskana limo ĝi rekomencas ebenan iron. === Per ŝipo === [[File:Porto di Lavagna.JPG|thumb|left|La haveno de [[Lavagna]]]] [[File:Portofino_-_2016-06-02_-_View_from_Chiesa_San_Giorgio_-_3284.jpg|thumb|[[Portofino]]]] Ekzistas multaj turisthavenoj kaj havenetoj sur la marbordo. === Per trajno === La Riviera di Levante estas trairita de la fervoja linio [[Ĝenovo]] - [[La Spezia]]. {{-}} {{Parto de|Ligurio}} gwswesmj5xh7fjhe5b5sa404hhaamc6