mirror of
				https://github.com/gpxstudio/gpx.studio.git
				synced 2025-11-04 05:21:09 +00:00 
			
		
		
		
	statistics
This commit is contained in:
		@@ -7,23 +7,26 @@
 | 
			
		||||
 | 
			
		||||
    import { i18n } from '$lib/i18n.svelte';
 | 
			
		||||
    import type { GPXStatistics } from 'gpx';
 | 
			
		||||
    import type { Writable } from 'svelte/store';
 | 
			
		||||
    import { settings } from '$lib/db';
 | 
			
		||||
 | 
			
		||||
    export let gpxStatistics: Writable<GPXStatistics>;
 | 
			
		||||
    export let slicedGPXStatistics: Writable<[GPXStatistics, number, number] | undefined>;
 | 
			
		||||
    export let orientation: 'horizontal' | 'vertical';
 | 
			
		||||
    export let panelSize: number;
 | 
			
		||||
    import type { Readable } from 'svelte/store';
 | 
			
		||||
    import { settings } from '$lib/logic/settings';
 | 
			
		||||
 | 
			
		||||
    const { velocityUnits } = settings;
 | 
			
		||||
 | 
			
		||||
    let statistics: GPXStatistics;
 | 
			
		||||
    let {
 | 
			
		||||
        gpxStatistics,
 | 
			
		||||
        slicedGPXStatistics,
 | 
			
		||||
        orientation,
 | 
			
		||||
        panelSize,
 | 
			
		||||
    }: {
 | 
			
		||||
        gpxStatistics: Readable<GPXStatistics>;
 | 
			
		||||
        slicedGPXStatistics: Readable<[GPXStatistics, number, number] | undefined>;
 | 
			
		||||
        orientation: 'horizontal' | 'vertical';
 | 
			
		||||
        panelSize: number;
 | 
			
		||||
    } = $props();
 | 
			
		||||
 | 
			
		||||
    $: if ($slicedGPXStatistics !== undefined) {
 | 
			
		||||
        statistics = $slicedGPXStatistics[0];
 | 
			
		||||
    } else {
 | 
			
		||||
        statistics = $gpxStatistics;
 | 
			
		||||
    }
 | 
			
		||||
    let statistics = $derived(
 | 
			
		||||
        $slicedGPXStatistics !== undefined ? $slicedGPXStatistics[0] : $gpxStatistics
 | 
			
		||||
    );
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<Card.Root
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@
 | 
			
		||||
    } from './file-list';
 | 
			
		||||
    import { i18n } from '$lib/i18n.svelte';
 | 
			
		||||
    import { settings } from '$lib/logic/settings';
 | 
			
		||||
    import type { GPXFileWithStatistics } from '$lib/logic/statistics';
 | 
			
		||||
    import type { GPXFileWithStatistics } from '$lib/logic/statistics-tree';
 | 
			
		||||
    import { selection } from '$lib/logic/selection';
 | 
			
		||||
 | 
			
		||||
    let {
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@
 | 
			
		||||
        type ListItem,
 | 
			
		||||
    } from './file-list';
 | 
			
		||||
    import { isMac } from '$lib/utils';
 | 
			
		||||
    import type { GPXFileWithStatistics } from '$lib/logic/statistics';
 | 
			
		||||
    import type { GPXFileWithStatistics } from '$lib/logic/statistics-tree';
 | 
			
		||||
    import { settings } from '$lib/logic/settings';
 | 
			
		||||
    import { getFileIds, moveItems } from '$lib/logic/file-actions';
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@
 | 
			
		||||
    import { getContext } from 'svelte';
 | 
			
		||||
    import type { Readable } from 'svelte/store';
 | 
			
		||||
    import { ListFileItem } from './file-list';
 | 
			
		||||
    import type { GPXFileWithStatistics } from '$lib/logic/statistics';
 | 
			
		||||
    import type { GPXFileWithStatistics } from '$lib/logic/statistics-tree';
 | 
			
		||||
 | 
			
		||||
    let {
 | 
			
		||||
        file,
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ import {
 | 
			
		||||
import { selectedWaypoint } from '$lib/components/toolbar/tools/waypoint/waypoint';
 | 
			
		||||
import { MapPin, Square } from 'lucide-static';
 | 
			
		||||
import { getSymbolKey, symbols } from '$lib/assets/symbols';
 | 
			
		||||
import type { GPXFileWithStatistics } from '$lib/logic/statistics';
 | 
			
		||||
import type { GPXFileWithStatistics } from '$lib/logic/statistics-tree';
 | 
			
		||||
import { selection } from '$lib/logic/selection';
 | 
			
		||||
import { settings } from '$lib/logic/settings';
 | 
			
		||||
import { currentTool, Tool } from '$lib/components/toolbar/tools';
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@ import {
 | 
			
		||||
    ListTrackSegmentItem,
 | 
			
		||||
} from '$lib/components/file-list/file-list';
 | 
			
		||||
import { getClosestLinePoint, resetCursor, setGrabbingCursor } from '$lib/utils';
 | 
			
		||||
import type { GPXFileWithStatistics } from '$lib/logic/statistics';
 | 
			
		||||
import type { GPXFileWithStatistics } from '$lib/logic/statistics-tree';
 | 
			
		||||
 | 
			
		||||
// const { streetViewSource } = settings;
 | 
			
		||||
export const canChangeStart = writable(false);
 | 
			
		||||
 
 | 
			
		||||
@@ -2,12 +2,12 @@ import { updateAnchorPoints } from '$lib/components/toolbar/tools/routing/Simpli
 | 
			
		||||
import { db, type Database } from '$lib/db';
 | 
			
		||||
import { liveQuery } from 'dexie';
 | 
			
		||||
import { GPXFile } from 'gpx';
 | 
			
		||||
import { GPXStatisticsTree, type GPXFileWithStatistics } from '$lib/logic/statistics';
 | 
			
		||||
import { GPXStatisticsTree, type GPXFileWithStatistics } from '$lib/logic/statistics-tree';
 | 
			
		||||
import { settings } from '$lib/logic/settings';
 | 
			
		||||
import { get, writable, type Subscriber, type Writable } from 'svelte/store';
 | 
			
		||||
 | 
			
		||||
// Observe a single file from the database, and maintain its statistics
 | 
			
		||||
class GPXFileState {
 | 
			
		||||
export class GPXFileState {
 | 
			
		||||
    private _file: Writable<GPXFileWithStatistics | undefined>;
 | 
			
		||||
    private _subscription: { unsubscribe: () => void } | undefined;
 | 
			
		||||
 | 
			
		||||
@@ -119,6 +119,10 @@ export class GPXFileStateCollection {
 | 
			
		||||
        return get(this._files).size;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getFileState(fileId: string): GPXFileState | undefined {
 | 
			
		||||
        return get(this._files).get(fileId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getFile(fileId: string): GPXFile | undefined {
 | 
			
		||||
        let fileState = get(this._files).get(fileId);
 | 
			
		||||
        return fileState?.file;
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ import {
 | 
			
		||||
import { fileStateCollection } from '$lib/logic/file-state';
 | 
			
		||||
import { settings } from '$lib/logic/settings';
 | 
			
		||||
import type { GPXFile } from 'gpx';
 | 
			
		||||
import { get, writable, type Writable } from 'svelte/store';
 | 
			
		||||
import { get, writable, type Readable, type Writable } from 'svelte/store';
 | 
			
		||||
import { SelectionTreeType } from '$lib/logic/selection-tree';
 | 
			
		||||
 | 
			
		||||
export class Selection {
 | 
			
		||||
@@ -203,11 +203,11 @@ export class Selection {
 | 
			
		||||
        this._cut.set(false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get copied(): ListItem[] | undefined {
 | 
			
		||||
    get copied(): Readable<ListItem[] | undefined> {
 | 
			
		||||
        return this._copied;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get cut(): boolean {
 | 
			
		||||
    get cut(): Readable<boolean> {
 | 
			
		||||
        return this._cut;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -219,7 +219,7 @@ export function applyToOrderedItemsFromFile(
 | 
			
		||||
    callback: (fileId: string, level: ListLevel | undefined, items: ListItem[]) => void,
 | 
			
		||||
    reverse: boolean = true
 | 
			
		||||
) {
 | 
			
		||||
    settings.fileOrder.value.forEach((fileId) => {
 | 
			
		||||
    get(settings.fileOrder).forEach((fileId) => {
 | 
			
		||||
        let level: ListLevel | undefined = undefined;
 | 
			
		||||
        let items: ListItem[] = [];
 | 
			
		||||
        selectedItems.forEach((item) => {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										46
									
								
								website/src/lib/logic/statistics-tree.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								website/src/lib/logic/statistics-tree.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
import { ListItem, ListLevel } from '$lib/components/file-list/file-list';
 | 
			
		||||
import { GPXFile, GPXStatistics, type Track } from 'gpx';
 | 
			
		||||
 | 
			
		||||
export class GPXStatisticsTree {
 | 
			
		||||
    level: ListLevel;
 | 
			
		||||
    statistics: {
 | 
			
		||||
        [key: string]: GPXStatisticsTree | GPXStatistics;
 | 
			
		||||
    } = {};
 | 
			
		||||
 | 
			
		||||
    constructor(element: GPXFile | Track) {
 | 
			
		||||
        if (element instanceof GPXFile) {
 | 
			
		||||
            this.level = ListLevel.FILE;
 | 
			
		||||
            element.children.forEach((child, index) => {
 | 
			
		||||
                this.statistics[index] = new GPXStatisticsTree(child);
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
            this.level = ListLevel.TRACK;
 | 
			
		||||
            element.children.forEach((child, index) => {
 | 
			
		||||
                this.statistics[index] = child.getStatistics();
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getStatisticsFor(item: ListItem): GPXStatistics {
 | 
			
		||||
        let statistics = new GPXStatistics();
 | 
			
		||||
        let id = item.getIdAtLevel(this.level);
 | 
			
		||||
        if (id === undefined || id === 'waypoints') {
 | 
			
		||||
            Object.keys(this.statistics).forEach((key) => {
 | 
			
		||||
                if (this.statistics[key] instanceof GPXStatistics) {
 | 
			
		||||
                    statistics.mergeWith(this.statistics[key]);
 | 
			
		||||
                } else {
 | 
			
		||||
                    statistics.mergeWith(this.statistics[key].getStatisticsFor(item));
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
            let child = this.statistics[id];
 | 
			
		||||
            if (child instanceof GPXStatistics) {
 | 
			
		||||
                statistics.mergeWith(child);
 | 
			
		||||
            } else if (child !== undefined) {
 | 
			
		||||
                statistics.mergeWith(child.getStatisticsFor(item));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return statistics;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
export type GPXFileWithStatistics = { file: GPXFile; statistics: GPXStatisticsTree };
 | 
			
		||||
@@ -1,46 +1,80 @@
 | 
			
		||||
import { ListItem, ListLevel } from '$lib/components/file-list/file-list';
 | 
			
		||||
import { GPXFile, GPXStatistics, type Track } from 'gpx';
 | 
			
		||||
import { selection } from '$lib/logic/selection';
 | 
			
		||||
import { GPXStatistics } from 'gpx';
 | 
			
		||||
import { fileStateCollection, GPXFileState } from '$lib/logic/file-state';
 | 
			
		||||
import {
 | 
			
		||||
    ListFileItem,
 | 
			
		||||
    ListWaypointItem,
 | 
			
		||||
    ListWaypointsItem,
 | 
			
		||||
} from '$lib/components/file-list/file-list';
 | 
			
		||||
import { get, writable, type Writable } from 'svelte/store';
 | 
			
		||||
 | 
			
		||||
export class GPXStatisticsTree {
 | 
			
		||||
    level: ListLevel;
 | 
			
		||||
    statistics: {
 | 
			
		||||
        [key: string]: GPXStatisticsTree | GPXStatistics;
 | 
			
		||||
    } = {};
 | 
			
		||||
 | 
			
		||||
    constructor(element: GPXFile | Track) {
 | 
			
		||||
        if (element instanceof GPXFile) {
 | 
			
		||||
            this.level = ListLevel.FILE;
 | 
			
		||||
            element.children.forEach((child, index) => {
 | 
			
		||||
                this.statistics[index] = new GPXStatisticsTree(child);
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
            this.level = ListLevel.TRACK;
 | 
			
		||||
            element.children.forEach((child, index) => {
 | 
			
		||||
                this.statistics[index] = child.getStatistics();
 | 
			
		||||
            });
 | 
			
		||||
export class SelectedGPXStatistics {
 | 
			
		||||
    private _statistics: Writable<GPXStatistics>;
 | 
			
		||||
    private _files: Map<
 | 
			
		||||
        string,
 | 
			
		||||
        {
 | 
			
		||||
            file: GPXFileState;
 | 
			
		||||
            unsubscribe: () => void;
 | 
			
		||||
        }
 | 
			
		||||
    >;
 | 
			
		||||
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this._statistics = writable(new GPXStatistics());
 | 
			
		||||
        this._files = new Map();
 | 
			
		||||
        selection.subscribe(() => this.update());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getStatisticsFor(item: ListItem): GPXStatistics {
 | 
			
		||||
    subscribe(run: (value: GPXStatistics) => void, invalidate?: (value?: GPXStatistics) => void) {
 | 
			
		||||
        return this._statistics.subscribe(run, invalidate);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    update() {
 | 
			
		||||
        let statistics = new GPXStatistics();
 | 
			
		||||
        let id = item.getIdAtLevel(this.level);
 | 
			
		||||
        if (id === undefined || id === 'waypoints') {
 | 
			
		||||
            Object.keys(this.statistics).forEach((key) => {
 | 
			
		||||
                if (this.statistics[key] instanceof GPXStatistics) {
 | 
			
		||||
                    statistics.mergeWith(this.statistics[key]);
 | 
			
		||||
                } else {
 | 
			
		||||
                    statistics.mergeWith(this.statistics[key].getStatisticsFor(item));
 | 
			
		||||
        selection.applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
 | 
			
		||||
            let stats = fileStateCollection.getStatistics(fileId);
 | 
			
		||||
            if (stats) {
 | 
			
		||||
                let first = true;
 | 
			
		||||
                items.forEach((item) => {
 | 
			
		||||
                    if (
 | 
			
		||||
                        !(item instanceof ListWaypointItem || item instanceof ListWaypointsItem) ||
 | 
			
		||||
                        first
 | 
			
		||||
                    ) {
 | 
			
		||||
                        statistics.mergeWith(stats.getStatisticsFor(item));
 | 
			
		||||
                        first = false;
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!this._files.has(fileId)) {
 | 
			
		||||
                let file = fileStateCollection.getFileState(fileId);
 | 
			
		||||
                if (file) {
 | 
			
		||||
                    let first = true;
 | 
			
		||||
                    let unsubscribe = file.subscribe(() => {
 | 
			
		||||
                        if (first) first = false;
 | 
			
		||||
                        else this.update();
 | 
			
		||||
                    });
 | 
			
		||||
                    this._files.set(fileId, { file, unsubscribe });
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
            let child = this.statistics[id];
 | 
			
		||||
            if (child instanceof GPXStatistics) {
 | 
			
		||||
                statistics.mergeWith(child);
 | 
			
		||||
            } else if (child !== undefined) {
 | 
			
		||||
                statistics.mergeWith(child.getStatisticsFor(item));
 | 
			
		||||
            }
 | 
			
		||||
        }, false);
 | 
			
		||||
        this._statistics.set(statistics);
 | 
			
		||||
        for (let [fileId, entry] of this._files) {
 | 
			
		||||
            if (
 | 
			
		||||
                !get(fileStateCollection).has(fileId) ||
 | 
			
		||||
                !get(selection).hasAnyChildren(new ListFileItem(fileId))
 | 
			
		||||
            ) {
 | 
			
		||||
                entry.unsubscribe();
 | 
			
		||||
                this._files.delete(fileId);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return statistics;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
export type GPXFileWithStatistics = { file: GPXFile; statistics: GPXStatisticsTree };
 | 
			
		||||
 | 
			
		||||
export const gpxStatistics = new SelectedGPXStatistics();
 | 
			
		||||
 | 
			
		||||
export const slicedGPXStatistics: Writable<[GPXStatistics, number, number] | undefined> =
 | 
			
		||||
    writable(undefined);
 | 
			
		||||
 | 
			
		||||
gpxStatistics.subscribe(() => {
 | 
			
		||||
    slicedGPXStatistics.set(undefined);
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -22,64 +22,6 @@
 | 
			
		||||
// export const embedding = writable(false);
 | 
			
		||||
// export const selectFiles = writable<{ [key: string]: (fileId?: string) => void }>({});
 | 
			
		||||
 | 
			
		||||
// export const gpxStatistics: Writable<GPXStatistics> = writable(new GPXStatistics());
 | 
			
		||||
// export const slicedGPXStatistics: Writable<[GPXStatistics, number, number] | undefined> =
 | 
			
		||||
//     writable(undefined);
 | 
			
		||||
 | 
			
		||||
// export function updateGPXData() {
 | 
			
		||||
//     let statistics = new GPXStatistics();
 | 
			
		||||
//     applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
 | 
			
		||||
//         let stats = getStatistics(fileId);
 | 
			
		||||
//         if (stats) {
 | 
			
		||||
//             let first = true;
 | 
			
		||||
//             items.forEach((item) => {
 | 
			
		||||
//                 if (
 | 
			
		||||
//                     !(item instanceof ListWaypointItem || item instanceof ListWaypointsItem) ||
 | 
			
		||||
//                     first
 | 
			
		||||
//                 ) {
 | 
			
		||||
//                     statistics.mergeWith(stats.getStatisticsFor(item));
 | 
			
		||||
//                     first = false;
 | 
			
		||||
//                 }
 | 
			
		||||
//             });
 | 
			
		||||
//         }
 | 
			
		||||
//     }, false);
 | 
			
		||||
//     gpxStatistics.set(statistics);
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
// let unsubscribes: Map<string, () => void> = new Map();
 | 
			
		||||
// selection.subscribe(($selection) => {
 | 
			
		||||
//     // Maintain up-to-date statistics for the current selection
 | 
			
		||||
//     updateGPXData();
 | 
			
		||||
 | 
			
		||||
//     while (unsubscribes.size > 0) {
 | 
			
		||||
//         let [fileId, unsubscribe] = unsubscribes.entries().next().value;
 | 
			
		||||
//         unsubscribe();
 | 
			
		||||
//         unsubscribes.delete(fileId);
 | 
			
		||||
//     }
 | 
			
		||||
 | 
			
		||||
//     $selection.forEach((item) => {
 | 
			
		||||
//         let fileId = item.getFileId();
 | 
			
		||||
//         if (!unsubscribes.has(fileId)) {
 | 
			
		||||
//             let fileObserver = get(fileObservers).get(fileId);
 | 
			
		||||
//             if (fileObserver) {
 | 
			
		||||
//                 let first = true;
 | 
			
		||||
//                 unsubscribes.set(
 | 
			
		||||
//                     fileId,
 | 
			
		||||
//                     fileObserver.subscribe(() => {
 | 
			
		||||
//                         if (first) first = false;
 | 
			
		||||
//                         else updateGPXData();
 | 
			
		||||
//                     })
 | 
			
		||||
//                 );
 | 
			
		||||
//             }
 | 
			
		||||
//         }
 | 
			
		||||
//     });
 | 
			
		||||
// });
 | 
			
		||||
 | 
			
		||||
// gpxStatistics.subscribe(() => {
 | 
			
		||||
//     slicedGPXStatistics.set(undefined);
 | 
			
		||||
// });
 | 
			
		||||
 | 
			
		||||
// export const gpxLayers: Map<string, GPXLayer> = new Map();
 | 
			
		||||
// export const routingControls: Map<string, RoutingControls> = new Map();
 | 
			
		||||
 | 
			
		||||
// export function selectFileWhenLoaded(fileId: string) {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
    import GPXLayers from '$lib/components/map/gpx-layer/GPXLayers.svelte';
 | 
			
		||||
    // import ElevationProfile from '$lib/components/ElevationProfile.svelte';
 | 
			
		||||
    // import FileList from '$lib/components/file-list/FileList.svelte';
 | 
			
		||||
    // import GPXStatistics from '$lib/components/GPXStatistics.svelte';
 | 
			
		||||
    import GPXStatistics from '$lib/components/GPXStatistics.svelte';
 | 
			
		||||
    import Map from '$lib/components/map/Map.svelte';
 | 
			
		||||
    import Menu from '$lib/components/Menu.svelte';
 | 
			
		||||
    // import Toolbar from '$lib/components/toolbar/Toolbar.svelte';
 | 
			
		||||
@@ -11,7 +11,6 @@
 | 
			
		||||
    // import CoordinatesPopup from '$lib/components/map/CoordinatesPopup.svelte';
 | 
			
		||||
    import Resizer from '$lib/components/Resizer.svelte';
 | 
			
		||||
    import { Toaster } from '$lib/components/ui/sonner';
 | 
			
		||||
    // import { gpxStatistics, loadFiles, slicedGPXStatistics } from '$lib/stores';
 | 
			
		||||
    // import { onMount } from 'svelte';
 | 
			
		||||
    // import { page } from '$app/state';
 | 
			
		||||
    import { languages } from '$lib/languages';
 | 
			
		||||
@@ -23,6 +22,7 @@
 | 
			
		||||
    import { loadFiles } from '$lib/logic/file-actions';
 | 
			
		||||
    import { onMount } from 'svelte';
 | 
			
		||||
    import { page } from '$app/state';
 | 
			
		||||
    import { gpxStatistics, slicedGPXStatistics } from '$lib/logic/statistics';
 | 
			
		||||
 | 
			
		||||
    const {
 | 
			
		||||
        treeFileView,
 | 
			
		||||
@@ -127,12 +127,12 @@
 | 
			
		||||
            class="{$elevationProfile ? '' : 'h-10'} flex flex-row gap-2 px-2 sm:px-4"
 | 
			
		||||
            style={$elevationProfile ? `height: ${$bottomPanelSize}px` : ''}
 | 
			
		||||
        >
 | 
			
		||||
            <!-- <GPXStatistics
 | 
			
		||||
            <GPXStatistics
 | 
			
		||||
                {gpxStatistics}
 | 
			
		||||
                {slicedGPXStatistics}
 | 
			
		||||
                panelSize={$bottomPanelSize}
 | 
			
		||||
                orientation={$elevationProfile ? 'vertical' : 'horizontal'}
 | 
			
		||||
            /> -->
 | 
			
		||||
            />
 | 
			
		||||
            <!-- {#if $elevationProfile}
 | 
			
		||||
                <ElevationProfile
 | 
			
		||||
                    {gpxStatistics}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user