@palbase/web 3.0.0 → 4.0.0

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.
@@ -1,4 +1,3 @@
1
- import { Room, ExternalE2EEKeyProvider } from 'livekit-client';
2
1
  import { S as SessionStorageAdapter } from './storage-BPaeSG8K.cjs';
3
2
  import { F } from './pooled-flags-4GtDtsiu.js';
4
3
 
@@ -533,12 +532,9 @@ declare class Call {
533
532
  private readonly _listeners;
534
533
  private readonly _room;
535
534
  private readonly _keyProvider;
536
- /** @internal — obtain via PalbeCalls.start() / .accept() */
537
- constructor(callId: string, room: Room, keyProvider: ExternalE2EEKeyProvider);
538
535
  get state(): CallState;
539
536
  /** Snapshot of current remote participants (does NOT include the local participant). */
540
537
  get participants(): readonly CallParticipant[];
541
- get localParticipant(): Room['localParticipant'];
542
538
  /**
543
539
  * Subscribe to call changes (state + participant updates).
544
540
  * Returns an `Unsubscribe` function — matches the SDK's flags/auth pattern.
@@ -551,7 +547,7 @@ declare class Call {
551
547
  /**
552
548
  * Set a raw frame encryption key (ArrayBuffer) for this call.
553
549
  * Design seam for SP-1.x web-MLS: call this with the MLS exporter secret
554
- * to enable frame-level E2EE via ExternalE2EEKeyProvider.
550
+ * to enable frame-level E2EE via the media engine's external key provider.
555
551
  *
556
552
  * NOTE: The room must have been opened with `e2ee` options for this to take
557
553
  * effect. Currently calls connect WITHOUT e2ee — see module docstring.
@@ -559,13 +555,13 @@ declare class Call {
559
555
  * TODO(SP-1-web): wire this to MLS-derived key on session join.
560
556
  */
561
557
  setMediaKey(key: ArrayBuffer): Promise<void>;
562
- /** Leave the call and disconnect from the LiveKit room. */
558
+ /** Leave the call and disconnect from the media room. */
563
559
  leave(): Promise<void>;
564
560
  private _setState;
565
561
  private _emit;
566
562
  private _upsertParticipant;
567
563
  private _attachTrack;
568
- private _wireRoomEvents;
564
+ private _wireMediaEvents;
569
565
  }
570
566
  declare class PalbeCalls {
571
567
  private readonly rt;
@@ -575,9 +571,9 @@ declare class PalbeCalls {
575
571
  *
576
572
  * @param groupId - Messaging group display-id (`grp_<uuidv7>`)
577
573
  * @param media - Which media tracks to publish (default: audio + video)
578
- * @returns A `Call` in `connecting` state; transitions to `active` once LiveKit connects.
574
+ * @returns A `Call` in `connecting` state; transitions to `active` once the media room connects.
579
575
  *
580
- * @throws BackendError('network', { code: 'call_service_unavailable' }) if LiveKit SFU is down (503)
576
+ * @throws BackendError('network', { code: 'call_service_unavailable' }) if the SFU is down (503)
581
577
  * @throws BackendError('forbidden', { code: 'not_group_member' }) if the caller is not a member (403)
582
578
  * @throws BackendError('conflict', { code: 'call_room_full' }) if the room is full (409)
583
579
  */
@@ -920,19 +916,6 @@ interface MentionRange {
920
916
  length: number;
921
917
  mentionedUserId: string;
922
918
  }
923
- interface ReactionPayload {
924
- targetClientMsgId: string;
925
- emoji: string;
926
- op: 'add' | 'remove';
927
- }
928
- interface EditPayload {
929
- targetClientMsgId: string;
930
- newText: string;
931
- }
932
- interface DeletePayload {
933
- targetClientMsgId: string;
934
- scope: string;
935
- }
936
919
  /** Per-message TTL spec (decoded). senderSendTs present iff start === 'send'. */
937
920
  interface ExpirySpec {
938
921
  v: number;
@@ -941,51 +924,6 @@ interface ExpirySpec {
941
924
  senderSendTs: number | null;
942
925
  }
943
926
 
944
- /** A decoded incoming message handed to chat listeners. */
945
- interface IncomingMessage {
946
- kind: 'application' | 'commit' | 'proposal' | 'welcome';
947
- group: MessagingGroup;
948
- text: string | null;
949
- senderDeviceId: string | null;
950
- epoch: number;
951
- serverSeq: number;
952
- receivedAt: Date;
953
- /** The client-minted idempotency id from the decoded envelope (empty string for legacy/system). */
954
- clientMsgId: string;
955
- /** The decoded reply reference, if present in the envelope. */
956
- replyRef: ReplyRef | null;
957
- /**
958
- * The decoded envelope discriminator (`'text'`/`'reaction'`/`'media'`/…).
959
- * Defaults to `'text'` at every existing call site — only the reaction branch
960
- * sets `'reaction'`, so the Chat can route a reaction into its fold instead of
961
- * appending a visible bubble. Optional for forward-compat with old emitters.
962
- */
963
- envelopeType?: string;
964
- /** The decoded reaction payload, present only when `envelopeType === 'reaction'`. */
965
- reaction?: ReactionPayload | null;
966
- /** The decoded edit payload, present only when `envelopeType === 'edit'`. Lets
967
- * the Chat route an edit into its EditFold instead of appending a visible bubble. */
968
- edit?: EditPayload | null;
969
- /** The decoded delete payload, present only when `envelopeType === 'delete'`. Lets
970
- * the Chat route a delete-for-everyone tombstone into its DeleteFold instead of
971
- * appending a visible bubble. */
972
- delete?: DeletePayload | null;
973
- /** The decoded mention ranges (raw, un-normalized). Present on a `'text'` bubble
974
- * with `body_ranges` OR on an `'edit'` (the edit's replacement ranges). The Chat
975
- * normalizes + resolves roster names → `ChatMessage.mentions` (mentions T6). */
976
- bodyRanges?: MentionRange[] | null;
977
- /** The decoded `timer_set` payload, present only when `envelopeType === 'timer_set'`
978
- * (disappearing T10). Lets the Chat route a chat-default timer into its TimerFold
979
- * instead of appending a visible bubble. */
980
- timer?: {
981
- ttlSeconds: number | null;
982
- start: 'send' | 'read';
983
- } | null;
984
- /** The decoded per-message TTL spec, present only on a `'text'` bubble that carried an
985
- * `expiry` (disappearing T10). Lets the Chat arm the message's purge on first display. */
986
- expiry?: ExpirySpec | null;
987
- }
988
-
989
927
  /** The intended participants of a draft chat (held until the first send). */
990
928
  interface ChatDraft {
991
929
  mode: {
@@ -1163,16 +1101,6 @@ declare class Chat {
1163
1101
  * the SDK guarantees the DECISION, not the buzz. Mirrors iOS `Chat.onMentionElevation`.
1164
1102
  */
1165
1103
  onMentionElevation?: (message: ChatMessage) => void;
1166
- /** @internal — obtain via pb.messaging.directChat / groupChat / chat(id). */
1167
- constructor(args: {
1168
- group: MessagingGroup;
1169
- kind: ChatKind;
1170
- backend: ChatBackend;
1171
- } | {
1172
- draft: ChatDraft;
1173
- kind: ChatKind;
1174
- backend: ChatBackend;
1175
- });
1176
1104
  /** Subscribe to any change in this chat (messages/members/typing/state). */
1177
1105
  onChange(cb: () => void): Unsubscribe$1;
1178
1106
  private emit;
@@ -1212,8 +1140,6 @@ declare class Chat {
1212
1140
  private loadElevated;
1213
1141
  private hydrateHistory;
1214
1142
  private mergeHistory;
1215
- /** @internal — called by the backend's live subscription. */
1216
- ingestLive(incoming: IncomingMessage): Promise<void>;
1217
1143
  /** Normalize a decoded `IncomingMessage.expiry` / `StoredMessage.expiry` into the
1218
1144
  * `ExpirySpec` the arm path consumes (or null when absent). */
1219
1145
  private toExpirySpec;
@@ -1311,8 +1237,6 @@ declare class Chat {
1311
1237
  * history fold) is preserved. PRESERVES reactions + replyTo.
1312
1238
  */
1313
1239
  private applyEditOverlay;
1314
- /** @internal — called by the backend's conv subscription. */
1315
- applyConv(event: string, payload: Record<string, unknown>): void;
1316
1240
  private kindOf;
1317
1241
  private internalKey;
1318
1242
  private publicId;
@@ -1628,8 +1552,6 @@ declare class RealtimeChannel {
1628
1552
  /** The app-defined channel name (bare sub-topic, no "realtime:" prefix). */
1629
1553
  readonly name: string;
1630
1554
  private readonly owner;
1631
- /** @internal — obtain channels via `pb.realtime.channel(name)`. */
1632
- constructor(name: string, owner: PalbeRealtime);
1633
1555
  /**
1634
1556
  * Subscribe `handler` to `event` on this channel. Fire-and-forget: the
1635
1557
  * join rides the shared socket asynchronously. Hold the returned
@@ -1665,10 +1587,6 @@ declare class PalbeRealtime {
1665
1587
  destroy(): void;
1666
1588
  /** The observable connection status. Safe to read anywhere (reports `idle` until a socket exists). */
1667
1589
  get status(): RealtimeStatus;
1668
- /** @internal */
1669
- subscribe(topic: string, event: string, handler: RealtimeHandler): RealtimeSubscription;
1670
- /** @internal */
1671
- send(topic: string, event: string, payload: RealtimePayload): void;
1672
1590
  /** Lazily build + start the shared socket on first subscription/send. */
1673
1591
  private ensureSocket;
1674
1592
  private route;
@@ -1,4 +1,3 @@
1
- import { Room, ExternalE2EEKeyProvider } from 'livekit-client';
2
1
  import { S as SessionStorageAdapter } from './storage-BPaeSG8K.js';
3
2
  import { F } from './pooled-flags-4GtDtsiu.js';
4
3
 
@@ -533,12 +532,9 @@ declare class Call {
533
532
  private readonly _listeners;
534
533
  private readonly _room;
535
534
  private readonly _keyProvider;
536
- /** @internal — obtain via PalbeCalls.start() / .accept() */
537
- constructor(callId: string, room: Room, keyProvider: ExternalE2EEKeyProvider);
538
535
  get state(): CallState;
539
536
  /** Snapshot of current remote participants (does NOT include the local participant). */
540
537
  get participants(): readonly CallParticipant[];
541
- get localParticipant(): Room['localParticipant'];
542
538
  /**
543
539
  * Subscribe to call changes (state + participant updates).
544
540
  * Returns an `Unsubscribe` function — matches the SDK's flags/auth pattern.
@@ -551,7 +547,7 @@ declare class Call {
551
547
  /**
552
548
  * Set a raw frame encryption key (ArrayBuffer) for this call.
553
549
  * Design seam for SP-1.x web-MLS: call this with the MLS exporter secret
554
- * to enable frame-level E2EE via ExternalE2EEKeyProvider.
550
+ * to enable frame-level E2EE via the media engine's external key provider.
555
551
  *
556
552
  * NOTE: The room must have been opened with `e2ee` options for this to take
557
553
  * effect. Currently calls connect WITHOUT e2ee — see module docstring.
@@ -559,13 +555,13 @@ declare class Call {
559
555
  * TODO(SP-1-web): wire this to MLS-derived key on session join.
560
556
  */
561
557
  setMediaKey(key: ArrayBuffer): Promise<void>;
562
- /** Leave the call and disconnect from the LiveKit room. */
558
+ /** Leave the call and disconnect from the media room. */
563
559
  leave(): Promise<void>;
564
560
  private _setState;
565
561
  private _emit;
566
562
  private _upsertParticipant;
567
563
  private _attachTrack;
568
- private _wireRoomEvents;
564
+ private _wireMediaEvents;
569
565
  }
570
566
  declare class PalbeCalls {
571
567
  private readonly rt;
@@ -575,9 +571,9 @@ declare class PalbeCalls {
575
571
  *
576
572
  * @param groupId - Messaging group display-id (`grp_<uuidv7>`)
577
573
  * @param media - Which media tracks to publish (default: audio + video)
578
- * @returns A `Call` in `connecting` state; transitions to `active` once LiveKit connects.
574
+ * @returns A `Call` in `connecting` state; transitions to `active` once the media room connects.
579
575
  *
580
- * @throws BackendError('network', { code: 'call_service_unavailable' }) if LiveKit SFU is down (503)
576
+ * @throws BackendError('network', { code: 'call_service_unavailable' }) if the SFU is down (503)
581
577
  * @throws BackendError('forbidden', { code: 'not_group_member' }) if the caller is not a member (403)
582
578
  * @throws BackendError('conflict', { code: 'call_room_full' }) if the room is full (409)
583
579
  */
@@ -920,19 +916,6 @@ interface MentionRange {
920
916
  length: number;
921
917
  mentionedUserId: string;
922
918
  }
923
- interface ReactionPayload {
924
- targetClientMsgId: string;
925
- emoji: string;
926
- op: 'add' | 'remove';
927
- }
928
- interface EditPayload {
929
- targetClientMsgId: string;
930
- newText: string;
931
- }
932
- interface DeletePayload {
933
- targetClientMsgId: string;
934
- scope: string;
935
- }
936
919
  /** Per-message TTL spec (decoded). senderSendTs present iff start === 'send'. */
937
920
  interface ExpirySpec {
938
921
  v: number;
@@ -941,51 +924,6 @@ interface ExpirySpec {
941
924
  senderSendTs: number | null;
942
925
  }
943
926
 
944
- /** A decoded incoming message handed to chat listeners. */
945
- interface IncomingMessage {
946
- kind: 'application' | 'commit' | 'proposal' | 'welcome';
947
- group: MessagingGroup;
948
- text: string | null;
949
- senderDeviceId: string | null;
950
- epoch: number;
951
- serverSeq: number;
952
- receivedAt: Date;
953
- /** The client-minted idempotency id from the decoded envelope (empty string for legacy/system). */
954
- clientMsgId: string;
955
- /** The decoded reply reference, if present in the envelope. */
956
- replyRef: ReplyRef | null;
957
- /**
958
- * The decoded envelope discriminator (`'text'`/`'reaction'`/`'media'`/…).
959
- * Defaults to `'text'` at every existing call site — only the reaction branch
960
- * sets `'reaction'`, so the Chat can route a reaction into its fold instead of
961
- * appending a visible bubble. Optional for forward-compat with old emitters.
962
- */
963
- envelopeType?: string;
964
- /** The decoded reaction payload, present only when `envelopeType === 'reaction'`. */
965
- reaction?: ReactionPayload | null;
966
- /** The decoded edit payload, present only when `envelopeType === 'edit'`. Lets
967
- * the Chat route an edit into its EditFold instead of appending a visible bubble. */
968
- edit?: EditPayload | null;
969
- /** The decoded delete payload, present only when `envelopeType === 'delete'`. Lets
970
- * the Chat route a delete-for-everyone tombstone into its DeleteFold instead of
971
- * appending a visible bubble. */
972
- delete?: DeletePayload | null;
973
- /** The decoded mention ranges (raw, un-normalized). Present on a `'text'` bubble
974
- * with `body_ranges` OR on an `'edit'` (the edit's replacement ranges). The Chat
975
- * normalizes + resolves roster names → `ChatMessage.mentions` (mentions T6). */
976
- bodyRanges?: MentionRange[] | null;
977
- /** The decoded `timer_set` payload, present only when `envelopeType === 'timer_set'`
978
- * (disappearing T10). Lets the Chat route a chat-default timer into its TimerFold
979
- * instead of appending a visible bubble. */
980
- timer?: {
981
- ttlSeconds: number | null;
982
- start: 'send' | 'read';
983
- } | null;
984
- /** The decoded per-message TTL spec, present only on a `'text'` bubble that carried an
985
- * `expiry` (disappearing T10). Lets the Chat arm the message's purge on first display. */
986
- expiry?: ExpirySpec | null;
987
- }
988
-
989
927
  /** The intended participants of a draft chat (held until the first send). */
990
928
  interface ChatDraft {
991
929
  mode: {
@@ -1163,16 +1101,6 @@ declare class Chat {
1163
1101
  * the SDK guarantees the DECISION, not the buzz. Mirrors iOS `Chat.onMentionElevation`.
1164
1102
  */
1165
1103
  onMentionElevation?: (message: ChatMessage) => void;
1166
- /** @internal — obtain via pb.messaging.directChat / groupChat / chat(id). */
1167
- constructor(args: {
1168
- group: MessagingGroup;
1169
- kind: ChatKind;
1170
- backend: ChatBackend;
1171
- } | {
1172
- draft: ChatDraft;
1173
- kind: ChatKind;
1174
- backend: ChatBackend;
1175
- });
1176
1104
  /** Subscribe to any change in this chat (messages/members/typing/state). */
1177
1105
  onChange(cb: () => void): Unsubscribe$1;
1178
1106
  private emit;
@@ -1212,8 +1140,6 @@ declare class Chat {
1212
1140
  private loadElevated;
1213
1141
  private hydrateHistory;
1214
1142
  private mergeHistory;
1215
- /** @internal — called by the backend's live subscription. */
1216
- ingestLive(incoming: IncomingMessage): Promise<void>;
1217
1143
  /** Normalize a decoded `IncomingMessage.expiry` / `StoredMessage.expiry` into the
1218
1144
  * `ExpirySpec` the arm path consumes (or null when absent). */
1219
1145
  private toExpirySpec;
@@ -1311,8 +1237,6 @@ declare class Chat {
1311
1237
  * history fold) is preserved. PRESERVES reactions + replyTo.
1312
1238
  */
1313
1239
  private applyEditOverlay;
1314
- /** @internal — called by the backend's conv subscription. */
1315
- applyConv(event: string, payload: Record<string, unknown>): void;
1316
1240
  private kindOf;
1317
1241
  private internalKey;
1318
1242
  private publicId;
@@ -1628,8 +1552,6 @@ declare class RealtimeChannel {
1628
1552
  /** The app-defined channel name (bare sub-topic, no "realtime:" prefix). */
1629
1553
  readonly name: string;
1630
1554
  private readonly owner;
1631
- /** @internal — obtain channels via `pb.realtime.channel(name)`. */
1632
- constructor(name: string, owner: PalbeRealtime);
1633
1555
  /**
1634
1556
  * Subscribe `handler` to `event` on this channel. Fire-and-forget: the
1635
1557
  * join rides the shared socket asynchronously. Hold the returned
@@ -1665,10 +1587,6 @@ declare class PalbeRealtime {
1665
1587
  destroy(): void;
1666
1588
  /** The observable connection status. Safe to read anywhere (reports `idle` until a socket exists). */
1667
1589
  get status(): RealtimeStatus;
1668
- /** @internal */
1669
- subscribe(topic: string, event: string, handler: RealtimeHandler): RealtimeSubscription;
1670
- /** @internal */
1671
- send(topic: string, event: string, payload: RealtimePayload): void;
1672
1590
  /** Lazily build + start the shared socket on first subscription/send. */
1673
1591
  private ensureSocket;
1674
1592
  private route;
@@ -1735,19 +1735,29 @@ import {
1735
1735
  RoomEvent,
1736
1736
  Track
1737
1737
  } from "livekit-client";
1738
- var Call = class {
1738
+ var Call = class _Call {
1739
1739
  id;
1740
1740
  _state = "connecting";
1741
1741
  _participants = /* @__PURE__ */ new Map();
1742
1742
  _listeners = /* @__PURE__ */ new Set();
1743
1743
  _room;
1744
1744
  _keyProvider;
1745
- /** @internal obtain via PalbeCalls.start() / .accept() */
1745
+ // PRIVATE constructor + `@internal` factory: the media-engine types (`Room`,
1746
+ // `ExternalE2EEKeyProvider`) appear ONLY on a private constructor and an
1747
+ // `@internal` static factory, both of which `stripInternal` (set in this
1748
+ // package's tsconfig) removes from the emitted public `.d.ts`. So no engine type
1749
+ // ever reaches the public API surface — the same "no engine type in the public
1750
+ // interface" contract the iOS SDK enforces. Consumers obtain a `Call` only
1751
+ // through `pb.calls.start()` / `.accept()`.
1746
1752
  constructor(callId, room, keyProvider) {
1747
1753
  this.id = callId;
1748
1754
  this._room = room;
1749
1755
  this._keyProvider = keyProvider;
1750
- this._wireRoomEvents();
1756
+ this._wireMediaEvents();
1757
+ }
1758
+ /** @internal — facade-only factory; stripped from the public `.d.ts`. */
1759
+ static _create(callId, room, keyProvider) {
1760
+ return new _Call(callId, room, keyProvider);
1751
1761
  }
1752
1762
  // ─── State ──────────────────────────────────────────────────────────────
1753
1763
  get state() {
@@ -1757,9 +1767,9 @@ var Call = class {
1757
1767
  get participants() {
1758
1768
  return Array.from(this._participants.values());
1759
1769
  }
1760
- get localParticipant() {
1761
- return this._room.localParticipant;
1762
- }
1770
+ // (No `localParticipant` accessor: it would return a raw media-engine participant
1771
+ // object and leak the engine type onto the public API. Local mic/camera control is
1772
+ // exposed engine-agnostically via `mute()` / `setCamera()` below.)
1763
1773
  // ─── Subscribe ──────────────────────────────────────────────────────────
1764
1774
  /**
1765
1775
  * Subscribe to call changes (state + participant updates).
@@ -1783,7 +1793,7 @@ var Call = class {
1783
1793
  /**
1784
1794
  * Set a raw frame encryption key (ArrayBuffer) for this call.
1785
1795
  * Design seam for SP-1.x web-MLS: call this with the MLS exporter secret
1786
- * to enable frame-level E2EE via ExternalE2EEKeyProvider.
1796
+ * to enable frame-level E2EE via the media engine's external key provider.
1787
1797
  *
1788
1798
  * NOTE: The room must have been opened with `e2ee` options for this to take
1789
1799
  * effect. Currently calls connect WITHOUT e2ee — see module docstring.
@@ -1793,7 +1803,7 @@ var Call = class {
1793
1803
  async setMediaKey(key) {
1794
1804
  await this._keyProvider.setKey(key);
1795
1805
  }
1796
- /** Leave the call and disconnect from the LiveKit room. */
1806
+ /** Leave the call and disconnect from the media room. */
1797
1807
  async leave() {
1798
1808
  await this._room.disconnect();
1799
1809
  this._setState("ended");
@@ -1835,7 +1845,7 @@ var Call = class {
1835
1845
  }
1836
1846
  this._emit();
1837
1847
  }
1838
- _wireRoomEvents() {
1848
+ _wireMediaEvents() {
1839
1849
  this._room.on(RoomEvent.Connected, () => {
1840
1850
  this._setState("active");
1841
1851
  }).on(
@@ -1876,9 +1886,9 @@ var PalbeCalls = class {
1876
1886
  *
1877
1887
  * @param groupId - Messaging group display-id (`grp_<uuidv7>`)
1878
1888
  * @param media - Which media tracks to publish (default: audio + video)
1879
- * @returns A `Call` in `connecting` state; transitions to `active` once LiveKit connects.
1889
+ * @returns A `Call` in `connecting` state; transitions to `active` once the media room connects.
1880
1890
  *
1881
- * @throws BackendError('network', { code: 'call_service_unavailable' }) if LiveKit SFU is down (503)
1891
+ * @throws BackendError('network', { code: 'call_service_unavailable' }) if the SFU is down (503)
1882
1892
  * @throws BackendError('forbidden', { code: 'not_group_member' }) if the caller is not a member (403)
1883
1893
  * @throws BackendError('conflict', { code: 'call_room_full' }) if the room is full (409)
1884
1894
  */
@@ -1935,7 +1945,7 @@ var PalbeCalls = class {
1935
1945
  adaptiveStream: true,
1936
1946
  dynacast: true
1937
1947
  });
1938
- const call = new Call(callId, room, keyProvider);
1948
+ const call = Call._create(callId, room, keyProvider);
1939
1949
  await room.connect(edgeUrl, token);
1940
1950
  if (media.includes("audio")) {
1941
1951
  await room.localParticipant.setMicrophoneEnabled(true);
@@ -8924,7 +8934,7 @@ function defaultSessionStorage(key) {
8924
8934
  }
8925
8935
 
8926
8936
  // src/version.ts
8927
- var VERSION = "3.0.0";
8937
+ var VERSION = "4.0.0";
8928
8938
 
8929
8939
  // src/runtime.ts
8930
8940
  function buildRuntime(config) {
@@ -9351,4 +9361,4 @@ export {
9351
9361
  pb,
9352
9362
  createBoundClient
9353
9363
  };
9354
- //# sourceMappingURL=chunk-3HVTEZ7N.js.map
9364
+ //# sourceMappingURL=chunk-NP4NIY7A.js.map