lint fixes

This commit is contained in:
vcoppe committed 2026-10-28 22:40:48 +01:00
1 parent f5a2db0565
commit 6956c19410
45 files changed
+243 -244

No files matched your search

+4 -4
View File
@@ -1,7 +1,7 @@
@import 'tailwindcss';
@import 'tw-animate-css';
@import "shadcn-svelte/tailwind.css";
@import "@fontsource-variable/inter";
@import 'shadcn-svelte/tailwind.css';
@import '@fontsource-variable/inter';
@custom-variant dark (&:is(.dark *));
@@ -158,7 +158,7 @@
body {
@apply bg-background text-foreground;
}
html {
@apply font-sans;
html {
@apply font-sans;
}
}
@@ -26,7 +26,7 @@
<Tooltip.Root>
<Tooltip.Trigger>
{#snippet child({ props })}
<Button {...props} {variant} class="bg-inherit {className}" {onclick}>
<Button {...props} {variant} {disabled} class="bg-inherit {className}" {onclick}>
{@render children()}
</Button>
{/snippet}
+3 -3
View File
@@ -39,7 +39,7 @@ export function getPreviousGuide(currentGuide: string): string | undefined {
return `${previousGuide}/${guides[previousGuide][guides[previousGuide].length - 1]}`;
}
} else {
if (guides.hasOwnProperty(subguides[0])) {
if (Object.hasOwn(guides, subguides[0])) {
const subguideIndex = guides[subguides[0]].indexOf(subguides[1]);
if (subguideIndex > 0) {
return `${subguides[0]}/${guides[subguides[0]][subguideIndex - 1]}`;
@@ -56,7 +56,7 @@ export function getNextGuide(currentGuide: string): string | undefined {
const subguides = currentGuide.split('/');
if (subguides.length === 1) {
if (guides.hasOwnProperty(currentGuide)) {
if (Object.hasOwn(guides, currentGuide)) {
if (guides[currentGuide].length === 0) {
const keys = Object.keys(guides);
const index = keys.indexOf(currentGuide);
@@ -68,7 +68,7 @@ export function getNextGuide(currentGuide: string): string | undefined {
return undefined;
}
} else {
if (guides.hasOwnProperty(subguides[0])) {
if (Object.hasOwn(guides, subguides[0])) {
const subguideIndex = guides[subguides[0]].indexOf(subguides[1]);
if (subguideIndex < guides[subguides[0]].length - 1) {
return `${subguides[0]}/${guides[subguides[0]][subguideIndex + 1]}`;
@@ -148,7 +148,7 @@ export class ElevationProfile {
}
initialize() {
let options: ChartOptions<'line'> = {
const options: ChartOptions<'line'> = {
animation: false,
parsing: false,
maintainAspectRatio: false,
@@ -199,7 +199,7 @@ export class ElevationProfile {
return '';
},
label: (context: TooltipItem<'line'>) => {
let point = context.raw as ElevationProfilePoint;
const point = context.raw as ElevationProfilePoint;
if (context.datasetIndex === 0) {
this._hoveredPoint.set(
this._dragging
@@ -223,16 +223,18 @@ export class ElevationProfile {
}
},
afterBody: (contexts: TooltipItem<'line'>[]) => {
let context = contexts.filter((context) => context.datasetIndex === 0);
const context = contexts.filter(
(context) => context.datasetIndex === 0
);
if (context.length === 0) return;
let point = context[0].raw as ElevationProfilePoint;
const point = context[0].raw as ElevationProfilePoint;
// the rest of the data is there once it is read (see `hover`)
const hovered = this._hovered;
const details =
hovered?.index === point.index ? hovered.point : undefined;
const elevationFill = get(this._elevationFill);
let labels = [
const labels = [
` ${i18n._('quantities.distance')}: ${getDistanceWithUnits(point.x, false)}`,
];
@@ -250,10 +252,10 @@ export class ElevationProfile {
}
labels.push(` ${i18n._('quantities.slope')}: ${slope}`);
}
let surface = details.surface ?? 'unknown';
let highway = details.highway ?? 'unknown';
let sacScale = details.sacScale;
let mtbScale = details.mtbScale;
const surface = details.surface ?? 'unknown';
const highway = details.highway ?? 'unknown';
const sacScale = details.sacScale;
const mtbScale = details.mtbScale;
if (elevationFill === 'surface') {
labels.push(
@@ -305,7 +307,7 @@ export class ElevationProfile {
enabled: true,
},
mode: 'x',
onZoomStart: ({ chart, event }: { chart: Chart; event: any }) => {
onZoomStart: ({ event }: { event: any }) => {
if (!this._chart) {
return false;
}
@@ -335,7 +337,7 @@ export class ElevationProfile {
},
};
let datasets: string[] = ['speed', 'hr', 'cad', 'atemp', 'power'];
const datasets: string[] = ['speed', 'hr', 'cad', 'atemp', 'power'];
datasets.forEach((id) => {
options.scales![`y${id}`] = {
type: 'linear',
@@ -580,11 +582,11 @@ export class ElevationProfile {
}
const additionalDatasets = get(this._additionalDatasets);
let includeSpeed = additionalDatasets.includes('speed');
let includeHeartRate = additionalDatasets.includes('hr');
let includeCadence = additionalDatasets.includes('cad');
let includeTemperature = additionalDatasets.includes('atemp');
let includePower = additionalDatasets.includes('power');
const includeSpeed = additionalDatasets.includes('speed');
const includeHeartRate = additionalDatasets.includes('hr');
const includeCadence = additionalDatasets.includes('cad');
const includeTemperature = additionalDatasets.includes('atemp');
const includePower = additionalDatasets.includes('power');
if (this._chart.data.datasets.length == 6) {
this._chart.data.datasets[1].hidden = !includeSpeed;
this._chart.data.datasets[2].hidden = !includeHeartRate;
@@ -639,21 +641,21 @@ export class ElevationProfile {
const slicedStatistics = get(this._slicedStatistics);
if (slicedStatistics) {
let startIndex = slicedStatistics.start;
let endIndex = slicedStatistics.end;
const startIndex = slicedStatistics.start;
const endIndex = slicedStatistics.end;
// Draw selection rectangle
let selectionContext = this._overlay.getContext('2d');
const selectionContext = this._overlay.getContext('2d');
if (selectionContext) {
selectionContext.fillStyle = mode.current === 'dark' ? 'white' : 'black';
selectionContext.globalAlpha = mode.current === 'dark' ? 0.2 : 0.1;
selectionContext.clearRect(0, 0, this._overlay.width, this._overlay.height);
const statistics = get(this._statistics);
let startPixel = this._chart.scales.x.getPixelForValue(
const startPixel = this._chart.scales.x.getPixelForValue(
getConvertedDistance(statistics.totalDistance[startIndex] ?? 0)
);
let endPixel = this._chart.scales.x.getPixelForValue(
const endPixel = this._chart.scales.x.getPixelForValue(
getConvertedDistance(statistics.totalDistance[endIndex] ?? 0)
);
@@ -665,7 +667,7 @@ export class ElevationProfile {
);
}
} else if (this._overlay) {
let selectionContext = this._overlay.getContext('2d');
const selectionContext = this._overlay.getContext('2d');
if (selectionContext) {
selectionContext.clearRect(0, 0, this._overlay.width, this._overlay.height);
}
@@ -109,7 +109,7 @@ export function getURLForGoogleDriveFile(fileId: string): string {
}
export function convertOldEmbeddingOptions(options: URLSearchParams): any {
let newOptions: any = {
const newOptions: any = {
key: PUBLIC_MAPTILER_KEY,
files: [],
ids: [],
@@ -128,7 +128,7 @@ export function convertOldEmbeddingOptions(options: URLSearchParams): any {
}
}
if (options.has('source')) {
let basemap = options.get('source')!;
const basemap = options.get('source')!;
if (basemap === 'satellite') {
newOptions.basemap = 'libertySatellite';
} else if (basemap === 'otm') {
@@ -132,7 +132,6 @@
<div class="flex flex-col h-full">
<div class="px-2 py-1 text-sm font-semibold shrink-0">{i18n._('menu.explorer')}</div>
<ScrollArea class="grow min-h-0">
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
<div
bind:this={container}
data-explorer
@@ -121,7 +121,6 @@
let isCut = $derived($clipboard?.cut === true && isInClipboard($clipboard, node));
</script>
<!-- svelte-ignore a11y_click_events_have_key_events -->
<!-- svelte-ignore a11y_no_static_element_interactions -->
<ContextMenu.Root
onOpenChange={(open) => {
@@ -241,9 +241,9 @@ export class SortableFileList {
return;
}
const selection_ = get(engine.selection);
for (let id of changed) {
let element = this._elements[id];
let node = this.childNode(id);
for (const id of changed) {
const element = this._elements[id];
const node = this.childNode(id);
if (element && node) {
if (isSelected(selection_, node)) {
Sortable.utils.select(element);
@@ -344,7 +344,7 @@ export class SortableFileList {
const files = get(engine.files);
this._container.childNodes.forEach((element) => {
if (element instanceof HTMLElement) {
let attr = element.getAttribute('data-id');
const attr = element.getAttribute('data-id');
if (attr) {
if (this._sortableLevel === 'file' && !files.has(attr)) {
this.forget(element);
@@ -392,12 +392,12 @@ export class SortableFileList {
}
getChangedIds() {
let changed: string[] = [];
const changed: string[] = [];
const selection_ = get(engine.selection);
Object.entries(this._elements).forEach(([id, element]) => {
const node = this.childNode(id);
let inSelection = node !== undefined && isSelected(selection_, node);
let isSelectedInList = element.classList.contains('sortable-selected');
const inSelection = node !== undefined && isSelected(selection_, node);
const isSelectedInList = element.classList.contains('sortable-selected');
if (inSelection !== isSelectedInList) {
changed.push(id);
}
@@ -77,9 +77,11 @@
</div>
<ScrollArea class="flex flex-col max-h-[30dvh]">
{#if waypoint.item.desc}
<!-- eslint-disable-next-line svelte/no-at-html-tags -- sanitized -->
<span class="whitespace-pre-wrap">{@html sanitize(waypoint.item.desc)}</span>
{/if}
{#if waypoint.item.cmt && waypoint.item.cmt !== waypoint.item.desc}
<!-- eslint-disable-next-line svelte/no-at-html-tags -- sanitized -->
<span class="whitespace-pre-wrap">{@html sanitize(waypoint.item.cmt)}</span>
{/if}
</ScrollArea>
@@ -35,7 +35,8 @@ export class DistanceMarkers {
try {
if (get(distanceMarkers) && !get(allHidden)) {
let distanceSource: GeoJSONSource | undefined = map_.getSource('distance-markers');
const distanceSource: GeoJSONSource | undefined =
map_.getSource('distance-markers');
if (distanceSource) {
distanceSource.setData(this.getDistanceMarkersGeoJSON());
} else {
@@ -90,7 +91,7 @@ export class DistanceMarkers {
map_.removeLayer('distance-markers');
}
}
} catch (e) {
} catch {
// No reliable way to check if the map is ready to add sources and layers
return;
}
@@ -104,12 +105,12 @@ export class DistanceMarkers {
// the distance from the start of the selection, and the position, of each trackpoint
const { length, totalDistance, lng, lat } = get(engine.statistics);
let features: GeoJSON.Feature[] = [];
const features: GeoJSON.Feature[] = [];
let currentTargetDistance = 1;
for (let i = 0; i < length; i++) {
if (totalDistance[i] >= getConvertedDistanceToKilometers(currentTargetDistance)) {
let distance = currentTargetDistance.toFixed(0);
let level = levels.find((level) => currentTargetDistance % level === 0) || 1;
const distance = currentTargetDistance.toFixed(0);
const level = levels.find((level) => currentTargetDistance % level === 0) || 1;
features.push({
type: 'Feature',
geometry: {
@@ -23,7 +23,7 @@ import { mapCursor, MapCursorState } from '$lib/state/map-cursor';
import { ANCHOR_LAYER_KEY } from '$lib/components/map/style';
export function getSvgForSymbol(symbol?: string | undefined, layerColor?: string | undefined) {
let symbolSvg = symbol ? symbols[symbol]?.iconSvg : undefined;
const symbolSvg = symbol ? symbols[symbol]?.iconSvg : undefined;
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
${
layerColor
@@ -63,7 +63,7 @@ export class GPXLayer {
currentWaypointData: GeoJSON.FeatureCollection | null = null;
draggedWaypointIndex: number | null = null;
draggingStartingPosition: Point = new Point(0, 0);
unsubscribe: Function[] = [];
unsubscribe: (() => void)[] = [];
updateBinded: () => void = this.update.bind(this);
layerOnMouseEnterBinded: (e: any) => void = this.layerOnMouseEnter.bind(this);
@@ -101,7 +101,7 @@ export class GPXLayer {
this.unsubscribe.push(
engine.selection.subscribe(($selection) => {
this.selectionState = $selection;
let newSelected = hasSelectionWithin($selection, this.fileNode());
const newSelected = hasSelectionWithin($selection, this.fileNode());
if (this.selected || newSelected) {
this.selected = newSelected;
this.update();
@@ -146,7 +146,7 @@ export class GPXLayer {
this.loadIcons();
try {
let source = _map.getSource(this.fileId) as GeoJSONSource | undefined;
const source = _map.getSource(this.fileId) as GeoJSONSource | undefined;
if (source) {
source.setData(this.getGeoJSON());
} else {
@@ -234,7 +234,7 @@ export class GPXLayer {
}
}
let waypointSource = _map.getSource(this.fileId + '-waypoints') as
const waypointSource = _map.getSource(this.fileId + '-waypoints') as
| GeoJSONSource
| undefined;
this.currentWaypointData = this.getWaypointsGeoJSON();
@@ -301,7 +301,7 @@ export class GPXLayer {
['in', ['get', 'waypointIndex'], ['literal', visibleWaypoints]],
{ validate: false }
);
} catch (e) {
} catch {
// No reliable way to check if the map is ready to add sources and layers
return;
}
@@ -584,7 +584,7 @@ export class GPXLayer {
this.currentWaypointData!.features[this.draggedWaypointIndex].geometry as GeoJSON.Point
).coordinates = [e.lngLat.lng, e.lngLat.lat];
let waypointSource = get(map)?.getSource(this.fileId + '-waypoints') as
const waypointSource = get(map)?.getSource(this.fileId + '-waypoints') as
| GeoJSONSource
| undefined;
if (waypointSource) {
@@ -698,7 +698,7 @@ export class GPXLayer {
return;
}
let symbols = new Set<string | undefined>();
const symbols = new Set<string | undefined>();
get(this.file).waypoints.features.forEach((feature) => {
symbols.add(getSymbolKey(feature.properties.sym));
});
@@ -100,7 +100,7 @@ export class StartEndMarkers {
});
}
let source = map_.getSource('start-end-markers') as GeoJSONSource | undefined;
const source = map_.getSource('start-end-markers') as GeoJSONSource | undefined;
if (source) {
source.setData(data);
} else {
@@ -136,7 +136,7 @@
function getLayerId() {
for (let id = 0; ; id++) {
if (!$customLayers.hasOwnProperty(`custom-${id}`)) {
if (!Object.hasOwn($customLayers, `custom-${id}`)) {
return `custom-${id}`;
}
}
@@ -145,7 +145,7 @@
function addLayer(layerId: string) {
if (layerType === 'basemap') {
selectedBasemapTree.update(($tree) => {
if (!$tree.basemaps.hasOwnProperty('custom')) {
if (!Object.hasOwn($tree.basemaps, 'custom')) {
$tree.basemaps['custom'] = {};
}
$tree.basemaps['custom'][layerId] = true;
@@ -161,7 +161,7 @@
}
} else {
selectedOverlayTree.update(($tree) => {
if (!$tree.overlays.hasOwnProperty('custom')) {
if (!Object.hasOwn($tree.overlays, 'custom')) {
$tree.overlays['custom'] = {};
}
$tree.overlays['custom'][layerId] = true;
@@ -169,7 +169,7 @@
});
currentOverlays.update(($overlays) => {
if (!$overlays.overlays.hasOwnProperty('custom')) {
if (!Object.hasOwn($overlays.overlays, 'custom')) {
$overlays.overlays['custom'] = {};
}
$overlays.overlays['custom'][layerId] = true;
@@ -183,7 +183,7 @@
}
function tryDeleteLayer(node: any, id: string): any {
if (node.hasOwnProperty(id)) {
if (Object.hasOwn(node, id)) {
delete node[id];
}
return node;
@@ -365,7 +365,7 @@
<Label for="name">{i18n._('menu.metadata.name')}</Label>
<Input bind:value={name} id="name" class="h-8" />
<Label for="url">{i18n._('layers.custom_layers.urls')}</Label>
{#each tileUrls as url, i}
{#each tileUrls as _, i}
<div class="flex flex-row gap-2">
<Input
bind:value={tileUrls[i]}
@@ -45,7 +45,7 @@
function setOpacityFromSelection() {
if (selectedOverlay) {
if ($opacities.hasOwnProperty(selectedOverlay)) {
if (Object.hasOwn($opacities, selectedOverlay)) {
overlayOpacity = $opacities[selectedOverlay];
} else {
overlayOpacity = 1;
@@ -169,7 +169,7 @@
{#if isSelected($selectedOverlayTree, selectedOverlay)}
{#if $isLayerFromExtension(selectedOverlay)}
{$getLayerName(selectedOverlay)}
{:else if $customLayers.hasOwnProperty(selectedOverlay)}
{:else if Object.hasOwn($customLayers, selectedOverlay)}
{$customLayers[selectedOverlay].name}
{:else}
{i18n._(`layers.label.${selectedOverlay}`)}
@@ -218,7 +218,7 @@
if ($map.getLayer(selectedOverlay)) {
$map.removeLayer(selectedOverlay);
}
} catch (e) {
} catch {
// No reliable way to check if the map is ready to remove sources and layers
}
}
@@ -31,7 +31,7 @@
$effect.pre(() => {
if (checked !== undefined) {
Object.keys(node).forEach((id) => {
if (!checked.hasOwnProperty(id)) {
if (!Object.hasOwn(checked, id)) {
if (typeof node[id] == 'boolean') {
checked[id] = false;
} else {
@@ -72,7 +72,7 @@
/>
{/if}
<Label for="{name}-{id}" class="flex flex-row items-center gap-1">
{#if $customLayers.hasOwnProperty(id)}
{#if Object.hasOwn($customLayers, id)}
{$customLayers[id].name}
{:else if $isLayerFromExtension(id)}
{$getLayerName(id)}
@@ -1,7 +1,7 @@
import { settings } from '$lib/state/settings';
import { derived, get, writable, type Writable } from 'svelte/store';
import { isSelected, remove, removeAll } from './utils';
import { overlays, overlayTree } from '$lib/data/layers';
import { overlays, overlayTree, type LayerTreeType } from '$lib/data/layers';
import { browser } from '$app/environment';
import { map } from '$lib/components/map/map';
@@ -19,7 +19,7 @@ export class ExtensionAPI {
private _overlays: Writable<Map<string, CustomOverlay>> = writable(new Map());
init() {
if (browser && !window.hasOwnProperty('gpxstudio')) {
if (browser && !Object.hasOwn(window, 'gpxstudio')) {
Object.defineProperty(window, 'gpxstudio', {
value: this,
});
@@ -84,14 +84,14 @@ export class ExtensionAPI {
],
};
if (!overlayTree.overlays.hasOwnProperty(overlay.extensionName)) {
if (!Object.hasOwn(overlayTree.overlays as LayerTreeType, overlay.extensionName)) {
overlayTree.overlays[overlay.extensionName] = {};
}
overlayTree.overlays[overlay.extensionName][overlay.id] = true;
selectedOverlayTree.update((selected) => {
if (!selected.overlays.hasOwnProperty(overlay.extensionName)) {
if (!Object.hasOwn(selected.overlays, overlay.extensionName)) {
selected.overlays[overlay.extensionName] = {};
}
selected.overlays[overlay.extensionName][overlay.id] = true;
@@ -104,13 +104,13 @@ export class ExtensionAPI {
show = true;
try {
get(map)?.removeLayer(overlay.id);
} catch (e) {
} catch {
// No reliable way to check if the map is ready to remove sources and layers
}
}
currentOverlays.update((current) => {
if (!current.overlays.hasOwnProperty(overlay.extensionName)) {
if (!Object.hasOwn(current.overlays, overlay.extensionName)) {
current.overlays[overlay.extensionName] = {};
}
current.overlays[overlay.extensionName][overlay.id] = show;
@@ -155,13 +155,13 @@ export class ExtensionAPI {
updateOverlaysOrder(ids: string[]) {
ids = ids.map((id) => this.getOverlayId(id));
selectedOverlayTree.update((selected) => {
let isSelected: Record<string, boolean> = {};
const isSelected: Record<string, boolean> = {};
ids.forEach((id) => {
const overlay = get(this._overlays).get(id);
if (
overlay &&
selected.overlays.hasOwnProperty(overlay.extensionName) &&
selected.overlays[overlay.extensionName].hasOwnProperty(id)
Object.hasOwn(selected.overlays, overlay.extensionName) &&
Object.hasOwn(selected.overlays[overlay.extensionName] as LayerTreeType, id)
) {
isSelected[id] = selected.overlays[overlay.extensionName][id];
delete selected.overlays[overlay.extensionName][id];
@@ -86,7 +86,7 @@ export class OverpassLayer {
};
try {
let source = this.map.getSource('overpass') as GeoJSONSource | undefined;
const source = this.map.getSource('overpass') as GeoJSONSource | undefined;
if (source) {
source.setData(d);
} else {
@@ -115,7 +115,7 @@ export class OverpassLayer {
this.layerEventManager.on('mouseenter', 'overpass', this.onHoverBinded);
this.layerEventManager.on('click', 'overpass', this.onHoverBinded);
}
} catch (e) {
} catch {
// No reliable way to check if the map is ready to add sources and layers
}
}
@@ -135,7 +135,7 @@ export class OverpassLayer {
if (this.map.getSource('overpass')) {
this.map.removeSource('overpass');
}
} catch (e) {
} catch {
// No reliable way to check if the map is ready to remove sources and layers
}
}
@@ -151,12 +151,12 @@ export class OverpassLayer {
}
query(bbox: [number, number, number, number]) {
let queries = getCurrentQueries();
const queries = getCurrentQueries();
if (queries.length === 0) {
return;
}
let tileLimits = mercator.xyz(bbox, this.queryZoom);
const tileLimits = mercator.xyz(bbox, this.queryZoom);
for (let x = tileLimits.minX; x <= tileLimits.maxX; x++) {
for (let y = tileLimits.minY; y <= tileLimits.maxY; y++) {
@@ -189,8 +189,8 @@ export class OverpassLayer {
}
this.data.update((updatedData) => {
for (let element of data.elements) {
for (let query of queries) {
for (const element of data.elements) {
for (const query of queries) {
if (belongsToQuery(element, query)) {
updatedData.features.push({
type: 'Feature',
@@ -224,7 +224,7 @@ export class OverpassLayer {
}
loadIcons() {
let currentQueries = getCurrentQueries();
const currentQueries = getCurrentQueries();
currentQueries.forEach((query) => {
loadSVGIcon(
this.map,
@@ -257,7 +257,7 @@ function getQuery(query: string) {
}
function getQueryItem(tags: Record<string, string | string[]>) {
let arrayEntry = Object.entries(tags).find((entry): entry is [string, string[]] =>
const arrayEntry = Object.entries(tags).find((entry): entry is [string, string[]] =>
Array.isArray(entry[1])
);
if (arrayEntry !== undefined) {
@@ -291,12 +291,12 @@ function belongsToQueryItem(element: any, tags: Record<string, string | string[]
}
function getCurrentQueries() {
let currentQueries = get(currentOverpassQueries);
const currentQueries = get(currentOverpassQueries);
if (currentQueries === undefined) {
return [];
}
return Object.entries(getLayers(currentQueries))
.filter(([_, selected]) => selected)
.map(([query, _]) => query);
.filter(([, selected]) => selected)
.map(([query]) => query);
}
@@ -235,7 +235,7 @@ export class MapLayerEventManager {
private _filterLayersIntersectingBounds(layerIds: string[], bounds: LngLatBounds): string[] {
const files = get(engine.files);
let result = layerIds.filter((layerId) => {
const result = layerIds.filter((layerId) => {
if (!this._map.getLayer(layerId)) return false;
const fileId = layerId.replace('-waypoints', '');
if (fileId === layerId) {
+3 -3
View File
@@ -13,7 +13,7 @@ import { MapLayerEventManager } from '$lib/components/map/map-layer-event-manage
const { treeFileView, elevationProfile, bottomPanelSize, rightPanelSize, distanceUnits } = settings;
let fitBoundsOptions: maplibregl.MapOptions['fitBoundsOptions'] = {
const fitBoundsOptions: maplibregl.MapOptions['fitBoundsOptions'] = {
maxZoom: 15,
linear: true,
easing: () => 1,
@@ -75,7 +75,7 @@ export class MapLibreGLMap {
})
);
if (geocoder) {
let geocoder = new MaplibreGeocoder(
const geocoder = new MaplibreGeocoder(
{
forwardGeocode: async (config) => {
const results: MaplibreGeocoderFeatureResults = {
@@ -96,7 +96,7 @@ export class MapLibreGLMap {
place_name: result.display_name,
};
});
} catch (e) {}
} catch {}
return results;
},
},
@@ -89,7 +89,7 @@ export class MapillaryLayer {
this.viewer.on('position', async () => {
if (this.active) {
popupOpen.value = true;
let latLng = await this.viewer.getPosition();
const latLng = await this.viewer.getPosition();
this.marker.setLngLat(latLng).addTo(this.map);
if (!this.map.getBounds()?.contains(latLng)) {
this.map.panTo(latLng);
+9 -9
View File
@@ -87,7 +87,7 @@ export class StyleManager {
updateBasemap() {
const map_ = get(this._map);
if (!map_) return;
let basemap = get(currentBasemap);
const basemap = get(currentBasemap);
this.buildStyle(basemap).then((style) => {
if (get(currentBasemap) === basemap) map_.setStyle(style);
});
@@ -148,18 +148,18 @@ export class StyleManager {
const overlayOpacities = get(opacities);
try {
const layers = getLayers(get(currentOverlays) ?? {});
for (let overlay in layers) {
for (const overlay in layers) {
if (!layers[overlay]) {
if (this._pastOverlays.has(overlay)) {
const overlayInfo = custom[overlay]?.value ?? overlays[overlay];
try {
const overlayStyle = await this.get(overlayInfo);
for (let layer of overlayStyle.layers ?? []) {
for (const layer of overlayStyle.layers ?? []) {
if (map_.getLayer(layer.id)) {
map_.removeLayer(layer.id);
}
}
} catch (e) {
} catch {
// Should not happen
}
this._pastOverlays.delete(overlay);
@@ -170,13 +170,13 @@ export class StyleManager {
const overlayStyle = await this.get(overlayInfo);
const opacity = overlayOpacities[overlay];
for (let sourceId in overlayStyle.sources) {
for (const sourceId in overlayStyle.sources) {
if (!map_.getSource(sourceId)) {
map_.addSource(sourceId, overlayStyle.sources[sourceId]);
}
}
for (let layer of overlayStyle.layers ?? []) {
for (const layer of overlayStyle.layers ?? []) {
if (!map_.getLayer(layer.id)) {
if (opacity !== undefined) {
if (layer.type === 'raster') {
@@ -200,7 +200,7 @@ export class StyleManager {
}
}
}
} catch (e) {}
} catch {}
}
updateTerrain() {
@@ -223,7 +223,7 @@ export class StyleManager {
async get(styleInfo: StyleSpecification | string): Promise<StyleSpecification> {
if (typeof styleInfo === 'string') {
let styleUrl = styleInfo as string;
const styleUrl = styleInfo as string;
const response = await fetch(styleUrl, { cache: 'force-cache' });
if (!response.ok) {
throw new Error(`HTTP error fetching style "${styleInfo}": ${response.status}`);
@@ -238,7 +238,7 @@ export class StyleManager {
merge(style: StyleSpecification, other: StyleSpecification) {
style.sources = { ...style.sources, ...other.sources };
const units = get(distanceUnits);
for (let layer of other.layers ?? []) {
for (const layer of other.layers ?? []) {
if ('source' in layer) {
if (layer.source == 'contours_m' && units === 'imperial') continue;
if (layer.source == 'contours_ft' && units !== 'imperial') continue;
@@ -92,7 +92,7 @@
}
}
function onMouseUp(e: any) {
function onMouseUp() {
mousedown = false;
}
@@ -74,7 +74,7 @@ export class RoutingControls {
listenedFileIds: string[] = [];
popup: Popup;
popupElement: HTMLElement;
unsubscribes: Function[] = [];
unsubscribes: (() => void)[] = [];
updateBinded: () => void = this.update.bind(this);
appendAnchorBinded: (e: MapMouseEvent) => void = this.appendAnchor.bind(this);
@@ -270,7 +270,7 @@ export class RoutingControls {
layerEventManager.on('mousedown', LAYER_ID, this.onMouseDownBinded);
layerEventManager.on('touchstart', LAYER_ID, this.onTouchStartBinded);
}
} catch (e) {
} catch {
// No reliable way to check if the map is ready to add sources and layers
}
}
@@ -303,7 +303,7 @@ export class RoutingControls {
if (map_?.getSource(LAYER_ID)) {
map_?.removeSource(LAYER_ID);
}
} catch (e) {
} catch {
// No reliable way to check if the map is ready to remove sources and layers
}
@@ -137,7 +137,7 @@ async function getGraphHopperRoute(
graphHopperProfile: string,
privateRoads: boolean
): Promise<RoutedPoints> {
let response = await fetch('https://graphhopper.gpx.studio/route', {
const response = await fetch('https://graphhopper.gpx.studio/route', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@@ -222,9 +222,9 @@ async function getBRouterRoute(
points: Coordinates[],
brouterProfile: string
): Promise<RoutedPoints> {
let url = `https://brouter.de/brouter?lonlats=${points.map((point) => `${point.lng.toFixed(8)},${point.lat.toFixed(8)}`).join('|')}&profile=${brouterProfile}&format=geojson&alternativeidx=0`;
const url = `https://brouter.de/brouter?lonlats=${points.map((point) => `${point.lng.toFixed(8)},${point.lat.toFixed(8)}`).join('|')}&profile=${brouterProfile}&format=geojson&alternativeidx=0`;
let response = await fetch(url);
const response = await fetch(url);
if (!response.ok) {
throw brouterError(await response.text());
@@ -289,11 +289,10 @@ export function parseBRouterRoute(geojson: any): RoutedPoints {
/** The tags of a way, `key=value` separated by spaces, with the `:` of the keys as `_`. */
export function getTags(message: string): { [key: string]: string } {
const fields = message.split(' ');
let tags: { [key: string]: string } = {};
const tags: { [key: string]: string } = {};
for (let i = 0; i < fields.length; i++) {
let [key, value] = fields[i].split('=');
key = key.replace(/:/g, '_');
tags[key] = value;
const [key, value] = fields[i].split('=');
tags[key.replace(/:/g, '_')] = value;
}
return tags;
}
@@ -12,7 +12,7 @@ export const SplitType = {
} as const satisfies Record<string, EngineSplitType>;
export type SplitType = (typeof SplitType)[keyof typeof SplitType];
export let splitAs: Writable<SplitType> = writable(SplitType.FILES);
export const splitAs: Writable<SplitType> = writable(SplitType.FILES);
/** The ids of the segments of the routes of the files of the selection. */
export function routeSegmentIds(selection: Selection): Set<string> {
@@ -23,7 +23,7 @@ import {
export class SplitControls {
map: Map;
layerEventManager: MapLayerEventManager;
unsubscribes: Function[] = [];
unsubscribes: (() => void)[] = [];
/** What the tool needs from the engine, while it shows the anchors. */
request: StatisticsRequest = engine.requestStatistics();
selection: Selection = { type: 'empty' };
@@ -116,7 +116,7 @@ export class SplitControls {
};
try {
let source = this.map.getSource('split-controls') as GeoJSONSource | undefined;
const source = this.map.getSource('split-controls') as GeoJSONSource | undefined;
if (source) {
source.setData(data);
} else {
@@ -154,7 +154,7 @@ export class SplitControls {
);
this.layerEventManager.on('click', 'split-controls', this.layerOnClickBinded);
}
} catch (e) {
} catch {
// No reliable way to check if the map is ready to add sources and layers
}
}
@@ -172,12 +172,12 @@ export class SplitControls {
if (this.map.getSource('split-controls')) {
this.map.removeSource('split-controls');
}
} catch (e) {
} catch {
// No reliable way to check if the map is ready to remove sources and layers
}
}
layerOnMouseEnter(e: any) {
layerOnMouseEnter() {
mapCursor.notify(MapCursorState.SPLIT_CONTROL, true);
}
@@ -101,10 +101,7 @@
if (typeof hours === 'string') {
hours = parseInt(hours);
}
if (hours >= 0) {
} else if (hours < 0) {
hours = 0;
} else {
if (hours < 0) {
hours = 0;
}
onChange();
@@ -124,12 +121,9 @@
if (typeof minutes === 'string') {
minutes = parseInt(minutes);
}
if (minutes >= 0 && (minutes <= 59 || !showHours)) {
} else if (minutes < 0) {
minutes = 0;
} else if (showHours && minutes > 59) {
if (showHours && minutes > 59) {
minutes = 59;
} else {
} else if (minutes < 0) {
minutes = 0;
}
minutes = minutes.toString().padStart(showHours ? 2 : 1, '0');
@@ -149,12 +143,9 @@
if (typeof seconds === 'string') {
seconds = parseInt(seconds);
}
if (seconds >= 0 && seconds <= 59) {
} else if (seconds < 0) {
seconds = 0;
} else if (seconds > 59) {
if (seconds > 59) {
seconds = 59;
} else {
} else if (seconds < 0) {
seconds = 0;
}
seconds = seconds.toString().padStart(2, '0');
+8 -8
View File
@@ -96,10 +96,10 @@ function createPattern(
size: number = 16,
lineWidth: number = 4
) {
let canvas = document.createElement('canvas');
const canvas = document.createElement('canvas');
canvas.width = size;
canvas.height = size;
let ctx = canvas.getContext('2d');
const ctx = canvas.getContext('2d');
if (ctx) {
ctx.fillStyle = backgroundColor;
ctx.fillRect(0, 0, size, size);
@@ -139,11 +139,11 @@ export function getHighwayColor(
sacScale: string | undefined,
mtbScale: string | undefined
) {
let backgroundColor = highwayColors[highway] ? highwayColors[highway] : highwayColors.missing;
let sacScaleColor = sacScale ? sacScaleColors[sacScale] : undefined;
let mtbScaleColor = mtbScale ? mtbScaleColors[mtbScale] : undefined;
const backgroundColor = highwayColors[highway] ? highwayColors[highway] : highwayColors.missing;
const sacScaleColor = sacScale ? sacScaleColors[sacScale] : undefined;
const mtbScaleColor = mtbScale ? mtbScaleColors[mtbScale] : undefined;
if (sacScale || mtbScale) {
let patternId = `${backgroundColor}-${[sacScale, mtbScale].filter((x) => x).join('-')}`;
const patternId = `${backgroundColor}-${[sacScale, mtbScale].filter((x) => x).join('-')}`;
if (!patterns[patternId]) {
patterns[patternId] = createPattern(backgroundColor, sacScaleColor, mtbScaleColor);
}
@@ -164,8 +164,8 @@ export function getSlopeColor(slope: number): string {
v = 1 / (1 + Math.exp(-6 * v));
v = v - 0.5;
let hue = ((0.5 - v) * 120).toString(10);
let lightness = 90 - Math.abs(v) * 70;
const hue = ((0.5 - v) * 120).toString(10);
const lightness = 90 - Math.abs(v) * 70;
return `hsl(${hue},70%,${lightness}%)`;
}
+1 -1
View File
@@ -1,5 +1,5 @@
import { get, writable, type Readable } from 'svelte/store';
import { categoryIntervals, type CategoryIntervals } from '$lib/engine/trackpoint-categories';
import type { CategoryIntervals } from '$lib/engine/trackpoint-categories';
import type { Backend } from './backend';
import {
EMPTY_SELECTION_STATISTICS,
+1 -1
View File
@@ -1,5 +1,5 @@
import type { Readable } from 'svelte/store';
import type { Feature, FeatureCollection, LineString, Point } from 'geojson';
import type { FeatureCollection, LineString, Point } from 'geojson';
import type { Visibility } from '$lib/engine/file-visibility';
import type { CategoryIntervals } from '$lib/engine/trackpoint-categories';
import type { FileStructure, GlobalStatistics, SelectionPoint } from 'gpx-wasm';
+3 -3
View File
@@ -19,7 +19,7 @@ export class BoundsManager {
this.fitBoundsOnLoad(Array.from(newFiles.keys()));
}
},
(fileId) => {},
() => {},
() => {}
);
}
@@ -40,7 +40,7 @@ export class BoundsManager {
}
});
},
(fileId) => {},
() => {},
() => {}
);
}
@@ -51,7 +51,7 @@ export class BoundsManager {
this._files.delete(fileId);
if (file.statistics.bounds) {
let bounds = new LngLatBounds([
const bounds = new LngLatBounds([
file.statistics.bounds.west,
file.statistics.bounds.south,
file.statistics.bounds.east,
+2 -2
View File
@@ -36,10 +36,10 @@ export class MapCursor {
constructor() {
this._states = writable(new Set());
this._states.subscribe((states) => {
let state = Array.from(states.values()).reduce((max, value) => {
const state = Array.from(states.values()).reduce((max, value) => {
return value > max ? value : max;
}, MapCursorState.DEFAULT);
let canvas = get(map)?.getCanvas();
const canvas = get(map)?.getCanvas();
if (canvas) {
canvas.style.cursor = cursorStyles[state];
}
+1 -1
View File
@@ -126,7 +126,7 @@ export function getArrayValidator<V>(allowed: V[]) {
export function getLayerValidator(allowed: Record<string, any>, fallback: string) {
return (layer: string) =>
allowed.hasOwnProperty(layer) ||
Object.hasOwn(allowed, layer) ||
layer.startsWith('custom-') ||
layer.startsWith('extension-')
? layer
-1
View File
@@ -10,7 +10,6 @@ import {
defaultTerrainSource,
overpassTree,
type CustomLayer,
type LayerTreeType,
} from '$lib/data/layers';
import { browser } from '$app/environment';
import type { DistanceUnits, TemperatureUnits, VelocityUnits } from '$lib/units/conversions';
+5 -1
View File
@@ -40,7 +40,11 @@ describe('getURLForLanguage', () => {
describe('cn', () => {
it('merges class names, the last tailwind class winning', () => {
assert.equal(cn('p-2', 'p-4'), 'p-4');
assert.equal(cn('text-sm', false && 'hidden', undefined, 'font-bold'), 'text-sm font-bold');
const hidden: boolean = false;
assert.equal(
cn('text-sm', hidden && 'hidden', undefined, 'font-bold'),
'text-sm font-bold'
);
assert.equal(cn(['a', { b: true, c: false }]), 'a b');
});
});
+21 -21
View File
@@ -22,22 +22,22 @@ export function getElevation(
ELEVATION_ZOOM: number = 12,
tileSize = 512
): Promise<number[]> {
let coordinates = points;
let bbox = new LngLatBounds();
const coordinates = points;
const bbox = new LngLatBounds();
coordinates.forEach((coord) => bbox.extend(coord));
let tiles = coordinates.map((coord) => pointToTile(coord.lng, coord.lat, ELEVATION_ZOOM));
let uniqueTiles = Array.from(new Set(tiles.map((tile) => tile.join(',')))).map((tile) =>
const tiles = coordinates.map((coord) => pointToTile(coord.lng, coord.lat, ELEVATION_ZOOM));
const uniqueTiles = Array.from(new Set(tiles.map((tile) => tile.join(',')))).map((tile) =>
tile.split(',').map((x) => parseInt(x))
);
let images = new Map<string, ImageData>();
const images = new Map<string, ImageData>();
const getPixelFromImageData = (imageData: ImageData, x: number, y: number): number[] => {
const index = (y * imageData.width + x) * 4;
return [imageData.data[index], imageData.data[index + 1], imageData.data[index + 2]];
};
let promises = uniqueTiles.map((tile) =>
const promises = uniqueTiles.map((tile) =>
fetch(`https://tiles.gpx.studio/mapterhorn/${ELEVATION_ZOOM}/${tile[0]}/${tile[1]}.webp`, {
cache: 'force-cache',
})
@@ -71,20 +71,20 @@ export function getElevation(
return Promise.all(promises).then(() =>
coordinates.map((coord, index) => {
let tile = tiles[index];
let imageData = images.get(tile.join(','));
const tile = tiles[index];
const imageData = images.get(tile.join(','));
if (!imageData) {
return 0;
}
let tf = pointToTileFraction(coord.lng, coord.lat, ELEVATION_ZOOM);
let x = tileSize * (tf[0] - tile[0]);
let y = tileSize * (tf[1] - tile[1]);
let _x = Math.floor(x);
let _y = Math.floor(y);
let dx = x - _x;
let dy = y - _y;
const tf = pointToTileFraction(coord.lng, coord.lat, ELEVATION_ZOOM);
const x = tileSize * (tf[0] - tile[0]);
const y = tileSize * (tf[1] - tile[1]);
const _x = Math.floor(x);
const _y = Math.floor(y);
const dx = x - _x;
const dy = y - _y;
const p00 = getPixelFromImageData(imageData, _x, _y);
const p01 = getPixelFromImageData(imageData, _x, _y + (_y + 1 == tileSize ? 0 : 1));
@@ -95,10 +95,10 @@ export function getElevation(
_y + (_y + 1 == tileSize ? 0 : 1)
);
let ele00 = -32768 + p00[0] * 256 + p00[1] + p00[2] / 256;
let ele01 = -32768 + p01[0] * 256 + p01[1] + p01[2] / 256;
let ele10 = -32768 + p10[0] * 256 + p10[1] + p10[2] / 256;
let ele11 = -32768 + p11[0] * 256 + p11[1] + p11[2] / 256;
const ele00 = -32768 + p00[0] * 256 + p00[1] + p00[2] / 256;
const ele01 = -32768 + p01[0] * 256 + p01[1] + p01[2] / 256;
const ele10 = -32768 + p10[0] * 256 + p10[1] + p10[2] / 256;
const ele11 = -32768 + p11[0] * 256 + p11[1] + p11[2] / 256;
return (
ele00 * (1 - dx) * (1 - dy) +
@@ -112,7 +112,7 @@ export function getElevation(
export function loadSVGIcon(map: MapLibreMap, id: string, svg: string, size: number = 100) {
if (!map.hasImage(id)) {
let icon = new Image(size, size);
const icon = new Image(size, size);
icon.onload = () => {
if (!map.hasImage(id)) {
map.addImage(id, icon);
@@ -134,7 +134,7 @@ export function getURLForLanguage(lang: string, path: string): string {
let newPath = path.replace(base, '');
let languageInPath = newPath.split('/')[1];
if (!languages.hasOwnProperty(languageInPath)) {
if (!Object.hasOwn(languages, languageInPath)) {
languageInPath = 'en';
}
+2 -2
View File
@@ -15,9 +15,9 @@ export async function load({ params }) {
const { language } = params;
const guideTitles: Record<string, string> = {};
for (let guide of Object.keys(guides)) {
for (const guide of Object.keys(guides)) {
guideTitles[guide] = (await getModule(language, guide)).metadata.title;
for (let subguide of guides[guide]) {
for (const subguide of guides[guide]) {
guideTitles[`${guide}/${subguide}`] = (
await getModule(language, `${guide}/${subguide}`)
).metadata.title;
+1 -1
View File
@@ -40,7 +40,7 @@
if (page.params.language) {
let lang = page.params.language.replace('/', '');
if (i18n.lang !== lang) {
if (languages.hasOwnProperty(lang)) {
if (Object.hasOwn(languages, lang)) {
i18n.lang = lang;
} else if (browser) {
goto(`${base}/404`);
+1 -1
View File
@@ -145,7 +145,7 @@
{elevationFill}
/>
</div>
<GPXStatistics {statistics} {slicedStatistics} orientation={'horizontal'} />
<GPXStatistics {statistics} {slicedStatistics} orientation="horizontal" />
</div>
</div>
<div class="grid md:grid-rows-subgrid md:row-start-3 md:row-end-5 gap-4">
@@ -3,14 +3,14 @@ import { guides } from '$lib/components/docs/docs';
import type { EntryGenerator } from './$types';
export const entries: EntryGenerator = () => {
let entries = [];
for (let lang of Object.keys(languages)) {
for (let guide of Object.keys(guides)) {
const entries = [];
for (const lang of Object.keys(languages)) {
for (const guide of Object.keys(guides)) {
entries.push({
language: lang == 'en' ? '' : lang,
guide,
});
for (let subguide of guides[guide]) {
for (const subguide of guides[guide]) {
entries.push({
language: lang == 'en' ? '' : lang,
guide: `${guide}/${subguide}`,