@minmaps-dev/mm-web-sdk 1.0.0-rc.33 → 1.0.0-rc.35
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 +4 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +875 -65
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +1 -1
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.ts +59 -14
- package/dist/react.js +1 -1
- package/dist/react.js.map +1 -1
- package/package.json +3 -2
- package/src/themes/alt3-hybrid-style.json +922 -364
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IControl, ControlPosition, StyleSpecification
|
|
1
|
+
import { Map, IControl, ControlPosition, StyleSpecification } from 'maplibre-gl';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Represents a floor in a building
|
|
@@ -14,6 +14,10 @@ interface Floor {
|
|
|
14
14
|
mapId?: string | number;
|
|
15
15
|
/** Display name of the floor */
|
|
16
16
|
name: string;
|
|
17
|
+
/** Short display name of the floor (e.g. "L2"). Optional: JACS leaves it
|
|
18
|
+
* unset on plenty of floors, and `JacsDataProvider` maps a blank one to
|
|
19
|
+
* `undefined` rather than inventing a value. */
|
|
20
|
+
shortName?: string;
|
|
17
21
|
/** Floor sequence/order (e.g., -1 for basement, 0 for ground, 1 for first floor) */
|
|
18
22
|
sequence?: number;
|
|
19
23
|
/** Associated map data */
|
|
@@ -29,6 +33,7 @@ interface Floor {
|
|
|
29
33
|
interface FloorMetadata {
|
|
30
34
|
id: string | number;
|
|
31
35
|
name: string;
|
|
36
|
+
shortName?: string;
|
|
32
37
|
sequence?: number;
|
|
33
38
|
isDefault?: boolean;
|
|
34
39
|
isActive?: boolean;
|
|
@@ -51,6 +56,17 @@ interface POI {
|
|
|
51
56
|
floorId: string | number;
|
|
52
57
|
/** Category/type of amenity (e.g., 'restroom', 'elevator') */
|
|
53
58
|
amenityType?: string;
|
|
59
|
+
/** Locale-stable classification text (name + type + keywords, frozen at
|
|
60
|
+
* load before any locale patch can translate them). Copied from the
|
|
61
|
+
* source `Amenity.classifyText`; used by `amenityCategoryFor`/rank
|
|
62
|
+
* instead of the live, possibly-translated fields. See `Amenity.classifyText`. */
|
|
63
|
+
classifyText?: string;
|
|
64
|
+
/** Which amenity icon layer this POI renders in — `'connector'`,
|
|
65
|
+
* `'entrance'`, `'parking'`, `'bus'`, `'information'` or `'other'`.
|
|
66
|
+
* Derived from the amenity's connector flag, name, type and keywords;
|
|
67
|
+
* emitted as the `amenityCategory` feature property the theme filters on.
|
|
68
|
+
* Amenities only. See `amenityCategoryFor`. */
|
|
69
|
+
amenityCategory?: 'connector' | 'entrance' | 'parking' | 'bus' | 'information' | 'other';
|
|
54
70
|
/** Search keywords */
|
|
55
71
|
keywords?: string[];
|
|
56
72
|
/** Additional properties */
|
|
@@ -98,6 +114,17 @@ interface Amenity {
|
|
|
98
114
|
waypoints?: Waypoint[];
|
|
99
115
|
/** Amenity type/category */
|
|
100
116
|
type?: string;
|
|
117
|
+
/**
|
|
118
|
+
* Locale-stable snapshot of `name + type + keywords`, captured once from
|
|
119
|
+
* the `/all` payload before `applyLocale` ever runs. `amenityCategoryFor`
|
|
120
|
+
* and the icon-rank heuristics in `poi.ts` match hard-coded English
|
|
121
|
+
* vocabulary against those fields; `name`/`keywords` are legitimately
|
|
122
|
+
* overwritten with translated text on a language switch
|
|
123
|
+
* (`LOCALIZED_FIELDS.amenity`), which reclassified every translated
|
|
124
|
+
* amenity to `'other'`/tier-3 and dropped its icon until the next zoom
|
|
125
|
+
* recomputed the rank gate. Classification reads this frozen copy instead.
|
|
126
|
+
*/
|
|
127
|
+
classifyText?: string;
|
|
101
128
|
/** Extended properties */
|
|
102
129
|
extensors?: Record<string, unknown>;
|
|
103
130
|
}
|
|
@@ -113,22 +140,34 @@ interface Destination {
|
|
|
113
140
|
waypoints?: Waypoint[];
|
|
114
141
|
/** Category/classification */
|
|
115
142
|
category?: string;
|
|
143
|
+
/** Room number — the CMS's "Room Number" field. A **real JACS column**, not
|
|
144
|
+
* one of the `mm_` stand-in extensors, so it arrives on the entity rather
|
|
145
|
+
* than in `extensors`. Surfaced as `getPOIDetails().roomNumber`. */
|
|
146
|
+
unitNumber?: string | null;
|
|
147
|
+
/** Search keywords */
|
|
148
|
+
keywords?: string[];
|
|
116
149
|
/** Additional properties */
|
|
117
150
|
properties?: Record<string, unknown>;
|
|
118
|
-
/**
|
|
119
|
-
*
|
|
120
|
-
*
|
|
151
|
+
/** The CMS "Location Image" — a photo or logo for the popover, not a map
|
|
152
|
+
* marker. JACS `/all` fullcall serves this as
|
|
153
|
+
* `{ items: [{ resourceType, mimeType, path }] }`; the legacy/basic shape is
|
|
154
|
+
* `[{ locales: [{ uriPath }] }]`. `destinationImageSrc` handles both, and
|
|
155
|
+
* surfaces the result on `sdk.getPOIDetails(poi).imageUrl`. */
|
|
121
156
|
uris?: unknown;
|
|
122
|
-
/**
|
|
157
|
+
/** Inline SVG for the uploaded image, embedded by JACS `/all`. Preferred over
|
|
158
|
+
* fetching `uris[].path` — no network round-trip. */
|
|
159
|
+
svg?: string;
|
|
160
|
+
/** Free-form CMS metadata. */
|
|
123
161
|
extensors?: Record<string, unknown>;
|
|
124
|
-
/**
|
|
125
|
-
*
|
|
126
|
-
*
|
|
162
|
+
/** @deprecated Read by nothing in the SDK as of rc.34.
|
|
163
|
+
*
|
|
164
|
+
* JACS still serves the old map-manager "Label Display" mode
|
|
165
|
+
* (`0` Hidden · `1` Label · `2` Image), but the CMS removed the picker and
|
|
166
|
+
* pins every write to `1`. Rows authored before that keep a stale `0`/`2`
|
|
167
|
+
* the author can no longer change, so honouring the field would hide labels
|
|
168
|
+
* with no way to bring them back. Destinations always render dot + text
|
|
169
|
+
* label; the uploaded image goes to the popover instead. */
|
|
127
170
|
displayMode?: number;
|
|
128
|
-
/** Runtime-assigned map-image id, decorated in place by
|
|
129
|
-
* `DestinationIcons.register` (only for `displayMode === 2`).
|
|
130
|
-
* Read by the POI builder + theme layer. */
|
|
131
|
-
iconId?: string;
|
|
132
171
|
}
|
|
133
172
|
/**
|
|
134
173
|
* Waypoint - a specific point location
|
|
@@ -206,17 +245,16 @@ type WayfindCenterMode = 'none' | 'destination' | 'route';
|
|
|
206
245
|
/**
|
|
207
246
|
* Per-call routing preferences forwarded to the wayfinding provider.
|
|
208
247
|
*
|
|
209
|
-
* - `
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
248
|
+
* - `avoidStairs` — hard-filter stairs from the graph. Accessibility
|
|
249
|
+
* preference otherwise comes from the CMS's per-path-type `weight`
|
|
250
|
+
* (elevators score low, stairs/escalators score high) — see
|
|
251
|
+
* `data/wayfinding/weights.ts` — not from a caller-supplied flag.
|
|
213
252
|
*
|
|
214
253
|
* The bundled stub provider doesn't compute routes; consumers wire a real
|
|
215
|
-
* provider (see `mm-web-sdk-example/lib/wayfinding`) that reads
|
|
216
|
-
*
|
|
254
|
+
* provider (see `mm-web-sdk-example/lib/wayfinding`) that reads this
|
|
255
|
+
* flag when building edge weights.
|
|
217
256
|
*/
|
|
218
257
|
type RoutingOptions = {
|
|
219
|
-
accessible?: boolean;
|
|
220
258
|
avoidStairs?: boolean;
|
|
221
259
|
};
|
|
222
260
|
|
|
@@ -254,13 +292,18 @@ type StepBase = {
|
|
|
254
292
|
floorId: number | null;
|
|
255
293
|
/** Localized instruction text. */
|
|
256
294
|
text: string;
|
|
257
|
-
/** Total walking distance within this step, in
|
|
258
|
-
|
|
295
|
+
/** Total walking distance within this step, in feet (rounded). */
|
|
296
|
+
distanceFeet?: number;
|
|
259
297
|
/** Landmark name used for anchoring, if any. */
|
|
260
298
|
landmark?: string;
|
|
261
299
|
};
|
|
262
300
|
type DepartStep = StepBase & {
|
|
263
301
|
type: 'depart';
|
|
302
|
+
/** Which way the traveller turns before walking off, relative to the
|
|
303
|
+
* way they're facing at the origin. Absent when `originFacingBearing`
|
|
304
|
+
* wasn't supplied (direction unknowable) or when the route heads
|
|
305
|
+
* straight ahead. Consumers use it to pick the step's icon. */
|
|
306
|
+
initialTurn?: 'left' | 'right' | 'around';
|
|
264
307
|
};
|
|
265
308
|
type TurnStep = StepBase & {
|
|
266
309
|
type: 'turn-left' | 'turn-right' | 'u-turn';
|
|
@@ -339,16 +382,16 @@ type AmenityBadgeStyle = {
|
|
|
339
382
|
/** Ring width in logical px. Default `2`. */
|
|
340
383
|
ringWidth?: number;
|
|
341
384
|
};
|
|
342
|
-
type DestinationChipStyle = {
|
|
343
|
-
/** Chip fill colour. Default `'#FFFFFF'`. */
|
|
344
|
-
color?: string;
|
|
345
|
-
/** Chip border colour. Default navy `'#162e51'`. */
|
|
346
|
-
borderColor?: string;
|
|
347
|
-
/** Chip border width in logical px. Default `2`. */
|
|
348
|
-
borderWidth?: number;
|
|
349
|
-
};
|
|
350
385
|
interface SDKOptions {
|
|
351
386
|
debug?: boolean;
|
|
387
|
+
/**
|
|
388
|
+
* `window` key the SDK instance is published under while `debug` is on, so
|
|
389
|
+
* a running kiosk can be driven from devtools (`mm.debug.hide('labels')`,
|
|
390
|
+
* `mm.getMap()`). Defaults to `'mm'`. Pass another name to avoid a clash,
|
|
391
|
+
* or `false` to publish nothing even in debug mode. Ignored entirely when
|
|
392
|
+
* `debug` is off.
|
|
393
|
+
*/
|
|
394
|
+
debugGlobal?: string | false;
|
|
352
395
|
/**
|
|
353
396
|
* Initial theme. `'default'` uses the bundled hybrid 3D theme.
|
|
354
397
|
* `'high-contrast'` uses the WCAG-AA tuned theme. Pass a
|
|
@@ -375,6 +418,20 @@ interface SDKOptions {
|
|
|
375
418
|
* controls the automatic highlight on `routeReady`.
|
|
376
419
|
*/
|
|
377
420
|
routeStepHighlight?: boolean;
|
|
421
|
+
/**
|
|
422
|
+
* Whether restroom pins that are too close together to draw individually
|
|
423
|
+
* collapse into a single Material `wc` badge. Defaults to `true`.
|
|
424
|
+
*
|
|
425
|
+
* Venues author men's and women's restrooms as two amenities a few metres
|
|
426
|
+
* apart. Both are wayfinding-critical (rank 0) and both draw on a layer that
|
|
427
|
+
* doesn't allow icon overlap, so without this MapLibre resolves the collision
|
|
428
|
+
* by hiding one of them outright until the camera is very close in. Grouping
|
|
429
|
+
* shows one badge in their place and hands back *all* the members when it's
|
|
430
|
+
* tapped, so the consumer can offer directions to each.
|
|
431
|
+
*
|
|
432
|
+
* Set `false` to opt out and get the raw collision behaviour back.
|
|
433
|
+
*/
|
|
434
|
+
groupRestroomIcons?: boolean;
|
|
378
435
|
initialFloor?: string | number;
|
|
379
436
|
enableInteractions?: boolean;
|
|
380
437
|
customSprite?: string;
|
|
@@ -387,6 +444,16 @@ interface SDKOptions {
|
|
|
387
444
|
*/
|
|
388
445
|
wallThickness?: number;
|
|
389
446
|
boundsPadding?: BoundsPadding;
|
|
447
|
+
/**
|
|
448
|
+
* Caps how far a visitor can pan/zoom out. By default the SDK derives this
|
|
449
|
+
* from the venue's own bounds, scaled to 3x its width/height around the
|
|
450
|
+
* same center — enough room to pan around the building without drifting
|
|
451
|
+
* into an empty, un-tiled region. Pass a number to use a different
|
|
452
|
+
* multiplier (e.g. `1.5` for a tighter leash), explicit `[[west, south],
|
|
453
|
+
* [east, north]]` bounds to override entirely, or `false` to disable
|
|
454
|
+
* max-bounds clamping.
|
|
455
|
+
*/
|
|
456
|
+
maxBounds?: Bounds | number | false;
|
|
390
457
|
/**
|
|
391
458
|
* Pitch (deg) for the opening view, applied centred on the kiosk ("You
|
|
392
459
|
* are here"). Omit for top-down.
|
|
@@ -438,13 +505,20 @@ interface SDKOptions {
|
|
|
438
505
|
*/
|
|
439
506
|
connectorBadge?: AmenityBadgeStyle | false;
|
|
440
507
|
/**
|
|
441
|
-
*
|
|
442
|
-
*
|
|
443
|
-
*
|
|
444
|
-
*
|
|
445
|
-
*
|
|
508
|
+
* Badge for information-desk amenities (curated `information`/`info`
|
|
509
|
+
* icon). These render as their own visual class — a green disc with a
|
|
510
|
+
* white glyph by default — so information reads distinct from the gold
|
|
511
|
+
* service amenities. Pass `false` to fall them back into the regular gold
|
|
512
|
+
* badge, or an object to tune the disc / ring. When `amenityBadge` is
|
|
513
|
+
* `false`, information icons are badge-less too unless this is set
|
|
514
|
+
* explicitly.
|
|
515
|
+
*/
|
|
516
|
+
informationBadge?: AmenityBadgeStyle | false;
|
|
517
|
+
/**
|
|
518
|
+
* Glyph colour for information icons on their badge. Default white
|
|
519
|
+
* (matches `informationBadge`'s default green disc).
|
|
446
520
|
*/
|
|
447
|
-
|
|
521
|
+
informationIconColor?: string;
|
|
448
522
|
styleMode?: 'venueStyleUrl' | 'sdkTemplate';
|
|
449
523
|
templateOverrideMode?: 'colorsOnly' | 'colorsAndConstants' | 'all';
|
|
450
524
|
}
|
|
@@ -497,6 +571,230 @@ type SDKConfig = {
|
|
|
497
571
|
options?: SDKOptions;
|
|
498
572
|
};
|
|
499
573
|
|
|
574
|
+
type Visibility = 'visible' | 'none';
|
|
575
|
+
type DebugLayersDeps = {
|
|
576
|
+
getMap: () => Map | null;
|
|
577
|
+
/**
|
|
578
|
+
* Re-assert the visibility the SDK itself owns — floor layers, the POI
|
|
579
|
+
* category filter, the 2D/3D view mode. Called at the end of `reset()`,
|
|
580
|
+
* because restoring a captured `visibility` can't distinguish "the theme
|
|
581
|
+
* ships this visible" from "the SDK hid it because it belongs to another
|
|
582
|
+
* floor", and the naive restore would reveal every floor at once.
|
|
583
|
+
*/
|
|
584
|
+
reapplySdkState?: () => void;
|
|
585
|
+
log?: (...args: unknown[]) => void;
|
|
586
|
+
};
|
|
587
|
+
type LayerRow = {
|
|
588
|
+
id: string;
|
|
589
|
+
type: string;
|
|
590
|
+
visibility: Visibility;
|
|
591
|
+
/**
|
|
592
|
+
* What this layer's visibility was before we touched it — i.e. what the
|
|
593
|
+
* theme and the SDK want it to be. Equal to `visibility` for any layer we
|
|
594
|
+
* hold no override on. A UI wanting to show "is this group on" should judge
|
|
595
|
+
* only the layers whose `base` is `'visible'`: the rest (the 3D extrusions
|
|
596
|
+
* in flat mode, the 2D outlines outside it) aren't rendering by design, so
|
|
597
|
+
* counting them makes a healthy group look half-off.
|
|
598
|
+
*/
|
|
599
|
+
base: Visibility;
|
|
600
|
+
};
|
|
601
|
+
/**
|
|
602
|
+
* Console-facing layer inspector for demos, screenshots and debugging.
|
|
603
|
+
*
|
|
604
|
+
* Reachable as `sdk.debug`, and as `window.mm.debug` when
|
|
605
|
+
* `options.debug` is on (see `options.debugGlobal`).
|
|
606
|
+
*
|
|
607
|
+
* Two things make it more than a wrapper around `setLayoutProperty`:
|
|
608
|
+
*
|
|
609
|
+
* 1. **Selectors.** `hide('amenities')`, `hide('route-')`, `hide('/^poi-/')`
|
|
610
|
+
* and `hide('type:fill-extrusion')` all work, so you don't have to know
|
|
611
|
+
* the theme's layer ids to start poking at it.
|
|
612
|
+
* 2. **Overrides are sticky.** The SDK re-asserts layer visibility on floor
|
|
613
|
+
* changes, `setPOIFilter`, flat-mode toggles and theme swaps — all of which
|
|
614
|
+
* would otherwise wipe a manual toggle mid-demo. Every override is re-applied
|
|
615
|
+
* on `styledata`, so what you hid stays hidden until `reset()`.
|
|
616
|
+
*/
|
|
617
|
+
declare class DebugLayers {
|
|
618
|
+
private deps;
|
|
619
|
+
/** layer id → visibility this API is asserting. */
|
|
620
|
+
private overrides;
|
|
621
|
+
/** layer id → visibility before we first touched it. */
|
|
622
|
+
private originals;
|
|
623
|
+
/** `${layer}|${prop}` → paint value before we first touched it. */
|
|
624
|
+
private paintOriginals;
|
|
625
|
+
private sticky;
|
|
626
|
+
private attachedTo;
|
|
627
|
+
/** Re-entrancy guard: our own `setLayoutProperty` fires `styledata`. */
|
|
628
|
+
private applying;
|
|
629
|
+
private readonly onStyleData;
|
|
630
|
+
constructor(deps: DebugLayersDeps);
|
|
631
|
+
/** Begin re-asserting overrides across style/floor changes. */
|
|
632
|
+
attach(map: Map): void;
|
|
633
|
+
detach(): void;
|
|
634
|
+
/**
|
|
635
|
+
* Every layer in the active style, newest-on-top last, with its current
|
|
636
|
+
* visibility. Pass a selector to narrow it (same grammar as `hide`).
|
|
637
|
+
*/
|
|
638
|
+
list(selector?: string): LayerRow[];
|
|
639
|
+
/** Just the ids currently rendering — the quickest "what am I looking at". */
|
|
640
|
+
visible(): string[];
|
|
641
|
+
/** Group name → the ids it resolves to *in the active style*. */
|
|
642
|
+
groups(): Record<string, string[]>;
|
|
643
|
+
/** Hide every layer the selectors resolve to. Returns the ids affected. */
|
|
644
|
+
hide(...selectors: string[]): string[];
|
|
645
|
+
/**
|
|
646
|
+
* **Force** every resolved layer visible — including ones the SDK
|
|
647
|
+
* deliberately keeps off: the 3D extrusions while flat mode is on, the 2D
|
|
648
|
+
* outlines while it isn't, every floor but the active one. Forcing those
|
|
649
|
+
* renders two representations of the same geometry at once, or every floor
|
|
650
|
+
* stacked, and the map looks wrong.
|
|
651
|
+
*
|
|
652
|
+
* So this is *not* the way to undo a `hide()` — use `restore()`, which puts
|
|
653
|
+
* each layer back to what it was rather than blanket-revealing the group.
|
|
654
|
+
* Reach for `show()` only when you actually mean "reveal this regardless".
|
|
655
|
+
*/
|
|
656
|
+
show(...selectors: string[]): string[];
|
|
657
|
+
/**
|
|
658
|
+
* Undo our overrides on these layers: each goes back to the visibility it
|
|
659
|
+
* had before we first touched it, and control returns to the SDK (floor
|
|
660
|
+
* layers, POI filter, view mode re-assert afterwards).
|
|
661
|
+
*
|
|
662
|
+
* This is the correct inverse of `hide()`. A group is rarely uniformly
|
|
663
|
+
* visible to begin with — `rooms` hides either the 2D outline or the 3D
|
|
664
|
+
* extrusion depending on view mode, and every floor layer but the active
|
|
665
|
+
* one is off — so `hide()` then `show()` does not round-trip, but `hide()`
|
|
666
|
+
* then `restore()` does.
|
|
667
|
+
*
|
|
668
|
+
* Returns the ids that actually had an override; layers we never touched
|
|
669
|
+
* are left alone.
|
|
670
|
+
*/
|
|
671
|
+
restore(...selectors: string[]): string[];
|
|
672
|
+
/** Flip each resolved layer independently. Returns the ids affected. */
|
|
673
|
+
toggle(...selectors: string[]): string[];
|
|
674
|
+
/**
|
|
675
|
+
* Show only what the selectors resolve to — everything else is hidden
|
|
676
|
+
* (except `background`, which is just the canvas colour). The one-liner for
|
|
677
|
+
* "which layer is drawing that thing".
|
|
678
|
+
*
|
|
679
|
+
* The kept set is *restored*, not forced: anything we'd previously hidden
|
|
680
|
+
* comes back, but a layer the theme ships hidden stays hidden. Soloing must
|
|
681
|
+
* not invent geometry that never renders normally — see `show()`.
|
|
682
|
+
*/
|
|
683
|
+
solo(...selectors: string[]): string[];
|
|
684
|
+
/**
|
|
685
|
+
* Set a paint property — `paint('units-fill', 'fill-color', '#f00')`. The
|
|
686
|
+
* original value is captured so `reset()` puts it back. Not sticky: unlike
|
|
687
|
+
* visibility, a theme swap rebuilds paint from the new style and re-applying
|
|
688
|
+
* a captured expression across themes is exactly the bug `setTheme` had to
|
|
689
|
+
* fix. Re-run it after a swap if you need it back.
|
|
690
|
+
*/
|
|
691
|
+
paint(selector: string, prop: string, value: unknown): string[];
|
|
692
|
+
/**
|
|
693
|
+
* Drop every override and paint change, then let the SDK re-assert the
|
|
694
|
+
* visibility it owns (floor layers, POI filter, view mode). Back to the map
|
|
695
|
+
* you'd have had without touching anything.
|
|
696
|
+
*/
|
|
697
|
+
reset(): void;
|
|
698
|
+
/**
|
|
699
|
+
* Hand the layers we just released back to the SDK, then re-assert whatever
|
|
700
|
+
* overrides are still standing.
|
|
701
|
+
*
|
|
702
|
+
* The second half is not belt-and-braces. The SDK's re-assert passes are
|
|
703
|
+
* all-or-nothing: with no POI filter active, `applyPOIFilter` writes
|
|
704
|
+
* `visible` to *every* POI category layer, and the floor / view-mode passes
|
|
705
|
+
* sweep their whole layer sets the same way. So releasing one group would
|
|
706
|
+
* un-hide every other group you'd hidden — hide labels, destinations and
|
|
707
|
+
* amenities, re-check one, and all three came back.
|
|
708
|
+
*
|
|
709
|
+
* Doing it here rather than waiting for the `styledata` the SDK's writes
|
|
710
|
+
* trigger also keeps it synchronous: MapLibre fires that on a later frame,
|
|
711
|
+
* so a UI reading visibility straight after this call would otherwise see —
|
|
712
|
+
* and render — the clobbered state.
|
|
713
|
+
*/
|
|
714
|
+
private handBackToSdk;
|
|
715
|
+
/**
|
|
716
|
+
* The current override set as a plain object — save it, paste it back with
|
|
717
|
+
* `apply()` to reproduce the exact same framing for a screenshot later.
|
|
718
|
+
*/
|
|
719
|
+
snapshot(): Record<string, Visibility>;
|
|
720
|
+
/** Apply a `snapshot()` (or any layer-id → visibility map). */
|
|
721
|
+
apply(snapshot: Record<string, Visibility>): string[];
|
|
722
|
+
/**
|
|
723
|
+
* Stop (or resume) re-asserting overrides when the style changes. Turn it
|
|
724
|
+
* off if you want a floor switch or `setPOIFilter` to win over what you
|
|
725
|
+
* toggled by hand.
|
|
726
|
+
*/
|
|
727
|
+
setSticky(enabled: boolean): boolean;
|
|
728
|
+
/** Console cheat sheet. */
|
|
729
|
+
help(): Array<{
|
|
730
|
+
call: string;
|
|
731
|
+
does: string;
|
|
732
|
+
}>;
|
|
733
|
+
/**
|
|
734
|
+
* Resolve one selector to layer ids present in the active style, tried in
|
|
735
|
+
* order: group name → exact layer id → `type:<layer type>` → `/regex/` →
|
|
736
|
+
* case-insensitive substring on the id.
|
|
737
|
+
*/
|
|
738
|
+
resolve(selector: string): string[];
|
|
739
|
+
private resolveAll;
|
|
740
|
+
private set;
|
|
741
|
+
/**
|
|
742
|
+
* Put these layers back to their pre-override visibility and forget them.
|
|
743
|
+
* Callers decide whether to follow up with `reapplySdkState` — `restore()`
|
|
744
|
+
* and `reset()` do, `solo()` deliberately doesn't.
|
|
745
|
+
*/
|
|
746
|
+
private restoreVisibility;
|
|
747
|
+
/** Write one layer's visibility and remember it as an override. */
|
|
748
|
+
private write;
|
|
749
|
+
/**
|
|
750
|
+
* Re-assert overrides after something else rewrote layer visibility. Only
|
|
751
|
+
* writes when the current value actually differs, so this doesn't feed
|
|
752
|
+
* itself through the `styledata` it triggers.
|
|
753
|
+
*/
|
|
754
|
+
private reapply;
|
|
755
|
+
private styleLayers;
|
|
756
|
+
private visibilityOf;
|
|
757
|
+
/**
|
|
758
|
+
* MapLibre throws from these getters/setters while a style is mid-swap (the
|
|
759
|
+
* layer exists in `getStyle()` but its owner is being replaced). A debug tool
|
|
760
|
+
* that can break the map it's inspecting is worse than useless.
|
|
761
|
+
*/
|
|
762
|
+
private safe;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
type LayerAudit = {
|
|
766
|
+
/** `featureType` values the CMS permits for this customer. */
|
|
767
|
+
allowed: string[];
|
|
768
|
+
/** `featureType` values actually present in the loaded floors. */
|
|
769
|
+
inData: string[];
|
|
770
|
+
/** `featureType` values some theme layer filters on. */
|
|
771
|
+
inStyle: string[];
|
|
772
|
+
/**
|
|
773
|
+
* Drawn on a map but not in the customer's allowed list — a mis-authored
|
|
774
|
+
* or renamed layer. These render only by accident (if the theme happens to
|
|
775
|
+
* match the string) and are invisible otherwise.
|
|
776
|
+
*/
|
|
777
|
+
unauthorized: string[];
|
|
778
|
+
/**
|
|
779
|
+
* Present in the data and allowed, but no theme layer filters on it. The
|
|
780
|
+
* author drew something the map will never show.
|
|
781
|
+
*/
|
|
782
|
+
unstyled: string[];
|
|
783
|
+
/**
|
|
784
|
+
* The theme filters on it, but no loaded floor contains it. Dead weight in
|
|
785
|
+
* the style *for this venue* — another venue may well use it, so this is a
|
|
786
|
+
* prompt to check, not a delete list. Cross-reference `allowed`: a value
|
|
787
|
+
* that isn't in there either is dead everywhere for this customer.
|
|
788
|
+
*/
|
|
789
|
+
unused: string[];
|
|
790
|
+
/**
|
|
791
|
+
* Allowed by the CMS but no theme rule matches it, whether or not this
|
|
792
|
+
* venue happens to draw it. The SDK's total blind spot — an author can
|
|
793
|
+
* legitimately draw any of these and get nothing.
|
|
794
|
+
*/
|
|
795
|
+
allowedNotStyled: string[];
|
|
796
|
+
};
|
|
797
|
+
|
|
500
798
|
type LoggerFn = (...args: unknown[]) => void;
|
|
501
799
|
type AmenityManagerDeps = {
|
|
502
800
|
getVenue: () => any;
|
|
@@ -520,8 +818,13 @@ declare class AmenityManager {
|
|
|
520
818
|
* three times in a venue list); this collapses those into a single record
|
|
521
819
|
* with all its waypoints merged across floors.
|
|
522
820
|
*
|
|
523
|
-
* Also folds any duplicate-id records from the provider
|
|
524
|
-
*
|
|
821
|
+
* Also folds any duplicate-id records from the provider into a single entry
|
|
822
|
+
* so React lists don't trip on dup keys. This used to say those duplicates
|
|
823
|
+
* were "a CMS data bug" — they weren't. JACS returns one record per amenity;
|
|
824
|
+
* the SDK's own floor index pushed it once per waypoint, so an amenity with
|
|
825
|
+
* four placements on a floor came back four times. Fixed at the source in
|
|
826
|
+
* `jacsDataProvider.floorIdsForWaypoints`; the fold stays as a cheap guard
|
|
827
|
+
* for a provider that genuinely repeats an id.
|
|
525
828
|
*
|
|
526
829
|
* Use this for venue-wide browse UIs; pair it with `findClosestWaypoint`
|
|
527
830
|
* (on the SDK) to resolve a tap to the nearest physical instance.
|
|
@@ -533,6 +836,175 @@ declare class AmenityManager {
|
|
|
533
836
|
logKioskForFloor(floorId: Floor['id']): void;
|
|
534
837
|
}
|
|
535
838
|
|
|
839
|
+
/**
|
|
840
|
+
* The `mm_`-prefixed extensor keys the CMS reserves for fields JACS has no
|
|
841
|
+
* column for yet.
|
|
842
|
+
*
|
|
843
|
+
* This file is the read half of a cross-repo table: the write half is
|
|
844
|
+
* `cms/packages/map-manager/app/utils/reserved-extensors.js`, which owns the key
|
|
845
|
+
* names, the value encodings, and the rule that a default value is deleted
|
|
846
|
+
* rather than stored. Change them together.
|
|
847
|
+
*
|
|
848
|
+
* The `mm_` prefix is load-bearing on both sides. Authors can type anything into
|
|
849
|
+
* the CMS's free-form Properties editor, so an unprefixed key like
|
|
850
|
+
* `point_of_interest` could collide with a hand-entered one; the prefix also
|
|
851
|
+
* makes "is this key reserved?" a prefix scan rather than a hand-maintained list
|
|
852
|
+
* once JACS grows real columns and these are migrated away.
|
|
853
|
+
*
|
|
854
|
+
* Two things that look like they belong here and don't:
|
|
855
|
+
*
|
|
856
|
+
* - **Room number.** The CMS labels it "Room Number", but it writes the real
|
|
857
|
+
* `Destination.unitNumber` field, not an extensor. `getPOIDetails().roomNumber`
|
|
858
|
+
* reads that field (see `sdk.ts`).
|
|
859
|
+
* - **`mm_point_of_interest`.** Registered by the CMS and parsed here for
|
|
860
|
+
* completeness, but deliberately not surfaced on `getPOIDetails` — nothing has
|
|
861
|
+
* pinned down whether an unflagged destination should drop out of search, out
|
|
862
|
+
* of the map, or neither, and guessing wrong is worse than omitting it.
|
|
863
|
+
*/
|
|
864
|
+
declare const RESERVED_EXTENSOR_PREFIX = "mm_";
|
|
865
|
+
/** Weekly opening hours. Value shape and parser live in `openHours.ts`. */
|
|
866
|
+
declare const OPEN_HOURS_EXTENSOR_KEY = "mm_open_hours";
|
|
867
|
+
/** Phone number, with the extension folded into the same value. */
|
|
868
|
+
declare const PHONE_EXTENSOR_KEY = "mm_phone";
|
|
869
|
+
/** Alt text for the destination's uploaded Location Image. */
|
|
870
|
+
declare const IMAGE_ALT_EXTENSOR_KEY = "mm_image_alt";
|
|
871
|
+
/** Author-set "this is a point of interest" flag. Parsed, not surfaced. */
|
|
872
|
+
declare const POINT_OF_INTEREST_EXTENSOR_KEY = "mm_point_of_interest";
|
|
873
|
+
/**
|
|
874
|
+
* Which building on the campus the destination stands in.
|
|
875
|
+
*
|
|
876
|
+
* The venue's own `Building` record can't answer this: the CMS binds a venue to
|
|
877
|
+
* a single building and hangs the floor list off it, so a campus with a dozen
|
|
878
|
+
* numbered buildings has one `Building` and no way to say which one a room is
|
|
879
|
+
* in. The author types it as free text, and that text is what a kiosk prints —
|
|
880
|
+
* it is not a reference to anything, so don't try to resolve it against
|
|
881
|
+
* `venue.buildings`.
|
|
882
|
+
*/
|
|
883
|
+
declare const BUILDING_NAME_EXTENSOR_KEY = "mm_building_name";
|
|
884
|
+
interface DestinationPhone {
|
|
885
|
+
/** Exactly as the author typed it — `"(408) 300-9294"`. Deliberately not
|
|
886
|
+
* normalised: doing that properly across international formats needs a real
|
|
887
|
+
* phone library, and the CMS makes the same choice on the way in. */
|
|
888
|
+
number: string;
|
|
889
|
+
/** Internal extension digits, when there is one. */
|
|
890
|
+
ext?: string;
|
|
891
|
+
}
|
|
892
|
+
/**
|
|
893
|
+
* `"(408) 300-9294;ext=123"` → `{ number, ext }`. `null` when there's no number
|
|
894
|
+
* — including for the empty string, which is how JACS spells a deleted key.
|
|
895
|
+
*/
|
|
896
|
+
declare function parsePhone(raw: unknown): DestinationPhone | null;
|
|
897
|
+
/** Alt text for the Location Image, or `undefined` when the author set none. */
|
|
898
|
+
declare function parseImageAlt(raw: unknown): string | undefined;
|
|
899
|
+
/** The building name, or `undefined` when the author set none. */
|
|
900
|
+
declare function parseBuildingName(raw: unknown): string | undefined;
|
|
901
|
+
/** The point-of-interest flag. Absence means false — only the checked state is
|
|
902
|
+
* ever stored. */
|
|
903
|
+
declare function parsePointOfInterest(raw: unknown): boolean;
|
|
904
|
+
|
|
905
|
+
/**
|
|
906
|
+
* Weekly opening hours for a destination.
|
|
907
|
+
*
|
|
908
|
+
* JACS has no hours column, so the CMS ships the whole week in a single
|
|
909
|
+
* destination extensor — key `mm_open_hours`, value a JSON string:
|
|
910
|
+
*
|
|
911
|
+
* {"v":1,"days":{"mon":[["09:00","17:30"]],"sat":[],"sun":[["00:00","24:00"]]}}
|
|
912
|
+
*
|
|
913
|
+
* - Times are 24-hour `"HH:MM"` and **venue-local**; no timezone is recorded.
|
|
914
|
+
* - Each day maps to an array of `[open, close]` ranges. The editor exposes one
|
|
915
|
+
* range per day today, but the array shape leaves room for split shifts (a
|
|
916
|
+
* cafeteria that closes over the afternoon) and extra ranges round-trip.
|
|
917
|
+
* - An empty array — or a missing day — means closed.
|
|
918
|
+
* - `[["00:00","24:00"]]` means open 24 hours.
|
|
919
|
+
*
|
|
920
|
+
* This module owns the read half: parse the value (`parseOpenHours`) and derive
|
|
921
|
+
* the live open/closed state from it (`getOpenStatus`). The write half lives in
|
|
922
|
+
* the CMS (`map-manager`'s `utils/open-hours.js`) — the two must agree on the
|
|
923
|
+
* wire shape above, so change them together. The key itself is registered in
|
|
924
|
+
* `reservedExtensors.ts` alongside the CMS's other stand-in fields, mirroring
|
|
925
|
+
* the same split on the authoring side.
|
|
926
|
+
*/
|
|
927
|
+
|
|
928
|
+
/** Wire-format version this module understands. */
|
|
929
|
+
declare const OPEN_HOURS_VERSION = 1;
|
|
930
|
+
type DayKey = 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat' | 'sun';
|
|
931
|
+
/** Monday-first, matching the wire format's own day order. `getOpenStatus`
|
|
932
|
+
* reports `OpenHoursTransition.day` as one of these. */
|
|
933
|
+
declare const DAY_KEYS: readonly DayKey[];
|
|
934
|
+
/** One open→close stretch within a single day. 24-hour `"HH:MM"`, venue-local.
|
|
935
|
+
* `close` may be `"24:00"` (end of day); `open` never is. */
|
|
936
|
+
interface HoursRange {
|
|
937
|
+
open: string;
|
|
938
|
+
close: string;
|
|
939
|
+
}
|
|
940
|
+
/** A parsed week. Every day is present; a closed day is an empty array. */
|
|
941
|
+
interface OpenHours {
|
|
942
|
+
days: Record<DayKey, HoursRange[]>;
|
|
943
|
+
/** Open every minute of the week (a 24/7 emergency department, say). The
|
|
944
|
+
* status has no `closesAt` in this case — there is nothing to count down to. */
|
|
945
|
+
alwaysOpen: boolean;
|
|
946
|
+
}
|
|
947
|
+
/** A point in the week the status is counting toward. */
|
|
948
|
+
interface OpenHoursTransition {
|
|
949
|
+
/** Day the transition falls on, venue-local. */
|
|
950
|
+
day: DayKey;
|
|
951
|
+
/** 24-hour `"HH:MM"`, venue-local. Midnight is always `"00:00"` on the
|
|
952
|
+
* following day — `"24:00"` never surfaces here. */
|
|
953
|
+
time: string;
|
|
954
|
+
/** Whole minutes from `now`. */
|
|
955
|
+
minutesUntil: number;
|
|
956
|
+
/** Calendar days ahead: `0` today, `1` tomorrow. */
|
|
957
|
+
daysAhead: number;
|
|
958
|
+
}
|
|
959
|
+
interface OpenStatus {
|
|
960
|
+
/** Open right now. */
|
|
961
|
+
open: boolean;
|
|
962
|
+
/** Open every minute of the week — no closing time to show. */
|
|
963
|
+
alwaysOpen: boolean;
|
|
964
|
+
/** Open, and closing within `soonMinutes`. */
|
|
965
|
+
closingSoon: boolean;
|
|
966
|
+
/** Closed, and opening within `soonMinutes`. */
|
|
967
|
+
openingSoon: boolean;
|
|
968
|
+
/** When open: the end of the current stretch. Absent when `alwaysOpen`. */
|
|
969
|
+
closesAt?: OpenHoursTransition;
|
|
970
|
+
/** When closed: the next time it opens. Absent when no day is open. */
|
|
971
|
+
opensAt?: OpenHoursTransition;
|
|
972
|
+
}
|
|
973
|
+
interface OpenStatusOptions {
|
|
974
|
+
/** How near a transition counts as "soon". Default `30`. */
|
|
975
|
+
soonMinutes?: number;
|
|
976
|
+
/** IANA zone the hours are expressed in (`'America/Denver'`). Omit — the
|
|
977
|
+
* normal case for a kiosk standing in the venue — to read the host clock.
|
|
978
|
+
* An unrecognised zone falls back to the host clock rather than throwing. */
|
|
979
|
+
timeZone?: string;
|
|
980
|
+
}
|
|
981
|
+
/**
|
|
982
|
+
* Extensor value → a parsed week, or `null` when there is nothing usable.
|
|
983
|
+
*
|
|
984
|
+
* Accepts the stored JSON string or an already-parsed object. Anything
|
|
985
|
+
* unreadable — absent key, malformed JSON, no open day — is `null` rather than
|
|
986
|
+
* a throw, so a bad value costs the consumer an omitted section, not a crash.
|
|
987
|
+
*
|
|
988
|
+
* An unknown `v` is also `null`, deliberately. A future version could add
|
|
989
|
+
* holiday overrides or a timezone; reading only the `days` it recognises would
|
|
990
|
+
* let the SDK announce "Open" on a day the venue marked closed, and a confidently
|
|
991
|
+
* wrong answer at a kiosk is worse than a missing one.
|
|
992
|
+
*/
|
|
993
|
+
declare function parseOpenHours(raw: unknown): OpenHours | null;
|
|
994
|
+
/**
|
|
995
|
+
* The live open/closed state for a parsed week.
|
|
996
|
+
*
|
|
997
|
+
* Pure and time-explicit: pass the `now` you want evaluated (default: the
|
|
998
|
+
* moment of the call). Nothing is cached, so a consumer that wants a status
|
|
999
|
+
* that stays true — a kiosk card sitting open — re-calls this on a tick rather
|
|
1000
|
+
* than holding the result.
|
|
1001
|
+
*
|
|
1002
|
+
* Hours carry no timezone of their own, so they are read against the host clock
|
|
1003
|
+
* unless `options.timeZone` names the venue's zone. The kiosk case needs no
|
|
1004
|
+
* option: the machine stands in the building it is describing.
|
|
1005
|
+
*/
|
|
1006
|
+
declare function getOpenStatus(hours: OpenHours, now?: Date, options?: OpenStatusOptions): OpenStatus;
|
|
1007
|
+
|
|
536
1008
|
declare class MinuteMaps {
|
|
537
1009
|
private config;
|
|
538
1010
|
private map;
|
|
@@ -559,22 +1031,45 @@ declare class MinuteMaps {
|
|
|
559
1031
|
private floorsApi;
|
|
560
1032
|
private venue;
|
|
561
1033
|
private spriteKeys;
|
|
562
|
-
private readonly
|
|
1034
|
+
private readonly debugEnabled;
|
|
563
1035
|
private readonly logger;
|
|
1036
|
+
/**
|
|
1037
|
+
* Console-facing layer inspector — `sdk.debug.hide('labels')`,
|
|
1038
|
+
* `sdk.debug.solo('route')`, `sdk.debug.reset()`. Always present so demo
|
|
1039
|
+
* code can drive it; additionally reachable as `window.mm.debug` when
|
|
1040
|
+
* `options.debug` is on. See `DebugLayers`.
|
|
1041
|
+
*/
|
|
1042
|
+
readonly debug: DebugLayers;
|
|
1043
|
+
/** The `window` key `debug` mode installed this instance under, if any. */
|
|
1044
|
+
private debugGlobalKey;
|
|
564
1045
|
private defaultCamera;
|
|
1046
|
+
/** This venue's opening zoom, captured once after the initial fit resolves.
|
|
1047
|
+
* Anchors `applyRelativeIconZoomRanges` so icon/label reveal thresholds
|
|
1048
|
+
* are relative to this venue's own opening view rather than an absolute
|
|
1049
|
+
* MapLibre zoom — re-applied after every `setTheme()` swap too, since
|
|
1050
|
+
* `setStyle({ diff: false })` recreates layers from the pristine theme. */
|
|
1051
|
+
private iconZoomBase;
|
|
565
1052
|
private viewModes;
|
|
566
1053
|
/** Mirror of `config.options.reducedMotion`, mutable via `setReducedMotion`. */
|
|
567
1054
|
private reducedMotion;
|
|
1055
|
+
/** Whether map labels render in OpenDyslexic, mutable via `setDyslexicFont`.
|
|
1056
|
+
* Re-applied after every `setTheme()` swap, same reason as `iconZoomBase`. */
|
|
1057
|
+
private dyslexicFont;
|
|
568
1058
|
/** Tracks the active theme name so `setTheme()` is a no-op when re-requested. */
|
|
569
1059
|
private activeThemeName;
|
|
570
1060
|
/** Tracks the active locale so `setLocale()` is a no-op when re-requested.
|
|
571
1061
|
* Seeded from `config.jmap.locale` at construction; `undefined` means
|
|
572
1062
|
* whatever the customer's default locale is on the JACS side. */
|
|
573
1063
|
private currentLocale;
|
|
1064
|
+
/** The destination of the last successfully computed route — kept so
|
|
1065
|
+
* `setLocale()` can rebuild + re-emit `routeReady` with retranslated
|
|
1066
|
+
* step text without recomputing the path. Cleared on route failure. */
|
|
1067
|
+
private lastRouteDestinationPoi;
|
|
574
1068
|
private amenityManager;
|
|
575
1069
|
private wayfinding;
|
|
576
1070
|
private highlightManager;
|
|
577
1071
|
private selectionManager;
|
|
1072
|
+
private restroomGroups;
|
|
578
1073
|
/** Captured unit paint values to restore when the selection clears, or
|
|
579
1074
|
* `null` when no room is currently focused. See `UNIT_DIM_TARGETS`. */
|
|
580
1075
|
private unitDimRestore;
|
|
@@ -586,6 +1081,15 @@ declare class MinuteMaps {
|
|
|
586
1081
|
* *previous* filters, not the ids) so `setTheme` can re-apply the same focus
|
|
587
1082
|
* to the new style's layers after a swap discards the old ones. */
|
|
588
1083
|
private destFocusIds;
|
|
1084
|
+
/** Coordinates of the current tap/Info selection, or `null` when nothing is
|
|
1085
|
+
* selected. `easeToSelection` reads `getBoundsPadding()` at the moment a
|
|
1086
|
+
* selection is made, which is often *before* the consumer's info card has
|
|
1087
|
+
* mounted and been measured into that padding — so the first pan can land
|
|
1088
|
+
* the POI behind the card. Kept here so `setBoundsPadding` can re-nudge the
|
|
1089
|
+
* camera once the consumer measures its now-mounted chrome and reports
|
|
1090
|
+
* fresh insets, the same way it already re-fits an active route. Cleared by
|
|
1091
|
+
* `clearHighlight`. */
|
|
1092
|
+
private selectedCoordinates;
|
|
589
1093
|
private youAreHerePulse;
|
|
590
1094
|
/** Theme layers whose features represent a tappable destination/amenity.
|
|
591
1095
|
* A click hit-tests these (see `SelectionManager`) → `poiSelected`. The
|
|
@@ -599,6 +1103,15 @@ declare class MinuteMaps {
|
|
|
599
1103
|
* identically. Kept separate from the pin list because these carry no POI
|
|
600
1104
|
* identity of their own — they resolve spatially. */
|
|
601
1105
|
private static readonly CLICKABLE_UNIT_LAYERS;
|
|
1106
|
+
/** The kiosk's own "you are here" pin — icon, directional heading wedge,
|
|
1107
|
+
* and the ring drawn behind them. Deliberately **not** part of
|
|
1108
|
+
* `CLICKABLE_POI_LAYERS`: that list feeds `emitPoiSelected`, which opens
|
|
1109
|
+
* a selection card for a destination/amenity, and this pin isn't one —
|
|
1110
|
+
* it's where the kiosk itself is standing. A tap here means "where am
|
|
1111
|
+
* I", so it gets its own delegated listener emitting `youAreHereClicked`
|
|
1112
|
+
* instead, for a consumer to wire to the same recenter action as its
|
|
1113
|
+
* own recenter control. */
|
|
1114
|
+
private static readonly YOU_ARE_HERE_LAYERS;
|
|
602
1115
|
/** While a room is selected, the other units are recolored to a flat, muted
|
|
603
1116
|
* gray so the raised, full-strength highlight block reads as the focus. We
|
|
604
1117
|
* recolor rather than lower opacity on purpose: translucent extrusions blend
|
|
@@ -616,10 +1129,9 @@ declare class MinuteMaps {
|
|
|
616
1129
|
* visible as wayfinding reference. Restored on `clearHighlight`. */
|
|
617
1130
|
private static readonly DESTINATION_FOCUS_LAYERS;
|
|
618
1131
|
/** Categorical POI layers in the bundled theme that `setPOIFilter`
|
|
619
|
-
* toggles. Layers absent from this list — `poi-you-are-here
|
|
620
|
-
* `poi-
|
|
621
|
-
*
|
|
622
|
-
* indicators, or transient focus state, not categorical content. */
|
|
1132
|
+
* toggles. Layers absent from this list — `poi-you-are-here-*` and the
|
|
1133
|
+
* `poi-highlight-*` layers — are intentionally unaffected; they're
|
|
1134
|
+
* anchors or transient focus state, not categorical content. */
|
|
623
1135
|
private static readonly POI_CATEGORY_LAYERS;
|
|
624
1136
|
private poiVisibleTypes;
|
|
625
1137
|
constructor(config: SDKConfig);
|
|
@@ -647,6 +1159,16 @@ declare class MinuteMaps {
|
|
|
647
1159
|
off(event: string, cb?: (e: MapEvent) => void): void;
|
|
648
1160
|
addControl(control: IControl, position?: ControlPosition): void;
|
|
649
1161
|
setView(options: ViewOptions): void;
|
|
1162
|
+
/**
|
|
1163
|
+
* Force a camera move to land instantly while reduced motion is on.
|
|
1164
|
+
*
|
|
1165
|
+
* The single gate every consumer-driven move goes through — zoom
|
|
1166
|
+
* buttons, compass reset, go-home, recenter, route fits — so the one
|
|
1167
|
+
* toggle covers them all instead of each call site remembering to ask.
|
|
1168
|
+
* Returns `opts` untouched when the preference is off, so a caller that
|
|
1169
|
+
* asked for `animate: false` keeps it either way.
|
|
1170
|
+
*/
|
|
1171
|
+
private motionGated;
|
|
650
1172
|
get amenities(): AmenityManager;
|
|
651
1173
|
resetView(opts?: {
|
|
652
1174
|
animate?: boolean;
|
|
@@ -676,6 +1198,24 @@ declare class MinuteMaps {
|
|
|
676
1198
|
set3dEnabled(enabled: boolean): void;
|
|
677
1199
|
toggle3d(): void;
|
|
678
1200
|
getIs3dEnabled(): boolean;
|
|
1201
|
+
/**
|
|
1202
|
+
* (Re-)register per-amenity icons, per-destination logos, and the kiosk
|
|
1203
|
+
* "you are here" icon. Needed both at init and after every `setTheme()`
|
|
1204
|
+
* call — `map.setStyle(..., { diff: false })` tears down and recreates
|
|
1205
|
+
* the whole `Style` object, which drops every image added at runtime via
|
|
1206
|
+
* `map.addImage`. Only `route-arrow` re-registers itself lazily via
|
|
1207
|
+
* `styleimagemissing`; everything else must be re-run explicitly here or
|
|
1208
|
+
* it silently goes blank after a theme swap.
|
|
1209
|
+
*
|
|
1210
|
+
* `themeName === 'high-contrast'` recolors both the amenity badge disc
|
|
1211
|
+
* and the connector (elevator/stairs/escalator) badge disc to
|
|
1212
|
+
* `HIGH_CONTRAST_AMENITY_BADGE_COLOR`, and forces both the regular and
|
|
1213
|
+
* connector glyph to `HIGH_CONTRAST_AMENITY_ICON_COLOR` so neither
|
|
1214
|
+
* washes out against its now-yellow disc and the two match each other.
|
|
1215
|
+
* Ring colors are left untouched. Failures per icon set are logged and
|
|
1216
|
+
* skipped so one bad icon doesn't block the rest.
|
|
1217
|
+
*/
|
|
1218
|
+
private registerRuntimeIcons;
|
|
679
1219
|
/**
|
|
680
1220
|
* Set the active map theme by name (`'default'` / `'high-contrast'`) or by
|
|
681
1221
|
* passing a custom `StyleSpecification`. The current floor, route, POIs
|
|
@@ -688,12 +1228,39 @@ declare class MinuteMaps {
|
|
|
688
1228
|
/** Currently active theme name (or `'custom'` when a raw style was passed). */
|
|
689
1229
|
getActiveTheme(): 'default' | 'high-contrast' | 'custom';
|
|
690
1230
|
/**
|
|
691
|
-
* Update the SDK's reduced-motion preference at runtime. When true,
|
|
692
|
-
* imperative camera
|
|
693
|
-
*
|
|
1231
|
+
* Update the SDK's reduced-motion preference at runtime. When true, every
|
|
1232
|
+
* imperative camera move (`setView`, `resetView`, `refit`, recenter, route
|
|
1233
|
+
* fits, selection pans, floor fits) runs with `duration: 0`, and every
|
|
1234
|
+
* looping animation the SDK drives — the route line-draw, the flowing route
|
|
1235
|
+
* arrows, the "You are here" pulse, the selection ring's ping — is stopped.
|
|
1236
|
+
*
|
|
1237
|
+
* Anything already on screen is switched over here, not just on the next
|
|
1238
|
+
* action: a visitor who flips the toggle mid-route is doing it *because* of
|
|
1239
|
+
* the motion they can see, so waiting for the next event would be the one
|
|
1240
|
+
* moment the preference doesn't work.
|
|
694
1241
|
*/
|
|
695
1242
|
setReducedMotion(enabled: boolean): void;
|
|
696
1243
|
getReducedMotion(): boolean;
|
|
1244
|
+
/**
|
|
1245
|
+
* Swap every map label (street names, POI names, building labels, "You are
|
|
1246
|
+
* here") between the bundled themes' default font and OpenDyslexic. Mirrors
|
|
1247
|
+
* the DOM-side dyslexic-font accommodation onto the canvas, which CSS can't
|
|
1248
|
+
* reach.
|
|
1249
|
+
*
|
|
1250
|
+
* Goes through the same local-glyph fallback the themes already use for
|
|
1251
|
+
* `Material Icons` (`LOCAL_GLYPH_FONTS`): `text-font` values are swapped to
|
|
1252
|
+
* fontstack names intentionally absent from the glyph server
|
|
1253
|
+
* (`OpenDyslexic Bold` etc.), so MapLibre rasterizes them from a
|
|
1254
|
+
* page-loaded `@font-face` instead. The consuming app owns loading that
|
|
1255
|
+
* font — the SDK ships no assets — so this is a no-op glyph-wise (labels
|
|
1256
|
+
* fall back to tofu-free default rendering) if the app never declared it.
|
|
1257
|
+
*
|
|
1258
|
+
* Re-applied after `setTheme()`, since `setStyle({ diff: false })`
|
|
1259
|
+
* recreates every layer from the pristine (non-dyslexic) theme JSON.
|
|
1260
|
+
*/
|
|
1261
|
+
setDyslexicFont(enabled: boolean): Promise<void>;
|
|
1262
|
+
getDyslexicFont(): boolean;
|
|
1263
|
+
private applyDyslexicFontToLabels;
|
|
697
1264
|
/**
|
|
698
1265
|
* Switch the locale used for POI / amenity / destination / floor names at
|
|
699
1266
|
* runtime. The SDK refetches localized names from JACS (per-entity
|
|
@@ -707,9 +1274,12 @@ declare class MinuteMaps {
|
|
|
707
1274
|
* Emits a `localeChanged` event with the new code after the patch
|
|
708
1275
|
* completes. No-op when the code matches the current locale.
|
|
709
1276
|
*
|
|
710
|
-
* Throws
|
|
711
|
-
* (only `JacsDataProvider`
|
|
712
|
-
*
|
|
1277
|
+
* Throws only on programmer error — a provider without locale support
|
|
1278
|
+
* (only `JacsDataProvider` has it today) or an empty code. A **failed
|
|
1279
|
+
* JACS fetch is not fatal**: the locale still switches and is reported,
|
|
1280
|
+
* it's only the localized names that stay on the prior language. That
|
|
1281
|
+
* split is deliberate — generated directions text ships inside the SDK
|
|
1282
|
+
* and must not be held hostage to a network round-trip.
|
|
713
1283
|
*/
|
|
714
1284
|
setLocale(locale: string): Promise<void>;
|
|
715
1285
|
/** Currently active locale (BCP-47), or `undefined` when no locale has
|
|
@@ -733,26 +1303,122 @@ declare class MinuteMaps {
|
|
|
733
1303
|
getZoneForPOI(poi: POI): Zone | null;
|
|
734
1304
|
/** Human-readable detail fields for a POI info popover. Only surfaces
|
|
735
1305
|
* fields that exist on the current data — `category`, `floorName`,
|
|
736
|
-
* `zoneName`, `keywords`, and `
|
|
737
|
-
* Keeps the display-field derivation (incl. the zone lookup)
|
|
738
|
-
* so consumers stay thin. */
|
|
1306
|
+
* `zoneName`, `keywords`, `description`, and `imageUrl` are each omitted
|
|
1307
|
+
* when absent. Keeps the display-field derivation (incl. the zone lookup)
|
|
1308
|
+
* in the SDK so consumers stay thin. */
|
|
739
1309
|
getPOIDetails(poi: POI): {
|
|
740
1310
|
name: string;
|
|
741
1311
|
type: 'amenity' | 'destination' | 'kiosk';
|
|
742
1312
|
category?: string;
|
|
743
1313
|
floorName?: string;
|
|
1314
|
+
floorShortName?: string;
|
|
744
1315
|
zoneName?: string;
|
|
745
1316
|
zoneDescription?: string;
|
|
1317
|
+
/** The department's authored hex colour (`Zone.color`) — the same value
|
|
1318
|
+
* that tints this room's polygon on the map, so a consumer can print a
|
|
1319
|
+
* swatch beside the department name and connect the two. Absent when the
|
|
1320
|
+
* author never picked one, which is also when the map leaves the room
|
|
1321
|
+
* untinted; treat "no colour" as "this department isn't colour-coded",
|
|
1322
|
+
* not as "fall back to a default swatch". */
|
|
1323
|
+
zoneColor?: string;
|
|
746
1324
|
keywords?: string[];
|
|
747
1325
|
description?: string;
|
|
1326
|
+
/** CMS-authored extras from the entity's `extensors` bag (opening hours,
|
|
1327
|
+
* days, room, building). Free-form — the consumer decides what to render.
|
|
1328
|
+
* Artwork is not in here; see `imageUrl`. */
|
|
1329
|
+
properties?: Record<string, unknown>;
|
|
1330
|
+
/** The destination's uploaded location image, ready for an `<img src>`.
|
|
1331
|
+
* Destinations only — amenities use sprite glyphs, not photos. Inline SVG
|
|
1332
|
+
* from `/all` comes back as a data URI; otherwise it's the uploaded uri
|
|
1333
|
+
* path. Absent when nothing was uploaded in the CMS. */
|
|
1334
|
+
imageUrl?: string;
|
|
1335
|
+
/** Author-written alt text for `imageUrl` (`mm_image_alt`) — a description
|
|
1336
|
+
* of the place, for screen readers and for anyone the image fails to load
|
|
1337
|
+
* for. Absent when the author wrote none, in which case the image is
|
|
1338
|
+
* decorative and belongs in an `<img alt="">`, not an unlabelled one. */
|
|
1339
|
+
imageAlt?: string;
|
|
1340
|
+
/** Room number — the CMS's "Room Number". Reads the real
|
|
1341
|
+
* `Destination.unitNumber` column, falling back to a legacy hand-typed
|
|
1342
|
+
* `room_number` property for venues authored before that field existed. */
|
|
1343
|
+
roomNumber?: string;
|
|
1344
|
+
/** Which building on the campus this destination is in (`mm_building_name`),
|
|
1345
|
+
* as the author typed it — "200", "Ambulatory Care". Free text, not a
|
|
1346
|
+
* reference to a `Building` record; render it, don't resolve it. Falls back
|
|
1347
|
+
* to the legacy hand-typed `building_name` property, which is unprefixed
|
|
1348
|
+
* and therefore a different key. */
|
|
1349
|
+
buildingName?: string;
|
|
1350
|
+
/** Phone number and internal extension (`mm_phone`). The number is exactly
|
|
1351
|
+
* as the author typed it, not normalised — see `parsePhone`. */
|
|
1352
|
+
phone?: DestinationPhone;
|
|
1353
|
+
/** The CMS-authored opening hours (`mm_open_hours`), parsed. Absent when
|
|
1354
|
+
* the author set none, or the stored value is unreadable.
|
|
1355
|
+
*
|
|
1356
|
+
* Static — it describes the week, not this moment. Pass it to
|
|
1357
|
+
* `getOpenStatus()` for the live open/closed state, and re-call that on a
|
|
1358
|
+
* tick if the UI stays on screen. The raw string also remains in
|
|
1359
|
+
* `properties` for consumers that would rather parse it themselves. */
|
|
1360
|
+
openHours?: OpenHours;
|
|
748
1361
|
};
|
|
749
1362
|
/** Resolve the source Destination/Amenity record backing a rendered POI,
|
|
750
1363
|
* for detail fields (category, localized description) that don't live on
|
|
751
1364
|
* the built POI object. */
|
|
752
1365
|
private getSourceEntity;
|
|
753
1366
|
getPolygonLayers(): any[];
|
|
1367
|
+
/**
|
|
1368
|
+
* Cross-reference the venue's drawn layers against the customer's allowed
|
|
1369
|
+
* layer list (JACS `GET /customer/{id}/polygon-layer`) and against what the
|
|
1370
|
+
* active theme can actually render.
|
|
1371
|
+
*
|
|
1372
|
+
* Three failure modes, none of which is visible by looking at the map:
|
|
1373
|
+
* a layer drawn under a name the CMS doesn't list (`unauthorized`), a layer
|
|
1374
|
+
* legitimately drawn that no theme rule matches (`unstyled`), and a theme
|
|
1375
|
+
* rule with nothing to draw at this venue (`unused`). Runs automatically
|
|
1376
|
+
* once after `ready` when `options.debug` is on; call it directly —
|
|
1377
|
+
* `mm.validateMapLayers()` — any time.
|
|
1378
|
+
*
|
|
1379
|
+
* Only counts floors whose geojson has loaded. Init preloads the rest in
|
|
1380
|
+
* the background, so a call in the first moments after `ready` may report
|
|
1381
|
+
* fewer `inData` types than a call a second later.
|
|
1382
|
+
*/
|
|
1383
|
+
validateMapLayers(): Promise<LayerAudit>;
|
|
1384
|
+
/** Debug-mode auto-run: log findings once, stay silent when clean. */
|
|
1385
|
+
private reportLayerAudit;
|
|
754
1386
|
getFloorMapTemplate3d(floorId: string | number): any[];
|
|
755
1387
|
getAllPOIs(floor?: Floor): POI[];
|
|
1388
|
+
/**
|
|
1389
|
+
* Put the map on the kiosk's floor before drawing a route from it.
|
|
1390
|
+
*
|
|
1391
|
+
* **A route from the kiosk always starts on the kiosk's floor**, so that is
|
|
1392
|
+
* the floor the visitor has to be looking at when it appears. The renderer
|
|
1393
|
+
* agrees with that already — `wayfinding` reveals and frames *the active
|
|
1394
|
+
* floor's* slice of the route — which is exactly why this matters: leave the
|
|
1395
|
+
* map where the visitor had wandered to and the route arrives framed on the
|
|
1396
|
+
* wrong leg, or on no leg at all.
|
|
1397
|
+
*
|
|
1398
|
+
* Both halves of that were reported from a real kiosk. Browse up to Level 3,
|
|
1399
|
+
* search, press Directions: if Level 3 isn't on the route the fit falls back
|
|
1400
|
+
* to the union of every floor and nothing reads as a path from here; if it
|
|
1401
|
+
* *is* on the route — because the destination is up there — the visitor is
|
|
1402
|
+
* looking at the last leg of a walk they haven't started, with no indication
|
|
1403
|
+
* that the first one is two floors down.
|
|
1404
|
+
*
|
|
1405
|
+
* Called before the route is computed rather than after it's drawn, so the
|
|
1406
|
+
* camera makes one move instead of fitting the wrong floor and correcting.
|
|
1407
|
+
* No-op when the venue has no kiosk anchor (those routes fail anyway) or the
|
|
1408
|
+
* map is already there.
|
|
1409
|
+
*/
|
|
1410
|
+
private showKioskFloorForRoute;
|
|
1411
|
+
/**
|
|
1412
|
+
* The floor the kiosk is physically anchored to — not necessarily the
|
|
1413
|
+
* floor currently displayed (the visitor may have panned the floor
|
|
1414
|
+
* selector to preview a destination on another level, and the SDK opens
|
|
1415
|
+
* on the venue's configured default floor rather than the kiosk's own —
|
|
1416
|
+
* see `FloorManager.selectInitialFloor`). Anchor resolution (routing,
|
|
1417
|
+
* recentering, closest-waypoint) must resolve against this floor, never
|
|
1418
|
+
* `getCurrentFloor()`, or it silently misses the "you are here" POI
|
|
1419
|
+
* whenever the two diverge. `null` when the venue has no kiosk anchor.
|
|
1420
|
+
*/
|
|
1421
|
+
getKioskFloor(): Floor | null;
|
|
756
1422
|
getYouAreHerePOI(floor?: Floor): POI | null;
|
|
757
1423
|
getYouAreHereCoordinates(floor?: Floor): [number, number] | null;
|
|
758
1424
|
/**
|
|
@@ -767,6 +1433,14 @@ declare class MinuteMaps {
|
|
|
767
1433
|
* cone rendered next to the "You are here" marker.
|
|
768
1434
|
*/
|
|
769
1435
|
getKioskHeading(): number | null;
|
|
1436
|
+
/**
|
|
1437
|
+
* Bearing (degrees clockwise from north) the visitor at the kiosk is
|
|
1438
|
+
* FACING — the device heading rotated 180°, since they stand in front
|
|
1439
|
+
* of the screen looking back at it. `null` when the device record
|
|
1440
|
+
* carries no heading, in which case direction-relative wording ("turn
|
|
1441
|
+
* right and walk 40 ft") is suppressed rather than guessed.
|
|
1442
|
+
*/
|
|
1443
|
+
private getVisitorFacingBearing;
|
|
770
1444
|
/**
|
|
771
1445
|
* Display name of the JACS device the kiosk is anchored to (e.g.
|
|
772
1446
|
* "Main Lobby Kiosk", "Information Desk Kiosk"). `null` when the venue
|
|
@@ -837,8 +1511,6 @@ declare class MinuteMaps {
|
|
|
837
1511
|
wayfindBetweenWaypoints(fromWaypoint: any, toWaypoint: any, options?: {
|
|
838
1512
|
centerMode?: 'none' | 'destination' | 'route';
|
|
839
1513
|
zoom?: number;
|
|
840
|
-
/** Prefer accessible paths (drops or penalizes stairs / inaccessible edges). */
|
|
841
|
-
accessible?: boolean;
|
|
842
1514
|
/** Hard-filter stairs from the graph. */
|
|
843
1515
|
avoidStairs?: boolean;
|
|
844
1516
|
}): Promise<any>;
|
|
@@ -851,12 +1523,23 @@ declare class MinuteMaps {
|
|
|
851
1523
|
* you want a visual focus rather than a route.
|
|
852
1524
|
*/
|
|
853
1525
|
navigateFromKioskToPOI(poi: POI, options?: {
|
|
854
|
-
accessible?: boolean;
|
|
855
1526
|
avoidStairs?: boolean;
|
|
856
1527
|
}): Promise<any>;
|
|
857
1528
|
/** Build the landmark / floor-name context the directions module needs.
|
|
858
1529
|
* Pulled out so `setLocale()` or `setActiveStep()` can rebuild it on
|
|
859
1530
|
* demand if we ever surface a locale-aware variant. */
|
|
1531
|
+
/**
|
|
1532
|
+
* Rewrite every source whose features carry venue-authored *text* for a
|
|
1533
|
+
* floor: POI labels and map labels. Both read their names straight out of
|
|
1534
|
+
* the venue model, so anything that mutates that model in place — today
|
|
1535
|
+
* `setLocale`'s translation patch — has to call this or the map keeps
|
|
1536
|
+
* rendering the old strings until the next floor change.
|
|
1537
|
+
*
|
|
1538
|
+
* Map labels ride the same lifecycle as POIs and carry the `allLevels`
|
|
1539
|
+
* flag, which the projector has already honored by duplicating the
|
|
1540
|
+
* instance under every floor's list.
|
|
1541
|
+
*/
|
|
1542
|
+
private redrawFloorText;
|
|
860
1543
|
private buildDirectionsContext;
|
|
861
1544
|
/**
|
|
862
1545
|
* Drive the turn-by-turn UI. Two effects:
|
|
@@ -885,6 +1568,42 @@ declare class MinuteMaps {
|
|
|
885
1568
|
* it lives on another one. Pass a POI / amenity / destination id.
|
|
886
1569
|
*/
|
|
887
1570
|
highlightPOI(id: string | number): Promise<void>;
|
|
1571
|
+
/**
|
|
1572
|
+
* Select a POI programmatically — the same end state as tapping it on the
|
|
1573
|
+
* map, from a list or any other chrome.
|
|
1574
|
+
*
|
|
1575
|
+
* Switches the active floor first when the POI lives on another one, raises
|
|
1576
|
+
* its room as a highlighted block, mutes the neighbouring units, declutters
|
|
1577
|
+
* to the selected destination(s), pans it into the unobscured map area and
|
|
1578
|
+
* emits **`poiSelected`** carrying every co-located POI. A consumer that
|
|
1579
|
+
* already renders an info card off that event therefore needs no second code
|
|
1580
|
+
* path: a tap and a list pick arrive the same way.
|
|
1581
|
+
*
|
|
1582
|
+
* This is deliberately *not* `highlightPOI`, which is the search-locate
|
|
1583
|
+
* gesture — it zooms and recenters and draws a pulsing ring, and emits
|
|
1584
|
+
* nothing. Selection is the quieter one: current zoom kept, no ring, the
|
|
1585
|
+
* raised room is the indicator.
|
|
1586
|
+
*
|
|
1587
|
+
* Accepts a `POI` (preferred — its `type` and `waypointId` pin down the exact
|
|
1588
|
+
* instance, which matters for an amenity that shares one id across every
|
|
1589
|
+
* physical pin) or a bare id.
|
|
1590
|
+
*
|
|
1591
|
+
* **`includeCoLocated: false` emits only the requested POI.** By default the
|
|
1592
|
+
* payload carries everything sharing the room, which is right when the
|
|
1593
|
+
* gesture was a tap — the visitor pointed at a place on a floor plan and the
|
|
1594
|
+
* consumer has to show them what's there. It's wrong when they picked one
|
|
1595
|
+
* entry out of a named list: they have already disambiguated, and handing
|
|
1596
|
+
* back four places would ask them to do it again, on a card that opened
|
|
1597
|
+
* *because* they were specific. The map treatment is identical either way
|
|
1598
|
+
* (same room raised, same neighbours muted, same pan); only the payload —
|
|
1599
|
+
* and so the declutter's allow-list — narrows.
|
|
1600
|
+
*
|
|
1601
|
+
* Returns the selected POIs, `pois[0]` being the requested one; an empty
|
|
1602
|
+
* array if no POI matched, which is also when nothing on the map changes.
|
|
1603
|
+
*/
|
|
1604
|
+
selectPOI(target: POI | string | number, options?: {
|
|
1605
|
+
includeCoLocated?: boolean;
|
|
1606
|
+
}): Promise<POI[]>;
|
|
888
1607
|
/** Remove the POI highlight set by `highlightPOI`, un-dim the other units,
|
|
889
1608
|
* and bring back the destination markers hidden by a room selection. */
|
|
890
1609
|
clearHighlight(): void;
|
|
@@ -962,17 +1681,17 @@ declare class MinuteMaps {
|
|
|
962
1681
|
* `navigateFromKioskToPOI` — so step-by-step directions, the
|
|
963
1682
|
* `routeReady` event, and the active-floor camera fit all "just work."
|
|
964
1683
|
*
|
|
965
|
-
* Pass `
|
|
966
|
-
* routing engine reads
|
|
967
|
-
*
|
|
968
|
-
*
|
|
969
|
-
*
|
|
970
|
-
*
|
|
971
|
-
*
|
|
972
|
-
*
|
|
1684
|
+
* Pass `avoidStairs` to hard-filter stairs from the *route* (the SDK's
|
|
1685
|
+
* routing engine reads it per call; the CMS's per-path-type weight
|
|
1686
|
+
* otherwise handles accessibility preference automatically). Note:
|
|
1687
|
+
* closest-instance picking itself is currently distance-based and does
|
|
1688
|
+
* not honor `avoidStairs` — the underlying walk-time graph applies
|
|
1689
|
+
* pixel-length only. In practice this matters when an amenity has
|
|
1690
|
+
* multiple instances and the geometrically closest is reachable only
|
|
1691
|
+
* via stairs; the picked instance won't change today, but the *route*
|
|
1692
|
+
* to it will avoid stairs (or fail gracefully) if `avoidStairs` is set.
|
|
973
1693
|
*/
|
|
974
1694
|
navigateFromKioskToClosestAmenity(amenityId: string | number, options?: {
|
|
975
|
-
accessible?: boolean;
|
|
976
1695
|
avoidStairs?: boolean;
|
|
977
1696
|
}): Promise<any>;
|
|
978
1697
|
/**
|
|
@@ -993,6 +1712,19 @@ declare class MinuteMaps {
|
|
|
993
1712
|
private findFloorForWaypoint;
|
|
994
1713
|
getCameraPosition(): CameraState | null;
|
|
995
1714
|
getMap(): Map | null;
|
|
1715
|
+
/**
|
|
1716
|
+
* Put this instance on `window` so a kiosk running in a browser can be
|
|
1717
|
+
* driven from devtools — `mm.debug.help()`, `mm.getMap()`, `mm.setTheme(…)`.
|
|
1718
|
+
* Debug builds only: nothing is exposed unless `options.debug` is on, and
|
|
1719
|
+
* `options.debugGlobal` renames the key (or `false` opts out entirely).
|
|
1720
|
+
*
|
|
1721
|
+
* Refuses to clobber a key that already holds something that isn't a
|
|
1722
|
+
* MinuteMaps — a kiosk shell with its own `window.mm` shouldn't lose it to
|
|
1723
|
+
* a dev-mode convenience.
|
|
1724
|
+
*/
|
|
1725
|
+
private exposeDebugGlobal;
|
|
1726
|
+
/** Drop the `window` handle, but only if it still points at this instance. */
|
|
1727
|
+
private releaseDebugGlobal;
|
|
996
1728
|
destroy(): void;
|
|
997
1729
|
setCurrentFloor(floor: Floor): Promise<void>;
|
|
998
1730
|
/**
|
|
@@ -1023,6 +1755,13 @@ declare class MinuteMaps {
|
|
|
1023
1755
|
*/
|
|
1024
1756
|
private clampPadding;
|
|
1025
1757
|
private getVenueBounds;
|
|
1758
|
+
/**
|
|
1759
|
+
* Resolve `options.maxBounds` into the actual pan/zoom-out cap. `false`
|
|
1760
|
+
* disables it, explicit bounds pass through as-is, and a number (or the
|
|
1761
|
+
* unset default of 3) scales the venue's own bounds outward around its
|
|
1762
|
+
* center — see `scaleBounds`.
|
|
1763
|
+
*/
|
|
1764
|
+
private getMaxBounds;
|
|
1026
1765
|
/**
|
|
1027
1766
|
* Opening-framing policy applied once after the initial floor fit.
|
|
1028
1767
|
* - `initialPitch`: tilt to this and re-fit the building footprint so the
|
|
@@ -1076,5 +1815,76 @@ declare function groupStepsIntoFloorSections(steps: WayfindStep[]): RouteFloorSe
|
|
|
1076
1815
|
*/
|
|
1077
1816
|
declare function activeSectionIndex(sections: RouteFloorSection[], activeStepIndex: number): number;
|
|
1078
1817
|
|
|
1079
|
-
|
|
1080
|
-
|
|
1818
|
+
/** True when an amenity is a vertical-circulation connector. The provider
|
|
1819
|
+
* stamps `_connector` on every synthetic elevator / stairs / escalator, which
|
|
1820
|
+
* is the reliable signal — `extensors.iconName` is only the *display* glyph
|
|
1821
|
+
* and may be any CMS-assigned icon (we still honour it as a fallback for
|
|
1822
|
+
* amenities authored with a connector icon name directly). */
|
|
1823
|
+
declare function isConnectorAmenity(amenity: AmenityLike): boolean;
|
|
1824
|
+
type LocaleField = {
|
|
1825
|
+
locale?: string;
|
|
1826
|
+
uriPath?: string;
|
|
1827
|
+
};
|
|
1828
|
+
type UriField = {
|
|
1829
|
+
mimeType?: string;
|
|
1830
|
+
resourceType?: string;
|
|
1831
|
+
locales?: LocaleField[];
|
|
1832
|
+
};
|
|
1833
|
+
type AmenityLike = {
|
|
1834
|
+
id: number | string;
|
|
1835
|
+
iconId?: string;
|
|
1836
|
+
uris?: UriField[] | null;
|
|
1837
|
+
/** Inline SVG markup. Used by the SDK for synthetic connector
|
|
1838
|
+
* amenities (elevator / stairs / escalator) where the CMS has no
|
|
1839
|
+
* uploaded icon to fetch. When set, this short-circuits the
|
|
1840
|
+
* `uris[].locales[].uriPath` lookup. */
|
|
1841
|
+
svg?: string;
|
|
1842
|
+
/** Free-form CMS metadata. When `extensors.iconName` names a curated
|
|
1843
|
+
* Material Symbols icon, the SDK renders it from the bundled registry
|
|
1844
|
+
* (no upload, no network) — see `pickMaterialSvg`. */
|
|
1845
|
+
extensors?: Record<string, unknown> | null;
|
|
1846
|
+
/** Set by the JACS provider on synthetic vertical-circulation amenities
|
|
1847
|
+
* (elevator / stairs / escalator built from path types). The reliable
|
|
1848
|
+
* connector signal — `extensors.iconName` is the *display* glyph, which
|
|
1849
|
+
* may be any CMS-assigned icon, not the connector kind. */
|
|
1850
|
+
_connector?: boolean;
|
|
1851
|
+
};
|
|
1852
|
+
type ResolvedIconSource = {
|
|
1853
|
+
/** Map image id to register/reference. Shared across amenities for
|
|
1854
|
+
* connectors (preset) and curated Material icons (`material-<name>`). */
|
|
1855
|
+
iconId: string;
|
|
1856
|
+
/** Source for `composeAmenityBitmap` — exactly one of url / inlineSvg. */
|
|
1857
|
+
source: {
|
|
1858
|
+
url?: string;
|
|
1859
|
+
inlineSvg?: string;
|
|
1860
|
+
};
|
|
1861
|
+
/**
|
|
1862
|
+
* Where the artwork came from. The map doesn't care — it rasterises all
|
|
1863
|
+
* three the same way — but a DOM consumer must, because provenance decides
|
|
1864
|
+
* both trust and styling:
|
|
1865
|
+
*
|
|
1866
|
+
* - `material` — from the SDK's bundled registry. Ours, so it's safe to
|
|
1867
|
+
* inline into the DOM, and safe to recolour (it's a monochrome glyph).
|
|
1868
|
+
* - `inline` — an `svg` string off the CMS record. **Author-supplied
|
|
1869
|
+
* markup**: an inline `<svg>` can carry `<script>`, so render it through
|
|
1870
|
+
* an `<img src="data:…">` (which never executes script), not
|
|
1871
|
+
* `dangerouslySetInnerHTML`.
|
|
1872
|
+
* - `upload` — a URL to a CMS-uploaded file. Also author-supplied, also an
|
|
1873
|
+
* `<img>`; and it arrives in whatever colours the author chose, so don't
|
|
1874
|
+
* assume you can tint it to match a badge.
|
|
1875
|
+
*/
|
|
1876
|
+
kind: 'material' | 'inline' | 'upload';
|
|
1877
|
+
};
|
|
1878
|
+
/**
|
|
1879
|
+
* Pure icon-source resolution by precedence — no map/DOM side effects, so it's
|
|
1880
|
+
* unit-testable:
|
|
1881
|
+
* 1. inline svg — explicit inline-SVG override (rare)
|
|
1882
|
+
* 2. extensors.iconName — curated Material icon (bundled, shared bitmap);
|
|
1883
|
+
* also how synthetic connectors render now
|
|
1884
|
+
* 3. uris[].uriPath — legacy / custom-uploaded SVG (fetched)
|
|
1885
|
+
* Returns null when the amenity has no resolvable icon.
|
|
1886
|
+
*/
|
|
1887
|
+
declare function resolveAmenityIconSource(amenity: AmenityLike, preferredLocale?: string): ResolvedIconSource | null;
|
|
1888
|
+
|
|
1889
|
+
export { BUILDING_NAME_EXTENSOR_KEY, DAY_KEYS, IMAGE_ALT_EXTENSOR_KEY, MinuteMaps, OPEN_HOURS_EXTENSOR_KEY, OPEN_HOURS_VERSION, PHONE_EXTENSOR_KEY, POINT_OF_INTEREST_EXTENSOR_KEY, RESERVED_EXTENSOR_PREFIX, activeSectionIndex, createMinuteMapsSDK, getOpenStatus, groupStepsIntoFloorSections, isConnectorAmenity, parseBuildingName, parseImageAlt, parseOpenHours, parsePhone, parsePointOfInterest, resolveAmenityIconSource };
|
|
1890
|
+
export type { Amenity, AmenityBadgeStyle, AmenityWithFloor, Bounds, BoundsPadding, CameraState, DayKey, Destination, DestinationPhone, EventCallback, Floor, FloorMetadata, HoursRange, JMapAuth, JMapConfig, JacsAuth, JacsConfig, MapEvent, OpenHours, OpenHoursTransition, OpenStatus, OpenStatusOptions, POI, POISearchResult, ResolvedIconSource, RouteFloorSection, RoutePoint, RoutingOptions, SDKConfig, SDKOptions, ThemeName, TransitionStep, ViewOptions, WayfindCenterMode, WayfindStep, Waypoint, Zone };
|