forked from MapComplete/MapComplete
		
	Add 'export as GPX'-feature, fix #276
This commit is contained in:
		
							parent
							
								
									91fe29cfdd
								
							
						
					
					
						commit
						e8ce53d5eb
					
				
					 9 changed files with 308 additions and 79 deletions
				
			
		| 
						 | 
				
			
			@ -1,5 +1,9 @@
 | 
			
		|||
import * as turf from '@turf/turf'
 | 
			
		||||
import {BBox} from "./BBox";
 | 
			
		||||
import togpx from "togpx"
 | 
			
		||||
import Constants from "../Models/Constants";
 | 
			
		||||
import LayerConfig from "../Models/ThemeConfig/LayerConfig";
 | 
			
		||||
import {meta} from "@turf/turf";
 | 
			
		||||
 | 
			
		||||
export class GeoOperations {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -436,6 +440,31 @@ export class GeoOperations {
 | 
			
		|||
        return undefined;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static AsGpx(feature, generatedWithLayer?: LayerConfig){
 | 
			
		||||
        
 | 
			
		||||
        const metadata = {}
 | 
			
		||||
        const tags = feature.properties
 | 
			
		||||
        
 | 
			
		||||
        if(generatedWithLayer !== undefined){
 | 
			
		||||
            
 | 
			
		||||
            metadata["name"] = generatedWithLayer.title?.GetRenderValue(tags)?.Subs(tags)?.txt
 | 
			
		||||
            metadata["desc"] = "Generated with MapComplete layer "+generatedWithLayer.id
 | 
			
		||||
            if(tags._backend?.contains("openstreetmap")){
 | 
			
		||||
                metadata["copyright"]= "Data copyrighted by OpenStreetMap-contributors, freely available under ODbL. See https://www.openstreetmap.org/copyright"
 | 
			
		||||
                metadata["author"] = tags["_last_edit:contributor"]
 | 
			
		||||
                metadata["link"]= "https://www.openstreetmap.org/"+tags.id
 | 
			
		||||
                metadata["time"] = tags["_last_edit:timestamp"]
 | 
			
		||||
            }else{
 | 
			
		||||
                metadata["time"] = new Date().toISOString()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        return togpx(feature, {
 | 
			
		||||
            creator: "MapComplete "+Constants.vNumber,
 | 
			
		||||
            metadata
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -301,4 +301,16 @@ export default class LayoutConfig {
 | 
			
		|||
        return this.layers.some(l => l.isLeftRightSensitive())
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public getMatchingLayer(tags: any) : LayerConfig | undefined{
 | 
			
		||||
        if(tags === undefined){
 | 
			
		||||
            return undefined
 | 
			
		||||
        }
 | 
			
		||||
        for (const layer of this.layers) {
 | 
			
		||||
            if (layer.source.osmTags.matchesProperties(tags)) {
 | 
			
		||||
                return layer
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return undefined
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -38,10 +38,11 @@ import ChangeTagAction from "../Logic/Osm/Actions/ChangeTagAction";
 | 
			
		|||
import {And} from "../Logic/Tags/And";
 | 
			
		||||
import Toggle from "./Input/Toggle";
 | 
			
		||||
import {DefaultGuiState} from "./DefaultGuiState";
 | 
			
		||||
import {GeoOperations} from "../Logic/GeoOperations";
 | 
			
		||||
 | 
			
		||||
export interface SpecialVisualization {
 | 
			
		||||
    funcName: string,
 | 
			
		||||
    constr: ((state: State, tagSource: UIEventSource<any>, argument: string[], guistate: DefaultGuiState) => BaseUIElement),
 | 
			
		||||
    constr: ((state: State, tagSource: UIEventSource<any>, argument: string[], guistate: DefaultGuiState, ) => BaseUIElement),
 | 
			
		||||
    docs: string,
 | 
			
		||||
    example?: string,
 | 
			
		||||
    args: { name: string, defaultValue?: string, doc: string }[]
 | 
			
		||||
| 
						 | 
				
			
			@ -425,12 +426,7 @@ export default class SpecialVisualizations {
 | 
			
		|||
 | 
			
		||||
                            const title = state?.layoutToUse?.title?.txt ?? "MapComplete";
 | 
			
		||||
 | 
			
		||||
                            let matchingLayer: LayerConfig = undefined;
 | 
			
		||||
                            for (const layer of (state?.layoutToUse?.layers ?? [])) {
 | 
			
		||||
                                if (layer.source.osmTags.matchesProperties(tagSource?.data)) {
 | 
			
		||||
                                    matchingLayer = layer
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            let matchingLayer: LayerConfig = state?.layoutToUse?.getMatchingLayer(tagSource?.data);
 | 
			
		||||
                            let name = matchingLayer?.title?.GetRenderValue(tagSource.data)?.txt ?? tagSource.data?.name ?? "POI";
 | 
			
		||||
                            if (name) {
 | 
			
		||||
                                name = `${name} (${title})`
 | 
			
		||||
| 
						 | 
				
			
			@ -603,6 +599,31 @@ export default class SpecialVisualizations {
 | 
			
		|||
                        )
 | 
			
		||||
                        , undefined, state.osmConnection.isLoggedIn)
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                funcName: "export_as_gpx",
 | 
			
		||||
                docs: "Exports the selected feature as GPX-file",
 | 
			
		||||
                args: [],
 | 
			
		||||
                constr: (state, tagSource, args) => {
 | 
			
		||||
                    const t = Translations.t.general.download;
 | 
			
		||||
                    
 | 
			
		||||
                    return new SubtleButton(Svg.download_ui(), 
 | 
			
		||||
                        new Combine([t.downloadGpx.SetClass("font-bold text-lg"),
 | 
			
		||||
                            t.downloadGpxHelper.SetClass("subtle")]).SetClass("flex flex-col")
 | 
			
		||||
                    ).onClick(() => {
 | 
			
		||||
                        console.log("Exporting as GPX!")
 | 
			
		||||
                        const tags = tagSource.data
 | 
			
		||||
                        const feature = state.allElements.ContainingFeatures.get(tags.id)
 | 
			
		||||
                        const matchingLayer = state?.layoutToUse?.getMatchingLayer(tags)
 | 
			
		||||
                        const gpx = GeoOperations.AsGpx(feature, matchingLayer)
 | 
			
		||||
                        const title = matchingLayer.title?.GetRenderValue(tags)?.Subs(tags)?.txt ?? "gpx_track"
 | 
			
		||||
                        Utils.offerContentsAsDownloadableFile(gpx, title+"_mapcomplete_export.gpx", {
 | 
			
		||||
                            mimetype: "{gpx=application/gpx+xml}"
 | 
			
		||||
                        })
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    })
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,18 @@
 | 
			
		|||
    "osmTags": "user:location=yes",
 | 
			
		||||
    "maxCacheAge": 0
 | 
			
		||||
  },
 | 
			
		||||
  "title": {
 | 
			
		||||
    "render": "Your travelled path"
 | 
			
		||||
  },
 | 
			
		||||
  "tagRenderings": [
 | 
			
		||||
    {
 | 
			
		||||
      "id": "Privacy notice",
 | 
			
		||||
      "render": {
 | 
			
		||||
        "en": "This is the path you've travelled since this website is opened. Don't worry - this is only visible to you and no one else. Your location data is never sent off-device."
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "export_as_gpx"
 | 
			
		||||
  ],
 | 
			
		||||
  "name": "Your track",
 | 
			
		||||
  "mapRendering": [
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,9 @@
 | 
			
		|||
  "images": {
 | 
			
		||||
    "render": "{image_carousel()}{image_upload()}"
 | 
			
		||||
  },
 | 
			
		||||
"export_as_gpx":{
 | 
			
		||||
  "render":  "{export_as_gpx()}"
 | 
			
		||||
},
 | 
			
		||||
  "wikipedia": {
 | 
			
		||||
    "render": "{wikipedia():max-height:25rem}",
 | 
			
		||||
    "question": {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,10 +64,14 @@
 | 
			
		|||
        },
 | 
			
		||||
        "minzoom": 13,
 | 
			
		||||
        "minzoomVisible": 0,
 | 
			
		||||
        "mapRendering": [
 | 
			
		||||
          {
 | 
			
		||||
            "icon": {
 | 
			
		||||
              "render": "circle:#FE6F32;./assets/themes/natuurpunt/nature_reserve.svg"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "#": "Nature reserve overview from cache, points only, z < 13",
 | 
			
		||||
| 
						 | 
				
			
			@ -84,11 +88,15 @@
 | 
			
		|||
          "isOsmCache": "duplicate"
 | 
			
		||||
        },
 | 
			
		||||
        "minzoom": 1,
 | 
			
		||||
        "mapRendering": [
 | 
			
		||||
          {
 | 
			
		||||
            "icon": {
 | 
			
		||||
              "render": "circle:#FE6F32;./assets/themes/natuurpunt/nature_reserve.svg"
 | 
			
		||||
            },
 | 
			
		||||
            "presets": []
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "builtin": "visitor_information_centre",
 | 
			
		||||
| 
						 | 
				
			
			@ -103,10 +111,14 @@
 | 
			
		|||
          "isOsmCache": true
 | 
			
		||||
        },
 | 
			
		||||
        "minzoom": 1,
 | 
			
		||||
        "mapRendering": [
 | 
			
		||||
          {
 | 
			
		||||
            "icon": {
 | 
			
		||||
              "render": "circle:#FE6F32;./assets/themes/natuurpunt/information.svg"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "builtin": "trail",
 | 
			
		||||
| 
						 | 
				
			
			@ -122,6 +134,8 @@
 | 
			
		|||
          "isOsmCache": true
 | 
			
		||||
        },
 | 
			
		||||
        "minzoom": 10,
 | 
			
		||||
        "mapRendering": [
 | 
			
		||||
          {
 | 
			
		||||
            "icon": {
 | 
			
		||||
              "render": "circle:#FE6F32;./assets/themes/natuurpunt/trail.svg",
 | 
			
		||||
              "mappings": [
 | 
			
		||||
| 
						 | 
				
			
			@ -136,6 +150,8 @@
 | 
			
		|||
              ]
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "builtin": "toilet",
 | 
			
		||||
| 
						 | 
				
			
			@ -146,6 +162,8 @@
 | 
			
		|||
          "geoJsonZoomLevel": 12,
 | 
			
		||||
          "isOsmCache": true
 | 
			
		||||
        },
 | 
			
		||||
        "mapRendering": [
 | 
			
		||||
          {
 | 
			
		||||
            "icon": {
 | 
			
		||||
              "render": "circle:#FE6F32;./assets/themes/natuurpunt/toilets.svg",
 | 
			
		||||
              "mappings": [
 | 
			
		||||
| 
						 | 
				
			
			@ -160,6 +178,8 @@
 | 
			
		|||
              ]
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "builtin": "birdhide",
 | 
			
		||||
| 
						 | 
				
			
			@ -170,11 +190,15 @@
 | 
			
		|||
          "geoJsonZoomLevel": 12,
 | 
			
		||||
          "isOsmCache": true
 | 
			
		||||
        },
 | 
			
		||||
        "mapRendering": [
 | 
			
		||||
          {
 | 
			
		||||
            "icon": {
 | 
			
		||||
              "render": "circle:#FE6F32;./assets/themes/natuurpunt/birdhide.svg",
 | 
			
		||||
              "mappings": null
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "builtin": "picnic_table",
 | 
			
		||||
| 
						 | 
				
			
			@ -185,10 +209,14 @@
 | 
			
		|||
          "geoJsonZoomLevel": 12,
 | 
			
		||||
          "isOsmCache": true
 | 
			
		||||
        },
 | 
			
		||||
        "mapRendering": [
 | 
			
		||||
          {
 | 
			
		||||
            "icon": {
 | 
			
		||||
              "render": "circle:#FE6F32;./assets/themes/natuurpunt/picnic_table.svg"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "builtin": "drinking_water",
 | 
			
		||||
| 
						 | 
				
			
			@ -199,15 +227,21 @@
 | 
			
		|||
          "geoJsonZoomLevel": 12,
 | 
			
		||||
          "isOsmCache": true
 | 
			
		||||
        },
 | 
			
		||||
        "mapRendering": [
 | 
			
		||||
          {
 | 
			
		||||
            "icon": {
 | 
			
		||||
              "render": "circle:#FE6F32;./assets/themes/natuurpunt/drips.svg"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "builtin": "parking",
 | 
			
		||||
      "override": {
 | 
			
		||||
        "minzoom": "16",
 | 
			
		||||
        "mapRendering": [
 | 
			
		||||
          {
 | 
			
		||||
            "icon": {
 | 
			
		||||
              "render": "circle:#FE6F32;./assets/themes/natuurpunt/parking.svg",
 | 
			
		||||
              "mappings": [
 | 
			
		||||
| 
						 | 
				
			
			@ -218,11 +252,6 @@
 | 
			
		|||
              ]
 | 
			
		||||
            },
 | 
			
		||||
            "iconOverlays": [
 | 
			
		||||
          {
 | 
			
		||||
            "if": "amenity=motorcycle_parking",
 | 
			
		||||
            "then": "circle:#335D9F;./assets/themes/natuurpunt/parkingmotor.svg",
 | 
			
		||||
            "badge": true
 | 
			
		||||
          },
 | 
			
		||||
              {
 | 
			
		||||
                "if": "capacity:disabled=yes",
 | 
			
		||||
                "then": "circle:#335D9F;./assets/themes/natuurpunt/parkingwheels.svg",
 | 
			
		||||
| 
						 | 
				
			
			@ -230,6 +259,8 @@
 | 
			
		|||
              }
 | 
			
		||||
            ]
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "builtin": "information_board",
 | 
			
		||||
| 
						 | 
				
			
			@ -240,10 +271,14 @@
 | 
			
		|||
          "geoJsonZoomLevel": 12,
 | 
			
		||||
          "isOsmCache": true
 | 
			
		||||
        },
 | 
			
		||||
        "mapRendering": [
 | 
			
		||||
          {
 | 
			
		||||
            "icon": {
 | 
			
		||||
              "render": "circle:#FE6F32;./assets/themes/natuurpunt/information_board.svg"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "builtin": "bench",
 | 
			
		||||
| 
						 | 
				
			
			@ -254,10 +289,14 @@
 | 
			
		|||
          "geoJsonZoomLevel": 12,
 | 
			
		||||
          "isOsmCache": true
 | 
			
		||||
        },
 | 
			
		||||
        "mapRendering": [
 | 
			
		||||
          {
 | 
			
		||||
            "icon": {
 | 
			
		||||
              "render": "circle:#FE6F32;./assets/themes/natuurpunt/bench.svg"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "builtin": "watermill",
 | 
			
		||||
| 
						 | 
				
			
			@ -268,10 +307,14 @@
 | 
			
		|||
          "geoJsonZoomLevel": 12,
 | 
			
		||||
          "isOsmCache": true
 | 
			
		||||
        },
 | 
			
		||||
        "mapRendering": [
 | 
			
		||||
          {
 | 
			
		||||
            "icon": {
 | 
			
		||||
              "render": "circle:#FE6F32;./assets/themes/natuurpunt/watermill.svg"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "enableIframePopout": false
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -190,6 +190,8 @@
 | 
			
		|||
      "downloadAsPdf": "Download a PDF of the current map",
 | 
			
		||||
      "downloadAsPdfHelper": "Ideal to print the current map",
 | 
			
		||||
      "downloadGeojson": "Download visible data as GeoJSON",
 | 
			
		||||
      "downloadGpx":"Download as GPX-file",
 | 
			
		||||
      "downloadGpxHelper":"A GPX-file can be used with most navigation devices and applications",
 | 
			
		||||
      "exporting": "Exporting…",
 | 
			
		||||
      "downloadGeoJsonHelper": "Compatible with QGIS, ArcGIS, ESRI, …",
 | 
			
		||||
      "downloadCSV": "Download visible data as CSV",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										106
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										106
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							| 
						 | 
				
			
			@ -46,6 +46,7 @@
 | 
			
		|||
        "parcel": "^1.2.4",
 | 
			
		||||
        "prompt-sync": "^4.2.0",
 | 
			
		||||
        "tailwindcss": "^2.2.15",
 | 
			
		||||
        "togpx": "^0.5.4",
 | 
			
		||||
        "tslint": "^6.1.3",
 | 
			
		||||
        "wikibase-sdk": "^7.14.0",
 | 
			
		||||
        "wikidata-sdk": "^7.14.0"
 | 
			
		||||
| 
						 | 
				
			
			@ -3756,6 +3757,23 @@
 | 
			
		|||
      "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
 | 
			
		||||
      "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/bops": {
 | 
			
		||||
      "version": "0.0.6",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/bops/-/bops-0.0.6.tgz",
 | 
			
		||||
      "integrity": "sha1-CC0dVfoB5g29wuvC26N/ZZVUzzo=",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "base64-js": "0.0.2",
 | 
			
		||||
        "to-utf8": "0.0.1"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/bops/node_modules/base64-js": {
 | 
			
		||||
      "version": "0.0.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.2.tgz",
 | 
			
		||||
      "integrity": "sha1-Ak8Pcq+iW3X5wO5zzU9V7Bvtl4Q=",
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">= 0.4"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/brace-expansion": {
 | 
			
		||||
      "version": "1.1.11",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -8619,6 +8637,14 @@
 | 
			
		|||
        "safe-buffer": "^5.0.1"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/jxon": {
 | 
			
		||||
      "version": "2.0.0-beta.5",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/jxon/-/jxon-2.0.0-beta.5.tgz",
 | 
			
		||||
      "integrity": "sha1-O2qUEE+YAe5oL9BWZF/1Rz2bND4=",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "xmldom": "^0.1.21"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/kind-of": {
 | 
			
		||||
      "version": "6.0.3",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -15930,6 +15956,36 @@
 | 
			
		|||
        "node": ">=8.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/to-utf8": {
 | 
			
		||||
      "version": "0.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/to-utf8/-/to-utf8-0.0.1.tgz",
 | 
			
		||||
      "integrity": "sha1-0Xrqcv8vujm55DYBvns/9y4ImFI="
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/togpx": {
 | 
			
		||||
      "version": "0.5.4",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/togpx/-/togpx-0.5.4.tgz",
 | 
			
		||||
      "integrity": "sha1-sz27BUHfBL1rpPULhtqVNCS7d3M=",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "concat-stream": "~1.0.1",
 | 
			
		||||
        "jxon": "~2.0.0-beta.5",
 | 
			
		||||
        "optimist": "~0.3.5",
 | 
			
		||||
        "xmldom": "~0.1.17"
 | 
			
		||||
      },
 | 
			
		||||
      "bin": {
 | 
			
		||||
        "togpx": "togpx"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/togpx/node_modules/concat-stream": {
 | 
			
		||||
      "version": "1.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.0.1.tgz",
 | 
			
		||||
      "integrity": "sha1-AYsYvBx9BzotyCqkhEI0GixN158=",
 | 
			
		||||
      "engines": [
 | 
			
		||||
        "node >= 0.8.0"
 | 
			
		||||
      ],
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "bops": "0.0.6"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/toidentifier": {
 | 
			
		||||
      "version": "1.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -21029,6 +21085,22 @@
 | 
			
		|||
      "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
 | 
			
		||||
      "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
 | 
			
		||||
    },
 | 
			
		||||
    "bops": {
 | 
			
		||||
      "version": "0.0.6",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/bops/-/bops-0.0.6.tgz",
 | 
			
		||||
      "integrity": "sha1-CC0dVfoB5g29wuvC26N/ZZVUzzo=",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "base64-js": "0.0.2",
 | 
			
		||||
        "to-utf8": "0.0.1"
 | 
			
		||||
      },
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "base64-js": {
 | 
			
		||||
          "version": "0.0.2",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.2.tgz",
 | 
			
		||||
          "integrity": "sha1-Ak8Pcq+iW3X5wO5zzU9V7Bvtl4Q="
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "brace-expansion": {
 | 
			
		||||
      "version": "1.1.11",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -24823,6 +24895,14 @@
 | 
			
		|||
        "safe-buffer": "^5.0.1"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "jxon": {
 | 
			
		||||
      "version": "2.0.0-beta.5",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/jxon/-/jxon-2.0.0-beta.5.tgz",
 | 
			
		||||
      "integrity": "sha1-O2qUEE+YAe5oL9BWZF/1Rz2bND4=",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "xmldom": "^0.1.21"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "kind-of": {
 | 
			
		||||
      "version": "6.0.3",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
 | 
			
		||||
| 
						 | 
				
			
			@ -30870,6 +30950,32 @@
 | 
			
		|||
        "is-number": "^7.0.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "to-utf8": {
 | 
			
		||||
      "version": "0.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/to-utf8/-/to-utf8-0.0.1.tgz",
 | 
			
		||||
      "integrity": "sha1-0Xrqcv8vujm55DYBvns/9y4ImFI="
 | 
			
		||||
    },
 | 
			
		||||
    "togpx": {
 | 
			
		||||
      "version": "0.5.4",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/togpx/-/togpx-0.5.4.tgz",
 | 
			
		||||
      "integrity": "sha1-sz27BUHfBL1rpPULhtqVNCS7d3M=",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "concat-stream": "~1.0.1",
 | 
			
		||||
        "jxon": "~2.0.0-beta.5",
 | 
			
		||||
        "optimist": "~0.3.5",
 | 
			
		||||
        "xmldom": "~0.1.17"
 | 
			
		||||
      },
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "concat-stream": {
 | 
			
		||||
          "version": "1.0.1",
 | 
			
		||||
          "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.0.1.tgz",
 | 
			
		||||
          "integrity": "sha1-AYsYvBx9BzotyCqkhEI0GixN158=",
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "bops": "0.0.6"
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "toidentifier": {
 | 
			
		||||
      "version": "1.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -94,6 +94,7 @@
 | 
			
		|||
    "parcel": "^1.2.4",
 | 
			
		||||
    "prompt-sync": "^4.2.0",
 | 
			
		||||
    "tailwindcss": "^2.2.15",
 | 
			
		||||
    "togpx": "^0.5.4",
 | 
			
		||||
    "tslint": "^6.1.3",
 | 
			
		||||
    "wikibase-sdk": "^7.14.0",
 | 
			
		||||
    "wikidata-sdk": "^7.14.0"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue