@ai-matrx/meet 0.7.10 → 0.7.11

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.js CHANGED
@@ -241,7 +241,14 @@ var MEET_ROUTES = {
241
241
  */
242
242
  moderate: "/api/v1/meet/moderate",
243
243
  /** Meet wave 2: the SAVED chat — `POST` sends to everyone, `GET ?meeting_id=` reads history. */
244
- chat: "/api/v1/meet/chat"
244
+ chat: "/api/v1/meet/chat",
245
+ /**
246
+ * Meet wave 5: polls, Q&A, the shared whiteboard and breakout rooms. `POST` acts
247
+ * (`{meeting_id, action, …}`), `GET ?meeting_id=` reads what this viewer may see.
248
+ */
249
+ collab: "/api/v1/meet/collab",
250
+ /** Meet wave 5: translate finished caption lines into this viewer's language. */
251
+ captionsTranslate: "/api/v1/meet/captions/translate"
245
252
  };
246
253
  function meetingPath(template, meetingId) {
247
254
  return template.replace("{meeting_id}", encodeURIComponent(meetingId));
@@ -300,7 +307,8 @@ function parseRoomToken(body, roomName) {
300
307
  // server that has not landed MRI-A11 — and never invents a host from
301
308
  // silence, because both fallbacks below grant nothing.
302
309
  role: readRole(payload, "role") ?? (isHost ? "host" : identity.startsWith("guest:") ? "guest" : "participant"),
303
- lobby: readBoolean(payload, "lobby", false)
310
+ lobby: readBoolean(payload, "lobby", false),
311
+ breakoutRoomId: readString(payload, "breakout_room_id") ?? null
304
312
  };
305
313
  }
306
314
  function createTokenClient(options) {
@@ -348,6 +356,7 @@ function createTokenClient(options) {
348
356
  room_name: input.roomName,
349
357
  ...input.meetingId !== void 0 ? { meeting_id: input.meetingId } : {},
350
358
  ...input.slug !== void 0 ? { slug: input.slug } : {},
359
+ ...input.breakoutRoomId != null ? { breakout_room_id: input.breakoutRoomId } : {},
351
360
  organization_id: input.identity.organizationId,
352
361
  display_name: input.identity.displayName,
353
362
  device_id: input.identity.deviceId,
@@ -411,7 +420,8 @@ function createTokenClient(options) {
411
420
  return {
412
421
  get(input) {
413
422
  const entry = cache.get(input.roomName);
414
- if (entry !== void 0) {
423
+ const sameRoom = entry !== void 0 && (entry.token.breakoutRoomId ?? null) === (input.breakoutRoomId ?? null);
424
+ if (entry !== void 0 && sameRoom) {
415
425
  if (entry.inFlight !== null) return entry.inFlight;
416
426
  if (!expired(entry)) return Promise.resolve(entry.token);
417
427
  }
@@ -457,7 +467,8 @@ function placeholder(roomName) {
457
467
  canRecord: false,
458
468
  isHost: false,
459
469
  role: "participant",
460
- lobby: false
470
+ lobby: false,
471
+ breakoutRoomId: null
461
472
  };
462
473
  }
463
474
  async function serverSentence(response) {
@@ -1515,6 +1526,339 @@ function listenOnlyNotice(media) {
1515
1526
  return isListenOnly(media) ? LISTEN_ONLY_NOTICE : null;
1516
1527
  }
1517
1528
 
1529
+ // src/core/collab.ts
1530
+ var EMPTY_COLLAB = {
1531
+ loaded: false,
1532
+ error: null,
1533
+ settings: null,
1534
+ polls: [],
1535
+ questions: [],
1536
+ strokes: [],
1537
+ breakout: null,
1538
+ broadcast: null,
1539
+ moveRequest: null,
1540
+ panelRequest: null,
1541
+ captionLanguage: null,
1542
+ captionTranslations: {},
1543
+ captionTranslationError: null
1544
+ };
1545
+ function obj(value) {
1546
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
1547
+ }
1548
+ function str(value) {
1549
+ return typeof value === "string" ? value : null;
1550
+ }
1551
+ function num(value) {
1552
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
1553
+ }
1554
+ function strings(value) {
1555
+ return Array.isArray(value) ? value.filter((v) => typeof v === "string") : [];
1556
+ }
1557
+ function pollFromRow(row) {
1558
+ const id = str(row["id"]);
1559
+ if (id === null) return null;
1560
+ const options = [];
1561
+ for (const raw of Array.isArray(row["options"]) ? row["options"] : []) {
1562
+ const option = obj(raw);
1563
+ const optionId = option === null ? null : str(option["id"]);
1564
+ if (option === null || optionId === null) continue;
1565
+ const votes = num(option["votes"]);
1566
+ options.push({
1567
+ id: optionId,
1568
+ text: str(option["text"]) ?? "",
1569
+ ...votes !== null ? { votes } : {},
1570
+ ...Array.isArray(option["voters"]) ? { voters: strings(option["voters"]) } : {}
1571
+ });
1572
+ }
1573
+ const state = str(row["state"]);
1574
+ return {
1575
+ id,
1576
+ question: str(row["question"]) ?? "",
1577
+ options,
1578
+ multiple: row["multiple"] === true,
1579
+ anonymous: row["anonymous"] === true,
1580
+ state: state === "live" || state === "closed" ? state : "draft",
1581
+ resultsShared: row["results_shared"] === true,
1582
+ voterCount: num(row["voter_count"]),
1583
+ myVote: strings(row["my_vote"]),
1584
+ createdByName: str(row["created_by_name"]) ?? "",
1585
+ createdAt: str(row["created_at"])
1586
+ };
1587
+ }
1588
+ function questionFromRow(row) {
1589
+ const id = str(row["id"]);
1590
+ if (id === null) return null;
1591
+ const state = str(row["state"]);
1592
+ return {
1593
+ id,
1594
+ text: str(row["text"]) ?? "",
1595
+ askerName: str(row["asker_name"]) ?? "",
1596
+ anonymous: row["anonymous"] === true,
1597
+ state: state === "answered" || state === "dismissed" ? state : "open",
1598
+ answer: str(row["answer"]),
1599
+ answeredByName: str(row["answered_by_name"]),
1600
+ upvotes: num(row["upvotes"]) ?? 0,
1601
+ upvotedByMe: row["upvoted_by_me"] === true,
1602
+ mine: row["mine"] === true,
1603
+ createdAt: str(row["created_at"])
1604
+ };
1605
+ }
1606
+ function strokeFromRow(row) {
1607
+ const id = str(row["id"]);
1608
+ if (id === null || !Array.isArray(row["points"])) return null;
1609
+ const points = [];
1610
+ for (const raw of row["points"]) {
1611
+ if (Array.isArray(raw) && typeof raw[0] === "number" && typeof raw[1] === "number") {
1612
+ points.push([raw[0], raw[1]]);
1613
+ }
1614
+ }
1615
+ return {
1616
+ id,
1617
+ points,
1618
+ color: str(row["color"]) ?? "#111827",
1619
+ width: num(row["width"]) ?? 3,
1620
+ tool: row["tool"] === "highlighter" ? "highlighter" : "pen",
1621
+ by: str(row["by"]) ?? "",
1622
+ byName: str(row["by_name"]) ?? ""
1623
+ };
1624
+ }
1625
+ function broadcastFrom(value) {
1626
+ const row = obj(value);
1627
+ const text3 = row === null ? null : str(row["text"]);
1628
+ if (row === null || text3 === null) return null;
1629
+ return { text: text3, by: str(row["by"]) ?? "", at: str(row["at"]) ?? "" };
1630
+ }
1631
+ function planFromRow(row) {
1632
+ const id = str(row["id"]);
1633
+ if (id === null) return null;
1634
+ const rooms = [];
1635
+ for (const raw of Array.isArray(row["rooms"]) ? row["rooms"] : []) {
1636
+ const room = obj(raw);
1637
+ const roomId = room === null ? null : str(room["id"]);
1638
+ if (room === null || roomId === null) continue;
1639
+ rooms.push({ id: roomId, name: str(room["name"]) ?? roomId, identities: strings(room["identities"]) });
1640
+ }
1641
+ return {
1642
+ id,
1643
+ state: row["state"] === "open" ? "open" : "closed",
1644
+ rooms,
1645
+ allowChoose: row["allow_choose"] === true,
1646
+ minutes: num(row["minutes"]) ?? 0,
1647
+ openedAt: str(row["opened_at"]),
1648
+ endsAt: str(row["ends_at"]),
1649
+ closedAt: str(row["closed_at"]),
1650
+ broadcasts: (Array.isArray(row["broadcasts"]) ? row["broadcasts"] : []).map(broadcastFrom).filter((b) => b !== null)
1651
+ };
1652
+ }
1653
+ function settingsFromRow(row) {
1654
+ if (row === null) return null;
1655
+ return {
1656
+ pollsEnabled: row["polls_enabled"] === true,
1657
+ pollMaxOptions: num(row["poll_max_options"]) ?? 10,
1658
+ qaEnabled: row["qa_enabled"] === true,
1659
+ qaAnonymousAllowed: row["qa_anonymous_allowed"] === true,
1660
+ whiteboardEnabled: row["whiteboard_enabled"] === true,
1661
+ breakoutsEnabled: row["breakouts_enabled"] === true,
1662
+ breakoutMaxRooms: num(row["breakout_max_rooms"]) ?? 20,
1663
+ breakoutDefaultMinutes: num(row["breakout_default_minutes"]) ?? 15,
1664
+ captionTranslationEnabled: row["caption_translation_enabled"] === true,
1665
+ captionTranslationLanguage: str(row["caption_translation_language"]) ?? ""
1666
+ };
1667
+ }
1668
+ function collabFromState(body, previous) {
1669
+ const list = (key, parse) => (Array.isArray(body[key]) ? body[key] : []).map((raw) => {
1670
+ const row = obj(raw);
1671
+ return row === null ? null : parse(row);
1672
+ }).filter((item) => item !== null);
1673
+ const breakoutRow = obj(body["breakout"]);
1674
+ return {
1675
+ ...previous,
1676
+ loaded: true,
1677
+ error: null,
1678
+ settings: settingsFromRow(obj(body["settings"])),
1679
+ polls: list("polls", pollFromRow),
1680
+ questions: list("questions", questionFromRow),
1681
+ strokes: list("strokes", strokeFromRow),
1682
+ breakout: breakoutRow === null ? null : planFromRow(breakoutRow)
1683
+ };
1684
+ }
1685
+ function upsert(items, next) {
1686
+ const index = items.findIndex((item) => item.id === next.id);
1687
+ if (index === -1) return [...items, next];
1688
+ const copy = items.slice();
1689
+ copy[index] = next;
1690
+ return copy;
1691
+ }
1692
+ function withItem(collab, row, fromRoom = false) {
1693
+ const kind = str(row["kind"]);
1694
+ if (kind === "poll") {
1695
+ const poll = pollFromRow(row);
1696
+ if (poll === null) return collab;
1697
+ const known = collab.polls.find((p) => p.id === poll.id);
1698
+ const merged = fromRoom && known !== void 0 ? { ...poll, myVote: known.myVote } : poll;
1699
+ return { ...collab, polls: upsert(collab.polls, merged) };
1700
+ }
1701
+ if (kind === "question") {
1702
+ const question = questionFromRow(row);
1703
+ if (question === null) return collab;
1704
+ const known = collab.questions.find((q) => q.id === question.id);
1705
+ const merged = fromRoom && known !== void 0 ? { ...question, mine: known.mine, upvotedByMe: known.upvotedByMe } : question;
1706
+ return { ...collab, questions: upsert(collab.questions, merged) };
1707
+ }
1708
+ if (kind === "stroke") {
1709
+ const stroke = strokeFromRow(row);
1710
+ if (stroke === null) return collab;
1711
+ return { ...collab, strokes: upsert(collab.strokes, stroke) };
1712
+ }
1713
+ if (kind === "breakout") {
1714
+ const plan = planFromRow(row);
1715
+ if (plan === null) return collab;
1716
+ return { ...collab, breakout: plan };
1717
+ }
1718
+ return collab;
1719
+ }
1720
+ function without(collab, ids) {
1721
+ const gone = new Set(ids);
1722
+ return {
1723
+ ...collab,
1724
+ polls: collab.polls.filter((p) => !gone.has(p.id)),
1725
+ questions: collab.questions.filter((q) => !gone.has(q.id)),
1726
+ strokes: collab.strokes.filter((s) => !gone.has(s.id))
1727
+ };
1728
+ }
1729
+ function applyCollabPacket(collab, payload, context) {
1730
+ const item = obj(payload["item"]);
1731
+ const audience = str(payload["audience"]);
1732
+ if (item !== null) {
1733
+ const kind = str(item["kind"]);
1734
+ const hostOnlyView = kind === "poll" || kind === "question";
1735
+ if (hostOnlyView && context.isHost && audience !== "hosts") {
1736
+ return { next: null, dropped: "the room copy of an item a host receives in full" };
1737
+ }
1738
+ let next = withItem(collab, item, true);
1739
+ if (kind === "poll" && str(item["state"]) === "live") {
1740
+ const before = collab.polls.find((p) => p.id === str(item["id"]));
1741
+ if (before === void 0 || before.state !== "live") {
1742
+ next = { ...next, panelRequest: { panel: "polls", at: context.now } };
1743
+ }
1744
+ }
1745
+ if (kind === "breakout") {
1746
+ const plan = planFromRow(item);
1747
+ if (plan !== null && plan.state === "closed") {
1748
+ next = { ...next, moveRequest: { roomId: null, at: context.now } };
1749
+ }
1750
+ }
1751
+ const move = obj(payload["move"]);
1752
+ if (move !== null && str(move["identity"]) === context.localIdentity) {
1753
+ next = { ...next, moveRequest: { roomId: str(move["room_id"]), at: context.now } };
1754
+ }
1755
+ return { next };
1756
+ }
1757
+ if (Array.isArray(payload["removed"])) {
1758
+ return { next: without(collab, strings(payload["removed"])) };
1759
+ }
1760
+ if (Array.isArray(payload["hidden"])) {
1761
+ return context.isHost ? { next: null, dropped: "hosts keep dismissed questions" } : { next: without(collab, strings(payload["hidden"])) };
1762
+ }
1763
+ if (payload["cleared"] === "whiteboard") {
1764
+ return { next: { ...collab, strokes: [] } };
1765
+ }
1766
+ const broadcast = broadcastFrom(payload["broadcast"]);
1767
+ if (broadcast !== null) {
1768
+ return { next: { ...collab, broadcast } };
1769
+ }
1770
+ return { next: null, dropped: "a collab packet with nothing this version understands" };
1771
+ }
1772
+ function assignedRoom(plan, identity) {
1773
+ if (plan === null || plan.state !== "open" || identity === null) return null;
1774
+ return plan.rooms.find((room) => room.identities.includes(identity)) ?? null;
1775
+ }
1776
+ function autoAssign(identities, rooms, exclude = []) {
1777
+ const count2 = Math.max(1, Math.floor(rooms));
1778
+ const out = Array.from({ length: count2 }, () => []);
1779
+ const skip = new Set(exclude);
1780
+ let index = 0;
1781
+ for (const identity of identities) {
1782
+ if (skip.has(identity)) continue;
1783
+ out[index % count2].push(identity);
1784
+ index += 1;
1785
+ }
1786
+ return out;
1787
+ }
1788
+ function breakoutRemainingMs(plan, now) {
1789
+ if (plan === null || plan.state !== "open" || plan.endsAt === null) return null;
1790
+ const end = Date.parse(plan.endsAt);
1791
+ return Number.isNaN(end) ? null : Math.max(0, end - now);
1792
+ }
1793
+ function defaultCaptionLanguage(settings, viewerLanguage) {
1794
+ const configured = settings?.captionTranslationLanguage.trim() ?? "";
1795
+ if (configured.length > 0) return configured;
1796
+ const own = (viewerLanguage ?? "").trim();
1797
+ return own.length > 0 ? own : "en";
1798
+ }
1799
+ var CAPTION_LANGUAGES = [
1800
+ { tag: "en", name: "English" },
1801
+ { tag: "es", name: "Spanish" },
1802
+ { tag: "fr", name: "French" },
1803
+ { tag: "de", name: "German" },
1804
+ { tag: "it", name: "Italian" },
1805
+ { tag: "pt", name: "Portuguese" },
1806
+ { tag: "nl", name: "Dutch" },
1807
+ { tag: "pl", name: "Polish" },
1808
+ { tag: "ru", name: "Russian" },
1809
+ { tag: "uk", name: "Ukrainian" },
1810
+ { tag: "tr", name: "Turkish" },
1811
+ { tag: "ar", name: "Arabic" },
1812
+ { tag: "he", name: "Hebrew" },
1813
+ { tag: "fa", name: "Persian" },
1814
+ { tag: "hi", name: "Hindi" },
1815
+ { tag: "bn", name: "Bengali" },
1816
+ { tag: "zh", name: "Chinese" },
1817
+ { tag: "ja", name: "Japanese" },
1818
+ { tag: "ko", name: "Korean" },
1819
+ { tag: "vi", name: "Vietnamese" },
1820
+ { tag: "th", name: "Thai" },
1821
+ { tag: "id", name: "Indonesian" },
1822
+ { tag: "sv", name: "Swedish" }
1823
+ ];
1824
+ async function loadMeetingActivities(api, meetingId, roomToken = null) {
1825
+ let response;
1826
+ try {
1827
+ response = await api.request({
1828
+ path: `${MEET_ROUTES.collab}?meeting_id=${encodeURIComponent(meetingId)}`,
1829
+ method: "GET",
1830
+ operation: "meet.loadMeetingActivities",
1831
+ requireAuth: roomToken === null,
1832
+ ...roomToken !== null ? { headers: { [ROOM_TOKEN_HEADER]: roomToken } } : {}
1833
+ });
1834
+ } catch (error) {
1835
+ return {
1836
+ collab: null,
1837
+ refusal: {
1838
+ message: `Polls, questions and the whiteboard could not be read (${error.message}).`,
1839
+ remedy: error.remedy ?? "Reload the page."
1840
+ }
1841
+ };
1842
+ }
1843
+ if (!response.ok) {
1844
+ let body = null;
1845
+ try {
1846
+ body = await response.json();
1847
+ } catch {
1848
+ body = null;
1849
+ }
1850
+ const said = readServerRefusal(body);
1851
+ return {
1852
+ collab: null,
1853
+ refusal: {
1854
+ message: said?.reason ?? `Polls and questions could not be read (the server answered ${response.status}).`,
1855
+ remedy: said?.remedy || "Reload the page."
1856
+ }
1857
+ };
1858
+ }
1859
+ return { collab: collabFromState(await response.json(), EMPTY_COLLAB), refusal: null };
1860
+ }
1861
+
1518
1862
  // src/core/transcript.ts
1519
1863
  function normalizeSpoken(text3) {
1520
1864
  return text3.toLowerCase().replace(/[^\p{L}\p{N}]+/gu, " ").trim();
@@ -1616,7 +1960,9 @@ var EMPTY = {
1616
1960
  wrapUp: null,
1617
1961
  noteTakerRefusal: null,
1618
1962
  media: IDLE_MEDIA,
1619
- failure: null
1963
+ failure: null,
1964
+ collab: EMPTY_COLLAB,
1965
+ breakoutRoomId: null
1620
1966
  };
1621
1967
  function effectiveRole(snapshot) {
1622
1968
  const me = snapshot.participants.find(
@@ -2267,7 +2613,19 @@ var INVITEE_COLUMNS = "id,meeting_id,invitee_user_id,email,display_name,role,rsv
2267
2613
  var RECORDING_COLUMNS = "id,meeting_id,state,started_at,ended_at,started_by,file_id,failure_reason";
2268
2614
  var SEGMENT_COLUMNS = "id,meeting_id,identity,speaker,text,started_at,is_final,metadata";
2269
2615
  var NOTE_COLUMNS = "id,meeting_id,text,kind,assignee_user_id,created_at,metadata";
2270
- var ATTENDEE_COLUMNS = "id,meeting_id,identity,participant_user_id,display_name,avatar_url,role,admission_state,is_agent,joined_at,left_at";
2616
+ 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";
2617
+ function projectStays(value) {
2618
+ if (!Array.isArray(value)) return [];
2619
+ const stays = [];
2620
+ for (const item of value) {
2621
+ if (item === null || typeof item !== "object") continue;
2622
+ const joined = item["joined_at"];
2623
+ const left = item["left_at"];
2624
+ if (typeof joined !== "string" || joined.length === 0) continue;
2625
+ stays.push({ joinedAt: joined, leftAt: typeof left === "string" && left.length > 0 ? left : null });
2626
+ }
2627
+ return stays;
2628
+ }
2271
2629
  function text(row, key) {
2272
2630
  const value = row[key];
2273
2631
  return typeof value === "string" && value.length > 0 ? value : null;
@@ -2366,7 +2724,7 @@ var OCCURRENCE_STATES = ["scheduled", "moved", "cancelled"];
2366
2724
  function rsvpState(value) {
2367
2725
  return RSVP_STATES.includes(value) ? value : "needs_action";
2368
2726
  }
2369
- function num(row, key) {
2727
+ function num2(row, key) {
2370
2728
  const value = row[key];
2371
2729
  return typeof value === "number" ? value : null;
2372
2730
  }
@@ -2388,7 +2746,7 @@ function projectInvitee(row) {
2388
2746
  rsvpState: rsvpState(text(row, "rsvp_state")),
2389
2747
  respondedAt: when(row, "responded_at"),
2390
2748
  rsvpNote: text(row, "rsvp_note"),
2391
- lastSentSequence: num(row, "last_sent_sequence"),
2749
+ lastSentSequence: num2(row, "last_sent_sequence"),
2392
2750
  lastSentAt: when(row, "last_sent_at")
2393
2751
  };
2394
2752
  }
@@ -2399,10 +2757,10 @@ function projectOccurrence(row) {
2399
2757
  meetingId: asMeetingId(requireText(row, "meeting_id", operation)),
2400
2758
  originalStart: when(row, "original_start") ?? requireText(row, "original_start", operation),
2401
2759
  occurrenceStart: when(row, "occurrence_start") ?? requireText(row, "occurrence_start", operation),
2402
- durationMinutes: num(row, "duration_minutes"),
2760
+ durationMinutes: num2(row, "duration_minutes"),
2403
2761
  // An unknown state is shown as scheduled, never dropped: the row is real.
2404
2762
  state: OCCURRENCE_STATES.includes(state) ? state : "scheduled",
2405
- sequence: num(row, "sequence") ?? 0
2763
+ sequence: num2(row, "sequence") ?? 0
2406
2764
  };
2407
2765
  }
2408
2766
  function projectUpcoming(row) {
@@ -2431,9 +2789,9 @@ function projectOverride(row) {
2431
2789
  originalStart: when(row, "original_start") ?? requireText(row, "original_start", operation),
2432
2790
  state: text(row, "state") === "moved" ? "moved" : "cancelled",
2433
2791
  newStart: when(row, "new_start"),
2434
- newDurationMinutes: num(row, "new_duration_minutes"),
2792
+ newDurationMinutes: num2(row, "new_duration_minutes"),
2435
2793
  reason: text(row, "reason"),
2436
- calendarSequence: num(row, "calendar_sequence") ?? 0,
2794
+ calendarSequence: num2(row, "calendar_sequence") ?? 0,
2437
2795
  deletedAt: when(row, "deleted_at")
2438
2796
  };
2439
2797
  }
@@ -2457,7 +2815,7 @@ function projectRsvpInvitation(body) {
2457
2815
  title: text(meeting, "title") ?? "Meeting",
2458
2816
  slug: requireText(meeting, "slug", operation),
2459
2817
  scheduledFor: when(meeting, "scheduled_for"),
2460
- durationMinutes: num(meeting, "duration_minutes"),
2818
+ durationMinutes: num2(meeting, "duration_minutes"),
2461
2819
  timeZone: text(meeting, "time_zone") ?? "UTC",
2462
2820
  agenda: text(meeting, "agenda"),
2463
2821
  recurrenceRule: text(meeting, "recurrence_rule"),
@@ -2491,6 +2849,7 @@ function changesPatch(changes) {
2491
2849
  patch["scheduled_duration_minutes"] = changes.scheduledDurationMinutes;
2492
2850
  }
2493
2851
  if (changes.recurrenceRule !== void 0) patch["recurrence_rule"] = changes.recurrenceRule;
2852
+ if (changes.keepExceptions !== void 0) patch["keep_exceptions"] = changes.keepExceptions;
2494
2853
  return patch;
2495
2854
  }
2496
2855
  function createMeetRepository(options) {
@@ -2637,7 +2996,8 @@ function createMeetRepository(options) {
2637
2996
  admissionState: states.includes(admission) ? admission : "admitted",
2638
2997
  isAgent: bool(row, "is_agent", false),
2639
2998
  joinedAt: text(row, "joined_at"),
2640
- leftAt: text(row, "left_at")
2999
+ leftAt: text(row, "left_at"),
3000
+ sessions: projectStays(row["sessions"])
2641
3001
  };
2642
3002
  }
2643
3003
  function requireOrg(organizationId, operation) {
@@ -3031,8 +3391,8 @@ function projectLibraryRecording(row) {
3031
3391
  fileId: text(row, "file_id"),
3032
3392
  startedAt: text(row, "started_at"),
3033
3393
  endedAt: text(row, "ended_at"),
3034
- durationMs: num(row, "duration_ms"),
3035
- sizeBytes: num(row, "size_bytes"),
3394
+ durationMs: num2(row, "duration_ms"),
3395
+ sizeBytes: num2(row, "size_bytes"),
3036
3396
  failureReason: text(row, "failure_reason"),
3037
3397
  archivedAt: text(row, "deleted_at"),
3038
3398
  organizationId: asOrganizationId(requireText(row, "organization_id", operation))
@@ -3059,7 +3419,7 @@ function projectSearchHit(row) {
3059
3419
  speaker: text(row, "speaker"),
3060
3420
  snippet: text(row, "snippet") ?? "",
3061
3421
  at: text(row, "said_at"),
3062
- rank: num(row, "rank") ?? 0
3422
+ rank: num2(row, "rank") ?? 0
3063
3423
  };
3064
3424
  }
3065
3425
  function snippetRuns(snippet) {
@@ -3204,7 +3564,14 @@ var ROOM_EVENTS = {
3204
3564
  * person concerned; `lower-hands {identities: [...] | "*"}` · `role {identity,
3205
3565
  * role}` — to everyone.
3206
3566
  */
3207
- moderation: "matrx.meet.moderation"
3567
+ moderation: "matrx.meet.moderation",
3568
+ /**
3569
+ * A meeting ROOM ITEM changed (Meet wave 5): a poll, a Q&A question, a whiteboard
3570
+ * stroke or the breakout plan. Payload `{ meeting_id, item }` · `{ removed: [ids] }` ·
3571
+ * `{ hidden: [ids] }` · `{ cleared: "whiteboard" }` · `{ broadcast }` · `{ item, move }`.
3572
+ * A host's fuller copy of a poll or question carries `audience: "hosts"`.
3573
+ */
3574
+ collab: "matrx.meet.collab"
3208
3575
  };
3209
3576
  function isRoomEventTopic(topic) {
3210
3577
  return topic.startsWith(ROOM_EVENT_PREFIX);
@@ -3244,10 +3611,27 @@ function applyRoomEvent(args) {
3244
3611
  return applyChat(store, payload);
3245
3612
  case ROOM_EVENTS.moderation:
3246
3613
  return applyModeration(store, payload, now);
3614
+ case ROOM_EVENTS.collab:
3615
+ return applyCollab(store, payload, now);
3247
3616
  default:
3248
3617
  return ignored(`${topic} is not known to this version of @ai-matrx/meet`);
3249
3618
  }
3250
3619
  }
3620
+ function applyCollab(store, payload, now) {
3621
+ const snapshot = store.snapshot();
3622
+ const meeting = snapshot.meeting;
3623
+ if (meeting !== null && text2(payload["meeting_id"]) !== null && payload["meeting_id"] !== meeting.id) {
3624
+ return ignored("a collab event for a different meeting than this room is showing");
3625
+ }
3626
+ const result = applyCollabPacket(snapshot.collab, payload, {
3627
+ localIdentity: snapshot.localIdentity,
3628
+ isHost: ROLE_RANK[effectiveRole(snapshot)] >= ROLE_RANK.cohost,
3629
+ now: now()
3630
+ });
3631
+ if (result.next === null) return ignored(result.dropped ?? "a collab packet that changed nothing");
3632
+ store.patch({ collab: result.next });
3633
+ return HANDLED;
3634
+ }
3251
3635
  function applyNote(store, payload) {
3252
3636
  const row = object(payload["note"]);
3253
3637
  if (row === null) return ignored("a note event with no `note` row");
@@ -3569,6 +3953,7 @@ function createRoomEngine(options) {
3569
3953
  let joining = null;
3570
3954
  let lastRequest = null;
3571
3955
  let disposed = false;
3956
+ let moving = false;
3572
3957
  const confirmingEnds = /* @__PURE__ */ new WeakSet();
3573
3958
  async function leaveRoom() {
3574
3959
  const target = driver;
@@ -3798,6 +4183,7 @@ function createRoomEngine(options) {
3798
4183
  }
3799
4184
  },
3800
4185
  disconnected(reason) {
4186
+ if (moving) return;
3801
4187
  if (current !== null) {
3802
4188
  tokens.invalidate(current.roomName);
3803
4189
  current = null;
@@ -3812,11 +4198,13 @@ function createRoomEngine(options) {
3812
4198
  roomName: request.roomName,
3813
4199
  identity,
3814
4200
  ...request.meetingId !== void 0 ? { meetingId: request.meetingId } : {},
3815
- ...request.slug !== void 0 ? { slug: request.slug } : {}
4201
+ ...request.slug !== void 0 ? { slug: request.slug } : {},
4202
+ ...request.breakoutRoomId != null ? { breakoutRoomId: request.breakoutRoomId } : {}
3816
4203
  });
3817
4204
  current = token;
3818
4205
  store.patch({
3819
4206
  localIdentity: token.identity,
4207
+ breakoutRoomId: token.breakoutRoomId ?? null,
3820
4208
  grants: {
3821
4209
  role: token.role,
3822
4210
  canRecord: token.canRecord,
@@ -3935,6 +4323,56 @@ function createRoomEngine(options) {
3935
4323
  });
3936
4324
  return joining;
3937
4325
  },
4326
+ async moveToBreakout(roomId) {
4327
+ const request = lastRequest;
4328
+ if (request === null || driver === null) {
4329
+ report(
4330
+ "warn",
4331
+ "meet.moveToBreakout: this engine is not in a meeting room",
4332
+ "Join the meeting first; a breakout is a room OF a meeting."
4333
+ );
4334
+ return;
4335
+ }
4336
+ if ((store.snapshot().breakoutRoomId ?? null) === roomId) return;
4337
+ if (joining !== null) await joining.catch(() => void 0);
4338
+ const previous = driver;
4339
+ const next = {
4340
+ ...request,
4341
+ breakoutRoomId: roomId,
4342
+ // Arrive as you were: camera and microphone as they are now.
4343
+ mode: store.snapshot().media.camera.enabled ? "video" : "audio",
4344
+ microphone: store.snapshot().media.microphone.enabled
4345
+ };
4346
+ moving = true;
4347
+ try {
4348
+ driver = null;
4349
+ tokens.invalidate(request.roomName);
4350
+ current = null;
4351
+ await previous.disconnect();
4352
+ lastRequest = next;
4353
+ joining = connect(next).finally(() => {
4354
+ joining = null;
4355
+ });
4356
+ await joining;
4357
+ } catch (error) {
4358
+ const normalized = normalizeMeetError(error, "meet.moveToBreakout");
4359
+ report("warn", normalized.message, normalized.remedy);
4360
+ if (roomId !== null) {
4361
+ lastRequest = { ...next, breakoutRoomId: null };
4362
+ joining = connect(lastRequest).finally(() => {
4363
+ joining = null;
4364
+ });
4365
+ await joining.catch((again) => {
4366
+ throw fail(again, "meet.moveToBreakout");
4367
+ });
4368
+ } else {
4369
+ throw fail(error, "meet.moveToBreakout");
4370
+ }
4371
+ throw normalized;
4372
+ } finally {
4373
+ moving = false;
4374
+ }
4375
+ },
3938
4376
  leave: leaveRoom,
3939
4377
  // Turning a device on mid-meeting is the SAME operation as turning it on
3940
4378
  // during the join, so it runs the same function. A failure here used to
@@ -4204,6 +4642,109 @@ function createInRoomClient(options) {
4204
4642
  (row) => typeof row === "object" && row !== null ? chatFromRow(row) : null
4205
4643
  ).filter((message) => message !== null);
4206
4644
  store.loadChat(messages);
4645
+ },
4646
+ async loadCollab() {
4647
+ const operation = "meet.loadCollab";
4648
+ const id = meetingId(operation);
4649
+ const hdrs = headers();
4650
+ const response = await api.request({
4651
+ path: `${MEET_ROUTES.collab}?meeting_id=${encodeURIComponent(id)}`,
4652
+ method: "GET",
4653
+ operation,
4654
+ ...hdrs !== void 0 ? { headers: hdrs } : {}
4655
+ });
4656
+ if (!response.ok) {
4657
+ const error = await refusal2(
4658
+ response,
4659
+ operation,
4660
+ "Polls, questions and the whiteboard could not be read. New ones still arrive."
4661
+ );
4662
+ store.patch({ collab: { ...store.snapshot().collab, loaded: true, error: error.message } });
4663
+ throw error;
4664
+ }
4665
+ const body = await response.json();
4666
+ store.patch({ collab: collabFromState(body, store.snapshot().collab) });
4667
+ },
4668
+ async collab(request) {
4669
+ const operation = `meet.collab(${request.action})`;
4670
+ const hdrs = headers();
4671
+ const response = await api.request({
4672
+ path: MEET_ROUTES.collab,
4673
+ method: "POST",
4674
+ operation,
4675
+ body: {
4676
+ meeting_id: meetingId(operation),
4677
+ action: request.action,
4678
+ ...request.itemId !== void 0 ? { item_id: request.itemId } : {},
4679
+ ...request.question !== void 0 ? { question: request.question } : {},
4680
+ ...request.options !== void 0 ? { options: request.options } : {},
4681
+ ...request.multiple !== void 0 ? { multiple: request.multiple } : {},
4682
+ ...request.anonymous !== void 0 ? { anonymous: request.anonymous } : {},
4683
+ ...request.optionIds !== void 0 ? { option_ids: request.optionIds } : {},
4684
+ ...request.text !== void 0 ? { text: request.text } : {},
4685
+ ...request.stroke !== void 0 ? { stroke: request.stroke } : {},
4686
+ ...request.rooms !== void 0 ? { rooms: request.rooms } : {},
4687
+ ...request.allowChoose !== void 0 ? { allow_choose: request.allowChoose } : {},
4688
+ ...request.minutes !== void 0 ? { minutes: request.minutes } : {},
4689
+ ...request.identity !== void 0 ? { identity: request.identity } : {},
4690
+ ...request.roomId !== void 0 ? { room_id: request.roomId } : {}
4691
+ },
4692
+ ...hdrs !== void 0 ? { headers: hdrs } : {}
4693
+ });
4694
+ if (!response.ok) {
4695
+ throw await refusal2(response, operation, "Nothing was changed.");
4696
+ }
4697
+ const payload = await response.json();
4698
+ const removed = Array.isArray(payload["removed"]) ? payload["removed"].filter((v) => typeof v === "string") : [];
4699
+ let next = store.snapshot().collab;
4700
+ const item = payload["item"];
4701
+ if (typeof item === "object" && item !== null) next = withItem(next, item);
4702
+ if (removed.length > 0) {
4703
+ const gone = new Set(removed);
4704
+ next = {
4705
+ ...next,
4706
+ polls: next.polls.filter((p) => !gone.has(p.id)),
4707
+ questions: next.questions.filter((q) => !gone.has(q.id)),
4708
+ strokes: next.strokes.filter((st) => !gone.has(st.id))
4709
+ };
4710
+ }
4711
+ store.patch({ collab: next });
4712
+ const itemId = typeof item === "object" && item !== null && typeof item["id"] === "string" ? item["id"] : null;
4713
+ return {
4714
+ action: request.action,
4715
+ message: typeof payload["message"] === "string" ? payload["message"] : "Done.",
4716
+ removed,
4717
+ itemId
4718
+ };
4719
+ },
4720
+ async translateCaptions(language, lines) {
4721
+ if (lines.length === 0) return;
4722
+ const operation = "meet.translateCaptions";
4723
+ const hdrs = headers();
4724
+ const response = await api.request({
4725
+ path: MEET_ROUTES.captionsTranslate,
4726
+ method: "POST",
4727
+ operation,
4728
+ body: { meeting_id: meetingId(operation), target_language: language, lines },
4729
+ ...hdrs !== void 0 ? { headers: hdrs } : {}
4730
+ });
4731
+ if (!response.ok) {
4732
+ const error = await refusal2(response, operation, "Captions stay in the language they were spoken.");
4733
+ store.patch({
4734
+ collab: { ...store.snapshot().collab, captionTranslationError: error.message }
4735
+ });
4736
+ throw error;
4737
+ }
4738
+ const payload = await response.json();
4739
+ const current = store.snapshot().collab;
4740
+ if (current.captionLanguage !== language) return;
4741
+ const merged = { ...current.captionTranslations };
4742
+ for (const [id, value] of Object.entries(payload.translations ?? {})) {
4743
+ if (typeof value === "string") merged[id] = value;
4744
+ }
4745
+ store.patch({
4746
+ collab: { ...current, captionTranslations: merged, captionTranslationError: null }
4747
+ });
4207
4748
  }
4208
4749
  };
4209
4750
  }
@@ -4771,6 +5312,14 @@ function MeetRuntime(props) {
4771
5312
  }
4772
5313
  if (chatReadFor === snapshot.meeting.id) return;
4773
5314
  chatReadFor = snapshot.meeting.id;
5315
+ void inRoom.loadCollab().catch((error) => {
5316
+ const normalized = error;
5317
+ report({
5318
+ level: "warn",
5319
+ message: normalized.message ?? "meet: polls, questions and the whiteboard could not be read",
5320
+ ...normalized.remedy !== void 0 ? { remedy: normalized.remedy } : {}
5321
+ });
5322
+ });
4774
5323
  void inRoom.loadChat().catch((error) => {
4775
5324
  const normalized = error;
4776
5325
  store.patch({
@@ -6111,7 +6660,7 @@ function useGuestRecordAccess(meeting) {
6111
6660
  }
6112
6661
 
6113
6662
  // src/react/components.tsx
6114
- import { useEffect as useEffect3, useLayoutEffect, useMemo as useMemo3, useRef as useRef3, useState as useState3 } from "react";
6663
+ import { useEffect as useEffect4, useLayoutEffect, useMemo as useMemo3, useRef as useRef4, useState as useState4 } from "react";
6115
6664
  import { ErrorBox } from "@ai-matrx/design-system";
6116
6665
  import { avatarPaletteIndex, formatDurationMs as formatDurationMs3, getInitials } from "@ai-matrx/kit/format";
6117
6666
 
@@ -6178,12 +6727,19 @@ function coveredMs(intervals) {
6178
6727
  }
6179
6728
  function attendanceReport(meeting, attendees, names = {}) {
6180
6729
  const end = ms(meeting.endedAt);
6730
+ const measuredOf = /* @__PURE__ */ new Map();
6181
6731
  const perJoin = attendees.map((person) => {
6182
- const joined = ms(person.joinedAt);
6183
- const left = ms(person.leftAt);
6184
- const until = left ?? end;
6185
- const duration = joined !== null && until !== null && until >= joined ? until - joined : null;
6186
- return {
6732
+ 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)]];
6733
+ let toEnd = false;
6734
+ const measured = [];
6735
+ for (const [joined, left] of stays) {
6736
+ const until = left ?? end;
6737
+ if (joined === null || until === null || until < joined) continue;
6738
+ if (left === null) toEnd = true;
6739
+ measured.push([joined, until]);
6740
+ }
6741
+ const duration = measured.length === 0 ? null : coveredMs(measured);
6742
+ const row = {
6187
6743
  id: person.id,
6188
6744
  identity: person.identity,
6189
6745
  name: displayNameFor(names, person.identity, person.displayName),
@@ -6192,10 +6748,12 @@ function attendanceReport(meeting, attendees, names = {}) {
6192
6748
  joinedAt: person.joinedAt,
6193
6749
  leftAt: person.leftAt,
6194
6750
  durationMs: duration,
6195
- durationToEnd: duration !== null && left === null,
6751
+ durationToEnd: duration !== null && toEnd,
6196
6752
  admission: person.admissionState,
6197
- joins: 1
6753
+ joins: Math.max(1, person.sessions?.length ?? 0)
6198
6754
  };
6755
+ measuredOf.set(row, measured);
6756
+ return row;
6199
6757
  });
6200
6758
  const groups = /* @__PURE__ */ new Map();
6201
6759
  attendees.forEach((person, index) => {
@@ -6218,17 +6776,14 @@ function attendanceReport(meeting, attendees, names = {}) {
6218
6776
  const left = ms(row.leftAt);
6219
6777
  return left !== null && (latest === null || left > latest) ? left : latest;
6220
6778
  }, null);
6221
- const intervals = came.flatMap((row) => {
6222
- const joined = ms(row.joinedAt);
6223
- return joined !== null && row.durationMs !== null ? [[joined, joined + row.durationMs]] : [];
6224
- });
6779
+ const intervals = came.flatMap((row) => measuredOf.get(row) ?? []);
6225
6780
  return {
6226
6781
  ...first,
6227
6782
  kind,
6228
6783
  leftAt: open ? null : lastLeave === null ? null : new Date(lastLeave).toISOString(),
6229
6784
  durationMs: intervals.length === 0 ? null : coveredMs(intervals),
6230
6785
  durationToEnd: came.some((row) => row.durationToEnd),
6231
- joins: came.length === 0 ? joins.length : came.length
6786
+ joins: came.length === 0 ? joins.length : came.reduce((total, row) => total + row.joins, 0)
6232
6787
  };
6233
6788
  });
6234
6789
  const rank = KIND_RANK;
@@ -6372,8 +6927,8 @@ function transcriptDocument(bundle, format, options = {}) {
6372
6927
  if (line.identity !== last) {
6373
6928
  if (last !== null) out.push("");
6374
6929
  const who = speaker(line);
6375
- const clock = clockOfDay(line.startedAt, options);
6376
- out.push(format === "md" ? `**${who}** \xB7 ${clock}` : `${who} (${clock})`);
6930
+ const clock2 = clockOfDay(line.startedAt, options);
6931
+ out.push(format === "md" ? `**${who}** \xB7 ${clock2}` : `${who} (${clock2})`);
6377
6932
  last = line.identity;
6378
6933
  }
6379
6934
  out.push(line.text.trim());
@@ -6554,6 +7109,9 @@ function countLabel(count2, singular, plural = `${singular}s`) {
6554
7109
  return `${count2} ${count2 === 1 ? singular : plural}`;
6555
7110
  }
6556
7111
 
7112
+ // src/react/collab.tsx
7113
+ import { useEffect as useEffect3, useRef as useRef3, useState as useState3 } from "react";
7114
+
6557
7115
  // src/react/icons.tsx
6558
7116
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
6559
7117
  function Icon({ children, ...props }) {
@@ -6738,109 +7296,1138 @@ function FlagIcon(props) {
6738
7296
  function PencilIcon(props) {
6739
7297
  return /* @__PURE__ */ jsx2(Icon, { ...props, children: /* @__PURE__ */ jsx2("path", { d: "M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z" }) });
6740
7298
  }
6741
-
6742
- // src/react/components.tsx
6743
- import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
6744
- function InertNotice({ what }) {
6745
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__empty", role: "status", children: [
6746
- /* @__PURE__ */ jsxs2("p", { className: "mx-meet__empty-title", children: [
6747
- what,
6748
- " is not ready yet"
6749
- ] }),
6750
- /* @__PURE__ */ jsx3("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." })
7299
+ function ActivitiesIcon(props) {
7300
+ return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
7301
+ /* @__PURE__ */ jsx2("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" }),
7302
+ /* @__PURE__ */ jsx2("rect", { x: "3", y: "14", width: "7", height: "7", rx: "1" }),
7303
+ /* @__PURE__ */ jsx2("circle", { cx: "17.5", cy: "17.5", r: "3.5" })
6751
7304
  ] });
6752
7305
  }
6753
- function Avatar({
6754
- name,
6755
- url,
6756
- size = 40
6757
- }) {
6758
- const tint = avatarPaletteIndex(name);
6759
- if (url != null && url.length > 0) {
6760
- return /* @__PURE__ */ jsx3(
6761
- "img",
6762
- {
6763
- className: "mx-meet__avatar",
6764
- src: url,
6765
- alt: "",
6766
- width: size,
6767
- height: size,
6768
- style: { width: size, height: size }
6769
- }
6770
- );
6771
- }
6772
- return /* @__PURE__ */ jsx3(
6773
- "span",
6774
- {
6775
- className: "mx-meet__avatar mx-meet__avatar--initials",
6776
- style: {
6777
- width: size,
6778
- height: size,
6779
- fontSize: Math.round(size * 0.38),
6780
- background: `var(--mx-meet-avatar-${tint})`
6781
- },
6782
- "aria-hidden": "true",
6783
- children: getInitials(name)
6784
- }
6785
- );
7306
+ function PollIcon(props) {
7307
+ return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
7308
+ /* @__PURE__ */ jsx2("line", { x1: "18", x2: "18", y1: "20", y2: "10" }),
7309
+ /* @__PURE__ */ jsx2("line", { x1: "12", x2: "12", y1: "20", y2: "4" }),
7310
+ /* @__PURE__ */ jsx2("line", { x1: "6", x2: "6", y1: "20", y2: "14" })
7311
+ ] });
6786
7312
  }
6787
- function ControlButton({
6788
- label,
6789
- active = false,
6790
- danger = false,
6791
- onClick,
6792
- children
6793
- }) {
6794
- return /* @__PURE__ */ jsx3(
6795
- "button",
6796
- {
6797
- type: "button",
6798
- className: [
6799
- "mx-meet__control",
6800
- active ? "mx-meet__control--active" : "",
6801
- danger ? "mx-meet__control--danger" : ""
6802
- ].filter(Boolean).join(" "),
6803
- "aria-label": label,
6804
- title: label,
6805
- onClick,
6806
- children
6807
- }
6808
- );
7313
+ function QuestionIcon(props) {
7314
+ return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
7315
+ /* @__PURE__ */ jsx2("path", { d: "M7.9 20A9 9 0 1 0 4 16.1L2 22Z" }),
7316
+ /* @__PURE__ */ jsx2("path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }),
7317
+ /* @__PURE__ */ jsx2("path", { d: "M12 17h.01" })
7318
+ ] });
6809
7319
  }
6810
- function RecordingIndicator() {
6811
- const { state, label } = useRecording();
6812
- if (label === null) return null;
6813
- return /* @__PURE__ */ jsxs2(
6814
- "span",
6815
- {
6816
- className: `mx-meet__recording mx-meet__recording--${state}`,
6817
- role: "status",
6818
- "aria-live": "polite",
6819
- children: [
6820
- /* @__PURE__ */ jsx3(RecordIcon, { width: 10, height: 10 }),
6821
- label
6822
- ]
6823
- }
6824
- );
7320
+ function WhiteboardIcon(props) {
7321
+ return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
7322
+ /* @__PURE__ */ jsx2("path", { d: "M2 3h20" }),
7323
+ /* @__PURE__ */ jsx2("path", { d: "M21 3v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V3" }),
7324
+ /* @__PURE__ */ jsx2("path", { d: "m7 21 5-5 5 5" })
7325
+ ] });
6825
7326
  }
6826
- function ConnectionDot({ quality }) {
6827
- if (quality === "excellent" || quality === "good" || quality === "unknown") return null;
6828
- return /* @__PURE__ */ jsx3("span", { className: `mx-meet__quality mx-meet__quality--${quality}`, title: `Connection ${quality}`, children: /* @__PURE__ */ jsx3(WifiLowIcon, { width: 14, height: 14 }) });
7327
+ function BreakoutIcon(props) {
7328
+ return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
7329
+ /* @__PURE__ */ jsx2("rect", { width: "7", height: "18", x: "3", y: "3", rx: "1" }),
7330
+ /* @__PURE__ */ jsx2("rect", { width: "7", height: "7", x: "14", y: "3", rx: "1" }),
7331
+ /* @__PURE__ */ jsx2("rect", { width: "7", height: "7", x: "14", y: "14", rx: "1" })
7332
+ ] });
6829
7333
  }
6830
- function RoleBadge({ role }) {
6831
- if (role === "host") return /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Host" });
6832
- if (role === "cohost") return /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Co-host" });
6833
- if (role === "guest") return /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Guest" });
6834
- return null;
7334
+ function UpvoteIcon(props) {
7335
+ return /* @__PURE__ */ jsx2(Icon, { ...props, children: /* @__PURE__ */ jsx2("path", { d: "M9 18v-6H5l7-7 7 7h-4v6H9z" }) });
6835
7336
  }
6836
- function ParticipantTile({
7337
+ function EraserIcon(props) {
7338
+ return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
7339
+ /* @__PURE__ */ jsx2("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" }),
7340
+ /* @__PURE__ */ jsx2("path", { d: "M22 21H7" }),
7341
+ /* @__PURE__ */ jsx2("path", { d: "m5 11 9 9" })
7342
+ ] });
7343
+ }
7344
+ function HighlighterIcon(props) {
7345
+ return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
7346
+ /* @__PURE__ */ jsx2("path", { d: "m9 11-6 6v3h9l3-3" }),
7347
+ /* @__PURE__ */ jsx2("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" })
7348
+ ] });
7349
+ }
7350
+ function UndoIcon(props) {
7351
+ return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
7352
+ /* @__PURE__ */ jsx2("path", { d: "M9 14 4 9l5-5" }),
7353
+ /* @__PURE__ */ jsx2("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" })
7354
+ ] });
7355
+ }
7356
+
7357
+ // src/react/collab.tsx
7358
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
7359
+ function useCollab() {
7360
+ const host = useMeetHost();
7361
+ const snapshot = useMeetSnapshot();
7362
+ const isHost = useIsHost();
7363
+ return {
7364
+ collab: snapshot?.collab ?? null,
7365
+ isHost,
7366
+ localIdentity: snapshot?.localIdentity ?? null,
7367
+ breakoutRoomId: snapshot?.breakoutRoomId ?? null,
7368
+ async act(request) {
7369
+ if (host === null) return { ok: false, message: "This meeting is not connected." };
7370
+ try {
7371
+ const result = await host.inRoom.collab(request);
7372
+ return { ok: true, message: result.message, itemId: result.itemId };
7373
+ } catch (error) {
7374
+ return { ok: false, message: error.message ?? "That did not work." };
7375
+ }
7376
+ },
7377
+ async moveTo(roomId) {
7378
+ if (host === null) return { ok: false, message: "This meeting is not connected." };
7379
+ try {
7380
+ await host.engine.moveToBreakout(roomId);
7381
+ return { ok: true, message: roomId === null ? "Back in the main room." : "Joined the breakout room." };
7382
+ } catch (error) {
7383
+ return { ok: false, message: error.message ?? "That room could not be joined." };
7384
+ }
7385
+ }
7386
+ };
7387
+ }
7388
+ function useNotice() {
7389
+ const [notice, setNotice] = useState3(null);
7390
+ useEffect3(() => {
7391
+ if (notice === null) return void 0;
7392
+ const timer = setTimeout(() => setNotice(null), notice.failed ? 7e3 : 3e3);
7393
+ return () => clearTimeout(timer);
7394
+ }, [notice]);
7395
+ return [notice, (result) => setNotice({ text: result.message, failed: !result.ok })];
7396
+ }
7397
+ function Notice({ notice }) {
7398
+ if (notice === null) return null;
7399
+ return /* @__PURE__ */ jsx3("p", { className: notice.failed ? "mx-meet__panel-note mx-meet__collab-error" : "mx-meet__panel-note", role: "status", children: notice.text });
7400
+ }
7401
+ var ACTIVITY_LABELS = {
7402
+ polls: "Polls",
7403
+ qa: "Q&A",
7404
+ whiteboard: "Whiteboard",
7405
+ breakouts: "Breakout rooms"
7406
+ };
7407
+ function ActivityIcon({ panel }) {
7408
+ const props = { width: 16, height: 16 };
7409
+ if (panel === "polls") return /* @__PURE__ */ jsx3(PollIcon, { ...props });
7410
+ if (panel === "qa") return /* @__PURE__ */ jsx3(QuestionIcon, { ...props });
7411
+ if (panel === "whiteboard") return /* @__PURE__ */ jsx3(WhiteboardIcon, { ...props });
7412
+ return /* @__PURE__ */ jsx3(BreakoutIcon, { ...props });
7413
+ }
7414
+ function useAvailableActivities() {
7415
+ const { collab, isHost } = useCollab();
7416
+ const settings = collab?.settings ?? null;
7417
+ if (settings === null) return [];
7418
+ const out = [];
7419
+ if (settings.whiteboardEnabled) out.push("whiteboard");
7420
+ if (settings.pollsEnabled && (isHost || (collab?.polls.length ?? 0) > 0)) out.push("polls");
7421
+ if (settings.qaEnabled) out.push("qa");
7422
+ if (settings.breakoutsEnabled && (isHost || collab?.breakout?.state === "open")) out.push("breakouts");
7423
+ return out;
7424
+ }
7425
+ function useActivityAttention() {
7426
+ const { collab, isHost } = useCollab();
7427
+ if (collab === null) return false;
7428
+ if (collab.polls.some((poll) => poll.state === "live" && poll.myVote.length === 0 && !isHost)) return true;
7429
+ if (isHost && collab.questions.some((q) => q.state === "open")) return true;
7430
+ return false;
7431
+ }
7432
+ function ActivitiesControl({
7433
+ active,
7434
+ onOpen
7435
+ }) {
7436
+ const [open, setOpen] = useState3(false);
7437
+ const available = useAvailableActivities();
7438
+ const attention = useActivityAttention();
7439
+ if (available.length === 0) return null;
7440
+ return /* @__PURE__ */ jsxs2("span", { className: "mx-meet__anchor", children: [
7441
+ /* @__PURE__ */ jsxs2(ControlButton, { label: "Activities", active: open || active !== null, onClick: () => setOpen(!open), children: [
7442
+ /* @__PURE__ */ jsx3(ActivitiesIcon, {}),
7443
+ attention ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
7444
+ ] }),
7445
+ open ? /* @__PURE__ */ jsx3(Popover, { label: "Activities", onClose: () => setOpen(false), children: /* @__PURE__ */ jsx3("div", { className: "mx-meet__menu", role: "menu", children: available.map((panel) => /* @__PURE__ */ jsxs2(
7446
+ MenuItem,
7447
+ {
7448
+ onSelect: () => {
7449
+ setOpen(false);
7450
+ onOpen(panel);
7451
+ },
7452
+ children: [
7453
+ /* @__PURE__ */ jsx3(ActivityIcon, { panel }),
7454
+ " ",
7455
+ ACTIVITY_LABELS[panel]
7456
+ ]
7457
+ },
7458
+ panel
7459
+ )) }) }) : null
7460
+ ] });
7461
+ }
7462
+ function PollComposer({ maxOptions, onDone }) {
7463
+ const { act } = useCollab();
7464
+ const [question, setQuestion] = useState3("");
7465
+ const [options, setOptions] = useState3(["", ""]);
7466
+ const [multiple, setMultiple] = useState3(false);
7467
+ const [anonymous, setAnonymous] = useState3(false);
7468
+ const [busy, setBusy] = useState3(false);
7469
+ const [notice, show] = useNotice();
7470
+ const filled = options.map((o) => o.trim()).filter(Boolean);
7471
+ const ready = question.trim().length > 0 && filled.length >= 2;
7472
+ const save = async (launch) => {
7473
+ setBusy(true);
7474
+ const created = await act({ action: "poll_create", question, options: filled, multiple, anonymous });
7475
+ if (!created.ok) {
7476
+ show(created);
7477
+ setBusy(false);
7478
+ return;
7479
+ }
7480
+ if (launch && created.itemId != null) {
7481
+ const launched = await act({ action: "poll_launch", itemId: created.itemId });
7482
+ if (!launched.ok) {
7483
+ show(launched);
7484
+ setBusy(false);
7485
+ return;
7486
+ }
7487
+ }
7488
+ setBusy(false);
7489
+ onDone();
7490
+ };
7491
+ return /* @__PURE__ */ jsxs2(
7492
+ "form",
7493
+ {
7494
+ className: "mx-meet__collab-card",
7495
+ onSubmit: (event) => {
7496
+ event.preventDefault();
7497
+ if (ready) void save(true);
7498
+ },
7499
+ children: [
7500
+ /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
7501
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "Question" }),
7502
+ /* @__PURE__ */ jsx3(
7503
+ "input",
7504
+ {
7505
+ className: "mx-meet__input",
7506
+ value: question,
7507
+ maxLength: 1e3,
7508
+ onChange: (event) => setQuestion(event.target.value),
7509
+ placeholder: "Ask the room something",
7510
+ autoFocus: true
7511
+ }
7512
+ )
7513
+ ] }),
7514
+ options.map((option, index) => /* @__PURE__ */ jsxs2("div", { className: "mx-meet__composer-row", children: [
7515
+ /* @__PURE__ */ jsx3(
7516
+ "input",
7517
+ {
7518
+ className: "mx-meet__input",
7519
+ value: option,
7520
+ maxLength: 200,
7521
+ "aria-label": `Answer ${index + 1}`,
7522
+ placeholder: `Answer ${index + 1}`,
7523
+ onChange: (event) => setOptions(options.map((o, i) => i === index ? event.target.value : o))
7524
+ }
7525
+ ),
7526
+ options.length > 2 ? /* @__PURE__ */ jsx3(ControlButton, { label: `Remove answer ${index + 1}`, onClick: () => setOptions(options.filter((_, i) => i !== index)), children: /* @__PURE__ */ jsx3(CloseIcon, { width: 14, height: 14 }) }) : null
7527
+ ] }, index)),
7528
+ options.length < maxOptions ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: () => setOptions([...options, ""]), children: "Add an answer" }) : null,
7529
+ /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
7530
+ /* @__PURE__ */ jsx3("input", { type: "checkbox", checked: multiple, onChange: (event) => setMultiple(event.target.checked) }),
7531
+ "People can pick more than one"
7532
+ ] }),
7533
+ /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
7534
+ /* @__PURE__ */ jsx3("input", { type: "checkbox", checked: anonymous, onChange: (event) => setAnonymous(event.target.checked) }),
7535
+ "Anonymous \u2014 nobody sees who picked what"
7536
+ ] }),
7537
+ /* @__PURE__ */ jsx3(Notice, { notice }),
7538
+ /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-actions", children: [
7539
+ /* @__PURE__ */ jsx3("button", { type: "submit", className: "mx-meet__primary mx-meet__primary--small", disabled: !ready || busy, children: "Launch" }),
7540
+ /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", disabled: !ready || busy, onClick: () => void save(false), children: "Save draft" }),
7541
+ /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: onDone, children: "Cancel" })
7542
+ ] })
7543
+ ]
7544
+ }
7545
+ );
7546
+ }
7547
+ function PollCard({ poll }) {
7548
+ const { act, isHost } = useCollab();
7549
+ const [picked, setPicked] = useState3(poll.myVote.slice());
7550
+ const [notice, show] = useNotice();
7551
+ useEffect3(() => setPicked(poll.myVote.slice()), [poll.myVote]);
7552
+ const counts = poll.options.some((o) => o.votes !== void 0);
7553
+ const total = poll.options.reduce((sum, o) => sum + (o.votes ?? 0), 0);
7554
+ const canVote = poll.state === "live";
7555
+ const voted = poll.myVote.length > 0;
7556
+ const stateWord = poll.state === "draft" ? "Draft" : poll.state === "live" ? "Open" : "Closed";
7557
+ const toggle = (id) => {
7558
+ if (!canVote) return;
7559
+ setPicked(poll.multiple ? picked.includes(id) ? picked.filter((p) => p !== id) : [...picked, id] : [id]);
7560
+ };
7561
+ return /* @__PURE__ */ jsxs2("article", { className: "mx-meet__collab-card", "aria-label": poll.question, children: [
7562
+ /* @__PURE__ */ jsxs2("header", { className: "mx-meet__collab-head", children: [
7563
+ /* @__PURE__ */ jsx3("strong", { className: "mx-meet__collab-title", children: poll.question }),
7564
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__collab-state", children: stateWord })
7565
+ ] }),
7566
+ /* @__PURE__ */ jsxs2("p", { className: "mx-meet__panel-note", children: [
7567
+ poll.multiple ? "Pick any." : "Pick one.",
7568
+ poll.anonymous ? " Anonymous." : "",
7569
+ counts && poll.voterCount !== null ? ` ${poll.voterCount} voted.` : "",
7570
+ isHost && poll.state !== "draft" && !poll.resultsShared ? " Results are visible only to hosts." : ""
7571
+ ] }),
7572
+ /* @__PURE__ */ jsx3("ul", { className: "mx-meet__poll-options", children: poll.options.map((option) => {
7573
+ const share = counts && total > 0 ? Math.round((option.votes ?? 0) / total * 100) : 0;
7574
+ const chosen = picked.includes(option.id);
7575
+ return /* @__PURE__ */ jsxs2("li", { children: [
7576
+ /* @__PURE__ */ jsxs2(
7577
+ "button",
7578
+ {
7579
+ type: "button",
7580
+ className: chosen ? "mx-meet__poll-option mx-meet__poll-option--chosen" : "mx-meet__poll-option",
7581
+ "aria-pressed": chosen,
7582
+ disabled: !canVote,
7583
+ onClick: () => toggle(option.id),
7584
+ children: [
7585
+ counts ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__poll-bar", style: { width: `${share}%` }, "aria-hidden": "true" }) : null,
7586
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__poll-text", children: option.text }),
7587
+ counts ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__poll-count", children: [
7588
+ option.votes ?? 0,
7589
+ " \xB7 ",
7590
+ share,
7591
+ "%"
7592
+ ] }) : null
7593
+ ]
7594
+ }
7595
+ ),
7596
+ option.voters !== void 0 && option.voters.length > 0 ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__poll-voters", children: option.voters.join(", ") }) : null
7597
+ ] }, option.id);
7598
+ }) }),
7599
+ /* @__PURE__ */ jsx3(Notice, { notice }),
7600
+ /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-actions", children: [
7601
+ canVote ? /* @__PURE__ */ jsx3(
7602
+ "button",
7603
+ {
7604
+ type: "button",
7605
+ className: "mx-meet__primary mx-meet__primary--small",
7606
+ disabled: picked.length === 0 || voted && picked.join() === poll.myVote.join(),
7607
+ onClick: () => void act({ action: "poll_vote", itemId: poll.id, optionIds: picked }).then(show),
7608
+ children: voted ? "Change vote" : "Vote"
7609
+ }
7610
+ ) : null,
7611
+ isHost && poll.state === "draft" ? /* @__PURE__ */ jsx3("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,
7612
+ isHost && poll.state === "live" ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "poll_close", itemId: poll.id }).then(show), children: "End poll" }) : null,
7613
+ isHost && poll.state !== "draft" ? /* @__PURE__ */ jsx3("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,
7614
+ isHost && poll.state === "live" ? null : isHost ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: () => void act({ action: "poll_delete", itemId: poll.id }).then(show), children: "Delete" }) : null
7615
+ ] })
7616
+ ] });
7617
+ }
7618
+ function PollsPanel({ onClose }) {
7619
+ const { collab, isHost } = useCollab();
7620
+ const [composing, setComposing] = useState3(false);
7621
+ const polls = collab?.polls ?? [];
7622
+ const maxOptions = collab?.settings?.pollMaxOptions ?? 10;
7623
+ const ordered = [...polls].reverse();
7624
+ return /* @__PURE__ */ jsxs2(PanelShell, { title: "Polls", onClose, children: [
7625
+ collab?.error != null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
7626
+ isHost && !composing ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__primary mx-meet__primary--small", onClick: () => setComposing(true), children: "New poll" }) : null,
7627
+ isHost && composing ? /* @__PURE__ */ jsx3(PollComposer, { maxOptions, onDone: () => setComposing(false) }) : null,
7628
+ ordered.length === 0 && !composing ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: isHost ? "No polls yet. Polls and their results are kept with the meeting." : "No polls yet." }) : null,
7629
+ ordered.map((poll) => /* @__PURE__ */ jsx3(PollCard, { poll }, poll.id))
7630
+ ] });
7631
+ }
7632
+ function QuestionCard({ question }) {
7633
+ const { act, isHost } = useCollab();
7634
+ const [answering, setAnswering] = useState3(false);
7635
+ const [reply, setReply] = useState3("");
7636
+ const [notice, show] = useNotice();
7637
+ return /* @__PURE__ */ jsxs2("li", { className: `mx-meet__collab-card mx-meet__question mx-meet__question--${question.state}`, children: [
7638
+ /* @__PURE__ */ jsxs2("div", { className: "mx-meet__question-row", children: [
7639
+ /* @__PURE__ */ jsxs2(
7640
+ "button",
7641
+ {
7642
+ type: "button",
7643
+ className: question.upvotedByMe ? "mx-meet__upvote mx-meet__upvote--on" : "mx-meet__upvote",
7644
+ "aria-pressed": question.upvotedByMe,
7645
+ "aria-label": question.upvotedByMe ? "Remove your upvote" : "Upvote",
7646
+ disabled: question.state === "dismissed",
7647
+ onClick: () => void act({ action: "question_upvote", itemId: question.id }).then((r) => r.ok ? void 0 : show(r)),
7648
+ children: [
7649
+ /* @__PURE__ */ jsx3(UpvoteIcon, { width: 16, height: 16 }),
7650
+ /* @__PURE__ */ jsx3("span", { children: question.upvotes })
7651
+ ]
7652
+ }
7653
+ ),
7654
+ /* @__PURE__ */ jsxs2("div", { className: "mx-meet__question-body", children: [
7655
+ /* @__PURE__ */ jsxs2("span", { className: "mx-meet__chat-meta", children: [
7656
+ /* @__PURE__ */ jsx3("strong", { children: question.mine ? "You" : question.askerName }),
7657
+ question.mine && question.anonymous ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__chat-private", children: "anonymous" }) : null,
7658
+ question.state !== "open" ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__collab-state", children: question.state === "answered" ? "Answered" : "Dismissed" }) : null
7659
+ ] }),
7660
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__chat-text", children: question.text }),
7661
+ question.answer !== null ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__question-answer", children: [
7662
+ /* @__PURE__ */ jsxs2("strong", { children: [
7663
+ question.answeredByName ?? "Host",
7664
+ ":"
7665
+ ] }),
7666
+ " ",
7667
+ question.answer
7668
+ ] }) : null
7669
+ ] })
7670
+ ] }),
7671
+ answering ? /* @__PURE__ */ jsxs2(
7672
+ "form",
7673
+ {
7674
+ className: "mx-meet__composer-row",
7675
+ onSubmit: (event) => {
7676
+ event.preventDefault();
7677
+ void act({ action: "question_answer", itemId: question.id, text: reply }).then((r) => {
7678
+ show(r);
7679
+ if (r.ok) {
7680
+ setAnswering(false);
7681
+ setReply("");
7682
+ }
7683
+ });
7684
+ },
7685
+ children: [
7686
+ /* @__PURE__ */ jsx3(
7687
+ "input",
7688
+ {
7689
+ className: "mx-meet__input",
7690
+ value: reply,
7691
+ maxLength: 2e3,
7692
+ onChange: (event) => setReply(event.target.value),
7693
+ placeholder: "Type an answer, or leave empty if you answered out loud",
7694
+ "aria-label": "Answer",
7695
+ autoFocus: true
7696
+ }
7697
+ ),
7698
+ /* @__PURE__ */ jsx3("button", { type: "submit", className: "mx-meet__send", children: "Done" })
7699
+ ]
7700
+ }
7701
+ ) : null,
7702
+ /* @__PURE__ */ jsx3(Notice, { notice }),
7703
+ isHost || question.mine ? /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-actions", children: [
7704
+ isHost && question.state === "open" && !answering ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => setAnswering(true), children: "Answer" }) : null,
7705
+ isHost && question.state === "open" ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "question_dismiss", itemId: question.id }).then(show), children: "Dismiss" }) : null,
7706
+ isHost && question.state !== "open" ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "question_reopen", itemId: question.id }).then(show), children: "Reopen" }) : null,
7707
+ question.mine || isHost ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: () => void act({ action: "question_delete", itemId: question.id }).then(show), children: "Delete" }) : null
7708
+ ] }) : null
7709
+ ] });
7710
+ }
7711
+ function QaPanel({ onClose }) {
7712
+ const { collab, act } = useCollab();
7713
+ const [draft, setDraft] = useState3("");
7714
+ const [anonymous, setAnonymous] = useState3(false);
7715
+ const [order, setOrder] = useState3("popular");
7716
+ const [notice, show] = useNotice();
7717
+ const allowAnonymous = collab?.settings?.qaAnonymousAllowed === true;
7718
+ const questions = [...collab?.questions ?? []];
7719
+ const rank = (q) => q.state === "open" ? 0 : q.state === "answered" ? 1 : 2;
7720
+ questions.sort(
7721
+ (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 ?? "")
7722
+ );
7723
+ return /* @__PURE__ */ jsxs2(PanelShell, { title: "Q&A", onClose, children: [
7724
+ collab?.error != null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
7725
+ /* @__PURE__ */ jsxs2(
7726
+ "form",
7727
+ {
7728
+ className: "mx-meet__composer mx-meet__composer--chat",
7729
+ onSubmit: (event) => {
7730
+ event.preventDefault();
7731
+ const text3 = draft.trim();
7732
+ if (text3.length === 0) return;
7733
+ void act({ action: "question_ask", text: text3, anonymous: allowAnonymous && anonymous }).then((r) => {
7734
+ if (r.ok) setDraft("");
7735
+ else show(r);
7736
+ });
7737
+ },
7738
+ children: [
7739
+ /* @__PURE__ */ jsxs2("div", { className: "mx-meet__composer-row", children: [
7740
+ /* @__PURE__ */ jsx3(
7741
+ "input",
7742
+ {
7743
+ className: "mx-meet__input",
7744
+ value: draft,
7745
+ maxLength: 1e3,
7746
+ onChange: (event) => setDraft(event.target.value),
7747
+ placeholder: "Ask the host a question",
7748
+ "aria-label": "Ask the host a question"
7749
+ }
7750
+ ),
7751
+ /* @__PURE__ */ jsx3("button", { type: "submit", className: "mx-meet__send", disabled: draft.trim().length === 0, children: "Ask" })
7752
+ ] }),
7753
+ allowAnonymous ? /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
7754
+ /* @__PURE__ */ jsx3("input", { type: "checkbox", checked: anonymous, onChange: (event) => setAnonymous(event.target.checked) }),
7755
+ "Ask anonymously"
7756
+ ] }) : null
7757
+ ]
7758
+ }
7759
+ ),
7760
+ /* @__PURE__ */ jsx3(Notice, { notice }),
7761
+ questions.length > 1 ? /* @__PURE__ */ jsx3("div", { className: "mx-meet__pills", role: "group", "aria-label": "Order questions", children: ["popular", "recent"].map((value) => /* @__PURE__ */ jsx3(
7762
+ "button",
7763
+ {
7764
+ type: "button",
7765
+ className: order === value ? "mx-meet__pill mx-meet__pill--on" : "mx-meet__pill",
7766
+ "aria-pressed": order === value,
7767
+ onClick: () => setOrder(value),
7768
+ children: value === "popular" ? "Popular" : "Recent"
7769
+ },
7770
+ value
7771
+ )) }) : null,
7772
+ questions.length === 0 ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: "No questions yet. Questions are kept with the meeting." }) : /* @__PURE__ */ jsx3("ul", { className: "mx-meet__chat", children: questions.map((question) => /* @__PURE__ */ jsx3(QuestionCard, { question }, question.id)) })
7773
+ ] });
7774
+ }
7775
+ var BOARD_W = 1600;
7776
+ var BOARD_H = 1e3;
7777
+ var INK = ["#111827", "#dc2626", "#2563eb", "#16a34a", "#f59e0b", "#7c3aed"];
7778
+ function strokePath(points) {
7779
+ if (points.length === 0) return "";
7780
+ const [first, ...rest] = points;
7781
+ const move = `M${(first[0] * BOARD_W).toFixed(1)} ${(first[1] * BOARD_H).toFixed(1)}`;
7782
+ if (rest.length === 0) return `${move} l0.1 0`;
7783
+ return `${move} ${rest.map(([x, y]) => `L${(x * BOARD_W).toFixed(1)} ${(y * BOARD_H).toFixed(1)}`).join(" ")}`;
7784
+ }
7785
+ function StrokeView({ stroke, onPick }) {
7786
+ return /* @__PURE__ */ jsx3(
7787
+ "path",
7788
+ {
7789
+ d: strokePath(stroke.points),
7790
+ fill: "none",
7791
+ stroke: stroke.color,
7792
+ strokeWidth: stroke.tool === "highlighter" ? stroke.width * 4 : stroke.width,
7793
+ strokeOpacity: stroke.tool === "highlighter" ? 0.35 : stroke.pending === true ? 0.6 : 1,
7794
+ strokeLinecap: "round",
7795
+ strokeLinejoin: "round",
7796
+ onPointerDown: onPick,
7797
+ style: onPick !== void 0 ? { cursor: "pointer" } : void 0,
7798
+ children: /* @__PURE__ */ jsx3("title", { children: stroke.byName })
7799
+ }
7800
+ );
7801
+ }
7802
+ function WhiteboardPanel({ onClose }) {
7803
+ const { collab, act, isHost, localIdentity } = useCollab();
7804
+ const [tool, setTool] = useState3("pen");
7805
+ const [color, setColor] = useState3(INK[0]);
7806
+ const [drawing, setDrawing] = useState3(null);
7807
+ const [pending, setPending] = useState3([]);
7808
+ const [notice, show] = useNotice();
7809
+ const svgRef = useRef3(null);
7810
+ const strokes = collab?.strokes ?? [];
7811
+ const mine = strokes.filter((s) => s.by === localIdentity);
7812
+ const point = (event) => {
7813
+ const svg = svgRef.current;
7814
+ if (svg === null) return null;
7815
+ const rect = svg.getBoundingClientRect();
7816
+ const scale = Math.min(rect.width / BOARD_W, rect.height / BOARD_H);
7817
+ const offsetX = (rect.width - BOARD_W * scale) / 2;
7818
+ const offsetY = (rect.height - BOARD_H * scale) / 2;
7819
+ const x = (event.clientX - rect.left - offsetX) / (BOARD_W * scale);
7820
+ const y = (event.clientY - rect.top - offsetY) / (BOARD_H * scale);
7821
+ return [Math.min(1, Math.max(0, x)), Math.min(1, Math.max(0, y))];
7822
+ };
7823
+ const finish = () => {
7824
+ const points = drawing;
7825
+ setDrawing(null);
7826
+ if (points === null || points.length === 0 || tool === "eraser") return;
7827
+ const thinned = points.filter((p, i) => i === 0 || i === points.length - 1 || i % 2 === 0).slice(0, 2e3);
7828
+ const stroke = {
7829
+ points: thinned.map(([x, y]) => [Number(x.toFixed(4)), Number(y.toFixed(4))]),
7830
+ color,
7831
+ width: tool === "highlighter" ? 4 : 3,
7832
+ tool: tool === "highlighter" ? "highlighter" : "pen"
7833
+ };
7834
+ const localId = `pending-${Date.now()}`;
7835
+ setPending((list) => [...list, { id: localId, ...stroke, by: localIdentity ?? "", byName: "You", pending: true }]);
7836
+ void act({ action: "stroke_add", stroke }).then((result) => {
7837
+ setPending((list) => list.filter((s) => s.id !== localId));
7838
+ if (!result.ok) show(result);
7839
+ });
7840
+ };
7841
+ return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__whiteboard", "aria-label": "Whiteboard", children: [
7842
+ /* @__PURE__ */ jsxs2("header", { className: "mx-meet__whiteboard-bar", children: [
7843
+ /* @__PURE__ */ jsx3("strong", { className: "mx-meet__panel-title", children: "Whiteboard" }),
7844
+ /* @__PURE__ */ jsx3("div", { className: "mx-meet__pills", role: "group", "aria-label": "Tool", children: [
7845
+ ["pen", "Pen", /* @__PURE__ */ jsx3(PencilIcon, { width: 16, height: 16 }, "p")],
7846
+ ["highlighter", "Highlighter", /* @__PURE__ */ jsx3(HighlighterIcon, { width: 16, height: 16 }, "h")],
7847
+ ["eraser", "Eraser \u2014 click a stroke", /* @__PURE__ */ jsx3(EraserIcon, { width: 16, height: 16 }, "e")]
7848
+ ].map(([value, label, icon]) => /* @__PURE__ */ jsx3(
7849
+ "button",
7850
+ {
7851
+ type: "button",
7852
+ className: tool === value ? "mx-meet__pill mx-meet__pill--on" : "mx-meet__pill",
7853
+ "aria-pressed": tool === value,
7854
+ "aria-label": label,
7855
+ title: label,
7856
+ onClick: () => setTool(value),
7857
+ children: icon
7858
+ },
7859
+ value
7860
+ )) }),
7861
+ /* @__PURE__ */ jsx3("div", { className: "mx-meet__swatches", role: "group", "aria-label": "Color", children: INK.map((ink) => /* @__PURE__ */ jsx3(
7862
+ "button",
7863
+ {
7864
+ type: "button",
7865
+ className: ink === color ? "mx-meet__swatch mx-meet__swatch--on" : "mx-meet__swatch",
7866
+ style: { background: ink },
7867
+ "aria-label": `Color ${ink}`,
7868
+ "aria-pressed": ink === color,
7869
+ onClick: () => {
7870
+ setColor(ink);
7871
+ if (tool === "eraser") setTool("pen");
7872
+ }
7873
+ },
7874
+ ink
7875
+ )) }),
7876
+ /* @__PURE__ */ jsx3(
7877
+ ControlButton,
7878
+ {
7879
+ label: "Undo my last stroke",
7880
+ onClick: () => {
7881
+ const last = mine[mine.length - 1];
7882
+ if (last !== void 0) void act({ action: "stroke_erase", itemId: last.id }).then((r) => r.ok ? void 0 : show(r));
7883
+ },
7884
+ children: /* @__PURE__ */ jsx3(UndoIcon, { width: 16, height: 16 })
7885
+ }
7886
+ ),
7887
+ isHost && strokes.length > 0 ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "whiteboard_clear" }).then(show), children: "Clear board" }) : null,
7888
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__whiteboard-note", children: "Saved with the meeting" }),
7889
+ /* @__PURE__ */ jsx3(ControlButton, { label: "Close whiteboard", onClick: onClose, children: /* @__PURE__ */ jsx3(CloseIcon, { width: 16, height: 16 }) })
7890
+ ] }),
7891
+ /* @__PURE__ */ jsx3(Notice, { notice }),
7892
+ /* @__PURE__ */ jsxs2(
7893
+ "svg",
7894
+ {
7895
+ ref: svgRef,
7896
+ className: tool === "eraser" ? "mx-meet__board mx-meet__board--erase" : "mx-meet__board",
7897
+ viewBox: `0 0 ${BOARD_W} ${BOARD_H}`,
7898
+ preserveAspectRatio: "xMidYMid meet",
7899
+ role: "img",
7900
+ "aria-label": `Shared whiteboard, ${strokes.length} strokes`,
7901
+ onPointerDown: (event) => {
7902
+ if (tool === "eraser") return;
7903
+ const p = point(event);
7904
+ if (p === null) return;
7905
+ event.target.setPointerCapture?.(event.pointerId);
7906
+ setDrawing([p]);
7907
+ },
7908
+ onPointerMove: (event) => {
7909
+ if (drawing === null) return;
7910
+ const p = point(event);
7911
+ if (p !== null) setDrawing([...drawing, p]);
7912
+ },
7913
+ onPointerUp: finish,
7914
+ onPointerCancel: finish,
7915
+ children: [
7916
+ /* @__PURE__ */ jsx3("rect", { x: 0, y: 0, width: BOARD_W, height: BOARD_H, className: "mx-meet__board-paper" }),
7917
+ strokes.map((stroke) => /* @__PURE__ */ jsx3(
7918
+ StrokeView,
7919
+ {
7920
+ stroke,
7921
+ 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
7922
+ },
7923
+ stroke.id
7924
+ )),
7925
+ pending.map((stroke) => /* @__PURE__ */ jsx3(StrokeView, { stroke }, stroke.id)),
7926
+ drawing !== null ? /* @__PURE__ */ jsx3(
7927
+ StrokeView,
7928
+ {
7929
+ stroke: {
7930
+ id: "drawing",
7931
+ points: drawing,
7932
+ color,
7933
+ width: tool === "highlighter" ? 4 : 3,
7934
+ tool: tool === "highlighter" ? "highlighter" : "pen",
7935
+ by: "",
7936
+ byName: "You"
7937
+ }
7938
+ }
7939
+ ) : null
7940
+ ]
7941
+ }
7942
+ )
7943
+ ] });
7944
+ }
7945
+ function clock(ms2) {
7946
+ const total = Math.ceil(ms2 / 1e3);
7947
+ const minutes = Math.floor(total / 60);
7948
+ const seconds = total % 60;
7949
+ return `${minutes}:${seconds.toString().padStart(2, "0")}`;
7950
+ }
7951
+ function useNow(active) {
7952
+ const [now, setNow] = useState3(() => Date.now());
7953
+ useEffect3(() => {
7954
+ if (!active) return void 0;
7955
+ const timer = setInterval(() => setNow(Date.now()), 1e3);
7956
+ return () => clearInterval(timer);
7957
+ }, [active]);
7958
+ return now;
7959
+ }
7960
+ function BreakoutSetup() {
7961
+ const { collab, act } = useCollab();
7962
+ const snapshot = useMeetSnapshot();
7963
+ const settings = collab?.settings ?? null;
7964
+ const people = (snapshot?.participants ?? []).filter(
7965
+ (p) => !p.isAgent && p.role !== "host" && p.role !== "cohost"
7966
+ );
7967
+ const [count2, setCount] = useState3(Math.min(Math.max(2, Math.ceil(people.length / 4)), settings?.breakoutMaxRooms ?? 20));
7968
+ const [mode, setMode] = useState3("auto");
7969
+ const [minutes, setMinutes] = useState3(settings?.breakoutDefaultMinutes ?? 15);
7970
+ const [manual, setManual] = useState3({});
7971
+ const [busy, setBusy] = useState3(false);
7972
+ const [notice, show] = useNotice();
7973
+ const max = settings?.breakoutMaxRooms ?? 20;
7974
+ const rooms = Math.min(Math.max(1, count2), max);
7975
+ const assignment = mode === "auto" ? autoAssign(
7976
+ people.map((p) => p.identity),
7977
+ rooms
7978
+ ) : mode === "manual" ? Array.from(
7979
+ { length: rooms },
7980
+ (_, index) => people.filter((p) => (manual[p.identity] ?? -1) === index).map((p) => p.identity)
7981
+ ) : Array.from({ length: rooms }, () => []);
7982
+ const nameOf = (identity) => people.find((p) => p.identity === identity)?.displayName ?? identity;
7983
+ return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-card", children: [
7984
+ /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
7985
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "Rooms" }),
7986
+ /* @__PURE__ */ jsx3(
7987
+ "input",
7988
+ {
7989
+ className: "mx-meet__input",
7990
+ type: "number",
7991
+ min: 1,
7992
+ max,
7993
+ value: count2,
7994
+ onChange: (event) => setCount(Number(event.target.value) || 1)
7995
+ }
7996
+ )
7997
+ ] }),
7998
+ /* @__PURE__ */ jsx3("div", { className: "mx-meet__pills", role: "group", "aria-label": "How people are placed", children: [
7999
+ ["auto", "Automatically"],
8000
+ ["manual", "Manually"],
8001
+ ["choose", "Let people choose"]
8002
+ ].map(([value, label]) => /* @__PURE__ */ jsx3(
8003
+ "button",
8004
+ {
8005
+ type: "button",
8006
+ className: mode === value ? "mx-meet__pill mx-meet__pill--on" : "mx-meet__pill",
8007
+ "aria-pressed": mode === value,
8008
+ onClick: () => setMode(value),
8009
+ children: label
8010
+ },
8011
+ value
8012
+ )) }),
8013
+ /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
8014
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "Timer (minutes, 0 for none)" }),
8015
+ /* @__PURE__ */ jsx3(
8016
+ "input",
8017
+ {
8018
+ className: "mx-meet__input",
8019
+ type: "number",
8020
+ min: 0,
8021
+ max: 720,
8022
+ value: minutes,
8023
+ onChange: (event) => setMinutes(Math.max(0, Number(event.target.value) || 0))
8024
+ }
8025
+ )
8026
+ ] }),
8027
+ mode === "manual" ? people.length === 0 ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: "Nobody else is in the meeting yet." }) : /* @__PURE__ */ jsx3("ul", { className: "mx-meet__people", children: people.map((person) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__person", children: [
8028
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__person-name", children: person.displayName }),
8029
+ /* @__PURE__ */ jsxs2(
8030
+ "select",
8031
+ {
8032
+ className: "mx-meet__select mx-meet__select--compact",
8033
+ "aria-label": `Room for ${person.displayName}`,
8034
+ value: manual[person.identity] ?? -1,
8035
+ onChange: (event) => setManual({ ...manual, [person.identity]: Number(event.target.value) }),
8036
+ children: [
8037
+ /* @__PURE__ */ jsx3("option", { value: -1, children: "Main room" }),
8038
+ Array.from({ length: rooms }, (_, index) => /* @__PURE__ */ jsxs2("option", { value: index, children: [
8039
+ "Room ",
8040
+ index + 1
8041
+ ] }, index))
8042
+ ]
8043
+ }
8044
+ )
8045
+ ] }, person.identity)) }) : mode === "auto" ? /* @__PURE__ */ jsx3("ul", { className: "mx-meet__breakout-rooms", children: assignment.map((members, index) => /* @__PURE__ */ jsxs2("li", { children: [
8046
+ /* @__PURE__ */ jsxs2("strong", { children: [
8047
+ "Room ",
8048
+ index + 1
8049
+ ] }),
8050
+ " ",
8051
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__panel-note", children: members.length === 0 ? "empty" : members.map(nameOf).join(", ") })
8052
+ ] }, index)) }) : /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: "Everyone picks a room from their own screen." }),
8053
+ /* @__PURE__ */ jsx3(Notice, { notice }),
8054
+ /* @__PURE__ */ jsxs2(
8055
+ "button",
8056
+ {
8057
+ type: "button",
8058
+ className: "mx-meet__primary mx-meet__primary--small",
8059
+ disabled: busy,
8060
+ onClick: () => {
8061
+ setBusy(true);
8062
+ void act({
8063
+ action: "breakout_open",
8064
+ rooms: assignment.map((identities, index) => ({ name: `Room ${index + 1}`, identities })),
8065
+ allowChoose: mode === "choose",
8066
+ minutes
8067
+ }).then((result) => {
8068
+ setBusy(false);
8069
+ show(result);
8070
+ });
8071
+ },
8072
+ children: [
8073
+ "Open ",
8074
+ rooms,
8075
+ " room",
8076
+ rooms === 1 ? "" : "s"
8077
+ ]
8078
+ }
8079
+ )
8080
+ ] });
8081
+ }
8082
+ function BreakoutRun({ plan }) {
8083
+ const { act, moveTo, isHost, breakoutRoomId, localIdentity } = useCollab();
8084
+ const snapshot = useMeetSnapshot();
8085
+ const now = useNow(plan.endsAt !== null);
8086
+ const remaining = breakoutRemainingMs(plan, now);
8087
+ const [broadcast, setBroadcast] = useState3("");
8088
+ const [notice, show] = useNotice();
8089
+ const nameOf = (identity) => displayNameFor(snapshot?.names ?? {}, identity, snapshot?.participants.find((p) => p.identity === identity)?.displayName);
8090
+ const mine = assignedRoom(plan, localIdentity);
8091
+ const join = async (roomId) => {
8092
+ const said = await act({ action: "breakout_join", roomId });
8093
+ if (!said.ok) {
8094
+ show(said);
8095
+ return;
8096
+ }
8097
+ show(await moveTo(roomId));
8098
+ };
8099
+ return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-card", children: [
8100
+ /* @__PURE__ */ jsxs2("p", { className: "mx-meet__panel-note", children: [
8101
+ plan.rooms.length,
8102
+ " room",
8103
+ plan.rooms.length === 1 ? "" : "s",
8104
+ " open",
8105
+ remaining !== null ? ` \xB7 ${clock(remaining)} left` : "",
8106
+ plan.allowChoose ? " \xB7 people choose their room" : ""
8107
+ ] }),
8108
+ /* @__PURE__ */ jsx3("ul", { className: "mx-meet__breakout-rooms", children: plan.rooms.map((room) => {
8109
+ const here = breakoutRoomId === room.id;
8110
+ const mayJoin = isHost || plan.allowChoose || mine?.id === room.id;
8111
+ return /* @__PURE__ */ jsxs2("li", { className: here ? "mx-meet__breakout-room mx-meet__breakout-room--here" : "mx-meet__breakout-room", children: [
8112
+ /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-head", children: [
8113
+ /* @__PURE__ */ jsx3("strong", { children: room.name }),
8114
+ here ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__collab-state", children: "You are here" }) : mayJoin ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => void join(room.id), children: "Join" }) : null
8115
+ ] }),
8116
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__panel-note", children: room.identities.length === 0 ? "Nobody assigned" : room.identities.map(nameOf).join(", ") }),
8117
+ isHost && room.identities.length > 0 ? /* @__PURE__ */ jsx3("ul", { className: "mx-meet__people", children: room.identities.map((identity) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__person", children: [
8118
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__person-name", children: nameOf(identity) }),
8119
+ /* @__PURE__ */ jsxs2(
8120
+ "select",
8121
+ {
8122
+ className: "mx-meet__select mx-meet__select--compact",
8123
+ "aria-label": `Move ${nameOf(identity)}`,
8124
+ value: room.id,
8125
+ onChange: (event) => void act({
8126
+ action: "breakout_move",
8127
+ identity,
8128
+ roomId: event.target.value === "" ? null : event.target.value
8129
+ }).then(show),
8130
+ children: [
8131
+ /* @__PURE__ */ jsx3("option", { value: "", children: "Main room" }),
8132
+ plan.rooms.map((option) => /* @__PURE__ */ jsx3("option", { value: option.id, children: option.name }, option.id))
8133
+ ]
8134
+ }
8135
+ )
8136
+ ] }, identity)) }) : null
8137
+ ] }, room.id);
8138
+ }) }),
8139
+ breakoutRoomId !== null ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => void join(null), children: "Return to the main room" }) : null,
8140
+ isHost ? /* @__PURE__ */ jsxs2(
8141
+ "form",
8142
+ {
8143
+ className: "mx-meet__composer-row",
8144
+ onSubmit: (event) => {
8145
+ event.preventDefault();
8146
+ const text3 = broadcast.trim();
8147
+ if (text3.length === 0) return;
8148
+ void act({ action: "breakout_broadcast", text: text3 }).then((result) => {
8149
+ show(result);
8150
+ if (result.ok) setBroadcast("");
8151
+ });
8152
+ },
8153
+ children: [
8154
+ /* @__PURE__ */ jsx3(
8155
+ "input",
8156
+ {
8157
+ className: "mx-meet__input",
8158
+ value: broadcast,
8159
+ maxLength: 500,
8160
+ onChange: (event) => setBroadcast(event.target.value),
8161
+ placeholder: "Message every room",
8162
+ "aria-label": "Message every room"
8163
+ }
8164
+ ),
8165
+ /* @__PURE__ */ jsx3("button", { type: "submit", className: "mx-meet__send", disabled: broadcast.trim().length === 0, children: "Send" })
8166
+ ]
8167
+ }
8168
+ ) : null,
8169
+ /* @__PURE__ */ jsx3(Notice, { notice }),
8170
+ isHost ? /* @__PURE__ */ jsx3(
8171
+ "button",
8172
+ {
8173
+ type: "button",
8174
+ className: "mx-meet__primary mx-meet__primary--small",
8175
+ onClick: () => void act({ action: "breakout_close" }).then(show),
8176
+ children: "Bring everyone back"
8177
+ }
8178
+ ) : null
8179
+ ] });
8180
+ }
8181
+ function BreakoutsPanel({ onClose }) {
8182
+ const { collab, isHost } = useCollab();
8183
+ const plan = collab?.breakout?.state === "open" ? collab.breakout : null;
8184
+ return /* @__PURE__ */ jsxs2(PanelShell, { title: "Breakout rooms", onClose, children: [
8185
+ collab?.error != null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
8186
+ plan !== null ? /* @__PURE__ */ jsx3(BreakoutRun, { plan }) : isHost ? /* @__PURE__ */ jsx3(BreakoutSetup, {}) : /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: "Breakout rooms are closed." })
8187
+ ] });
8188
+ }
8189
+ function BreakoutBanner() {
8190
+ const host = useMeetHost();
8191
+ const { collab, act, moveTo, localIdentity, breakoutRoomId } = useCollab();
8192
+ const plan = collab?.breakout ?? null;
8193
+ const open = plan?.state === "open" ? plan : null;
8194
+ const now = useNow(open?.endsAt != null);
8195
+ const remaining = breakoutRemainingMs(open, now);
8196
+ const assigned = assignedRoom(open, localIdentity);
8197
+ const [dismissedBroadcast, setDismissedBroadcast] = useState3(null);
8198
+ const [failure, setFailure] = useState3(null);
8199
+ const expireAsked = useRef3(null);
8200
+ const moveAt = collab?.moveRequest?.at ?? null;
8201
+ useEffect3(() => {
8202
+ const request = host?.store.snapshot().collab.moveRequest ?? null;
8203
+ if (request === null || host === null) return;
8204
+ host.store.patch({ collab: { ...host.store.snapshot().collab, moveRequest: null } });
8205
+ const here = host.store.snapshot().breakoutRoomId;
8206
+ if ((here ?? null) === request.roomId) return;
8207
+ void moveTo(request.roomId).then((result) => setFailure(result.ok ? null : result.message));
8208
+ }, [moveAt, host, moveTo]);
8209
+ useEffect3(() => {
8210
+ if (open === null || remaining === null || remaining > 0) return;
8211
+ if (expireAsked.current === open.id) return;
8212
+ expireAsked.current = open.id;
8213
+ void act({ action: "breakout_expire" });
8214
+ }, [open, remaining, act]);
8215
+ const broadcast = collab?.broadcast ?? null;
8216
+ const showBroadcast = broadcast !== null && broadcast.at !== dismissedBroadcast && open !== null;
8217
+ const room = open?.rooms.find((r) => r.id === breakoutRoomId) ?? null;
8218
+ if (open === null && failure === null) return null;
8219
+ return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__breakout-banner", role: "status", children: [
8220
+ failure !== null ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__collab-error", children: failure }) : null,
8221
+ room !== null ? /* @__PURE__ */ jsxs2("span", { children: [
8222
+ /* @__PURE__ */ jsx3("strong", { children: room.name }),
8223
+ remaining !== null ? ` \xB7 ${clock(remaining)} left` : "",
8224
+ /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => void moveTo(null), children: "Return to main room" })
8225
+ ] }) : assigned !== null ? /* @__PURE__ */ jsxs2("span", { children: [
8226
+ "You are assigned to ",
8227
+ /* @__PURE__ */ jsx3("strong", { children: assigned.name }),
8228
+ remaining !== null ? ` \xB7 ${clock(remaining)} left` : "",
8229
+ /* @__PURE__ */ jsx3(
8230
+ "button",
8231
+ {
8232
+ type: "button",
8233
+ className: "mx-meet__primary mx-meet__primary--small",
8234
+ onClick: () => void act({ action: "breakout_join", roomId: assigned.id }).then(async (said) => {
8235
+ const result = said.ok ? await moveTo(assigned.id) : said;
8236
+ setFailure(result.ok ? null : result.message);
8237
+ }),
8238
+ children: "Join"
8239
+ }
8240
+ )
8241
+ ] }) : open?.allowChoose ? /* @__PURE__ */ jsx3("span", { children: "Breakout rooms are open \u2014 pick one under Activities." }) : null,
8242
+ showBroadcast ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__breakout-broadcast", children: [
8243
+ /* @__PURE__ */ jsxs2("strong", { children: [
8244
+ broadcast.by,
8245
+ ":"
8246
+ ] }),
8247
+ " ",
8248
+ broadcast.text,
8249
+ /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: () => setDismissedBroadcast(broadcast.at), children: "Dismiss" })
8250
+ ] }) : null
8251
+ ] });
8252
+ }
8253
+ function useCaptionTranslation(lines) {
8254
+ const host = useMeetHost();
8255
+ const snapshot = useMeetSnapshot();
8256
+ const collab = snapshot?.collab ?? null;
8257
+ const language = collab?.captionLanguage ?? null;
8258
+ const asked = useRef3(/* @__PURE__ */ new Set());
8259
+ const translations = collab?.captionTranslations ?? {};
8260
+ const missing = lines.filter((line) => line.final && translations[line.id] === void 0).map(({ id, text: text3 }) => ({ id, text: text3 }));
8261
+ const key = `${language ?? ""}|${missing.map((l) => l.id).join(",")}`;
8262
+ const pending = useRef3(missing);
8263
+ pending.current = missing;
8264
+ useEffect3(() => {
8265
+ if (host === null || language === null) return;
8266
+ const batch = pending.current.filter((line) => !asked.current.has(`${language}:${line.id}`)).slice(-20);
8267
+ if (batch.length === 0) return;
8268
+ for (const line of batch) asked.current.add(`${language}:${line.id}`);
8269
+ void host.inRoom.translateCaptions(language, batch).catch(() => void 0);
8270
+ }, [host, language, key]);
8271
+ return { language, translations, error: collab?.captionTranslationError ?? null };
8272
+ }
8273
+ function CaptionLanguageSettings() {
8274
+ const host = useMeetHost();
8275
+ const snapshot = useMeetSnapshot();
8276
+ const collab = snapshot?.collab ?? null;
8277
+ const settings = collab?.settings ?? null;
8278
+ if (host === null || settings === null || !settings.captionTranslationEnabled) return null;
8279
+ const viewer = typeof navigator !== "undefined" && typeof navigator.language === "string" ? navigator.language.slice(0, 2) : null;
8280
+ const preferred = defaultCaptionLanguage(settings, viewer);
8281
+ const current = collab?.captionLanguage ?? "";
8282
+ const choices = CAPTION_LANGUAGES.some((l) => l.tag === preferred) ? CAPTION_LANGUAGES : [{ tag: preferred, name: preferred }, ...CAPTION_LANGUAGES];
8283
+ return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__section", "aria-label": "Captions", children: [
8284
+ /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
8285
+ /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "Translate captions to" }),
8286
+ /* @__PURE__ */ jsxs2(
8287
+ "select",
8288
+ {
8289
+ className: "mx-meet__select",
8290
+ value: current,
8291
+ onChange: (event) => {
8292
+ const next = event.target.value === "" ? null : event.target.value;
8293
+ host.store.patch({
8294
+ collab: {
8295
+ ...host.store.snapshot().collab,
8296
+ captionLanguage: next,
8297
+ captionTranslations: {},
8298
+ captionTranslationError: null
8299
+ }
8300
+ });
8301
+ },
8302
+ children: [
8303
+ /* @__PURE__ */ jsx3("option", { value: "", children: "Off \u2014 as spoken" }),
8304
+ current === "" ? /* @__PURE__ */ jsxs2("option", { value: preferred, children: [
8305
+ choices.find((c) => c.tag === preferred)?.name ?? preferred,
8306
+ " (yours)"
8307
+ ] }) : null,
8308
+ choices.filter((choice) => current !== "" || choice.tag !== preferred).map((choice) => /* @__PURE__ */ jsx3("option", { value: choice.tag, children: choice.name }, choice.tag))
8309
+ ]
8310
+ }
8311
+ )
8312
+ ] }),
8313
+ collab?.captionTranslationError != null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.captionTranslationError }) : null
8314
+ ] });
8315
+ }
8316
+ function useCollabPanelRequest(onRequest) {
8317
+ const host = useMeetHost();
8318
+ const at = useMeetSnapshot()?.collab.panelRequest?.at ?? null;
8319
+ const callback = useRef3(onRequest);
8320
+ callback.current = onRequest;
8321
+ useEffect3(() => {
8322
+ const request = host?.store.snapshot().collab.panelRequest ?? null;
8323
+ if (request === null || host === null) return;
8324
+ host.store.patch({ collab: { ...host.store.snapshot().collab, panelRequest: null } });
8325
+ callback.current(request.panel);
8326
+ }, [at, host]);
8327
+ }
8328
+
8329
+ // src/react/components.tsx
8330
+ import { Fragment, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
8331
+ function InertNotice({ what }) {
8332
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__empty", role: "status", children: [
8333
+ /* @__PURE__ */ jsxs3("p", { className: "mx-meet__empty-title", children: [
8334
+ what,
8335
+ " is not ready yet"
8336
+ ] }),
8337
+ /* @__PURE__ */ jsx4("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." })
8338
+ ] });
8339
+ }
8340
+ function Avatar({
8341
+ name,
8342
+ url,
8343
+ size = 40
8344
+ }) {
8345
+ const tint = avatarPaletteIndex(name);
8346
+ if (url != null && url.length > 0) {
8347
+ return /* @__PURE__ */ jsx4(
8348
+ "img",
8349
+ {
8350
+ className: "mx-meet__avatar",
8351
+ src: url,
8352
+ alt: "",
8353
+ width: size,
8354
+ height: size,
8355
+ style: { width: size, height: size }
8356
+ }
8357
+ );
8358
+ }
8359
+ return /* @__PURE__ */ jsx4(
8360
+ "span",
8361
+ {
8362
+ className: "mx-meet__avatar mx-meet__avatar--initials",
8363
+ style: {
8364
+ width: size,
8365
+ height: size,
8366
+ fontSize: Math.round(size * 0.38),
8367
+ background: `var(--mx-meet-avatar-${tint})`
8368
+ },
8369
+ "aria-hidden": "true",
8370
+ children: getInitials(name)
8371
+ }
8372
+ );
8373
+ }
8374
+ function ControlButton({
8375
+ label,
8376
+ active = false,
8377
+ danger = false,
8378
+ onClick,
8379
+ children
8380
+ }) {
8381
+ return /* @__PURE__ */ jsx4(
8382
+ "button",
8383
+ {
8384
+ type: "button",
8385
+ className: [
8386
+ "mx-meet__control",
8387
+ active ? "mx-meet__control--active" : "",
8388
+ danger ? "mx-meet__control--danger" : ""
8389
+ ].filter(Boolean).join(" "),
8390
+ "aria-label": label,
8391
+ title: label,
8392
+ onClick,
8393
+ children
8394
+ }
8395
+ );
8396
+ }
8397
+ function RecordingIndicator() {
8398
+ const { state, label } = useRecording();
8399
+ if (label === null) return null;
8400
+ return /* @__PURE__ */ jsxs3(
8401
+ "span",
8402
+ {
8403
+ className: `mx-meet__recording mx-meet__recording--${state}`,
8404
+ role: "status",
8405
+ "aria-live": "polite",
8406
+ children: [
8407
+ /* @__PURE__ */ jsx4(RecordIcon, { width: 10, height: 10 }),
8408
+ label
8409
+ ]
8410
+ }
8411
+ );
8412
+ }
8413
+ function ConnectionDot({ quality }) {
8414
+ if (quality === "excellent" || quality === "good" || quality === "unknown") return null;
8415
+ return /* @__PURE__ */ jsx4("span", { className: `mx-meet__quality mx-meet__quality--${quality}`, title: `Connection ${quality}`, children: /* @__PURE__ */ jsx4(WifiLowIcon, { width: 14, height: 14 }) });
8416
+ }
8417
+ function RoleBadge({ role }) {
8418
+ if (role === "host") return /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Host" });
8419
+ if (role === "cohost") return /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Co-host" });
8420
+ if (role === "guest") return /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Guest" });
8421
+ return null;
8422
+ }
8423
+ function ParticipantTile({
6837
8424
  participant,
6838
8425
  featured = false
6839
8426
  }) {
6840
8427
  const host = useMeetHost();
6841
8428
  const snapshot = useMeetSnapshot();
6842
8429
  const queue = useHandQueue();
6843
- const [menu, setMenu] = useState3(false);
8430
+ const [menu, setMenu] = useState4(false);
6844
8431
  const videoRef = useTrack(
6845
8432
  participant.identity,
6846
8433
  participant.screenSharing ? "screen" : "camera"
@@ -6849,7 +8436,7 @@ function ParticipantTile({
6849
8436
  const pinnedHere = snapshot?.pinned === participant.identity;
6850
8437
  const spotlit = snapshot?.spotlight === participant.identity;
6851
8438
  const handPosition = participant.handRaised ? queue.findIndex((entry) => entry.identity === participant.identity) + 1 : 0;
6852
- return /* @__PURE__ */ jsxs2(
8439
+ return /* @__PURE__ */ jsxs3(
6853
8440
  "div",
6854
8441
  {
6855
8442
  className: [
@@ -6859,7 +8446,7 @@ function ParticipantTile({
6859
8446
  ].filter(Boolean).join(" "),
6860
8447
  "data-identity": participant.identity,
6861
8448
  children: [
6862
- showVideo ? /* @__PURE__ */ jsx3(
8449
+ showVideo ? /* @__PURE__ */ jsx4(
6863
8450
  "video",
6864
8451
  {
6865
8452
  ref: videoRef,
@@ -6868,43 +8455,43 @@ function ParticipantTile({
6868
8455
  playsInline: true,
6869
8456
  muted: participant.isLocal
6870
8457
  }
6871
- ) : /* @__PURE__ */ jsx3("div", { className: "mx-meet__tile-placeholder", children: /* @__PURE__ */ jsx3(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: featured ? 96 : 56 }) }),
6872
- participant.handRaised ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__tile-hand", title: `Hand raised \xB7 ${ordinal(handPosition)} in line`, children: [
6873
- /* @__PURE__ */ jsx3(HandIcon, { width: 14, height: 14 }),
8458
+ ) : /* @__PURE__ */ jsx4("div", { className: "mx-meet__tile-placeholder", children: /* @__PURE__ */ jsx4(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: featured ? 96 : 56 }) }),
8459
+ participant.handRaised ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__tile-hand", title: `Hand raised \xB7 ${ordinal(handPosition)} in line`, children: [
8460
+ /* @__PURE__ */ jsx4(HandIcon, { width: 14, height: 14 }),
6874
8461
  handPosition > 0 ? handPosition : null
6875
8462
  ] }) : null,
6876
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__tile-bar", children: [
6877
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__tile-name", children: [
6878
- spotlit ? /* @__PURE__ */ jsx3("span", { title: "Spotlighted for everyone", className: "mx-meet__tile-flag", children: /* @__PURE__ */ jsx3(SpotlightIcon, { width: 12, height: 12 }) }) : null,
8463
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__tile-bar", children: [
8464
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__tile-name", children: [
8465
+ spotlit ? /* @__PURE__ */ jsx4("span", { title: "Spotlighted for everyone", className: "mx-meet__tile-flag", children: /* @__PURE__ */ jsx4(SpotlightIcon, { width: 12, height: 12 }) }) : null,
6879
8466
  participant.displayName,
6880
8467
  participant.isLocal ? " (you)" : "",
6881
- participant.isAgent ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "AI" }) : null,
6882
- /* @__PURE__ */ jsx3(RoleBadge, { role: participant.role })
8468
+ participant.isAgent ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "AI" }) : null,
8469
+ /* @__PURE__ */ jsx4(RoleBadge, { role: participant.role })
6883
8470
  ] }),
6884
- !participant.micEnabled ? /* @__PURE__ */ jsx3(MicOffIcon, { width: 14, height: 14 }) : null,
6885
- /* @__PURE__ */ jsx3(QualityBars, { quality: participant.quality })
8471
+ !participant.micEnabled ? /* @__PURE__ */ jsx4(MicOffIcon, { width: 14, height: 14 }) : null,
8472
+ /* @__PURE__ */ jsx4(QualityBars, { quality: participant.quality })
6886
8473
  ] }),
6887
- /* @__PURE__ */ jsxs2("div", { className: menu ? "mx-meet__tile-actions mx-meet__tile-actions--open" : "mx-meet__tile-actions", children: [
6888
- /* @__PURE__ */ jsx3(
8474
+ /* @__PURE__ */ jsxs3("div", { className: menu ? "mx-meet__tile-actions mx-meet__tile-actions--open" : "mx-meet__tile-actions", children: [
8475
+ /* @__PURE__ */ jsx4(
6889
8476
  ControlButton,
6890
8477
  {
6891
8478
  label: pinnedHere ? "Unpin" : `Pin ${participant.displayName} for me`,
6892
8479
  active: pinnedHere,
6893
8480
  onClick: () => host?.engine.pin(pinnedHere ? null : participant.identity),
6894
- children: /* @__PURE__ */ jsx3(PinIcon, { width: 16, height: 16 })
8481
+ children: /* @__PURE__ */ jsx4(PinIcon, { width: 16, height: 16 })
6895
8482
  }
6896
8483
  ),
6897
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__anchor", children: [
6898
- /* @__PURE__ */ jsx3(
8484
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
8485
+ /* @__PURE__ */ jsx4(
6899
8486
  ControlButton,
6900
8487
  {
6901
8488
  label: `More for ${participant.displayName}`,
6902
8489
  active: menu,
6903
8490
  onClick: () => setMenu(!menu),
6904
- children: /* @__PURE__ */ jsx3(MoreIcon, { width: 16, height: 16 })
8491
+ children: /* @__PURE__ */ jsx4(MoreIcon, { width: 16, height: 16 })
6905
8492
  }
6906
8493
  ),
6907
- menu ? /* @__PURE__ */ jsx3(PersonMenu, { participant, onClose: () => setMenu(false), placement: "down" }) : null
8494
+ menu ? /* @__PURE__ */ jsx4(PersonMenu, { participant, onClose: () => setMenu(false), placement: "down" }) : null
6908
8495
  ] })
6909
8496
  ] })
6910
8497
  ]
@@ -6920,28 +8507,28 @@ function QualityBars({ quality }) {
6920
8507
  if (quality === "unknown") return null;
6921
8508
  const bars = quality === "excellent" ? 3 : quality === "good" ? 2 : quality === "poor" ? 1 : 0;
6922
8509
  const label = quality === "lost" ? "Connection lost" : quality === "poor" ? "Poor connection" : `Connection ${quality}`;
6923
- return /* @__PURE__ */ jsx3("span", { className: `mx-meet__signal mx-meet__signal--${quality}`, title: label, "aria-label": label, role: "img", children: /* @__PURE__ */ jsx3(SignalIcon, { bars, width: 14, height: 14 }) });
8510
+ return /* @__PURE__ */ jsx4("span", { className: `mx-meet__signal mx-meet__signal--${quality}`, title: label, "aria-label": label, role: "img", children: /* @__PURE__ */ jsx4(SignalIcon, { bars, width: 14, height: 14 }) });
6924
8511
  }
6925
8512
  function Stage({ pageSize }) {
6926
8513
  const stage = useStage(pageSize);
6927
8514
  const columns = gridColumns(stage.tiles.length);
6928
8515
  if (stage.feature === null && stage.tiles.length === 0) {
6929
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__stage mx-meet__stage--empty", children: [
6930
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-title", children: "Waiting for others to join" }),
6931
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-body", children: "Share the meeting link and people can join from anywhere \u2014 no account needed." })
8516
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__stage mx-meet__stage--empty", children: [
8517
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-title", children: "Waiting for others to join" }),
8518
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-body", children: "Share the meeting link and people can join from anywhere \u2014 no account needed." })
6932
8519
  ] });
6933
8520
  }
6934
- return /* @__PURE__ */ jsxs2("div", { className: `mx-meet__stage${stage.feature !== null ? " mx-meet__stage--speaker" : ""}`, children: [
6935
- stage.feature !== null ? /* @__PURE__ */ jsx3(ParticipantTile, { participant: stage.feature, featured: true }) : null,
6936
- /* @__PURE__ */ jsx3(
8521
+ return /* @__PURE__ */ jsxs3("div", { className: `mx-meet__stage${stage.feature !== null ? " mx-meet__stage--speaker" : ""}`, children: [
8522
+ stage.feature !== null ? /* @__PURE__ */ jsx4(ParticipantTile, { participant: stage.feature, featured: true }) : null,
8523
+ /* @__PURE__ */ jsx4(
6937
8524
  "div",
6938
8525
  {
6939
8526
  className: "mx-meet__grid",
6940
8527
  style: { "--mx-meet-columns": columns },
6941
- children: stage.tiles.map((participant) => /* @__PURE__ */ jsx3(ParticipantTile, { participant }, participant.identity))
8528
+ children: stage.tiles.map((participant) => /* @__PURE__ */ jsx4(ParticipantTile, { participant }, participant.identity))
6942
8529
  }
6943
8530
  ),
6944
- stage.overflow > 0 ? /* @__PURE__ */ jsxs2("p", { className: "mx-meet__overflow", children: [
8531
+ stage.overflow > 0 ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__overflow", children: [
6945
8532
  "+",
6946
8533
  stage.overflow,
6947
8534
  " more ",
@@ -6954,20 +8541,28 @@ var MEET_REACTIONS = ["\u{1F496}", "\u{1F44D}", "\u{1F389}", "\u{1F44F}", "\u{1F
6954
8541
  function ControlBar({ onLeave }) {
6955
8542
  const room = useRoom();
6956
8543
  const recording = useRecording();
6957
- const [panel, setPanel] = useState3("none");
6958
- const [chatTo, setChatTo] = useState3(null);
6959
- const [popover, setPopover] = useState3("none");
6960
- const [shortcuts, setShortcuts] = useState3(false);
8544
+ const [panel, setPanel] = useState4("none");
8545
+ const [chatTo, setChatTo] = useState4(null);
8546
+ const [popover, setPopover] = useState4("none");
8547
+ const [shortcuts, setShortcuts] = useState4(false);
6961
8548
  const snapshot = useMeetSnapshot();
6962
8549
  const lobby = useLobby();
6963
8550
  const controls = useHostControls();
6964
8551
  const queue = useHandQueue();
6965
8552
  const micUnavailable = useLocalMedia().microphone.unavailable;
6966
8553
  const unread = useUnreadChat(panel === "chat");
8554
+ const [whiteboard, setWhiteboard] = useState4(false);
6967
8555
  const toggle = (next) => setPanel(panel === next ? "none" : next);
8556
+ const openActivity = (activity) => {
8557
+ if (activity === "whiteboard") setWhiteboard(true);
8558
+ else setPanel(activity);
8559
+ };
8560
+ useCollabPanelRequest((activity) => {
8561
+ if (!controls.isHost) openActivity(activity);
8562
+ });
6968
8563
  const privateChatAt = snapshot?.privateChatRequest?.at ?? null;
6969
8564
  const meetStore = useMeetHost()?.store ?? null;
6970
- useEffect3(() => {
8565
+ useEffect4(() => {
6971
8566
  const request = meetStore?.snapshot().privateChatRequest ?? null;
6972
8567
  if (request === null) return;
6973
8568
  setChatTo(request.to);
@@ -6983,11 +8578,11 @@ function ControlBar({ onLeave }) {
6983
8578
  help: () => setShortcuts(true)
6984
8579
  });
6985
8580
  const hasSpotlight = snapshot?.spotlight !== null && snapshot?.spotlight !== void 0;
6986
- return /* @__PURE__ */ jsxs2(Fragment, { children: [
6987
- /* @__PURE__ */ jsx3(MeetingOverlays, {}),
6988
- shortcuts ? /* @__PURE__ */ jsx3(ShortcutsSheet, { onClose: () => setShortcuts(false) }) : null,
6989
- panel === "chat" ? /* @__PURE__ */ jsx3(ChatPanel, { onClose: () => setPanel("none"), to: chatTo, onTo: setChatTo }) : null,
6990
- panel === "people" ? /* @__PURE__ */ jsx3(
8581
+ return /* @__PURE__ */ jsxs3(Fragment, { children: [
8582
+ /* @__PURE__ */ jsx4(MeetingOverlays, {}),
8583
+ shortcuts ? /* @__PURE__ */ jsx4(ShortcutsSheet, { onClose: () => setShortcuts(false) }) : null,
8584
+ panel === "chat" ? /* @__PURE__ */ jsx4(ChatPanel, { onClose: () => setPanel("none"), to: chatTo, onTo: setChatTo }) : null,
8585
+ panel === "people" ? /* @__PURE__ */ jsx4(
6991
8586
  PeoplePanel,
6992
8587
  {
6993
8588
  onClose: () => setPanel("none"),
@@ -6997,48 +8592,53 @@ function ControlBar({ onLeave }) {
6997
8592
  }
6998
8593
  }
6999
8594
  ) : null,
7000
- panel === "ai" ? /* @__PURE__ */ jsx3(AiPanel, { onClose: () => setPanel("none") }) : null,
7001
- panel === "settings" ? /* @__PURE__ */ jsx3(SettingsPanel, { onClose: () => setPanel("none") }) : null,
7002
- controls.notice !== null && panel !== "people" ? /* @__PURE__ */ jsx3(Toast, { text: controls.notice.text, failed: controls.notice.failed, onDone: controls.clearNotice }) : null,
7003
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__controls", children: [
7004
- /* @__PURE__ */ jsx3(
8595
+ panel === "ai" ? /* @__PURE__ */ jsx4(AiPanel, { onClose: () => setPanel("none") }) : null,
8596
+ panel === "settings" ? /* @__PURE__ */ jsx4(SettingsPanel, { onClose: () => setPanel("none") }) : null,
8597
+ panel === "polls" ? /* @__PURE__ */ jsx4(PollsPanel, { onClose: () => setPanel("none") }) : null,
8598
+ panel === "qa" ? /* @__PURE__ */ jsx4(QaPanel, { onClose: () => setPanel("none") }) : null,
8599
+ panel === "breakouts" ? /* @__PURE__ */ jsx4(BreakoutsPanel, { onClose: () => setPanel("none") }) : null,
8600
+ whiteboard ? /* @__PURE__ */ jsx4(WhiteboardPanel, { onClose: () => setWhiteboard(false) }) : null,
8601
+ /* @__PURE__ */ jsx4(BreakoutBanner, {}),
8602
+ controls.notice !== null && panel !== "people" ? /* @__PURE__ */ jsx4(Toast, { text: controls.notice.text, failed: controls.notice.failed, onDone: controls.clearNotice }) : null,
8603
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__controls", children: [
8604
+ /* @__PURE__ */ jsx4(
7005
8605
  ControlButton,
7006
8606
  {
7007
8607
  label: micUnavailable !== null ? `Unmute \u2014 ${micUnavailable.remedy}` : room.local?.micEnabled === true ? "Mute (\u2318D)" : "Unmute (\u2318D)",
7008
8608
  active: room.local?.micEnabled === true,
7009
8609
  onClick: () => void room.toggleMicrophone(),
7010
- children: room.local?.micEnabled === true ? /* @__PURE__ */ jsx3(MicIcon, {}) : /* @__PURE__ */ jsx3(MicOffIcon, {})
8610
+ children: room.local?.micEnabled === true ? /* @__PURE__ */ jsx4(MicIcon, {}) : /* @__PURE__ */ jsx4(MicOffIcon, {})
7011
8611
  }
7012
8612
  ),
7013
- /* @__PURE__ */ jsx3(
8613
+ /* @__PURE__ */ jsx4(
7014
8614
  ControlButton,
7015
8615
  {
7016
8616
  label: room.local?.cameraEnabled === true ? "Stop video (\u2318E)" : "Start video (\u2318E)",
7017
8617
  active: room.local?.cameraEnabled === true,
7018
8618
  onClick: () => void room.toggleCamera(),
7019
- children: room.local?.cameraEnabled === true ? /* @__PURE__ */ jsx3(CameraIcon, {}) : /* @__PURE__ */ jsx3(CameraOffIcon, {})
8619
+ children: room.local?.cameraEnabled === true ? /* @__PURE__ */ jsx4(CameraIcon, {}) : /* @__PURE__ */ jsx4(CameraOffIcon, {})
7020
8620
  }
7021
8621
  ),
7022
- /* @__PURE__ */ jsx3(
8622
+ /* @__PURE__ */ jsx4(
7023
8623
  ControlButton,
7024
8624
  {
7025
8625
  label: room.local?.screenSharing === true ? "Stop sharing" : "Share screen",
7026
8626
  active: room.local?.screenSharing === true,
7027
8627
  onClick: () => void room.toggleScreenShare(),
7028
- children: /* @__PURE__ */ jsx3(ScreenShareIcon, {})
8628
+ children: /* @__PURE__ */ jsx4(ScreenShareIcon, {})
7029
8629
  }
7030
8630
  ),
7031
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__anchor", children: [
7032
- /* @__PURE__ */ jsx3(
8631
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
8632
+ /* @__PURE__ */ jsx4(
7033
8633
  ControlButton,
7034
8634
  {
7035
8635
  label: "Send a reaction",
7036
8636
  active: popover === "reactions",
7037
8637
  onClick: () => setPopover(popover === "reactions" ? "none" : "reactions"),
7038
- children: /* @__PURE__ */ jsx3(SmileIcon, {})
8638
+ children: /* @__PURE__ */ jsx4(SmileIcon, {})
7039
8639
  }
7040
8640
  ),
7041
- popover === "reactions" ? /* @__PURE__ */ jsx3(Popover, { label: "Reactions", onClose: () => setPopover("none"), children: /* @__PURE__ */ jsx3("div", { className: "mx-meet__emoji-bar", children: MEET_REACTIONS.map((emoji) => /* @__PURE__ */ jsx3(
8641
+ popover === "reactions" ? /* @__PURE__ */ jsx4(Popover, { label: "Reactions", onClose: () => setPopover("none"), children: /* @__PURE__ */ jsx4("div", { className: "mx-meet__emoji-bar", children: MEET_REACTIONS.map((emoji) => /* @__PURE__ */ jsx4(
7042
8642
  "button",
7043
8643
  {
7044
8644
  type: "button",
@@ -7050,46 +8650,53 @@ function ControlBar({ onLeave }) {
7050
8650
  emoji
7051
8651
  )) }) }) : null
7052
8652
  ] }),
7053
- /* @__PURE__ */ jsx3(
8653
+ /* @__PURE__ */ jsx4(
7054
8654
  ControlButton,
7055
8655
  {
7056
8656
  label: room.local?.handRaised === true ? "Lower hand (\u2318\u2325H)" : "Raise hand (\u2318\u2325H)",
7057
8657
  active: room.local?.handRaised === true,
7058
8658
  onClick: () => void room.toggleHand(),
7059
- children: /* @__PURE__ */ jsx3(HandIcon, {})
8659
+ children: /* @__PURE__ */ jsx4(HandIcon, {})
7060
8660
  }
7061
8661
  ),
7062
- /* @__PURE__ */ jsxs2(ControlButton, { label: "Chat (\u2318\u2325C)", active: panel === "chat", onClick: () => toggle("chat"), children: [
7063
- /* @__PURE__ */ jsx3(ChatIcon, {}),
7064
- unread > 0 ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
8662
+ /* @__PURE__ */ jsxs3(ControlButton, { label: "Chat (\u2318\u2325C)", active: panel === "chat", onClick: () => toggle("chat"), children: [
8663
+ /* @__PURE__ */ jsx4(ChatIcon, {}),
8664
+ unread > 0 ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
7065
8665
  ] }),
7066
- /* @__PURE__ */ jsxs2(
8666
+ /* @__PURE__ */ jsxs3(
7067
8667
  ControlButton,
7068
8668
  {
7069
8669
  label: lobby.waiting.length > 0 ? `People \u2014 ${lobby.waiting.length} waiting` : `People \u2014 ${(snapshot?.participants ?? []).length} in the meeting`,
7070
8670
  active: panel === "people",
7071
8671
  onClick: () => toggle("people"),
7072
8672
  children: [
7073
- /* @__PURE__ */ jsx3(PeopleIcon, {}),
7074
- lobby.waiting.length > 0 || controls.isHost && queue.length > 0 ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
8673
+ /* @__PURE__ */ jsx4(PeopleIcon, {}),
8674
+ lobby.waiting.length > 0 || controls.isHost && queue.length > 0 ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
7075
8675
  ]
7076
8676
  }
7077
8677
  ),
7078
- /* @__PURE__ */ jsx3(AiControl, { active: panel === "ai", onToggle: () => toggle("ai") }),
7079
- recording.canStart ? /* @__PURE__ */ jsx3(ControlButton, { label: "Start recording", onClick: () => void recording.start(), children: /* @__PURE__ */ jsx3(RecordIcon, {}) }) : null,
7080
- recording.canStop ? /* @__PURE__ */ jsx3(ControlButton, { label: "Stop recording", active: true, onClick: () => void recording.stop(), children: /* @__PURE__ */ jsx3(RecordIcon, {}) }) : null,
7081
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__anchor", children: [
7082
- /* @__PURE__ */ jsx3(
8678
+ /* @__PURE__ */ jsx4(
8679
+ ActivitiesControl,
8680
+ {
8681
+ active: whiteboard ? "whiteboard" : panel === "polls" || panel === "qa" || panel === "breakouts" ? panel : null,
8682
+ onOpen: openActivity
8683
+ }
8684
+ ),
8685
+ /* @__PURE__ */ jsx4(AiControl, { active: panel === "ai", onToggle: () => toggle("ai") }),
8686
+ recording.canStart ? /* @__PURE__ */ jsx4(ControlButton, { label: "Start recording", onClick: () => void recording.start(), children: /* @__PURE__ */ jsx4(RecordIcon, {}) }) : null,
8687
+ recording.canStop ? /* @__PURE__ */ jsx4(ControlButton, { label: "Stop recording", active: true, onClick: () => void recording.stop(), children: /* @__PURE__ */ jsx4(RecordIcon, {}) }) : null,
8688
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
8689
+ /* @__PURE__ */ jsx4(
7083
8690
  ControlButton,
7084
8691
  {
7085
8692
  label: "More options",
7086
8693
  active: popover === "more" || panel === "settings",
7087
8694
  onClick: () => setPopover(popover === "more" ? "none" : "more"),
7088
- children: /* @__PURE__ */ jsx3(MoreIcon, {})
8695
+ children: /* @__PURE__ */ jsx4(MoreIcon, {})
7089
8696
  }
7090
8697
  ),
7091
- popover === "more" ? /* @__PURE__ */ jsx3(Popover, { label: "More options", onClose: () => setPopover("none"), children: /* @__PURE__ */ jsxs2("div", { className: "mx-meet__menu", role: "menu", children: [
7092
- /* @__PURE__ */ jsxs2(
8698
+ popover === "more" ? /* @__PURE__ */ jsx4(Popover, { label: "More options", onClose: () => setPopover("none"), children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu", role: "menu", children: [
8699
+ /* @__PURE__ */ jsxs3(
7093
8700
  MenuItem,
7094
8701
  {
7095
8702
  onSelect: () => {
@@ -7097,12 +8704,12 @@ function ControlBar({ onLeave }) {
7097
8704
  setPanel("settings");
7098
8705
  },
7099
8706
  children: [
7100
- /* @__PURE__ */ jsx3(SettingsIcon, { width: 16, height: 16 }),
7101
- " Audio, video and effects"
8707
+ /* @__PURE__ */ jsx4(SettingsIcon, { width: 16, height: 16 }),
8708
+ " Settings"
7102
8709
  ]
7103
8710
  }
7104
8711
  ),
7105
- /* @__PURE__ */ jsxs2(
8712
+ /* @__PURE__ */ jsxs3(
7106
8713
  MenuItem,
7107
8714
  {
7108
8715
  onSelect: () => {
@@ -7110,14 +8717,14 @@ function ControlBar({ onLeave }) {
7110
8717
  setShortcuts(true);
7111
8718
  },
7112
8719
  children: [
7113
- /* @__PURE__ */ jsx3(KeyboardIcon, { width: 16, height: 16 }),
8720
+ /* @__PURE__ */ jsx4(KeyboardIcon, { width: 16, height: 16 }),
7114
8721
  " Keyboard shortcuts"
7115
8722
  ]
7116
8723
  }
7117
8724
  ),
7118
- controls.isHost ? /* @__PURE__ */ jsxs2(Fragment, { children: [
7119
- /* @__PURE__ */ jsx3("div", { className: "mx-meet__menu-sep", role: "separator" }),
7120
- /* @__PURE__ */ jsxs2(
8725
+ controls.isHost ? /* @__PURE__ */ jsxs3(Fragment, { children: [
8726
+ /* @__PURE__ */ jsx4("div", { className: "mx-meet__menu-sep", role: "separator" }),
8727
+ /* @__PURE__ */ jsxs3(
7121
8728
  MenuItem,
7122
8729
  {
7123
8730
  onSelect: () => {
@@ -7125,12 +8732,12 @@ function ControlBar({ onLeave }) {
7125
8732
  void controls.run({ action: "mute_all" });
7126
8733
  },
7127
8734
  children: [
7128
- /* @__PURE__ */ jsx3(MicOffIcon, { width: 16, height: 16 }),
8735
+ /* @__PURE__ */ jsx4(MicOffIcon, { width: 16, height: 16 }),
7129
8736
  " Mute everyone"
7130
8737
  ]
7131
8738
  }
7132
8739
  ),
7133
- /* @__PURE__ */ jsxs2(
8740
+ /* @__PURE__ */ jsxs3(
7134
8741
  MenuItem,
7135
8742
  {
7136
8743
  onSelect: () => {
@@ -7138,12 +8745,12 @@ function ControlBar({ onLeave }) {
7138
8745
  void controls.run({ action: "ask_all_unmute" });
7139
8746
  },
7140
8747
  children: [
7141
- /* @__PURE__ */ jsx3(MicIcon, { width: 16, height: 16 }),
8748
+ /* @__PURE__ */ jsx4(MicIcon, { width: 16, height: 16 }),
7142
8749
  " Ask everyone to unmute"
7143
8750
  ]
7144
8751
  }
7145
8752
  ),
7146
- queue.length > 0 ? /* @__PURE__ */ jsxs2(
8753
+ queue.length > 0 ? /* @__PURE__ */ jsxs3(
7147
8754
  MenuItem,
7148
8755
  {
7149
8756
  onSelect: () => {
@@ -7151,14 +8758,14 @@ function ControlBar({ onLeave }) {
7151
8758
  void controls.run({ action: "lower_all_hands" });
7152
8759
  },
7153
8760
  children: [
7154
- /* @__PURE__ */ jsx3(HandIcon, { width: 16, height: 16 }),
8761
+ /* @__PURE__ */ jsx4(HandIcon, { width: 16, height: 16 }),
7155
8762
  " Lower all hands (",
7156
8763
  queue.length,
7157
8764
  ")"
7158
8765
  ]
7159
8766
  }
7160
8767
  ) : null,
7161
- hasSpotlight ? /* @__PURE__ */ jsxs2(
8768
+ hasSpotlight ? /* @__PURE__ */ jsxs3(
7162
8769
  MenuItem,
7163
8770
  {
7164
8771
  onSelect: () => {
@@ -7166,7 +8773,7 @@ function ControlBar({ onLeave }) {
7166
8773
  void controls.run({ action: "spotlight", identity: null });
7167
8774
  },
7168
8775
  children: [
7169
- /* @__PURE__ */ jsx3(SpotlightIcon, { width: 16, height: 16 }),
8776
+ /* @__PURE__ */ jsx4(SpotlightIcon, { width: 16, height: 16 }),
7170
8777
  " Remove spotlight"
7171
8778
  ]
7172
8779
  }
@@ -7174,7 +8781,7 @@ function ControlBar({ onLeave }) {
7174
8781
  ] }) : null
7175
8782
  ] }) }) : null
7176
8783
  ] }),
7177
- /* @__PURE__ */ jsx3(
8784
+ /* @__PURE__ */ jsx4(
7178
8785
  ControlButton,
7179
8786
  {
7180
8787
  label: "Leave",
@@ -7183,7 +8790,7 @@ function ControlBar({ onLeave }) {
7183
8790
  void room.leave();
7184
8791
  onLeave?.();
7185
8792
  },
7186
- children: /* @__PURE__ */ jsx3(PhoneOffIcon, {})
8793
+ children: /* @__PURE__ */ jsx4(PhoneOffIcon, {})
7187
8794
  }
7188
8795
  )
7189
8796
  ] })
@@ -7193,13 +8800,13 @@ function useUnreadChat(open) {
7193
8800
  const snapshot = useMeetSnapshot();
7194
8801
  const chat = snapshot?.chat ?? [];
7195
8802
  const local = snapshot?.localIdentity ?? null;
7196
- const [seen, setSeen] = useState3(0);
7197
- useEffect3(() => {
8803
+ const [seen, setSeen] = useState4(0);
8804
+ useEffect4(() => {
7198
8805
  if (open) setSeen(chat.length);
7199
8806
  }, [open, chat.length]);
7200
8807
  const loaded = snapshot?.chatLoaded === true;
7201
- const [baseline, setBaseline] = useState3(null);
7202
- useEffect3(() => {
8808
+ const [baseline, setBaseline] = useState4(null);
8809
+ useEffect4(() => {
7203
8810
  if (loaded && baseline === null) setBaseline(chat.length);
7204
8811
  }, [loaded, baseline, chat.length]);
7205
8812
  if (open) return 0;
@@ -7212,8 +8819,8 @@ function Popover({
7212
8819
  children,
7213
8820
  placement = "up"
7214
8821
  }) {
7215
- const ref = useRef3(null);
7216
- const [style, setStyle] = useState3({
8822
+ const ref = useRef4(null);
8823
+ const [style, setStyle] = useState4({
7217
8824
  position: "fixed",
7218
8825
  top: 0,
7219
8826
  left: 0,
@@ -7264,7 +8871,7 @@ function Popover({
7264
8871
  window.removeEventListener("scroll", place, true);
7265
8872
  };
7266
8873
  }, [placement]);
7267
- useEffect3(() => {
8874
+ useEffect4(() => {
7268
8875
  const onKey = (event) => {
7269
8876
  if (event.key === "Escape") onClose();
7270
8877
  };
@@ -7279,14 +8886,14 @@ function Popover({
7279
8886
  window.removeEventListener("pointerdown", onPointer);
7280
8887
  };
7281
8888
  }, [onClose]);
7282
- return /* @__PURE__ */ jsx3("div", { ref, className: "mx-meet__popover", style, role: "dialog", "aria-label": label, children });
8889
+ return /* @__PURE__ */ jsx4("div", { ref, className: "mx-meet__popover", style, role: "dialog", "aria-label": label, children });
7283
8890
  }
7284
8891
  function MenuItem({
7285
8892
  onSelect,
7286
8893
  danger = false,
7287
8894
  children
7288
8895
  }) {
7289
- return /* @__PURE__ */ jsx3(
8896
+ return /* @__PURE__ */ jsx4(
7290
8897
  "button",
7291
8898
  {
7292
8899
  type: "button",
@@ -7298,28 +8905,28 @@ function MenuItem({
7298
8905
  );
7299
8906
  }
7300
8907
  function Toast({ text: text3, failed, onDone }) {
7301
- useEffect3(() => {
8908
+ useEffect4(() => {
7302
8909
  const timer = setTimeout(onDone, failed ? 7e3 : 4e3);
7303
8910
  return () => clearTimeout(timer);
7304
8911
  }, [text3, failed, onDone]);
7305
- return /* @__PURE__ */ jsxs2("div", { className: failed ? "mx-meet__toast mx-meet__toast--failed" : "mx-meet__toast", role: "status", children: [
7306
- /* @__PURE__ */ jsx3("span", { children: text3 }),
7307
- /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: onDone, children: /* @__PURE__ */ jsx3(CloseIcon, { width: 14, height: 14 }) })
8912
+ return /* @__PURE__ */ jsxs3("div", { className: failed ? "mx-meet__toast mx-meet__toast--failed" : "mx-meet__toast", role: "status", children: [
8913
+ /* @__PURE__ */ jsx4("span", { children: text3 }),
8914
+ /* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: onDone, children: /* @__PURE__ */ jsx4(CloseIcon, { width: 14, height: 14 }) })
7308
8915
  ] });
7309
8916
  }
7310
8917
  function MeetingOverlays() {
7311
8918
  const reactions = useReactions();
7312
8919
  const { notice, dismiss } = useModerationNotice();
7313
8920
  const room = useRoom();
7314
- return /* @__PURE__ */ jsxs2(Fragment, { children: [
7315
- /* @__PURE__ */ jsx3(ReactionOverlay, { reactions }),
8921
+ return /* @__PURE__ */ jsxs3(Fragment, { children: [
8922
+ /* @__PURE__ */ jsx4(ReactionOverlay, { reactions }),
7316
8923
  notice !== null && notice.kind !== "removed" ? (
7317
8924
  // A host's request ("the host is asking you to unmute"), not an error:
7318
8925
  // an assertive status, so it is announced at once without being filed
7319
8926
  // as a failure (design-system error-box census).
7320
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__notice-bar", role: "status", "aria-live": "assertive", children: [
7321
- /* @__PURE__ */ jsx3("span", { children: notice.text }),
7322
- notice.kind === "ask-unmute" && room.local?.micEnabled !== true ? /* @__PURE__ */ jsx3(
8927
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__notice-bar", role: "status", "aria-live": "assertive", children: [
8928
+ /* @__PURE__ */ jsx4("span", { children: notice.text }),
8929
+ notice.kind === "ask-unmute" && room.local?.micEnabled !== true ? /* @__PURE__ */ jsx4(
7323
8930
  "button",
7324
8931
  {
7325
8932
  type: "button",
@@ -7331,20 +8938,20 @@ function MeetingOverlays() {
7331
8938
  children: "Unmute"
7332
8939
  }
7333
8940
  ) : null,
7334
- /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: dismiss, children: /* @__PURE__ */ jsx3(CloseIcon, { width: 14, height: 14 }) })
8941
+ /* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: dismiss, children: /* @__PURE__ */ jsx4(CloseIcon, { width: 14, height: 14 }) })
7335
8942
  ] })
7336
8943
  ) : null
7337
8944
  ] });
7338
8945
  }
7339
8946
  function ShortcutsSheet({ onClose }) {
7340
- useEffect3(() => {
8947
+ useEffect4(() => {
7341
8948
  const onKey = (event) => {
7342
8949
  if (event.key === "Escape") onClose();
7343
8950
  };
7344
8951
  window.addEventListener("keydown", onKey);
7345
8952
  return () => window.removeEventListener("keydown", onKey);
7346
8953
  }, [onClose]);
7347
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet__sheet-backdrop", onClick: onClose, children: /* @__PURE__ */ jsxs2(
8954
+ return /* @__PURE__ */ jsx4("div", { className: "mx-meet__sheet-backdrop", onClick: onClose, children: /* @__PURE__ */ jsxs3(
7348
8955
  "div",
7349
8956
  {
7350
8957
  className: "mx-meet__sheet",
@@ -7352,13 +8959,13 @@ function ShortcutsSheet({ onClose }) {
7352
8959
  "aria-label": "Keyboard shortcuts",
7353
8960
  onClick: (event) => event.stopPropagation(),
7354
8961
  children: [
7355
- /* @__PURE__ */ jsxs2("header", { className: "mx-meet__panel-head", children: [
7356
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__panel-title", children: "Keyboard shortcuts" }),
7357
- /* @__PURE__ */ jsx3(ControlButton, { label: "Close", onClick: onClose, children: /* @__PURE__ */ jsx3(CloseIcon, { width: 16, height: 16 }) })
8962
+ /* @__PURE__ */ jsxs3("header", { className: "mx-meet__panel-head", children: [
8963
+ /* @__PURE__ */ jsx4("h2", { className: "mx-meet__panel-title", children: "Keyboard shortcuts" }),
8964
+ /* @__PURE__ */ jsx4(ControlButton, { label: "Close", onClick: onClose, children: /* @__PURE__ */ jsx4(CloseIcon, { width: 16, height: 16 }) })
7358
8965
  ] }),
7359
- /* @__PURE__ */ jsx3("dl", { className: "mx-meet__shortcuts", children: MEET_SHORTCUTS.map((shortcut) => /* @__PURE__ */ jsxs2("div", { className: "mx-meet__shortcut", children: [
7360
- /* @__PURE__ */ jsx3("dt", { children: shortcut.label }),
7361
- /* @__PURE__ */ jsx3("dd", { children: /* @__PURE__ */ jsx3("kbd", { className: "mx-meet__kbd", children: shortcut.keys }) })
8966
+ /* @__PURE__ */ jsx4("dl", { className: "mx-meet__shortcuts", children: MEET_SHORTCUTS.map((shortcut) => /* @__PURE__ */ jsxs3("div", { className: "mx-meet__shortcut", children: [
8967
+ /* @__PURE__ */ jsx4("dt", { children: shortcut.label }),
8968
+ /* @__PURE__ */ jsx4("dd", { children: /* @__PURE__ */ jsx4("kbd", { className: "mx-meet__kbd", children: shortcut.keys }) })
7362
8969
  ] }, shortcut.id)) })
7363
8970
  ]
7364
8971
  }
@@ -7368,19 +8975,19 @@ function AiControl({ active, onToggle }) {
7368
8975
  const snapshot = useMeetSnapshot();
7369
8976
  const meeting = snapshot?.meeting ?? null;
7370
8977
  if (meeting === null || !meeting.aiEnabled) return null;
7371
- return /* @__PURE__ */ jsx3(ControlButton, { label: "Meeting assistant", active, onClick: onToggle, children: /* @__PURE__ */ jsx3(SparklesIcon, {}) });
8978
+ return /* @__PURE__ */ jsx4(ControlButton, { label: "Meeting assistant", active, onClick: onToggle, children: /* @__PURE__ */ jsx4(SparklesIcon, {}) });
7372
8979
  }
7373
8980
  function PanelShell({
7374
8981
  title,
7375
8982
  onClose,
7376
8983
  children
7377
8984
  }) {
7378
- return /* @__PURE__ */ jsxs2("aside", { className: "mx-meet__panel", "aria-label": title, children: [
7379
- /* @__PURE__ */ jsxs2("header", { className: "mx-meet__panel-head", children: [
7380
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__panel-title", children: title }),
7381
- /* @__PURE__ */ jsx3(ControlButton, { label: "Close panel", onClick: onClose, children: /* @__PURE__ */ jsx3(CloseIcon, { width: 16, height: 16 }) })
8985
+ return /* @__PURE__ */ jsxs3("aside", { className: "mx-meet__panel", "aria-label": title, children: [
8986
+ /* @__PURE__ */ jsxs3("header", { className: "mx-meet__panel-head", children: [
8987
+ /* @__PURE__ */ jsx4("h2", { className: "mx-meet__panel-title", children: title }),
8988
+ /* @__PURE__ */ jsx4(ControlButton, { label: "Close panel", onClick: onClose, children: /* @__PURE__ */ jsx4(CloseIcon, { width: 16, height: 16 }) })
7382
8989
  ] }),
7383
- /* @__PURE__ */ jsx3("div", { className: "mx-meet__panel-body", children })
8990
+ /* @__PURE__ */ jsx4("div", { className: "mx-meet__panel-body", children })
7384
8991
  ] });
7385
8992
  }
7386
8993
  function ChatPanel({
@@ -7390,17 +8997,17 @@ function ChatPanel({
7390
8997
  }) {
7391
8998
  const snapshot = useMeetSnapshot();
7392
8999
  const room = useRoom();
7393
- const [draft, setDraft] = useState3("");
7394
- const [recipient, setRecipient] = useState3(to);
7395
- const listRef = useRef3(null);
9000
+ const [draft, setDraft] = useState4("");
9001
+ const [recipient, setRecipient] = useState4(to);
9002
+ const listRef = useRef4(null);
7396
9003
  const messages = snapshot?.chat ?? [];
7397
9004
  const local = snapshot?.localIdentity ?? null;
7398
9005
  const people = (snapshot?.participants ?? []).filter(
7399
9006
  (participant) => !participant.isLocal && !participant.isAgent
7400
9007
  );
7401
9008
  const recipientName = recipient === null ? null : people.find((p) => p.identity === recipient)?.displayName ?? null;
7402
- useEffect3(() => setRecipient(to), [to]);
7403
- useEffect3(() => {
9009
+ useEffect4(() => setRecipient(to), [to]);
9010
+ useEffect4(() => {
7404
9011
  const list = listRef.current;
7405
9012
  if (list !== null) list.scrollTop = list.scrollHeight;
7406
9013
  }, [messages.length]);
@@ -7408,13 +9015,13 @@ function ChatPanel({
7408
9015
  setRecipient(next);
7409
9016
  onTo?.(next);
7410
9017
  };
7411
- return /* @__PURE__ */ jsxs2(PanelShell, { title: "Chat", onClose, children: [
7412
- /* @__PURE__ */ jsxs2("ul", { className: "mx-meet__chat", ref: listRef, children: [
7413
- snapshot?.chatHistoryError != null ? /* @__PURE__ */ jsx3("li", { className: "mx-meet__panel-note", children: snapshot.chatHistoryError }) : null,
7414
- snapshot?.chatLoaded !== true && messages.length === 0 ? /* @__PURE__ */ jsx3("li", { className: "mx-meet__panel-note", children: "Reading earlier messages\u2026" }) : messages.length === 0 && snapshot?.chatHistoryError == null ? /* @__PURE__ */ jsx3("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,
7415
- messages.map((message) => /* @__PURE__ */ jsx3(ChatLine, { message, local, people }, message.id))
9018
+ return /* @__PURE__ */ jsxs3(PanelShell, { title: "Chat", onClose, children: [
9019
+ /* @__PURE__ */ jsxs3("ul", { className: "mx-meet__chat", ref: listRef, children: [
9020
+ snapshot?.chatHistoryError != null ? /* @__PURE__ */ jsx4("li", { className: "mx-meet__panel-note", children: snapshot.chatHistoryError }) : null,
9021
+ snapshot?.chatLoaded !== true && messages.length === 0 ? /* @__PURE__ */ jsx4("li", { className: "mx-meet__panel-note", children: "Reading earlier messages\u2026" }) : messages.length === 0 && snapshot?.chatHistoryError == null ? /* @__PURE__ */ jsx4("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,
9022
+ messages.map((message) => /* @__PURE__ */ jsx4(ChatLine, { message, local, people }, message.id))
7416
9023
  ] }),
7417
- /* @__PURE__ */ jsxs2(
9024
+ /* @__PURE__ */ jsxs3(
7418
9025
  "form",
7419
9026
  {
7420
9027
  className: "mx-meet__composer mx-meet__composer--chat",
@@ -7427,7 +9034,7 @@ function ChatPanel({
7427
9034
  else void room.sendPrivateChat(recipient, text3);
7428
9035
  },
7429
9036
  children: [
7430
- people.length > 0 ? /* @__PURE__ */ jsxs2(
9037
+ people.length > 0 ? /* @__PURE__ */ jsxs3(
7431
9038
  "select",
7432
9039
  {
7433
9040
  className: "mx-meet__select mx-meet__select--compact",
@@ -7435,16 +9042,16 @@ function ChatPanel({
7435
9042
  value: recipient ?? "",
7436
9043
  onChange: (event) => choose(event.target.value === "" ? null : event.target.value),
7437
9044
  children: [
7438
- /* @__PURE__ */ jsx3("option", { value: "", children: "Everyone" }),
7439
- people.map((participant) => /* @__PURE__ */ jsxs2("option", { value: participant.identity, children: [
9045
+ /* @__PURE__ */ jsx4("option", { value: "", children: "Everyone" }),
9046
+ people.map((participant) => /* @__PURE__ */ jsxs3("option", { value: participant.identity, children: [
7440
9047
  participant.displayName,
7441
9048
  " (private)"
7442
9049
  ] }, participant.identity))
7443
9050
  ]
7444
9051
  }
7445
9052
  ) : null,
7446
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__composer-row", children: [
7447
- /* @__PURE__ */ jsx3(
9053
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__composer-row", children: [
9054
+ /* @__PURE__ */ jsx4(
7448
9055
  "input",
7449
9056
  {
7450
9057
  className: "mx-meet__input",
@@ -7455,9 +9062,9 @@ function ChatPanel({
7455
9062
  maxLength: 4e3
7456
9063
  }
7457
9064
  ),
7458
- /* @__PURE__ */ jsx3("button", { type: "submit", className: "mx-meet__send", disabled: draft.trim().length === 0, children: "Send" })
9065
+ /* @__PURE__ */ jsx4("button", { type: "submit", className: "mx-meet__send", disabled: draft.trim().length === 0, children: "Send" })
7459
9066
  ] }),
7460
- recipientName !== null ? /* @__PURE__ */ jsxs2("p", { className: "mx-meet__panel-note", children: [
9067
+ recipientName !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
7461
9068
  "Only ",
7462
9069
  recipientName,
7463
9070
  " sees this. Private messages are not saved."
@@ -7475,7 +9082,7 @@ function ChatLine({
7475
9082
  const mine = message.identity === local;
7476
9083
  const privateTo = message.to ?? null;
7477
9084
  const counterpart = privateTo === null ? null : mine ? people.find((p) => p.identity === privateTo)?.displayName ?? "them" : "you";
7478
- return /* @__PURE__ */ jsxs2(
9085
+ return /* @__PURE__ */ jsxs3(
7479
9086
  "li",
7480
9087
  {
7481
9088
  className: [
@@ -7484,17 +9091,17 @@ function ChatLine({
7484
9091
  message.failed !== void 0 ? "mx-meet__chat-line--failed" : ""
7485
9092
  ].filter(Boolean).join(" "),
7486
9093
  children: [
7487
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__chat-meta", children: [
7488
- /* @__PURE__ */ jsx3("strong", { children: mine ? "You" : message.displayName }),
7489
- counterpart !== null ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__chat-private", children: [
9094
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__chat-meta", children: [
9095
+ /* @__PURE__ */ jsx4("strong", { children: mine ? "You" : message.displayName }),
9096
+ counterpart !== null ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__chat-private", children: [
7490
9097
  "to ",
7491
9098
  counterpart,
7492
9099
  " \xB7 private"
7493
9100
  ] }) : null,
7494
- /* @__PURE__ */ jsx3("time", { dateTime: message.at, children: clockOf(message.at) })
9101
+ /* @__PURE__ */ jsx4("time", { dateTime: message.at, children: clockOf(message.at) })
7495
9102
  ] }),
7496
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__chat-text", children: message.text }),
7497
- message.failed !== void 0 ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__chat-failed", children: message.failed }) : privateTo === null && message.saved === false ? /* @__PURE__ */ jsx3("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
9103
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__chat-text", children: message.text }),
9104
+ message.failed !== void 0 ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__chat-failed", children: message.failed }) : privateTo === null && message.saved === false ? /* @__PURE__ */ jsx4("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
7498
9105
  ]
7499
9106
  }
7500
9107
  );
@@ -7506,22 +9113,22 @@ function PeoplePanel({
7506
9113
  const snapshot = useMeetSnapshot();
7507
9114
  const controls = useHostControls();
7508
9115
  const queue = useHandQueue();
7509
- const [query, setQuery] = useState3("");
7510
- const [menuFor, setMenuFor] = useState3(null);
9116
+ const [query, setQuery] = useState4("");
9117
+ const [menuFor, setMenuFor] = useState4(null);
7511
9118
  const myRole = useRole();
7512
9119
  const local = snapshot?.localIdentity ?? null;
7513
9120
  const everyone = snapshot?.participants ?? [];
7514
9121
  const needle = query.trim().toLowerCase();
7515
9122
  const shown = needle.length === 0 ? everyone : everyone.filter((participant) => participant.displayName.toLowerCase().includes(needle));
7516
- return /* @__PURE__ */ jsxs2(PanelShell, { title: `People (${everyone.length})`, onClose, children: [
7517
- /* @__PURE__ */ jsx3(LobbyPanel, {}),
7518
- queue.length > 0 ? /* @__PURE__ */ jsxs2("section", { className: "mx-meet__section", "aria-label": "Raised hands", children: [
7519
- /* @__PURE__ */ jsxs2("header", { className: "mx-meet__section-head", children: [
7520
- /* @__PURE__ */ jsxs2("h3", { className: "mx-meet__section-title", children: [
9123
+ return /* @__PURE__ */ jsxs3(PanelShell, { title: `People (${everyone.length})`, onClose, children: [
9124
+ /* @__PURE__ */ jsx4(LobbyPanel, {}),
9125
+ queue.length > 0 ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__section", "aria-label": "Raised hands", children: [
9126
+ /* @__PURE__ */ jsxs3("header", { className: "mx-meet__section-head", children: [
9127
+ /* @__PURE__ */ jsxs3("h3", { className: "mx-meet__section-title", children: [
7521
9128
  "Raised hands \xB7 ",
7522
9129
  queue.length
7523
9130
  ] }),
7524
- controls.isHost ? /* @__PURE__ */ jsx3(
9131
+ controls.isHost ? /* @__PURE__ */ jsx4(
7525
9132
  "button",
7526
9133
  {
7527
9134
  type: "button",
@@ -7531,13 +9138,13 @@ function PeoplePanel({
7531
9138
  }
7532
9139
  ) : null
7533
9140
  ] }),
7534
- /* @__PURE__ */ jsx3("ol", { className: "mx-meet__queue", children: queue.map((participant) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__person", children: [
7535
- /* @__PURE__ */ jsx3(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 28 }),
7536
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__person-name", children: [
9141
+ /* @__PURE__ */ jsx4("ol", { className: "mx-meet__queue", children: queue.map((participant) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__person", children: [
9142
+ /* @__PURE__ */ jsx4(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 28 }),
9143
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
7537
9144
  participant.displayName,
7538
- participant.identity === local ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__you", children: " (you)" }) : null
9145
+ participant.identity === local ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__you", children: " (you)" }) : null
7539
9146
  ] }),
7540
- controls.isHost || participant.identity === local ? /* @__PURE__ */ jsx3(
9147
+ controls.isHost || participant.identity === local ? /* @__PURE__ */ jsx4(
7541
9148
  "button",
7542
9149
  {
7543
9150
  type: "button",
@@ -7548,27 +9155,27 @@ function PeoplePanel({
7548
9155
  ) : null
7549
9156
  ] }, participant.identity)) })
7550
9157
  ] }) : null,
7551
- controls.isHost && everyone.length > 1 ? /* @__PURE__ */ jsxs2("div", { className: "mx-meet__bulk", children: [
7552
- /* @__PURE__ */ jsxs2("button", { type: "button", className: "mx-meet__chip", onClick: () => void controls.run({ action: "mute_all" }), children: [
7553
- /* @__PURE__ */ jsx3(MicOffIcon, { width: 14, height: 14 }),
9158
+ controls.isHost && everyone.length > 1 ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__bulk", children: [
9159
+ /* @__PURE__ */ jsxs3("button", { type: "button", className: "mx-meet__chip", onClick: () => void controls.run({ action: "mute_all" }), children: [
9160
+ /* @__PURE__ */ jsx4(MicOffIcon, { width: 14, height: 14 }),
7554
9161
  " Mute all"
7555
9162
  ] }),
7556
- /* @__PURE__ */ jsxs2(
9163
+ /* @__PURE__ */ jsxs3(
7557
9164
  "button",
7558
9165
  {
7559
9166
  type: "button",
7560
9167
  className: "mx-meet__chip",
7561
9168
  onClick: () => void controls.run({ action: "ask_all_unmute" }),
7562
9169
  children: [
7563
- /* @__PURE__ */ jsx3(MicIcon, { width: 14, height: 14 }),
9170
+ /* @__PURE__ */ jsx4(MicIcon, { width: 14, height: 14 }),
7564
9171
  " Ask all to unmute"
7565
9172
  ]
7566
9173
  }
7567
9174
  )
7568
9175
  ] }) : null,
7569
- everyone.length > 4 ? /* @__PURE__ */ jsxs2("label", { className: "mx-meet__search", children: [
7570
- /* @__PURE__ */ jsx3(SearchIcon, { width: 16, height: 16 }),
7571
- /* @__PURE__ */ jsx3(
9176
+ everyone.length > 4 ? /* @__PURE__ */ jsxs3("label", { className: "mx-meet__search", children: [
9177
+ /* @__PURE__ */ jsx4(SearchIcon, { width: 16, height: 16 }),
9178
+ /* @__PURE__ */ jsx4(
7572
9179
  "input",
7573
9180
  {
7574
9181
  className: "mx-meet__input mx-meet__input--bare",
@@ -7579,31 +9186,31 @@ function PeoplePanel({
7579
9186
  }
7580
9187
  )
7581
9188
  ] }) : null,
7582
- controls.notice !== null ? /* @__PURE__ */ jsx3("p", { className: controls.notice.failed ? "mx-meet__error" : "mx-meet__notice", role: "status", children: controls.notice.text }) : null,
7583
- /* @__PURE__ */ jsxs2("ul", { className: "mx-meet__people", children: [
7584
- shown.map((participant) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__person", children: [
7585
- /* @__PURE__ */ jsx3(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 32 }),
7586
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__person-name", children: [
9189
+ controls.notice !== null ? /* @__PURE__ */ jsx4("p", { className: controls.notice.failed ? "mx-meet__error" : "mx-meet__notice", role: "status", children: controls.notice.text }) : null,
9190
+ /* @__PURE__ */ jsxs3("ul", { className: "mx-meet__people", children: [
9191
+ shown.map((participant) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__person", children: [
9192
+ /* @__PURE__ */ jsx4(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 32 }),
9193
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
7587
9194
  participant.displayName,
7588
- participant.identity === local ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__you", children: " (you)" }) : null,
7589
- /* @__PURE__ */ jsx3(RoleBadge, { role: participant.identity === local ? myRole : participant.role }),
7590
- isNoteTaker(participant) ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null,
7591
- snapshot?.spotlight === participant.identity ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Spotlight" }) : null
9195
+ participant.identity === local ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__you", children: " (you)" }) : null,
9196
+ /* @__PURE__ */ jsx4(RoleBadge, { role: participant.identity === local ? myRole : participant.role }),
9197
+ isNoteTaker(participant) ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null,
9198
+ snapshot?.spotlight === participant.identity ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Spotlight" }) : null
7592
9199
  ] }),
7593
- participant.handRaised ? /* @__PURE__ */ jsx3(HandIcon, { width: 14, height: 14 }) : null,
7594
- !participant.micEnabled && !isNoteTaker(participant) ? /* @__PURE__ */ jsx3(MicOffIcon, { width: 14, height: 14 }) : null,
7595
- /* @__PURE__ */ jsx3(QualityBars, { quality: participant.quality }),
7596
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__anchor", children: [
7597
- /* @__PURE__ */ jsx3(
9200
+ participant.handRaised ? /* @__PURE__ */ jsx4(HandIcon, { width: 14, height: 14 }) : null,
9201
+ !participant.micEnabled && !isNoteTaker(participant) ? /* @__PURE__ */ jsx4(MicOffIcon, { width: 14, height: 14 }) : null,
9202
+ /* @__PURE__ */ jsx4(QualityBars, { quality: participant.quality }),
9203
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
9204
+ /* @__PURE__ */ jsx4(
7598
9205
  ControlButton,
7599
9206
  {
7600
9207
  label: `More for ${participant.displayName}`,
7601
9208
  active: menuFor === participant.identity,
7602
9209
  onClick: () => setMenuFor(menuFor === participant.identity ? null : participant.identity),
7603
- children: /* @__PURE__ */ jsx3(MoreIcon, { width: 16, height: 16 })
9210
+ children: /* @__PURE__ */ jsx4(MoreIcon, { width: 16, height: 16 })
7604
9211
  }
7605
9212
  ),
7606
- menuFor === participant.identity ? /* @__PURE__ */ jsx3(
9213
+ menuFor === participant.identity ? /* @__PURE__ */ jsx4(
7607
9214
  PersonMenu,
7608
9215
  {
7609
9216
  participant,
@@ -7614,13 +9221,13 @@ function PeoplePanel({
7614
9221
  ) : null
7615
9222
  ] })
7616
9223
  ] }, participant.identity)),
7617
- shown.length === 0 ? /* @__PURE__ */ jsxs2("li", { className: "mx-meet__panel-note", children: [
9224
+ shown.length === 0 ? /* @__PURE__ */ jsxs3("li", { className: "mx-meet__panel-note", children: [
7618
9225
  "Nobody matches \u201C",
7619
9226
  query,
7620
9227
  "\u201D."
7621
9228
  ] }) : null
7622
9229
  ] }),
7623
- snapshot?.meeting !== null && snapshot?.meeting !== void 0 ? /* @__PURE__ */ jsx3(GuestRecordAccessControl, { meeting: snapshot.meeting }) : null
9230
+ snapshot?.meeting !== null && snapshot?.meeting !== void 0 ? /* @__PURE__ */ jsx4(GuestRecordAccessControl, { meeting: snapshot.meeting }) : null
7624
9231
  ] });
7625
9232
  }
7626
9233
  function PersonMenu({
@@ -7632,14 +9239,14 @@ function PersonMenu({
7632
9239
  const host = useMeetHost();
7633
9240
  const snapshot = useMeetSnapshot();
7634
9241
  const controls = useHostControls();
7635
- const [mode, setMode] = useState3("menu");
7636
- const [text3, setText] = useState3("");
9242
+ const [mode, setMode] = useState4("menu");
9243
+ const [text3, setText] = useState4("");
7637
9244
  const self = participant.identity === snapshot?.localIdentity;
7638
9245
  const moderate = controls.canModerate(participant);
7639
9246
  const pinned = snapshot?.pinned === participant.identity;
7640
9247
  const spotlit = snapshot?.spotlight === participant.identity;
7641
9248
  const hasAccount = participant.userId !== null;
7642
- const [refused, setRefused] = useState3(false);
9249
+ const [refused, setRefused] = useState4(false);
7643
9250
  const act = (request) => {
7644
9251
  setRefused(false);
7645
9252
  void controls.run(request).then((result) => {
@@ -7647,10 +9254,10 @@ function PersonMenu({
7647
9254
  else setRefused(true);
7648
9255
  });
7649
9256
  };
7650
- const refusal2 = refused && controls.notice?.failed === true ? /* @__PURE__ */ jsx3(ErrorBox, { as: "p", className: "mx-meet__error", message: controls.notice.text, operation: "Change this participant", origin: "meet/components", children: controls.notice.text }) : null;
9257
+ const refusal2 = refused && controls.notice?.failed === true ? /* @__PURE__ */ jsx4(ErrorBox, { as: "p", className: "mx-meet__error", message: controls.notice.text, operation: "Change this participant", origin: "meet/components", children: controls.notice.text }) : null;
7651
9258
  if (mode === "rename" || mode === "report") {
7652
9259
  const renaming = mode === "rename";
7653
- return /* @__PURE__ */ jsx3(Popover, { label: renaming ? "Rename" : "Report", onClose, placement, children: /* @__PURE__ */ jsxs2(
9260
+ return /* @__PURE__ */ jsx4(Popover, { label: renaming ? "Rename" : "Report", onClose, placement, children: /* @__PURE__ */ jsxs3(
7654
9261
  "form",
7655
9262
  {
7656
9263
  className: "mx-meet__menu-form",
@@ -7662,9 +9269,9 @@ function PersonMenu({
7662
9269
  );
7663
9270
  },
7664
9271
  children: [
7665
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
7666
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: renaming ? "Name shown in this meeting" : `What did ${participant.displayName} do?` }),
7667
- renaming ? /* @__PURE__ */ jsx3(
9272
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
9273
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__field-label", children: renaming ? "Name shown in this meeting" : `What did ${participant.displayName} do?` }),
9274
+ renaming ? /* @__PURE__ */ jsx4(
7668
9275
  "input",
7669
9276
  {
7670
9277
  className: "mx-meet__input",
@@ -7673,7 +9280,7 @@ function PersonMenu({
7673
9280
  value: text3,
7674
9281
  onChange: (event) => setText(event.target.value)
7675
9282
  }
7676
- ) : /* @__PURE__ */ jsx3(
9283
+ ) : /* @__PURE__ */ jsx4(
7677
9284
  "textarea",
7678
9285
  {
7679
9286
  className: "mx-meet__input",
@@ -7686,9 +9293,9 @@ function PersonMenu({
7686
9293
  )
7687
9294
  ] }),
7688
9295
  refusal2,
7689
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__menu-actions", children: [
7690
- /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Back" }),
7691
- /* @__PURE__ */ jsx3("button", { type: "submit", className: "mx-meet__send", disabled: text3.trim().length === 0 || controls.busy, children: renaming ? "Rename" : "Report" })
9296
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu-actions", children: [
9297
+ /* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Back" }),
9298
+ /* @__PURE__ */ jsx4("button", { type: "submit", className: "mx-meet__send", disabled: text3.trim().length === 0 || controls.busy, children: renaming ? "Rename" : "Report" })
7692
9299
  ] })
7693
9300
  ]
7694
9301
  }
@@ -7696,12 +9303,12 @@ function PersonMenu({
7696
9303
  }
7697
9304
  if (mode === "remove" || mode === "transfer") {
7698
9305
  const removing = mode === "remove";
7699
- return /* @__PURE__ */ jsx3(Popover, { label: removing ? "Remove" : "Make host", onClose, placement, children: /* @__PURE__ */ jsxs2("div", { className: "mx-meet__menu-form", children: [
7700
- /* @__PURE__ */ jsx3("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.` }),
9306
+ return /* @__PURE__ */ jsx4(Popover, { label: removing ? "Remove" : "Make host", onClose, placement, children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu-form", children: [
9307
+ /* @__PURE__ */ jsx4("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.` }),
7701
9308
  refusal2,
7702
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__menu-actions", children: [
7703
- /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Cancel" }),
7704
- /* @__PURE__ */ jsx3(
9309
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu-actions", children: [
9310
+ /* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Cancel" }),
9311
+ /* @__PURE__ */ jsx4(
7705
9312
  "button",
7706
9313
  {
7707
9314
  type: "button",
@@ -7714,8 +9321,8 @@ function PersonMenu({
7714
9321
  ] })
7715
9322
  ] }) });
7716
9323
  }
7717
- return /* @__PURE__ */ jsx3(Popover, { label: `Options for ${participant.displayName}`, onClose, placement, children: /* @__PURE__ */ jsxs2("div", { className: "mx-meet__menu", role: "menu", children: [
7718
- /* @__PURE__ */ jsxs2(
9324
+ return /* @__PURE__ */ jsx4(Popover, { label: `Options for ${participant.displayName}`, onClose, placement, children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu", role: "menu", children: [
9325
+ /* @__PURE__ */ jsxs3(
7719
9326
  MenuItem,
7720
9327
  {
7721
9328
  onSelect: () => {
@@ -7723,13 +9330,13 @@ function PersonMenu({
7723
9330
  onClose();
7724
9331
  },
7725
9332
  children: [
7726
- /* @__PURE__ */ jsx3(PinIcon, { width: 16, height: 16 }),
9333
+ /* @__PURE__ */ jsx4(PinIcon, { width: 16, height: 16 }),
7727
9334
  " ",
7728
9335
  pinned ? "Unpin" : "Pin for me"
7729
9336
  ]
7730
9337
  }
7731
9338
  ),
7732
- !self && !participant.isAgent && (onMessage !== void 0 || host !== null) ? /* @__PURE__ */ jsxs2(
9339
+ !self && !participant.isAgent && (onMessage !== void 0 || host !== null) ? /* @__PURE__ */ jsxs3(
7733
9340
  MenuItem,
7734
9341
  {
7735
9342
  onSelect: () => {
@@ -7741,42 +9348,42 @@ function PersonMenu({
7741
9348
  onClose();
7742
9349
  },
7743
9350
  children: [
7744
- /* @__PURE__ */ jsx3(ChatIcon, { width: 16, height: 16 }),
9351
+ /* @__PURE__ */ jsx4(ChatIcon, { width: 16, height: 16 }),
7745
9352
  " Message privately"
7746
9353
  ]
7747
9354
  }
7748
9355
  ) : null,
7749
- controls.isHost ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "spotlight", identity: spotlit ? null : participant.identity }), children: [
7750
- /* @__PURE__ */ jsx3(SpotlightIcon, { width: 16, height: 16 }),
9356
+ controls.isHost ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "spotlight", identity: spotlit ? null : participant.identity }), children: [
9357
+ /* @__PURE__ */ jsx4(SpotlightIcon, { width: 16, height: 16 }),
7751
9358
  " ",
7752
9359
  spotlit ? "Remove spotlight" : "Spotlight for everyone"
7753
9360
  ] }) : null,
7754
- moderate ? /* @__PURE__ */ jsxs2(Fragment, { children: [
7755
- /* @__PURE__ */ jsx3("div", { className: "mx-meet__menu-sep", role: "separator" }),
7756
- participant.micEnabled ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "mute", identity: participant.identity }), children: [
7757
- /* @__PURE__ */ jsx3(MicOffIcon, { width: 16, height: 16 }),
9361
+ moderate ? /* @__PURE__ */ jsxs3(Fragment, { children: [
9362
+ /* @__PURE__ */ jsx4("div", { className: "mx-meet__menu-sep", role: "separator" }),
9363
+ participant.micEnabled ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "mute", identity: participant.identity }), children: [
9364
+ /* @__PURE__ */ jsx4(MicOffIcon, { width: 16, height: 16 }),
7758
9365
  " Mute"
7759
- ] }) : !participant.isAgent ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "ask_unmute", identity: participant.identity }), children: [
7760
- /* @__PURE__ */ jsx3(MicIcon, { width: 16, height: 16 }),
9366
+ ] }) : !participant.isAgent ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "ask_unmute", identity: participant.identity }), children: [
9367
+ /* @__PURE__ */ jsx4(MicIcon, { width: 16, height: 16 }),
7761
9368
  " Ask to unmute"
7762
9369
  ] }) : null,
7763
- participant.cameraEnabled ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "stop_video", identity: participant.identity }), children: [
7764
- /* @__PURE__ */ jsx3(CameraOffIcon, { width: 16, height: 16 }),
9370
+ participant.cameraEnabled ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "stop_video", identity: participant.identity }), children: [
9371
+ /* @__PURE__ */ jsx4(CameraOffIcon, { width: 16, height: 16 }),
7765
9372
  " Stop video"
7766
9373
  ] }) : null,
7767
- participant.screenSharing ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "stop_screen", identity: participant.identity }), children: [
7768
- /* @__PURE__ */ jsx3(ScreenShareIcon, { width: 16, height: 16 }),
9374
+ participant.screenSharing ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "stop_screen", identity: participant.identity }), children: [
9375
+ /* @__PURE__ */ jsx4(ScreenShareIcon, { width: 16, height: 16 }),
7769
9376
  " Stop screen share"
7770
9377
  ] }) : null,
7771
- participant.handRaised ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "lower_hand", identity: participant.identity }), children: [
7772
- /* @__PURE__ */ jsx3(HandIcon, { width: 16, height: 16 }),
9378
+ participant.handRaised ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "lower_hand", identity: participant.identity }), children: [
9379
+ /* @__PURE__ */ jsx4(HandIcon, { width: 16, height: 16 }),
7773
9380
  " Lower hand"
7774
9381
  ] }) : null,
7775
- hasAccount && !participant.isAgent && participant.role !== "cohost" ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "make_cohost", identity: participant.identity }), children: [
7776
- /* @__PURE__ */ jsx3(PeopleIcon, { width: 16, height: 16 }),
9382
+ hasAccount && !participant.isAgent && participant.role !== "cohost" ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "make_cohost", identity: participant.identity }), children: [
9383
+ /* @__PURE__ */ jsx4(PeopleIcon, { width: 16, height: 16 }),
7777
9384
  " Make co-host"
7778
9385
  ] }) : null,
7779
- !participant.isAgent ? /* @__PURE__ */ jsxs2(
9386
+ !participant.isAgent ? /* @__PURE__ */ jsxs3(
7780
9387
  MenuItem,
7781
9388
  {
7782
9389
  onSelect: () => {
@@ -7784,21 +9391,21 @@ function PersonMenu({
7784
9391
  setMode("rename");
7785
9392
  },
7786
9393
  children: [
7787
- /* @__PURE__ */ jsx3(PencilIcon, { width: 16, height: 16 }),
9394
+ /* @__PURE__ */ jsx4(PencilIcon, { width: 16, height: 16 }),
7788
9395
  " Rename"
7789
9396
  ]
7790
9397
  }
7791
9398
  ) : null
7792
9399
  ] }) : null,
7793
- controls.isOwner && participant.role === "cohost" ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "revoke_cohost", identity: participant.identity }), children: [
7794
- /* @__PURE__ */ jsx3(PeopleIcon, { width: 16, height: 16 }),
9400
+ controls.isOwner && participant.role === "cohost" ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "revoke_cohost", identity: participant.identity }), children: [
9401
+ /* @__PURE__ */ jsx4(PeopleIcon, { width: 16, height: 16 }),
7795
9402
  " Remove co-host"
7796
9403
  ] }) : null,
7797
- controls.isOwner && !self && hasAccount && !participant.isAgent ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => setMode("transfer"), children: [
7798
- /* @__PURE__ */ jsx3(SpotlightIcon, { width: 16, height: 16 }),
9404
+ controls.isOwner && !self && hasAccount && !participant.isAgent ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => setMode("transfer"), children: [
9405
+ /* @__PURE__ */ jsx4(SpotlightIcon, { width: 16, height: 16 }),
7799
9406
  " Make host"
7800
9407
  ] }) : null,
7801
- self ? /* @__PURE__ */ jsxs2(
9408
+ self ? /* @__PURE__ */ jsxs3(
7802
9409
  MenuItem,
7803
9410
  {
7804
9411
  onSelect: () => {
@@ -7806,12 +9413,12 @@ function PersonMenu({
7806
9413
  setMode("rename");
7807
9414
  },
7808
9415
  children: [
7809
- /* @__PURE__ */ jsx3(PencilIcon, { width: 16, height: 16 }),
9416
+ /* @__PURE__ */ jsx4(PencilIcon, { width: 16, height: 16 }),
7810
9417
  " Rename yourself"
7811
9418
  ]
7812
9419
  }
7813
9420
  ) : null,
7814
- !self && !participant.isAgent ? /* @__PURE__ */ jsxs2(
9421
+ !self && !participant.isAgent ? /* @__PURE__ */ jsxs3(
7815
9422
  MenuItem,
7816
9423
  {
7817
9424
  onSelect: () => {
@@ -7819,21 +9426,21 @@ function PersonMenu({
7819
9426
  setMode("report");
7820
9427
  },
7821
9428
  children: [
7822
- /* @__PURE__ */ jsx3(FlagIcon, { width: 16, height: 16 }),
9429
+ /* @__PURE__ */ jsx4(FlagIcon, { width: 16, height: 16 }),
7823
9430
  " Report"
7824
9431
  ]
7825
9432
  }
7826
9433
  ) : null,
7827
- moderate && !participant.isAgent ? /* @__PURE__ */ jsxs2(MenuItem, { danger: true, onSelect: () => setMode("remove"), children: [
7828
- /* @__PURE__ */ jsx3(CloseIcon, { width: 16, height: 16 }),
9434
+ moderate && !participant.isAgent ? /* @__PURE__ */ jsxs3(MenuItem, { danger: true, onSelect: () => setMode("remove"), children: [
9435
+ /* @__PURE__ */ jsx4(CloseIcon, { width: 16, height: 16 }),
7829
9436
  " Remove from meeting"
7830
9437
  ] }) : null
7831
9438
  ] }) });
7832
9439
  }
7833
9440
  function SettingsPanel({ onClose }) {
7834
9441
  const host = useRequiredMeetHost();
7835
- return /* @__PURE__ */ jsxs2(PanelShell, { title: "Audio, video and effects", onClose, children: [
7836
- /* @__PURE__ */ jsx3(
9442
+ return /* @__PURE__ */ jsxs3(PanelShell, { title: "Settings", onClose, children: [
9443
+ /* @__PURE__ */ jsx4(
7837
9444
  DeviceSettings,
7838
9445
  {
7839
9446
  onPick: (kind, deviceId2) => {
@@ -7842,7 +9449,8 @@ function SettingsPanel({ onClose }) {
7842
9449
  }
7843
9450
  }
7844
9451
  ),
7845
- /* @__PURE__ */ jsx3(EffectsSettings, {})
9452
+ /* @__PURE__ */ jsx4(EffectsSettings, {}),
9453
+ /* @__PURE__ */ jsx4(CaptionLanguageSettings, {})
7846
9454
  ] });
7847
9455
  }
7848
9456
  function DeviceSettings({
@@ -7854,15 +9462,15 @@ function DeviceSettings({
7854
9462
  const speaker = devices?.selected.audiooutput ?? host.devices.resolve("audiooutput");
7855
9463
  const stream = useMicrophoneStream(microphone);
7856
9464
  const level = useAudioLevel(stream);
7857
- const [testing, setTesting] = useState3(false);
7858
- useEffect3(() => {
9465
+ const [testing, setTesting] = useState4(false);
9466
+ useEffect4(() => {
7859
9467
  void host.devices.refresh();
7860
9468
  }, [host]);
7861
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__section", "aria-label": "Devices", children: [
7862
- /* @__PURE__ */ jsx3(DevicePicker, { kind: "audioinput", label: "Microphone", onPick }),
7863
- /* @__PURE__ */ jsx3("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__ */ jsx3("span", { style: { width: `${Math.min(100, Math.round(level * 160))}%` } }) }),
7864
- /* @__PURE__ */ jsx3(DevicePicker, { kind: "audiooutput", label: "Speaker", onPick }),
7865
- /* @__PURE__ */ jsxs2(
9469
+ return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__section", "aria-label": "Devices", children: [
9470
+ /* @__PURE__ */ jsx4(DevicePicker, { kind: "audioinput", label: "Microphone", onPick }),
9471
+ /* @__PURE__ */ jsx4("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__ */ jsx4("span", { style: { width: `${Math.min(100, Math.round(level * 160))}%` } }) }),
9472
+ /* @__PURE__ */ jsx4(DevicePicker, { kind: "audiooutput", label: "Speaker", onPick }),
9473
+ /* @__PURE__ */ jsxs3(
7866
9474
  "button",
7867
9475
  {
7868
9476
  type: "button",
@@ -7873,19 +9481,19 @@ function DeviceSettings({
7873
9481
  void playTestSound(speaker).finally(() => setTesting(false));
7874
9482
  },
7875
9483
  children: [
7876
- /* @__PURE__ */ jsx3(SpeakerIcon, { width: 14, height: 14 }),
9484
+ /* @__PURE__ */ jsx4(SpeakerIcon, { width: 14, height: 14 }),
7877
9485
  " ",
7878
9486
  testing ? "Playing\u2026" : "Test speaker"
7879
9487
  ]
7880
9488
  }
7881
9489
  ),
7882
- /* @__PURE__ */ jsx3(DevicePicker, { kind: "videoinput", label: "Camera", onPick })
9490
+ /* @__PURE__ */ jsx4(DevicePicker, { kind: "videoinput", label: "Camera", onPick })
7883
9491
  ] });
7884
9492
  }
7885
9493
  function EffectsSettings({ preview }) {
7886
9494
  const effects = useMediaEffects();
7887
- const [error, setError] = useState3(null);
7888
- const fileRef = useRef3(null);
9495
+ const [error, setError] = useState4(null);
9496
+ const fileRef = useRef4(null);
7889
9497
  const supported = effects.backgroundsSupported || preview != null || videoEffectsSupported();
7890
9498
  const apply = (next) => {
7891
9499
  setError(null);
@@ -7897,9 +9505,9 @@ function EffectsSettings({ preview }) {
7897
9505
  );
7898
9506
  }
7899
9507
  };
7900
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__section", "aria-label": "Effects", children: [
7901
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
7902
- /* @__PURE__ */ jsx3(
9508
+ return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__section", "aria-label": "Effects", children: [
9509
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__toggle", children: [
9510
+ /* @__PURE__ */ jsx4(
7903
9511
  "input",
7904
9512
  {
7905
9513
  type: "checkbox",
@@ -7908,11 +9516,11 @@ function EffectsSettings({ preview }) {
7908
9516
  }
7909
9517
  ),
7910
9518
  "Noise suppression",
7911
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__hint", children: "Filters keyboards, fans and background chatter." })
9519
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__hint", children: "Filters keyboards, fans and background chatter." })
7912
9520
  ] }),
7913
- supported ? /* @__PURE__ */ jsxs2("div", { className: "mx-meet__field", children: [
7914
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "Background" }),
7915
- /* @__PURE__ */ jsx3("div", { className: "mx-meet__pills", role: "radiogroup", "aria-label": "Background", children: ["none", "blur", "image"].map((kind) => /* @__PURE__ */ jsx3(
9521
+ supported ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__field", children: [
9522
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__field-label", children: "Background" }),
9523
+ /* @__PURE__ */ jsx4("div", { className: "mx-meet__pills", role: "radiogroup", "aria-label": "Background", children: ["none", "blur", "image"].map((kind) => /* @__PURE__ */ jsx4(
7916
9524
  "button",
7917
9525
  {
7918
9526
  type: "button",
@@ -7930,7 +9538,7 @@ function EffectsSettings({ preview }) {
7930
9538
  },
7931
9539
  kind
7932
9540
  )) }),
7933
- /* @__PURE__ */ jsx3(
9541
+ /* @__PURE__ */ jsx4(
7934
9542
  "input",
7935
9543
  {
7936
9544
  ref: fileRef,
@@ -7945,7 +9553,7 @@ function EffectsSettings({ preview }) {
7945
9553
  }
7946
9554
  }
7947
9555
  ),
7948
- error !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__error", children: error }) : null
9556
+ error !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__error", children: error }) : null
7949
9557
  ] }) : null
7950
9558
  ] });
7951
9559
  }
@@ -8004,8 +9612,8 @@ async function playTestSound(sinkId) {
8004
9612
  await context.close();
8005
9613
  }
8006
9614
  function useMicrophoneStream(deviceId2) {
8007
- const [stream, setStream] = useState3(null);
8008
- useEffect3(() => {
9615
+ const [stream, setStream] = useState4(null);
9616
+ useEffect4(() => {
8009
9617
  if (deviceId2 === "off") return void 0;
8010
9618
  let live = true;
8011
9619
  let opened = null;
@@ -8030,25 +9638,25 @@ function useMicrophoneStream(deviceId2) {
8030
9638
  function LobbyPanel() {
8031
9639
  const lobby = useLobby();
8032
9640
  if (!lobby.canAdmit || lobby.waiting.length === 0) return null;
8033
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__lobby", "aria-label": "Waiting room", children: [
8034
- /* @__PURE__ */ jsxs2("header", { className: "mx-meet__lobby-head", children: [
8035
- /* @__PURE__ */ jsx3("h3", { className: "mx-meet__lobby-title", children: lobby.waiting.length === 1 ? "1 person is waiting" : `${lobby.waiting.length} people are waiting` }),
8036
- /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: () => void lobby.admitAll(), children: "Admit all" })
9641
+ return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__lobby", "aria-label": "Waiting room", children: [
9642
+ /* @__PURE__ */ jsxs3("header", { className: "mx-meet__lobby-head", children: [
9643
+ /* @__PURE__ */ jsx4("h3", { className: "mx-meet__lobby-title", children: lobby.waiting.length === 1 ? "1 person is waiting" : `${lobby.waiting.length} people are waiting` }),
9644
+ /* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__link", onClick: () => void lobby.admitAll(), children: "Admit all" })
8037
9645
  ] }),
8038
- /* @__PURE__ */ jsx3("ul", { className: "mx-meet__lobby-list", children: lobby.waiting.map((entry) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__lobby-row", children: [
8039
- /* @__PURE__ */ jsx3(Avatar, { name: entry.displayName, url: entry.avatarUrl, size: 32 }),
8040
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__person-name", children: [
9646
+ /* @__PURE__ */ jsx4("ul", { className: "mx-meet__lobby-list", children: lobby.waiting.map((entry) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__lobby-row", children: [
9647
+ /* @__PURE__ */ jsx4(Avatar, { name: entry.displayName, url: entry.avatarUrl, size: 32 }),
9648
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
8041
9649
  entry.displayName,
8042
- entry.userId === null ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Guest" }) : null
9650
+ entry.userId === null ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Guest" }) : null
8043
9651
  ] }),
8044
- /* @__PURE__ */ jsx3(ControlButton, { label: `Admit ${entry.displayName}`, onClick: () => void lobby.admit(entry), children: /* @__PURE__ */ jsx3(CheckIcon, { width: 16, height: 16 }) }),
8045
- /* @__PURE__ */ jsx3(
9652
+ /* @__PURE__ */ jsx4(ControlButton, { label: `Admit ${entry.displayName}`, onClick: () => void lobby.admit(entry), children: /* @__PURE__ */ jsx4(CheckIcon, { width: 16, height: 16 }) }),
9653
+ /* @__PURE__ */ jsx4(
8046
9654
  ControlButton,
8047
9655
  {
8048
9656
  label: `Deny ${entry.displayName}`,
8049
9657
  danger: true,
8050
9658
  onClick: () => void lobby.deny(entry),
8051
- children: /* @__PURE__ */ jsx3(CloseIcon, { width: 16, height: 16 })
9659
+ children: /* @__PURE__ */ jsx4(CloseIcon, { width: 16, height: 16 })
8052
9660
  }
8053
9661
  )
8054
9662
  ] }, entry.identity)) })
@@ -8058,21 +9666,21 @@ function NoteTakerRow() {
8058
9666
  const ai = useMeetAi();
8059
9667
  const status = ai.noteTaker;
8060
9668
  const duplicateError = status.refusal !== null && ai.error !== null && status.refusal.reason === ai.error.message && status.refusal.remedy === ai.error.remedy;
8061
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__note-taker", "aria-label": "Note-taker", children: [
8062
- /* @__PURE__ */ jsxs2("p", { className: `mx-meet__note-taker-state mx-meet__note-taker-state--${status.state}`, children: [
8063
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__note-taker-dot", "aria-hidden": "true" }),
9669
+ return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-taker", "aria-label": "Note-taker", children: [
9670
+ /* @__PURE__ */ jsxs3("p", { className: `mx-meet__note-taker-state mx-meet__note-taker-state--${status.state}`, children: [
9671
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__note-taker-dot", "aria-hidden": "true" }),
8064
9672
  ai.noteTakerLabel
8065
9673
  ] }),
8066
- status.detail !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: status.detail }) : null,
8067
- status.refusal !== null ? /* @__PURE__ */ jsxs2(ErrorBox, { as: "div", className: "mx-meet__refusal", error: status.refusal, operation: "Join this meeting", origin: "meet/components", children: [
8068
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-reason", children: status.refusal.reason }),
8069
- status.refusal.remedy.length > 0 ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-remedy", children: status.refusal.remedy }) : null
9674
+ status.detail !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: status.detail }) : null,
9675
+ status.refusal !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: status.refusal, operation: "Join this meeting", origin: "meet/components", children: [
9676
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-reason", children: status.refusal.reason }),
9677
+ status.refusal.remedy.length > 0 ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-remedy", children: status.refusal.remedy }) : null
8070
9678
  ] }) : null,
8071
- ai.error !== null && !duplicateError ? /* @__PURE__ */ jsxs2(ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
8072
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
8073
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
9679
+ ai.error !== null && !duplicateError ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
9680
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
9681
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
8074
9682
  ] }) : null,
8075
- ai.canControlNoteTaker ? status.state === "transcribing" || status.state === "joining" || status.state === "handoff_pending" ? /* @__PURE__ */ jsx3(
9683
+ ai.canControlNoteTaker ? status.state === "transcribing" || status.state === "joining" || status.state === "handoff_pending" ? /* @__PURE__ */ jsx4(
8076
9684
  "button",
8077
9685
  {
8078
9686
  type: "button",
@@ -8080,7 +9688,7 @@ function NoteTakerRow() {
8080
9688
  onClick: () => void ai.stopNoteTaker(),
8081
9689
  children: "Dismiss the note-taker"
8082
9690
  }
8083
- ) : /* @__PURE__ */ jsx3(
9691
+ ) : /* @__PURE__ */ jsx4(
8084
9692
  "button",
8085
9693
  {
8086
9694
  type: "button",
@@ -8096,24 +9704,24 @@ function NoteList({
8096
9704
  notes,
8097
9705
  empty
8098
9706
  }) {
8099
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__note-group", "aria-label": title, children: [
8100
- /* @__PURE__ */ jsx3("h3", { className: "mx-meet__note-group-title", children: title }),
8101
- notes.length === 0 ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: empty }) : /* @__PURE__ */ jsx3("ul", { className: "mx-meet__notes", children: notes.map((note) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__note", children: [
9707
+ return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-group", "aria-label": title, children: [
9708
+ /* @__PURE__ */ jsx4("h3", { className: "mx-meet__note-group-title", children: title }),
9709
+ notes.length === 0 ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: empty }) : /* @__PURE__ */ jsx4("ul", { className: "mx-meet__notes", children: notes.map((note) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__note", children: [
8102
9710
  note.text,
8103
- note.assigneeDisplayName !== void 0 && note.assigneeDisplayName !== null ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__assignee", children: note.assigneeDisplayName }) : null
9711
+ note.assigneeDisplayName !== void 0 && note.assigneeDisplayName !== null ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__assignee", children: note.assigneeDisplayName }) : null
8104
9712
  ] }, note.id)) })
8105
9713
  ] });
8106
9714
  }
8107
9715
  function AiPanel({ onClose }) {
8108
9716
  const ai = useMeetAi();
8109
- const [question, setQuestion] = useState3("");
8110
- return /* @__PURE__ */ jsxs2(PanelShell, { title: "Meeting assistant", onClose, children: [
8111
- /* @__PURE__ */ jsx3(NoteTakerRow, {}),
8112
- ai.summary !== null ? /* @__PURE__ */ jsxs2("section", { className: "mx-meet__note-group", "aria-label": "Summary", children: [
8113
- /* @__PURE__ */ jsx3("h3", { className: "mx-meet__note-group-title", children: "Summary" }),
8114
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__summary", children: ai.summary.text })
9717
+ const [question, setQuestion] = useState4("");
9718
+ return /* @__PURE__ */ jsxs3(PanelShell, { title: "Meeting assistant", onClose, children: [
9719
+ /* @__PURE__ */ jsx4(NoteTakerRow, {}),
9720
+ ai.summary !== null ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-group", "aria-label": "Summary", children: [
9721
+ /* @__PURE__ */ jsx4("h3", { className: "mx-meet__note-group-title", children: "Summary" }),
9722
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__summary", children: ai.summary.text })
8115
9723
  ] }) : null,
8116
- ai.wrapUp !== null ? /* @__PURE__ */ jsxs2("p", { className: "mx-meet__wrap-up-notice", role: "status", children: [
9724
+ ai.wrapUp !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__wrap-up-notice", role: "status", children: [
8117
9725
  "The wrap-up is written \u2014 ",
8118
9726
  ai.wrapUp.noteIds.length,
8119
9727
  " ",
@@ -8125,7 +9733,7 @@ function AiPanel({ onClose }) {
8125
9733
  ai.wrapUp.segmentCount === 1 ? "transcript line" : "transcript lines",
8126
9734
  "."
8127
9735
  ] }) : null,
8128
- /* @__PURE__ */ jsx3(
9736
+ /* @__PURE__ */ jsx4(
8129
9737
  NoteList,
8130
9738
  {
8131
9739
  title: "Notes",
@@ -8133,7 +9741,7 @@ function AiPanel({ onClose }) {
8133
9741
  empty: "Notes appear here as the meeting goes on."
8134
9742
  }
8135
9743
  ),
8136
- /* @__PURE__ */ jsx3(
9744
+ /* @__PURE__ */ jsx4(
8137
9745
  NoteList,
8138
9746
  {
8139
9747
  title: "Decisions",
@@ -8141,7 +9749,7 @@ function AiPanel({ onClose }) {
8141
9749
  empty: "Nothing has been decided yet."
8142
9750
  }
8143
9751
  ),
8144
- /* @__PURE__ */ jsx3(
9752
+ /* @__PURE__ */ jsx4(
8145
9753
  NoteList,
8146
9754
  {
8147
9755
  title: "Action items",
@@ -8149,21 +9757,21 @@ function AiPanel({ onClose }) {
8149
9757
  empty: "No action items yet."
8150
9758
  }
8151
9759
  ),
8152
- ai.transcript.length > 0 ? /* @__PURE__ */ jsxs2("section", { className: "mx-meet__note-group", "aria-label": "Transcript", children: [
8153
- /* @__PURE__ */ jsx3("h3", { className: "mx-meet__note-group-title", children: "Transcript" }),
8154
- /* @__PURE__ */ jsx3("ul", { className: "mx-meet__transcript", children: ai.transcript.map((line) => /* @__PURE__ */ jsxs2(
9760
+ ai.transcript.length > 0 ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-group", "aria-label": "Transcript", children: [
9761
+ /* @__PURE__ */ jsx4("h3", { className: "mx-meet__note-group-title", children: "Transcript" }),
9762
+ /* @__PURE__ */ jsx4("ul", { className: "mx-meet__transcript", children: ai.transcript.map((line) => /* @__PURE__ */ jsxs3(
8155
9763
  "li",
8156
9764
  {
8157
9765
  className: line.final && line.source === "record" ? "mx-meet__line" : "mx-meet__line mx-meet__line--interim",
8158
9766
  children: [
8159
- /* @__PURE__ */ jsx3("strong", { children: line.speaker }),
8160
- /* @__PURE__ */ jsx3("span", { children: line.text })
9767
+ /* @__PURE__ */ jsx4("strong", { children: line.speaker }),
9768
+ /* @__PURE__ */ jsx4("span", { children: line.text })
8161
9769
  ]
8162
9770
  },
8163
9771
  line.id
8164
9772
  )) })
8165
9773
  ] }) : null,
8166
- /* @__PURE__ */ jsxs2(
9774
+ /* @__PURE__ */ jsxs3(
8167
9775
  "form",
8168
9776
  {
8169
9777
  className: "mx-meet__composer",
@@ -8174,7 +9782,7 @@ function AiPanel({ onClose }) {
8174
9782
  void ai.ask(asked);
8175
9783
  },
8176
9784
  children: [
8177
- /* @__PURE__ */ jsx3(
9785
+ /* @__PURE__ */ jsx4(
8178
9786
  "input",
8179
9787
  {
8180
9788
  className: "mx-meet__input",
@@ -8184,13 +9792,13 @@ function AiPanel({ onClose }) {
8184
9792
  "aria-label": "Ask about this meeting"
8185
9793
  }
8186
9794
  ),
8187
- /* @__PURE__ */ jsx3("button", { type: "submit", className: "mx-meet__send", disabled: ai.asking, children: ai.asking ? "Asking\u2026" : "Ask" })
9795
+ /* @__PURE__ */ jsx4("button", { type: "submit", className: "mx-meet__send", disabled: ai.asking, children: ai.asking ? "Asking\u2026" : "Ask" })
8188
9796
  ]
8189
9797
  }
8190
9798
  ),
8191
- ai.asking && ai.phase !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", role: "status", children: ai.phase }) : null,
8192
- ai.answer !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__answer", children: ai.answer }) : null,
8193
- ai.answer !== null && ai.coverage !== null ? /* @__PURE__ */ jsxs2("p", { className: "mx-meet__coverage", children: [
9799
+ ai.asking && ai.phase !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", role: "status", children: ai.phase }) : null,
9800
+ ai.answer !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__answer", children: ai.answer }) : null,
9801
+ ai.answer !== null && ai.coverage !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__coverage", children: [
8194
9802
  "Answered from ",
8195
9803
  ai.coverage.segmentsUsed,
8196
9804
  " of ",
@@ -8199,48 +9807,56 @@ function AiPanel({ onClose }) {
8199
9807
  ai.coverage.truncated ? " (the oldest were left out)" : "",
8200
9808
  "."
8201
9809
  ] }) : null,
8202
- ai.error !== null ? /* @__PURE__ */ jsxs2(ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
8203
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
8204
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
9810
+ ai.error !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
9811
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
9812
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
8205
9813
  ] }) : null
8206
9814
  ] });
8207
9815
  }
8208
9816
  function Captions({ lines = 3 }) {
8209
9817
  const ai = useMeetAi();
8210
9818
  const visible = ai.transcript.slice(-lines);
9819
+ const translation = useCaptionTranslation(visible);
8211
9820
  if (visible.length === 0) return null;
8212
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet__captions", "aria-live": "polite", "aria-label": "Live captions", children: visible.map((line) => /* @__PURE__ */ jsxs2(
8213
- "p",
8214
- {
8215
- className: line.final ? "mx-meet__caption" : "mx-meet__caption mx-meet__caption--interim",
8216
- children: [
8217
- /* @__PURE__ */ jsx3("strong", { children: line.speaker }),
8218
- " ",
8219
- line.text
8220
- ]
8221
- },
8222
- line.id
8223
- )) });
9821
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__captions", "aria-live": "polite", "aria-label": "Live captions", children: [
9822
+ visible.map((line) => {
9823
+ const translated = translation.language === null ? void 0 : translation.translations[line.id];
9824
+ return /* @__PURE__ */ jsxs3(
9825
+ "p",
9826
+ {
9827
+ className: line.final ? "mx-meet__caption" : "mx-meet__caption mx-meet__caption--interim",
9828
+ children: [
9829
+ /* @__PURE__ */ jsx4("strong", { children: line.speaker }),
9830
+ " ",
9831
+ translated ?? line.text,
9832
+ translated !== void 0 ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__caption-original", children: line.text }) : null
9833
+ ]
9834
+ },
9835
+ line.id
9836
+ );
9837
+ }),
9838
+ translation.language !== null && translation.error !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__caption mx-meet__caption--interim", children: translation.error }) : null
9839
+ ] });
8224
9840
  }
8225
9841
  function ConsentNotice() {
8226
9842
  const notice = useConsentNotice();
8227
9843
  if (notice === null) return null;
8228
- return /* @__PURE__ */ jsx3("p", { className: "mx-meet__consent", role: "status", children: notice });
9844
+ return /* @__PURE__ */ jsx4("p", { className: "mx-meet__consent", role: "status", children: notice });
8229
9845
  }
8230
9846
  function AttendanceNotice() {
8231
9847
  const media = useLocalMedia();
8232
9848
  const notice = listenOnlyNotice(media);
8233
9849
  if (notice === null) return null;
8234
9850
  const refused = media.microphone.unavailable;
8235
- return /* @__PURE__ */ jsxs2("p", { className: "mx-meet__banner mx-meet__banner--attendance", role: "status", children: [
9851
+ return /* @__PURE__ */ jsxs3("p", { className: "mx-meet__banner mx-meet__banner--attendance", role: "status", children: [
8236
9852
  notice,
8237
- refused === null ? null : /* @__PURE__ */ jsx3("span", { className: "mx-meet__remedy", children: refused.remedy })
9853
+ refused === null ? null : /* @__PURE__ */ jsx4("span", { className: "mx-meet__remedy", children: refused.remedy })
8238
9854
  ] });
8239
9855
  }
8240
9856
  function PreJoin(props) {
8241
9857
  const host = useMeetHost();
8242
- if (host === null) return /* @__PURE__ */ jsx3(InertNotice, { what: "This meeting" });
8243
- return /* @__PURE__ */ jsx3(PreJoinBody, { ...props, host });
9858
+ if (host === null) return /* @__PURE__ */ jsx4(InertNotice, { what: "This meeting" });
9859
+ return /* @__PURE__ */ jsx4(PreJoinBody, { ...props, host });
8244
9860
  }
8245
9861
  function PreJoinBody({
8246
9862
  roomName,
@@ -8254,21 +9870,21 @@ function PreJoinBody({
8254
9870
  const recording = useRecording();
8255
9871
  const effects = useMediaEffects();
8256
9872
  const { notice } = useModerationNotice();
8257
- const [mode, setMode] = useState3("video");
8258
- const [microphone, setMicrophone] = useState3(true);
8259
- const [joining, setJoining] = useState3(false);
9873
+ const [mode, setMode] = useState4("video");
9874
+ const [microphone, setMicrophone] = useState4(true);
9875
+ const [joining, setJoining] = useState4(false);
8260
9876
  const camera = devices?.selected.videoinput ?? host.devices.resolve("videoinput");
8261
9877
  const mic = devices?.selected.audioinput ?? host.devices.resolve("audioinput");
8262
9878
  const preview = useCameraPreview(mode === "video" ? camera : void 0, effects.effects);
8263
9879
  const micStream = useMicrophoneStream(microphone ? mic : "off");
8264
9880
  const level = useAudioLevel(micStream);
8265
- const [speakerTesting, setSpeakerTesting] = useState3(false);
8266
- useEffect3(() => {
9881
+ const [speakerTesting, setSpeakerTesting] = useState4(false);
9882
+ useEffect4(() => {
8267
9883
  void host.devices.refresh();
8268
9884
  }, [host]);
8269
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__prejoin", children: [
8270
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__preview", children: [
8271
- mode === "video" && preview.preview !== null ? /* @__PURE__ */ jsx3(
9885
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__prejoin", children: [
9886
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__preview", children: [
9887
+ mode === "video" && preview.preview !== null ? /* @__PURE__ */ jsx4(
8272
9888
  "video",
8273
9889
  {
8274
9890
  className: "mx-meet__video mx-meet__video--mirror",
@@ -8279,16 +9895,16 @@ function PreJoinBody({
8279
9895
  if (element !== null) preview.preview?.attach(element);
8280
9896
  }
8281
9897
  }
8282
- ) : /* @__PURE__ */ jsx3("div", { className: "mx-meet__tile-placeholder", children: /* @__PURE__ */ jsx3(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 96 }) }),
8283
- mode === "video" && preview.error !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__preview-note", children: preview.error }) : null,
8284
- microphone && micStream !== null ? /* @__PURE__ */ jsx3("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__ */ jsx3("span", { style: { width: `${Math.min(100, Math.round(level * 160))}%` } }) }) : null
9898
+ ) : /* @__PURE__ */ jsx4("div", { className: "mx-meet__tile-placeholder", children: /* @__PURE__ */ jsx4(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 96 }) }),
9899
+ mode === "video" && preview.error !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__preview-note", children: preview.error }) : null,
9900
+ microphone && micStream !== null ? /* @__PURE__ */ jsx4("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__ */ jsx4("span", { style: { width: `${Math.min(100, Math.round(level * 160))}%` } }) }) : null
8285
9901
  ] }),
8286
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__prejoin-panel", children: [
8287
- /* @__PURE__ */ jsx3("h1", { className: "mx-meet__prejoin-title", children: "Ready to join?" }),
8288
- notice?.kind === "removed" ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__warning", children: notice.text }) : null,
8289
- devices?.labelsHidden === true ? /* @__PURE__ */ jsxs2("p", { className: "mx-meet__panel-note", children: [
9902
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__prejoin-panel", children: [
9903
+ /* @__PURE__ */ jsx4("h1", { className: "mx-meet__prejoin-title", children: "Ready to join?" }),
9904
+ notice?.kind === "removed" ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__warning", children: notice.text }) : null,
9905
+ devices?.labelsHidden === true ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
8290
9906
  "Your browser is hiding device names until you allow camera and microphone access.",
8291
- /* @__PURE__ */ jsx3(
9907
+ /* @__PURE__ */ jsx4(
8292
9908
  "button",
8293
9909
  {
8294
9910
  type: "button",
@@ -8300,11 +9916,11 @@ function PreJoinBody({
8300
9916
  }
8301
9917
  )
8302
9918
  ] }) : null,
8303
- devices?.fallbackNotice != null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__warning", children: devices.fallbackNotice }) : null,
8304
- /* @__PURE__ */ jsx3(DevicePicker, { kind: "audioinput", label: "Microphone" }),
8305
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__field-row", children: [
8306
- /* @__PURE__ */ jsx3(DevicePicker, { kind: "audiooutput", label: "Speaker" }),
8307
- /* @__PURE__ */ jsxs2(
9919
+ devices?.fallbackNotice != null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__warning", children: devices.fallbackNotice }) : null,
9920
+ /* @__PURE__ */ jsx4(DevicePicker, { kind: "audioinput", label: "Microphone" }),
9921
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__field-row", children: [
9922
+ /* @__PURE__ */ jsx4(DevicePicker, { kind: "audiooutput", label: "Speaker" }),
9923
+ /* @__PURE__ */ jsxs3(
8308
9924
  "button",
8309
9925
  {
8310
9926
  type: "button",
@@ -8317,19 +9933,19 @@ function PreJoinBody({
8317
9933
  );
8318
9934
  },
8319
9935
  children: [
8320
- /* @__PURE__ */ jsx3(SpeakerIcon, { width: 14, height: 14 }),
9936
+ /* @__PURE__ */ jsx4(SpeakerIcon, { width: 14, height: 14 }),
8321
9937
  " ",
8322
9938
  speakerTesting ? "Playing\u2026" : "Test"
8323
9939
  ]
8324
9940
  }
8325
9941
  )
8326
9942
  ] }),
8327
- /* @__PURE__ */ jsx3(DevicePicker, { kind: "videoinput", label: "Camera" }),
8328
- /* @__PURE__ */ jsx3(EffectsSettings, { preview: preview.preview }),
8329
- recording.consentNotice !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__consent", children: recording.consentNotice }) : null,
8330
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__prejoin-actions", children: [
8331
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
8332
- /* @__PURE__ */ jsx3(
9943
+ /* @__PURE__ */ jsx4(DevicePicker, { kind: "videoinput", label: "Camera" }),
9944
+ /* @__PURE__ */ jsx4(EffectsSettings, { preview: preview.preview }),
9945
+ recording.consentNotice !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__consent", children: recording.consentNotice }) : null,
9946
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__prejoin-actions", children: [
9947
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__toggle", children: [
9948
+ /* @__PURE__ */ jsx4(
8333
9949
  "input",
8334
9950
  {
8335
9951
  type: "checkbox",
@@ -8339,8 +9955,8 @@ function PreJoinBody({
8339
9955
  ),
8340
9956
  "Join with video"
8341
9957
  ] }),
8342
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
8343
- /* @__PURE__ */ jsx3(
9958
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__toggle", children: [
9959
+ /* @__PURE__ */ jsx4(
8344
9960
  "input",
8345
9961
  {
8346
9962
  type: "checkbox",
@@ -8350,7 +9966,7 @@ function PreJoinBody({
8350
9966
  ),
8351
9967
  "Join with microphone"
8352
9968
  ] }),
8353
- /* @__PURE__ */ jsx3(
9969
+ /* @__PURE__ */ jsx4(
8354
9970
  "button",
8355
9971
  {
8356
9972
  type: "button",
@@ -8370,20 +9986,20 @@ function PreJoinBody({
8370
9986
  }
8371
9987
  )
8372
9988
  ] }),
8373
- room.failure !== null ? /* @__PURE__ */ jsxs2("p", { className: "mx-meet__error", children: [
9989
+ room.failure !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__error", children: [
8374
9990
  room.failure.message,
8375
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__remedy", children: room.failure.remedy })
9991
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__remedy", children: room.failure.remedy })
8376
9992
  ] }) : null
8377
9993
  ] })
8378
9994
  ] });
8379
9995
  }
8380
9996
  function useCameraPreview(deviceId2, effects) {
8381
- const [preview, setPreview] = useState3(null);
8382
- const [error, setError] = useState3(null);
8383
- const current = useRef3(null);
8384
- const initialEffect = useRef3(toVideoEffect(effects));
9997
+ const [preview, setPreview] = useState4(null);
9998
+ const [error, setError] = useState4(null);
9999
+ const current = useRef4(null);
10000
+ const initialEffect = useRef4(toVideoEffect(effects));
8385
10001
  initialEffect.current = toVideoEffect(effects);
8386
- useEffect3(() => {
10002
+ useEffect4(() => {
8387
10003
  if (deviceId2 === void 0) return void 0;
8388
10004
  let live = true;
8389
10005
  setError(null);
@@ -8427,9 +10043,9 @@ function DevicePicker({
8427
10043
  const devices = useDeviceSnapshot();
8428
10044
  const list = devices?.devices[kind] ?? [];
8429
10045
  if (list.length === 0) return null;
8430
- return /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
8431
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: label }),
8432
- /* @__PURE__ */ jsx3(
10046
+ return /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
10047
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__field-label", children: label }),
10048
+ /* @__PURE__ */ jsx4(
8433
10049
  "select",
8434
10050
  {
8435
10051
  className: "mx-meet__select",
@@ -8438,7 +10054,7 @@ function DevicePicker({
8438
10054
  if (onPick !== void 0) onPick(kind, event.target.value);
8439
10055
  else host.devices.select(kind, event.target.value);
8440
10056
  },
8441
- children: list.map((device) => /* @__PURE__ */ jsx3("option", { value: device.deviceId, children: device.label.length > 0 ? device.label : `${label} (name hidden)` }, device.deviceId))
10057
+ children: list.map((device) => /* @__PURE__ */ jsx4("option", { value: device.deviceId, children: device.label.length > 0 ? device.label : `${label} (name hidden)` }, device.deviceId))
8442
10058
  }
8443
10059
  )
8444
10060
  ] });
@@ -8446,9 +10062,9 @@ function DevicePicker({
8446
10062
  function MeetingRoom(props) {
8447
10063
  const host = useMeetHost();
8448
10064
  if (host === null) {
8449
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet", children: /* @__PURE__ */ jsx3(InertNotice, { what: "This meeting" }) });
10065
+ return /* @__PURE__ */ jsx4("div", { className: "mx-meet", children: /* @__PURE__ */ jsx4(InertNotice, { what: "This meeting" }) });
8450
10066
  }
8451
- return /* @__PURE__ */ jsx3(MeetingRoomBody, { ...props, host });
10067
+ return /* @__PURE__ */ jsx4(MeetingRoomBody, { ...props, host });
8452
10068
  }
8453
10069
  function MeetingRoomBody({
8454
10070
  roomName,
@@ -8463,25 +10079,25 @@ function MeetingRoomBody({
8463
10079
  const isHost = useIsHost();
8464
10080
  const elapsed = useElapsed(snapshot?.meeting?.startedAt ?? null);
8465
10081
  const phase = snapshot?.phase ?? "idle";
8466
- useEffect3(() => {
10082
+ useEffect4(() => {
8467
10083
  host.meetings.watch(roomName);
8468
10084
  }, [host, roomName]);
8469
- useEffect3(() => {
10085
+ useEffect4(() => {
8470
10086
  if (given === void 0) return;
8471
10087
  if (host.store.snapshot().meeting !== null) return;
8472
10088
  host.store.patch({ meeting: given, locked: given.locked });
8473
10089
  }, [host, given]);
8474
10090
  const watchedId = meetingId ?? snapshot?.meeting?.id ?? null;
8475
- useEffect3(() => {
10091
+ useEffect4(() => {
8476
10092
  if (watchedId === null) return;
8477
10093
  host.meetings.watchMeeting(asMeetingId(watchedId));
8478
10094
  }, [host, watchedId]);
8479
10095
  const record = snapshot?.meeting ?? given ?? null;
8480
10096
  if (hasEnded(record) && phase !== "connected" && phase !== "reconnecting") {
8481
- return /* @__PURE__ */ jsx3(MeetingRecordView, { meeting: record });
10097
+ return /* @__PURE__ */ jsx4(MeetingRecordView, { meeting: record });
8482
10098
  }
8483
10099
  if (phase === "idle" || phase === "failed" || phase === "left") {
8484
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet", children: /* @__PURE__ */ jsx3(
10100
+ return /* @__PURE__ */ jsx4("div", { className: "mx-meet", children: /* @__PURE__ */ jsx4(
8485
10101
  PreJoin,
8486
10102
  {
8487
10103
  roomName,
@@ -8491,42 +10107,42 @@ function MeetingRoomBody({
8491
10107
  ) });
8492
10108
  }
8493
10109
  if (phase === "lobby") {
8494
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet mx-meet--lobby", children: /* @__PURE__ */ jsx3(WaitingRoom, { roomName, host }) });
8495
- }
8496
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet", children: [
8497
- /* @__PURE__ */ jsx3(ConsentNotice, {}),
8498
- /* @__PURE__ */ jsx3(AttendanceNotice, {}),
8499
- /* @__PURE__ */ jsxs2("header", { className: "mx-meet__header", children: [
8500
- /* @__PURE__ */ jsx3("h1", { className: "mx-meet__title", children: snapshot?.meeting?.title ?? "Meeting" }),
8501
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__meta", children: [
10110
+ return /* @__PURE__ */ jsx4("div", { className: "mx-meet mx-meet--lobby", children: /* @__PURE__ */ jsx4(WaitingRoom, { roomName, host }) });
10111
+ }
10112
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet", children: [
10113
+ /* @__PURE__ */ jsx4(ConsentNotice, {}),
10114
+ /* @__PURE__ */ jsx4(AttendanceNotice, {}),
10115
+ /* @__PURE__ */ jsxs3("header", { className: "mx-meet__header", children: [
10116
+ /* @__PURE__ */ jsx4("h1", { className: "mx-meet__title", children: snapshot?.meeting?.title ?? "Meeting" }),
10117
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__meta", children: [
8502
10118
  participantSummary(snapshot?.participants ?? []),
8503
10119
  elapsed > 0 ? ` \xB7 ${formatDurationMs3(elapsed)}` : ""
8504
10120
  ] }),
8505
- /* @__PURE__ */ jsx3(RecordingIndicator, {}),
8506
- snapshot?.locked === true ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__badge", children: [
8507
- /* @__PURE__ */ jsx3(LockIcon, { width: 12, height: 12 }),
10121
+ /* @__PURE__ */ jsx4(RecordingIndicator, {}),
10122
+ snapshot?.locked === true ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__badge", children: [
10123
+ /* @__PURE__ */ jsx4(LockIcon, { width: 12, height: 12 }),
8508
10124
  " Locked"
8509
10125
  ] }) : null,
8510
- headerControls !== void 0 && headerControls !== null ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__header-controls", "data-meet-header-controls": "", children: headerControls }) : null,
8511
- isHost ? /* @__PURE__ */ jsx3(HostMenu, {}) : null
10126
+ headerControls !== void 0 && headerControls !== null ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__header-controls", "data-meet-header-controls": "", children: headerControls }) : null,
10127
+ isHost ? /* @__PURE__ */ jsx4(HostMenu, {}) : null
8512
10128
  ] }),
8513
- phase === "reconnecting" ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__banner", role: "status", children: "Reconnecting\u2026" }) : null,
8514
- /* @__PURE__ */ jsx3(Stage, {}),
8515
- /* @__PURE__ */ jsx3(Captions, {}),
8516
- /* @__PURE__ */ jsx3(ControlBar, { ...onLeave !== void 0 ? { onLeave } : {} })
10129
+ phase === "reconnecting" ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__banner", role: "status", children: "Reconnecting\u2026" }) : null,
10130
+ /* @__PURE__ */ jsx4(Stage, {}),
10131
+ /* @__PURE__ */ jsx4(Captions, {}),
10132
+ /* @__PURE__ */ jsx4(ControlBar, { ...onLeave !== void 0 ? { onLeave } : {} })
8517
10133
  ] });
8518
10134
  }
8519
10135
  function WaitingRoom({ roomName, host }) {
8520
- const knocked = useRef3(false);
8521
- useEffect3(() => {
10136
+ const knocked = useRef4(false);
10137
+ useEffect4(() => {
8522
10138
  if (knocked.current) return;
8523
10139
  knocked.current = true;
8524
10140
  host.meetings.knock(roomName);
8525
10141
  }, [host, roomName]);
8526
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__waiting", children: [
8527
- /* @__PURE__ */ jsx3(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 72 }),
8528
- /* @__PURE__ */ jsx3("h1", { className: "mx-meet__prejoin-title", children: "Waiting for the host to let you in" }),
8529
- /* @__PURE__ */ jsxs2("p", { className: "mx-meet__empty-body", children: [
10142
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__waiting", children: [
10143
+ /* @__PURE__ */ jsx4(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 72 }),
10144
+ /* @__PURE__ */ jsx4("h1", { className: "mx-meet__prejoin-title", children: "Waiting for the host to let you in" }),
10145
+ /* @__PURE__ */ jsxs3("p", { className: "mx-meet__empty-body", children: [
8530
10146
  "You are in the waiting room as ",
8531
10147
  host.identity.displayName,
8532
10148
  ". You will join automatically once you are admitted."
@@ -8537,10 +10153,10 @@ function HostMenu() {
8537
10153
  const host = useRequiredMeetHost();
8538
10154
  const snapshot = useMeetSnapshot();
8539
10155
  const end = useEndMeeting();
8540
- const [confirmingEnd, setConfirmingEnd] = useState3(false);
10156
+ const [confirmingEnd, setConfirmingEnd] = useState4(false);
8541
10157
  const locked = snapshot?.locked === true;
8542
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__host-menu", children: [
8543
- /* @__PURE__ */ jsx3(
10158
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__host-menu", children: [
10159
+ /* @__PURE__ */ jsx4(
8544
10160
  "button",
8545
10161
  {
8546
10162
  type: "button",
@@ -8551,9 +10167,9 @@ function HostMenu() {
8551
10167
  children: locked ? "Unlock meeting" : "Lock meeting"
8552
10168
  }
8553
10169
  ),
8554
- end.canEnd ? confirmingEnd ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__confirm", role: "group", "aria-label": "End this meeting?", children: [
8555
- /* @__PURE__ */ jsx3("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." }),
8556
- /* @__PURE__ */ jsx3(
10170
+ end.canEnd ? confirmingEnd ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__confirm", role: "group", "aria-label": "End this meeting?", children: [
10171
+ /* @__PURE__ */ jsx4("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." }),
10172
+ /* @__PURE__ */ jsx4(
8557
10173
  "button",
8558
10174
  {
8559
10175
  type: "button",
@@ -8565,7 +10181,7 @@ function HostMenu() {
8565
10181
  children: "End it"
8566
10182
  }
8567
10183
  ),
8568
- /* @__PURE__ */ jsx3(
10184
+ /* @__PURE__ */ jsx4(
8569
10185
  "button",
8570
10186
  {
8571
10187
  type: "button",
@@ -8574,7 +10190,7 @@ function HostMenu() {
8574
10190
  children: "Keep it running"
8575
10191
  }
8576
10192
  )
8577
- ] }) : /* @__PURE__ */ jsx3(
10193
+ ] }) : /* @__PURE__ */ jsx4(
8578
10194
  "button",
8579
10195
  {
8580
10196
  type: "button",
@@ -8583,7 +10199,7 @@ function HostMenu() {
8583
10199
  children: end.ending ? "Ending\u2026" : "End meeting for everyone"
8584
10200
  }
8585
10201
  ) : null,
8586
- end.notice !== null ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__notice", role: "status", children: end.notice }) : null
10202
+ end.notice !== null ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__notice", role: "status", children: end.notice }) : null
8587
10203
  ] });
8588
10204
  }
8589
10205
  function CallButton({
@@ -8593,7 +10209,7 @@ function CallButton({
8593
10209
  }) {
8594
10210
  const calls = useCalls();
8595
10211
  if (!calls.canCall) return null;
8596
- return /* @__PURE__ */ jsx3(
10212
+ return /* @__PURE__ */ jsx4(
8597
10213
  "button",
8598
10214
  {
8599
10215
  type: "button",
@@ -8602,55 +10218,55 @@ function CallButton({
8602
10218
  void calls.call([person.userId], mode);
8603
10219
  },
8604
10220
  "aria-label": `Call ${person.displayName}`,
8605
- children: children ?? /* @__PURE__ */ jsx3(PhoneIcon, { width: 18, height: 18 })
10221
+ children: children ?? /* @__PURE__ */ jsx4(PhoneIcon, { width: 18, height: 18 })
8606
10222
  }
8607
10223
  );
8608
10224
  }
8609
10225
  function IncomingCallHost() {
8610
10226
  const calls = useCalls();
8611
10227
  if (calls.incoming.length === 0) return null;
8612
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet__ringing-stack", children: calls.incoming.map((invite) => /* @__PURE__ */ jsx3(IncomingCallCard, { invite }, invite.id)) });
10228
+ return /* @__PURE__ */ jsx4("div", { className: "mx-meet__ringing-stack", children: calls.incoming.map((invite) => /* @__PURE__ */ jsx4(IncomingCallCard, { invite }, invite.id)) });
8613
10229
  }
8614
10230
  function IncomingCallCard({ invite }) {
8615
10231
  const calls = useCalls();
8616
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__ringing", role: "alertdialog", "aria-label": "Incoming call", children: [
8617
- /* @__PURE__ */ jsx3(Avatar, { name: invite.callerName, url: invite.callerAvatarUrl, size: 56 }),
8618
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__ringing-text", children: [
8619
- /* @__PURE__ */ jsx3("strong", { children: invite.callerName }),
8620
- /* @__PURE__ */ jsx3("span", { children: invite.mode === "video" ? "Incoming video call" : "Incoming call" })
10232
+ return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__ringing", role: "alertdialog", "aria-label": "Incoming call", children: [
10233
+ /* @__PURE__ */ jsx4(Avatar, { name: invite.callerName, url: invite.callerAvatarUrl, size: 56 }),
10234
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__ringing-text", children: [
10235
+ /* @__PURE__ */ jsx4("strong", { children: invite.callerName }),
10236
+ /* @__PURE__ */ jsx4("span", { children: invite.mode === "video" ? "Incoming video call" : "Incoming call" })
8621
10237
  ] }),
8622
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__ringing-actions", children: [
8623
- /* @__PURE__ */ jsx3(ControlButton, { label: "Decline", danger: true, onClick: () => void calls.decline(invite), children: /* @__PURE__ */ jsx3(PhoneOffIcon, {}) }),
8624
- invite.mode === "video" ? /* @__PURE__ */ jsx3(
10238
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__ringing-actions", children: [
10239
+ /* @__PURE__ */ jsx4(ControlButton, { label: "Decline", danger: true, onClick: () => void calls.decline(invite), children: /* @__PURE__ */ jsx4(PhoneOffIcon, {}) }),
10240
+ invite.mode === "video" ? /* @__PURE__ */ jsx4(
8625
10241
  ControlButton,
8626
10242
  {
8627
10243
  label: "Accept without video",
8628
10244
  onClick: () => void calls.accept({ ...invite, mode: "audio" }),
8629
- children: /* @__PURE__ */ jsx3(CameraOffIcon, {})
10245
+ children: /* @__PURE__ */ jsx4(CameraOffIcon, {})
8630
10246
  }
8631
10247
  ) : null,
8632
- /* @__PURE__ */ jsx3(ControlButton, { label: "Accept", onClick: () => void calls.accept(invite), children: /* @__PURE__ */ jsx3(PhoneIcon, {}) })
10248
+ /* @__PURE__ */ jsx4(ControlButton, { label: "Accept", onClick: () => void calls.accept(invite), children: /* @__PURE__ */ jsx4(PhoneIcon, {}) })
8633
10249
  ] })
8634
10250
  ] });
8635
10251
  }
8636
10252
  function ScheduleMeeting(props) {
8637
10253
  const host = useMeetHost();
8638
- if (host === null) return /* @__PURE__ */ jsx3(InertNotice, { what: "Scheduling a meeting" });
8639
- return /* @__PURE__ */ jsx3(ScheduleMeetingBody, { ...props, host });
10254
+ if (host === null) return /* @__PURE__ */ jsx4(InertNotice, { what: "Scheduling a meeting" });
10255
+ return /* @__PURE__ */ jsx4(ScheduleMeetingBody, { ...props, host });
8640
10256
  }
8641
10257
  function ScheduleMeetingBody({
8642
10258
  appBaseUrl,
8643
10259
  onScheduled,
8644
10260
  host
8645
10261
  }) {
8646
- const [title, setTitle] = useState3("");
8647
- const [when2, setWhen] = useState3("");
8648
- const [kind, setKind] = useState3("scheduled");
8649
- const [busy, setBusy] = useState3(false);
8650
- const [link, setLink] = useState3(null);
8651
- const [error, setError] = useState3(null);
10262
+ const [title, setTitle] = useState4("");
10263
+ const [when2, setWhen] = useState4("");
10264
+ const [kind, setKind] = useState4("scheduled");
10265
+ const [busy, setBusy] = useState4(false);
10266
+ const [link, setLink] = useState4(null);
10267
+ const [error, setError] = useState4(null);
8652
10268
  const disabled = useMemo3(() => title.trim().length === 0 || busy, [title, busy]);
8653
- return /* @__PURE__ */ jsxs2(
10269
+ return /* @__PURE__ */ jsxs3(
8654
10270
  "form",
8655
10271
  {
8656
10272
  className: "mx-meet__schedule",
@@ -8675,9 +10291,9 @@ function ScheduleMeetingBody({
8675
10291
  }).finally(() => setBusy(false));
8676
10292
  },
8677
10293
  children: [
8678
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
8679
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "Title" }),
8680
- /* @__PURE__ */ jsx3(
10294
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
10295
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__field-label", children: "Title" }),
10296
+ /* @__PURE__ */ jsx4(
8681
10297
  "input",
8682
10298
  {
8683
10299
  className: "mx-meet__input",
@@ -8687,9 +10303,9 @@ function ScheduleMeetingBody({
8687
10303
  }
8688
10304
  )
8689
10305
  ] }),
8690
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
8691
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "When" }),
8692
- /* @__PURE__ */ jsx3(
10306
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
10307
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__field-label", children: "When" }),
10308
+ /* @__PURE__ */ jsx4(
8693
10309
  "input",
8694
10310
  {
8695
10311
  className: "mx-meet__input",
@@ -8699,27 +10315,27 @@ function ScheduleMeetingBody({
8699
10315
  }
8700
10316
  )
8701
10317
  ] }),
8702
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
8703
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "Repeats" }),
8704
- /* @__PURE__ */ jsxs2(
10318
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
10319
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__field-label", children: "Repeats" }),
10320
+ /* @__PURE__ */ jsxs3(
8705
10321
  "select",
8706
10322
  {
8707
10323
  className: "mx-meet__select",
8708
10324
  value: kind,
8709
10325
  onChange: (event) => setKind(event.target.value),
8710
10326
  children: [
8711
- /* @__PURE__ */ jsx3("option", { value: "scheduled", children: "Once" }),
8712
- /* @__PURE__ */ jsx3("option", { value: "recurring", children: "Recurring \u2014 one link, every time" })
10327
+ /* @__PURE__ */ jsx4("option", { value: "scheduled", children: "Once" }),
10328
+ /* @__PURE__ */ jsx4("option", { value: "recurring", children: "Recurring \u2014 one link, every time" })
8713
10329
  ]
8714
10330
  }
8715
10331
  )
8716
10332
  ] }),
8717
- /* @__PURE__ */ jsx3("button", { type: "submit", className: "mx-meet__primary", disabled, children: busy ? "Creating\u2026" : "Create meeting" }),
8718
- link !== null ? /* @__PURE__ */ jsxs2("p", { className: "mx-meet__link-out", children: [
8719
- /* @__PURE__ */ jsx3("span", { children: "Anyone with this link can join \u2014 no account needed." }),
8720
- /* @__PURE__ */ jsx3("code", { children: link })
10333
+ /* @__PURE__ */ jsx4("button", { type: "submit", className: "mx-meet__primary", disabled, children: busy ? "Creating\u2026" : "Create meeting" }),
10334
+ link !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__link-out", children: [
10335
+ /* @__PURE__ */ jsx4("span", { children: "Anyone with this link can join \u2014 no account needed." }),
10336
+ /* @__PURE__ */ jsx4("code", { children: link })
8721
10337
  ] }) : null,
8722
- error !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__error", children: error }) : null
10338
+ error !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__error", children: error }) : null
8723
10339
  ]
8724
10340
  }
8725
10341
  );
@@ -8728,7 +10344,7 @@ function ReactionOverlay({
8728
10344
  reactions
8729
10345
  }) {
8730
10346
  if (reactions.length === 0) return null;
8731
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet__reactions", "aria-hidden": "true", children: reactions.map((reaction) => /* @__PURE__ */ jsx3("span", { className: "mx-meet__reaction", children: reaction.emoji }, reaction.id)) });
10347
+ return /* @__PURE__ */ jsx4("div", { className: "mx-meet__reactions", "aria-hidden": "true", children: reactions.map((reaction) => /* @__PURE__ */ jsx4("span", { className: "mx-meet__reaction", children: reaction.emoji }, reaction.id)) });
8732
10348
  }
8733
10349
  function GuestRecordAccessControl({
8734
10350
  meeting
@@ -8740,11 +10356,11 @@ function GuestRecordAccessControl({
8740
10356
  const isHost = inRoomHost || viewerId !== null && meeting.hostUserId === viewerId;
8741
10357
  if (host === null || !isHost) return null;
8742
10358
  const resolved = access.setting === "default" && access.effective !== null ? ` Right now that means: ${guestRecordAccessLabel(access.effective.level).toLowerCase()}.` : "";
8743
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "What guests may read", children: [
8744
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "What guests may read" }),
8745
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
8746
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "People who attended by link, without an account" }),
8747
- /* @__PURE__ */ jsx3(
10359
+ return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "What guests may read", children: [
10360
+ /* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "What guests may read" }),
10361
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
10362
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__field-label", children: "People who attended by link, without an account" }),
10363
+ /* @__PURE__ */ jsx4(
8748
10364
  "select",
8749
10365
  {
8750
10366
  className: "mx-meet__select",
@@ -8755,18 +10371,18 @@ function GuestRecordAccessControl({
8755
10371
  event.target.value
8756
10372
  );
8757
10373
  },
8758
- children: GUEST_RECORD_ACCESS_CHOICES.map((choice) => /* @__PURE__ */ jsx3("option", { value: choice, children: guestRecordAccessLabel(choice) }, choice))
10374
+ children: GUEST_RECORD_ACCESS_CHOICES.map((choice) => /* @__PURE__ */ jsx4("option", { value: choice, children: guestRecordAccessLabel(choice) }, choice))
8759
10375
  }
8760
10376
  )
8761
10377
  ] }),
8762
- /* @__PURE__ */ jsxs2("p", { className: "mx-meet__panel-note", children: [
10378
+ /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
8763
10379
  guestRecordAccessExplanation(access.setting),
8764
10380
  resolved
8765
10381
  ] }),
8766
- access.saving ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", role: "status", children: "Saving what guests may read\u2026" }) : null,
8767
- access.error !== null ? /* @__PURE__ */ jsxs2(ErrorBox, { as: "div", className: "mx-meet__refusal", error: access.error, operation: "Change who can join", origin: "meet/components", children: [
8768
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-reason", children: access.error.message }),
8769
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-remedy", children: access.error.remedy })
10382
+ access.saving ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", role: "status", children: "Saving what guests may read\u2026" }) : null,
10383
+ access.error !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: access.error, operation: "Change who can join", origin: "meet/components", children: [
10384
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-reason", children: access.error.message }),
10385
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-remedy", children: access.error.remedy })
8770
10386
  ] }) : null
8771
10387
  ] });
8772
10388
  }
@@ -8776,9 +10392,9 @@ function MeetingRecordView({
8776
10392
  }) {
8777
10393
  const host = useMeetHost();
8778
10394
  if (host === null) {
8779
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsx3(InertNotice, { what: "This meeting record" }) });
10395
+ return /* @__PURE__ */ jsx4("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsx4(InertNotice, { what: "This meeting record" }) });
8780
10396
  }
8781
- return /* @__PURE__ */ jsx3(MeetingRecordBody, { meeting, ...onRejoin !== void 0 ? { onRejoin } : {} });
10397
+ return /* @__PURE__ */ jsx4(MeetingRecordBody, { meeting, ...onRejoin !== void 0 ? { onRejoin } : {} });
8782
10398
  }
8783
10399
  function MeetingRecordBody({
8784
10400
  meeting,
@@ -8786,19 +10402,19 @@ function MeetingRecordBody({
8786
10402
  }) {
8787
10403
  const host = useRequiredMeetHost();
8788
10404
  const record = useMeetingRecord(meeting);
8789
- const [question, setQuestion] = useState3("");
8790
- const [tab, setTab] = useState3("summary");
10405
+ const [question, setQuestion] = useState4("");
10406
+ const [tab, setTab] = useState4("summary");
8791
10407
  if (record.failure !== null) {
8792
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsxs2(ErrorBox, { as: "div", className: "mx-meet__empty", error: record.failure, operation: "Open this meeting record", origin: "meet/components", children: [
8793
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-title", children: "This meeting record could not be opened" }),
8794
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-body", children: record.failure.message }),
8795
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-body", children: record.failure.remedy })
10408
+ return /* @__PURE__ */ jsx4("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__empty", error: record.failure, operation: "Open this meeting record", origin: "meet/components", children: [
10409
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-title", children: "This meeting record could not be opened" }),
10410
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-body", children: record.failure.message }),
10411
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-body", children: record.failure.remedy })
8796
10412
  ] }) });
8797
10413
  }
8798
10414
  if (record.loading || record.record === null) {
8799
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsxs2("div", { className: "mx-meet__empty", role: "status", children: [
8800
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-title", children: "Opening the meeting record\u2026" }),
8801
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-body", children: "Reading the summary, the notes and the transcript this meeting left behind." })
10415
+ return /* @__PURE__ */ jsx4("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__empty", role: "status", children: [
10416
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-title", children: "Opening the meeting record\u2026" }),
10417
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-body", children: "Reading the summary, the notes and the transcript this meeting left behind." })
8802
10418
  ] }) });
8803
10419
  }
8804
10420
  const bundle = record.record;
@@ -8817,44 +10433,44 @@ function MeetingRecordBody({
8817
10433
  );
8818
10434
  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;
8819
10435
  if (entirelyRestricted) {
8820
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet mx-meet--record", children: [
8821
- /* @__PURE__ */ jsx3("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ jsxs2("div", { className: "mx-meet__record-head-inner", children: [
8822
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
8823
- /* @__PURE__ */ jsx3("h1", { className: "mx-meet__record-title", children: meeting.title }),
8824
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
8825
- onRejoin !== void 0 ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
10436
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet mx-meet--record", children: [
10437
+ /* @__PURE__ */ jsx4("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-head-inner", children: [
10438
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
10439
+ /* @__PURE__ */ jsx4("h1", { className: "mx-meet__record-title", children: meeting.title }),
10440
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
10441
+ onRejoin !== void 0 ? /* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
8826
10442
  ] }) }),
8827
- /* @__PURE__ */ jsx3("div", { className: "mx-meet__record-body", children: restrictionNotices.map((notice2) => /* @__PURE__ */ jsxs2("div", { className: "mx-meet__record-access", role: "status", children: [
8828
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-access-title", children: "About this record" }),
8829
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-access-message", children: notice2.message }),
8830
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
10443
+ /* @__PURE__ */ jsx4("div", { className: "mx-meet__record-body", children: restrictionNotices.map((notice2) => /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-access", role: "status", children: [
10444
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-access-title", children: "About this record" }),
10445
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-access-message", children: notice2.message }),
10446
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
8831
10447
  ] }, notice2.parts.join("-"))) })
8832
10448
  ] });
8833
10449
  }
8834
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet mx-meet--record", children: [
8835
- /* @__PURE__ */ jsx3("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ jsxs2("div", { className: "mx-meet__record-head-inner", children: [
8836
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
8837
- /* @__PURE__ */ jsx3("h1", { className: "mx-meet__record-title", children: meeting.title }),
8838
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
8839
- onRejoin !== void 0 ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
10450
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet mx-meet--record", children: [
10451
+ /* @__PURE__ */ jsx4("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-head-inner", children: [
10452
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
10453
+ /* @__PURE__ */ jsx4("h1", { className: "mx-meet__record-title", children: meeting.title }),
10454
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
10455
+ onRejoin !== void 0 ? /* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
8840
10456
  ] }) }),
8841
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__record-body", children: [
8842
- restrictionNotices.map((notice2) => /* @__PURE__ */ jsxs2("div", { className: "mx-meet__record-access", role: "status", children: [
8843
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-access-title", children: "About this record" }),
8844
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-access-message", children: notice2.message }),
8845
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
10457
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-body", children: [
10458
+ restrictionNotices.map((notice2) => /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-access", role: "status", children: [
10459
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-access-title", children: "About this record" }),
10460
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-access-message", children: notice2.message }),
10461
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
8846
10462
  ] }, notice2.parts.join("-"))),
8847
10463
  attended.length === 0 ? (
8848
10464
  /* NOT SILENCE. A refused attendance read used to remove the whole
8849
10465
  section, so the reader could not tell "nobody" from "not shown". */
8850
- /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
8851
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
8852
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: absenceSentence(bundle, "attendance", "Nobody is recorded as having attended.") })
10466
+ /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
10467
+ /* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
10468
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: absenceSentence(bundle, "attendance", "Nobody is recorded as having attended.") })
8853
10469
  ] })
8854
- ) : /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
8855
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
8856
- /* @__PURE__ */ jsx3("ul", { className: "mx-meet__record-attendees", children: attended.map((person) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__record-attendee", children: [
8857
- /* @__PURE__ */ jsx3(
10470
+ ) : /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
10471
+ /* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
10472
+ /* @__PURE__ */ jsx4("ul", { className: "mx-meet__record-attendees", children: attended.map((person) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__record-attendee", children: [
10473
+ /* @__PURE__ */ jsx4(
8858
10474
  Avatar,
8859
10475
  {
8860
10476
  name: displayNameFor(bundle.names, person.identity, person.displayName),
@@ -8862,26 +10478,26 @@ function MeetingRecordBody({
8862
10478
  size: 28
8863
10479
  }
8864
10480
  ),
8865
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__person-name", children: [
10481
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
8866
10482
  displayNameFor(bundle.names, person.identity, person.displayName),
8867
- person.role === "host" ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Host" }) : null,
8868
- person.role === "guest" ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Guest" }) : null,
8869
- person.isAgent ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null
10483
+ person.role === "host" ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Host" }) : null,
10484
+ person.role === "guest" ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Guest" }) : null,
10485
+ person.isAgent ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null
8870
10486
  ] })
8871
10487
  ] }, person.id)) })
8872
10488
  ] }),
8873
- bundle.recording !== null ? /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section mx-meet__recording-card", "aria-label": "Recording", children: [
8874
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
8875
- fileId !== null ? /* @__PURE__ */ jsxs2(Fragment, { children: [
8876
- /* @__PURE__ */ jsx3(RecordingPlayer, { fileId }),
8877
- notice !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: notice }) : null
8878
- ] }) : /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: notice ?? "This recording has no file." })
8879
- ] }) : wasRefused(bundle, "recording") ? /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "Recording", children: [
8880
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
8881
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: REFUSED_ABSENCE })
10489
+ bundle.recording !== null ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section mx-meet__recording-card", "aria-label": "Recording", children: [
10490
+ /* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
10491
+ fileId !== null ? /* @__PURE__ */ jsxs3(Fragment, { children: [
10492
+ /* @__PURE__ */ jsx4(RecordingPlayer, { fileId }),
10493
+ notice !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: notice }) : null
10494
+ ] }) : /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: notice ?? "This recording has no file." })
10495
+ ] }) : wasRefused(bundle, "recording") ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Recording", children: [
10496
+ /* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
10497
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: REFUSED_ABSENCE })
8882
10498
  ] }) : null,
8883
- /* @__PURE__ */ jsxs2("nav", { className: "mx-meet__record-tabs", "aria-label": "Meeting record sections", children: [
8884
- /* @__PURE__ */ jsx3(
10499
+ /* @__PURE__ */ jsxs3("nav", { className: "mx-meet__record-tabs", "aria-label": "Meeting record sections", children: [
10500
+ /* @__PURE__ */ jsx4(
8885
10501
  "button",
8886
10502
  {
8887
10503
  type: "button",
@@ -8891,7 +10507,7 @@ function MeetingRecordBody({
8891
10507
  children: "Summary & decisions"
8892
10508
  }
8893
10509
  ),
8894
- /* @__PURE__ */ jsx3(
10510
+ /* @__PURE__ */ jsx4(
8895
10511
  "button",
8896
10512
  {
8897
10513
  type: "button",
@@ -8901,7 +10517,7 @@ function MeetingRecordBody({
8901
10517
  children: "Notes as it happened"
8902
10518
  }
8903
10519
  ),
8904
- /* @__PURE__ */ jsx3(
10520
+ /* @__PURE__ */ jsx4(
8905
10521
  "button",
8906
10522
  {
8907
10523
  type: "button",
@@ -8912,15 +10528,15 @@ function MeetingRecordBody({
8912
10528
  }
8913
10529
  )
8914
10530
  ] }),
8915
- tab === "summary" ? /* @__PURE__ */ jsxs2(Fragment, { children: [
8916
- /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "Summary", children: [
8917
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "Summary" }),
8918
- wrapUp.state === "written" ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-summary", children: bundle.summary?.text }) : wrapUp.state === "in-progress" ? /* @__PURE__ */ jsxs2("div", { className: "mx-meet__panel-note", role: "status", children: [
8919
- /* @__PURE__ */ jsx3("p", { children: wrapUp.message }),
8920
- /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: record.reload, children: "Check again" })
8921
- ] }) : /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", role: wrapUp.state === "failed" ? "alert" : void 0, children: wrapUp.message })
10531
+ tab === "summary" ? /* @__PURE__ */ jsxs3(Fragment, { children: [
10532
+ /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Summary", children: [
10533
+ /* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "Summary" }),
10534
+ wrapUp.state === "written" ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-summary", children: bundle.summary?.text }) : wrapUp.state === "in-progress" ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__panel-note", role: "status", children: [
10535
+ /* @__PURE__ */ jsx4("p", { children: wrapUp.message }),
10536
+ /* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__link", onClick: record.reload, children: "Check again" })
10537
+ ] }) : /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", role: wrapUp.state === "failed" ? "alert" : void 0, children: wrapUp.message })
8922
10538
  ] }),
8923
- /* @__PURE__ */ jsx3(
10539
+ /* @__PURE__ */ jsx4(
8924
10540
  NoteList,
8925
10541
  {
8926
10542
  title: "Decisions",
@@ -8932,7 +10548,7 @@ function MeetingRecordBody({
8932
10548
  )
8933
10549
  }
8934
10550
  ),
8935
- /* @__PURE__ */ jsx3(
10551
+ /* @__PURE__ */ jsx4(
8936
10552
  NoteList,
8937
10553
  {
8938
10554
  title: "Action items",
@@ -8945,42 +10561,42 @@ function MeetingRecordBody({
8945
10561
  }
8946
10562
  )
8947
10563
  ] }) : null,
8948
- tab === "notes" ? /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "Notes as it happened", children: [
8949
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "Notes as it happened" }),
8950
- bundle.liveNotes.length === 0 ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: absenceSentence(
10564
+ tab === "notes" ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Notes as it happened", children: [
10565
+ /* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "Notes as it happened" }),
10566
+ bundle.liveNotes.length === 0 ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: absenceSentence(
8951
10567
  bundle,
8952
10568
  "notes",
8953
10569
  "No live notes are available for this meeting."
8954
- ) }) : /* @__PURE__ */ jsx3("ul", { className: "mx-meet__notes", children: bundle.liveNotes.map((note) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__note", children: [
8955
- note.window !== null ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__badge", children: [
10570
+ ) }) : /* @__PURE__ */ jsx4("ul", { className: "mx-meet__notes", children: bundle.liveNotes.map((note) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__note", children: [
10571
+ note.window !== null ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__badge", children: [
8956
10572
  "Window ",
8957
10573
  note.window
8958
10574
  ] }) : null,
8959
10575
  note.text
8960
10576
  ] }, note.id)) })
8961
10577
  ] }) : null,
8962
- tab === "transcript" ? /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "Transcript", children: [
8963
- /* @__PURE__ */ jsxs2("h2", { className: "mx-meet__record-section-title", children: [
10578
+ tab === "transcript" ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Transcript", children: [
10579
+ /* @__PURE__ */ jsxs3("h2", { className: "mx-meet__record-section-title", children: [
8964
10580
  "Transcript",
8965
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__record-count", children: bundle.transcript.length === 1 ? "1 line" : `${bundle.transcript.length} lines` })
10581
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__record-count", children: bundle.transcript.length === 1 ? "1 line" : `${bundle.transcript.length} lines` })
8966
10582
  ] }),
8967
- blocks.length === 0 ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: absenceSentence(
10583
+ blocks.length === 0 ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: absenceSentence(
8968
10584
  bundle,
8969
10585
  "transcript",
8970
10586
  "No transcript is available for this meeting."
8971
- ) }) : /* @__PURE__ */ jsx3("ol", { className: "mx-meet__record-transcript", children: blocks.map((block) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__record-block", children: [
8972
- /* @__PURE__ */ jsxs2("p", { className: "mx-meet__record-speaker", children: [
10587
+ ) }) : /* @__PURE__ */ jsx4("ol", { className: "mx-meet__record-transcript", children: blocks.map((block) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__record-block", children: [
10588
+ /* @__PURE__ */ jsxs3("p", { className: "mx-meet__record-speaker", children: [
8973
10589
  block.speaker,
8974
- /* @__PURE__ */ jsx3("time", { className: "mx-meet__record-time", dateTime: block.startedAt, children: clockOf(block.startedAt) })
10590
+ /* @__PURE__ */ jsx4("time", { className: "mx-meet__record-time", dateTime: block.startedAt, children: clockOf(block.startedAt) })
8975
10591
  ] }),
8976
- block.lines.map((line) => /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-line", children: line.text }, line.id))
10592
+ block.lines.map((line) => /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-line", children: line.text }, line.id))
8977
10593
  ] }, block.id)) })
8978
10594
  ] }) : null,
8979
- /* @__PURE__ */ jsx3(GuestRecordAccessControl, { meeting }),
8980
- /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "Ask about this meeting", children: [
8981
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "Ask about this meeting" }),
8982
- guestFinishedMeeting ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: "Sign in to ask the assistant about a meeting after it ends." }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
8983
- /* @__PURE__ */ jsxs2(
10595
+ /* @__PURE__ */ jsx4(GuestRecordAccessControl, { meeting }),
10596
+ /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Ask about this meeting", children: [
10597
+ /* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "Ask about this meeting" }),
10598
+ guestFinishedMeeting ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: "Sign in to ask the assistant about a meeting after it ends." }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
10599
+ /* @__PURE__ */ jsxs3(
8984
10600
  "form",
8985
10601
  {
8986
10602
  className: "mx-meet__composer",
@@ -8991,7 +10607,7 @@ function MeetingRecordBody({
8991
10607
  void record.ask(trimmed);
8992
10608
  },
8993
10609
  children: [
8994
- /* @__PURE__ */ jsx3(
10610
+ /* @__PURE__ */ jsx4(
8995
10611
  "input",
8996
10612
  {
8997
10613
  className: "mx-meet__input",
@@ -9001,7 +10617,7 @@ function MeetingRecordBody({
9001
10617
  "aria-label": "Ask about this meeting"
9002
10618
  }
9003
10619
  ),
9004
- /* @__PURE__ */ jsx3(
10620
+ /* @__PURE__ */ jsx4(
9005
10621
  "button",
9006
10622
  {
9007
10623
  type: "submit",
@@ -9013,8 +10629,8 @@ function MeetingRecordBody({
9013
10629
  ]
9014
10630
  }
9015
10631
  ),
9016
- record.answer !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__answer", children: record.answer }) : null,
9017
- record.coverage !== null ? /* @__PURE__ */ jsxs2("p", { className: "mx-meet__coverage", children: [
10632
+ record.answer !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__answer", children: record.answer }) : null,
10633
+ record.coverage !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__coverage", children: [
9018
10634
  "Answered from ",
9019
10635
  record.coverage.segmentsUsed,
9020
10636
  " of ",
@@ -9025,9 +10641,9 @@ function MeetingRecordBody({
9025
10641
  record.coverage.truncated ? " (the oldest were left out)" : "",
9026
10642
  "."
9027
10643
  ] }) : null,
9028
- record.askError !== null ? /* @__PURE__ */ jsxs2(ErrorBox, { as: "div", className: "mx-meet__refusal", error: record.askError, operation: "Ask about this meeting", origin: "meet/components", children: [
9029
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-reason", children: record.askError.message }),
9030
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-remedy", children: record.askError.remedy })
10644
+ record.askError !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: record.askError, operation: "Ask about this meeting", origin: "meet/components", children: [
10645
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-reason", children: record.askError.message }),
10646
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-remedy", children: record.askError.remedy })
9031
10647
  ] }) : null
9032
10648
  ] })
9033
10649
  ] })
@@ -9038,21 +10654,21 @@ var STREAM_REFUSED = "Streaming playback did not start, so this recording was do
9038
10654
  var PLAYBACK_RETRY_REMEDY = "Reload the page and try again. If it still will not play, ask a meeting host to check the recording.";
9039
10655
  function RecordingPlayer(props) {
9040
10656
  const host = useMeetHost();
9041
- if (host === null) return /* @__PURE__ */ jsx3(InertNotice, { what: "This recording" });
9042
- return /* @__PURE__ */ jsx3(RecordingPlayerBody, { ...props, host });
10657
+ if (host === null) return /* @__PURE__ */ jsx4(InertNotice, { what: "This recording" });
10658
+ return /* @__PURE__ */ jsx4(RecordingPlayerBody, { ...props, host });
9043
10659
  }
9044
10660
  function RecordingPlayerBody({ fileId, host }) {
9045
- const [media, setMedia] = useState3(null);
9046
- const [loading, setLoading] = useState3(false);
9047
- const [error, setError] = useState3(null);
9048
- useEffect3(() => {
10661
+ const [media, setMedia] = useState4(null);
10662
+ const [loading, setLoading] = useState4(false);
10663
+ const [error, setError] = useState4(null);
10664
+ useEffect4(() => {
9049
10665
  if (media === null || media.kind !== "bytes") return void 0;
9050
10666
  const url = media.url;
9051
10667
  return () => URL.revokeObjectURL(url);
9052
10668
  }, [media]);
9053
10669
  if (media !== null) {
9054
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__record-section", children: [
9055
- /* @__PURE__ */ jsx3(
10670
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-section", children: [
10671
+ /* @__PURE__ */ jsx4(
9056
10672
  "video",
9057
10673
  {
9058
10674
  className: "mx-meet__record-player",
@@ -9094,15 +10710,15 @@ function RecordingPlayerBody({ fileId, host }) {
9094
10710
  }
9095
10711
  }
9096
10712
  ),
9097
- media.fallbackReason !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: media.fallbackReason }) : null
10713
+ media.fallbackReason !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: media.fallbackReason }) : null
9098
10714
  ] });
9099
10715
  }
9100
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__record-section", children: [
9101
- error !== null ? /* @__PURE__ */ jsxs2(ErrorBox, { as: "div", className: "mx-meet__refusal", error, operation: "Complete this meeting action", origin: "meet/components", children: [
9102
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-reason", children: error.message }),
9103
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-remedy", children: error.remedy })
10716
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-section", children: [
10717
+ error !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error, operation: "Complete this meeting action", origin: "meet/components", children: [
10718
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-reason", children: error.message }),
10719
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-remedy", children: error.remedy })
9104
10720
  ] }) : null,
9105
- /* @__PURE__ */ jsx3(
10721
+ /* @__PURE__ */ jsx4(
9106
10722
  "button",
9107
10723
  {
9108
10724
  type: "button",
@@ -9138,35 +10754,35 @@ function clockOf(iso) {
9138
10754
  function MeetingList({ baseUrl }) {
9139
10755
  const host = useMeetHost();
9140
10756
  const list = useMeetings();
9141
- if (host === null) return /* @__PURE__ */ jsx3(InertNotice, { what: "Your meetings" });
10757
+ if (host === null) return /* @__PURE__ */ jsx4(InertNotice, { what: "Your meetings" });
9142
10758
  if (list.failure !== null) {
9143
- return /* @__PURE__ */ jsxs2(ErrorBox, { as: "div", className: "mx-meet__empty", error: list.failure, operation: "List your meetings", origin: "meet/components", children: [
9144
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-title", children: "Your meetings could not be listed" }),
9145
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-body", children: list.failure.message }),
9146
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-body", children: list.failure.remedy })
10759
+ return /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__empty", error: list.failure, operation: "List your meetings", origin: "meet/components", children: [
10760
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-title", children: "Your meetings could not be listed" }),
10761
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-body", children: list.failure.message }),
10762
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-body", children: list.failure.remedy })
9147
10763
  ] });
9148
10764
  }
9149
10765
  if (list.loading) {
9150
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet__empty", role: "status", children: /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-title", children: "Loading your meetings\u2026" }) });
10766
+ return /* @__PURE__ */ jsx4("div", { className: "mx-meet__empty", role: "status", children: /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-title", children: "Loading your meetings\u2026" }) });
9151
10767
  }
9152
10768
  if (list.meetings.length === 0) {
9153
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__empty", role: "status", children: [
9154
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-title", children: "No meetings yet" }),
9155
- /* @__PURE__ */ jsx3("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." })
10769
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__empty", role: "status", children: [
10770
+ /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-title", children: "No meetings yet" }),
10771
+ /* @__PURE__ */ jsx4("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." })
9156
10772
  ] });
9157
10773
  }
9158
10774
  const origin = baseUrl ?? (typeof window === "undefined" ? "" : window.location.origin);
9159
- return /* @__PURE__ */ jsx3("ul", { className: "mx-meet-list", children: list.meetings.map((meeting) => {
10775
+ return /* @__PURE__ */ jsx4("ul", { className: "mx-meet-list", children: list.meetings.map((meeting) => {
9160
10776
  const ended = meeting.endedAt !== null;
9161
- return /* @__PURE__ */ jsxs2("li", { className: "mx-meet-list__row", children: [
9162
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet-list__main", children: [
9163
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet-list__title", children: [
10777
+ return /* @__PURE__ */ jsxs3("li", { className: "mx-meet-list__row", children: [
10778
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet-list__main", children: [
10779
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet-list__title", children: [
9164
10780
  meeting.title,
9165
- ended ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Ended" }) : null
10781
+ ended ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Ended" }) : null
9166
10782
  ] }),
9167
- /* @__PURE__ */ jsx3("span", { className: "mx-meet-list__when", children: meetingWhen(meeting) })
10783
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet-list__when", children: meetingWhen(meeting) })
9168
10784
  ] }),
9169
- /* @__PURE__ */ jsx3("a", { className: "mx-meet-list__action", href: meetingLink(origin, meeting.slug), children: ended ? "Open the record" : "Join" })
10785
+ /* @__PURE__ */ jsx4("a", { className: "mx-meet-list__action", href: meetingLink(origin, meeting.slug), children: ended ? "Open the record" : "Join" })
9170
10786
  ] }, meeting.id);
9171
10787
  }) });
9172
10788
  }
@@ -9323,15 +10939,22 @@ async function pushMeetingToGoogleCalendar(api, meetingId, target) {
9323
10939
  }
9324
10940
  export {
9325
10941
  ATTENDANCE_CSV_HEADER,
10942
+ ActivitiesControl,
10943
+ ActivitiesIcon,
9326
10944
  AiPanel,
9327
10945
  AttendanceNotice,
9328
10946
  Avatar,
10947
+ BreakoutBanner,
10948
+ BreakoutIcon,
10949
+ BreakoutsPanel,
9329
10950
  CALL_INVITE_KIND,
9330
10951
  CALL_INVITE_VERSION,
10952
+ CAPTION_LANGUAGES,
9331
10953
  CONSENT_NOTICE_ATTRIBUTE,
9332
10954
  CallButton,
9333
10955
  CameraIcon,
9334
10956
  CameraOffIcon,
10957
+ CaptionLanguageSettings,
9335
10958
  Captions,
9336
10959
  ChatIcon,
9337
10960
  ChatPanel,
@@ -9344,6 +10967,7 @@ export {
9344
10967
  DATA_TOPICS,
9345
10968
  DEFAULT_EFFECTS,
9346
10969
  DEFAULT_PAGE_SIZE,
10970
+ EMPTY_COLLAB,
9347
10971
  END_MEETING_NOT_SERVED,
9348
10972
  FILE_SESSION_PATH,
9349
10973
  FlagIcon,
@@ -9396,8 +11020,12 @@ export {
9396
11020
  PhoneIcon,
9397
11021
  PhoneOffIcon,
9398
11022
  PinIcon,
11023
+ PollIcon,
11024
+ PollsPanel,
9399
11025
  PreJoin,
11026
+ QaPanel,
9400
11027
  QualityBars,
11028
+ QuestionIcon,
9401
11029
  REACTION_TTL_MS,
9402
11030
  REFUSED_ABSENCE,
9403
11031
  ROLE_RANK,
@@ -9424,10 +11052,13 @@ export {
9424
11052
  TABLES,
9425
11053
  TRANSCRIPTION_ATTRIBUTES,
9426
11054
  TRANSCRIPTION_TOPIC,
11055
+ WhiteboardIcon,
11056
+ WhiteboardPanel,
9427
11057
  WifiLowIcon,
9428
11058
  absenceSentence,
9429
11059
  activeWrapUpSummary,
9430
11060
  announceMeeting,
11061
+ applyCollabPacket,
9431
11062
  applyRoomEvent,
9432
11063
  asCallId,
9433
11064
  asMeetingId,
@@ -9435,10 +11066,13 @@ export {
9435
11066
  asParticipantIdentity,
9436
11067
  asRoomName,
9437
11068
  asUserId,
11069
+ assignedRoom,
9438
11070
  attendanceCsv,
9439
11071
  attendanceReport,
9440
11072
  attendanceTotals,
9441
11073
  attendeeKey,
11074
+ autoAssign,
11075
+ breakoutRemainingMs,
9442
11076
  callInviteAction,
9443
11077
  callInviteText,
9444
11078
  callStateLabel,
@@ -9448,6 +11082,7 @@ export {
9448
11082
  captionSegment,
9449
11083
  changesPatch,
9450
11084
  clockPosition,
11085
+ collabFromState,
9451
11086
  computeStage,
9452
11087
  countLabel,
9453
11088
  createCallCenter,
@@ -9468,6 +11103,7 @@ export {
9468
11103
  createWebDeviceStorage,
9469
11104
  createWebEffectsStorage,
9470
11105
  createWebRoomTokenStorage,
11106
+ defaultCaptionLanguage,
9471
11107
  displayNameFor,
9472
11108
  fileDownloadPath,
9473
11109
  gridColumns,
@@ -9490,6 +11126,7 @@ export {
9490
11126
  listenOnlyNotice,
9491
11127
  loadFollowUpDraft,
9492
11128
  loadGuestMeetingRecord,
11129
+ loadMeetingActivities,
9493
11130
  loadMeetingChat,
9494
11131
  loadMeetingRecord,
9495
11132
  mapConnectionState,
@@ -9544,9 +11181,13 @@ export {
9544
11181
  unavailableFrom,
9545
11182
  uniqueAttendees,
9546
11183
  useAudioLevel,
11184
+ useAvailableActivities,
9547
11185
  useCalls,
9548
11186
  useCanModerate,
9549
11187
  useCanRecord,
11188
+ useCaptionTranslation,
11189
+ useCollab,
11190
+ useCollabPanelRequest,
9550
11191
  useConsentNotice,
9551
11192
  useDeviceSnapshot,
9552
11193
  useElapsed,
@@ -9578,6 +11219,7 @@ export {
9578
11219
  useTrack,
9579
11220
  userTopic,
9580
11221
  wasRefused,
11222
+ withItem,
9581
11223
  wrapUpStatus
9582
11224
  };
9583
11225
  //# sourceMappingURL=react.js.map