@arenarium/maps 1.2.2 → 1.2.4

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/README.md CHANGED
@@ -1,309 +1,16 @@
1
- # Installation
2
-
3
- ## NPM
4
-
5
- To install the `@aranarium/maps` library using npm, run the following command in your project directory:
6
-
7
- ```
8
- npm install @arenarium/maps
9
- ```
10
-
11
- Import the necessary module and CSS file into your project to begin using the map:
12
-
13
- ```js
14
- import { MapManager } from '@arenarium/maps';
15
- import '@arenarium/maps/dist/style.css';
16
-
17
- // Initialize and mount the map manager (further configuration details follow)
18
- const mapManager = new MapManager(...);
19
- ```
20
-
21
- ## CDN
22
-
23
- To include `@aranarium/maps` directly in your HTML via a Content Delivery Network (CDN), add these script and stylesheet tags to the `<head>` or `<body>` of your HTML document:
24
-
25
- ```html
26
- <script src="https://unpkg.com/maplibre-gl@^5.6.0/dist/maplibre-gl.js"></script>
27
- <link href="https://unpkg.com/maplibre-gl@^5.6.0/dist/maplibre-gl.css" rel="stylesheet" />
28
-
29
- <script src="https://unpkg.com/@arenarium/maps@^1.0.124/dist/index.js"></script>
30
- <link href="https://unpkg.com/@arenarium/maps@^1.0.124/dist/style.css" rel="stylesheet" />
31
- ```
32
-
33
- Once included, you can access the library's functions through the global `arenarium` object to mount the map:
34
-
35
- ```js
36
- // Initialize and mount the map manager (further configuration details follow)
37
- const mapManager = new arenarium.MapManager(...);
38
- ```
39
-
40
- # Usage
41
-
42
- ## Initialization
43
-
44
- To initialize the map, first add a container element to your HTML where the map will be rendered. Then go to the [API Keys](https://arenarium.dev/keys) page and create a new API key. Then depending on the map library used there are different instructions:
45
-
46
- ```html
47
- <div id="map"></div>
48
- ```
49
-
50
- ## Maplibre GL
51
-
52
- First, install the `maplibre-gl` library:
53
-
54
- ```
55
- npm install maplibre-gl
56
- ```
57
-
58
- Next, create a `MapLibreProvider` instance which requires a `maplibre.Map` class, a `maplibre.Marker` class and a `maplibre.MapOptions` object. Use the `MapLibreProvider` instance, along with the API key, to initialize the map manager.
59
-
60
- ```js
61
- import maplibregl from 'maplibre-gl';
62
- import 'maplibre-gl/dist/maplibre-gl.css';
63
-
64
- import { MapManager } from '@arenarium/maps';
65
- import { MapLibreProvider } from '@arenarium/maps/maplibre';
66
- import '@arenarium/maps/dist/style.css';
67
-
68
- // Create a maplibre provider instance
69
- const maplibreProvider = new MapLibreProvider(maplibregl.Map, maplibregl.Marker, {
70
- container: 'map',
71
- ...
72
- });
73
-
74
- // Initialize the map manager with the provider
75
- const mapManager = new MapManager("YOUR_API_KEY", maplibreProvider);
76
-
77
- // Access the maplibre instance for direct map interactions
78
- const maplibreMap = mapLibreProvider.getMap();
79
- ```
80
-
81
- You can change the map's visual appearance by setting a predefined dark or light theme:
82
-
83
- ```js
84
- import { MaplibreDarkStyle, MaplibreLightStyle } from '@arenarium/maps/maplibre';
85
-
86
- maplibreMap.setStyle(MaplibreDarkStyle); // or MaplibreLightStyle
87
- ```
88
-
89
- Alternatively, you can apply a custom map style by providing a URL to a JSON file that adheres to the [MapLibre Style Specification](https://maplibre.org/maplibre-style-spec/). You can also override specific color properties within a custom style.
90
-
91
- ```js
92
- mapLibre.setStyle('https://tiles.openfreemap.org/styles/liberty.json');
93
- ```
94
-
95
- ## Mapbox GL
96
-
97
- First, install the `mapbox-gl` library:
98
-
99
- ```
100
- npm install mapbox-gl
101
- ```
102
-
103
- Next, create a `MapboxProvider` instance which requires a `mapbox.Map` class, a `mapbox.Marker` class and a `mapbox.MapOptions` object. Use the `MapboxProvider` instance, along with the API key, to initialize the map manager.
104
-
105
- ```js
106
- import mapbox from 'mapbox-gl';
107
- import 'mapbox-gl/dist/mapbox-gl.css';
108
-
109
- import { MapManager } from '@arenarium/maps';
110
- import { MapboxProvider } from '@arenarium/maps/mapbox';
111
- import '@arenarium/maps/dist/style.css';
112
-
113
- // Create a mapbox provider instance
114
- const mapboxProvider = new MapboxProvider(mapbox.Map, mapbox.Marker, {
115
- container: 'map',
116
- ...
117
- });
118
-
119
- // Initialize the map manager with the provider
120
- const mapManager = new MapManager("YOUR_API_KEY", mapboxProvider);
121
-
122
- // Access the mapbox instance for direct map interactions
123
- const mapboxMap = mapboxProvider.getMap();
124
- ```
125
-
126
- ## Google Maps
127
-
128
- First, install the `@googlemaps/js-api-loader` library:
129
-
130
- ```
131
- npm install @googlemaps/js-api-loader
132
- ```
133
-
134
- To use Google Maps, you'll need to load the Google Maps JavaScript API and create a Google Maps provider instance. Next, create a `GoogleMapsProvider` instance which requires a `google.maps.Map` class, a `google.maps.Marker.AdvancedMarkerElement` class, and a `google.maps.MapOptions`. Use the `GoogleMapsProvider` instance, along with the API key, to initialize the map manager.
135
-
136
- ```js
137
- import { Loader } from '@googlemaps/js-api-loader';
138
-
139
- import { MapManager } from '@arenarium/maps';
140
- import { GoogleMapsProvider } from '@arenarium/maps/google';
141
- import '@arenarium/maps/dist/style.css';
142
-
143
- // Load Google Maps API
144
- const loader = new Loader({
145
- apiKey: 'YOUR_GOOGLE_MAPS_API_KEY',
146
- version: 'weekly'
147
- });
148
-
149
- // Import required libraries
150
- const mapsLibrary = await loader.importLibrary('maps');
151
- const markerLibrary = await loader.importLibrary('marker');
152
-
153
- // Create a Google Maps provider instance
154
- const mapElement = document.getElementById('map')!;
155
- const mapGoogleProvider = new GoogleMapsProvider(mapsLibrary.Map, markerLibrary.AdvancedMarkerElement, mapElement, {
156
- mapId: 'YOUR_GOOGLE_MAPS_MAP_ID', // For enabling advanced marker elements
157
- ...
158
- });
159
-
160
- // Initialize the map manager with the provider
161
- const mapManager = new MapManager("YOUR_API_KEY", mapGoogleProvider);
162
-
163
- // Access the Google Maps instance for direct map interactions
164
- const mapGoogle = mapGoogleProvider.getMap();
165
- ```
166
-
167
- You can change the map's visual appearance by using the predefined styles in combination with custom `StyledMapType`:
168
-
169
- ```js
170
- import { GoogleMapsDarkStyle, GoogleMapsLightStyle } from '@arenarium/maps/google';
171
-
172
- const mapTypeLight = new google.maps.StyledMapType(GoogleMapsLightStyle, { name: 'Light Map' });
173
- const mapTypeDark = new google.maps.StyledMapType(GoogleMapsDarkStyle, { name: 'Dark Map' });
174
-
175
- mapGoogle.mapTypes.set('light-id', mapTypeLight);
176
- mapGoogle.mapTypes.set('dark-id', mapTypeDark);
177
-
178
- mapGoogle.setMapTypeId('light-id'); // or "dark-id" for dark theme
179
- ```
180
-
181
- ## Markers
182
-
183
- A marker consist of a pin, a tooltip and an optional popup. The pin is an element that should convey the marker's location and and basic information like an icon or a color. The tooltip is an element that should provide additional information thats needs to be readable, it could be small or large amount of information depending on the application. The popup is an element that should be displayed when the user clicks on the marker. It should contain additional information thats not necessary or too large for a tooltip.
184
-
185
- The markers toogle between the pin and the tooltip elements as the user zoom in. The pin is displayed when there is no room for the tooltip. When the user zooms in and more space is available, more tooltips are displayed. Which tooltips are displayed first is determined by the ranking of the markers. The higher the rank, the sooner the tooltip is displayed.
186
-
187
- To add markers to the map, you first need to define an array of `MapMarker` objects. Provide the base marker data and the configuration for the tooltip, pin and popup. The configurations have body callbacks which should return a `HTMLElement`.
188
-
189
- Use the `updateMarkers` method on the map manager to display or update update the markers. This method adds new markers and updates existing ones based on their IDs. Markers not present in the provided array will remain on the map. This approach is designed for continuous updates of map markers.
190
-
191
- ```js
192
- import { type MapMarker } from '@arenarium/maps';
193
-
194
- const markers: MapMarker[] = [];
195
-
196
- for (let i = 0; i < count; i++) {
197
- markers.push({
198
- // A unique identifier for the marker
199
- id: ...,
200
- // The ranking of the marker, used for prioritization
201
- rank: ..,
202
- // The latitude of the marker's location
203
- lat: ...,
204
- // The longitude of the marker's location
205
- lng: ...,
206
- // The tooltip configuration of the marker (required)
207
- tooltip: {
208
- style: {
209
- // The desired height of the marker's tooltip area
210
- height: ...,
211
- // The desired width of the marker's tooltip area
212
- width: ...,
213
- // The desired margin of the marker's tooltip area
214
- margin: ...,
215
- // The desired radius of the marker's tooltip area
216
- radius: ...,
217
- },
218
- // Callback function that returns the HTMLElement object for the tooltip body
219
- body: async (id) => { ... }
220
- },
221
- // The pin configuration of the marker (optional)
222
- pin: {
223
- style: {
224
- // The desired height of the marker's pin area
225
- height: ...,
226
- // The desired width of the marker's pin area
227
- width: ...,
228
- // The desired radius of the marker's pin area
229
- radius: ...,
230
- },
231
- // Callback function that returns the HTMLElement object for the pin body
232
- body: async (id) => { ... }
233
- },
234
- // The popup configuration of the marker (optional)
235
- popup: {
236
- style: {
237
- // The desired height of the marker's popup area
238
- height: ...,
239
- // The desired width of the marker's popup area
240
- width: ...,
241
- // The desired margin of the marker's popup area
242
- margin: ...,
243
- // The desired radius of the marker's popup area
244
- radius: ...,
245
- },
246
- // Callback function that returns the HTMLElement object for the popup body
247
- body: async (id) => { ... }
248
- }
249
- });
250
- }
251
-
252
- await mapManager.updateMarkers(markers);
253
- ```
254
-
255
- To remove all markers from the map, use the `removeMarkers` method:
256
-
257
- ```js
258
- mapManager.removeMarkers();
259
- ```
260
-
261
- To toggle the popup of a marker, use the `showPopup` and `hidePopup` methods:
262
-
263
- ```js
264
- mapManager.showPopup(id);
265
- mapManager.hidePopup(id);
266
- ```
267
-
268
- ## Style
269
-
270
- You can change the markers style by using the predefined CSS variables:
271
-
272
- ```scss
273
- --arenarium-maps-pin-background: ...;
274
- --arenarium-maps-pin-border: ...;
275
- --arenarium-maps-pin-shadow: ...;
276
-
277
- --arenarium-maps-tooltip-background: ...;
278
- --arenarium-maps-tooltip-shadow: ...;
279
- --arenarium-maps-tooltip-shadow-hover: ...;
280
- ```
1
+ # About
281
2
 
282
- # API
3
+ Visualize complex map markers clearly. A JavaScript library for effective display of map markers, compatible with MapLibre, Mapbox, and Google Maps.
283
4
 
284
- You can provide a your own backend URL to the map manager to use the API for calculating the marker states. For more information about the API, please feel free to reach out.
5
+ # Docs
285
6
 
286
- ```js
287
- const mapManager = new MapManager(mapProvider, {
288
- api: {
289
- states: {
290
- url: 'YOUR_BACKEND_URL'
291
- }
292
- }
293
- });
294
- ```
7
+ https://arenarium.dev/docs
295
8
 
296
9
  # Examples
297
10
 
298
11
  [https://github.com/arenarium-dev/arenarium-maps-svelte-kit-example](https://github.com/arenarium-dev/arenarium-maps-svelte-kit-example)
299
12
 
300
- # About
301
-
302
- **@arenarium/maps** is a library designed for the efficient visualization of a large number of ranked points of interest on your maps. It excels in scenarios where you need to present numerous location-based markers with a clear visual hierarchy based on their importance or ranking. By leveraging optimized rendering techniques and a dedicated API for managing dynamic marker states, this library ensures a smooth and informative user experience.
303
-
304
- # Docs
305
-
306
- https://arenarium.dev/docs
13
+ [https://github.com/arenarium-dev/arenarium-maps-react-example](https://github.com/arenarium-dev/arenarium-maps-react-example)
307
14
 
308
15
  # License
309
16
 
package/dist/main.css ADDED
@@ -0,0 +1 @@
1
+ .pin.svelte-e30vfn4rttu1{position:absolute;box-sizing:border-box;transform-origin:0% 0%;backface-visibility:hidden;will-change:scale;border-style:solid;transform:translate(-50%,-50%)}.pin.svelte-e30vfn4rttu1{display:none;content-visibility:hidden}.pin.displayed.svelte-e30vfn4rttu1{display:initial;content-visibility:initial}.pin.svelte-e30vfn4rttu1{opacity:1}.pin.suppressed.svelte-e30vfn4rttu1{opacity:.5;box-shadow:none!important}.element.svelte-vkqe2rkto2oe{box-sizing:border-box}.anchor.svelte-vkqe2rkto2oe{display:block;position:absolute;width:0;height:0;transition:filter .125s ease-in-out}.anchor.svelte-vkqe2rkto2oe>.pointer:where(.svelte-vkqe2rkto2oe){position:absolute;transform-origin:0% 0%;border-radius:1px;top:0;left:0}.anchor.svelte-vkqe2rkto2oe>.tooltip:where(.svelte-vkqe2rkto2oe){position:absolute;top:0;left:0}.anchor.svelte-vkqe2rkto2oe>.tooltip:where(.svelte-vkqe2rkto2oe)>.body:where(.svelte-vkqe2rkto2oe){cursor:pointer}.anchor.svelte-vkqe2rkto2oe{opacity:0;will-change:opacity}.anchor.svelte-vkqe2rkto2oe>.pointer:where(.svelte-vkqe2rkto2oe){transform-origin:0% 0%;will-change:transform,scale;scale:0}.anchor.svelte-vkqe2rkto2oe>.tooltip:where(.svelte-vkqe2rkto2oe){transform-origin:0% 0%;will-change:transform,scale;scale:0}.anchor.svelte-vkqe2rkto2oe{display:none;content-visibility:hidden}.anchor.displayed.svelte-vkqe2rkto2oe{display:initial;content-visibility:initial}.body.svelte-vkqe2rkto2oe{backface-visibility:initial;transform-style:initial}.body.svelte-vkqe2rkto2oe:hover{backface-visibility:hidden;transform-style:preserve-3d}
package/dist/main.d.ts CHANGED
@@ -1,165 +1,3 @@
1
- import * as v from 'valibot';
2
-
3
- export declare const getAttributionHtml: () => string;
4
-
5
- export declare const getImageHtml: () => string;
6
-
7
- export declare type MapBounds = v.InferOutput<typeof mapBoundsSchema>;
8
-
9
- declare const mapBoundsSchema: v.ObjectSchema<{
10
- readonly sw: v.ObjectSchema<{
11
- readonly lat: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, -90, undefined>, v.MaxValueAction<number, 90, undefined>]>;
12
- readonly lng: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, -180, undefined>, v.MaxValueAction<number, 180, undefined>]>;
13
- }, undefined>;
14
- readonly ne: v.ObjectSchema<{
15
- readonly lat: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, -90, undefined>, v.MaxValueAction<number, 90, undefined>]>;
16
- readonly lng: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, -180, undefined>, v.MaxValueAction<number, 180, undefined>]>;
17
- }, undefined>;
18
- }, undefined>;
19
-
20
- export declare type MapConfiguration = v.InferOutput<typeof mapConfigurationSchema>;
21
-
22
- declare const mapConfigurationSchema: v.ObjectSchema<{
23
- readonly pin: v.OptionalSchema<v.ObjectSchema<{
24
- readonly fade: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
25
- readonly maxCount: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
26
- readonly maxZoom: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
27
- }, undefined>, undefined>;
28
- readonly animation: v.OptionalSchema<v.ObjectSchema<{
29
- readonly queue: v.OptionalSchema<v.ObjectSchema<{
30
- readonly limit: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
31
- }, undefined>, undefined>;
32
- }, undefined>, undefined>;
33
- }, undefined>;
34
-
35
- export declare class MapManager {
36
- private apiKey;
37
- private apiToken;
38
- private apiDevEnvironment;
39
- private mapProvider;
40
- private mapMarkerProcessor;
41
- private mapMarkerElementArray;
42
- private mapMarkerElementMap;
43
- private mapMarkerElementsUpdating;
44
- private constructor();
45
- static create(apiKey: string, mapProvider: MapProvider, mapConfiguration?: MapConfiguration): Promise<MapManager>;
46
- setConfiguration(configuration: MapConfiguration | undefined): void;
47
- updateMarkers(markers: MapMarker[]): Promise<void>;
48
- removeMarkers(): void;
49
- showPopup(id: string): void;
50
- hidePopup(id?: string): void;
51
- private updateMarkerElements;
52
- private removeMarkerElements;
53
- private getMarkerStates;
54
- private processMarkerElementsCallback;
55
- private processMarkerElements;
56
- private log;
57
- }
58
-
59
- export declare type MapMarker = v.InferOutput<typeof mapMarkerSchema>;
60
-
61
- declare const mapMarkerSchema: v.ObjectSchema<{
62
- readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
63
- readonly rank: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>]>;
64
- readonly lat: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, -90, undefined>, v.MaxValueAction<number, 90, undefined>]>;
65
- readonly lng: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, -180, undefined>, v.MaxValueAction<number, 180, undefined>]>;
66
- readonly tooltip: v.ObjectSchema<{
67
- readonly body: v.SchemaWithPipe<readonly [v.FunctionSchema<undefined>, v.ArgsAction<(...args: unknown[]) => unknown, v.TupleSchema<[v.StringSchema<undefined>], undefined>>, v.ReturnsActionAsync<(args_0: string) => unknown, v.SchemaWithPipeAsync<readonly [v.PromiseSchema<undefined>, v.AwaitActionAsync<Promise<unknown>>, v.CustomSchema<HTMLElement, v.ErrorMessage<v.CustomIssue> | undefined>]>>]>;
68
- readonly style: v.SchemaWithPipe<readonly [v.ObjectSchema<{
69
- readonly width: v.NumberSchema<undefined>;
70
- readonly height: v.NumberSchema<undefined>;
71
- readonly margin: v.NumberSchema<undefined>;
72
- readonly radius: v.NumberSchema<undefined>;
73
- }, undefined>, v.CheckAction<{
74
- width: number;
75
- height: number;
76
- margin: number;
77
- radius: number;
78
- }, "Minimum of width or height must be greater than or equal to 6 * margin">]>;
79
- readonly colors: v.OptionalSchema<v.ObjectSchema<{
80
- readonly background: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
81
- readonly shadow: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
82
- }, undefined>, undefined>;
83
- }, undefined>;
84
- readonly pin: v.OptionalSchema<v.ObjectSchema<{
85
- readonly body: v.SchemaWithPipe<readonly [v.FunctionSchema<undefined>, v.ArgsAction<(...args: unknown[]) => unknown, v.TupleSchema<[v.StringSchema<undefined>], undefined>>, v.ReturnsActionAsync<(args_0: string) => unknown, v.SchemaWithPipeAsync<readonly [v.PromiseSchema<undefined>, v.AwaitActionAsync<Promise<unknown>>, v.CustomSchema<HTMLElement, v.ErrorMessage<v.CustomIssue> | undefined>]>>]>;
86
- readonly style: v.OptionalSchema<v.ObjectSchema<{
87
- readonly width: v.NumberSchema<undefined>;
88
- readonly height: v.NumberSchema<undefined>;
89
- readonly radius: v.NumberSchema<undefined>;
90
- }, undefined>, undefined>;
91
- readonly colors: v.OptionalSchema<v.ObjectSchema<{
92
- readonly background: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
93
- readonly border: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
94
- readonly shadow: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
95
- }, undefined>, undefined>;
96
- }, undefined>, undefined>;
97
- readonly popup: v.OptionalSchema<v.ObjectSchema<{
98
- readonly body: v.SchemaWithPipe<readonly [v.FunctionSchema<undefined>, v.ArgsAction<(...args: unknown[]) => unknown, v.TupleSchema<[v.StringSchema<undefined>], undefined>>, v.ReturnsActionAsync<(args_0: string) => unknown, v.SchemaWithPipeAsync<readonly [v.PromiseSchema<undefined>, v.AwaitActionAsync<Promise<unknown>>, v.CustomSchema<HTMLElement, v.ErrorMessage<v.CustomIssue> | undefined>]>>]>;
99
- readonly style: v.SchemaWithPipe<readonly [v.ObjectSchema<{
100
- readonly width: v.NumberSchema<undefined>;
101
- readonly height: v.NumberSchema<undefined>;
102
- readonly margin: v.NumberSchema<undefined>;
103
- readonly radius: v.NumberSchema<undefined>;
104
- }, undefined>, v.CheckAction<{
105
- width: number;
106
- height: number;
107
- margin: number;
108
- radius: number;
109
- }, "Minimum of width or height must be greater than or equal to 6 * margin">]>;
110
- readonly colors: v.OptionalSchema<v.ObjectSchema<{
111
- readonly background: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
112
- readonly shadow: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
113
- }, undefined>, undefined>;
114
- }, undefined>, undefined>;
115
- }, undefined>;
116
-
117
- export declare type MapProvider = v.InferOutput<typeof mapProviderSchema>;
118
-
119
- export declare type MapProviderMarker = v.InferOutput<typeof mapProviderMarkerSchema>;
120
-
121
- declare const mapProviderMarkerSchema: v.ObjectSchema<{
122
- readonly inserted: v.SchemaWithPipe<readonly [v.FunctionSchema<undefined>, v.ArgsAction<(...args: unknown[]) => unknown, v.TupleSchema<[], undefined>>, v.ReturnsAction<() => unknown, v.BooleanSchema<undefined>>]>;
123
- readonly insert: v.SchemaWithPipe<readonly [v.FunctionSchema<undefined>, v.ArgsAction<(...args: unknown[]) => unknown, v.TupleSchema<[], undefined>>, v.ReturnsAction<() => unknown, v.VoidSchema<undefined>>]>;
124
- readonly remove: v.SchemaWithPipe<readonly [v.FunctionSchema<undefined>, v.ArgsAction<(...args: unknown[]) => unknown, v.TupleSchema<[], undefined>>, v.ReturnsAction<() => unknown, v.VoidSchema<undefined>>]>;
125
- readonly update: v.SchemaWithPipe<readonly [v.FunctionSchema<undefined>, v.ArgsAction<(...args: unknown[]) => unknown, v.TupleSchema<[v.NumberSchema<undefined>], undefined>>, v.ReturnsAction<(args_0: number) => unknown, v.VoidSchema<undefined>>]>;
126
- }, undefined>;
127
-
128
- export declare type MapProviderParameters = v.InferOutput<typeof mapProviderParametersSchema>;
129
-
130
- declare const mapProviderParametersSchema: v.ObjectSchema<{
131
- readonly mapSize: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>]>;
132
- readonly zoomMin: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>]>;
133
- readonly zoomMax: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>]>;
134
- readonly zoomScale: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>, v.MaxValueAction<number, 10, undefined>]>;
135
- }, undefined>;
136
-
137
- declare const mapProviderSchema: v.ObjectSchema<{
138
- readonly getParameters: v.SchemaWithPipe<readonly [v.FunctionSchema<undefined>, v.ArgsAction<(...args: unknown[]) => unknown, v.TupleSchema<[], undefined>>, v.ReturnsAction<() => unknown, v.ObjectSchema<{
139
- readonly mapSize: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>]>;
140
- readonly zoomMin: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>]>;
141
- readonly zoomMax: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>]>;
142
- readonly zoomScale: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>, v.MaxValueAction<number, 10, undefined>]>;
143
- }, undefined>>]>;
144
- readonly getContainer: v.SchemaWithPipe<readonly [v.FunctionSchema<undefined>, v.ArgsAction<(...args: unknown[]) => unknown, v.TupleSchema<[], undefined>>, v.ReturnsAction<() => unknown, v.CustomSchema<HTMLElement, v.ErrorMessage<v.CustomIssue> | undefined>>]>;
145
- readonly getZoom: v.SchemaWithPipe<readonly [v.FunctionSchema<undefined>, v.ArgsAction<(...args: unknown[]) => unknown, v.TupleSchema<[], undefined>>, v.ReturnsAction<() => unknown, v.NumberSchema<undefined>>]>;
146
- readonly getBounds: v.SchemaWithPipe<readonly [v.FunctionSchema<undefined>, v.ArgsAction<(...args: unknown[]) => unknown, v.TupleSchema<[], undefined>>, v.ReturnsAction<() => unknown, v.ObjectSchema<{
147
- readonly sw: v.ObjectSchema<{
148
- readonly lat: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, -90, undefined>, v.MaxValueAction<number, 90, undefined>]>;
149
- readonly lng: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, -180, undefined>, v.MaxValueAction<number, 180, undefined>]>;
150
- }, undefined>;
151
- readonly ne: v.ObjectSchema<{
152
- readonly lat: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, -90, undefined>, v.MaxValueAction<number, 90, undefined>]>;
153
- readonly lng: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, -180, undefined>, v.MaxValueAction<number, 180, undefined>]>;
154
- }, undefined>;
155
- }, undefined>>]>;
156
- readonly panBy: v.SchemaWithPipe<readonly [v.FunctionSchema<undefined>, v.ArgsAction<(...args: unknown[]) => unknown, v.TupleSchema<[v.NumberSchema<undefined>, v.NumberSchema<undefined>], undefined>>, v.ReturnsAction<(args_0: number, args_1: number) => unknown, v.VoidSchema<undefined>>]>;
157
- readonly createMarker: v.SchemaWithPipe<readonly [v.FunctionSchema<undefined>, v.ArgsAction<(...args: unknown[]) => unknown, v.TupleSchema<[v.CustomSchema<HTMLElement, v.ErrorMessage<v.CustomIssue> | undefined>, v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, -90, undefined>, v.MaxValueAction<number, 90, undefined>]>, v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, -180, undefined>, v.MaxValueAction<number, 180, undefined>]>, v.NumberSchema<undefined>], undefined>>, v.ReturnsAction<(args_0: HTMLElement, args_1: number, args_2: number, args_3: number) => unknown, v.ObjectSchema<{
158
- readonly inserted: v.SchemaWithPipe<readonly [v.FunctionSchema<undefined>, v.ArgsAction<(...args: unknown[]) => unknown, v.TupleSchema<[], undefined>>, v.ReturnsAction<() => unknown, v.BooleanSchema<undefined>>]>;
159
- readonly insert: v.SchemaWithPipe<readonly [v.FunctionSchema<undefined>, v.ArgsAction<(...args: unknown[]) => unknown, v.TupleSchema<[], undefined>>, v.ReturnsAction<() => unknown, v.VoidSchema<undefined>>]>;
160
- readonly remove: v.SchemaWithPipe<readonly [v.FunctionSchema<undefined>, v.ArgsAction<(...args: unknown[]) => unknown, v.TupleSchema<[], undefined>>, v.ReturnsAction<() => unknown, v.VoidSchema<undefined>>]>;
161
- readonly update: v.SchemaWithPipe<readonly [v.FunctionSchema<undefined>, v.ArgsAction<(...args: unknown[]) => unknown, v.TupleSchema<[v.NumberSchema<undefined>], undefined>>, v.ReturnsAction<(args_0: number) => unknown, v.VoidSchema<undefined>>]>;
162
- }, undefined>>]>;
163
- }, undefined>;
164
-
165
- export { }
1
+ import { MapManager } from "$lib/map/manager";
2
+ import { MapConfiguration, MapProvider, MapProviderParameters, MapProviderMarker, MapProviderEvent, MapMarkerData, MapCoordinates, MapBounds, MapViewport } from "@arenarium/maps-core/schemas";
3
+ export { MapViewport, MapProviderParameters, MapProviderMarker, MapProviderEvent, MapProvider, MapMarkerData, MapManager, MapCoordinates, MapConfiguration, MapBounds };
package/dist/main.js ADDED
@@ -0,0 +1 @@
1
+ async function s0(x){return new Promise((q)=>setTimeout(q,x))}async function r0(x,q){let J=0,Q=Math.max(1,q?.retry??1);while(J<Q)try{return await x()}catch(F){if(console.log(`[HTTP RETRY] ${J} of ${Q}`),console.log(F),J++,J==Q)throw F;if(q?.delay)await s0(q.delay[J-1]??0)}throw Error("Unreachable code")}async function H2(x,q){let J=await r0(async()=>await fetch(x,q));if(!J.ok)throw Error(J.statusText);return await J.json()}async function O2(x,q,J){let Q=await fetch(x,{method:"POST",body:JSON.stringify(q),headers:{"Content-Type":"application/json",...J?.headers},...J});if(!Q.ok)throw Error(Q.statusText);return await Q.json()}async function z2(x,q,J){let Q=await fetch(x,{method:"PUT",body:JSON.stringify(q),headers:{"Content-Type":"application/json",...J?.headers},...J});if(!Q.ok)throw Error(Q.statusText)}var L={delay:s0,retry:r0,get:H2,post:O2,put:z2};class d{endtime=0;lifespan;paused=!1;enqueued=!1;interval;timeout;callback;constructor(x,q,J){if((q??0)<0)throw Error("Lifespan must be greater than 0");if((J??0)<0)throw Error("Interval must be greater than 0");this.interval=J??(navigator?.hardwareConcurrency?100:200/navigator.hardwareConcurrency),this.lifespan=q??this.interval,this.callback=x}async run(){let x=performance.now();if(this.enqueued)this.endtime=x+this.lifespan,this.enqueued=!1;if(this.endtime<x){this.stop();return}if(this.paused==!1){if(await this.callback()&&!this.enqueued){this.stop();return}}this.timeout=window.setTimeout(this.run.bind(this),this.interval)}start(){if(this.enqueued=!0,!this.timeout)this.run()}stop(){if(this.timeout)window.clearTimeout(this.timeout);this.timeout=void 0}pause(){this.paused=!0}resume(){this.paused=!1}}class J0{data;state;constructor(x){this.data=x,this.state=void 0}get input(){return{id:this.data.id,rank:this.data.rank,lat:this.data.lat,lng:this.data.lng,width:this.data.tooltip.style.dimensions.width,height:this.data.tooltip.style.dimensions.height,margin:this.data.tooltip.style.dimensions.margin}}}class Q0{callback;timeout;id;constructor(x,q){if(q<=0)throw Error("Timeout must be greater than 0");this.callback=x,this.timeout=q}start(){if(this.id!=null)return;this.id=window.setInterval(this.callback,this.timeout)}stop(){if(this.id==null)return;window.clearInterval(this.id),this.id=void 0}}class G0{viewport=void 0;state="idle";provider;interval;onCancel;onError;onMove;onIdle;constructor(x,q,J,Q,F,G){this.provider=x,this.interval=new Q0(this.onInterval.bind(this),q),this.onCancel=J,this.onError=Q,this.onMove=F,this.onIdle=G}start(){this.interval.start()}stop(){this.interval.stop()}onInterval(){try{if(this.onCancel()){this.interval.stop();return}let x=this.provider.getViewport(),q=this.state,J=JSON.stringify(x)!==JSON.stringify(this.viewport)?"move":"idle";if(J=="move")this.onMove();if(J=="idle"&&q=="move")this.onIdle();this.state=J,this.viewport=x}catch(x){this.onError("Failed to process map state interval",x)}}}var i0=75,n0=150,R0=0.00025,p0=1e6,o0=2000000,k0=3000000,F0=10,g=16,h0=2,$=0.5,n="white",t0="darkgreen",K0="0px 2px 2px rgba(0, 0, 0, 0.5)";import W0 from"@arenarium/maps-core/mercator";class p{sw;ne;constructor(x,q,J,Q){if(J<x)throw Error(`Invalid bounds: ${x}, ${q}, ${J}, ${Q}`);if(Q<q)throw Error(`Invalid bounds: ${x}, ${q}, ${J}, ${Q}`);this.sw={lat:x,lng:q},this.ne={lat:J,lng:Q}}contains(x,q){if(x<this.sw.lat||this.ne.lat<x)return!1;if(q<this.sw.lng||this.ne.lng<q)return!1;return!0}intersects(x){if(x.ne.lat<this.sw.lat||this.ne.lat<x.sw.lat)return!1;if(x.ne.lng<this.sw.lng||this.ne.lng<x.sw.lng)return!1;return!0}}class b{blockL;blockR;sw;ne;constructor(x,q,J,Q){if(J<x)throw Error(`Invalid bounds: ${x}, ${q}, ${J}, ${Q}`);if(this.sw={lat:x,lng:q},this.ne={lat:J,lng:Q},q<Q)this.blockL=new p(x,q,J,Q),this.blockR=new p(0,0,0,0);else this.blockL=new p(x,-180,J,Q),this.blockR=new p(x,q,J,180)}static normalize(x){let{bounds:q,center:J}=x;if(Math.abs(q.ne.lng-J.lng)+Math.abs(q.sw.lng-J.lng)>360)q.sw.lng=-180,q.ne.lng=180;if(q.ne.lng-q.sw.lng>360){q.sw.lng=-180,q.ne.lng=180;return}if(q.sw.lng<-180)q.sw.lng+=360;if(q.sw.lng>180)q.sw.lng-=360;if(q.ne.lng<-180)q.ne.lng+=360;if(q.ne.lng>180)q.ne.lng-=360}static bounds(x){this.normalize(x);let q=x.bounds,J=q.sw,Q=q.ne;return new b(J.lat,J.lng,Q.lat,Q.lng)}static offset(x,q,J){this.normalize(x);let{bounds:Q,zoom:F}=x,G=q*Math.pow(2,F),j=W0.project(Q.sw.lat,Q.sw.lng,G),U=W0.project(Q.ne.lat,Q.ne.lng,G),V=Math.max(j.x-J.left,0),O=Math.min(j.y+J.bottom,G),B=Math.min(U.x+J.right,G),S=Math.max(U.y-J.top,0),N=W0.unproject(V,O,G),I=W0.unproject(B,S,G);return new b(N.lat,N.lng,I.lat,I.lng)}contains(x,q){return this.blockL.contains(x,q)||this.blockR.contains(x,q)}intersects(x){return this.blockL.intersects(x)||this.blockR.intersects(x)}}class Y0{id;bounds;markers;constructor(x,q){this.id=x,this.bounds=q,this.markers=[]}belongs(x){let q=this.bounds.sw;if(x.lat<q.lat)return!1;if(x.lng<q.lng)return!1;let J=this.bounds.ne;if(J.lat<x.lat)return!1;if(J.lng<x.lng)return!1;return!0}neighbours(x,q){let J=Math.abs(x.id.length-this.id.length);if(J>q)return!1;let Q=Math.min(this.id.length,x.id.length)-q+J;for(let F=0;F<Q;F++)if(this.id[F]!=x.id[F])return!1;return!0}}class Z0{tree;zoom;cell;branches;constructor(x,q,J,Q){this.tree=x,this.zoom=J,this.cell=new Y0(q,Q),this.branches=[]}split(){let x=this.cell.bounds,q=Math.pow(2,this.tree.depth),J=(x.ne.lat-x.sw.lat)/q,Q=(x.ne.lng-x.sw.lng)/q;for(let F=0;F<q;F++)for(let G=0;G<q;G++){let j=x.sw.lat+F*J,U=x.sw.lng+G*Q,V=j+J,O=U+Q;this.branches.push(new Z0(this.tree,`${this.cell.id}${F*2+G}`,this.zoom+this.tree.depth,{sw:{lat:j,lng:U},ne:{lat:V,lng:O}}))}}add(x){if(this.cell.belongs(x.data)==!1)return!1;if(this.cell.markers.length<this.tree.capacity)return this.cell.markers.push(x),!0;if(this.branches.length==0)this.split();for(let q=0;q<this.branches.length;q++)if(this.branches[q].add(x))return!0;throw Error("Failed to add marker to branch")}compact(){if(this.branches.length==0)return;for(let Q=0;Q<this.branches.length;Q++)this.branches[Q].compact();let x=[],q=[];for(let Q=0;Q<this.branches.length;Q++){let F=this.branches[Q];x.push(...F.branches),q.push(...F.cell.markers)}let J=new Z0(this.tree,this.cell.id,this.zoom+this.tree.depth,this.cell.bounds);J.branches=x,J.cell.markers=q,this.branches=[J]}cells(x,q,J){if(x<this.zoom)return J;if(q.intersects(this.cell.bounds)==!1)return J;J.push(this.cell);for(let Q=0;Q<this.branches.length;Q++)this.branches[Q].cells(x,q,J);return J}print(x){console.log(`${"---".repeat(x)}|${this.cell.id} zoom=[${this.zoom}] markers=[${this.cell.markers.length}]`);for(let q=0;q<this.branches.length;q++)this.branches[q].print(x+1)}count(){return this.cell.markers.length+this.branches.reduce((x,q)=>x+q.count(),0)}}class o{capacity;depth;root;constructor(x,q,J){this.capacity=J,this.depth=q,this.root=new Z0(this,"R",x,{sw:{lat:-90,lng:-180},ne:{lat:90,lng:180}})}add(x){return this.root.add(x)}compact(){this.root.compact()}cells(x,q){let J=[];return this.root.cells(x,q,J),J}print(){this.root.print(0)}}var a0=2,e0=1,x2=g*4,q2=1024;class j0{mapProvider;mapMarkersVisibilityTree;mapMarkersVisible;mapMarkerTreeCellCapacity=a0;mapMarkerTreeCellZoomDelta=e0;mapMarkerTreeCellSize=x2;mapMarkerTreeLimit=q2;constructor(x){this.mapProvider=x}set configuration(x){this.mapMarkerTreeCellCapacity=x?.process?.visibility?.cell?.capacity??a0,this.mapMarkerTreeCellZoomDelta=x?.process?.visibility?.cell?.depth??e0,this.mapMarkerTreeCellSize=x?.process?.visibility?.cell?.size??x2,this.mapMarkerTreeLimit=x?.process?.visibility?.limit??q2}get markers(){return Array.from(this.mapMarkersVisible??[])}insertMarkers(x){this.mapMarkersVisibilityTree=this.createVisibilityTree(x)}clearMarkers(){this.mapMarkersVisibilityTree=void 0,this.mapMarkersVisible=void 0}updateVisibleMarkers(x,q){if(this.mapMarkersVisibilityTree==null)return;let J=b.bounds(x),Q=[],F=x.zoom;while(F<q.zoomMax&&Q.length<this.mapMarkerTreeLimit)Q=this.mapMarkersVisibilityTree.cells(F,J).flatMap((G)=>G.markers),F++;this.mapMarkersVisible=Q}createVisibilityTree(x){if(x.length<this.mapMarkerTreeLimit){let q=new o(0,0,x.length);for(let J=0;J<x.length;J++){let Q=x[J];if(!q.add(Q))throw Error("Failed to add marker to fill tree")}return q}else{let q=-Math.floor(Math.log2(this.mapProvider.getParameters().mapSize/this.mapMarkerTreeCellSize)),J=new o(q,this.mapMarkerTreeCellZoomDelta,this.mapMarkerTreeCellCapacity);for(let F=0;F<x.length;F++){let G=x[F];if(!J.add(G))throw Error("Failed to add marker to fill tree")}let Q=-q;for(let F=0;F<Q;F++)J.compact();return J}}}import{mount as I2}from"svelte";import"svelte/internal/disclose-version";import*as K from"svelte/internal/client";import{sineInOut as B2}from"svelte/easing";class m{animationEasing;animationRun;animating;value;time;constructor(x){if(x.max<=x.min)throw Error("Min must be less than max");if(x.value<x.min||x.max<x.value)throw Error("Value must be between min and max");this.animationEasing=x.easing,this.animationRun=x.callback,this.animating=!1,this.value={current:x.value,start:x.value,end:x.value,min:x.min,max:x.max},this.time={start:0,end:0,span:x.timespan}}animationFrame(){let x=performance.now();if(x>this.time.end)this.value.current=this.value.end;else{let q=(x-this.time.start)/(this.time.end-this.time.start),J=this.animationEasing(q);this.value.current=this.value.start+(this.value.end-this.value.start)*J}if(this.animationRun(this.value.current),this.value.current===this.value.end){this.animating=!1;return}window.requestAnimationFrame(this.animationFrame.bind(this))}target(x){if(x===this.value.end)return;this.value.start=this.value.current,this.value.end=x;let q=performance.now(),J=Math.abs(this.value.start-this.value.end),Q=this.value.max-this.value.min;if(this.time.start=q,this.time.end=q+this.time.span*Math.sqrt(J/Q),this.animating)return;this.animating=!0,window.requestAnimationFrame(this.animationFrame.bind(this))}set(x){if(x===this.value.end)return;this.value.current=x,this.value.start=x,this.value.end=x;let q=performance.now();this.time.start=q,this.time.end=q,window.requestAnimationFrame(this.animationRun.bind(this,x))}end(){this.set(this.value.end)}expired(){return performance.now()>this.time.end}}var N2=K.from_html("<div></div>");function S0(x,q){K.push(q,!0);let J=K.rest_props(q,["$$slots","$$events","$$legacy"]),Q=q.id,F=q.style,G=q.content,j={setDisplayed:l,getDisplayed:A,setSuppressed:P,setCollapsed:z,getCollapsed:y,setScale:r};function U(){return j}let V,O=F.dimensions.width,B=F.dimensions.height,S=F.dimensions.radius,N=F.dimensions.padding??h0,I=F.colors?.border??n,D=F.colors?.background??t0,X=F.colors?.shadow??K0,Z=K.state(!1),M=!1,v=!1;function l(Y){if(Y==K.get(Z))return;if(K.set(Z,Y,!0),Y==!0){if(G==null)return;if(v)return;if(M)return;M=!0,G(Q).then((w)=>{if(w instanceof HTMLElement)V.appendChild(w);else console.error("Failed to load pin content")}).catch((w)=>console.error(w)).finally(()=>{v=!0,M=!1})}if(Y==!1)_.end()}function A(){return K.get(Z)}let C=K.state(!0);function P(Y){if(Y==K.get(C))return;if(K.set(C,Y,!0),Y)s=$,_.set($)}let H=K.state(!0);function z(Y){if(Y==K.get(H))return;K.set(H,Y,!0),_.target(K.get(H)?0:s)}function y(){if(!K.get(Z))return!0;return _.expired()}let s=$,_=new m({value:$,min:0,max:1,timespan:i0,easing:B2,callback:y0});function r(Y){s=Y,_.target(Y)}function y0(Y){V.style.scale=Y.toString(),V.style.filter=`brightness(${e(Y)})`}function e(Y){return 0.25+0.75*Y}var b0={invoke:U},T=N2();let x0;return K.bind_this(T,(Y)=>V=Y,()=>V),K.template_effect((Y)=>{K.set_class(T,1,K.clsx(["pin",K.get(Z)&&"displayed",K.get(C)&&"suppressed"]),"svelte-e30vfn4rttu1"),x0=K.set_style(T,"",x0,Y)},[()=>({width:`${O}px`,height:`${B}px`,"border-radius":`${S}px`,"border-color":I,"background-color":D,"border-width":`${N}px`,"box-shadow":X,scale:$,filter:`brightness(${e($)})`})]),K.append(x,T),K.pop(b0)}class E{div;marker;constructor(x,q,J,Q){this.div=document.createElement("div"),this.marker=x.createMarker(this.div,q,J,Q)}insert(){if(this.marker.inserted()==!0)return;this.marker.insert()}remove(){if(this.marker.inserted()==!1)return;this.marker.remove()}update(x){this.marker.update(x)}}class k{shown;id;lat;lng;rank;marker;constructor(x,q){if(new.target===k)throw Error("Cannot instantiate an abstract class directly.");this.shown=!0,this.id=x.id,this.lat=x.lat,this.lng=x.lng,this.rank=x.rank,this.marker=q}}class V0 extends k{width;height;zoom;component;constructor(x,q){super(x,new E(q,x.lat,x.lng,x.rank));let J=x.pin?.style.dimensions.width??g,Q=x.pin?.style.dimensions.height??g,F=x.pin?.style.dimensions.padding??h0,G=x.pin?.style.dimensions.radius??g/2;this.width=J,this.height=Q,this.zoom=NaN,this.component=I2(S0,{target:this.marker.div,props:{id:this.id,style:{dimensions:{width:J,height:Q,padding:F,radius:G},colors:x.pin?.style.colors},content:x.pin?.body}})}get zIndex(){if(Number.isNaN(this.zoom))return this.rank;return Math.round(-this.zoom*F0)+p0}}import{mount as D2}from"svelte";import"svelte/internal/disclose-version";import*as h from"svelte/internal/client";import{sineInOut as y2}from"svelte/easing";class t{animating;animationTimestamp;animationEnd;animationCallback;speed;value;constructor(x){this.animating=!1,this.animationTimestamp=0,this.animationEnd=0,this.animationCallback=x.callback,this.speed={current:0,spring:{stiffness:x.stiffness,damping:2*Math.sqrt(x.stiffness)}},this.value={current:x.value,target:x.value,precision:x.precision,min:x.min,max:x.max}}animationFrame(){try{let x=performance.now(),q=x-this.animationTimestamp;if(this.animationTimestamp=x,x>=this.animationEnd){this.speed.current=0,this.value.current=this.value.target;return}let J=this.value.target-this.value.current;if(Math.abs(J)<this.value.precision){this.speed.current=0,this.value.current=this.value.target;return}let Q=J*this.speed.spring.stiffness-this.speed.spring.damping*this.speed.current;if(this.speed.current+=Q*q,this.value.current+=this.speed.current*q,this.value.current<this.value.min){this.value.current=this.value.target,this.speed.current=0;return}if(this.value.current>this.value.max){this.value.current=this.value.target,this.speed.current=0;return}}finally{if(this.animationCallback(this.value.current),this.value.current===this.value.target){this.animating=!1;return}window.requestAnimationFrame(this.animationFrame.bind(this))}}target(x){if(x===this.value.target)return;let q=Math.sqrt(2*Math.abs(x-this.value.current)/this.speed.spring.stiffness);if(this.animationEnd=performance.now()+q,this.value.target=x,this.animating)return;this.animating=!0,this.animationTimestamp=performance.now(),window.requestAnimationFrame(this.animationFrame.bind(this))}set(x){if(x===this.value.target)return;this.animationEnd=performance.now(),this.value.current=x,this.value.target=x,this.speed.current=0,window.requestAnimationFrame(this.animationCallback.bind(this,x))}end(){this.set(this.value.target)}expired(){return performance.now()>this.animationEnd}}import J2 from"@arenarium/maps-core/rectangle";var b2=h.from_html('<div><div class="element pointer svelte-vkqe2rkto2oe"></div> <div class="element tooltip svelte-vkqe2rkto2oe"><div class="element body svelte-vkqe2rkto2oe"></div></div></div>');function a(x,q){h.push(q,!0);let J=h.rest_props(q,["$$slots","$$events","$$legacy"]),Q=q.id,F=q.style,G=q.content,j={setDisplayed:s,getDisplayed:_,setCollapsed:y0,getCollapsed:e,getExpanded:b0,setAngle:h2};function U(){return j}let V,O=F.colors?.shadow??K0,B,S=Math.min(F.dimensions.width,F.dimensions.height)/Math.SQRT2,N=Math.min(F.dimensions.width,F.dimensions.height)/Math.SQRT2,I=F.colors?.background??n,D,X=F.dimensions.width+2*F.dimensions.margin,Z=F.dimensions.height+2*F.dimensions.margin,M=F.dimensions.margin,v,l=F.dimensions.width,A=F.dimensions.height,C=F.dimensions.radius,P=F.colors?.background??n,H=h.state(!1),z=!1,y=!1;function s(W){if(W==h.get(H))return;if(h.set(H,W,!0),W){if(G==null)return;if(y)return;if(z)return;z=!0,G(Q).then((f)=>{if(f instanceof HTMLElement)v.appendChild(f);else console.error("Failed to load tooltip content")}).catch((f)=>console.error(f)).finally(()=>{y=!0,z=!1})}if(W==!1)T.end(),D0.end(),v0.end()}function _(){return h.get(H)}let r=h.state(!0);function y0(W){if(W==h.get(r))return;h.set(r,W,!0),T.target(h.get(r)?0:1)}function e(){if(!h.get(H))return!0;return T.expired()}function b0(){if(!h.get(H))return!1;return T.expired()}let T=new m({value:0,min:0,max:1,timespan:n0,easing:y2,callback:x0});function x0(W){V.style.opacity=`${W}`,D.style.scale=`${W}`,B.style.scale=`${W}`}let Y=NaN,w=h.state(!1),_0=-X/2,D0=new t({value:-X/2,min:-X,max:0,precision:1,stiffness:R0,callback:K2}),$0=-Z/2,v0=new t({value:-Z/2,min:-Z,max:0,precision:1,stiffness:R0,callback:W2});function h2(W,f){if(Number.isNaN(W)){Y=NaN,h.set(w,!1);return}if(h.get(w)==!1||f==!0){h.set(w,!0),Y=W;let R=J2.getOffsets(X,Z,W);D0.set(Math.round(R.x)),v0.set(Math.round(R.y));return}if(Y!=W){Y=W;let R=J2.getOffsets(X,Z,W);D0.target(Math.round(R.x)),v0.target(Math.round(R.y));return}}function K2(W){_0=W,E0()}function W2(W){$0=W,E0()}function E0(){let W=_0,f=$0,R=W+X/2,m0=f+Z/2,T0=Z<X?R*Z/X:R,f0=Z>X?m0*X/Z:m0,Z2=Math.atan2(f0,T0),u2=0,L2=30,w0=Math.sqrt(T0*T0+f0*f0),i=Math.min(X,Z)/2,j2=i*Math.SQRT2,V2=(w0-i)/(j2-i),X2=Z2/Math.PI*180-45,l0=0+V2*30,U2=w0<i?w0/i:1;D.style.transform=`translate(${Math.round(W)}px, ${Math.round(f)}px)`,B.style.transform=`scale(${U2}) rotate(${X2}deg) skew(${l0}deg, ${l0}deg)`}var Y2={invoke:U},u=b2();let c0;var C0=h.child(u);let u0;h.bind_this(C0,(W)=>B=W,()=>B);var q0=h.sibling(C0,2);let L0;var d0=h.child(q0);let g0;return h.bind_this(d0,(W)=>v=W,()=>v),h.reset(q0),h.bind_this(q0,(W)=>D=W,()=>D),h.reset(u),h.bind_this(u,(W)=>V=W,()=>V),h.template_effect(()=>{h.set_class(u,1,h.clsx(["element anchor",h.get(H)&&"displayed"]),"svelte-vkqe2rkto2oe"),c0=h.set_style(u,"",c0,{filter:`drop-shadow(${O})`}),u0=h.set_style(C0,"",u0,{width:`${S}px`,height:`${N}px`,"background-color":I}),L0=h.set_style(q0,"",L0,{width:`${X}px`,height:`${Z}px`,padding:`${M}px;`}),g0=h.set_style(d0,"",g0,{width:`${l}px`,height:`${A}px`,"border-radius":`${C}px;`,"background-color":P})}),h.append(x,u),h.pop(Y2)}class X0 extends k{width;height;zoom;angle;states;component;constructor(x,q){super(x,new E(q,x.lat,x.lng,x.rank));this.width=x.tooltip.style.dimensions.width+x.tooltip.style.dimensions.margin*2,this.height=x.tooltip.style.dimensions.height+x.tooltip.style.dimensions.margin*2,this.zoom=NaN,this.angle=NaN,this.states=[],this.component=D2(a,{target:this.marker.div,props:{id:this.id,style:x.tooltip.style,content:x.tooltip.body}})}get zIndex(){if(Number.isNaN(this.zoom))return this.rank;return Math.round(-this.zoom*F0)+o0}}import{mount as v2}from"svelte";class U0 extends k{width;height;margin;angle;component;constructor(x,q){if(x.popup==null)throw Error("Failed to create popup");super(x,new E(q,x.lat,x.lng,k0));this.width=x.popup.style.dimensions.width,this.height=x.popup.style.dimensions.height,this.margin=x.popup.style.dimensions.margin,this.angle=NaN,this.shown=!1,this.component=v2(a,{target:this.marker.div,props:{id:this.id,style:x.popup.style,content:x.popup.body}})}get zIndex(){return k0}}class H0{id;state=void 0;pin;tooltip;popup;constructor(x,q){if(this.id=x.id,this.pin=new V0(x,q),this.tooltip=new X0(x,q),x.popup!=null)this.popup=new U0(x,q)}}var M0=4;class O0{pins=new Set;pinMaxWidth=0;pinMaxHeight=0;pinFade=!1;pinZoomMax=M0;pinZoomDelta=M0;set configuration(x){this.pinFade=x?.pin?.fade??!0,this.pinZoomMax=x?.pin?.maxZoom??M0,this.pinZoomDelta=this.pinZoomMax}insert(x,q){this.update(x,q),this.pins.add(x)}update(x,q){x.zoom=q?q[0]:NaN,x.marker.update(x.zIndex)}remove(x){x.shown=!0,x.zoom=NaN,x.component.invoke().setCollapsed(!1),x.component.invoke().setSuppressed(!0),x.component.invoke().setDisplayed(!1),x.marker.update(x.zIndex),x.marker.remove(),this.pins.delete(x)}clear(){this.pins.forEach((x)=>x.marker.remove()),this.pins.clear()}refresh(){let x=Array.from(this.pins);this.pinMaxWidth=x.reduce((q,J)=>Math.max(q,J.width),0),this.pinMaxHeight=x.reduce((q,J)=>Math.max(q,J.height),0),this.pinZoomDelta=Math.max(1,this.pinZoomMax-Math.log10(x.length))}render(x,q){let J=x.zoom,Q=q.mapSize,F=b.offset(x,Q,{top:this.pinMaxHeight,bottom:this.pinMaxHeight,right:this.pinMaxWidth,left:this.pinMaxWidth});for(let G of this.pins)if(F.contains(G.lat,G.lng)){if(Number.isNaN(G.zoom))G.component.invoke().setDisplayed(!0),G.component.invoke().setSuppressed(!0),G.component.invoke().setCollapsed(!1),G.marker.insert();else if(G.component.invoke().setSuppressed(!1),G.shown&&J<G.zoom&&G.zoom<J+this.pinZoomDelta)G.component.invoke().setDisplayed(!0),G.component.invoke().setCollapsed(!1),G.component.invoke().setScale(this.pinFade?Math.max(0,1-(G.zoom-J)*0.2):1),G.marker.insert();else if(G.component.invoke().setCollapsed(!0),G.component.invoke().getCollapsed())G.component.invoke().setDisplayed(!1),G.marker.remove()}else G.component.invoke().setDisplayed(!1),G.marker.remove()}}import C2 from"@arenarium/maps-core/angles";class z0{tooltips=new Set;tooltipMaxWidth=0;tooltipMaxHeight=0;insert(x,q){this.update(x,q),this.tooltips.add(x)}update(x,q){if(q)x.zoom=q[0],x.states=q[1].map((J)=>[J[0],C2.DEGREES[J[1]]]);else x.zoom=NaN,x.states=[];x.marker.update(x.zIndex)}remove(x){x.shown=!0,x.zoom=NaN,x.angle=NaN,x.states=[],x.component.invoke().setAngle(NaN),x.component.invoke().setCollapsed(!0),x.component.invoke().setDisplayed(!1),x.marker.update(x.zIndex),x.marker.remove(),this.tooltips.delete(x)}clear(){this.tooltips.forEach((x)=>x.marker.remove()),this.tooltips.clear()}refresh(){let x=Array.from(this.tooltips);this.tooltipMaxWidth=x.reduce((q,J)=>Math.max(q,J.width),0),this.tooltipMaxHeight=x.reduce((q,J)=>Math.max(q,J.height),0)}render(x,q){let J=x.zoom,Q=q.mapSize,F=b.offset(x,Q,{top:this.tooltipMaxHeight,bottom:this.tooltipMaxHeight,right:this.tooltipMaxWidth,left:this.tooltipMaxWidth});for(let G of this.tooltips)if(F.contains(G.lat,G.lng)){if(Number.isNaN(G.zoom)==!1&&G.shown&&G.zoom<=J){let j=G.states.findLast((U)=>U[0]<=J)?.[1];if(j==null)throw Error("Angle not found");G.angle=j,G.component.invoke().setDisplayed(!0),G.component.invoke().setCollapsed(!1),G.component.invoke().setAngle(j),G.marker.insert()}else if(G.component.invoke().setCollapsed(!0),G.component.invoke().getCollapsed())G.component.invoke().setDisplayed(!1),G.marker.remove()}else G.component.invoke().setDisplayed(!1),G.marker.remove()}}import A0 from"@arenarium/maps-core/mercator";import T2 from"@arenarium/maps-core/rectangle";class B0{popups=new Set;pan=!0;set configuration(x){this.pan=x?.popup?.pan??!0}insert(x){this.popups.add(x)}remove(x){x.angle=NaN,x.shown=!1,x.marker.remove(),x.component.invoke().setAngle(NaN),x.component.invoke().setCollapsed(!0),x.component.invoke().setDisplayed(!1),this.popups.delete(x)}clear(){this.popups.forEach((x)=>x.marker.remove()),this.popups.clear()}show(x,q){if(!x.popup||!x.tooltip||!x.pin)return;if(x.pin.shown=!1,x.tooltip.shown=!1,x.popup.angle=x.tooltip.angle,x.popup.shown=!0,this.pan==!1)return;let J=x.popup,Q=q.getViewport(),F=Q.bounds,G=Q.zoom,U=q.getParameters().mapSize*Math.pow(2,G),V=A0.project(F.ne.lat,F.sw.lng,U),O=A0.project(F.sw.lat,F.ne.lng,U),B=O.x-V.x,S=O.y-V.y,N=J.width+J.margin*8,I=J.height+J.margin*8,D=A0.project(J.lat,J.lng,U),X=T2.getOffsets(N,I,x.tooltip.angle),Z=D.x+X.x,M=Z+N,v=D.y+X.y,l=v+I,A=Z-V.x,C=O.x-M,P=v-V.y,H=O.y-l,z=0;if(B<N)z=(A-C)/2;else{if(A<0)z=A;if(C<0)z=-C}let y=0;if(S<I)y=(P-H)/2;else{if(P<0)y=P;if(H<0)y=-H}if(z!=0||y!=0)q.panBy(z,y)}hide(x){if(!x.popup||!x.tooltip||!x.pin)return;x.pin.shown=!0,x.tooltip.shown=!0,x.popup.shown=!1}render(){for(let x of this.popups)if(x.shown)x.component.invoke().setDisplayed(!0),x.component.invoke().setCollapsed(!1),x.component.invoke().setAngle(x.angle,!0),x.marker.insert();else if(x.component.invoke().setCollapsed(!0),x.component.invoke().getCollapsed())x.component.invoke().setDisplayed(!1),x.marker.remove()}}class N0{mapProvider;mapPinManager;mapTooltipManager;mapPopupManager;mapElements;constructor(x){this.mapProvider=x,this.mapPinManager=new O0,this.mapTooltipManager=new z0,this.mapPopupManager=new B0,this.mapElements=new Map}set configuration(x){this.mapPinManager.configuration=x,this.mapPopupManager.configuration=x}clearElements(){this.mapElements.clear(),this.mapPinManager.clear(),this.mapTooltipManager.clear(),this.mapPopupManager.clear()}removeElements(x){for(let q of x){let J=this.mapElements.get(q.data.id);if(J==null)continue;if(this.mapPinManager.remove(J.pin),this.mapTooltipManager.remove(J.tooltip),J.popup!=null)this.mapPopupManager.remove(J.popup)}this.mapPinManager.refresh(),this.mapTooltipManager.refresh()}updateElements(x){for(let q of x){let J=this.mapElements.get(q.data.id);if(J==null)continue;this.mapPinManager.update(J.pin,q.state),this.mapTooltipManager.update(J.tooltip,q.state)}}insertElements(x,q){for(let J of x){let Q=this.mapElements.get(J.data.id);if(Q==null)Q=new H0(J.data,this.mapProvider),Q.tooltip.marker.div.addEventListener("click",(F)=>q(F,J.data.id)),this.mapElements.set(J.data.id,Q);if(this.mapPinManager.insert(Q.pin,J.state),this.mapTooltipManager.insert(Q.tooltip,J.state),Q.popup!=null)this.mapPopupManager.insert(Q.popup)}this.mapPinManager.refresh(),this.mapTooltipManager.refresh()}renderElements(x,q){this.mapPopupManager.render(),this.mapTooltipManager.render(x,q),this.mapPinManager.render(x,q)}showPopup(x){let q=this.mapElements.values();for(let J of q)if(J.id==x)this.mapPopupManager.show(J,this.mapProvider);else this.mapPopupManager.hide(J)}hidePopup(x){let q=this.mapElements.get(x);if(q==null)return;this.mapPopupManager.hide(q)}hidePopups(){let x=this.mapElements.values();for(let q of x)this.mapPopupManager.hide(q)}}import f2 from"@arenarium/maps-core/hash";import Q2 from"@arenarium/maps-core/angles";var w2="https://maps.api.arenarium.dev/states",R2=3,k2=[500,1000,2000];class I0{apiKey;apiToken;apiDevEnvironment;mapMarkerStatesStore;constructor(x,q){this.apiKey=x,this.apiToken=q,this.apiDevEnvironment=window?.location.host.startsWith("localhost")||window?.location.host.startsWith("127.0.0.1"),this.mapMarkerStatesStore=new Map}clearStates(){this.mapMarkerStatesStore.clear()}resetStates(x){for(let q=0;q<x.length;q++){let J=x[q];J.state=void 0}}async updateStates(x,q){if(x.length==0)return;x.sort((G,j)=>G.data.id.localeCompare(j.data.id));let J=x.map((G)=>G.input),Q=await f2.object(J),F=this.mapMarkerStatesStore.get(Q);if(F==null)F=await this.fetchStates(J,q),this.mapMarkerStatesStore.set(Q,F);for(let G=0;G<x.length;G++){let j=x[G];j.state=F[G]}}async fetchStates(x,q){if(x.length==0)return[];if(x.length==1)return[[0,[[0,Q2.DEGREES.indexOf(Q2.DEGREES_DEFAULT)]]]];let J={key:this.apiKey,token:this.apiToken,input:x,parameters:q},Q=await L.retry(async()=>await L.post(w2,J,{headers:{"Cache-Control":this.apiDevEnvironment?"no-cache":""},retry:R2,delay:k2}));if(Q.token)this.apiToken=Q.token;return Q.states}}import{apiKeySchema as S2,apiTokenSchema as M2,mapMarkerDataSchema as A2,mapProviderSchema as P2}from"@arenarium/maps-core/schemas";import*as c from"valibot";var G2="1.2.4",_2="https://maps.api.arenarium.dev/auth",$2="https://maps.api.arenarium.dev/log",E2=100,F2=500,c2=500;class P0{apiKey;mapProvider;mapMarkers;mapMarkersVisibilityManager;mapMarkerElementsManager;mapMarkerStatesManager;mapMarkerRenderProcessor;mapMarkerVisibilityProcessor;mapMarkerStateProcessor;mapMarkerStatesProcessDelay=500;mapMarkerStatesProcessTimeout=void 0;mapStateManager;constructor(x,q,J,Q){c.parse(S2,x),c.parse(M2,q),c.parse(P2,J),this.apiKey=x,this.mapProvider=J,this.mapProvider.getContainer().addEventListener("click",this.onMapClick.bind(this)),this.mapMarkers=new Map,this.mapMarkersVisibilityManager=new j0(this.mapProvider),this.mapMarkerElementsManager=new N0(this.mapProvider),this.mapMarkerStatesManager=new I0(x,q),this.mapMarkerRenderProcessor=new d(this.onMapMarkerRenderProcess.bind(this),F2),this.mapMarkerVisibilityProcessor=new d(this.onMapMarkerVisiblityProcess.bind(this),F2),this.mapMarkerStateProcessor=new d(this.onMapMarkerStateProcess.bind(this)),this.mapStateManager=new G0(this.mapProvider,E2/(navigator?.hardwareConcurrency??1),this.dettached.bind(this),this.error.bind(this),this.onMapMove.bind(this),this.onMapIdle.bind(this)),this.configuration=Q}static async create(x,q,J){let Q={key:x,version:G2},G=(await L.post(_2,Q)).token;if(!G)throw Error("Failed to get api token");return new P0(x,G,q,J)}set configuration(x){this.mapMarkerStatesProcessDelay=x?.process?.states?.delay??c2,this.mapMarkersVisibilityManager.configuration=x,this.mapMarkerElementsManager.configuration=x}clear(){this.mapMarkers.clear(),this.mapMarkersVisibilityManager.clearMarkers(),this.mapMarkerStatesManager.clearStates(),this.mapMarkerElementsManager.clearElements(),this.mapStateManager.stop(),this.mapMarkerVisibilityProcessor.stop(),this.mapMarkerStateProcessor.stop(),this.mapMarkerRenderProcessor.stop()}dettached(){return this.mapProvider.getContainer().parentElement==null}error(x,q){this.log("error",x,q),this.configuration?.events?.error?.(x,q)}async log(x,q,J){switch(x){case"info":console.info(J);break;case"warning":console.warn(J);break;case"error":console.error(J);break}if(J instanceof Error==!1)return;try{let Q={key:this.apiKey,title:q,level:x,content:{version:G2,...J}};await L.put($2,Q)}catch(Q){console.error(Q)}}onMapClick(){this.hidePopup()}onMapMarkerClick(x,q){x.stopPropagation(),this.showPopup(q)}onMapMove(){this.mapMarkerVisibilityProcessor.start()}onMapIdle(){if(this.mapMarkerStatesProcessTimeout)window.clearTimeout(this.mapMarkerStatesProcessTimeout);this.mapMarkerStatesProcessTimeout=window.setTimeout(()=>{this.mapMarkerStateProcessor.start()},this.mapMarkerStatesProcessDelay)}async onMapMarkerVisiblityProcess(){try{if(this.dettached())return!0;let x=this.mapProvider.getViewport(),q=this.mapProvider.getParameters(),J=new Set(this.mapMarkersVisibilityManager.markers);this.mapMarkersVisibilityManager.updateVisibleMarkers(x,q);let Q=new Set(this.mapMarkersVisibilityManager.markers),F=Array.from(J.difference(Q)),G=Array.from(Q.difference(J));return this.mapMarkerStatesManager.resetStates(F),this.mapMarkerElementsManager.removeElements(F),this.mapMarkerElementsManager.insertElements(G,this.onMapMarkerClick.bind(this)),this.mapMarkerRenderProcessor.start(),!1}catch(x){return this.clear(),this.error("Failed to process map move",x),!0}}async onMapMarkerStateProcess(){try{if(this.dettached())return!0;let x=this.mapMarkersVisibilityManager.markers,q=this.mapProvider.getParameters();return await this.mapMarkerStatesManager.updateStates(x,q),this.mapMarkerElementsManager.updateElements(x),this.mapMarkerRenderProcessor.start(),!1}catch(x){return this.clear(),this.error("Failed to process map idle",x),!0}}async onMapMarkerRenderProcess(){try{if(this.dettached())return!0;let x=this.mapProvider.getViewport(),q=this.mapProvider.getParameters();return this.mapMarkerElementsManager.renderElements(x,q),!1}catch(x){return this.clear(),this.error("Failed to process map render",x),!0}}updateMarkers(x){c.parse(c.array(A2),x);try{for(let J of x)if(this.mapMarkers.has(J.id)==!1)this.mapMarkers.set(J.id,new J0(J));let q=Array.from(this.mapMarkers.values());q.sort((J,Q)=>Q.data.rank-J.data.rank),this.mapMarkersVisibilityManager.insertMarkers(q),this.mapStateManager.start(),this.mapMarkerVisibilityProcessor.start(),this.mapMarkerStateProcessor.start(),this.mapMarkerRenderProcessor.start()}catch(q){throw this.clear(),this.error("Failed to update markers",q),q}}removeMarkers(){try{this.clear()}catch(x){throw this.error("Failed to remove markers",x),x}}showPopup(x){try{this.mapMarkerElementsManager.showPopup(x)}catch(q){throw this.mapMarkerElementsManager.hidePopups(),this.error("Failed to show popup",q),q}finally{this.mapMarkerRenderProcessor.start()}}hidePopup(){try{this.mapMarkerElementsManager.hidePopups()}catch(x){throw this.error("Failed to hide popup",x),x}finally{this.mapMarkerRenderProcessor.start()}}}export{P0 as MapManager};