@minmaps-dev/mm-web-sdk 1.0.0-rc.32 → 1.0.0-rc.34

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/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { IControl, ControlPosition, StyleSpecification, Map } from 'maplibre-gl';
1
+ import { Map, IControl, ControlPosition, StyleSpecification } from 'maplibre-gl';
2
2
 
3
3
  /**
4
4
  * Represents a floor in a building
@@ -51,6 +51,12 @@ interface POI {
51
51
  floorId: string | number;
52
52
  /** Category/type of amenity (e.g., 'restroom', 'elevator') */
53
53
  amenityType?: string;
54
+ /** Which amenity icon layer this POI renders in — `'connector'`,
55
+ * `'entrance'`, `'parking'`, `'bus'` or `'other'`. Derived from the
56
+ * amenity's connector flag, name, type and keywords; emitted as the
57
+ * `amenityCategory` feature property the theme filters on. Amenities
58
+ * only. See `amenityCategoryFor`. */
59
+ amenityCategory?: 'connector' | 'entrance' | 'parking' | 'bus' | 'other';
54
60
  /** Search keywords */
55
61
  keywords?: string[];
56
62
  /** Additional properties */
@@ -115,20 +121,26 @@ interface Destination {
115
121
  category?: string;
116
122
  /** Additional properties */
117
123
  properties?: Record<string, unknown>;
118
- /** Uploaded image (e.g. brand/store logo). JACS `/all` fullcall serves this
119
- * as `{ items: [{ resourceType, mimeType, path }] }`; the legacy/basic shape
120
- * is `[{ locales: [{ uriPath }] }]`. `DestinationIcons.register` handles both. */
124
+ /** The CMS "Location Image" — a photo or logo for the popover, not a map
125
+ * marker. JACS `/all` fullcall serves this as
126
+ * `{ items: [{ resourceType, mimeType, path }] }`; the legacy/basic shape is
127
+ * `[{ locales: [{ uriPath }] }]`. `destinationImageSrc` handles both, and
128
+ * surfaces the result on `sdk.getPOIDetails(poi).imageUrl`. */
121
129
  uris?: unknown;
122
- /** Free-form CMS metadata (reserved for future destination icon options). */
130
+ /** Inline SVG for the uploaded image, embedded by JACS `/all`. Preferred over
131
+ * fetching `uris[].path` — no network round-trip. */
132
+ svg?: string;
133
+ /** Free-form CMS metadata. */
123
134
  extensors?: Record<string, unknown>;
124
- /** Map-manager "Label Display" mode (JACS `displayMode`):
125
- * `0` Hidden (dot only) · `1` Label (dot + text) · `2` Image (uploaded logo).
126
- * Undefined treated as Label (backwards-compatible default). */
135
+ /** @deprecated Read by nothing in the SDK as of rc.34.
136
+ *
137
+ * JACS still serves the old map-manager "Label Display" mode
138
+ * (`0` Hidden · `1` Label · `2` Image), but the CMS removed the picker and
139
+ * pins every write to `1`. Rows authored before that keep a stale `0`/`2`
140
+ * the author can no longer change, so honouring the field would hide labels
141
+ * with no way to bring them back. Destinations always render dot + text
142
+ * label; the uploaded image goes to the popover instead. */
127
143
  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
144
  }
133
145
  /**
134
146
  * Waypoint - a specific point location
@@ -339,16 +351,16 @@ type AmenityBadgeStyle = {
339
351
  /** Ring width in logical px. Default `2`. */
340
352
  ringWidth?: number;
341
353
  };
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
354
  interface SDKOptions {
351
355
  debug?: boolean;
356
+ /**
357
+ * `window` key the SDK instance is published under while `debug` is on, so
358
+ * a running kiosk can be driven from devtools (`mm.debug.hide('labels')`,
359
+ * `mm.getMap()`). Defaults to `'mm'`. Pass another name to avoid a clash,
360
+ * or `false` to publish nothing even in debug mode. Ignored entirely when
361
+ * `debug` is off.
362
+ */
363
+ debugGlobal?: string | false;
352
364
  /**
353
365
  * Initial theme. `'default'` uses the bundled hybrid 3D theme.
354
366
  * `'high-contrast'` uses the WCAG-AA tuned theme. Pass a
@@ -437,14 +449,6 @@ interface SDKOptions {
437
449
  * unless this is set explicitly.
438
450
  */
439
451
  connectorBadge?: AmenityBadgeStyle | false;
440
- /**
441
- * Chip composited behind each destination's uploaded logo. Destinations are
442
- * full-colour brand images (not recoloured), so they get a neutral white
443
- * rounded chip for legibility instead of the amenity gold badge. Pass `false`
444
- * to render the logo bare, or an object to tune the chip fill / border.
445
- * Defaults to a white chip with a 2px navy border.
446
- */
447
- destinationChip?: DestinationChipStyle | false;
448
452
  styleMode?: 'venueStyleUrl' | 'sdkTemplate';
449
453
  templateOverrideMode?: 'colorsOnly' | 'colorsAndConstants' | 'all';
450
454
  }
@@ -497,6 +501,230 @@ type SDKConfig = {
497
501
  options?: SDKOptions;
498
502
  };
499
503
 
504
+ type Visibility = 'visible' | 'none';
505
+ type DebugLayersDeps = {
506
+ getMap: () => Map | null;
507
+ /**
508
+ * Re-assert the visibility the SDK itself owns — floor layers, the POI
509
+ * category filter, the 2D/3D view mode. Called at the end of `reset()`,
510
+ * because restoring a captured `visibility` can't distinguish "the theme
511
+ * ships this visible" from "the SDK hid it because it belongs to another
512
+ * floor", and the naive restore would reveal every floor at once.
513
+ */
514
+ reapplySdkState?: () => void;
515
+ log?: (...args: unknown[]) => void;
516
+ };
517
+ type LayerRow = {
518
+ id: string;
519
+ type: string;
520
+ visibility: Visibility;
521
+ /**
522
+ * What this layer's visibility was before we touched it — i.e. what the
523
+ * theme and the SDK want it to be. Equal to `visibility` for any layer we
524
+ * hold no override on. A UI wanting to show "is this group on" should judge
525
+ * only the layers whose `base` is `'visible'`: the rest (the 3D extrusions
526
+ * in flat mode, the 2D outlines outside it) aren't rendering by design, so
527
+ * counting them makes a healthy group look half-off.
528
+ */
529
+ base: Visibility;
530
+ };
531
+ /**
532
+ * Console-facing layer inspector for demos, screenshots and debugging.
533
+ *
534
+ * Reachable as `sdk.debug`, and as `window.mm.debug` when
535
+ * `options.debug` is on (see `options.debugGlobal`).
536
+ *
537
+ * Two things make it more than a wrapper around `setLayoutProperty`:
538
+ *
539
+ * 1. **Selectors.** `hide('amenities')`, `hide('route-')`, `hide('/^poi-/')`
540
+ * and `hide('type:fill-extrusion')` all work, so you don't have to know
541
+ * the theme's layer ids to start poking at it.
542
+ * 2. **Overrides are sticky.** The SDK re-asserts layer visibility on floor
543
+ * changes, `setPOIFilter`, flat-mode toggles and theme swaps — all of which
544
+ * would otherwise wipe a manual toggle mid-demo. Every override is re-applied
545
+ * on `styledata`, so what you hid stays hidden until `reset()`.
546
+ */
547
+ declare class DebugLayers {
548
+ private deps;
549
+ /** layer id → visibility this API is asserting. */
550
+ private overrides;
551
+ /** layer id → visibility before we first touched it. */
552
+ private originals;
553
+ /** `${layer}|${prop}` → paint value before we first touched it. */
554
+ private paintOriginals;
555
+ private sticky;
556
+ private attachedTo;
557
+ /** Re-entrancy guard: our own `setLayoutProperty` fires `styledata`. */
558
+ private applying;
559
+ private readonly onStyleData;
560
+ constructor(deps: DebugLayersDeps);
561
+ /** Begin re-asserting overrides across style/floor changes. */
562
+ attach(map: Map): void;
563
+ detach(): void;
564
+ /**
565
+ * Every layer in the active style, newest-on-top last, with its current
566
+ * visibility. Pass a selector to narrow it (same grammar as `hide`).
567
+ */
568
+ list(selector?: string): LayerRow[];
569
+ /** Just the ids currently rendering — the quickest "what am I looking at". */
570
+ visible(): string[];
571
+ /** Group name → the ids it resolves to *in the active style*. */
572
+ groups(): Record<string, string[]>;
573
+ /** Hide every layer the selectors resolve to. Returns the ids affected. */
574
+ hide(...selectors: string[]): string[];
575
+ /**
576
+ * **Force** every resolved layer visible — including ones the SDK
577
+ * deliberately keeps off: the 3D extrusions while flat mode is on, the 2D
578
+ * outlines while it isn't, every floor but the active one. Forcing those
579
+ * renders two representations of the same geometry at once, or every floor
580
+ * stacked, and the map looks wrong.
581
+ *
582
+ * So this is *not* the way to undo a `hide()` — use `restore()`, which puts
583
+ * each layer back to what it was rather than blanket-revealing the group.
584
+ * Reach for `show()` only when you actually mean "reveal this regardless".
585
+ */
586
+ show(...selectors: string[]): string[];
587
+ /**
588
+ * Undo our overrides on these layers: each goes back to the visibility it
589
+ * had before we first touched it, and control returns to the SDK (floor
590
+ * layers, POI filter, view mode re-assert afterwards).
591
+ *
592
+ * This is the correct inverse of `hide()`. A group is rarely uniformly
593
+ * visible to begin with — `rooms` hides either the 2D outline or the 3D
594
+ * extrusion depending on view mode, and every floor layer but the active
595
+ * one is off — so `hide()` then `show()` does not round-trip, but `hide()`
596
+ * then `restore()` does.
597
+ *
598
+ * Returns the ids that actually had an override; layers we never touched
599
+ * are left alone.
600
+ */
601
+ restore(...selectors: string[]): string[];
602
+ /** Flip each resolved layer independently. Returns the ids affected. */
603
+ toggle(...selectors: string[]): string[];
604
+ /**
605
+ * Show only what the selectors resolve to — everything else is hidden
606
+ * (except `background`, which is just the canvas colour). The one-liner for
607
+ * "which layer is drawing that thing".
608
+ *
609
+ * The kept set is *restored*, not forced: anything we'd previously hidden
610
+ * comes back, but a layer the theme ships hidden stays hidden. Soloing must
611
+ * not invent geometry that never renders normally — see `show()`.
612
+ */
613
+ solo(...selectors: string[]): string[];
614
+ /**
615
+ * Set a paint property — `paint('units-fill', 'fill-color', '#f00')`. The
616
+ * original value is captured so `reset()` puts it back. Not sticky: unlike
617
+ * visibility, a theme swap rebuilds paint from the new style and re-applying
618
+ * a captured expression across themes is exactly the bug `setTheme` had to
619
+ * fix. Re-run it after a swap if you need it back.
620
+ */
621
+ paint(selector: string, prop: string, value: unknown): string[];
622
+ /**
623
+ * Drop every override and paint change, then let the SDK re-assert the
624
+ * visibility it owns (floor layers, POI filter, view mode). Back to the map
625
+ * you'd have had without touching anything.
626
+ */
627
+ reset(): void;
628
+ /**
629
+ * Hand the layers we just released back to the SDK, then re-assert whatever
630
+ * overrides are still standing.
631
+ *
632
+ * The second half is not belt-and-braces. The SDK's re-assert passes are
633
+ * all-or-nothing: with no POI filter active, `applyPOIFilter` writes
634
+ * `visible` to *every* POI category layer, and the floor / view-mode passes
635
+ * sweep their whole layer sets the same way. So releasing one group would
636
+ * un-hide every other group you'd hidden — hide labels, destinations and
637
+ * amenities, re-check one, and all three came back.
638
+ *
639
+ * Doing it here rather than waiting for the `styledata` the SDK's writes
640
+ * trigger also keeps it synchronous: MapLibre fires that on a later frame,
641
+ * so a UI reading visibility straight after this call would otherwise see —
642
+ * and render — the clobbered state.
643
+ */
644
+ private handBackToSdk;
645
+ /**
646
+ * The current override set as a plain object — save it, paste it back with
647
+ * `apply()` to reproduce the exact same framing for a screenshot later.
648
+ */
649
+ snapshot(): Record<string, Visibility>;
650
+ /** Apply a `snapshot()` (or any layer-id → visibility map). */
651
+ apply(snapshot: Record<string, Visibility>): string[];
652
+ /**
653
+ * Stop (or resume) re-asserting overrides when the style changes. Turn it
654
+ * off if you want a floor switch or `setPOIFilter` to win over what you
655
+ * toggled by hand.
656
+ */
657
+ setSticky(enabled: boolean): boolean;
658
+ /** Console cheat sheet. */
659
+ help(): Array<{
660
+ call: string;
661
+ does: string;
662
+ }>;
663
+ /**
664
+ * Resolve one selector to layer ids present in the active style, tried in
665
+ * order: group name → exact layer id → `type:<layer type>` → `/regex/` →
666
+ * case-insensitive substring on the id.
667
+ */
668
+ resolve(selector: string): string[];
669
+ private resolveAll;
670
+ private set;
671
+ /**
672
+ * Put these layers back to their pre-override visibility and forget them.
673
+ * Callers decide whether to follow up with `reapplySdkState` — `restore()`
674
+ * and `reset()` do, `solo()` deliberately doesn't.
675
+ */
676
+ private restoreVisibility;
677
+ /** Write one layer's visibility and remember it as an override. */
678
+ private write;
679
+ /**
680
+ * Re-assert overrides after something else rewrote layer visibility. Only
681
+ * writes when the current value actually differs, so this doesn't feed
682
+ * itself through the `styledata` it triggers.
683
+ */
684
+ private reapply;
685
+ private styleLayers;
686
+ private visibilityOf;
687
+ /**
688
+ * MapLibre throws from these getters/setters while a style is mid-swap (the
689
+ * layer exists in `getStyle()` but its owner is being replaced). A debug tool
690
+ * that can break the map it's inspecting is worse than useless.
691
+ */
692
+ private safe;
693
+ }
694
+
695
+ type LayerAudit = {
696
+ /** `featureType` values the CMS permits for this customer. */
697
+ allowed: string[];
698
+ /** `featureType` values actually present in the loaded floors. */
699
+ inData: string[];
700
+ /** `featureType` values some theme layer filters on. */
701
+ inStyle: string[];
702
+ /**
703
+ * Drawn on a map but not in the customer's allowed list — a mis-authored
704
+ * or renamed layer. These render only by accident (if the theme happens to
705
+ * match the string) and are invisible otherwise.
706
+ */
707
+ unauthorized: string[];
708
+ /**
709
+ * Present in the data and allowed, but no theme layer filters on it. The
710
+ * author drew something the map will never show.
711
+ */
712
+ unstyled: string[];
713
+ /**
714
+ * The theme filters on it, but no loaded floor contains it. Dead weight in
715
+ * the style *for this venue* — another venue may well use it, so this is a
716
+ * prompt to check, not a delete list. Cross-reference `allowed`: a value
717
+ * that isn't in there either is dead everywhere for this customer.
718
+ */
719
+ unused: string[];
720
+ /**
721
+ * Allowed by the CMS but no theme rule matches it, whether or not this
722
+ * venue happens to draw it. The SDK's total blind spot — an author can
723
+ * legitimately draw any of these and get nothing.
724
+ */
725
+ allowedNotStyled: string[];
726
+ };
727
+
500
728
  type LoggerFn = (...args: unknown[]) => void;
501
729
  type AmenityManagerDeps = {
502
730
  getVenue: () => any;
@@ -536,14 +764,40 @@ declare class AmenityManager {
536
764
  declare class MinuteMaps {
537
765
  private config;
538
766
  private map;
767
+ /**
768
+ * Generation token for `init()`. Bumped by every `init()` and by `destroy()`,
769
+ * so an init suspended on a network await can tell it has been superseded and
770
+ * bail instead of creating a map nobody holds a reference to.
771
+ *
772
+ * This is what makes `destroy()` safe *during* init: `destroy()` only removes
773
+ * `this.map`, which is still null until step 3, so a teardown that lands
774
+ * mid-fetch has nothing to clean up — and without this token the init would
775
+ * resume and build a fully live orphan (WebGL context, render loop, map-level
776
+ * listeners, YAH pulse) that can never be reached to shut down. React
777
+ * StrictMode's mount → unmount → mount does exactly this on every dev load.
778
+ *
779
+ * A counter, not a sticky `destroyed` flag: `destroy()` → `init()` re-init is
780
+ * a supported lifecycle (see the manager-class note in CLAUDE.md), so the
781
+ * instance has to stay usable after teardown.
782
+ */
783
+ private initGeneration;
539
784
  private data;
540
785
  private wayfindingProvider;
541
786
  private events;
542
787
  private floorsApi;
543
788
  private venue;
544
789
  private spriteKeys;
545
- private readonly debug;
790
+ private readonly debugEnabled;
546
791
  private readonly logger;
792
+ /**
793
+ * Console-facing layer inspector — `sdk.debug.hide('labels')`,
794
+ * `sdk.debug.solo('route')`, `sdk.debug.reset()`. Always present so demo
795
+ * code can drive it; additionally reachable as `window.mm.debug` when
796
+ * `options.debug` is on. See `DebugLayers`.
797
+ */
798
+ readonly debug: DebugLayers;
799
+ /** The `window` key `debug` mode installed this instance under, if any. */
800
+ private debugGlobalKey;
547
801
  private defaultCamera;
548
802
  private viewModes;
549
803
  /** Mirror of `config.options.reducedMotion`, mutable via `setReducedMotion`. */
@@ -564,6 +818,11 @@ declare class MinuteMaps {
564
818
  /** Captured destination-layer filters to restore when the selection clears,
565
819
  * or `null` when no destination focus is active. See `setDestinationFocus`. */
566
820
  private destFocusRestore;
821
+ /** The allow-list currently narrowing the destination layers, or `null` when
822
+ * no focus is active. Kept alongside `destFocusRestore` (which holds the
823
+ * *previous* filters, not the ids) so `setTheme` can re-apply the same focus
824
+ * to the new style's layers after a swap discards the old ones. */
825
+ private destFocusIds;
567
826
  private youAreHerePulse;
568
827
  /** Theme layers whose features represent a tappable destination/amenity.
569
828
  * A click hit-tests these (see `SelectionManager`) → `poiSelected`. The
@@ -594,14 +853,32 @@ declare class MinuteMaps {
594
853
  * visible as wayfinding reference. Restored on `clearHighlight`. */
595
854
  private static readonly DESTINATION_FOCUS_LAYERS;
596
855
  /** Categorical POI layers in the bundled theme that `setPOIFilter`
597
- * toggles. Layers absent from this list — `poi-you-are-here-*`, the
598
- * `poi-accessibility-icons` badge, and the `poi-highlight-*` layers
599
- * are intentionally unaffected; they're either anchors, status
600
- * indicators, or transient focus state, not categorical content. */
856
+ * toggles. Layers absent from this list — `poi-you-are-here-*` and the
857
+ * `poi-highlight-*` layers are intentionally unaffected; they're
858
+ * anchors or transient focus state, not categorical content. */
601
859
  private static readonly POI_CATEGORY_LAYERS;
602
860
  private poiVisibleTypes;
603
861
  constructor(config: SDKConfig);
604
862
  init(): Promise<void>;
863
+ /**
864
+ * Supply an image the current style has requested but doesn't have.
865
+ *
866
+ * Every imperatively-registered image is served from here, because a theme
867
+ * swap (`setStyle` with `diff: false`) drops all of them and the code that
868
+ * registered them doesn't run again:
869
+ *
870
+ * - the **route arrow** isn't in the sprite sheet at all — it's canvas-drawn
871
+ * on demand (this was already the case);
872
+ * - **amenity / destination icons** come back from `iconCache`. Their
873
+ * registrars run only during `init`, so before this they went missing on
874
+ * the first theme swap and never returned — the map kept the dots and
875
+ * labels but lost every badge and logo.
876
+ *
877
+ * Serving lazily (rather than re-registering everything on `style.load`)
878
+ * means only the ids the new style actually asks for are restored, with no
879
+ * refetch and no re-compositing.
880
+ */
881
+ private serveMissingStyleImage;
605
882
  on(event: string, cb: (e: MapEvent) => void): void;
606
883
  off(event: string, cb?: (e: MapEvent) => void): void;
607
884
  addControl(control: IControl, position?: ControlPosition): void;
@@ -635,6 +912,21 @@ declare class MinuteMaps {
635
912
  set3dEnabled(enabled: boolean): void;
636
913
  toggle3d(): void;
637
914
  getIs3dEnabled(): boolean;
915
+ /**
916
+ * (Re-)register per-amenity icons, per-destination logos, and the kiosk
917
+ * "you are here" icon. Needed both at init and after every `setTheme()`
918
+ * call — `map.setStyle(..., { diff: false })` tears down and recreates
919
+ * the whole `Style` object, which drops every image added at runtime via
920
+ * `map.addImage`. Only `route-arrow` re-registers itself lazily via
921
+ * `styleimagemissing`; everything else must be re-run explicitly here or
922
+ * it silently goes blank after a theme swap.
923
+ *
924
+ * `themeName === 'high-contrast'` recolors the amenity badge disc to
925
+ * `HIGH_CONTRAST_AMENITY_BADGE_COLOR`, leaving ring/glyph colors and
926
+ * connector (elevator/stairs/escalator) badges untouched. Failures per
927
+ * icon set are logged and skipped so one bad icon doesn't block the rest.
928
+ */
929
+ private registerRuntimeIcons;
638
930
  /**
639
931
  * Set the active map theme by name (`'default'` / `'high-contrast'`) or by
640
932
  * passing a custom `StyleSpecification`. The current floor, route, POIs
@@ -692,9 +984,9 @@ declare class MinuteMaps {
692
984
  getZoneForPOI(poi: POI): Zone | null;
693
985
  /** Human-readable detail fields for a POI info popover. Only surfaces
694
986
  * fields that exist on the current data — `category`, `floorName`,
695
- * `zoneName`, `keywords`, and `description` are each omitted when absent.
696
- * Keeps the display-field derivation (incl. the zone lookup) in the SDK
697
- * so consumers stay thin. */
987
+ * `zoneName`, `keywords`, `description`, and `imageUrl` are each omitted
988
+ * when absent. Keeps the display-field derivation (incl. the zone lookup)
989
+ * in the SDK so consumers stay thin. */
698
990
  getPOIDetails(poi: POI): {
699
991
  name: string;
700
992
  type: 'amenity' | 'destination' | 'kiosk';
@@ -704,12 +996,36 @@ declare class MinuteMaps {
704
996
  zoneDescription?: string;
705
997
  keywords?: string[];
706
998
  description?: string;
999
+ /** The destination's uploaded location image, ready for an `<img src>`.
1000
+ * Destinations only — amenities use sprite glyphs, not photos. Inline SVG
1001
+ * from `/all` comes back as a data URI; otherwise it's the uploaded uri
1002
+ * path. Absent when nothing was uploaded in the CMS. */
1003
+ imageUrl?: string;
707
1004
  };
708
1005
  /** Resolve the source Destination/Amenity record backing a rendered POI,
709
1006
  * for detail fields (category, localized description) that don't live on
710
1007
  * the built POI object. */
711
1008
  private getSourceEntity;
712
1009
  getPolygonLayers(): any[];
1010
+ /**
1011
+ * Cross-reference the venue's drawn layers against the customer's allowed
1012
+ * layer list (JACS `GET /customer/{id}/polygon-layer`) and against what the
1013
+ * active theme can actually render.
1014
+ *
1015
+ * Three failure modes, none of which is visible by looking at the map:
1016
+ * a layer drawn under a name the CMS doesn't list (`unauthorized`), a layer
1017
+ * legitimately drawn that no theme rule matches (`unstyled`), and a theme
1018
+ * rule with nothing to draw at this venue (`unused`). Runs automatically
1019
+ * once after `ready` when `options.debug` is on; call it directly —
1020
+ * `mm.validateMapLayers()` — any time.
1021
+ *
1022
+ * Only counts floors whose geojson has loaded. Init preloads the rest in
1023
+ * the background, so a call in the first moments after `ready` may report
1024
+ * fewer `inData` types than a call a second later.
1025
+ */
1026
+ validateMapLayers(): Promise<LayerAudit>;
1027
+ /** Debug-mode auto-run: log findings once, stay silent when clean. */
1028
+ private reportLayerAudit;
713
1029
  getFloorMapTemplate3d(floorId: string | number): any[];
714
1030
  getAllPOIs(floor?: Floor): POI[];
715
1031
  getYouAreHerePOI(floor?: Floor): POI | null;
@@ -952,6 +1268,19 @@ declare class MinuteMaps {
952
1268
  private findFloorForWaypoint;
953
1269
  getCameraPosition(): CameraState | null;
954
1270
  getMap(): Map | null;
1271
+ /**
1272
+ * Put this instance on `window` so a kiosk running in a browser can be
1273
+ * driven from devtools — `mm.debug.help()`, `mm.getMap()`, `mm.setTheme(…)`.
1274
+ * Debug builds only: nothing is exposed unless `options.debug` is on, and
1275
+ * `options.debugGlobal` renames the key (or `false` opts out entirely).
1276
+ *
1277
+ * Refuses to clobber a key that already holds something that isn't a
1278
+ * MinuteMaps — a kiosk shell with its own `window.mm` shouldn't lose it to
1279
+ * a dev-mode convenience.
1280
+ */
1281
+ private exposeDebugGlobal;
1282
+ /** Drop the `window` handle, but only if it still points at this instance. */
1283
+ private releaseDebugGlobal;
955
1284
  destroy(): void;
956
1285
  setCurrentFloor(floor: Floor): Promise<void>;
957
1286
  /**
@@ -1036,4 +1365,4 @@ declare function groupStepsIntoFloorSections(steps: WayfindStep[]): RouteFloorSe
1036
1365
  declare function activeSectionIndex(sections: RouteFloorSection[], activeStepIndex: number): number;
1037
1366
 
1038
1367
  export { MinuteMaps, activeSectionIndex, createMinuteMapsSDK, groupStepsIntoFloorSections };
1039
- export type { Amenity, AmenityBadgeStyle, AmenityWithFloor, Bounds, BoundsPadding, CameraState, Destination, DestinationChipStyle, EventCallback, Floor, FloorMetadata, JMapAuth, JMapConfig, JacsAuth, JacsConfig, MapEvent, POI, POISearchResult, RouteFloorSection, RoutePoint, RoutingOptions, SDKConfig, SDKOptions, ThemeName, TransitionStep, ViewOptions, WayfindCenterMode, WayfindStep, Waypoint, Zone };
1368
+ export type { Amenity, AmenityBadgeStyle, AmenityWithFloor, Bounds, BoundsPadding, CameraState, Destination, EventCallback, Floor, FloorMetadata, JMapAuth, JMapConfig, JacsAuth, JacsConfig, MapEvent, POI, POISearchResult, RouteFloorSection, RoutePoint, RoutingOptions, SDKConfig, SDKOptions, ThemeName, TransitionStep, ViewOptions, WayfindCenterMode, WayfindStep, Waypoint, Zone };