refactoring: move logic of lastclick into special layer, fix labels, fix anchoring
This commit is contained in:
parent
25a98af057
commit
52a0810ea9
47 changed files with 682 additions and 197 deletions
|
@ -50,6 +50,9 @@ export default class SelectedElementTagsUpdater {
|
|||
const state = this.state
|
||||
state.selectedElement.addCallbackAndRunD(async (s) => {
|
||||
let id = s.properties?.id
|
||||
if (!id) {
|
||||
return
|
||||
}
|
||||
|
||||
const backendUrl = state.osmConnection._oauth_config.url
|
||||
if (id.startsWith(backendUrl)) {
|
||||
|
|
|
@ -20,32 +20,24 @@ export default class TitleHandler {
|
|||
(selected) => {
|
||||
const defaultTitle = state.layout?.title?.txt ?? "MapComplete"
|
||||
|
||||
if (selected === undefined) {
|
||||
if (selected === undefined || selectedLayer.data === undefined) {
|
||||
return defaultTitle
|
||||
}
|
||||
|
||||
const tags = selected.properties
|
||||
for (const layer of state.layout?.layers ?? []) {
|
||||
if (layer.title === undefined) {
|
||||
continue
|
||||
}
|
||||
if (layer.source.osmTags.matchesProperties(tags)) {
|
||||
const tagsSource =
|
||||
allElements.getStore(tags.id) ??
|
||||
new UIEventSource<Record<string, string>>(tags)
|
||||
const title = new SvelteUIElement(TagRenderingAnswer, {
|
||||
tags: tagsSource,
|
||||
state,
|
||||
selectedElement: selectedElement.data,
|
||||
layer: selectedLayer.data,
|
||||
})
|
||||
return (
|
||||
new Combine([defaultTitle, " | ", title]).ConstructElement()
|
||||
?.textContent ?? defaultTitle
|
||||
)
|
||||
}
|
||||
}
|
||||
return defaultTitle
|
||||
const layer = selectedLayer.data
|
||||
const tagsSource =
|
||||
allElements.getStore(tags.id) ?? new UIEventSource<Record<string, string>>(tags)
|
||||
const title = new SvelteUIElement(TagRenderingAnswer, {
|
||||
tags: tagsSource,
|
||||
state,
|
||||
selectedElement: selectedElement.data,
|
||||
layer,
|
||||
})
|
||||
return (
|
||||
new Combine([defaultTitle, " | ", title]).ConstructElement()?.textContent ??
|
||||
defaultTitle
|
||||
)
|
||||
},
|
||||
[Locale.language, selectedLayer]
|
||||
)
|
||||
|
|
|
@ -43,6 +43,10 @@ export default class FeaturePropertiesStore {
|
|||
return this._elements.get(id)
|
||||
}
|
||||
|
||||
public addSpecial(id: string, store: UIEventSource<Record<string, string>>) {
|
||||
this._elements.set(id, store)
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrites the tags of the old properties object, returns true if a change was made.
|
||||
* Metatags are overriden if they are in the new properties, but not removed
|
||||
|
|
57
Logic/FeatureSource/Sources/LastClickFeatureSource.ts
Normal file
57
Logic/FeatureSource/Sources/LastClickFeatureSource.ts
Normal file
|
@ -0,0 +1,57 @@
|
|||
import LayoutConfig from "../../../Models/ThemeConfig/LayoutConfig"
|
||||
import FeatureSource from "../FeatureSource"
|
||||
import { ImmutableStore, Store } from "../../UIEventSource"
|
||||
import { Feature, Point } from "geojson"
|
||||
import { TagUtils } from "../../Tags/TagUtils"
|
||||
import BaseUIElement from "../../../UI/BaseUIElement"
|
||||
import { Utils } from "../../../Utils"
|
||||
import { regex_not_newline_characters } from "svelte/types/compiler/utils/patterns"
|
||||
import { render } from "sass"
|
||||
|
||||
/**
|
||||
* Highly specialized feature source.
|
||||
* Based on a lon/lat UIEVentSource, will generate the corresponding feature with the correct properties
|
||||
*/
|
||||
export class LastClickFeatureSource implements FeatureSource {
|
||||
features: Store<Feature[]>
|
||||
|
||||
public properties: Record<string, string>
|
||||
constructor(location: Store<{ lon: number; lat: number }>, layout: LayoutConfig) {
|
||||
const allPresets: BaseUIElement[] = []
|
||||
for (const layer of layout.layers)
|
||||
for (let i = 0; i < (layer.presets ?? []).length; i++) {
|
||||
const preset = layer.presets[i]
|
||||
const tags = new ImmutableStore(TagUtils.KVtoProperties(preset.tags))
|
||||
const { html } = layer.mapRendering[0].RenderIcon(tags, false, {
|
||||
noSize: true,
|
||||
includeBadges: false,
|
||||
})
|
||||
allPresets.push(html)
|
||||
}
|
||||
|
||||
const renderings = Utils.Dedup(
|
||||
allPresets.map((uiElem) => uiElem.ConstructElement().innerHTML)
|
||||
)
|
||||
|
||||
const properties = {
|
||||
lastclick: "yes",
|
||||
id: "last_click",
|
||||
has_note_layer: layout.layers.some((l) => l.id === "note") ? "yes" : "no",
|
||||
has_presets: layout.layers.some((l) => l.presets?.length > 0) ? "yes" : "no",
|
||||
renderings: renderings.join(""),
|
||||
number_of_presets: "" + renderings.length,
|
||||
first_preset: renderings[0],
|
||||
}
|
||||
this.properties = properties
|
||||
this.features = location.mapD(({ lon, lat }) => [
|
||||
<Feature<Point>>{
|
||||
type: "Feature",
|
||||
properties,
|
||||
geometry: {
|
||||
type: "Point",
|
||||
coordinates: [lon, lat],
|
||||
},
|
||||
},
|
||||
])
|
||||
}
|
||||
}
|
|
@ -21,16 +21,16 @@ export class TagUtils {
|
|||
[">", (a, b) => a > b],
|
||||
]
|
||||
|
||||
static KVtoProperties(tags: Tag[]): any {
|
||||
const properties = {}
|
||||
static KVtoProperties(tags: Tag[]): Record<string, string> {
|
||||
const properties : Record<string, string> = {}
|
||||
for (const tag of tags) {
|
||||
properties[tag.key] = tag.value
|
||||
}
|
||||
return properties
|
||||
}
|
||||
|
||||
static changeAsProperties(kvs: { k: string; v: string }[]): any {
|
||||
const tags = {}
|
||||
static changeAsProperties(kvs: { k: string; v: string }[]): Record<string, string> {
|
||||
const tags: Record<string, string> = {}
|
||||
for (const kv of kvs) {
|
||||
tags[kv.k] = kv.v
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ export default class Constants {
|
|||
"home_location",
|
||||
"gps_track",
|
||||
"range",
|
||||
"last_click",
|
||||
] as const
|
||||
/**
|
||||
* Special layers which are not included in a theme by default
|
||||
|
@ -66,10 +67,10 @@ export default class Constants {
|
|||
themeGeneratorReadOnlyUnlock: 50,
|
||||
themeGeneratorFullUnlock: 500,
|
||||
addNewPointWithUnreadMessagesUnlock: 500,
|
||||
minZoomLevelToAddNewPoints: Constants.isRetina() ? 18 : 19,
|
||||
|
||||
importHelperUnlock: 5000,
|
||||
}
|
||||
static readonly minZoomLevelToAddNewPoint = Constants.isRetina() ? 18 : 19
|
||||
/**
|
||||
* Used by 'PendingChangesUploader', which waits this amount of seconds to upload changes.
|
||||
* (Note that pendingChanges might upload sooner if the popup is closed or similar)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { UIEventSource } from "../Logic/UIEventSource"
|
||||
import { Store, UIEventSource } from "../Logic/UIEventSource"
|
||||
import { BBox } from "../Logic/BBox"
|
||||
import { RasterLayerPolygon } from "./RasterLayers"
|
||||
|
||||
|
@ -10,5 +10,7 @@ export interface MapProperties {
|
|||
readonly maxbounds: UIEventSource<undefined | BBox>
|
||||
readonly allowMoving: UIEventSource<true | boolean>
|
||||
|
||||
readonly lastClickLocation: Store<{ lon: number; lat: number }>
|
||||
|
||||
readonly allowZooming: UIEventSource<true | boolean>
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import metapaths from "../../../assets/layoutconfigmeta.json"
|
|||
import tagrenderingmetapaths from "../../../assets/questionabletagrenderingconfigmeta.json"
|
||||
import Translations from "../../../UI/i18n/Translations"
|
||||
|
||||
import { parse as parse_html } from "node-html-parser"
|
||||
export class ExtractImages extends Conversion<
|
||||
LayoutConfigJson,
|
||||
{ path: string; context: string }[]
|
||||
|
@ -190,6 +191,17 @@ export class ExtractImages extends Conversion<
|
|||
const cleanedImages: { path: string; context: string }[] = []
|
||||
|
||||
for (const foundImage of allFoundImages) {
|
||||
if (foundImage.path.startsWith("<") && foundImage.path.endsWith(">")) {
|
||||
// These is probably html - we ignore
|
||||
const doc = parse_html(foundImage.path)
|
||||
const images = Array.from(doc.getElementsByTagName("img"))
|
||||
const paths = images.map((i) => i.getAttribute("src"))
|
||||
cleanedImages.push(
|
||||
...paths.map((path) => ({ path, context: foundImage.context + " (in html)" }))
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
// Split "circle:white;./assets/layers/.../something.svg" into ["circle", "./assets/layers/.../something.svg"]
|
||||
const allPaths = Utils.NoNull(
|
||||
Utils.NoEmpty(foundImage.path?.split(";")?.map((part) => part.split(":")[0]))
|
||||
|
|
|
@ -101,6 +101,11 @@ export class DoesImageExist extends DesugaringStep<string> {
|
|||
}
|
||||
}
|
||||
|
||||
if (image.startsWith("<") && image.endsWith(">")) {
|
||||
// This is probably HTML, you're on your own here
|
||||
return { result: image }
|
||||
}
|
||||
|
||||
if (!this._knownImagePaths.has(image)) {
|
||||
if (this.doesPathExist === undefined) {
|
||||
errors.push(
|
||||
|
@ -730,9 +735,9 @@ export class ValidateLayer extends DesugaringStep<LayerConfigJson> {
|
|||
}
|
||||
}
|
||||
|
||||
if (json.minzoom > Constants.userJourney.minZoomLevelToAddNewPoints) {
|
||||
if (json.minzoom > Constants.minZoomLevelToAddNewPoint) {
|
||||
;(json.presets?.length > 0 ? errors : warnings).push(
|
||||
`At ${context}: minzoom is ${json.minzoom}, this should be at most ${Constants.userJourney.minZoomLevelToAddNewPoints} as a preset is set. Why? Selecting the pin for a new item will zoom in to level before adding the point. Having a greater minzoom will hide the points, resulting in possible duplicates`
|
||||
`At ${context}: minzoom is ${json.minzoom}, this should be at most ${Constants.minZoomLevelToAddNewPoint} as a preset is set. Why? Selecting the pin for a new item will zoom in to level before adding the point. Having a greater minzoom will hide the points, resulting in possible duplicates`
|
||||
)
|
||||
}
|
||||
{
|
||||
|
|
|
@ -69,15 +69,25 @@ export default interface PointRenderingConfigJson {
|
|||
label?: string | TagRenderingConfigJson
|
||||
|
||||
/**
|
||||
* A snippet of css code
|
||||
* A snippet of css code which is applied onto the container of the entire marker
|
||||
*/
|
||||
css?: string | TagRenderingConfigJson
|
||||
|
||||
/**
|
||||
* A snippet of css-classes. They can be space-separated
|
||||
* A snippet of css-classes which are applied onto the container of the entire marker. They can be space-separated
|
||||
*/
|
||||
cssClasses?: string | TagRenderingConfigJson
|
||||
|
||||
/**
|
||||
* Css that is applied onto the label
|
||||
*/
|
||||
labelCss?: string | TagRenderingConfigJson
|
||||
|
||||
/**
|
||||
* Css classes that are applied onto the label; can be space-separated
|
||||
*/
|
||||
labelCssClasses?: string | TagRenderingConfigJson
|
||||
|
||||
/**
|
||||
* If the map is pitched, the marker will stay parallel to the screen.
|
||||
* Set to 'map' if you want to put it flattened on the map
|
||||
|
|
|
@ -30,6 +30,7 @@ import { FixedUiElement } from "../../UI/Base/FixedUiElement"
|
|||
import Svg from "../../Svg"
|
||||
import { ImmutableStore } from "../../Logic/UIEventSource"
|
||||
import { OsmTags } from "../OsmFeature"
|
||||
import Constants from "../Constants"
|
||||
|
||||
export default class LayerConfig extends WithContextLoader {
|
||||
public static readonly syncSelectionAllowed = ["no", "local", "theme-only", "global"] as const
|
||||
|
@ -322,7 +323,8 @@ export default class LayerConfig extends WithContextLoader {
|
|||
} else if (
|
||||
!hasCenterRendering &&
|
||||
this.lineRendering.length === 0 &&
|
||||
!this.source.geojsonSource?.startsWith(
|
||||
Constants.priviliged_layers.indexOf(<any>this.id) < 0 &&
|
||||
!this.source?.geojsonSource?.startsWith(
|
||||
"https://api.openstreetmap.org/api/0.6/notes.json"
|
||||
)
|
||||
) {
|
||||
|
@ -425,8 +427,10 @@ export default class LayerConfig extends WithContextLoader {
|
|||
return mapRendering.GetBaseIcon(this.GetBaseTags())
|
||||
}
|
||||
|
||||
public GetBaseTags(): any {
|
||||
return TagUtils.changeAsProperties(this.source.osmTags.asChange({ id: "node/-1" }))
|
||||
public GetBaseTags(): Record<string, string> {
|
||||
return TagUtils.changeAsProperties(
|
||||
this.source?.osmTags?.asChange({ id: "node/-1" }) ?? [{ k: "id", v: "node/-1" }]
|
||||
)
|
||||
}
|
||||
|
||||
public GenerateDocumentation(
|
||||
|
|
|
@ -11,6 +11,7 @@ import { FixedUiElement } from "../../UI/Base/FixedUiElement"
|
|||
import Img from "../../UI/Base/Img"
|
||||
import Combine from "../../UI/Base/Combine"
|
||||
import { VariableUiElement } from "../../UI/Base/VariableUIElement"
|
||||
import { html } from "svelte/types/compiler/utils/namespaces"
|
||||
|
||||
export default class PointRenderingConfig extends WithContextLoader {
|
||||
private static readonly allowed_location_codes = new Set<string>([
|
||||
|
@ -28,6 +29,8 @@ export default class PointRenderingConfig extends WithContextLoader {
|
|||
public readonly iconBadges: { if: TagsFilter; then: TagRenderingConfig }[]
|
||||
public readonly iconSize: TagRenderingConfig
|
||||
public readonly label: TagRenderingConfig
|
||||
public readonly labelCss: TagRenderingConfig
|
||||
public readonly labelCssClasses: TagRenderingConfig
|
||||
public readonly rotation: TagRenderingConfig
|
||||
public readonly cssDef: TagRenderingConfig
|
||||
public readonly cssClasses?: TagRenderingConfig
|
||||
|
@ -72,6 +75,8 @@ export default class PointRenderingConfig extends WithContextLoader {
|
|||
this.cssDef = this.tr("css", undefined)
|
||||
}
|
||||
this.cssClasses = this.tr("cssClasses", undefined)
|
||||
this.labelCss = this.tr("labelCss", undefined)
|
||||
this.labelCssClasses = this.tr("labelCssClasses", undefined)
|
||||
this.iconBadges = (json.iconBadges ?? []).map((overlay, i) => {
|
||||
return {
|
||||
if: TagUtils.Tag(overlay.if),
|
||||
|
@ -150,7 +155,7 @@ export default class PointRenderingConfig extends WithContextLoader {
|
|||
}
|
||||
}
|
||||
|
||||
public GetBaseIcon(tags?: any): BaseUIElement {
|
||||
public GetBaseIcon(tags?: Record<string, string>): BaseUIElement {
|
||||
tags = tags ?? { id: "node/-1" }
|
||||
let defaultPin: BaseUIElement = undefined
|
||||
if (this.label === undefined) {
|
||||
|
@ -168,6 +173,10 @@ export default class PointRenderingConfig extends WithContextLoader {
|
|||
// This layer doesn't want to show an icon right now
|
||||
return undefined
|
||||
}
|
||||
if (htmlDefs.startsWith("<") && htmlDefs.endsWith(">")) {
|
||||
// This is probably already prepared HTML
|
||||
return new FixedUiElement(Utils.SubstituteKeys(htmlDefs, tags))
|
||||
}
|
||||
return PointRenderingConfig.FromHtmlMulti(htmlDefs, rotation, false, defaultPin)
|
||||
}
|
||||
|
||||
|
@ -225,10 +234,10 @@ export default class PointRenderingConfig extends WithContextLoader {
|
|||
}
|
||||
|
||||
if (mode === "top") {
|
||||
anchorH = -iconH / 2
|
||||
anchorH = iconH / 2
|
||||
}
|
||||
if (mode === "bottom") {
|
||||
anchorH = iconH / 2
|
||||
anchorH = -iconH / 2
|
||||
}
|
||||
|
||||
const icon = this.GetSimpleIcon(tags)
|
||||
|
@ -244,10 +253,11 @@ export default class PointRenderingConfig extends WithContextLoader {
|
|||
iconAndBadges.SetClass("w-full h-full")
|
||||
}
|
||||
|
||||
const css = this.cssDef?.GetRenderValue(tags)?.txt
|
||||
const cssClasses = this.cssClasses?.GetRenderValue(tags)?.txt
|
||||
const css = this.cssDef?.GetRenderValue(tags.data)?.txt
|
||||
const cssClasses = this.cssClasses?.GetRenderValue(tags.data)?.txt
|
||||
|
||||
let label = this.GetLabel(tags)
|
||||
|
||||
let htmlEl: BaseUIElement
|
||||
if (icon === undefined && label === undefined) {
|
||||
htmlEl = undefined
|
||||
|
@ -288,6 +298,12 @@ export default class PointRenderingConfig extends WithContextLoader {
|
|||
badge.then.GetRenderValue(tags)?.txt,
|
||||
tags
|
||||
)
|
||||
if (htmlDefs.startsWith("<") && htmlDefs.endsWith(">")) {
|
||||
// This is probably an HTML-element
|
||||
return new FixedUiElement(Utils.SubstituteKeys(htmlDefs, tags))
|
||||
.SetStyle("width: 1.5rem")
|
||||
.SetClass("block")
|
||||
}
|
||||
const badgeElement = PointRenderingConfig.FromHtmlMulti(
|
||||
htmlDefs,
|
||||
"0",
|
||||
|
@ -308,14 +324,20 @@ export default class PointRenderingConfig extends WithContextLoader {
|
|||
if (this.label === undefined) {
|
||||
return undefined
|
||||
}
|
||||
const cssLabel = this.labelCss?.GetRenderValue(tags.data)?.txt
|
||||
const cssClassesLabel = this.labelCssClasses?.GetRenderValue(tags.data)?.txt
|
||||
const self = this
|
||||
return new VariableUiElement(
|
||||
tags.map((tags) => {
|
||||
const label = self.label
|
||||
?.GetRenderValue(tags)
|
||||
?.Subs(tags)
|
||||
?.SetClass("block text-center")
|
||||
return new Combine([label]).SetClass("flex flex-col items-center mt-1")
|
||||
?.SetClass("block center absolute text-center ")
|
||||
?.SetClass(cssClassesLabel)
|
||||
if (cssLabel) {
|
||||
label.SetStyle(cssLabel)
|
||||
}
|
||||
return new Combine([label]).SetClass("flex flex-col items-center")
|
||||
})
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import LayoutConfig from "./ThemeConfig/LayoutConfig"
|
||||
import { SpecialVisualizationState } from "../UI/SpecialVisualization"
|
||||
import { Changes } from "../Logic/Osm/Changes"
|
||||
import { Store, UIEventSource } from "../Logic/UIEventSource"
|
||||
import { ImmutableStore, Store, UIEventSource } from "../Logic/UIEventSource"
|
||||
import FeatureSource, {
|
||||
IndexedFeatureSource,
|
||||
WritableFeatureSource,
|
||||
|
@ -38,6 +38,7 @@ import Constants from "./Constants"
|
|||
import Hotkeys from "../UI/Base/Hotkeys"
|
||||
import Translations from "../UI/i18n/Translations"
|
||||
import { GeoIndexedStoreForLayer } from "../Logic/FeatureSource/Actors/GeoIndexedStore"
|
||||
import { LastClickFeatureSource } from "../Logic/FeatureSource/Sources/LastClickFeatureSource"
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -105,6 +106,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
this.mapProperties,
|
||||
this.userRelatedState.gpsLocationHistoryRetentionTime
|
||||
)
|
||||
|
||||
this.availableLayers = AvailableRasterLayers.layersAvailableAt(this.mapProperties.location)
|
||||
|
||||
this.layerState = new LayerState(this.osmConnection, layout.layers, layout.id)
|
||||
|
@ -203,11 +205,45 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
*/
|
||||
private drawSpecialLayers() {
|
||||
type AddedByDefaultTypes = typeof Constants.added_by_default[number]
|
||||
const empty = []
|
||||
{
|
||||
// The last_click gets a _very_ special treatment
|
||||
const last_click = new LastClickFeatureSource(
|
||||
this.mapProperties.lastClickLocation,
|
||||
this.layout
|
||||
)
|
||||
const last_click_layer = this.layerState.filteredLayers.get("last_click")
|
||||
this.featureProperties.addSpecial(
|
||||
"last_click",
|
||||
new UIEventSource<Record<string, string>>(last_click.properties)
|
||||
)
|
||||
new ShowDataLayer(this.map, {
|
||||
features: last_click,
|
||||
doShowLayer: new ImmutableStore(true),
|
||||
layer: last_click_layer.layerDef,
|
||||
selectedElement: this.selectedElement,
|
||||
selectedLayer: this.selectedLayer,
|
||||
onClick: (feature: Feature) => {
|
||||
if (this.mapProperties.zoom.data < Constants.minZoomLevelToAddNewPoint) {
|
||||
this.map.data.flyTo({
|
||||
zoom: Constants.minZoomLevelToAddNewPoint,
|
||||
center: this.mapProperties.lastClickLocation.data,
|
||||
})
|
||||
return
|
||||
}
|
||||
this.selectedElement.setData(feature)
|
||||
this.selectedLayer.setData(last_click_layer.layerDef)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* A listing which maps the layerId onto the featureSource
|
||||
*/
|
||||
const empty = []
|
||||
const specialLayers: Record<AddedByDefaultTypes | "current_view", FeatureSource> = {
|
||||
const specialLayers: Record<
|
||||
Exclude<AddedByDefaultTypes, "last_click"> | "current_view",
|
||||
FeatureSource
|
||||
> = {
|
||||
home_location: this.userRelatedState.homeLocation,
|
||||
gps_location: this.geolocation.currentUserLocation,
|
||||
gps_location_history: this.geolocation.historicalUserLocations,
|
||||
|
@ -261,12 +297,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
*/
|
||||
private initActors() {
|
||||
// Various actors that we don't need to reference
|
||||
new TitleHandler(
|
||||
this.selectedElement,
|
||||
this.selectedLayer,
|
||||
this.featureProperties,
|
||||
this.layout
|
||||
)
|
||||
new TitleHandler(this.selectedElement, this.selectedLayer, this.featureProperties, this)
|
||||
new ChangeToElementsActor(this.changes, this.featureProperties)
|
||||
new PendingChangesUploader(this.changes, this.selectedElement)
|
||||
new SelectedElementTagsUpdater({
|
||||
|
|
11
UI/Base/FloatOver.svelte
Normal file
11
UI/Base/FloatOver.svelte
Normal file
|
@ -0,0 +1,11 @@
|
|||
<script lang="ts">
|
||||
/**
|
||||
* The slotted element will be shown on top, with a lower-opacity border
|
||||
*/
|
||||
</script>
|
||||
|
||||
<div class="absolute top-0 right-0 w-screen h-screen overflow-auto" style="background-color: #00000088">
|
||||
<div class="flex flex-col m-4 sm:m-6 md:m-8 p-4 sm:p-6 md:m-8 normal-background rounded normal-background">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Asks to add a feature at the last clicked location, at least if zoom is sufficient
|
||||
*/
|
||||
import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import { ImmutableStore, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import Svg from "../../Svg"
|
||||
import { SubtleButton } from "../Base/SubtleButton"
|
||||
import Combine from "../Base/Combine"
|
||||
|
@ -16,18 +16,14 @@ import CreateNewNodeAction from "../../Logic/Osm/Actions/CreateNewNodeAction"
|
|||
import { OsmObject, OsmWay } from "../../Logic/Osm/OsmObject"
|
||||
import PresetConfig from "../../Models/ThemeConfig/PresetConfig"
|
||||
import FilteredLayer from "../../Models/FilteredLayer"
|
||||
import Loc from "../../Models/Loc"
|
||||
import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"
|
||||
import { Changes } from "../../Logic/Osm/Changes"
|
||||
import FeaturePipeline from "../../Logic/FeatureSource/FeaturePipeline"
|
||||
import { ElementStorage } from "../../Logic/ElementStorage"
|
||||
import ConfirmLocationOfPoint from "../NewPoint/ConfirmLocationOfPoint"
|
||||
import Loading from "../Base/Loading"
|
||||
import Hash from "../../Logic/Web/Hash"
|
||||
import { WayId } from "../../Models/OsmFeature"
|
||||
import { Tag } from "../../Logic/Tags/Tag"
|
||||
import { LoginToggle } from "../Popup/LoginButton"
|
||||
import { GlobalFilter } from "../../Models/GlobalFilter"
|
||||
import { SpecialVisualizationState } from "../SpecialVisualization"
|
||||
import { Feature } from "geojson"
|
||||
|
||||
/*
|
||||
* The SimpleAddUI is a single panel, which can have multiple states:
|
||||
|
@ -47,34 +43,8 @@ export interface PresetInfo extends PresetConfig {
|
|||
export default class SimpleAddUI extends LoginToggle {
|
||||
/**
|
||||
*
|
||||
* @param isShown
|
||||
* @param resetScrollSignal
|
||||
* @param filterViewIsOpened
|
||||
* @param state
|
||||
* @param takeLocationFrom: defaults to state.lastClickLocation. Take this location to add the new point around
|
||||
*/
|
||||
constructor(
|
||||
isShown: UIEventSource<boolean>,
|
||||
resetScrollSignal: UIEventSource<void>,
|
||||
filterViewIsOpened: UIEventSource<boolean>,
|
||||
state: {
|
||||
featureSwitchIsTesting: UIEventSource<boolean>
|
||||
featureSwitchUserbadge: Store<boolean>
|
||||
layoutToUse: LayoutConfig
|
||||
osmConnection: OsmConnection
|
||||
changes: Changes
|
||||
allElements: ElementStorage
|
||||
LastClickLocation: UIEventSource<{ lat: number; lon: number }>
|
||||
featurePipeline: FeaturePipeline
|
||||
selectedElement: UIEventSource<any>
|
||||
locationControl: UIEventSource<Loc>
|
||||
filteredLayers: UIEventSource<FilteredLayer[]>
|
||||
featureSwitchFilter: UIEventSource<boolean>
|
||||
backgroundLayer: UIEventSource<BaseLayer>
|
||||
globalFilters: UIEventSource<GlobalFilter[]>
|
||||
},
|
||||
takeLocationFrom?: UIEventSource<{ lat: number; lon: number }>
|
||||
) {
|
||||
constructor(state: SpecialVisualizationState) {
|
||||
const readYourMessages = new Combine([
|
||||
Translations.t.general.readYourMessages.Clone().SetClass("alert"),
|
||||
new SubtleButton(Svg.envelope_ui(), Translations.t.general.goToInbox, {
|
||||
|
@ -83,13 +53,10 @@ export default class SimpleAddUI extends LoginToggle {
|
|||
}),
|
||||
])
|
||||
|
||||
takeLocationFrom = takeLocationFrom ?? state.LastClickLocation
|
||||
const filterViewIsOpened = state.guistate.filterViewIsOpened
|
||||
const takeLocationFrom = state.mapProperties.lastClickLocation
|
||||
const selectedPreset = new UIEventSource<PresetInfo>(undefined)
|
||||
selectedPreset.addCallback((_) => {
|
||||
resetScrollSignal.ping()
|
||||
})
|
||||
|
||||
isShown.addCallback((_) => selectedPreset.setData(undefined)) // Clear preset selection when the UI is closed/opened
|
||||
takeLocationFrom.addCallback((_) => selectedPreset.setData(undefined))
|
||||
|
||||
const presetsOverview = SimpleAddUI.CreateAllPresetsPanel(selectedPreset, state)
|
||||
|
@ -104,14 +71,13 @@ export default class SimpleAddUI extends LoginToggle {
|
|||
tags.push(new Tag("_referencing_ways", "way/" + snapOntoWay.id))
|
||||
}
|
||||
const newElementAction = new CreateNewNodeAction(tags, location.lat, location.lon, {
|
||||
theme: state.layoutToUse?.id ?? "unkown",
|
||||
theme: state.layout?.id ?? "unkown",
|
||||
changeType: "create",
|
||||
snapOnto: snapOntoWay,
|
||||
})
|
||||
await state.changes.applyAction(newElementAction)
|
||||
selectedPreset.setData(undefined)
|
||||
isShown.setData(false)
|
||||
const selectedFeature = state.allElements.ContainingFeatures.get(
|
||||
const selectedFeature: Feature = state.indexedFeatures.featuresById.data.get(
|
||||
newElementAction.newElementId
|
||||
)
|
||||
state.selectedElement.setData(selectedFeature)
|
||||
|
@ -156,7 +122,7 @@ export default class SimpleAddUI extends LoginToggle {
|
|||
confirm,
|
||||
cancel,
|
||||
() => {
|
||||
isShown.setData(false)
|
||||
selectedPreset.setData(undefined)
|
||||
},
|
||||
{
|
||||
cancelIcon: Svg.back_svg(),
|
||||
|
@ -172,11 +138,11 @@ export default class SimpleAddUI extends LoginToggle {
|
|||
new Toggle(
|
||||
new Loading(Translations.t.general.add.stillLoading).SetClass("alert"),
|
||||
addUi,
|
||||
state.featurePipeline.runningQuery
|
||||
state.dataIsLoading
|
||||
),
|
||||
Translations.t.general.add.zoomInFurther.Clone().SetClass("alert"),
|
||||
state.locationControl.map(
|
||||
(loc) => loc.zoom >= Constants.userJourney.minZoomLevelToAddNewPoints
|
||||
state.mapProperties.zoom.map(
|
||||
(zoom) => zoom >= Constants.minZoomLevelToAddNewPoint
|
||||
)
|
||||
),
|
||||
readYourMessages,
|
||||
|
@ -222,12 +188,7 @@ export default class SimpleAddUI extends LoginToggle {
|
|||
|
||||
private static CreateAllPresetsPanel(
|
||||
selectedPreset: UIEventSource<PresetInfo>,
|
||||
state: {
|
||||
featureSwitchIsTesting: UIEventSource<boolean>
|
||||
filteredLayers: UIEventSource<FilteredLayer[]>
|
||||
featureSwitchFilter: UIEventSource<boolean>
|
||||
osmConnection: OsmConnection
|
||||
}
|
||||
state: SpecialVisualizationState
|
||||
): BaseUIElement {
|
||||
const presetButtons = SimpleAddUI.CreatePresetButtons(state, selectedPreset)
|
||||
let intro: BaseUIElement = Translations.t.general.add.intro
|
||||
|
@ -260,18 +221,14 @@ export default class SimpleAddUI extends LoginToggle {
|
|||
/*
|
||||
* Generates the list with all the buttons.*/
|
||||
private static CreatePresetButtons(
|
||||
state: {
|
||||
filteredLayers: UIEventSource<FilteredLayer[]>
|
||||
featureSwitchFilter: UIEventSource<boolean>
|
||||
osmConnection: OsmConnection
|
||||
},
|
||||
state: SpecialVisualizationState,
|
||||
selectedPreset: UIEventSource<PresetInfo>
|
||||
): BaseUIElement {
|
||||
const allButtons = []
|
||||
for (const layer of state.filteredLayers.data) {
|
||||
for (const layer of Array.from(state.layerState.filteredLayers.values())) {
|
||||
if (layer.isDisplayed.data === false) {
|
||||
// The layer is not displayed...
|
||||
if (!state.featureSwitchFilter.data) {
|
||||
if (!state.featureSwitches.featureSwitchFilter.data) {
|
||||
// ...and we cannot enable the layer control -> we skip, as these presets can never be shown anyway
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -48,7 +48,6 @@ export default class DefaultGUI {
|
|||
public setup() {
|
||||
this.SetupUIElements()
|
||||
this.SetupMap()
|
||||
ScrollableFullScreen.ActivateCurrent()
|
||||
|
||||
if (
|
||||
this.state.layoutToUse.customCss !== undefined &&
|
||||
|
@ -168,13 +167,6 @@ export default class DefaultGUI {
|
|||
features: state.selectedElementsLayer,
|
||||
state,
|
||||
})
|
||||
|
||||
state.leafletMap.addCallbackAndRunD((_) => {
|
||||
// Lets assume that all showDataLayers are initialized at this point
|
||||
state.selectedElement.ping()
|
||||
State.state.locationControl.ping()
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
private SetupUIElements() {
|
||||
|
|
|
@ -20,11 +20,12 @@ import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeature
|
|||
|
||||
class PointRenderingLayer {
|
||||
private readonly _config: PointRenderingConfig
|
||||
private readonly _visibility?: Store<boolean>
|
||||
private readonly _fetchStore?: (id: string) => Store<Record<string, string>>
|
||||
private readonly _map: MlMap
|
||||
private readonly _onClick: (feature: Feature) => void
|
||||
private readonly _allMarkers: Map<string, Marker> = new Map<string, Marker>()
|
||||
|
||||
private _dirty = false
|
||||
constructor(
|
||||
map: MlMap,
|
||||
features: FeatureSource,
|
||||
|
@ -33,6 +34,7 @@ class PointRenderingLayer {
|
|||
fetchStore?: (id: string) => Store<Record<string, string>>,
|
||||
onClick?: (feature: Feature) => void
|
||||
) {
|
||||
this._visibility = visibility
|
||||
this._config = config
|
||||
this._map = map
|
||||
this._fetchStore = fetchStore
|
||||
|
@ -40,10 +42,20 @@ class PointRenderingLayer {
|
|||
const self = this
|
||||
|
||||
features.features.addCallbackAndRunD((features) => self.updateFeatures(features))
|
||||
visibility?.addCallbackAndRunD((visible) => self.setVisibility(visible))
|
||||
visibility?.addCallbackAndRunD((visible) => {
|
||||
if (visible === true && self._dirty) {
|
||||
self.updateFeatures(features.features.data)
|
||||
}
|
||||
self.setVisibility(visible)
|
||||
})
|
||||
}
|
||||
|
||||
private updateFeatures(features: Feature[]) {
|
||||
if (this._visibility?.data === false) {
|
||||
this._dirty = true
|
||||
return
|
||||
}
|
||||
this._dirty = false
|
||||
const cache = this._allMarkers
|
||||
const unseenKeys = new Set(cache.keys())
|
||||
for (const location of this._config.location) {
|
||||
|
@ -58,6 +70,9 @@ class PointRenderingLayer {
|
|||
this._config
|
||||
)
|
||||
}
|
||||
const id = feature.properties.id + "-" + location
|
||||
unseenKeys.delete(id)
|
||||
|
||||
const loc = GeoOperations.featureToCoordinateWithRenderingType(
|
||||
<any>feature,
|
||||
location
|
||||
|
@ -65,8 +80,6 @@ class PointRenderingLayer {
|
|||
if (loc === undefined) {
|
||||
continue
|
||||
}
|
||||
const id = feature.properties.id + "-" + location
|
||||
unseenKeys.delete(id)
|
||||
|
||||
if (cache.has(id)) {
|
||||
const cached = cache.get(id)
|
||||
|
@ -357,10 +370,12 @@ export default class ShowDataLayer {
|
|||
|
||||
private initDrawFeatures(map: MlMap) {
|
||||
let { features, doShowLayer, fetchStore, selectedElement, selectedLayer } = this._options
|
||||
const onClick = (feature: Feature) => {
|
||||
selectedElement?.setData(feature)
|
||||
selectedLayer?.setData(this._options.layer)
|
||||
}
|
||||
const onClick =
|
||||
this._options.onClick ??
|
||||
((feature: Feature) => {
|
||||
selectedElement?.setData(feature)
|
||||
selectedLayer?.setData(this._options.layer)
|
||||
})
|
||||
for (let i = 0; i < this._options.layer.lineRendering.length; i++) {
|
||||
const lineRenderingConfig = this._options.layer.lineRendering[i]
|
||||
new LineRenderingLayer(
|
||||
|
|
|
@ -33,4 +33,6 @@ export interface ShowDataLayerOptions {
|
|||
* If given, the map will update when a property is changed
|
||||
*/
|
||||
fetchStore?: (id: string) => Store<Record<string, string>>
|
||||
|
||||
onClick?: (feature: Feature) => void
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ import Toggle from "../Input/Toggle"
|
|||
import Title from "../Base/Title"
|
||||
import { MapillaryLinkVis } from "./MapillaryLinkVis"
|
||||
import { SpecialVisualization, SpecialVisualizationState } from "../SpecialVisualization"
|
||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
|
||||
import { Feature } from "geojson"
|
||||
|
||||
export class NearbyImageVis implements SpecialVisualization {
|
||||
args: { name: string; defaultValue?: string; doc: string; required?: boolean }[] = [
|
||||
|
@ -39,11 +41,12 @@ export class NearbyImageVis implements SpecialVisualization {
|
|||
constr(
|
||||
state: SpecialVisualizationState,
|
||||
tagSource: UIEventSource<Record<string, string>>,
|
||||
args: string[]
|
||||
args: string[],
|
||||
feature: Feature,
|
||||
layer: LayerConfig
|
||||
): BaseUIElement {
|
||||
const t = Translations.t.image.nearbyPictures
|
||||
const mode: "open" | "expandable" | "collapsable" = <any>args[0]
|
||||
const feature = state.indexedFeatures.featuresById.data.get(tagSource.data.id)
|
||||
const [lon, lat] = GeoOperations.centerpointCoordinates(feature)
|
||||
const id: string = tagSource.data["id"]
|
||||
const canBeEdited: boolean = !!id?.match("(node|way|relation)/-?[0-9]+")
|
||||
|
@ -128,7 +131,7 @@ export class NearbyImageVis implements SpecialVisualization {
|
|||
slideshow,
|
||||
controls,
|
||||
saveButton,
|
||||
new MapillaryLinkVis().constr(state, tagSource, []).SetClass("mt-6"),
|
||||
new MapillaryLinkVis().constr(state, tagSource, [], feature).SetClass("mt-6"),
|
||||
])
|
||||
})
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import { onDestroy } from "svelte";
|
||||
import { Translation } from "../../i18n/Translation";
|
||||
import Locale from "../../i18n/Locale";
|
||||
import FromHtml from "../../Base/FromHtml.svelte";
|
||||
|
||||
export let template: Translation;
|
||||
let _template: string
|
||||
|
@ -20,7 +21,7 @@
|
|||
</script>
|
||||
|
||||
<span>
|
||||
{Utils.SubstituteKeys(before, _tags)}
|
||||
<FromHtml src={Utils.SubstituteKeys(before, _tags)}/>
|
||||
<slot />
|
||||
{Utils.SubstituteKeys(after, _tags)}
|
||||
<FromHtml src={Utils.SubstituteKeys(after, _tags)}/>
|
||||
</span>
|
||||
|
|
|
@ -41,10 +41,7 @@
|
|||
return true;
|
||||
}
|
||||
|
||||
console.log("Got layer", layer, onlyForLabels, notForLabels);
|
||||
|
||||
const baseQuestions = (layer.tagRenderings ?? [])?.filter(tr => allowed(tr.labels) && tr.question !== undefined);
|
||||
console.log("BaseQuestions are", baseQuestions);
|
||||
let skippedQuestions = new UIEventSource<Set<string>>(new Set<string>());
|
||||
|
||||
let questionsToAsk = tags.map(tags => {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
import { createEventDispatcher } from "svelte";
|
||||
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig";
|
||||
import { ExclamationIcon } from "@rgossiaux/svelte-heroicons/solid";
|
||||
import SpecialTranslation from "./SpecialTranslation.svelte";
|
||||
|
||||
export let config: TagRenderingConfig;
|
||||
export let tags: UIEventSource<Record<string, string>>;
|
||||
|
@ -86,15 +87,15 @@
|
|||
<div class="border border-black subtle-background flex flex-col">
|
||||
<If condition={state.featureSwitchIsTesting}>
|
||||
<div class="flex justify-between">
|
||||
<Tr t={config.question}></Tr>
|
||||
<SpecialTranslation t={config.question} {tags} {state} {layer} feature={selectedElement}></SpecialTranslation>
|
||||
<span class="alert">{config.id}</span>
|
||||
</div>
|
||||
<Tr slot="else" t={config.question}></Tr>
|
||||
<SpecialTranslation slot="else" t={config.question} {tags} {state} {layer} feature={selectedElement}></SpecialTranslation>
|
||||
</If>
|
||||
|
||||
{#if config.questionhint}
|
||||
<div class="subtle">
|
||||
<Tr t={config.questionHint}></Tr>
|
||||
<SpecialTranslation t={config.questionhint} {tags} {state} {layer} feature={selectedElement}></SpecialTranslation>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import FullNodeDatabaseSource from "../Logic/FeatureSource/TiledFeatureSource/Fu
|
|||
import { MangroveIdentity } from "../Logic/Web/MangroveReviews"
|
||||
import { GeoIndexedStoreForLayer } from "../Logic/FeatureSource/Actors/GeoIndexedStore"
|
||||
import LayerConfig from "../Models/ThemeConfig/LayerConfig"
|
||||
import FeatureSwitchState from "../Logic/State/FeatureSwitchState"
|
||||
|
||||
/**
|
||||
* The state needed to render a special Visualisation.
|
||||
|
@ -19,6 +20,7 @@ import LayerConfig from "../Models/ThemeConfig/LayerConfig"
|
|||
export interface SpecialVisualizationState {
|
||||
readonly guistate: DefaultGuiState
|
||||
readonly layout: LayoutConfig
|
||||
readonly featureSwitches: FeatureSwitchState
|
||||
|
||||
readonly layerState: LayerState
|
||||
readonly featureProperties: { getStore(id: string): UIEventSource<Record<string, string>> }
|
||||
|
|
|
@ -56,6 +56,7 @@ import Maproulette from "../Logic/Maproulette"
|
|||
import SvelteUIElement from "./Base/SvelteUIElement"
|
||||
import { BBoxFeatureSourceForLayer } from "../Logic/FeatureSource/Sources/TouchesBboxFeatureSource"
|
||||
import QuestionViz from "./Popup/QuestionViz"
|
||||
import SimpleAddUI from "./BigComponents/SimpleAddUI"
|
||||
|
||||
export default class SpecialVisualizations {
|
||||
public static specialVisualizations: SpecialVisualization[] = SpecialVisualizations.initList()
|
||||
|
@ -232,6 +233,15 @@ export default class SpecialVisualizations {
|
|||
private static initList(): SpecialVisualization[] {
|
||||
const specialVisualizations: SpecialVisualization[] = [
|
||||
new QuestionViz(),
|
||||
{
|
||||
funcName: "add_new_point",
|
||||
docs: "An element which allows to add a new point on the 'last_click'-location. Only makes sense in the layer `last_click`",
|
||||
args: [],
|
||||
constr(state: SpecialVisualizationState): BaseUIElement {
|
||||
return new SimpleAddUI(state)
|
||||
},
|
||||
},
|
||||
|
||||
new HistogramViz(),
|
||||
new StealViz(),
|
||||
new MinimapViz(),
|
||||
|
@ -670,7 +680,9 @@ export default class SpecialVisualizations {
|
|||
if (title === undefined) {
|
||||
return undefined
|
||||
}
|
||||
return new SubstitutedTranslation(title, tagsSource, state)
|
||||
return new SubstitutedTranslation(title, tagsSource, state).RemoveClass(
|
||||
"w-full"
|
||||
)
|
||||
})
|
||||
),
|
||||
},
|
||||
|
|
|
@ -11,6 +11,7 @@ import LinkToWeblate from "./Base/LinkToWeblate"
|
|||
import { SpecialVisualization, SpecialVisualizationState } from "./SpecialVisualization"
|
||||
import SpecialVisualizations from "./SpecialVisualizations"
|
||||
import { Feature } from "geojson"
|
||||
import LayerConfig from "../Models/ThemeConfig/LayerConfig"
|
||||
|
||||
export class SubstitutedTranslation extends VariableUiElement {
|
||||
public constructor(
|
||||
|
@ -24,7 +25,8 @@ export class SubstitutedTranslation extends VariableUiElement {
|
|||
state: SpecialVisualizationState,
|
||||
tagSource: UIEventSource<Record<string, string>>,
|
||||
argument: string[],
|
||||
feature: Feature
|
||||
feature: Feature,
|
||||
layer: LayerConfig
|
||||
) => BaseUIElement)
|
||||
> = undefined
|
||||
) {
|
||||
|
@ -85,7 +87,7 @@ export class SubstitutedTranslation extends VariableUiElement {
|
|||
tagsSource.data.id
|
||||
)
|
||||
return viz.func
|
||||
.constr(state, tagsSource, proto.args, feature)
|
||||
.constr(state, tagsSource, proto.args, feature, undefined)
|
||||
?.SetStyle(proto.style)
|
||||
} catch (e) {
|
||||
console.error("SPECIALRENDERING FAILED for", tagsSource.data?.id, e)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { Store, UIEventSource } from "../Logic/UIEventSource";
|
||||
import { ImmutableStore, Store, UIEventSource } from "../Logic/UIEventSource";
|
||||
import { Map as MlMap } from "maplibre-gl";
|
||||
import MaplibreMap from "./Map/MaplibreMap.svelte";
|
||||
import LayoutConfig from "../Models/ThemeConfig/LayoutConfig";
|
||||
|
@ -22,6 +22,7 @@
|
|||
import { MenuIcon } from "@rgossiaux/svelte-heroicons/solid";
|
||||
import Tr from "./Base/Tr.svelte";
|
||||
import CommunityIndexView from "./BigComponents/CommunityIndexView.svelte";
|
||||
import FloatOver from "./Base/FloatOver.svelte";
|
||||
|
||||
export let layout: LayoutConfig;
|
||||
const state = new ThemeViewState(layout);
|
||||
|
@ -57,6 +58,11 @@
|
|||
<MapControlButton on:click={() =>state.guistate.menuIsOpened.setData(true)}>
|
||||
<MenuIcon class="w-8 h-8"></MenuIcon>
|
||||
</MapControlButton>
|
||||
<If condition={state.featureSwitchIsTesting}>
|
||||
<span class="alert">
|
||||
Testmode
|
||||
</span>
|
||||
</If>
|
||||
</div>
|
||||
|
||||
<div class="absolute bottom-0 left-0 mb-4 ml-4">
|
||||
|
@ -87,8 +93,7 @@
|
|||
|
||||
<If condition={state.guistate.welcomeMessageIsOpened}>
|
||||
<!-- Theme page -->
|
||||
<div class="absolute top-0 left-0 w-screen h-screen" style="background-color: #00000088">
|
||||
<div class="flex flex-col m-4 sm:m-6 md:m-8 p-4 sm:p-6 md:m-8 normal-background rounded">
|
||||
<FloatOver>
|
||||
<div on:click={() => state.guistate.welcomeMessageIsOpened.setData(false)}>Close</div>
|
||||
<TabGroup>
|
||||
<TabList>
|
||||
|
@ -136,15 +141,13 @@
|
|||
<TabPanel>Content 3</TabPanel>
|
||||
</TabPanels>
|
||||
</TabGroup>
|
||||
</div>
|
||||
</div>
|
||||
</FloatOver>
|
||||
</If>
|
||||
|
||||
|
||||
<If condition={state.guistate.menuIsOpened}>
|
||||
<!-- Menu page -->
|
||||
<div class="absolute top-0 left-0 w-screen h-screen overflow-auto" style="background-color: #00000088">
|
||||
<div class="flex flex-col m-4 sm:m-6 md:m-8 p-4 sm:p-6 md:m-8 normal-background rounded">
|
||||
<FloatOver>
|
||||
<div on:click={() => state.guistate.menuIsOpened.setData(false)}>Close</div>
|
||||
<TabGroup>
|
||||
<TabList>
|
||||
|
@ -174,20 +177,15 @@
|
|||
<TabPanel>Privacy</TabPanel>
|
||||
</TabPanels>
|
||||
</TabGroup>
|
||||
</div>
|
||||
</div>
|
||||
</FloatOver>
|
||||
</If>
|
||||
|
||||
{#if $selectedElement !== undefined && $selectedLayer !== undefined}
|
||||
<div class="absolute top-0 right-0 w-screen h-screen overflow-auto" style="background-color: #00000088">
|
||||
<FloatOver>
|
||||
<SelectedElementView layer={$selectedLayer} selectedElement={$selectedElement}
|
||||
tags={$selectedElementTags} state={state}></SelectedElementView>
|
||||
</FloatOver>
|
||||
|
||||
<div class="flex flex-col m-4 sm:m-6 md:m-8 p-4 sm:p-6 md:m-8 normal-background rounded normal-background">
|
||||
|
||||
<SelectedElementView layer={$selectedLayer} selectedElement={$selectedElement}
|
||||
tags={$selectedElementTags} state={state}></SelectedElementView>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<style>
|
||||
/* WARNING: This is just for demonstration.
|
||||
|
|
116
assets/layers/last_click/last_click.json
Normal file
116
assets/layers/last_click/last_click.json
Normal file
|
@ -0,0 +1,116 @@
|
|||
{
|
||||
"id": "last_click",
|
||||
"description": "This layer defines how to render the 'last click'-location. By default, it will show a marker with the possibility to add a new point (if there are some presets) and/or to add a new note (if the 'note' layer attribute is set). If none are possible, this layer won't show up",
|
||||
"source": "special",
|
||||
"name": null,
|
||||
"titleIcons": [],
|
||||
"title": {
|
||||
"mappings": [
|
||||
{
|
||||
"if": {
|
||||
"and": [
|
||||
"has_note_layer=yes",
|
||||
"has_presets=yes"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"en": "Add a new point or add a note",
|
||||
"nl": "Voeg een nieuw punt of een nieuwe kaartnota toe"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "has_note_layer=yes",
|
||||
"then": {
|
||||
"en": "Add a new note",
|
||||
"nl": "Voeg een nieuwe kaartnota toe"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "has_presets=yes",
|
||||
"then": {
|
||||
"en": "Add a new point",
|
||||
"nl": "Voeg een nieuw punt toe"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"tagRenderings": [
|
||||
{
|
||||
"id": "add_new",
|
||||
"mappings": [
|
||||
{
|
||||
"if": "has_presets=yes",
|
||||
"then": {
|
||||
"*": "{add_new_point()}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"all_tags"
|
||||
],
|
||||
"mapRendering": [
|
||||
{
|
||||
"icon": {
|
||||
"mappings": [
|
||||
{
|
||||
"if": "number_of_presets=1",
|
||||
"then": "{first_preset}"
|
||||
}
|
||||
],
|
||||
"render": "<div class='relative'> <img src='./assets/svg/add_pin.svg' class='absolute' style='height: 50px'> <div class='absolute top-0 left-0 rounded-full overflow-hidden' style='width: 40px; height: 40px'><div class='flex slide min-w-min' style='animation: slide linear {number_of_presets}s infinite; width: calc( (1 + {number_of_presets}) * 40px ); height: 40px'>{renderings}{first_preset}</div></div></div>"
|
||||
},
|
||||
"labelCssClasses": "text-sm min-w-min pl-1 pr-1 bg-gray-400 rounded-3xl text-white opacity-65 whitespace-nowrap",
|
||||
"label": {
|
||||
"render": {
|
||||
"ca": "Afegir nou element",
|
||||
"cs": "Klikněte zde pro přidání nové položky",
|
||||
"da": "Klik her for at tilføje et nyt punkt",
|
||||
"de": "Hier klicken, um ein neues Element hinzuzufügen",
|
||||
"en": "Click here to add a new item",
|
||||
"es": "Haga clic aquí para añadir un nuevo ítem",
|
||||
"fil": "I-click ito para mag-dagdag ng bagong bagay",
|
||||
"fr": "Cliquez ici pour ajouter un élément",
|
||||
"hu": "Új elem hozzáadásához kattints ide",
|
||||
"id": "Klik di sini untuk menambahkan item baru",
|
||||
"it": "Aggiungi nuovo elemento",
|
||||
"nb_NO": "Legg til nytt element",
|
||||
"nl": "Klik hier om een item toe te voegen",
|
||||
"pt": "Adicionar novo item",
|
||||
"zh_Hant": "點這邊新增新項目"
|
||||
}
|
||||
},
|
||||
"iconBadges": [
|
||||
{
|
||||
"if": {
|
||||
"or": [
|
||||
"has_note_layer=yes",
|
||||
"has_presets=yes"
|
||||
]
|
||||
},
|
||||
"then": "<img class='animate-pulse' src='./assets/svg/addSmall.svg'>"
|
||||
}
|
||||
],
|
||||
"location": [
|
||||
"point"
|
||||
],
|
||||
"iconSize": "40,50,bottom"
|
||||
}
|
||||
],
|
||||
"filter": [
|
||||
{
|
||||
"id": "action",
|
||||
"options": [
|
||||
{
|
||||
"default": true,
|
||||
"question": "only_if_action_is_possible",
|
||||
"osmTags": {
|
||||
"or": [
|
||||
"has_note_layer=yes",
|
||||
"has_presets=yes"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -22,4 +22,4 @@
|
|||
"cssClasses": "block relative rounded-full"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,27 +2,39 @@
|
|||
"id": "shared_questions",
|
||||
"questions": {
|
||||
"description": "Show the images block at this location",
|
||||
"render": "{questions()}"
|
||||
"render": {
|
||||
"*": "{questions()}"
|
||||
}
|
||||
},
|
||||
"images": {
|
||||
"description": "This block shows the known images which are linked with the `image`-keys, but also via `mapillary` and `wikidata`",
|
||||
"render": "{image_carousel()}{image_upload()}{nearby_images(expandable)}"
|
||||
"render": {
|
||||
"*": "{image_carousel()}{image_upload()}{nearby_images(expandable)}"
|
||||
}
|
||||
},
|
||||
"mapillary": {
|
||||
"description": "Shows a button to open Mapillary on this location",
|
||||
"render": "{mapillary()}"
|
||||
"render": {
|
||||
"*": "{mapillary()}"
|
||||
}
|
||||
},
|
||||
"export_as_gpx": {
|
||||
"description": "Shows a button to export this feature as GPX. Especially useful for route relations",
|
||||
"render": "{export_as_gpx()}"
|
||||
"render": {
|
||||
"*": "{export_as_gpx()}"
|
||||
}
|
||||
},
|
||||
"export_as_geojson": {
|
||||
"description": "Shows a button to export this feature as geojson. Especially useful for debugging or using this in other programs",
|
||||
"render": "{export_as_geojson()}"
|
||||
"render": {
|
||||
"*": "{export_as_geojson()}"
|
||||
}
|
||||
},
|
||||
"wikipedia": {
|
||||
"description": "Shows a wikipedia box with the corresponding wikipedia article; the wikidata-item link can be changed by a contributor",
|
||||
"render": "{wikipedia():max-height:25rem}",
|
||||
"render": {
|
||||
"*": "{wikipedia():max-height:25rem}"
|
||||
},
|
||||
"question": {
|
||||
"en": "What is the corresponding Wikidata entity?",
|
||||
"nl": "Welk Wikidata-item komt overeen met dit object?",
|
||||
|
@ -106,11 +118,15 @@
|
|||
},
|
||||
"reviews": {
|
||||
"description": "Shows the reviews module (including the possibility to leave a review)",
|
||||
"render": "{reviews()}"
|
||||
"render": {
|
||||
"*": "{reviews()}"
|
||||
}
|
||||
},
|
||||
"minimap": {
|
||||
"description": "Shows a small map with the feature. Added by default to every popup",
|
||||
"render": "{minimap(18, id): width:100%; height:8rem; border-radius:2rem; overflow: hidden; pointer-events: none;}"
|
||||
"render": {
|
||||
"*": "{minimap(18, id): width:100%; height:8rem; border-radius:2rem; overflow: hidden; pointer-events: none;}"
|
||||
}
|
||||
},
|
||||
"phone": {
|
||||
"question": {
|
||||
|
@ -138,7 +154,9 @@
|
|||
"da": "Hvad er telefonnummeret til {title()}?",
|
||||
"cs": "Jaké je telefonní číslo {title()}?"
|
||||
},
|
||||
"render": "<a href='tel:{phone}'>{phone}</a>",
|
||||
"render": {
|
||||
"*": "<a href='tel:{phone}'>{phone}</a>"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "contact:phone~*",
|
||||
|
@ -155,7 +173,9 @@
|
|||
}
|
||||
},
|
||||
"osmlink": {
|
||||
"render": "<a href='https://openstreetmap.org/{id}' target='_blank'><img src='./assets/svg/osm-logo-us.svg'/></a>",
|
||||
"render": {
|
||||
"*": "<a href='https://openstreetmap.org/{id}' target='_blank'><img src='./assets/svg/osm-logo-us.svg'/></a>"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "id~=-",
|
||||
|
@ -164,7 +184,9 @@
|
|||
]
|
||||
},
|
||||
"wikipedialink": {
|
||||
"render": "<a href='https://wikipedia.org/wiki/{wikipedia}' target='_blank'><img src='./assets/wikipedia.svg' alt='WP'/></a>",
|
||||
"render": {
|
||||
"*": "<a href='https://wikipedia.org/wiki/{wikipedia}' target='_blank'><img src='./assets/wikipedia.svg' alt='WP'/></a>"
|
||||
},
|
||||
"question": {
|
||||
"en": "What is the corresponding item on Wikipedia?",
|
||||
"nl": "Welk Wikipedia-artikel beschrijft dit object?",
|
||||
|
@ -217,7 +239,9 @@
|
|||
}
|
||||
},
|
||||
"email": {
|
||||
"render": "<a href='mailto:{email}' target='_blank'>{email}</a>",
|
||||
"render": {
|
||||
"*": "<a href='mailto:{email}' target='_blank'>{email}</a>"
|
||||
},
|
||||
"question": {
|
||||
"nl": "Wat is het e-mailadres van {title()}?",
|
||||
"fr": "Quelle est l'adresse courriel de {title()} ?",
|
||||
|
@ -284,7 +308,9 @@
|
|||
"da": "Hvad er webstedet for {title()}?",
|
||||
"cs": "Jaká je webová stránka {title()}?"
|
||||
},
|
||||
"render": "<a href='{website}' rel='nofollow noopener noreferrer' target='_blank'>{website}</a>",
|
||||
"render": {
|
||||
"*": "<a href='{website}' rel='nofollow noopener noreferrer' target='_blank'>{website}</a>"
|
||||
},
|
||||
"freeform": {
|
||||
"key": "website",
|
||||
"type": "url",
|
||||
|
@ -598,7 +624,9 @@
|
|||
"da": "Er der stadig noget relevant, du ikke kunne give i de foregående spørgsmål? Tilføj det her.",
|
||||
"cs": "Je ještě něco relevantního, co jste nemohli uvést v předchozích otázkách? Přidejte to sem."
|
||||
},
|
||||
"render": "{description}",
|
||||
"render": {
|
||||
"*": "{description}"
|
||||
},
|
||||
"freeform": {
|
||||
"key": "description"
|
||||
},
|
||||
|
@ -1385,11 +1413,15 @@
|
|||
"last_edit": {
|
||||
"#": "Gives some metainfo about the last edit and who did edit it - rendering only",
|
||||
"condition": "_last_edit:contributor~*",
|
||||
"render": "<div class='subtle' style='font-size: small; margin-top: 2em; margin-bottom: 0.5em;'><a href='https://www.openStreetMap.org/changeset/{_last_edit:changeset}' target='_blank'>Last edited on {_last_edit:timestamp}</a> by <a href='https://www.openStreetMap.org/user/{_last_edit:contributor}' target='_blank'>{_last_edit:contributor}</a></div>"
|
||||
"render": {
|
||||
"*": "<div class='subtle' style='font-size: small; margin-top: 2em; margin-bottom: 0.5em;'><a href='https://www.openStreetMap.org/changeset/{_last_edit:changeset}' target='_blank'>Last edited on {_last_edit:timestamp}</a> by <a href='https://www.openStreetMap.org/user/{_last_edit:contributor}' target='_blank'>{_last_edit:contributor}</a></div>"
|
||||
}
|
||||
},
|
||||
"all_tags": {
|
||||
"description": "Shows a table with all the tags of the feature",
|
||||
"render": "{all_tags()}"
|
||||
"render": {
|
||||
"*": "{all_tags()}"
|
||||
}
|
||||
},
|
||||
"multilevels": {
|
||||
"builtin": "level",
|
||||
|
@ -1984,4 +2016,4 @@
|
|||
"pl": "Nazwa sieci to <b>{internet_access:ssid}</b>"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,6 @@
|
|||
"aboutMapcomplete": "<h3>Sobre</h3><p>Utilitza MapCompelte per afegir informació a OpenStreetMap amb una <b>petició.</b> Respon preguntes i en minuts les teves contribucions estaran disponibles arreu. En molts temes pots afegir fotografies o fins i tot afegeix \"reviews\". La persona <b>gestionadora</b> defineix elements, preguntes i idiomes per a fer-ho possible.</p><h3>Troba més info</h3><p>MapComplete sempre <b>ofereix el següent pas</b> per aprendre'n més sobre OpenStreetMap.</p><ul><li>Inclòs en una pàgina web et porta a MapComplete a pantalla completa.</li><li>Aquesta versió ofereix informació sobre OpenStreetMap.</li><li>Veure funciona sense entrar però editar o contribuir requereix un compte d'OSM.</li><li>Si no has entrat et demanarà que ho facis.</li><li>Responent una simple pregunta, pots afegir nous elements al mapa</li><li> Després d'una estona es mostraran les etiquetes actuals , i després els enllaços a la wiki.</li></ul><p></p><br><p>Has trobat alguna <b>incidència</b>? Tens alguna <b> petició </b>? Vols <b>ajudar a traduir</b>? Vés a <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\"> per accedir al codi font</a> o al <a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\">registre d'incidències.</a> </p><p> Vols veure <b>els teus progressos </b>? Segueix el recompte d'edicions a <a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a>.</p>",
|
||||
"add": {
|
||||
"addNew": "Afegir {category} aquí",
|
||||
"addNewMapLabel": "Afegir nou element",
|
||||
"backToSelect": "Selecciona una categoria diferent",
|
||||
"confirmButton": "Afegir una {category}<br/><div class='alert'>La teva atribució és visible per a tots</div>",
|
||||
"confirmIntro": "<h3>Afegir {title} aquí?</h3>L'element que estàs creant <b>el veurà tothom</b>. Només afegeix coses que realment existeixen. Moltes aplicacions fan servir aquestes dades.",
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
"aboutMapcomplete": "<h3>O službě</h3><p>Pomocí MapComplete můžete přidávat informace z OpenStreetMap na <b>samostatné téma</b>. Odpovězte na otázky a během několika minut jsou vaše příspěvky dostupné všude. Ve většině témat můžete přidávat obrázky nebo dokonce zanechat hodnocení. <b>Správce tématu</b> pro něj definuje prvky, otázky a jazyky.</p><h3>Další informace</h3><p>MapComplete vždy <b>nabízí další krok</b> k získání dalších informací o OpenStreetMap.<ul><li>Při vložení do webové stránky odkazuje iframe na MapComplete na celou obrazovku.</li><li>Verze na celou obrazovku nabízí informace o OpenStreetMap.</li><li>Prohlížení funguje bez přihlášení, ale editace vyžaduje účet OSM.</li><li>Pokud nejste přihlášeni, jste k tomu vyzváni</li><li>Po zodpovězení jedné otázky můžete do mapy přidávat nové funkce</li><li>Po chvíli se zobrazí aktuální značky OSM, později odkaz na wiki</li></ul></p><br/><p>Všimli jste si <b>problému</b>? Máte <b>požadavek na funkci</b>? Chcete <b>pomoci s překladem</b>? Přejděte na <a href='https://github.com/pietervdvn/MapComplete' target='_blank'>zdrojový kód</a> nebo <a href='https://github.com/pietervdvn/MapComplete/issues' target='_blank'>sledovač problémů.</a> </p><p> Chcete se podívat na <b>svůj pokrok</b>? Sledujte počet úprav na <a href='{osmcha_link}' target='_blank' >OsmCha</a>.</p>",
|
||||
"add": {
|
||||
"addNew": "Přidat {category}",
|
||||
"addNewMapLabel": "Klikněte zde pro přidání nové položky",
|
||||
"confirmButton": "Přidat kategorii {category}<br/><div class='alert'>Váš příspěvek je viditelný pro všechny</div>",
|
||||
"disableFilters": "Vypnout všechny filtry",
|
||||
"import": {
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
"aboutMapcomplete": "<h3>Om MapComplete</h3><p>Brug det til at tilføje OpenStreetMap information om et <b>bestemt tema.</b> Besvar spørgsmål, og i løbet af få minutter er dine bidrag tilgængelige overalt. <b>temabestyreren</b> definerer elementer, spørgsmål og sprog for temaet.</p><h3>Find ud af mere</h3><p>MapComplete <b>tilbyder altid det næste trin</b> for at lære mere om OpenStreetMap.</p><ul><li>Når det er indlejret på et websted, linker iframe-en til et fuldskærms MapComplete</li><li>Fuldskærmsversionen tilbyder information om OpenStreetMap</li><li>Man kan se det uden at logge ind, men redigering kræver en OSM-konto.</li><li>Hvis du ikke har logget ind, vil du blive bedt om at gøre det</li><li>Når du har besvaret et enkelt spørgsmål, kan du tilføje nye punkter til kortet</li><li>Efter et stykke tid bliver faktiske OSM-tags vist, senere igen links til wiki-en</li></ul><p></p><br><p>Bemærkede du <b>et problem</b>? Har du en<b>anmodning om en ny funktion</b>? Vil du <b>hjælpe med at oversætte</b>? Gå til <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\">kildekoden</a> eller <a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\">issue trackeren.</a> </p><p> Vil du se <b>dit fremskridt</b>? Følg antallet af rettelser på <a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a>.</p>",
|
||||
"add": {
|
||||
"addNew": "Tilføj {category}",
|
||||
"addNewMapLabel": "Klik her for at tilføje et nyt punkt",
|
||||
"confirmButton": "Tilføj en {category}<br><div class=\"alert\">Din tilføjelse er synlig for alle</div>",
|
||||
"confirmIntro": "<h3>Tilføj en {title}?</h3>Punktet du opretter her vil være <b>synligt for alle</b>. Tilføj kun ting til kortet, hvis de virkelig findes. Mange programmer bruger disse data.",
|
||||
"disableFilters": "Slå alle filtre fra",
|
||||
|
|
|
@ -85,7 +85,6 @@
|
|||
"aboutMapcomplete": "<h3>Über</h3><p>Verwenden Sie MapComplete, um <b>themenbezogene Informationen</b> zu OpenStreetMap hinzuzufügen. Beantworten Sie Fragen, und in wenigen Minuten sind Ihre Beiträge überall verfügbar. Zu den meisten Themen können Sie Bilder hinzufügen oder eine Bewertung hinterlassen. Der <b>Theme-Maintainer</b> definiert dafür Elemente, Fragen und Sprachen.</p><h3>Mehr erfahren</h3><p>MapComplete bietet immer <b>den nächsten Schritt</b>, um mehr über OpenStreetMap zu erfahren.</p><ul><li>In einer Website eingebettet, verlinkt der iframe zu einer Vollbildversion von MapComplete</li><li>Die Vollbildversion bietet Informationen über OpenStreetMap</li><li>Das Betrachten funktioniert ohne Anmeldung, das Bearbeiten erfordert ein OSM-Konto.</li><li>Wenn Sie nicht angemeldet sind, werden Sie dazu aufgefordert</li><li>Sobald Sie eine Frage beantwortet haben, können Sie der Karte neue Objekte hinzufügen</li><li>Nach einer Weile werden aktuelle OSM-Tags angezeigt, die später mit dem Wiki verlinkt werden</li></ul><p></p><br/><p>Haben Sie ein <b>Problem</b> bemerkt? Haben Sie einen <b>Funktionswunsch</b>? Möchten Sie bei der <b>Übersetzung</b> helfen? Hier geht es zum <a href='https://github.com/pietervdvn/MapComplete' target='_blank'>Quellcode</a> und <a href='https://github.com/pietervdvn/MapComplete/issues' target='_blank'>Issue Tracker</a> </p><p>Möchten Sie Ihre <b>Bearbeitungen</b> sehen? Verfolgen Sie Ihre Änderungen auf <a href='{osmcha_link}' target='_blank' >OsmCha</a>.</p>",
|
||||
"add": {
|
||||
"addNew": "{category} hinzufügen",
|
||||
"addNewMapLabel": "Hier klicken, um ein neues Element hinzuzufügen",
|
||||
"backToSelect": "Wählen Sie eine andere Kategorie",
|
||||
"confirmButton": "Eine {category} hinzufügen.<br><div class=\"alert\">Ihre Ergänzung ist für alle sichtbar</div>",
|
||||
"confirmIntro": "<h3>Einen {title} hinzufügen?</h3>Das Objekt, das Sie erstellen wird <b>für alle sichtbar sein</b>. Bitte nur Dinge hinzufügen, die wirklich existieren. Viele Anwendungen verwenden diese Daten.",
|
||||
|
|
|
@ -91,7 +91,6 @@
|
|||
"aboutMapcomplete": "<p>Use MapComplete to add OpenStreetMap info on a <b>single theme.</b> Answer questions, and within minutes your contributions are available everywhere. In most themes you can add pictures or even leave a review. The <b>theme maintainer</b> defines elements, questions and languages for it.</p><h3>Find out more</h3><p>MapComplete always <b>offers the next step</b> to learn more about OpenStreetMap.<ul><li>When embedded in a website, the iframe links to a full-screen MapComplete.</li><li>The fullscreen version offers info about OpenStreetMap.</li><li>Viewing works without login, but editing requires an OSM account.</li><li>If you are not logged in, you are asked to do so</li><li>Once you answered a single question, you can add new features to the map</li><li>After a while, actual OSM-tags are shown, later linking to the wiki</li></ul></p><br/><p>Did you notice <b>an issue</b>? Do you have a <b>feature request</b>? Want to <b>help translate</b>? Head over to <a href='https://github.com/pietervdvn/MapComplete' target='_blank'>the source code</a> or <a href='https://github.com/pietervdvn/MapComplete/issues' target='_blank'>issue tracker.</a> </p><p> Want to see <b>your progress</b>? Follow the edit count on <a href='{osmcha_link}' target='_blank' >OsmCha</a>.</p>",
|
||||
"add": {
|
||||
"addNew": "Add {category}",
|
||||
"addNewMapLabel": "Click here to add a new item",
|
||||
"backToSelect": "Select a different category",
|
||||
"confirmButton": "Add a {category}<br/><div class='alert'>Your addition is visible for everyone</div>",
|
||||
"confirmIntro": "<h3>Add a {title}?</h3>The feature you create here will be <b>visible for everyone</b>. Please, only add things on to the map if they truly exist. A lot of applications use this data.",
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
"aboutMapcomplete": "<h3>Aceca de MapComplete</h3><p>Lo utilizamos para añadir información de OpenStreetMap en un <b>único tema. Responde preguntas, y en minutos tus contribuciones estarán disponibles en todos lados. El <b>mantenedor del tema</b> define elementos, preguntas e idiomas para él.</b></p><h3><b>Descubre más</b></h3><p><b>MapComplete siempre <b>ofrece el siguiente paso</b> para aprender más sobre OpenStreetMap.</b></p><ul><li><b>Cuando se embebe en un sitio web, el iframe enlaza a un MapComplete a pantalla completa</b></li><li><b>La versión a pantalla completa ofrece información sobre OpenStreetMpa</b></li><li><b>Se puede ver el trabajo sin iniciar sesión, pero la edición requiere una cuenta de OSM.</b></li><li><b>Si no has iniciado sesión, se te pedirá que lo hagas</b></li><li><b>Una vez que hayas respondido a una simple pregunta, podrás añadir nuevos puntos al mapa</b></li><li><b>Después de un poco, las etiquetas de OSM se mostrarán, después de enlazar a la wiki</b></li></ul><p></p><b><br><p>¿Te fijaste en <b>un problema</b>? Tienes una <b>petición de característica</b>?¿Quieres ayudar a traducir? Ve <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\"> al código fuente</a> o <a href=\"https://github/pietervdvn/MapComplete/issues\" target=\"_blank\">issue tracker.</a> </p><p>¿Quieres ver <b>tu progreso</b>? Sigue a la cuenta de ediciones en <a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a>.</p></b>",
|
||||
"add": {
|
||||
"addNew": "Añadir {category}",
|
||||
"addNewMapLabel": "Haga clic aquí para añadir un nuevo ítem",
|
||||
"confirmButton": "Añadir una {category} .<br><div class=\"alert\">Tu contribución es visible para todos</div>",
|
||||
"confirmIntro": "<h3>Añadir {title} aquí?</h3>El punto que estás creando <b>lo verá todo el mundo</b>. Sólo añade cosas que realmente existan. Muchas aplicaciones usan estos datos.",
|
||||
"disableFilters": "Desactivar todos los filtros",
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
"about": "Madaling i-edit at mag-dagdag sa OpenStreetMap gamit ang mga partikular na tikha",
|
||||
"add": {
|
||||
"addNew": "Dagdagan ng {category}",
|
||||
"addNewMapLabel": "I-click ito para mag-dagdag ng bagong bagay",
|
||||
"confirmButton": "Magdagdag ng {category}<br><div class=\"alert\">Makikita ng lahat ang idinagdag mo</div>",
|
||||
"confirmIntro": "<h3>Mag-dagdag ng {title}?</h3>Ang tampók na ida-dagdag mo ay <b>makikita ng lahat</b>. Paki-usap, mag-dagdag lamang ng mga bagay na tutuong umiiral. Marami pang mga aplikasyon ang gumagamit ng datos na ito.",
|
||||
"disableFilters": "Huwag paganahin ang lahat ng filter",
|
||||
|
|
|
@ -57,7 +57,6 @@
|
|||
"aboutMapcomplete": "<h3>À propos de MapComplete</h3><p>Avec MapComplete vous pouvez enrichir OpenStreetMap d'informations sur un <b>thème unique.</b> Répondez à quelques questions, et en quelques minutes vos contributions seront disponibles dans le monde entier ! Le <b>concepteur du thème</b> définis les éléments, questions et langues pour le thème.</p><h3>En savoir plus</h3><p>MapComplete <b>propose toujours l'étape suivante</b> pour en apprendre plus sur OpenStreetMap.</p><ul><li>Lorsqu'il est intégré dans un site Web, l'<i>iframe</i> pointe vers MapComplete en plein écran</li><li>La version plein écran donne des informations sur OpenStreetMap</li><li>Il est possible de regarder sans se connecter, mais l'édition demande une connexion à OSM.</li><li>Si vous n'êtes pas connecté, il vous est demandé de le faire</li><li>Une fois que vous avez répondu à une seule question, vous pouvez ajouter de nouveaux points à la carte</li><li>Au bout d'un moment, les vrais tags OSM sont montrés, qui pointent ensuite vers le wiki</li></ul><p></p><br><p>Vous avez remarqué <b>un problème</b> ? Vous souhaitez <b>demander une fonctionnalité</b> ? Vous voulez <b>aider à traduire</b> ? Allez voir <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\">le code source</a> ou le <a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\"><i>gestionnaire de tickets</i></a>.</p><p> Vous voulez visualiser <b>votre progression</b> ? Suivez le compteur d'édition sur <a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a>.</p>",
|
||||
"add": {
|
||||
"addNew": "Ajouter {category}",
|
||||
"addNewMapLabel": "Cliquez ici pour ajouter un élément",
|
||||
"backToSelect": "Sélectionner une catégorie différente",
|
||||
"confirmButton": "Ajouter un/une {category} ici.<br><div class=\"alert\">Votre ajout sera visible par tout le monde</div>",
|
||||
"confirmIntro": "<h3>Ajouter un/une {title} ici ?</h3>L’élément que vous ajouterez sera <b>visible par tout le monde</b>. Merci de vous assurer que celui-ci existe réellement. Beaucoup d'autres applications utilisent ces données.",
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
"aboutMapcomplete": "<h3>Névjegy</h3><p>A MapComplete-et használhatod, hogy egy <b>egy adott téma szerint</b> OpenStreetMap-adatokat adj hozzá az adatbázishoz. Válaszolj a kérdésekre, és a szerkesztéseid perceken belül mindenhol elérhetővé válnak. A legtöbb témánál hozzáadhatsz képeket vagy akár véleményt is írhatsz. A témához tartozó elemeket, kérdéseket és nyelveket a <b>téma karbantartója</b> határozza meg .</p><h3>További információk</h3><p>A MapComplete mindig <b>felkínálja a következő lépést</b> ahhoz, hogy tanulhass az OpenStreetMapről.</p><ul><li>Weboldalba ágyazva az iframe egy teljes képernyős MapComplete-hez vezet</li><li>A teljes képernyős változat az OpenStreetMapről mutat adatokat</li><li>A megtekintés bejelentkezés nélkül is működik, de a szerkesztéshez OSM-fiók szükséges</li><li>Ha nem vagy bejelentkezve, kérjük, tedd meg</li><li>Miután válaszoltál egy kérdésre, új elemeket helyezhetsz a térképre</li><li>Egy idő után megjelennek a tényleges OSM-címkék, amelyek később a wikire hivatkoznak</li></ul><p></p><br><p>Észrevettél <b>egy problémát</b>? Új <b>funkciót szeretnél kérni</b>? Szeretnél <b>segíteni a fordításban</b>? Látogass el a <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\">forráskódhoz</a> vagy a <a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\">problémakövetőhöz (issue tracker)</a>. </p><p> Szeretnéd látni <b>a fejlődést</b>? Kövesd a szerkesztések számát az <a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a> módosításkészlet-elemzőn.</p>",
|
||||
"add": {
|
||||
"addNew": "Új {category} hozzáadása",
|
||||
"addNewMapLabel": "Új elem hozzáadásához kattints ide",
|
||||
"confirmButton": "{category} hozzáadása.<br><div class=\"alert\">A hozzáadott objektum mindenki számára látható lesz</div>",
|
||||
"confirmIntro": "<h3>Felrajzolsz egy {title} objektumot?</h3>Az itt létrehozandó térképelemet <b>mindenki láthatja majd</b>. Kérjük, csak valóban létező dolgokat rajzolj fel a térképre. Ezeket az adatokat sok alkalmazás használja.",
|
||||
"disableFilters": "Minden szűrő kikapcsolása",
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
"general": {
|
||||
"add": {
|
||||
"addNew": "Tambahkan {category}",
|
||||
"addNewMapLabel": "Klik di sini untuk menambahkan item baru",
|
||||
"confirmButton": "Tambahkan {category}<br><div class=\"alert\">Penambahan Anda akan terlihat oleh semua orang</div>",
|
||||
"confirmIntro": "<h3>Tambahkan {title}?</h3>Fitur yang Anda buat di sini akan <b>terlihat oleh semua orang</b>. Harap menambahkan sesuatu ke peta hanya jika ia benar-benar ada. Banyak aplikasi menggunakan data ini.",
|
||||
"disableFiltersExplanation": "Beberapa fitur mungkin disembunyikan oleh penyaringan",
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
"aboutMapcomplete": "<h3>Informazioni</h3><p>Con MapComplete puoi arricchire OpenStreetMap con informazioni su un <b>singolo argomento</b>. Rispondi a poche domande e in pochi minuti i tuoi contributi saranno disponibili a tutto il mondo! L’utente <b>gestore del tema</b> definisce gli elementi, le domande e le lingue per quel tema.</p><h3>Scopri altro</h3><p>MapComplete <b>propone sempre un passo in più</b> per imparare qualcosa di nuovo su OpenStreetMap.</p><ul><li>Quando viene incorporato in un sito web, il collegamento dell’iframe punta a MapComplete a tutto schermo</li><li>La versione a tutto schermo fornisce informazioni su OpenStreetMap</li><li>La visualizzazione non necessita di alcun accesso ma per modificare occorre aver effettuato l’accesso su OSM.</li><li>Se non hai effettuato l’accesso, ti verrà richiesto di farlo</li><li>Dopo aver risposto ad una sola domanda potrai aggiungere dei nuovi punti alla mappa</li><li>Dopo qualche momento verranno mostrate le etichette effettive, in seguito i collegamenti alla wiki</li></ul><p></p><br><p>Hai trovato un <b>errore</b>? Vuoi richiedere <b>nuove funzionalità</b>? Vuoi aiutare con la <b>traduzione</b>? Dai un’occhiata al <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\">codice sorgente</a> oppure al <a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\">tracker degli errori.</a></p><p>Vuoi vedere i <b>tuoi progressi</b>?Segui il contatore delle modifiche su <a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a>.</p>",
|
||||
"add": {
|
||||
"addNew": "Aggiungi {category} qua",
|
||||
"addNewMapLabel": "Aggiungi nuovo elemento",
|
||||
"confirmButton": "Aggiungi una {category} qua.<br><div class=\"alert\">La tua aggiunta è visibile a chiunque</div>",
|
||||
"confirmIntro": "<h3>Aggiungere un {title}?</h3>L'elemento che hai creato qui sarà <b>visibile da chiunque</b>. Per favore, aggiungi sulla mappa solo oggetti realmente esistenti. Molte applicazioni usano questi dati.",
|
||||
"disableFilters": "Disabilita tutti i filtri",
|
||||
|
|
|
@ -74,7 +74,6 @@
|
|||
"aboutMapcomplete": "<h3>Om</h3><p>Bruk MapComplete til å legge til OpenStreetMap-info i <b>ett tema. </b>Besvar spørsmål og få endringene vist i løpet av minutter. I de fleste temaene kan du legge inn bilder eller legge igjen en vurdering. <b>Temavedlikeholderen</b> definerer elementer, spørsmål og språk for det.</p><h3>Finn ut mer</h3><p>MapComplete tilbyr alltid <b>neste steg</b> for å lære mer om OpenStreetMap.<ul><li>Når bygd inn på en nettside lenker iframe-elementet til en fullskjermsversjon av MapComplete.</li><li>Fullskjermsversjonen tilbyr info om OpenStreetMap.</li><li>Visning fungerer uten innlogging, men redigering krever en OSM-konto.</li><li>Hvis du ikke er innlogget blir du spurt om å gjøre det.</li><li>Når du har besvart ett spørsmål, kan du legge til nye funksjoner på kartet.</li><li>Etter en stund vil OSM-etiketter bli vist, som i sin tur lenker til wiki-en.</li></ul></p><br/><p>Har du oppdaget <b>et problem</b>? Har du en <b>funksjonsforespørsel</b>? Vil du bistå <b>oversettelsen</b>? Gå til <a href='https://github.com/pietervdvn/MapComplete' target='_blank'>kildekoden</a> eller <a href='https://github.com/pietervdvn/MapComplete/issues' target='_blank'>problemsporeren.</a> </p><p>Vil du se <b>din framdrift</b>? Følg redigeringsantallet på <a href='{osmcha_link}' target='_blank' >OsmCha</a>.</p>",
|
||||
"add": {
|
||||
"addNew": "Legg til {category} her",
|
||||
"addNewMapLabel": "Legg til nytt element",
|
||||
"backToSelect": "Velg en annen kategori",
|
||||
"confirmButton": "Legg til en {category} her.<br/><div class='alert'>Din endring er synlig for alle</div>",
|
||||
"confirmIntro": "<h3>Legg til {title} her?</h3>Punktet du oppretter her vil være <b>synlig for alle</b>. Kun legg til ting på kartet hvis de virkelig finnes. Mange programmer bruker denne dataen.",
|
||||
|
|
|
@ -91,7 +91,6 @@
|
|||
"aboutMapcomplete": "<h3>Over MapComplete</h3><p>Met MapComplete kun je OpenStreetMap verrijken met informatie over een bepaald thema. Beantwoord enkele vragen, en binnen een paar minuten is jouw bijdrage wereldwijd beschikbaar! In de meeste thema's kan je foto's toevoegen of zelfs een review achterlaten. De <b>maker van het thema</b> bepaalt de elementen, vragen en taalversies voor het thema.</p><h3>Ontdek meer</h3><p>MapComplete <b>biedt altijd de volgende stap</b> naar meer OpenStreetMap:</p><ul><li>Indien ingebed in een website linkt het iframe naar de volledige MapComplete</li><li>De volledige versie heeft uitleg over OpenStreetMap</li><li>Bekijken kan altijd, maar wijzigen vereist een OSM-account</li><li>Als je niet aangemeld bent, wordt je gevraagd dit te doen</li><li>Als je minstens één vraag hebt beantwoord, kan je ook elementen toevoegen</li><li>Heb je genoeg changesets, dan verschijnen de OSM-tags, nog later links naar de wiki</li></ul><p></p><p>Merk je <b>een bug</b> of wil je een <b>extra feature</b>? Wil je <b>helpen vertalen</b>? Bezoek dan de <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\">broncode</a> en <a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\">issue tracker</a>. </p><p></p>Wil je <b>je vorderingen</b> zien? Volg de edits <a href=\"{osmcha_link}\" target=\"_blank\">op OsmCha</a>.<p></p>",
|
||||
"add": {
|
||||
"addNew": "Voeg {category} toe",
|
||||
"addNewMapLabel": "Klik hier om een item toe te voegen",
|
||||
"backToSelect": "Selecteer een andere categorie",
|
||||
"confirmButton": "Voeg een {category} toe<br><div class=\"alert\">Je toevoeging is voor iedereen zichtbaar</div>",
|
||||
"confirmIntro": "<h3>Voeg een {title} toe?</h3>Het object dat je toevoegt, is <b>zichtbaar voor iedereen</b>. Veel applicaties gebruiken deze data, voeg dus enkel punten toe die echt bestaan.",
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
"aboutMapcomplete": "<h3>Sobre</h3><p>Use o MapComplete para adicionar informações ao OpenStreetMap <b>sobre um tema específico</b>. Responda a perguntas e em poucos minutos as suas contribuições estão disponíveis em todos os lugares. Na maioria dos temas pode adicionar imagens ou mesmo deixar uma avaliação. O <b>responsável pelo tema</b> define os elementos, as perguntas e os idiomas disponíveis nele.</p> <h3>Descubra mais</h3><p>O MapComplete <b>mostra sempre o próximo passo</b> para saber mais sobre o OpenStreetMap.</p><ul> <li>Quando incorporado num site, o iframe liga-se ao MapComplete em ecrã cheio.</li><li>A versão ecrã cheio fornece informações sobre o OpenStreetMap</li><li>A visualização funciona sem ser preciso autenticar-se, mas a edição requer uma conta no OpenStreetMap.</li> <li>Se não estiver autenticado, é solicitado a fazê-lo</li><li>Após responder a uma pergunta, pode adicionar novos elementos ao mapa</li><li>Depois de um tempo, as etiquetas reais do OpenStreetMap são mostradas, mais tarde vinculando-se à wiki</li></ul><p></p><br><p>Deparou-se com <b>um problema</b>? Quer uma <b>nova funcionalidade</b>? Quer <b>ajudar a traduzir</b>? Vá ao <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\">código-fonte</a> ou <a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\">rastreador de problemas</a>. </p> <p>Quer ver <b>o seu progresso</b>? Veja a contagem de edições em <a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a>.</p>",
|
||||
"add": {
|
||||
"addNew": "Adicionar {category} aqui",
|
||||
"addNewMapLabel": "Adicionar novo item",
|
||||
"confirmButton": "Adicione uma {category} aqui.<br><div class=\"alert\">Esta adição será visível a todos</div>",
|
||||
"confirmIntro": "<h3>Adicionar {title} aqui?</h3>O elemento que criar aqui será <b>visível a todos</b>. Por favor, só adicione coisas ao mapa se elas realmente existirem. Muitas aplicações usam estes dados.",
|
||||
"disableFilters": "Desativar todos os filtros",
|
||||
|
|
|
@ -50,7 +50,6 @@
|
|||
"aboutMapcomplete": "<h3>關於</h3><p>使用 MapComplete 你可以藉由<b>單一主題</b>新增開放街圖的圖資。回答幾個問題,然後幾分鐘之內你的貢獻立刻就傳遍全球!大部分的主題都能新增圖片甚至留下評論。<b>主題維護者</b>定議主題的元素、問題與語言。</p><h3>發現更多</h3><p>MapComplete 總是提供學習更多開放街圖<b>下一步的知識</b>。</p><ul><li>當你內嵌網站,網頁內嵌會連結到全螢幕的 MapComplete</li><li>全螢幕的版本提供關於開放街圖的資訊</li><li>不登入檢視成果,但是要編輯則需要 OSM 帳號。</li><li>如果你沒有登入,你會被要求先登入</li><li>當你回答單一問題時,你可以在地圖新增新的圖徵</li><li>過了一陣子,實際的 OSM-標籤會顯示,之後會連結到 wiki</li></ul><p></p><br><p>你有注意到<b>問題</b>嗎?你想請求<b>功能</b>嗎?想要<b>幫忙翻譯</b>嗎?來到<a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\">原始碼</a>或是<a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\">問題追蹤器。</a></p><p>想要看到<b>你的進度</b>嗎?到<a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a>追蹤編輯數。</p>",
|
||||
"add": {
|
||||
"addNew": "在這裡新增新的 {category}",
|
||||
"addNewMapLabel": "點這邊新增新項目",
|
||||
"confirmButton": "在此新增 {category}。<br><div class=\"alert\">大家都可以看到您新增的內容</div>",
|
||||
"confirmIntro": "<h3>在這裡新增 {title} ?</h3>你在這裡新增的圖徵<b>所有人都看得到</b>。請只有在確定有物件存在的情形下才新增上去,許多應用程式都使用這份資料。",
|
||||
"disableFilters": "關閉所有篩選器",
|
||||
|
|
221
package-lock.json
generated
221
package-lock.json
generated
|
@ -38,6 +38,7 @@
|
|||
"lz-string": "^1.4.4",
|
||||
"mangrove-reviews-typescript": "^1.1.0",
|
||||
"maplibre-gl": "^2.4.0",
|
||||
"node-html-parser": "^6.1.5",
|
||||
"opening_hours": "^3.6.0",
|
||||
"osm-auth": "^1.0.2",
|
||||
"osmtogeojson": "^3.0.0-beta.5",
|
||||
|
@ -4281,6 +4282,11 @@
|
|||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
|
||||
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
|
||||
},
|
||||
"node_modules/boolbase": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
|
||||
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
|
||||
},
|
||||
"node_modules/bops": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/bops/-/bops-0.0.6.tgz",
|
||||
|
@ -4871,6 +4877,70 @@
|
|||
"utrie": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/css-select": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
|
||||
"integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
|
||||
"dependencies": {
|
||||
"boolbase": "^1.0.0",
|
||||
"css-what": "^6.1.0",
|
||||
"domhandler": "^5.0.2",
|
||||
"domutils": "^3.0.1",
|
||||
"nth-check": "^2.0.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/fb55"
|
||||
}
|
||||
},
|
||||
"node_modules/css-select/node_modules/domelementtype": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
|
||||
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/fb55"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/css-select/node_modules/domhandler": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
|
||||
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
|
||||
"dependencies": {
|
||||
"domelementtype": "^2.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/domhandler?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/css-select/node_modules/domutils": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
|
||||
"integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
|
||||
"dependencies": {
|
||||
"dom-serializer": "^2.0.0",
|
||||
"domelementtype": "^2.3.0",
|
||||
"domhandler": "^5.0.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/domutils?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/css-what": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
|
||||
"integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/fb55"
|
||||
}
|
||||
},
|
||||
"node_modules/csscolorparser": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz",
|
||||
|
@ -5342,6 +5412,44 @@
|
|||
"doctest-ts-improved": "dist/main.js"
|
||||
}
|
||||
},
|
||||
"node_modules/dom-serializer": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
|
||||
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
|
||||
"dependencies": {
|
||||
"domelementtype": "^2.3.0",
|
||||
"domhandler": "^5.0.2",
|
||||
"entities": "^4.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/dom-serializer/node_modules/domelementtype": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
|
||||
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/fb55"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/dom-serializer/node_modules/domhandler": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
|
||||
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
|
||||
"dependencies": {
|
||||
"domelementtype": "^2.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/domhandler?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/dom-walk": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
|
||||
|
@ -5464,7 +5572,6 @@
|
|||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
|
||||
"integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==",
|
||||
"devOptional": true,
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
},
|
||||
|
@ -7860,6 +7967,15 @@
|
|||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/node-html-parser": {
|
||||
"version": "6.1.5",
|
||||
"resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-6.1.5.tgz",
|
||||
"integrity": "sha512-fAaM511feX++/Chnhe475a0NHD8M7AxDInsqQpz6x63GRF7xYNdS8Vo5dKsIVPgsOvG7eioRRTZQnWBrhDHBSg==",
|
||||
"dependencies": {
|
||||
"css-select": "^5.1.0",
|
||||
"he": "1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/node-releases": {
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz",
|
||||
|
@ -7874,6 +7990,17 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/nth-check": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
|
||||
"integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
|
||||
"dependencies": {
|
||||
"boolbase": "^1.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/nth-check?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/nwmatcher": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz",
|
||||
|
@ -15160,6 +15287,11 @@
|
|||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
|
||||
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
|
||||
},
|
||||
"boolbase": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
|
||||
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
|
||||
},
|
||||
"bops": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/bops/-/bops-0.0.6.tgz",
|
||||
|
@ -15591,6 +15723,48 @@
|
|||
"utrie": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"css-select": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
|
||||
"integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
|
||||
"requires": {
|
||||
"boolbase": "^1.0.0",
|
||||
"css-what": "^6.1.0",
|
||||
"domhandler": "^5.0.2",
|
||||
"domutils": "^3.0.1",
|
||||
"nth-check": "^2.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"domelementtype": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
|
||||
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="
|
||||
},
|
||||
"domhandler": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
|
||||
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
|
||||
"requires": {
|
||||
"domelementtype": "^2.3.0"
|
||||
}
|
||||
},
|
||||
"domutils": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
|
||||
"integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
|
||||
"requires": {
|
||||
"dom-serializer": "^2.0.0",
|
||||
"domelementtype": "^2.3.0",
|
||||
"domhandler": "^5.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"css-what": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
|
||||
"integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw=="
|
||||
},
|
||||
"csscolorparser": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz",
|
||||
|
@ -15938,6 +16112,31 @@
|
|||
"typescript": "^4.6.2"
|
||||
}
|
||||
},
|
||||
"dom-serializer": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
|
||||
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
|
||||
"requires": {
|
||||
"domelementtype": "^2.3.0",
|
||||
"domhandler": "^5.0.2",
|
||||
"entities": "^4.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"domelementtype": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
|
||||
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="
|
||||
},
|
||||
"domhandler": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
|
||||
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
|
||||
"requires": {
|
||||
"domelementtype": "^2.3.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"dom-walk": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
|
||||
|
@ -16050,8 +16249,7 @@
|
|||
"entities": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
|
||||
"integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==",
|
||||
"devOptional": true
|
||||
"integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA=="
|
||||
},
|
||||
"es6-object-assign": {
|
||||
"version": "1.1.0",
|
||||
|
@ -17867,6 +18065,15 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node-html-parser": {
|
||||
"version": "6.1.5",
|
||||
"resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-6.1.5.tgz",
|
||||
"integrity": "sha512-fAaM511feX++/Chnhe475a0NHD8M7AxDInsqQpz6x63GRF7xYNdS8Vo5dKsIVPgsOvG7eioRRTZQnWBrhDHBSg==",
|
||||
"requires": {
|
||||
"css-select": "^5.1.0",
|
||||
"he": "1.2.0"
|
||||
}
|
||||
},
|
||||
"node-releases": {
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz",
|
||||
|
@ -17878,6 +18085,14 @@
|
|||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
|
||||
},
|
||||
"nth-check": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
|
||||
"integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
|
||||
"requires": {
|
||||
"boolbase": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"nwmatcher": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz",
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
"lz-string": "^1.4.4",
|
||||
"mangrove-reviews-typescript": "^1.1.0",
|
||||
"maplibre-gl": "^2.4.0",
|
||||
"opening_hours": "^3.6.0",
|
||||
"opening_hours": "^3.6.0",
|
||||
"osm-auth": "^1.0.2",
|
||||
"osmtogeojson": "^3.0.0-beta.5",
|
||||
"papaparse": "^5.3.1",
|
||||
|
@ -126,6 +126,7 @@
|
|||
"dependency-cruiser": "^10.4.0",
|
||||
"fs": "0.0.1-security",
|
||||
"jsdom": "^21.1.0",
|
||||
"node-html-parser": "^6.1.5",
|
||||
"prettier": "^2.7.1",
|
||||
"prettier-plugin-svelte": "^2.9.0",
|
||||
"read-file": "^0.2.0",
|
||||
|
|
6
test.ts
6
test.ts
|
@ -2,7 +2,7 @@ import SvelteUIElement from "./UI/Base/SvelteUIElement"
|
|||
import ThemeViewGUI from "./UI/ThemeViewGUI.svelte"
|
||||
import { FixedUiElement } from "./UI/Base/FixedUiElement"
|
||||
import LayoutConfig from "./Models/ThemeConfig/LayoutConfig"
|
||||
import * as benches from "./assets/generated/themes/cyclofix.json"
|
||||
import * as theme from "./assets/generated/themes/shops.json"
|
||||
import { UIEventSource } from "./Logic/UIEventSource"
|
||||
import ThemeViewState from "./Models/ThemeViewState"
|
||||
import Combine from "./UI/Base/Combine"
|
||||
|
@ -13,13 +13,13 @@ import { Translation } from "./UI/i18n/Translation"
|
|||
|
||||
async function main() {
|
||||
new FixedUiElement("").AttachTo("extradiv")
|
||||
const layout = new LayoutConfig(<any>benches, true) // qp.data === "" ? : new AllKnownLayoutsLazy().get(qp.data)
|
||||
const layout = new LayoutConfig(<any>theme, true) // qp.data === "" ? : new AllKnownLayoutsLazy().get(qp.data)
|
||||
const main = new SvelteUIElement(ThemeViewGUI, { layout })
|
||||
main.AttachTo("maindiv")
|
||||
}
|
||||
|
||||
async function testspecial() {
|
||||
const layout = new LayoutConfig(<any>benches, true) // qp.data === "" ? : new AllKnownLayoutsLazy().get(qp.data)
|
||||
const layout = new LayoutConfig(<any>theme, true) // qp.data === "" ? : new AllKnownLayoutsLazy().get(qp.data)
|
||||
const state = new ThemeViewState(layout)
|
||||
|
||||
const all = SpecialVisualizations.specialVisualizations.map((s) =>
|
||||
|
|
Loading…
Reference in a new issue