Bugfixes, add A3 poster

This commit is contained in:
pietervdvn 2022-09-18 12:45:02 +02:00
parent 1f87728782
commit b912343805
14 changed files with 2933 additions and 439 deletions

View file

@ -191,6 +191,9 @@ export default class OverpassFeatureSource implements FeatureSource {
const self = this
const overpassUrls = self.state.overpassUrl.data
if(overpassUrls === undefined || overpassUrls.length === 0){
throw "Panic: overpassFeatureSource didn't receive any overpassUrls"
}
let bounds: BBox
do {
try {

View file

@ -14,7 +14,7 @@ export class Overpass {
private readonly _interpreterUrl: string
private readonly _timeout: Store<number>
private readonly _extraScripts: string[]
private _includeMeta: boolean
private readonly _includeMeta: boolean
private _relationTracker: RelationsTracker
constructor(

View file

@ -166,9 +166,9 @@ export default class FeatureSwitchState {
(layoutToUse?.overpassUrl ?? Constants.defaultOverpassUrls).join(","),
"Point mapcomplete to a different overpass-instance. Example: https://overpass-api.de/api/interpreter"
).sync(
(param) => param.split(","),
(param) => param?.split(","),
[],
(urls) => urls.join(",")
(urls) => urls?.join(",")
)
this.overpassTimeout = UIEventSource.asFloat(

View file

@ -6,11 +6,11 @@ import Hash from "./Hash"
import { Utils } from "../../Utils"
export class QueryParameters {
static defaults = {}
static defaults : Record<string, string> = {}
static documentation: Map<string, string> = new Map<string, string>()
private static order: string[] = ["layout", "test", "z", "lat", "lon"]
private static _wasInitialized: Set<string> = new Set()
private static knownSources = {}
protected static readonly _wasInitialized: Set<string> = new Set()
protected static readonly knownSources: Record<string, UIEventSource<string>> = {}
private static initialized = false
public static GetQueryParameter(
@ -105,14 +105,19 @@ export class QueryParameters {
}
if (!Utils.runningFromConsole) {
// Don't pollute the history every time a parameter changes
history.replaceState(null, "", "?" + parts.join("&") + Hash.Current())
try{
history.replaceState(null, "", "?" + parts.join("&") + Hash.Current())
}catch(e){
console.error(e)
}
}
}
static ClearAll() {
for (const name in QueryParameters.knownSources) {
QueryParameters.knownSources[name].setData("")
QueryParameters.knownSources[name].setData(undefined)
}
QueryParameters._wasInitialized.clear()
QueryParameters.order = []
}
}

View file

@ -119,6 +119,7 @@ export default class MinimapImplementation extends BaseUIElement implements Mini
public async TakeScreenshot(format: "blob"): Promise<Blob> ;
public async TakeScreenshot(format: "image" | "blob"): Promise<string | Blob> ;
public async TakeScreenshot(format: "image" | "blob" = "image"): Promise<string | Blob> {
console.log("Taking a screenshot...")
const screenshotter = new SimpleMapScreenshoter()
screenshotter.addTo(this.leafletMap.data)
const result = <any> await screenshotter.takeScreen((<any> format) ?? "image")

View file

@ -0,0 +1,272 @@
import Combine from "../Base/Combine";
import {FlowPanelFactory, FlowStep} from "../ImportFlow/FlowStep";
import {ImmutableStore, Store, UIEventSource} from "../../Logic/UIEventSource";
import {InputElement} from "../Input/InputElement";
import {SvgToPdf, SvgToPdfOptions} from "../../Utils/svgToPdf";
import {FixedInputElement} from "../Input/FixedInputElement";
import {FixedUiElement} from "../Base/FixedUiElement";
import FileSelectorButton from "../Input/FileSelectorButton";
import InputElementMap from "../Input/InputElementMap";
import {RadioButton} from "../Input/RadioButton";
import {Utils} from "../../Utils";
import {VariableUiElement} from "../Base/VariableUIElement";
import Loading from "../Base/Loading";
import BaseUIElement from "../BaseUIElement";
import Img from "../Base/Img";
import Title from "../Base/Title";
import CheckBoxes, {CheckBox} from "../Input/Checkboxes";
import Minimap from "../Base/Minimap";
import SearchAndGo from "./SearchAndGo";
import Toggle from "../Input/Toggle";
import List from "../Base/List";
import LeftIndex from "../Base/LeftIndex";
import Constants from "../../Models/Constants";
class SelectTemplate extends Combine implements FlowStep<{ title: string, pages: string[] }> {
readonly IsValid: Store<boolean>;
readonly Value: Store<{ title: string, pages: string[] }>;
constructor() {
const elements: InputElement<{ templateName: string, pages: string[] }>[] = []
for (const templateName in SvgToPdf.templates) {
const template = SvgToPdf.templates[templateName]
elements.push(new FixedInputElement(
new Combine([new FixedUiElement(templateName).SetClass("font-bold pr-2"),
template.description
])
, new UIEventSource({templateName, pages: template.pages})))
}
const file = new FileSelectorButton(new FixedUiElement("Select an svg image which acts as template"), {
acceptType: "image/svg+xml",
allowMultiple: true
})
const fileMapped = new InputElementMap<FileList, { templateName: string, pages: string[], fromFile: true }>(file, (x0, x1) => x0 === x1,
(filelist) => {
if (filelist === undefined) {
return undefined;
}
const pages = []
let templateName: string = undefined;
for (const file of Array.from(filelist)) {
if (templateName == undefined) {
templateName = file.name.substring(file.name.lastIndexOf("/") + 1)
templateName = templateName.substring(0, templateName.lastIndexOf("."))
}
pages.push(file.text())
}
return {
templateName,
pages,
fromFile: true
}
},
fromX => undefined
)
elements.push(fileMapped)
const radio = new RadioButton(elements, {selectFirstAsDefault: true})
const loaded: Store<{ success: { title: string, pages: string[] } } | { error: any }> = radio.GetValue().bind(template => {
if (template === undefined) {
return undefined
}
if (template["fromFile"]) {
return UIEventSource.FromPromiseWithErr(Promise.all(template.pages).then(pages => ({
title: template.templateName,
pages
})))
}
const urls = template.pages.map(p => SelectTemplate.ToUrl(p))
const dloadAll: Promise<{ title: string, pages: string[] }> = Promise.all(urls.map(url => Utils.download(url))).then(pages => ({
pages,
title: template.templateName
}))
return UIEventSource.FromPromiseWithErr(dloadAll)
})
const preview = new VariableUiElement(
loaded.map(pages => {
if (pages === undefined) {
return new Loading()
}
if (pages["err"] !== undefined) {
return new FixedUiElement("Loading preview failed: " + pages["err"]).SetClass("alert")
}
const svgs = pages["success"].pages
if (svgs.length === 0) {
return new FixedUiElement("No pages loaded...").SetClass("alert")
}
const els: BaseUIElement[] = []
for (const pageSrc of svgs) {
const el = new Img(pageSrc, true)
.SetClass("w-96 m-2 border-black border-2")
els.push(el)
}
return new Combine(els).SetClass("flex border border-subtle rounded-xl");
})
)
super([
new Title("Select template"),
radio,
new Title("Preview"),
preview
]);
this.Value = loaded.map(l => l === undefined ? undefined : l["success"])
this.IsValid = this.Value.map(v => v !== undefined)
}
public static ToUrl(spec: string) {
if (spec.startsWith("http")) {
return spec
}
return window.location.protocol + "//" + window.location.host + "/" + spec
}
}
class SelectPdfOptions extends Combine implements FlowStep<{ title: string, pages: string[], options: SvgToPdfOptions }> {
readonly IsValid: Store<boolean>;
readonly Value: Store<{ title: string, pages: string[], options: SvgToPdfOptions }>;
constructor(title: string, pages: string[], getFreeDiv: () => string) {
const dummy = new CheckBox("Don't add data to the map (to quickly preview the PDF)", false)
const overrideMapLocation = new CheckBox("Override map location: use a selected location instead of the location set in the template", false)
const locationInput = Minimap.createMiniMap().SetClass("block w-full")
const searchField = new SearchAndGo({leafletMap: locationInput.leafletMap})
const selectLocation =
new Combine([
new Toggle(new Combine([new Title("Select override location"), searchField]).SetClass("flex"), undefined, overrideMapLocation.GetValue()),
new Toggle(locationInput.SetStyle("height: 20rem"), undefined, overrideMapLocation.GetValue()).SetStyle("height: 20rem")
]).SetClass("block").SetStyle("height: 25rem")
super([new Title("Select options"),
dummy,
overrideMapLocation,
selectLocation
]);
this.Value = dummy.GetValue().map((disableMaps) => {
return {
pages,
title,
options: <SvgToPdfOptions>{
disableMaps,
getFreeDiv,
overrideLocation: overrideMapLocation.GetValue().data ? locationInput.location.data : undefined
}
}
}, [overrideMapLocation.GetValue(), locationInput.location])
this.IsValid = new ImmutableStore(true)
}
}
class PreparePdf extends Combine implements FlowStep<{ svgToPdf: SvgToPdf, languages: string[] }> {
readonly IsValid: Store<boolean>;
readonly Value: Store<{ svgToPdf: SvgToPdf, languages: string[] }>;
constructor(title: string, pages: string[], options: SvgToPdfOptions) {
const svgToPdf = new SvgToPdf(title, pages, options)
const languageOptions = [
new FixedInputElement("Nederlands", "nl"),
new FixedInputElement("English", "en")
]
const languages = new CheckBoxes(languageOptions)
const isPrepared = UIEventSource.FromPromiseWithErr(svgToPdf.Prepare())
super([
new Title("Select languages..."),
languages,
new Toggle(
new Loading("Preparing maps..."),
undefined,
isPrepared.map(p => p === undefined)
)
]);
this.Value = isPrepared.map(isPrepped => {
if (isPrepped === undefined) {
return undefined
}
if (isPrepped["success"] !== undefined) {
const svgToPdf = isPrepped["success"]
const langs = languages.GetValue().data.map(i => languageOptions[i].GetValue().data)
if (langs.length === 0) {
return undefined
}
return {svgToPdf, languages: langs}
}
return undefined;
}, [languages.GetValue()])
this.IsValid = this.Value.map(v => v !== undefined)
}
}
class SavePdf extends Combine {
constructor(svgToPdf: SvgToPdf, languages: string[]) {
super([
new Title("Generating your pdfs..."),
new List(languages.map(lng => new Toggle(
lng + " is done!",
new Loading("Creating pdf for " + lng),
UIEventSource.FromPromiseWithErr(svgToPdf.ConvertSvg(lng).then(() => true))
.map(x => x !== undefined && x["success"] === true)
)))
]);
}
}
export class PdfExportGui extends LeftIndex {
constructor(freeDivId: string) {
let i = 0
const createDiv = (): string => {
const div = document.createElement("div")
div.id = "freediv-" + (i++)
document.getElementById(freeDivId).append(div)
return div.id
}
Constants.defaultOverpassUrls.splice(0, 1)
const {flow, furthestStep, titles} = FlowPanelFactory.start(
new Title("Select template"), new SelectTemplate()
).then(new Title("Select options"), ({title, pages}) => new SelectPdfOptions(title, pages, createDiv))
.then("Generate maps...", ({title, pages, options}) => new PreparePdf(title, pages, options))
.finish("Generating...", ({svgToPdf, languages}) => new SavePdf(svgToPdf, languages))
const toc = new List(
titles.map(
(title, i) =>
new VariableUiElement(
furthestStep.map((currentStep) => {
if (i > currentStep) {
return new Combine([title]).SetClass("subtle")
}
if (i == currentStep) {
return new Combine([title]).SetClass("font-bold")
}
if (i < currentStep) {
return title
}
})
)
),
true
)
const leftContents: BaseUIElement[] = [
toc
].map((el) => el?.SetClass("pl-4"))
super(leftContents, flow)
}
}

View file

@ -96,12 +96,10 @@ export class PngMapCreator {
})
await Utils.waitFor(2000)
}
minimap.TakeScreenshot(format).then(result => {
minimap.TakeScreenshot(format).then(async result => {
const divId = this._options.divId
window.setTimeout(() => {
await Utils.waitFor(250)
document.getElementById(divId).removeChild(/*Will fetch the cached htmlelement:*/minimap.ConstructElement())
}, 500)
return resolve(result);
}).catch(failreason => {
console.error("Could no make a screenshot due to ",failreason)

View file

@ -13,6 +13,7 @@ import {Utils} from "../Utils";
import Locale from "../UI/i18n/Locale";
import Constants from "../Models/Constants";
import Hash from "../Logic/Web/Hash";
import {QueryParameters} from "../Logic/Web/QueryParameters";
class SvgToPdfInternals {
private readonly doc: jsPDF;
@ -213,7 +214,7 @@ class SvgToPdfInternals {
private extractTranslation(text: string) {
if(text === "$version"){
return new Date().toISOString().substring("2022-01-02THH:MM".length )+" - v"+Constants.vNumber
return new Date().toISOString().substring(0, "2022-01-02THH:MM".length )+" - v"+Constants.vNumber
}
const pathPart = text.match(/\$(([_a-zA-Z0-9?]+\.)+[_a-zA-Z0-9?]+)(.*)/)
if (pathPart === null) {
@ -289,33 +290,57 @@ class SvgToPdfInternals {
this.doc.setFontSize(fontsize * 2.5)
let textTemplate = tspan.textContent.split(" ")
let result: string[] = []
let result: string = ""
let addSpace = false
for (let text of textTemplate) {
if (!text.startsWith("$")) {
result.push(text)
if(text === "\\n"){
result += "\n"
addSpace = false
continue
}
if (text.startsWith("$list(")) {
text = text.substring("$list(".length, text.length - ")".length)
result.push("\n")
let r = this.extractTranslation("$" + text + "0");
let i = 0
while (r !== undefined && i < 100) {
result.push("• " + r + "\n")
i++
r = this.extractTranslation("$" + text + i);
if(text === "\\n\\n"){
result += "\n\n"
addSpace = false
continue
}
if (!text.startsWith("$")) {
if(addSpace){
result += " "
}
result += text
addSpace = true
continue
}
const list = text.match(/\$list\(([a-zA-Z0-9_.-]+)\)/)
if (list) {
const key = list[1]
console.log("Generating a list with key" + key)
let r = this.extractTranslation("$" + key + "0");
let i = 0
result += "\n"
while (r !== undefined && i < 100) {
result += "• " + r + "\n"
i++
r = this.extractTranslation("$" + key + i);
}
result += "\n"
addSpace = false
} else {
const found = this.extractTranslation(text) ?? text
result.push(found)
if(addSpace){
result += " "
}
result += found
addSpace = true
}
}
this.doc.text(result.join(" "), x, y, {
this.doc.text(result, x, y, {
maxWidth,
}, this.currentMatrix)
}
private drawSvgViaCanvas(element: Element): void {
@ -649,7 +674,7 @@ export class SvgToPdfPage {
console.error("Could not show map with parameters", params)
throw "Theme not found:" + params["theme"] + ". Use theme: to define which theme to use. "
}
layout.widenFactor = 0
layout.widenFactor = 0
layout.overpassTimeout = 600
layout.defaultBackgroundId = params["background"] ?? layout.defaultBackgroundId
for (const paramsKey in params) {
@ -669,7 +694,7 @@ export class SvgToPdfPage {
const zoom = Number(params["zoom"] ?? params["z"] ?? 14);
Hash.hash.setData(undefined)
history.replaceState(null, "", "")
// QueryParameters.ClearAll()
const state = new FeaturePipelineState(layout)
state.locationControl.setData({
@ -678,6 +703,8 @@ export class SvgToPdfPage {
lon: this.options?.overrideLocation?.lon ?? Number(params["lon"] ?? 3.717842)
})
console.log("Params are", params, params["layers"]==="none")
const fl = state.filteredLayers.data
for (const filteredLayer of fl) {
if (params["layer-" + filteredLayer.layerDef.id] !== undefined) {
@ -783,7 +810,7 @@ export class SvgToPdf {
public static readonly templates : Record<string, {pages: string[], description: string | Translation}>= {
flyer_a4:{pages: ["/assets/templates/MapComplete-flyer.svg","/assets/templates/MapComplete-flyer.back.svg"], description: Translations.t.flyer.description},
poster_a2: {pages: ["/assets/templates/MapComplete-poster-a2.svg"], description: "A basic A2 poster (similar to the flyer)"}
poster_a3: {pages: ["/assets/templates/MapComplete-poster-a3.svg"], description: "A basic A3 poster (similar to the flyer)"}
}
private readonly _title: string;

View file

@ -26,9 +26,9 @@
showgrid="false"
showguides="true"
inkscape:guide-bbox="true"
inkscape:zoom="2.0156476"
inkscape:cx="420.46041"
inkscape:cy="393.42195"
inkscape:zoom="3.2396737"
inkscape:cx="234.12852"
inkscape:cy="507.61285"
inkscape:window-width="1920"
inkscape:window-height="1007"
inkscape:window-x="0"
@ -416,6 +416,12 @@
width="296.10439"
height="80.904815"
id="rect28360" />
<rect
x="28.759502"
y="661.40118"
width="286.60455"
height="141.05191"
id="rect56707" />
</defs>
<g
inkscape:groupmode="layer"
@ -453,14 +459,14 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect21432-8);display:inline;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.264848;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"><tspan
x="28.759766"
y="697.7954"
id="tspan8299"><tspan
id="tspan32787"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8297">$map(theme:aed,z:14,lat:</tspan></tspan><tspan
id="tspan32785">$map(theme:aed,z:14,lat:</tspan></tspan><tspan
x="28.759766"
y="747.7954"
id="tspan8303"><tspan
id="tspan32791"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8301">51.2098,lon:3.2284)</tspan></tspan></text>
id="tspan32789">51.2098,lon:3.2284)</tspan></tspan></text>
<text
xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,1.3325782,-88.396258)"
@ -468,45 +474,39 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect13433);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="28.759766"
y="697.7954"
id="tspan8307"><tspan
id="tspan32795"><tspan
style="font-size:16px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8305">$flyer.toerisme_vlaanderen</tspan></tspan></text>
id="tspan32793">$flyer.toerisme_vlaanderen</tspan></tspan></text>
<rect
style="fill:#deadff;fill-opacity:1;stroke:#000000;stroke-width:0.0182753;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect11121"
width="90.0849"
height="80.149857"
x="5.3507514"
y="122.62533" />
style="display:inline;fill:#deadff;fill-opacity:1;stroke:#000000;stroke-width:0.0224792;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect11121-7"
width="88.887001"
height="79.970268"
x="5.4906716"
y="123.10045" />
<text
xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,3.1668997,-43.500981)"
id="text17151"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect17153);fill:#000000;fill-opacity:1;stroke:none"><tspan
transform="matrix(0.26458333,0,0,0.26458333,5.7370355,-43.141658)"
id="text56705"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect56707);display:inline;fill:#000000;fill-opacity:1;stroke:none"><tspan
x="28.759766"
y="677.7954"
id="tspan8311"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8309">$map(theme:toerisme_vlaandere</tspan></tspan><tspan
id="tspan32799"><tspan
style="font-size:13.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan32797">$map(theme:toerisme_vlaanderen,lat:</tspan></tspan><tspan
x="28.759766"
y="691.20604"
id="tspan8317"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8313">n,layers:none</tspan><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8315">,layer-</tspan></tspan><tspan
y="692.05876"
id="tspan32805"><tspan
style="font-size:13.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan32801">50.8552,lon:4.3156, </tspan><tspan
style="font-size:13.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan32803">z:10,layers:none,
</tspan></tspan><tspan
x="28.759766"
y="704.61669"
id="tspan8321"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8319">charging_station_ebikes:force,lat:</tspan></tspan><tspan
x="28.759766"
y="718.02733"
id="tspan8327"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8323">50.8552</tspan><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8325">,lon:4.3156, z:10)</tspan></tspan></text>
y="706.32213"
id="tspan32809"><tspan
style="font-size:13.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan32807">layer-charging_station_ebikes:force)</tspan></tspan></text>
<rect
style="fill:#cccccc;fill-opacity:1;stroke:#000000;stroke-width:0.0161075;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect11459"
@ -521,34 +521,36 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect21432);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="28.759766"
y="677.7954"
id="tspan8331"><tspan
id="tspan32813"><tspan
style="font-size:13.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8329">$map(theme:cyclofix,z:14,lat:51.05016,lon:</tspan></tspan><tspan
id="tspan32811">$map(theme:cyclofix,z:14,lat:51.05016,lon:</tspan></tspan><tspan
x="28.759766"
y="692.05876"
id="tspan8335"><tspan
id="tspan32817"><tspan
style="font-size:13.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8333">3.717842,layers:none,layer-</tspan></tspan><tspan
id="tspan32815">3.717842,layers:none,layer-</tspan></tspan><tspan
x="28.759766"
y="706.32213"
id="tspan8339"><tspan
id="tspan32821"><tspan
style="font-size:13.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8337">bike_repair_station:true,layer-</tspan></tspan><tspan
id="tspan32819">bike_repair_station:true,layer-</tspan></tspan><tspan
x="28.759766"
y="720.5855"
id="tspan8343"><tspan
id="tspan32827"><tspan
style="font-size:13.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8341">drinking_water:true,layer-</tspan></tspan><tspan
id="tspan32823">drinking_water:true,layer-</tspan><tspan
style="font-size:13.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan32825">bike_cafe:true, </tspan></tspan><tspan
x="28.759766"
y="734.84886"
id="tspan8347"><tspan
id="tspan32831"><tspan
style="font-size:13.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8345">bike_cafe:true,layer-</tspan></tspan><tspan
id="tspan32829">layer-charging_station_ebikes:false,layer-</tspan></tspan><tspan
x="28.759766"
y="749.11223"
id="tspan8351"><tspan
id="tspan32835"><tspan
style="font-size:13.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8349">bicycle_tube_vending_machine: true)</tspan></tspan></text>
id="tspan32833">bicycle_tube_vending_machine: true)</tspan></tspan></text>
<rect
style="fill:#733034;fill-opacity:1;stroke:#000000;stroke-width:0.0661458;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect11543"
@ -570,14 +572,14 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;white-space:pre;shape-inside:url(#rect20457);display:inline;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.264848;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"><tspan
x="28.759766"
y="697.7954"
id="tspan8355"><tspan
id="tspan32839"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8353">$map(theme:artwork,z:15,lat:51.2098,lon:</tspan></tspan><tspan
id="tspan32837">$map(theme:artwork,z:15,lat:51.2098,lon:</tspan></tspan><tspan
x="28.759766"
y="747.7954"
id="tspan8359"><tspan
id="tspan32843"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8357">3.2284,background:AGIV)</tspan></tspan></text>
id="tspan32841">3.2284,background:AGIV)</tspan></tspan></text>
<rect
style="fill:#cccccc;fill-opacity:1;stroke:#000000;stroke-width:0.0700743;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect11647"
@ -592,19 +594,19 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect3239);display:inline;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.264848;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"><tspan
x="28.759766"
y="697.7954"
id="tspan8363"><tspan
id="tspan32847"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8361">$map(theme:cyclestreets,</tspan></tspan><tspan
id="tspan32845">$map(theme:cyclestreets,</tspan></tspan><tspan
x="28.759766"
y="747.7954"
id="tspan8367"><tspan
id="tspan32851"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8365">z:15,lat:51.02702,lon:</tspan></tspan><tspan
id="tspan32849">z:15,lat:51.02702,lon:</tspan></tspan><tspan
x="28.759766"
y="797.7954"
id="tspan8371"><tspan
id="tspan32855"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8369">4.48029, scaling:3)</tspan></tspan></text>
id="tspan32853">4.48029, scaling:3)</tspan></tspan></text>
<g
id="g1367"
transform="matrix(-1,0,-0.20502864,-1,112.68819,218.91305)">
@ -637,14 +639,14 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect890);display:inline;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.264848;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"><tspan
x="28.759766"
y="697.7954"
id="tspan8375"><tspan
id="tspan32859"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8373">$map(theme:benches,z:14,lat:51.2098,lon:</tspan></tspan><tspan
id="tspan32857">$map(theme:benches,z:14,lat:51.2098,lon:</tspan></tspan><tspan
x="28.759766"
y="747.7954"
id="tspan8379"><tspan
id="tspan32863"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8377">3.2284, layers:none, layer-bench:force)</tspan></tspan></text>
id="tspan32861">3.2284, layers:none, layer-bench:force)</tspan></tspan></text>
<text
xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,205.99418,0.58092297)"
@ -652,19 +654,19 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect6468);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="28.759766"
y="697.7954"
id="tspan8383"><tspan
id="tspan32867"><tspan
style="font-size:16px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8381">$flyer.aerial</tspan></tspan></text>
id="tspan32865">$flyer.aerial</tspan></tspan></text>
<text
xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,-1.7998979,-153.42245)"
transform="matrix(0.26458333,0,0,0.26458333,-1.7998979,-158.2795)"
id="text3510"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect3512);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="28.759766"
y="697.7954"
id="tspan8387"><tspan
id="tspan32871"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8385">$flyer.examples</tspan></tspan></text>
id="tspan32869">$flyer.examples</tspan></tspan></text>
<g
id="path15616"
transform="matrix(-1,0,0,1,497.66957,-0.86523396)">
@ -732,9 +734,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect5917);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="28.759766"
y="697.7954"
id="tspan8391"><tspan
id="tspan32875"><tspan
style="font-size:16px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8389">$flyer.lines_too</tspan></tspan></text>
id="tspan32873">$flyer.lines_too</tspan></tspan></text>
<rect
style="fill:#cccccc;fill-opacity:1;stroke:#000000;stroke-width:0.0161075;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect5197"
@ -749,26 +751,26 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect5203);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="28.759766"
y="677.7954"
id="tspan8395"><tspan
id="tspan32879"><tspan
style="font-size:13.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8393">$map(theme:onwheels,z:19,lat:50.86622,lon:</tspan></tspan><tspan
id="tspan32877">$map(theme:onwheels,z:19,lat:50.86622,lon:</tspan></tspan><tspan
x="28.759766"
y="692.05876"
id="tspan8401"><tspan
id="tspan32885"><tspan
style="font-size:13.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8397">4.35012</tspan><tspan
id="tspan32881">4.35012</tspan><tspan
style="font-size:13.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8399">,layer-governments:false,layer-</tspan></tspan><tspan
id="tspan32883">,layer-governments:false,layer-</tspan></tspan><tspan
x="28.759766"
y="706.32213"
id="tspan8405"><tspan
id="tspan32889"><tspan
style="font-size:13.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8403">parking:false,layer-toilet:false,layer-</tspan></tspan><tspan
id="tspan32887">parking:false,layer-toilet:false,layer-</tspan></tspan><tspan
x="28.759766"
y="720.5855"
id="tspan8409"><tspan
id="tspan32893"><tspan
style="font-size:13.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8407">cafe_pub:false,layer-food:false,scaling:1.5)</tspan></tspan></text>
id="tspan32891">cafe_pub:false,layer-food:false,scaling:1.5)</tspan></tspan></text>
<text
xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,99.365194,-41.995408)"
@ -776,9 +778,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect23050);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="28.759766"
y="677.7954"
id="tspan8413"><tspan
id="tspan32897"><tspan
style="font-size:16px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8411">$flyer.onwheels</tspan></tspan></text>
id="tspan32895">$flyer.onwheels</tspan></tspan></text>
<g
id="g23048"
transform="matrix(0.99953426,0.03051675,0.2354499,-0.99327745,75.052107,241.32304)">
@ -811,9 +813,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect28360);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="28.759766"
y="677.7954"
id="tspan8417"><tspan
id="tspan32901"><tspan
style="font-size:16px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8415">$flyer.cyclofix</tspan></tspan></text>
id="tspan32899">$flyer.cyclofix</tspan></tspan></text>
<text
xml:space="preserve"
transform="matrix(0,-0.26458333,0.26458333,0,165.86686,413.77896)"
@ -821,9 +823,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0;font-family:sans-serif;white-space:pre;shape-inside:url(#rect4214);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="1082.1387"
y="452.37548"
id="tspan8421"><tspan
id="tspan32905"><tspan
style="font-size:8px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan8419">$version</tspan></tspan></text>
id="tspan32903">$version</tspan></tspan></text>
<g
id="g7940"
transform="matrix(0.97797993,0.20869898,-0.00818509,1.0207692,100.41144,13.334379)">
@ -883,9 +885,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect135032);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="8.7285156"
y="42.098132"
id="tspan8425"><tspan
id="tspan32909"><tspan
style="font-weight:bold;font-size:34.6667px;-inkscape-font-specification:'sans-serif, Bold'"
id="tspan8423">$flyer.title</tspan></tspan></text>
id="tspan32907">$flyer.title</tspan></tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.5833px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

View file

@ -26,9 +26,9 @@
showgrid="false"
showguides="true"
inkscape:guide-bbox="true"
inkscape:zoom="1.0625506"
inkscape:cx="677.14423"
inkscape:cy="419.74472"
inkscape:zoom="1.2588311"
inkscape:cx="425.39465"
inkscape:cy="693.10333"
inkscape:window-width="1920"
inkscape:window-height="1007"
inkscape:window-x="0"
@ -373,7 +373,7 @@
<rect
x="381.53312"
y="90.109134"
width="349.47661"
width="352.78406"
height="154.40214"
id="rect214922" />
<rect
@ -490,9 +490,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.75;font-family:sans-serif;white-space:pre;shape-inside:url(#rect45500);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="27.585938"
y="594.75243"
id="tspan9088"><tspan
id="tspan7259"><tspan
style="font-size:20px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9086">$flyer.frontParagraph</tspan></tspan></text>
id="tspan7257">$flyer.frontParagraph</tspan></tspan></text>
<text
xml:space="preserve"
transform="scale(0.26458333)"
@ -516,9 +516,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect61742);fill:#d4f1f4;fill-opacity:1;stroke:none"><tspan
x="11.105469"
y="116.27391"
id="tspan9092"><tspan
id="tspan7263"><tspan
style="font-weight:bold;font-size:26.6667px;-inkscape-font-specification:'sans-serif, Bold'"
id="tspan9090">$flyer.tagline</tspan></tspan></text>
id="tspan7261">$flyer.tagline</tspan></tspan></text>
<text
xml:space="preserve"
transform="scale(0.26458333)"
@ -531,7 +531,7 @@
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:32px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;white-space:pre;shape-inside:url(#rect135032);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="8.7285156"
y="34.819131"
id="tspan9094">$flyer.title</tspan></text>
id="tspan7265">$flyer.title</tspan></text>
<text
xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,97.529993,-16.582379)"
@ -539,9 +539,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect61742-2);display:inline;fill:#d4f1f4;fill-opacity:1;stroke:none"><tspan
x="11.105469"
y="116.27391"
id="tspan9098"><tspan
id="tspan7269"><tspan
style="font-weight:bold;font-size:32px;-inkscape-font-specification:'sans-serif, Bold';fill:#000000"
id="tspan9096">$flyer.whatIsOsm</tspan></tspan></text>
id="tspan7267">$flyer.whatIsOsm</tspan></tspan></text>
<image
width="55.363865"
height="21.384291"
@ -558,9 +558,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect20620);fill:#d4f1f4;fill-opacity:1;stroke:none"><tspan
x="11.105469"
y="116.27391"
id="tspan9102"><tspan
id="tspan7273"><tspan
style="font-weight:bold;font-size:26.6667px;-inkscape-font-specification:'sans-serif, Bold'"
id="tspan9100">$flyer.mapcomplete.title</tspan></tspan></text>
id="tspan7271">$flyer.mapcomplete.title</tspan></tspan></text>
<text
xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,93.634029,-58.617677)"
@ -568,69 +568,69 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.75;font-family:sans-serif;white-space:pre;shape-inside:url(#rect21926);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="27.585938"
y="594.75243"
id="tspan9106"><tspan
id="tspan7277"><tspan
style="font-size:17.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9104">$flyer.mapcomplete.intro
id="tspan7275">$fmc.intro \n $list(fmc.li)
</tspan></tspan><tspan
x="27.585938"
y="624.75243"
id="tspan9110"><tspan
id="tspan7281"><tspan
style="font-size:17.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9108">
id="tspan7279">
</tspan></tspan><tspan
x="27.585938"
y="654.75243"
id="tspan9114"><tspan
id="tspan7285"><tspan
style="font-size:17.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9112">$list(flyer.mapcomplete.li)
id="tspan7283">
</tspan></tspan><tspan
x="27.585938"
y="684.75243"
id="tspan9118"><tspan
id="tspan7289"><tspan
style="font-size:17.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9116">
id="tspan7287">
</tspan></tspan><tspan
x="27.585938"
y="714.75243"
id="tspan9122"><tspan
id="tspan7293"><tspan
style="font-size:17.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9120">
id="tspan7291">
</tspan></tspan><tspan
x="27.585938"
y="744.75243"
id="tspan9126"><tspan
id="tspan7297"><tspan
style="font-size:17.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9124">
id="tspan7295">
</tspan></tspan><tspan
x="27.585938"
y="774.75243"
id="tspan9130"><tspan
id="tspan7301"><tspan
style="font-size:17.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9128">
id="tspan7299">
</tspan></tspan><tspan
x="27.585938"
y="804.75243"
id="tspan9134"><tspan
id="tspan7305"><tspan
style="font-size:17.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9132">
id="tspan7303">
</tspan></tspan><tspan
x="27.585938"
y="834.75243"
id="tspan9138"><tspan
id="tspan7309"><tspan
style="font-size:17.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9136">
id="tspan7307">
</tspan></tspan><tspan
x="27.585938"
y="864.75243"
id="tspan9142"><tspan
id="tspan7313"><tspan
style="font-size:17.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9140">
id="tspan7311">
</tspan></tspan><tspan
x="27.585938"
y="894.75243"
id="tspan9146"><tspan
id="tspan7317"><tspan
style="font-weight:bold;font-size:17.3333px;-inkscape-font-specification:'sans-serif, Bold'"
id="tspan9144">$flyer.mapcomplete.customize</tspan></tspan></text>
id="tspan7315">$fmc.customize</tspan></tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.5833px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
@ -689,17 +689,17 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.75;font-family:sans-serif;white-space:pre;shape-inside:url(#rect169564);display:inline;fill:#000000;fill-opacity:1;stroke:none"><tspan
x="27.585938"
y="594.75243"
id="tspan9152"><tspan
id="tspan7323"><tspan
style="font-weight:bold;font-size:24px;-inkscape-font-specification:'sans-serif, Bold'"
id="tspan9148">$flyer.callToAction</tspan><tspan
id="tspan7319">$flyer.callToAction</tspan><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9150">
id="tspan7321">
</tspan></tspan><tspan
x="27.585938"
y="624.75243"
id="tspan9156"><tspan
id="tspan7327"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9154"> </tspan></tspan></text>
id="tspan7325"> </tspan></tspan></text>
<text
xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,-0.23977866,-9.5462662)"
@ -707,9 +707,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect171375);display:inline;fill:#000000;fill-opacity:1;stroke:none"><tspan
x="381.5332"
y="126.50438"
id="tspan9160"><tspan
id="tspan7331"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9158">$flyer.osm</tspan></tspan></text>
id="tspan7329">$flyer.osm</tspan></tspan></text>
<text
xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,2.1333012,-21.220244)"
@ -717,9 +717,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect111721);fill:#d4f1f4;fill-opacity:1;stroke:none"><tspan
x="11.105469"
y="116.27391"
id="tspan9164"><tspan
id="tspan7335"><tspan
style="font-weight:bold;font-size:26.6667px;-inkscape-font-specification:'sans-serif, Bold'"
id="tspan9162">$flyer.editing.title</tspan></tspan></text>
id="tspan7333">$flyer.editing.title</tspan></tspan></text>
<text
xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,-95.490982,-6.8838542)"
@ -727,9 +727,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect214922);display:inline;fill:#000000;fill-opacity:1;stroke:none"><tspan
x="381.5332"
y="126.50438"
id="tspan9168"><tspan
id="tspan7339"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9166">$flyer.editing.intro</tspan></tspan></text>
id="tspan7337">$flyer.editing.intro \n\n $flyer.editing.ex</tspan></tspan></text>
</g>
<g
inkscape:groupmode="layer"
@ -776,45 +776,51 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.45;font-family:sans-serif;white-space:pre;shape-inside:url(#rect14034);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="7.6972656"
y="-104.42726"
id="tspan9172"><tspan
id="tspan7343"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9170">$import layer.nature_reserve as nr
id="tspan7341">$import layer.nature_reserve as nr
</tspan></tspan><tspan
x="7.6972656"
y="-85.149922"
id="tspan9176"><tspan
id="tspan7347"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9174">$import layer.nature_reserve.tagRenderings.Dogs? as nrd
id="tspan7345">$import layer.nature_reserve.tagRenderings.Dogs? as nrd
</tspan></tspan><tspan
x="7.6972656"
y="-65.872586"
id="tspan9180"><tspan
id="tspan7351"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9178">$import layer.nature_reserve.tagRenderings.Access tag as nra
id="tspan7349">$import layer.nature_reserve.tagRenderings.Access tag as nra
</tspan></tspan><tspan
x="7.6972656"
y="-46.59525"
id="tspan9184"><tspan
id="tspan7355"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9182">$import layer.nature_reserve.tagRenderings.Surface area as nrsa
id="tspan7353">$import layer.nature_reserve.tagRenderings.Surface area as nrsa
</tspan></tspan><tspan
x="7.6972656"
y="-27.317914"
id="tspan9188"><tspan
id="tspan7359"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9186">$import flyer.fakeui as fui
id="tspan7357">$import flyer.fakeui as fui
</tspan></tspan><tspan
x="7.6972656"
y="-8.0405798"
id="tspan9192"><tspan
id="tspan7363"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9190">$import general as g
id="tspan7361">$import flyer.mapcomplete as fmc
</tspan></tspan><tspan
x="7.6972656"
y="11.236754"
id="tspan9196"><tspan
id="tspan7367"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9194">$set(_surface:ha, 13.2)
id="tspan7365">$import general as g
</tspan></tspan><tspan
x="7.6972656"
y="30.514089"
id="tspan7371"><tspan
style="font-size:18.6667px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan7369">$set(_surface:ha, 13.2)
</tspan></tspan></text>
<image
width="57.702705"
@ -877,9 +883,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.15;font-family:sans-serif;white-space:pre;shape-inside:url(#rect30576);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="854.50391"
y="305.80712"
id="tspan9200"><tspan
id="tspan7375"><tspan
style="font-size:16px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9198">$image.addPicture</tspan></tspan></text>
id="tspan7373">$image.addPicture</tspan></tspan></text>
<rect
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.284055;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:20;stroke-dasharray:none;stroke-opacity:1"
id="rect71653"
@ -907,9 +913,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect89979);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="1032.8457"
y="190.16259"
id="tspan9204"><tspan
id="tspan7379"><tspan
style="font-weight:bold;font-size:13.3333px;-inkscape-font-specification:'sans-serif, Bold';fill:#ff0000"
id="tspan9202">$fui.add_images</tspan></tspan></text>
id="tspan7377">$fui.add_images</tspan></tspan></text>
<g
id="g92580"
transform="matrix(-0.69752475,-0.7165607,0.57354815,-0.8444402,16.089563,191.00078)"
@ -945,9 +951,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect108073);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="1032.8457"
y="190.16259"
id="tspan9208"><tspan
id="tspan7383"><tspan
style="font-weight:bold;font-size:13.3333px;-inkscape-font-specification:'sans-serif, Bold';fill:#ff0000"
id="tspan9206">$fui.see_images</tspan></tspan></text>
id="tspan7381">$fui.see_images</tspan></tspan></text>
<image
preserveAspectRatio="none"
inkscape:svg-dpi="96"
@ -991,9 +997,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect216807);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="1032.8457"
y="190.16259"
id="tspan9212"><tspan
id="tspan7387"><tspan
style="font-weight:bold;font-size:13.3333px;-inkscape-font-specification:'sans-serif, Bold';fill:#ff0000"
id="tspan9210">$fui.wikipedia</tspan></tspan></text>
id="tspan7385">$fui.wikipedia</tspan></tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.5833px;line-height:0.7;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.265;stroke-miterlimit:20;stroke-dasharray:none"
@ -1016,9 +1022,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.15;font-family:sans-serif;white-space:pre;shape-inside:url(#rect225337);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="854.50391"
y="305.80712"
id="tspan9216"><tspan
id="tspan7391"><tspan
style="font-size:16px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9214">$nra.mappings.0.then</tspan></tspan></text>
id="tspan7389">$nra.mappings.0.then</tspan></tspan></text>
<image
preserveAspectRatio="none"
inkscape:svg-dpi="96"
@ -1039,9 +1045,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.15;font-family:sans-serif;white-space:pre;shape-inside:url(#rect230739);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="854.50391"
y="305.80712"
id="tspan9220"><tspan
id="tspan7395"><tspan
style="font-size:16px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9218">$nrsa.render</tspan></tspan></text>
id="tspan7393">$nrsa.render</tspan></tspan></text>
<text
xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,-206.41628,69.858951)"
@ -1049,9 +1055,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect246777);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="1032.8457"
y="190.16259"
id="tspan9224"><tspan
id="tspan7399"><tspan
style="font-weight:bold;font-size:13.3333px;-inkscape-font-specification:'sans-serif, Bold';fill:#ff0000"
id="tspan9222">$fui.attributes</tspan></tspan></text>
id="tspan7397">$fui.attributes</tspan></tspan></text>
<text
xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,-206.15705,87.121482)"
@ -1059,9 +1065,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect251315);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="1032.8457"
y="190.16259"
id="tspan9228"><tspan
id="tspan7403"><tspan
style="font-weight:bold;font-size:13.3333px;-inkscape-font-specification:'sans-serif, Bold';fill:#ff0000"
id="tspan9226">$fui.edit
id="tspan7401">$fui.edit
</tspan></tspan></text>
<text
xml:space="preserve"
@ -1070,9 +1076,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.15;font-family:sans-serif;white-space:pre;shape-inside:url(#rect256692);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="854.50391"
y="305.80712"
id="tspan9232"><tspan
id="tspan7407"><tspan
style="font-size:16px;-inkscape-font-specification:'sans-serif, Normal';fill:#0000e2"
id="tspan9230">www.example.org/nature</tspan></tspan></text>
id="tspan7405">www.example.org/nature</tspan></tspan></text>
<image
preserveAspectRatio="none"
inkscape:svg-dpi="96"
@ -1158,9 +1164,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.15;font-family:sans-serif;white-space:pre;shape-inside:url(#rect277342);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="854.50391"
y="305.80712"
id="tspan9236"><tspan
id="tspan7411"><tspan
style="font-size:12px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9234">$g.wikipedia.fromWikipedia</tspan></tspan></text>
id="tspan7409">$g.wikipedia.fromWikipedia</tspan></tspan></text>
<rect
style="fill:#dddddd;fill-opacity:1;stroke:none;stroke-width:0.4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect288579"
@ -1312,9 +1318,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect289465);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="1032.8457"
y="190.16259"
id="tspan9240"><tspan
id="tspan7415"><tspan
style="font-weight:bold;font-size:13.3333px;-inkscape-font-specification:'sans-serif, Bold';fill:#ff0000"
id="tspan9238">$fui.question</tspan></tspan></text>
id="tspan7413">$fui.question</tspan></tspan></text>
<g
id="g289463"
transform="matrix(-0.23283267,0.97251682,0.92477942,0.43222644,-27.808776,134.07207)"
@ -1415,9 +1421,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.1;font-family:sans-serif;white-space:pre;shape-inside:url(#rect132688);fill:#ffffff;fill-opacity:1;stroke:none"><tspan
x="883.77344"
y="652.63329"
id="tspan9244"><tspan
id="tspan7419"><tspan
style="font-weight:bold;font-size:13.3333px;-inkscape-font-specification:'sans-serif, Bold'"
id="tspan9242">$general.save</tspan></tspan></text>
id="tspan7417">$general.save</tspan></tspan></text>
<text
xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,-9.21118,20.980622)"
@ -1430,9 +1436,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.15;font-family:sans-serif;white-space:pre;shape-inside:url(#rect152029);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="773.85742"
y="628.17821"
id="tspan9248"><tspan
id="tspan7423"><tspan
style="font-weight:bold;font-size:18.6667px;-inkscape-font-specification:'sans-serif, Bold'"
id="tspan9246">$nrd.question</tspan></tspan></text>
id="tspan7421">$nrd.question</tspan></tspan></text>
<text
xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,-191.88164,14.564459)"
@ -1440,21 +1446,21 @@
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:1.15;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;white-space:pre;shape-inside:url(#rect159507);fill:#000000;fill-opacity:1;stroke:none"><tspan
x="773.85742"
y="627.54121"
id="tspan9252"><tspan
id="tspan7427"><tspan
style="font-size:13.3333px"
id="tspan9250">$nrd.mappings.0.then
id="tspan7425">$nrd.mappings.0.then
</tspan></tspan><tspan
x="773.85742"
y="645.94123"
id="tspan9256"><tspan
id="tspan7431"><tspan
style="font-size:13.3333px"
id="tspan9254">$nrd.mappings.1.then
id="tspan7429">$nrd.mappings.1.then
</tspan></tspan><tspan
x="773.85742"
y="664.34125"
id="tspan9260"><tspan
id="tspan7435"><tspan
style="font-size:13.3333px"
id="tspan9258">$nrd.mappings.2.then</tspan></tspan></text>
id="tspan7433">$nrd.mappings.2.then</tspan></tspan></text>
<text
xml:space="preserve"
transform="matrix(0.26458333,0,0,0.26458333,-208.55017,26.703456)"
@ -1462,9 +1468,9 @@
style="font-style:normal;font-weight:normal;font-size:40px;line-height:0.1;font-family:sans-serif;white-space:pre;shape-inside:url(#rect132688-6);fill:#ffffff;fill-opacity:1;stroke:none"><tspan
x="883.77344"
y="652.63329"
id="tspan9264"><tspan
id="tspan7439"><tspan
style="font-size:13.3333px;-inkscape-font-specification:'sans-serif, Normal'"
id="tspan9262">Skip</tspan></tspan></text>
id="tspan7437">Skip</tspan></tspan></text>
<circle
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.264999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:20;stroke-dasharray:none;stroke-opacity:1"
id="circle213345"

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.5 MiB

View file

@ -45,7 +45,8 @@
"cyclofix": "Bicycle pumps, repair stations, drinking water and cycle shops are on cyclofix",
"description": "An A4-landscape flyer to promote MapComplete",
"editing": {
"intro": "The user is greeted by a map with feature. Upon selecting one, the information about that feature is shown. A simplified example of what this looks like for a nature reserve is shown below.",
"ex": "A simplified example of what this looks like for a nature reserve is shown below.",
"intro": "The user is greeted by a map with feature. Upon selecting one, the information about that feature is shown.",
"title": "What does the interface look like?"
},
"examples": "There are many thematic maps available of which a few are printed here.\n\nThere are many more thematic maps online: about healthcare, indoor navigation, wheelchair accessibility, waste facilities, public bookcases, pedestrian crossings with a rainbow-painting,... Discover them all on mapcomplete.osm.be ",
@ -61,7 +62,7 @@
"lines_too": "Lines and polygons are shown too. Attributes and images can be added and updated on those objects as well.",
"mapcomplete": {
"customize": "MapComplete can be tailored to your needs, with new map layers, new functionalities or styled with your organisations colours and font.\nWe also have experience with starting campaigns to crowdsource geodata.\nContact pietervdvn@posteo.net for a quote.",
"intro": "MapComplete is a website which has {mapCount} interactive maps. Every single map allows to add or update information.",
"intro": "MapComplete is a website which has {mapCount} interactive maps. Every single map allows to add or update information. It has many features:",
"li0": "Show where POI are",
"li1": "Add new points and update information on existing points",
"li2": "Add contact information and opening hours easily",

View file

@ -44,7 +44,8 @@
"callToAction": "Probeer het uit op mapcomplete.osm.be",
"cyclofix": "Fietspompen, -winkels, -bandenautomaten en drinkwaterkraantjes vind je op Cyclofix",
"editing": {
"intro": "De gebruiker krijgt eerst een kaart met interesspunten te zien. Klik je op een punt, dan wordt de interface met informatie geopend.\nEen (vereenvoudigd) voorbeeld voor een natuurgebied wordt hieronder getoond:",
"ex": "Een (vereenvoudigd) voorbeeld voor een natuurgebied wordt hieronder getoond:",
"intro": "De gebruiker krijgt eerst een kaart met interesspunten te zien. Klik je op een punt, dan wordt de interface met informatie geopend.",
"title": "Hoe ziet de interface eruit?"
},
"examples": "Online zijn verschillende kaarten met diverse thema's beschikbaar, zoals gezondheidszorg, binnenruimtes, rolstoeltoegankelijkheid, afvalcontainers, boekenruilkasten, regenboog-zebrapaden,...\nEnkele zijn hier afgeprint.\n\nOntdek ze allemaal op mapcomplete.osm.be",
@ -56,7 +57,7 @@
"see_images": "Toont afbeeldingen van eerdere bijdragers, Wikipedia, Mapillary, ...",
"wikipedia": "Gelinkte Wikipedia-artikelen worden getoond"
},
"frontParagraph": "MapComplete is een web-applicatie om OpenStreetMap-data te tonen en aan te passen op basis van thematische kaarten. Het maakt het mogelijk om open geodata te crowdsourcen en te managen op een makkelijke manier.\n\nNieuwe categorieën en attributen kunnen op vraag worden toegevoegd.",
"frontParagraph": "MapComplete is een web-applicatie om OpenStreetMap-data te tonen en aan te passen op thematische kaarten.\nHet maakt het mogelijk om open geodata te crowdsourcen en te managen op een makkelijke manier.\n\nNieuwe categorieën en attributen kunnen op vraag worden toegevoegd.",
"lines_too": "Lijnobjecten en polygonen worden ook getoond. Afbeeldingen en attributen daarvan kunnen toegevoegd en aangepast worden.",
"mapcomplete": {
"customize": "Wil je een versie op maat?\nWil je een versie in jullie huisstijl?\nWil je een nieuwe kaartlaag of functionaliteit?\nWil je een crowdsourcing-campagne opzetten?\nNeem contact op met pietervdvn@posteo.net voor meer info.",

224
test.ts
View file

@ -1,226 +1,6 @@
import MinimapImplementation from "./UI/Base/MinimapImplementation";
import {Utils} from "./Utils";
import {FlowPanelFactory, FlowStep} from "./UI/ImportFlow/FlowStep";
import Title from "./UI/Base/Title";
import Combine from "./UI/Base/Combine";
import {ImmutableStore, Store, UIEventSource} from "./Logic/UIEventSource";
import {RadioButton} from "./UI/Input/RadioButton";
import {InputElement} from "./UI/Input/InputElement";
import {FixedInputElement} from "./UI/Input/FixedInputElement";
import List from "./UI/Base/List";
import {VariableUiElement} from "./UI/Base/VariableUIElement";
import BaseUIElement from "./UI/BaseUIElement";
import LeftIndex from "./UI/Base/LeftIndex";
import {SvgToPdf, SvgToPdfOptions} from "./Utils/svgToPdf";
import Img from "./UI/Base/Img";
import Toggle from "./UI/Input/Toggle";
import CheckBoxes, {CheckBox} from "./UI/Input/Checkboxes";
import Loading from "./UI/Base/Loading";
import Minimap from "./UI/Base/Minimap";
import {FixedUiElement} from "./UI/Base/FixedUiElement";
import SearchAndGo from "./UI/BigComponents/SearchAndGo";
import {SubtleButton} from "./UI/Base/SubtleButton";
import {PdfExportGui} from "./UI/BigComponents/PdfExportGui";
MinimapImplementation.initialize()
let i = 0
function createElement(): string {
const div = document.createElement("div")
div.id = "freediv-" + (i++)
document.getElementById("extradiv").append(div)
return div.id
}
class SelectTemplate extends Combine implements FlowStep<{ title: string, pages: string[] }> {
readonly IsValid: Store<boolean>;
readonly Value: Store<{ title: string, pages: string[] }>;
constructor() {
const elements: InputElement<{ templateName: string, pages: string[] }>[] = []
for (const templateName in SvgToPdf.templates) {
const template = SvgToPdf.templates[templateName]
elements.push(new FixedInputElement(
new Combine([new FixedUiElement(templateName).SetClass("font-bold pr-2"),
template.description
])
, new UIEventSource({templateName, pages: template.pages})))
}
const radio = new RadioButton(elements, {selectFirstAsDefault: true})
const loaded: Store<{ success: { title: string, pages: string[] } } | { error: any }> = radio.GetValue().bind(template => {
if (template === undefined) {
return undefined
}
const urls = template.pages.map(p => SelectTemplate.ToUrl(p))
const dloadAll: Promise<{ title: string, pages: string[] }> = Promise.all(urls.map(url => Utils.download(url))).then(pages => ({
pages,
title: template.templateName
}))
return UIEventSource.FromPromiseWithErr(dloadAll)
})
const preview = new VariableUiElement(
loaded.map(pages => {
if (pages === undefined) {
return new Loading()
}
if (pages["err"] !== undefined) {
return new FixedUiElement("Loading preview failed: " + pages["err"]).SetClass("alert")
}
const els: BaseUIElement[] = []
for (const pageSrc of pages["success"].pages) {
const el = new Img(pageSrc, true)
.SetClass("w-96 m-2 border-black border-2")
els.push(el)
}
return new Combine(els).SetClass("flex border border-subtle rounded-xl");
})
)
super([
new Title("Select template"),
radio,
new Title("Preview"),
preview
]);
this.Value = loaded.map(l => l === undefined ? undefined : l["success"])
this.IsValid = this.Value.map(v => v !== undefined)
}
public static ToUrl(spec: string) {
if (spec.startsWith("http")) {
return spec
}
return window.location.protocol + "//" + window.location.host + "/" + spec
}
}
class SelectPdfOptions extends Combine implements FlowStep<{ title: string, pages: string[], options: SvgToPdfOptions }> {
readonly IsValid: Store<boolean>;
readonly Value: Store<{ title: string, pages: string[], options: SvgToPdfOptions }>;
constructor(title: string, pages: string[], getFreeDiv: () => string) {
const dummy = new CheckBox("Don't add data to the map (to quickly preview the PDF)", false)
const overrideMapLocation = new CheckBox("Override map location: use a selected location instead of the location set in the template", false)
const locationInput = Minimap.createMiniMap().SetClass("block w-full")
const searchField = new SearchAndGo({leafletMap: locationInput.leafletMap})
const selectLocation =
new Combine([
new Toggle(new Combine([new Title("Select override location"), searchField]).SetClass("flex"), undefined, overrideMapLocation.GetValue()),
new Toggle(locationInput.SetStyle("height: 20rem"), undefined, overrideMapLocation.GetValue()).SetStyle("height: 20rem")
]).SetClass("block").SetStyle("height: 25rem")
super([new Title("Select options"),
dummy,
overrideMapLocation,
selectLocation
]);
this.Value = dummy.GetValue().map((disableMaps) => {
return {
pages,
title,
options: <SvgToPdfOptions>{
disableMaps,
getFreeDiv,
overrideLocation: overrideMapLocation.GetValue().data ? locationInput.location.data : undefined
}
}
}, [overrideMapLocation.GetValue(), locationInput.location])
this.IsValid = new ImmutableStore(true)
}
}
class PreparePdf extends Combine implements FlowStep<{ svgToPdf: SvgToPdf, languages: string[] }> {
readonly IsValid: Store<boolean>;
readonly Value: Store<{ svgToPdf: SvgToPdf, languages: string[] }>;
constructor(title: string, pages: string[], options: SvgToPdfOptions) {
const svgToPdf = new SvgToPdf(title, pages, options)
const languageOptions = [
new FixedInputElement("Nederlands", "nl"),
new FixedInputElement("English", "en")
]
const languages = new CheckBoxes(languageOptions)
const isPrepared = UIEventSource.FromPromiseWithErr(svgToPdf.Prepare())
super([
new Title("Select languages..."),
languages,
new Toggle(
new Loading("Preparing maps..."),
undefined,
isPrepared.map(p => p === undefined)
)
]);
this.Value = isPrepared.map(isPrepped => {
if (isPrepped === undefined) {
return undefined
}
if (isPrepped["success"] !== undefined) {
const svgToPdf = isPrepped["success"]
const langs = languages.GetValue().data.map(i => languageOptions[i].GetValue().data)
if (langs.length === 0) {
return undefined
}
return {svgToPdf, languages: langs}
}
return undefined;
}, [languages.GetValue()])
this.IsValid = this.Value.map(v => v !== undefined)
}
}
class SavePdf extends Combine {
constructor(svgToPdf: SvgToPdf, languages: string[]) {
super([
new Title("Generating your pdfs..."),
new List(languages.map(lng => new Toggle(
lng + " is done!",
new Loading("Creating pdf for " + lng),
UIEventSource.FromPromiseWithErr(svgToPdf.ConvertSvg(lng).then(() => true))
.map(x => x !== undefined && x["success"] === true)
)))
]);
}
}
const {flow, furthestStep, titles} = FlowPanelFactory.start(
new Title("Select template"), new SelectTemplate()
).then(new Title("Select options"), ({title, pages}) => new SelectPdfOptions(title, pages, createElement))
.then("Generate maps...", ({title, pages, options}) => new PreparePdf(title, pages, options))
.finish("Generating...", ({svgToPdf, languages}) => new SavePdf(svgToPdf, languages))
const toc = new List(
titles.map(
(title, i) =>
new VariableUiElement(
furthestStep.map((currentStep) => {
if (i > currentStep) {
return new Combine([title]).SetClass("subtle")
}
if (i == currentStep) {
return new Combine([title]).SetClass("font-bold")
}
if (i < currentStep) {
return title
}
})
)
),
true
)
const leftContents: BaseUIElement[] = [
toc
].map((el) => el?.SetClass("pl-4"))
new LeftIndex(leftContents, flow).AttachTo("maindiv")
// main().then(() => console.log("Done!"))
new PdfExportGui("extradiv").AttachTo("maindiv")