commit
2bbf966d22
10 changed files with 2123 additions and 432 deletions
1
.eslintignore
Normal file
1
.eslintignore
Normal file
|
@ -0,0 +1 @@
|
|||
src/test.ts
|
27
.eslintrc.cjs
Normal file
27
.eslintrc.cjs
Normal file
|
@ -0,0 +1,27 @@
|
|||
/* eslint-env node */
|
||||
module.exports = {
|
||||
extends: [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:svelte/recommended",
|
||||
],
|
||||
parser: "@typescript-eslint/parser",
|
||||
parserOptions: {
|
||||
extraFileExtensions: [".svelte"],
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ["*.svelte"],
|
||||
parser: "svelte-eslint-parser",
|
||||
parserOptions: {
|
||||
parser: "@typescript-eslint/parser",
|
||||
},
|
||||
},
|
||||
],
|
||||
plugins: ["@typescript-eslint"],
|
||||
root: true,
|
||||
env: {
|
||||
browser: true,
|
||||
node: true,
|
||||
},
|
||||
}
|
17
.vscode/extensions.json
vendored
17
.vscode/extensions.json
vendored
|
@ -1,10 +1,11 @@
|
|||
{
|
||||
"recommendations": [
|
||||
"esbenp.prettier-vscode",
|
||||
"eamodio.gitlens",
|
||||
"github.vscode-pull-request-github",
|
||||
"svelte.svelte-vscode",
|
||||
"bradlc.vscode-tailwindcss",
|
||||
"editorconfig.editorconfig"
|
||||
]
|
||||
"recommendations": [
|
||||
"esbenp.prettier-vscode",
|
||||
"eamodio.gitlens",
|
||||
"github.vscode-pull-request-github",
|
||||
"svelte.svelte-vscode",
|
||||
"bradlc.vscode-tailwindcss",
|
||||
"editorconfig.editorconfig",
|
||||
"dbaeumer.vscode-eslint"
|
||||
]
|
||||
}
|
||||
|
|
2438
package-lock.json
generated
2438
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -79,6 +79,9 @@
|
|||
"generate": "mkdir -p ./assets/generated; npm run generate:licenses; npm run generate:images; npm run generate:charging-stations; npm run generate:translations; npm run reset:layeroverview; npm run generate:service-worker",
|
||||
"generate:charging-stations": "cd ./assets/layers/charging_station && vite-node csvToJson.ts && cd -",
|
||||
"prepare-deploy": "npm run generate:service-worker && ./scripts/build.sh",
|
||||
"lint": "npm run lint:prettier && npm run lint:eslint",
|
||||
"lint:eslint": "eslint ./src",
|
||||
"lint:prettier": "prettier --check '**/*.ts' '**/*.svelte'",
|
||||
"format": "prettier --write '**/*.ts' '**/*.svelte'",
|
||||
"clean:tests": "find . -type f -name \"*.doctest.ts\" | xargs -r rm",
|
||||
"clean": "rm -rf .cache/ && (find *.html | grep -v \"^\\(404\\|index\\|land\\|test\\|studio\\|theme\\|style_test\\|statistics\\).html\" | xargs -r rm) && (ls | grep \"^index_[a-zA-Z_-]\\+\\.ts$\" | xargs -r rm)",
|
||||
|
@ -165,9 +168,13 @@
|
|||
"@types/prompt-sync": "^4.1.0",
|
||||
"@types/wikidata-sdk": "^6.1.0",
|
||||
"@types/xml2js": "^0.4.9",
|
||||
"@typescript-eslint/eslint-plugin": "^6.1.0",
|
||||
"@typescript-eslint/parser": "^6.1.0",
|
||||
"assert": "^2.0.0",
|
||||
"chai": "^4.3.6",
|
||||
"dependency-cruiser": "^10.4.0",
|
||||
"eslint": "^8.45.0",
|
||||
"eslint-plugin-svelte": "^2.32.2",
|
||||
"fs": "0.0.1-security",
|
||||
"node-html-parser": "^6.1.5",
|
||||
"prettier": "^2.8.8",
|
||||
|
@ -182,8 +189,6 @@
|
|||
"ts-node": "^10.9.1",
|
||||
"ts2json-schema": "^1.4.0",
|
||||
"tslib": "^2.5.0",
|
||||
"tslint": "^6.1.3",
|
||||
"tslint-no-circular-imports": "^0.7.0",
|
||||
"typescript": "^4.7.4",
|
||||
"vite": "^4.0.5"
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ export class OpenJosm extends Combine {
|
|||
|
||||
const josmState = new UIEventSource<string>(undefined)
|
||||
// Reset after 15s
|
||||
josmState.stabilized(15000).addCallbackD((_) => josmState.setData(undefined))
|
||||
josmState.stabilized(15000).addCallbackD(() => josmState.setData(undefined))
|
||||
|
||||
const stateIndication = new VariableUiElement(
|
||||
josmState.map((state) => {
|
||||
|
@ -45,7 +45,7 @@ export class OpenJosm extends Combine {
|
|||
const josmLink = `http://127.0.0.1:8111/load_and_zoom?left=${left}&right=${right}&top=${top}&bottom=${bottom}`
|
||||
Utils.download(josmLink)
|
||||
.then((answer) => josmState.setData(answer.replace(/\n/g, "").trim()))
|
||||
.catch((_) => josmState.setData("ERROR"))
|
||||
.catch(() => josmState.setData("ERROR"))
|
||||
})
|
||||
.SetClass("w-full"),
|
||||
undefined,
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
mimetype="image/png"
|
||||
mainText={t.downloadAsPng}
|
||||
helperText={t.downloadAsPngHelper}
|
||||
construct={(_) => state.mapProperties.exportAsPng(4)}
|
||||
construct={() => state.mapProperties.exportAsPng(4)}
|
||||
/>
|
||||
|
||||
<div class="flex flex-col">
|
||||
|
|
18
src/Utils.ts
18
src/Utils.ts
|
@ -235,7 +235,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
}
|
||||
|
||||
public static TimesT<T>(count: number, f: (i: number) => T): T[] {
|
||||
let res: T[] = []
|
||||
const res: T[] = []
|
||||
for (let i = 0; i < count; i++) {
|
||||
res.push(f(i))
|
||||
}
|
||||
|
@ -828,7 +828,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
}
|
||||
|
||||
static getOrSetDefault<K, V>(dict: Map<K, V>, k: K, v: () => V) {
|
||||
let found = dict.get(k)
|
||||
const found = dict.get(k)
|
||||
if (found !== undefined) {
|
||||
return found
|
||||
}
|
||||
|
@ -849,7 +849,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
if (i >= 124) {
|
||||
code += 1 // Character 127 is our 'escape' character |
|
||||
}
|
||||
let replacement = "|" + String.fromCharCode(code)
|
||||
const replacement = "|" + String.fromCharCode(code)
|
||||
stringified = stringified.replace(new RegExp(`\"${knownKey}\":`, "g"), replacement)
|
||||
}
|
||||
|
||||
|
@ -1126,7 +1126,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
seconds = seconds % 60
|
||||
let hours = Math.floor(minutes / 60)
|
||||
minutes = minutes % 60
|
||||
let days = Math.floor(hours / 24)
|
||||
const days = Math.floor(hours / 24)
|
||||
hours = hours % 24
|
||||
if (days > 0) {
|
||||
return days + "days" + " " + hours + "h"
|
||||
|
@ -1289,7 +1289,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
|
||||
for (const k in d) {
|
||||
const vs = d[k]
|
||||
for (let v of vs) {
|
||||
for (const v of vs) {
|
||||
const list = newD[v]
|
||||
if (list === undefined) {
|
||||
newD[v] = [k] // Left: indexing; right: list with one element
|
||||
|
@ -1311,7 +1311,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
}
|
||||
|
||||
function componentToHex(n) {
|
||||
let hex = n.toString(16)
|
||||
const hex = n.toString(16)
|
||||
return hex.length == 1 ? "0" + hex : hex
|
||||
}
|
||||
|
||||
|
@ -1430,8 +1430,8 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
return false
|
||||
}
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
let ai = a[i]
|
||||
let bi = b[i]
|
||||
const ai = a[i]
|
||||
const bi = b[i]
|
||||
if (ai == bi) {
|
||||
continue
|
||||
}
|
||||
|
@ -1525,7 +1525,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
if (matchWithFuncName) {
|
||||
;[_, functionName, path, line, column] = matchWithFuncName
|
||||
} else {
|
||||
let regexNoFuncName: RegExp = new RegExp("at ([a-zA-Z0-9/.]+):([0-9]+):([0-9]+)")
|
||||
const regexNoFuncName: RegExp = new RegExp("at ([a-zA-Z0-9/.]+):([0-9]+):([0-9]+)")
|
||||
;[_, path, line, column] = stackItem.match(regexNoFuncName)
|
||||
}
|
||||
|
||||
|
|
|
@ -209,7 +209,7 @@ class SvgToPdfInternals {
|
|||
if (element.childElementCount == 0) {
|
||||
this.drawTspan(element)
|
||||
} else {
|
||||
for (let child of Array.from(element.children)) {
|
||||
for (const child of Array.from(element.children)) {
|
||||
this.handleElement(child)
|
||||
}
|
||||
}
|
||||
|
@ -224,7 +224,7 @@ class SvgToPdfInternals {
|
|||
}
|
||||
|
||||
if (element.tagName === "g" || element.tagName === "text") {
|
||||
for (let child of Array.from(element.children)) {
|
||||
for (const child of Array.from(element.children)) {
|
||||
this.handleElement(child)
|
||||
}
|
||||
}
|
||||
|
@ -256,7 +256,7 @@ class SvgToPdfInternals {
|
|||
const css = SvgToPdfInternals.css(element)
|
||||
this.doc.saveGraphicsState()
|
||||
if (css["fill-opacity"] !== "0" && css["fill"] !== "none") {
|
||||
let color = css["fill"] ?? "black"
|
||||
const color = css["fill"] ?? "black"
|
||||
let opacity = 1
|
||||
if (css["fill-opacity"]) {
|
||||
opacity = Number(css["fill-opacity"])
|
||||
|
@ -314,13 +314,13 @@ class SvgToPdfInternals {
|
|||
console.log("Creating image with key", key, "searching rect in", x, y)
|
||||
const rectangle: SVGRectElement = this.page.findSmallestRectContaining(x, y, false)
|
||||
console.log("Got rect", rectangle)
|
||||
let w = SvgToPdfInternals.attrNumber(rectangle, "width")
|
||||
let h = SvgToPdfInternals.attrNumber(rectangle, "height")
|
||||
const w = SvgToPdfInternals.attrNumber(rectangle, "width")
|
||||
const h = SvgToPdfInternals.attrNumber(rectangle, "height")
|
||||
x = SvgToPdfInternals.attrNumber(rectangle, "x")
|
||||
y = SvgToPdfInternals.attrNumber(rectangle, "y")
|
||||
|
||||
// Actually, dots per mm, not dots per inch ;)
|
||||
let dpi = 60
|
||||
const dpi = 60
|
||||
const img = this.page.options.createImage(key, dpi * w + "px", dpi * h + "px")
|
||||
|
||||
const canvas = document.createElement("canvas")
|
||||
|
@ -363,7 +363,7 @@ class SvgToPdfInternals {
|
|||
fontFamily = "Ubuntu"
|
||||
}
|
||||
|
||||
let fontWeight = css["font-weight"] ?? "normal"
|
||||
const fontWeight = css["font-weight"] ?? "normal"
|
||||
this.doc.setFont(fontFamily, fontWeight)
|
||||
|
||||
const fontColor = css["fill"]
|
||||
|
@ -372,13 +372,13 @@ class SvgToPdfInternals {
|
|||
} else {
|
||||
this.doc.setTextColor("black")
|
||||
}
|
||||
let fontsize = parseFloat(css["font-size"])
|
||||
const fontsize = parseFloat(css["font-size"])
|
||||
this.doc.setFontSize(fontsize * 2.5)
|
||||
|
||||
let textTemplate = tspan.textContent.split(" ")
|
||||
const textTemplate = tspan.textContent.split(" ")
|
||||
let result: string = ""
|
||||
let addSpace = false
|
||||
for (let text of textTemplate) {
|
||||
for (const text of textTemplate) {
|
||||
if (text === "\\n") {
|
||||
result += "\n"
|
||||
addSpace = false
|
||||
|
@ -446,7 +446,7 @@ class SvgToPdfInternals {
|
|||
const svgWidth = SvgToPdfInternals.attrNumber(svgRoot, "width")
|
||||
const svgHeight = SvgToPdfInternals.attrNumber(svgRoot, "height")
|
||||
|
||||
let img = this.page.images[base64src]
|
||||
const img = this.page.images[base64src]
|
||||
// This is an svg image, we use the canvas to convert it to a png
|
||||
const canvas = document.createElement("canvas")
|
||||
const ctx = canvas.getContext("2d")
|
||||
|
@ -607,7 +607,7 @@ class SvgToPdfPage {
|
|||
const parts = tc.split(" ").filter((p) => p.startsWith("$") && p.indexOf("(") < 0)
|
||||
for (let part of parts) {
|
||||
part = part.substring(1) // Drop the $
|
||||
let path = part.split(".")
|
||||
const path = part.split(".")
|
||||
const importPath = this.importedTranslations[path[0]]
|
||||
if (importPath) {
|
||||
translations.add(importPath + "." + path.slice(1).join("."))
|
||||
|
@ -636,7 +636,7 @@ class SvgToPdfPage {
|
|||
|
||||
if (element.tagName === "tspan" && element.childElementCount == 0) {
|
||||
const specialValues = element.textContent.split(" ").filter((t) => t.startsWith("$"))
|
||||
for (let specialValue of specialValues) {
|
||||
for (const specialValue of specialValues) {
|
||||
const importMatch = element.textContent.match(
|
||||
/\$import ([a-zA-Z-_0-9.? ]+) as ([a-zA-Z0-9]+)/
|
||||
)
|
||||
|
@ -665,7 +665,7 @@ class SvgToPdfPage {
|
|||
element.tagName === "tspan" ||
|
||||
element.tagName === "defs"
|
||||
) {
|
||||
for (let child of Array.from(element.children)) {
|
||||
for (const child of Array.from(element.children)) {
|
||||
await this.prepareElement(child, mapTextSpecs, inDefs || element.tagName === "defs")
|
||||
}
|
||||
}
|
||||
|
@ -694,7 +694,7 @@ class SvgToPdfPage {
|
|||
}
|
||||
this._isPrepared = true
|
||||
const mapSpecs: SVGTSpanElement[] = []
|
||||
for (let child of Array.from(this._svgRoot.children)) {
|
||||
for (const child of Array.from(this._svgRoot.children)) {
|
||||
await this.prepareElement(<any>child, mapSpecs, child.tagName === "defs")
|
||||
}
|
||||
|
||||
|
@ -715,7 +715,7 @@ class SvgToPdfPage {
|
|||
const internal = new SvgToPdfInternals(advancedApi, this, (key) =>
|
||||
self.extractTranslation(key, language)
|
||||
)
|
||||
for (let child of Array.from(this._svgRoot.children)) {
|
||||
for (const child of Array.from(this._svgRoot.children)) {
|
||||
internal.handleElement(<any>child)
|
||||
}
|
||||
}
|
||||
|
@ -805,11 +805,11 @@ class SvgToPdfPage {
|
|||
|
||||
private loadImage(element: Element | string): Promise<void> {
|
||||
const xlink = typeof element === "string" ? element : element.getAttribute("xlink:href")
|
||||
let img = document.createElement("img")
|
||||
const img = document.createElement("img")
|
||||
|
||||
if (xlink.startsWith("data:image/svg+xml;")) {
|
||||
const base64src = xlink
|
||||
let svgXml = atob(
|
||||
const svgXml = atob(
|
||||
base64src.substring(base64src.indexOf(";base64,") + ";base64,".length)
|
||||
)
|
||||
const parser = new DOMParser()
|
||||
|
@ -884,7 +884,7 @@ class SvgToPdfPage {
|
|||
throw "Invalid mapspec:" + spec
|
||||
}
|
||||
const params = SvgToPdfInternals.parseCss(match[1], ",")
|
||||
let layout = AllKnownLayouts.allKnownLayouts.get(params["theme"])
|
||||
const layout = AllKnownLayouts.allKnownLayouts.get(params["theme"])
|
||||
if (layout === undefined) {
|
||||
console.error("Could not show map with parameters", params)
|
||||
throw (
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { Utils } from "./Utils"
|
||||
import AllThemesGui from "./UI/AllThemesGui"
|
||||
import { QueryParameters } from "./Logic/Web/QueryParameters"
|
||||
|
||||
|
|
Loading…
Reference in a new issue