@ai-matrx/meet 0.11.43 → 0.11.44

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.
@@ -2,7 +2,7 @@
2
2
  "use client";
3
3
 
4
4
  // src/skins/meet/components.tsx
5
- import { useEffect as useEffect6, useLayoutEffect, useRef as useRef6, useState as useState4 } from "react";
5
+ import { useEffect as useEffect6, useLayoutEffect, useRef as useRef6, useState as useState5 } from "react";
6
6
 
7
7
  // src/react/facade.ts
8
8
  import { useMemo as useMemo5 } from "react";
@@ -283,11 +283,13 @@ function minutesLeft(policy, startedAtMs, nowMs) {
283
283
  }
284
284
 
285
285
  // src/core/attendance.ts
286
+ var IDLE_PREVIEW = { state: "idle", unavailable: null };
286
287
  var IDLE_MEDIA_REGION = {
287
288
  permission: { microphone: "unknown", camera: "unknown" },
288
289
  audioOutput: "ok",
289
290
  notice: null,
290
- offer: null
291
+ offer: null,
292
+ preview: { microphone: IDLE_PREVIEW, camera: IDLE_PREVIEW }
291
293
  };
292
294
  var IDLE_TRACK = { enabled: false, unavailable: null };
293
295
  var IDLE_MEDIA = {
@@ -446,7 +448,7 @@ function effectiveStanding(snapshot) {
446
448
  var REACTION_TTL_MS = 5e3;
447
449
 
448
450
  // src/react/root.tsx
449
- import { useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2 } from "react";
451
+ import { useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
450
452
 
451
453
  // src/core/media-supervisor.ts
452
454
  function classifyDeviceFailure(error, permission) {
@@ -508,7 +510,7 @@ function deviceFixSteps(kind, reason, where) {
508
510
  case "safari":
509
511
  return where.os === "ios" ? [`Settings \u203A Apps \u203A Safari \u203A ${device}`, "Choose Allow", "Return here and press Try again"] : ["Safari \u203A Settings for This Website", `Set ${device} to Allow`, "Press Try again"];
510
512
  default:
511
- return ["Click the icon left of the web address", `Set ${device} to Allow`, "Press Try again"];
513
+ return ["Click the site settings icon in the address bar", `Set ${device} to Allow`, "Press Try again"];
512
514
  }
513
515
  case "blocked_os": {
514
516
  const app = where.browser === "chrome" ? "Google Chrome" : where.browser === "edge" ? "Microsoft Edge" : where.browser === "firefox" ? "Firefox" : "your browser";
@@ -602,6 +604,21 @@ function observedDevice(track, permission = "unknown", held = null) {
602
604
  const reason = deviceUnavailableReason(track, permission);
603
605
  return reason === null ? "muted_by_me" : `unavailable:${reason}`;
604
606
  }
607
+ function observedPreview(preview, permission = "unknown") {
608
+ if (permission === "denied") return "unavailable:denied";
609
+ switch (preview.state) {
610
+ case "on":
611
+ return "on";
612
+ case "off":
613
+ return "muted_by_me";
614
+ case "prompting":
615
+ return "prompting";
616
+ case "unavailable":
617
+ return `unavailable:${preview.unavailable?.reason ?? "failed"}`;
618
+ default:
619
+ return null;
620
+ }
621
+ }
605
622
  function endedRecord(snapshot, given) {
606
623
  const record = snapshot?.meeting ?? given;
607
624
  return record !== null && record.endedAt !== null;
@@ -625,18 +642,22 @@ function observe(input) {
625
642
  const canAdmit = actual !== "none" && ADMITTER_ROLES.has(actual);
626
643
  const role = actual === "none" || snapshot === null ? "none" : observedRole(actual, effectiveStanding(snapshot));
627
644
  const deviceInPlay = phase === "joining" || inCall;
645
+ const region = snapshot?.mediaRegion;
646
+ const atPrejoin = phase === "prejoin" && region !== void 0;
628
647
  return {
629
648
  phase,
630
649
  reason: phase === "ended" ? snapshot?.reason ?? null : snapshot?.reason ?? reasonOf(phase),
631
650
  role,
632
- connection: snapshot?.connection ?? "stable",
651
+ // `net-blip`: in the call, a drop shorter than `reconnect_banner_delay_ms` is not something the
652
+ // person sees — the contract says what is on screen, so it reads `stable` until the banner shows.
653
+ connection: snapshot === null ? "stable" : inCall && snapshot.connection !== "stable" && !snapshot.connectionBanner ? "stable" : snapshot.connection,
633
654
  hostPresent: inCall && snapshot !== null ? snapshot.participants.some((p) => ADMITTER_ROLES.has(p.role)) : snapshot !== null && isWaitingPhase(snapshot.phase) ? snapshot.waiting?.admittersPresent ?? null : null,
634
655
  lobbyCount: canAdmit && snapshot !== null ? snapshot.lobby.filter((entry) => entry.state === "knocking").length : 0,
635
656
  recording: snapshot?.recording === "recording" || snapshot?.recording === "stopping",
636
657
  // S6c: the autoplay region is known only inside the room (no remote audio exists elsewhere).
637
658
  audioBlocked: inCall && snapshot !== null ? snapshot.mediaRegion.audioOutput === "blocked" : null,
638
- camera: deviceInPlay && snapshot !== null ? observedDevice(snapshot.media.camera, snapshot.mediaRegion.permission.camera, lockedFor(snapshot, "camera", inCall)) : null,
639
- microphone: deviceInPlay && snapshot !== null ? observedDevice(snapshot.media.microphone, snapshot.mediaRegion.permission.microphone, lockedFor(snapshot, "microphone", inCall)) : null
659
+ camera: deviceInPlay && snapshot !== null ? observedDevice(snapshot.media.camera, snapshot.mediaRegion.permission.camera, lockedFor(snapshot, "camera", inCall)) : atPrejoin ? observedPreview(region.preview.camera, region.permission.camera) : null,
660
+ microphone: deviceInPlay && snapshot !== null ? observedDevice(snapshot.media.microphone, snapshot.mediaRegion.permission.microphone, lockedFor(snapshot, "microphone", inCall)) : atPrejoin ? observedPreview(region.preview.microphone, region.permission.microphone) : null
640
661
  };
641
662
  }
642
663
  function lockedFor(snapshot, kind, inCall) {
@@ -890,7 +911,7 @@ function useCanRecord() {
890
911
  }
891
912
 
892
913
  // src/react/root.tsx
893
- import { jsx as jsx2 } from "react/jsx-runtime";
914
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
894
915
  function useCoreObservation(options = {}) {
895
916
  const snapshot = useMeetSnapshot();
896
917
  const { meeting, phase, reason } = options;
@@ -1047,7 +1068,7 @@ function useMeetAppPanel(meeting) {
1047
1068
  }
1048
1069
 
1049
1070
  // src/react/hooks.ts
1050
- import { useCallback as useCallback2, useEffect as useEffect3, useMemo as useMemo4, useRef as useRef3, useState as useState2, useSyncExternalStore as useSyncExternalStore2 } from "react";
1071
+ import { useCallback as useCallback2, useEffect as useEffect3, useMemo as useMemo4, useRef as useRef3, useState as useState3, useSyncExternalStore as useSyncExternalStore2 } from "react";
1051
1072
  import { useRealtimeManager as useRealtimeManager2 } from "@ai-matrx/realtime/react";
1052
1073
 
1053
1074
  // src/core/record.ts
@@ -1173,7 +1194,8 @@ function useRoom() {
1173
1194
  failure: snapshot?.failure ?? null,
1174
1195
  secondDevice: snapshot?.secondDevice ?? null,
1175
1196
  local,
1176
- canShareScreen: engine?.supportsScreenShare() ?? true,
1197
+ // An observer (role `viewer`) publishes nothing: no Share screen to press and be refused (MD-16).
1198
+ canShareScreen: (engine?.supportsScreenShare() ?? true) && !isObserverRole(snapshot?.grants.role ?? null),
1177
1199
  join: useCallback2(
1178
1200
  async (request) => requireEngine(engine, "join").join(request),
1179
1201
  [engine]
@@ -1230,7 +1252,7 @@ function useRoom() {
1230
1252
  }
1231
1253
  function useStage(pageSize = DEFAULT_PAGE_SIZE) {
1232
1254
  const snapshot = useMeetSnapshot();
1233
- const [page, setPage] = useState2(0);
1255
+ const [page, setPage] = useState3(0);
1234
1256
  const stage = useMemo4(
1235
1257
  () => computeStage({
1236
1258
  participants: snapshot?.participants ?? [],
@@ -1291,7 +1313,7 @@ function useLobby() {
1291
1313
  };
1292
1314
  }
1293
1315
  function useCountdown(untilMs) {
1294
- const [now, setNow] = useState2(() => Date.now());
1316
+ const [now, setNow] = useState3(() => Date.now());
1295
1317
  const active = typeof untilMs === "number" && untilMs > now;
1296
1318
  useEffect3(() => {
1297
1319
  if (!active) return void 0;
@@ -1304,7 +1326,7 @@ function useCountdown(untilMs) {
1304
1326
  }
1305
1327
  function useKnockNotice() {
1306
1328
  const lobby = useLobby();
1307
- const [dismissed, setDismissed] = useState2([]);
1329
+ const [dismissed, setDismissed] = useState3([]);
1308
1330
  const keyOf = (entry) => `${entry.identity}@${entry.knockedAt}`;
1309
1331
  const open = lobby.canAdmit ? lobby.waiting.filter((entry) => !dismissed.includes(keyOf(entry))) : [];
1310
1332
  const knocker = open[0] ?? null;
@@ -1390,11 +1412,11 @@ function useMeetAi() {
1390
1412
  const host = useMeetHost();
1391
1413
  const snapshot = useMeetSnapshot();
1392
1414
  const isHost = useIsHost();
1393
- const [asking, setAsking] = useState2(false);
1394
- const [answer, setAnswer] = useState2(null);
1395
- const [coverage, setCoverage] = useState2(null);
1396
- const [phase, setPhase] = useState2(null);
1397
- const [error, setError] = useState2(null);
1415
+ const [asking, setAsking] = useState3(false);
1416
+ const [answer, setAnswer] = useState3(null);
1417
+ const [coverage, setCoverage] = useState3(null);
1418
+ const [phase, setPhase] = useState3(null);
1419
+ const [error, setError] = useState3(null);
1398
1420
  const ai = host?.ai ?? null;
1399
1421
  const meeting = snapshot?.meeting ?? null;
1400
1422
  const participants = snapshot?.participants ?? [];
@@ -1547,8 +1569,8 @@ function useEndMeeting() {
1547
1569
  const host = useMeetHost();
1548
1570
  const snapshot = useMeetSnapshot();
1549
1571
  const isHost = useIsHost();
1550
- const [ending, setEnding] = useState2(false);
1551
- const [notice, setNotice] = useState2(null);
1572
+ const [ending, setEnding] = useState3(false);
1573
+ const [notice, setNotice] = useState3(null);
1552
1574
  const meeting = snapshot?.meeting ?? null;
1553
1575
  const session = host?.meetings ?? null;
1554
1576
  return {
@@ -1599,6 +1621,12 @@ function useMediaSupervisor() {
1599
1621
  retry: useCallback2(
1600
1622
  async (kind) => kind === "microphone" ? engine?.setMicrophoneEnabled(true) : engine?.setCameraEnabled(true),
1601
1623
  [engine]
1624
+ ),
1625
+ reportPreview: useCallback2(
1626
+ (kind, outcome) => {
1627
+ void engine?.previewDevice(kind, outcome);
1628
+ },
1629
+ [engine]
1602
1630
  )
1603
1631
  };
1604
1632
  }
@@ -1618,7 +1646,7 @@ function useReactions() {
1618
1646
  return snapshot?.reactions ?? [];
1619
1647
  }
1620
1648
  function useElapsed(startedAt) {
1621
- const [now, setNow] = useState2(() => Date.now());
1649
+ const [now, setNow] = useState3(() => Date.now());
1622
1650
  useEffect3(() => {
1623
1651
  if (startedAt === null) return void 0;
1624
1652
  const timer = setInterval(() => setNow(Date.now()), 1e3);
@@ -1635,7 +1663,7 @@ function useHostControls() {
1635
1663
  (participant) => participant.identity === snapshot.localIdentity
1636
1664
  );
1637
1665
  const actor = me === void 0 ? void 0 : { ...me, role };
1638
- const [busy, setBusy] = useState2(false);
1666
+ const [busy, setBusy] = useState3(false);
1639
1667
  const inRoom = host?.inRoom ?? null;
1640
1668
  const store = host?.store ?? null;
1641
1669
  const notice = snapshot?.actionNotice ?? null;
@@ -1718,7 +1746,7 @@ function useModerationNotice() {
1718
1746
  };
1719
1747
  }
1720
1748
  function useAudioLevel(stream) {
1721
- const [level, setLevel] = useState2(0);
1749
+ const [level, setLevel] = useState3(0);
1722
1750
  useEffect3(() => {
1723
1751
  if (stream === null || stream.getAudioTracks().length === 0) {
1724
1752
  setLevel(0);
@@ -1789,10 +1817,10 @@ function useGuestRecordAccess(meeting) {
1789
1817
  const host = useMeetHost();
1790
1818
  const api = host?.api ?? null;
1791
1819
  const stored = guestRecordAccessSetting(meeting);
1792
- const [chosen, setChosen] = useState2(null);
1793
- const [effective, setEffective] = useState2(null);
1794
- const [saving, setSaving] = useState2(false);
1795
- const [error, setError] = useState2(null);
1820
+ const [chosen, setChosen] = useState3(null);
1821
+ const [effective, setEffective] = useState3(null);
1822
+ const [saving, setSaving] = useState3(false);
1823
+ const [error, setError] = useState3(null);
1796
1824
  useEffect3(() => {
1797
1825
  setChosen(null);
1798
1826
  }, [stored, meeting?.id]);
@@ -1831,7 +1859,7 @@ function useGuestRecordAccess(meeting) {
1831
1859
  function useLivePolicy() {
1832
1860
  const snapshot = useMeetSnapshot();
1833
1861
  const role = useRole();
1834
- const [now, setNow] = useState2(() => Date.now());
1862
+ const [now, setNow] = useState3(() => Date.now());
1835
1863
  const limited = (snapshot?.livePolicy.timeLimitMinutes ?? 0) > 0;
1836
1864
  useEffect3(() => {
1837
1865
  if (!limited) return void 0;
@@ -1919,6 +1947,39 @@ function useCollabPanelRequest(onRequest) {
1919
1947
  // src/core/reactions.ts
1920
1948
  var MEET_REACTIONS = ["\u{1F496}", "\u{1F44D}", "\u{1F389}", "\u{1F44F}", "\u{1F602}", "\u{1F62E}", "\u{1F622}", "\u{1F914}", "\u{1F44E}"];
1921
1949
 
1950
+ // src/core/speaking-detector.ts
1951
+ function createSpeakingWhileMutedDetector(options = {}) {
1952
+ const threshold = options.threshold ?? 0.06;
1953
+ const holdMs = options.holdMs ?? 600;
1954
+ const gapMs = options.gapMs ?? 400;
1955
+ const cooldownMs = options.cooldownMs ?? 2e4;
1956
+ let speechStart = null;
1957
+ let lastLoud = null;
1958
+ let firedAt = null;
1959
+ return {
1960
+ feed(level, at) {
1961
+ if (level >= threshold) {
1962
+ if (speechStart === null || lastLoud === null || at - lastLoud > gapMs) speechStart = at;
1963
+ lastLoud = at;
1964
+ } else if (lastLoud !== null && at - lastLoud > gapMs) {
1965
+ speechStart = null;
1966
+ lastLoud = null;
1967
+ }
1968
+ if (speechStart === null || at - speechStart < holdMs) return false;
1969
+ if (firedAt !== null && at - firedAt < cooldownMs) return false;
1970
+ firedAt = at;
1971
+ speechStart = null;
1972
+ lastLoud = null;
1973
+ return true;
1974
+ },
1975
+ reset() {
1976
+ speechStart = null;
1977
+ lastLoud = null;
1978
+ firedAt = null;
1979
+ }
1980
+ };
1981
+ }
1982
+
1922
1983
  // src/react/facade.ts
1923
1984
  var NO_ACTIONS = {
1924
1985
  join: async () => void 0,
@@ -1983,10 +2044,10 @@ function useMeetCore() {
1983
2044
  import { Alert, AlertDescription, Button, Checkbox, ErrorBox, Label, SegmentedControl, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@ai-matrx/design-system";
1984
2045
 
1985
2046
  // src/skins/meet/collab.tsx
1986
- import { useEffect as useEffect5, useRef as useRef5, useState as useState3 } from "react";
2047
+ import { useEffect as useEffect5, useRef as useRef5, useState as useState4 } from "react";
1987
2048
 
1988
2049
  // src/skins/meet/icons.tsx
1989
- import { jsx as jsx4, jsxs } from "react/jsx-runtime";
2050
+ import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
1990
2051
  function Icon({ children, ...props }) {
1991
2052
  return /* @__PURE__ */ jsx4(
1992
2053
  "svg",
@@ -2007,14 +2068,14 @@ function Icon({ children, ...props }) {
2007
2068
  );
2008
2069
  }
2009
2070
  function MicIcon(props) {
2010
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2071
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2011
2072
  /* @__PURE__ */ jsx4("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z" }),
2012
2073
  /* @__PURE__ */ jsx4("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
2013
2074
  /* @__PURE__ */ jsx4("path", { d: "M12 19v3" })
2014
2075
  ] });
2015
2076
  }
2016
2077
  function MicOffIcon(props) {
2017
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2078
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2018
2079
  /* @__PURE__ */ jsx4("path", { d: "M2 2l20 20" }),
2019
2080
  /* @__PURE__ */ jsx4("path", { d: "M9 9v3a3 3 0 0 0 5.12 2.12" }),
2020
2081
  /* @__PURE__ */ jsx4("path", { d: "M15 9.34V5a3 3 0 0 0-5.94-.6" }),
@@ -2023,20 +2084,20 @@ function MicOffIcon(props) {
2023
2084
  ] });
2024
2085
  }
2025
2086
  function CameraIcon(props) {
2026
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2087
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2027
2088
  /* @__PURE__ */ jsx4("path", { d: "m23 7-7 5 7 5V7Z" }),
2028
2089
  /* @__PURE__ */ jsx4("rect", { x: "1", y: "5", width: "15", height: "14", rx: "2" })
2029
2090
  ] });
2030
2091
  }
2031
2092
  function CameraOffIcon(props) {
2032
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2093
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2033
2094
  /* @__PURE__ */ jsx4("path", { d: "M2 2l20 20" }),
2034
2095
  /* @__PURE__ */ jsx4("path", { d: "M10.66 5H14a2 2 0 0 1 2 2v3.34l1 1L23 7v10" }),
2035
2096
  /* @__PURE__ */ jsx4("path", { d: "M16 16a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h2" })
2036
2097
  ] });
2037
2098
  }
2038
2099
  function ScreenShareIcon(props) {
2039
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2100
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2040
2101
  /* @__PURE__ */ jsx4("rect", { x: "2", y: "3", width: "20", height: "14", rx: "2" }),
2041
2102
  /* @__PURE__ */ jsx4("path", { d: "M8 21h8M12 17v4" }),
2042
2103
  /* @__PURE__ */ jsx4("path", { d: "M12 13V8m0 0-2.5 2.5M12 8l2.5 2.5" })
@@ -2049,7 +2110,7 @@ function PhoneOffIcon(props) {
2049
2110
  return /* @__PURE__ */ jsx4(Icon, { fill: "currentColor", stroke: "none", ...props, children: /* @__PURE__ */ jsx4("path", { d: "M12 9c-1.6 0-3.15.25-4.6.72v3.1c0 .39-.23.74-.56.9-.98.49-1.87 1.12-2.66 1.85-.18.18-.43.28-.7.28-.28 0-.53-.11-.71-.29L.29 13.08a.99.99 0 0 1-.29-.7c0-.28.11-.53.29-.71C3.34 8.78 7.46 7 12 7s8.66 1.78 11.71 4.67c.18.18.29.43.29.71 0 .28-.11.53-.29.71l-2.48 2.48c-.18.18-.43.29-.71.29-.27 0-.52-.11-.7-.28a11.27 11.27 0 0 0-2.67-1.85.996.996 0 0 1-.56-.9v-3.1C15.15 9.25 13.6 9 12 9Z" }) });
2050
2111
  }
2051
2112
  function HandIcon(props) {
2052
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2113
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2053
2114
  /* @__PURE__ */ jsx4("path", { d: "M18 11V6a2 2 0 0 0-4 0v5" }),
2054
2115
  /* @__PURE__ */ jsx4("path", { d: "M14 10V4a2 2 0 0 0-4 0v7" }),
2055
2116
  /* @__PURE__ */ jsx4("path", { d: "M10 10.5V6a2 2 0 0 0-4 0v8" }),
@@ -2060,7 +2121,7 @@ function ChatIcon(props) {
2060
2121
  return /* @__PURE__ */ jsx4(Icon, { ...props, children: /* @__PURE__ */ jsx4("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2Z" }) });
2061
2122
  }
2062
2123
  function PeopleIcon(props) {
2063
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2124
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2064
2125
  /* @__PURE__ */ jsx4("path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" }),
2065
2126
  /* @__PURE__ */ jsx4("circle", { cx: "9", cy: "7", r: "4" }),
2066
2127
  /* @__PURE__ */ jsx4("path", { d: "M22 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75" })
@@ -2070,37 +2131,37 @@ function RecordIcon(props) {
2070
2131
  return /* @__PURE__ */ jsx4(Icon, { ...props, children: /* @__PURE__ */ jsx4("circle", { cx: "12", cy: "12", r: "8", fill: "currentColor", stroke: "none" }) });
2071
2132
  }
2072
2133
  function SparklesIcon(props) {
2073
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2134
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2074
2135
  /* @__PURE__ */ jsx4("path", { d: "M12 3l1.9 4.6L18.5 9.5l-4.6 1.9L12 16l-1.9-4.6L5.5 9.5l4.6-1.9L12 3Z" }),
2075
2136
  /* @__PURE__ */ jsx4("path", { d: "M19 15l.9 2.1 2.1.9-2.1.9-.9 2.1-.9-2.1-2.1-.9 2.1-.9L19 15Z" })
2076
2137
  ] });
2077
2138
  }
2078
2139
  function CaptionsIcon(props) {
2079
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2140
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2080
2141
  /* @__PURE__ */ jsx4("rect", { x: "3", y: "5", width: "18", height: "14", rx: "2" }),
2081
2142
  /* @__PURE__ */ jsx4("path", { d: "M10 10.5a2 2 0 1 0 0 3M16 10.5a2 2 0 1 0 0 3" })
2082
2143
  ] });
2083
2144
  }
2084
2145
  function NotesIcon(props) {
2085
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2146
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2086
2147
  /* @__PURE__ */ jsx4("path", { d: "M4 20l1-4L16.5 4.5a2.1 2.1 0 0 1 3 3L8 19l-4 1Z" }),
2087
2148
  /* @__PURE__ */ jsx4("path", { d: "M14 7l3 3" })
2088
2149
  ] });
2089
2150
  }
2090
2151
  function LockIcon(props) {
2091
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2152
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2092
2153
  /* @__PURE__ */ jsx4("rect", { x: "4", y: "10", width: "16", height: "11", rx: "2" }),
2093
2154
  /* @__PURE__ */ jsx4("path", { d: "M8 10V7a4 4 0 0 1 8 0v3" })
2094
2155
  ] });
2095
2156
  }
2096
2157
  function LayoutIcon(props) {
2097
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2158
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2098
2159
  /* @__PURE__ */ jsx4("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
2099
2160
  /* @__PURE__ */ jsx4("path", { d: "M3 9h18M9 21V9" })
2100
2161
  ] });
2101
2162
  }
2102
2163
  function SettingsIcon(props) {
2103
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2164
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2104
2165
  /* @__PURE__ */ jsx4("circle", { cx: "12", cy: "12", r: "3" }),
2105
2166
  /* @__PURE__ */ jsx4("path", { d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.6a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z" })
2106
2167
  ] });
@@ -2112,19 +2173,19 @@ function CloseIcon(props) {
2112
2173
  return /* @__PURE__ */ jsx4(Icon, { ...props, children: /* @__PURE__ */ jsx4("path", { d: "M18 6 6 18M6 6l12 12" }) });
2113
2174
  }
2114
2175
  function PinIcon(props) {
2115
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2176
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2116
2177
  /* @__PURE__ */ jsx4("path", { d: "M12 17v5" }),
2117
2178
  /* @__PURE__ */ jsx4("path", { d: "M9 2h6l-1 6 3.5 3.5V14H6.5v-2.5L10 8 9 2Z" })
2118
2179
  ] });
2119
2180
  }
2120
2181
  function WifiLowIcon(props) {
2121
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2182
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2122
2183
  /* @__PURE__ */ jsx4("path", { d: "M12 20h.01" }),
2123
2184
  /* @__PURE__ */ jsx4("path", { d: "M8.5 16.5a5 5 0 0 1 7 0" })
2124
2185
  ] });
2125
2186
  }
2126
2187
  function SmileIcon(props) {
2127
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2188
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2128
2189
  /* @__PURE__ */ jsx4("circle", { cx: "12", cy: "12", r: "10" }),
2129
2190
  /* @__PURE__ */ jsx4("path", { d: "M8 14s1.5 2 4 2 4-2 4-2" }),
2130
2191
  /* @__PURE__ */ jsx4("line", { x1: "9", x2: "9.01", y1: "9", y2: "9" }),
@@ -2132,20 +2193,20 @@ function SmileIcon(props) {
2132
2193
  ] });
2133
2194
  }
2134
2195
  function MoreIcon(props) {
2135
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2196
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2136
2197
  /* @__PURE__ */ jsx4("circle", { cx: "12", cy: "12", r: "1" }),
2137
2198
  /* @__PURE__ */ jsx4("circle", { cx: "19", cy: "12", r: "1" }),
2138
2199
  /* @__PURE__ */ jsx4("circle", { cx: "5", cy: "12", r: "1" })
2139
2200
  ] });
2140
2201
  }
2141
2202
  function SearchIcon(props) {
2142
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2203
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2143
2204
  /* @__PURE__ */ jsx4("circle", { cx: "11", cy: "11", r: "8" }),
2144
2205
  /* @__PURE__ */ jsx4("path", { d: "m21 21-4.3-4.3" })
2145
2206
  ] });
2146
2207
  }
2147
2208
  function KeyboardIcon(props) {
2148
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2209
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2149
2210
  /* @__PURE__ */ jsx4("path", { d: "M10 8h.01M12 12h.01M14 8h.01M16 12h.01M18 8h.01M6 8h.01M7 16h10M8 12h.01" }),
2150
2211
  /* @__PURE__ */ jsx4("rect", { width: "20", height: "16", x: "2", y: "4", rx: "2" })
2151
2212
  ] });
@@ -2154,7 +2215,7 @@ function SpotlightIcon(props) {
2154
2215
  return /* @__PURE__ */ jsx4(Icon, { ...props, children: /* @__PURE__ */ jsx4("path", { d: "M12 2 15 8.5 22 9.3 17 14 18.2 21 12 17.6 5.8 21 7 14 2 9.3 9 8.5Z" }) });
2155
2216
  }
2156
2217
  function SignalIcon({ bars, ...props }) {
2157
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2218
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2158
2219
  /* @__PURE__ */ jsx4("path", { d: "M4 20v-2", opacity: bars >= 1 ? 1 : 0.3 }),
2159
2220
  /* @__PURE__ */ jsx4("path", { d: "M10 20v-6", opacity: bars >= 2 ? 1 : 0.3 }),
2160
2221
  /* @__PURE__ */ jsx4("path", { d: "M16 20V9", opacity: bars >= 3 ? 1 : 0.3 }),
@@ -2162,14 +2223,14 @@ function SignalIcon({ bars, ...props }) {
2162
2223
  ] });
2163
2224
  }
2164
2225
  function SpeakerIcon(props) {
2165
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2226
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2166
2227
  /* @__PURE__ */ jsx4("path", { d: "M11 5 6 9H2v6h4l5 4V5Z" }),
2167
2228
  /* @__PURE__ */ jsx4("path", { d: "M15.54 8.46a5 5 0 0 1 0 7.07" }),
2168
2229
  /* @__PURE__ */ jsx4("path", { d: "M19.07 4.93a10 10 0 0 1 0 14.14" })
2169
2230
  ] });
2170
2231
  }
2171
2232
  function FlagIcon(props) {
2172
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2233
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2173
2234
  /* @__PURE__ */ jsx4("path", { d: "M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z" }),
2174
2235
  /* @__PURE__ */ jsx4("line", { x1: "4", x2: "4", y1: "22", y2: "15" })
2175
2236
  ] });
@@ -2178,35 +2239,35 @@ function PencilIcon(props) {
2178
2239
  return /* @__PURE__ */ jsx4(Icon, { ...props, children: /* @__PURE__ */ jsx4("path", { d: "M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z" }) });
2179
2240
  }
2180
2241
  function ActivitiesIcon(props) {
2181
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2242
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2182
2243
  /* @__PURE__ */ jsx4("path", { d: "M8.3 10a.7.7 0 0 1-.626-1.079L11.4 3a.7.7 0 0 1 1.198-.043L16.3 8.9a.7.7 0 0 1-.572 1.1Z" }),
2183
2244
  /* @__PURE__ */ jsx4("rect", { x: "3", y: "14", width: "7", height: "7", rx: "1" }),
2184
2245
  /* @__PURE__ */ jsx4("circle", { cx: "17.5", cy: "17.5", r: "3.5" })
2185
2246
  ] });
2186
2247
  }
2187
2248
  function PollIcon(props) {
2188
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2249
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2189
2250
  /* @__PURE__ */ jsx4("line", { x1: "18", x2: "18", y1: "20", y2: "10" }),
2190
2251
  /* @__PURE__ */ jsx4("line", { x1: "12", x2: "12", y1: "20", y2: "4" }),
2191
2252
  /* @__PURE__ */ jsx4("line", { x1: "6", x2: "6", y1: "20", y2: "14" })
2192
2253
  ] });
2193
2254
  }
2194
2255
  function QuestionIcon(props) {
2195
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2256
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2196
2257
  /* @__PURE__ */ jsx4("path", { d: "M7.9 20A9 9 0 1 0 4 16.1L2 22Z" }),
2197
2258
  /* @__PURE__ */ jsx4("path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }),
2198
2259
  /* @__PURE__ */ jsx4("path", { d: "M12 17h.01" })
2199
2260
  ] });
2200
2261
  }
2201
2262
  function WhiteboardIcon(props) {
2202
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2263
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2203
2264
  /* @__PURE__ */ jsx4("path", { d: "M2 3h20" }),
2204
2265
  /* @__PURE__ */ jsx4("path", { d: "M21 3v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V3" }),
2205
2266
  /* @__PURE__ */ jsx4("path", { d: "m7 21 5-5 5 5" })
2206
2267
  ] });
2207
2268
  }
2208
2269
  function BreakoutIcon(props) {
2209
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2270
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2210
2271
  /* @__PURE__ */ jsx4("rect", { width: "7", height: "18", x: "3", y: "3", rx: "1" }),
2211
2272
  /* @__PURE__ */ jsx4("rect", { width: "7", height: "7", x: "14", y: "3", rx: "1" }),
2212
2273
  /* @__PURE__ */ jsx4("rect", { width: "7", height: "7", x: "14", y: "14", rx: "1" })
@@ -2216,29 +2277,32 @@ function UpvoteIcon(props) {
2216
2277
  return /* @__PURE__ */ jsx4(Icon, { ...props, children: /* @__PURE__ */ jsx4("path", { d: "M9 18v-6H5l7-7 7 7h-4v6H9z" }) });
2217
2278
  }
2218
2279
  function EraserIcon(props) {
2219
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2280
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2220
2281
  /* @__PURE__ */ jsx4("path", { d: "m7 21-4.3-4.3c-1-1-1-2.5 0-3.4l9.6-9.6c1-1 2.5-1 3.4 0l5.6 5.6c1 1 1 2.5 0 3.4L13 21" }),
2221
2282
  /* @__PURE__ */ jsx4("path", { d: "M22 21H7" }),
2222
2283
  /* @__PURE__ */ jsx4("path", { d: "m5 11 9 9" })
2223
2284
  ] });
2224
2285
  }
2225
2286
  function HighlighterIcon(props) {
2226
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2287
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2227
2288
  /* @__PURE__ */ jsx4("path", { d: "m9 11-6 6v3h9l3-3" }),
2228
2289
  /* @__PURE__ */ jsx4("path", { d: "m22 12-4.6 4.6a2 2 0 0 1-2.8 0l-5.2-5.2a2 2 0 0 1 0-2.8L14 4" })
2229
2290
  ] });
2230
2291
  }
2231
2292
  function UndoIcon(props) {
2232
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
2293
+ return /* @__PURE__ */ jsxs2(Icon, { ...props, children: [
2233
2294
  /* @__PURE__ */ jsx4("path", { d: "M9 14 4 9l5-5" }),
2234
2295
  /* @__PURE__ */ jsx4("path", { d: "M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11" })
2235
2296
  ] });
2236
2297
  }
2298
+ function ChevronUpIcon(props) {
2299
+ return /* @__PURE__ */ jsx4(Icon, { ...props, children: /* @__PURE__ */ jsx4("path", { d: "m6 15 6-6 6 6" }) });
2300
+ }
2237
2301
 
2238
2302
  // src/skins/meet/collab.tsx
2239
- import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
2303
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
2240
2304
  function useNotice() {
2241
- const [notice, setNotice] = useState3(null);
2305
+ const [notice, setNotice] = useState4(null);
2242
2306
  useEffect5(() => {
2243
2307
  if (notice === null) return void 0;
2244
2308
  const timer = setTimeout(() => setNotice(null), notice.failed ? 7e3 : 3e3);
@@ -2267,16 +2331,16 @@ function ActivitiesControl({
2267
2331
  active,
2268
2332
  onOpen
2269
2333
  }) {
2270
- const [open, setOpen] = useState3(false);
2334
+ const [open, setOpen] = useState4(false);
2271
2335
  const available = useAvailableActivities();
2272
2336
  const attention = useActivityAttention();
2273
2337
  if (available.length === 0) return null;
2274
- return /* @__PURE__ */ jsxs2("span", { className: "mx-meet__anchor", children: [
2275
- /* @__PURE__ */ jsxs2(ControlButton, { label: "Activities", active: open || active !== null, onClick: () => setOpen(!open), children: [
2338
+ return /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
2339
+ /* @__PURE__ */ jsxs3(ControlButton, { label: "Activities", active: open || active !== null, onClick: () => setOpen(!open), children: [
2276
2340
  /* @__PURE__ */ jsx5(ActivitiesIcon, {}),
2277
2341
  attention ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
2278
2342
  ] }),
2279
- open ? /* @__PURE__ */ jsx5(Popover, { label: "Activities", onClose: () => setOpen(false), children: /* @__PURE__ */ jsx5("div", { className: "mx-meet__menu", role: "menu", children: available.map((panel) => /* @__PURE__ */ jsxs2(
2343
+ open ? /* @__PURE__ */ jsx5(Popover, { label: "Activities", onClose: () => setOpen(false), children: /* @__PURE__ */ jsx5("div", { className: "mx-meet__menu", role: "menu", children: available.map((panel) => /* @__PURE__ */ jsxs3(
2280
2344
  MenuItem,
2281
2345
  {
2282
2346
  onSelect: () => {
@@ -2295,11 +2359,11 @@ function ActivitiesControl({
2295
2359
  }
2296
2360
  function PollComposer({ maxOptions, onDone }) {
2297
2361
  const { act } = useCollab();
2298
- const [question, setQuestion] = useState3("");
2299
- const [options, setOptions] = useState3(["", ""]);
2300
- const [multiple, setMultiple] = useState3(false);
2301
- const [anonymous, setAnonymous] = useState3(false);
2302
- const [busy, setBusy] = useState3(false);
2362
+ const [question, setQuestion] = useState4("");
2363
+ const [options, setOptions] = useState4(["", ""]);
2364
+ const [multiple, setMultiple] = useState4(false);
2365
+ const [anonymous, setAnonymous] = useState4(false);
2366
+ const [busy, setBusy] = useState4(false);
2303
2367
  const [notice, show] = useNotice();
2304
2368
  const filled = options.map((o) => o.trim()).filter(Boolean);
2305
2369
  const ready = question.trim().length > 0 && filled.length >= 2;
@@ -2322,7 +2386,7 @@ function PollComposer({ maxOptions, onDone }) {
2322
2386
  setBusy(false);
2323
2387
  onDone();
2324
2388
  };
2325
- return /* @__PURE__ */ jsxs2(
2389
+ return /* @__PURE__ */ jsxs3(
2326
2390
  "form",
2327
2391
  {
2328
2392
  className: "mx-meet__collab-card",
@@ -2331,7 +2395,7 @@ function PollComposer({ maxOptions, onDone }) {
2331
2395
  if (ready) void save(true);
2332
2396
  },
2333
2397
  children: [
2334
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
2398
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
2335
2399
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__field-label", children: "Question" }),
2336
2400
  /* @__PURE__ */ jsx5(
2337
2401
  "input",
@@ -2345,7 +2409,7 @@ function PollComposer({ maxOptions, onDone }) {
2345
2409
  }
2346
2410
  )
2347
2411
  ] }),
2348
- options.map((option, index) => /* @__PURE__ */ jsxs2("div", { className: "mx-meet__composer-row", children: [
2412
+ options.map((option, index) => /* @__PURE__ */ jsxs3("div", { className: "mx-meet__composer-row", children: [
2349
2413
  /* @__PURE__ */ jsx5(
2350
2414
  "input",
2351
2415
  {
@@ -2360,16 +2424,16 @@ function PollComposer({ maxOptions, onDone }) {
2360
2424
  options.length > 2 ? /* @__PURE__ */ jsx5(ControlButton, { label: `Remove answer ${index + 1}`, onClick: () => setOptions(options.filter((_, i) => i !== index)), children: /* @__PURE__ */ jsx5(CloseIcon, { width: 14, height: 14 }) }) : null
2361
2425
  ] }, index)),
2362
2426
  options.length < maxOptions ? /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__link", onClick: () => setOptions([...options, ""]), children: "Add an answer" }) : null,
2363
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
2427
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__toggle", children: [
2364
2428
  /* @__PURE__ */ jsx5("input", { type: "checkbox", checked: multiple, onChange: (event) => setMultiple(event.target.checked) }),
2365
2429
  "People can pick more than one"
2366
2430
  ] }),
2367
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
2431
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__toggle", children: [
2368
2432
  /* @__PURE__ */ jsx5("input", { type: "checkbox", checked: anonymous, onChange: (event) => setAnonymous(event.target.checked) }),
2369
2433
  "Anonymous \u2014 nobody sees who picked what"
2370
2434
  ] }),
2371
2435
  /* @__PURE__ */ jsx5(Notice, { notice }),
2372
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-actions", children: [
2436
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__collab-actions", children: [
2373
2437
  /* @__PURE__ */ jsx5("button", { type: "submit", className: "mx-meet__primary mx-meet__primary--small", disabled: !ready || busy, children: "Launch" }),
2374
2438
  /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", disabled: !ready || busy, onClick: () => void save(false), children: "Save draft" }),
2375
2439
  /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__link", onClick: onDone, children: "Cancel" })
@@ -2380,7 +2444,7 @@ function PollComposer({ maxOptions, onDone }) {
2380
2444
  }
2381
2445
  function PollCard({ poll }) {
2382
2446
  const { act, isHost } = useCollab();
2383
- const [picked, setPicked] = useState3(poll.myVote.slice());
2447
+ const [picked, setPicked] = useState4(poll.myVote.slice());
2384
2448
  const [notice, show] = useNotice();
2385
2449
  useEffect5(() => setPicked(poll.myVote.slice()), [poll.myVote]);
2386
2450
  const counts = poll.options.some((o) => o.votes !== void 0);
@@ -2392,12 +2456,12 @@ function PollCard({ poll }) {
2392
2456
  if (!canVote) return;
2393
2457
  setPicked(poll.multiple ? picked.includes(id) ? picked.filter((p) => p !== id) : [...picked, id] : [id]);
2394
2458
  };
2395
- return /* @__PURE__ */ jsxs2("article", { className: "mx-meet__collab-card", "aria-label": poll.question, children: [
2396
- /* @__PURE__ */ jsxs2("header", { className: "mx-meet__collab-head", children: [
2459
+ return /* @__PURE__ */ jsxs3("article", { className: "mx-meet__collab-card", "aria-label": poll.question, children: [
2460
+ /* @__PURE__ */ jsxs3("header", { className: "mx-meet__collab-head", children: [
2397
2461
  /* @__PURE__ */ jsx5("strong", { className: "mx-meet__collab-title", children: poll.question }),
2398
2462
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__collab-state", children: stateWord })
2399
2463
  ] }),
2400
- /* @__PURE__ */ jsxs2("p", { className: "mx-meet__panel-note", children: [
2464
+ /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
2401
2465
  poll.multiple ? "Pick any." : "Pick one.",
2402
2466
  poll.anonymous ? " Anonymous." : "",
2403
2467
  counts && poll.voterCount !== null ? ` ${poll.voterCount} voted.` : "",
@@ -2406,8 +2470,8 @@ function PollCard({ poll }) {
2406
2470
  /* @__PURE__ */ jsx5("ul", { className: "mx-meet__poll-options", children: poll.options.map((option) => {
2407
2471
  const share = counts && total > 0 ? Math.round((option.votes ?? 0) / total * 100) : 0;
2408
2472
  const chosen = picked.includes(option.id);
2409
- return /* @__PURE__ */ jsxs2("li", { children: [
2410
- /* @__PURE__ */ jsxs2(
2473
+ return /* @__PURE__ */ jsxs3("li", { children: [
2474
+ /* @__PURE__ */ jsxs3(
2411
2475
  "button",
2412
2476
  {
2413
2477
  type: "button",
@@ -2418,7 +2482,7 @@ function PollCard({ poll }) {
2418
2482
  children: [
2419
2483
  counts ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__poll-bar", style: { width: `${share}%` }, "aria-hidden": "true" }) : null,
2420
2484
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__poll-text", children: option.text }),
2421
- counts ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__poll-count", children: [
2485
+ counts ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__poll-count", children: [
2422
2486
  option.votes ?? 0,
2423
2487
  " \xB7 ",
2424
2488
  share,
@@ -2431,7 +2495,7 @@ function PollCard({ poll }) {
2431
2495
  ] }, option.id);
2432
2496
  }) }),
2433
2497
  /* @__PURE__ */ jsx5(Notice, { notice }),
2434
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-actions", children: [
2498
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__collab-actions", children: [
2435
2499
  canVote ? /* @__PURE__ */ jsx5(
2436
2500
  "button",
2437
2501
  {
@@ -2451,11 +2515,11 @@ function PollCard({ poll }) {
2451
2515
  }
2452
2516
  function PollsPanel({ onClose }) {
2453
2517
  const { collab, isHost } = useCollab();
2454
- const [composing, setComposing] = useState3(false);
2518
+ const [composing, setComposing] = useState4(false);
2455
2519
  const polls = collab?.polls ?? [];
2456
2520
  const maxOptions = collab?.settings?.pollMaxOptions ?? 10;
2457
2521
  const ordered = [...polls].reverse();
2458
- return /* @__PURE__ */ jsxs2(PanelShell, { title: "Polls", onClose, children: [
2522
+ return /* @__PURE__ */ jsxs3(PanelShell, { title: "Polls", onClose, children: [
2459
2523
  collab?.error != null ? /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
2460
2524
  isHost && !composing ? /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__primary mx-meet__primary--small", onClick: () => setComposing(true), children: "New poll" }) : null,
2461
2525
  isHost && composing ? /* @__PURE__ */ jsx5(PollComposer, { maxOptions, onDone: () => setComposing(false) }) : null,
@@ -2465,12 +2529,12 @@ function PollsPanel({ onClose }) {
2465
2529
  }
2466
2530
  function QuestionCard({ question }) {
2467
2531
  const { act, isHost } = useCollab();
2468
- const [answering, setAnswering] = useState3(false);
2469
- const [reply, setReply] = useState3("");
2532
+ const [answering, setAnswering] = useState4(false);
2533
+ const [reply, setReply] = useState4("");
2470
2534
  const [notice, show] = useNotice();
2471
- return /* @__PURE__ */ jsxs2("li", { className: `mx-meet__collab-card mx-meet__question mx-meet__question--${question.state}`, children: [
2472
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__question-row", children: [
2473
- /* @__PURE__ */ jsxs2(
2535
+ return /* @__PURE__ */ jsxs3("li", { className: `mx-meet__collab-card mx-meet__question mx-meet__question--${question.state}`, children: [
2536
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__question-row", children: [
2537
+ /* @__PURE__ */ jsxs3(
2474
2538
  "button",
2475
2539
  {
2476
2540
  type: "button",
@@ -2485,15 +2549,15 @@ function QuestionCard({ question }) {
2485
2549
  ]
2486
2550
  }
2487
2551
  ),
2488
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__question-body", children: [
2489
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__chat-meta", children: [
2552
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__question-body", children: [
2553
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__chat-meta", children: [
2490
2554
  /* @__PURE__ */ jsx5("strong", { children: question.mine ? "You" : question.askerName }),
2491
2555
  question.mine && question.anonymous ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__chat-private", children: "anonymous" }) : null,
2492
2556
  question.state !== "open" ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__collab-state", children: question.state === "answered" ? "Answered" : "Dismissed" }) : null
2493
2557
  ] }),
2494
2558
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__chat-text", children: question.text }),
2495
- question.answer !== null ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__question-answer", children: [
2496
- /* @__PURE__ */ jsxs2("strong", { children: [
2559
+ question.answer !== null ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__question-answer", children: [
2560
+ /* @__PURE__ */ jsxs3("strong", { children: [
2497
2561
  question.answeredByName ?? "Host",
2498
2562
  ":"
2499
2563
  ] }),
@@ -2502,7 +2566,7 @@ function QuestionCard({ question }) {
2502
2566
  ] }) : null
2503
2567
  ] })
2504
2568
  ] }),
2505
- answering ? /* @__PURE__ */ jsxs2(
2569
+ answering ? /* @__PURE__ */ jsxs3(
2506
2570
  "form",
2507
2571
  {
2508
2572
  className: "mx-meet__composer-row",
@@ -2534,7 +2598,7 @@ function QuestionCard({ question }) {
2534
2598
  }
2535
2599
  ) : null,
2536
2600
  /* @__PURE__ */ jsx5(Notice, { notice }),
2537
- isHost || question.mine ? /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-actions", children: [
2601
+ isHost || question.mine ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__collab-actions", children: [
2538
2602
  isHost && question.state === "open" && !answering ? /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", onClick: () => setAnswering(true), children: "Answer" }) : null,
2539
2603
  isHost && question.state === "open" ? /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "question_dismiss", itemId: question.id }).then(show), children: "Dismiss" }) : null,
2540
2604
  isHost && question.state !== "open" ? /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "question_reopen", itemId: question.id }).then(show), children: "Reopen" }) : null,
@@ -2544,9 +2608,9 @@ function QuestionCard({ question }) {
2544
2608
  }
2545
2609
  function QaPanel({ onClose }) {
2546
2610
  const { collab, act } = useCollab();
2547
- const [draft, setDraft] = useState3("");
2548
- const [anonymous, setAnonymous] = useState3(false);
2549
- const [order, setOrder] = useState3("popular");
2611
+ const [draft, setDraft] = useState4("");
2612
+ const [anonymous, setAnonymous] = useState4(false);
2613
+ const [order, setOrder] = useState4("popular");
2550
2614
  const [notice, show] = useNotice();
2551
2615
  const allowAnonymous = collab?.settings?.qaAnonymousAllowed === true;
2552
2616
  const questions = [...collab?.questions ?? []];
@@ -2554,9 +2618,9 @@ function QaPanel({ onClose }) {
2554
2618
  questions.sort(
2555
2619
  (a, b) => rank(a) !== rank(b) ? rank(a) - rank(b) : order === "popular" ? b.upvotes - a.upvotes || (b.createdAt ?? "").localeCompare(a.createdAt ?? "") : (b.createdAt ?? "").localeCompare(a.createdAt ?? "")
2556
2620
  );
2557
- return /* @__PURE__ */ jsxs2(PanelShell, { title: "Q&A", onClose, children: [
2621
+ return /* @__PURE__ */ jsxs3(PanelShell, { title: "Q&A", onClose, children: [
2558
2622
  collab?.error != null ? /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
2559
- /* @__PURE__ */ jsxs2(
2623
+ /* @__PURE__ */ jsxs3(
2560
2624
  "form",
2561
2625
  {
2562
2626
  className: "mx-meet__composer mx-meet__composer--chat",
@@ -2570,7 +2634,7 @@ function QaPanel({ onClose }) {
2570
2634
  });
2571
2635
  },
2572
2636
  children: [
2573
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__composer-row", children: [
2637
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__composer-row", children: [
2574
2638
  /* @__PURE__ */ jsx5(
2575
2639
  "input",
2576
2640
  {
@@ -2584,7 +2648,7 @@ function QaPanel({ onClose }) {
2584
2648
  ),
2585
2649
  /* @__PURE__ */ jsx5("button", { type: "submit", className: "mx-meet__send", disabled: draft.trim().length === 0, children: "Ask" })
2586
2650
  ] }),
2587
- allowAnonymous ? /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
2651
+ allowAnonymous ? /* @__PURE__ */ jsxs3("label", { className: "mx-meet__toggle", children: [
2588
2652
  /* @__PURE__ */ jsx5("input", { type: "checkbox", checked: anonymous, onChange: (event) => setAnonymous(event.target.checked) }),
2589
2653
  "Ask anonymously"
2590
2654
  ] }) : null
@@ -2635,10 +2699,10 @@ function StrokeView({ stroke, onPick }) {
2635
2699
  }
2636
2700
  function WhiteboardPanel({ onClose }) {
2637
2701
  const { collab, act, isHost, localIdentity } = useCollab();
2638
- const [tool, setTool] = useState3("pen");
2639
- const [color, setColor] = useState3(INK[0]);
2640
- const [drawing, setDrawing] = useState3(null);
2641
- const [pending, setPending] = useState3([]);
2702
+ const [tool, setTool] = useState4("pen");
2703
+ const [color, setColor] = useState4(INK[0]);
2704
+ const [drawing, setDrawing] = useState4(null);
2705
+ const [pending, setPending] = useState4([]);
2642
2706
  const [notice, show] = useNotice();
2643
2707
  const svgRef = useRef5(null);
2644
2708
  const strokes = collab?.strokes ?? [];
@@ -2672,8 +2736,8 @@ function WhiteboardPanel({ onClose }) {
2672
2736
  if (!result.ok) show(result);
2673
2737
  });
2674
2738
  };
2675
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__whiteboard", "aria-label": "Whiteboard", children: [
2676
- /* @__PURE__ */ jsxs2("header", { className: "mx-meet__whiteboard-bar", children: [
2739
+ return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__whiteboard", "aria-label": "Whiteboard", children: [
2740
+ /* @__PURE__ */ jsxs3("header", { className: "mx-meet__whiteboard-bar", children: [
2677
2741
  /* @__PURE__ */ jsx5("strong", { className: "mx-meet__panel-title", children: "Whiteboard" }),
2678
2742
  /* @__PURE__ */ jsx5("div", { className: "mx-meet__pills", role: "group", "aria-label": "Tool", children: [
2679
2743
  ["pen", "Pen", /* @__PURE__ */ jsx5(PencilIcon, { width: 16, height: 16 }, "p")],
@@ -2723,7 +2787,7 @@ function WhiteboardPanel({ onClose }) {
2723
2787
  /* @__PURE__ */ jsx5(ControlButton, { label: "Close whiteboard", onClick: onClose, children: /* @__PURE__ */ jsx5(CloseIcon, { width: 16, height: 16 }) })
2724
2788
  ] }),
2725
2789
  /* @__PURE__ */ jsx5(Notice, { notice }),
2726
- /* @__PURE__ */ jsxs2(
2790
+ /* @__PURE__ */ jsxs3(
2727
2791
  "svg",
2728
2792
  {
2729
2793
  ref: svgRef,
@@ -2781,7 +2845,7 @@ function clock(ms) {
2781
2845
  }
2782
2846
  var BREAKOUT_EXPIRE_RETRY_MS = 5e3;
2783
2847
  function useNow(active) {
2784
- const [now, setNow] = useState3(() => Date.now());
2848
+ const [now, setNow] = useState4(() => Date.now());
2785
2849
  useEffect5(() => {
2786
2850
  if (!active) return void 0;
2787
2851
  const timer = setInterval(() => setNow(Date.now()), 1e3);
@@ -2796,11 +2860,11 @@ function BreakoutSetup() {
2796
2860
  const people = (snapshot?.participants ?? []).filter(
2797
2861
  (p) => !p.isAgent && p.role !== "host" && p.role !== "cohost"
2798
2862
  );
2799
- const [count, setCount] = useState3(Math.min(Math.max(2, Math.ceil(people.length / 4)), settings?.breakoutMaxRooms ?? 20));
2800
- const [mode, setMode] = useState3("auto");
2801
- const [minutes, setMinutes] = useState3(settings?.breakoutDefaultMinutes ?? 15);
2802
- const [manual, setManual] = useState3({});
2803
- const [busy, setBusy] = useState3(false);
2863
+ const [count, setCount] = useState4(Math.min(Math.max(2, Math.ceil(people.length / 4)), settings?.breakoutMaxRooms ?? 20));
2864
+ const [mode, setMode] = useState4("auto");
2865
+ const [minutes, setMinutes] = useState4(settings?.breakoutDefaultMinutes ?? 15);
2866
+ const [manual, setManual] = useState4({});
2867
+ const [busy, setBusy] = useState4(false);
2804
2868
  const [notice, show] = useNotice();
2805
2869
  const max = settings?.breakoutMaxRooms ?? 20;
2806
2870
  const rooms = Math.min(Math.max(1, count), max);
@@ -2812,8 +2876,8 @@ function BreakoutSetup() {
2812
2876
  (_, index) => people.filter((p) => (manual[p.identity] ?? -1) === index).map((p) => p.identity)
2813
2877
  ) : Array.from({ length: rooms }, () => []);
2814
2878
  const nameOf = (identity) => people.find((p) => p.identity === identity)?.displayName ?? identity;
2815
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-card", children: [
2816
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
2879
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__collab-card", children: [
2880
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
2817
2881
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__field-label", children: "Rooms" }),
2818
2882
  /* @__PURE__ */ jsx5(
2819
2883
  "input",
@@ -2842,7 +2906,7 @@ function BreakoutSetup() {
2842
2906
  },
2843
2907
  value
2844
2908
  )) }),
2845
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
2909
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
2846
2910
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__field-label", children: "Timer (minutes, 0 for none)" }),
2847
2911
  /* @__PURE__ */ jsx5(
2848
2912
  "input",
@@ -2856,9 +2920,9 @@ function BreakoutSetup() {
2856
2920
  }
2857
2921
  )
2858
2922
  ] }),
2859
- mode === "manual" ? people.length === 0 ? /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note", children: "Nobody else is in the meeting yet." }) : /* @__PURE__ */ jsx5("ul", { className: "mx-meet__people", children: people.map((person) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__person", children: [
2923
+ mode === "manual" ? people.length === 0 ? /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note", children: "Nobody else is in the meeting yet." }) : /* @__PURE__ */ jsx5("ul", { className: "mx-meet__people", children: people.map((person) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__person", children: [
2860
2924
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__person-name", children: person.displayName }),
2861
- /* @__PURE__ */ jsxs2(
2925
+ /* @__PURE__ */ jsxs3(
2862
2926
  "select",
2863
2927
  {
2864
2928
  className: "mx-meet__select mx-meet__select--compact",
@@ -2867,15 +2931,15 @@ function BreakoutSetup() {
2867
2931
  onChange: (event) => setManual({ ...manual, [person.identity]: Number(event.target.value) }),
2868
2932
  children: [
2869
2933
  /* @__PURE__ */ jsx5("option", { value: -1, children: "Main room" }),
2870
- Array.from({ length: rooms }, (_, index) => /* @__PURE__ */ jsxs2("option", { value: index, children: [
2934
+ Array.from({ length: rooms }, (_, index) => /* @__PURE__ */ jsxs3("option", { value: index, children: [
2871
2935
  "Room ",
2872
2936
  index + 1
2873
2937
  ] }, index))
2874
2938
  ]
2875
2939
  }
2876
2940
  )
2877
- ] }, person.identity)) }) : mode === "auto" ? /* @__PURE__ */ jsx5("ul", { className: "mx-meet__breakout-rooms", children: assignment.map((members, index) => /* @__PURE__ */ jsxs2("li", { children: [
2878
- /* @__PURE__ */ jsxs2("strong", { children: [
2941
+ ] }, person.identity)) }) : mode === "auto" ? /* @__PURE__ */ jsx5("ul", { className: "mx-meet__breakout-rooms", children: assignment.map((members, index) => /* @__PURE__ */ jsxs3("li", { children: [
2942
+ /* @__PURE__ */ jsxs3("strong", { children: [
2879
2943
  "Room ",
2880
2944
  index + 1
2881
2945
  ] }),
@@ -2883,7 +2947,7 @@ function BreakoutSetup() {
2883
2947
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__panel-note", children: members.length === 0 ? "empty" : members.map(nameOf).join(", ") })
2884
2948
  ] }, index)) }) : /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note", children: "Everyone picks a room from their own screen." }),
2885
2949
  /* @__PURE__ */ jsx5(Notice, { notice }),
2886
- /* @__PURE__ */ jsxs2(
2950
+ /* @__PURE__ */ jsxs3(
2887
2951
  "button",
2888
2952
  {
2889
2953
  type: "button",
@@ -2916,7 +2980,7 @@ function BreakoutRun({ plan }) {
2916
2980
  const snapshot = useMeetSnapshot();
2917
2981
  const now = useNow(plan.endsAt !== null);
2918
2982
  const remaining = breakoutRemainingMs(plan, now);
2919
- const [broadcast, setBroadcast] = useState3("");
2983
+ const [broadcast, setBroadcast] = useState4("");
2920
2984
  const [notice, show] = useNotice();
2921
2985
  const nameOf = (identity) => displayNameFor(snapshot?.names ?? {}, identity, snapshot?.participants.find((p) => p.identity === identity)?.displayName);
2922
2986
  const mine = assignedRoom(plan, localIdentity);
@@ -2928,8 +2992,8 @@ function BreakoutRun({ plan }) {
2928
2992
  }
2929
2993
  show(await moveTo(roomId));
2930
2994
  };
2931
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-card", children: [
2932
- /* @__PURE__ */ jsxs2("p", { className: "mx-meet__panel-note", children: [
2995
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__collab-card", children: [
2996
+ /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
2933
2997
  plan.rooms.length,
2934
2998
  " room",
2935
2999
  plan.rooms.length === 1 ? "" : "s",
@@ -2940,15 +3004,15 @@ function BreakoutRun({ plan }) {
2940
3004
  /* @__PURE__ */ jsx5("ul", { className: "mx-meet__breakout-rooms", children: plan.rooms.map((room) => {
2941
3005
  const here = breakoutRoomId === room.id;
2942
3006
  const mayJoin = isHost || plan.allowChoose || mine?.id === room.id;
2943
- return /* @__PURE__ */ jsxs2("li", { className: here ? "mx-meet__breakout-room mx-meet__breakout-room--here" : "mx-meet__breakout-room", children: [
2944
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-head", children: [
3007
+ return /* @__PURE__ */ jsxs3("li", { className: here ? "mx-meet__breakout-room mx-meet__breakout-room--here" : "mx-meet__breakout-room", children: [
3008
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__collab-head", children: [
2945
3009
  /* @__PURE__ */ jsx5("strong", { children: room.name }),
2946
3010
  here ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__collab-state", children: "You are here" }) : mayJoin ? /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", onClick: () => void join(room.id), children: "Join" }) : null
2947
3011
  ] }),
2948
3012
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__panel-note", children: room.identities.length === 0 ? "Nobody assigned" : room.identities.map(nameOf).join(", ") }),
2949
- isHost && room.identities.length > 0 ? /* @__PURE__ */ jsx5("ul", { className: "mx-meet__people", children: room.identities.map((identity) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__person", children: [
3013
+ isHost && room.identities.length > 0 ? /* @__PURE__ */ jsx5("ul", { className: "mx-meet__people", children: room.identities.map((identity) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__person", children: [
2950
3014
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__person-name", children: nameOf(identity) }),
2951
- /* @__PURE__ */ jsxs2(
3015
+ /* @__PURE__ */ jsxs3(
2952
3016
  "select",
2953
3017
  {
2954
3018
  className: "mx-meet__select mx-meet__select--compact",
@@ -2969,7 +3033,7 @@ function BreakoutRun({ plan }) {
2969
3033
  ] }, room.id);
2970
3034
  }) }),
2971
3035
  breakoutRoomId !== null ? /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", onClick: () => void join(null), children: "Return to the main room" }) : null,
2972
- isHost ? /* @__PURE__ */ jsxs2(
3036
+ isHost ? /* @__PURE__ */ jsxs3(
2973
3037
  "form",
2974
3038
  {
2975
3039
  className: "mx-meet__composer-row",
@@ -3013,7 +3077,7 @@ function BreakoutRun({ plan }) {
3013
3077
  function BreakoutsPanel({ onClose }) {
3014
3078
  const { collab, isHost } = useCollab();
3015
3079
  const plan = collab?.breakout?.state === "open" ? collab.breakout : null;
3016
- return /* @__PURE__ */ jsxs2(PanelShell, { title: "Breakout rooms", onClose, children: [
3080
+ return /* @__PURE__ */ jsxs3(PanelShell, { title: "Breakout rooms", onClose, children: [
3017
3081
  collab?.error != null ? /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
3018
3082
  plan !== null ? /* @__PURE__ */ jsx5(BreakoutRun, { plan }) : isHost ? /* @__PURE__ */ jsx5(BreakoutSetup, {}) : /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note", children: "Breakout rooms are closed." })
3019
3083
  ] });
@@ -3027,12 +3091,12 @@ function BreakoutBanner() {
3027
3091
  const remaining = breakoutRemainingMs(open, now);
3028
3092
  const closing = breakoutClosingMs(open, now);
3029
3093
  const assigned = assignedRoom(open, localIdentity);
3030
- const [later, setLater] = useState3(null);
3031
- const [autoSince, setAutoSince] = useState3(null);
3094
+ const [later, setLater] = useState4(null);
3095
+ const [autoSince, setAutoSince] = useState4(null);
3032
3096
  const AUTO_MOVE_MS = 1e4;
3033
3097
  const autoLeft = open?.moveMode === "auto" && assigned !== null && autoSince?.id === open.id && later !== open.id ? Math.max(0, AUTO_MOVE_MS - (now - autoSince.at)) : null;
3034
- const [dismissedBroadcast, setDismissedBroadcast] = useState3(null);
3035
- const [failure, setFailure] = useState3(null);
3098
+ const [dismissedBroadcast, setDismissedBroadcast] = useState4(null);
3099
+ const [failure, setFailure] = useState4(null);
3036
3100
  const expireAsked = useRef5(null);
3037
3101
  const moveAt = collab?.moveRequest?.at ?? null;
3038
3102
  useEffect5(() => {
@@ -3067,29 +3131,29 @@ function BreakoutBanner() {
3067
3131
  const showBroadcast = broadcast !== null && broadcast.at !== dismissedBroadcast && open !== null;
3068
3132
  const room = open?.rooms.find((r) => r.id === breakoutRoomId) ?? null;
3069
3133
  if (open === null && failure === null) return null;
3070
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__breakout-banner", role: "status", children: [
3134
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__breakout-banner", role: "status", children: [
3071
3135
  failure !== null ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__collab-error", children: failure }) : null,
3072
- closing !== null ? /* @__PURE__ */ jsxs2("span", { role: "status", "data-meet-notice": "breakout-closing", children: [
3136
+ closing !== null ? /* @__PURE__ */ jsxs3("span", { role: "status", "data-meet-notice": "breakout-closing", children: [
3073
3137
  "Rooms closing in ",
3074
3138
  Math.ceil(closing / 1e3),
3075
3139
  room !== null ? " \u2014 you return to the main meeting" : ""
3076
3140
  ] }) : null,
3077
- room !== null ? /* @__PURE__ */ jsxs2("span", { children: [
3141
+ room !== null ? /* @__PURE__ */ jsxs3("span", { children: [
3078
3142
  /* @__PURE__ */ jsx5("strong", { children: room.name }),
3079
3143
  remaining !== null && closing === null ? ` \xB7 ${clock(remaining)} left` : "",
3080
3144
  /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", onClick: () => void moveTo(null), children: "Return to main room" })
3081
- ] }) : assigned !== null && later !== open?.id ? /* @__PURE__ */ jsxs2("span", { children: [
3145
+ ] }) : assigned !== null && later !== open?.id ? /* @__PURE__ */ jsxs3("span", { children: [
3082
3146
  autoLeft !== null ? `You're being moved to ${assigned.name} in ${Math.ceil(autoLeft / 1e3)} s` : `You're invited to ${assigned.name}`,
3083
3147
  remaining !== null && closing === null ? ` \xB7 ${clock(remaining)} left` : "",
3084
3148
  /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__primary mx-meet__primary--small", onClick: () => void joinAssigned(), children: "Join room" }),
3085
3149
  /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", onClick: () => setLater(open?.id ?? null), children: "Later" })
3086
- ] }) : assigned !== null ? /* @__PURE__ */ jsxs2("span", { children: [
3150
+ ] }) : assigned !== null ? /* @__PURE__ */ jsxs3("span", { children: [
3087
3151
  assigned.name,
3088
3152
  " is open",
3089
3153
  /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__chip", onClick: () => void joinAssigned(), children: "Join room" })
3090
3154
  ] }) : open?.allowChoose ? /* @__PURE__ */ jsx5("span", { children: "Rooms are open \u2014 pick one under Activities." }) : null,
3091
- showBroadcast ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__breakout-broadcast", children: [
3092
- /* @__PURE__ */ jsxs2("strong", { children: [
3155
+ showBroadcast ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__breakout-broadcast", children: [
3156
+ /* @__PURE__ */ jsxs3("strong", { children: [
3093
3157
  broadcast.by,
3094
3158
  ":"
3095
3159
  ] }),
@@ -3109,10 +3173,10 @@ function CaptionLanguageSettings() {
3109
3173
  const preferred = defaultCaptionLanguage(settings, viewer);
3110
3174
  const current = collab?.captionLanguage ?? "";
3111
3175
  const choices = CAPTION_LANGUAGES.some((l) => l.tag === preferred) ? CAPTION_LANGUAGES : [{ tag: preferred, name: preferred }, ...CAPTION_LANGUAGES];
3112
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__section", "aria-label": "Captions", children: [
3113
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
3176
+ return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__section", "aria-label": "Captions", children: [
3177
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
3114
3178
  /* @__PURE__ */ jsx5("span", { className: "mx-meet__field-label", children: "Translate captions to" }),
3115
- /* @__PURE__ */ jsxs2(
3179
+ /* @__PURE__ */ jsxs3(
3116
3180
  "select",
3117
3181
  {
3118
3182
  className: "mx-meet__select",
@@ -3123,7 +3187,7 @@ function CaptionLanguageSettings() {
3123
3187
  },
3124
3188
  children: [
3125
3189
  /* @__PURE__ */ jsx5("option", { value: "", children: "Off \u2014 as spoken" }),
3126
- current === "" ? /* @__PURE__ */ jsxs2("option", { value: preferred, children: [
3190
+ current === "" ? /* @__PURE__ */ jsxs3("option", { value: preferred, children: [
3127
3191
  choices.find((c) => c.tag === preferred)?.name ?? preferred,
3128
3192
  " (yours)"
3129
3193
  ] }) : null,
@@ -3164,10 +3228,10 @@ function TakeNotesControl() {
3164
3228
  }
3165
3229
 
3166
3230
  // src/skins/meet/components.tsx
3167
- import { Fragment, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
3231
+ import { Fragment, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
3168
3232
  function InertNotice({ what }) {
3169
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__empty", role: "status", children: [
3170
- /* @__PURE__ */ jsxs3("p", { className: "mx-meet__empty-title", children: [
3233
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__empty", role: "status", children: [
3234
+ /* @__PURE__ */ jsxs4("p", { className: "mx-meet__empty-title", children: [
3171
3235
  what,
3172
3236
  " is not ready yet"
3173
3237
  ] }),
@@ -3237,7 +3301,7 @@ function RecordingIndicator() {
3237
3301
  const { state, label, canStart } = useRecording();
3238
3302
  const snapshot = useMeetSnapshot();
3239
3303
  const previous = useRef6(state);
3240
- const [stoppedAt, setStoppedAt] = useState4(null);
3304
+ const [stoppedAt, setStoppedAt] = useState5(null);
3241
3305
  useEffect6(() => {
3242
3306
  const was = previous.current;
3243
3307
  previous.current = state;
@@ -3250,8 +3314,8 @@ function RecordingIndicator() {
3250
3314
  }, [state]);
3251
3315
  const meetingId = snapshot?.meeting?.id ?? null;
3252
3316
  if (label === null && stoppedAt === null) return null;
3253
- return /* @__PURE__ */ jsxs3(Fragment, { children: [
3254
- label !== null ? /* @__PURE__ */ jsxs3(
3317
+ return /* @__PURE__ */ jsxs4(Fragment, { children: [
3318
+ label !== null ? /* @__PURE__ */ jsxs4(
3255
3319
  "span",
3256
3320
  {
3257
3321
  className: `mx-meet__recording mx-meet__recording--${state}`,
@@ -3292,7 +3356,7 @@ function ParticipantTile({
3292
3356
  const host = useMeetHost();
3293
3357
  const snapshot = useMeetSnapshot();
3294
3358
  const queue = useHandQueue();
3295
- const [menu, setMenu] = useState4(false);
3359
+ const [menu, setMenu] = useState5(false);
3296
3360
  const videoRef = useTrack(
3297
3361
  participant.identity,
3298
3362
  participant.screenSharing ? "screen" : "camera"
@@ -3302,7 +3366,7 @@ function ParticipantTile({
3302
3366
  const spotlit = snapshot?.spotlight === participant.identity;
3303
3367
  const presenting = snapshot?.presenter === participant.identity;
3304
3368
  const handPosition = participant.handRaised ? queue.findIndex((entry) => entry.identity === participant.identity) + 1 : 0;
3305
- return /* @__PURE__ */ jsxs3(
3369
+ return /* @__PURE__ */ jsxs4(
3306
3370
  "div",
3307
3371
  {
3308
3372
  className: [
@@ -3325,12 +3389,12 @@ function ParticipantTile({
3325
3389
  }
3326
3390
  ) : /* @__PURE__ */ jsx6("div", { className: "mx-meet__tile-placeholder", children: /* @__PURE__ */ jsx6(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: featured ? 96 : 56 }) }),
3327
3391
  presenting ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__tile-presenting", role: "status", children: participant.isLocal ? "You are presenting" : `${participant.displayName} is presenting` }) : null,
3328
- participant.handRaised ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__tile-hand", title: `Hand raised \xB7 ${ordinal(handPosition)} in line`, children: [
3392
+ participant.handRaised ? /* @__PURE__ */ jsxs4("span", { className: "mx-meet__tile-hand", title: `Hand raised \xB7 ${ordinal(handPosition)} in line`, children: [
3329
3393
  /* @__PURE__ */ jsx6(HandIcon, { width: 14, height: 14 }),
3330
3394
  handPosition > 0 ? handPosition : null
3331
3395
  ] }) : null,
3332
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__tile-bar", children: [
3333
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__tile-name", children: [
3396
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__tile-bar", children: [
3397
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__tile-name", children: [
3334
3398
  spotlit ? /* @__PURE__ */ jsx6("span", { title: "Spotlighted for everyone", className: "mx-meet__tile-flag", children: /* @__PURE__ */ jsx6(SpotlightIcon, { width: 12, height: 12 }) }) : null,
3335
3399
  participant.displayName,
3336
3400
  participant.isLocal ? " (you)" : "",
@@ -3341,7 +3405,7 @@ function ParticipantTile({
3341
3405
  !participant.micEnabled ? /* @__PURE__ */ jsx6(MicOffIcon, { width: 14, height: 14 }) : null,
3342
3406
  /* @__PURE__ */ jsx6(QualityBars, { quality: participant.quality })
3343
3407
  ] }),
3344
- /* @__PURE__ */ jsxs3("div", { className: menu ? "mx-meet__tile-actions mx-meet__tile-actions--open" : "mx-meet__tile-actions", children: [
3408
+ /* @__PURE__ */ jsxs4("div", { className: menu ? "mx-meet__tile-actions mx-meet__tile-actions--open" : "mx-meet__tile-actions", children: [
3345
3409
  /* @__PURE__ */ jsx6(
3346
3410
  ControlButton,
3347
3411
  {
@@ -3351,7 +3415,7 @@ function ParticipantTile({
3351
3415
  children: /* @__PURE__ */ jsx6(PinIcon, { width: 16, height: 16 })
3352
3416
  }
3353
3417
  ),
3354
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
3418
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__anchor", children: [
3355
3419
  /* @__PURE__ */ jsx6(
3356
3420
  ControlButton,
3357
3421
  {
@@ -3389,12 +3453,12 @@ function Stage({ pageSize }) {
3389
3453
  const stage = useStage(pageSize);
3390
3454
  const columns = gridColumns(stage.tiles.length);
3391
3455
  if (stage.feature === null && stage.tiles.length === 0) {
3392
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__stage mx-meet__stage--empty", children: [
3456
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__stage mx-meet__stage--empty", children: [
3393
3457
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__empty-title", children: "Waiting for others to join" }),
3394
3458
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__empty-body", children: "Share the meeting link and people can join from anywhere \u2014 no account needed." })
3395
3459
  ] });
3396
3460
  }
3397
- return /* @__PURE__ */ jsxs3("div", { className: `mx-meet__stage${stage.feature !== null ? " mx-meet__stage--speaker" : ""}`, children: [
3461
+ return /* @__PURE__ */ jsxs4("div", { className: `mx-meet__stage${stage.feature !== null ? " mx-meet__stage--speaker" : ""}`, children: [
3398
3462
  stage.feature !== null ? /* @__PURE__ */ jsx6(ParticipantTile, { participant: stage.feature, featured: true }) : null,
3399
3463
  /* @__PURE__ */ jsx6(
3400
3464
  "div",
@@ -3404,7 +3468,7 @@ function Stage({ pageSize }) {
3404
3468
  children: stage.tiles.map((participant) => /* @__PURE__ */ jsx6(ParticipantTile, { participant }, participant.identity))
3405
3469
  }
3406
3470
  ),
3407
- stage.overflow > 0 ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__overflow", children: [
3471
+ stage.overflow > 0 ? /* @__PURE__ */ jsxs4("p", { className: "mx-meet__overflow", children: [
3408
3472
  "+",
3409
3473
  stage.overflow,
3410
3474
  " more ",
@@ -3416,10 +3480,10 @@ function Stage({ pageSize }) {
3416
3480
  function ControlBar({ onLeave }) {
3417
3481
  const room = useRoom();
3418
3482
  const recording = useRecording();
3419
- const [panel, setPanel] = useState4("none");
3420
- const [chatTo, setChatTo] = useState4(null);
3421
- const [popover, setPopover] = useState4("none");
3422
- const [shortcuts, setShortcuts] = useState4(false);
3483
+ const [panel, setPanel] = useState5("none");
3484
+ const [chatTo, setChatTo] = useState5(null);
3485
+ const [popover, setPopover] = useState5("none");
3486
+ const [shortcuts, setShortcuts] = useState5(false);
3423
3487
  const snapshot = useMeetSnapshot();
3424
3488
  const lobby = useLobby();
3425
3489
  const controls = useHostControls();
@@ -3427,7 +3491,7 @@ function ControlBar({ onLeave }) {
3427
3491
  const micUnavailable = useLocalMedia().microphone.unavailable;
3428
3492
  const live = useLivePolicy();
3429
3493
  const unread = useUnreadChat(panel === "chat");
3430
- const [whiteboard, setWhiteboard] = useState4(false);
3494
+ const [whiteboard, setWhiteboard] = useState5(false);
3431
3495
  const app = useMeetAppPanel();
3432
3496
  const appOpened = useRef6(false);
3433
3497
  useEffect6(() => {
@@ -3461,7 +3525,7 @@ function ControlBar({ onLeave }) {
3461
3525
  help: () => setShortcuts(true)
3462
3526
  });
3463
3527
  const hasSpotlight = snapshot?.spotlight !== null && snapshot?.spotlight !== void 0;
3464
- return /* @__PURE__ */ jsxs3(Fragment, { children: [
3528
+ return /* @__PURE__ */ jsxs4(Fragment, { children: [
3465
3529
  /* @__PURE__ */ jsx6(MeetingOverlays, {}),
3466
3530
  shortcuts ? /* @__PURE__ */ jsx6(ShortcutsSheet, { onClose: () => setShortcuts(false) }) : null,
3467
3531
  panel === "chat" ? /* @__PURE__ */ jsx6(ChatPanel, { onClose: () => setPanel("none"), to: chatTo, onTo: setChatTo }) : null,
@@ -3491,8 +3555,9 @@ function ControlBar({ onLeave }) {
3491
3555
  ) }) }) : null,
3492
3556
  /* @__PURE__ */ jsx6(BreakoutBanner, {}),
3493
3557
  panel !== "people" ? /* @__PURE__ */ jsx6(KnockNotice, { onView: () => setPanel("people") }) : null,
3558
+ /* @__PURE__ */ jsx6(SpeakingWhileMutedNudge, {}),
3494
3559
  controls.notice !== null && panel !== "people" ? /* @__PURE__ */ jsx6(Toast, { text: controls.notice.text, failed: controls.notice.failed, onDone: controls.clearNotice }) : null,
3495
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__controls", children: [
3560
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__controls", children: [
3496
3561
  live.micLocked ? null : /* @__PURE__ */ jsx6(
3497
3562
  ControlButton,
3498
3563
  {
@@ -3502,6 +3567,7 @@ function ControlBar({ onLeave }) {
3502
3567
  children: room.local?.micEnabled === true ? /* @__PURE__ */ jsx6(MicIcon, {}) : /* @__PURE__ */ jsx6(MicOffIcon, {})
3503
3568
  }
3504
3569
  ),
3570
+ /* @__PURE__ */ jsx6(AudioSettingsControl, {}),
3505
3571
  live.cameraLocked ? null : /* @__PURE__ */ jsx6(
3506
3572
  ControlButton,
3507
3573
  {
@@ -3521,7 +3587,7 @@ function ControlBar({ onLeave }) {
3521
3587
  children: /* @__PURE__ */ jsx6(ScreenShareIcon, {})
3522
3588
  }
3523
3589
  ) : null,
3524
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
3590
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__anchor", children: [
3525
3591
  /* @__PURE__ */ jsx6(
3526
3592
  ControlButton,
3527
3593
  {
@@ -3553,11 +3619,11 @@ function ControlBar({ onLeave }) {
3553
3619
  }
3554
3620
  ),
3555
3621
  app !== null ? /* @__PURE__ */ jsx6(ControlButton, { label: app.title, active: panel === "app", onClick: () => toggle("app"), children: /* @__PURE__ */ jsx6(FlagIcon, {}) }) : null,
3556
- /* @__PURE__ */ jsxs3(ControlButton, { label: "Chat (\u2318\u2325C)", active: panel === "chat", onClick: () => toggle("chat"), children: [
3622
+ /* @__PURE__ */ jsxs4(ControlButton, { label: "Chat (\u2318\u2325C)", active: panel === "chat", onClick: () => toggle("chat"), children: [
3557
3623
  /* @__PURE__ */ jsx6(ChatIcon, {}),
3558
3624
  unread > 0 ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
3559
3625
  ] }),
3560
- /* @__PURE__ */ jsxs3(
3626
+ /* @__PURE__ */ jsxs4(
3561
3627
  ControlButton,
3562
3628
  {
3563
3629
  label: lobby.waiting.length > 0 ? `People \u2014 ${lobby.waiting.length} waiting` : `People \u2014 ${(snapshot?.participants ?? []).length} in the meeting`,
@@ -3580,7 +3646,7 @@ function ControlBar({ onLeave }) {
3580
3646
  /* @__PURE__ */ jsx6(AiControl, { active: panel === "ai", onToggle: () => toggle("ai") }),
3581
3647
  recording.canStart ? /* @__PURE__ */ jsx6(ControlButton, { label: "Start recording", onClick: () => void recording.start(), children: /* @__PURE__ */ jsx6(RecordIcon, {}) }) : null,
3582
3648
  recording.canStop ? /* @__PURE__ */ jsx6(ControlButton, { label: "Stop recording", active: true, onClick: () => void recording.stop(), children: /* @__PURE__ */ jsx6(RecordIcon, {}) }) : null,
3583
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
3649
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__anchor", children: [
3584
3650
  /* @__PURE__ */ jsx6(
3585
3651
  ControlButton,
3586
3652
  {
@@ -3590,8 +3656,8 @@ function ControlBar({ onLeave }) {
3590
3656
  children: /* @__PURE__ */ jsx6(MoreIcon, {})
3591
3657
  }
3592
3658
  ),
3593
- popover === "more" ? /* @__PURE__ */ jsx6(Popover, { label: "More options", onClose: () => setPopover("none"), children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu", role: "menu", children: [
3594
- /* @__PURE__ */ jsxs3(
3659
+ popover === "more" ? /* @__PURE__ */ jsx6(Popover, { label: "More options", onClose: () => setPopover("none"), children: /* @__PURE__ */ jsxs4("div", { className: "mx-meet__menu", role: "menu", children: [
3660
+ /* @__PURE__ */ jsxs4(
3595
3661
  MenuItem,
3596
3662
  {
3597
3663
  onSelect: () => {
@@ -3604,7 +3670,7 @@ function ControlBar({ onLeave }) {
3604
3670
  ]
3605
3671
  }
3606
3672
  ),
3607
- /* @__PURE__ */ jsxs3(
3673
+ /* @__PURE__ */ jsxs4(
3608
3674
  MenuItem,
3609
3675
  {
3610
3676
  onSelect: () => {
@@ -3617,9 +3683,16 @@ function ControlBar({ onLeave }) {
3617
3683
  ]
3618
3684
  }
3619
3685
  ),
3620
- controls.isHost ? /* @__PURE__ */ jsxs3(Fragment, { children: [
3686
+ !room.canShareScreen && room.local?.screenSharing !== true ? (
3687
+ // `share-unsupported-mobile`: the control is absent; the menu says where it lives.
3688
+ /* @__PURE__ */ jsxs4("p", { className: "mx-meet__menu-note", role: "note", "data-meet-notice": "share-unsupported", children: [
3689
+ /* @__PURE__ */ jsx6(ScreenShareIcon, { width: 16, height: 16 }),
3690
+ " Present from a computer"
3691
+ ] })
3692
+ ) : null,
3693
+ controls.isHost ? /* @__PURE__ */ jsxs4(Fragment, { children: [
3621
3694
  /* @__PURE__ */ jsx6("div", { className: "mx-meet__menu-sep", role: "separator" }),
3622
- /* @__PURE__ */ jsxs3(
3695
+ /* @__PURE__ */ jsxs4(
3623
3696
  MenuItem,
3624
3697
  {
3625
3698
  onSelect: () => {
@@ -3632,7 +3705,7 @@ function ControlBar({ onLeave }) {
3632
3705
  ]
3633
3706
  }
3634
3707
  ),
3635
- /* @__PURE__ */ jsxs3(
3708
+ /* @__PURE__ */ jsxs4(
3636
3709
  MenuItem,
3637
3710
  {
3638
3711
  onSelect: () => {
@@ -3649,7 +3722,7 @@ function ControlBar({ onLeave }) {
3649
3722
  ]
3650
3723
  }
3651
3724
  ),
3652
- /* @__PURE__ */ jsxs3(
3725
+ /* @__PURE__ */ jsxs4(
3653
3726
  MenuItem,
3654
3727
  {
3655
3728
  onSelect: () => {
@@ -3662,7 +3735,7 @@ function ControlBar({ onLeave }) {
3662
3735
  ]
3663
3736
  }
3664
3737
  ),
3665
- queue.length > 0 ? /* @__PURE__ */ jsxs3(
3738
+ queue.length > 0 ? /* @__PURE__ */ jsxs4(
3666
3739
  MenuItem,
3667
3740
  {
3668
3741
  onSelect: () => {
@@ -3677,7 +3750,7 @@ function ControlBar({ onLeave }) {
3677
3750
  ]
3678
3751
  }
3679
3752
  ) : null,
3680
- hasSpotlight ? /* @__PURE__ */ jsxs3(
3753
+ hasSpotlight ? /* @__PURE__ */ jsxs4(
3681
3754
  MenuItem,
3682
3755
  {
3683
3756
  onSelect: () => {
@@ -3704,8 +3777,8 @@ var LEAVE_WORDS = {
3704
3777
  };
3705
3778
  function LeaveControl({ onLeave }) {
3706
3779
  const leave = useLeave();
3707
- const [open, setOpen] = useState4("none");
3708
- const [failure, setFailure] = useState4(null);
3780
+ const [open, setOpen] = useState5("none");
3781
+ const [failure, setFailure] = useState5(null);
3709
3782
  const words = LEAVE_WORDS[leave.policy.hostLeavePrompt];
3710
3783
  const run = (work, leaving) => {
3711
3784
  setFailure(null);
@@ -3716,7 +3789,7 @@ function LeaveControl({ onLeave }) {
3716
3789
  };
3717
3790
  const leaveNow = () => run(leave.leave, true);
3718
3791
  const endNow = () => run(leave.endForAll, false);
3719
- return /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
3792
+ return /* @__PURE__ */ jsxs4("span", { className: "mx-meet__anchor", children: [
3720
3793
  /* @__PURE__ */ jsx6(
3721
3794
  ControlButton,
3722
3795
  {
@@ -3730,7 +3803,7 @@ function LeaveControl({ onLeave }) {
3730
3803
  children: /* @__PURE__ */ jsx6(PhoneOffIcon, {})
3731
3804
  }
3732
3805
  ),
3733
- open !== "none" ? /* @__PURE__ */ jsx6(Popover, { label: open === "assign" ? words.assign_and_leave : "Leave", onClose: () => setOpen("none"), children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu", "data-meet-leave-menu": leave.policy.hostLeavePrompt, children: [
3806
+ open !== "none" ? /* @__PURE__ */ jsx6(Popover, { label: open === "assign" ? words.assign_and_leave : "Leave", onClose: () => setOpen("none"), children: /* @__PURE__ */ jsxs4("div", { className: "mx-meet__menu", "data-meet-leave-menu": leave.policy.hostLeavePrompt, children: [
3734
3807
  open === "menu" ? leave.choices.map((choice) => /* @__PURE__ */ jsx6(
3735
3808
  "button",
3736
3809
  {
@@ -3756,7 +3829,7 @@ function LeaveControl({ onLeave }) {
3756
3829
  },
3757
3830
  String(person.identity)
3758
3831
  )) : null,
3759
- open === "confirm" ? /* @__PURE__ */ jsxs3(Fragment, { children: [
3832
+ open === "confirm" ? /* @__PURE__ */ jsxs4(Fragment, { children: [
3760
3833
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__menu-item mx-meet__menu-item--danger", onClick: endNow, children: words.end_for_all }),
3761
3834
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__menu-item", onClick: () => setOpen("menu"), children: "Cancel" })
3762
3835
  ] }) : null,
@@ -3777,12 +3850,12 @@ function useUnreadChat(open) {
3777
3850
  const snapshot = useMeetSnapshot();
3778
3851
  const chat = snapshot?.chat ?? [];
3779
3852
  const local = snapshot?.localIdentity ?? null;
3780
- const [seen, setSeen] = useState4(0);
3853
+ const [seen, setSeen] = useState5(0);
3781
3854
  useEffect6(() => {
3782
3855
  if (open) setSeen(chat.length);
3783
3856
  }, [open, chat.length]);
3784
3857
  const loaded = snapshot?.chatLoaded === true;
3785
- const [baseline, setBaseline] = useState4(null);
3858
+ const [baseline, setBaseline] = useState5(null);
3786
3859
  useEffect6(() => {
3787
3860
  if (loaded && baseline === null) setBaseline(chat.length);
3788
3861
  }, [loaded, baseline, chat.length]);
@@ -3797,7 +3870,7 @@ function Popover({
3797
3870
  placement = "up"
3798
3871
  }) {
3799
3872
  const ref = useRef6(null);
3800
- const [style, setStyle] = useState4({
3873
+ const [style, setStyle] = useState5({
3801
3874
  position: "fixed",
3802
3875
  top: 0,
3803
3876
  left: 0,
@@ -3886,15 +3959,103 @@ function Toast({ text, failed, onDone }) {
3886
3959
  const timer = setTimeout(onDone, failed ? 7e3 : 4e3);
3887
3960
  return () => clearTimeout(timer);
3888
3961
  }, [text, failed, onDone]);
3889
- return /* @__PURE__ */ jsxs3("div", { className: failed ? "mx-meet__toast mx-meet__toast--failed" : "mx-meet__toast", role: "status", children: [
3962
+ return /* @__PURE__ */ jsxs4("div", { className: failed ? "mx-meet__toast mx-meet__toast--failed" : "mx-meet__toast", role: "status", children: [
3890
3963
  /* @__PURE__ */ jsx6("span", { children: text }),
3891
3964
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: onDone, children: /* @__PURE__ */ jsx6(CloseIcon, { width: 14, height: 14 }) })
3892
3965
  ] });
3893
3966
  }
3967
+ function AudioSettingsControl() {
3968
+ const host = useMeetHost();
3969
+ const devices = useDeviceSnapshot();
3970
+ const [open, setOpen] = useState5(false);
3971
+ const list = (devices?.devices.audioinput ?? []).filter((device) => device.deviceId.length > 0);
3972
+ if (host === null || list.length < 2) return null;
3973
+ const current = devices?.selected.audioinput ?? host.devices.resolve("audioinput");
3974
+ return /* @__PURE__ */ jsxs4("span", { className: "mx-meet__anchor", children: [
3975
+ /* @__PURE__ */ jsx6(
3976
+ ControlButton,
3977
+ {
3978
+ label: "Audio settings",
3979
+ active: open,
3980
+ onClick: () => {
3981
+ if (!open) void host.devices.refresh();
3982
+ setOpen(!open);
3983
+ },
3984
+ children: /* @__PURE__ */ jsx6(ChevronUpIcon, {})
3985
+ }
3986
+ ),
3987
+ open ? /* @__PURE__ */ jsx6(Popover, { label: "Microphone", onClose: () => setOpen(false), children: /* @__PURE__ */ jsx6("div", { className: "mx-meet__menu", role: "menu", "aria-label": "Microphone", children: list.map((device) => /* @__PURE__ */ jsxs4(
3988
+ "button",
3989
+ {
3990
+ type: "button",
3991
+ role: "menuitemradio",
3992
+ "aria-checked": device.deviceId === current,
3993
+ className: "mx-meet__menu-item",
3994
+ onClick: () => {
3995
+ setOpen(false);
3996
+ host.devices.select("audioinput", device.deviceId);
3997
+ void host.engine.switchDevice("audioinput", device.deviceId).catch(() => void 0);
3998
+ },
3999
+ children: [
4000
+ device.deviceId === current ? /* @__PURE__ */ jsx6(CheckIcon, { width: 16, height: 16 }) : /* @__PURE__ */ jsx6("span", { className: "mx-meet__menu-gap" }),
4001
+ device.label.length > 0 ? device.label : "Microphone"
4002
+ ]
4003
+ },
4004
+ device.deviceId
4005
+ )) }) }) : null
4006
+ ] });
4007
+ }
4008
+ function SpeakingWhileMutedNudge() {
4009
+ const room = useRoom();
4010
+ const host = useMeetHost();
4011
+ const devices = useDeviceSnapshot();
4012
+ const microphone = useLocalMedia().microphone;
4013
+ const mutedByMe = host !== null && room.local != null && room.local.micEnabled !== true && microphone.unavailable === null;
4014
+ const mic = devices?.selected.audioinput ?? host?.devices.resolve("audioinput") ?? null;
4015
+ const stream = useMicrophoneStream(mutedByMe ? mic : "off");
4016
+ const level = useAudioLevel(stream);
4017
+ const latest = useRef6(0);
4018
+ latest.current = level;
4019
+ const [shown, setShown] = useState5(false);
4020
+ const [detector] = useState5(() => createSpeakingWhileMutedDetector());
4021
+ useEffect6(() => {
4022
+ if (!mutedByMe) {
4023
+ detector.reset();
4024
+ setShown(false);
4025
+ return void 0;
4026
+ }
4027
+ const timer = setInterval(() => {
4028
+ if (detector.feed(latest.current, Date.now())) setShown(true);
4029
+ }, 150);
4030
+ return () => clearInterval(timer);
4031
+ }, [mutedByMe, detector]);
4032
+ useEffect6(() => {
4033
+ if (!shown) return void 0;
4034
+ const timer = setTimeout(() => setShown(false), 8e3);
4035
+ return () => clearTimeout(timer);
4036
+ }, [shown]);
4037
+ if (!shown || !mutedByMe) return null;
4038
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__notice-bar", role: "status", "data-meet-notice": "speaking-while-muted", children: [
4039
+ /* @__PURE__ */ jsx6(MicOffIcon, { width: 16, height: 16 }),
4040
+ /* @__PURE__ */ jsx6("span", { children: "You're muted" }),
4041
+ /* @__PURE__ */ jsx6(
4042
+ "button",
4043
+ {
4044
+ type: "button",
4045
+ className: "mx-meet__primary mx-meet__primary--small",
4046
+ onClick: () => {
4047
+ setShown(false);
4048
+ void room.toggleMicrophone();
4049
+ },
4050
+ children: "Unmute"
4051
+ }
4052
+ )
4053
+ ] });
4054
+ }
3894
4055
  function MediaNotices() {
3895
4056
  const media = useLocalMedia();
3896
4057
  const { region, where, enableAudio, acceptOffer, dismissOffer, dismissNotice, retry } = useMediaSupervisor();
3897
- const [fixing, setFixing] = useState4(null);
4058
+ const [fixing, setFixing] = useState5(null);
3898
4059
  const chips = ["microphone", "camera"].flatMap((kind) => {
3899
4060
  const reason = deviceUnavailableReason(media[kind], region.permission[kind]);
3900
4061
  return reason === null ? [] : [{ kind, reason }];
@@ -3904,8 +4065,8 @@ function MediaNotices() {
3904
4065
  const offer = region.offer;
3905
4066
  const name = (kind) => kind === "microphone" ? "Microphone" : "Camera";
3906
4067
  if (chips.length === 0 && region.audioOutput !== "blocked" && notice === null && offer === null) return null;
3907
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__media-notices", children: [
3908
- region.audioOutput === "blocked" ? /* @__PURE__ */ jsxs3(
4068
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__media-notices", children: [
4069
+ region.audioOutput === "blocked" ? /* @__PURE__ */ jsxs4(
3909
4070
  ErrorBox,
3910
4071
  {
3911
4072
  as: "div",
@@ -3920,7 +4081,7 @@ function MediaNotices() {
3920
4081
  ]
3921
4082
  }
3922
4083
  ) : null,
3923
- chips.map(({ kind, reason }) => /* @__PURE__ */ jsxs3("div", { className: "mx-meet__media-pill", role: "status", "data-meet-notice": deviceNoticeCode(kind, reason), children: [
4084
+ chips.map(({ kind, reason }) => /* @__PURE__ */ jsxs4("div", { className: "mx-meet__media-pill", role: "status", "data-meet-notice": deviceNoticeCode(kind, reason), children: [
3924
4085
  /* @__PURE__ */ jsx6("span", { children: deviceChipLabel(kind, reason) }),
3925
4086
  /* @__PURE__ */ jsx6(
3926
4087
  "button",
@@ -3934,9 +4095,9 @@ function MediaNotices() {
3934
4095
  }
3935
4096
  )
3936
4097
  ] }, kind)),
3937
- fixing !== null && fixReason !== null ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__popover mx-meet__fix-sheet", role: "dialog", "aria-label": `Fix ${name(fixing).toLowerCase()}`, children: [
4098
+ fixing !== null && fixReason !== null ? /* @__PURE__ */ jsxs4("div", { className: "mx-meet__popover mx-meet__fix-sheet", role: "dialog", "aria-label": `Fix ${name(fixing).toLowerCase()}`, children: [
3938
4099
  /* @__PURE__ */ jsx6("ol", { className: "mx-meet__fix-steps", children: deviceFixSteps(fixing, fixReason, where).map((step) => /* @__PURE__ */ jsx6("li", { children: step }, step)) }),
3939
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__fix-actions", children: [
4100
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__fix-actions", children: [
3940
4101
  /* @__PURE__ */ jsx6(
3941
4102
  "button",
3942
4103
  {
@@ -3953,7 +4114,7 @@ function MediaNotices() {
3953
4114
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Close", onClick: () => setFixing(null), children: /* @__PURE__ */ jsx6(CloseIcon, { width: 14, height: 14 }) })
3954
4115
  ] })
3955
4116
  ] }) : null,
3956
- notice !== null ? /* @__PURE__ */ jsxs3(
4117
+ notice !== null ? /* @__PURE__ */ jsxs4(
3957
4118
  "div",
3958
4119
  {
3959
4120
  className: "mx-meet__media-pill",
@@ -3965,7 +4126,7 @@ function MediaNotices() {
3965
4126
  ]
3966
4127
  }
3967
4128
  ) : null,
3968
- offer !== null ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__media-pill", role: "status", children: [
4129
+ offer !== null ? /* @__PURE__ */ jsxs4("div", { className: "mx-meet__media-pill", role: "status", children: [
3969
4130
  /* @__PURE__ */ jsx6("span", { children: `New ${offer.kind}: ${offer.label || name(offer.kind)}` }),
3970
4131
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__primary mx-meet__primary--small", onClick: () => void acceptOffer(), children: "Use it" }),
3971
4132
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: dismissOffer, children: /* @__PURE__ */ jsx6(CloseIcon, { width: 14, height: 14 }) })
@@ -3980,22 +4141,22 @@ function MeetingOverlays() {
3980
4141
  const snapshot = useMeetSnapshot();
3981
4142
  const controls = useHostControls();
3982
4143
  const isHostNow = useRole() === "host";
3983
- return /* @__PURE__ */ jsxs3(Fragment, { children: [
4144
+ return /* @__PURE__ */ jsxs4(Fragment, { children: [
3984
4145
  /* @__PURE__ */ jsx6(ReactionOverlay, { reactions }),
3985
4146
  /* @__PURE__ */ jsx6(MediaNotices, {}),
3986
4147
  snapshot !== null && snapshot.phase === "in_call" && snapshot.participants.length >= 2 && !snapshot.participants.some((p) => p.role === "host" || p.role === "cohost") ? (
3987
4148
  // meeting-without-host: the call goes on; host-only controls are simply not on screen.
3988
4149
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "host-absent", children: "The host has left the meeting. Host controls are not available until a host is back." })
3989
4150
  ) : null,
3990
- live.consent !== null ? /* @__PURE__ */ jsx6("div", { className: "mx-meet__sheet-backdrop", children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__sheet", role: "alertdialog", "aria-label": "This meeting is being recorded", "data-meet-notice": "recording-consent", children: [
4151
+ live.consent !== null ? /* @__PURE__ */ jsx6("div", { className: "mx-meet__sheet-backdrop", children: /* @__PURE__ */ jsxs4("div", { className: "mx-meet__sheet", role: "alertdialog", "aria-label": "This meeting is being recorded", "data-meet-notice": "recording-consent", children: [
3991
4152
  /* @__PURE__ */ jsx6("h2", { className: "mx-meet__panel-title", children: "This meeting is being recorded" }),
3992
4153
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__confirm-text", children: live.consent === "ok_or_leave" ? "By staying you agree to be recorded. You can leave now if you do not agree." : "Until you agree to the recording you can watch and listen, but not use your microphone or camera." }),
3993
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu-actions", children: [
4154
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__menu-actions", children: [
3994
4155
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__send", onClick: live.agree, children: live.consent === "ok_or_leave" ? "OK" : "I agree" }),
3995
4156
  live.consent === "ok_or_leave" ? /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__link", onClick: () => void room.leave(), children: "Leave meeting" }) : null
3996
4157
  ] })
3997
4158
  ] }) }) : null,
3998
- snapshot?.canReclaim === true && !isHostNow ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__notice-bar", role: "status", "data-meet-notice": "host-reclaim", children: [
4159
+ snapshot?.canReclaim === true && !isHostNow ? /* @__PURE__ */ jsxs4("div", { className: "mx-meet__notice-bar", role: "status", "data-meet-notice": "host-reclaim", children: [
3999
4160
  /* @__PURE__ */ jsx6("span", { children: "You started this meeting. Take back the host?" }),
4000
4161
  /* @__PURE__ */ jsx6(
4001
4162
  "button",
@@ -4008,7 +4169,7 @@ function MeetingOverlays() {
4008
4169
  )
4009
4170
  ] }) : null,
4010
4171
  live.micLocked || live.cameraLocked ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "mic-locked", children: live.micLocked && live.cameraLocked ? "Your microphone and camera are turned off by the organizer." : live.micLocked ? "Your microphone is turned off by the organizer." : "Your camera is turned off by the organizer." }) : null,
4011
- live.timeWarning && live.minutesLeft !== null && live.minutesLeft > 0 ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "time-warning", children: [
4172
+ live.timeWarning && live.minutesLeft !== null && live.minutesLeft > 0 ? /* @__PURE__ */ jsxs4("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "time-warning", children: [
4012
4173
  "This meeting will end in ",
4013
4174
  live.minutesLeft,
4014
4175
  " ",
@@ -4019,7 +4180,7 @@ function MeetingOverlays() {
4019
4180
  // A host's request ("the host is asking you to unmute"), not an error:
4020
4181
  // an assertive status, so it is announced at once without being filed
4021
4182
  // as a failure (design-system error-box census).
4022
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__notice-bar", role: "status", "aria-live": "assertive", children: [
4183
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__notice-bar", role: "status", "aria-live": "assertive", children: [
4023
4184
  /* @__PURE__ */ jsx6("span", { children: notice.text }),
4024
4185
  notice.kind === "ask-unmute" && room.local?.micEnabled !== true ? /* @__PURE__ */ jsx6(
4025
4186
  "button",
@@ -4046,7 +4207,7 @@ function ShortcutsSheet({ onClose }) {
4046
4207
  window.addEventListener("keydown", onKey);
4047
4208
  return () => window.removeEventListener("keydown", onKey);
4048
4209
  }, [onClose]);
4049
- return /* @__PURE__ */ jsx6("div", { className: "mx-meet__sheet-backdrop", onClick: onClose, children: /* @__PURE__ */ jsxs3(
4210
+ return /* @__PURE__ */ jsx6("div", { className: "mx-meet__sheet-backdrop", onClick: onClose, children: /* @__PURE__ */ jsxs4(
4050
4211
  "div",
4051
4212
  {
4052
4213
  className: "mx-meet__sheet",
@@ -4054,11 +4215,11 @@ function ShortcutsSheet({ onClose }) {
4054
4215
  "aria-label": "Keyboard shortcuts",
4055
4216
  onClick: (event) => event.stopPropagation(),
4056
4217
  children: [
4057
- /* @__PURE__ */ jsxs3("header", { className: "mx-meet__panel-head", children: [
4218
+ /* @__PURE__ */ jsxs4("header", { className: "mx-meet__panel-head", children: [
4058
4219
  /* @__PURE__ */ jsx6("h2", { className: "mx-meet__panel-title", children: "Keyboard shortcuts" }),
4059
4220
  /* @__PURE__ */ jsx6(ControlButton, { label: "Close", onClick: onClose, children: /* @__PURE__ */ jsx6(CloseIcon, { width: 16, height: 16 }) })
4060
4221
  ] }),
4061
- /* @__PURE__ */ jsx6("dl", { className: "mx-meet__shortcuts", children: MEET_SHORTCUTS.map((shortcut) => /* @__PURE__ */ jsxs3("div", { className: "mx-meet__shortcut", children: [
4222
+ /* @__PURE__ */ jsx6("dl", { className: "mx-meet__shortcuts", children: MEET_SHORTCUTS.map((shortcut) => /* @__PURE__ */ jsxs4("div", { className: "mx-meet__shortcut", children: [
4062
4223
  /* @__PURE__ */ jsx6("dt", { children: shortcut.label }),
4063
4224
  /* @__PURE__ */ jsx6("dd", { children: /* @__PURE__ */ jsx6("kbd", { className: "mx-meet__kbd", children: shortcut.keys }) })
4064
4225
  ] }, shortcut.id)) })
@@ -4090,8 +4251,8 @@ function PanelShell({
4090
4251
  observer.observe(header);
4091
4252
  return () => observer.disconnect();
4092
4253
  }, []);
4093
- return /* @__PURE__ */ jsxs3("aside", { ref, className: "mx-meet__panel", "aria-label": title, children: [
4094
- /* @__PURE__ */ jsxs3("header", { className: "mx-meet__panel-head", children: [
4254
+ return /* @__PURE__ */ jsxs4("aside", { ref, className: "mx-meet__panel", "aria-label": title, children: [
4255
+ /* @__PURE__ */ jsxs4("header", { className: "mx-meet__panel-head", children: [
4095
4256
  /* @__PURE__ */ jsx6("h2", { className: "mx-meet__panel-title", children: title }),
4096
4257
  /* @__PURE__ */ jsx6(ControlButton, { label: "Close panel", onClick: onClose, children: /* @__PURE__ */ jsx6(CloseIcon, { width: 16, height: 16 }) })
4097
4258
  ] }),
@@ -4106,8 +4267,8 @@ function ChatPanel({
4106
4267
  const snapshot = useMeetSnapshot();
4107
4268
  const room = useRoom();
4108
4269
  const live = useLivePolicy();
4109
- const [draft, setDraft] = useState4("");
4110
- const [recipient, setRecipient] = useState4(to);
4270
+ const [draft, setDraft] = useState5("");
4271
+ const [recipient, setRecipient] = useState5(to);
4111
4272
  const listRef = useRef6(null);
4112
4273
  const messages = snapshot?.chat ?? [];
4113
4274
  const local = snapshot?.localIdentity ?? null;
@@ -4124,13 +4285,13 @@ function ChatPanel({
4124
4285
  setRecipient(next);
4125
4286
  onTo?.(next);
4126
4287
  };
4127
- return /* @__PURE__ */ jsxs3(PanelShell, { title: "Chat", onClose, children: [
4128
- /* @__PURE__ */ jsxs3("ul", { className: "mx-meet__chat", ref: listRef, children: [
4288
+ return /* @__PURE__ */ jsxs4(PanelShell, { title: "Chat", onClose, children: [
4289
+ /* @__PURE__ */ jsxs4("ul", { className: "mx-meet__chat", ref: listRef, children: [
4129
4290
  snapshot?.chatHistoryError != null ? /* @__PURE__ */ jsx6("li", { className: "mx-meet__panel-note", children: snapshot.chatHistoryError }) : null,
4130
4291
  snapshot?.chatLoaded !== true && messages.length === 0 ? /* @__PURE__ */ jsx6("li", { className: "mx-meet__panel-note", children: "Reading earlier messages\u2026" }) : messages.length === 0 && snapshot?.chatHistoryError == null ? /* @__PURE__ */ jsx6("li", { className: "mx-meet__panel-note", children: "No messages yet. Messages to everyone stay with the meeting, so people who join later see them." }) : null,
4131
4292
  messages.map((message) => /* @__PURE__ */ jsx6(ChatLine, { message, local, people }, message.id))
4132
4293
  ] }),
4133
- !live.canChat ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", role: "status", "data-meet-notice": "chat-restricted", children: live.chatMode === "off" ? "Chat is turned off for this meeting." : "Chat is limited to the host and co-hosts in this meeting." }) : /* @__PURE__ */ jsxs3(
4294
+ !live.canChat ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", role: "status", "data-meet-notice": "chat-restricted", children: live.chatMode === "off" ? "Chat is turned off for this meeting." : "Chat is limited to the host and co-hosts in this meeting." }) : /* @__PURE__ */ jsxs4(
4134
4295
  "form",
4135
4296
  {
4136
4297
  className: "mx-meet__composer mx-meet__composer--chat",
@@ -4143,7 +4304,7 @@ function ChatPanel({
4143
4304
  else void room.sendPrivateChat(recipient, text);
4144
4305
  },
4145
4306
  children: [
4146
- people.length > 0 ? /* @__PURE__ */ jsxs3(
4307
+ people.length > 0 ? /* @__PURE__ */ jsxs4(
4147
4308
  "select",
4148
4309
  {
4149
4310
  className: "mx-meet__select mx-meet__select--compact",
@@ -4152,14 +4313,14 @@ function ChatPanel({
4152
4313
  onChange: (event) => choose(event.target.value === "" ? null : event.target.value),
4153
4314
  children: [
4154
4315
  /* @__PURE__ */ jsx6("option", { value: "", children: "Everyone" }),
4155
- people.map((participant) => /* @__PURE__ */ jsxs3("option", { value: participant.identity, children: [
4316
+ people.map((participant) => /* @__PURE__ */ jsxs4("option", { value: participant.identity, children: [
4156
4317
  participant.displayName,
4157
4318
  " (private)"
4158
4319
  ] }, participant.identity))
4159
4320
  ]
4160
4321
  }
4161
4322
  ) : null,
4162
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__composer-row", children: [
4323
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__composer-row", children: [
4163
4324
  /* @__PURE__ */ jsx6(
4164
4325
  "input",
4165
4326
  {
@@ -4173,7 +4334,7 @@ function ChatPanel({
4173
4334
  ),
4174
4335
  /* @__PURE__ */ jsx6("button", { type: "submit", className: "mx-meet__send", disabled: draft.trim().length === 0, children: "Send" })
4175
4336
  ] }),
4176
- recipientName !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
4337
+ recipientName !== null ? /* @__PURE__ */ jsxs4("p", { className: "mx-meet__panel-note", children: [
4177
4338
  "Only ",
4178
4339
  recipientName,
4179
4340
  " sees this. Private messages are not saved."
@@ -4191,7 +4352,7 @@ function ChatLine({
4191
4352
  const mine = message.identity === local;
4192
4353
  const privateTo = message.to ?? null;
4193
4354
  const counterpart = privateTo === null ? null : mine ? people.find((p) => p.identity === privateTo)?.displayName ?? "them" : "you";
4194
- return /* @__PURE__ */ jsxs3(
4355
+ return /* @__PURE__ */ jsxs4(
4195
4356
  "li",
4196
4357
  {
4197
4358
  className: [
@@ -4200,9 +4361,9 @@ function ChatLine({
4200
4361
  message.failed !== void 0 ? "mx-meet__chat-line--failed" : ""
4201
4362
  ].filter(Boolean).join(" "),
4202
4363
  children: [
4203
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__chat-meta", children: [
4364
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__chat-meta", children: [
4204
4365
  /* @__PURE__ */ jsx6("strong", { children: mine ? "You" : message.displayName }),
4205
- counterpart !== null ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__chat-private", children: [
4366
+ counterpart !== null ? /* @__PURE__ */ jsxs4("span", { className: "mx-meet__chat-private", children: [
4206
4367
  "to ",
4207
4368
  counterpart,
4208
4369
  " \xB7 private"
@@ -4222,8 +4383,8 @@ function PeoplePanel({
4222
4383
  const snapshot = useMeetSnapshot();
4223
4384
  const controls = useHostControls();
4224
4385
  const queue = useHandQueue();
4225
- const [query, setQuery] = useState4("");
4226
- const [menuFor, setMenuFor] = useState4(null);
4386
+ const [query, setQuery] = useState5("");
4387
+ const [menuFor, setMenuFor] = useState5(null);
4227
4388
  const myRole = useRole();
4228
4389
  const local = snapshot?.localIdentity ?? null;
4229
4390
  const observersHidden = snapshot?.grants.observersVisibleTo === "hosts" && !controls.isHost;
@@ -4232,11 +4393,11 @@ function PeoplePanel({
4232
4393
  );
4233
4394
  const needle = query.trim().toLowerCase();
4234
4395
  const shown = needle.length === 0 ? everyone : everyone.filter((participant) => participant.displayName.toLowerCase().includes(needle));
4235
- return /* @__PURE__ */ jsxs3(PanelShell, { title: `People (${everyone.length})`, onClose, children: [
4396
+ return /* @__PURE__ */ jsxs4(PanelShell, { title: `People (${everyone.length})`, onClose, children: [
4236
4397
  /* @__PURE__ */ jsx6(LobbyPanel, {}),
4237
- queue.length > 0 ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__section", "aria-label": "Raised hands", children: [
4238
- /* @__PURE__ */ jsxs3("header", { className: "mx-meet__section-head", children: [
4239
- /* @__PURE__ */ jsxs3("h3", { className: "mx-meet__section-title", children: [
4398
+ queue.length > 0 ? /* @__PURE__ */ jsxs4("section", { className: "mx-meet__section", "aria-label": "Raised hands", children: [
4399
+ /* @__PURE__ */ jsxs4("header", { className: "mx-meet__section-head", children: [
4400
+ /* @__PURE__ */ jsxs4("h3", { className: "mx-meet__section-title", children: [
4240
4401
  "Raised hands \xB7 ",
4241
4402
  queue.length
4242
4403
  ] }),
@@ -4250,9 +4411,9 @@ function PeoplePanel({
4250
4411
  }
4251
4412
  ) : null
4252
4413
  ] }),
4253
- /* @__PURE__ */ jsx6("ol", { className: "mx-meet__queue", children: queue.map((participant) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__person", children: [
4414
+ /* @__PURE__ */ jsx6("ol", { className: "mx-meet__queue", children: queue.map((participant) => /* @__PURE__ */ jsxs4("li", { className: "mx-meet__person", children: [
4254
4415
  /* @__PURE__ */ jsx6(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 28 }),
4255
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
4416
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__person-name", children: [
4256
4417
  participant.displayName,
4257
4418
  participant.identity === local ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__you", children: " (you)" }) : null
4258
4419
  ] }),
@@ -4267,12 +4428,12 @@ function PeoplePanel({
4267
4428
  ) : null
4268
4429
  ] }, participant.identity)) })
4269
4430
  ] }) : null,
4270
- controls.isHost && everyone.length > 1 ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__bulk", children: [
4271
- /* @__PURE__ */ jsxs3("button", { type: "button", className: "mx-meet__chip", onClick: () => void controls.run({ action: "mute_all" }), children: [
4431
+ controls.isHost && everyone.length > 1 ? /* @__PURE__ */ jsxs4("div", { className: "mx-meet__bulk", children: [
4432
+ /* @__PURE__ */ jsxs4("button", { type: "button", className: "mx-meet__chip", onClick: () => void controls.run({ action: "mute_all" }), children: [
4272
4433
  /* @__PURE__ */ jsx6(MicOffIcon, { width: 14, height: 14 }),
4273
4434
  " Mute all"
4274
4435
  ] }),
4275
- /* @__PURE__ */ jsxs3(
4436
+ /* @__PURE__ */ jsxs4(
4276
4437
  "button",
4277
4438
  {
4278
4439
  type: "button",
@@ -4285,7 +4446,7 @@ function PeoplePanel({
4285
4446
  }
4286
4447
  )
4287
4448
  ] }) : null,
4288
- everyone.length > 4 ? /* @__PURE__ */ jsxs3("label", { className: "mx-meet__search", children: [
4449
+ everyone.length > 4 ? /* @__PURE__ */ jsxs4("label", { className: "mx-meet__search", children: [
4289
4450
  /* @__PURE__ */ jsx6(SearchIcon, { width: 16, height: 16 }),
4290
4451
  /* @__PURE__ */ jsx6(
4291
4452
  "input",
@@ -4299,10 +4460,10 @@ function PeoplePanel({
4299
4460
  )
4300
4461
  ] }) : null,
4301
4462
  controls.notice !== null ? /* @__PURE__ */ jsx6("p", { className: controls.notice.failed ? "mx-meet__error" : "mx-meet__notice", role: "status", children: controls.notice.text }) : null,
4302
- /* @__PURE__ */ jsxs3("ul", { className: "mx-meet__people", children: [
4303
- shown.map((participant) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__person", children: [
4463
+ /* @__PURE__ */ jsxs4("ul", { className: "mx-meet__people", children: [
4464
+ shown.map((participant) => /* @__PURE__ */ jsxs4("li", { className: "mx-meet__person", children: [
4304
4465
  /* @__PURE__ */ jsx6(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 32 }),
4305
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
4466
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__person-name", children: [
4306
4467
  participant.displayName,
4307
4468
  participant.identity === local ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__you", children: " (you)" }) : null,
4308
4469
  /* @__PURE__ */ jsx6(
@@ -4319,7 +4480,7 @@ function PeoplePanel({
4319
4480
  participant.handRaised ? /* @__PURE__ */ jsx6(HandIcon, { width: 14, height: 14 }) : null,
4320
4481
  !participant.micEnabled && !isNoteTaker(participant) ? /* @__PURE__ */ jsx6(MicOffIcon, { width: 14, height: 14 }) : null,
4321
4482
  /* @__PURE__ */ jsx6(QualityBars, { quality: participant.quality }),
4322
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
4483
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__anchor", children: [
4323
4484
  /* @__PURE__ */ jsx6(
4324
4485
  ControlButton,
4325
4486
  {
@@ -4340,7 +4501,7 @@ function PeoplePanel({
4340
4501
  ) : null
4341
4502
  ] })
4342
4503
  ] }, participant.identity)),
4343
- shown.length === 0 ? /* @__PURE__ */ jsxs3("li", { className: "mx-meet__panel-note", children: [
4504
+ shown.length === 0 ? /* @__PURE__ */ jsxs4("li", { className: "mx-meet__panel-note", children: [
4344
4505
  "Nobody matches \u201C",
4345
4506
  query,
4346
4507
  "\u201D."
@@ -4358,14 +4519,14 @@ function PersonMenu({
4358
4519
  const host = useMeetHost();
4359
4520
  const snapshot = useMeetSnapshot();
4360
4521
  const controls = useHostControls();
4361
- const [mode, setMode] = useState4("menu");
4362
- const [text, setText] = useState4("");
4522
+ const [mode, setMode] = useState5("menu");
4523
+ const [text, setText] = useState5("");
4363
4524
  const self = participant.identity === snapshot?.localIdentity;
4364
4525
  const moderate = controls.canModerate(participant);
4365
4526
  const pinned = snapshot?.pinned === participant.identity;
4366
4527
  const spotlit = snapshot?.spotlight === participant.identity;
4367
4528
  const hasAccount = participant.userId !== null;
4368
- const [refused, setRefused] = useState4(false);
4529
+ const [refused, setRefused] = useState5(false);
4369
4530
  const act = (request) => {
4370
4531
  setRefused(false);
4371
4532
  void controls.run(request).then((result) => {
@@ -4376,7 +4537,7 @@ function PersonMenu({
4376
4537
  const refusal = refused && controls.notice?.failed === true ? /* @__PURE__ */ jsx6(ErrorBox, { as: "p", className: "mx-meet__error", message: controls.notice.text, operation: "Change this participant", origin: "meet/components", children: controls.notice.text }) : null;
4377
4538
  if (mode === "rename" || mode === "report") {
4378
4539
  const renaming = mode === "rename";
4379
- return /* @__PURE__ */ jsx6(Popover, { label: renaming ? "Rename" : "Report", onClose, placement, children: /* @__PURE__ */ jsxs3(
4540
+ return /* @__PURE__ */ jsx6(Popover, { label: renaming ? "Rename" : "Report", onClose, placement, children: /* @__PURE__ */ jsxs4(
4380
4541
  "form",
4381
4542
  {
4382
4543
  className: "mx-meet__menu-form",
@@ -4388,7 +4549,7 @@ function PersonMenu({
4388
4549
  );
4389
4550
  },
4390
4551
  children: [
4391
- /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
4552
+ /* @__PURE__ */ jsxs4("label", { className: "mx-meet__field", children: [
4392
4553
  /* @__PURE__ */ jsx6("span", { className: "mx-meet__field-label", children: renaming ? "Name shown in this meeting" : `What did ${participant.displayName} do?` }),
4393
4554
  renaming ? /* @__PURE__ */ jsx6(
4394
4555
  "input",
@@ -4412,7 +4573,7 @@ function PersonMenu({
4412
4573
  )
4413
4574
  ] }),
4414
4575
  refusal,
4415
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu-actions", children: [
4576
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__menu-actions", children: [
4416
4577
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Back" }),
4417
4578
  /* @__PURE__ */ jsx6("button", { type: "submit", className: "mx-meet__send", disabled: text.trim().length === 0 || controls.busy, children: renaming ? "Rename" : "Report" })
4418
4579
  ] })
@@ -4422,10 +4583,10 @@ function PersonMenu({
4422
4583
  }
4423
4584
  if (mode === "remove" || mode === "transfer") {
4424
4585
  const removing = mode === "remove";
4425
- return /* @__PURE__ */ jsx6(Popover, { label: removing ? "Remove" : "Make host", onClose, placement, children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu-form", children: [
4586
+ return /* @__PURE__ */ jsx6(Popover, { label: removing ? "Remove" : "Make host", onClose, placement, children: /* @__PURE__ */ jsxs4("div", { className: "mx-meet__menu-form", children: [
4426
4587
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__confirm-text", children: removing ? `Remove ${participant.displayName}? They leave immediately and cannot rejoin this meeting.` : `Make ${participant.displayName} the host? They get every host control and own this meeting. You stay on as a co-host.` }),
4427
4588
  refusal,
4428
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu-actions", children: [
4589
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__menu-actions", children: [
4429
4590
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Cancel" }),
4430
4591
  /* @__PURE__ */ jsx6(
4431
4592
  "button",
@@ -4440,8 +4601,8 @@ function PersonMenu({
4440
4601
  ] })
4441
4602
  ] }) });
4442
4603
  }
4443
- return /* @__PURE__ */ jsx6(Popover, { label: `Options for ${participant.displayName}`, onClose, placement, children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu", role: "menu", children: [
4444
- /* @__PURE__ */ jsxs3(
4604
+ return /* @__PURE__ */ jsx6(Popover, { label: `Options for ${participant.displayName}`, onClose, placement, children: /* @__PURE__ */ jsxs4("div", { className: "mx-meet__menu", role: "menu", children: [
4605
+ /* @__PURE__ */ jsxs4(
4445
4606
  MenuItem,
4446
4607
  {
4447
4608
  onSelect: () => {
@@ -4455,7 +4616,7 @@ function PersonMenu({
4455
4616
  ]
4456
4617
  }
4457
4618
  ),
4458
- !self && !participant.isAgent && (onMessage !== void 0 || host !== null) ? /* @__PURE__ */ jsxs3(
4619
+ !self && !participant.isAgent && (onMessage !== void 0 || host !== null) ? /* @__PURE__ */ jsxs4(
4459
4620
  MenuItem,
4460
4621
  {
4461
4622
  onSelect: () => {
@@ -4472,44 +4633,44 @@ function PersonMenu({
4472
4633
  ]
4473
4634
  }
4474
4635
  ) : null,
4475
- controls.isHost ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "spotlight", identity: spotlit ? null : participant.identity }), children: [
4636
+ controls.isHost ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "spotlight", identity: spotlit ? null : participant.identity }), children: [
4476
4637
  /* @__PURE__ */ jsx6(SpotlightIcon, { width: 16, height: 16 }),
4477
4638
  " ",
4478
4639
  spotlit ? "Remove spotlight" : "Spotlight for everyone"
4479
4640
  ] }) : null,
4480
- moderate ? /* @__PURE__ */ jsxs3(Fragment, { children: [
4641
+ moderate ? /* @__PURE__ */ jsxs4(Fragment, { children: [
4481
4642
  /* @__PURE__ */ jsx6("div", { className: "mx-meet__menu-sep", role: "separator" }),
4482
- participant.micEnabled ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "mute", identity: participant.identity }), children: [
4643
+ participant.micEnabled ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "mute", identity: participant.identity }), children: [
4483
4644
  /* @__PURE__ */ jsx6(MicOffIcon, { width: 16, height: 16 }),
4484
4645
  " Mute"
4485
- ] }) : !participant.isAgent ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "ask_unmute", identity: participant.identity }), children: [
4646
+ ] }) : !participant.isAgent ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "ask_unmute", identity: participant.identity }), children: [
4486
4647
  /* @__PURE__ */ jsx6(MicIcon, { width: 16, height: 16 }),
4487
4648
  " Ask to unmute"
4488
4649
  ] }) : null,
4489
- participant.cameraEnabled ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "stop_video", identity: participant.identity }), children: [
4650
+ participant.cameraEnabled ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "stop_video", identity: participant.identity }), children: [
4490
4651
  /* @__PURE__ */ jsx6(CameraOffIcon, { width: 16, height: 16 }),
4491
4652
  " Stop video"
4492
4653
  ] }) : null,
4493
- participant.screenSharing ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "stop_screen", identity: participant.identity }), children: [
4654
+ participant.screenSharing ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "stop_screen", identity: participant.identity }), children: [
4494
4655
  /* @__PURE__ */ jsx6(ScreenShareIcon, { width: 16, height: 16 }),
4495
4656
  " Stop screen share"
4496
4657
  ] }) : null,
4497
- participant.handRaised ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "lower_hand", identity: participant.identity }), children: [
4658
+ participant.handRaised ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "lower_hand", identity: participant.identity }), children: [
4498
4659
  /* @__PURE__ */ jsx6(HandIcon, { width: 16, height: 16 }),
4499
4660
  " Lower hand"
4500
4661
  ] }) : null,
4501
- hasAccount && !participant.isAgent && participant.role !== "cohost" ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "make_cohost", identity: participant.identity }), children: [
4662
+ hasAccount && !participant.isAgent && participant.role !== "cohost" ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "make_cohost", identity: participant.identity }), children: [
4502
4663
  /* @__PURE__ */ jsx6(PeopleIcon, { width: 16, height: 16 }),
4503
4664
  " Make co-host"
4504
4665
  ] }) : null,
4505
- !participant.isAgent && participant.role !== "cohost" && participant.role !== "host" ? participant.role === "presenter" ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "revoke_presenter", identity: participant.identity }), children: [
4666
+ !participant.isAgent && participant.role !== "cohost" && participant.role !== "host" ? participant.role === "presenter" ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "revoke_presenter", identity: participant.identity }), children: [
4506
4667
  /* @__PURE__ */ jsx6(ScreenShareIcon, { width: 16, height: 16 }),
4507
4668
  " Remove presenter"
4508
- ] }) : /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "make_presenter", identity: participant.identity }), children: [
4669
+ ] }) : /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "make_presenter", identity: participant.identity }), children: [
4509
4670
  /* @__PURE__ */ jsx6(ScreenShareIcon, { width: 16, height: 16 }),
4510
4671
  " Make presenter"
4511
4672
  ] }) : null,
4512
- !participant.isAgent ? /* @__PURE__ */ jsxs3(
4673
+ !participant.isAgent ? /* @__PURE__ */ jsxs4(
4513
4674
  MenuItem,
4514
4675
  {
4515
4676
  onSelect: () => {
@@ -4523,15 +4684,15 @@ function PersonMenu({
4523
4684
  }
4524
4685
  ) : null
4525
4686
  ] }) : null,
4526
- controls.isOwner && participant.role === "cohost" ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "revoke_cohost", identity: participant.identity }), children: [
4687
+ controls.isOwner && participant.role === "cohost" ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => act({ action: "revoke_cohost", identity: participant.identity }), children: [
4527
4688
  /* @__PURE__ */ jsx6(PeopleIcon, { width: 16, height: 16 }),
4528
4689
  " Remove co-host"
4529
4690
  ] }) : null,
4530
- controls.isOwner && !self && hasAccount && !participant.isAgent ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => setMode("transfer"), children: [
4691
+ controls.isOwner && !self && hasAccount && !participant.isAgent ? /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => setMode("transfer"), children: [
4531
4692
  /* @__PURE__ */ jsx6(SpotlightIcon, { width: 16, height: 16 }),
4532
4693
  " Make host"
4533
4694
  ] }) : null,
4534
- self ? /* @__PURE__ */ jsxs3(
4695
+ self ? /* @__PURE__ */ jsxs4(
4535
4696
  MenuItem,
4536
4697
  {
4537
4698
  onSelect: () => {
@@ -4544,7 +4705,7 @@ function PersonMenu({
4544
4705
  ]
4545
4706
  }
4546
4707
  ) : null,
4547
- !self && !participant.isAgent ? /* @__PURE__ */ jsxs3(
4708
+ !self && !participant.isAgent ? /* @__PURE__ */ jsxs4(
4548
4709
  MenuItem,
4549
4710
  {
4550
4711
  onSelect: () => {
@@ -4557,7 +4718,7 @@ function PersonMenu({
4557
4718
  ]
4558
4719
  }
4559
4720
  ) : null,
4560
- moderate && !participant.isAgent ? /* @__PURE__ */ jsxs3(MenuItem, { danger: true, onSelect: () => setMode("remove"), children: [
4721
+ moderate && !participant.isAgent ? /* @__PURE__ */ jsxs4(MenuItem, { danger: true, onSelect: () => setMode("remove"), children: [
4561
4722
  /* @__PURE__ */ jsx6(CloseIcon, { width: 16, height: 16 }),
4562
4723
  " Remove from meeting"
4563
4724
  ] }) : null
@@ -4565,7 +4726,7 @@ function PersonMenu({
4565
4726
  }
4566
4727
  function SettingsPanel({ onClose }) {
4567
4728
  const host = useRequiredMeetHost();
4568
- return /* @__PURE__ */ jsxs3(PanelShell, { title: "Settings", onClose, children: [
4729
+ return /* @__PURE__ */ jsxs4(PanelShell, { title: "Settings", onClose, children: [
4569
4730
  /* @__PURE__ */ jsx6(
4570
4731
  DeviceSettings,
4571
4732
  {
@@ -4588,15 +4749,15 @@ function DeviceSettings({
4588
4749
  const speaker = devices?.selected.audiooutput ?? host.devices.resolve("audiooutput");
4589
4750
  const stream = useMicrophoneStream(microphone);
4590
4751
  const level = useAudioLevel(stream);
4591
- const [testing, setTesting] = useState4(false);
4752
+ const [testing, setTesting] = useState5(false);
4592
4753
  useEffect6(() => {
4593
4754
  void host.devices.refresh();
4594
4755
  }, [host]);
4595
- return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__section", "aria-label": "Devices", children: [
4756
+ return /* @__PURE__ */ jsxs4("section", { className: "mx-meet__section", "aria-label": "Devices", children: [
4596
4757
  /* @__PURE__ */ jsx6(DevicePicker, { kind: "audioinput", label: "Microphone", onPick }),
4597
4758
  /* @__PURE__ */ jsx6("div", { className: "mx-meet__meter", role: "meter", "aria-label": "Microphone level", "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": Math.round(level * 100), children: /* @__PURE__ */ jsx6("span", { style: { width: `${Math.min(100, Math.round(level * 160))}%` } }) }),
4598
4759
  /* @__PURE__ */ jsx6(DevicePicker, { kind: "audiooutput", label: "Speaker", onPick }),
4599
- /* @__PURE__ */ jsxs3(
4760
+ /* @__PURE__ */ jsxs4(
4600
4761
  "button",
4601
4762
  {
4602
4763
  type: "button",
@@ -4618,7 +4779,7 @@ function DeviceSettings({
4618
4779
  }
4619
4780
  function EffectsSettings({ preview }) {
4620
4781
  const effects = useMediaEffects();
4621
- const [error, setError] = useState4(null);
4782
+ const [error, setError] = useState5(null);
4622
4783
  const fileRef = useRef6(null);
4623
4784
  const supported = effects.backgroundsSupported || preview != null || videoEffectsSupported();
4624
4785
  const apply = (next) => {
@@ -4631,8 +4792,8 @@ function EffectsSettings({ preview }) {
4631
4792
  );
4632
4793
  }
4633
4794
  };
4634
- return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__section", "aria-label": "Effects", children: [
4635
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__check", children: [
4795
+ return /* @__PURE__ */ jsxs4("section", { className: "mx-meet__section", "aria-label": "Effects", children: [
4796
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__check", children: [
4636
4797
  /* @__PURE__ */ jsx6(
4637
4798
  Checkbox,
4638
4799
  {
@@ -4641,12 +4802,12 @@ function EffectsSettings({ preview }) {
4641
4802
  onCheckedChange: (checked) => apply({ noiseSuppression: checked === true })
4642
4803
  }
4643
4804
  ),
4644
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__check-text", children: [
4805
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__check-text", children: [
4645
4806
  /* @__PURE__ */ jsx6(Label, { htmlFor: "mx-meet-noise", children: "Noise suppression" }),
4646
4807
  /* @__PURE__ */ jsx6("span", { className: "mx-meet__hint", children: "Filters keyboards, fans and background chatter." })
4647
4808
  ] })
4648
4809
  ] }),
4649
- supported ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__field", children: [
4810
+ supported ? /* @__PURE__ */ jsxs4("div", { className: "mx-meet__field", children: [
4650
4811
  /* @__PURE__ */ jsx6(Label, { children: "Background" }),
4651
4812
  /* @__PURE__ */ jsx6(
4652
4813
  SegmentedControl,
@@ -4740,14 +4901,20 @@ async function playTestSound(sinkId) {
4740
4901
  audio.pause();
4741
4902
  await context.close();
4742
4903
  }
4743
- function useMicrophoneStream(deviceId) {
4744
- const [stream, setStream] = useState4(null);
4904
+ function useMicrophoneStream(deviceId, report, attempt = 0) {
4905
+ const [stream, setStream] = useState5(null);
4906
+ const reportRef = useRef6(report);
4907
+ reportRef.current = report;
4745
4908
  useEffect6(() => {
4746
- if (deviceId === "off") return void 0;
4909
+ if (deviceId === "off") {
4910
+ reportRef.current?.("off");
4911
+ return void 0;
4912
+ }
4747
4913
  let live = true;
4748
4914
  let opened = null;
4749
4915
  const media = globalThis.navigator?.mediaDevices;
4750
4916
  if (media === void 0) return void 0;
4917
+ reportRef.current?.("prompting");
4751
4918
  void media.getUserMedia({ audio: deviceId === null ? true : { deviceId: { exact: deviceId } } }).then((next) => {
4752
4919
  if (!live) {
4753
4920
  next.getTracks().forEach((track) => track.stop());
@@ -4755,20 +4922,54 @@ function useMicrophoneStream(deviceId) {
4755
4922
  }
4756
4923
  opened = next;
4757
4924
  setStream(next);
4758
- }).catch(() => setStream(null));
4925
+ reportRef.current?.("on");
4926
+ }).catch((thrown) => {
4927
+ setStream(null);
4928
+ if (live) reportRef.current?.({ error: thrown });
4929
+ });
4759
4930
  return () => {
4760
4931
  live = false;
4761
4932
  opened?.getTracks().forEach((track) => track.stop());
4762
4933
  setStream(null);
4763
4934
  };
4764
- }, [deviceId]);
4935
+ }, [deviceId, attempt]);
4765
4936
  return stream;
4766
4937
  }
4938
+ function PreviewStatus({ onRetry }) {
4939
+ const { region, where } = useMediaSupervisor();
4940
+ const [waited, setWaited] = useState5(false);
4941
+ const prompting = region.preview.microphone.state === "prompting" || region.preview.camera.state === "prompting";
4942
+ useEffect6(() => {
4943
+ if (!prompting) {
4944
+ setWaited(false);
4945
+ return void 0;
4946
+ }
4947
+ const timer = setTimeout(() => setWaited(true), 800);
4948
+ return () => clearTimeout(timer);
4949
+ }, [prompting]);
4950
+ const refused = ["microphone", "camera"].flatMap((kind) => {
4951
+ const preview = region.preview[kind];
4952
+ const reason = region.permission[kind] === "denied" ? "denied" : preview.state === "unavailable" ? preview.unavailable?.reason ?? "failed" : null;
4953
+ return reason === null ? [] : [{ kind, reason }];
4954
+ });
4955
+ if (refused.length === 0) {
4956
+ if (!prompting || !waited) return null;
4957
+ return /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", role: "status", "data-meet-notice": "permission-prompt", children: "Allow camera and microphone when your browser asks" });
4958
+ }
4959
+ const first = refused[0];
4960
+ const both = refused.length === 2 && refused[0].reason === refused[1].reason;
4961
+ const label = both ? deviceChipLabel("camera", first.reason).replace(/^Camera/, "Camera and mic") : refused.map((r) => deviceChipLabel(r.kind, r.reason)).join(" \xB7 ");
4962
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__warning", role: "status", "data-meet-notice": deviceNoticeCode(first.kind, first.reason), children: [
4963
+ /* @__PURE__ */ jsx6("strong", { children: label }),
4964
+ /* @__PURE__ */ jsx6("ol", { className: "mx-meet__fix-steps", children: deviceFixSteps(first.kind, first.reason, where).map((step) => /* @__PURE__ */ jsx6("li", { children: step }, step)) }),
4965
+ /* @__PURE__ */ jsx6(Button, { type: "button", variant: "outline", size: "sm", onClick: onRetry, children: "Try again" })
4966
+ ] });
4967
+ }
4767
4968
  function KnockNotice({ onView }) {
4768
4969
  const { knocker, others, admit, dismiss } = useKnockNotice();
4769
4970
  if (knocker === null) return null;
4770
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__notice-bar", role: "status", "data-meet-notice": "knock-received", "data-meet-participant-name": knocker.displayName, children: [
4771
- /* @__PURE__ */ jsxs3("span", { children: [
4971
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__notice-bar", role: "status", "data-meet-notice": "knock-received", "data-meet-participant-name": knocker.displayName, children: [
4972
+ /* @__PURE__ */ jsxs4("span", { children: [
4772
4973
  knocker.displayName,
4773
4974
  " wants to join",
4774
4975
  others > 0 ? ` (+${others} more)` : ""
@@ -4792,15 +4993,15 @@ function KnockNotice({ onView }) {
4792
4993
  function LobbyPanel() {
4793
4994
  const lobby = useLobby();
4794
4995
  if (!lobby.canAdmit || lobby.waiting.length === 0 && lobby.declined.length === 0) return null;
4795
- return /* @__PURE__ */ jsxs3(Fragment, { children: [
4996
+ return /* @__PURE__ */ jsxs4(Fragment, { children: [
4796
4997
  lobby.waiting.length > 0 ? /* @__PURE__ */ jsx6(WaitingList, { lobby }) : null,
4797
4998
  lobby.declined.length > 0 ? /* @__PURE__ */ jsx6(DeclinedList, { lobby }) : null
4798
4999
  ] });
4799
5000
  }
4800
5001
  function DeclinedList({ lobby }) {
4801
- return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__lobby", "aria-label": "Declined requests", "data-meet-declined": "", children: [
5002
+ return /* @__PURE__ */ jsxs4("section", { className: "mx-meet__lobby", "aria-label": "Declined requests", "data-meet-declined": "", children: [
4802
5003
  /* @__PURE__ */ jsx6("header", { className: "mx-meet__lobby-head", children: /* @__PURE__ */ jsx6("h3", { className: "mx-meet__lobby-title", children: "Declined" }) }),
4803
- /* @__PURE__ */ jsx6("ul", { className: "mx-meet__lobby-list", children: lobby.declined.map((entry) => /* @__PURE__ */ jsxs3(
5004
+ /* @__PURE__ */ jsx6("ul", { className: "mx-meet__lobby-list", children: lobby.declined.map((entry) => /* @__PURE__ */ jsxs4(
4804
5005
  "li",
4805
5006
  {
4806
5007
  className: "mx-meet__lobby-row",
@@ -4826,12 +5027,12 @@ function DeclinedList({ lobby }) {
4826
5027
  ] });
4827
5028
  }
4828
5029
  function WaitingList({ lobby }) {
4829
- return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__lobby", "aria-label": "Waiting room", children: [
4830
- /* @__PURE__ */ jsxs3("header", { className: "mx-meet__lobby-head", children: [
5030
+ return /* @__PURE__ */ jsxs4("section", { className: "mx-meet__lobby", "aria-label": "Waiting room", children: [
5031
+ /* @__PURE__ */ jsxs4("header", { className: "mx-meet__lobby-head", children: [
4831
5032
  /* @__PURE__ */ jsx6("h3", { className: "mx-meet__lobby-title", children: lobby.waiting.length === 1 ? "1 person is waiting" : `${lobby.waiting.length} people are waiting` }),
4832
5033
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__link", onClick: () => void lobby.admitAll(), children: "Admit all" })
4833
5034
  ] }),
4834
- /* @__PURE__ */ jsx6("ul", { className: "mx-meet__lobby-list", children: lobby.waiting.map((entry) => /* @__PURE__ */ jsxs3(
5035
+ /* @__PURE__ */ jsx6("ul", { className: "mx-meet__lobby-list", children: lobby.waiting.map((entry) => /* @__PURE__ */ jsxs4(
4835
5036
  "li",
4836
5037
  {
4837
5038
  className: "mx-meet__lobby-row",
@@ -4839,7 +5040,7 @@ function WaitingList({ lobby }) {
4839
5040
  "data-meet-participant-name": entry.displayName,
4840
5041
  children: [
4841
5042
  /* @__PURE__ */ jsx6(Avatar, { name: entry.displayName, url: entry.avatarUrl, size: 32 }),
4842
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
5043
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__person-name", children: [
4843
5044
  entry.displayName,
4844
5045
  entry.userId === null ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__badge", children: "Guest" }) : null
4845
5046
  ] }),
@@ -4863,17 +5064,17 @@ function NoteTakerRow() {
4863
5064
  const ai = useMeetAi();
4864
5065
  const status = ai.noteTaker;
4865
5066
  const duplicateError = status.refusal !== null && ai.error !== null && status.refusal.reason === ai.error.message && status.refusal.remedy === ai.error.remedy;
4866
- return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-taker", "aria-label": "Note-taker", children: [
4867
- /* @__PURE__ */ jsxs3("p", { className: `mx-meet__note-taker-state mx-meet__note-taker-state--${status.state}`, children: [
5067
+ return /* @__PURE__ */ jsxs4("section", { className: "mx-meet__note-taker", "aria-label": "Note-taker", children: [
5068
+ /* @__PURE__ */ jsxs4("p", { className: `mx-meet__note-taker-state mx-meet__note-taker-state--${status.state}`, children: [
4868
5069
  /* @__PURE__ */ jsx6("span", { className: "mx-meet__note-taker-dot", "aria-hidden": "true" }),
4869
5070
  ai.noteTakerLabel
4870
5071
  ] }),
4871
5072
  status.detail !== null ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", children: status.detail }) : null,
4872
- status.refusal !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: status.refusal, operation: "Join this meeting", origin: "meet/components", children: [
5073
+ status.refusal !== null ? /* @__PURE__ */ jsxs4(ErrorBox, { as: "div", className: "mx-meet__refusal", error: status.refusal, operation: "Join this meeting", origin: "meet/components", children: [
4873
5074
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-reason", children: status.refusal.reason }),
4874
5075
  status.refusal.remedy.length > 0 ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-remedy", children: status.refusal.remedy }) : null
4875
5076
  ] }) : null,
4876
- ai.error !== null && !duplicateError ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
5077
+ ai.error !== null && !duplicateError ? /* @__PURE__ */ jsxs4(ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
4877
5078
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
4878
5079
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
4879
5080
  ] }) : null,
@@ -4901,9 +5102,9 @@ function NoteList({
4901
5102
  notes,
4902
5103
  empty
4903
5104
  }) {
4904
- return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-group", "aria-label": title, children: [
5105
+ return /* @__PURE__ */ jsxs4("section", { className: "mx-meet__note-group", "aria-label": title, children: [
4905
5106
  /* @__PURE__ */ jsx6("h3", { className: "mx-meet__note-group-title", children: title }),
4906
- notes.length === 0 ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", children: empty }) : /* @__PURE__ */ jsx6("ul", { className: "mx-meet__notes", children: notes.map((note) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__note", children: [
5107
+ notes.length === 0 ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", children: empty }) : /* @__PURE__ */ jsx6("ul", { className: "mx-meet__notes", children: notes.map((note) => /* @__PURE__ */ jsxs4("li", { className: "mx-meet__note", children: [
4907
5108
  note.text,
4908
5109
  note.assigneeDisplayName !== void 0 && note.assigneeDisplayName !== null ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__assignee", children: note.assigneeDisplayName }) : null
4909
5110
  ] }, note.id)) })
@@ -4911,14 +5112,14 @@ function NoteList({
4911
5112
  }
4912
5113
  function AiPanel({ onClose }) {
4913
5114
  const ai = useMeetAi();
4914
- const [question, setQuestion] = useState4("");
4915
- return /* @__PURE__ */ jsxs3(PanelShell, { title: "Meeting assistant", onClose, children: [
5115
+ const [question, setQuestion] = useState5("");
5116
+ return /* @__PURE__ */ jsxs4(PanelShell, { title: "Meeting assistant", onClose, children: [
4916
5117
  /* @__PURE__ */ jsx6(NoteTakerRow, {}),
4917
- ai.summary !== null ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-group", "aria-label": "Summary", children: [
5118
+ ai.summary !== null ? /* @__PURE__ */ jsxs4("section", { className: "mx-meet__note-group", "aria-label": "Summary", children: [
4918
5119
  /* @__PURE__ */ jsx6("h3", { className: "mx-meet__note-group-title", children: "Summary" }),
4919
5120
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__summary", children: ai.summary.text })
4920
5121
  ] }) : null,
4921
- ai.wrapUp !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__wrap-up-notice", role: "status", children: [
5122
+ ai.wrapUp !== null ? /* @__PURE__ */ jsxs4("p", { className: "mx-meet__wrap-up-notice", role: "status", children: [
4922
5123
  "The wrap-up is written \u2014 ",
4923
5124
  ai.wrapUp.noteIds.length,
4924
5125
  " ",
@@ -4954,9 +5155,9 @@ function AiPanel({ onClose }) {
4954
5155
  empty: "No action items yet."
4955
5156
  }
4956
5157
  ),
4957
- ai.transcript.length > 0 ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-group", "aria-label": "Transcript", children: [
5158
+ ai.transcript.length > 0 ? /* @__PURE__ */ jsxs4("section", { className: "mx-meet__note-group", "aria-label": "Transcript", children: [
4958
5159
  /* @__PURE__ */ jsx6("h3", { className: "mx-meet__note-group-title", children: "Transcript" }),
4959
- /* @__PURE__ */ jsx6("ul", { className: "mx-meet__transcript", children: ai.transcript.map((line) => /* @__PURE__ */ jsxs3(
5160
+ /* @__PURE__ */ jsx6("ul", { className: "mx-meet__transcript", children: ai.transcript.map((line) => /* @__PURE__ */ jsxs4(
4960
5161
  "li",
4961
5162
  {
4962
5163
  className: line.final && line.source === "record" ? "mx-meet__line" : "mx-meet__line mx-meet__line--interim",
@@ -4968,7 +5169,7 @@ function AiPanel({ onClose }) {
4968
5169
  line.id
4969
5170
  )) })
4970
5171
  ] }) : null,
4971
- /* @__PURE__ */ jsxs3(
5172
+ /* @__PURE__ */ jsxs4(
4972
5173
  "form",
4973
5174
  {
4974
5175
  className: "mx-meet__composer",
@@ -4995,7 +5196,7 @@ function AiPanel({ onClose }) {
4995
5196
  ),
4996
5197
  ai.asking && ai.phase !== null ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", role: "status", children: ai.phase }) : null,
4997
5198
  ai.answer !== null ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__answer", children: ai.answer }) : null,
4998
- ai.answer !== null && ai.coverage !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__coverage", children: [
5199
+ ai.answer !== null && ai.coverage !== null ? /* @__PURE__ */ jsxs4("p", { className: "mx-meet__coverage", children: [
4999
5200
  "Answered from ",
5000
5201
  ai.coverage.segmentsUsed,
5001
5202
  " of ",
@@ -5004,7 +5205,7 @@ function AiPanel({ onClose }) {
5004
5205
  ai.coverage.truncated ? " (the oldest were left out)" : "",
5005
5206
  "."
5006
5207
  ] }) : null,
5007
- ai.error !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
5208
+ ai.error !== null ? /* @__PURE__ */ jsxs4(ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
5008
5209
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
5009
5210
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
5010
5211
  ] }) : null
@@ -5017,7 +5218,7 @@ function Captions({ lines = 3 }) {
5017
5218
  const captions = useCaptions();
5018
5219
  if (!captions.on) return null;
5019
5220
  if (captions.state === "unavailable") {
5020
- return /* @__PURE__ */ jsx6("div", { className: "mx-meet__captions", role: "status", "data-meet-notice": "captions-unavailable", children: /* @__PURE__ */ jsxs3("p", { className: "mx-meet__caption", children: [
5221
+ return /* @__PURE__ */ jsx6("div", { className: "mx-meet__captions", role: "status", "data-meet-notice": "captions-unavailable", children: /* @__PURE__ */ jsxs4("p", { className: "mx-meet__caption", children: [
5021
5222
  "Captions are unavailable. ",
5022
5223
  captions.reason,
5023
5224
  captions.remedy !== null ? ` ${captions.remedy}` : ""
@@ -5026,10 +5227,10 @@ function Captions({ lines = 3 }) {
5026
5227
  if (visible.length === 0) {
5027
5228
  return /* @__PURE__ */ jsx6("div", { className: "mx-meet__captions", "aria-live": "polite", "aria-label": "Live captions", "data-meet-caption": captions.state, children: /* @__PURE__ */ jsx6("p", { className: "mx-meet__caption mx-meet__caption--interim", children: captions.state === "starting" ? "Starting captions. They appear as people speak." : "Captions are on. They appear as people speak." }) });
5028
5229
  }
5029
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__captions", "aria-live": "polite", "aria-label": "Live captions", "data-meet-caption": "live", children: [
5230
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__captions", "aria-live": "polite", "aria-label": "Live captions", "data-meet-caption": "live", children: [
5030
5231
  visible.map((line) => {
5031
5232
  const translated = translation.language === null ? void 0 : translation.translations[line.id];
5032
- return /* @__PURE__ */ jsxs3(
5233
+ return /* @__PURE__ */ jsxs4(
5033
5234
  "p",
5034
5235
  {
5035
5236
  className: line.final ? "mx-meet__caption" : "mx-meet__caption mx-meet__caption--interim",
@@ -5057,7 +5258,7 @@ function AttendanceNotice() {
5057
5258
  if (notice === null) return null;
5058
5259
  const refused = media.microphone.unavailable;
5059
5260
  const code = microphoneNoticeCode(media.microphone);
5060
- return /* @__PURE__ */ jsxs3(
5261
+ return /* @__PURE__ */ jsxs4(
5061
5262
  "p",
5062
5263
  {
5063
5264
  className: "mx-meet__banner mx-meet__banner--attendance",
@@ -5088,15 +5289,22 @@ function PreJoinBody({
5088
5289
  const recording = useRecording();
5089
5290
  const effects = useMediaEffects();
5090
5291
  const { notice } = useModerationNotice();
5091
- const [mode, setMode] = useState4("video");
5092
- const [microphone, setMicrophone] = useState4(true);
5093
- const [joining, setJoining] = useState4(false);
5292
+ const [mode, setMode] = useState5("video");
5293
+ const [microphone, setMicrophone] = useState5(true);
5294
+ const [joining, setJoining] = useState5(false);
5094
5295
  const camera = devices?.selected.videoinput ?? host.devices.resolve("videoinput");
5095
5296
  const mic = devices?.selected.audioinput ?? host.devices.resolve("audioinput");
5096
- const preview = useCameraPreview(mode === "video" ? camera : void 0, effects.effects);
5097
- const micStream = useMicrophoneStream(microphone ? mic : "off");
5297
+ const { reportPreview } = useMediaSupervisor();
5298
+ const [attempt, setAttempt] = useState5(0);
5299
+ const preview = useCameraPreview(
5300
+ mode === "video" ? camera : void 0,
5301
+ effects.effects,
5302
+ (outcome) => reportPreview("camera", outcome),
5303
+ attempt
5304
+ );
5305
+ const micStream = useMicrophoneStream(microphone ? mic : "off", (outcome) => reportPreview("microphone", outcome), attempt);
5098
5306
  const level = useAudioLevel(micStream);
5099
- const [speakerTesting, setSpeakerTesting] = useState4(false);
5307
+ const [speakerTesting, setSpeakerTesting] = useState5(false);
5100
5308
  useEffect6(() => {
5101
5309
  void host.devices.refresh();
5102
5310
  }, [host]);
@@ -5119,8 +5327,8 @@ function PreJoinBody({
5119
5327
  ...secondDevice !== void 0 ? { secondDevice } : {}
5120
5328
  }).then(() => onJoined?.()).catch(() => void 0).finally(() => setJoining(false));
5121
5329
  };
5122
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__prejoin", children: [
5123
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__preview", children: [
5330
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__prejoin", children: [
5331
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__preview", children: [
5124
5332
  mode === "video" && preview.preview !== null ? /* @__PURE__ */ jsx6(
5125
5333
  "video",
5126
5334
  {
@@ -5136,10 +5344,11 @@ function PreJoinBody({
5136
5344
  mode === "video" && preview.error !== null ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__preview-note", children: preview.error }) : null,
5137
5345
  microphone && micStream !== null ? /* @__PURE__ */ jsx6("div", { className: "mx-meet__meter mx-meet__meter--preview", role: "meter", "aria-label": "Microphone level", "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": Math.round(level * 100), children: /* @__PURE__ */ jsx6("span", { style: { width: `${Math.min(100, Math.round(level * 160))}%` } }) }) : null
5138
5346
  ] }),
5139
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__prejoin-panel", children: [
5347
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__prejoin-panel", children: [
5140
5348
  /* @__PURE__ */ jsx6("h1", { className: "mx-meet__prejoin-title", children: "Ready to join?" }),
5349
+ /* @__PURE__ */ jsx6(PreviewStatus, { onRetry: () => setAttempt((n) => n + 1) }),
5141
5350
  notice?.kind === "removed" ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__warning", children: notice.text }) : null,
5142
- devices?.labelsHidden === true ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
5351
+ devices?.labelsHidden === true ? /* @__PURE__ */ jsxs4("p", { className: "mx-meet__panel-note", children: [
5143
5352
  "Your browser is hiding device names until you allow camera and microphone access.",
5144
5353
  /* @__PURE__ */ jsx6(
5145
5354
  "button",
@@ -5155,9 +5364,9 @@ function PreJoinBody({
5155
5364
  ] }) : null,
5156
5365
  devices?.fallbackNotice != null ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__warning", children: devices.fallbackNotice }) : null,
5157
5366
  /* @__PURE__ */ jsx6(DevicePicker, { kind: "audioinput", label: "Microphone" }),
5158
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__field-row", children: [
5367
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__field-row", children: [
5159
5368
  /* @__PURE__ */ jsx6(DevicePicker, { kind: "audiooutput", label: "Speaker" }),
5160
- /* @__PURE__ */ jsxs3(
5369
+ /* @__PURE__ */ jsxs4(
5161
5370
  Button,
5162
5371
  {
5163
5372
  type: "button",
@@ -5180,8 +5389,8 @@ function PreJoinBody({
5180
5389
  /* @__PURE__ */ jsx6(DevicePicker, { kind: "videoinput", label: "Camera" }),
5181
5390
  /* @__PURE__ */ jsx6(EffectsSettings, { preview: preview.preview }),
5182
5391
  recording.consentNotice !== null ? /* @__PURE__ */ jsx6(Alert, { variant: "info", children: /* @__PURE__ */ jsx6(AlertDescription, { children: recording.consentNotice }) }) : null,
5183
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__prejoin-actions", children: [
5184
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__check", children: [
5392
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__prejoin-actions", children: [
5393
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__check", children: [
5185
5394
  /* @__PURE__ */ jsx6(
5186
5395
  Checkbox,
5187
5396
  {
@@ -5192,7 +5401,7 @@ function PreJoinBody({
5192
5401
  ),
5193
5402
  /* @__PURE__ */ jsx6(Label, { htmlFor: "mx-meet-join-video", children: "Join with video" })
5194
5403
  ] }),
5195
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__check", children: [
5404
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__check", children: [
5196
5405
  /* @__PURE__ */ jsx6(
5197
5406
  Checkbox,
5198
5407
  {
@@ -5206,7 +5415,7 @@ function PreJoinBody({
5206
5415
  room.secondDevice === null ? /* @__PURE__ */ jsx6(Button, { type: "button", className: "mx-meet__join", disabled: joining, onClick: () => joinWith(), children: joining ? "Joining\u2026" : observe2 ? "Observe" : "Join now" }) : (
5207
5416
  // S7: ALREADY IN THIS MEETING on another tab or device — the meeting's choice
5208
5417
  // (Meet: Switch here / Join here too; Teams: Transfer here / Add this device).
5209
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__second-device", "data-meet-region": "second-device", children: [
5418
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__second-device", "data-meet-region": "second-device", children: [
5210
5419
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__hint", children: "You're in this meeting on another device" }),
5211
5420
  /* @__PURE__ */ jsx6(
5212
5421
  Button,
@@ -5233,23 +5442,29 @@ function PreJoinBody({
5233
5442
  ] })
5234
5443
  )
5235
5444
  ] }),
5236
- room.failure !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__error", children: [
5445
+ room.failure !== null ? /* @__PURE__ */ jsxs4("p", { className: "mx-meet__error", children: [
5237
5446
  room.failure.message,
5238
5447
  /* @__PURE__ */ jsx6("span", { className: "mx-meet__remedy", children: room.failure.remedy })
5239
5448
  ] }) : null
5240
5449
  ] })
5241
5450
  ] });
5242
5451
  }
5243
- function useCameraPreview(deviceId, effects) {
5244
- const [preview, setPreview] = useState4(null);
5245
- const [error, setError] = useState4(null);
5452
+ function useCameraPreview(deviceId, effects, report, attempt = 0) {
5453
+ const reportRef = useRef6(report);
5454
+ reportRef.current = report;
5455
+ const [preview, setPreview] = useState5(null);
5456
+ const [error, setError] = useState5(null);
5246
5457
  const current = useRef6(null);
5247
5458
  const initialEffect = useRef6(toVideoEffect(effects));
5248
5459
  initialEffect.current = toVideoEffect(effects);
5249
5460
  useEffect6(() => {
5250
- if (deviceId === void 0) return void 0;
5461
+ if (deviceId === void 0) {
5462
+ reportRef.current?.("off");
5463
+ return void 0;
5464
+ }
5251
5465
  let live = true;
5252
5466
  setError(null);
5467
+ reportRef.current?.("prompting");
5253
5468
  void createCameraPreview(deviceId, initialEffect.current).then((created) => {
5254
5469
  if (!live) {
5255
5470
  created.stop();
@@ -5257,8 +5472,10 @@ function useCameraPreview(deviceId, effects) {
5257
5472
  }
5258
5473
  current.current = created;
5259
5474
  setPreview(created);
5475
+ reportRef.current?.("on");
5260
5476
  }).catch((thrown) => {
5261
5477
  if (!live) return;
5478
+ reportRef.current?.({ error: thrown });
5262
5479
  const failure = thrown;
5263
5480
  const message = (failure.message ?? "").replace(/^meet\.[A-Za-z.()]+:\s*/, "");
5264
5481
  const sentence = message.length > 0 ? message.charAt(0).toUpperCase() + message.slice(1) : "";
@@ -5270,7 +5487,7 @@ function useCameraPreview(deviceId, effects) {
5270
5487
  current.current = null;
5271
5488
  setPreview(null);
5272
5489
  };
5273
- }, [deviceId]);
5490
+ }, [deviceId, attempt]);
5274
5491
  return {
5275
5492
  preview,
5276
5493
  error,
@@ -5293,9 +5510,9 @@ function DevicePicker({
5293
5510
  const triggerId = `mx-meet-device-${kind}`;
5294
5511
  const valueOf = (deviceId) => deviceId.length > 0 ? deviceId : "default";
5295
5512
  const current = devices?.selected[kind] ?? host.devices.resolve(kind) ?? "";
5296
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__field", children: [
5513
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__field", children: [
5297
5514
  /* @__PURE__ */ jsx6(Label, { htmlFor: triggerId, children: label }),
5298
- /* @__PURE__ */ jsxs3(
5515
+ /* @__PURE__ */ jsxs4(
5299
5516
  Select,
5300
5517
  {
5301
5518
  ...current.length > 0 ? { value: valueOf(current) } : {},
@@ -5382,19 +5599,19 @@ function MeetSkinRoom({
5382
5599
  if (screen === "refused" || screen === "exit") {
5383
5600
  return /* @__PURE__ */ jsx6("div", { className: "mx-meet mx-meet--lobby", children: /* @__PURE__ */ jsx6(ExitScreen, { ...onLeave !== void 0 ? { onLeave } : {} }) });
5384
5601
  }
5385
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet", children: [
5602
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet", children: [
5386
5603
  /* @__PURE__ */ jsx6(ConsentNotice, {}),
5387
5604
  /* @__PURE__ */ jsx6(AttendanceNotice, {}),
5388
- /* @__PURE__ */ jsxs3("header", { className: "mx-meet__header", children: [
5605
+ /* @__PURE__ */ jsxs4("header", { className: "mx-meet__header", children: [
5389
5606
  /* @__PURE__ */ jsx6("h1", { className: "mx-meet__title", children: snapshot?.meeting?.title ?? "Meeting" }),
5390
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__meta", children: [
5607
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__meta", children: [
5391
5608
  participantSummary(snapshot?.participants ?? []),
5392
5609
  elapsed > 0 ? ` \xB7 ${formatDurationMs2(elapsed)}` : ""
5393
5610
  ] }),
5394
5611
  /* @__PURE__ */ jsx6(RecordingIndicator, {}),
5395
5612
  captureHeldOf(snapshot?.meeting) ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__badge", "data-meet-capture-held": "", children: "Confidential \xB7 not recorded" }) : null,
5396
5613
  isObserverRole(snapshot?.grants.role) ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__badge", "data-meet-observing": "self", children: "Observing" }) : null,
5397
- snapshot?.locked === true ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__badge", children: [
5614
+ snapshot?.locked === true ? /* @__PURE__ */ jsxs4("span", { className: "mx-meet__badge", children: [
5398
5615
  /* @__PURE__ */ jsx6(LockIcon, { width: 12, height: 12 }),
5399
5616
  " Locked"
5400
5617
  ] }) : null,
@@ -5410,9 +5627,17 @@ function MeetSkinRoom({
5410
5627
  }
5411
5628
  function ShareNotice() {
5412
5629
  const { share, actions } = useMeetCore();
5630
+ const [soundHintClosed, setSoundHintClosed] = useState5(null);
5631
+ if (share.state === "presenting" && share.audio === false && soundHintClosed !== share.at) {
5632
+ return /* @__PURE__ */ jsxs4("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "share-audio-missing", children: [
5633
+ "Sound not shared",
5634
+ /* @__PURE__ */ jsx6("span", { className: "mx-meet__remedy", children: "To include sound, share a tab and turn on Also share tab audio" }),
5635
+ /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__link", onClick: () => setSoundHintClosed(share.at), children: "Dismiss" })
5636
+ ] });
5637
+ }
5413
5638
  if (share.state !== "refused") return null;
5414
5639
  const text = share.reason === "unsupported" ? "You can't share your screen from this browser" : share.reason === "blocked" ? "Screen sharing is blocked" : "Couldn't start sharing your screen";
5415
- return /* @__PURE__ */ jsxs3("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "share-unavailable", children: [
5640
+ return /* @__PURE__ */ jsxs4("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "share-unavailable", children: [
5416
5641
  text,
5417
5642
  share.remedy !== null ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__remedy", children: share.remedy }) : null,
5418
5643
  /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__link", onClick: actions.dismissShareNotice, children: "Dismiss" })
@@ -5440,7 +5665,7 @@ function clockText(ms) {
5440
5665
  }
5441
5666
  function ExitScreen({ onLeave }) {
5442
5667
  const { phase, reason, host, snapshot, actions, call, connection } = useMeetCore();
5443
- const [busy, setBusy] = useState4(false);
5668
+ const [busy, setBusy] = useState5(false);
5444
5669
  const failure = snapshot?.failure ?? null;
5445
5670
  const retryLeft = useCountdown(phase === "refused:lobby_rejects" ? failure?.retryAt ?? null : null);
5446
5671
  const rejoin = /* @__PURE__ */ jsx6(
@@ -5481,7 +5706,7 @@ function ExitScreen({ onLeave }) {
5481
5706
  const code = phase.slice("refused:".length);
5482
5707
  title = REFUSED_TITLES[code] ?? "You can't join this meeting";
5483
5708
  line = code === "too_early" || code === "registration_required" || code === "cancelled" ? failure?.remedy ?? null : null;
5484
- actionsNode = /* @__PURE__ */ jsxs3(Fragment, { children: [
5709
+ actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
5485
5710
  /* @__PURE__ */ jsx6(Button, { type: "button", variant: "outline", onClick: actions.retry, children: "Try again" }),
5486
5711
  home
5487
5712
  ] });
@@ -5492,7 +5717,7 @@ function ExitScreen({ onLeave }) {
5492
5717
  actionsNode = home;
5493
5718
  } else if (retryLeft === 0) {
5494
5719
  line = "You can ask to join again";
5495
- actionsNode = /* @__PURE__ */ jsxs3(Fragment, { children: [
5720
+ actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
5496
5721
  /* @__PURE__ */ jsx6(
5497
5722
  Button,
5498
5723
  {
@@ -5516,16 +5741,37 @@ function ExitScreen({ onLeave }) {
5516
5741
  switch (phase) {
5517
5742
  case "left":
5518
5743
  title = "You left the meeting";
5519
- actionsNode = /* @__PURE__ */ jsxs3(Fragment, { children: [
5744
+ actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
5520
5745
  rejoin,
5521
5746
  home
5522
5747
  ] });
5523
5748
  break;
5524
5749
  case "disconnected":
5750
+ if (failure?.stage === "join" && (failure.reason ?? null) === null) {
5751
+ title = "Can't connect to the meeting";
5752
+ line = connection === "offline" ? "You're offline. Check your internet connection." : "Check your network. A VPN, firewall or proxy may be blocking the call.";
5753
+ notice = "cannot-connect";
5754
+ actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
5755
+ /* @__PURE__ */ jsx6(
5756
+ Button,
5757
+ {
5758
+ type: "button",
5759
+ disabled: busy,
5760
+ onClick: () => {
5761
+ setBusy(true);
5762
+ void actions.rejoin().catch(() => void 0).finally(() => setBusy(false));
5763
+ },
5764
+ children: "Try again"
5765
+ }
5766
+ ),
5767
+ home
5768
+ ] });
5769
+ break;
5770
+ }
5525
5771
  title = "You lost your connection to the meeting";
5526
5772
  line = connection === "offline" ? "You're offline. You'll rejoin automatically when your internet is back." : connection === "server_unreachable" ? "Can't reach the meeting server. You'll rejoin automatically when it answers." : failure?.remedy ?? "Check your internet connection, then rejoin.";
5527
5773
  notice = "disconnected";
5528
- actionsNode = /* @__PURE__ */ jsxs3(Fragment, { children: [
5774
+ actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
5529
5775
  rejoin,
5530
5776
  home
5531
5777
  ] });
@@ -5538,14 +5784,14 @@ function ExitScreen({ onLeave }) {
5538
5784
  title = "You joined from another tab or device";
5539
5785
  line = "This screen left the meeting so you aren't in it twice.";
5540
5786
  notice = "displaced";
5541
- actionsNode = /* @__PURE__ */ jsxs3(Fragment, { children: [
5787
+ actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
5542
5788
  rejoin,
5543
5789
  home
5544
5790
  ] });
5545
5791
  break;
5546
5792
  case "inactive":
5547
5793
  title = "You left the meeting because this tab was inactive";
5548
- actionsNode = /* @__PURE__ */ jsxs3(Fragment, { children: [
5794
+ actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
5549
5795
  rejoin,
5550
5796
  home
5551
5797
  ] });
@@ -5568,7 +5814,7 @@ function ExitScreen({ onLeave }) {
5568
5814
  break;
5569
5815
  }
5570
5816
  }
5571
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__waiting", "data-meet-exit": phase, children: [
5817
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__waiting", "data-meet-exit": phase, children: [
5572
5818
  /* @__PURE__ */ jsx6(Avatar, { name: host?.identity.displayName ?? "", url: host?.identity.avatarUrl ?? null, size: 72 }),
5573
5819
  /* @__PURE__ */ jsx6("h1", { className: "mx-meet__prejoin-title", children: title }),
5574
5820
  line !== null ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__empty-body", children: line }) : null,
@@ -5579,7 +5825,7 @@ function ExitScreen({ onLeave }) {
5579
5825
  function WaitingRoom({ host, onLeave }) {
5580
5826
  const { waiting, withdraw, askAgain } = useWaiting();
5581
5827
  const { phaseNotice } = useMeetCore();
5582
- const [busy, setBusy] = useState4(false);
5828
+ const [busy, setBusy] = useState5(false);
5583
5829
  const admission = waiting?.admission ?? "knocking";
5584
5830
  const reknockLeft = useCountdown(admission === "denied" ? waiting?.reknockAt ?? null : null);
5585
5831
  const run = (action) => () => {
@@ -5602,21 +5848,21 @@ function WaitingRoom({ host, onLeave }) {
5602
5848
  line = `You can ask again in ${clockText(reknockLeft)}`;
5603
5849
  cooldownNotice = true;
5604
5850
  }
5605
- actions = /* @__PURE__ */ jsxs3(Fragment, { children: [
5851
+ actions = /* @__PURE__ */ jsxs4(Fragment, { children: [
5606
5852
  waiting?.reknockAllowed === true || waiting?.reknockAt != null && reknockLeft === 0 ? /* @__PURE__ */ jsx6(Button, { type: "button", disabled: busy, onClick: run(askAgain), children: "Ask to join again" }) : null,
5607
5853
  home
5608
5854
  ] });
5609
5855
  break;
5610
5856
  case "expired":
5611
5857
  title = "No one responded";
5612
- actions = /* @__PURE__ */ jsxs3(Fragment, { children: [
5858
+ actions = /* @__PURE__ */ jsxs4(Fragment, { children: [
5613
5859
  /* @__PURE__ */ jsx6(Button, { type: "button", disabled: busy, onClick: run(askAgain), children: "Ask again" }),
5614
5860
  home
5615
5861
  ] });
5616
5862
  break;
5617
5863
  case "withdrawn":
5618
5864
  title = "You left the waiting room";
5619
- actions = /* @__PURE__ */ jsxs3(Fragment, { children: [
5865
+ actions = /* @__PURE__ */ jsxs4(Fragment, { children: [
5620
5866
  /* @__PURE__ */ jsx6(Button, { type: "button", disabled: busy, onClick: run(askAgain), children: "Rejoin" }),
5621
5867
  home
5622
5868
  ] });
@@ -5630,7 +5876,7 @@ function WaitingRoom({ host, onLeave }) {
5630
5876
  line = waiting?.admittersPresent === false ? "The host isn't here yet" : null;
5631
5877
  actions = /* @__PURE__ */ jsx6(Button, { type: "button", variant: "outline", disabled: busy, onClick: run(withdraw), children: "Cancel request" });
5632
5878
  }
5633
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__waiting", children: [
5879
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__waiting", children: [
5634
5880
  /* @__PURE__ */ jsx6(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 72 }),
5635
5881
  /* @__PURE__ */ jsx6("h1", { className: "mx-meet__prejoin-title", children: title }),
5636
5882
  phaseNotice === "sent-to-waiting" ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__empty-body", role: "status", "data-meet-notice": "sent-to-waiting", children: "The host moved you back to the waiting room" }) : null,
@@ -5650,9 +5896,9 @@ function HostMenu() {
5650
5896
  const host = useRequiredMeetHost();
5651
5897
  const snapshot = useMeetSnapshot();
5652
5898
  const end = useEndMeeting();
5653
- const [confirmingEnd, setConfirmingEnd] = useState4(false);
5899
+ const [confirmingEnd, setConfirmingEnd] = useState5(false);
5654
5900
  const locked = snapshot?.locked === true;
5655
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__host-menu", children: [
5901
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__host-menu", children: [
5656
5902
  /* @__PURE__ */ jsx6(
5657
5903
  "button",
5658
5904
  {
@@ -5664,7 +5910,7 @@ function HostMenu() {
5664
5910
  children: locked ? "Unlock meeting" : "Lock meeting"
5665
5911
  }
5666
5912
  ),
5667
- end.canEnd ? confirmingEnd ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__confirm", role: "group", "aria-label": "End this meeting?", children: [
5913
+ end.canEnd ? confirmingEnd ? /* @__PURE__ */ jsxs4("span", { className: "mx-meet__confirm", role: "group", "aria-label": "End this meeting?", children: [
5668
5914
  /* @__PURE__ */ jsx6("span", { className: "mx-meet__confirm-text", children: "End it for everyone? Every participant is disconnected, the note-taker stops, and the wrap-up is written. Nobody can rejoin this meeting afterwards." }),
5669
5915
  /* @__PURE__ */ jsx6(
5670
5916
  "button",
@@ -5720,9 +5966,9 @@ function GuestRecordAccessControl({
5720
5966
  const isHost = inRoomHost || viewerId !== null && meeting.hostUserId === viewerId;
5721
5967
  if (host === null || !isHost) return null;
5722
5968
  const resolved = access.setting === "default" && access.effective !== null ? ` Right now that means: ${guestRecordAccessLabel(access.effective.level).toLowerCase()}.` : "";
5723
- return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "What guests may read", children: [
5969
+ return /* @__PURE__ */ jsxs4("section", { className: "mx-meet__record-section", "aria-label": "What guests may read", children: [
5724
5970
  /* @__PURE__ */ jsx6("h2", { className: "mx-meet__record-section-title", children: "What guests may read" }),
5725
- /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
5971
+ /* @__PURE__ */ jsxs4("label", { className: "mx-meet__field", children: [
5726
5972
  /* @__PURE__ */ jsx6("span", { className: "mx-meet__field-label", children: "People who attended by link, without an account" }),
5727
5973
  /* @__PURE__ */ jsx6(
5728
5974
  "select",
@@ -5739,12 +5985,12 @@ function GuestRecordAccessControl({
5739
5985
  }
5740
5986
  )
5741
5987
  ] }),
5742
- /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
5988
+ /* @__PURE__ */ jsxs4("p", { className: "mx-meet__panel-note", children: [
5743
5989
  guestRecordAccessExplanation(access.setting),
5744
5990
  resolved
5745
5991
  ] }),
5746
5992
  access.saving ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", role: "status", children: "Saving what guests may read\u2026" }) : null,
5747
- access.error !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: access.error, operation: "Change who can join", origin: "meet/components", children: [
5993
+ access.error !== null ? /* @__PURE__ */ jsxs4(ErrorBox, { as: "div", className: "mx-meet__refusal", error: access.error, operation: "Change who can join", origin: "meet/components", children: [
5748
5994
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-reason", children: access.error.message }),
5749
5995
  /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-remedy", children: access.error.remedy })
5750
5996
  ] }) : null
@@ -5767,6 +6013,7 @@ export {
5767
6013
  ChatIcon,
5768
6014
  ChatPanel,
5769
6015
  CheckIcon,
6016
+ ChevronUpIcon,
5770
6017
  CloseIcon,
5771
6018
  ConnectionDot,
5772
6019
  ConsentNotice,