Better social images
|
@ -8,6 +8,7 @@ import {ExtractImages} from "./Conversion/FixImages";
|
||||||
import ExtraLinkConfig from "./ExtraLinkConfig";
|
import ExtraLinkConfig from "./ExtraLinkConfig";
|
||||||
|
|
||||||
export default class LayoutConfig {
|
export default class LayoutConfig {
|
||||||
|
public static readonly defaultSocialImage = "assets/SocialImage.png"
|
||||||
public readonly id: string;
|
public readonly id: string;
|
||||||
public readonly maintainer: string;
|
public readonly maintainer: string;
|
||||||
public readonly credits?: string;
|
public readonly credits?: string;
|
||||||
|
@ -54,7 +55,7 @@ export default class LayoutConfig {
|
||||||
|
|
||||||
public readonly usedImages: string[]
|
public readonly usedImages: string[]
|
||||||
public readonly extraLink?: ExtraLinkConfig
|
public readonly extraLink?: ExtraLinkConfig
|
||||||
|
|
||||||
constructor(json: LayoutConfigJson, official = true, context?: string) {
|
constructor(json: LayoutConfigJson, official = true, context?: string) {
|
||||||
this.official = official;
|
this.official = official;
|
||||||
this.id = json.id;
|
this.id = json.id;
|
||||||
|
@ -103,10 +104,10 @@ export default class LayoutConfig {
|
||||||
this.shortDescription = json.shortDescription === undefined ? this.description.FirstSentence() : new Translation(json.shortDescription, context + ".shortdescription");
|
this.shortDescription = json.shortDescription === undefined ? this.description.FirstSentence() : new Translation(json.shortDescription, context + ".shortdescription");
|
||||||
this.descriptionTail = json.descriptionTail === undefined ? undefined : new Translation(json.descriptionTail, context + ".descriptionTail");
|
this.descriptionTail = json.descriptionTail === undefined ? undefined : new Translation(json.descriptionTail, context + ".descriptionTail");
|
||||||
this.icon = json.icon;
|
this.icon = json.icon;
|
||||||
this.socialImage = json.socialImage;
|
this.socialImage = json.socialImage ?? LayoutConfig.defaultSocialImage;
|
||||||
if (this.socialImage === null || this.socialImage === "" || this.socialImage === undefined) {
|
if (this.socialImage === "") {
|
||||||
if (official) {
|
if (official) {
|
||||||
throw "Theme " + json.id + " has no social image defined"
|
throw "Theme " + json.id + " has empty string as social image"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.startZoom = json.startZoom;
|
this.startZoom = json.startZoom;
|
||||||
|
|
21
Utils.ts
|
@ -432,27 +432,32 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply a function on every leaf of the JSON; used to rewrite parts of the JSON
|
* Apply a function on every leaf of the JSON; used to rewrite parts of the JSON
|
||||||
* @param json
|
|
||||||
* @param f
|
|
||||||
* @constructor
|
|
||||||
*/
|
*/
|
||||||
static WalkJson(json: any, f: (v: number | string | boolean | undefined) => any) {
|
static WalkJson(json: any, f: (v: number | string | boolean | undefined) => any, isLeaf: (object) => boolean = undefined) {
|
||||||
if (json === undefined) {
|
if (json === undefined) {
|
||||||
return f(undefined)
|
return f(undefined)
|
||||||
}
|
}
|
||||||
const jtp = typeof json
|
const jtp = typeof json
|
||||||
if (jtp === "boolean" || jtp === "string" || jtp === "number") {
|
if(isLeaf !== undefined) {
|
||||||
|
if(jtp === "object"){
|
||||||
|
if(isLeaf(json)){
|
||||||
|
return f(json)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return json
|
||||||
|
}
|
||||||
|
}else if (jtp === "boolean" || jtp === "string" || jtp === "number") {
|
||||||
return f(json)
|
return f(json)
|
||||||
}
|
}
|
||||||
if (json.map !== undefined) {
|
if (Array.isArray(json)) {
|
||||||
return json.map(sub => {
|
return json.map(sub => {
|
||||||
return Utils.WalkJson(sub, f);
|
return Utils.WalkJson(sub, f, isLeaf);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const cp = {...json}
|
const cp = {...json}
|
||||||
for (const key in json) {
|
for (const key in json) {
|
||||||
cp[key] = Utils.WalkJson(json[key], f)
|
cp[key] = Utils.WalkJson(json[key], f, isLeaf)
|
||||||
}
|
}
|
||||||
return cp
|
return cp
|
||||||
}
|
}
|
||||||
|
|
2930
assets/SocialImageTemplate.svg
Normal file
After Width: | Height: | Size: 3.1 MiB |
2629
assets/SocialImageTemplateWide.svg
Normal file
After Width: | Height: | Size: 3.1 MiB |
|
@ -1 +1,55 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 141.73 141.73"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#3c3d3c;}</style></defs><g id="Laag_1" data-name="Laag 1"><circle class="cls-1" cx="70.87" cy="70.87" r="70.87"/></g><g id="Laag_2" data-name="Laag 2"><path class="cls-2" d="M102.39,75a18.18,18.18,0,0,0-3.92.43L92.87,57a7,7,0,0,0-6.77-5H80.67v2.59H86.1a4.45,4.45,0,0,1,4.29,3.19l1.72,5.66H55.54l-2-4.89h3.72S62,57.77,62,54.14H46.39v4.33h4.35l2.55,6.25L47.67,76.27A18.31,18.31,0,1,0,59,96.27h8l1-.43L93.33,67.37,96,76.15a18.28,18.28,0,1,0,6.4-1.17ZM41,109a15.72,15.72,0,1,1,5.58-30.4l-7.69,15.8L40,96.27H56.38A15.74,15.74,0,0,1,41,109Zm15.7-15.33H42.07l6.8-14a15.71,15.71,0,0,1,7.8,13.56C56.67,93.42,56.66,93.55,56.65,93.68ZM50,77.39l4.61-9.45,10.5,25.74H59.24c0-.13,0-.26,0-.39A18.33,18.33,0,0,0,50,77.39ZM67.45,92.56,56.59,66H91.13ZM102.39,109a15.71,15.71,0,0,1-5.65-30.38l4.56,15,2.48-.76-4.56-15A15.72,15.72,0,1,1,102.39,109Z"/><path class="cls-2" d="M78.72,40.26a13.89,13.89,0,0,1-5.58,1.25,9.86,9.86,0,0,1-5.6-1.61,9,9,0,0,1-3.39-4.41h9.4l1.07-2.89-.13-.36h-11a2.91,2.91,0,0,1,0-.4v-.57c0-.4,0-.79.05-1.17h12l1.08-2.93L76.36,27H64.13a8.69,8.69,0,0,1,3.48-4.43A10.82,10.82,0,0,1,73.55,21a16.47,16.47,0,0,1,4.55.68l.13,0,1.08-3-.15-.05a16.56,16.56,0,0,0-5.3-.81,14.91,14.91,0,0,0-8.42,2.35A11.73,11.73,0,0,0,60.66,27h-2.3l-1.08,2.93.19.19h2.69c0,.16,0,.32,0,.49v1.23c0,.14,0,.29,0,.42h-1.8L57.28,35.3l.19.19h3.21a12.2,12.2,0,0,0,4.48,6.72,12.47,12.47,0,0,0,7.64,2.46A16.44,16.44,0,0,0,79,43.39l.09,0v-3l-.28-.16Z"/></g></svg>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 141.73 141.73"
|
||||||
|
version="1.1"
|
||||||
|
id="svg14"
|
||||||
|
sodipodi:docname="rental.svg"
|
||||||
|
inkscape:version="1.1.1 (1:1.1+202109281949+c3084ef5ed)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview16"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#eeeeee"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:pageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="2.6516417"
|
||||||
|
inkscape:cx="41.10661"
|
||||||
|
inkscape:cy="42.615109"
|
||||||
|
inkscape:current-layer="svg14" />
|
||||||
|
<defs
|
||||||
|
id="defs4">
|
||||||
|
<style
|
||||||
|
id="style2">.cls-1{fill:#fff;}.cls-2{fill:#3c3d3c;}</style>
|
||||||
|
</defs>
|
||||||
|
<g
|
||||||
|
id="g838">
|
||||||
|
<g
|
||||||
|
id="Laag_1"
|
||||||
|
data-name="Laag 1">
|
||||||
|
<circle
|
||||||
|
class="cls-1"
|
||||||
|
cx="70.87"
|
||||||
|
cy="70.87"
|
||||||
|
r="70.87"
|
||||||
|
id="circle6" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="Laag_2"
|
||||||
|
data-name="Laag 2">
|
||||||
|
<path
|
||||||
|
class="cls-2"
|
||||||
|
d="M102.39,75a18.18,18.18,0,0,0-3.92.43L92.87,57a7,7,0,0,0-6.77-5H80.67v2.59H86.1a4.45,4.45,0,0,1,4.29,3.19l1.72,5.66H55.54l-2-4.89h3.72S62,57.77,62,54.14H46.39v4.33h4.35l2.55,6.25L47.67,76.27A18.31,18.31,0,1,0,59,96.27h8l1-.43L93.33,67.37,96,76.15a18.28,18.28,0,1,0,6.4-1.17ZM41,109a15.72,15.72,0,1,1,5.58-30.4l-7.69,15.8L40,96.27H56.38A15.74,15.74,0,0,1,41,109Zm15.7-15.33H42.07l6.8-14a15.71,15.71,0,0,1,7.8,13.56C56.67,93.42,56.66,93.55,56.65,93.68ZM50,77.39l4.61-9.45,10.5,25.74H59.24c0-.13,0-.26,0-.39A18.33,18.33,0,0,0,50,77.39ZM67.45,92.56,56.59,66H91.13ZM102.39,109a15.71,15.71,0,0,1-5.65-30.38l4.56,15,2.48-.76-4.56-15A15.72,15.72,0,1,1,102.39,109Z"
|
||||||
|
id="path9" />
|
||||||
|
<path
|
||||||
|
class="cls-2"
|
||||||
|
d="M78.72,40.26a13.89,13.89,0,0,1-5.58,1.25,9.86,9.86,0,0,1-5.6-1.61,9,9,0,0,1-3.39-4.41h9.4l1.07-2.89-.13-.36h-11a2.91,2.91,0,0,1,0-.4v-.57c0-.4,0-.79.05-1.17h12l1.08-2.93L76.36,27H64.13a8.69,8.69,0,0,1,3.48-4.43A10.82,10.82,0,0,1,73.55,21a16.47,16.47,0,0,1,4.55.68l.13,0,1.08-3-.15-.05a16.56,16.56,0,0,0-5.3-.81,14.91,14.91,0,0,0-8.42,2.35A11.73,11.73,0,0,0,60.66,27h-2.3l-1.08,2.93.19.19h2.69c0,.16,0,.32,0,.49v1.23c0,.14,0,.29,0,.42h-1.8L57.28,35.3l.19.19h3.21a12.2,12.2,0,0,0,4.48,6.72,12.47,12.47,0,0,0,7.64,2.46A16.44,16.44,0,0,0,79,43.39l.09,0v-3l-.28-.16Z"
|
||||||
|
id="path11" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
@ -2,16 +2,34 @@
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
<svg
|
<svg
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
version="1.1"
|
version="1.1"
|
||||||
width="100%"
|
width="14px"
|
||||||
height="100%"
|
height="14px"
|
||||||
viewBox="0 0 14 14"
|
viewBox="0 0 14 14"
|
||||||
id="svg2">
|
id="svg2"
|
||||||
|
sodipodi:docname="recycling-14.svg"
|
||||||
|
inkscape:version="1.1.1 (1:1.1+202109281949+c3084ef5ed)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview7"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#eeeeee"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:pageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
showgrid="false"
|
||||||
|
units="px"
|
||||||
|
inkscape:zoom="60.071429"
|
||||||
|
inkscape:cx="6.9916766"
|
||||||
|
inkscape:cy="7.0083234"
|
||||||
|
inkscape:current-layer="svg2" />
|
||||||
<metadata
|
<metadata
|
||||||
id="metadata8">
|
id="metadata8">
|
||||||
<rdf:RDF>
|
<rdf:RDF>
|
||||||
|
@ -20,7 +38,6 @@
|
||||||
<dc:format>image/svg+xml</dc:format>
|
<dc:format>image/svg+xml</dc:format>
|
||||||
<dc:type
|
<dc:type
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
</cc:Work>
|
||||||
</rdf:RDF>
|
</rdf:RDF>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
@ -32,9 +49,9 @@
|
||||||
x="0"
|
x="0"
|
||||||
y="0"
|
y="0"
|
||||||
id="canvas"
|
id="canvas"
|
||||||
style="fill:none;stroke:none;visibility:hidden" />
|
style="visibility:hidden;fill:none;stroke:none" />
|
||||||
<path
|
<path
|
||||||
d="M 5.111113,8.690628 3.513352,5.804047 0.3,5.804047 1.60621,6.5880837 0.798678,8.031102 c -0.06887,0.130859 -0.103304,0.267511 -0.103301,0.409961 -3e-6,0.142456 0.03443,0.27911 0.103301,0.40996 l 1.271077,2.298282 c 0.05733,-0.166376 0.11466,-0.309011 0.171995,-0.427902 L 3.82273,7.906591 5.111113,8.690628 z m -2.38799,2.316224 c -0.09194,0.154416 -0.137914,0.320611 -0.13791,0.498585 -4e-6,0.273307 0.09456,0.504931 0.283685,0.694868 0.189119,0.189939 0.415298,0.284906 0.678537,0.284906 l 3.161963,0 0,-2.654413 -3.333432,0 C 3.352886,9.878288 3.266892,10.0327 3.117975,10.294041 l -0.394852,0.712811 z m 4.278351,-6.5745954 3.196047,0 L 11.812587,1.54622 10.506901,2.3302555 9.698844,0.8866933 C 9.549912,0.6137609 9.320934,0.4772893 9.011916,0.4772767 l -2.543205,0 c 0.10312,0.1185426 0.189116,0.2372528 0.257992,0.3561331 L 8.289856,3.6482199 8.032389,3.8086154 7.001474,4.4322566 z M 5.437797,0.6197306 C 5.07108,0.6197421 4.796134,0.7859374 4.61296,1.1183163 L 3.015198,3.9690109 C 3.622066,4.3372941 4.360906,4.7767964 5.231719,5.2875185 5.746994,4.372999 6.302478,3.3752843 6.898173,2.2943703 L 6.262635,1.1183163 C 6.079446,0.7859374 5.804501,0.6197421 5.437797,0.6197306 l 0,0 z m 4.106882,9.1751824 0,-0.320793 0,-1.228795 L 7.946393,11.131363 9.544679,14 l 0,-1.55013 1.597761,0 c 0.309366,0 0.54411,-0.136653 0.704231,-0.409962 l 1.271602,-2.298279 c -0.171656,0.04749 -0.314811,0.07123 -0.42946,0.07123 L 9.544679,9.794909 z m 2.37121,-4.88147 c -0.05735,0.035533 -0.79636,0.4750321 -2.217045,1.3185066 0.710337,1.2708484 1.271764,2.2745434 1.684282,3.0110934 l 1.288383,0 c 0.378233,2e-6 0.658946,-0.166373 0.842142,-0.499132 0.171629,-0.320788 0.165862,-0.647379 -0.01731,-0.979774 l -1.58045,-2.850694 z"
|
d="M 5.111113,8.690628 3.513352,5.804047 H 0.3 L 1.60621,6.5880837 0.798678,8.031102 c -0.06887,0.130859 -0.103304,0.267511 -0.103301,0.409961 -3e-6,0.142456 0.03443,0.27911 0.103301,0.40996 l 1.271077,2.298282 c 0.05733,-0.166376 0.11466,-0.309011 0.171995,-0.427902 L 3.82273,7.906591 Z m -2.38799,2.316224 c -0.09194,0.154416 -0.137914,0.320611 -0.13791,0.498585 -4e-6,0.273307 0.09456,0.504931 0.283685,0.694868 0.189119,0.189939 0.415298,0.284906 0.678537,0.284906 H 6.709398 V 9.830798 H 3.375966 C 3.352886,9.878288 3.266892,10.0327 3.117975,10.294041 Z M 7.001474,4.4322566 h 3.196047 L 11.812587,1.54622 10.506901,2.3302555 9.698844,0.8866933 C 9.549912,0.6137609 9.320934,0.4772893 9.011916,0.4772767 H 6.468711 c 0.10312,0.1185426 0.189116,0.2372528 0.257992,0.3561331 L 8.289856,3.6482199 8.032389,3.8086154 Z M 5.437797,0.6197306 C 5.07108,0.6197421 4.796134,0.7859374 4.61296,1.1183163 L 3.015198,3.9690109 C 3.622066,4.3372941 4.360906,4.7767964 5.231719,5.2875185 5.746994,4.372999 6.302478,3.3752843 6.898173,2.2943703 L 6.262635,1.1183163 C 6.079446,0.7859374 5.804501,0.6197421 5.437797,0.6197306 Z M 9.544679,9.794913 V 9.47412 8.245325 L 7.946393,11.131363 9.544679,14 v -1.55013 h 1.597761 c 0.309366,0 0.54411,-0.136653 0.704231,-0.409962 l 1.271602,-2.298279 c -0.171656,0.04749 -0.314811,0.07123 -0.42946,0.07123 L 9.544679,9.794909 Z m 2.37121,-4.88147 c -0.05735,0.035533 -0.79636,0.4750321 -2.217045,1.3185066 0.710337,1.2708484 1.271764,2.2745434 1.684282,3.0110934 h 1.288383 c 0.378233,2e-6 0.658946,-0.166373 0.842142,-0.499132 0.171629,-0.320788 0.165862,-0.647379 -0.01731,-0.979774 l -1.58045,-2.850694 z"
|
||||||
id="recycling"
|
id="recycling"
|
||||||
style="fill:#000000;fill-opacity:1;stroke:none" />
|
style="fill:#000000;fill-opacity:1;stroke:none" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 3.1 KiB |
|
@ -352,7 +352,8 @@
|
||||||
"zh_Hant": "這間商業空間是否允許犬隻?",
|
"zh_Hant": "這間商業空間是否允許犬隻?",
|
||||||
"ru": "Впускают ли собак в это здание?",
|
"ru": "Впускают ли собак в это здание?",
|
||||||
"pl": "Czy w tej firmie psy są dozwolone?",
|
"pl": "Czy w tej firmie psy są dozwolone?",
|
||||||
"ja": "犬を飼うことができますか?"
|
"ja": "犬を飼うことができますか?",
|
||||||
|
"id": "Apakah anjing diperbolehkan dalam bisnis ini?"
|
||||||
},
|
},
|
||||||
"mappings": [
|
"mappings": [
|
||||||
{
|
{
|
||||||
|
@ -435,7 +436,8 @@
|
||||||
"zh_Hant": "允許犬隻而且可以自由跑動",
|
"zh_Hant": "允許犬隻而且可以自由跑動",
|
||||||
"ru": "Собак свободно впускают",
|
"ru": "Собак свободно впускают",
|
||||||
"pl": "Psy dozwolone i mogą biegać bez ograniczeń",
|
"pl": "Psy dozwolone i mogą biegać bez ograniczeń",
|
||||||
"ja": "犬同伴可能、自由に走り回れる"
|
"ja": "犬同伴可能、自由に走り回れる",
|
||||||
|
"id": "Anjing diperbolehkan dan dapat berkeliaran dengan bebas"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -754,7 +756,8 @@
|
||||||
"it": "Si trova sotto il livello stradale",
|
"it": "Si trova sotto il livello stradale",
|
||||||
"nb_NO": "Under bakken",
|
"nb_NO": "Under bakken",
|
||||||
"ca": "Situat a planta subterrani",
|
"ca": "Situat a planta subterrani",
|
||||||
"ja": "地下にあります"
|
"ja": "地下にあります",
|
||||||
|
"id": "Terletak di bawah tanah"
|
||||||
},
|
},
|
||||||
"hideInAnswer": true
|
"hideInAnswer": true
|
||||||
},
|
},
|
||||||
|
@ -776,7 +779,8 @@
|
||||||
"it": "Si trova al pianoterra",
|
"it": "Si trova al pianoterra",
|
||||||
"nb_NO": "På gateplan",
|
"nb_NO": "På gateplan",
|
||||||
"ca": "Situat a planta zero",
|
"ca": "Situat a planta zero",
|
||||||
"ja": "1階にあります"
|
"ja": "1階にあります",
|
||||||
|
"id": "Terletak di lantai dasar"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -798,7 +802,8 @@
|
||||||
"it": "Si trova al pianoterra",
|
"it": "Si trova al pianoterra",
|
||||||
"nb_NO": "På gateplan",
|
"nb_NO": "På gateplan",
|
||||||
"ca": "Situat a planta zero",
|
"ca": "Situat a planta zero",
|
||||||
"ja": "1階にあります"
|
"ja": "1階にあります",
|
||||||
|
"id": "Terletak di lantai dasar"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -830,7 +835,8 @@
|
||||||
"nl": "Bevindt zich in de eerste kelderverdieping",
|
"nl": "Bevindt zich in de eerste kelderverdieping",
|
||||||
"zh_Hant": "位於地下一樓",
|
"zh_Hant": "位於地下一樓",
|
||||||
"de": "Ist im 1. Untergeschoss",
|
"de": "Ist im 1. Untergeschoss",
|
||||||
"hu": "Az első alagsori szinten"
|
"hu": "Az első alagsori szinten",
|
||||||
|
"id": "Terletak di lantai basement pertama"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
"pt_BR": "Abrir mapa AED"
|
"pt_BR": "Abrir mapa AED"
|
||||||
},
|
},
|
||||||
"maintainer": "MapComplete",
|
"maintainer": "MapComplete",
|
||||||
"icon": "./assets/themes/aed/logo.svg",
|
"icon": "./assets/themes/aed/aed.svg",
|
||||||
"description": {
|
"description": {
|
||||||
"en": "On this map, one can find and mark nearby defibrillators",
|
"en": "On this map, one can find and mark nearby defibrillators",
|
||||||
"ca": "En aquest mapa , qualsevol pot trobar i marcar els desfibril·ladors externs automàtics més propers",
|
"ca": "En aquest mapa , qualsevol pot trobar i marcar els desfibril·ladors externs automàtics més propers",
|
||||||
|
|
|
@ -1,8 +1,30 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="375px" height="375px" viewBox="0 0 375 375" version="1.1">
|
<svg
|
||||||
<g id="surface1">
|
width="375px"
|
||||||
<rect x="0" y="0" width="375" height="375" style="fill:rgb(0%,53.333336%,33.333334%);fill-opacity:1;stroke:none;"/>
|
height="375px"
|
||||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 279.210938 32.8125 L 309.375 32.8125 L 309.375 63.179688 L 339.742188 63.179688 L 339.742188 93.34375 L 309.375 93.34375 L 309.375 123.710938 L 279.210938 123.710938 L 279.210938 93.34375 L 248.84375 93.34375 L 248.84375 63.179688 L 279.210938 63.179688 Z M 279.210938 32.8125 "/>
|
viewBox="0 0 375 375"
|
||||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 96.808594 114.742188 C 57.675781 115.148438 22.621094 154.074219 33.21875 205.433594 C 41.167969 244.769531 82.949219 295.71875 155.707031 345.039062 C 228.464844 295.515625 270.246094 244.566406 278.191406 205.433594 C 288.789062 153.871094 253.941406 115.148438 214.605469 114.742188 C 194.429688 114.335938 169.15625 125.136719 155.707031 150.816406 C 142.253906 125.136719 116.984375 114.335938 96.808594 114.742188 Z M 187.09375 145.925781 L 152.851562 216.238281 L 196.261719 216.238281 L 120.246094 304.6875 L 149.59375 235.394531 L 107.40625 235.394531 Z M 187.09375 145.925781 "/>
|
version="1.1"
|
||||||
|
id="svg9"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs13" />
|
||||||
|
<g
|
||||||
|
id="surface1">
|
||||||
|
<rect
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="375"
|
||||||
|
height="375"
|
||||||
|
style="fill:rgb(0%,53.333336%,33.333334%);fill-opacity:1;stroke:none;"
|
||||||
|
id="rect2" />
|
||||||
|
<path
|
||||||
|
style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;"
|
||||||
|
d="M 279.210938 32.8125 L 309.375 32.8125 L 309.375 63.179688 L 339.742188 63.179688 L 339.742188 93.34375 L 309.375 93.34375 L 309.375 123.710938 L 279.210938 123.710938 L 279.210938 93.34375 L 248.84375 93.34375 L 248.84375 63.179688 L 279.210938 63.179688 Z M 279.210938 32.8125 "
|
||||||
|
id="path4" />
|
||||||
|
<path
|
||||||
|
style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;"
|
||||||
|
d="M 96.808594 114.742188 C 57.675781 115.148438 22.621094 154.074219 33.21875 205.433594 C 41.167969 244.769531 82.949219 295.71875 155.707031 345.039062 C 228.464844 295.515625 270.246094 244.566406 278.191406 205.433594 C 288.789062 153.871094 253.941406 115.148438 214.605469 114.742188 C 194.429688 114.335938 169.15625 125.136719 155.707031 150.816406 C 142.253906 125.136719 116.984375 114.335938 96.808594 114.742188 Z M 187.09375 145.925781 L 152.851562 216.238281 L 196.261719 216.238281 L 120.246094 304.6875 L 149.59375 235.394531 L 107.40625 235.394531 Z M 187.09375 145.925781 "
|
||||||
|
id="path6" />
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.6 KiB |
|
@ -4,7 +4,7 @@
|
||||||
"nl": "Open AED-kaart - Brugge edition"
|
"nl": "Open AED-kaart - Brugge edition"
|
||||||
},
|
},
|
||||||
"maintainer": "MapComplete",
|
"maintainer": "MapComplete",
|
||||||
"icon": "./assets/themes/aed/logo.svg",
|
"icon": "./assets/themes/aed/aed.svg",
|
||||||
"description": {
|
"description": {
|
||||||
"nl": "Op deze kaart kan je informatie over AEDs vinden en verbeteren + een export van de brugse defibrillatoren"
|
"nl": "Op deze kaart kan je informatie over AEDs vinden en verbeteren + een export van de brugse defibrillatoren"
|
||||||
},
|
},
|
||||||
|
|
|
@ -8,15 +8,5 @@
|
||||||
"sources": [
|
"sources": [
|
||||||
"https://commons.wikimedia.org/wiki/File:ISO_7010_E010.svg"
|
"https://commons.wikimedia.org/wiki/File:ISO_7010_E010.svg"
|
||||||
]
|
]
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "logo.svg",
|
|
||||||
"license": "CC-BY-SA 4.0",
|
|
||||||
"authors": [
|
|
||||||
"M!dgard"
|
|
||||||
],
|
|
||||||
"sources": [
|
|
||||||
"https://commons.wikimedia.org/wiki/File:ISO_7010_E010.svg"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
Before Width: | Height: | Size: 54 KiB |
|
@ -25,7 +25,8 @@
|
||||||
"zh_Hant": "長椅的地圖",
|
"zh_Hant": "長椅的地圖",
|
||||||
"nb_NO": "Et benkekart",
|
"nb_NO": "Et benkekart",
|
||||||
"pt_BR": "Um mapa de bancadas",
|
"pt_BR": "Um mapa de bancadas",
|
||||||
"hu": "Padtérkép"
|
"hu": "Padtérkép",
|
||||||
|
"id": "Peta bangku"
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"en": "This map shows all benches that are recorded in OpenStreetMap: Individual benches, and benches belonging to public transport stops or shelters. With an OpenStreetMap account, you can map new benches or edit details of existing benches.",
|
"en": "This map shows all benches that are recorded in OpenStreetMap: Individual benches, and benches belonging to public transport stops or shelters. With an OpenStreetMap account, you can map new benches or edit details of existing benches.",
|
||||||
|
|
|
@ -3,12 +3,14 @@
|
||||||
"title": {
|
"title": {
|
||||||
"en": "Bicycle rental",
|
"en": "Bicycle rental",
|
||||||
"nl": "Fietsverhuur",
|
"nl": "Fietsverhuur",
|
||||||
"de": "Fahrradverleih"
|
"de": "Fahrradverleih",
|
||||||
|
"id": "Sewa sepeda"
|
||||||
},
|
},
|
||||||
"shortDescription": {
|
"shortDescription": {
|
||||||
"en": "A map with bicycle rental stations and bicycle rental shops",
|
"en": "A map with bicycle rental stations and bicycle rental shops",
|
||||||
"nl": "Een kaart met fietsverhuurpunten en fietsverhuurzaken",
|
"nl": "Een kaart met fietsverhuurpunten en fietsverhuurzaken",
|
||||||
"de": "Eine Karte mit Fahrradverleihstationen und Fahrradverleihern"
|
"de": "Eine Karte mit Fahrradverleihstationen und Fahrradverleihern",
|
||||||
|
"id": "Peta dengan stasiun persewaan sepeda dan toko penyewaan sepeda"
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"en": "On this map, you'll find the many bicycle rental stations as they are known by OpenStreetMap",
|
"en": "On this map, you'll find the many bicycle rental stations as they are known by OpenStreetMap",
|
||||||
|
|
|
@ -1 +1,56 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 141.73 141.73"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#3c3d3c;}</style></defs><g id="Laag_1" data-name="Laag 1"><circle class="cls-1" cx="70.87" cy="70.87" r="70.87"/></g><g id="Laag_2" data-name="Laag 2"><path class="cls-2" d="M102.39,75a18.18,18.18,0,0,0-3.92.43L92.87,57a7,7,0,0,0-6.77-5H80.67v2.59H86.1a4.45,4.45,0,0,1,4.29,3.19l1.72,5.66H55.54l-2-4.89h3.72S62,57.77,62,54.14H46.39v4.33h4.35l2.55,6.25L47.67,76.27A18.31,18.31,0,1,0,59,96.27h8l1-.43L93.33,67.37,96,76.15a18.28,18.28,0,1,0,6.4-1.17ZM41,109a15.72,15.72,0,1,1,5.58-30.4l-7.69,15.8L40,96.27H56.38A15.74,15.74,0,0,1,41,109Zm15.7-15.33H42.07l6.8-14a15.71,15.71,0,0,1,7.8,13.56C56.67,93.42,56.66,93.55,56.65,93.68ZM50,77.39l4.61-9.45,10.5,25.74H59.24c0-.13,0-.26,0-.39A18.33,18.33,0,0,0,50,77.39ZM67.45,92.56,56.59,66H91.13ZM102.39,109a15.71,15.71,0,0,1-5.65-30.38l4.56,15,2.48-.76-4.56-15A15.72,15.72,0,1,1,102.39,109Z"/><path class="cls-2" d="M78.72,40.26a13.89,13.89,0,0,1-5.58,1.25,9.86,9.86,0,0,1-5.6-1.61,9,9,0,0,1-3.39-4.41h9.4l1.07-2.89-.13-.36h-11a2.91,2.91,0,0,1,0-.4v-.57c0-.4,0-.79.05-1.17h12l1.08-2.93L76.36,27H64.13a8.69,8.69,0,0,1,3.48-4.43A10.82,10.82,0,0,1,73.55,21a16.47,16.47,0,0,1,4.55.68l.13,0,1.08-3-.15-.05a16.56,16.56,0,0,0-5.3-.81,14.91,14.91,0,0,0-8.42,2.35A11.73,11.73,0,0,0,60.66,27h-2.3l-1.08,2.93.19.19h2.69c0,.16,0,.32,0,.49v1.23c0,.14,0,.29,0,.42h-1.8L57.28,35.3l.19.19h3.21a12.2,12.2,0,0,0,4.48,6.72,12.47,12.47,0,0,0,7.64,2.46A16.44,16.44,0,0,0,79,43.39l.09,0v-3l-.28-.16Z"/></g></svg>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 150 150"
|
||||||
|
version="1.1"
|
||||||
|
id="svg14"
|
||||||
|
sodipodi:docname="logo.svg"
|
||||||
|
width="150"
|
||||||
|
height="150"
|
||||||
|
inkscape:version="1.1.1 (1:1.1+202109281949+c3084ef5ed)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview16"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#eeeeee"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:pageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="4.78212"
|
||||||
|
inkscape:cx="65.661254"
|
||||||
|
inkscape:cy="75.280419"
|
||||||
|
inkscape:current-layer="svg14" />
|
||||||
|
<defs
|
||||||
|
id="defs4">
|
||||||
|
<style
|
||||||
|
id="style2">.cls-1{fill:#fff;}.cls-2{fill:#3c3d3c;}</style>
|
||||||
|
</defs>
|
||||||
|
<g
|
||||||
|
id="Laag_1"
|
||||||
|
data-name="Laag 1"
|
||||||
|
transform="scale(1.0573395)">
|
||||||
|
<circle
|
||||||
|
class="cls-1"
|
||||||
|
cx="70.870003"
|
||||||
|
cy="70.870003"
|
||||||
|
r="70.870003"
|
||||||
|
id="circle6" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="Laag_2"
|
||||||
|
data-name="Laag 2"
|
||||||
|
transform="scale(1.0573395)">
|
||||||
|
<path
|
||||||
|
class="cls-2"
|
||||||
|
d="m 102.39,75 a 18.18,18.18 0 0 0 -3.92,0.43 L 92.87,57 A 7,7 0 0 0 86.1,52 h -5.43 v 2.59 h 5.43 a 4.45,4.45 0 0 1 4.29,3.19 l 1.72,5.66 H 55.54 l -2,-4.89 h 3.72 c 0,0 4.74,-0.78 4.74,-4.41 H 46.39 v 4.33 h 4.35 l 2.55,6.25 -5.62,11.55 a 18.31,18.31 0 1 0 11.33,20 h 8 L 68,95.84 93.33,67.37 96,76.15 a 18.28,18.28 0 1 0 6.4,-1.17 z M 41,109 A 15.72,15.72 0 1 1 46.58,78.6 L 38.89,94.4 40,96.27 H 56.38 A 15.74,15.74 0 0 1 41,109 Z M 56.7,93.67 H 42.07 l 6.8,-14 a 15.71,15.71 0 0 1 7.8,13.56 c 0,0.19 -0.01,0.32 -0.02,0.45 z M 50,77.39 l 4.61,-9.45 10.5,25.74 h -5.87 c 0,-0.13 0,-0.26 0,-0.39 A 18.33,18.33 0 0 0 50,77.39 Z M 67.45,92.56 56.59,66 H 91.13 Z M 102.39,109 A 15.71,15.71 0 0 1 96.74,78.62 l 4.56,15 2.48,-0.76 -4.56,-15 a 15.72,15.72 0 1 1 3.17,31.14 z"
|
||||||
|
id="path9" />
|
||||||
|
<path
|
||||||
|
class="cls-2"
|
||||||
|
d="m 78.72,40.26 a 13.89,13.89 0 0 1 -5.58,1.25 9.86,9.86 0 0 1 -5.6,-1.61 9,9 0 0 1 -3.39,-4.41 h 9.4 l 1.07,-2.89 -0.13,-0.36 h -11 a 2.91,2.91 0 0 1 0,-0.4 v -0.57 c 0,-0.4 0,-0.79 0.05,-1.17 h 12 L 76.62,27.17 76.36,27 H 64.13 a 8.69,8.69 0 0 1 3.48,-4.43 10.82,10.82 0 0 1 5.94,-1.57 16.47,16.47 0 0 1 4.55,0.68 h 0.13 l 1.08,-3 -0.15,-0.05 a 16.56,16.56 0 0 0 -5.3,-0.81 14.91,14.91 0 0 0 -8.42,2.35 11.73,11.73 0 0 0 -4.78,6.83 h -2.3 l -1.08,2.93 0.19,0.19 h 2.69 c 0,0.16 0,0.32 0,0.49 v 1.23 c 0,0.14 0,0.29 0,0.42 h -1.8 l -1.08,3.04 0.19,0.19 h 3.21 a 12.2,12.2 0 0 0 4.48,6.72 12.47,12.47 0 0 0 7.64,2.46 16.44,16.44 0 0 0 6.2,-1.28 h 0.09 v -3 l -0.28,-0.16 z"
|
||||||
|
id="path11" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 2.7 KiB |
|
@ -14,7 +14,8 @@
|
||||||
"de": "Fahrradbibliothek",
|
"de": "Fahrradbibliothek",
|
||||||
"pt_BR": "Bibliotecas de bicicletas",
|
"pt_BR": "Bibliotecas de bicicletas",
|
||||||
"pl": "Wypożyczalnie rowerów",
|
"pl": "Wypożyczalnie rowerów",
|
||||||
"hu": "Kerékpárkönyvtárak"
|
"hu": "Kerékpárkönyvtárak",
|
||||||
|
"id": "Perpustakaan sepeda"
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"nl": "Een fietsbibliotheek is een plaats waar men een fiets kan lenen, vaak voor een klein bedrag per jaar. Een typisch voorbeeld zijn kinderfietsbibliotheken, waar men een fiets op maat van het kind kan lenen. Is het kind de fiets ontgroeid, dan kan het te kleine fietsje omgeruild worden voor een grotere.",
|
"nl": "Een fietsbibliotheek is een plaats waar men een fiets kan lenen, vaak voor een klein bedrag per jaar. Een typisch voorbeeld zijn kinderfietsbibliotheken, waar men een fiets op maat van het kind kan lenen. Is het kind de fiets ontgroeid, dan kan het te kleine fietsje omgeruild worden voor een grotere.",
|
||||||
|
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 26 KiB |
|
@ -1,16 +1,13 @@
|
||||||
{
|
{
|
||||||
"id": "mapcomplete-changes",
|
"id": "mapcomplete-changes",
|
||||||
"title": {
|
"title": {
|
||||||
"en": "Changes made with MapComplete",
|
"en": "Changes made with MapComplete"
|
||||||
"de": "Änderungen mit MapComplete"
|
|
||||||
},
|
},
|
||||||
"shortDescription": {
|
"shortDescription": {
|
||||||
"en": "Shows changes made by MapComplete",
|
"en": "Shows changes made by MapComplete"
|
||||||
"de": "Zeigt Änderungen, die von MapComplete vorgenommen wurden"
|
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"en": "This maps shows all the changes made with MapComplete",
|
"en": "This maps shows all the changes made with MapComplete"
|
||||||
"de": "Diese Karte zeigt alle mit MapComplete vorgenommenen Änderungen"
|
|
||||||
},
|
},
|
||||||
"maintainer": "",
|
"maintainer": "",
|
||||||
"icon": "./assets/svg/logo.svg",
|
"icon": "./assets/svg/logo.svg",
|
||||||
|
@ -25,8 +22,7 @@
|
||||||
{
|
{
|
||||||
"id": "mapcomplete-changes",
|
"id": "mapcomplete-changes",
|
||||||
"name": {
|
"name": {
|
||||||
"en": "Changeset centers",
|
"en": "Changeset centers"
|
||||||
"de": "Schwerpunkte von Änderungssätzen"
|
|
||||||
},
|
},
|
||||||
"minzoom": 0,
|
"minzoom": 0,
|
||||||
"source": {
|
"source": {
|
||||||
|
@ -40,41 +36,35 @@
|
||||||
],
|
],
|
||||||
"title": {
|
"title": {
|
||||||
"render": {
|
"render": {
|
||||||
"en": "Changeset for {theme}",
|
"en": "Changeset for {theme}"
|
||||||
"de": "Änderungssatz für {theme}"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"en": "Shows all MapComplete changes",
|
"en": "Shows all MapComplete changes"
|
||||||
"de": "Zeigt alle MapComplete-Änderungen"
|
|
||||||
},
|
},
|
||||||
"tagRenderings": [
|
"tagRenderings": [
|
||||||
{
|
{
|
||||||
"id": "render_id",
|
"id": "render_id",
|
||||||
"render": {
|
"render": {
|
||||||
"en": "Changeset <a href='https://openstreetmap.org/changeset/{id}' target='_blank'>{id}</a>",
|
"en": "Changeset <a href='https://openstreetmap.org/changeset/{id}' target='_blank'>{id}</a>"
|
||||||
"de": "Änderungssatz <a href='https://openstreetmap.org/changeset/{id}' target='_blank'>{id}</a>"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "contributor",
|
"id": "contributor",
|
||||||
"render": {
|
"render": {
|
||||||
"en": "Change made by <a href='https://openstreetmap.org/user/{_last_edit:contributor}' target='_blank'>{_last_edit:contributor}</a>",
|
"en": "Change made by <a href='https://openstreetmap.org/user/{_last_edit:contributor}' target='_blank'>{_last_edit:contributor}</a>"
|
||||||
"de": "Geändert von <a href='https://openstreetmap.org/user/{_last_edit:contributor}' target='_blank'>{_last_edit:contributor}</a>"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "theme",
|
"id": "theme",
|
||||||
"render": {
|
"render": {
|
||||||
"en": "Change with theme <a href='https://mapcomplete.osm.be/{theme}'>{theme}</a>",
|
"en": "Change with theme <a href='https://mapcomplete.osm.be/{theme}'>{theme}</a>"
|
||||||
"de": "Änderung mit Thema <a href='https://mapcomplete.osm.be/{theme}'>{theme}</a>"
|
|
||||||
},
|
},
|
||||||
"mappings": [
|
"mappings": [
|
||||||
{
|
{
|
||||||
"if": "theme~http.*",
|
"if": "theme~http.*",
|
||||||
"then": {
|
"then": {
|
||||||
"en": "Change with <b>unofficial</b> theme <a href='https://mapcomplete.osm.be/theme.html?userlayout={theme}'>{theme}</a>",
|
"en": "Change with <b>unofficial</b> theme <a href='https://mapcomplete.osm.be/theme.html?userlayout={theme}'>{theme}</a>"
|
||||||
"de": "Änderung mit <b>inoffiziellem</b> Thema <a href='https://mapcomplete.osm.be/theme.html?userlayout={theme}'>{theme}</a>"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -91,11 +81,11 @@
|
||||||
"mappings": [
|
"mappings": [
|
||||||
{
|
{
|
||||||
"if": "theme=aed",
|
"if": "theme=aed",
|
||||||
"then": "./assets/themes/aed/logo.svg"
|
"then": "./assets/themes/aed/aed.svg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"if": "theme=aed_brugge",
|
"if": "theme=aed_brugge",
|
||||||
"then": "./assets/themes/aed/logo.svg"
|
"then": "./assets/themes/aed/aed.svg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"if": "theme=artwork",
|
"if": "theme=artwork",
|
||||||
|
@ -338,8 +328,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"question": {
|
"question": {
|
||||||
"en": "Themename contains {search}",
|
"en": "Themename contains {search}"
|
||||||
"de": "Themenname enthält {search}"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -355,8 +344,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"question": {
|
"question": {
|
||||||
"en": "Made by contributor {search}",
|
"en": "Made by contributor {search}"
|
||||||
"de": "Erstellt von Mitwirkendem {search}"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -372,8 +360,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"question": {
|
"question": {
|
||||||
"en": "<b>Not</b> made by contributor {search}",
|
"en": "<b>Not</b> made by contributor {search}"
|
||||||
"de": "<b> Nicht</b> erstellt von Mitwirkendem {search}"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -388,8 +375,7 @@
|
||||||
{
|
{
|
||||||
"id": "link_to_more",
|
"id": "link_to_more",
|
||||||
"render": {
|
"render": {
|
||||||
"en": "More statistics can be found <a href='https://github.com/pietervdvn/MapComplete/tree/develop/Docs/Tools/graphs' target='_blank'>here</a>",
|
"en": "More statistics can be found <a href='https://github.com/pietervdvn/MapComplete/tree/develop/Docs/Tools/graphs' target='_blank'>here</a>"
|
||||||
"de": "Weitere Statistiken finden Sie <a href='https://github.com/pietervdvn/MapComplete/tree/develop/Docs/Tools/graphs' target='_blank'>hier</a>"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,52 +9,52 @@
|
||||||
"orientation": "portrait-primary, landscape-primary",
|
"orientation": "portrait-primary, landscape-primary",
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
"src": "assets/generated/svg_mapcomplete_logo72.png",
|
"src": "assets/generated/images/mapcomplete_logo72.png",
|
||||||
"sizes": "72x72",
|
"sizes": "72x72",
|
||||||
"type": "image/png"
|
"type": "image/png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "assets/generated/svg_mapcomplete_logo96.png",
|
"src": "assets/generated/images/mapcomplete_logo96.png",
|
||||||
"sizes": "96x96",
|
"sizes": "96x96",
|
||||||
"type": "image/png"
|
"type": "image/png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "assets/generated/svg_mapcomplete_logo120.png",
|
"src": "assets/generated/images/mapcomplete_logo120.png",
|
||||||
"sizes": "120x120",
|
"sizes": "120x120",
|
||||||
"type": "image/png"
|
"type": "image/png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "assets/generated/svg_mapcomplete_logo128.png",
|
"src": "assets/generated/images/mapcomplete_logo128.png",
|
||||||
"sizes": "128x128",
|
"sizes": "128x128",
|
||||||
"type": "image/png"
|
"type": "image/png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "assets/generated/svg_mapcomplete_logo144.png",
|
"src": "assets/generated/images/mapcomplete_logo144.png",
|
||||||
"sizes": "144x144",
|
"sizes": "144x144",
|
||||||
"type": "image/png"
|
"type": "image/png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "assets/generated/svg_mapcomplete_logo152.png",
|
"src": "assets/generated/images/mapcomplete_logo152.png",
|
||||||
"sizes": "152x152",
|
"sizes": "152x152",
|
||||||
"type": "image/png"
|
"type": "image/png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "assets/generated/svg_mapcomplete_logo180.png",
|
"src": "assets/generated/images/mapcomplete_logo180.png",
|
||||||
"sizes": "180x180",
|
"sizes": "180x180",
|
||||||
"type": "image/png"
|
"type": "image/png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "assets/generated/svg_mapcomplete_logo192.png",
|
"src": "assets/generated/images/mapcomplete_logo192.png",
|
||||||
"sizes": "192x192",
|
"sizes": "192x192",
|
||||||
"type": "image/png"
|
"type": "image/png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "assets/generated/svg_mapcomplete_logo384.png",
|
"src": "assets/generated/images/mapcomplete_logo384.png",
|
||||||
"sizes": "384x384",
|
"sizes": "384x384",
|
||||||
"type": "image/png"
|
"type": "image/png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "assets/generated/svg_mapcomplete_logo512.png",
|
"src": "assets/generated/images/mapcomplete_logo512.png",
|
||||||
"sizes": "512x512",
|
"sizes": "512x512",
|
||||||
"type": "image/png"
|
"type": "image/png"
|
||||||
},
|
},
|
||||||
|
|
|
@ -8,12 +8,12 @@
|
||||||
"delete": {
|
"delete": {
|
||||||
"cancel": "Batal",
|
"cancel": "Batal",
|
||||||
"cannotBeDeleted": "Fitur ini tidak dapat dihapus",
|
"cannotBeDeleted": "Fitur ini tidak dapat dihapus",
|
||||||
|
"delete": "Hapus",
|
||||||
"explanations": {
|
"explanations": {
|
||||||
"selectReason": "Silahkan pilih mengapa fitur ini harus dihapus"
|
"selectReason": "Silahkan pilih mengapa fitur ini harus dihapus"
|
||||||
},
|
},
|
||||||
"isntAPoint": "Hanya titik yang dapat dihapus, fitur yang dipilih adalah jalan, area, atau relasi.",
|
"isDeleted": "Fitur ini telah dihapus",
|
||||||
"delete": "Hapus",
|
"isntAPoint": "Hanya titik yang dapat dihapus, fitur yang dipilih adalah jalan, area, atau relasi."
|
||||||
"isDeleted": "Fitur ini telah dihapus"
|
|
||||||
},
|
},
|
||||||
"favourite": {
|
"favourite": {
|
||||||
"reload": "Muat ulang data"
|
"reload": "Muat ulang data"
|
||||||
|
@ -115,4 +115,4 @@
|
||||||
"split": {
|
"split": {
|
||||||
"cancel": "Batal"
|
"cancel": "Batal"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -25,18 +25,18 @@
|
||||||
},
|
},
|
||||||
"level": {
|
"level": {
|
||||||
"mappings": {
|
"mappings": {
|
||||||
"3": {
|
"0": {
|
||||||
"then": "Berlokasi di lantai pertama"
|
"then": "Terletak di bawah tanah"
|
||||||
},
|
},
|
||||||
"1": {
|
"1": {
|
||||||
"then": "Terletak di lantai dasar"
|
"then": "Terletak di lantai dasar"
|
||||||
},
|
},
|
||||||
"0": {
|
|
||||||
"then": "Terletak di bawah tanah"
|
|
||||||
},
|
|
||||||
"2": {
|
"2": {
|
||||||
"then": "Terletak di lantai dasar"
|
"then": "Terletak di lantai dasar"
|
||||||
},
|
},
|
||||||
|
"3": {
|
||||||
|
"then": "Berlokasi di lantai pertama"
|
||||||
|
},
|
||||||
"4": {
|
"4": {
|
||||||
"then": "Terletak di lantai basement pertama"
|
"then": "Terletak di lantai basement pertama"
|
||||||
}
|
}
|
||||||
|
@ -61,4 +61,4 @@
|
||||||
"question": "Apa situs web dari {title()}?"
|
"question": "Apa situs web dari {title()}?"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,8 +8,15 @@
|
||||||
"title": "Buka Peta Karya Seni"
|
"title": "Buka Peta Karya Seni"
|
||||||
},
|
},
|
||||||
"benches": {
|
"benches": {
|
||||||
"title": "Bangku",
|
"shortDescription": "Peta bangku",
|
||||||
"shortDescription": "Peta bangku"
|
"title": "Bangku"
|
||||||
|
},
|
||||||
|
"bicycle_rental": {
|
||||||
|
"shortDescription": "Peta dengan stasiun persewaan sepeda dan toko penyewaan sepeda",
|
||||||
|
"title": "Sewa sepeda"
|
||||||
|
},
|
||||||
|
"bicyclelib": {
|
||||||
|
"title": "Perpustakaan sepeda"
|
||||||
},
|
},
|
||||||
"cafes_and_pubs": {
|
"cafes_and_pubs": {
|
||||||
"title": "Kafe dan pub"
|
"title": "Kafe dan pub"
|
||||||
|
@ -283,12 +290,5 @@
|
||||||
},
|
},
|
||||||
"waste_basket": {
|
"waste_basket": {
|
||||||
"title": "Keranjang Sampah"
|
"title": "Keranjang Sampah"
|
||||||
},
|
|
||||||
"bicyclelib": {
|
|
||||||
"title": "Perpustakaan sepeda"
|
|
||||||
},
|
|
||||||
"bicycle_rental": {
|
|
||||||
"title": "Sewa sepeda",
|
|
||||||
"shortDescription": "Peta dengan stasiun persewaan sepeda dan toko penyewaan sepeda"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import {lstatSync, readdirSync, readFileSync} from "fs";
|
import {existsSync, lstatSync, readdirSync, readFileSync} from "fs";
|
||||||
import {Utils} from "../Utils";
|
import {Utils} from "../Utils";
|
||||||
import * as https from "https";
|
import * as https from "https";
|
||||||
import {LayoutConfigJson} from "../Models/ThemeConfig/Json/LayoutConfigJson";
|
import {LayoutConfigJson} from "../Models/ThemeConfig/Json/LayoutConfigJson";
|
||||||
|
@ -146,6 +146,9 @@ export default class ScriptUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async ReadSvg(path: string): Promise<any>{
|
public static async ReadSvg(path: string): Promise<any>{
|
||||||
|
if(!existsSync(path)){
|
||||||
|
throw "File not found: "+path
|
||||||
|
}
|
||||||
const root = await xml2js.parseStringPromise(readFileSync(path, "UTF8"))
|
const root = await xml2js.parseStringPromise(readFileSync(path, "UTF8"))
|
||||||
return root.svg
|
return root.svg
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,6 +102,9 @@ class LayerOverviewUtils {
|
||||||
.filter(path => !path.startsWith("./assets/generated"))
|
.filter(path => !path.startsWith("./assets/generated"))
|
||||||
let errCount = 0;
|
let errCount = 0;
|
||||||
for (const path of allSvgs) {
|
for (const path of allSvgs) {
|
||||||
|
if(path.indexOf("assets/SocialImageTemplate") >= 0){
|
||||||
|
continue
|
||||||
|
}
|
||||||
const contents = readFileSync(path, "UTF8")
|
const contents = readFileSync(path, "UTF8")
|
||||||
if (contents.indexOf("data:image/png;") < 0) {
|
if (contents.indexOf("data:image/png;") < 0) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {LayoutConfigJson} from "../Models/ThemeConfig/Json/LayoutConfigJson";
|
||||||
import LayoutConfig from "../Models/ThemeConfig/LayoutConfig";
|
import LayoutConfig from "../Models/ThemeConfig/LayoutConfig";
|
||||||
import xml2js from 'xml2js';
|
import xml2js from 'xml2js';
|
||||||
import ScriptUtils from "./ScriptUtils";
|
import ScriptUtils from "./ScriptUtils";
|
||||||
|
import {Utils} from "../Utils";
|
||||||
|
|
||||||
const sharp = require('sharp');
|
const sharp = require('sharp');
|
||||||
const template = readFileSync("theme.html", "utf8");
|
const template = readFileSync("theme.html", "utf8");
|
||||||
|
@ -19,72 +20,126 @@ function enc(str: string): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createIcon(iconPath: string, size: number, alreadyWritten: string[]) {
|
async function createIcon(iconPath: string, size: number, alreadyWritten: string[]) {
|
||||||
let name = iconPath.split(".").slice(0, -1).join(".");
|
let name = iconPath.split(".").slice(0, -1).join("."); // drop svg suffix
|
||||||
if (name.startsWith("./")) {
|
if (name.startsWith("./")) {
|
||||||
name = name.substr(2)
|
name = name.substr(2)
|
||||||
}
|
}
|
||||||
const newname = `${name}${size}.png`
|
|
||||||
.replace(/\//g, "_")
|
const newname = `assets/generated/images${name.substring(name.lastIndexOf("/"))}${size}.png`;
|
||||||
.replace("assets_", "assets/generated/");
|
|
||||||
|
|
||||||
if (alreadyWritten.indexOf(newname) >= 0) {
|
if (alreadyWritten.indexOf(newname) >= 0) {
|
||||||
return newname;
|
return newname;
|
||||||
}
|
}
|
||||||
alreadyWritten.push(newname);
|
alreadyWritten.push(newname);
|
||||||
try {
|
if (existsSync(newname)) {
|
||||||
readFileSync(newname);
|
return newname
|
||||||
return newname; // File already exists - nothing to do
|
}
|
||||||
} catch (e) {
|
|
||||||
// Errors are normal here if this file does not exists
|
if (!existsSync(iconPath)) {
|
||||||
|
throw "No file at " + iconPath
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// We already read to file, in order to crash here if the file is not found
|
// We already read to file, in order to crash here if the file is not found
|
||||||
readFileSync(iconPath);
|
|
||||||
let img = await sharp(iconPath)
|
let img = await sharp(iconPath)
|
||||||
let resized = await img.resize(size)
|
let resized = await img.resize(size)
|
||||||
await resized.toFile(newname)
|
await resized.toFile(newname)
|
||||||
|
console.log("Written", newname)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Could not read icon", iconPath, "due to", e)
|
console.error("Could not read icon", iconPath, " to create a PNG due to", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
return newname;
|
return newname;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createManifest(layout: LayoutConfig, alreadyWritten: string[]) {
|
async function createSocialImage(layout: LayoutConfig, template: "" | "Wide"): Promise<string> {
|
||||||
|
if (!layout.icon.endsWith(".svg")) {
|
||||||
|
console.warn("Not creating a social image for " + layout.id + " as it is _not_ a .svg: " + layout.icon)
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
const path = `./assets/generated/images/social_image_${layout.id}_${template}.svg`
|
||||||
|
if(existsSync(path)){
|
||||||
|
// return path;
|
||||||
|
}
|
||||||
|
const svg = await ScriptUtils.ReadSvg(layout.icon)
|
||||||
|
let width: string = svg.$.width;
|
||||||
|
if (width === undefined) {
|
||||||
|
throw "The logo at " + layout.icon + " does not have a defined width"
|
||||||
|
}
|
||||||
|
if (width?.endsWith("px")) {
|
||||||
|
width = width.substring(0, width.length - 2)
|
||||||
|
}
|
||||||
|
if (width?.endsWith("%")) {
|
||||||
|
throw "The logo at " + layout.icon + " has a relative width; this is not supported"
|
||||||
|
}
|
||||||
|
delete svg["defs"]
|
||||||
|
delete svg["$"]
|
||||||
|
let templateSvg = await ScriptUtils.ReadSvg("./assets/SocialImageTemplate" + template + ".svg")
|
||||||
|
templateSvg = Utils.WalkJson(templateSvg,
|
||||||
|
(leaf) => {
|
||||||
|
const {cx, cy, r} = leaf["circle"][0].$
|
||||||
|
return {
|
||||||
|
$: {
|
||||||
|
id: "icon",
|
||||||
|
transform: `translate(${cx - r},${cy - r}) scale(${(r * 2) / Number(width)}) `
|
||||||
|
},
|
||||||
|
g: [svg]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(mightBeTokenToReplace) => {
|
||||||
|
if (mightBeTokenToReplace?.circle === undefined) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return mightBeTokenToReplace.circle[0]?.$?.style?.indexOf("fill:#ff00ff") >= 0
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
const builder = new xml2js.Builder();
|
||||||
|
const xml = builder.buildObject({svg: templateSvg});
|
||||||
|
writeFileSync(path, xml)
|
||||||
|
console.log("Written", path)
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createManifest(layout: LayoutConfig, alreadyWritten: string[]): Promise<{
|
||||||
|
manifest: any,
|
||||||
|
whiteIcons: string[]
|
||||||
|
}> {
|
||||||
const name = layout.id;
|
const name = layout.id;
|
||||||
|
|
||||||
Translation.forcedLanguage = "en"
|
Translation.forcedLanguage = "en"
|
||||||
const icons = [];
|
const icons = [];
|
||||||
|
|
||||||
|
const whiteIcons: string[] = []
|
||||||
let icon = layout.icon;
|
let icon = layout.icon;
|
||||||
if (icon.endsWith(".svg") || icon.startsWith("<svg") || icon.startsWith("<?xml")) {
|
if (icon.endsWith(".svg") || icon.startsWith("<svg") || icon.startsWith("<?xml")) {
|
||||||
// This is an svg. Lets create the needed pngs and do some checkes!
|
// This is an svg. Lets create the needed pngs and do some checkes!
|
||||||
|
|
||||||
const whiteBackgroundPath = "./assets/generated/theme_"+layout.id+"_white_background.svg"
|
const whiteBackgroundPath = "./assets/generated/images/theme_" + layout.id + "_white_background.svg"
|
||||||
{
|
{
|
||||||
const svg = await ScriptUtils.ReadSvg(icon)
|
const svg = await ScriptUtils.ReadSvg(icon)
|
||||||
const width: string = svg.$.width;
|
const width: string = svg.$.width;
|
||||||
const height: string = svg.$.height;
|
const height: string = svg.$.height;
|
||||||
|
|
||||||
const builder = new xml2js.Builder();
|
const builder = new xml2js.Builder();
|
||||||
const withRect = {rect: {"$":{width, height, style: "fill:#ffffff;"}}, ...svg}
|
const withRect = {rect: {"$": {width, height, style: "fill:#ffffff;"}}, ...svg}
|
||||||
const xml = builder.buildObject({svg: withRect});
|
const xml = builder.buildObject({svg: withRect});
|
||||||
writeFileSync(whiteBackgroundPath, xml)
|
writeFileSync(whiteBackgroundPath, xml)
|
||||||
}
|
}
|
||||||
|
|
||||||
let path = layout.icon;
|
let path = layout.icon;
|
||||||
if (layout.icon.startsWith("<")) {
|
if (layout.icon.startsWith("<")) {
|
||||||
// THis is already the svg
|
// THis is already the svg
|
||||||
path = "./assets/generated/" + layout.id + "_logo.svg"
|
path = "./assets/generated/images/" + layout.id + "_logo.svg"
|
||||||
writeFileSync(path, layout.icon)
|
writeFileSync(path, layout.icon)
|
||||||
}
|
}
|
||||||
|
|
||||||
const sizes = [72, 96, 120, 128, 144, 152, 180, 192, 384, 512];
|
const sizes = [72, 96, 120, 128, 144, 152, 180, 192, 384, 512];
|
||||||
for (const size of sizes) {
|
for (const size of sizes) {
|
||||||
const name = await createIcon(path, size, alreadyWritten);
|
const name = await createIcon(path, size, alreadyWritten);
|
||||||
await createIcon(whiteBackgroundPath, size, alreadyWritten)
|
const whiteIcon = await createIcon(whiteBackgroundPath, size, alreadyWritten)
|
||||||
|
whiteIcons.push(whiteIcon)
|
||||||
icons.push({
|
icons.push({
|
||||||
src: name,
|
src: name,
|
||||||
sizes: size + "x" + size,
|
sizes: size + "x" + size,
|
||||||
|
@ -109,7 +164,7 @@ async function createManifest(layout: LayoutConfig, alreadyWritten: string[]) {
|
||||||
const ogTitle = Translations.WT(layout.title).txt;
|
const ogTitle = Translations.WT(layout.title).txt;
|
||||||
const ogDescr = Translations.WT(layout.description ?? "").txt;
|
const ogDescr = Translations.WT(layout.description ?? "").txt;
|
||||||
|
|
||||||
return {
|
const manifest = {
|
||||||
name: name,
|
name: name,
|
||||||
short_name: ogTitle,
|
short_name: ogTitle,
|
||||||
start_url: `${layout.id.toLowerCase()}.html`,
|
start_url: `${layout.id.toLowerCase()}.html`,
|
||||||
|
@ -121,15 +176,32 @@ async function createManifest(layout: LayoutConfig, alreadyWritten: string[]) {
|
||||||
icons: icons,
|
icons: icons,
|
||||||
categories: ["map", "navigation"]
|
categories: ["map", "navigation"]
|
||||||
};
|
};
|
||||||
|
return {
|
||||||
|
manifest,
|
||||||
|
whiteIcons
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createLandingPage(layout: LayoutConfig, manifest) {
|
async function createLandingPage(layout: LayoutConfig, manifest, whiteIcons, alreadyWritten) {
|
||||||
|
|
||||||
Locale.language.setData(layout.language[0]);
|
Locale.language.setData(layout.language[0]);
|
||||||
const targetLanguage = layout.language[0]
|
const targetLanguage = layout.language[0]
|
||||||
const ogTitle = Translations.WT(layout.title).textFor(targetLanguage).replace(/"/g, '\\"');
|
const ogTitle = Translations.WT(layout.title).textFor(targetLanguage).replace(/"/g, '\\"');
|
||||||
const ogDescr = Translations.WT(layout.shortDescription ?? "Easily add and edit geodata with OpenStreetMap").textFor(targetLanguage).replace(/"/g, '\\"');
|
const ogDescr = Translations.WT(layout.shortDescription ?? "Easily add and edit geodata with OpenStreetMap").textFor(targetLanguage).replace(/"/g, '\\"');
|
||||||
const ogImage = layout.socialImage;
|
let ogImage = layout.socialImage;
|
||||||
|
let twitterImage = ogImage
|
||||||
|
if (ogImage === LayoutConfig.defaultSocialImage && layout.official) {
|
||||||
|
ogImage = await createSocialImage(layout, "") ?? layout.socialImage
|
||||||
|
twitterImage = await createSocialImage(layout, "Wide") ?? layout.socialImage
|
||||||
|
}
|
||||||
|
if (twitterImage.endsWith(".svg")) {
|
||||||
|
// svgs are badly supported as social image, we use a generated svg instead
|
||||||
|
twitterImage = await createIcon(twitterImage, 512, alreadyWritten);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ogImage.endsWith(".svg")){
|
||||||
|
ogImage = await createIcon(ogImage, 512, alreadyWritten)
|
||||||
|
}
|
||||||
|
|
||||||
let customCss = "";
|
let customCss = "";
|
||||||
if (layout.customCss !== undefined && layout.customCss !== "") {
|
if (layout.customCss !== undefined && layout.customCss !== "") {
|
||||||
|
@ -147,29 +219,26 @@ async function createLandingPage(layout: LayoutConfig, manifest) {
|
||||||
<meta property="og:title" content="${ogTitle}">
|
<meta property="og:title" content="${ogTitle}">
|
||||||
<meta property="og:description" content="${ogDescr}">
|
<meta property="og:description" content="${ogDescr}">
|
||||||
<meta name="twitter:card" content="summary_large_image">
|
<meta name="twitter:card" content="summary_large_image">
|
||||||
<meta name="twitter:site" content="@mapcomplete.osm;be">
|
<meta name="twitter:site" content="@mapcomplete.osm.be">
|
||||||
<meta name="twitter:creator" content="@pietervdvn">
|
<meta name="twitter:creator" content="@pietervdvn">
|
||||||
<meta name="twitter:title" content="${ogTitle}">
|
<meta name="twitter:title" content="${ogTitle}">
|
||||||
<meta name="twitter:description" content="${ogDescr}">
|
<meta name="twitter:description" content="${ogDescr}">
|
||||||
<meta name="twitter:image" content="${ogImage}">`
|
<meta name="twitter:image" content="${twitterImage}">`
|
||||||
|
|
||||||
let icon = layout.icon;
|
let icon = layout.icon;
|
||||||
if (icon.startsWith("<?xml") || icon.startsWith("<svg")) {
|
if (icon.startsWith("<?xml") || icon.startsWith("<svg")) {
|
||||||
// This already is an svg
|
// This already is an svg
|
||||||
icon = `./assets/generated/${layout.id}_icon.svg`
|
icon = `./assets/generated/images/${layout.id}_icon.svg`
|
||||||
writeFileSync(icon, layout.icon);
|
writeFileSync(icon, layout.icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
const apple_icons = []
|
const apple_icons = []
|
||||||
for (const icon of manifest.icons) {
|
for (const icon of whiteIcons) {
|
||||||
if (icon.type !== "image/png") {
|
if (!existsSync(icon)) {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const whiteBgPath = `./assets/generated/generated_theme_${layout.id}_white_background${icon.sizes.substr(icon.sizes.indexOf("x")+ 1)}.png`
|
|
||||||
if(!existsSync(whiteBgPath)){
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
apple_icons.push(`<link rel="apple-touch-icon" sizes="${icon.sizes}" href="${whiteBgPath}">`)
|
const size = icon.replace(/[^0-9]/g, "")
|
||||||
|
apple_icons.push(`<link rel="apple-touch-icon" sizes="${size}x${size}" href="${icon}">`)
|
||||||
}
|
}
|
||||||
|
|
||||||
let themeSpecific = [
|
let themeSpecific = [
|
||||||
|
@ -206,31 +275,32 @@ async function createIndexFor(theme: LayoutConfig) {
|
||||||
appendFileSync(filename, codeTemplate)
|
appendFileSync(filename, codeTemplate)
|
||||||
}
|
}
|
||||||
|
|
||||||
function createDir(path){
|
function createDir(path) {
|
||||||
if (!existsSync(path)) {
|
if (!existsSync(path)) {
|
||||||
mkdirSync(path)
|
mkdirSync(path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main(): Promise<void>{
|
async function main(): Promise<void> {
|
||||||
|
|
||||||
|
|
||||||
const alreadyWritten = []
|
const alreadyWritten = []
|
||||||
createDir("./assets/generated")
|
createDir("./assets/generated")
|
||||||
createDir("./assets/generated/layers")
|
createDir("./assets/generated/layers")
|
||||||
createDir("./assets/generated/themes")
|
createDir("./assets/generated/themes")
|
||||||
|
createDir("./assets/generated/images")
|
||||||
|
|
||||||
const blacklist = ["", "test", ".", "..", "manifest", "index", "land", "preferences", "account", "openstreetmap", "custom", "theme"]
|
const blacklist = ["", "test", ".", "..", "manifest", "index", "land", "preferences", "account", "openstreetmap", "custom", "theme"]
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const all: LayoutConfigJson[] = all_known_layouts.themes;
|
const all: LayoutConfigJson[] = all_known_layouts.themes;
|
||||||
const args = process.argv
|
const args = process.argv
|
||||||
const theme = args[2]
|
const theme = args[2]
|
||||||
if(theme !== undefined){
|
if (theme !== undefined) {
|
||||||
console.warn("Only generating layout "+theme)
|
console.warn("Only generating layout " + theme)
|
||||||
}
|
}
|
||||||
for (const i in all) {
|
for (const i in all) {
|
||||||
const layoutConfigJson: LayoutConfigJson = all[i]
|
const layoutConfigJson: LayoutConfigJson = all[i]
|
||||||
if(theme !== undefined && layoutConfigJson.id !== theme){
|
if (theme !== undefined && layoutConfigJson.id !== theme) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
const layout = new LayoutConfig(layoutConfigJson, true, "generating layouts")
|
const layout = new LayoutConfig(layoutConfigJson, true, "generating layouts")
|
||||||
|
@ -244,21 +314,20 @@ async function main(): Promise<void>{
|
||||||
console.log("Could not write manifest for ", layoutName, " because ", err)
|
console.log("Could not write manifest for ", layoutName, " because ", err)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
await createManifest(layout, alreadyWritten).then(manifObj => {
|
const {manifest, whiteIcons} = await createManifest(layout, alreadyWritten)
|
||||||
const manif = JSON.stringify(manifObj, undefined, 2);
|
const manif = JSON.stringify(manifest, undefined, 2);
|
||||||
const manifestLocation = encodeURIComponent(layout.id.toLowerCase()) + ".webmanifest";
|
const manifestLocation = encodeURIComponent(layout.id.toLowerCase()) + ".webmanifest";
|
||||||
writeFile(manifestLocation, manif, err);
|
writeFile(manifestLocation, manif, err);
|
||||||
|
|
||||||
// Create a landing page for the given theme
|
// Create a landing page for the given theme
|
||||||
createLandingPage(layout, manifObj).then(landing => {
|
createLandingPage(layout, manifest, whiteIcons, alreadyWritten).then(landing => {
|
||||||
writeFile(enc(layout.id) + ".html", landing, err)
|
writeFile(enc(layout.id) + ".html", landing, err)
|
||||||
});
|
});
|
||||||
createIndexFor(layout)
|
createIndexFor(layout)
|
||||||
}).catch(e => console.log("Could not generate the manifest: ", e))
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await createManifest(new LayoutConfig({
|
|
||||||
|
const {manifest, whiteIcons} = await createManifest(new LayoutConfig({
|
||||||
icon: "./assets/svg/mapcomplete_logo.svg",
|
icon: "./assets/svg/mapcomplete_logo.svg",
|
||||||
id: "index",
|
id: "index",
|
||||||
layers: [],
|
layers: [],
|
||||||
|
@ -270,10 +339,10 @@ async function main(): Promise<void>{
|
||||||
title: {en: "MapComplete"},
|
title: {en: "MapComplete"},
|
||||||
version: Constants.vNumber,
|
version: Constants.vNumber,
|
||||||
description: {en: "A thematic map viewer and editor based on OpenStreetMap"}
|
description: {en: "A thematic map viewer and editor based on OpenStreetMap"}
|
||||||
}), alreadyWritten).then(manifObj => {
|
}), alreadyWritten);
|
||||||
const manif = JSON.stringify(manifObj, undefined, 2);
|
|
||||||
writeFileSync("index.manifest", manif)
|
const manif = JSON.stringify(manifest, undefined, 2);
|
||||||
})
|
writeFileSync("index.manifest", manif)
|
||||||
}
|
}
|
||||||
|
|
||||||
main().then(() => {
|
main().then(() => {
|
||||||
|
|