@projektemacher/storymapjs 0.10.0 → 0.10.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,1357 @@
1
+ import OlMap from 'ol/Map';
2
+ import { Vector, Tile } from 'ol/layer';
3
+ import { Style } from 'ol/style';
4
+ import Projection from 'ol/proj/Projection';
5
+ import TileGrid from 'ol/tilegrid/TileGrid';
6
+ import OverviewMap from 'ol/control/OverviewMap';
7
+ import { Map as Map$1 } from 'ol';
8
+ import Overlay from 'ol/Overlay';
9
+
10
+ /** Eventing members provided by the Evented mixin. */
11
+ interface EventedInstance {
12
+ on: (type: string, fn: unknown, context?: unknown) => unknown;
13
+ off: (type: string, fn: unknown, context?: unknown) => unknown;
14
+ fire: (type: string, data?: unknown, target?: unknown) => unknown;
15
+ hasEventListeners: (type: string) => boolean;
16
+ }
17
+
18
+ interface StorymapSlideText {
19
+ headline?: string;
20
+ text?: string;
21
+ text_align?: string;
22
+ }
23
+ interface StorymapSlideLocation {
24
+ lat?: number;
25
+ lon?: number;
26
+ zoom?: number;
27
+ line?: boolean;
28
+ icon?: string;
29
+ iconSize?: number[];
30
+ image?: string;
31
+ use_custom_marker?: boolean;
32
+ [key: string]: unknown;
33
+ }
34
+ type MediaTypeMatch = {
35
+ type: string;
36
+ name: string;
37
+ match_str: string;
38
+ cls: new (data: StorymapSlideMedia, options: Record<string, unknown>) => unknown;
39
+ };
40
+ interface StorymapSlideMedia {
41
+ url?: string | null;
42
+ caption?: string | null;
43
+ credit?: string | null;
44
+ thumb?: string | null;
45
+ mediatype?: MediaTypeMatch | null;
46
+ [key: string]: unknown;
47
+ }
48
+ interface StorymapSlideBackground {
49
+ url?: string | null;
50
+ color?: string | null;
51
+ opacity?: number;
52
+ }
53
+ interface StorymapSlide {
54
+ type?: string;
55
+ date?: string | Record<string, unknown> | null;
56
+ group?: string;
57
+ location?: StorymapSlideLocation;
58
+ media?: StorymapSlideMedia;
59
+ text?: StorymapSlideText;
60
+ background?: StorymapSlideBackground | string | null;
61
+ uniqueid?: string;
62
+ [key: string]: unknown;
63
+ }
64
+ interface StorymapData {
65
+ uniqueid?: string;
66
+ slides: StorymapSlide[];
67
+ [key: string]: unknown;
68
+ }
69
+ interface StorymapDataWrapper {
70
+ storymap: StorymapData;
71
+ }
72
+ interface StorymapOptions {
73
+ width: number;
74
+ height: number;
75
+ layout: string;
76
+ base_class: string;
77
+ default_bg_color: {
78
+ r: number;
79
+ g: number;
80
+ b: number;
81
+ };
82
+ map_size_sticky: number;
83
+ map_center_offset: {
84
+ left: number;
85
+ top: number;
86
+ } | null;
87
+ less_bounce: boolean;
88
+ start_at_slide: number;
89
+ call_to_action: boolean;
90
+ call_to_action_text: string;
91
+ menubar_height: number;
92
+ /** Show a fullscreen toggle button in the menubar (default: true) */
93
+ fullscreen: boolean;
94
+ /** Show the map overview button in the menubar (default: true) */
95
+ show_overview: boolean;
96
+ /** Show the back-to-the-beginning button in the menubar (default: true) */
97
+ show_back_to_start: boolean;
98
+ skinny_size: number;
99
+ duration: number;
100
+ ease: unknown;
101
+ dragging: boolean;
102
+ trackResize: boolean;
103
+ /** Re-fetch the source file on every load, bypassing caches (issue #417) */
104
+ nocache: boolean;
105
+ /** Advance slides automatically every N milliseconds; 0 disables (issue #380) */
106
+ autoplay: number;
107
+ /** Show a progress bar in the menubar (issue #247) */
108
+ show_progress: boolean;
109
+ /** Show the slide headline as a label on the active map marker (issue #243) */
110
+ marker_labels: boolean;
111
+ /** Default text alignment for slide text: left, center or right (issue #244) */
112
+ text_align: "left" | "center" | "right";
113
+ /** Override the overview fit center (issues #107, #271) */
114
+ map_overview_center: {
115
+ lat: number;
116
+ lon: number;
117
+ } | null;
118
+ map_type: string;
119
+ attribution: string;
120
+ map_mini: boolean;
121
+ map_subdomains: string;
122
+ map_as_image: boolean;
123
+ map_access_token: string;
124
+ map_background_color: string;
125
+ /**
126
+ * Limit the map to a bounding box `[west, south, east, north]` (lon/lat;
127
+ * raw image pixel coordinates for image-space maps). Nothing outside of
128
+ * the box can be visible. `null` (default) leaves the map unconstrained.
129
+ */
130
+ map_bbox: number[] | null;
131
+ /**
132
+ * Legacy zoomify image pyramid (map_type: "zoomify"): the tiles are
133
+ * placed at the standard mercator tile positions, stretched from the
134
+ * world's top-left corner.
135
+ */
136
+ zoomify?: {
137
+ path?: string;
138
+ width?: number;
139
+ height?: number;
140
+ tolerance?: number;
141
+ attribution?: string;
142
+ } | boolean;
143
+ /**
144
+ * Ask for permission before loading anything from external services
145
+ * (media embeds, map tiles, external font CSS) — GDPR consent mode.
146
+ * Grants are remembered per service in a cookie for 90 days.
147
+ */
148
+ consent_required: boolean;
149
+ /** Slide text color override, sets --vco-color-text (issue #177) */
150
+ text_color: string;
151
+ /** Slide panel background color override (issue #177) */
152
+ text_background_color: string;
153
+ /** Show the great-circle route distance in the menubar (issue #341) */
154
+ show_distance: boolean;
155
+ /**
156
+ * Raw OpenLayers map configuration. `controls` and `interactions` replace
157
+ * the StoryMapJS defaults, `view` is merged over the computed default view
158
+ * and `element` (an HTMLElement or DOM id) replaces the auto-created map
159
+ * container div.
160
+ */
161
+ map_options: StorymapMapOptions;
162
+ map_popup: boolean;
163
+ zoom_distance: number;
164
+ calculate_zoom: boolean;
165
+ line_follows_path: boolean;
166
+ line_color: string;
167
+ line_color_inactive: string;
168
+ line_join: string;
169
+ line_weight: number;
170
+ line_opacity: number;
171
+ line_dash: string;
172
+ show_lines: boolean;
173
+ show_history_line: boolean;
174
+ use_custom_markers: boolean;
175
+ iiif: {
176
+ url: string;
177
+ attribution: string;
178
+ };
179
+ map_height: number;
180
+ storyslider_height: number;
181
+ slide_padding_lr: number;
182
+ slide_default_fade: string;
183
+ menubar_default_y: number;
184
+ path_gfx: string;
185
+ script_path: string;
186
+ font_css: string;
187
+ language: string;
188
+ api_key_flickr: string;
189
+ [key: string]: unknown;
190
+ }
191
+ interface AnimationHandle {
192
+ stop: (jump?: boolean) => void;
193
+ }
194
+ /** OpenLayers passthrough options (see StorymapOptions.map_options) */
195
+ interface StorymapMapOptions {
196
+ /** HTMLElement or DOM id that becomes the real map container */
197
+ element?: HTMLElement | string;
198
+ /** Merged over the default view configuration */
199
+ view?: Record<string, unknown>;
200
+ /** Replaces the default (empty) controls list */
201
+ controls?: unknown[];
202
+ /** Replaces the default (empty) interactions list */
203
+ interactions?: unknown[];
204
+ /** Any other ol/Map constructor option (layers, pixelRatio, ...) */
205
+ [key: string]: unknown;
206
+ }
207
+ interface LatLngLiteral {
208
+ lat: number | undefined;
209
+ lon?: number | undefined;
210
+ lng?: number | undefined;
211
+ }
212
+ interface MapMarkerData {
213
+ real_marker?: boolean;
214
+ location?: StorymapSlideLocation;
215
+ media?: StorymapSlideMedia & {
216
+ mediatype?: MediaTypeMatch | null;
217
+ };
218
+ text?: {
219
+ headline?: string;
220
+ };
221
+ type?: string;
222
+ [key: string]: unknown;
223
+ }
224
+ type IconSpec = {
225
+ url: string;
226
+ size: number[];
227
+ anchor: number[];
228
+ };
229
+
230
+ declare class MapMarkerBase {
231
+ "_el": Record<string, HTMLElement>;
232
+ "_marker": HTMLDivElement;
233
+ "_icon": IconSpec | HTMLDivElement | false;
234
+ "_custom_icon": IconSpec | false;
235
+ "_custom_icon_url": string;
236
+ "_custom_image_icon": string | false;
237
+ "marker_number": number;
238
+ "media_icon_class": string;
239
+ "timer": ReturnType<typeof setTimeout> | null;
240
+ "data": MapMarkerData;
241
+ "options": StorymapOptions;
242
+ "animator": AnimationHandle | null;
243
+ "fire": EventedInstance["fire"];
244
+ constructor(data?: MapMarkerData, options?: Partial<StorymapOptions>);
245
+ show(): void;
246
+ hide(): void;
247
+ addTo(m: unknown): void;
248
+ removeFrom(m: unknown): void;
249
+ updateDisplay(w: number, h: number, a?: boolean): void;
250
+ createMarker(d?: MapMarkerData, o?: StorymapOptions): void;
251
+ active(a: boolean): void;
252
+ location(): LatLngLiteral;
253
+ _createMarker(d?: MapMarkerData, o?: StorymapOptions): void;
254
+ _addTo(m: unknown): void;
255
+ _removeFrom(m: unknown): void;
256
+ _active(a: boolean): void;
257
+ _location(): LatLngLiteral;
258
+ _onMarkerClick(e?: unknown): void;
259
+ _initLayout(): void;
260
+ _updateDisplay(width: number, height: number, animate?: boolean): void;
261
+ }
262
+ declare const MapMarker_base: {
263
+ new (...args: any[]): {
264
+ _vco_events?: Record<string, {
265
+ action: unknown;
266
+ context: unknown;
267
+ }[]>;
268
+ on(type: string, fn: unknown, context?: unknown): /*elided*/ any;
269
+ hasEventListeners(type: string): boolean;
270
+ off(type: string, fn: unknown, context?: unknown): /*elided*/ any;
271
+ fire(type: string, data?: unknown, target?: unknown): /*elided*/ any;
272
+ };
273
+ } & typeof MapMarkerBase;
274
+ declare class MapMarker extends MapMarker_base {
275
+ constructor(...args: ConstructorParameters<typeof MapMarkerBase>);
276
+ }
277
+
278
+ /** Options accepted by viewTo/_viewTo. */
279
+ interface ViewToOptions {
280
+ calculate_zoom?: boolean;
281
+ duration?: number;
282
+ zoom?: number;
283
+ }
284
+ /** A point of the connection line: either a slide or a raw lat/lon pair. */
285
+ interface LinePoint {
286
+ location?: StorymapSlideLocation;
287
+ lat?: number;
288
+ lon?: number;
289
+ }
290
+
291
+ /** Wheel/scroll zoom bookkeeping (handles cleared via clearTimeout). */
292
+ interface ScrollState {
293
+ start_time: number | null;
294
+ timer?: ReturnType<typeof setTimeout>;
295
+ timer_done?: ReturnType<typeof setTimeout>;
296
+ }
297
+ declare class MapBase {
298
+ "_el": {
299
+ container: HTMLElement;
300
+ map: HTMLElement;
301
+ map_mask: HTMLElement;
302
+ };
303
+ "_loaded": {
304
+ data: boolean;
305
+ map: boolean;
306
+ };
307
+ "_map": Map$1 | null;
308
+ "_mini_map": OverviewMap | null;
309
+ "_markers": MapMarker[];
310
+ "zoom_min_max": {
311
+ min: number | null;
312
+ max: number | null;
313
+ };
314
+ "_line": Vector | null;
315
+ "_line_active": Vector | null;
316
+ "current_marker": number;
317
+ "bounds_array": number[][] | null;
318
+ "_tile_layer": Tile | null;
319
+ "_tile_layer_mini": Tile | null;
320
+ "_image_layer": Tile | null;
321
+ "data": StorymapData;
322
+ "options": StorymapOptions;
323
+ "animator": AnimationHandle | null;
324
+ "_transition_duration": number;
325
+ "timer": ReturnType<typeof setTimeout> | null;
326
+ "touch_scale": number;
327
+ "scroll": ScrollState;
328
+ "fire": EventedInstance["fire"];
329
+ constructor(elem: string | HTMLElement, data?: Partial<StorymapData>, options?: Partial<StorymapOptions>);
330
+ updateDisplay(w: number, h: number, animate?: boolean, d?: number, offset?: unknown): void;
331
+ goTo(n: number, change?: boolean): void;
332
+ panTo(loc: LatLngLiteral, animate?: boolean): void;
333
+ zoomTo(z: number, animate?: boolean): void;
334
+ viewTo(loc: StorymapSlideLocation, opts?: ViewToOptions): void;
335
+ getBoundsZoom(m1: LatLngLiteral, m2: LatLngLiteral, inside?: boolean, padding?: unknown): void;
336
+ markerOverview(): void;
337
+ calculateMarkerZooms(): void;
338
+ createMiniMap(): void;
339
+ setMapOffset(left: number, top: number): void;
340
+ calculateMinMaxZoom(): void;
341
+ updateMinMaxZoom(zoom: number): void;
342
+ initialMapLocation(): void;
343
+ show(): void;
344
+ hide(): void;
345
+ createMarkers(array: StorymapSlide[]): void;
346
+ createMarker(d: StorymapSlide): void;
347
+ _destroyMarker(marker: MapMarker): void;
348
+ _createMarkers(array: StorymapSlide[]): void;
349
+ /**
350
+ * A slide has a real location: lat and lon are both numbers — lat 0 and
351
+ * lon 0 are valid coordinates and must not be treated as missing.
352
+ */
353
+ _hasLocation(d: StorymapSlide): boolean;
354
+ _createMap(): void;
355
+ _createMiniMap(): void;
356
+ _createMarker(d?: StorymapSlide): void;
357
+ _addMarker(marker: MapMarker): void;
358
+ _removeMarker(marker: MapMarker): void;
359
+ _resetMarkersActive(): void;
360
+ _calculateMarkerZooms(): void;
361
+ _createLine(d?: StorymapSlide): unknown;
362
+ _addToLine(line: Vector | null, d: LinePoint): void;
363
+ _replaceLines(line: Vector | null, d: LinePoint[], animate?: {
364
+ duration: number;
365
+ retractFrom?: LinePoint[];
366
+ }): void;
367
+ _addLineToMap(line: Vector): void;
368
+ _panTo(loc: LatLngLiteral, animate?: boolean): void;
369
+ _zoomTo(z: number, animate?: boolean): void;
370
+ _viewTo(loc: StorymapSlideLocation, opts?: ViewToOptions): void;
371
+ _updateMapDisplay(animate?: boolean, d?: number): void;
372
+ _refreshMap(): void;
373
+ _getMapZoom(): number;
374
+ _getMapCenter(correct_for_center?: boolean): LatLngLiteral;
375
+ _getBoundsZoom(m1: LatLngLiteral, m2: LatLngLiteral, inside?: boolean, padding?: unknown): number;
376
+ _markerOverview(duration?: number): void;
377
+ /**
378
+ * Great-circle length of the route through all markers in kilometers;
379
+ * `undefined` when the map cannot compute it or there are fewer than two
380
+ * markers (issue #341).
381
+ */
382
+ getRouteDistance(): number | undefined;
383
+ _onMarkerChange(e?: unknown): void;
384
+ _onMarkerClick(e: {
385
+ marker_number: number;
386
+ }): void;
387
+ _onMapLoaded(e?: unknown): void;
388
+ _onWheel(e: WheelEvent): void;
389
+ _scollZoom(e?: unknown): void;
390
+ _scollZoomDone(e?: unknown): void;
391
+ _calculateZoomChange(origin: LatLngLiteral, destination: LatLngLiteral, correct_for_center?: boolean): number;
392
+ _updateDisplay(w?: number, h?: number, animate?: boolean, d?: number, offset?: unknown): void;
393
+ /** Re-apply runtime-changed options (no-op in the base class) */
394
+ applyOptions(_keys: string[]): void;
395
+ _initLayout(): void;
396
+ _initData(): void;
397
+ /** Hook after marker creation (overridden per engine as needed) */
398
+ _afterCreateMarkers(): void;
399
+ _initEvents(): void;
400
+ }
401
+ declare const Map_base: {
402
+ new (...args: any[]): {
403
+ show(animate?: unknown): void;
404
+ hide(): void;
405
+ addTo(container: HTMLElement): /*elided*/ any;
406
+ removeFrom(container: HTMLElement): /*elided*/ any;
407
+ setPosition(pos: Record<string, number>, el?: HTMLElement): /*elided*/ any;
408
+ onLoaded(): void;
409
+ onAdd(): void;
410
+ onRemove(): void;
411
+ _el: Record<string, HTMLElement>;
412
+ data?: unknown;
413
+ on: (type: string, fn: unknown, context?: unknown) => unknown;
414
+ off: (type: string, fn: unknown, context?: unknown) => unknown;
415
+ fire: (type: string, data?: unknown, target?: unknown) => unknown;
416
+ hasEventListeners: (type: string) => boolean;
417
+ };
418
+ } & {
419
+ new (...args: any[]): {
420
+ _vco_events?: Record<string, {
421
+ action: unknown;
422
+ context: unknown;
423
+ }[]>;
424
+ on(type: string, fn: unknown, context?: unknown): /*elided*/ any;
425
+ hasEventListeners(type: string): boolean;
426
+ off(type: string, fn: unknown, context?: unknown): /*elided*/ any;
427
+ fire(type: string, data?: unknown, target?: unknown): /*elided*/ any;
428
+ };
429
+ } & typeof MapBase;
430
+ declare class Map extends Map_base {
431
+ constructor(...args: ConstructorParameters<typeof MapBase>);
432
+ }
433
+
434
+ declare class OpenLayersMapMarker extends MapMarker {
435
+ "_overlay": Overlay;
436
+ _createMarker(d?: MapMarkerData, o?: StorymapOptions): void;
437
+ _createMarkerElement(d: MapMarkerData, o?: StorymapOptions): HTMLDivElement;
438
+ _addTo(m: Map$1): void;
439
+ _removeFrom(m: Map$1): void;
440
+ _active(a: boolean): void;
441
+ _customIconAnchor(size?: number[]): number[];
442
+ _location(): LatLngLiteral;
443
+ }
444
+
445
+ /**
446
+ * Per-StoryMap GDPR consent manager. When the `consent_required` option is
447
+ * set, every external service (media embeds, map tiles, external font CSS)
448
+ * asks for permission before anything is loaded. Decisions are remembered
449
+ * per service in a cookie for 90 days — clearing cookies asks again.
450
+ */
451
+ declare class ConsentManager {
452
+ private granted;
453
+ private denied;
454
+ /** unanswered asks per service (preloaded slides stack several) */
455
+ private pending;
456
+ constructor();
457
+ /** Seed the per-service state from the consent cookie, if present. */
458
+ private restore;
459
+ /** Persist the per-service state to the consent cookie. */
460
+ private persist;
461
+ isGranted(service: string): boolean;
462
+ isDenied(service: string): boolean;
463
+ /**
464
+ * Ask the visitor for permission to load `service` (a human-readable
465
+ * name like "YouTube" or "map tiles"), optionally naming the `host`.
466
+ * The ask is rendered into `container`; resolves `true`/`false` on the
467
+ * visitor's decision, or immediately when the service was already
468
+ * granted or denied.
469
+ */
470
+ request(service: string, host: string, container: HTMLElement): Promise<boolean>;
471
+ }
472
+
473
+ declare class OpenLayers extends Map {
474
+ "_map": OlMap;
475
+ "_tile_layer": Tile;
476
+ "_line": Vector;
477
+ "_line_active": Vector;
478
+ "_tile_layer_mini": Tile | null;
479
+ "_mini_map": OverviewMap;
480
+ "_markers": OpenLayersMapMarker[];
481
+ /** rAF handle of the running active-line draw animation */
482
+ "_line_animation": number | null;
483
+ _createMap(): void;
484
+ _getAttribution(map_type: string): string;
485
+ /**
486
+ * Create the tile layer and register its load handler. Deferred until
487
+ * the visitor allows map tiles in consent mode.
488
+ */
489
+ _addTileLayer(): void;
490
+ /**
491
+ * Ask for tile consent, then attach the layers if allowed.
492
+ */
493
+ _requestTileConsent(consent: ConsentManager, tile_service: string): Promise<void>;
494
+ /**
495
+ * Map tiles were allowed: attach the main tile layer, create the
496
+ * minimap's deferred layer if it was withheld, then re-fit.
497
+ */
498
+ _onTilesAllowed(): void;
499
+ /**
500
+ * Legacy zoomify image pyramid: the levels (image size per level), the
501
+ * max zoom and the mercator bounds the image occupies (stretched from
502
+ * the world's top-left corner, the original renderer's mapping).
503
+ */
504
+ _zoomifyPyramid(): {
505
+ sizes: Array<[number, number]>;
506
+ maxZoom: number;
507
+ extent: number[];
508
+ tileGrid: TileGrid;
509
+ } | null;
510
+ /**
511
+ * The zoomify overview state: the best-fit pyramid level for a map
512
+ * window (the level whose image, times the tolerance, fits the window —
513
+ * the legacy `_getBestFitZoom`) and the image's mercator center.
514
+ */
515
+ _zoomifyOverview(mapSize: [number, number]): {
516
+ zoom: number;
517
+ center: number[];
518
+ } | null;
519
+ _createTileLayer(map_type: string): Tile;
520
+ _createVectorStyleLayer(style_url: string): Tile;
521
+ _createMiniMap(): void;
522
+ _fitMiniMapToImage(): void;
523
+ _createMarker(d: StorymapSlide): void;
524
+ _addMarker(marker: OpenLayersMapMarker): void;
525
+ /**
526
+ * Position marker overlays on the unwrapped longitude path so they sit on
527
+ * the same world copy as the fitted view and the line (issue #381).
528
+ * Image-space coordinates are not degrees and stay untouched.
529
+ */
530
+ _afterCreateMarkers(): void;
531
+ _removeMarker(marker: OpenLayersMapMarker): void;
532
+ _getAllMarkersBounds(markers_array: OpenLayersMapMarker[]): number[][];
533
+ /**
534
+ * Normalize a longitude sequence so consecutive values differ by at most
535
+ * 180 degrees: markers keep their raw coordinates (OpenLayers wraps the
536
+ * display), but fits and lines use the unwrapped path (issue #381).
537
+ */
538
+ _unwrapLongitudes(lons: number[]): number[];
539
+ _markerCoordsToViewCoords(coords: number[][]): number[][];
540
+ /**
541
+ * The View extent for the `map_bbox` option, or `null` when unset.
542
+ */
543
+ _bboxExtent(): number[] | null;
544
+ /**
545
+ * The slide content panel can be opaque — it then covers part of the map
546
+ * and the effective visible area shrinks. Returns the pixel padding for
547
+ * the covered side (right in landscape, bottom in portrait) so fits keep
548
+ * the story inside the visible region; transparent panels add nothing.
549
+ */
550
+ _opaquePanelPadding(): [number, number, number, number];
551
+ _fitView(ol_map: OlMap, coords: number[][], duration?: number): void;
552
+ _calculateMarkerZooms(): void;
553
+ /**
554
+ * Stroke style for the route lines: the dash pattern and line join are
555
+ * applied at init too, matching the original rendering (the lines are
556
+ * dashed "5,5" by default, not solid).
557
+ */
558
+ _lineStyle(color: string): Style;
559
+ _createLine(d?: StorymapSlide): Vector;
560
+ _addLineToMap(line: Vector): void;
561
+ _addToLine(line: Vector, d: LinePoint): void;
562
+ /**
563
+ * Replace a line's geometry. With `animate.duration > 0` the active line
564
+ * is drawn progressively, in sync with the view animation: the target
565
+ * path is truncated by cumulative length at the eased progress, so half
566
+ * way through the pan only half the route is red.
567
+ */
568
+ _replaceLines(line: Vector, array: LinePoint[], animate?: {
569
+ duration: number;
570
+ retractFrom?: LinePoint[];
571
+ }): void;
572
+ /** Cancel a running active-line draw animation. */
573
+ _cancelLineAnimation(): void;
574
+ /** Total euclidean length of a path in view coordinates. */
575
+ _pathLength(coords: number[][]): number;
576
+ /**
577
+ * The prefix of the path up to `length` (in view units), with the cut
578
+ * point interpolated inside its segment.
579
+ */
580
+ _truncatePath(coords: number[][], length: number): number[][];
581
+ _panTo(loc: LatLngLiteral, animate?: boolean): void;
582
+ _zoomTo(z: number, animate?: boolean): void;
583
+ _viewTo(loc: StorymapSlideLocation, opts?: ViewToOptions): void;
584
+ _toViewCoords(loc: LatLngLiteral): number[];
585
+ _getMapZoom(): number;
586
+ _getMapCenter(offset?: boolean): LatLngLiteral;
587
+ _getMapCenterOffset(location: LatLngLiteral, zoom: number): LatLngLiteral;
588
+ _fromViewCoords(coord: number[], projection: Projection): LatLngLiteral;
589
+ _getBoundsZoom(origin: LatLngLiteral, destination: LatLngLiteral, correct_for_center?: boolean): number;
590
+ _initialMapLocation(): void;
591
+ /**
592
+ * Great-circle (haversine) length of the route through all markers in
593
+ * kilometers (issue #341).
594
+ */
595
+ getRouteDistance(): number | undefined;
596
+ _markerOverview(duration?: number): void;
597
+ /**
598
+ * Re-apply runtime-changed options (driven by StoryMap.setMapOptions).
599
+ * Only keys with an immediate effect are handled here; everything else is
600
+ * picked up on the next navigation or layout pass.
601
+ */
602
+ applyOptions(keys: string[]): void;
603
+ _updateMapDisplay(animate?: boolean, d?: number, instant?: boolean): void;
604
+ _refreshMap(instant?: boolean): void;
605
+ /**
606
+ * Set the view synchronously (resize path): OL's animate() applies its
607
+ * end state asynchronously which can leave marker overlays rendering
608
+ * stale positions after a size change.
609
+ */
610
+ _setViewInstant(loc: StorymapSlideLocation, zoom: number): void;
611
+ }
612
+
613
+ interface MenuBarOptions {
614
+ width: number;
615
+ height: number;
616
+ duration: number;
617
+ ease: unknown;
618
+ menubar_default_y: number;
619
+ [key: string]: unknown;
620
+ }
621
+ declare class MenuBarBase {
622
+ "_el": Record<string, HTMLElement>;
623
+ "collapsed": boolean;
624
+ "options": MenuBarOptions;
625
+ "animator": Record<string, unknown>;
626
+ "fire": EventedInstance["fire"];
627
+ constructor(elem: HTMLElement | string, parent_elem?: HTMLElement, options?: object);
628
+ show(d?: number): void;
629
+ hide(top: number): void;
630
+ setSticky(y: number): void;
631
+ setColor(inverted: boolean): void;
632
+ /**
633
+ * Reflect the fullscreen state in the button label/icon.
634
+ */
635
+ setFullscreenState(active: boolean): void;
636
+ /**
637
+ * Update the progress indicator (issue #247); no-op when disabled.
638
+ */
639
+ setProgress(current: number, total: number): void;
640
+ /**
641
+ * Update the route distance display (issue #341); no-op when disabled or
642
+ * before the first reading.
643
+ */
644
+ setDistance(kilometers?: number): void;
645
+ updateDisplay(w?: number, h?: number, a?: boolean): void;
646
+ _onButtonOverview(e: Event): void;
647
+ _onButtonBackToStart(e: Event): void;
648
+ _onButtonFullscreen(e: Event): void;
649
+ _onButtonCollapseMap(e: Event): void;
650
+ _initLayout(): void;
651
+ _updateDisplay(width?: number, height?: number, animate?: boolean): void;
652
+ }
653
+ declare const MenuBar_base: {
654
+ new (...args: any[]): {
655
+ show(animate?: unknown): void;
656
+ hide(): void;
657
+ addTo(container: HTMLElement): /*elided*/ any;
658
+ removeFrom(container: HTMLElement): /*elided*/ any;
659
+ setPosition(pos: Record<string, number>, el?: HTMLElement): /*elided*/ any;
660
+ onLoaded(): void;
661
+ onAdd(): void;
662
+ onRemove(): void;
663
+ _el: Record<string, HTMLElement>;
664
+ data?: unknown;
665
+ on: (type: string, fn: unknown, context?: unknown) => unknown;
666
+ off: (type: string, fn: unknown, context?: unknown) => unknown;
667
+ fire: (type: string, data?: unknown, target?: unknown) => unknown;
668
+ hasEventListeners: (type: string) => boolean;
669
+ };
670
+ } & {
671
+ new (...args: any[]): {
672
+ _vco_events?: Record<string, {
673
+ action: unknown;
674
+ context: unknown;
675
+ }[]>;
676
+ on(type: string, fn: unknown, context?: unknown): /*elided*/ any;
677
+ hasEventListeners(type: string): boolean;
678
+ off(type: string, fn: unknown, context?: unknown): /*elided*/ any;
679
+ fire(type: string, data?: unknown, target?: unknown): /*elided*/ any;
680
+ };
681
+ } & typeof MenuBarBase;
682
+ declare class MenuBar extends MenuBar_base {
683
+ constructor(...args: ConstructorParameters<typeof MenuBarBase>);
684
+ }
685
+
686
+ interface SlideNavData {
687
+ title: string;
688
+ description: string;
689
+ date?: string;
690
+ [key: string]: unknown;
691
+ }
692
+ interface SlideNavOptions {
693
+ direction: string;
694
+ [key: string]: unknown;
695
+ }
696
+ declare class SlideNavBase {
697
+ "_el": Record<string, HTMLElement>;
698
+ "mediatype": unknown;
699
+ "data": SlideNavData;
700
+ "options": SlideNavOptions;
701
+ "animator": AnimationHandle | null;
702
+ "animator_position": AnimationHandle | null;
703
+ "fire": EventedInstance["fire"];
704
+ constructor(data?: Partial<SlideNavData>, options?: Partial<SlideNavOptions>, add_to_container?: HTMLElement);
705
+ update(d?: Partial<SlideNavData>): void;
706
+ setColor(inverted: boolean): void;
707
+ updatePosition(pos: Record<string, number | string>, use_percent: boolean, duration: number, ease: unknown, start_value: number, return_to_default: boolean): void;
708
+ _onUpdatePositionComplete(return_to_default: boolean): void;
709
+ _onMouseClick(): void;
710
+ _update(d?: Partial<SlideNavData>): void;
711
+ _initLayout(): void;
712
+ _initEvents(): void;
713
+ }
714
+ declare const SlideNav_base: {
715
+ new (...args: any[]): {
716
+ show(animate?: unknown): void;
717
+ hide(): void;
718
+ addTo(container: HTMLElement): /*elided*/ any;
719
+ removeFrom(container: HTMLElement): /*elided*/ any;
720
+ setPosition(pos: Record<string, number>, el?: HTMLElement): /*elided*/ any;
721
+ onLoaded(): void;
722
+ onAdd(): void;
723
+ onRemove(): void;
724
+ _el: Record<string, HTMLElement>;
725
+ data?: unknown;
726
+ on: (type: string, fn: unknown, context?: unknown) => unknown;
727
+ off: (type: string, fn: unknown, context?: unknown) => unknown;
728
+ fire: (type: string, data?: unknown, target?: unknown) => unknown;
729
+ hasEventListeners: (type: string) => boolean;
730
+ };
731
+ } & {
732
+ new (...args: any[]): {
733
+ _vco_events?: Record<string, {
734
+ action: unknown;
735
+ context: unknown;
736
+ }[]>;
737
+ on(type: string, fn: unknown, context?: unknown): /*elided*/ any;
738
+ hasEventListeners(type: string): boolean;
739
+ off(type: string, fn: unknown, context?: unknown): /*elided*/ any;
740
+ fire(type: string, data?: unknown, target?: unknown): /*elided*/ any;
741
+ };
742
+ } & typeof SlideNavBase;
743
+ declare class SlideNav extends SlideNav_base {
744
+ constructor(...args: ConstructorParameters<typeof SlideNavBase>);
745
+ }
746
+
747
+ interface TextData {
748
+ uniqueid?: string | null;
749
+ headline?: string;
750
+ text?: string;
751
+ text_align?: string;
752
+ date?: {
753
+ created_time?: string;
754
+ [key: string]: unknown;
755
+ } | null;
756
+ }
757
+ interface TextOptions {
758
+ title?: boolean;
759
+ text_align?: string;
760
+ }
761
+ declare class TextBase {
762
+ "_el": Record<string, HTMLElement>;
763
+ "data": TextData;
764
+ "options": TextOptions;
765
+ "fire": EventedInstance["fire"];
766
+ constructor(data: TextData, options?: TextOptions, add_to_container?: HTMLElement);
767
+ show(): void;
768
+ hide(): void;
769
+ addTo(container: HTMLElement): void;
770
+ removeFrom(container: HTMLElement): void;
771
+ headlineHeight(): number;
772
+ addDateText(str: string): void;
773
+ onLoaded(): void;
774
+ onAdd(): void;
775
+ onRemove(): void;
776
+ _initLayout(): void;
777
+ }
778
+ declare const Text_base: {
779
+ new (...args: any[]): {
780
+ _vco_events?: Record<string, {
781
+ action: unknown;
782
+ context: unknown;
783
+ }[]>;
784
+ on(type: string, fn: unknown, context?: unknown): /*elided*/ any;
785
+ hasEventListeners(type: string): boolean;
786
+ off(type: string, fn: unknown, context?: unknown): /*elided*/ any;
787
+ fire(type: string, data?: unknown, target?: unknown): /*elided*/ any;
788
+ };
789
+ } & typeof TextBase;
790
+ declare class Text extends Text_base {
791
+ constructor(...args: ConstructorParameters<typeof TextBase>);
792
+ }
793
+
794
+ interface MediaInstance {
795
+ addTo: (container: HTMLElement) => void;
796
+ loadMedia: () => void;
797
+ stopMedia: () => void;
798
+ updateDisplay: (w?: number, h?: number, l?: string) => void;
799
+ _state?: {
800
+ loaded?: boolean;
801
+ };
802
+ }
803
+ interface SlideHas {
804
+ headline: boolean;
805
+ text: boolean;
806
+ media: boolean;
807
+ title: boolean;
808
+ background: {
809
+ image: boolean;
810
+ color: boolean;
811
+ color_value: string;
812
+ };
813
+ }
814
+ interface SlideOptions {
815
+ duration: number;
816
+ slide_padding_lr: number;
817
+ ease: unknown;
818
+ width: number;
819
+ height: number;
820
+ skinny_size: number;
821
+ media_name?: string;
822
+ media_type?: string;
823
+ [key: string]: unknown;
824
+ }
825
+ declare class SlideBase {
826
+ "_el": Record<string, HTMLElement>;
827
+ "_media": MediaInstance | null;
828
+ "_mediaclass": unknown;
829
+ "_text": Text;
830
+ "_state": {
831
+ loaded: boolean;
832
+ };
833
+ "has": SlideHas;
834
+ "title": string;
835
+ "data": StorymapSlide;
836
+ "options": SlideOptions;
837
+ "active": boolean;
838
+ "animator": unknown;
839
+ "fire": EventedInstance["fire"];
840
+ "onLoaded": () => void;
841
+ constructor(data: StorymapSlide, options: Record<string, unknown>, title_slide?: boolean);
842
+ show(): void;
843
+ hide(): void;
844
+ setActive(is_active: boolean): void;
845
+ updateDisplay(w?: number, h?: number, l?: string): void;
846
+ loadMedia(): void;
847
+ stopMedia(): void;
848
+ getBackground(): {
849
+ image: boolean;
850
+ color: boolean;
851
+ color_value: string;
852
+ };
853
+ scrollToTop(): void;
854
+ addCallToAction(str: string): void;
855
+ _onCallToAction(e: Event): void;
856
+ _initLayout(): void;
857
+ _updateDisplay(width?: number, height?: number, layout?: string): void;
858
+ }
859
+ declare const Slide_base: {
860
+ new (...args: any[]): {
861
+ show(animate?: unknown): void;
862
+ hide(): void;
863
+ addTo(container: HTMLElement): /*elided*/ any;
864
+ removeFrom(container: HTMLElement): /*elided*/ any;
865
+ setPosition(pos: Record<string, number>, el?: HTMLElement): /*elided*/ any;
866
+ onLoaded(): void;
867
+ onAdd(): void;
868
+ onRemove(): void;
869
+ _el: Record<string, HTMLElement>;
870
+ data?: unknown;
871
+ on: (type: string, fn: unknown, context?: unknown) => unknown;
872
+ off: (type: string, fn: unknown, context?: unknown) => unknown;
873
+ fire: (type: string, data?: unknown, target?: unknown) => unknown;
874
+ hasEventListeners: (type: string) => boolean;
875
+ };
876
+ } & {
877
+ new (...args: any[]): {
878
+ _vco_events?: Record<string, {
879
+ action: unknown;
880
+ context: unknown;
881
+ }[]>;
882
+ on(type: string, fn: unknown, context?: unknown): /*elided*/ any;
883
+ hasEventListeners(type: string): boolean;
884
+ off(type: string, fn: unknown, context?: unknown): /*elided*/ any;
885
+ fire(type: string, data?: unknown, target?: unknown): /*elided*/ any;
886
+ };
887
+ } & typeof SlideBase;
888
+ declare class Slide extends Slide_base {
889
+ constructor(...args: ConstructorParameters<typeof SlideBase>);
890
+ }
891
+
892
+ /** Legacy drag handlers historically mixed mouse and touch event surfaces. */
893
+ type LegacyEvent = Event & {
894
+ originalEvent?: TouchEvent;
895
+ targetTouches?: TouchList;
896
+ pageX?: number;
897
+ pageY?: number;
898
+ };
899
+
900
+ interface DragEventNames {
901
+ down: string;
902
+ up: string;
903
+ leave: string;
904
+ move: string;
905
+ }
906
+ interface SwipableOptions {
907
+ snap: boolean;
908
+ enable: {
909
+ x: boolean;
910
+ y: boolean;
911
+ };
912
+ constraint: {
913
+ top: number | boolean;
914
+ bottom: number | boolean;
915
+ left: number | boolean;
916
+ right: number | boolean;
917
+ };
918
+ momentum_multiplier: number;
919
+ duration: number;
920
+ ease: unknown;
921
+ }
922
+ interface DragData {
923
+ sliding: boolean;
924
+ direction: string | null;
925
+ pagex: {
926
+ start: number;
927
+ end: number;
928
+ };
929
+ pagey: {
930
+ start: number;
931
+ end: number;
932
+ };
933
+ pos: {
934
+ start: {
935
+ x: number;
936
+ y: number;
937
+ };
938
+ end: {
939
+ x: number;
940
+ y: number;
941
+ };
942
+ };
943
+ new_pos: {
944
+ x: number;
945
+ y: number;
946
+ };
947
+ new_pos_parent: {
948
+ x: number;
949
+ y: number;
950
+ };
951
+ time: {
952
+ start: number;
953
+ end: number;
954
+ };
955
+ touch: boolean;
956
+ }
957
+ declare class SwipableBase {
958
+ "mousedrag": DragEventNames;
959
+ "touchdrag": DragEventNames;
960
+ "_el": Record<string, HTMLElement>;
961
+ "options": SwipableOptions;
962
+ "animator": AnimationHandle | null;
963
+ "dragevent": DragEventNames;
964
+ "data": DragData;
965
+ "fire": EventedInstance["fire"];
966
+ constructor(drag_elem: HTMLElement, move_elem?: HTMLElement, options?: Record<string, unknown>);
967
+ enable(e?: LegacyEvent): void;
968
+ disable(): void;
969
+ stopMomentum(): void;
970
+ updateConstraint(c: SwipableOptions["constraint"]): void;
971
+ _onDragStart(e: LegacyEvent): void;
972
+ _onDragEnd(e: LegacyEvent): void;
973
+ _onDragMove(e: LegacyEvent): void;
974
+ _momentum(): void;
975
+ _animateMomentum(): void;
976
+ }
977
+ declare const Swipable_base: {
978
+ new (...args: any[]): {
979
+ _vco_events?: Record<string, {
980
+ action: unknown;
981
+ context: unknown;
982
+ }[]>;
983
+ on(type: string, fn: unknown, context?: unknown): /*elided*/ any;
984
+ hasEventListeners(type: string): boolean;
985
+ off(type: string, fn: unknown, context?: unknown): /*elided*/ any;
986
+ fire(type: string, data?: unknown, target?: unknown): /*elided*/ any;
987
+ };
988
+ } & typeof SwipableBase;
989
+ declare class Swipable extends Swipable_base {
990
+ constructor(...args: ConstructorParameters<typeof SwipableBase>);
991
+ }
992
+
993
+ interface MessageOptions {
994
+ width: number;
995
+ height: number;
996
+ message_class: string;
997
+ message_icon_class: string;
998
+ [key: string]: unknown;
999
+ }
1000
+ declare class MessageBase {
1001
+ "_el": Record<string, HTMLElement>;
1002
+ "options": MessageOptions;
1003
+ "data": Record<string, unknown>;
1004
+ "animator": Record<string, unknown>;
1005
+ "fire": EventedInstance["fire"];
1006
+ constructor(data?: Record<string, unknown>, options?: Record<string, unknown>, add_to_container?: HTMLElement);
1007
+ updateMessage(t: string): void;
1008
+ _updateMessage(t?: string): void;
1009
+ _onMouseClick(): void;
1010
+ _initLayout(): void;
1011
+ _initEvents(): void;
1012
+ }
1013
+ declare const Message_base: {
1014
+ new (...args: any[]): {
1015
+ show(animate?: unknown): void;
1016
+ hide(): void;
1017
+ addTo(container: HTMLElement): /*elided*/ any;
1018
+ removeFrom(container: HTMLElement): /*elided*/ any;
1019
+ setPosition(pos: Record<string, number>, el?: HTMLElement): /*elided*/ any;
1020
+ onLoaded(): void;
1021
+ onAdd(): void;
1022
+ onRemove(): void;
1023
+ _el: Record<string, HTMLElement>;
1024
+ data?: unknown;
1025
+ on: (type: string, fn: unknown, context?: unknown) => unknown;
1026
+ off: (type: string, fn: unknown, context?: unknown) => unknown;
1027
+ fire: (type: string, data?: unknown, target?: unknown) => unknown;
1028
+ hasEventListeners: (type: string) => boolean;
1029
+ };
1030
+ } & {
1031
+ new (...args: any[]): {
1032
+ _vco_events?: Record<string, {
1033
+ action: unknown;
1034
+ context: unknown;
1035
+ }[]>;
1036
+ on(type: string, fn: unknown, context?: unknown): /*elided*/ any;
1037
+ hasEventListeners(type: string): boolean;
1038
+ off(type: string, fn: unknown, context?: unknown): /*elided*/ any;
1039
+ fire(type: string, data?: unknown, target?: unknown): /*elided*/ any;
1040
+ };
1041
+ } & typeof MessageBase;
1042
+ declare class Message extends Message_base {
1043
+ constructor(...args: ConstructorParameters<typeof MessageBase>);
1044
+ }
1045
+
1046
+ interface StorySliderOptions {
1047
+ id?: string;
1048
+ layout: string;
1049
+ width: number;
1050
+ height: number;
1051
+ default_bg_color: {
1052
+ r: number;
1053
+ g: number;
1054
+ b: number;
1055
+ };
1056
+ slide_padding_lr: number;
1057
+ start_at_slide: number;
1058
+ slide_default_fade: string;
1059
+ duration: number;
1060
+ ease: unknown;
1061
+ skinny_size?: number;
1062
+ call_to_action?: boolean;
1063
+ call_to_action_text?: string;
1064
+ dragging?: boolean;
1065
+ trackResize?: boolean;
1066
+ [key: string]: unknown;
1067
+ }
1068
+ interface SlideBackgroundChange {
1069
+ color_value?: string;
1070
+ image?: boolean;
1071
+ }
1072
+ declare class StorySliderBase {
1073
+ "_el": Record<string, HTMLElement>;
1074
+ "_nav": {
1075
+ previous: SlideNav;
1076
+ next: SlideNav;
1077
+ };
1078
+ "slide_spacing": number;
1079
+ "_slides": Slide[];
1080
+ "_swipable": Swipable;
1081
+ "preloadTimer": ReturnType<typeof setTimeout>;
1082
+ "_message": Message;
1083
+ "current_slide": number;
1084
+ "current_bg_color": string | null;
1085
+ "data": Partial<StorymapData>;
1086
+ "options": StorySliderOptions;
1087
+ "animator": AnimationHandle | null;
1088
+ "animator_background": AnimationHandle | null;
1089
+ "fire": EventedInstance["fire"];
1090
+ "_loaded": boolean;
1091
+ "hasEventListeners": EventedInstance["hasEventListeners"];
1092
+ constructor(elem: HTMLElement | string, data: Partial<StorymapData>, options?: Partial<StorySliderOptions>, init?: boolean);
1093
+ init(): void;
1094
+ updateDisplay(w?: number, h?: number, a?: unknown, l?: string): void;
1095
+ createSlide(d: StorymapSlide): void;
1096
+ createSlides(array: StorymapData["slides"]): void;
1097
+ _createSlides(array: StorymapData["slides"]): void;
1098
+ _createSlide(d: StorymapSlide, title_slide?: boolean): void;
1099
+ _addSlide(slide: Slide): void;
1100
+ goToId(n: string | number, fast?: boolean, displayupdate?: boolean): void;
1101
+ goTo(n: number, fast?: boolean, displayupdate?: boolean): void;
1102
+ preloadSlides(): void;
1103
+ getNavInfo(slide: Slide): {
1104
+ title: string;
1105
+ description: string;
1106
+ };
1107
+ next(): void;
1108
+ previous(): void;
1109
+ showNav(nav_obj: SlideNav, show: boolean): void;
1110
+ changeBackground(bg: SlideBackgroundChange): void;
1111
+ fadeInBackground(bg_css: string): void;
1112
+ _updateDisplay(width?: number, height?: number, animate?: unknown, layout?: string): void;
1113
+ _introInterface(): void;
1114
+ _initLayout(): void;
1115
+ _initEvents(): void;
1116
+ _onKeyDown(e: Event): void;
1117
+ _initData(): void;
1118
+ _onBackgroundChange(e: SlideBackgroundChange): void;
1119
+ _onMessageClick(e?: unknown): void;
1120
+ _onSwipeNoDirection(e?: unknown): void;
1121
+ _onNavigation(e: {
1122
+ direction: string;
1123
+ }): void;
1124
+ _onSlideAdded(e?: unknown): void;
1125
+ _onSlideChange(displayupdate?: boolean): void;
1126
+ _onLoaded(): void;
1127
+ }
1128
+ declare const StorySlider_base: {
1129
+ new (...args: any[]): {
1130
+ _vco_events?: Record<string, {
1131
+ action: unknown;
1132
+ context: unknown;
1133
+ }[]>;
1134
+ on(type: string, fn: unknown, context?: unknown): /*elided*/ any;
1135
+ hasEventListeners(type: string): boolean;
1136
+ off(type: string, fn: unknown, context?: unknown): /*elided*/ any;
1137
+ fire(type: string, data?: unknown, target?: unknown): /*elided*/ any;
1138
+ };
1139
+ } & typeof StorySliderBase;
1140
+ declare class StorySlider extends StorySlider_base {
1141
+ constructor(...args: ConstructorParameters<typeof StorySliderBase>);
1142
+ }
1143
+
1144
+ type StoryMapListener = (e: unknown) => void;
1145
+ /**
1146
+ * Interactive StoryMap viewer.
1147
+ *
1148
+ * Renders a storymap JSON document (or a IIIF Presentation 3 manifest) into an
1149
+ * element: an OpenLayers map on one side and a slide slider on the other.
1150
+ *
1151
+ * @example
1152
+ * ```ts
1153
+ * import { StoryMap } from "storymapjs";
1154
+ * // from an inline data object
1155
+ * const map = new StoryMap("embed", { storymap: { ... } }, { start_at_slide: 2 });
1156
+ * // or straight from a source file (storymap JSON or IIIF manifest)
1157
+ * const map2 = new StoryMap(document.getElementById("embed"), "./my-storymap.json");
1158
+ * ```
1159
+ */
1160
+ declare class StoryMapBase {
1161
+ "_loaded": {
1162
+ storyslider: boolean;
1163
+ map: boolean;
1164
+ };
1165
+ "on": EventedInstance["on"];
1166
+ "version": string;
1167
+ "ready": boolean;
1168
+ "_el": {
1169
+ container: HTMLElement;
1170
+ menubar: HTMLElement;
1171
+ map: HTMLElement;
1172
+ storyslider: HTMLElement;
1173
+ };
1174
+ "_storyslider": StorySlider;
1175
+ "_map": OpenLayers;
1176
+ "map": Map$1;
1177
+ "_menubar": MenuBar;
1178
+ "data": StorymapData;
1179
+ "options": StorymapOptions;
1180
+ "current_slide": number;
1181
+ "animator_map": AnimationHandle | null;
1182
+ "animator_storyslider": AnimationHandle | null;
1183
+ "_autoplay_timer": ReturnType<typeof setTimeout> | null;
1184
+ "_autoplay_stopped": boolean;
1185
+ "_hash_initialized": boolean;
1186
+ /** the data source was a IIIF Presentation manifest (legacy zoomify options are ignored) */
1187
+ "_data_from_manifest": boolean;
1188
+ "_resize_observer": ResizeObserver | null;
1189
+ "_resize_timer": ReturnType<typeof setTimeout> | null;
1190
+ "fire": EventedInstance["fire"];
1191
+ "hasEventListeners": EventedInstance["hasEventListeners"];
1192
+ /**
1193
+ * Create a StoryMap inside the given element.
1194
+ *
1195
+ * @param elem - The container element, or its DOM id.
1196
+ * @param data - Either an inline storymap document (`{ storymap: ... }`),
1197
+ * an inline IIIF Presentation 3 manifest, or the URL of a source file
1198
+ * (storymap JSON or IIIF manifest) that is fetched automatically.
1199
+ * @param options - Optional {@link StorymapOptions} overrides (map type,
1200
+ * lines, fonts, animation, raw OpenLayers options via `map_options`...).
1201
+ * @param listeners - Optional event listeners keyed by event name
1202
+ * (`change`, `title`, `loaded`, ...) attached on creation.
1203
+ */
1204
+ constructor(elem: string | HTMLElement, data: string | StorymapDataWrapper | Record<string, unknown>, options?: Partial<StorymapOptions>, listeners?: Record<string, StoryMapListener | StoryMapListener[]>);
1205
+ _initData(data: string | StorymapDataWrapper | Record<string, unknown>): void;
1206
+ _loadDataFromUrl(url: string, source: string): Promise<void>;
1207
+ _initOptions(): void;
1208
+ _loadLanguage(): void;
1209
+ _loadFontCss(): Promise<void>;
1210
+ _onFontLoaded(font: string): void;
1211
+ /**
1212
+ * Navigate to a slide by index.
1213
+ *
1214
+ * @param n - Zero-based slide index; the map animates to the slide's
1215
+ * marker (or the overview when `n` is 0 for storymaps with one).
1216
+ */
1217
+ goTo(n: number): void;
1218
+ /**
1219
+ * Re-measure the container and re-layout the map, slider and menubar.
1220
+ * Called automatically on resize (see the `trackResize` option).
1221
+ */
1222
+ updateDisplay(): void;
1223
+ /**
1224
+ * Change a single map option at runtime and apply its effect immediately.
1225
+ *
1226
+ * Runtime-changeable options: `map_type` (rebuilds the tile layer),
1227
+ * `show_lines`, `line_color`, `line_color_inactive`, `line_weight`,
1228
+ * `line_opacity`, `line_dash`, `line_join`, `line_follows_path`,
1229
+ * `show_history_line` (restyled instantly), `map_center_offset` (applied on
1230
+ * the next navigation), `duration`, `ease`, `calculate_zoom`,
1231
+ * `map_background_color`. All other options only take effect on the next
1232
+ * navigation or require re-creating the StoryMap.
1233
+ */
1234
+ setMapOption(name: string, value: unknown): void;
1235
+ /**
1236
+ * Change several map options at runtime (see setMapOption).
1237
+ */
1238
+ setMapOptions(options: Partial<StorymapOptions>): void;
1239
+ _initLayout(): void;
1240
+ _initEvents(): void;
1241
+ _updateDisplay(map_height?: number, animate?: boolean, d?: number): void;
1242
+ _onDataLoaded(e?: unknown): void;
1243
+ _startAutoplay(): void;
1244
+ _scheduleAutoplay(): void;
1245
+ _stopAutoplay(): void;
1246
+ /** Keep the URL hash in sync with the current slide (#slide-N). */
1247
+ _syncHash(): void;
1248
+ /** A #slide-N hash deep-links the storymap (applied on load + hashchange). */
1249
+ _applyHashSlide(): boolean;
1250
+ _initResizeHandling(): void;
1251
+ /**
1252
+ * Resolve a caller-supplied map element (options.map_options.element).
1253
+ * The passed element is "replaced by the real one": it is adopted as the
1254
+ * map container (given the vco-map class) and moved into place between
1255
+ * the menubar and the story slider.
1256
+ */
1257
+ _resolveMapElement(): HTMLElement | null;
1258
+ _onTitle(e: unknown): void;
1259
+ _onColorChange(e: {
1260
+ color?: unknown;
1261
+ image?: unknown;
1262
+ }): void;
1263
+ _onSlideChange(e: {
1264
+ current_slide: number;
1265
+ }): void;
1266
+ _onMapChange(e: {
1267
+ current_marker: number;
1268
+ }): void;
1269
+ _updateProgress(): void;
1270
+ _onOverview(e?: unknown): void;
1271
+ /**
1272
+ * Toggle the native fullscreen API on the storymap container and keep the
1273
+ * menubar button state in sync.
1274
+ */
1275
+ _onFullscreenToggle(e?: unknown): void;
1276
+ _onFullscreenChange(): void;
1277
+ _onBackToStart(e?: unknown): void;
1278
+ _onMenuBarCollapse(e: {
1279
+ y: number;
1280
+ }): void;
1281
+ _onMapLoaded(): void;
1282
+ _onStorySliderLoaded(): void;
1283
+ /**
1284
+ * Compute and display the great-circle distance of the marker route
1285
+ * (issue #341); hidden when `show_distance` is off.
1286
+ */
1287
+ _updateDistance(): void;
1288
+ _onLoaded(): void;
1289
+ }
1290
+ declare const StoryMap_base: {
1291
+ new (...args: any[]): {
1292
+ _vco_events?: Record<string, {
1293
+ action: unknown;
1294
+ context: unknown;
1295
+ }[]>;
1296
+ on(type: string, fn: unknown, context?: unknown): /*elided*/ any;
1297
+ hasEventListeners(type: string): boolean;
1298
+ off(type: string, fn: unknown, context?: unknown): /*elided*/ any;
1299
+ fire(type: string, data?: unknown, target?: unknown): /*elided*/ any;
1300
+ };
1301
+ } & typeof StoryMapBase;
1302
+ declare class StoryMap extends StoryMap_base {
1303
+ /**
1304
+ * The library base path (the directory containing the module).
1305
+ * Derived from `import.meta.url`, which works both for the source module
1306
+ * (src/main.ts) and the built ESM bundle (js/storymap.js).
1307
+ */
1308
+ static SCRIPT_PATH: string;
1309
+ constructor(...args: ConstructorParameters<typeof StoryMapBase>);
1310
+ }
1311
+
1312
+ interface LoadOptions {
1313
+ /** Abort the load (removes the element, rejects the promise). */
1314
+ signal?: AbortSignal;
1315
+ }
1316
+ /**
1317
+ * Append one stylesheet to the document head.
1318
+ *
1319
+ * @param url - The stylesheet URL.
1320
+ * @param options - Optional AbortSignal to cancel an in-flight load.
1321
+ * @returns Resolves when the stylesheet has loaded, rejects on error or abort.
1322
+ */
1323
+ declare function loadCSS(url: string, options?: LoadOptions): Promise<void>;
1324
+
1325
+ /**
1326
+ * Resolve the media handler for a slide's media object: matches the URL (and
1327
+ * optional explicit `type`) against the supported media types — YouTube,
1328
+ * Vimeo, images, audio, video, ...
1329
+ *
1330
+ * @param m - The slide media definition.
1331
+ * @returns The matching media type entry, or `false` for unknown media.
1332
+ */
1333
+ declare function MediaType(m: StorymapSlideMedia): MediaTypeMatch | false;
1334
+
1335
+ interface LanguageEntry {
1336
+ buttons?: Record<string, string>;
1337
+ messages?: Record<string, string>;
1338
+ [key: string]: unknown;
1339
+ }
1340
+ /**
1341
+ * Switch the active UI language.
1342
+ *
1343
+ * @param code - A locale code for which a locale file exists (e.g. `"en"`).
1344
+ * @returns The language entry that is now active.
1345
+ */
1346
+ declare function setLanguage(code: string): LanguageEntry;
1347
+
1348
+ interface StorymapError {
1349
+ path: string;
1350
+ message: string;
1351
+ }
1352
+ /** Validate storymap JSON (the object containing a "storymap" property). */
1353
+ declare function validateStorymap(data: unknown): StorymapError[];
1354
+ /** Validate and report all errors to the JavaScript console. Returns true when valid. */
1355
+ declare function validateStorymapAndReport(data: unknown, source?: string): boolean;
1356
+
1357
+ export { MediaType, StoryMap, loadCSS, setLanguage, validateStorymap, validateStorymapAndReport };