@open-pioneer/spatial-bookmarks 1.4.0-dev.20260624132304 → 1.4.0-dev.20260727093741
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -2
- package/SpatialBookmarksViewModel.d.ts +1 -17
- package/SpatialBookmarksViewModel.js +31 -31
- package/SpatialBookmarksViewModel.js.map +1 -1
- package/package.json +12 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
# @open-pioneer/spatial-bookmarks
|
|
2
2
|
|
|
3
|
-
## 1.4.0-dev.
|
|
3
|
+
## 1.4.0-dev.20260727093741
|
|
4
4
|
|
|
5
5
|
### Minor Changes
|
|
6
6
|
|
|
7
|
-
- c30396d: Update Chakra to 3.36.
|
|
7
|
+
- c30396d: Update Chakra to 3.36.1
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 078bef5: Use private JavaScript properties (#) instead of TypeScript keyword.
|
|
8
12
|
|
|
9
13
|
## 1.3.0
|
|
10
14
|
|
|
@@ -13,10 +13,7 @@ export interface Bookmark {
|
|
|
13
13
|
projection: string;
|
|
14
14
|
}
|
|
15
15
|
export declare class SpatialBookmarkViewModel {
|
|
16
|
-
private
|
|
17
|
-
private packageNamespace;
|
|
18
|
-
private writableBookmarks;
|
|
19
|
-
private watchBookmarksHandle;
|
|
16
|
+
#private;
|
|
20
17
|
/**
|
|
21
18
|
* Provides read-only access to the bookmarks array.
|
|
22
19
|
* The UI simply renders the contents of the store and
|
|
@@ -43,18 +40,5 @@ export declare class SpatialBookmarkViewModel {
|
|
|
43
40
|
* Deletes all bookmarks.
|
|
44
41
|
*/
|
|
45
42
|
deleteAllBookmarks(): void;
|
|
46
|
-
/**
|
|
47
|
-
* Loads the bookmarks from local storage.
|
|
48
|
-
* If the bookmarks are not valid, the initial state (empty array) is restored.
|
|
49
|
-
*/
|
|
50
|
-
private loadState;
|
|
51
|
-
/**
|
|
52
|
-
* Saves the bookmarks to local storage.
|
|
53
|
-
*/
|
|
54
|
-
private saveState;
|
|
55
|
-
/** Computes an OpenLayers extent for the given bookmark. */
|
|
56
|
-
private getBookmarkExtent;
|
|
57
|
-
/** Moves the map to the given extent. */
|
|
58
|
-
private applyExtent;
|
|
59
43
|
}
|
|
60
44
|
export {};
|
|
@@ -7,38 +7,38 @@ import { v4 } from 'uuid';
|
|
|
7
7
|
|
|
8
8
|
const LOG = createLogger(sourceId);
|
|
9
9
|
class SpatialBookmarkViewModel {
|
|
10
|
-
map;
|
|
11
|
-
packageNamespace;
|
|
12
|
-
writableBookmarks = reactiveArray([]);
|
|
13
|
-
watchBookmarksHandle;
|
|
10
|
+
#map;
|
|
11
|
+
#packageNamespace;
|
|
12
|
+
#writableBookmarks = reactiveArray([]);
|
|
13
|
+
#watchBookmarksHandle;
|
|
14
14
|
/**
|
|
15
15
|
* Provides read-only access to the bookmarks array.
|
|
16
16
|
* The UI simply renders the contents of the store and
|
|
17
17
|
* uses the methods below to modify the state.
|
|
18
18
|
*/
|
|
19
19
|
get bookmarks() {
|
|
20
|
-
return this
|
|
20
|
+
return this.#writableBookmarks.getItems();
|
|
21
21
|
}
|
|
22
22
|
constructor(map, localStorageService) {
|
|
23
|
-
this
|
|
24
|
-
this
|
|
25
|
-
this
|
|
26
|
-
this
|
|
27
|
-
() => [this
|
|
28
|
-
([bookmarks]) => this
|
|
23
|
+
this.#map = map;
|
|
24
|
+
this.#packageNamespace = localStorageService.getNamespace("spatial-bookmarks");
|
|
25
|
+
this.#loadState();
|
|
26
|
+
this.#watchBookmarksHandle = watch(
|
|
27
|
+
() => [this.#writableBookmarks.getItems()],
|
|
28
|
+
([bookmarks]) => this.#saveState(bookmarks),
|
|
29
29
|
{ immediate: false }
|
|
30
30
|
);
|
|
31
31
|
}
|
|
32
32
|
destroy() {
|
|
33
|
-
this
|
|
33
|
+
this.#watchBookmarksHandle.destroy();
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
36
|
* Creates a new bookmark with the `title` provided by the UI.
|
|
37
37
|
* The current map extent is used for the new bookmark's extent.
|
|
38
38
|
*/
|
|
39
39
|
createBookmark(title) {
|
|
40
|
-
const olExtent = this
|
|
41
|
-
const projection = this
|
|
40
|
+
const olExtent = this.#map.olView.calculateExtent();
|
|
41
|
+
const projection = this.#map.projection.getCode();
|
|
42
42
|
const [minX = 0, minY = 0, maxX = 0, maxY = 0] = olExtent;
|
|
43
43
|
const extent = { minX, minY, maxX, maxY };
|
|
44
44
|
const bookmark = {
|
|
@@ -48,7 +48,7 @@ class SpatialBookmarkViewModel {
|
|
|
48
48
|
projection
|
|
49
49
|
};
|
|
50
50
|
LOG.debug("Created a new bookmark", bookmark);
|
|
51
|
-
const bookmarks = this
|
|
51
|
+
const bookmarks = this.#writableBookmarks;
|
|
52
52
|
bookmarks.push(bookmark);
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
@@ -57,18 +57,18 @@ class SpatialBookmarkViewModel {
|
|
|
57
57
|
*/
|
|
58
58
|
activateBookmark(bookmark) {
|
|
59
59
|
LOG.debug("Activating bookmark", bookmark);
|
|
60
|
-
const extent = this
|
|
60
|
+
const extent = this.#getBookmarkExtent(bookmark);
|
|
61
61
|
LOG.debug("Attempting to apply extent", extent);
|
|
62
|
-
this
|
|
62
|
+
this.#applyExtent(extent);
|
|
63
63
|
}
|
|
64
64
|
/**
|
|
65
65
|
* Deletes the bookmark with the given id.
|
|
66
66
|
*/
|
|
67
67
|
deleteBookmark(id) {
|
|
68
68
|
LOG.debug("Deleting bookmark", id);
|
|
69
|
-
const index = this
|
|
69
|
+
const index = this.#writableBookmarks.findIndex((bookmark) => bookmark.id === id);
|
|
70
70
|
if (index > -1) {
|
|
71
|
-
this
|
|
71
|
+
this.#writableBookmarks.splice(index, 1);
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
/**
|
|
@@ -76,34 +76,34 @@ class SpatialBookmarkViewModel {
|
|
|
76
76
|
*/
|
|
77
77
|
deleteAllBookmarks() {
|
|
78
78
|
LOG.debug("Deleting all bookmarks");
|
|
79
|
-
this
|
|
79
|
+
this.#writableBookmarks.splice(0);
|
|
80
80
|
}
|
|
81
81
|
/**
|
|
82
82
|
* Loads the bookmarks from local storage.
|
|
83
83
|
* If the bookmarks are not valid, the initial state (empty array) is restored.
|
|
84
84
|
*/
|
|
85
|
-
loadState() {
|
|
85
|
+
#loadState() {
|
|
86
86
|
LOG.debug("Restoring bookmarks from local storage");
|
|
87
|
-
const rawBookmarks = this
|
|
87
|
+
const rawBookmarks = this.#packageNamespace.get("bookmarks") ?? [];
|
|
88
88
|
try {
|
|
89
89
|
validateBookmarks(rawBookmarks);
|
|
90
|
-
this
|
|
90
|
+
this.#writableBookmarks.push(...rawBookmarks);
|
|
91
91
|
} catch (e) {
|
|
92
92
|
LOG.error("Bookmarks data in local storage is invalid, resetting to default value.", e);
|
|
93
|
-
this
|
|
94
|
-
this
|
|
93
|
+
this.#writableBookmarks.splice(0);
|
|
94
|
+
this.#saveState([]);
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
/**
|
|
98
98
|
* Saves the bookmarks to local storage.
|
|
99
99
|
*/
|
|
100
|
-
saveState(bookmarks) {
|
|
100
|
+
#saveState(bookmarks) {
|
|
101
101
|
LOG.debug("Saving bookmarks to local storage");
|
|
102
|
-
this
|
|
102
|
+
this.#packageNamespace.set("bookmarks", bookmarks);
|
|
103
103
|
}
|
|
104
104
|
/** Computes an OpenLayers extent for the given bookmark. */
|
|
105
|
-
getBookmarkExtent(bookmark) {
|
|
106
|
-
const olView = this
|
|
105
|
+
#getBookmarkExtent(bookmark) {
|
|
106
|
+
const olView = this.#map.olView;
|
|
107
107
|
const extent = bookmark.extent;
|
|
108
108
|
const olExtent = [extent.minX, extent.minY, extent.maxX, extent.maxY];
|
|
109
109
|
const viewProjection = olView.getProjection();
|
|
@@ -111,8 +111,8 @@ class SpatialBookmarkViewModel {
|
|
|
111
111
|
return transformExtent(olExtent, extentProjection, viewProjection);
|
|
112
112
|
}
|
|
113
113
|
/** Moves the map to the given extent. */
|
|
114
|
-
applyExtent(olExtent) {
|
|
115
|
-
const olView = this
|
|
114
|
+
#applyExtent(olExtent) {
|
|
115
|
+
const olView = this.#map.olView;
|
|
116
116
|
const center = getCenter(olExtent);
|
|
117
117
|
const resolution = olView.getResolutionForExtent(olExtent);
|
|
118
118
|
olView.setCenter(center);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SpatialBookmarksViewModel.js","sources":["SpatialBookmarksViewModel.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { CleanupHandle, reactiveArray, watch } from \"@conterra/reactivity-core\";\nimport { createLogger } from \"@open-pioneer/core\";\nimport { LocalStorageNamespace, LocalStorageService } from \"@open-pioneer/local-storage\";\nimport { MapModel } from \"@open-pioneer/map\";\nimport { Extent as OlExtent, getCenter } from \"ol/extent\";\nimport { transformExtent } from \"ol/proj\";\nimport { sourceId } from \"open-pioneer:source-info\";\nimport { v4 as uuid4v } from \"uuid\";\n\nconst LOG = createLogger(sourceId);\n\ninterface Extent {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}\n\nexport interface Bookmark {\n id: string;\n title: string;\n extent: Extent;\n projection: string;\n}\n\nexport class SpatialBookmarkViewModel {\n private map: MapModel;\n private packageNamespace: LocalStorageNamespace;\n private writableBookmarks = reactiveArray<Bookmark>([]);\n private watchBookmarksHandle: CleanupHandle;\n\n /**\n * Provides read-only access to the bookmarks array.\n * The UI simply renders the contents of the store and\n * uses the methods below to modify the state.\n */\n get bookmarks(): Bookmark[] {\n return this.writableBookmarks.getItems();\n }\n\n constructor(map: MapModel, localStorageService: LocalStorageService) {\n this.map = map;\n this.packageNamespace = localStorageService.getNamespace(\"spatial-bookmarks\");\n\n // Load from local storage on start; save changes whenever bookmarks change.\n this.loadState();\n this.watchBookmarksHandle = watch(\n () => [this.writableBookmarks.getItems()],\n ([bookmarks]) => this.saveState(bookmarks),\n { immediate: false }\n );\n }\n\n destroy() {\n this.watchBookmarksHandle.destroy();\n }\n\n /**\n * Creates a new bookmark with the `title` provided by the UI.\n * The current map extent is used for the new bookmark's extent.\n */\n createBookmark(title: string) {\n // minx, miny, maxx, maxy\n const olExtent = this.map.olView.calculateExtent();\n const projection = this.map.projection.getCode();\n const [minX = 0, minY = 0, maxX = 0, maxY = 0] = olExtent;\n const extent: Extent = { minX, minY, maxX, maxY };\n\n const bookmark: Bookmark = {\n id: uuid4v(),\n title,\n extent,\n projection\n };\n LOG.debug(\"Created a new bookmark\", bookmark);\n\n const bookmarks = this.writableBookmarks;\n bookmarks.push(bookmark);\n }\n\n /**\n * Activates the bookmark with the given id by zooming\n * to the bookmark's extent.\n */\n activateBookmark(bookmark: Bookmark) {\n LOG.debug(\"Activating bookmark\", bookmark);\n const extent = this.getBookmarkExtent(bookmark);\n\n LOG.debug(\"Attempting to apply extent\", extent);\n this.applyExtent(extent);\n }\n\n /**\n * Deletes the bookmark with the given id.\n */\n deleteBookmark(id: string) {\n LOG.debug(\"Deleting bookmark\", id);\n const index = this.writableBookmarks.findIndex((bookmark) => bookmark.id === id);\n if (index > -1) {\n this.writableBookmarks.splice(index, 1);\n }\n }\n\n /**\n * Deletes all bookmarks.\n */\n deleteAllBookmarks() {\n LOG.debug(\"Deleting all bookmarks\");\n this.writableBookmarks.splice(0);\n }\n\n /**\n * Loads the bookmarks from local storage.\n * If the bookmarks are not valid, the initial state (empty array) is restored.\n */\n private loadState() {\n LOG.debug(\"Restoring bookmarks from local storage\");\n\n const rawBookmarks = this.packageNamespace.get(\"bookmarks\") ?? [];\n try {\n validateBookmarks(rawBookmarks);\n this.writableBookmarks.push(...rawBookmarks);\n } catch (e) {\n LOG.error(\"Bookmarks data in local storage is invalid, resetting to default value.\", e);\n this.writableBookmarks.splice(0);\n this.saveState([]);\n }\n }\n\n /**\n * Saves the bookmarks to local storage.\n */\n private saveState(bookmarks: Bookmark[]) {\n LOG.debug(\"Saving bookmarks to local storage\");\n this.packageNamespace.set(\"bookmarks\", bookmarks);\n }\n\n /** Computes an OpenLayers extent for the given bookmark. */\n private getBookmarkExtent(bookmark: Bookmark) {\n const olView = this.map.olView;\n const extent = bookmark.extent;\n const olExtent = [extent.minX, extent.minY, extent.maxX, extent.maxY];\n const viewProjection = olView.getProjection();\n const extentProjection = bookmark.projection;\n return transformExtent(olExtent, extentProjection, viewProjection);\n }\n\n /** Moves the map to the given extent. */\n private applyExtent(olExtent: OlExtent) {\n const olView = this.map.olView;\n const center = getCenter(olExtent);\n const resolution = olView.getResolutionForExtent(olExtent);\n olView.setCenter(center);\n olView.setResolution(resolution);\n }\n}\n\nfunction validateBookmarks(rawBookmarks: unknown): asserts rawBookmarks is Bookmark[] {\n if (!Array.isArray(rawBookmarks)) {\n throw new Error(`Expected bookmarks from local storage to be an array.`);\n }\n for (const rawBookmark of rawBookmarks) {\n validateBookmark(rawBookmark);\n }\n}\n\nfunction validateBookmark(rawBookmark: unknown): asserts rawBookmark is Bookmark {\n if (!rawBookmark || typeof rawBookmark !== \"object\") {\n throw new Error(`Expected bookmark from local storage to be an object.`);\n }\n\n const bookmark = rawBookmark as Record<keyof Bookmark, unknown>;\n if (typeof bookmark.id !== \"string\") {\n throw new Error(\"Bookmark does not have a valid id.\");\n }\n if (typeof bookmark.title !== \"string\") {\n throw new Error(\"Bookmark does not have a valid title.\");\n }\n validateExtent(bookmark.extent);\n if (typeof bookmark.projection !== \"string\") {\n throw new Error(\"Bookmark does not have a valid projection value.\");\n }\n}\n\nfunction validateExtent(rawExtent: unknown): asserts rawExtent is Extent {\n if (!rawExtent || typeof rawExtent !== \"object\") {\n throw new Error(`Expected bookmark extent from local storage to be an object.`);\n }\n\n const extent = rawExtent as Record<keyof Extent, unknown>;\n if (\n typeof extent.minX !== \"number\" ||\n typeof extent.minY !== \"number\" ||\n typeof extent.maxX !== \"number\" ||\n typeof extent.maxY !== \"number\"\n ) {\n throw new Error(\"Expected bookmark extent from local storage to have valid coordinates.\");\n }\n}\n"],"names":["uuid4v"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SpatialBookmarksViewModel.js","sources":["SpatialBookmarksViewModel.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { CleanupHandle, reactiveArray, watch } from \"@conterra/reactivity-core\";\nimport { createLogger } from \"@open-pioneer/core\";\nimport { LocalStorageNamespace, LocalStorageService } from \"@open-pioneer/local-storage\";\nimport { MapModel } from \"@open-pioneer/map\";\nimport { Extent as OlExtent, getCenter } from \"ol/extent\";\nimport { transformExtent } from \"ol/proj\";\nimport { sourceId } from \"open-pioneer:source-info\";\nimport { v4 as uuid4v } from \"uuid\";\n\nconst LOG = createLogger(sourceId);\n\ninterface Extent {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}\n\nexport interface Bookmark {\n id: string;\n title: string;\n extent: Extent;\n projection: string;\n}\n\nexport class SpatialBookmarkViewModel {\n #map: MapModel;\n #packageNamespace: LocalStorageNamespace;\n #writableBookmarks = reactiveArray<Bookmark>([]);\n #watchBookmarksHandle: CleanupHandle;\n\n /**\n * Provides read-only access to the bookmarks array.\n * The UI simply renders the contents of the store and\n * uses the methods below to modify the state.\n */\n get bookmarks(): Bookmark[] {\n return this.#writableBookmarks.getItems();\n }\n\n constructor(map: MapModel, localStorageService: LocalStorageService) {\n this.#map = map;\n this.#packageNamespace = localStorageService.getNamespace(\"spatial-bookmarks\");\n\n // Load from local storage on start; save changes whenever bookmarks change.\n this.#loadState();\n this.#watchBookmarksHandle = watch(\n () => [this.#writableBookmarks.getItems()],\n ([bookmarks]) => this.#saveState(bookmarks),\n { immediate: false }\n );\n }\n\n destroy() {\n this.#watchBookmarksHandle.destroy();\n }\n\n /**\n * Creates a new bookmark with the `title` provided by the UI.\n * The current map extent is used for the new bookmark's extent.\n */\n createBookmark(title: string) {\n // minx, miny, maxx, maxy\n const olExtent = this.#map.olView.calculateExtent();\n const projection = this.#map.projection.getCode();\n const [minX = 0, minY = 0, maxX = 0, maxY = 0] = olExtent;\n const extent: Extent = { minX, minY, maxX, maxY };\n\n const bookmark: Bookmark = {\n id: uuid4v(),\n title,\n extent,\n projection\n };\n LOG.debug(\"Created a new bookmark\", bookmark);\n\n const bookmarks = this.#writableBookmarks;\n bookmarks.push(bookmark);\n }\n\n /**\n * Activates the bookmark with the given id by zooming\n * to the bookmark's extent.\n */\n activateBookmark(bookmark: Bookmark) {\n LOG.debug(\"Activating bookmark\", bookmark);\n const extent = this.#getBookmarkExtent(bookmark);\n\n LOG.debug(\"Attempting to apply extent\", extent);\n this.#applyExtent(extent);\n }\n\n /**\n * Deletes the bookmark with the given id.\n */\n deleteBookmark(id: string) {\n LOG.debug(\"Deleting bookmark\", id);\n const index = this.#writableBookmarks.findIndex((bookmark) => bookmark.id === id);\n if (index > -1) {\n this.#writableBookmarks.splice(index, 1);\n }\n }\n\n /**\n * Deletes all bookmarks.\n */\n deleteAllBookmarks() {\n LOG.debug(\"Deleting all bookmarks\");\n this.#writableBookmarks.splice(0);\n }\n\n /**\n * Loads the bookmarks from local storage.\n * If the bookmarks are not valid, the initial state (empty array) is restored.\n */\n #loadState() {\n LOG.debug(\"Restoring bookmarks from local storage\");\n\n const rawBookmarks = this.#packageNamespace.get(\"bookmarks\") ?? [];\n try {\n validateBookmarks(rawBookmarks);\n this.#writableBookmarks.push(...rawBookmarks);\n } catch (e) {\n LOG.error(\"Bookmarks data in local storage is invalid, resetting to default value.\", e);\n this.#writableBookmarks.splice(0);\n this.#saveState([]);\n }\n }\n\n /**\n * Saves the bookmarks to local storage.\n */\n #saveState(bookmarks: Bookmark[]) {\n LOG.debug(\"Saving bookmarks to local storage\");\n this.#packageNamespace.set(\"bookmarks\", bookmarks);\n }\n\n /** Computes an OpenLayers extent for the given bookmark. */\n #getBookmarkExtent(bookmark: Bookmark) {\n const olView = this.#map.olView;\n const extent = bookmark.extent;\n const olExtent = [extent.minX, extent.minY, extent.maxX, extent.maxY];\n const viewProjection = olView.getProjection();\n const extentProjection = bookmark.projection;\n return transformExtent(olExtent, extentProjection, viewProjection);\n }\n\n /** Moves the map to the given extent. */\n #applyExtent(olExtent: OlExtent) {\n const olView = this.#map.olView;\n const center = getCenter(olExtent);\n const resolution = olView.getResolutionForExtent(olExtent);\n olView.setCenter(center);\n olView.setResolution(resolution);\n }\n}\n\nfunction validateBookmarks(rawBookmarks: unknown): asserts rawBookmarks is Bookmark[] {\n if (!Array.isArray(rawBookmarks)) {\n throw new Error(`Expected bookmarks from local storage to be an array.`);\n }\n for (const rawBookmark of rawBookmarks) {\n validateBookmark(rawBookmark);\n }\n}\n\nfunction validateBookmark(rawBookmark: unknown): asserts rawBookmark is Bookmark {\n if (!rawBookmark || typeof rawBookmark !== \"object\") {\n throw new Error(`Expected bookmark from local storage to be an object.`);\n }\n\n const bookmark = rawBookmark as Record<keyof Bookmark, unknown>;\n if (typeof bookmark.id !== \"string\") {\n throw new Error(\"Bookmark does not have a valid id.\");\n }\n if (typeof bookmark.title !== \"string\") {\n throw new Error(\"Bookmark does not have a valid title.\");\n }\n validateExtent(bookmark.extent);\n if (typeof bookmark.projection !== \"string\") {\n throw new Error(\"Bookmark does not have a valid projection value.\");\n }\n}\n\nfunction validateExtent(rawExtent: unknown): asserts rawExtent is Extent {\n if (!rawExtent || typeof rawExtent !== \"object\") {\n throw new Error(`Expected bookmark extent from local storage to be an object.`);\n }\n\n const extent = rawExtent as Record<keyof Extent, unknown>;\n if (\n typeof extent.minX !== \"number\" ||\n typeof extent.minY !== \"number\" ||\n typeof extent.maxX !== \"number\" ||\n typeof extent.maxY !== \"number\"\n ) {\n throw new Error(\"Expected bookmark extent from local storage to have valid coordinates.\");\n }\n}\n"],"names":["uuid4v"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@open-pioneer/spatial-bookmarks",
|
|
4
|
-
"version": "1.4.0-dev.
|
|
4
|
+
"version": "1.4.0-dev.20260727093741",
|
|
5
5
|
"description": "This package provides a UI component that allows the user to store, manage, and easily navigate between different map extents by creating bookmarks.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"open-pioneer-trails"
|
|
@@ -14,19 +14,19 @@
|
|
|
14
14
|
"directory": "src/packages/spatial-bookmarks"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@chakra-ui/react": "^3.36.
|
|
18
|
-
"@open-pioneer/chakra-snippets": "4.7.0-dev.
|
|
19
|
-
"@open-pioneer/core": "4.7.0-dev.
|
|
20
|
-
"@open-pioneer/local-storage": "4.7.0-dev.
|
|
21
|
-
"@open-pioneer/react-utils": "4.7.0-dev.
|
|
22
|
-
"@open-pioneer/runtime": "4.7.0-dev.
|
|
17
|
+
"@chakra-ui/react": "^3.36.1",
|
|
18
|
+
"@open-pioneer/chakra-snippets": "4.7.0-dev.20260727091735",
|
|
19
|
+
"@open-pioneer/core": "4.7.0-dev.20260727091735",
|
|
20
|
+
"@open-pioneer/local-storage": "4.7.0-dev.20260727091735",
|
|
21
|
+
"@open-pioneer/react-utils": "4.7.0-dev.20260727091735",
|
|
22
|
+
"@open-pioneer/runtime": "4.7.0-dev.20260727091735",
|
|
23
23
|
"ol": "^10.9.0",
|
|
24
|
-
"react": "^19.2.
|
|
25
|
-
"react-icons": "^5.
|
|
24
|
+
"react": "^19.2.8",
|
|
25
|
+
"react-icons": "^5.7.0",
|
|
26
26
|
"@conterra/reactivity-core": "^0.8.6",
|
|
27
|
-
"@open-pioneer/reactivity": "4.7.0-dev.
|
|
28
|
-
"uuid": "^14.0.
|
|
29
|
-
"@open-pioneer/map": "1.4.0-dev.
|
|
27
|
+
"@open-pioneer/reactivity": "4.7.0-dev.20260727091735",
|
|
28
|
+
"uuid": "^14.0.1",
|
|
29
|
+
"@open-pioneer/map": "1.4.0-dev.20260727093741"
|
|
30
30
|
},
|
|
31
31
|
"exports": {
|
|
32
32
|
"./package.json": "./package.json",
|