@edgepdf/viewer-js 0.0.1

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.
@@ -0,0 +1,108 @@
1
+ import L from 'leaflet';
2
+ import type { TileConfig, ImageInfo } from '@edgepdf/types';
3
+ /**
4
+ * TileLayerManager - Manages Leaflet tile layer for displaying image tiles
5
+ *
6
+ * This class handles:
7
+ * - XYZ tile URL template processing
8
+ * - Tile layer creation and configuration
9
+ * - Bounds calculation for seamless tile rendering
10
+ * - Tile grid sizing and management
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const manager = new TileLayerManager({
15
+ * tileUrl: '/tiles/{z}/{x}/{y}.webp',
16
+ * imageInfo: {
17
+ * width: 2000,
18
+ * height: 3000,
19
+ * tileSize: 256,
20
+ * maxZoom: 5,
21
+ * minZoom: 0
22
+ * }
23
+ * });
24
+ *
25
+ * const tileLayer = manager.createTileLayer();
26
+ * tileLayer.addTo(map);
27
+ * ```
28
+ */
29
+ export declare class TileLayerManager {
30
+ private config;
31
+ private tileLayer;
32
+ /**
33
+ * Creates a new TileLayerManager instance
34
+ *
35
+ * @param config - Tile configuration with URL template and image info
36
+ *
37
+ * @throws {Error} If config is invalid or tile URL template is malformed
38
+ */
39
+ constructor(config: TileConfig);
40
+ /**
41
+ * Creates and configures a Leaflet tile layer
42
+ *
43
+ * @param map - Optional Leaflet map instance (for event handling)
44
+ * @returns Configured Leaflet tile layer
45
+ *
46
+ * @throws {Error} If tile layer creation fails
47
+ */
48
+ createTileLayer(map?: L.Map): L.TileLayer;
49
+ /**
50
+ * Calculates tile bounds based on image dimensions
51
+ *
52
+ * Uses the minimum zoom level to ensure consistent coordinate system
53
+ * across all zoom levels.
54
+ *
55
+ * @returns Leaflet bounds for the tile layer
56
+ */
57
+ calculateTileBounds(): L.LatLngBoundsExpression;
58
+ /**
59
+ * Calculates tile grid dimensions for a specific zoom level
60
+ *
61
+ * @param zoom - Zoom level to calculate grid for
62
+ * @returns Object with tileX and tileY counts
63
+ */
64
+ calculateGridSize(zoom: number): {
65
+ tileX: number;
66
+ tileY: number;
67
+ };
68
+ /**
69
+ * Generates a tile URL for specific coordinates
70
+ *
71
+ * @param z - Zoom level
72
+ * @param x - Tile X coordinate
73
+ * @param y - Tile Y coordinate
74
+ * @returns Complete tile URL
75
+ */
76
+ getTileUrl(z: number, x: number, y: number): string;
77
+ /**
78
+ * Gets the current tile layer instance
79
+ *
80
+ * @returns The tile layer, or null if not created
81
+ */
82
+ getTileLayer(): L.TileLayer | null;
83
+ /**
84
+ * Removes the tile layer from the map and cleans up
85
+ *
86
+ * @param map - Optional map instance to remove layer from
87
+ */
88
+ removeTileLayer(map?: L.Map): void;
89
+ /**
90
+ * Sets up event listeners for tile loading events
91
+ *
92
+ * @param _map - Leaflet map instance (unused but kept for future use)
93
+ */
94
+ private setupEventListeners;
95
+ /**
96
+ * Gets the image info configuration
97
+ *
98
+ * @returns Image info object
99
+ */
100
+ getImageInfo(): ImageInfo;
101
+ /**
102
+ * Gets the tile configuration
103
+ *
104
+ * @returns Tile configuration object
105
+ */
106
+ getConfig(): TileConfig;
107
+ }
108
+ //# sourceMappingURL=tile-layer-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tile-layer-manager.d.ts","sourceRoot":"","sources":["../../src/lib/tile-layer-manager.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,SAAS,CAAC;AACxB,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAQ5D;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,SAAS,CAA4B;IAE7C;;;;;;OAMG;gBACS,MAAM,EAAE,UAAU;IAmB9B;;;;;;;OAOG;IACH,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,SAAS;IAkDzC;;;;;;;OAOG;IACH,mBAAmB,IAAI,CAAC,CAAC,sBAAsB;IAK/C;;;;;OAKG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAKjE;;;;;;;OAOG;IACH,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM;IAInD;;;;OAIG;IACH,YAAY,IAAI,CAAC,CAAC,SAAS,GAAG,IAAI;IAIlC;;;;OAIG;IACH,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,IAAI;IAUlC;;;;OAIG;IAEH,OAAO,CAAC,mBAAmB;IAwB3B;;;;OAIG;IACH,YAAY,IAAI,SAAS;IAIzB;;;;OAIG;IACH,SAAS,IAAI,UAAU;CAGxB"}
@@ -0,0 +1,135 @@
1
+ import L from 'leaflet';
2
+ import type { ViewerConfig, MapOptions } from '@edgepdf/types';
3
+ import { TileLayerManager } from './tile-layer-manager.js';
4
+ import { CoordinateMapper } from './coordinate-mapper.js';
5
+ import { ZoomController } from './zoom-controller.js';
6
+ import { MarkerManager } from './marker-manager.js';
7
+ /**
8
+ * EdgePdfViewer - Core class for initializing and managing Leaflet map instances
9
+ *
10
+ * This class provides the foundation for the EdgePDF viewer, handling:
11
+ * - Leaflet map initialization with custom CRS
12
+ * - Map container lifecycle management
13
+ * - Basic cleanup and disposal
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const viewer = new EdgePdfViewer({
18
+ * container: document.getElementById('map'),
19
+ * config: {
20
+ * tileUrl: 'https://example.com/tiles/{z}/{x}/{y}.png',
21
+ * imageInfo: {
22
+ * width: 2000,
23
+ * height: 3000,
24
+ * tileSize: 256,
25
+ * maxZoom: 5,
26
+ * minZoom: 0
27
+ * }
28
+ * }
29
+ * });
30
+ *
31
+ * viewer.initialize();
32
+ * ```
33
+ */
34
+ export declare class EdgePdfViewer {
35
+ private map;
36
+ private container;
37
+ private config;
38
+ private mapOptions?;
39
+ private tileLayerManager;
40
+ private coordinateMapper;
41
+ private zoomController;
42
+ private markerManager;
43
+ /**
44
+ * Creates a new EdgePdfViewer instance
45
+ *
46
+ * @param options - Configuration options for the viewer
47
+ * @param options.container - HTML element that will contain the map
48
+ * @param options.config - Viewer configuration with tile URL and image info
49
+ * @param options.mapOptions - Optional Leaflet map options
50
+ *
51
+ * @throws {Error} If container is not provided or invalid
52
+ * @throws {Error} If config is not provided or invalid
53
+ */
54
+ constructor(options: {
55
+ container: HTMLElement;
56
+ config: ViewerConfig;
57
+ mapOptions?: MapOptions;
58
+ });
59
+ /**
60
+ * Initializes the Leaflet map with custom CRS
61
+ *
62
+ * Sets up a custom coordinate reference system (CRS.Simple) suitable for
63
+ * displaying image tiles without geographic coordinates.
64
+ *
65
+ * @throws {Error} If map initialization fails
66
+ */
67
+ initialize(): void;
68
+ /**
69
+ * Calculates optimal initial zoom based on device type
70
+ *
71
+ * Mobile devices start zoomed out for overview, desktop starts with more detail.
72
+ *
73
+ * @returns Calculated zoom level
74
+ */
75
+ private calculateOptimalInitialZoom;
76
+ /**
77
+ * Adds CSS for seamless tile rendering
78
+ *
79
+ * Removes borders and gaps between tiles for a seamless appearance.
80
+ */
81
+ private addSeamlessTileStyles;
82
+ /**
83
+ * Gets the Leaflet map instance
84
+ *
85
+ * @returns The Leaflet map instance, or null if not initialized
86
+ */
87
+ getMap(): L.Map | null;
88
+ /**
89
+ * Checks if the map is initialized
90
+ *
91
+ * @returns True if map is initialized, false otherwise
92
+ */
93
+ isInitialized(): boolean;
94
+ /**
95
+ * Adds the tile layer to the map
96
+ *
97
+ * Creates a TileLayerManager and adds the tile layer to the initialized map.
98
+ * This is called automatically during initialization.
99
+ *
100
+ * @throws {Error} If map is not initialized or tile layer creation fails
101
+ */
102
+ private addTileLayer;
103
+ /**
104
+ * Gets the tile layer manager instance
105
+ *
106
+ * @returns The tile layer manager, or null if not created
107
+ */
108
+ getTileLayerManager(): TileLayerManager | null;
109
+ /**
110
+ * Gets the coordinate mapper instance
111
+ *
112
+ * @returns The coordinate mapper, or null if not created
113
+ */
114
+ getCoordinateMapper(): CoordinateMapper | null;
115
+ /**
116
+ * Gets the zoom controller instance
117
+ *
118
+ * @returns The zoom controller, or null if not created
119
+ */
120
+ getZoomController(): ZoomController | null;
121
+ /**
122
+ * Gets the marker manager instance
123
+ *
124
+ * @returns The marker manager, or null if not created
125
+ */
126
+ getMarkerManager(): MarkerManager | null;
127
+ /**
128
+ * Disposes of the map instance and cleans up resources
129
+ *
130
+ * This should be called when the viewer is no longer needed to prevent
131
+ * memory leaks and event listener issues.
132
+ */
133
+ dispose(): void;
134
+ }
135
+ //# sourceMappingURL=viewer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewer.d.ts","sourceRoot":"","sources":["../../src/lib/viewer.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,SAAS,CAAC;AACxB,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,GAAG,CAAsB;IACjC,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,UAAU,CAAC,CAAa;IAChC,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,aAAa,CAA8B;IAEnD;;;;;;;;;;OAUG;gBACS,OAAO,EAAE;QACnB,SAAS,EAAE,WAAW,CAAC;QACvB,MAAM,EAAE,YAAY,CAAC;QACrB,UAAU,CAAC,EAAE,UAAU,CAAC;KACzB;IAmBD;;;;;;;OAOG;IACH,UAAU,IAAI,IAAI;IAsFlB;;;;;;OAMG;IACH,OAAO,CAAC,2BAA2B;IAmBnC;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAuB7B;;;;OAIG;IACH,MAAM,IAAI,CAAC,CAAC,GAAG,GAAG,IAAI;IAItB;;;;OAIG;IACH,aAAa,IAAI,OAAO;IAIxB;;;;;;;OAOG;IACH,OAAO,CAAC,YAAY;IAwBpB;;;;OAIG;IACH,mBAAmB,IAAI,gBAAgB,GAAG,IAAI;IAI9C;;;;OAIG;IACH,mBAAmB,IAAI,gBAAgB,GAAG,IAAI;IAI9C;;;;OAIG;IACH,iBAAiB,IAAI,cAAc,GAAG,IAAI;IAI1C;;;;OAIG;IACH,gBAAgB,IAAI,aAAa,GAAG,IAAI;IAIxC;;;;;OAKG;IACH,OAAO,IAAI,IAAI;CA0BhB"}
@@ -0,0 +1,182 @@
1
+ import L from 'leaflet';
2
+ import type { ImageInfo, ZoomConfig, ZoomState } from '@edgepdf/types';
3
+ /**
4
+ * ZoomController - Manages zoom state and operations for the viewer
5
+ *
6
+ * This class provides:
7
+ * - Zoom state management
8
+ * - Zoom level calculations from image dimensions
9
+ * - Zoom constraints enforcement
10
+ * - Responsive initial zoom calculation
11
+ * - Zoom control methods (zoomIn, zoomOut, setZoom)
12
+ * - Zoom event handling
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * const zoomController = new ZoomController({
17
+ * map: leafletMap,
18
+ * imageInfo: {
19
+ * width: 2000,
20
+ * height: 3000,
21
+ * tileSize: 256,
22
+ * maxZoom: 5,
23
+ * minZoom: 0
24
+ * }
25
+ * });
26
+ *
27
+ * // Zoom in
28
+ * zoomController.zoomIn();
29
+ *
30
+ * // Zoom out
31
+ * zoomController.zoomOut();
32
+ *
33
+ * // Set specific zoom level
34
+ * zoomController.setZoom(3);
35
+ *
36
+ * // Get current zoom state
37
+ * const state = zoomController.getZoomState();
38
+ * ```
39
+ */
40
+ export declare class ZoomController {
41
+ private map;
42
+ private imageInfo;
43
+ private config;
44
+ private zoomState;
45
+ private zoomChangeListeners;
46
+ /**
47
+ * Creates a new ZoomController instance
48
+ *
49
+ * @param options - Configuration options
50
+ * @param options.map - Leaflet map instance
51
+ * @param options.imageInfo - Image information for zoom calculations
52
+ * @param options.config - Optional zoom configuration (overrides imageInfo zoom levels)
53
+ *
54
+ * @throws {Error} If map is not provided or invalid
55
+ * @throws {Error} If imageInfo is invalid
56
+ */
57
+ constructor(options: {
58
+ map: L.Map;
59
+ imageInfo: ImageInfo;
60
+ config?: Partial<ZoomConfig>;
61
+ });
62
+ /**
63
+ * Calculates maximum zoom level from image dimensions
64
+ *
65
+ * The calculation considers:
66
+ * - Image dimensions and tile size
67
+ * - Sharp pixel limit (16,383px per dimension) for performance
68
+ * - Practical maximum zoom level (typically 5)
69
+ *
70
+ * @returns Calculated maximum zoom level
71
+ */
72
+ calculateMaxZoomFromDimensions(): number;
73
+ /**
74
+ * Calculates optimal initial zoom based on viewport size
75
+ *
76
+ * Mobile devices start zoomed out for overview, desktop starts with more detail.
77
+ *
78
+ * @returns Calculated initial zoom level
79
+ */
80
+ calculateOptimalInitialZoom(): number;
81
+ /**
82
+ * Constrains a zoom level to the valid range
83
+ *
84
+ * @param zoom - Zoom level to constrain
85
+ * @returns Constrained zoom level within [minZoom, maxZoom]
86
+ */
87
+ constrainZoom(zoom: number): number;
88
+ /**
89
+ * Validates if a zoom level is within the valid range
90
+ *
91
+ * @param zoom - Zoom level to validate
92
+ * @returns True if zoom is valid, false otherwise
93
+ */
94
+ isValidZoom(zoom: number): boolean;
95
+ /**
96
+ * Zooms in by the configured zoom delta
97
+ *
98
+ * @param options - Optional zoom options
99
+ * @param options.animate - Whether to animate the zoom (default: true)
100
+ * @returns True if zoom was successful, false if already at max zoom
101
+ */
102
+ zoomIn(options?: {
103
+ animate?: boolean;
104
+ }): boolean;
105
+ /**
106
+ * Zooms out by the configured zoom delta
107
+ *
108
+ * @param options - Optional zoom options
109
+ * @param options.animate - Whether to animate the zoom (default: true)
110
+ * @returns True if zoom was successful, false if already at min zoom
111
+ */
112
+ zoomOut(options?: {
113
+ animate?: boolean;
114
+ }): boolean;
115
+ /**
116
+ * Sets the zoom level to a specific value
117
+ *
118
+ * @param zoom - Target zoom level
119
+ * @param options - Optional zoom options
120
+ * @param options.animate - Whether to animate the zoom (default: true)
121
+ * @throws {Error} If zoom level is not a finite number
122
+ */
123
+ setZoom(zoom: number, options?: {
124
+ animate?: boolean;
125
+ }): void;
126
+ /**
127
+ * Gets the current zoom state
128
+ *
129
+ * @returns Current zoom state
130
+ */
131
+ getZoomState(): ZoomState;
132
+ /**
133
+ * Gets the current zoom level
134
+ *
135
+ * @returns Current zoom level
136
+ */
137
+ getZoom(): number;
138
+ /**
139
+ * Gets the minimum zoom level
140
+ *
141
+ * @returns Minimum zoom level
142
+ */
143
+ getMinZoom(): number;
144
+ /**
145
+ * Gets the maximum zoom level
146
+ *
147
+ * @returns Maximum zoom level
148
+ */
149
+ getMaxZoom(): number;
150
+ /**
151
+ * Checks if zoom can be increased
152
+ *
153
+ * @returns True if zoom can be increased, false otherwise
154
+ */
155
+ canZoomIn(): boolean;
156
+ /**
157
+ * Checks if zoom can be decreased
158
+ *
159
+ * @returns True if zoom can be decreased, false otherwise
160
+ */
161
+ canZoomOut(): boolean;
162
+ /**
163
+ * Adds a listener for zoom change events
164
+ *
165
+ * @param listener - Callback function called when zoom changes
166
+ * @returns Function to remove the listener
167
+ */
168
+ onZoomChange(listener: (state: ZoomState) => void): () => void;
169
+ /**
170
+ * Removes all zoom change listeners
171
+ */
172
+ removeAllListeners(): void;
173
+ /**
174
+ * Sets up zoom event listeners on the map
175
+ */
176
+ private setupZoomListeners;
177
+ /**
178
+ * Disposes of the zoom controller and cleans up resources
179
+ */
180
+ dispose(): void;
181
+ }
182
+ //# sourceMappingURL=zoom-controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zoom-controller.d.ts","sourceRoot":"","sources":["../../src/lib/zoom-controller.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,SAAS,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,GAAG,CAAQ;IACnB,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,mBAAmB,CAA8C;IAEzE;;;;;;;;;;OAUG;gBACS,OAAO,EAAE;QACnB,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC;QACX,SAAS,EAAE,SAAS,CAAC;QACrB,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;KAC9B;IAkDD;;;;;;;;;OASG;IACH,8BAA8B,IAAI,MAAM;IAsBxC;;;;;;OAMG;IACH,2BAA2B,IAAI,MAAM;IAoBrC;;;;;OAKG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAOnC;;;;;OAKG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAQlC;;;;;;OAMG;IACH,MAAM,CAAC,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO;IAahD;;;;;;OAMG;IACH,OAAO,CAAC,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO;IAajD;;;;;;;OAOG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IAe5D;;;;OAIG;IACH,YAAY,IAAI,SAAS;IAIzB;;;;OAIG;IACH,OAAO,IAAI,MAAM;IAIjB;;;;OAIG;IACH,UAAU,IAAI,MAAM;IAIpB;;;;OAIG;IACH,UAAU,IAAI,MAAM;IAIpB;;;;OAIG;IACH,SAAS,IAAI,OAAO;IAIpB;;;;OAIG;IACH,UAAU,IAAI,OAAO;IAIrB;;;;;OAKG;IACH,YAAY,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,GAAG,MAAM,IAAI;IAS9D;;OAEG;IACH,kBAAkB,IAAI,IAAI;IAI1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAwB1B;;OAEG;IACH,OAAO,IAAI,IAAI;CAKhB"}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@edgepdf/viewer-js",
3
+ "version": "0.0.1",
4
+ "description": "EdgePDF Viewer - JavaScript library for viewing PDF documents with interactive markers and zoom controls",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "license": "MIT",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/EdgeTechStudio/EdgePDF.git",
13
+ "directory": "packages/viewer-js"
14
+ },
15
+ "keywords": [
16
+ "pdf",
17
+ "viewer",
18
+ "leaflet",
19
+ "markers",
20
+ "zoom",
21
+ "interactive"
22
+ ],
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "exports": {
27
+ "./package.json": "./package.json",
28
+ ".": {
29
+ "@edge-pdf/workspace": "./src/index.ts",
30
+ "types": "./dist/index.d.ts",
31
+ "import": "./dist/index.js",
32
+ "default": "./dist/index.js"
33
+ },
34
+ "./styles.css": "./src/styles.css"
35
+ },
36
+ "files": [
37
+ "dist",
38
+ "!**/*.tsbuildinfo"
39
+ ],
40
+ "dependencies": {
41
+ "leaflet": "^1.9.4"
42
+ },
43
+ "devDependencies": {
44
+ "@edgepdf/types": "workspace:*",
45
+ "@edgepdf/utils": "workspace:*",
46
+ "@types/leaflet": "^1.9.21",
47
+ "jest-environment-jsdom": "^30.0.2"
48
+ }
49
+ }