diff --git a/.github/workflows/deploy_pietervdvn.yml b/.github/workflows/deploy_pietervdvn.yml index f787b077d5..36d4ebc269 100644 --- a/.github/workflows/deploy_pietervdvn.yml +++ b/.github/workflows/deploy_pietervdvn.yml @@ -3,7 +3,8 @@ on: push: branches: - develop - - feature/svelte + - feature/* + - theme/* jobs: build: runs-on: ubuntu-latest diff --git a/UI/BigComponents/AddNewMarker.ts b/UI/BigComponents/AddNewMarker.ts index 6c3fe93d6e..ab2c727301 100644 --- a/UI/BigComponents/AddNewMarker.ts +++ b/UI/BigComponents/AddNewMarker.ts @@ -24,13 +24,17 @@ export default class AddNewMarker extends Combine { for (const preset of filteredLayer.layerDef.presets) { const tags = TagUtils.KVtoProperties(preset.tags) const icon = layer.mapRendering[0] - .GenerateLeafletStyle(new UIEventSource(tags), false) + .GenerateLeafletStyle(new UIEventSource(tags), false, { + noSize: true, + }) .html.SetClass("block relative") .SetStyle("width: 42px; height: 42px;") icons.push(icon) if (last === undefined) { last = layer.mapRendering[0] - .GenerateLeafletStyle(new UIEventSource(tags), false) + .GenerateLeafletStyle(new UIEventSource(tags), false, { + noSize: true, + }) .html.SetClass("block relative") .SetStyle("width: 42px; height: 42px;") } diff --git a/UI/Input/LocationInput.ts b/UI/Input/LocationInput.ts index 56f20f4451..f52a392434 100644 --- a/UI/Input/LocationInput.ts +++ b/UI/Input/LocationInput.ts @@ -176,13 +176,13 @@ export default class LocationInput loc.lat, ]) if (min === undefined) { - min = nearestPointOnLine + min = { ...nearestPointOnLine } matchedWay = feature continue } if (min.properties.dist > nearestPointOnLine.properties.dist) { - min = nearestPointOnLine + min = { ...nearestPointOnLine } matchedWay = feature } } catch (e) { @@ -208,6 +208,10 @@ export default class LocationInput } } min.properties = options?.snappedPointTags ?? min.properties + min.properties = { + ...min.properties, + _referencing_ways: JSON.stringify([matchedWay.properties.id]), + } self.snappedOnto.setData(matchedWay) return min }, diff --git a/assets/layers/map/map.json b/assets/layers/map/map.json index 47844271a7..4cb7a9dda0 100644 --- a/assets/layers/map/map.json +++ b/assets/layers/map/map.json @@ -44,6 +44,7 @@ "tagRenderings": [ "images", { + "labels": ["map"], "question": { "en": "On which data is this map based?", "nl": "Op welke data is deze kaart gebaseerd?", @@ -87,6 +88,7 @@ }, { "id": "map-attribution", + "labels": ["map"], "question": { "en": "Is the OpenStreetMap-attribution given?", "nl": "Is de attributie voor OpenStreetMap aanwezig?", @@ -272,4 +274,4 @@ } } ] -} \ No newline at end of file +} diff --git a/assets/tagRenderings/questions.json b/assets/tagRenderings/questions.json index 78c71f3a9d..dcd0ce41cf 100644 --- a/assets/tagRenderings/questions.json +++ b/assets/tagRenderings/questions.json @@ -1936,5 +1936,54 @@ "ca": "El nom de la xarxa és {internet_access:ssid}", "pl": "Nazwa sieci to {internet_access:ssid}" } + }, + "luminous_or_lit": { + "question": { + "en": "Is this object lit or does it emit light?" + }, + "mappings": [ + { + "if": { + "and": [ + "lit=yes", + "luminous=yes" + ] + }, + "then": { + "en":"This object both emits light and is lighted by an external light source" + } + }, + { + "if": + "luminous=yes" + , + "then": { + "en": "This object emits light" + }, + "addExtraTags": [ + "lit=no" + ] + }, + { + "if": + "lit=yes" + , + "then":{"en": "This object is lit externally, e.g. by a spotlight or other lights"}, + "addExtraTags": [ + "luminous=no" + ] + }, + { + "if": { + "and": [ + "lit=no", + "luminous=no" + ] + }, + "then": { + "en": "This object does not emit light and is not lighted by externally" + } + } + ] } } diff --git a/assets/themes/advertising/AdvertisingColumn_001.jpg b/assets/themes/advertising/AdvertisingColumn_001.jpg new file mode 100644 index 0000000000..71b69cbe8c Binary files /dev/null and b/assets/themes/advertising/AdvertisingColumn_001.jpg differ diff --git a/assets/themes/advertising/AdvertisingColumn_003.jpg b/assets/themes/advertising/AdvertisingColumn_003.jpg new file mode 100644 index 0000000000..8efb383acf Binary files /dev/null and b/assets/themes/advertising/AdvertisingColumn_003.jpg differ diff --git a/assets/themes/advertising/AdvertisingTotem_003.jpg b/assets/themes/advertising/AdvertisingTotem_003.jpg new file mode 100644 index 0000000000..62cde80c06 Binary files /dev/null and b/assets/themes/advertising/AdvertisingTotem_003.jpg differ diff --git a/assets/themes/advertising/AdvertisingTotem_004.jpg b/assets/themes/advertising/AdvertisingTotem_004.jpg new file mode 100644 index 0000000000..7a15b44944 Binary files /dev/null and b/assets/themes/advertising/AdvertisingTotem_004.jpg differ diff --git a/assets/themes/advertising/Advertising_flag.jpg b/assets/themes/advertising/Advertising_flag.jpg new file mode 100644 index 0000000000..3b315e4b3a Binary files /dev/null and b/assets/themes/advertising/Advertising_flag.jpg differ diff --git a/assets/themes/advertising/Aircraft_Sculpture.jpg b/assets/themes/advertising/Aircraft_Sculpture.jpg new file mode 100644 index 0000000000..b9bfc6386f Binary files /dev/null and b/assets/themes/advertising/Aircraft_Sculpture.jpg differ diff --git a/assets/themes/advertising/BS.JPG b/assets/themes/advertising/BS.JPG new file mode 100644 index 0000000000..58d79e516c Binary files /dev/null and b/assets/themes/advertising/BS.JPG differ diff --git a/assets/themes/advertising/Capitol_wall.jpg b/assets/themes/advertising/Capitol_wall.jpg new file mode 100644 index 0000000000..2c137771ab Binary files /dev/null and b/assets/themes/advertising/Capitol_wall.jpg differ diff --git a/assets/themes/advertising/City-Light-Poster.jpg b/assets/themes/advertising/City-Light-Poster.jpg new file mode 100644 index 0000000000..b0c1c86cf5 Binary files /dev/null and b/assets/themes/advertising/City-Light-Poster.jpg differ diff --git a/assets/themes/advertising/FGV_Founding.jpg b/assets/themes/advertising/FGV_Founding.jpg new file mode 100644 index 0000000000..e57a4bb92f Binary files /dev/null and b/assets/themes/advertising/FGV_Founding.jpg differ diff --git a/assets/themes/advertising/JR_Central.jpg b/assets/themes/advertising/JR_Central.jpg new file mode 100644 index 0000000000..8e07fb47b8 Binary files /dev/null and b/assets/themes/advertising/JR_Central.jpg differ diff --git a/assets/themes/advertising/KFC_Billboard.jpg b/assets/themes/advertising/KFC_Billboard.jpg new file mode 100644 index 0000000000..dd489eceaa Binary files /dev/null and b/assets/themes/advertising/KFC_Billboard.jpg differ diff --git a/assets/themes/advertising/LIDL_Billboard.jpg b/assets/themes/advertising/LIDL_Billboard.jpg new file mode 100644 index 0000000000..60985764b3 Binary files /dev/null and b/assets/themes/advertising/LIDL_Billboard.jpg differ diff --git a/assets/themes/advertising/Lidl_totem.jpg b/assets/themes/advertising/Lidl_totem.jpg new file mode 100644 index 0000000000..0d65058eb3 Binary files /dev/null and b/assets/themes/advertising/Lidl_totem.jpg differ diff --git a/assets/themes/advertising/Mug.jpg b/assets/themes/advertising/Mug.jpg new file mode 100644 index 0000000000..31ab48ccd5 Binary files /dev/null and b/assets/themes/advertising/Mug.jpg differ diff --git a/assets/themes/advertising/Mupi_Alcoi.jpg b/assets/themes/advertising/Mupi_Alcoi.jpg new file mode 100644 index 0000000000..1b5db60502 Binary files /dev/null and b/assets/themes/advertising/Mupi_Alcoi.jpg differ diff --git a/assets/themes/advertising/Mupi_spain.jpg b/assets/themes/advertising/Mupi_spain.jpg new file mode 100644 index 0000000000..44400a69a4 Binary files /dev/null and b/assets/themes/advertising/Mupi_spain.jpg differ diff --git a/assets/themes/advertising/Repsol_Billboard.jpg b/assets/themes/advertising/Repsol_Billboard.jpg new file mode 100644 index 0000000000..0fd1ad9c7d Binary files /dev/null and b/assets/themes/advertising/Repsol_Billboard.jpg differ diff --git a/assets/themes/advertising/Screen_poster_box.jpg b/assets/themes/advertising/Screen_poster_box.jpg new file mode 100644 index 0000000000..3465db0dc9 Binary files /dev/null and b/assets/themes/advertising/Screen_poster_box.jpg differ diff --git a/assets/themes/advertising/Small_Board.jpg b/assets/themes/advertising/Small_Board.jpg new file mode 100644 index 0000000000..3c0a66f030 Binary files /dev/null and b/assets/themes/advertising/Small_Board.jpg differ diff --git a/assets/themes/advertising/Subway_screen.jpg b/assets/themes/advertising/Subway_screen.jpg new file mode 100644 index 0000000000..cdc9bff448 Binary files /dev/null and b/assets/themes/advertising/Subway_screen.jpg differ diff --git a/assets/themes/advertising/TV_media.jpg b/assets/themes/advertising/TV_media.jpg new file mode 100644 index 0000000000..f5a07f9a2a Binary files /dev/null and b/assets/themes/advertising/TV_media.jpg differ diff --git a/assets/themes/advertising/Times square.jpg b/assets/themes/advertising/Times square.jpg new file mode 100644 index 0000000000..a5445cf15a Binary files /dev/null and b/assets/themes/advertising/Times square.jpg differ diff --git a/assets/themes/advertising/Waitrose_sign.jpg b/assets/themes/advertising/Waitrose_sign.jpg new file mode 100644 index 0000000000..f0099c9d61 Binary files /dev/null and b/assets/themes/advertising/Waitrose_sign.jpg differ diff --git a/assets/themes/advertising/advertising.json b/assets/themes/advertising/advertising.json new file mode 100644 index 0000000000..71cc5c2fd8 --- /dev/null +++ b/assets/themes/advertising/advertising.json @@ -0,0 +1,1038 @@ +{ + "id": "advertising", + "credits": "Offsel", + "title": { + "en": "Open Advertising Map", + "ca": "Mapa obert de publicitat", + "es": "Mapa abierto de publicidad" + }, + "shortDescription": { + "ca": "On puc trobar elements publicitaris?", + "es": "Dónde puedo encontrar elementos publicitarios?", + "en": "Where I can find advertising features?" + }, + "description": { + "ca": "Alguna vegada t'has preguntat quanta publictat hi ha als nostres carrers i carreteres? Amb aquest mapa podràs trobar i afegir informació de tots els elements publictaris que t'hi trobes pel carrer", + "es": "¿Alguna vez te has preguntado cuanta publicidad hay en nuestras calles y carreteras? Con este mapa podrás encontrar y añadir información de todos los elementos publicitarios que te encuentres por la calle", + "en": "Have you ever wondered how many advertising there are in our streets and roads? With this map you could find and add information about all the advertising features that you can find on the street" + }, + "maintainer": "Offsel", + "icon": "./assets/themes/advertising/poster_box.svg", + "version": "2023_01_29", + "startLat": 0, + "startLon": 0, + "startZoom": 1, + "widenFactor": 0.01, + "layers": [ + { + "id": "advertising", + "name": { + "ca": "Publicitat", + "es": "Publicidad", + "en": "Advertise" + }, + "minzoom": 15, + "source": { + "osmTags": "advertising~*" + }, + "title": { + "render": { + "*": "{advertising}" + }, + "mappings": [ + { + "if": { + "and": [ + "advertising=billboard" + ] + }, + "then": { + "ca": "Tanca publicitària", + "es": "Valla publicitaria", + "en": "Billboard" + } + }, + { + "if": { + "and": [ + "advertising=board" + ] + }, + "then": { + "ca": "Tauló d'anuncis", + "es": "Tablon de anuncios", + "en": "Board" + } + }, + { + "if": { + "and": [ + "advertising=poster_box" + ] + }, + "then": { + "ca": "Mupi", + "es": "Mupi", + "en": "Poster Box" + } + }, + { + "if": { + "and": [ + "advertising=column" + ] + }, + "then": { + "ca": "Columna", + "es": "Columna", + "en": "Column" + } + }, + { + "if": { + "and": [ + "advertising=flag" + ] + }, + "then": { + "ca": "Bandera", + "es": "Bandera", + "en": "Flag" + } + }, + { + "if": { + "and": [ + "advertising=screen" + ] + }, + "then": { + "ca": "Pantalla", + "es": "Pantalla", + "en": "Screen" + } + }, + { + "if": { + "and": [ + "advertising=sculpture" + ] + }, + "then": { + "ca": "Esculptura", + "es": "Escultura", + "en": "Sculpture" + } + }, + { + "if": { + "and": [ + "advertising=sign" + ] + }, + "then": { + "ca": "Cartell", + "es": "Cartel", + "en": "Sign" + } + }, + { + "if": { + "and": [ + "advertising=tarp" + ] + }, + "then": { + "ca": "Lona", + "es": "Lona", + "en": "Tarp" + } + }, + { + "if": { + "and": [ + "advertising=totem" + ] + }, + "then": { + "ca": "Tòtem", + "es": "Tótem", + "en": "Totem" + } + }, + { + "if": { + "and": [ + "advertising=wall_painting" + ] + }, + "then": { + "ca": "Paret Pintada", + "es": "Pared Pintada", + "en": "Wall painting" + } + } + ] + }, + "description": { + "ca": "Completarem les dades dels elements publicitaris amb referència, operador i il·luminació", + "es": "Completaremos los datos de los elementos publicitarios con referencia, operador y iluminación", + "en": "We will complete data from advertising features with reference, operator and lit" + }, + "tagRenderings": [ + "images", + { + "id": "type", + "render": { + "ca": "Açò és un {advertising}", + "es": "Esto es un {advertising}", + "en": "This is a {advertising}" + }, + "question": { + "ca": "Quin tipus d'element publicitari és aquest?", + "es": "¿Qué tipo de elemento publicitario es?", + "en": "Which type of advertising feature is this?" + }, + "freeform": { + "key": "advertising" + }, + "mappings": [ + { + "if": { + "and": [ + "advertising=billboard" + ] + }, + "then": { + "ca": "Açò és una tanca publicitària", + "es": "Esto es una valla publicitaria", + "en": "This is a billboard" + }, + "icon": { + "path": "./assets/themes/advertising/billboard.svg", + "class": "medium" + } + }, + { + "if": { + "and": [ + "advertising=board" + ] + }, + "then": { + "ca": "Açò és un tauló d'anunis", + "es": "Esto es un tablón de anuncios", + "en": "This is a board" + }, + "icon": { + "path": "./assets/themes/advertising/board.svg", + "class": "medium" + } + }, + { + "if": { + "and": [ + "advertising=column" + ] + }, + "then": { + "ca": "Açò és una columna", + "es": "Esto es una columna", + "en": "This is a column" + }, + "icon": { + "path": "./assets/themes/advertising/column.svg", + "class": "medium" + } + }, + { + "if": { + "and": [ + "advertising=flag" + ] + }, + "then": { + "ca": "Açò és una bandera", + "es": "Esto es una bndera", + "en": "This is a flag" + }, + "icon": { + "path": "./assets/themes/advertising/flag.svg", + "class": "medium" + } + }, + { + "if": { + "and": [ + "advertising=poster_box" + ] + }, + "then": { + "ca": "Açò és un mupi", + "es": "Esto es un mupi", + "en": "This is a poster Box" + }, + "icon": { + "path": "./assets/themes/advertising/poster_box.svg", + "class": "medium" + } + }, + { + "if": { + "and": [ + "advertising=screen" + ] + }, + "then": { + "ca": "Açò és una pantalla", + "es": "Esto es una pantalla", + "en": "This is a screen" + }, + "icon": { + "path": "./assets/themes/advertising/screen.svg", + "class": "medium" + } + }, + { + "if": { + "and": [ + "advertising=sculpture" + ] + }, + "then": { + "ca": "Açò és una esculptura", + "es": "Esto es una escultura", + "en": "This is a sculpture" + }, + "icon": { + "path": "./assets/themes/advertising/sculpture.svg", + "class": "medium" + } + }, + { + "if": { + "and": [ + "advertising=sign" + ] + }, + "then": { + "ca": "Açò és un cartell", + "es": "Esto es un cartel", + "en": "This is a sign" + }, + "icon": { + "path": "./assets/themes/advertising/sign.svg", + "class": "medium" + } + }, + { + "if": { + "and": [ + "advertising=tarp" + ] + }, + "then": { + "ca": "Açò és una lona", + "es": "Esto es una lona", + "en": "This is a tarp (a weatherproof piece of textile with an advertising message)" + }, + "icon": { + "path": "./assets/themes/advertising/tarp.svg", + "class": "medium" + } + }, + { + "if": { + "and": [ + "advertising=totem" + ] + }, + "then": { + "ca": "Açò és un tòtem", + "es": "Esto es un tótem", + "en": "This is a totem" + }, + "icon": { + "path": "./assets/themes/advertising/totem.svg", + "class": "medium" + } + }, + { + "if": { + "and": [ + "advertising=wall_painting" + ] + }, + "then": { + "ca": "Açò és una paret pintada", + "es": "Esto es una pared pintada", + "en": "This is a wall painting" + }, + "icon": { + "path": "./assets/themes/advertising/wall_painting.svg", + "class": "medium" + } + } + ] + }, + { + "id": "animated", + "question": { + "ca": "Com canvien els anuncis d'aquest element?", + "es": "¿Como cambian los anuncios de este elemento?", + "en": "Does this advertisement cycle through multiple messages?" + }, + "condition": { + "#": "Screens are _always_ animated; flags, tarps, and wall_paintings cannot be animated; signs can be anything so we don't make guesses", + "and": [ + "advertising!=screen", + "advertising!=flag", + "advertising!=tarp", + "advertising!=wall_painting", + "advertising!=sign" + ] + }, + "mappings": [ + { + "if": "animated=no", + "then": { + "ca": "Estàtic, sense animació", + "es": "Estático, sin animación", + "en": "Static, always shows the same message" + } + }, + { + "if": "animated=digital_display", + "then": { + "en": "This object has a built-in digital display to show prices or some other message" + }, + "hideInAnswer": { + "and": [ + "advertising!=billboard", + "advertising!=poster_box", + "advertising!=totem", + "advertising!=column" + ] + } + }, + { + "if": "animated=travision_blades", + "then": { + "ca": "Trivision", + "es": "Trivision", + "en": "Trivision - the billboard consists of many triangular prisms which regularly rotate" + }, + "icon": { + "class": "large", + "path": "./assets/themes/advertising/trivision.svg" + }, + "#": "Only applicable to billboards", + "hideInAnswer": "advertising!=billboard" + + }, + { + "if": "animated=winding_posters", + "then": { + "ca": "Cartells Rotatius", + "es": "Cartells Rotatius", + "en": "Scrolling posters" + }, + "hideInAnswer": { + "and": [ + "advertising!=poster_box", + "advertising!=column" + ] + } + }, + { + "if": "animated=revolving", + "then": { + "ca": "Rota sobre si mateix", + "es": "Rota sobre si mismo", + "en": "Rotates on itself" + }, + "hideInAnswer": { + "and": [ + "advertising!=totem", + "advertising!=column", + "advertising!=poster_box" + ] + } + } + ] + }, + { + "builtin": "luminous_or_lit", + "override": { + "+mappings": [ + { + "if": "luminous=neon", + "then": { + "en": "This is a neon-tube light" + }, + "hideInAnswer": "advertising!=sign" + } + ], + "condition": { + "#": "A screen is always luminous", + "and": [ + "advertising!=screen" + ] + } + } + }, + { + "id": "operator", + "render": { + "ca": "L'operador és {operator}", + "es": "El operador es {operator}", + "en": "Operated by {operator}" + }, + "question": { + "ca": "Qui opera aquest element?", + "es": "¿Quien opera este elemento?", + "en": "Who operates this feature?" + }, + "freeform": { + "addExtraTags": [], + "key": "operator" + } + }, + { + "id": "message_type", + "question": { + "ca": "Quin tipus de missatge es mostra?", + "es": "Que tipo de mensaje se muestra?", + "en": "What kind of message is shown?" + }, + "mappings": [ + { + "if": "message=commercial", + "ifnot": "message=", + "then": { + "ca": "Missatge comercial", + "es": "Mensaje comercial", + "en": "Commercial message" + } + }, + { + "if": "message=local", + "ifnot": "message=", + "then": { + "ca": "Informació municipal", + "es": "Información municipal", + "en": "Local information" + } + }, + { + "if": "message=safety", + "ifnot": "message=", + "then": { + "ca": "Informació de seguretat", + "es": "Información de seguridad", + "en": "Securty information" + }, + "hideInAnswer": { + "and": [ + "advertising=flag" + ] + } + }, + { + "if": "message=political", + "ifnot": "message=", + "then": { + "ca": "Publicitat electoral", + "es": "Publicidad electoral", + "en": "Electoral advertising" + } + }, + { + "if": "message=showbiz", + "ifnot": "message=", + "then": { + "ca": "Informació sobre teatres, concerts, ...", + "es": "Información sobre teatros, conciertos, ...", + "en": "Inormation related to theatre, concerts, ..." + }, + "hideInAnswer": { + "and": [ + "advertising=flag" + ] + } + }, + { + "if": "message=non_profit", + "ifnot": "message=", + "then": { + "ca": "Missatge d'organitzacions sense ànim de lucre", + "es": "Mensaje de organizaciones sin ánimo de lucro", + "en": "Message from non-profit organizations" + } + }, + { + "if": "message=opinion", + "ifnot": "message=", + "then": { + "ca": "Per a expressar la teua opinió", + "es": "Para expresar tu opinión", + "en": "To expres your opinion" + }, + "hideInAnswer": { + "or": [ + "advertising=flag", + "advertising=screen" + ] + } + }, + { + "if": "message=religion", + "ifnot": "message=", + "then": { + "ca": "Missatge religiós", + "es": "Mensaje religioso", + "en": "Religious message" + } + }, + { + "if": "message=funding", + "ifnot": "message=", + "then": { + "ca": "Cartell de financiació", + "es": "Cartel de financiación", + "en": "Funding sign" + }, + "hideInAnswer": { + "or": [ + "advertising=flag", + "advertising=column" + ] + } + }, + { + "if": "information=map", + "ifnot": "information=", + "then": { + "en": "A map" + } + } + ], + "multiAnswer": true + }, + { + "id": "Sides", + "condition": { + "and": [ + "_referencing_ways=", + "advertising=poster_box" + ] + }, + "question": { + "ca": "Per quants costats pots veure publicitat?", + "es": "¿Por cuantos lados puedes ver publicidad?", + "en": "From how many sides you can watch advertisments?" + }, + "mappings": [ + { + "if": "sides=1", + "then": { + "en": "This poster box has advertisements on a single side" + } + }, + { + "if": "sides=2", + "then": { + "en": "This poster box has advertisements on both sides" + } + } + ] + }, + { + "id": "ref", + "render": { + "ca": "El número de referència és {ref}", + "es": "El número de referencia es {ref}", + "en": "Reference number is {ref}" + }, + "question": { + "ca": "Quin és el número de refèrencia?", + "es": "¿Cual es el número de referencia?", + "en": "Wich is the reference number?" + }, + "freeform": { + "key": "ref" + }, + "condition": { + "and": ["advertising!=sign"] + } + } + ], + "mapRendering": [ + { + "location": [ + "point", + "centroid" + ], + "icon": { + "render": "./assets/themes/advertising/sign.svg", + "mappings": [ + { + "if": { + "or": [ + "advertising=billboard" + ] + }, + "then": "./assets/themes/advertising/billboard.svg" + }, + { + "if": "advertising=board", + "then": "./assets/themes/advertising/board.svg" + }, + { + "if": "advertising=column", + "then": "./assets/themes/advertising/column.svg" + }, + { + "if": "advertising=flag", + "then": "./assets/themes/advertising/flag.svg" + }, + { + "if": { + "and": [ + "advertising=poster_box", + "_referencing_ways=[\"way/-1\"]" + ] + }, + "then": "brick_wall_square;./assets/themes/advertising/poster_box_no_support.svg" + }, + { + "if": { + "and": [ + "advertising=poster_box", + "_referencing_ways~*" + ] + }, + "then": "./assets/themes/advertising/poster_box_no_support.svg" + }, + { + "if": "advertising=poster_box", + "then": "./assets/themes/advertising/poster_box.svg" + }, + { + "if": { + "and": [ + "advertising=screen", + "_referencing_ways=[\"way/-1\"]" + ] + }, + "then": "brick_wall_square;./assets/themes/advertising/screen_no_support.svg" + }, + { + "if": { + "and": [ + "advertising=screen", + "_referencing_ways~*" + ] + }, + "then": "./assets/themes/advertising/screen_no_support.svg" + }, + { + "if": "advertising=screen", + "then": "./assets/themes/advertising/screen.svg" + }, + { + "if": "advertising=sculpture", + "then": "./assets/themes/advertising/sculpture.svg" + }, + { + "if": { + "and": [ + "advertising=sign", + "_referencing_ways=[\"way/-1\"]" + ] + }, + "then": "brick_wall_square;./assets/themes/advertising/sign.svg" + }, + { + "if": "advertising=sign", + "then": "./assets/themes/advertising/sign.svg" + }, + { + "if": "advertising=tarp", + "then": "./assets/themes/advertising/tarp.svg" + }, + { + "if": "advertising=totem", + "then": "./assets/themes/advertising/totem.svg" + }, + { + "if": "advertising=wall_painting", + "then": "./assets/themes/advertising/wall_painting.svg" + } + ] + }, + "iconSize": { + "render": "40,40,bottom", + "mappings": [ + { + "if": "_referencing_ways~*", + "then": "40,40,center" + }, + { + "if": "advertising=flag", + "then": "60,60,bottom" + }, + { + "if": "advertising=sculpture", + "then": "50,50,bottom" + } + ] + } + }, + { + "width": { + "render": "8" + }, + "color": { + "render": "#00f" + } + } + ], + "allowMove": { + "enableImproveAccuracy": true, + "enableRelocation": false + }, + "deletion": true, + "presets": [ + { + "tags": [ + "advertising=billboard" + ], + "title": { + "en": "a billboard", + "ca": "una tanca publicitària", + "es": "una valla publicitària" + }, + "description": { + "en": "A large outdoor advertising structure, typically found in high-traffic areas such as alongside busy roads", + "ca": "Les tanques publicitàries normalment són de gran tamany i estan situades prop de les carreteres", + "es": "Las vallas publicitarias normalment son de gran tamanó y están situadas cerca de las carreteras" + }, + "exampleImages": [ + "./assets/themes/advertising/KFC_Billboard.jpg", + "./assets/themes/advertising/LIDL_Billboard.jpg", + "./assets/themes/advertising/Repsol_Billboard.jpg" + ] + }, + { + "tags": [ + "advertising=poster_box" + ], + "title": { + "en": "a freestanding poster box" + }, + "exampleImages": [ + "./assets/themes/advertising/Mupi_spain.jpg", + "./assets/themes/advertising/Mupi_Alcoi.jpg" + ] + }, + { + "tags": [ + "advertising=poster_box" + ], + "title": { + "en": "a poster box mounted on a wall" + }, + "preciseInput": { + "snapToLayer": "walls_and_buildings" + } + }, + { + "tags": [ + "advertising=board" + ], + "title": { + "ca": "un tauló d'anunis", + "es": "un tablón de anuncios", + "en": "a billboard" + }, + "description": { + "en": "Small billboard for neighbourhood advertising, generally intended for pedestrians", + "es": "Un pequeño tablón de anuncios para anuncios del vecindario, normalmente destinado a peatones", + "ca": "Un xicotet tauló d'anuncics per a anuncis del veïnat, normalment destitat a peatons" + }, + "exampleImages": [ + "./assets/themes/advertising/local_Board.jpg", + "./assets/themes/advertising/FGV_Founding.jpg", + "./assets/themes/advertising/Small_Board.jpg" + ] + }, + { + "tags": [ + "advertising=column" + ], + "title": { + "ca": "una columna", + "es": "una columna", + "en": "a column" + }, + "description": { + "en": "A cylindrical outdoor structure which shows advertisements", + "es": "Una estructura cilíndrica exterior que muestra publicidad", + "ca": "Una extructura cilíndica exterior que mostra publicitat" + }, + "exampleImages": [ + "./assets/themes/advertising/AdvertisingColumn_001.jpg", + "./assets/themes/advertising/AdvertisingColumn_003.jpg" + ] + }, + { + "tags": [ + "advertising=flag", + "man_made=pole" + ], + "title": { + "ca": "una bandera", + "es": "una bandera", + "en": "a flag" + }, + "exampleImages": [ + "./assets/themes/advertising/Advertising_flag.jpg", + "./assets/themes/advertising/JR_Central.jpg" + ] + }, + { + "tags": [ + "advertising=screen" + ], + "title": { + "ca": "una pantalla", + "es": "una pantalla", + "en": "a screen" + }, + "exampleImages": [ + "./assets/themes/advertising/Screen_poster_box.jpg", + "./assets/themes/advertising/City-Light-Poster.jpg" + ] + }, + { + "tags": [ + "advertising=screen" + ], + "title": { + "ca": "una patalla sobre una paret", + "es": "una pantalla sobre una pared", + "en": "a screen mounted on a wall" + }, + "preciseInput": { + "preferredBackground": "map", + "snapToLayer": "walls_and_buildings", + "maxSnapDistance": 5 + }, + "exampleImages": [ + "./assets/themes/advertising/Subway_screen.jpg", + "./assets/themes/advertising/TV_media.jpg", + "./assets/themes/advertising/Times square.jpg" + ] + }, + + { + "tags": [ + "advertising=tarp" + ], + "title": { + "ca": "una lona", + "es": "una lona", + "en": "a tarp" + }, + "description": { + "en": "A piece of waterproof textile with a printed message, permanently anchored on a wall" + }, + "preciseInput": { + "preferredBackground": "map", + "snapToLayer": "walls_and_buildings", + "maxSnapDistance": 5 + }, + "exampleImages": [ + "./assets/themes/advertising/tarp_feder.jpg", + "./assets/themes/advertising/tarp_madrid.jpg" + ] + }, + { + "tags": [ + "advertising=totem" + ], + "title": { + "ca": "un tòtem", + "es": "un tótem", + "en": "a totem" + }, + "exampleImages": [ + "./assets/themes/advertising/AdvertisingTotem_004.jpg", + "./assets/themes/advertising/AdvertisingTotem_003.jpg", + "./assets/themes/advertising/Lidl_totem.jpg" + ] + }, + { + "tags": [ + "advertising=sign" + ], + "title": { + "ca": "un lletrer", + "es": "un lletrer", + "en": "a sign" + }, + "preciseInput": { + "preferredBackground": "map", + "snapToLayer": "walls_and_buildings", + "maxSnapDistance": 5 + }, + "description": { + "en": "Used for advertising signs, neon signs, logos & institutional entrance signs", + "es": "Se utiliza para carteles publicitarios, letreros de neón, logotipos y carteles en entradas institucionales", + "ca": "S'utilitza per a cartells publicitaris, retols de neó, logotips i cartells en entrades institucionals" + }, + "exampleImages": [ + "./assets/themes/advertising/Waitrose_sign.jpg", + "./assets/themes/advertising/sign_EOI.jpg", + "./assets/themes/advertising/farma_sign.jpg" + ] + }, + { + "tags": [ + "advertising=sculpture" + ], + "title": { + "ca": "una escupltura", + "es": "una escultura", + "en": "a sculpture" + }, + "exampleImages": [ + "./assets/themes/advertising/Aircraft_Sculpture.jpg", + "./assets/themes/advertising/Mug.jpg", + "./assets/themes/advertising/BS.JPG" + ] + }, + { + "tags": [ + "advertising=wall_painting" + ], + "title": { + "ca": "una paret pintada", + "es": "una pared pintada", + "en": "a wall painting" + }, + "preciseInput": { + "preferredBackground": "map", + "snapToLayer": "walls_and_buildings", + "maxSnapDistance": 5 + }, + "exampleImages": [ + "./assets/themes/advertising/Capitol_wall.jpg", + "./assets/themes/advertising/clarke_wall.jpg" + ] + } + ] + } + ] +} diff --git a/assets/themes/advertising/billboard.svg b/assets/themes/advertising/billboard.svg new file mode 100644 index 0000000000..b98e6e834c --- /dev/null +++ b/assets/themes/advertising/billboard.svg @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/assets/themes/advertising/board.svg b/assets/themes/advertising/board.svg new file mode 100644 index 0000000000..917190ea8e --- /dev/null +++ b/assets/themes/advertising/board.svg @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/themes/advertising/clarke_wall.jpg b/assets/themes/advertising/clarke_wall.jpg new file mode 100644 index 0000000000..4e031a1908 Binary files /dev/null and b/assets/themes/advertising/clarke_wall.jpg differ diff --git a/assets/themes/advertising/column.svg b/assets/themes/advertising/column.svg new file mode 100644 index 0000000000..f1ff90bf2c --- /dev/null +++ b/assets/themes/advertising/column.svg @@ -0,0 +1,285 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/themes/advertising/farma_sign.jpg b/assets/themes/advertising/farma_sign.jpg new file mode 100644 index 0000000000..62360c3f09 Binary files /dev/null and b/assets/themes/advertising/farma_sign.jpg differ diff --git a/assets/themes/advertising/flag.svg b/assets/themes/advertising/flag.svg new file mode 100644 index 0000000000..668b69d975 --- /dev/null +++ b/assets/themes/advertising/flag.svg @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + diff --git a/assets/themes/advertising/icon.svg b/assets/themes/advertising/icon.svg new file mode 100644 index 0000000000..c5864208b8 --- /dev/null +++ b/assets/themes/advertising/icon.svg @@ -0,0 +1,83 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/assets/themes/advertising/license_info.json b/assets/themes/advertising/license_info.json new file mode 100644 index 0000000000..b813d045e2 --- /dev/null +++ b/assets/themes/advertising/license_info.json @@ -0,0 +1,484 @@ +[ + { + "path": "AdvertisingColumn_001.jpg", + "license": "CC BY-SA 4.0", + "authors": [ + "Segnargs" + ], + "sources": [ + "https://wiki.openstreetmap.org/wiki/File:AdvertisingColumn_001.jpg" + ] + }, + { + "path": "AdvertisingColumn_003.jpg", + "license": "CC BY-SA 4.0", + "authors": [ + "Segnargsed" + ], + "sources": [ + "https://wiki.openstreetmap.org/wiki/File:AdvertisingColumn_003.jpg#file" + ] + }, + { + "path": "AdvertisingTotem_003.jpg", + "license": "CC BY-SA 4.0", + "authors": [ + "Segnargsed" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:AdvertisingTotem_003.jpg" + ] + }, + { + "path": "AdvertisingTotem_004.jpg", + "license": "CC BY-SA 4.0", + "authors": [ + "Segnargsed" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:AdvertisingTotem_004.jpg" + ] + }, + { + "path": "Advertising_flag.jpg", + "license": "CC BY-SA 2.0", + "authors": [ + "Sandy B" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:Advertising_flags_-_geograph.org.uk_-_2433864.jpg" + ] + }, + { + "path": "Aircraft_Sculpture.jpg", + "license": "CC BY-SA 2.0", + "authors": [ + "Rod Waddington" + ], + "sources": [ + "https://wiki.openstreetmap.org/wiki/File:Aircraft_Sculpture-Advertisment-Restaurant_Jimma_Ethiopia.jpg" + ] + }, + { + "path": "BS.JPG", + "license": "CC BY-SA 4.0", + "authors": [ + "TeWeBs" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:BS_Schraubenschluessel.JPG" + ] + }, + { + "path": "Capitol_wall.jpg", + "license": "CC BY-SA 4.0", + "authors": [ + "Artaxerxes" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:Advertising_mural_on_wall_of_Capitol_Stationers_65_Main_Street_downtown_Montpelier_VT_August_2017.jpg" + ] + }, + { + "path": "City-Light-Poster.jpg", + "license": "CC-BY SA 4.0", + "authors": [ + "Bärwinkel, Klaus" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:City-Light-Poster_Mittelstra%C3%9Fe.jpg" + ] + }, + { + "path": "FGV_Founding.jpg", + "license": "CC BY-SA 4.0", + "authors": [ + "Paunofu" + ], + "sources": [ + "https://imgur.com/epyuPXs" + ] + }, + { + "path": "JR_Central.jpg", + "license": "CC BY-SA 4.0", + "authors": [ + "ジェーアール東海一口株主" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:JR_Central_corporate_flag_by_Nagoya_Station.jpg" + ] + }, + { + "path": "KFC_Billboard.jpg", + "license": "CC BY 4.0", + "authors": [ + "Paunofu" + ], + "sources": [ + "https://imgur.com/2xJaUXd" + ] + }, + { + "path": "LIDL_Billboard.jpg", + "license": "CC BY-SA 4.0", + "authors": [ + "Paul Williams" + ], + "sources": [ + "https://archive.org/details/northfleet-2021-05-30/PXL_20210530_175057096.jpg" + ] + }, + { + "path": "Lidl_totem.jpg", + "license": "CC BY-SA 4.0", + "authors": [ + "Donald Trung" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:Lidl_informational_sign,_Hesel_(2019)_01.jpg" + ] + }, + { + "path": "Mug.jpg", + "license": "Public Domain", + "authors": [ + "Carol M. Highsmith" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:The_Frostop_mug_advertising_sign_outside_%22The_Drive_In%22_restaurant_in_Taylors_Falls,_Minnesota.jpg" + ] + }, + { + "path": "Mupi_Alcoi.jpg", + "license": "CC-BY 4.0", + "authors": [ + "Paunofu" + ], + "sources": [ + "https://imgur.com/4Q3glWH" + ] + }, + { + "path": "Mupi_spain.jpg", + "license": "CC0 1.0", + "authors": [ + "Jusotil_1943" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:Mupi_(42556631491).jpg" + ] + }, + { + "path": "Repsol_Billboard.jpg", + "license": "CC BY 4.0", + "authors": [ + "Paunofu" + ], + "sources": [ + "https://imgur.com/MwvK0jc" + ] + }, + { + "path": "Screen_poster_box.jpg", + "license": "CC BY-SA 4.0", + "authors": [ + "T. Segonds" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:Screen_poster_box.jpg" + ] + }, + { + "path": "Small_Board.jpg", + "license": "CC BY-SA 4.0", + "authors": [ + "Segnargsed" + ], + "sources": [ + "https://wiki.openstreetmap.org/wiki/File:AdvertisingBoard_001.jpg" + ] + }, + { + "path": "Subway_screen.jpg", + "license": "CC BY 2.0", + "authors": [ + "Metropolitan Transportation Authority of the State of New York" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:Subway_Station_Digital_Advertising_Screens_(13251000543).jpg" + ] + }, + { + "path": "TV_media.jpg", + "license": "CC BY 3.0", + "authors": [ + "Roger Carvell" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:TV_media_advertising_at_London_Victoria_station._-_panoramio.jpg" + ] + }, + { + "path": "Times square.jpg", + "license": "CC BY-SA 4.0", + "authors": [ + "chensiyuan" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:1_times_square_night_2013.jpg" + ] + }, + { + "path": "Waitrose_sign.jpg", + "license": "CC BY-SA 2.0", + "authors": [ + "Geographer" + ], + "sources": [ + "https://www.geograph.org.uk/photo/4343364" + ] + }, + { + "path": "billboard.svg", + "license": "CC BY-SA 3.0", + "authors": [ + "Barnes38" + ], + "sources": [ + "https://wiki.openstreetmap.org/wiki/File:Billboard_trunk.svg" + ] + }, + { + "path": "board.svg", + "license": "CC BY-SA 3.0", + "authors": [ + "Barnes38" + ], + "sources": [ + "https://wiki.openstreetmap.org/wiki/File:Board.svg" + ] + }, + { + "path": "clarke_wall.jpg", + "license": "CC BY-SA 2.0", + "authors": [ + "Albert Bridge" + ], + "sources": [ + "https://www.geograph.org.uk/photo/2478313" + ] + }, + { + "path": "column.svg", + "license": "CC BY-SA 3.0", + "authors": [ + "Barnes38" + ], + "sources": [ + "https://wiki.openstreetmap.org/wiki/File:Column.svg" + ] + }, + { + "path": "farma_sign.jpg", + "license": "CC-BY-SA 4.0", + "authors": [ + "paunofu" + ], + "sources": [ + "https://imgur.com/bGF0kdd" + ] + }, + { + "path": "flag.svg", + "license": "CC BY-SA 3.0", + "authors": [ + "Barnes38", + "Ash Crow", + "Happy-melon", + "Aris Katsaris", + "Pietervdvn" + ], + "sources": [ + "https://wiki.openstreetmap.org/wiki/File:Column.svg", + "https://commons.wikimedia.org/wiki/File:Flag_icon_darkblue.svg" + ] + }, + { + "path": "icon.svg", + "license": "CC-BY-SA 4.0", + "authors": [ + "Panier Avide" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:Advertising_icon.svg" + ] + }, + { + "path": "local_Board.jpg", + "license": "CC-BY-SA 4.0", + "authors": [ + "Segnargsed" + ], + "sources": [ + "https://wiki.openstreetmap.org/wiki/File:ReservedAdvertisingUnit_008.jpg" + ] + }, + { + "path": "newspaper_kiosk.svg", + "license": "CC BY-SA 3.0", + "authors": [ + "Barnes38" + ], + "sources": [ + "https://wiki.openstreetmap.org/wiki/File:Newspaper_kiosk_3.svg" + ] + }, + { + "path": "poster_box.svg", + "license": "CC BY-SA 3.0", + "authors": [ + "Barnes38" + ], + "sources": [ + "https://wiki.openstreetmap.org/wiki/File:Poster_box.svg" + ] + }, + { + "path": "poster_box_no_support.svg", + "license": "CC BY-SA 3.0", + "authors": [ + "Barnes38" + ], + "sources": [ + "https://wiki.openstreetmap.org/wiki/File:Poster_box.svg" + ] + }, + { + "path": "screen alcoi.jpg", + "license": "CC-BY 4.0", + "authors": [ + "paunofu" + ], + "sources": [ + "https://imgur.com/HKsRycm" + ] + }, + { + "path": "screen.svg", + "license": "CC-BY-SA 4.0", + "authors": [ + "Barnes38", + "Pietervdvn" + ], + "sources": [ + "https://wiki.openstreetmap.org/wiki/File:Poster_box.svg" + ] + }, + { + "path": "screen_no_support.svg", + "license": "CC-BY-SA 4.0", + "authors": [ + "Barnes38", + "Pietervdvn" + ], + "sources": [ + "https://wiki.openstreetmap.org/wiki/File:Poster_box.svg" + ] + }, + { + "path": "sculpture.svg", + "license": "CC BY 3.0", + "authors": [ + "Nathaniel Smith", + "Pietervdvn" + ], + "sources": [ + "https://wiki.openstreetmap.org/wiki/File:Column.svg", + "https://commons.wikimedia.org/wiki/File:Sculpture_(NP100738).svg" + ] + }, + { + "path": "sign.svg", + "license": "CC BY-SA 3.0", + "authors": [ + "Barnes38" + ], + "sources": [ + "https://wiki.openstreetmap.org/wiki/File:Totem.svg" + ] + }, + { + "path": "sign_EOI.jpg", + "license": "CC-BY-SA 4.0", + "authors": [ + "paunofu" + ], + "sources": [ + "https://imgur.com/8D0BKNq" + ] + }, + { + "path": "tarp.svg", + "license": "CC BY-SA 3.0", + "authors": [ + "Barnes38", + "Pietervdvn" + ], + "sources": [ + "https://wiki.openstreetmap.org/wiki/File:Billboard_trunk.svg" + ] + }, + { + "path": "tarp_feder.jpg", + "license": "CC-BY SA 4.0", + "authors": [ + "paunofu" + ], + "sources": [ + "https://imgur.com/Gc3Tk41" + ] + }, + { + "path": "tarp_madrid.jpg", + "license": "CC BY 2.0", + "authors": [ + "Rogotan" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:Lona_(3741637137).jpg" + ] + }, + { + "path": "totem.svg", + "license": "CC BY-SA 3.0", + "authors": [ + "Barnes38" + ], + "sources": [ + "https://wiki.openstreetmap.org/wiki/File:Totem.svg" + ] + }, + { + "path": "trivision.svg", + "license": "CC BY-SA 3.0", + "authors": [ + "pietervdvn", + "Louis Dawson (via the Noun Project)" + ], + "sources": [ + "https://thenounproject.com/icon/rotating-arrow-184486/" + ] + }, + { + "path": "wall_painting.svg", + "license": "CC BY-SA 3.0", + "authors": [ + "Barnes38", + "Pietervdvn" + ], + "sources": [ + "https://wiki.openstreetmap.org/wiki/File:Billboard_trunk.svg" + ] + } +] \ No newline at end of file diff --git a/assets/themes/advertising/local_Board.jpg b/assets/themes/advertising/local_Board.jpg new file mode 100644 index 0000000000..eb204c0a44 Binary files /dev/null and b/assets/themes/advertising/local_Board.jpg differ diff --git a/assets/themes/advertising/newspaper_kiosk.svg b/assets/themes/advertising/newspaper_kiosk.svg new file mode 100644 index 0000000000..debaea46b5 --- /dev/null +++ b/assets/themes/advertising/newspaper_kiosk.svg @@ -0,0 +1,408 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/themes/advertising/poster_box.svg b/assets/themes/advertising/poster_box.svg new file mode 100644 index 0000000000..472d6e9175 --- /dev/null +++ b/assets/themes/advertising/poster_box.svg @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/themes/advertising/poster_box_no_support.svg b/assets/themes/advertising/poster_box_no_support.svg new file mode 100644 index 0000000000..cd3e701e1a --- /dev/null +++ b/assets/themes/advertising/poster_box_no_support.svg @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/themes/advertising/screen alcoi.jpg b/assets/themes/advertising/screen alcoi.jpg new file mode 100644 index 0000000000..46d2b17103 Binary files /dev/null and b/assets/themes/advertising/screen alcoi.jpg differ diff --git a/assets/themes/advertising/screen.svg b/assets/themes/advertising/screen.svg new file mode 100644 index 0000000000..40b676f5e1 --- /dev/null +++ b/assets/themes/advertising/screen.svg @@ -0,0 +1,127 @@ + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/themes/advertising/screen_no_support.svg b/assets/themes/advertising/screen_no_support.svg new file mode 100644 index 0000000000..120390f95a --- /dev/null +++ b/assets/themes/advertising/screen_no_support.svg @@ -0,0 +1,151 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/themes/advertising/sculpture.svg b/assets/themes/advertising/sculpture.svg new file mode 100644 index 0000000000..ec063bc4e6 --- /dev/null +++ b/assets/themes/advertising/sculpture.svg @@ -0,0 +1,64 @@ + + diff --git a/assets/themes/advertising/sign.svg b/assets/themes/advertising/sign.svg new file mode 100644 index 0000000000..23478cce29 --- /dev/null +++ b/assets/themes/advertising/sign.svg @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + diff --git a/assets/themes/advertising/sign_EOI.jpg b/assets/themes/advertising/sign_EOI.jpg new file mode 100644 index 0000000000..405a7b6742 Binary files /dev/null and b/assets/themes/advertising/sign_EOI.jpg differ diff --git a/assets/themes/advertising/tarp.svg b/assets/themes/advertising/tarp.svg new file mode 100644 index 0000000000..8349c1b59a --- /dev/null +++ b/assets/themes/advertising/tarp.svg @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/themes/advertising/tarp_feder.jpg b/assets/themes/advertising/tarp_feder.jpg new file mode 100644 index 0000000000..ef42dfe924 Binary files /dev/null and b/assets/themes/advertising/tarp_feder.jpg differ diff --git a/assets/themes/advertising/tarp_madrid.jpg b/assets/themes/advertising/tarp_madrid.jpg new file mode 100644 index 0000000000..470739156e Binary files /dev/null and b/assets/themes/advertising/tarp_madrid.jpg differ diff --git a/assets/themes/advertising/totem.svg b/assets/themes/advertising/totem.svg new file mode 100644 index 0000000000..2e97da890f --- /dev/null +++ b/assets/themes/advertising/totem.svg @@ -0,0 +1,283 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/themes/advertising/trivision.svg b/assets/themes/advertising/trivision.svg new file mode 100644 index 0000000000..6b13551ba7 --- /dev/null +++ b/assets/themes/advertising/trivision.svg @@ -0,0 +1,383 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/themes/advertising/wall_painting.svg b/assets/themes/advertising/wall_painting.svg new file mode 100644 index 0000000000..fbf462c648 --- /dev/null +++ b/assets/themes/advertising/wall_painting.svg @@ -0,0 +1,967 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/themes/mapcomplete-changes/mapcomplete-changes.json b/assets/themes/mapcomplete-changes/mapcomplete-changes.json index b6b71d1cbb..98962045af 100644 --- a/assets/themes/mapcomplete-changes/mapcomplete-changes.json +++ b/assets/themes/mapcomplete-changes/mapcomplete-changes.json @@ -114,6 +114,10 @@ "icon": { "render": "teardrop:#00cc00", "mappings": [ + { + "if": "theme=advertising", + "then": "./assets/themes/advertising/icon.svg" + }, { "if": "theme=aed", "then": "./assets/themes/aed/aed.svg" diff --git a/scripts/generateLayerOverview.ts b/scripts/generateLayerOverview.ts index f98e3fac46..d18e437db3 100644 --- a/scripts/generateLayerOverview.ts +++ b/scripts/generateLayerOverview.ts @@ -21,15 +21,19 @@ import { PrepareLayer } from "../Models/ThemeConfig/Conversion/PrepareLayer" import { PrepareTheme } from "../Models/ThemeConfig/Conversion/PrepareTheme" import { DesugaringContext } from "../Models/ThemeConfig/Conversion/Conversion" import { Utils } from "../Utils" +import Script from "./Script" import { AllSharedLayers } from "../Customizations/AllSharedLayers" // This scripts scans 'assets/layers/*.json' for layer definition files and 'assets/themes/*.json' for theme definition files. // It spits out an overview of those to be used to load them -class LayerOverviewUtils { +class LayerOverviewUtils extends Script { public static readonly layerPath = "./assets/generated/layers/" public static readonly themePath = "./assets/generated/themes/" + constructor() { + super("Reviews and generates the compiled themes") + } private static publicLayerIdsFrom(themefiles: LayoutConfigJson[]): Set { const publicThemes = [].concat(...themefiles.filter((th) => !th.hideFromOverview)) @@ -225,7 +229,7 @@ class LayerOverviewUtils { } } - main(args: string[]) { + async main(args: string[]) { if (fakedom === undefined) { throw "Fakedom not initialized" } @@ -505,4 +509,4 @@ class LayerOverviewUtils { } } -new LayerOverviewUtils().main(process.argv) +new LayerOverviewUtils().run() diff --git a/scripts/generateLicenseInfo.ts b/scripts/generateLicenseInfo.ts index 2ee17be968..7980e5493b 100644 --- a/scripts/generateLicenseInfo.ts +++ b/scripts/generateLicenseInfo.ts @@ -1,326 +1,352 @@ import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "fs" import SmallLicense from "../Models/smallLicense" import ScriptUtils from "./ScriptUtils" +import Script from "./Script" const prompt = require("prompt-sync")() -function validateLicenseInfo(l: SmallLicense) { - l.sources.map((s) => { - try { - return new URL(s) - } catch (e) { - throw "Could not parse URL " + s + " for a license for " + l.path + " due to " + e - } - }) -} -/** - * Sweeps the entire 'assets/' (except assets/generated) directory for image files and any 'license_info.json'-file. - * Checks that the license info is included for each of them and generates a compiles license_info.json for those - */ - -function generateLicenseInfos(paths: string[]): SmallLicense[] { - const licenses = [] - for (const path of paths) { - try { - const parsed = JSON.parse(readFileSync(path, { encoding: "utf8" })) - if (Array.isArray(parsed)) { - const l: SmallLicense[] = parsed - for (const smallLicens of l) { - smallLicens.path = - path.substring(0, path.length - "license_info.json".length) + - smallLicens.path - } - licenses.push(...l) - } else { - const smallLicens: SmallLicense = parsed - smallLicens.path = path.substring(0, 1 + path.lastIndexOf("/")) + smallLicens.path - licenses.push(smallLicens) - } - } catch (e) { - console.error("Error: ", e, "while handling", path) - } - } - return licenses -} - -function missingLicenseInfos(licenseInfos: SmallLicense[], allIcons: string[]) { - const missing = [] - - const knownPaths = new Set() - for (const licenseInfo of licenseInfos) { - knownPaths.add(licenseInfo.path) +export class GenerateLicenseInfo extends Script { + constructor() { + super("Validates the licenses and compiles them into one single asset file") } - for (const iconPath of allIcons) { - if (iconPath.indexOf("license_info.json") >= 0) { - continue - } - if (knownPaths.has(iconPath)) { - continue - } - missing.push(iconPath) - } - return missing -} + static defaultLicenses() { + const knownLicenses = new Map() + knownLicenses.set("me", { + authors: ["Pieter Vander Vennet"], + path: undefined, + license: "CC0", + sources: [], + }) + knownLicenses.set("streetcomplete", { + authors: ["Tobias Zwick (westnordost)"], + path: undefined, + license: "CC0", + sources: [ + "https://github.com/streetcomplete/StreetComplete/tree/master/res/graphics", + "https://f-droid.org/packages/de.westnordost.streetcomplete/", + ], + }) -const knownLicenses = new Map() -knownLicenses.set("me", { - authors: ["Pieter Vander Vennet"], - path: undefined, - license: "CC0", - sources: [], -}) -knownLicenses.set("streetcomplete", { - authors: ["Tobias Zwick (westnordost)"], - path: undefined, - license: "CC0", - sources: [ - "https://github.com/streetcomplete/StreetComplete/tree/master/res/graphics", - "https://f-droid.org/packages/de.westnordost.streetcomplete/", - ], -}) + knownLicenses.set("temaki", { + authors: ["Temaki"], + path: undefined, + license: "CC0", + sources: [ + "https://github.com/ideditor/temaki", + "https://ideditor.github.io/temaki/docs/", + ], + }) -knownLicenses.set("temaki", { - authors: ["Temaki"], - path: undefined, - license: "CC0", - sources: ["https://github.com/ideditor/temaki", "https://ideditor.github.io/temaki/docs/"], -}) + knownLicenses.set("maki", { + authors: ["Maki"], + path: undefined, + license: "CC0", + sources: ["https://labs.mapbox.com/maki-icons/"], + }) -knownLicenses.set("maki", { - authors: ["Maki"], - path: undefined, - license: "CC0", - sources: ["https://labs.mapbox.com/maki-icons/"], -}) - -knownLicenses.set("t", { - authors: [], - path: undefined, - license: "CC0; trivial", - sources: [], -}) -knownLicenses.set("na", { - authors: [], - path: undefined, - license: "CC0", - sources: [], -}) -knownLicenses.set("tv", { - authors: ["Toerisme Vlaanderen"], - path: undefined, - license: "CC0", - sources: [ - "https://toerismevlaanderen.be/pinjepunt", - "https://mapcomplete.osm.be/toerisme_vlaanderenn", - ], -}) -knownLicenses.set("tvf", { - authors: ["Jo De Baerdemaeker "], - path: undefined, - license: "All rights reserved", - sources: ["https://www.studiotype.be/fonts/flandersart"], -}) -knownLicenses.set("twemoji", { - authors: ["Twemoji"], - path: undefined, - license: "CC-BY 4.0", - sources: ["https://github.com/twitter/twemoji"], -}) - -function promptLicenseFor(path): SmallLicense { - console.log("License abbreviations:") - knownLicenses.forEach((value, key) => { - console.log(key, " => ", value) - }) - const author = prompt("What is the author for artwork " + path + "? (or: [Q]uit, [S]kip) > ") - path = path.substring(path.lastIndexOf("/") + 1) - - if (knownLicenses.has(author)) { - const license = knownLicenses.get(author) - license.path = path - return license + knownLicenses.set("t", { + authors: [], + path: undefined, + license: "CC0; trivial", + sources: [], + }) + knownLicenses.set("na", { + authors: [], + path: undefined, + license: "CC0", + sources: [], + }) + knownLicenses.set("tv", { + authors: ["Toerisme Vlaanderen"], + path: undefined, + license: "CC0", + sources: [ + "https://toerismevlaanderen.be/pinjepunt", + "https://mapcomplete.osm.be/toerisme_vlaanderenn", + ], + }) + knownLicenses.set("tvf", { + authors: ["Jo De Baerdemaeker "], + path: undefined, + license: "All rights reserved", + sources: ["https://www.studiotype.be/fonts/flandersart"], + }) + knownLicenses.set("twemoji", { + authors: ["Twemoji"], + path: undefined, + license: "CC-BY 4.0", + sources: ["https://github.com/twitter/twemoji"], + }) + return knownLicenses } - if (author == "s") { - return null - } - if (author == "Q" || author == "q" || author == "") { - throw "Quitting now!" - } - let authors = author.split(";") - if (author.toLowerCase() == "none") { - authors = [] - } - return { - authors: author.split(";"), - path: path, - license: prompt("What is the license for artwork " + path + "? > "), - sources: prompt("Where was this artwork found? > ").split(";"), - } -} - -function createLicenseInfoFor(path): void { - const li = promptLicenseFor(path) - if (li == null) { - return - } - writeFileSync(path + ".license_info.json", JSON.stringify(li, null, " ")) -} - -function cleanLicenseInfo(allPaths: string[], allLicenseInfos: SmallLicense[]) { - // Read the license info file from the generated assets, creates a compiled license info in every directory - // Note: this removes all the old license infos - for (const licensePath of allPaths) { - unlinkSync(licensePath) - } - - const perDirectory = new Map() - - for (const license of allLicenseInfos) { - const p = license.path - const dir = p.substring(0, p.lastIndexOf("/")) - license.path = p.substring(dir.length + 1) - if (!perDirectory.has(dir)) { - perDirectory.set(dir, []) - } - const cloned: SmallLicense = { - // We make a clone to force the order of the keys - path: license.path, - license: license.license, - authors: license.authors, - sources: license.sources, - } - perDirectory.get(dir).push(cloned) - } - - perDirectory.forEach((licenses, dir) => { - for (let i = licenses.length - 1; i >= 0; i--) { - const license = licenses[i] - const path = dir + "/" + license.path - if (!existsSync(path)) { - console.log( - "Found license for now missing file: ", - path, - " - removing this license" - ) - licenses.splice(i, 1) - } - } - - licenses.sort((a, b) => (a.path < b.path ? -1 : 1)) - writeFileSync(dir + "/license_info.json", JSON.stringify(licenses, null, 2)) - }) -} - -function queryMissingLicenses(missingLicenses: string[]) { - process.on("SIGINT", function () { - console.log("Aborting... Bye!") - process.exit() - }) - - let i = 1 - for (const missingLicens of missingLicenses) { - console.log(i + " / " + missingLicenses.length) - i++ - if (i < missingLicenses.length - 5) { - // continue - } - createLicenseInfoFor(missingLicens) - } - - console.log("You're through!") -} - -/** - * Creates the humongous license_info in the generated assets, containing all licenses with a path relative to the root - * @param licensePaths - */ -function createFullLicenseOverview(licensePaths: string[]) { - const allLicenses: SmallLicense[] = [] - for (const licensePath of licensePaths) { - if (!existsSync(licensePath)) { - continue - } - const licenses = JSON.parse(readFileSync(licensePath, { encoding: "utf8" })) - for (const license of licenses) { - validateLicenseInfo(license) - const dir = licensePath.substring(0, licensePath.length - "license_info.json".length) - license.path = dir + license.path - allLicenses.push(license) - } - } - - writeFileSync("./assets/generated/license_info.json", JSON.stringify(allLicenses, null, " ")) -} - -function main(args: string[]) { - console.log("Checking and compiling license info") - - if (!existsSync("./assets/generated")) { - mkdirSync("./assets/generated") - } - - let contents = ScriptUtils.readDirRecSync("./assets") - .filter((p) => !p.startsWith("./assets/templates/")) - .filter((entry) => entry.indexOf("./assets/generated") != 0) - let licensePaths = contents.filter((entry) => entry.indexOf("license_info.json") >= 0) - let licenseInfos = generateLicenseInfos(licensePaths) - - const artwork = contents.filter( - (pth) => pth.match(/(.svg|.png|.jpg|.ttf|.otf|.woff)$/i) != null - ) - const missingLicenses = missingLicenseInfos(licenseInfos, artwork) - if (args.indexOf("--prompt") >= 0 || args.indexOf("--query") >= 0) { - queryMissingLicenses(missingLicenses) - return main([]) - } - - const invalidLicenses = licenseInfos - .filter((l) => (l.license ?? "") === "") - .map((l) => `License for artwork ${l.path} is empty string or undefined`) - - let invalid = 0 - for (const licenseInfo of licenseInfos) { - const isTrivial = - licenseInfo.license - .split(";") - .map((l) => l.trim().toLowerCase()) - .indexOf("trivial") >= 0 - if (licenseInfo.sources.length + licenseInfo.authors.length == 0 && !isTrivial) { - invalid++ - invalidLicenses.push( - "Invalid license: No sources nor authors given in the license for " + - JSON.stringify(licenseInfo) - ) - continue - } - - for (const source of licenseInfo.sources) { - if (source == "") { - invalidLicenses.push( - "Invalid license: empty string in " + JSON.stringify(licenseInfo) - ) - } + validateLicenseInfo(l: SmallLicense) { + l.sources.map((s) => { try { - new URL(source) - } catch { - invalidLicenses.push("Not a valid URL: " + source) + return new URL(s) + } catch (e) { + throw "Could not parse URL " + s + " for a license for " + l.path + " due to " + e + } + }) + } + + /** + * Sweeps the entire 'assets/' (except assets/generated) directory for image files and any 'license_info.json'-file. + * Checks that the license info is included for each of them and generates a compiles license_info.json for those + */ + + generateLicenseInfos(paths: string[]): SmallLicense[] { + const licenses = [] + for (const path of paths) { + try { + const parsed = JSON.parse(readFileSync(path, { encoding: "utf8" })) + if (Array.isArray(parsed)) { + const l: SmallLicense[] = parsed + for (const smallLicens of l) { + smallLicens.path = + path.substring(0, path.length - "license_info.json".length) + + smallLicens.path + } + licenses.push(...l) + } else { + const smallLicens: SmallLicense = parsed + smallLicens.path = + path.substring(0, 1 + path.lastIndexOf("/")) + smallLicens.path + licenses.push(smallLicens) + } + } catch (e) { + console.error("Error: ", e, "while handling", path) } } + return licenses } - if (missingLicenses.length > 0 || invalidLicenses.length) { - const msg = `There are ${missingLicenses.length} licenses missing and ${invalidLicenses.length} invalid licenses.` - console.log(missingLicenses.concat(invalidLicenses).join("\n")) - console.error(msg) - if (args.indexOf("--no-fail") < 0) { - throw msg + missingLicenseInfos(licenseInfos: SmallLicense[], allIcons: string[]) { + const missing = [] + + const knownPaths = new Set() + for (const licenseInfo of licenseInfos) { + knownPaths.add(licenseInfo.path) + } + + for (const iconPath of allIcons) { + if (iconPath.indexOf("license_info.json") >= 0) { + continue + } + if (knownPaths.has(iconPath)) { + continue + } + missing.push(iconPath) + } + return missing + } + + promptLicenseFor(path): SmallLicense { + const knownLicenses = GenerateLicenseInfo.defaultLicenses() + console.log("License abbreviations:") + knownLicenses.forEach((value, key) => { + console.log(key, " => ", value) + }) + const author = prompt( + "What is the author for artwork " + path + "? (or: [Q]uit, [S]kip) > " + ) + path = path.substring(path.lastIndexOf("/") + 1) + + if (knownLicenses.has(author)) { + const license = knownLicenses.get(author) + license.path = path + return license + } + + if (author == "s") { + return null + } + if (author == "Q" || author == "q" || author == "") { + throw "Quitting now!" + } + let authors = author.split(";") + if (author.toLowerCase() == "none") { + authors = [] + } + return { + authors: author.split(";"), + path: path, + license: prompt("What is the license for artwork " + path + "? > "), + sources: prompt("Where was this artwork found? > ").split(";"), } } - cleanLicenseInfo(licensePaths, licenseInfos) - createFullLicenseOverview(licensePaths) + createLicenseInfoFor(path): void { + const li = this.promptLicenseFor(path) + if (li == null) { + return + } + writeFileSync(path + ".license_info.json", JSON.stringify(li, null, " ")) + } + + cleanLicenseInfo(allPaths: string[], allLicenseInfos: SmallLicense[]) { + // Read the license info file from the generated assets, creates a compiled license info in every directory + // Note: this removes all the old license infos + for (const licensePath of allPaths) { + unlinkSync(licensePath) + } + + const perDirectory = new Map() + + for (const license of allLicenseInfos) { + const p = license.path + const dir = p.substring(0, p.lastIndexOf("/")) + license.path = p.substring(dir.length + 1) + if (!perDirectory.has(dir)) { + perDirectory.set(dir, []) + } + const cloned: SmallLicense = { + // We make a clone to force the order of the keys + path: license.path, + license: license.license, + authors: license.authors, + sources: license.sources, + } + perDirectory.get(dir).push(cloned) + } + + perDirectory.forEach((licenses, dir) => { + for (let i = licenses.length - 1; i >= 0; i--) { + const license = licenses[i] + const path = dir + "/" + license.path + if (!existsSync(path)) { + console.log( + "Found license for now missing file: ", + path, + " - removing this license" + ) + licenses.splice(i, 1) + } + } + + licenses.sort((a, b) => (a.path < b.path ? -1 : 1)) + writeFileSync(dir + "/license_info.json", JSON.stringify(licenses, null, 2)) + }) + } + + queryMissingLicenses(missingLicenses: string[]) { + process.on("SIGINT", function () { + console.log("Aborting... Bye!") + process.exit() + }) + + let i = 1 + for (const missingLicens of missingLicenses) { + console.log(i + " / " + missingLicenses.length) + i++ + if (i < missingLicenses.length - 5) { + // continue + } + this.createLicenseInfoFor(missingLicens) + } + + console.log("You're through!") + } + + /** + * Creates the humongous license_info in the generated assets, containing all licenses with a path relative to the root + * @param licensePaths + */ + createFullLicenseOverview(licensePaths: string[]) { + const allLicenses: SmallLicense[] = [] + for (const licensePath of licensePaths) { + if (!existsSync(licensePath)) { + continue + } + const licenses = ( + JSON.parse(readFileSync(licensePath, { encoding: "utf8" })) + ) + for (const license of licenses) { + this.validateLicenseInfo(license) + const dir = licensePath.substring( + 0, + licensePath.length - "license_info.json".length + ) + license.path = dir + license.path + allLicenses.push(license) + } + } + + writeFileSync( + "./assets/generated/license_info.json", + JSON.stringify(allLicenses, null, " ") + ) + } + + async main(args: string[]) { + console.log("Checking and compiling license info") + + if (!existsSync("./assets/generated")) { + mkdirSync("./assets/generated") + } + + let contents = ScriptUtils.readDirRecSync("./assets") + .filter((p) => !p.startsWith("./assets/templates/")) + .filter((entry) => entry.indexOf("./assets/generated") != 0) + let licensePaths = contents.filter((entry) => entry.indexOf("license_info.json") >= 0) + let licenseInfos = this.generateLicenseInfos(licensePaths) + + const artwork = contents.filter( + (pth) => pth.match(/(.svg|.png|.jpg|.ttf|.otf|.woff)$/i) != null + ) + const missingLicenses = this.missingLicenseInfos(licenseInfos, artwork) + if (args.indexOf("--prompt") >= 0 || args.indexOf("--query") >= 0) { + this.queryMissingLicenses(missingLicenses) + return this.main([]) + } + + const invalidLicenses = licenseInfos + .filter((l) => (l.license ?? "") === "") + .map((l) => `License for artwork ${l.path} is empty string or undefined`) + + let invalid = 0 + for (const licenseInfo of licenseInfos) { + const isTrivial = + licenseInfo.license + .split(";") + .map((l) => l.trim().toLowerCase()) + .indexOf("trivial") >= 0 + if (licenseInfo.sources.length + licenseInfo.authors.length == 0 && !isTrivial) { + invalid++ + invalidLicenses.push( + "Invalid license: No sources nor authors given in the license for " + + JSON.stringify(licenseInfo) + ) + continue + } + + for (const source of licenseInfo.sources) { + if (source == "") { + invalidLicenses.push( + "Invalid license: empty string in " + JSON.stringify(licenseInfo) + ) + } + try { + new URL(source) + } catch { + invalidLicenses.push("Not a valid URL: " + source) + } + } + } + + if (missingLicenses.length > 0 || invalidLicenses.length) { + const msg = `There are ${missingLicenses.length} licenses missing and ${invalidLicenses.length} invalid licenses.` + console.log(missingLicenses.concat(invalidLicenses).join("\n")) + console.error(msg) + if (args.indexOf("--no-fail") < 0) { + throw msg + } + } + + this.cleanLicenseInfo(licensePaths, licenseInfos) + this.createFullLicenseOverview(licensePaths) + } } -main(process.argv.slice(2)) +new GenerateLicenseInfo().run() diff --git a/scripts/printVersion.ts b/scripts/printVersion.ts deleted file mode 100644 index 10bdf47657..0000000000 --- a/scripts/printVersion.ts +++ /dev/null @@ -1,3 +0,0 @@ -import Constants from "../Models/Constants" - -console.log("git tag -a", Constants.vNumber, `-m "Deployed on ${new Date()}"`)