@ai-matrx/meet 0.7.10 → 0.7.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.cjs CHANGED
@@ -33,15 +33,22 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
33
33
  var react_exports = {};
34
34
  __export(react_exports, {
35
35
  ATTENDANCE_CSV_HEADER: () => ATTENDANCE_CSV_HEADER,
36
+ ActivitiesControl: () => ActivitiesControl,
37
+ ActivitiesIcon: () => ActivitiesIcon,
36
38
  AiPanel: () => AiPanel,
37
39
  AttendanceNotice: () => AttendanceNotice,
38
40
  Avatar: () => Avatar,
41
+ BreakoutBanner: () => BreakoutBanner,
42
+ BreakoutIcon: () => BreakoutIcon,
43
+ BreakoutsPanel: () => BreakoutsPanel,
39
44
  CALL_INVITE_KIND: () => CALL_INVITE_KIND,
40
45
  CALL_INVITE_VERSION: () => CALL_INVITE_VERSION,
46
+ CAPTION_LANGUAGES: () => CAPTION_LANGUAGES,
41
47
  CONSENT_NOTICE_ATTRIBUTE: () => CONSENT_NOTICE_ATTRIBUTE,
42
48
  CallButton: () => CallButton,
43
49
  CameraIcon: () => CameraIcon,
44
50
  CameraOffIcon: () => CameraOffIcon,
51
+ CaptionLanguageSettings: () => CaptionLanguageSettings,
45
52
  Captions: () => Captions,
46
53
  ChatIcon: () => ChatIcon,
47
54
  ChatPanel: () => ChatPanel,
@@ -54,6 +61,7 @@ __export(react_exports, {
54
61
  DATA_TOPICS: () => DATA_TOPICS,
55
62
  DEFAULT_EFFECTS: () => DEFAULT_EFFECTS,
56
63
  DEFAULT_PAGE_SIZE: () => DEFAULT_PAGE_SIZE,
64
+ EMPTY_COLLAB: () => EMPTY_COLLAB,
57
65
  END_MEETING_NOT_SERVED: () => END_MEETING_NOT_SERVED,
58
66
  FILE_SESSION_PATH: () => FILE_SESSION_PATH,
59
67
  FlagIcon: () => FlagIcon,
@@ -106,8 +114,12 @@ __export(react_exports, {
106
114
  PhoneIcon: () => PhoneIcon,
107
115
  PhoneOffIcon: () => PhoneOffIcon,
108
116
  PinIcon: () => PinIcon,
117
+ PollIcon: () => PollIcon,
118
+ PollsPanel: () => PollsPanel,
109
119
  PreJoin: () => PreJoin,
120
+ QaPanel: () => QaPanel,
110
121
  QualityBars: () => QualityBars,
122
+ QuestionIcon: () => QuestionIcon,
111
123
  REACTION_TTL_MS: () => REACTION_TTL_MS,
112
124
  REFUSED_ABSENCE: () => REFUSED_ABSENCE,
113
125
  ROLE_RANK: () => ROLE_RANK,
@@ -134,10 +146,13 @@ __export(react_exports, {
134
146
  TABLES: () => TABLES,
135
147
  TRANSCRIPTION_ATTRIBUTES: () => TRANSCRIPTION_ATTRIBUTES,
136
148
  TRANSCRIPTION_TOPIC: () => TRANSCRIPTION_TOPIC,
149
+ WhiteboardIcon: () => WhiteboardIcon,
150
+ WhiteboardPanel: () => WhiteboardPanel,
137
151
  WifiLowIcon: () => WifiLowIcon,
138
152
  absenceSentence: () => absenceSentence,
139
153
  activeWrapUpSummary: () => activeWrapUpSummary,
140
154
  announceMeeting: () => announceMeeting,
155
+ applyCollabPacket: () => applyCollabPacket,
141
156
  applyRoomEvent: () => applyRoomEvent,
142
157
  asCallId: () => asCallId,
143
158
  asMeetingId: () => asMeetingId,
@@ -145,10 +160,13 @@ __export(react_exports, {
145
160
  asParticipantIdentity: () => asParticipantIdentity,
146
161
  asRoomName: () => asRoomName,
147
162
  asUserId: () => asUserId,
163
+ assignedRoom: () => assignedRoom,
148
164
  attendanceCsv: () => attendanceCsv,
149
165
  attendanceReport: () => attendanceReport,
150
166
  attendanceTotals: () => attendanceTotals,
151
167
  attendeeKey: () => attendeeKey,
168
+ autoAssign: () => autoAssign,
169
+ breakoutRemainingMs: () => breakoutRemainingMs,
152
170
  callInviteAction: () => callInviteAction,
153
171
  callInviteText: () => callInviteText,
154
172
  callStateLabel: () => callStateLabel,
@@ -158,6 +176,7 @@ __export(react_exports, {
158
176
  captionSegment: () => captionSegment,
159
177
  changesPatch: () => changesPatch,
160
178
  clockPosition: () => clockPosition,
179
+ collabFromState: () => collabFromState,
161
180
  computeStage: () => computeStage,
162
181
  countLabel: () => countLabel,
163
182
  createCallCenter: () => createCallCenter,
@@ -178,6 +197,7 @@ __export(react_exports, {
178
197
  createWebDeviceStorage: () => createWebDeviceStorage,
179
198
  createWebEffectsStorage: () => createWebEffectsStorage,
180
199
  createWebRoomTokenStorage: () => createWebRoomTokenStorage,
200
+ defaultCaptionLanguage: () => defaultCaptionLanguage,
181
201
  displayNameFor: () => displayNameFor,
182
202
  fileDownloadPath: () => fileDownloadPath,
183
203
  gridColumns: () => gridColumns,
@@ -200,6 +220,7 @@ __export(react_exports, {
200
220
  listenOnlyNotice: () => listenOnlyNotice,
201
221
  loadFollowUpDraft: () => loadFollowUpDraft,
202
222
  loadGuestMeetingRecord: () => loadGuestMeetingRecord,
223
+ loadMeetingActivities: () => loadMeetingActivities,
203
224
  loadMeetingChat: () => loadMeetingChat,
204
225
  loadMeetingRecord: () => loadMeetingRecord,
205
226
  mapConnectionState: () => mapConnectionState,
@@ -254,9 +275,13 @@ __export(react_exports, {
254
275
  unavailableFrom: () => unavailableFrom,
255
276
  uniqueAttendees: () => uniqueAttendees,
256
277
  useAudioLevel: () => useAudioLevel,
278
+ useAvailableActivities: () => useAvailableActivities,
257
279
  useCalls: () => useCalls,
258
280
  useCanModerate: () => useCanModerate,
259
281
  useCanRecord: () => useCanRecord,
282
+ useCaptionTranslation: () => useCaptionTranslation,
283
+ useCollab: () => useCollab,
284
+ useCollabPanelRequest: () => useCollabPanelRequest,
260
285
  useConsentNotice: () => useConsentNotice,
261
286
  useDeviceSnapshot: () => useDeviceSnapshot,
262
287
  useElapsed: () => useElapsed,
@@ -288,6 +313,7 @@ __export(react_exports, {
288
313
  useTrack: () => useTrack,
289
314
  userTopic: () => userTopic,
290
315
  wasRefused: () => wasRefused,
316
+ withItem: () => withItem,
291
317
  wrapUpStatus: () => wrapUpStatus
292
318
  });
293
319
  module.exports = __toCommonJS(react_exports);
@@ -519,7 +545,14 @@ var MEET_ROUTES = {
519
545
  */
520
546
  moderate: "/api/v1/meet/moderate",
521
547
  /** Meet wave 2: the SAVED chat — `POST` sends to everyone, `GET ?meeting_id=` reads history. */
522
- chat: "/api/v1/meet/chat"
548
+ chat: "/api/v1/meet/chat",
549
+ /**
550
+ * Meet wave 5: polls, Q&A, the shared whiteboard and breakout rooms. `POST` acts
551
+ * (`{meeting_id, action, …}`), `GET ?meeting_id=` reads what this viewer may see.
552
+ */
553
+ collab: "/api/v1/meet/collab",
554
+ /** Meet wave 5: translate finished caption lines into this viewer's language. */
555
+ captionsTranslate: "/api/v1/meet/captions/translate"
523
556
  };
524
557
  function meetingPath(template, meetingId) {
525
558
  return template.replace("{meeting_id}", encodeURIComponent(meetingId));
@@ -578,7 +611,8 @@ function parseRoomToken(body, roomName) {
578
611
  // server that has not landed MRI-A11 — and never invents a host from
579
612
  // silence, because both fallbacks below grant nothing.
580
613
  role: readRole(payload, "role") ?? (isHost ? "host" : identity.startsWith("guest:") ? "guest" : "participant"),
581
- lobby: readBoolean(payload, "lobby", false)
614
+ lobby: readBoolean(payload, "lobby", false),
615
+ breakoutRoomId: readString(payload, "breakout_room_id") ?? null
582
616
  };
583
617
  }
584
618
  function createTokenClient(options) {
@@ -626,6 +660,7 @@ function createTokenClient(options) {
626
660
  room_name: input.roomName,
627
661
  ...input.meetingId !== void 0 ? { meeting_id: input.meetingId } : {},
628
662
  ...input.slug !== void 0 ? { slug: input.slug } : {},
663
+ ...input.breakoutRoomId != null ? { breakout_room_id: input.breakoutRoomId } : {},
629
664
  organization_id: input.identity.organizationId,
630
665
  display_name: input.identity.displayName,
631
666
  device_id: input.identity.deviceId,
@@ -689,7 +724,8 @@ function createTokenClient(options) {
689
724
  return {
690
725
  get(input) {
691
726
  const entry = cache.get(input.roomName);
692
- if (entry !== void 0) {
727
+ const sameRoom = entry !== void 0 && (entry.token.breakoutRoomId ?? null) === (input.breakoutRoomId ?? null);
728
+ if (entry !== void 0 && sameRoom) {
693
729
  if (entry.inFlight !== null) return entry.inFlight;
694
730
  if (!expired(entry)) return Promise.resolve(entry.token);
695
731
  }
@@ -735,7 +771,8 @@ function placeholder(roomName) {
735
771
  canRecord: false,
736
772
  isHost: false,
737
773
  role: "participant",
738
- lobby: false
774
+ lobby: false,
775
+ breakoutRoomId: null
739
776
  };
740
777
  }
741
778
  async function serverSentence(response) {
@@ -1793,6 +1830,339 @@ function listenOnlyNotice(media) {
1793
1830
  return isListenOnly(media) ? LISTEN_ONLY_NOTICE : null;
1794
1831
  }
1795
1832
 
1833
+ // src/core/collab.ts
1834
+ var EMPTY_COLLAB = {
1835
+ loaded: false,
1836
+ error: null,
1837
+ settings: null,
1838
+ polls: [],
1839
+ questions: [],
1840
+ strokes: [],
1841
+ breakout: null,
1842
+ broadcast: null,
1843
+ moveRequest: null,
1844
+ panelRequest: null,
1845
+ captionLanguage: null,
1846
+ captionTranslations: {},
1847
+ captionTranslationError: null
1848
+ };
1849
+ function obj(value) {
1850
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
1851
+ }
1852
+ function str(value) {
1853
+ return typeof value === "string" ? value : null;
1854
+ }
1855
+ function num(value) {
1856
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
1857
+ }
1858
+ function strings(value) {
1859
+ return Array.isArray(value) ? value.filter((v) => typeof v === "string") : [];
1860
+ }
1861
+ function pollFromRow(row) {
1862
+ const id = str(row["id"]);
1863
+ if (id === null) return null;
1864
+ const options = [];
1865
+ for (const raw of Array.isArray(row["options"]) ? row["options"] : []) {
1866
+ const option = obj(raw);
1867
+ const optionId = option === null ? null : str(option["id"]);
1868
+ if (option === null || optionId === null) continue;
1869
+ const votes = num(option["votes"]);
1870
+ options.push({
1871
+ id: optionId,
1872
+ text: str(option["text"]) ?? "",
1873
+ ...votes !== null ? { votes } : {},
1874
+ ...Array.isArray(option["voters"]) ? { voters: strings(option["voters"]) } : {}
1875
+ });
1876
+ }
1877
+ const state = str(row["state"]);
1878
+ return {
1879
+ id,
1880
+ question: str(row["question"]) ?? "",
1881
+ options,
1882
+ multiple: row["multiple"] === true,
1883
+ anonymous: row["anonymous"] === true,
1884
+ state: state === "live" || state === "closed" ? state : "draft",
1885
+ resultsShared: row["results_shared"] === true,
1886
+ voterCount: num(row["voter_count"]),
1887
+ myVote: strings(row["my_vote"]),
1888
+ createdByName: str(row["created_by_name"]) ?? "",
1889
+ createdAt: str(row["created_at"])
1890
+ };
1891
+ }
1892
+ function questionFromRow(row) {
1893
+ const id = str(row["id"]);
1894
+ if (id === null) return null;
1895
+ const state = str(row["state"]);
1896
+ return {
1897
+ id,
1898
+ text: str(row["text"]) ?? "",
1899
+ askerName: str(row["asker_name"]) ?? "",
1900
+ anonymous: row["anonymous"] === true,
1901
+ state: state === "answered" || state === "dismissed" ? state : "open",
1902
+ answer: str(row["answer"]),
1903
+ answeredByName: str(row["answered_by_name"]),
1904
+ upvotes: num(row["upvotes"]) ?? 0,
1905
+ upvotedByMe: row["upvoted_by_me"] === true,
1906
+ mine: row["mine"] === true,
1907
+ createdAt: str(row["created_at"])
1908
+ };
1909
+ }
1910
+ function strokeFromRow(row) {
1911
+ const id = str(row["id"]);
1912
+ if (id === null || !Array.isArray(row["points"])) return null;
1913
+ const points = [];
1914
+ for (const raw of row["points"]) {
1915
+ if (Array.isArray(raw) && typeof raw[0] === "number" && typeof raw[1] === "number") {
1916
+ points.push([raw[0], raw[1]]);
1917
+ }
1918
+ }
1919
+ return {
1920
+ id,
1921
+ points,
1922
+ color: str(row["color"]) ?? "#111827",
1923
+ width: num(row["width"]) ?? 3,
1924
+ tool: row["tool"] === "highlighter" ? "highlighter" : "pen",
1925
+ by: str(row["by"]) ?? "",
1926
+ byName: str(row["by_name"]) ?? ""
1927
+ };
1928
+ }
1929
+ function broadcastFrom(value) {
1930
+ const row = obj(value);
1931
+ const text3 = row === null ? null : str(row["text"]);
1932
+ if (row === null || text3 === null) return null;
1933
+ return { text: text3, by: str(row["by"]) ?? "", at: str(row["at"]) ?? "" };
1934
+ }
1935
+ function planFromRow(row) {
1936
+ const id = str(row["id"]);
1937
+ if (id === null) return null;
1938
+ const rooms = [];
1939
+ for (const raw of Array.isArray(row["rooms"]) ? row["rooms"] : []) {
1940
+ const room = obj(raw);
1941
+ const roomId = room === null ? null : str(room["id"]);
1942
+ if (room === null || roomId === null) continue;
1943
+ rooms.push({ id: roomId, name: str(room["name"]) ?? roomId, identities: strings(room["identities"]) });
1944
+ }
1945
+ return {
1946
+ id,
1947
+ state: row["state"] === "open" ? "open" : "closed",
1948
+ rooms,
1949
+ allowChoose: row["allow_choose"] === true,
1950
+ minutes: num(row["minutes"]) ?? 0,
1951
+ openedAt: str(row["opened_at"]),
1952
+ endsAt: str(row["ends_at"]),
1953
+ closedAt: str(row["closed_at"]),
1954
+ broadcasts: (Array.isArray(row["broadcasts"]) ? row["broadcasts"] : []).map(broadcastFrom).filter((b) => b !== null)
1955
+ };
1956
+ }
1957
+ function settingsFromRow(row) {
1958
+ if (row === null) return null;
1959
+ return {
1960
+ pollsEnabled: row["polls_enabled"] === true,
1961
+ pollMaxOptions: num(row["poll_max_options"]) ?? 10,
1962
+ qaEnabled: row["qa_enabled"] === true,
1963
+ qaAnonymousAllowed: row["qa_anonymous_allowed"] === true,
1964
+ whiteboardEnabled: row["whiteboard_enabled"] === true,
1965
+ breakoutsEnabled: row["breakouts_enabled"] === true,
1966
+ breakoutMaxRooms: num(row["breakout_max_rooms"]) ?? 20,
1967
+ breakoutDefaultMinutes: num(row["breakout_default_minutes"]) ?? 15,
1968
+ captionTranslationEnabled: row["caption_translation_enabled"] === true,
1969
+ captionTranslationLanguage: str(row["caption_translation_language"]) ?? ""
1970
+ };
1971
+ }
1972
+ function collabFromState(body, previous) {
1973
+ const list = (key, parse) => (Array.isArray(body[key]) ? body[key] : []).map((raw) => {
1974
+ const row = obj(raw);
1975
+ return row === null ? null : parse(row);
1976
+ }).filter((item) => item !== null);
1977
+ const breakoutRow = obj(body["breakout"]);
1978
+ return {
1979
+ ...previous,
1980
+ loaded: true,
1981
+ error: null,
1982
+ settings: settingsFromRow(obj(body["settings"])),
1983
+ polls: list("polls", pollFromRow),
1984
+ questions: list("questions", questionFromRow),
1985
+ strokes: list("strokes", strokeFromRow),
1986
+ breakout: breakoutRow === null ? null : planFromRow(breakoutRow)
1987
+ };
1988
+ }
1989
+ function upsert(items, next) {
1990
+ const index = items.findIndex((item) => item.id === next.id);
1991
+ if (index === -1) return [...items, next];
1992
+ const copy = items.slice();
1993
+ copy[index] = next;
1994
+ return copy;
1995
+ }
1996
+ function withItem(collab, row, fromRoom = false) {
1997
+ const kind = str(row["kind"]);
1998
+ if (kind === "poll") {
1999
+ const poll = pollFromRow(row);
2000
+ if (poll === null) return collab;
2001
+ const known = collab.polls.find((p) => p.id === poll.id);
2002
+ const merged = fromRoom && known !== void 0 ? { ...poll, myVote: known.myVote } : poll;
2003
+ return { ...collab, polls: upsert(collab.polls, merged) };
2004
+ }
2005
+ if (kind === "question") {
2006
+ const question = questionFromRow(row);
2007
+ if (question === null) return collab;
2008
+ const known = collab.questions.find((q) => q.id === question.id);
2009
+ const merged = fromRoom && known !== void 0 ? { ...question, mine: known.mine, upvotedByMe: known.upvotedByMe } : question;
2010
+ return { ...collab, questions: upsert(collab.questions, merged) };
2011
+ }
2012
+ if (kind === "stroke") {
2013
+ const stroke = strokeFromRow(row);
2014
+ if (stroke === null) return collab;
2015
+ return { ...collab, strokes: upsert(collab.strokes, stroke) };
2016
+ }
2017
+ if (kind === "breakout") {
2018
+ const plan = planFromRow(row);
2019
+ if (plan === null) return collab;
2020
+ return { ...collab, breakout: plan };
2021
+ }
2022
+ return collab;
2023
+ }
2024
+ function without(collab, ids) {
2025
+ const gone = new Set(ids);
2026
+ return {
2027
+ ...collab,
2028
+ polls: collab.polls.filter((p) => !gone.has(p.id)),
2029
+ questions: collab.questions.filter((q) => !gone.has(q.id)),
2030
+ strokes: collab.strokes.filter((s) => !gone.has(s.id))
2031
+ };
2032
+ }
2033
+ function applyCollabPacket(collab, payload, context) {
2034
+ const item = obj(payload["item"]);
2035
+ const audience = str(payload["audience"]);
2036
+ if (item !== null) {
2037
+ const kind = str(item["kind"]);
2038
+ const hostOnlyView = kind === "poll" || kind === "question";
2039
+ if (hostOnlyView && context.isHost && audience !== "hosts") {
2040
+ return { next: null, dropped: "the room copy of an item a host receives in full" };
2041
+ }
2042
+ let next = withItem(collab, item, true);
2043
+ if (kind === "poll" && str(item["state"]) === "live") {
2044
+ const before = collab.polls.find((p) => p.id === str(item["id"]));
2045
+ if (before === void 0 || before.state !== "live") {
2046
+ next = { ...next, panelRequest: { panel: "polls", at: context.now } };
2047
+ }
2048
+ }
2049
+ if (kind === "breakout") {
2050
+ const plan = planFromRow(item);
2051
+ if (plan !== null && plan.state === "closed") {
2052
+ next = { ...next, moveRequest: { roomId: null, at: context.now } };
2053
+ }
2054
+ }
2055
+ const move = obj(payload["move"]);
2056
+ if (move !== null && str(move["identity"]) === context.localIdentity) {
2057
+ next = { ...next, moveRequest: { roomId: str(move["room_id"]), at: context.now } };
2058
+ }
2059
+ return { next };
2060
+ }
2061
+ if (Array.isArray(payload["removed"])) {
2062
+ return { next: without(collab, strings(payload["removed"])) };
2063
+ }
2064
+ if (Array.isArray(payload["hidden"])) {
2065
+ return context.isHost ? { next: null, dropped: "hosts keep dismissed questions" } : { next: without(collab, strings(payload["hidden"])) };
2066
+ }
2067
+ if (payload["cleared"] === "whiteboard") {
2068
+ return { next: { ...collab, strokes: [] } };
2069
+ }
2070
+ const broadcast = broadcastFrom(payload["broadcast"]);
2071
+ if (broadcast !== null) {
2072
+ return { next: { ...collab, broadcast } };
2073
+ }
2074
+ return { next: null, dropped: "a collab packet with nothing this version understands" };
2075
+ }
2076
+ function assignedRoom(plan, identity) {
2077
+ if (plan === null || plan.state !== "open" || identity === null) return null;
2078
+ return plan.rooms.find((room) => room.identities.includes(identity)) ?? null;
2079
+ }
2080
+ function autoAssign(identities, rooms, exclude = []) {
2081
+ const count2 = Math.max(1, Math.floor(rooms));
2082
+ const out = Array.from({ length: count2 }, () => []);
2083
+ const skip = new Set(exclude);
2084
+ let index = 0;
2085
+ for (const identity of identities) {
2086
+ if (skip.has(identity)) continue;
2087
+ out[index % count2].push(identity);
2088
+ index += 1;
2089
+ }
2090
+ return out;
2091
+ }
2092
+ function breakoutRemainingMs(plan, now) {
2093
+ if (plan === null || plan.state !== "open" || plan.endsAt === null) return null;
2094
+ const end = Date.parse(plan.endsAt);
2095
+ return Number.isNaN(end) ? null : Math.max(0, end - now);
2096
+ }
2097
+ function defaultCaptionLanguage(settings, viewerLanguage) {
2098
+ const configured = settings?.captionTranslationLanguage.trim() ?? "";
2099
+ if (configured.length > 0) return configured;
2100
+ const own = (viewerLanguage ?? "").trim();
2101
+ return own.length > 0 ? own : "en";
2102
+ }
2103
+ var CAPTION_LANGUAGES = [
2104
+ { tag: "en", name: "English" },
2105
+ { tag: "es", name: "Spanish" },
2106
+ { tag: "fr", name: "French" },
2107
+ { tag: "de", name: "German" },
2108
+ { tag: "it", name: "Italian" },
2109
+ { tag: "pt", name: "Portuguese" },
2110
+ { tag: "nl", name: "Dutch" },
2111
+ { tag: "pl", name: "Polish" },
2112
+ { tag: "ru", name: "Russian" },
2113
+ { tag: "uk", name: "Ukrainian" },
2114
+ { tag: "tr", name: "Turkish" },
2115
+ { tag: "ar", name: "Arabic" },
2116
+ { tag: "he", name: "Hebrew" },
2117
+ { tag: "fa", name: "Persian" },
2118
+ { tag: "hi", name: "Hindi" },
2119
+ { tag: "bn", name: "Bengali" },
2120
+ { tag: "zh", name: "Chinese" },
2121
+ { tag: "ja", name: "Japanese" },
2122
+ { tag: "ko", name: "Korean" },
2123
+ { tag: "vi", name: "Vietnamese" },
2124
+ { tag: "th", name: "Thai" },
2125
+ { tag: "id", name: "Indonesian" },
2126
+ { tag: "sv", name: "Swedish" }
2127
+ ];
2128
+ async function loadMeetingActivities(api, meetingId, roomToken = null) {
2129
+ let response;
2130
+ try {
2131
+ response = await api.request({
2132
+ path: `${MEET_ROUTES.collab}?meeting_id=${encodeURIComponent(meetingId)}`,
2133
+ method: "GET",
2134
+ operation: "meet.loadMeetingActivities",
2135
+ requireAuth: roomToken === null,
2136
+ ...roomToken !== null ? { headers: { [ROOM_TOKEN_HEADER]: roomToken } } : {}
2137
+ });
2138
+ } catch (error) {
2139
+ return {
2140
+ collab: null,
2141
+ refusal: {
2142
+ message: `Polls, questions and the whiteboard could not be read (${error.message}).`,
2143
+ remedy: error.remedy ?? "Reload the page."
2144
+ }
2145
+ };
2146
+ }
2147
+ if (!response.ok) {
2148
+ let body = null;
2149
+ try {
2150
+ body = await response.json();
2151
+ } catch {
2152
+ body = null;
2153
+ }
2154
+ const said = readServerRefusal(body);
2155
+ return {
2156
+ collab: null,
2157
+ refusal: {
2158
+ message: said?.reason ?? `Polls and questions could not be read (the server answered ${response.status}).`,
2159
+ remedy: said?.remedy || "Reload the page."
2160
+ }
2161
+ };
2162
+ }
2163
+ return { collab: collabFromState(await response.json(), EMPTY_COLLAB), refusal: null };
2164
+ }
2165
+
1796
2166
  // src/core/transcript.ts
1797
2167
  function normalizeSpoken(text3) {
1798
2168
  return text3.toLowerCase().replace(/[^\p{L}\p{N}]+/gu, " ").trim();
@@ -1894,7 +2264,9 @@ var EMPTY = {
1894
2264
  wrapUp: null,
1895
2265
  noteTakerRefusal: null,
1896
2266
  media: IDLE_MEDIA,
1897
- failure: null
2267
+ failure: null,
2268
+ collab: EMPTY_COLLAB,
2269
+ breakoutRoomId: null
1898
2270
  };
1899
2271
  function effectiveRole(snapshot) {
1900
2272
  const me = snapshot.participants.find(
@@ -2545,7 +2917,19 @@ var INVITEE_COLUMNS = "id,meeting_id,invitee_user_id,email,display_name,role,rsv
2545
2917
  var RECORDING_COLUMNS = "id,meeting_id,state,started_at,ended_at,started_by,file_id,failure_reason";
2546
2918
  var SEGMENT_COLUMNS = "id,meeting_id,identity,speaker,text,started_at,is_final,metadata";
2547
2919
  var NOTE_COLUMNS = "id,meeting_id,text,kind,assignee_user_id,created_at,metadata";
2548
- var ATTENDEE_COLUMNS = "id,meeting_id,identity,participant_user_id,display_name,avatar_url,role,admission_state,is_agent,joined_at,left_at";
2920
+ var ATTENDEE_COLUMNS = "id,meeting_id,identity,participant_user_id,display_name,avatar_url,role,admission_state,is_agent,joined_at,left_at,sessions:metadata->sessions";
2921
+ function projectStays(value) {
2922
+ if (!Array.isArray(value)) return [];
2923
+ const stays = [];
2924
+ for (const item of value) {
2925
+ if (item === null || typeof item !== "object") continue;
2926
+ const joined = item["joined_at"];
2927
+ const left = item["left_at"];
2928
+ if (typeof joined !== "string" || joined.length === 0) continue;
2929
+ stays.push({ joinedAt: joined, leftAt: typeof left === "string" && left.length > 0 ? left : null });
2930
+ }
2931
+ return stays;
2932
+ }
2549
2933
  function text(row, key) {
2550
2934
  const value = row[key];
2551
2935
  return typeof value === "string" && value.length > 0 ? value : null;
@@ -2644,7 +3028,7 @@ var OCCURRENCE_STATES = ["scheduled", "moved", "cancelled"];
2644
3028
  function rsvpState(value) {
2645
3029
  return RSVP_STATES.includes(value) ? value : "needs_action";
2646
3030
  }
2647
- function num(row, key) {
3031
+ function num2(row, key) {
2648
3032
  const value = row[key];
2649
3033
  return typeof value === "number" ? value : null;
2650
3034
  }
@@ -2666,7 +3050,7 @@ function projectInvitee(row) {
2666
3050
  rsvpState: rsvpState(text(row, "rsvp_state")),
2667
3051
  respondedAt: when(row, "responded_at"),
2668
3052
  rsvpNote: text(row, "rsvp_note"),
2669
- lastSentSequence: num(row, "last_sent_sequence"),
3053
+ lastSentSequence: num2(row, "last_sent_sequence"),
2670
3054
  lastSentAt: when(row, "last_sent_at")
2671
3055
  };
2672
3056
  }
@@ -2677,10 +3061,10 @@ function projectOccurrence(row) {
2677
3061
  meetingId: asMeetingId(requireText(row, "meeting_id", operation)),
2678
3062
  originalStart: when(row, "original_start") ?? requireText(row, "original_start", operation),
2679
3063
  occurrenceStart: when(row, "occurrence_start") ?? requireText(row, "occurrence_start", operation),
2680
- durationMinutes: num(row, "duration_minutes"),
3064
+ durationMinutes: num2(row, "duration_minutes"),
2681
3065
  // An unknown state is shown as scheduled, never dropped: the row is real.
2682
3066
  state: OCCURRENCE_STATES.includes(state) ? state : "scheduled",
2683
- sequence: num(row, "sequence") ?? 0
3067
+ sequence: num2(row, "sequence") ?? 0
2684
3068
  };
2685
3069
  }
2686
3070
  function projectUpcoming(row) {
@@ -2709,9 +3093,9 @@ function projectOverride(row) {
2709
3093
  originalStart: when(row, "original_start") ?? requireText(row, "original_start", operation),
2710
3094
  state: text(row, "state") === "moved" ? "moved" : "cancelled",
2711
3095
  newStart: when(row, "new_start"),
2712
- newDurationMinutes: num(row, "new_duration_minutes"),
3096
+ newDurationMinutes: num2(row, "new_duration_minutes"),
2713
3097
  reason: text(row, "reason"),
2714
- calendarSequence: num(row, "calendar_sequence") ?? 0,
3098
+ calendarSequence: num2(row, "calendar_sequence") ?? 0,
2715
3099
  deletedAt: when(row, "deleted_at")
2716
3100
  };
2717
3101
  }
@@ -2735,7 +3119,7 @@ function projectRsvpInvitation(body) {
2735
3119
  title: text(meeting, "title") ?? "Meeting",
2736
3120
  slug: requireText(meeting, "slug", operation),
2737
3121
  scheduledFor: when(meeting, "scheduled_for"),
2738
- durationMinutes: num(meeting, "duration_minutes"),
3122
+ durationMinutes: num2(meeting, "duration_minutes"),
2739
3123
  timeZone: text(meeting, "time_zone") ?? "UTC",
2740
3124
  agenda: text(meeting, "agenda"),
2741
3125
  recurrenceRule: text(meeting, "recurrence_rule"),
@@ -2769,6 +3153,7 @@ function changesPatch(changes) {
2769
3153
  patch["scheduled_duration_minutes"] = changes.scheduledDurationMinutes;
2770
3154
  }
2771
3155
  if (changes.recurrenceRule !== void 0) patch["recurrence_rule"] = changes.recurrenceRule;
3156
+ if (changes.keepExceptions !== void 0) patch["keep_exceptions"] = changes.keepExceptions;
2772
3157
  return patch;
2773
3158
  }
2774
3159
  function createMeetRepository(options) {
@@ -2915,7 +3300,8 @@ function createMeetRepository(options) {
2915
3300
  admissionState: states.includes(admission) ? admission : "admitted",
2916
3301
  isAgent: bool(row, "is_agent", false),
2917
3302
  joinedAt: text(row, "joined_at"),
2918
- leftAt: text(row, "left_at")
3303
+ leftAt: text(row, "left_at"),
3304
+ sessions: projectStays(row["sessions"])
2919
3305
  };
2920
3306
  }
2921
3307
  function requireOrg(organizationId, operation) {
@@ -3309,8 +3695,8 @@ function projectLibraryRecording(row) {
3309
3695
  fileId: text(row, "file_id"),
3310
3696
  startedAt: text(row, "started_at"),
3311
3697
  endedAt: text(row, "ended_at"),
3312
- durationMs: num(row, "duration_ms"),
3313
- sizeBytes: num(row, "size_bytes"),
3698
+ durationMs: num2(row, "duration_ms"),
3699
+ sizeBytes: num2(row, "size_bytes"),
3314
3700
  failureReason: text(row, "failure_reason"),
3315
3701
  archivedAt: text(row, "deleted_at"),
3316
3702
  organizationId: asOrganizationId(requireText(row, "organization_id", operation))
@@ -3337,7 +3723,7 @@ function projectSearchHit(row) {
3337
3723
  speaker: text(row, "speaker"),
3338
3724
  snippet: text(row, "snippet") ?? "",
3339
3725
  at: text(row, "said_at"),
3340
- rank: num(row, "rank") ?? 0
3726
+ rank: num2(row, "rank") ?? 0
3341
3727
  };
3342
3728
  }
3343
3729
  function snippetRuns(snippet) {
@@ -3482,7 +3868,14 @@ var ROOM_EVENTS = {
3482
3868
  * person concerned; `lower-hands {identities: [...] | "*"}` · `role {identity,
3483
3869
  * role}` — to everyone.
3484
3870
  */
3485
- moderation: "matrx.meet.moderation"
3871
+ moderation: "matrx.meet.moderation",
3872
+ /**
3873
+ * A meeting ROOM ITEM changed (Meet wave 5): a poll, a Q&A question, a whiteboard
3874
+ * stroke or the breakout plan. Payload `{ meeting_id, item }` · `{ removed: [ids] }` ·
3875
+ * `{ hidden: [ids] }` · `{ cleared: "whiteboard" }` · `{ broadcast }` · `{ item, move }`.
3876
+ * A host's fuller copy of a poll or question carries `audience: "hosts"`.
3877
+ */
3878
+ collab: "matrx.meet.collab"
3486
3879
  };
3487
3880
  function isRoomEventTopic(topic) {
3488
3881
  return topic.startsWith(ROOM_EVENT_PREFIX);
@@ -3522,10 +3915,27 @@ function applyRoomEvent(args) {
3522
3915
  return applyChat(store, payload);
3523
3916
  case ROOM_EVENTS.moderation:
3524
3917
  return applyModeration(store, payload, now);
3918
+ case ROOM_EVENTS.collab:
3919
+ return applyCollab(store, payload, now);
3525
3920
  default:
3526
3921
  return ignored(`${topic} is not known to this version of @ai-matrx/meet`);
3527
3922
  }
3528
3923
  }
3924
+ function applyCollab(store, payload, now) {
3925
+ const snapshot = store.snapshot();
3926
+ const meeting = snapshot.meeting;
3927
+ if (meeting !== null && text2(payload["meeting_id"]) !== null && payload["meeting_id"] !== meeting.id) {
3928
+ return ignored("a collab event for a different meeting than this room is showing");
3929
+ }
3930
+ const result = applyCollabPacket(snapshot.collab, payload, {
3931
+ localIdentity: snapshot.localIdentity,
3932
+ isHost: ROLE_RANK[effectiveRole(snapshot)] >= ROLE_RANK.cohost,
3933
+ now: now()
3934
+ });
3935
+ if (result.next === null) return ignored(result.dropped ?? "a collab packet that changed nothing");
3936
+ store.patch({ collab: result.next });
3937
+ return HANDLED;
3938
+ }
3529
3939
  function applyNote(store, payload) {
3530
3940
  const row = object(payload["note"]);
3531
3941
  if (row === null) return ignored("a note event with no `note` row");
@@ -3847,6 +4257,7 @@ function createRoomEngine(options) {
3847
4257
  let joining = null;
3848
4258
  let lastRequest = null;
3849
4259
  let disposed = false;
4260
+ let moving = false;
3850
4261
  const confirmingEnds = /* @__PURE__ */ new WeakSet();
3851
4262
  async function leaveRoom() {
3852
4263
  const target = driver;
@@ -4076,6 +4487,7 @@ function createRoomEngine(options) {
4076
4487
  }
4077
4488
  },
4078
4489
  disconnected(reason) {
4490
+ if (moving) return;
4079
4491
  if (current !== null) {
4080
4492
  tokens.invalidate(current.roomName);
4081
4493
  current = null;
@@ -4090,11 +4502,13 @@ function createRoomEngine(options) {
4090
4502
  roomName: request.roomName,
4091
4503
  identity,
4092
4504
  ...request.meetingId !== void 0 ? { meetingId: request.meetingId } : {},
4093
- ...request.slug !== void 0 ? { slug: request.slug } : {}
4505
+ ...request.slug !== void 0 ? { slug: request.slug } : {},
4506
+ ...request.breakoutRoomId != null ? { breakoutRoomId: request.breakoutRoomId } : {}
4094
4507
  });
4095
4508
  current = token;
4096
4509
  store.patch({
4097
4510
  localIdentity: token.identity,
4511
+ breakoutRoomId: token.breakoutRoomId ?? null,
4098
4512
  grants: {
4099
4513
  role: token.role,
4100
4514
  canRecord: token.canRecord,
@@ -4213,6 +4627,56 @@ function createRoomEngine(options) {
4213
4627
  });
4214
4628
  return joining;
4215
4629
  },
4630
+ async moveToBreakout(roomId) {
4631
+ const request = lastRequest;
4632
+ if (request === null || driver === null) {
4633
+ report(
4634
+ "warn",
4635
+ "meet.moveToBreakout: this engine is not in a meeting room",
4636
+ "Join the meeting first; a breakout is a room OF a meeting."
4637
+ );
4638
+ return;
4639
+ }
4640
+ if ((store.snapshot().breakoutRoomId ?? null) === roomId) return;
4641
+ if (joining !== null) await joining.catch(() => void 0);
4642
+ const previous = driver;
4643
+ const next = {
4644
+ ...request,
4645
+ breakoutRoomId: roomId,
4646
+ // Arrive as you were: camera and microphone as they are now.
4647
+ mode: store.snapshot().media.camera.enabled ? "video" : "audio",
4648
+ microphone: store.snapshot().media.microphone.enabled
4649
+ };
4650
+ moving = true;
4651
+ try {
4652
+ driver = null;
4653
+ tokens.invalidate(request.roomName);
4654
+ current = null;
4655
+ await previous.disconnect();
4656
+ lastRequest = next;
4657
+ joining = connect(next).finally(() => {
4658
+ joining = null;
4659
+ });
4660
+ await joining;
4661
+ } catch (error) {
4662
+ const normalized = normalizeMeetError(error, "meet.moveToBreakout");
4663
+ report("warn", normalized.message, normalized.remedy);
4664
+ if (roomId !== null) {
4665
+ lastRequest = { ...next, breakoutRoomId: null };
4666
+ joining = connect(lastRequest).finally(() => {
4667
+ joining = null;
4668
+ });
4669
+ await joining.catch((again) => {
4670
+ throw fail(again, "meet.moveToBreakout");
4671
+ });
4672
+ } else {
4673
+ throw fail(error, "meet.moveToBreakout");
4674
+ }
4675
+ throw normalized;
4676
+ } finally {
4677
+ moving = false;
4678
+ }
4679
+ },
4216
4680
  leave: leaveRoom,
4217
4681
  // Turning a device on mid-meeting is the SAME operation as turning it on
4218
4682
  // during the join, so it runs the same function. A failure here used to
@@ -4482,6 +4946,109 @@ function createInRoomClient(options) {
4482
4946
  (row) => typeof row === "object" && row !== null ? chatFromRow(row) : null
4483
4947
  ).filter((message) => message !== null);
4484
4948
  store.loadChat(messages);
4949
+ },
4950
+ async loadCollab() {
4951
+ const operation = "meet.loadCollab";
4952
+ const id = meetingId(operation);
4953
+ const hdrs = headers();
4954
+ const response = await api.request({
4955
+ path: `${MEET_ROUTES.collab}?meeting_id=${encodeURIComponent(id)}`,
4956
+ method: "GET",
4957
+ operation,
4958
+ ...hdrs !== void 0 ? { headers: hdrs } : {}
4959
+ });
4960
+ if (!response.ok) {
4961
+ const error = await refusal2(
4962
+ response,
4963
+ operation,
4964
+ "Polls, questions and the whiteboard could not be read. New ones still arrive."
4965
+ );
4966
+ store.patch({ collab: { ...store.snapshot().collab, loaded: true, error: error.message } });
4967
+ throw error;
4968
+ }
4969
+ const body = await response.json();
4970
+ store.patch({ collab: collabFromState(body, store.snapshot().collab) });
4971
+ },
4972
+ async collab(request) {
4973
+ const operation = `meet.collab(${request.action})`;
4974
+ const hdrs = headers();
4975
+ const response = await api.request({
4976
+ path: MEET_ROUTES.collab,
4977
+ method: "POST",
4978
+ operation,
4979
+ body: {
4980
+ meeting_id: meetingId(operation),
4981
+ action: request.action,
4982
+ ...request.itemId !== void 0 ? { item_id: request.itemId } : {},
4983
+ ...request.question !== void 0 ? { question: request.question } : {},
4984
+ ...request.options !== void 0 ? { options: request.options } : {},
4985
+ ...request.multiple !== void 0 ? { multiple: request.multiple } : {},
4986
+ ...request.anonymous !== void 0 ? { anonymous: request.anonymous } : {},
4987
+ ...request.optionIds !== void 0 ? { option_ids: request.optionIds } : {},
4988
+ ...request.text !== void 0 ? { text: request.text } : {},
4989
+ ...request.stroke !== void 0 ? { stroke: request.stroke } : {},
4990
+ ...request.rooms !== void 0 ? { rooms: request.rooms } : {},
4991
+ ...request.allowChoose !== void 0 ? { allow_choose: request.allowChoose } : {},
4992
+ ...request.minutes !== void 0 ? { minutes: request.minutes } : {},
4993
+ ...request.identity !== void 0 ? { identity: request.identity } : {},
4994
+ ...request.roomId !== void 0 ? { room_id: request.roomId } : {}
4995
+ },
4996
+ ...hdrs !== void 0 ? { headers: hdrs } : {}
4997
+ });
4998
+ if (!response.ok) {
4999
+ throw await refusal2(response, operation, "Nothing was changed.");
5000
+ }
5001
+ const payload = await response.json();
5002
+ const removed = Array.isArray(payload["removed"]) ? payload["removed"].filter((v) => typeof v === "string") : [];
5003
+ let next = store.snapshot().collab;
5004
+ const item = payload["item"];
5005
+ if (typeof item === "object" && item !== null) next = withItem(next, item);
5006
+ if (removed.length > 0) {
5007
+ const gone = new Set(removed);
5008
+ next = {
5009
+ ...next,
5010
+ polls: next.polls.filter((p) => !gone.has(p.id)),
5011
+ questions: next.questions.filter((q) => !gone.has(q.id)),
5012
+ strokes: next.strokes.filter((st) => !gone.has(st.id))
5013
+ };
5014
+ }
5015
+ store.patch({ collab: next });
5016
+ const itemId = typeof item === "object" && item !== null && typeof item["id"] === "string" ? item["id"] : null;
5017
+ return {
5018
+ action: request.action,
5019
+ message: typeof payload["message"] === "string" ? payload["message"] : "Done.",
5020
+ removed,
5021
+ itemId
5022
+ };
5023
+ },
5024
+ async translateCaptions(language, lines) {
5025
+ if (lines.length === 0) return;
5026
+ const operation = "meet.translateCaptions";
5027
+ const hdrs = headers();
5028
+ const response = await api.request({
5029
+ path: MEET_ROUTES.captionsTranslate,
5030
+ method: "POST",
5031
+ operation,
5032
+ body: { meeting_id: meetingId(operation), target_language: language, lines },
5033
+ ...hdrs !== void 0 ? { headers: hdrs } : {}
5034
+ });
5035
+ if (!response.ok) {
5036
+ const error = await refusal2(response, operation, "Captions stay in the language they were spoken.");
5037
+ store.patch({
5038
+ collab: { ...store.snapshot().collab, captionTranslationError: error.message }
5039
+ });
5040
+ throw error;
5041
+ }
5042
+ const payload = await response.json();
5043
+ const current = store.snapshot().collab;
5044
+ if (current.captionLanguage !== language) return;
5045
+ const merged = { ...current.captionTranslations };
5046
+ for (const [id, value] of Object.entries(payload.translations ?? {})) {
5047
+ if (typeof value === "string") merged[id] = value;
5048
+ }
5049
+ store.patch({
5050
+ collab: { ...current, captionTranslations: merged, captionTranslationError: null }
5051
+ });
4485
5052
  }
4486
5053
  };
4487
5054
  }
@@ -5049,6 +5616,14 @@ function MeetRuntime(props) {
5049
5616
  }
5050
5617
  if (chatReadFor === snapshot.meeting.id) return;
5051
5618
  chatReadFor = snapshot.meeting.id;
5619
+ void inRoom.loadCollab().catch((error) => {
5620
+ const normalized = error;
5621
+ report({
5622
+ level: "warn",
5623
+ message: normalized.message ?? "meet: polls, questions and the whiteboard could not be read",
5624
+ ...normalized.remedy !== void 0 ? { remedy: normalized.remedy } : {}
5625
+ });
5626
+ });
5052
5627
  void inRoom.loadChat().catch((error) => {
5053
5628
  const normalized = error;
5054
5629
  store.patch({
@@ -6389,7 +6964,7 @@ function useGuestRecordAccess(meeting) {
6389
6964
  }
6390
6965
 
6391
6966
  // src/react/components.tsx
6392
- var import_react4 = require("react");
6967
+ var import_react5 = require("react");
6393
6968
  var import_design_system = require("@ai-matrx/design-system");
6394
6969
  var import_format3 = require("@ai-matrx/kit/format");
6395
6970
 
@@ -6456,12 +7031,19 @@ function coveredMs(intervals) {
6456
7031
  }
6457
7032
  function attendanceReport(meeting, attendees, names = {}) {
6458
7033
  const end = ms(meeting.endedAt);
7034
+ const measuredOf = /* @__PURE__ */ new Map();
6459
7035
  const perJoin = attendees.map((person) => {
6460
- const joined = ms(person.joinedAt);
6461
- const left = ms(person.leftAt);
6462
- const until = left ?? end;
6463
- const duration = joined !== null && until !== null && until >= joined ? until - joined : null;
6464
- return {
7036
+ const stays = person.sessions !== void 0 && person.sessions.length > 0 ? person.sessions.map((stay) => [ms(stay.joinedAt), ms(stay.leftAt)]) : [[ms(person.joinedAt), ms(person.leftAt)]];
7037
+ let toEnd = false;
7038
+ const measured = [];
7039
+ for (const [joined, left] of stays) {
7040
+ const until = left ?? end;
7041
+ if (joined === null || until === null || until < joined) continue;
7042
+ if (left === null) toEnd = true;
7043
+ measured.push([joined, until]);
7044
+ }
7045
+ const duration = measured.length === 0 ? null : coveredMs(measured);
7046
+ const row = {
6465
7047
  id: person.id,
6466
7048
  identity: person.identity,
6467
7049
  name: displayNameFor(names, person.identity, person.displayName),
@@ -6470,10 +7052,12 @@ function attendanceReport(meeting, attendees, names = {}) {
6470
7052
  joinedAt: person.joinedAt,
6471
7053
  leftAt: person.leftAt,
6472
7054
  durationMs: duration,
6473
- durationToEnd: duration !== null && left === null,
7055
+ durationToEnd: duration !== null && toEnd,
6474
7056
  admission: person.admissionState,
6475
- joins: 1
7057
+ joins: Math.max(1, person.sessions?.length ?? 0)
6476
7058
  };
7059
+ measuredOf.set(row, measured);
7060
+ return row;
6477
7061
  });
6478
7062
  const groups = /* @__PURE__ */ new Map();
6479
7063
  attendees.forEach((person, index) => {
@@ -6496,17 +7080,14 @@ function attendanceReport(meeting, attendees, names = {}) {
6496
7080
  const left = ms(row.leftAt);
6497
7081
  return left !== null && (latest === null || left > latest) ? left : latest;
6498
7082
  }, null);
6499
- const intervals = came.flatMap((row) => {
6500
- const joined = ms(row.joinedAt);
6501
- return joined !== null && row.durationMs !== null ? [[joined, joined + row.durationMs]] : [];
6502
- });
7083
+ const intervals = came.flatMap((row) => measuredOf.get(row) ?? []);
6503
7084
  return {
6504
7085
  ...first,
6505
7086
  kind,
6506
7087
  leftAt: open ? null : lastLeave === null ? null : new Date(lastLeave).toISOString(),
6507
7088
  durationMs: intervals.length === 0 ? null : coveredMs(intervals),
6508
7089
  durationToEnd: came.some((row) => row.durationToEnd),
6509
- joins: came.length === 0 ? joins.length : came.length
7090
+ joins: came.length === 0 ? joins.length : came.reduce((total, row) => total + row.joins, 0)
6510
7091
  };
6511
7092
  });
6512
7093
  const rank = KIND_RANK;
@@ -6650,8 +7231,8 @@ function transcriptDocument(bundle, format, options = {}) {
6650
7231
  if (line.identity !== last) {
6651
7232
  if (last !== null) out.push("");
6652
7233
  const who = speaker(line);
6653
- const clock = clockOfDay(line.startedAt, options);
6654
- out.push(format === "md" ? `**${who}** \xB7 ${clock}` : `${who} (${clock})`);
7234
+ const clock2 = clockOfDay(line.startedAt, options);
7235
+ out.push(format === "md" ? `**${who}** \xB7 ${clock2}` : `${who} (${clock2})`);
6655
7236
  last = line.identity;
6656
7237
  }
6657
7238
  out.push(line.text.trim());
@@ -6832,6 +7413,9 @@ function countLabel(count2, singular, plural = `${singular}s`) {
6832
7413
  return `${count2} ${count2 === 1 ? singular : plural}`;
6833
7414
  }
6834
7415
 
7416
+ // src/react/collab.tsx
7417
+ var import_react4 = require("react");
7418
+
6835
7419
  // src/react/icons.tsx
6836
7420
  var import_jsx_runtime2 = require("react/jsx-runtime");
6837
7421
  function Icon({ children, ...props }) {
@@ -7016,99 +7600,1128 @@ function FlagIcon(props) {
7016
7600
  function PencilIcon(props) {
7017
7601
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z" }) });
7018
7602
  }
7019
-
7020
- // src/react/components.tsx
7021
- var import_jsx_runtime3 = require("react/jsx-runtime");
7022
- function InertNotice({ what }) {
7023
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__empty", role: "status", children: [
7024
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__empty-title", children: [
7025
- what,
7026
- " is not ready yet"
7027
- ] }),
7028
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-body", children: "Calls and meetings need a signed-in identity and an active organization. This will appear as soon as they resolve." })
7603
+ function ActivitiesIcon(props) {
7604
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Icon, { ...props, children: [
7605
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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" }),
7606
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { x: "3", y: "14", width: "7", height: "7", rx: "1" }),
7607
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "17.5", cy: "17.5", r: "3.5" })
7029
7608
  ] });
7030
7609
  }
7031
- function Avatar({
7032
- name,
7033
- url,
7034
- size = 40
7035
- }) {
7036
- const tint = (0, import_format3.avatarPaletteIndex)(name);
7037
- if (url != null && url.length > 0) {
7038
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
7039
- "img",
7040
- {
7041
- className: "mx-meet__avatar",
7042
- src: url,
7043
- alt: "",
7044
- width: size,
7045
- height: size,
7046
- style: { width: size, height: size }
7047
- }
7048
- );
7049
- }
7050
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
7051
- "span",
7052
- {
7053
- className: "mx-meet__avatar mx-meet__avatar--initials",
7054
- style: {
7055
- width: size,
7056
- height: size,
7057
- fontSize: Math.round(size * 0.38),
7058
- background: `var(--mx-meet-avatar-${tint})`
7059
- },
7060
- "aria-hidden": "true",
7061
- children: (0, import_format3.getInitials)(name)
7062
- }
7063
- );
7610
+ function PollIcon(props) {
7611
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Icon, { ...props, children: [
7612
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "18", x2: "18", y1: "20", y2: "10" }),
7613
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "12", x2: "12", y1: "20", y2: "4" }),
7614
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "6", x2: "6", y1: "20", y2: "14" })
7615
+ ] });
7064
7616
  }
7065
- function ControlButton({
7066
- label,
7067
- active = false,
7068
- danger = false,
7069
- onClick,
7070
- children
7071
- }) {
7072
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
7073
- "button",
7074
- {
7075
- type: "button",
7076
- className: [
7077
- "mx-meet__control",
7078
- active ? "mx-meet__control--active" : "",
7079
- danger ? "mx-meet__control--danger" : ""
7080
- ].filter(Boolean).join(" "),
7081
- "aria-label": label,
7082
- title: label,
7083
- onClick,
7084
- children
7085
- }
7086
- );
7617
+ function QuestionIcon(props) {
7618
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Icon, { ...props, children: [
7619
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M7.9 20A9 9 0 1 0 4 16.1L2 22Z" }),
7620
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }),
7621
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 17h.01" })
7622
+ ] });
7087
7623
  }
7088
- function RecordingIndicator() {
7089
- const { state, label } = useRecording();
7090
- if (label === null) return null;
7091
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
7092
- "span",
7093
- {
7094
- className: `mx-meet__recording mx-meet__recording--${state}`,
7095
- role: "status",
7096
- "aria-live": "polite",
7097
- children: [
7098
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RecordIcon, { width: 10, height: 10 }),
7099
- label
7100
- ]
7101
- }
7102
- );
7624
+ function WhiteboardIcon(props) {
7625
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Icon, { ...props, children: [
7626
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M2 3h20" }),
7627
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21 3v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V3" }),
7628
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m7 21 5-5 5 5" })
7629
+ ] });
7103
7630
  }
7104
- function ConnectionDot({ quality }) {
7105
- if (quality === "excellent" || quality === "good" || quality === "unknown") return null;
7106
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: `mx-meet__quality mx-meet__quality--${quality}`, title: `Connection ${quality}`, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(WifiLowIcon, { width: 14, height: 14 }) });
7631
+ function BreakoutIcon(props) {
7632
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Icon, { ...props, children: [
7633
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { width: "7", height: "18", x: "3", y: "3", rx: "1" }),
7634
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { width: "7", height: "7", x: "14", y: "3", rx: "1" }),
7635
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { width: "7", height: "7", x: "14", y: "14", rx: "1" })
7636
+ ] });
7637
+ }
7638
+ function UpvoteIcon(props) {
7639
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M9 18v-6H5l7-7 7 7h-4v6H9z" }) });
7640
+ }
7641
+ function EraserIcon(props) {
7642
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Icon, { ...props, children: [
7643
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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" }),
7644
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M22 21H7" }),
7645
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m5 11 9 9" })
7646
+ ] });
7647
+ }
7648
+ function HighlighterIcon(props) {
7649
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Icon, { ...props, children: [
7650
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m9 11-6 6v3h9l3-3" }),
7651
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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" })
7652
+ ] });
7653
+ }
7654
+ function UndoIcon(props) {
7655
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Icon, { ...props, children: [
7656
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M9 14 4 9l5-5" }),
7657
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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" })
7658
+ ] });
7659
+ }
7660
+
7661
+ // src/react/collab.tsx
7662
+ var import_jsx_runtime3 = require("react/jsx-runtime");
7663
+ function useCollab() {
7664
+ const host = useMeetHost();
7665
+ const snapshot = useMeetSnapshot();
7666
+ const isHost = useIsHost();
7667
+ return {
7668
+ collab: snapshot?.collab ?? null,
7669
+ isHost,
7670
+ localIdentity: snapshot?.localIdentity ?? null,
7671
+ breakoutRoomId: snapshot?.breakoutRoomId ?? null,
7672
+ async act(request) {
7673
+ if (host === null) return { ok: false, message: "This meeting is not connected." };
7674
+ try {
7675
+ const result = await host.inRoom.collab(request);
7676
+ return { ok: true, message: result.message, itemId: result.itemId };
7677
+ } catch (error) {
7678
+ return { ok: false, message: error.message ?? "That did not work." };
7679
+ }
7680
+ },
7681
+ async moveTo(roomId) {
7682
+ if (host === null) return { ok: false, message: "This meeting is not connected." };
7683
+ try {
7684
+ await host.engine.moveToBreakout(roomId);
7685
+ return { ok: true, message: roomId === null ? "Back in the main room." : "Joined the breakout room." };
7686
+ } catch (error) {
7687
+ return { ok: false, message: error.message ?? "That room could not be joined." };
7688
+ }
7689
+ }
7690
+ };
7691
+ }
7692
+ function useNotice() {
7693
+ const [notice, setNotice] = (0, import_react4.useState)(null);
7694
+ (0, import_react4.useEffect)(() => {
7695
+ if (notice === null) return void 0;
7696
+ const timer = setTimeout(() => setNotice(null), notice.failed ? 7e3 : 3e3);
7697
+ return () => clearTimeout(timer);
7698
+ }, [notice]);
7699
+ return [notice, (result) => setNotice({ text: result.message, failed: !result.ok })];
7700
+ }
7701
+ function Notice({ notice }) {
7702
+ if (notice === null) return null;
7703
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: notice.failed ? "mx-meet__panel-note mx-meet__collab-error" : "mx-meet__panel-note", role: "status", children: notice.text });
7704
+ }
7705
+ var ACTIVITY_LABELS = {
7706
+ polls: "Polls",
7707
+ qa: "Q&A",
7708
+ whiteboard: "Whiteboard",
7709
+ breakouts: "Breakout rooms"
7710
+ };
7711
+ function ActivityIcon({ panel }) {
7712
+ const props = { width: 16, height: 16 };
7713
+ if (panel === "polls") return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PollIcon, { ...props });
7714
+ if (panel === "qa") return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(QuestionIcon, { ...props });
7715
+ if (panel === "whiteboard") return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(WhiteboardIcon, { ...props });
7716
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(BreakoutIcon, { ...props });
7717
+ }
7718
+ function useAvailableActivities() {
7719
+ const { collab, isHost } = useCollab();
7720
+ const settings = collab?.settings ?? null;
7721
+ if (settings === null) return [];
7722
+ const out = [];
7723
+ if (settings.whiteboardEnabled) out.push("whiteboard");
7724
+ if (settings.pollsEnabled && (isHost || (collab?.polls.length ?? 0) > 0)) out.push("polls");
7725
+ if (settings.qaEnabled) out.push("qa");
7726
+ if (settings.breakoutsEnabled && (isHost || collab?.breakout?.state === "open")) out.push("breakouts");
7727
+ return out;
7728
+ }
7729
+ function useActivityAttention() {
7730
+ const { collab, isHost } = useCollab();
7731
+ if (collab === null) return false;
7732
+ if (collab.polls.some((poll) => poll.state === "live" && poll.myVote.length === 0 && !isHost)) return true;
7733
+ if (isHost && collab.questions.some((q) => q.state === "open")) return true;
7734
+ return false;
7735
+ }
7736
+ function ActivitiesControl({
7737
+ active,
7738
+ onOpen
7739
+ }) {
7740
+ const [open, setOpen] = (0, import_react4.useState)(false);
7741
+ const available = useAvailableActivities();
7742
+ const attention = useActivityAttention();
7743
+ if (available.length === 0) return null;
7744
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__anchor", children: [
7745
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(ControlButton, { label: "Activities", active: open || active !== null, onClick: () => setOpen(!open), children: [
7746
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ActivitiesIcon, {}),
7747
+ attention ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
7748
+ ] }),
7749
+ open ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Popover, { label: "Activities", onClose: () => setOpen(false), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__menu", role: "menu", children: available.map((panel) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
7750
+ MenuItem,
7751
+ {
7752
+ onSelect: () => {
7753
+ setOpen(false);
7754
+ onOpen(panel);
7755
+ },
7756
+ children: [
7757
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ActivityIcon, { panel }),
7758
+ " ",
7759
+ ACTIVITY_LABELS[panel]
7760
+ ]
7761
+ },
7762
+ panel
7763
+ )) }) }) : null
7764
+ ] });
7765
+ }
7766
+ function PollComposer({ maxOptions, onDone }) {
7767
+ const { act } = useCollab();
7768
+ const [question, setQuestion] = (0, import_react4.useState)("");
7769
+ const [options, setOptions] = (0, import_react4.useState)(["", ""]);
7770
+ const [multiple, setMultiple] = (0, import_react4.useState)(false);
7771
+ const [anonymous, setAnonymous] = (0, import_react4.useState)(false);
7772
+ const [busy, setBusy] = (0, import_react4.useState)(false);
7773
+ const [notice, show] = useNotice();
7774
+ const filled = options.map((o) => o.trim()).filter(Boolean);
7775
+ const ready = question.trim().length > 0 && filled.length >= 2;
7776
+ const save = async (launch) => {
7777
+ setBusy(true);
7778
+ const created = await act({ action: "poll_create", question, options: filled, multiple, anonymous });
7779
+ if (!created.ok) {
7780
+ show(created);
7781
+ setBusy(false);
7782
+ return;
7783
+ }
7784
+ if (launch && created.itemId != null) {
7785
+ const launched = await act({ action: "poll_launch", itemId: created.itemId });
7786
+ if (!launched.ok) {
7787
+ show(launched);
7788
+ setBusy(false);
7789
+ return;
7790
+ }
7791
+ }
7792
+ setBusy(false);
7793
+ onDone();
7794
+ };
7795
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
7796
+ "form",
7797
+ {
7798
+ className: "mx-meet__collab-card",
7799
+ onSubmit: (event) => {
7800
+ event.preventDefault();
7801
+ if (ready) void save(true);
7802
+ },
7803
+ children: [
7804
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
7805
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: "Question" }),
7806
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
7807
+ "input",
7808
+ {
7809
+ className: "mx-meet__input",
7810
+ value: question,
7811
+ maxLength: 1e3,
7812
+ onChange: (event) => setQuestion(event.target.value),
7813
+ placeholder: "Ask the room something",
7814
+ autoFocus: true
7815
+ }
7816
+ )
7817
+ ] }),
7818
+ options.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__composer-row", children: [
7819
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
7820
+ "input",
7821
+ {
7822
+ className: "mx-meet__input",
7823
+ value: option,
7824
+ maxLength: 200,
7825
+ "aria-label": `Answer ${index + 1}`,
7826
+ placeholder: `Answer ${index + 1}`,
7827
+ onChange: (event) => setOptions(options.map((o, i) => i === index ? event.target.value : o))
7828
+ }
7829
+ ),
7830
+ options.length > 2 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ControlButton, { label: `Remove answer ${index + 1}`, onClick: () => setOptions(options.filter((_, i) => i !== index)), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CloseIcon, { width: 14, height: 14 }) }) : null
7831
+ ] }, index)),
7832
+ options.length < maxOptions ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => setOptions([...options, ""]), children: "Add an answer" }) : null,
7833
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__toggle", children: [
7834
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { type: "checkbox", checked: multiple, onChange: (event) => setMultiple(event.target.checked) }),
7835
+ "People can pick more than one"
7836
+ ] }),
7837
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__toggle", children: [
7838
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { type: "checkbox", checked: anonymous, onChange: (event) => setAnonymous(event.target.checked) }),
7839
+ "Anonymous \u2014 nobody sees who picked what"
7840
+ ] }),
7841
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Notice, { notice }),
7842
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__collab-actions", children: [
7843
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", className: "mx-meet__primary mx-meet__primary--small", disabled: !ready || busy, children: "Launch" }),
7844
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__chip", disabled: !ready || busy, onClick: () => void save(false), children: "Save draft" }),
7845
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: onDone, children: "Cancel" })
7846
+ ] })
7847
+ ]
7848
+ }
7849
+ );
7850
+ }
7851
+ function PollCard({ poll }) {
7852
+ const { act, isHost } = useCollab();
7853
+ const [picked, setPicked] = (0, import_react4.useState)(poll.myVote.slice());
7854
+ const [notice, show] = useNotice();
7855
+ (0, import_react4.useEffect)(() => setPicked(poll.myVote.slice()), [poll.myVote]);
7856
+ const counts = poll.options.some((o) => o.votes !== void 0);
7857
+ const total = poll.options.reduce((sum, o) => sum + (o.votes ?? 0), 0);
7858
+ const canVote = poll.state === "live";
7859
+ const voted = poll.myVote.length > 0;
7860
+ const stateWord = poll.state === "draft" ? "Draft" : poll.state === "live" ? "Open" : "Closed";
7861
+ const toggle = (id) => {
7862
+ if (!canVote) return;
7863
+ setPicked(poll.multiple ? picked.includes(id) ? picked.filter((p) => p !== id) : [...picked, id] : [id]);
7864
+ };
7865
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("article", { className: "mx-meet__collab-card", "aria-label": poll.question, children: [
7866
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "mx-meet__collab-head", children: [
7867
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { className: "mx-meet__collab-title", children: poll.question }),
7868
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__collab-state", children: stateWord })
7869
+ ] }),
7870
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__panel-note", children: [
7871
+ poll.multiple ? "Pick any." : "Pick one.",
7872
+ poll.anonymous ? " Anonymous." : "",
7873
+ counts && poll.voterCount !== null ? ` ${poll.voterCount} voted.` : "",
7874
+ isHost && poll.state !== "draft" && !poll.resultsShared ? " Results are visible only to hosts." : ""
7875
+ ] }),
7876
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet__poll-options", children: poll.options.map((option) => {
7877
+ const share = counts && total > 0 ? Math.round((option.votes ?? 0) / total * 100) : 0;
7878
+ const chosen = picked.includes(option.id);
7879
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { children: [
7880
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
7881
+ "button",
7882
+ {
7883
+ type: "button",
7884
+ className: chosen ? "mx-meet__poll-option mx-meet__poll-option--chosen" : "mx-meet__poll-option",
7885
+ "aria-pressed": chosen,
7886
+ disabled: !canVote,
7887
+ onClick: () => toggle(option.id),
7888
+ children: [
7889
+ counts ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__poll-bar", style: { width: `${share}%` }, "aria-hidden": "true" }) : null,
7890
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__poll-text", children: option.text }),
7891
+ counts ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__poll-count", children: [
7892
+ option.votes ?? 0,
7893
+ " \xB7 ",
7894
+ share,
7895
+ "%"
7896
+ ] }) : null
7897
+ ]
7898
+ }
7899
+ ),
7900
+ option.voters !== void 0 && option.voters.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__poll-voters", children: option.voters.join(", ") }) : null
7901
+ ] }, option.id);
7902
+ }) }),
7903
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Notice, { notice }),
7904
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__collab-actions", children: [
7905
+ canVote ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
7906
+ "button",
7907
+ {
7908
+ type: "button",
7909
+ className: "mx-meet__primary mx-meet__primary--small",
7910
+ disabled: picked.length === 0 || voted && picked.join() === poll.myVote.join(),
7911
+ onClick: () => void act({ action: "poll_vote", itemId: poll.id, optionIds: picked }).then(show),
7912
+ children: voted ? "Change vote" : "Vote"
7913
+ }
7914
+ ) : null,
7915
+ isHost && poll.state === "draft" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__primary mx-meet__primary--small", onClick: () => void act({ action: "poll_launch", itemId: poll.id }).then(show), children: "Launch" }) : null,
7916
+ isHost && poll.state === "live" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "poll_close", itemId: poll.id }).then(show), children: "End poll" }) : null,
7917
+ isHost && poll.state !== "draft" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "poll_share", itemId: poll.id }).then(show), children: poll.resultsShared ? "Hide results" : "Share results" }) : null,
7918
+ isHost && poll.state === "live" ? null : isHost ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => void act({ action: "poll_delete", itemId: poll.id }).then(show), children: "Delete" }) : null
7919
+ ] })
7920
+ ] });
7921
+ }
7922
+ function PollsPanel({ onClose }) {
7923
+ const { collab, isHost } = useCollab();
7924
+ const [composing, setComposing] = (0, import_react4.useState)(false);
7925
+ const polls = collab?.polls ?? [];
7926
+ const maxOptions = collab?.settings?.pollMaxOptions ?? 10;
7927
+ const ordered = [...polls].reverse();
7928
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(PanelShell, { title: "Polls", onClose, children: [
7929
+ collab?.error != null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
7930
+ isHost && !composing ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__primary mx-meet__primary--small", onClick: () => setComposing(true), children: "New poll" }) : null,
7931
+ isHost && composing ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PollComposer, { maxOptions, onDone: () => setComposing(false) }) : null,
7932
+ ordered.length === 0 && !composing ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: isHost ? "No polls yet. Polls and their results are kept with the meeting." : "No polls yet." }) : null,
7933
+ ordered.map((poll) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PollCard, { poll }, poll.id))
7934
+ ] });
7935
+ }
7936
+ function QuestionCard({ question }) {
7937
+ const { act, isHost } = useCollab();
7938
+ const [answering, setAnswering] = (0, import_react4.useState)(false);
7939
+ const [reply, setReply] = (0, import_react4.useState)("");
7940
+ const [notice, show] = useNotice();
7941
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: `mx-meet__collab-card mx-meet__question mx-meet__question--${question.state}`, children: [
7942
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__question-row", children: [
7943
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
7944
+ "button",
7945
+ {
7946
+ type: "button",
7947
+ className: question.upvotedByMe ? "mx-meet__upvote mx-meet__upvote--on" : "mx-meet__upvote",
7948
+ "aria-pressed": question.upvotedByMe,
7949
+ "aria-label": question.upvotedByMe ? "Remove your upvote" : "Upvote",
7950
+ disabled: question.state === "dismissed",
7951
+ onClick: () => void act({ action: "question_upvote", itemId: question.id }).then((r) => r.ok ? void 0 : show(r)),
7952
+ children: [
7953
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UpvoteIcon, { width: 16, height: 16 }),
7954
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: question.upvotes })
7955
+ ]
7956
+ }
7957
+ ),
7958
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__question-body", children: [
7959
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__chat-meta", children: [
7960
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: question.mine ? "You" : question.askerName }),
7961
+ question.mine && question.anonymous ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__chat-private", children: "anonymous" }) : null,
7962
+ question.state !== "open" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__collab-state", children: question.state === "answered" ? "Answered" : "Dismissed" }) : null
7963
+ ] }),
7964
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__chat-text", children: question.text }),
7965
+ question.answer !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__question-answer", children: [
7966
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("strong", { children: [
7967
+ question.answeredByName ?? "Host",
7968
+ ":"
7969
+ ] }),
7970
+ " ",
7971
+ question.answer
7972
+ ] }) : null
7973
+ ] })
7974
+ ] }),
7975
+ answering ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
7976
+ "form",
7977
+ {
7978
+ className: "mx-meet__composer-row",
7979
+ onSubmit: (event) => {
7980
+ event.preventDefault();
7981
+ void act({ action: "question_answer", itemId: question.id, text: reply }).then((r) => {
7982
+ show(r);
7983
+ if (r.ok) {
7984
+ setAnswering(false);
7985
+ setReply("");
7986
+ }
7987
+ });
7988
+ },
7989
+ children: [
7990
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
7991
+ "input",
7992
+ {
7993
+ className: "mx-meet__input",
7994
+ value: reply,
7995
+ maxLength: 2e3,
7996
+ onChange: (event) => setReply(event.target.value),
7997
+ placeholder: "Type an answer, or leave empty if you answered out loud",
7998
+ "aria-label": "Answer",
7999
+ autoFocus: true
8000
+ }
8001
+ ),
8002
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", className: "mx-meet__send", children: "Done" })
8003
+ ]
8004
+ }
8005
+ ) : null,
8006
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Notice, { notice }),
8007
+ isHost || question.mine ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__collab-actions", children: [
8008
+ isHost && question.state === "open" && !answering ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__chip", onClick: () => setAnswering(true), children: "Answer" }) : null,
8009
+ isHost && question.state === "open" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "question_dismiss", itemId: question.id }).then(show), children: "Dismiss" }) : null,
8010
+ isHost && question.state !== "open" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "question_reopen", itemId: question.id }).then(show), children: "Reopen" }) : null,
8011
+ question.mine || isHost ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => void act({ action: "question_delete", itemId: question.id }).then(show), children: "Delete" }) : null
8012
+ ] }) : null
8013
+ ] });
8014
+ }
8015
+ function QaPanel({ onClose }) {
8016
+ const { collab, act } = useCollab();
8017
+ const [draft, setDraft] = (0, import_react4.useState)("");
8018
+ const [anonymous, setAnonymous] = (0, import_react4.useState)(false);
8019
+ const [order, setOrder] = (0, import_react4.useState)("popular");
8020
+ const [notice, show] = useNotice();
8021
+ const allowAnonymous = collab?.settings?.qaAnonymousAllowed === true;
8022
+ const questions = [...collab?.questions ?? []];
8023
+ const rank = (q) => q.state === "open" ? 0 : q.state === "answered" ? 1 : 2;
8024
+ questions.sort(
8025
+ (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 ?? "")
8026
+ );
8027
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(PanelShell, { title: "Q&A", onClose, children: [
8028
+ collab?.error != null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
8029
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
8030
+ "form",
8031
+ {
8032
+ className: "mx-meet__composer mx-meet__composer--chat",
8033
+ onSubmit: (event) => {
8034
+ event.preventDefault();
8035
+ const text3 = draft.trim();
8036
+ if (text3.length === 0) return;
8037
+ void act({ action: "question_ask", text: text3, anonymous: allowAnonymous && anonymous }).then((r) => {
8038
+ if (r.ok) setDraft("");
8039
+ else show(r);
8040
+ });
8041
+ },
8042
+ children: [
8043
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__composer-row", children: [
8044
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8045
+ "input",
8046
+ {
8047
+ className: "mx-meet__input",
8048
+ value: draft,
8049
+ maxLength: 1e3,
8050
+ onChange: (event) => setDraft(event.target.value),
8051
+ placeholder: "Ask the host a question",
8052
+ "aria-label": "Ask the host a question"
8053
+ }
8054
+ ),
8055
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", className: "mx-meet__send", disabled: draft.trim().length === 0, children: "Ask" })
8056
+ ] }),
8057
+ allowAnonymous ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__toggle", children: [
8058
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { type: "checkbox", checked: anonymous, onChange: (event) => setAnonymous(event.target.checked) }),
8059
+ "Ask anonymously"
8060
+ ] }) : null
8061
+ ]
8062
+ }
8063
+ ),
8064
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Notice, { notice }),
8065
+ questions.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__pills", role: "group", "aria-label": "Order questions", children: ["popular", "recent"].map((value) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8066
+ "button",
8067
+ {
8068
+ type: "button",
8069
+ className: order === value ? "mx-meet__pill mx-meet__pill--on" : "mx-meet__pill",
8070
+ "aria-pressed": order === value,
8071
+ onClick: () => setOrder(value),
8072
+ children: value === "popular" ? "Popular" : "Recent"
8073
+ },
8074
+ value
8075
+ )) }) : null,
8076
+ questions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: "No questions yet. Questions are kept with the meeting." }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet__chat", children: questions.map((question) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(QuestionCard, { question }, question.id)) })
8077
+ ] });
8078
+ }
8079
+ var BOARD_W = 1600;
8080
+ var BOARD_H = 1e3;
8081
+ var INK = ["#111827", "#dc2626", "#2563eb", "#16a34a", "#f59e0b", "#7c3aed"];
8082
+ function strokePath(points) {
8083
+ if (points.length === 0) return "";
8084
+ const [first, ...rest] = points;
8085
+ const move = `M${(first[0] * BOARD_W).toFixed(1)} ${(first[1] * BOARD_H).toFixed(1)}`;
8086
+ if (rest.length === 0) return `${move} l0.1 0`;
8087
+ return `${move} ${rest.map(([x, y]) => `L${(x * BOARD_W).toFixed(1)} ${(y * BOARD_H).toFixed(1)}`).join(" ")}`;
8088
+ }
8089
+ function StrokeView({ stroke, onPick }) {
8090
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8091
+ "path",
8092
+ {
8093
+ d: strokePath(stroke.points),
8094
+ fill: "none",
8095
+ stroke: stroke.color,
8096
+ strokeWidth: stroke.tool === "highlighter" ? stroke.width * 4 : stroke.width,
8097
+ strokeOpacity: stroke.tool === "highlighter" ? 0.35 : stroke.pending === true ? 0.6 : 1,
8098
+ strokeLinecap: "round",
8099
+ strokeLinejoin: "round",
8100
+ onPointerDown: onPick,
8101
+ style: onPick !== void 0 ? { cursor: "pointer" } : void 0,
8102
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("title", { children: stroke.byName })
8103
+ }
8104
+ );
8105
+ }
8106
+ function WhiteboardPanel({ onClose }) {
8107
+ const { collab, act, isHost, localIdentity } = useCollab();
8108
+ const [tool, setTool] = (0, import_react4.useState)("pen");
8109
+ const [color, setColor] = (0, import_react4.useState)(INK[0]);
8110
+ const [drawing, setDrawing] = (0, import_react4.useState)(null);
8111
+ const [pending, setPending] = (0, import_react4.useState)([]);
8112
+ const [notice, show] = useNotice();
8113
+ const svgRef = (0, import_react4.useRef)(null);
8114
+ const strokes = collab?.strokes ?? [];
8115
+ const mine = strokes.filter((s) => s.by === localIdentity);
8116
+ const point = (event) => {
8117
+ const svg = svgRef.current;
8118
+ if (svg === null) return null;
8119
+ const rect = svg.getBoundingClientRect();
8120
+ const scale = Math.min(rect.width / BOARD_W, rect.height / BOARD_H);
8121
+ const offsetX = (rect.width - BOARD_W * scale) / 2;
8122
+ const offsetY = (rect.height - BOARD_H * scale) / 2;
8123
+ const x = (event.clientX - rect.left - offsetX) / (BOARD_W * scale);
8124
+ const y = (event.clientY - rect.top - offsetY) / (BOARD_H * scale);
8125
+ return [Math.min(1, Math.max(0, x)), Math.min(1, Math.max(0, y))];
8126
+ };
8127
+ const finish = () => {
8128
+ const points = drawing;
8129
+ setDrawing(null);
8130
+ if (points === null || points.length === 0 || tool === "eraser") return;
8131
+ const thinned = points.filter((p, i) => i === 0 || i === points.length - 1 || i % 2 === 0).slice(0, 2e3);
8132
+ const stroke = {
8133
+ points: thinned.map(([x, y]) => [Number(x.toFixed(4)), Number(y.toFixed(4))]),
8134
+ color,
8135
+ width: tool === "highlighter" ? 4 : 3,
8136
+ tool: tool === "highlighter" ? "highlighter" : "pen"
8137
+ };
8138
+ const localId = `pending-${Date.now()}`;
8139
+ setPending((list) => [...list, { id: localId, ...stroke, by: localIdentity ?? "", byName: "You", pending: true }]);
8140
+ void act({ action: "stroke_add", stroke }).then((result) => {
8141
+ setPending((list) => list.filter((s) => s.id !== localId));
8142
+ if (!result.ok) show(result);
8143
+ });
8144
+ };
8145
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__whiteboard", "aria-label": "Whiteboard", children: [
8146
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "mx-meet__whiteboard-bar", children: [
8147
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { className: "mx-meet__panel-title", children: "Whiteboard" }),
8148
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__pills", role: "group", "aria-label": "Tool", children: [
8149
+ ["pen", "Pen", /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PencilIcon, { width: 16, height: 16 }, "p")],
8150
+ ["highlighter", "Highlighter", /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HighlighterIcon, { width: 16, height: 16 }, "h")],
8151
+ ["eraser", "Eraser \u2014 click a stroke", /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(EraserIcon, { width: 16, height: 16 }, "e")]
8152
+ ].map(([value, label, icon]) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8153
+ "button",
8154
+ {
8155
+ type: "button",
8156
+ className: tool === value ? "mx-meet__pill mx-meet__pill--on" : "mx-meet__pill",
8157
+ "aria-pressed": tool === value,
8158
+ "aria-label": label,
8159
+ title: label,
8160
+ onClick: () => setTool(value),
8161
+ children: icon
8162
+ },
8163
+ value
8164
+ )) }),
8165
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__swatches", role: "group", "aria-label": "Color", children: INK.map((ink) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8166
+ "button",
8167
+ {
8168
+ type: "button",
8169
+ className: ink === color ? "mx-meet__swatch mx-meet__swatch--on" : "mx-meet__swatch",
8170
+ style: { background: ink },
8171
+ "aria-label": `Color ${ink}`,
8172
+ "aria-pressed": ink === color,
8173
+ onClick: () => {
8174
+ setColor(ink);
8175
+ if (tool === "eraser") setTool("pen");
8176
+ }
8177
+ },
8178
+ ink
8179
+ )) }),
8180
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8181
+ ControlButton,
8182
+ {
8183
+ label: "Undo my last stroke",
8184
+ onClick: () => {
8185
+ const last = mine[mine.length - 1];
8186
+ if (last !== void 0) void act({ action: "stroke_erase", itemId: last.id }).then((r) => r.ok ? void 0 : show(r));
8187
+ },
8188
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UndoIcon, { width: 16, height: 16 })
8189
+ }
8190
+ ),
8191
+ isHost && strokes.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "whiteboard_clear" }).then(show), children: "Clear board" }) : null,
8192
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__whiteboard-note", children: "Saved with the meeting" }),
8193
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ControlButton, { label: "Close whiteboard", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CloseIcon, { width: 16, height: 16 }) })
8194
+ ] }),
8195
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Notice, { notice }),
8196
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
8197
+ "svg",
8198
+ {
8199
+ ref: svgRef,
8200
+ className: tool === "eraser" ? "mx-meet__board mx-meet__board--erase" : "mx-meet__board",
8201
+ viewBox: `0 0 ${BOARD_W} ${BOARD_H}`,
8202
+ preserveAspectRatio: "xMidYMid meet",
8203
+ role: "img",
8204
+ "aria-label": `Shared whiteboard, ${strokes.length} strokes`,
8205
+ onPointerDown: (event) => {
8206
+ if (tool === "eraser") return;
8207
+ const p = point(event);
8208
+ if (p === null) return;
8209
+ event.target.setPointerCapture?.(event.pointerId);
8210
+ setDrawing([p]);
8211
+ },
8212
+ onPointerMove: (event) => {
8213
+ if (drawing === null) return;
8214
+ const p = point(event);
8215
+ if (p !== null) setDrawing([...drawing, p]);
8216
+ },
8217
+ onPointerUp: finish,
8218
+ onPointerCancel: finish,
8219
+ children: [
8220
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("rect", { x: 0, y: 0, width: BOARD_W, height: BOARD_H, className: "mx-meet__board-paper" }),
8221
+ strokes.map((stroke) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8222
+ StrokeView,
8223
+ {
8224
+ stroke,
8225
+ onPick: tool === "eraser" && (isHost || stroke.by === localIdentity) ? () => void act({ action: "stroke_erase", itemId: stroke.id }).then((r) => r.ok ? void 0 : show(r)) : void 0
8226
+ },
8227
+ stroke.id
8228
+ )),
8229
+ pending.map((stroke) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(StrokeView, { stroke }, stroke.id)),
8230
+ drawing !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8231
+ StrokeView,
8232
+ {
8233
+ stroke: {
8234
+ id: "drawing",
8235
+ points: drawing,
8236
+ color,
8237
+ width: tool === "highlighter" ? 4 : 3,
8238
+ tool: tool === "highlighter" ? "highlighter" : "pen",
8239
+ by: "",
8240
+ byName: "You"
8241
+ }
8242
+ }
8243
+ ) : null
8244
+ ]
8245
+ }
8246
+ )
8247
+ ] });
8248
+ }
8249
+ function clock(ms2) {
8250
+ const total = Math.ceil(ms2 / 1e3);
8251
+ const minutes = Math.floor(total / 60);
8252
+ const seconds = total % 60;
8253
+ return `${minutes}:${seconds.toString().padStart(2, "0")}`;
8254
+ }
8255
+ function useNow(active) {
8256
+ const [now, setNow] = (0, import_react4.useState)(() => Date.now());
8257
+ (0, import_react4.useEffect)(() => {
8258
+ if (!active) return void 0;
8259
+ const timer = setInterval(() => setNow(Date.now()), 1e3);
8260
+ return () => clearInterval(timer);
8261
+ }, [active]);
8262
+ return now;
8263
+ }
8264
+ function BreakoutSetup() {
8265
+ const { collab, act } = useCollab();
8266
+ const snapshot = useMeetSnapshot();
8267
+ const settings = collab?.settings ?? null;
8268
+ const people = (snapshot?.participants ?? []).filter(
8269
+ (p) => !p.isAgent && p.role !== "host" && p.role !== "cohost"
8270
+ );
8271
+ const [count2, setCount] = (0, import_react4.useState)(Math.min(Math.max(2, Math.ceil(people.length / 4)), settings?.breakoutMaxRooms ?? 20));
8272
+ const [mode, setMode] = (0, import_react4.useState)("auto");
8273
+ const [minutes, setMinutes] = (0, import_react4.useState)(settings?.breakoutDefaultMinutes ?? 15);
8274
+ const [manual, setManual] = (0, import_react4.useState)({});
8275
+ const [busy, setBusy] = (0, import_react4.useState)(false);
8276
+ const [notice, show] = useNotice();
8277
+ const max = settings?.breakoutMaxRooms ?? 20;
8278
+ const rooms = Math.min(Math.max(1, count2), max);
8279
+ const assignment = mode === "auto" ? autoAssign(
8280
+ people.map((p) => p.identity),
8281
+ rooms
8282
+ ) : mode === "manual" ? Array.from(
8283
+ { length: rooms },
8284
+ (_, index) => people.filter((p) => (manual[p.identity] ?? -1) === index).map((p) => p.identity)
8285
+ ) : Array.from({ length: rooms }, () => []);
8286
+ const nameOf = (identity) => people.find((p) => p.identity === identity)?.displayName ?? identity;
8287
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__collab-card", children: [
8288
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
8289
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: "Rooms" }),
8290
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8291
+ "input",
8292
+ {
8293
+ className: "mx-meet__input",
8294
+ type: "number",
8295
+ min: 1,
8296
+ max,
8297
+ value: count2,
8298
+ onChange: (event) => setCount(Number(event.target.value) || 1)
8299
+ }
8300
+ )
8301
+ ] }),
8302
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__pills", role: "group", "aria-label": "How people are placed", children: [
8303
+ ["auto", "Automatically"],
8304
+ ["manual", "Manually"],
8305
+ ["choose", "Let people choose"]
8306
+ ].map(([value, label]) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8307
+ "button",
8308
+ {
8309
+ type: "button",
8310
+ className: mode === value ? "mx-meet__pill mx-meet__pill--on" : "mx-meet__pill",
8311
+ "aria-pressed": mode === value,
8312
+ onClick: () => setMode(value),
8313
+ children: label
8314
+ },
8315
+ value
8316
+ )) }),
8317
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
8318
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: "Timer (minutes, 0 for none)" }),
8319
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8320
+ "input",
8321
+ {
8322
+ className: "mx-meet__input",
8323
+ type: "number",
8324
+ min: 0,
8325
+ max: 720,
8326
+ value: minutes,
8327
+ onChange: (event) => setMinutes(Math.max(0, Number(event.target.value) || 0))
8328
+ }
8329
+ )
8330
+ ] }),
8331
+ mode === "manual" ? people.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: "Nobody else is in the meeting yet." }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet__people", children: people.map((person) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet__person", children: [
8332
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__person-name", children: person.displayName }),
8333
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
8334
+ "select",
8335
+ {
8336
+ className: "mx-meet__select mx-meet__select--compact",
8337
+ "aria-label": `Room for ${person.displayName}`,
8338
+ value: manual[person.identity] ?? -1,
8339
+ onChange: (event) => setManual({ ...manual, [person.identity]: Number(event.target.value) }),
8340
+ children: [
8341
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: -1, children: "Main room" }),
8342
+ Array.from({ length: rooms }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("option", { value: index, children: [
8343
+ "Room ",
8344
+ index + 1
8345
+ ] }, index))
8346
+ ]
8347
+ }
8348
+ )
8349
+ ] }, person.identity)) }) : mode === "auto" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet__breakout-rooms", children: assignment.map((members, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { children: [
8350
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("strong", { children: [
8351
+ "Room ",
8352
+ index + 1
8353
+ ] }),
8354
+ " ",
8355
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__panel-note", children: members.length === 0 ? "empty" : members.map(nameOf).join(", ") })
8356
+ ] }, index)) }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: "Everyone picks a room from their own screen." }),
8357
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Notice, { notice }),
8358
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
8359
+ "button",
8360
+ {
8361
+ type: "button",
8362
+ className: "mx-meet__primary mx-meet__primary--small",
8363
+ disabled: busy,
8364
+ onClick: () => {
8365
+ setBusy(true);
8366
+ void act({
8367
+ action: "breakout_open",
8368
+ rooms: assignment.map((identities, index) => ({ name: `Room ${index + 1}`, identities })),
8369
+ allowChoose: mode === "choose",
8370
+ minutes
8371
+ }).then((result) => {
8372
+ setBusy(false);
8373
+ show(result);
8374
+ });
8375
+ },
8376
+ children: [
8377
+ "Open ",
8378
+ rooms,
8379
+ " room",
8380
+ rooms === 1 ? "" : "s"
8381
+ ]
8382
+ }
8383
+ )
8384
+ ] });
8385
+ }
8386
+ function BreakoutRun({ plan }) {
8387
+ const { act, moveTo, isHost, breakoutRoomId, localIdentity } = useCollab();
8388
+ const snapshot = useMeetSnapshot();
8389
+ const now = useNow(plan.endsAt !== null);
8390
+ const remaining = breakoutRemainingMs(plan, now);
8391
+ const [broadcast, setBroadcast] = (0, import_react4.useState)("");
8392
+ const [notice, show] = useNotice();
8393
+ const nameOf = (identity) => displayNameFor(snapshot?.names ?? {}, identity, snapshot?.participants.find((p) => p.identity === identity)?.displayName);
8394
+ const mine = assignedRoom(plan, localIdentity);
8395
+ const join = async (roomId) => {
8396
+ const said = await act({ action: "breakout_join", roomId });
8397
+ if (!said.ok) {
8398
+ show(said);
8399
+ return;
8400
+ }
8401
+ show(await moveTo(roomId));
8402
+ };
8403
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__collab-card", children: [
8404
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__panel-note", children: [
8405
+ plan.rooms.length,
8406
+ " room",
8407
+ plan.rooms.length === 1 ? "" : "s",
8408
+ " open",
8409
+ remaining !== null ? ` \xB7 ${clock(remaining)} left` : "",
8410
+ plan.allowChoose ? " \xB7 people choose their room" : ""
8411
+ ] }),
8412
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet__breakout-rooms", children: plan.rooms.map((room) => {
8413
+ const here = breakoutRoomId === room.id;
8414
+ const mayJoin = isHost || plan.allowChoose || mine?.id === room.id;
8415
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: here ? "mx-meet__breakout-room mx-meet__breakout-room--here" : "mx-meet__breakout-room", children: [
8416
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__collab-head", children: [
8417
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: room.name }),
8418
+ here ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__collab-state", children: "You are here" }) : mayJoin ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__chip", onClick: () => void join(room.id), children: "Join" }) : null
8419
+ ] }),
8420
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__panel-note", children: room.identities.length === 0 ? "Nobody assigned" : room.identities.map(nameOf).join(", ") }),
8421
+ isHost && room.identities.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet__people", children: room.identities.map((identity) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet__person", children: [
8422
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__person-name", children: nameOf(identity) }),
8423
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
8424
+ "select",
8425
+ {
8426
+ className: "mx-meet__select mx-meet__select--compact",
8427
+ "aria-label": `Move ${nameOf(identity)}`,
8428
+ value: room.id,
8429
+ onChange: (event) => void act({
8430
+ action: "breakout_move",
8431
+ identity,
8432
+ roomId: event.target.value === "" ? null : event.target.value
8433
+ }).then(show),
8434
+ children: [
8435
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "", children: "Main room" }),
8436
+ plan.rooms.map((option) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: option.id, children: option.name }, option.id))
8437
+ ]
8438
+ }
8439
+ )
8440
+ ] }, identity)) }) : null
8441
+ ] }, room.id);
8442
+ }) }),
8443
+ breakoutRoomId !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__chip", onClick: () => void join(null), children: "Return to the main room" }) : null,
8444
+ isHost ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
8445
+ "form",
8446
+ {
8447
+ className: "mx-meet__composer-row",
8448
+ onSubmit: (event) => {
8449
+ event.preventDefault();
8450
+ const text3 = broadcast.trim();
8451
+ if (text3.length === 0) return;
8452
+ void act({ action: "breakout_broadcast", text: text3 }).then((result) => {
8453
+ show(result);
8454
+ if (result.ok) setBroadcast("");
8455
+ });
8456
+ },
8457
+ children: [
8458
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8459
+ "input",
8460
+ {
8461
+ className: "mx-meet__input",
8462
+ value: broadcast,
8463
+ maxLength: 500,
8464
+ onChange: (event) => setBroadcast(event.target.value),
8465
+ placeholder: "Message every room",
8466
+ "aria-label": "Message every room"
8467
+ }
8468
+ ),
8469
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", className: "mx-meet__send", disabled: broadcast.trim().length === 0, children: "Send" })
8470
+ ]
8471
+ }
8472
+ ) : null,
8473
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Notice, { notice }),
8474
+ isHost ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8475
+ "button",
8476
+ {
8477
+ type: "button",
8478
+ className: "mx-meet__primary mx-meet__primary--small",
8479
+ onClick: () => void act({ action: "breakout_close" }).then(show),
8480
+ children: "Bring everyone back"
8481
+ }
8482
+ ) : null
8483
+ ] });
8484
+ }
8485
+ function BreakoutsPanel({ onClose }) {
8486
+ const { collab, isHost } = useCollab();
8487
+ const plan = collab?.breakout?.state === "open" ? collab.breakout : null;
8488
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(PanelShell, { title: "Breakout rooms", onClose, children: [
8489
+ collab?.error != null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
8490
+ plan !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(BreakoutRun, { plan }) : isHost ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(BreakoutSetup, {}) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: "Breakout rooms are closed." })
8491
+ ] });
8492
+ }
8493
+ function BreakoutBanner() {
8494
+ const host = useMeetHost();
8495
+ const { collab, act, moveTo, localIdentity, breakoutRoomId } = useCollab();
8496
+ const plan = collab?.breakout ?? null;
8497
+ const open = plan?.state === "open" ? plan : null;
8498
+ const now = useNow(open?.endsAt != null);
8499
+ const remaining = breakoutRemainingMs(open, now);
8500
+ const assigned = assignedRoom(open, localIdentity);
8501
+ const [dismissedBroadcast, setDismissedBroadcast] = (0, import_react4.useState)(null);
8502
+ const [failure, setFailure] = (0, import_react4.useState)(null);
8503
+ const expireAsked = (0, import_react4.useRef)(null);
8504
+ const moveAt = collab?.moveRequest?.at ?? null;
8505
+ (0, import_react4.useEffect)(() => {
8506
+ const request = host?.store.snapshot().collab.moveRequest ?? null;
8507
+ if (request === null || host === null) return;
8508
+ host.store.patch({ collab: { ...host.store.snapshot().collab, moveRequest: null } });
8509
+ const here = host.store.snapshot().breakoutRoomId;
8510
+ if ((here ?? null) === request.roomId) return;
8511
+ void moveTo(request.roomId).then((result) => setFailure(result.ok ? null : result.message));
8512
+ }, [moveAt, host, moveTo]);
8513
+ (0, import_react4.useEffect)(() => {
8514
+ if (open === null || remaining === null || remaining > 0) return;
8515
+ if (expireAsked.current === open.id) return;
8516
+ expireAsked.current = open.id;
8517
+ void act({ action: "breakout_expire" });
8518
+ }, [open, remaining, act]);
8519
+ const broadcast = collab?.broadcast ?? null;
8520
+ const showBroadcast = broadcast !== null && broadcast.at !== dismissedBroadcast && open !== null;
8521
+ const room = open?.rooms.find((r) => r.id === breakoutRoomId) ?? null;
8522
+ if (open === null && failure === null) return null;
8523
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__breakout-banner", role: "status", children: [
8524
+ failure !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__collab-error", children: failure }) : null,
8525
+ room !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { children: [
8526
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: room.name }),
8527
+ remaining !== null ? ` \xB7 ${clock(remaining)} left` : "",
8528
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__chip", onClick: () => void moveTo(null), children: "Return to main room" })
8529
+ ] }) : assigned !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { children: [
8530
+ "You are assigned to ",
8531
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: assigned.name }),
8532
+ remaining !== null ? ` \xB7 ${clock(remaining)} left` : "",
8533
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8534
+ "button",
8535
+ {
8536
+ type: "button",
8537
+ className: "mx-meet__primary mx-meet__primary--small",
8538
+ onClick: () => void act({ action: "breakout_join", roomId: assigned.id }).then(async (said) => {
8539
+ const result = said.ok ? await moveTo(assigned.id) : said;
8540
+ setFailure(result.ok ? null : result.message);
8541
+ }),
8542
+ children: "Join"
8543
+ }
8544
+ )
8545
+ ] }) : open?.allowChoose ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "Breakout rooms are open \u2014 pick one under Activities." }) : null,
8546
+ showBroadcast ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__breakout-broadcast", children: [
8547
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("strong", { children: [
8548
+ broadcast.by,
8549
+ ":"
8550
+ ] }),
8551
+ " ",
8552
+ broadcast.text,
8553
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => setDismissedBroadcast(broadcast.at), children: "Dismiss" })
8554
+ ] }) : null
8555
+ ] });
8556
+ }
8557
+ function useCaptionTranslation(lines) {
8558
+ const host = useMeetHost();
8559
+ const snapshot = useMeetSnapshot();
8560
+ const collab = snapshot?.collab ?? null;
8561
+ const language = collab?.captionLanguage ?? null;
8562
+ const asked = (0, import_react4.useRef)(/* @__PURE__ */ new Set());
8563
+ const translations = collab?.captionTranslations ?? {};
8564
+ const missing = lines.filter((line) => line.final && translations[line.id] === void 0).map(({ id, text: text3 }) => ({ id, text: text3 }));
8565
+ const key = `${language ?? ""}|${missing.map((l) => l.id).join(",")}`;
8566
+ const pending = (0, import_react4.useRef)(missing);
8567
+ pending.current = missing;
8568
+ (0, import_react4.useEffect)(() => {
8569
+ if (host === null || language === null) return;
8570
+ const batch = pending.current.filter((line) => !asked.current.has(`${language}:${line.id}`)).slice(-20);
8571
+ if (batch.length === 0) return;
8572
+ for (const line of batch) asked.current.add(`${language}:${line.id}`);
8573
+ void host.inRoom.translateCaptions(language, batch).catch(() => void 0);
8574
+ }, [host, language, key]);
8575
+ return { language, translations, error: collab?.captionTranslationError ?? null };
8576
+ }
8577
+ function CaptionLanguageSettings() {
8578
+ const host = useMeetHost();
8579
+ const snapshot = useMeetSnapshot();
8580
+ const collab = snapshot?.collab ?? null;
8581
+ const settings = collab?.settings ?? null;
8582
+ if (host === null || settings === null || !settings.captionTranslationEnabled) return null;
8583
+ const viewer = typeof navigator !== "undefined" && typeof navigator.language === "string" ? navigator.language.slice(0, 2) : null;
8584
+ const preferred = defaultCaptionLanguage(settings, viewer);
8585
+ const current = collab?.captionLanguage ?? "";
8586
+ const choices = CAPTION_LANGUAGES.some((l) => l.tag === preferred) ? CAPTION_LANGUAGES : [{ tag: preferred, name: preferred }, ...CAPTION_LANGUAGES];
8587
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__section", "aria-label": "Captions", children: [
8588
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
8589
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: "Translate captions to" }),
8590
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
8591
+ "select",
8592
+ {
8593
+ className: "mx-meet__select",
8594
+ value: current,
8595
+ onChange: (event) => {
8596
+ const next = event.target.value === "" ? null : event.target.value;
8597
+ host.store.patch({
8598
+ collab: {
8599
+ ...host.store.snapshot().collab,
8600
+ captionLanguage: next,
8601
+ captionTranslations: {},
8602
+ captionTranslationError: null
8603
+ }
8604
+ });
8605
+ },
8606
+ children: [
8607
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "", children: "Off \u2014 as spoken" }),
8608
+ current === "" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("option", { value: preferred, children: [
8609
+ choices.find((c) => c.tag === preferred)?.name ?? preferred,
8610
+ " (yours)"
8611
+ ] }) : null,
8612
+ choices.filter((choice) => current !== "" || choice.tag !== preferred).map((choice) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: choice.tag, children: choice.name }, choice.tag))
8613
+ ]
8614
+ }
8615
+ )
8616
+ ] }),
8617
+ collab?.captionTranslationError != null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.captionTranslationError }) : null
8618
+ ] });
8619
+ }
8620
+ function useCollabPanelRequest(onRequest) {
8621
+ const host = useMeetHost();
8622
+ const at = useMeetSnapshot()?.collab.panelRequest?.at ?? null;
8623
+ const callback = (0, import_react4.useRef)(onRequest);
8624
+ callback.current = onRequest;
8625
+ (0, import_react4.useEffect)(() => {
8626
+ const request = host?.store.snapshot().collab.panelRequest ?? null;
8627
+ if (request === null || host === null) return;
8628
+ host.store.patch({ collab: { ...host.store.snapshot().collab, panelRequest: null } });
8629
+ callback.current(request.panel);
8630
+ }, [at, host]);
8631
+ }
8632
+
8633
+ // src/react/components.tsx
8634
+ var import_jsx_runtime4 = require("react/jsx-runtime");
8635
+ function InertNotice({ what }) {
8636
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__empty", role: "status", children: [
8637
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__empty-title", children: [
8638
+ what,
8639
+ " is not ready yet"
8640
+ ] }),
8641
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-body", children: "Calls and meetings need a signed-in identity and an active organization. This will appear as soon as they resolve." })
8642
+ ] });
8643
+ }
8644
+ function Avatar({
8645
+ name,
8646
+ url,
8647
+ size = 40
8648
+ }) {
8649
+ const tint = (0, import_format3.avatarPaletteIndex)(name);
8650
+ if (url != null && url.length > 0) {
8651
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8652
+ "img",
8653
+ {
8654
+ className: "mx-meet__avatar",
8655
+ src: url,
8656
+ alt: "",
8657
+ width: size,
8658
+ height: size,
8659
+ style: { width: size, height: size }
8660
+ }
8661
+ );
8662
+ }
8663
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8664
+ "span",
8665
+ {
8666
+ className: "mx-meet__avatar mx-meet__avatar--initials",
8667
+ style: {
8668
+ width: size,
8669
+ height: size,
8670
+ fontSize: Math.round(size * 0.38),
8671
+ background: `var(--mx-meet-avatar-${tint})`
8672
+ },
8673
+ "aria-hidden": "true",
8674
+ children: (0, import_format3.getInitials)(name)
8675
+ }
8676
+ );
8677
+ }
8678
+ function ControlButton({
8679
+ label,
8680
+ active = false,
8681
+ danger = false,
8682
+ onClick,
8683
+ children
8684
+ }) {
8685
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8686
+ "button",
8687
+ {
8688
+ type: "button",
8689
+ className: [
8690
+ "mx-meet__control",
8691
+ active ? "mx-meet__control--active" : "",
8692
+ danger ? "mx-meet__control--danger" : ""
8693
+ ].filter(Boolean).join(" "),
8694
+ "aria-label": label,
8695
+ title: label,
8696
+ onClick,
8697
+ children
8698
+ }
8699
+ );
8700
+ }
8701
+ function RecordingIndicator() {
8702
+ const { state, label } = useRecording();
8703
+ if (label === null) return null;
8704
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8705
+ "span",
8706
+ {
8707
+ className: `mx-meet__recording mx-meet__recording--${state}`,
8708
+ role: "status",
8709
+ "aria-live": "polite",
8710
+ children: [
8711
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RecordIcon, { width: 10, height: 10 }),
8712
+ label
8713
+ ]
8714
+ }
8715
+ );
8716
+ }
8717
+ function ConnectionDot({ quality }) {
8718
+ if (quality === "excellent" || quality === "good" || quality === "unknown") return null;
8719
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: `mx-meet__quality mx-meet__quality--${quality}`, title: `Connection ${quality}`, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(WifiLowIcon, { width: 14, height: 14 }) });
7107
8720
  }
7108
8721
  function RoleBadge({ role }) {
7109
- if (role === "host") return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Host" });
7110
- if (role === "cohost") return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Co-host" });
7111
- if (role === "guest") return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Guest" });
8722
+ if (role === "host") return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__badge", children: "Host" });
8723
+ if (role === "cohost") return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__badge", children: "Co-host" });
8724
+ if (role === "guest") return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__badge", children: "Guest" });
7112
8725
  return null;
7113
8726
  }
7114
8727
  function ParticipantTile({
@@ -7118,7 +8731,7 @@ function ParticipantTile({
7118
8731
  const host = useMeetHost();
7119
8732
  const snapshot = useMeetSnapshot();
7120
8733
  const queue = useHandQueue();
7121
- const [menu, setMenu] = (0, import_react4.useState)(false);
8734
+ const [menu, setMenu] = (0, import_react5.useState)(false);
7122
8735
  const videoRef = useTrack(
7123
8736
  participant.identity,
7124
8737
  participant.screenSharing ? "screen" : "camera"
@@ -7127,7 +8740,7 @@ function ParticipantTile({
7127
8740
  const pinnedHere = snapshot?.pinned === participant.identity;
7128
8741
  const spotlit = snapshot?.spotlight === participant.identity;
7129
8742
  const handPosition = participant.handRaised ? queue.findIndex((entry) => entry.identity === participant.identity) + 1 : 0;
7130
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
8743
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7131
8744
  "div",
7132
8745
  {
7133
8746
  className: [
@@ -7137,7 +8750,7 @@ function ParticipantTile({
7137
8750
  ].filter(Boolean).join(" "),
7138
8751
  "data-identity": participant.identity,
7139
8752
  children: [
7140
- showVideo ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8753
+ showVideo ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7141
8754
  "video",
7142
8755
  {
7143
8756
  ref: videoRef,
@@ -7146,43 +8759,43 @@ function ParticipantTile({
7146
8759
  playsInline: true,
7147
8760
  muted: participant.isLocal
7148
8761
  }
7149
- ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__tile-placeholder", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: featured ? 96 : 56 }) }),
7150
- participant.handRaised ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__tile-hand", title: `Hand raised \xB7 ${ordinal(handPosition)} in line`, children: [
7151
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HandIcon, { width: 14, height: 14 }),
8762
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__tile-placeholder", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: featured ? 96 : 56 }) }),
8763
+ participant.handRaised ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__tile-hand", title: `Hand raised \xB7 ${ordinal(handPosition)} in line`, children: [
8764
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HandIcon, { width: 14, height: 14 }),
7152
8765
  handPosition > 0 ? handPosition : null
7153
8766
  ] }) : null,
7154
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__tile-bar", children: [
7155
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__tile-name", children: [
7156
- spotlit ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { title: "Spotlighted for everyone", className: "mx-meet__tile-flag", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SpotlightIcon, { width: 12, height: 12 }) }) : null,
8767
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__tile-bar", children: [
8768
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__tile-name", children: [
8769
+ spotlit ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { title: "Spotlighted for everyone", className: "mx-meet__tile-flag", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SpotlightIcon, { width: 12, height: 12 }) }) : null,
7157
8770
  participant.displayName,
7158
8771
  participant.isLocal ? " (you)" : "",
7159
- participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "AI" }) : null,
7160
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RoleBadge, { role: participant.role })
8772
+ participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__badge", children: "AI" }) : null,
8773
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RoleBadge, { role: participant.role })
7161
8774
  ] }),
7162
- !participant.micEnabled ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicOffIcon, { width: 14, height: 14 }) : null,
7163
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(QualityBars, { quality: participant.quality })
8775
+ !participant.micEnabled ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MicOffIcon, { width: 14, height: 14 }) : null,
8776
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(QualityBars, { quality: participant.quality })
7164
8777
  ] }),
7165
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: menu ? "mx-meet__tile-actions mx-meet__tile-actions--open" : "mx-meet__tile-actions", children: [
7166
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8778
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: menu ? "mx-meet__tile-actions mx-meet__tile-actions--open" : "mx-meet__tile-actions", children: [
8779
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7167
8780
  ControlButton,
7168
8781
  {
7169
8782
  label: pinnedHere ? "Unpin" : `Pin ${participant.displayName} for me`,
7170
8783
  active: pinnedHere,
7171
8784
  onClick: () => host?.engine.pin(pinnedHere ? null : participant.identity),
7172
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PinIcon, { width: 16, height: 16 })
8785
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PinIcon, { width: 16, height: 16 })
7173
8786
  }
7174
8787
  ),
7175
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__anchor", children: [
7176
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8788
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__anchor", children: [
8789
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7177
8790
  ControlButton,
7178
8791
  {
7179
8792
  label: `More for ${participant.displayName}`,
7180
8793
  active: menu,
7181
8794
  onClick: () => setMenu(!menu),
7182
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MoreIcon, { width: 16, height: 16 })
8795
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MoreIcon, { width: 16, height: 16 })
7183
8796
  }
7184
8797
  ),
7185
- menu ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PersonMenu, { participant, onClose: () => setMenu(false), placement: "down" }) : null
8798
+ menu ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PersonMenu, { participant, onClose: () => setMenu(false), placement: "down" }) : null
7186
8799
  ] })
7187
8800
  ] })
7188
8801
  ]
@@ -7198,28 +8811,28 @@ function QualityBars({ quality }) {
7198
8811
  if (quality === "unknown") return null;
7199
8812
  const bars = quality === "excellent" ? 3 : quality === "good" ? 2 : quality === "poor" ? 1 : 0;
7200
8813
  const label = quality === "lost" ? "Connection lost" : quality === "poor" ? "Poor connection" : `Connection ${quality}`;
7201
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: `mx-meet__signal mx-meet__signal--${quality}`, title: label, "aria-label": label, role: "img", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SignalIcon, { bars, width: 14, height: 14 }) });
8814
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: `mx-meet__signal mx-meet__signal--${quality}`, title: label, "aria-label": label, role: "img", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SignalIcon, { bars, width: 14, height: 14 }) });
7202
8815
  }
7203
8816
  function Stage({ pageSize }) {
7204
8817
  const stage = useStage(pageSize);
7205
8818
  const columns = gridColumns(stage.tiles.length);
7206
8819
  if (stage.feature === null && stage.tiles.length === 0) {
7207
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__stage mx-meet__stage--empty", children: [
7208
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-title", children: "Waiting for others to join" }),
7209
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-body", children: "Share the meeting link and people can join from anywhere \u2014 no account needed." })
8820
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__stage mx-meet__stage--empty", children: [
8821
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-title", children: "Waiting for others to join" }),
8822
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-body", children: "Share the meeting link and people can join from anywhere \u2014 no account needed." })
7210
8823
  ] });
7211
8824
  }
7212
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `mx-meet__stage${stage.feature !== null ? " mx-meet__stage--speaker" : ""}`, children: [
7213
- stage.feature !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ParticipantTile, { participant: stage.feature, featured: true }) : null,
7214
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8825
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: `mx-meet__stage${stage.feature !== null ? " mx-meet__stage--speaker" : ""}`, children: [
8826
+ stage.feature !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ParticipantTile, { participant: stage.feature, featured: true }) : null,
8827
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7215
8828
  "div",
7216
8829
  {
7217
8830
  className: "mx-meet__grid",
7218
8831
  style: { "--mx-meet-columns": columns },
7219
- children: stage.tiles.map((participant) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ParticipantTile, { participant }, participant.identity))
8832
+ children: stage.tiles.map((participant) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ParticipantTile, { participant }, participant.identity))
7220
8833
  }
7221
8834
  ),
7222
- stage.overflow > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__overflow", children: [
8835
+ stage.overflow > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__overflow", children: [
7223
8836
  "+",
7224
8837
  stage.overflow,
7225
8838
  " more ",
@@ -7232,20 +8845,28 @@ var MEET_REACTIONS = ["\u{1F496}", "\u{1F44D}", "\u{1F389}", "\u{1F44F}", "\u{1F
7232
8845
  function ControlBar({ onLeave }) {
7233
8846
  const room = useRoom();
7234
8847
  const recording = useRecording();
7235
- const [panel, setPanel] = (0, import_react4.useState)("none");
7236
- const [chatTo, setChatTo] = (0, import_react4.useState)(null);
7237
- const [popover, setPopover] = (0, import_react4.useState)("none");
7238
- const [shortcuts, setShortcuts] = (0, import_react4.useState)(false);
8848
+ const [panel, setPanel] = (0, import_react5.useState)("none");
8849
+ const [chatTo, setChatTo] = (0, import_react5.useState)(null);
8850
+ const [popover, setPopover] = (0, import_react5.useState)("none");
8851
+ const [shortcuts, setShortcuts] = (0, import_react5.useState)(false);
7239
8852
  const snapshot = useMeetSnapshot();
7240
8853
  const lobby = useLobby();
7241
8854
  const controls = useHostControls();
7242
8855
  const queue = useHandQueue();
7243
8856
  const micUnavailable = useLocalMedia().microphone.unavailable;
7244
8857
  const unread = useUnreadChat(panel === "chat");
8858
+ const [whiteboard, setWhiteboard] = (0, import_react5.useState)(false);
7245
8859
  const toggle = (next) => setPanel(panel === next ? "none" : next);
8860
+ const openActivity = (activity) => {
8861
+ if (activity === "whiteboard") setWhiteboard(true);
8862
+ else setPanel(activity);
8863
+ };
8864
+ useCollabPanelRequest((activity) => {
8865
+ if (!controls.isHost) openActivity(activity);
8866
+ });
7246
8867
  const privateChatAt = snapshot?.privateChatRequest?.at ?? null;
7247
8868
  const meetStore = useMeetHost()?.store ?? null;
7248
- (0, import_react4.useEffect)(() => {
8869
+ (0, import_react5.useEffect)(() => {
7249
8870
  const request = meetStore?.snapshot().privateChatRequest ?? null;
7250
8871
  if (request === null) return;
7251
8872
  setChatTo(request.to);
@@ -7261,11 +8882,11 @@ function ControlBar({ onLeave }) {
7261
8882
  help: () => setShortcuts(true)
7262
8883
  });
7263
8884
  const hasSpotlight = snapshot?.spotlight !== null && snapshot?.spotlight !== void 0;
7264
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
7265
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MeetingOverlays, {}),
7266
- shortcuts ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ShortcutsSheet, { onClose: () => setShortcuts(false) }) : null,
7267
- panel === "chat" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ChatPanel, { onClose: () => setPanel("none"), to: chatTo, onTo: setChatTo }) : null,
7268
- panel === "people" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8885
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
8886
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MeetingOverlays, {}),
8887
+ shortcuts ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ShortcutsSheet, { onClose: () => setShortcuts(false) }) : null,
8888
+ panel === "chat" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChatPanel, { onClose: () => setPanel("none"), to: chatTo, onTo: setChatTo }) : null,
8889
+ panel === "people" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7269
8890
  PeoplePanel,
7270
8891
  {
7271
8892
  onClose: () => setPanel("none"),
@@ -7275,48 +8896,53 @@ function ControlBar({ onLeave }) {
7275
8896
  }
7276
8897
  }
7277
8898
  ) : null,
7278
- panel === "ai" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AiPanel, { onClose: () => setPanel("none") }) : null,
7279
- panel === "settings" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SettingsPanel, { onClose: () => setPanel("none") }) : null,
7280
- controls.notice !== null && panel !== "people" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Toast, { text: controls.notice.text, failed: controls.notice.failed, onDone: controls.clearNotice }) : null,
7281
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__controls", children: [
7282
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8899
+ panel === "ai" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AiPanel, { onClose: () => setPanel("none") }) : null,
8900
+ panel === "settings" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SettingsPanel, { onClose: () => setPanel("none") }) : null,
8901
+ panel === "polls" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PollsPanel, { onClose: () => setPanel("none") }) : null,
8902
+ panel === "qa" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(QaPanel, { onClose: () => setPanel("none") }) : null,
8903
+ panel === "breakouts" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(BreakoutsPanel, { onClose: () => setPanel("none") }) : null,
8904
+ whiteboard ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(WhiteboardPanel, { onClose: () => setWhiteboard(false) }) : null,
8905
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(BreakoutBanner, {}),
8906
+ controls.notice !== null && panel !== "people" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Toast, { text: controls.notice.text, failed: controls.notice.failed, onDone: controls.clearNotice }) : null,
8907
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__controls", children: [
8908
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7283
8909
  ControlButton,
7284
8910
  {
7285
8911
  label: micUnavailable !== null ? `Unmute \u2014 ${micUnavailable.remedy}` : room.local?.micEnabled === true ? "Mute (\u2318D)" : "Unmute (\u2318D)",
7286
8912
  active: room.local?.micEnabled === true,
7287
8913
  onClick: () => void room.toggleMicrophone(),
7288
- children: room.local?.micEnabled === true ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicOffIcon, {})
8914
+ children: room.local?.micEnabled === true ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MicIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MicOffIcon, {})
7289
8915
  }
7290
8916
  ),
7291
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8917
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7292
8918
  ControlButton,
7293
8919
  {
7294
8920
  label: room.local?.cameraEnabled === true ? "Stop video (\u2318E)" : "Start video (\u2318E)",
7295
8921
  active: room.local?.cameraEnabled === true,
7296
8922
  onClick: () => void room.toggleCamera(),
7297
- children: room.local?.cameraEnabled === true ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CameraIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CameraOffIcon, {})
8923
+ children: room.local?.cameraEnabled === true ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CameraIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CameraOffIcon, {})
7298
8924
  }
7299
8925
  ),
7300
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8926
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7301
8927
  ControlButton,
7302
8928
  {
7303
8929
  label: room.local?.screenSharing === true ? "Stop sharing" : "Share screen",
7304
8930
  active: room.local?.screenSharing === true,
7305
8931
  onClick: () => void room.toggleScreenShare(),
7306
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ScreenShareIcon, {})
8932
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ScreenShareIcon, {})
7307
8933
  }
7308
8934
  ),
7309
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__anchor", children: [
7310
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8935
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__anchor", children: [
8936
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7311
8937
  ControlButton,
7312
8938
  {
7313
8939
  label: "Send a reaction",
7314
8940
  active: popover === "reactions",
7315
8941
  onClick: () => setPopover(popover === "reactions" ? "none" : "reactions"),
7316
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SmileIcon, {})
8942
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SmileIcon, {})
7317
8943
  }
7318
8944
  ),
7319
- popover === "reactions" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Popover, { label: "Reactions", onClose: () => setPopover("none"), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__emoji-bar", children: MEET_REACTIONS.map((emoji) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8945
+ popover === "reactions" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Popover, { label: "Reactions", onClose: () => setPopover("none"), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__emoji-bar", children: MEET_REACTIONS.map((emoji) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7320
8946
  "button",
7321
8947
  {
7322
8948
  type: "button",
@@ -7328,46 +8954,53 @@ function ControlBar({ onLeave }) {
7328
8954
  emoji
7329
8955
  )) }) }) : null
7330
8956
  ] }),
7331
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8957
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7332
8958
  ControlButton,
7333
8959
  {
7334
8960
  label: room.local?.handRaised === true ? "Lower hand (\u2318\u2325H)" : "Raise hand (\u2318\u2325H)",
7335
8961
  active: room.local?.handRaised === true,
7336
8962
  onClick: () => void room.toggleHand(),
7337
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HandIcon, {})
8963
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HandIcon, {})
7338
8964
  }
7339
8965
  ),
7340
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(ControlButton, { label: "Chat (\u2318\u2325C)", active: panel === "chat", onClick: () => toggle("chat"), children: [
7341
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ChatIcon, {}),
7342
- unread > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
8966
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(ControlButton, { label: "Chat (\u2318\u2325C)", active: panel === "chat", onClick: () => toggle("chat"), children: [
8967
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChatIcon, {}),
8968
+ unread > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
7343
8969
  ] }),
7344
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
8970
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7345
8971
  ControlButton,
7346
8972
  {
7347
8973
  label: lobby.waiting.length > 0 ? `People \u2014 ${lobby.waiting.length} waiting` : `People \u2014 ${(snapshot?.participants ?? []).length} in the meeting`,
7348
8974
  active: panel === "people",
7349
8975
  onClick: () => toggle("people"),
7350
8976
  children: [
7351
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PeopleIcon, {}),
7352
- lobby.waiting.length > 0 || controls.isHost && queue.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
8977
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PeopleIcon, {}),
8978
+ lobby.waiting.length > 0 || controls.isHost && queue.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
7353
8979
  ]
7354
8980
  }
7355
8981
  ),
7356
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AiControl, { active: panel === "ai", onToggle: () => toggle("ai") }),
7357
- recording.canStart ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ControlButton, { label: "Start recording", onClick: () => void recording.start(), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RecordIcon, {}) }) : null,
7358
- recording.canStop ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ControlButton, { label: "Stop recording", active: true, onClick: () => void recording.stop(), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RecordIcon, {}) }) : null,
7359
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__anchor", children: [
7360
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8982
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8983
+ ActivitiesControl,
8984
+ {
8985
+ active: whiteboard ? "whiteboard" : panel === "polls" || panel === "qa" || panel === "breakouts" ? panel : null,
8986
+ onOpen: openActivity
8987
+ }
8988
+ ),
8989
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AiControl, { active: panel === "ai", onToggle: () => toggle("ai") }),
8990
+ recording.canStart ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ControlButton, { label: "Start recording", onClick: () => void recording.start(), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RecordIcon, {}) }) : null,
8991
+ recording.canStop ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ControlButton, { label: "Stop recording", active: true, onClick: () => void recording.stop(), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RecordIcon, {}) }) : null,
8992
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__anchor", children: [
8993
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7361
8994
  ControlButton,
7362
8995
  {
7363
8996
  label: "More options",
7364
8997
  active: popover === "more" || panel === "settings",
7365
8998
  onClick: () => setPopover(popover === "more" ? "none" : "more"),
7366
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MoreIcon, {})
8999
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MoreIcon, {})
7367
9000
  }
7368
9001
  ),
7369
- popover === "more" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Popover, { label: "More options", onClose: () => setPopover("none"), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__menu", role: "menu", children: [
7370
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9002
+ popover === "more" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Popover, { label: "More options", onClose: () => setPopover("none"), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__menu", role: "menu", children: [
9003
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7371
9004
  MenuItem,
7372
9005
  {
7373
9006
  onSelect: () => {
@@ -7375,12 +9008,12 @@ function ControlBar({ onLeave }) {
7375
9008
  setPanel("settings");
7376
9009
  },
7377
9010
  children: [
7378
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SettingsIcon, { width: 16, height: 16 }),
7379
- " Audio, video and effects"
9011
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SettingsIcon, { width: 16, height: 16 }),
9012
+ " Settings"
7380
9013
  ]
7381
9014
  }
7382
9015
  ),
7383
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9016
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7384
9017
  MenuItem,
7385
9018
  {
7386
9019
  onSelect: () => {
@@ -7388,14 +9021,14 @@ function ControlBar({ onLeave }) {
7388
9021
  setShortcuts(true);
7389
9022
  },
7390
9023
  children: [
7391
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(KeyboardIcon, { width: 16, height: 16 }),
9024
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(KeyboardIcon, { width: 16, height: 16 }),
7392
9025
  " Keyboard shortcuts"
7393
9026
  ]
7394
9027
  }
7395
9028
  ),
7396
- controls.isHost ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
7397
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__menu-sep", role: "separator" }),
7398
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9029
+ controls.isHost ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
9030
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__menu-sep", role: "separator" }),
9031
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7399
9032
  MenuItem,
7400
9033
  {
7401
9034
  onSelect: () => {
@@ -7403,12 +9036,12 @@ function ControlBar({ onLeave }) {
7403
9036
  void controls.run({ action: "mute_all" });
7404
9037
  },
7405
9038
  children: [
7406
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicOffIcon, { width: 16, height: 16 }),
9039
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MicOffIcon, { width: 16, height: 16 }),
7407
9040
  " Mute everyone"
7408
9041
  ]
7409
9042
  }
7410
9043
  ),
7411
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9044
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7412
9045
  MenuItem,
7413
9046
  {
7414
9047
  onSelect: () => {
@@ -7416,12 +9049,12 @@ function ControlBar({ onLeave }) {
7416
9049
  void controls.run({ action: "ask_all_unmute" });
7417
9050
  },
7418
9051
  children: [
7419
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicIcon, { width: 16, height: 16 }),
9052
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MicIcon, { width: 16, height: 16 }),
7420
9053
  " Ask everyone to unmute"
7421
9054
  ]
7422
9055
  }
7423
9056
  ),
7424
- queue.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9057
+ queue.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7425
9058
  MenuItem,
7426
9059
  {
7427
9060
  onSelect: () => {
@@ -7429,14 +9062,14 @@ function ControlBar({ onLeave }) {
7429
9062
  void controls.run({ action: "lower_all_hands" });
7430
9063
  },
7431
9064
  children: [
7432
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HandIcon, { width: 16, height: 16 }),
9065
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HandIcon, { width: 16, height: 16 }),
7433
9066
  " Lower all hands (",
7434
9067
  queue.length,
7435
9068
  ")"
7436
9069
  ]
7437
9070
  }
7438
9071
  ) : null,
7439
- hasSpotlight ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9072
+ hasSpotlight ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7440
9073
  MenuItem,
7441
9074
  {
7442
9075
  onSelect: () => {
@@ -7444,7 +9077,7 @@ function ControlBar({ onLeave }) {
7444
9077
  void controls.run({ action: "spotlight", identity: null });
7445
9078
  },
7446
9079
  children: [
7447
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SpotlightIcon, { width: 16, height: 16 }),
9080
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SpotlightIcon, { width: 16, height: 16 }),
7448
9081
  " Remove spotlight"
7449
9082
  ]
7450
9083
  }
@@ -7452,7 +9085,7 @@ function ControlBar({ onLeave }) {
7452
9085
  ] }) : null
7453
9086
  ] }) }) : null
7454
9087
  ] }),
7455
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9088
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7456
9089
  ControlButton,
7457
9090
  {
7458
9091
  label: "Leave",
@@ -7461,7 +9094,7 @@ function ControlBar({ onLeave }) {
7461
9094
  void room.leave();
7462
9095
  onLeave?.();
7463
9096
  },
7464
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PhoneOffIcon, {})
9097
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PhoneOffIcon, {})
7465
9098
  }
7466
9099
  )
7467
9100
  ] })
@@ -7471,13 +9104,13 @@ function useUnreadChat(open) {
7471
9104
  const snapshot = useMeetSnapshot();
7472
9105
  const chat = snapshot?.chat ?? [];
7473
9106
  const local = snapshot?.localIdentity ?? null;
7474
- const [seen, setSeen] = (0, import_react4.useState)(0);
7475
- (0, import_react4.useEffect)(() => {
9107
+ const [seen, setSeen] = (0, import_react5.useState)(0);
9108
+ (0, import_react5.useEffect)(() => {
7476
9109
  if (open) setSeen(chat.length);
7477
9110
  }, [open, chat.length]);
7478
9111
  const loaded = snapshot?.chatLoaded === true;
7479
- const [baseline, setBaseline] = (0, import_react4.useState)(null);
7480
- (0, import_react4.useEffect)(() => {
9112
+ const [baseline, setBaseline] = (0, import_react5.useState)(null);
9113
+ (0, import_react5.useEffect)(() => {
7481
9114
  if (loaded && baseline === null) setBaseline(chat.length);
7482
9115
  }, [loaded, baseline, chat.length]);
7483
9116
  if (open) return 0;
@@ -7490,14 +9123,14 @@ function Popover({
7490
9123
  children,
7491
9124
  placement = "up"
7492
9125
  }) {
7493
- const ref = (0, import_react4.useRef)(null);
7494
- const [style, setStyle] = (0, import_react4.useState)({
9126
+ const ref = (0, import_react5.useRef)(null);
9127
+ const [style, setStyle] = (0, import_react5.useState)({
7495
9128
  position: "fixed",
7496
9129
  top: 0,
7497
9130
  left: 0,
7498
9131
  visibility: "hidden"
7499
9132
  });
7500
- (0, import_react4.useLayoutEffect)(() => {
9133
+ (0, import_react5.useLayoutEffect)(() => {
7501
9134
  const element = ref.current;
7502
9135
  const anchor = element?.parentElement ?? null;
7503
9136
  if (element === null || anchor === null) return;
@@ -7542,7 +9175,7 @@ function Popover({
7542
9175
  window.removeEventListener("scroll", place, true);
7543
9176
  };
7544
9177
  }, [placement]);
7545
- (0, import_react4.useEffect)(() => {
9178
+ (0, import_react5.useEffect)(() => {
7546
9179
  const onKey = (event) => {
7547
9180
  if (event.key === "Escape") onClose();
7548
9181
  };
@@ -7557,14 +9190,14 @@ function Popover({
7557
9190
  window.removeEventListener("pointerdown", onPointer);
7558
9191
  };
7559
9192
  }, [onClose]);
7560
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref, className: "mx-meet__popover", style, role: "dialog", "aria-label": label, children });
9193
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref, className: "mx-meet__popover", style, role: "dialog", "aria-label": label, children });
7561
9194
  }
7562
9195
  function MenuItem({
7563
9196
  onSelect,
7564
9197
  danger = false,
7565
9198
  children
7566
9199
  }) {
7567
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9200
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7568
9201
  "button",
7569
9202
  {
7570
9203
  type: "button",
@@ -7576,28 +9209,28 @@ function MenuItem({
7576
9209
  );
7577
9210
  }
7578
9211
  function Toast({ text: text3, failed, onDone }) {
7579
- (0, import_react4.useEffect)(() => {
9212
+ (0, import_react5.useEffect)(() => {
7580
9213
  const timer = setTimeout(onDone, failed ? 7e3 : 4e3);
7581
9214
  return () => clearTimeout(timer);
7582
9215
  }, [text3, failed, onDone]);
7583
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: failed ? "mx-meet__toast mx-meet__toast--failed" : "mx-meet__toast", role: "status", children: [
7584
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: text3 }),
7585
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: onDone, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CloseIcon, { width: 14, height: 14 }) })
9216
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: failed ? "mx-meet__toast mx-meet__toast--failed" : "mx-meet__toast", role: "status", children: [
9217
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: text3 }),
9218
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: onDone, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CloseIcon, { width: 14, height: 14 }) })
7586
9219
  ] });
7587
9220
  }
7588
9221
  function MeetingOverlays() {
7589
9222
  const reactions = useReactions();
7590
9223
  const { notice, dismiss } = useModerationNotice();
7591
9224
  const room = useRoom();
7592
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
7593
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ReactionOverlay, { reactions }),
9225
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
9226
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ReactionOverlay, { reactions }),
7594
9227
  notice !== null && notice.kind !== "removed" ? (
7595
9228
  // A host's request ("the host is asking you to unmute"), not an error:
7596
9229
  // an assertive status, so it is announced at once without being filed
7597
9230
  // as a failure (design-system error-box census).
7598
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__notice-bar", role: "status", "aria-live": "assertive", children: [
7599
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: notice.text }),
7600
- notice.kind === "ask-unmute" && room.local?.micEnabled !== true ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9231
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__notice-bar", role: "status", "aria-live": "assertive", children: [
9232
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: notice.text }),
9233
+ notice.kind === "ask-unmute" && room.local?.micEnabled !== true ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7601
9234
  "button",
7602
9235
  {
7603
9236
  type: "button",
@@ -7609,20 +9242,20 @@ function MeetingOverlays() {
7609
9242
  children: "Unmute"
7610
9243
  }
7611
9244
  ) : null,
7612
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: dismiss, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CloseIcon, { width: 14, height: 14 }) })
9245
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: dismiss, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CloseIcon, { width: 14, height: 14 }) })
7613
9246
  ] })
7614
9247
  ) : null
7615
9248
  ] });
7616
9249
  }
7617
9250
  function ShortcutsSheet({ onClose }) {
7618
- (0, import_react4.useEffect)(() => {
9251
+ (0, import_react5.useEffect)(() => {
7619
9252
  const onKey = (event) => {
7620
9253
  if (event.key === "Escape") onClose();
7621
9254
  };
7622
9255
  window.addEventListener("keydown", onKey);
7623
9256
  return () => window.removeEventListener("keydown", onKey);
7624
9257
  }, [onClose]);
7625
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__sheet-backdrop", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9258
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__sheet-backdrop", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7626
9259
  "div",
7627
9260
  {
7628
9261
  className: "mx-meet__sheet",
@@ -7630,13 +9263,13 @@ function ShortcutsSheet({ onClose }) {
7630
9263
  "aria-label": "Keyboard shortcuts",
7631
9264
  onClick: (event) => event.stopPropagation(),
7632
9265
  children: [
7633
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "mx-meet__panel-head", children: [
7634
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__panel-title", children: "Keyboard shortcuts" }),
7635
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ControlButton, { label: "Close", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CloseIcon, { width: 16, height: 16 }) })
9266
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("header", { className: "mx-meet__panel-head", children: [
9267
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "mx-meet__panel-title", children: "Keyboard shortcuts" }),
9268
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ControlButton, { label: "Close", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CloseIcon, { width: 16, height: 16 }) })
7636
9269
  ] }),
7637
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("dl", { className: "mx-meet__shortcuts", children: MEET_SHORTCUTS.map((shortcut) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__shortcut", children: [
7638
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("dt", { children: shortcut.label }),
7639
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("dd", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("kbd", { className: "mx-meet__kbd", children: shortcut.keys }) })
9270
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dl", { className: "mx-meet__shortcuts", children: MEET_SHORTCUTS.map((shortcut) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__shortcut", children: [
9271
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dt", { children: shortcut.label }),
9272
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dd", { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("kbd", { className: "mx-meet__kbd", children: shortcut.keys }) })
7640
9273
  ] }, shortcut.id)) })
7641
9274
  ]
7642
9275
  }
@@ -7646,19 +9279,32 @@ function AiControl({ active, onToggle }) {
7646
9279
  const snapshot = useMeetSnapshot();
7647
9280
  const meeting = snapshot?.meeting ?? null;
7648
9281
  if (meeting === null || !meeting.aiEnabled) return null;
7649
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ControlButton, { label: "Meeting assistant", active, onClick: onToggle, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SparklesIcon, {}) });
9282
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ControlButton, { label: "Meeting assistant", active, onClick: onToggle, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SparklesIcon, {}) });
7650
9283
  }
7651
9284
  function PanelShell({
7652
9285
  title,
7653
9286
  onClose,
7654
9287
  children
7655
9288
  }) {
7656
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("aside", { className: "mx-meet__panel", "aria-label": title, children: [
7657
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "mx-meet__panel-head", children: [
7658
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__panel-title", children: title }),
7659
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ControlButton, { label: "Close panel", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CloseIcon, { width: 16, height: 16 }) })
9289
+ const ref = (0, import_react5.useRef)(null);
9290
+ (0, import_react5.useLayoutEffect)(() => {
9291
+ const panel = ref.current;
9292
+ const root = panel?.closest(".mx-meet");
9293
+ const header = root?.querySelector(":scope > .mx-meet__header") ?? null;
9294
+ if (!panel || !header) return void 0;
9295
+ const place = () => panel.style.setProperty("--mx-meet-panel-top", `${header.offsetHeight}px`);
9296
+ place();
9297
+ if (typeof ResizeObserver === "undefined") return void 0;
9298
+ const observer = new ResizeObserver(place);
9299
+ observer.observe(header);
9300
+ return () => observer.disconnect();
9301
+ }, []);
9302
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("aside", { ref, className: "mx-meet__panel", "aria-label": title, children: [
9303
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("header", { className: "mx-meet__panel-head", children: [
9304
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "mx-meet__panel-title", children: title }),
9305
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ControlButton, { label: "Close panel", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CloseIcon, { width: 16, height: 16 }) })
7660
9306
  ] }),
7661
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__panel-body", children })
9307
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__panel-body", children })
7662
9308
  ] });
7663
9309
  }
7664
9310
  function ChatPanel({
@@ -7668,17 +9314,17 @@ function ChatPanel({
7668
9314
  }) {
7669
9315
  const snapshot = useMeetSnapshot();
7670
9316
  const room = useRoom();
7671
- const [draft, setDraft] = (0, import_react4.useState)("");
7672
- const [recipient, setRecipient] = (0, import_react4.useState)(to);
7673
- const listRef = (0, import_react4.useRef)(null);
9317
+ const [draft, setDraft] = (0, import_react5.useState)("");
9318
+ const [recipient, setRecipient] = (0, import_react5.useState)(to);
9319
+ const listRef = (0, import_react5.useRef)(null);
7674
9320
  const messages = snapshot?.chat ?? [];
7675
9321
  const local = snapshot?.localIdentity ?? null;
7676
9322
  const people = (snapshot?.participants ?? []).filter(
7677
9323
  (participant) => !participant.isLocal && !participant.isAgent
7678
9324
  );
7679
9325
  const recipientName = recipient === null ? null : people.find((p) => p.identity === recipient)?.displayName ?? null;
7680
- (0, import_react4.useEffect)(() => setRecipient(to), [to]);
7681
- (0, import_react4.useEffect)(() => {
9326
+ (0, import_react5.useEffect)(() => setRecipient(to), [to]);
9327
+ (0, import_react5.useEffect)(() => {
7682
9328
  const list = listRef.current;
7683
9329
  if (list !== null) list.scrollTop = list.scrollHeight;
7684
9330
  }, [messages.length]);
@@ -7686,13 +9332,13 @@ function ChatPanel({
7686
9332
  setRecipient(next);
7687
9333
  onTo?.(next);
7688
9334
  };
7689
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(PanelShell, { title: "Chat", onClose, children: [
7690
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("ul", { className: "mx-meet__chat", ref: listRef, children: [
7691
- snapshot?.chatHistoryError != null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("li", { className: "mx-meet__panel-note", children: snapshot.chatHistoryError }) : null,
7692
- snapshot?.chatLoaded !== true && messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("li", { className: "mx-meet__panel-note", children: "Reading earlier messages\u2026" }) : messages.length === 0 && snapshot?.chatHistoryError == null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("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,
7693
- messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ChatLine, { message, local, people }, message.id))
9335
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(PanelShell, { title: "Chat", onClose, children: [
9336
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("ul", { className: "mx-meet__chat", ref: listRef, children: [
9337
+ snapshot?.chatHistoryError != null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("li", { className: "mx-meet__panel-note", children: snapshot.chatHistoryError }) : null,
9338
+ snapshot?.chatLoaded !== true && messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("li", { className: "mx-meet__panel-note", children: "Reading earlier messages\u2026" }) : messages.length === 0 && snapshot?.chatHistoryError == null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("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,
9339
+ messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChatLine, { message, local, people }, message.id))
7694
9340
  ] }),
7695
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9341
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7696
9342
  "form",
7697
9343
  {
7698
9344
  className: "mx-meet__composer mx-meet__composer--chat",
@@ -7705,7 +9351,7 @@ function ChatPanel({
7705
9351
  else void room.sendPrivateChat(recipient, text3);
7706
9352
  },
7707
9353
  children: [
7708
- people.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9354
+ people.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7709
9355
  "select",
7710
9356
  {
7711
9357
  className: "mx-meet__select mx-meet__select--compact",
@@ -7713,16 +9359,16 @@ function ChatPanel({
7713
9359
  value: recipient ?? "",
7714
9360
  onChange: (event) => choose(event.target.value === "" ? null : event.target.value),
7715
9361
  children: [
7716
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "", children: "Everyone" }),
7717
- people.map((participant) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("option", { value: participant.identity, children: [
9362
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "", children: "Everyone" }),
9363
+ people.map((participant) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("option", { value: participant.identity, children: [
7718
9364
  participant.displayName,
7719
9365
  " (private)"
7720
9366
  ] }, participant.identity))
7721
9367
  ]
7722
9368
  }
7723
9369
  ) : null,
7724
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__composer-row", children: [
7725
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9370
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__composer-row", children: [
9371
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7726
9372
  "input",
7727
9373
  {
7728
9374
  className: "mx-meet__input",
@@ -7733,9 +9379,9 @@ function ChatPanel({
7733
9379
  maxLength: 4e3
7734
9380
  }
7735
9381
  ),
7736
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", className: "mx-meet__send", disabled: draft.trim().length === 0, children: "Send" })
9382
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "submit", className: "mx-meet__send", disabled: draft.trim().length === 0, children: "Send" })
7737
9383
  ] }),
7738
- recipientName !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__panel-note", children: [
9384
+ recipientName !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__panel-note", children: [
7739
9385
  "Only ",
7740
9386
  recipientName,
7741
9387
  " sees this. Private messages are not saved."
@@ -7753,7 +9399,7 @@ function ChatLine({
7753
9399
  const mine = message.identity === local;
7754
9400
  const privateTo = message.to ?? null;
7755
9401
  const counterpart = privateTo === null ? null : mine ? people.find((p) => p.identity === privateTo)?.displayName ?? "them" : "you";
7756
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9402
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7757
9403
  "li",
7758
9404
  {
7759
9405
  className: [
@@ -7762,17 +9408,17 @@ function ChatLine({
7762
9408
  message.failed !== void 0 ? "mx-meet__chat-line--failed" : ""
7763
9409
  ].filter(Boolean).join(" "),
7764
9410
  children: [
7765
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__chat-meta", children: [
7766
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: mine ? "You" : message.displayName }),
7767
- counterpart !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__chat-private", children: [
9411
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__chat-meta", children: [
9412
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: mine ? "You" : message.displayName }),
9413
+ counterpart !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__chat-private", children: [
7768
9414
  "to ",
7769
9415
  counterpart,
7770
9416
  " \xB7 private"
7771
9417
  ] }) : null,
7772
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("time", { dateTime: message.at, children: clockOf(message.at) })
9418
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("time", { dateTime: message.at, children: clockOf(message.at) })
7773
9419
  ] }),
7774
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__chat-text", children: message.text }),
7775
- message.failed !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__chat-failed", children: message.failed }) : privateTo === null && message.saved === false ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__chat-pending", children: message.id.startsWith("pending-") ? "Sending\u2026" : "Not saved \u2014 people who join later will not see this" }) : null
9420
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__chat-text", children: message.text }),
9421
+ message.failed !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__chat-failed", children: message.failed }) : privateTo === null && message.saved === false ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__chat-pending", children: message.id.startsWith("pending-") ? "Sending\u2026" : "Not saved \u2014 people who join later will not see this" }) : null
7776
9422
  ]
7777
9423
  }
7778
9424
  );
@@ -7784,22 +9430,22 @@ function PeoplePanel({
7784
9430
  const snapshot = useMeetSnapshot();
7785
9431
  const controls = useHostControls();
7786
9432
  const queue = useHandQueue();
7787
- const [query, setQuery] = (0, import_react4.useState)("");
7788
- const [menuFor, setMenuFor] = (0, import_react4.useState)(null);
9433
+ const [query, setQuery] = (0, import_react5.useState)("");
9434
+ const [menuFor, setMenuFor] = (0, import_react5.useState)(null);
7789
9435
  const myRole = useRole();
7790
9436
  const local = snapshot?.localIdentity ?? null;
7791
9437
  const everyone = snapshot?.participants ?? [];
7792
9438
  const needle = query.trim().toLowerCase();
7793
9439
  const shown = needle.length === 0 ? everyone : everyone.filter((participant) => participant.displayName.toLowerCase().includes(needle));
7794
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(PanelShell, { title: `People (${everyone.length})`, onClose, children: [
7795
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(LobbyPanel, {}),
7796
- queue.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__section", "aria-label": "Raised hands", children: [
7797
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "mx-meet__section-head", children: [
7798
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("h3", { className: "mx-meet__section-title", children: [
9440
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(PanelShell, { title: `People (${everyone.length})`, onClose, children: [
9441
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LobbyPanel, {}),
9442
+ queue.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__section", "aria-label": "Raised hands", children: [
9443
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("header", { className: "mx-meet__section-head", children: [
9444
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("h3", { className: "mx-meet__section-title", children: [
7799
9445
  "Raised hands \xB7 ",
7800
9446
  queue.length
7801
9447
  ] }),
7802
- controls.isHost ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9448
+ controls.isHost ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7803
9449
  "button",
7804
9450
  {
7805
9451
  type: "button",
@@ -7809,13 +9455,13 @@ function PeoplePanel({
7809
9455
  }
7810
9456
  ) : null
7811
9457
  ] }),
7812
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ol", { className: "mx-meet__queue", children: queue.map((participant) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet__person", children: [
7813
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 28 }),
7814
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__person-name", children: [
9458
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ol", { className: "mx-meet__queue", children: queue.map((participant) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("li", { className: "mx-meet__person", children: [
9459
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 28 }),
9460
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__person-name", children: [
7815
9461
  participant.displayName,
7816
- participant.identity === local ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__you", children: " (you)" }) : null
9462
+ participant.identity === local ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__you", children: " (you)" }) : null
7817
9463
  ] }),
7818
- controls.isHost || participant.identity === local ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9464
+ controls.isHost || participant.identity === local ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7819
9465
  "button",
7820
9466
  {
7821
9467
  type: "button",
@@ -7826,27 +9472,27 @@ function PeoplePanel({
7826
9472
  ) : null
7827
9473
  ] }, participant.identity)) })
7828
9474
  ] }) : null,
7829
- controls.isHost && everyone.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__bulk", children: [
7830
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("button", { type: "button", className: "mx-meet__chip", onClick: () => void controls.run({ action: "mute_all" }), children: [
7831
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicOffIcon, { width: 14, height: 14 }),
9475
+ controls.isHost && everyone.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__bulk", children: [
9476
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("button", { type: "button", className: "mx-meet__chip", onClick: () => void controls.run({ action: "mute_all" }), children: [
9477
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MicOffIcon, { width: 14, height: 14 }),
7832
9478
  " Mute all"
7833
9479
  ] }),
7834
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9480
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7835
9481
  "button",
7836
9482
  {
7837
9483
  type: "button",
7838
9484
  className: "mx-meet__chip",
7839
9485
  onClick: () => void controls.run({ action: "ask_all_unmute" }),
7840
9486
  children: [
7841
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicIcon, { width: 14, height: 14 }),
9487
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MicIcon, { width: 14, height: 14 }),
7842
9488
  " Ask all to unmute"
7843
9489
  ]
7844
9490
  }
7845
9491
  )
7846
9492
  ] }) : null,
7847
- everyone.length > 4 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__search", children: [
7848
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SearchIcon, { width: 16, height: 16 }),
7849
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9493
+ everyone.length > 4 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "mx-meet__search", children: [
9494
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SearchIcon, { width: 16, height: 16 }),
9495
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7850
9496
  "input",
7851
9497
  {
7852
9498
  className: "mx-meet__input mx-meet__input--bare",
@@ -7857,31 +9503,31 @@ function PeoplePanel({
7857
9503
  }
7858
9504
  )
7859
9505
  ] }) : null,
7860
- controls.notice !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: controls.notice.failed ? "mx-meet__error" : "mx-meet__notice", role: "status", children: controls.notice.text }) : null,
7861
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("ul", { className: "mx-meet__people", children: [
7862
- shown.map((participant) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet__person", children: [
7863
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 32 }),
7864
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__person-name", children: [
9506
+ controls.notice !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: controls.notice.failed ? "mx-meet__error" : "mx-meet__notice", role: "status", children: controls.notice.text }) : null,
9507
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("ul", { className: "mx-meet__people", children: [
9508
+ shown.map((participant) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("li", { className: "mx-meet__person", children: [
9509
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 32 }),
9510
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__person-name", children: [
7865
9511
  participant.displayName,
7866
- participant.identity === local ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__you", children: " (you)" }) : null,
7867
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RoleBadge, { role: participant.identity === local ? myRole : participant.role }),
7868
- isNoteTaker(participant) ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null,
7869
- snapshot?.spotlight === participant.identity ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Spotlight" }) : null
9512
+ participant.identity === local ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__you", children: " (you)" }) : null,
9513
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RoleBadge, { role: participant.identity === local ? myRole : participant.role }),
9514
+ isNoteTaker(participant) ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null,
9515
+ snapshot?.spotlight === participant.identity ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__badge", children: "Spotlight" }) : null
7870
9516
  ] }),
7871
- participant.handRaised ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HandIcon, { width: 14, height: 14 }) : null,
7872
- !participant.micEnabled && !isNoteTaker(participant) ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicOffIcon, { width: 14, height: 14 }) : null,
7873
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(QualityBars, { quality: participant.quality }),
7874
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__anchor", children: [
7875
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9517
+ participant.handRaised ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HandIcon, { width: 14, height: 14 }) : null,
9518
+ !participant.micEnabled && !isNoteTaker(participant) ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MicOffIcon, { width: 14, height: 14 }) : null,
9519
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(QualityBars, { quality: participant.quality }),
9520
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__anchor", children: [
9521
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7876
9522
  ControlButton,
7877
9523
  {
7878
9524
  label: `More for ${participant.displayName}`,
7879
9525
  active: menuFor === participant.identity,
7880
9526
  onClick: () => setMenuFor(menuFor === participant.identity ? null : participant.identity),
7881
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MoreIcon, { width: 16, height: 16 })
9527
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MoreIcon, { width: 16, height: 16 })
7882
9528
  }
7883
9529
  ),
7884
- menuFor === participant.identity ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9530
+ menuFor === participant.identity ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7885
9531
  PersonMenu,
7886
9532
  {
7887
9533
  participant,
@@ -7892,13 +9538,13 @@ function PeoplePanel({
7892
9538
  ) : null
7893
9539
  ] })
7894
9540
  ] }, participant.identity)),
7895
- shown.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet__panel-note", children: [
9541
+ shown.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("li", { className: "mx-meet__panel-note", children: [
7896
9542
  "Nobody matches \u201C",
7897
9543
  query,
7898
9544
  "\u201D."
7899
9545
  ] }) : null
7900
9546
  ] }),
7901
- snapshot?.meeting !== null && snapshot?.meeting !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(GuestRecordAccessControl, { meeting: snapshot.meeting }) : null
9547
+ snapshot?.meeting !== null && snapshot?.meeting !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(GuestRecordAccessControl, { meeting: snapshot.meeting }) : null
7902
9548
  ] });
7903
9549
  }
7904
9550
  function PersonMenu({
@@ -7910,14 +9556,14 @@ function PersonMenu({
7910
9556
  const host = useMeetHost();
7911
9557
  const snapshot = useMeetSnapshot();
7912
9558
  const controls = useHostControls();
7913
- const [mode, setMode] = (0, import_react4.useState)("menu");
7914
- const [text3, setText] = (0, import_react4.useState)("");
9559
+ const [mode, setMode] = (0, import_react5.useState)("menu");
9560
+ const [text3, setText] = (0, import_react5.useState)("");
7915
9561
  const self = participant.identity === snapshot?.localIdentity;
7916
9562
  const moderate = controls.canModerate(participant);
7917
9563
  const pinned = snapshot?.pinned === participant.identity;
7918
9564
  const spotlit = snapshot?.spotlight === participant.identity;
7919
9565
  const hasAccount = participant.userId !== null;
7920
- const [refused, setRefused] = (0, import_react4.useState)(false);
9566
+ const [refused, setRefused] = (0, import_react5.useState)(false);
7921
9567
  const act = (request) => {
7922
9568
  setRefused(false);
7923
9569
  void controls.run(request).then((result) => {
@@ -7925,10 +9571,10 @@ function PersonMenu({
7925
9571
  else setRefused(true);
7926
9572
  });
7927
9573
  };
7928
- const refusal2 = refused && controls.notice?.failed === true ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_design_system.ErrorBox, { as: "p", className: "mx-meet__error", message: controls.notice.text, operation: "Change this participant", origin: "meet/components", children: controls.notice.text }) : null;
9574
+ const refusal2 = refused && controls.notice?.failed === true ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system.ErrorBox, { as: "p", className: "mx-meet__error", message: controls.notice.text, operation: "Change this participant", origin: "meet/components", children: controls.notice.text }) : null;
7929
9575
  if (mode === "rename" || mode === "report") {
7930
9576
  const renaming = mode === "rename";
7931
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Popover, { label: renaming ? "Rename" : "Report", onClose, placement, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9577
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Popover, { label: renaming ? "Rename" : "Report", onClose, placement, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7932
9578
  "form",
7933
9579
  {
7934
9580
  className: "mx-meet__menu-form",
@@ -7940,9 +9586,9 @@ function PersonMenu({
7940
9586
  );
7941
9587
  },
7942
9588
  children: [
7943
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
7944
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: renaming ? "Name shown in this meeting" : `What did ${participant.displayName} do?` }),
7945
- renaming ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9589
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "mx-meet__field", children: [
9590
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__field-label", children: renaming ? "Name shown in this meeting" : `What did ${participant.displayName} do?` }),
9591
+ renaming ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7946
9592
  "input",
7947
9593
  {
7948
9594
  className: "mx-meet__input",
@@ -7951,7 +9597,7 @@ function PersonMenu({
7951
9597
  value: text3,
7952
9598
  onChange: (event) => setText(event.target.value)
7953
9599
  }
7954
- ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9600
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7955
9601
  "textarea",
7956
9602
  {
7957
9603
  className: "mx-meet__input",
@@ -7964,9 +9610,9 @@ function PersonMenu({
7964
9610
  )
7965
9611
  ] }),
7966
9612
  refusal2,
7967
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__menu-actions", children: [
7968
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Back" }),
7969
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", className: "mx-meet__send", disabled: text3.trim().length === 0 || controls.busy, children: renaming ? "Rename" : "Report" })
9613
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__menu-actions", children: [
9614
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Back" }),
9615
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "submit", className: "mx-meet__send", disabled: text3.trim().length === 0 || controls.busy, children: renaming ? "Rename" : "Report" })
7970
9616
  ] })
7971
9617
  ]
7972
9618
  }
@@ -7974,12 +9620,12 @@ function PersonMenu({
7974
9620
  }
7975
9621
  if (mode === "remove" || mode === "transfer") {
7976
9622
  const removing = mode === "remove";
7977
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Popover, { label: removing ? "Remove" : "Make host", onClose, placement, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__menu-form", children: [
7978
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("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.` }),
9623
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Popover, { label: removing ? "Remove" : "Make host", onClose, placement, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__menu-form", children: [
9624
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("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.` }),
7979
9625
  refusal2,
7980
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__menu-actions", children: [
7981
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Cancel" }),
7982
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9626
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__menu-actions", children: [
9627
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Cancel" }),
9628
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7983
9629
  "button",
7984
9630
  {
7985
9631
  type: "button",
@@ -7992,8 +9638,8 @@ function PersonMenu({
7992
9638
  ] })
7993
9639
  ] }) });
7994
9640
  }
7995
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Popover, { label: `Options for ${participant.displayName}`, onClose, placement, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__menu", role: "menu", children: [
7996
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9641
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Popover, { label: `Options for ${participant.displayName}`, onClose, placement, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__menu", role: "menu", children: [
9642
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7997
9643
  MenuItem,
7998
9644
  {
7999
9645
  onSelect: () => {
@@ -8001,13 +9647,13 @@ function PersonMenu({
8001
9647
  onClose();
8002
9648
  },
8003
9649
  children: [
8004
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PinIcon, { width: 16, height: 16 }),
9650
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PinIcon, { width: 16, height: 16 }),
8005
9651
  " ",
8006
9652
  pinned ? "Unpin" : "Pin for me"
8007
9653
  ]
8008
9654
  }
8009
9655
  ),
8010
- !self && !participant.isAgent && (onMessage !== void 0 || host !== null) ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9656
+ !self && !participant.isAgent && (onMessage !== void 0 || host !== null) ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8011
9657
  MenuItem,
8012
9658
  {
8013
9659
  onSelect: () => {
@@ -8019,42 +9665,42 @@ function PersonMenu({
8019
9665
  onClose();
8020
9666
  },
8021
9667
  children: [
8022
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ChatIcon, { width: 16, height: 16 }),
9668
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChatIcon, { width: 16, height: 16 }),
8023
9669
  " Message privately"
8024
9670
  ]
8025
9671
  }
8026
9672
  ) : null,
8027
- controls.isHost ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "spotlight", identity: spotlit ? null : participant.identity }), children: [
8028
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SpotlightIcon, { width: 16, height: 16 }),
9673
+ controls.isHost ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(MenuItem, { onSelect: () => act({ action: "spotlight", identity: spotlit ? null : participant.identity }), children: [
9674
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SpotlightIcon, { width: 16, height: 16 }),
8029
9675
  " ",
8030
9676
  spotlit ? "Remove spotlight" : "Spotlight for everyone"
8031
9677
  ] }) : null,
8032
- moderate ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
8033
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__menu-sep", role: "separator" }),
8034
- participant.micEnabled ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "mute", identity: participant.identity }), children: [
8035
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicOffIcon, { width: 16, height: 16 }),
9678
+ moderate ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
9679
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__menu-sep", role: "separator" }),
9680
+ participant.micEnabled ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(MenuItem, { onSelect: () => act({ action: "mute", identity: participant.identity }), children: [
9681
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MicOffIcon, { width: 16, height: 16 }),
8036
9682
  " Mute"
8037
- ] }) : !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "ask_unmute", identity: participant.identity }), children: [
8038
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicIcon, { width: 16, height: 16 }),
9683
+ ] }) : !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(MenuItem, { onSelect: () => act({ action: "ask_unmute", identity: participant.identity }), children: [
9684
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MicIcon, { width: 16, height: 16 }),
8039
9685
  " Ask to unmute"
8040
9686
  ] }) : null,
8041
- participant.cameraEnabled ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "stop_video", identity: participant.identity }), children: [
8042
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CameraOffIcon, { width: 16, height: 16 }),
9687
+ participant.cameraEnabled ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(MenuItem, { onSelect: () => act({ action: "stop_video", identity: participant.identity }), children: [
9688
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CameraOffIcon, { width: 16, height: 16 }),
8043
9689
  " Stop video"
8044
9690
  ] }) : null,
8045
- participant.screenSharing ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "stop_screen", identity: participant.identity }), children: [
8046
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ScreenShareIcon, { width: 16, height: 16 }),
9691
+ participant.screenSharing ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(MenuItem, { onSelect: () => act({ action: "stop_screen", identity: participant.identity }), children: [
9692
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ScreenShareIcon, { width: 16, height: 16 }),
8047
9693
  " Stop screen share"
8048
9694
  ] }) : null,
8049
- participant.handRaised ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "lower_hand", identity: participant.identity }), children: [
8050
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HandIcon, { width: 16, height: 16 }),
9695
+ participant.handRaised ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(MenuItem, { onSelect: () => act({ action: "lower_hand", identity: participant.identity }), children: [
9696
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HandIcon, { width: 16, height: 16 }),
8051
9697
  " Lower hand"
8052
9698
  ] }) : null,
8053
- hasAccount && !participant.isAgent && participant.role !== "cohost" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "make_cohost", identity: participant.identity }), children: [
8054
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PeopleIcon, { width: 16, height: 16 }),
9699
+ hasAccount && !participant.isAgent && participant.role !== "cohost" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(MenuItem, { onSelect: () => act({ action: "make_cohost", identity: participant.identity }), children: [
9700
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PeopleIcon, { width: 16, height: 16 }),
8055
9701
  " Make co-host"
8056
9702
  ] }) : null,
8057
- !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9703
+ !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8058
9704
  MenuItem,
8059
9705
  {
8060
9706
  onSelect: () => {
@@ -8062,21 +9708,21 @@ function PersonMenu({
8062
9708
  setMode("rename");
8063
9709
  },
8064
9710
  children: [
8065
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PencilIcon, { width: 16, height: 16 }),
9711
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PencilIcon, { width: 16, height: 16 }),
8066
9712
  " Rename"
8067
9713
  ]
8068
9714
  }
8069
9715
  ) : null
8070
9716
  ] }) : null,
8071
- controls.isOwner && participant.role === "cohost" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "revoke_cohost", identity: participant.identity }), children: [
8072
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PeopleIcon, { width: 16, height: 16 }),
9717
+ controls.isOwner && participant.role === "cohost" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(MenuItem, { onSelect: () => act({ action: "revoke_cohost", identity: participant.identity }), children: [
9718
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PeopleIcon, { width: 16, height: 16 }),
8073
9719
  " Remove co-host"
8074
9720
  ] }) : null,
8075
- controls.isOwner && !self && hasAccount && !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => setMode("transfer"), children: [
8076
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SpotlightIcon, { width: 16, height: 16 }),
9721
+ controls.isOwner && !self && hasAccount && !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(MenuItem, { onSelect: () => setMode("transfer"), children: [
9722
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SpotlightIcon, { width: 16, height: 16 }),
8077
9723
  " Make host"
8078
9724
  ] }) : null,
8079
- self ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9725
+ self ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8080
9726
  MenuItem,
8081
9727
  {
8082
9728
  onSelect: () => {
@@ -8084,12 +9730,12 @@ function PersonMenu({
8084
9730
  setMode("rename");
8085
9731
  },
8086
9732
  children: [
8087
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PencilIcon, { width: 16, height: 16 }),
9733
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PencilIcon, { width: 16, height: 16 }),
8088
9734
  " Rename yourself"
8089
9735
  ]
8090
9736
  }
8091
9737
  ) : null,
8092
- !self && !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9738
+ !self && !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8093
9739
  MenuItem,
8094
9740
  {
8095
9741
  onSelect: () => {
@@ -8097,21 +9743,21 @@ function PersonMenu({
8097
9743
  setMode("report");
8098
9744
  },
8099
9745
  children: [
8100
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(FlagIcon, { width: 16, height: 16 }),
9746
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FlagIcon, { width: 16, height: 16 }),
8101
9747
  " Report"
8102
9748
  ]
8103
9749
  }
8104
9750
  ) : null,
8105
- moderate && !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { danger: true, onSelect: () => setMode("remove"), children: [
8106
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CloseIcon, { width: 16, height: 16 }),
9751
+ moderate && !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(MenuItem, { danger: true, onSelect: () => setMode("remove"), children: [
9752
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CloseIcon, { width: 16, height: 16 }),
8107
9753
  " Remove from meeting"
8108
9754
  ] }) : null
8109
9755
  ] }) });
8110
9756
  }
8111
9757
  function SettingsPanel({ onClose }) {
8112
9758
  const host = useRequiredMeetHost();
8113
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(PanelShell, { title: "Audio, video and effects", onClose, children: [
8114
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9759
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(PanelShell, { title: "Settings", onClose, children: [
9760
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8115
9761
  DeviceSettings,
8116
9762
  {
8117
9763
  onPick: (kind, deviceId2) => {
@@ -8120,7 +9766,8 @@ function SettingsPanel({ onClose }) {
8120
9766
  }
8121
9767
  }
8122
9768
  ),
8123
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(EffectsSettings, {})
9769
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(EffectsSettings, {}),
9770
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CaptionLanguageSettings, {})
8124
9771
  ] });
8125
9772
  }
8126
9773
  function DeviceSettings({
@@ -8132,15 +9779,15 @@ function DeviceSettings({
8132
9779
  const speaker = devices?.selected.audiooutput ?? host.devices.resolve("audiooutput");
8133
9780
  const stream = useMicrophoneStream(microphone);
8134
9781
  const level = useAudioLevel(stream);
8135
- const [testing, setTesting] = (0, import_react4.useState)(false);
8136
- (0, import_react4.useEffect)(() => {
9782
+ const [testing, setTesting] = (0, import_react5.useState)(false);
9783
+ (0, import_react5.useEffect)(() => {
8137
9784
  void host.devices.refresh();
8138
9785
  }, [host]);
8139
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__section", "aria-label": "Devices", children: [
8140
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DevicePicker, { kind: "audioinput", label: "Microphone", onPick }),
8141
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("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__ */ (0, import_jsx_runtime3.jsx)("span", { style: { width: `${Math.min(100, Math.round(level * 160))}%` } }) }),
8142
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DevicePicker, { kind: "audiooutput", label: "Speaker", onPick }),
8143
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9786
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__section", "aria-label": "Devices", children: [
9787
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DevicePicker, { kind: "audioinput", label: "Microphone", onPick }),
9788
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("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__ */ (0, import_jsx_runtime4.jsx)("span", { style: { width: `${Math.min(100, Math.round(level * 160))}%` } }) }),
9789
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DevicePicker, { kind: "audiooutput", label: "Speaker", onPick }),
9790
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8144
9791
  "button",
8145
9792
  {
8146
9793
  type: "button",
@@ -8151,19 +9798,19 @@ function DeviceSettings({
8151
9798
  void playTestSound(speaker).finally(() => setTesting(false));
8152
9799
  },
8153
9800
  children: [
8154
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SpeakerIcon, { width: 14, height: 14 }),
9801
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SpeakerIcon, { width: 14, height: 14 }),
8155
9802
  " ",
8156
9803
  testing ? "Playing\u2026" : "Test speaker"
8157
9804
  ]
8158
9805
  }
8159
9806
  ),
8160
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DevicePicker, { kind: "videoinput", label: "Camera", onPick })
9807
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DevicePicker, { kind: "videoinput", label: "Camera", onPick })
8161
9808
  ] });
8162
9809
  }
8163
9810
  function EffectsSettings({ preview }) {
8164
9811
  const effects = useMediaEffects();
8165
- const [error, setError] = (0, import_react4.useState)(null);
8166
- const fileRef = (0, import_react4.useRef)(null);
9812
+ const [error, setError] = (0, import_react5.useState)(null);
9813
+ const fileRef = (0, import_react5.useRef)(null);
8167
9814
  const supported = effects.backgroundsSupported || preview != null || videoEffectsSupported();
8168
9815
  const apply = (next) => {
8169
9816
  setError(null);
@@ -8175,9 +9822,9 @@ function EffectsSettings({ preview }) {
8175
9822
  );
8176
9823
  }
8177
9824
  };
8178
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__section", "aria-label": "Effects", children: [
8179
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__toggle", children: [
8180
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9825
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__section", "aria-label": "Effects", children: [
9826
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "mx-meet__toggle", children: [
9827
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8181
9828
  "input",
8182
9829
  {
8183
9830
  type: "checkbox",
@@ -8186,11 +9833,11 @@ function EffectsSettings({ preview }) {
8186
9833
  }
8187
9834
  ),
8188
9835
  "Noise suppression",
8189
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__hint", children: "Filters keyboards, fans and background chatter." })
9836
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__hint", children: "Filters keyboards, fans and background chatter." })
8190
9837
  ] }),
8191
- supported ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__field", children: [
8192
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: "Background" }),
8193
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__pills", role: "radiogroup", "aria-label": "Background", children: ["none", "blur", "image"].map((kind) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9838
+ supported ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__field", children: [
9839
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__field-label", children: "Background" }),
9840
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__pills", role: "radiogroup", "aria-label": "Background", children: ["none", "blur", "image"].map((kind) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8194
9841
  "button",
8195
9842
  {
8196
9843
  type: "button",
@@ -8208,7 +9855,7 @@ function EffectsSettings({ preview }) {
8208
9855
  },
8209
9856
  kind
8210
9857
  )) }),
8211
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9858
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8212
9859
  "input",
8213
9860
  {
8214
9861
  ref: fileRef,
@@ -8223,7 +9870,7 @@ function EffectsSettings({ preview }) {
8223
9870
  }
8224
9871
  }
8225
9872
  ),
8226
- error !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__error", children: error }) : null
9873
+ error !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__error", children: error }) : null
8227
9874
  ] }) : null
8228
9875
  ] });
8229
9876
  }
@@ -8282,8 +9929,8 @@ async function playTestSound(sinkId) {
8282
9929
  await context.close();
8283
9930
  }
8284
9931
  function useMicrophoneStream(deviceId2) {
8285
- const [stream, setStream] = (0, import_react4.useState)(null);
8286
- (0, import_react4.useEffect)(() => {
9932
+ const [stream, setStream] = (0, import_react5.useState)(null);
9933
+ (0, import_react5.useEffect)(() => {
8287
9934
  if (deviceId2 === "off") return void 0;
8288
9935
  let live = true;
8289
9936
  let opened = null;
@@ -8308,25 +9955,25 @@ function useMicrophoneStream(deviceId2) {
8308
9955
  function LobbyPanel() {
8309
9956
  const lobby = useLobby();
8310
9957
  if (!lobby.canAdmit || lobby.waiting.length === 0) return null;
8311
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__lobby", "aria-label": "Waiting room", children: [
8312
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "mx-meet__lobby-head", children: [
8313
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "mx-meet__lobby-title", children: lobby.waiting.length === 1 ? "1 person is waiting" : `${lobby.waiting.length} people are waiting` }),
8314
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => void lobby.admitAll(), children: "Admit all" })
9958
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__lobby", "aria-label": "Waiting room", children: [
9959
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("header", { className: "mx-meet__lobby-head", children: [
9960
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { className: "mx-meet__lobby-title", children: lobby.waiting.length === 1 ? "1 person is waiting" : `${lobby.waiting.length} people are waiting` }),
9961
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => void lobby.admitAll(), children: "Admit all" })
8315
9962
  ] }),
8316
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet__lobby-list", children: lobby.waiting.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet__lobby-row", children: [
8317
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Avatar, { name: entry.displayName, url: entry.avatarUrl, size: 32 }),
8318
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__person-name", children: [
9963
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ul", { className: "mx-meet__lobby-list", children: lobby.waiting.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("li", { className: "mx-meet__lobby-row", children: [
9964
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Avatar, { name: entry.displayName, url: entry.avatarUrl, size: 32 }),
9965
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__person-name", children: [
8319
9966
  entry.displayName,
8320
- entry.userId === null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Guest" }) : null
9967
+ entry.userId === null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__badge", children: "Guest" }) : null
8321
9968
  ] }),
8322
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ControlButton, { label: `Admit ${entry.displayName}`, onClick: () => void lobby.admit(entry), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CheckIcon, { width: 16, height: 16 }) }),
8323
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9969
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ControlButton, { label: `Admit ${entry.displayName}`, onClick: () => void lobby.admit(entry), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CheckIcon, { width: 16, height: 16 }) }),
9970
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8324
9971
  ControlButton,
8325
9972
  {
8326
9973
  label: `Deny ${entry.displayName}`,
8327
9974
  danger: true,
8328
9975
  onClick: () => void lobby.deny(entry),
8329
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CloseIcon, { width: 16, height: 16 })
9976
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CloseIcon, { width: 16, height: 16 })
8330
9977
  }
8331
9978
  )
8332
9979
  ] }, entry.identity)) })
@@ -8336,21 +9983,21 @@ function NoteTakerRow() {
8336
9983
  const ai = useMeetAi();
8337
9984
  const status = ai.noteTaker;
8338
9985
  const duplicateError = status.refusal !== null && ai.error !== null && status.refusal.reason === ai.error.message && status.refusal.remedy === ai.error.remedy;
8339
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__note-taker", "aria-label": "Note-taker", children: [
8340
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: `mx-meet__note-taker-state mx-meet__note-taker-state--${status.state}`, children: [
8341
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__note-taker-dot", "aria-hidden": "true" }),
9986
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__note-taker", "aria-label": "Note-taker", children: [
9987
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: `mx-meet__note-taker-state mx-meet__note-taker-state--${status.state}`, children: [
9988
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__note-taker-dot", "aria-hidden": "true" }),
8342
9989
  ai.noteTakerLabel
8343
9990
  ] }),
8344
- status.detail !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: status.detail }) : null,
8345
- status.refusal !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error: status.refusal, operation: "Join this meeting", origin: "meet/components", children: [
8346
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-reason", children: status.refusal.reason }),
8347
- status.refusal.remedy.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-remedy", children: status.refusal.remedy }) : null
9991
+ status.detail !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", children: status.detail }) : null,
9992
+ status.refusal !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error: status.refusal, operation: "Join this meeting", origin: "meet/components", children: [
9993
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-reason", children: status.refusal.reason }),
9994
+ status.refusal.remedy.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-remedy", children: status.refusal.remedy }) : null
8348
9995
  ] }) : null,
8349
- ai.error !== null && !duplicateError ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
8350
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
8351
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
9996
+ ai.error !== null && !duplicateError ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
9997
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
9998
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
8352
9999
  ] }) : null,
8353
- ai.canControlNoteTaker ? status.state === "transcribing" || status.state === "joining" || status.state === "handoff_pending" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10000
+ ai.canControlNoteTaker ? status.state === "transcribing" || status.state === "joining" || status.state === "handoff_pending" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8354
10001
  "button",
8355
10002
  {
8356
10003
  type: "button",
@@ -8358,7 +10005,7 @@ function NoteTakerRow() {
8358
10005
  onClick: () => void ai.stopNoteTaker(),
8359
10006
  children: "Dismiss the note-taker"
8360
10007
  }
8361
- ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10008
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8362
10009
  "button",
8363
10010
  {
8364
10011
  type: "button",
@@ -8374,24 +10021,24 @@ function NoteList({
8374
10021
  notes,
8375
10022
  empty
8376
10023
  }) {
8377
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__note-group", "aria-label": title, children: [
8378
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "mx-meet__note-group-title", children: title }),
8379
- notes.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: empty }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet__notes", children: notes.map((note) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet__note", children: [
10024
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__note-group", "aria-label": title, children: [
10025
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { className: "mx-meet__note-group-title", children: title }),
10026
+ notes.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", children: empty }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ul", { className: "mx-meet__notes", children: notes.map((note) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("li", { className: "mx-meet__note", children: [
8380
10027
  note.text,
8381
- note.assigneeDisplayName !== void 0 && note.assigneeDisplayName !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__assignee", children: note.assigneeDisplayName }) : null
10028
+ note.assigneeDisplayName !== void 0 && note.assigneeDisplayName !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__assignee", children: note.assigneeDisplayName }) : null
8382
10029
  ] }, note.id)) })
8383
10030
  ] });
8384
10031
  }
8385
10032
  function AiPanel({ onClose }) {
8386
10033
  const ai = useMeetAi();
8387
- const [question, setQuestion] = (0, import_react4.useState)("");
8388
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(PanelShell, { title: "Meeting assistant", onClose, children: [
8389
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(NoteTakerRow, {}),
8390
- ai.summary !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__note-group", "aria-label": "Summary", children: [
8391
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "mx-meet__note-group-title", children: "Summary" }),
8392
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__summary", children: ai.summary.text })
10034
+ const [question, setQuestion] = (0, import_react5.useState)("");
10035
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(PanelShell, { title: "Meeting assistant", onClose, children: [
10036
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(NoteTakerRow, {}),
10037
+ ai.summary !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__note-group", "aria-label": "Summary", children: [
10038
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { className: "mx-meet__note-group-title", children: "Summary" }),
10039
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__summary", children: ai.summary.text })
8393
10040
  ] }) : null,
8394
- ai.wrapUp !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__wrap-up-notice", role: "status", children: [
10041
+ ai.wrapUp !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__wrap-up-notice", role: "status", children: [
8395
10042
  "The wrap-up is written \u2014 ",
8396
10043
  ai.wrapUp.noteIds.length,
8397
10044
  " ",
@@ -8403,7 +10050,7 @@ function AiPanel({ onClose }) {
8403
10050
  ai.wrapUp.segmentCount === 1 ? "transcript line" : "transcript lines",
8404
10051
  "."
8405
10052
  ] }) : null,
8406
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10053
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8407
10054
  NoteList,
8408
10055
  {
8409
10056
  title: "Notes",
@@ -8411,7 +10058,7 @@ function AiPanel({ onClose }) {
8411
10058
  empty: "Notes appear here as the meeting goes on."
8412
10059
  }
8413
10060
  ),
8414
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10061
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8415
10062
  NoteList,
8416
10063
  {
8417
10064
  title: "Decisions",
@@ -8419,7 +10066,7 @@ function AiPanel({ onClose }) {
8419
10066
  empty: "Nothing has been decided yet."
8420
10067
  }
8421
10068
  ),
8422
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10069
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8423
10070
  NoteList,
8424
10071
  {
8425
10072
  title: "Action items",
@@ -8427,21 +10074,21 @@ function AiPanel({ onClose }) {
8427
10074
  empty: "No action items yet."
8428
10075
  }
8429
10076
  ),
8430
- ai.transcript.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__note-group", "aria-label": "Transcript", children: [
8431
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "mx-meet__note-group-title", children: "Transcript" }),
8432
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet__transcript", children: ai.transcript.map((line) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
10077
+ ai.transcript.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__note-group", "aria-label": "Transcript", children: [
10078
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { className: "mx-meet__note-group-title", children: "Transcript" }),
10079
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ul", { className: "mx-meet__transcript", children: ai.transcript.map((line) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8433
10080
  "li",
8434
10081
  {
8435
10082
  className: line.final && line.source === "record" ? "mx-meet__line" : "mx-meet__line mx-meet__line--interim",
8436
10083
  children: [
8437
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: line.speaker }),
8438
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: line.text })
10084
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: line.speaker }),
10085
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: line.text })
8439
10086
  ]
8440
10087
  },
8441
10088
  line.id
8442
10089
  )) })
8443
10090
  ] }) : null,
8444
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
10091
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8445
10092
  "form",
8446
10093
  {
8447
10094
  className: "mx-meet__composer",
@@ -8452,7 +10099,7 @@ function AiPanel({ onClose }) {
8452
10099
  void ai.ask(asked);
8453
10100
  },
8454
10101
  children: [
8455
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10102
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8456
10103
  "input",
8457
10104
  {
8458
10105
  className: "mx-meet__input",
@@ -8462,13 +10109,13 @@ function AiPanel({ onClose }) {
8462
10109
  "aria-label": "Ask about this meeting"
8463
10110
  }
8464
10111
  ),
8465
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", className: "mx-meet__send", disabled: ai.asking, children: ai.asking ? "Asking\u2026" : "Ask" })
10112
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "submit", className: "mx-meet__send", disabled: ai.asking, children: ai.asking ? "Asking\u2026" : "Ask" })
8466
10113
  ]
8467
10114
  }
8468
10115
  ),
8469
- ai.asking && ai.phase !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", role: "status", children: ai.phase }) : null,
8470
- ai.answer !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__answer", children: ai.answer }) : null,
8471
- ai.answer !== null && ai.coverage !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__coverage", children: [
10116
+ ai.asking && ai.phase !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", role: "status", children: ai.phase }) : null,
10117
+ ai.answer !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__answer", children: ai.answer }) : null,
10118
+ ai.answer !== null && ai.coverage !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__coverage", children: [
8472
10119
  "Answered from ",
8473
10120
  ai.coverage.segmentsUsed,
8474
10121
  " of ",
@@ -8477,48 +10124,56 @@ function AiPanel({ onClose }) {
8477
10124
  ai.coverage.truncated ? " (the oldest were left out)" : "",
8478
10125
  "."
8479
10126
  ] }) : null,
8480
- ai.error !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
8481
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
8482
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
10127
+ ai.error !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
10128
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
10129
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
8483
10130
  ] }) : null
8484
10131
  ] });
8485
10132
  }
8486
10133
  function Captions({ lines = 3 }) {
8487
10134
  const ai = useMeetAi();
8488
10135
  const visible = ai.transcript.slice(-lines);
10136
+ const translation = useCaptionTranslation(visible);
8489
10137
  if (visible.length === 0) return null;
8490
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__captions", "aria-live": "polite", "aria-label": "Live captions", children: visible.map((line) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
8491
- "p",
8492
- {
8493
- className: line.final ? "mx-meet__caption" : "mx-meet__caption mx-meet__caption--interim",
8494
- children: [
8495
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: line.speaker }),
8496
- " ",
8497
- line.text
8498
- ]
8499
- },
8500
- line.id
8501
- )) });
10138
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__captions", "aria-live": "polite", "aria-label": "Live captions", children: [
10139
+ visible.map((line) => {
10140
+ const translated = translation.language === null ? void 0 : translation.translations[line.id];
10141
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
10142
+ "p",
10143
+ {
10144
+ className: line.final ? "mx-meet__caption" : "mx-meet__caption mx-meet__caption--interim",
10145
+ children: [
10146
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: line.speaker }),
10147
+ " ",
10148
+ translated ?? line.text,
10149
+ translated !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__caption-original", children: line.text }) : null
10150
+ ]
10151
+ },
10152
+ line.id
10153
+ );
10154
+ }),
10155
+ translation.language !== null && translation.error !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__caption mx-meet__caption--interim", children: translation.error }) : null
10156
+ ] });
8502
10157
  }
8503
10158
  function ConsentNotice() {
8504
10159
  const notice = useConsentNotice();
8505
10160
  if (notice === null) return null;
8506
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__consent", role: "status", children: notice });
10161
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__consent", role: "status", children: notice });
8507
10162
  }
8508
10163
  function AttendanceNotice() {
8509
10164
  const media = useLocalMedia();
8510
10165
  const notice = listenOnlyNotice(media);
8511
10166
  if (notice === null) return null;
8512
10167
  const refused = media.microphone.unavailable;
8513
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__banner mx-meet__banner--attendance", role: "status", children: [
10168
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__banner mx-meet__banner--attendance", role: "status", children: [
8514
10169
  notice,
8515
- refused === null ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__remedy", children: refused.remedy })
10170
+ refused === null ? null : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__remedy", children: refused.remedy })
8516
10171
  ] });
8517
10172
  }
8518
10173
  function PreJoin(props) {
8519
10174
  const host = useMeetHost();
8520
- if (host === null) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(InertNotice, { what: "This meeting" });
8521
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PreJoinBody, { ...props, host });
10175
+ if (host === null) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(InertNotice, { what: "This meeting" });
10176
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PreJoinBody, { ...props, host });
8522
10177
  }
8523
10178
  function PreJoinBody({
8524
10179
  roomName,
@@ -8532,21 +10187,21 @@ function PreJoinBody({
8532
10187
  const recording = useRecording();
8533
10188
  const effects = useMediaEffects();
8534
10189
  const { notice } = useModerationNotice();
8535
- const [mode, setMode] = (0, import_react4.useState)("video");
8536
- const [microphone, setMicrophone] = (0, import_react4.useState)(true);
8537
- const [joining, setJoining] = (0, import_react4.useState)(false);
10190
+ const [mode, setMode] = (0, import_react5.useState)("video");
10191
+ const [microphone, setMicrophone] = (0, import_react5.useState)(true);
10192
+ const [joining, setJoining] = (0, import_react5.useState)(false);
8538
10193
  const camera = devices?.selected.videoinput ?? host.devices.resolve("videoinput");
8539
10194
  const mic = devices?.selected.audioinput ?? host.devices.resolve("audioinput");
8540
10195
  const preview = useCameraPreview(mode === "video" ? camera : void 0, effects.effects);
8541
10196
  const micStream = useMicrophoneStream(microphone ? mic : "off");
8542
10197
  const level = useAudioLevel(micStream);
8543
- const [speakerTesting, setSpeakerTesting] = (0, import_react4.useState)(false);
8544
- (0, import_react4.useEffect)(() => {
10198
+ const [speakerTesting, setSpeakerTesting] = (0, import_react5.useState)(false);
10199
+ (0, import_react5.useEffect)(() => {
8545
10200
  void host.devices.refresh();
8546
10201
  }, [host]);
8547
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__prejoin", children: [
8548
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__preview", children: [
8549
- mode === "video" && preview.preview !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10202
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__prejoin", children: [
10203
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__preview", children: [
10204
+ mode === "video" && preview.preview !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8550
10205
  "video",
8551
10206
  {
8552
10207
  className: "mx-meet__video mx-meet__video--mirror",
@@ -8557,16 +10212,16 @@ function PreJoinBody({
8557
10212
  if (element !== null) preview.preview?.attach(element);
8558
10213
  }
8559
10214
  }
8560
- ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__tile-placeholder", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 96 }) }),
8561
- mode === "video" && preview.error !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__preview-note", children: preview.error }) : null,
8562
- microphone && micStream !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("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__ */ (0, import_jsx_runtime3.jsx)("span", { style: { width: `${Math.min(100, Math.round(level * 160))}%` } }) }) : null
10215
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__tile-placeholder", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 96 }) }),
10216
+ mode === "video" && preview.error !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__preview-note", children: preview.error }) : null,
10217
+ microphone && micStream !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("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__ */ (0, import_jsx_runtime4.jsx)("span", { style: { width: `${Math.min(100, Math.round(level * 160))}%` } }) }) : null
8563
10218
  ] }),
8564
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__prejoin-panel", children: [
8565
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { className: "mx-meet__prejoin-title", children: "Ready to join?" }),
8566
- notice?.kind === "removed" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__warning", children: notice.text }) : null,
8567
- devices?.labelsHidden === true ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__panel-note", children: [
10219
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__prejoin-panel", children: [
10220
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h1", { className: "mx-meet__prejoin-title", children: "Ready to join?" }),
10221
+ notice?.kind === "removed" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__warning", children: notice.text }) : null,
10222
+ devices?.labelsHidden === true ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__panel-note", children: [
8568
10223
  "Your browser is hiding device names until you allow camera and microphone access.",
8569
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10224
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8570
10225
  "button",
8571
10226
  {
8572
10227
  type: "button",
@@ -8578,11 +10233,11 @@ function PreJoinBody({
8578
10233
  }
8579
10234
  )
8580
10235
  ] }) : null,
8581
- devices?.fallbackNotice != null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__warning", children: devices.fallbackNotice }) : null,
8582
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DevicePicker, { kind: "audioinput", label: "Microphone" }),
8583
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__field-row", children: [
8584
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DevicePicker, { kind: "audiooutput", label: "Speaker" }),
8585
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
10236
+ devices?.fallbackNotice != null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__warning", children: devices.fallbackNotice }) : null,
10237
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DevicePicker, { kind: "audioinput", label: "Microphone" }),
10238
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__field-row", children: [
10239
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DevicePicker, { kind: "audiooutput", label: "Speaker" }),
10240
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8586
10241
  "button",
8587
10242
  {
8588
10243
  type: "button",
@@ -8595,19 +10250,19 @@ function PreJoinBody({
8595
10250
  );
8596
10251
  },
8597
10252
  children: [
8598
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SpeakerIcon, { width: 14, height: 14 }),
10253
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SpeakerIcon, { width: 14, height: 14 }),
8599
10254
  " ",
8600
10255
  speakerTesting ? "Playing\u2026" : "Test"
8601
10256
  ]
8602
10257
  }
8603
10258
  )
8604
10259
  ] }),
8605
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DevicePicker, { kind: "videoinput", label: "Camera" }),
8606
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(EffectsSettings, { preview: preview.preview }),
8607
- recording.consentNotice !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__consent", children: recording.consentNotice }) : null,
8608
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__prejoin-actions", children: [
8609
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__toggle", children: [
8610
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10260
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DevicePicker, { kind: "videoinput", label: "Camera" }),
10261
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(EffectsSettings, { preview: preview.preview }),
10262
+ recording.consentNotice !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__consent", children: recording.consentNotice }) : null,
10263
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__prejoin-actions", children: [
10264
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "mx-meet__toggle", children: [
10265
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8611
10266
  "input",
8612
10267
  {
8613
10268
  type: "checkbox",
@@ -8617,8 +10272,8 @@ function PreJoinBody({
8617
10272
  ),
8618
10273
  "Join with video"
8619
10274
  ] }),
8620
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__toggle", children: [
8621
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10275
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "mx-meet__toggle", children: [
10276
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8622
10277
  "input",
8623
10278
  {
8624
10279
  type: "checkbox",
@@ -8628,7 +10283,7 @@ function PreJoinBody({
8628
10283
  ),
8629
10284
  "Join with microphone"
8630
10285
  ] }),
8631
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10286
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8632
10287
  "button",
8633
10288
  {
8634
10289
  type: "button",
@@ -8648,20 +10303,20 @@ function PreJoinBody({
8648
10303
  }
8649
10304
  )
8650
10305
  ] }),
8651
- room.failure !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__error", children: [
10306
+ room.failure !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__error", children: [
8652
10307
  room.failure.message,
8653
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__remedy", children: room.failure.remedy })
10308
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__remedy", children: room.failure.remedy })
8654
10309
  ] }) : null
8655
10310
  ] })
8656
10311
  ] });
8657
10312
  }
8658
10313
  function useCameraPreview(deviceId2, effects) {
8659
- const [preview, setPreview] = (0, import_react4.useState)(null);
8660
- const [error, setError] = (0, import_react4.useState)(null);
8661
- const current = (0, import_react4.useRef)(null);
8662
- const initialEffect = (0, import_react4.useRef)(toVideoEffect(effects));
10314
+ const [preview, setPreview] = (0, import_react5.useState)(null);
10315
+ const [error, setError] = (0, import_react5.useState)(null);
10316
+ const current = (0, import_react5.useRef)(null);
10317
+ const initialEffect = (0, import_react5.useRef)(toVideoEffect(effects));
8663
10318
  initialEffect.current = toVideoEffect(effects);
8664
- (0, import_react4.useEffect)(() => {
10319
+ (0, import_react5.useEffect)(() => {
8665
10320
  if (deviceId2 === void 0) return void 0;
8666
10321
  let live = true;
8667
10322
  setError(null);
@@ -8705,9 +10360,9 @@ function DevicePicker({
8705
10360
  const devices = useDeviceSnapshot();
8706
10361
  const list = devices?.devices[kind] ?? [];
8707
10362
  if (list.length === 0) return null;
8708
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
8709
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: label }),
8710
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10363
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "mx-meet__field", children: [
10364
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__field-label", children: label }),
10365
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8711
10366
  "select",
8712
10367
  {
8713
10368
  className: "mx-meet__select",
@@ -8716,7 +10371,7 @@ function DevicePicker({
8716
10371
  if (onPick !== void 0) onPick(kind, event.target.value);
8717
10372
  else host.devices.select(kind, event.target.value);
8718
10373
  },
8719
- children: list.map((device) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: device.deviceId, children: device.label.length > 0 ? device.label : `${label} (name hidden)` }, device.deviceId))
10374
+ children: list.map((device) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: device.deviceId, children: device.label.length > 0 ? device.label : `${label} (name hidden)` }, device.deviceId))
8720
10375
  }
8721
10376
  )
8722
10377
  ] });
@@ -8724,9 +10379,9 @@ function DevicePicker({
8724
10379
  function MeetingRoom(props) {
8725
10380
  const host = useMeetHost();
8726
10381
  if (host === null) {
8727
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(InertNotice, { what: "This meeting" }) });
10382
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(InertNotice, { what: "This meeting" }) });
8728
10383
  }
8729
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MeetingRoomBody, { ...props, host });
10384
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MeetingRoomBody, { ...props, host });
8730
10385
  }
8731
10386
  function MeetingRoomBody({
8732
10387
  roomName,
@@ -8741,25 +10396,25 @@ function MeetingRoomBody({
8741
10396
  const isHost = useIsHost();
8742
10397
  const elapsed = useElapsed(snapshot?.meeting?.startedAt ?? null);
8743
10398
  const phase = snapshot?.phase ?? "idle";
8744
- (0, import_react4.useEffect)(() => {
10399
+ (0, import_react5.useEffect)(() => {
8745
10400
  host.meetings.watch(roomName);
8746
10401
  }, [host, roomName]);
8747
- (0, import_react4.useEffect)(() => {
10402
+ (0, import_react5.useEffect)(() => {
8748
10403
  if (given === void 0) return;
8749
10404
  if (host.store.snapshot().meeting !== null) return;
8750
10405
  host.store.patch({ meeting: given, locked: given.locked });
8751
10406
  }, [host, given]);
8752
10407
  const watchedId = meetingId ?? snapshot?.meeting?.id ?? null;
8753
- (0, import_react4.useEffect)(() => {
10408
+ (0, import_react5.useEffect)(() => {
8754
10409
  if (watchedId === null) return;
8755
10410
  host.meetings.watchMeeting(asMeetingId(watchedId));
8756
10411
  }, [host, watchedId]);
8757
10412
  const record = snapshot?.meeting ?? given ?? null;
8758
10413
  if (hasEnded(record) && phase !== "connected" && phase !== "reconnecting") {
8759
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MeetingRecordView, { meeting: record });
10414
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MeetingRecordView, { meeting: record });
8760
10415
  }
8761
10416
  if (phase === "idle" || phase === "failed" || phase === "left") {
8762
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10417
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8763
10418
  PreJoin,
8764
10419
  {
8765
10420
  roomName,
@@ -8769,42 +10424,42 @@ function MeetingRoomBody({
8769
10424
  ) });
8770
10425
  }
8771
10426
  if (phase === "lobby") {
8772
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet mx-meet--lobby", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(WaitingRoom, { roomName, host }) });
8773
- }
8774
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet", children: [
8775
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ConsentNotice, {}),
8776
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AttendanceNotice, {}),
8777
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "mx-meet__header", children: [
8778
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { className: "mx-meet__title", children: snapshot?.meeting?.title ?? "Meeting" }),
8779
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__meta", children: [
10427
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet mx-meet--lobby", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(WaitingRoom, { roomName, host }) });
10428
+ }
10429
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet", children: [
10430
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ConsentNotice, {}),
10431
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AttendanceNotice, {}),
10432
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("header", { className: "mx-meet__header", children: [
10433
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h1", { className: "mx-meet__title", children: snapshot?.meeting?.title ?? "Meeting" }),
10434
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__meta", children: [
8780
10435
  participantSummary(snapshot?.participants ?? []),
8781
10436
  elapsed > 0 ? ` \xB7 ${(0, import_format3.formatDurationMs)(elapsed)}` : ""
8782
10437
  ] }),
8783
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RecordingIndicator, {}),
8784
- snapshot?.locked === true ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__badge", children: [
8785
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(LockIcon, { width: 12, height: 12 }),
10438
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RecordingIndicator, {}),
10439
+ snapshot?.locked === true ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__badge", children: [
10440
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LockIcon, { width: 12, height: 12 }),
8786
10441
  " Locked"
8787
10442
  ] }) : null,
8788
- headerControls !== void 0 && headerControls !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__header-controls", "data-meet-header-controls": "", children: headerControls }) : null,
8789
- isHost ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HostMenu, {}) : null
10443
+ headerControls !== void 0 && headerControls !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__header-controls", "data-meet-header-controls": "", children: headerControls }) : null,
10444
+ isHost ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HostMenu, {}) : null
8790
10445
  ] }),
8791
- phase === "reconnecting" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__banner", role: "status", children: "Reconnecting\u2026" }) : null,
8792
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stage, {}),
8793
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Captions, {}),
8794
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ControlBar, { ...onLeave !== void 0 ? { onLeave } : {} })
10446
+ phase === "reconnecting" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__banner", role: "status", children: "Reconnecting\u2026" }) : null,
10447
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Stage, {}),
10448
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Captions, {}),
10449
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ControlBar, { ...onLeave !== void 0 ? { onLeave } : {} })
8795
10450
  ] });
8796
10451
  }
8797
10452
  function WaitingRoom({ roomName, host }) {
8798
- const knocked = (0, import_react4.useRef)(false);
8799
- (0, import_react4.useEffect)(() => {
10453
+ const knocked = (0, import_react5.useRef)(false);
10454
+ (0, import_react5.useEffect)(() => {
8800
10455
  if (knocked.current) return;
8801
10456
  knocked.current = true;
8802
10457
  host.meetings.knock(roomName);
8803
10458
  }, [host, roomName]);
8804
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__waiting", children: [
8805
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 72 }),
8806
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { className: "mx-meet__prejoin-title", children: "Waiting for the host to let you in" }),
8807
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__empty-body", children: [
10459
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__waiting", children: [
10460
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 72 }),
10461
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h1", { className: "mx-meet__prejoin-title", children: "Waiting for the host to let you in" }),
10462
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__empty-body", children: [
8808
10463
  "You are in the waiting room as ",
8809
10464
  host.identity.displayName,
8810
10465
  ". You will join automatically once you are admitted."
@@ -8815,10 +10470,10 @@ function HostMenu() {
8815
10470
  const host = useRequiredMeetHost();
8816
10471
  const snapshot = useMeetSnapshot();
8817
10472
  const end = useEndMeeting();
8818
- const [confirmingEnd, setConfirmingEnd] = (0, import_react4.useState)(false);
10473
+ const [confirmingEnd, setConfirmingEnd] = (0, import_react5.useState)(false);
8819
10474
  const locked = snapshot?.locked === true;
8820
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__host-menu", children: [
8821
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10475
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__host-menu", children: [
10476
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8822
10477
  "button",
8823
10478
  {
8824
10479
  type: "button",
@@ -8829,9 +10484,9 @@ function HostMenu() {
8829
10484
  children: locked ? "Unlock meeting" : "Lock meeting"
8830
10485
  }
8831
10486
  ),
8832
- end.canEnd ? confirmingEnd ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__confirm", role: "group", "aria-label": "End this meeting?", children: [
8833
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("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." }),
8834
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10487
+ end.canEnd ? confirmingEnd ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__confirm", role: "group", "aria-label": "End this meeting?", children: [
10488
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("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." }),
10489
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8835
10490
  "button",
8836
10491
  {
8837
10492
  type: "button",
@@ -8843,7 +10498,7 @@ function HostMenu() {
8843
10498
  children: "End it"
8844
10499
  }
8845
10500
  ),
8846
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10501
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8847
10502
  "button",
8848
10503
  {
8849
10504
  type: "button",
@@ -8852,7 +10507,7 @@ function HostMenu() {
8852
10507
  children: "Keep it running"
8853
10508
  }
8854
10509
  )
8855
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10510
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8856
10511
  "button",
8857
10512
  {
8858
10513
  type: "button",
@@ -8861,7 +10516,7 @@ function HostMenu() {
8861
10516
  children: end.ending ? "Ending\u2026" : "End meeting for everyone"
8862
10517
  }
8863
10518
  ) : null,
8864
- end.notice !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__notice", role: "status", children: end.notice }) : null
10519
+ end.notice !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__notice", role: "status", children: end.notice }) : null
8865
10520
  ] });
8866
10521
  }
8867
10522
  function CallButton({
@@ -8871,7 +10526,7 @@ function CallButton({
8871
10526
  }) {
8872
10527
  const calls = useCalls();
8873
10528
  if (!calls.canCall) return null;
8874
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10529
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8875
10530
  "button",
8876
10531
  {
8877
10532
  type: "button",
@@ -8880,55 +10535,55 @@ function CallButton({
8880
10535
  void calls.call([person.userId], mode);
8881
10536
  },
8882
10537
  "aria-label": `Call ${person.displayName}`,
8883
- children: children ?? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PhoneIcon, { width: 18, height: 18 })
10538
+ children: children ?? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PhoneIcon, { width: 18, height: 18 })
8884
10539
  }
8885
10540
  );
8886
10541
  }
8887
10542
  function IncomingCallHost() {
8888
10543
  const calls = useCalls();
8889
10544
  if (calls.incoming.length === 0) return null;
8890
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__ringing-stack", children: calls.incoming.map((invite) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(IncomingCallCard, { invite }, invite.id)) });
10545
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__ringing-stack", children: calls.incoming.map((invite) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IncomingCallCard, { invite }, invite.id)) });
8891
10546
  }
8892
10547
  function IncomingCallCard({ invite }) {
8893
10548
  const calls = useCalls();
8894
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__ringing", role: "alertdialog", "aria-label": "Incoming call", children: [
8895
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Avatar, { name: invite.callerName, url: invite.callerAvatarUrl, size: 56 }),
8896
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__ringing-text", children: [
8897
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: invite.callerName }),
8898
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: invite.mode === "video" ? "Incoming video call" : "Incoming call" })
10549
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__ringing", role: "alertdialog", "aria-label": "Incoming call", children: [
10550
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Avatar, { name: invite.callerName, url: invite.callerAvatarUrl, size: 56 }),
10551
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__ringing-text", children: [
10552
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: invite.callerName }),
10553
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: invite.mode === "video" ? "Incoming video call" : "Incoming call" })
8899
10554
  ] }),
8900
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__ringing-actions", children: [
8901
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ControlButton, { label: "Decline", danger: true, onClick: () => void calls.decline(invite), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PhoneOffIcon, {}) }),
8902
- invite.mode === "video" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10555
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__ringing-actions", children: [
10556
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ControlButton, { label: "Decline", danger: true, onClick: () => void calls.decline(invite), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PhoneOffIcon, {}) }),
10557
+ invite.mode === "video" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8903
10558
  ControlButton,
8904
10559
  {
8905
10560
  label: "Accept without video",
8906
10561
  onClick: () => void calls.accept({ ...invite, mode: "audio" }),
8907
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CameraOffIcon, {})
10562
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CameraOffIcon, {})
8908
10563
  }
8909
10564
  ) : null,
8910
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ControlButton, { label: "Accept", onClick: () => void calls.accept(invite), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PhoneIcon, {}) })
10565
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ControlButton, { label: "Accept", onClick: () => void calls.accept(invite), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PhoneIcon, {}) })
8911
10566
  ] })
8912
10567
  ] });
8913
10568
  }
8914
10569
  function ScheduleMeeting(props) {
8915
10570
  const host = useMeetHost();
8916
- if (host === null) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(InertNotice, { what: "Scheduling a meeting" });
8917
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ScheduleMeetingBody, { ...props, host });
10571
+ if (host === null) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(InertNotice, { what: "Scheduling a meeting" });
10572
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ScheduleMeetingBody, { ...props, host });
8918
10573
  }
8919
10574
  function ScheduleMeetingBody({
8920
10575
  appBaseUrl,
8921
10576
  onScheduled,
8922
10577
  host
8923
10578
  }) {
8924
- const [title, setTitle] = (0, import_react4.useState)("");
8925
- const [when2, setWhen] = (0, import_react4.useState)("");
8926
- const [kind, setKind] = (0, import_react4.useState)("scheduled");
8927
- const [busy, setBusy] = (0, import_react4.useState)(false);
8928
- const [link, setLink] = (0, import_react4.useState)(null);
8929
- const [error, setError] = (0, import_react4.useState)(null);
8930
- const disabled = (0, import_react4.useMemo)(() => title.trim().length === 0 || busy, [title, busy]);
8931
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
10579
+ const [title, setTitle] = (0, import_react5.useState)("");
10580
+ const [when2, setWhen] = (0, import_react5.useState)("");
10581
+ const [kind, setKind] = (0, import_react5.useState)("scheduled");
10582
+ const [busy, setBusy] = (0, import_react5.useState)(false);
10583
+ const [link, setLink] = (0, import_react5.useState)(null);
10584
+ const [error, setError] = (0, import_react5.useState)(null);
10585
+ const disabled = (0, import_react5.useMemo)(() => title.trim().length === 0 || busy, [title, busy]);
10586
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8932
10587
  "form",
8933
10588
  {
8934
10589
  className: "mx-meet__schedule",
@@ -8953,9 +10608,9 @@ function ScheduleMeetingBody({
8953
10608
  }).finally(() => setBusy(false));
8954
10609
  },
8955
10610
  children: [
8956
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
8957
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: "Title" }),
8958
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10611
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "mx-meet__field", children: [
10612
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__field-label", children: "Title" }),
10613
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8959
10614
  "input",
8960
10615
  {
8961
10616
  className: "mx-meet__input",
@@ -8965,9 +10620,9 @@ function ScheduleMeetingBody({
8965
10620
  }
8966
10621
  )
8967
10622
  ] }),
8968
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
8969
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: "When" }),
8970
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10623
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "mx-meet__field", children: [
10624
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__field-label", children: "When" }),
10625
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8971
10626
  "input",
8972
10627
  {
8973
10628
  className: "mx-meet__input",
@@ -8977,27 +10632,27 @@ function ScheduleMeetingBody({
8977
10632
  }
8978
10633
  )
8979
10634
  ] }),
8980
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
8981
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: "Repeats" }),
8982
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
10635
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "mx-meet__field", children: [
10636
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__field-label", children: "Repeats" }),
10637
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8983
10638
  "select",
8984
10639
  {
8985
10640
  className: "mx-meet__select",
8986
10641
  value: kind,
8987
10642
  onChange: (event) => setKind(event.target.value),
8988
10643
  children: [
8989
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "scheduled", children: "Once" }),
8990
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "recurring", children: "Recurring \u2014 one link, every time" })
10644
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "scheduled", children: "Once" }),
10645
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "recurring", children: "Recurring \u2014 one link, every time" })
8991
10646
  ]
8992
10647
  }
8993
10648
  )
8994
10649
  ] }),
8995
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", className: "mx-meet__primary", disabled, children: busy ? "Creating\u2026" : "Create meeting" }),
8996
- link !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__link-out", children: [
8997
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "Anyone with this link can join \u2014 no account needed." }),
8998
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("code", { children: link })
10650
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "submit", className: "mx-meet__primary", disabled, children: busy ? "Creating\u2026" : "Create meeting" }),
10651
+ link !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__link-out", children: [
10652
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Anyone with this link can join \u2014 no account needed." }),
10653
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("code", { children: link })
8999
10654
  ] }) : null,
9000
- error !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__error", children: error }) : null
10655
+ error !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__error", children: error }) : null
9001
10656
  ]
9002
10657
  }
9003
10658
  );
@@ -9006,7 +10661,7 @@ function ReactionOverlay({
9006
10661
  reactions
9007
10662
  }) {
9008
10663
  if (reactions.length === 0) return null;
9009
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__reactions", "aria-hidden": "true", children: reactions.map((reaction) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__reaction", children: reaction.emoji }, reaction.id)) });
10664
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__reactions", "aria-hidden": "true", children: reactions.map((reaction) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__reaction", children: reaction.emoji }, reaction.id)) });
9010
10665
  }
9011
10666
  function GuestRecordAccessControl({
9012
10667
  meeting
@@ -9018,11 +10673,11 @@ function GuestRecordAccessControl({
9018
10673
  const isHost = inRoomHost || viewerId !== null && meeting.hostUserId === viewerId;
9019
10674
  if (host === null || !isHost) return null;
9020
10675
  const resolved = access.setting === "default" && access.effective !== null ? ` Right now that means: ${guestRecordAccessLabel(access.effective.level).toLowerCase()}.` : "";
9021
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "What guests may read", children: [
9022
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "What guests may read" }),
9023
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
9024
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: "People who attended by link, without an account" }),
9025
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10676
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "What guests may read", children: [
10677
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "mx-meet__record-section-title", children: "What guests may read" }),
10678
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "mx-meet__field", children: [
10679
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__field-label", children: "People who attended by link, without an account" }),
10680
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9026
10681
  "select",
9027
10682
  {
9028
10683
  className: "mx-meet__select",
@@ -9033,18 +10688,18 @@ function GuestRecordAccessControl({
9033
10688
  event.target.value
9034
10689
  );
9035
10690
  },
9036
- children: GUEST_RECORD_ACCESS_CHOICES.map((choice) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: choice, children: guestRecordAccessLabel(choice) }, choice))
10691
+ children: GUEST_RECORD_ACCESS_CHOICES.map((choice) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: choice, children: guestRecordAccessLabel(choice) }, choice))
9037
10692
  }
9038
10693
  )
9039
10694
  ] }),
9040
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__panel-note", children: [
10695
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__panel-note", children: [
9041
10696
  guestRecordAccessExplanation(access.setting),
9042
10697
  resolved
9043
10698
  ] }),
9044
- access.saving ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", role: "status", children: "Saving what guests may read\u2026" }) : null,
9045
- access.error !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error: access.error, operation: "Change who can join", origin: "meet/components", children: [
9046
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-reason", children: access.error.message }),
9047
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-remedy", children: access.error.remedy })
10699
+ access.saving ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", role: "status", children: "Saving what guests may read\u2026" }) : null,
10700
+ access.error !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error: access.error, operation: "Change who can join", origin: "meet/components", children: [
10701
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-reason", children: access.error.message }),
10702
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-remedy", children: access.error.remedy })
9048
10703
  ] }) : null
9049
10704
  ] });
9050
10705
  }
@@ -9054,9 +10709,9 @@ function MeetingRecordView({
9054
10709
  }) {
9055
10710
  const host = useMeetHost();
9056
10711
  if (host === null) {
9057
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(InertNotice, { what: "This meeting record" }) });
10712
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(InertNotice, { what: "This meeting record" }) });
9058
10713
  }
9059
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MeetingRecordBody, { meeting, ...onRejoin !== void 0 ? { onRejoin } : {} });
10714
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MeetingRecordBody, { meeting, ...onRejoin !== void 0 ? { onRejoin } : {} });
9060
10715
  }
9061
10716
  function MeetingRecordBody({
9062
10717
  meeting,
@@ -9064,19 +10719,19 @@ function MeetingRecordBody({
9064
10719
  }) {
9065
10720
  const host = useRequiredMeetHost();
9066
10721
  const record = useMeetingRecord(meeting);
9067
- const [question, setQuestion] = (0, import_react4.useState)("");
9068
- const [tab, setTab] = (0, import_react4.useState)("summary");
10722
+ const [question, setQuestion] = (0, import_react5.useState)("");
10723
+ const [tab, setTab] = (0, import_react5.useState)("summary");
9069
10724
  if (record.failure !== null) {
9070
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__empty", error: record.failure, operation: "Open this meeting record", origin: "meet/components", children: [
9071
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-title", children: "This meeting record could not be opened" }),
9072
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-body", children: record.failure.message }),
9073
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-body", children: record.failure.remedy })
10725
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__empty", error: record.failure, operation: "Open this meeting record", origin: "meet/components", children: [
10726
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-title", children: "This meeting record could not be opened" }),
10727
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-body", children: record.failure.message }),
10728
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-body", children: record.failure.remedy })
9074
10729
  ] }) });
9075
10730
  }
9076
10731
  if (record.loading || record.record === null) {
9077
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__empty", role: "status", children: [
9078
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-title", children: "Opening the meeting record\u2026" }),
9079
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-body", children: "Reading the summary, the notes and the transcript this meeting left behind." })
10732
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__empty", role: "status", children: [
10733
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-title", children: "Opening the meeting record\u2026" }),
10734
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-body", children: "Reading the summary, the notes and the transcript this meeting left behind." })
9080
10735
  ] }) });
9081
10736
  }
9082
10737
  const bundle = record.record;
@@ -9095,44 +10750,44 @@ function MeetingRecordBody({
9095
10750
  );
9096
10751
  const entirelyRestricted = everyRecordPartRefused && bundle.attendees.length === 0 && bundle.liveNotes.length === 0 && bundle.transcript.length === 0 && bundle.recording === null && bundle.summary === null && bundle.decisions.length === 0 && bundle.actionItems.length === 0;
9097
10752
  if (entirelyRestricted) {
9098
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet mx-meet--record", children: [
9099
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__record-head-inner", children: [
9100
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
9101
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { className: "mx-meet__record-title", children: meeting.title }),
9102
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
9103
- onRejoin !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
10753
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet mx-meet--record", children: [
10754
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__record-head-inner", children: [
10755
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
10756
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h1", { className: "mx-meet__record-title", children: meeting.title }),
10757
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
10758
+ onRejoin !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
9104
10759
  ] }) }),
9105
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__record-body", children: restrictionNotices.map((notice2) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__record-access", role: "status", children: [
9106
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-access-title", children: "About this record" }),
9107
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-access-message", children: notice2.message }),
9108
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
10760
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__record-body", children: restrictionNotices.map((notice2) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__record-access", role: "status", children: [
10761
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-access-title", children: "About this record" }),
10762
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-access-message", children: notice2.message }),
10763
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
9109
10764
  ] }, notice2.parts.join("-"))) })
9110
10765
  ] });
9111
10766
  }
9112
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet mx-meet--record", children: [
9113
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__record-head-inner", children: [
9114
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
9115
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { className: "mx-meet__record-title", children: meeting.title }),
9116
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
9117
- onRejoin !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
10767
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet mx-meet--record", children: [
10768
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__record-head-inner", children: [
10769
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
10770
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h1", { className: "mx-meet__record-title", children: meeting.title }),
10771
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
10772
+ onRejoin !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
9118
10773
  ] }) }),
9119
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__record-body", children: [
9120
- restrictionNotices.map((notice2) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__record-access", role: "status", children: [
9121
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-access-title", children: "About this record" }),
9122
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-access-message", children: notice2.message }),
9123
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
10774
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__record-body", children: [
10775
+ restrictionNotices.map((notice2) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__record-access", role: "status", children: [
10776
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-access-title", children: "About this record" }),
10777
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-access-message", children: notice2.message }),
10778
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
9124
10779
  ] }, notice2.parts.join("-"))),
9125
10780
  attended.length === 0 ? (
9126
10781
  /* NOT SILENCE. A refused attendance read used to remove the whole
9127
10782
  section, so the reader could not tell "nobody" from "not shown". */
9128
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
9129
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
9130
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: absenceSentence(bundle, "attendance", "Nobody is recorded as having attended.") })
10783
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
10784
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
10785
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", children: absenceSentence(bundle, "attendance", "Nobody is recorded as having attended.") })
9131
10786
  ] })
9132
- ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
9133
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
9134
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet__record-attendees", children: attended.map((person) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet__record-attendee", children: [
9135
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10787
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
10788
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
10789
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ul", { className: "mx-meet__record-attendees", children: attended.map((person) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("li", { className: "mx-meet__record-attendee", children: [
10790
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9136
10791
  Avatar,
9137
10792
  {
9138
10793
  name: displayNameFor(bundle.names, person.identity, person.displayName),
@@ -9140,26 +10795,26 @@ function MeetingRecordBody({
9140
10795
  size: 28
9141
10796
  }
9142
10797
  ),
9143
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__person-name", children: [
10798
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__person-name", children: [
9144
10799
  displayNameFor(bundle.names, person.identity, person.displayName),
9145
- person.role === "host" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Host" }) : null,
9146
- person.role === "guest" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Guest" }) : null,
9147
- person.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null
10800
+ person.role === "host" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__badge", children: "Host" }) : null,
10801
+ person.role === "guest" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__badge", children: "Guest" }) : null,
10802
+ person.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null
9148
10803
  ] })
9149
10804
  ] }, person.id)) })
9150
10805
  ] }),
9151
- bundle.recording !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section mx-meet__recording-card", "aria-label": "Recording", children: [
9152
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
9153
- fileId !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
9154
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RecordingPlayer, { fileId }),
9155
- notice !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: notice }) : null
9156
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: notice ?? "This recording has no file." })
9157
- ] }) : wasRefused(bundle, "recording") ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Recording", children: [
9158
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
9159
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: REFUSED_ABSENCE })
10806
+ bundle.recording !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__record-section mx-meet__recording-card", "aria-label": "Recording", children: [
10807
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
10808
+ fileId !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
10809
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RecordingPlayer, { fileId }),
10810
+ notice !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", children: notice }) : null
10811
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", children: notice ?? "This recording has no file." })
10812
+ ] }) : wasRefused(bundle, "recording") ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Recording", children: [
10813
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
10814
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", children: REFUSED_ABSENCE })
9160
10815
  ] }) : null,
9161
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("nav", { className: "mx-meet__record-tabs", "aria-label": "Meeting record sections", children: [
9162
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10816
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("nav", { className: "mx-meet__record-tabs", "aria-label": "Meeting record sections", children: [
10817
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9163
10818
  "button",
9164
10819
  {
9165
10820
  type: "button",
@@ -9169,7 +10824,7 @@ function MeetingRecordBody({
9169
10824
  children: "Summary & decisions"
9170
10825
  }
9171
10826
  ),
9172
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10827
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9173
10828
  "button",
9174
10829
  {
9175
10830
  type: "button",
@@ -9179,7 +10834,7 @@ function MeetingRecordBody({
9179
10834
  children: "Notes as it happened"
9180
10835
  }
9181
10836
  ),
9182
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10837
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9183
10838
  "button",
9184
10839
  {
9185
10840
  type: "button",
@@ -9190,15 +10845,15 @@ function MeetingRecordBody({
9190
10845
  }
9191
10846
  )
9192
10847
  ] }),
9193
- tab === "summary" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
9194
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Summary", children: [
9195
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "Summary" }),
9196
- wrapUp.state === "written" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-summary", children: bundle.summary?.text }) : wrapUp.state === "in-progress" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__panel-note", role: "status", children: [
9197
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { children: wrapUp.message }),
9198
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: record.reload, children: "Check again" })
9199
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", role: wrapUp.state === "failed" ? "alert" : void 0, children: wrapUp.message })
10848
+ tab === "summary" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
10849
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Summary", children: [
10850
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "mx-meet__record-section-title", children: "Summary" }),
10851
+ wrapUp.state === "written" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-summary", children: bundle.summary?.text }) : wrapUp.state === "in-progress" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__panel-note", role: "status", children: [
10852
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { children: wrapUp.message }),
10853
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", className: "mx-meet__link", onClick: record.reload, children: "Check again" })
10854
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", role: wrapUp.state === "failed" ? "alert" : void 0, children: wrapUp.message })
9200
10855
  ] }),
9201
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10856
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9202
10857
  NoteList,
9203
10858
  {
9204
10859
  title: "Decisions",
@@ -9210,7 +10865,7 @@ function MeetingRecordBody({
9210
10865
  )
9211
10866
  }
9212
10867
  ),
9213
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10868
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9214
10869
  NoteList,
9215
10870
  {
9216
10871
  title: "Action items",
@@ -9223,42 +10878,42 @@ function MeetingRecordBody({
9223
10878
  }
9224
10879
  )
9225
10880
  ] }) : null,
9226
- tab === "notes" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Notes as it happened", children: [
9227
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "Notes as it happened" }),
9228
- bundle.liveNotes.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: absenceSentence(
10881
+ tab === "notes" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Notes as it happened", children: [
10882
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "mx-meet__record-section-title", children: "Notes as it happened" }),
10883
+ bundle.liveNotes.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", children: absenceSentence(
9229
10884
  bundle,
9230
10885
  "notes",
9231
10886
  "No live notes are available for this meeting."
9232
- ) }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet__notes", children: bundle.liveNotes.map((note) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet__note", children: [
9233
- note.window !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__badge", children: [
10887
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ul", { className: "mx-meet__notes", children: bundle.liveNotes.map((note) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("li", { className: "mx-meet__note", children: [
10888
+ note.window !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__badge", children: [
9234
10889
  "Window ",
9235
10890
  note.window
9236
10891
  ] }) : null,
9237
10892
  note.text
9238
10893
  ] }, note.id)) })
9239
10894
  ] }) : null,
9240
- tab === "transcript" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Transcript", children: [
9241
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("h2", { className: "mx-meet__record-section-title", children: [
10895
+ tab === "transcript" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Transcript", children: [
10896
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("h2", { className: "mx-meet__record-section-title", children: [
9242
10897
  "Transcript",
9243
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__record-count", children: bundle.transcript.length === 1 ? "1 line" : `${bundle.transcript.length} lines` })
10898
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__record-count", children: bundle.transcript.length === 1 ? "1 line" : `${bundle.transcript.length} lines` })
9244
10899
  ] }),
9245
- blocks.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: absenceSentence(
10900
+ blocks.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", children: absenceSentence(
9246
10901
  bundle,
9247
10902
  "transcript",
9248
10903
  "No transcript is available for this meeting."
9249
- ) }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ol", { className: "mx-meet__record-transcript", children: blocks.map((block) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet__record-block", children: [
9250
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__record-speaker", children: [
10904
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ol", { className: "mx-meet__record-transcript", children: blocks.map((block) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("li", { className: "mx-meet__record-block", children: [
10905
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__record-speaker", children: [
9251
10906
  block.speaker,
9252
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("time", { className: "mx-meet__record-time", dateTime: block.startedAt, children: clockOf(block.startedAt) })
10907
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("time", { className: "mx-meet__record-time", dateTime: block.startedAt, children: clockOf(block.startedAt) })
9253
10908
  ] }),
9254
- block.lines.map((line) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-line", children: line.text }, line.id))
10909
+ block.lines.map((line) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-line", children: line.text }, line.id))
9255
10910
  ] }, block.id)) })
9256
10911
  ] }) : null,
9257
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(GuestRecordAccessControl, { meeting }),
9258
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Ask about this meeting", children: [
9259
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "Ask about this meeting" }),
9260
- guestFinishedMeeting ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: "Sign in to ask the assistant about a meeting after it ends." }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
9261
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
10912
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(GuestRecordAccessControl, { meeting }),
10913
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Ask about this meeting", children: [
10914
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "mx-meet__record-section-title", children: "Ask about this meeting" }),
10915
+ guestFinishedMeeting ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", children: "Sign in to ask the assistant about a meeting after it ends." }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
10916
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
9262
10917
  "form",
9263
10918
  {
9264
10919
  className: "mx-meet__composer",
@@ -9269,7 +10924,7 @@ function MeetingRecordBody({
9269
10924
  void record.ask(trimmed);
9270
10925
  },
9271
10926
  children: [
9272
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10927
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9273
10928
  "input",
9274
10929
  {
9275
10930
  className: "mx-meet__input",
@@ -9279,7 +10934,7 @@ function MeetingRecordBody({
9279
10934
  "aria-label": "Ask about this meeting"
9280
10935
  }
9281
10936
  ),
9282
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10937
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9283
10938
  "button",
9284
10939
  {
9285
10940
  type: "submit",
@@ -9291,8 +10946,8 @@ function MeetingRecordBody({
9291
10946
  ]
9292
10947
  }
9293
10948
  ),
9294
- record.answer !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__answer", children: record.answer }) : null,
9295
- record.coverage !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__coverage", children: [
10949
+ record.answer !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__answer", children: record.answer }) : null,
10950
+ record.coverage !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__coverage", children: [
9296
10951
  "Answered from ",
9297
10952
  record.coverage.segmentsUsed,
9298
10953
  " of ",
@@ -9303,9 +10958,9 @@ function MeetingRecordBody({
9303
10958
  record.coverage.truncated ? " (the oldest were left out)" : "",
9304
10959
  "."
9305
10960
  ] }) : null,
9306
- record.askError !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error: record.askError, operation: "Ask about this meeting", origin: "meet/components", children: [
9307
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-reason", children: record.askError.message }),
9308
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-remedy", children: record.askError.remedy })
10961
+ record.askError !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error: record.askError, operation: "Ask about this meeting", origin: "meet/components", children: [
10962
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-reason", children: record.askError.message }),
10963
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-remedy", children: record.askError.remedy })
9309
10964
  ] }) : null
9310
10965
  ] })
9311
10966
  ] })
@@ -9316,21 +10971,21 @@ var STREAM_REFUSED = "Streaming playback did not start, so this recording was do
9316
10971
  var PLAYBACK_RETRY_REMEDY = "Reload the page and try again. If it still will not play, ask a meeting host to check the recording.";
9317
10972
  function RecordingPlayer(props) {
9318
10973
  const host = useMeetHost();
9319
- if (host === null) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(InertNotice, { what: "This recording" });
9320
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RecordingPlayerBody, { ...props, host });
10974
+ if (host === null) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(InertNotice, { what: "This recording" });
10975
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RecordingPlayerBody, { ...props, host });
9321
10976
  }
9322
10977
  function RecordingPlayerBody({ fileId, host }) {
9323
- const [media, setMedia] = (0, import_react4.useState)(null);
9324
- const [loading, setLoading] = (0, import_react4.useState)(false);
9325
- const [error, setError] = (0, import_react4.useState)(null);
9326
- (0, import_react4.useEffect)(() => {
10978
+ const [media, setMedia] = (0, import_react5.useState)(null);
10979
+ const [loading, setLoading] = (0, import_react5.useState)(false);
10980
+ const [error, setError] = (0, import_react5.useState)(null);
10981
+ (0, import_react5.useEffect)(() => {
9327
10982
  if (media === null || media.kind !== "bytes") return void 0;
9328
10983
  const url = media.url;
9329
10984
  return () => URL.revokeObjectURL(url);
9330
10985
  }, [media]);
9331
10986
  if (media !== null) {
9332
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__record-section", children: [
9333
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10987
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__record-section", children: [
10988
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9334
10989
  "video",
9335
10990
  {
9336
10991
  className: "mx-meet__record-player",
@@ -9372,15 +11027,15 @@ function RecordingPlayerBody({ fileId, host }) {
9372
11027
  }
9373
11028
  }
9374
11029
  ),
9375
- media.fallbackReason !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: media.fallbackReason }) : null
11030
+ media.fallbackReason !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", children: media.fallbackReason }) : null
9376
11031
  ] });
9377
11032
  }
9378
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__record-section", children: [
9379
- error !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error, operation: "Complete this meeting action", origin: "meet/components", children: [
9380
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-reason", children: error.message }),
9381
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-remedy", children: error.remedy })
11033
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__record-section", children: [
11034
+ error !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error, operation: "Complete this meeting action", origin: "meet/components", children: [
11035
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-reason", children: error.message }),
11036
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-remedy", children: error.remedy })
9382
11037
  ] }) : null,
9383
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
11038
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9384
11039
  "button",
9385
11040
  {
9386
11041
  type: "button",
@@ -9416,35 +11071,35 @@ function clockOf(iso) {
9416
11071
  function MeetingList({ baseUrl }) {
9417
11072
  const host = useMeetHost();
9418
11073
  const list = useMeetings();
9419
- if (host === null) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(InertNotice, { what: "Your meetings" });
11074
+ if (host === null) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(InertNotice, { what: "Your meetings" });
9420
11075
  if (list.failure !== null) {
9421
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__empty", error: list.failure, operation: "List your meetings", origin: "meet/components", children: [
9422
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-title", children: "Your meetings could not be listed" }),
9423
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-body", children: list.failure.message }),
9424
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-body", children: list.failure.remedy })
11076
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__empty", error: list.failure, operation: "List your meetings", origin: "meet/components", children: [
11077
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-title", children: "Your meetings could not be listed" }),
11078
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-body", children: list.failure.message }),
11079
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-body", children: list.failure.remedy })
9425
11080
  ] });
9426
11081
  }
9427
11082
  if (list.loading) {
9428
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__empty", role: "status", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-title", children: "Loading your meetings\u2026" }) });
11083
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__empty", role: "status", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-title", children: "Loading your meetings\u2026" }) });
9429
11084
  }
9430
11085
  if (list.meetings.length === 0) {
9431
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__empty", role: "status", children: [
9432
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-title", children: "No meetings yet" }),
9433
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-body", children: "Create one above. Its link works before, during and after the meeting \u2014 afterwards it opens the record." })
11086
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__empty", role: "status", children: [
11087
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-title", children: "No meetings yet" }),
11088
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-body", children: "Create one above. Its link works before, during and after the meeting \u2014 afterwards it opens the record." })
9434
11089
  ] });
9435
11090
  }
9436
11091
  const origin = baseUrl ?? (typeof window === "undefined" ? "" : window.location.origin);
9437
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet-list", children: list.meetings.map((meeting) => {
11092
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ul", { className: "mx-meet-list", children: list.meetings.map((meeting) => {
9438
11093
  const ended = meeting.endedAt !== null;
9439
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet-list__row", children: [
9440
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet-list__main", children: [
9441
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet-list__title", children: [
11094
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("li", { className: "mx-meet-list__row", children: [
11095
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet-list__main", children: [
11096
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet-list__title", children: [
9442
11097
  meeting.title,
9443
- ended ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Ended" }) : null
11098
+ ended ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__badge", children: "Ended" }) : null
9444
11099
  ] }),
9445
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet-list__when", children: meetingWhen(meeting) })
11100
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet-list__when", children: meetingWhen(meeting) })
9446
11101
  ] }),
9447
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("a", { className: "mx-meet-list__action", href: meetingLink(origin, meeting.slug), children: ended ? "Open the record" : "Join" })
11102
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("a", { className: "mx-meet-list__action", href: meetingLink(origin, meeting.slug), children: ended ? "Open the record" : "Join" })
9448
11103
  ] }, meeting.id);
9449
11104
  }) });
9450
11105
  }