@ai-matrx/meet 0.7.9 → 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
  }
@@ -4322,6 +4863,15 @@ function createLiveKitDriver(handlers, options = {}) {
4322
4863
  handlers.participants([local, ...remotes]);
4323
4864
  };
4324
4865
  projectRoster = roster;
4866
+ created.on(RoomEvent.TrackSubscribed, (track) => {
4867
+ if (track.kind !== Track.Kind.Audio || typeof document === "undefined") return;
4868
+ const element = track.attach();
4869
+ element.setAttribute("data-mx-meet-audio", "");
4870
+ audioSink().appendChild(element);
4871
+ }).on(RoomEvent.TrackUnsubscribed, (track) => {
4872
+ if (track.kind !== Track.Kind.Audio) return;
4873
+ for (const element of track.detach()) element.remove();
4874
+ });
4325
4875
  created.on(RoomEvent.ParticipantConnected, roster).on(RoomEvent.ParticipantDisconnected, roster).on(RoomEvent.TrackSubscribed, roster).on(RoomEvent.TrackUnsubscribed, roster).on(RoomEvent.TrackMuted, roster).on(RoomEvent.TrackUnmuted, roster).on(RoomEvent.LocalTrackPublished, roster).on(RoomEvent.LocalTrackUnpublished, roster).on(RoomEvent.ParticipantNameChanged, roster).on(RoomEvent.ParticipantAttributesChanged, roster).on(RoomEvent.ParticipantMetadataChanged, roster).on(RoomEvent.RoomMetadataChanged, (metadata) => {
4326
4876
  handlers.roomMetadata?.(metadata ?? "");
4327
4877
  }).on(RoomEvent.ActiveSpeakersChanged, (speakers) => {
@@ -4337,6 +4887,8 @@ function createLiveKitDriver(handlers, options = {}) {
4337
4887
  participant?.identity ?? null
4338
4888
  );
4339
4889
  }).on(RoomEvent.Disconnected, (reason) => {
4890
+ audioContainer?.remove();
4891
+ audioContainer = null;
4340
4892
  handlers.disconnected(reason === void 0 ? null : String(reason));
4341
4893
  });
4342
4894
  try {
@@ -4378,10 +4930,26 @@ function createLiveKitDriver(handlers, options = {}) {
4378
4930
  microphone: Track.Source.Microphone,
4379
4931
  screen: Track.Source.ScreenShare
4380
4932
  };
4933
+ trackEvents = {
4934
+ subscribed: RoomEvent.TrackSubscribed,
4935
+ localPublished: RoomEvent.LocalTrackPublished
4936
+ };
4381
4937
  room = created;
4382
4938
  return created;
4383
4939
  }
4384
4940
  let sources = null;
4941
+ let trackEvents = null;
4942
+ let audioContainer = null;
4943
+ function audioSink() {
4944
+ if (audioContainer !== null && audioContainer.isConnected) return audioContainer;
4945
+ const container = document.createElement("div");
4946
+ container.setAttribute("data-mx-meet-audio-sink", "");
4947
+ container.setAttribute("aria-hidden", "true");
4948
+ container.style.display = "none";
4949
+ document.body.appendChild(container);
4950
+ audioContainer = container;
4951
+ return container;
4952
+ }
4385
4953
  function requireRoom(operation) {
4386
4954
  if (room === null) {
4387
4955
  throw new MeetError(
@@ -4412,6 +4980,8 @@ function createLiveKitDriver(handlers, options = {}) {
4412
4980
  } catch {
4413
4981
  }
4414
4982
  projectRoster = null;
4983
+ audioContainer?.remove();
4984
+ audioContainer = null;
4415
4985
  await target.disconnect();
4416
4986
  },
4417
4987
  async setMicrophoneEnabled(enabled) {
@@ -4477,14 +5047,33 @@ function createLiveKitDriver(handlers, options = {}) {
4477
5047
  attach(identity, kind, element) {
4478
5048
  const target = requireRoom("attach");
4479
5049
  const source = sources?.[kind];
4480
- const participant = target.localParticipant.identity === identity ? target.localParticipant : target.remoteParticipants.get(identity);
4481
- if (participant === void 0 || source === void 0) return () => void 0;
4482
- const publication = participant.getTrackPublication(source);
4483
- const track = publication?.track;
4484
- if (track === void 0) return () => void 0;
4485
- track.attach(element);
5050
+ if (source === void 0) return () => void 0;
5051
+ let current = null;
5052
+ const sync = () => {
5053
+ const participant = target.localParticipant.identity === identity ? target.localParticipant : target.remoteParticipants.get(identity);
5054
+ const track = participant?.getTrackPublication(source)?.track;
5055
+ if (track === void 0 || track === current) return;
5056
+ current?.detach(element);
5057
+ track.attach(element);
5058
+ current = track;
5059
+ };
5060
+ const onTrack = (...args) => {
5061
+ const who = args[args.length - 1];
5062
+ if (who?.identity === identity) sync();
5063
+ };
5064
+ sync();
5065
+ const events = trackEvents;
5066
+ if (events !== null) {
5067
+ target.on(events.subscribed, onTrack);
5068
+ target.on(events.localPublished, onTrack);
5069
+ }
4486
5070
  return () => {
4487
- track.detach(element);
5071
+ if (events !== null) {
5072
+ target.off(events.subscribed, onTrack);
5073
+ target.off(events.localPublished, onTrack);
5074
+ }
5075
+ current?.detach(element);
5076
+ current = null;
4488
5077
  };
4489
5078
  },
4490
5079
  activeDevices() {
@@ -4723,6 +5312,14 @@ function MeetRuntime(props) {
4723
5312
  }
4724
5313
  if (chatReadFor === snapshot.meeting.id) return;
4725
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
+ });
4726
5323
  void inRoom.loadChat().catch((error) => {
4727
5324
  const normalized = error;
4728
5325
  store.patch({
@@ -6063,7 +6660,7 @@ function useGuestRecordAccess(meeting) {
6063
6660
  }
6064
6661
 
6065
6662
  // src/react/components.tsx
6066
- 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";
6067
6664
  import { ErrorBox } from "@ai-matrx/design-system";
6068
6665
  import { avatarPaletteIndex, formatDurationMs as formatDurationMs3, getInitials } from "@ai-matrx/kit/format";
6069
6666
 
@@ -6074,6 +6671,7 @@ function kindOf(person) {
6074
6671
  if (person.role === "host") return "host";
6075
6672
  if (person.role === "cohost") return "cohost";
6076
6673
  if (person.role === "guest") return person.userId !== null ? "signed-in guest" : "guest";
6674
+ if (person.userId === null) return "guest";
6077
6675
  return "member";
6078
6676
  }
6079
6677
  function ms(iso) {
@@ -6129,12 +6727,19 @@ function coveredMs(intervals) {
6129
6727
  }
6130
6728
  function attendanceReport(meeting, attendees, names = {}) {
6131
6729
  const end = ms(meeting.endedAt);
6730
+ const measuredOf = /* @__PURE__ */ new Map();
6132
6731
  const perJoin = attendees.map((person) => {
6133
- const joined = ms(person.joinedAt);
6134
- const left = ms(person.leftAt);
6135
- const until = left ?? end;
6136
- const duration = joined !== null && until !== null && until >= joined ? until - joined : null;
6137
- 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 = {
6138
6743
  id: person.id,
6139
6744
  identity: person.identity,
6140
6745
  name: displayNameFor(names, person.identity, person.displayName),
@@ -6143,10 +6748,12 @@ function attendanceReport(meeting, attendees, names = {}) {
6143
6748
  joinedAt: person.joinedAt,
6144
6749
  leftAt: person.leftAt,
6145
6750
  durationMs: duration,
6146
- durationToEnd: duration !== null && left === null,
6751
+ durationToEnd: duration !== null && toEnd,
6147
6752
  admission: person.admissionState,
6148
- joins: 1
6753
+ joins: Math.max(1, person.sessions?.length ?? 0)
6149
6754
  };
6755
+ measuredOf.set(row, measured);
6756
+ return row;
6150
6757
  });
6151
6758
  const groups = /* @__PURE__ */ new Map();
6152
6759
  attendees.forEach((person, index) => {
@@ -6169,17 +6776,14 @@ function attendanceReport(meeting, attendees, names = {}) {
6169
6776
  const left = ms(row.leftAt);
6170
6777
  return left !== null && (latest === null || left > latest) ? left : latest;
6171
6778
  }, null);
6172
- const intervals = came.flatMap((row) => {
6173
- const joined = ms(row.joinedAt);
6174
- return joined !== null && row.durationMs !== null ? [[joined, joined + row.durationMs]] : [];
6175
- });
6779
+ const intervals = came.flatMap((row) => measuredOf.get(row) ?? []);
6176
6780
  return {
6177
6781
  ...first,
6178
6782
  kind,
6179
6783
  leftAt: open ? null : lastLeave === null ? null : new Date(lastLeave).toISOString(),
6180
6784
  durationMs: intervals.length === 0 ? null : coveredMs(intervals),
6181
6785
  durationToEnd: came.some((row) => row.durationToEnd),
6182
- joins: came.length === 0 ? joins.length : came.length
6786
+ joins: came.length === 0 ? joins.length : came.reduce((total, row) => total + row.joins, 0)
6183
6787
  };
6184
6788
  });
6185
6789
  const rank = KIND_RANK;
@@ -6323,8 +6927,8 @@ function transcriptDocument(bundle, format, options = {}) {
6323
6927
  if (line.identity !== last) {
6324
6928
  if (last !== null) out.push("");
6325
6929
  const who = speaker(line);
6326
- const clock = clockOfDay(line.startedAt, options);
6327
- 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})`);
6328
6932
  last = line.identity;
6329
6933
  }
6330
6934
  out.push(line.text.trim());
@@ -6505,6 +7109,9 @@ function countLabel(count2, singular, plural = `${singular}s`) {
6505
7109
  return `${count2} ${count2 === 1 ? singular : plural}`;
6506
7110
  }
6507
7111
 
7112
+ // src/react/collab.tsx
7113
+ import { useEffect as useEffect3, useRef as useRef3, useState as useState3 } from "react";
7114
+
6508
7115
  // src/react/icons.tsx
6509
7116
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
6510
7117
  function Icon({ children, ...props }) {
@@ -6689,60 +7296,1089 @@ function FlagIcon(props) {
6689
7296
  function PencilIcon(props) {
6690
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" }) });
6691
7298
  }
6692
-
6693
- // src/react/components.tsx
6694
- import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
6695
- function InertNotice({ what }) {
6696
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__empty", role: "status", children: [
6697
- /* @__PURE__ */ jsxs2("p", { className: "mx-meet__empty-title", children: [
6698
- what,
6699
- " is not ready yet"
6700
- ] }),
6701
- /* @__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" })
6702
7304
  ] });
6703
7305
  }
6704
- function Avatar({
6705
- name,
6706
- url,
6707
- size = 40
6708
- }) {
6709
- const tint = avatarPaletteIndex(name);
6710
- if (url != null && url.length > 0) {
6711
- return /* @__PURE__ */ jsx3(
6712
- "img",
6713
- {
6714
- className: "mx-meet__avatar",
6715
- src: url,
6716
- alt: "",
6717
- width: size,
6718
- height: size,
6719
- style: { width: size, height: size }
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
+ ] });
7312
+ }
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
+ ] });
7319
+ }
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
+ ] });
7326
+ }
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
+ ] });
7333
+ }
7334
+ function UpvoteIcon(props) {
7335
+ return /* @__PURE__ */ jsx2(Icon, { ...props, children: /* @__PURE__ */ jsx2("path", { d: "M9 18v-6H5l7-7 7 7h-4v6H9z" }) });
7336
+ }
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." };
6720
7384
  }
6721
- );
6722
- }
6723
- return /* @__PURE__ */ jsx3(
6724
- "span",
6725
- {
6726
- className: "mx-meet__avatar mx-meet__avatar--initials",
6727
- style: {
6728
- width: size,
6729
- height: size,
6730
- fontSize: Math.round(size * 0.38),
6731
- background: `var(--mx-meet-avatar-${tint})`
6732
- },
6733
- "aria-hidden": "true",
6734
- children: getInitials(name)
6735
7385
  }
6736
- );
7386
+ };
6737
7387
  }
6738
- function ControlButton({
6739
- label,
6740
- active = false,
6741
- danger = false,
6742
- onClick,
6743
- children
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
6744
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 }) {
6745
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(
6746
8382
  "button",
6747
8383
  {
6748
8384
  type: "button",
@@ -6761,14 +8397,14 @@ function ControlButton({
6761
8397
  function RecordingIndicator() {
6762
8398
  const { state, label } = useRecording();
6763
8399
  if (label === null) return null;
6764
- return /* @__PURE__ */ jsxs2(
8400
+ return /* @__PURE__ */ jsxs3(
6765
8401
  "span",
6766
8402
  {
6767
8403
  className: `mx-meet__recording mx-meet__recording--${state}`,
6768
8404
  role: "status",
6769
8405
  "aria-live": "polite",
6770
8406
  children: [
6771
- /* @__PURE__ */ jsx3(RecordIcon, { width: 10, height: 10 }),
8407
+ /* @__PURE__ */ jsx4(RecordIcon, { width: 10, height: 10 }),
6772
8408
  label
6773
8409
  ]
6774
8410
  }
@@ -6776,12 +8412,12 @@ function RecordingIndicator() {
6776
8412
  }
6777
8413
  function ConnectionDot({ quality }) {
6778
8414
  if (quality === "excellent" || quality === "good" || quality === "unknown") return null;
6779
- return /* @__PURE__ */ jsx3("span", { className: `mx-meet__quality mx-meet__quality--${quality}`, title: `Connection ${quality}`, children: /* @__PURE__ */ jsx3(WifiLowIcon, { width: 14, height: 14 }) });
8415
+ return /* @__PURE__ */ jsx4("span", { className: `mx-meet__quality mx-meet__quality--${quality}`, title: `Connection ${quality}`, children: /* @__PURE__ */ jsx4(WifiLowIcon, { width: 14, height: 14 }) });
6780
8416
  }
6781
8417
  function RoleBadge({ role }) {
6782
- if (role === "host") return /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Host" });
6783
- if (role === "cohost") return /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Co-host" });
6784
- if (role === "guest") return /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Guest" });
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" });
6785
8421
  return null;
6786
8422
  }
6787
8423
  function ParticipantTile({
@@ -6791,7 +8427,7 @@ function ParticipantTile({
6791
8427
  const host = useMeetHost();
6792
8428
  const snapshot = useMeetSnapshot();
6793
8429
  const queue = useHandQueue();
6794
- const [menu, setMenu] = useState3(false);
8430
+ const [menu, setMenu] = useState4(false);
6795
8431
  const videoRef = useTrack(
6796
8432
  participant.identity,
6797
8433
  participant.screenSharing ? "screen" : "camera"
@@ -6800,7 +8436,7 @@ function ParticipantTile({
6800
8436
  const pinnedHere = snapshot?.pinned === participant.identity;
6801
8437
  const spotlit = snapshot?.spotlight === participant.identity;
6802
8438
  const handPosition = participant.handRaised ? queue.findIndex((entry) => entry.identity === participant.identity) + 1 : 0;
6803
- return /* @__PURE__ */ jsxs2(
8439
+ return /* @__PURE__ */ jsxs3(
6804
8440
  "div",
6805
8441
  {
6806
8442
  className: [
@@ -6810,7 +8446,7 @@ function ParticipantTile({
6810
8446
  ].filter(Boolean).join(" "),
6811
8447
  "data-identity": participant.identity,
6812
8448
  children: [
6813
- showVideo ? /* @__PURE__ */ jsx3(
8449
+ showVideo ? /* @__PURE__ */ jsx4(
6814
8450
  "video",
6815
8451
  {
6816
8452
  ref: videoRef,
@@ -6819,43 +8455,43 @@ function ParticipantTile({
6819
8455
  playsInline: true,
6820
8456
  muted: participant.isLocal
6821
8457
  }
6822
- ) : /* @__PURE__ */ jsx3("div", { className: "mx-meet__tile-placeholder", children: /* @__PURE__ */ jsx3(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: featured ? 96 : 56 }) }),
6823
- participant.handRaised ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__tile-hand", title: `Hand raised \xB7 ${ordinal(handPosition)} in line`, children: [
6824
- /* @__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 }),
6825
8461
  handPosition > 0 ? handPosition : null
6826
8462
  ] }) : null,
6827
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__tile-bar", children: [
6828
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__tile-name", children: [
6829
- 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,
6830
8466
  participant.displayName,
6831
8467
  participant.isLocal ? " (you)" : "",
6832
- participant.isAgent ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "AI" }) : null,
6833
- /* @__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 })
6834
8470
  ] }),
6835
- !participant.micEnabled ? /* @__PURE__ */ jsx3(MicOffIcon, { width: 14, height: 14 }) : null,
6836
- /* @__PURE__ */ jsx3(QualityBars, { quality: participant.quality })
8471
+ !participant.micEnabled ? /* @__PURE__ */ jsx4(MicOffIcon, { width: 14, height: 14 }) : null,
8472
+ /* @__PURE__ */ jsx4(QualityBars, { quality: participant.quality })
6837
8473
  ] }),
6838
- /* @__PURE__ */ jsxs2("div", { className: menu ? "mx-meet__tile-actions mx-meet__tile-actions--open" : "mx-meet__tile-actions", children: [
6839
- /* @__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(
6840
8476
  ControlButton,
6841
8477
  {
6842
8478
  label: pinnedHere ? "Unpin" : `Pin ${participant.displayName} for me`,
6843
8479
  active: pinnedHere,
6844
8480
  onClick: () => host?.engine.pin(pinnedHere ? null : participant.identity),
6845
- children: /* @__PURE__ */ jsx3(PinIcon, { width: 16, height: 16 })
8481
+ children: /* @__PURE__ */ jsx4(PinIcon, { width: 16, height: 16 })
6846
8482
  }
6847
8483
  ),
6848
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__anchor", children: [
6849
- /* @__PURE__ */ jsx3(
8484
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
8485
+ /* @__PURE__ */ jsx4(
6850
8486
  ControlButton,
6851
8487
  {
6852
8488
  label: `More for ${participant.displayName}`,
6853
8489
  active: menu,
6854
8490
  onClick: () => setMenu(!menu),
6855
- children: /* @__PURE__ */ jsx3(MoreIcon, { width: 16, height: 16 })
8491
+ children: /* @__PURE__ */ jsx4(MoreIcon, { width: 16, height: 16 })
6856
8492
  }
6857
8493
  ),
6858
- menu ? /* @__PURE__ */ jsx3(PersonMenu, { participant, onClose: () => setMenu(false), placement: "down" }) : null
8494
+ menu ? /* @__PURE__ */ jsx4(PersonMenu, { participant, onClose: () => setMenu(false), placement: "down" }) : null
6859
8495
  ] })
6860
8496
  ] })
6861
8497
  ]
@@ -6871,28 +8507,28 @@ function QualityBars({ quality }) {
6871
8507
  if (quality === "unknown") return null;
6872
8508
  const bars = quality === "excellent" ? 3 : quality === "good" ? 2 : quality === "poor" ? 1 : 0;
6873
8509
  const label = quality === "lost" ? "Connection lost" : quality === "poor" ? "Poor connection" : `Connection ${quality}`;
6874
- 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 }) });
6875
8511
  }
6876
8512
  function Stage({ pageSize }) {
6877
8513
  const stage = useStage(pageSize);
6878
8514
  const columns = gridColumns(stage.tiles.length);
6879
8515
  if (stage.feature === null && stage.tiles.length === 0) {
6880
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__stage mx-meet__stage--empty", children: [
6881
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-title", children: "Waiting for others to join" }),
6882
- /* @__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." })
6883
8519
  ] });
6884
8520
  }
6885
- return /* @__PURE__ */ jsxs2("div", { className: `mx-meet__stage${stage.feature !== null ? " mx-meet__stage--speaker" : ""}`, children: [
6886
- stage.feature !== null ? /* @__PURE__ */ jsx3(ParticipantTile, { participant: stage.feature, featured: true }) : null,
6887
- /* @__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(
6888
8524
  "div",
6889
8525
  {
6890
8526
  className: "mx-meet__grid",
6891
8527
  style: { "--mx-meet-columns": columns },
6892
- children: stage.tiles.map((participant) => /* @__PURE__ */ jsx3(ParticipantTile, { participant }, participant.identity))
8528
+ children: stage.tiles.map((participant) => /* @__PURE__ */ jsx4(ParticipantTile, { participant }, participant.identity))
6893
8529
  }
6894
8530
  ),
6895
- stage.overflow > 0 ? /* @__PURE__ */ jsxs2("p", { className: "mx-meet__overflow", children: [
8531
+ stage.overflow > 0 ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__overflow", children: [
6896
8532
  "+",
6897
8533
  stage.overflow,
6898
8534
  " more ",
@@ -6905,20 +8541,28 @@ var MEET_REACTIONS = ["\u{1F496}", "\u{1F44D}", "\u{1F389}", "\u{1F44F}", "\u{1F
6905
8541
  function ControlBar({ onLeave }) {
6906
8542
  const room = useRoom();
6907
8543
  const recording = useRecording();
6908
- const [panel, setPanel] = useState3("none");
6909
- const [chatTo, setChatTo] = useState3(null);
6910
- const [popover, setPopover] = useState3("none");
6911
- 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);
6912
8548
  const snapshot = useMeetSnapshot();
6913
8549
  const lobby = useLobby();
6914
8550
  const controls = useHostControls();
6915
8551
  const queue = useHandQueue();
6916
8552
  const micUnavailable = useLocalMedia().microphone.unavailable;
6917
8553
  const unread = useUnreadChat(panel === "chat");
8554
+ const [whiteboard, setWhiteboard] = useState4(false);
6918
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
+ });
6919
8563
  const privateChatAt = snapshot?.privateChatRequest?.at ?? null;
6920
8564
  const meetStore = useMeetHost()?.store ?? null;
6921
- useEffect3(() => {
8565
+ useEffect4(() => {
6922
8566
  const request = meetStore?.snapshot().privateChatRequest ?? null;
6923
8567
  if (request === null) return;
6924
8568
  setChatTo(request.to);
@@ -6934,11 +8578,11 @@ function ControlBar({ onLeave }) {
6934
8578
  help: () => setShortcuts(true)
6935
8579
  });
6936
8580
  const hasSpotlight = snapshot?.spotlight !== null && snapshot?.spotlight !== void 0;
6937
- return /* @__PURE__ */ jsxs2(Fragment, { children: [
6938
- /* @__PURE__ */ jsx3(MeetingOverlays, {}),
6939
- shortcuts ? /* @__PURE__ */ jsx3(ShortcutsSheet, { onClose: () => setShortcuts(false) }) : null,
6940
- panel === "chat" ? /* @__PURE__ */ jsx3(ChatPanel, { onClose: () => setPanel("none"), to: chatTo, onTo: setChatTo }) : null,
6941
- 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(
6942
8586
  PeoplePanel,
6943
8587
  {
6944
8588
  onClose: () => setPanel("none"),
@@ -6948,48 +8592,53 @@ function ControlBar({ onLeave }) {
6948
8592
  }
6949
8593
  }
6950
8594
  ) : null,
6951
- panel === "ai" ? /* @__PURE__ */ jsx3(AiPanel, { onClose: () => setPanel("none") }) : null,
6952
- panel === "settings" ? /* @__PURE__ */ jsx3(SettingsPanel, { onClose: () => setPanel("none") }) : null,
6953
- controls.notice !== null && panel !== "people" ? /* @__PURE__ */ jsx3(Toast, { text: controls.notice.text, failed: controls.notice.failed, onDone: controls.clearNotice }) : null,
6954
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__controls", children: [
6955
- /* @__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(
6956
8605
  ControlButton,
6957
8606
  {
6958
8607
  label: micUnavailable !== null ? `Unmute \u2014 ${micUnavailable.remedy}` : room.local?.micEnabled === true ? "Mute (\u2318D)" : "Unmute (\u2318D)",
6959
8608
  active: room.local?.micEnabled === true,
6960
8609
  onClick: () => void room.toggleMicrophone(),
6961
- children: room.local?.micEnabled === true ? /* @__PURE__ */ jsx3(MicIcon, {}) : /* @__PURE__ */ jsx3(MicOffIcon, {})
8610
+ children: room.local?.micEnabled === true ? /* @__PURE__ */ jsx4(MicIcon, {}) : /* @__PURE__ */ jsx4(MicOffIcon, {})
6962
8611
  }
6963
8612
  ),
6964
- /* @__PURE__ */ jsx3(
8613
+ /* @__PURE__ */ jsx4(
6965
8614
  ControlButton,
6966
8615
  {
6967
8616
  label: room.local?.cameraEnabled === true ? "Stop video (\u2318E)" : "Start video (\u2318E)",
6968
8617
  active: room.local?.cameraEnabled === true,
6969
8618
  onClick: () => void room.toggleCamera(),
6970
- children: room.local?.cameraEnabled === true ? /* @__PURE__ */ jsx3(CameraIcon, {}) : /* @__PURE__ */ jsx3(CameraOffIcon, {})
8619
+ children: room.local?.cameraEnabled === true ? /* @__PURE__ */ jsx4(CameraIcon, {}) : /* @__PURE__ */ jsx4(CameraOffIcon, {})
6971
8620
  }
6972
8621
  ),
6973
- /* @__PURE__ */ jsx3(
8622
+ /* @__PURE__ */ jsx4(
6974
8623
  ControlButton,
6975
8624
  {
6976
8625
  label: room.local?.screenSharing === true ? "Stop sharing" : "Share screen",
6977
8626
  active: room.local?.screenSharing === true,
6978
8627
  onClick: () => void room.toggleScreenShare(),
6979
- children: /* @__PURE__ */ jsx3(ScreenShareIcon, {})
8628
+ children: /* @__PURE__ */ jsx4(ScreenShareIcon, {})
6980
8629
  }
6981
8630
  ),
6982
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__anchor", children: [
6983
- /* @__PURE__ */ jsx3(
8631
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
8632
+ /* @__PURE__ */ jsx4(
6984
8633
  ControlButton,
6985
8634
  {
6986
8635
  label: "Send a reaction",
6987
8636
  active: popover === "reactions",
6988
8637
  onClick: () => setPopover(popover === "reactions" ? "none" : "reactions"),
6989
- children: /* @__PURE__ */ jsx3(SmileIcon, {})
8638
+ children: /* @__PURE__ */ jsx4(SmileIcon, {})
6990
8639
  }
6991
8640
  ),
6992
- 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(
6993
8642
  "button",
6994
8643
  {
6995
8644
  type: "button",
@@ -7001,46 +8650,53 @@ function ControlBar({ onLeave }) {
7001
8650
  emoji
7002
8651
  )) }) }) : null
7003
8652
  ] }),
7004
- /* @__PURE__ */ jsx3(
8653
+ /* @__PURE__ */ jsx4(
7005
8654
  ControlButton,
7006
8655
  {
7007
8656
  label: room.local?.handRaised === true ? "Lower hand (\u2318\u2325H)" : "Raise hand (\u2318\u2325H)",
7008
8657
  active: room.local?.handRaised === true,
7009
8658
  onClick: () => void room.toggleHand(),
7010
- children: /* @__PURE__ */ jsx3(HandIcon, {})
8659
+ children: /* @__PURE__ */ jsx4(HandIcon, {})
7011
8660
  }
7012
8661
  ),
7013
- /* @__PURE__ */ jsxs2(ControlButton, { label: "Chat (\u2318\u2325C)", active: panel === "chat", onClick: () => toggle("chat"), children: [
7014
- /* @__PURE__ */ jsx3(ChatIcon, {}),
7015
- 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
7016
8665
  ] }),
7017
- /* @__PURE__ */ jsxs2(
8666
+ /* @__PURE__ */ jsxs3(
7018
8667
  ControlButton,
7019
8668
  {
7020
8669
  label: lobby.waiting.length > 0 ? `People \u2014 ${lobby.waiting.length} waiting` : `People \u2014 ${(snapshot?.participants ?? []).length} in the meeting`,
7021
8670
  active: panel === "people",
7022
8671
  onClick: () => toggle("people"),
7023
8672
  children: [
7024
- /* @__PURE__ */ jsx3(PeopleIcon, {}),
7025
- 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
7026
8675
  ]
7027
8676
  }
7028
8677
  ),
7029
- /* @__PURE__ */ jsx3(AiControl, { active: panel === "ai", onToggle: () => toggle("ai") }),
7030
- recording.canStart ? /* @__PURE__ */ jsx3(ControlButton, { label: "Start recording", onClick: () => void recording.start(), children: /* @__PURE__ */ jsx3(RecordIcon, {}) }) : null,
7031
- recording.canStop ? /* @__PURE__ */ jsx3(ControlButton, { label: "Stop recording", active: true, onClick: () => void recording.stop(), children: /* @__PURE__ */ jsx3(RecordIcon, {}) }) : null,
7032
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__anchor", children: [
7033
- /* @__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(
7034
8690
  ControlButton,
7035
8691
  {
7036
8692
  label: "More options",
7037
8693
  active: popover === "more" || panel === "settings",
7038
8694
  onClick: () => setPopover(popover === "more" ? "none" : "more"),
7039
- children: /* @__PURE__ */ jsx3(MoreIcon, {})
8695
+ children: /* @__PURE__ */ jsx4(MoreIcon, {})
7040
8696
  }
7041
8697
  ),
7042
- popover === "more" ? /* @__PURE__ */ jsx3(Popover, { label: "More options", onClose: () => setPopover("none"), children: /* @__PURE__ */ jsxs2("div", { className: "mx-meet__menu", role: "menu", children: [
7043
- /* @__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(
7044
8700
  MenuItem,
7045
8701
  {
7046
8702
  onSelect: () => {
@@ -7048,12 +8704,12 @@ function ControlBar({ onLeave }) {
7048
8704
  setPanel("settings");
7049
8705
  },
7050
8706
  children: [
7051
- /* @__PURE__ */ jsx3(SettingsIcon, { width: 16, height: 16 }),
7052
- " Audio, video and effects"
8707
+ /* @__PURE__ */ jsx4(SettingsIcon, { width: 16, height: 16 }),
8708
+ " Settings"
7053
8709
  ]
7054
8710
  }
7055
8711
  ),
7056
- /* @__PURE__ */ jsxs2(
8712
+ /* @__PURE__ */ jsxs3(
7057
8713
  MenuItem,
7058
8714
  {
7059
8715
  onSelect: () => {
@@ -7061,14 +8717,14 @@ function ControlBar({ onLeave }) {
7061
8717
  setShortcuts(true);
7062
8718
  },
7063
8719
  children: [
7064
- /* @__PURE__ */ jsx3(KeyboardIcon, { width: 16, height: 16 }),
8720
+ /* @__PURE__ */ jsx4(KeyboardIcon, { width: 16, height: 16 }),
7065
8721
  " Keyboard shortcuts"
7066
8722
  ]
7067
8723
  }
7068
8724
  ),
7069
- controls.isHost ? /* @__PURE__ */ jsxs2(Fragment, { children: [
7070
- /* @__PURE__ */ jsx3("div", { className: "mx-meet__menu-sep", role: "separator" }),
7071
- /* @__PURE__ */ jsxs2(
8725
+ controls.isHost ? /* @__PURE__ */ jsxs3(Fragment, { children: [
8726
+ /* @__PURE__ */ jsx4("div", { className: "mx-meet__menu-sep", role: "separator" }),
8727
+ /* @__PURE__ */ jsxs3(
7072
8728
  MenuItem,
7073
8729
  {
7074
8730
  onSelect: () => {
@@ -7076,12 +8732,12 @@ function ControlBar({ onLeave }) {
7076
8732
  void controls.run({ action: "mute_all" });
7077
8733
  },
7078
8734
  children: [
7079
- /* @__PURE__ */ jsx3(MicOffIcon, { width: 16, height: 16 }),
8735
+ /* @__PURE__ */ jsx4(MicOffIcon, { width: 16, height: 16 }),
7080
8736
  " Mute everyone"
7081
8737
  ]
7082
8738
  }
7083
8739
  ),
7084
- /* @__PURE__ */ jsxs2(
8740
+ /* @__PURE__ */ jsxs3(
7085
8741
  MenuItem,
7086
8742
  {
7087
8743
  onSelect: () => {
@@ -7089,12 +8745,12 @@ function ControlBar({ onLeave }) {
7089
8745
  void controls.run({ action: "ask_all_unmute" });
7090
8746
  },
7091
8747
  children: [
7092
- /* @__PURE__ */ jsx3(MicIcon, { width: 16, height: 16 }),
8748
+ /* @__PURE__ */ jsx4(MicIcon, { width: 16, height: 16 }),
7093
8749
  " Ask everyone to unmute"
7094
8750
  ]
7095
8751
  }
7096
8752
  ),
7097
- queue.length > 0 ? /* @__PURE__ */ jsxs2(
8753
+ queue.length > 0 ? /* @__PURE__ */ jsxs3(
7098
8754
  MenuItem,
7099
8755
  {
7100
8756
  onSelect: () => {
@@ -7102,14 +8758,14 @@ function ControlBar({ onLeave }) {
7102
8758
  void controls.run({ action: "lower_all_hands" });
7103
8759
  },
7104
8760
  children: [
7105
- /* @__PURE__ */ jsx3(HandIcon, { width: 16, height: 16 }),
8761
+ /* @__PURE__ */ jsx4(HandIcon, { width: 16, height: 16 }),
7106
8762
  " Lower all hands (",
7107
8763
  queue.length,
7108
8764
  ")"
7109
8765
  ]
7110
8766
  }
7111
8767
  ) : null,
7112
- hasSpotlight ? /* @__PURE__ */ jsxs2(
8768
+ hasSpotlight ? /* @__PURE__ */ jsxs3(
7113
8769
  MenuItem,
7114
8770
  {
7115
8771
  onSelect: () => {
@@ -7117,7 +8773,7 @@ function ControlBar({ onLeave }) {
7117
8773
  void controls.run({ action: "spotlight", identity: null });
7118
8774
  },
7119
8775
  children: [
7120
- /* @__PURE__ */ jsx3(SpotlightIcon, { width: 16, height: 16 }),
8776
+ /* @__PURE__ */ jsx4(SpotlightIcon, { width: 16, height: 16 }),
7121
8777
  " Remove spotlight"
7122
8778
  ]
7123
8779
  }
@@ -7125,7 +8781,7 @@ function ControlBar({ onLeave }) {
7125
8781
  ] }) : null
7126
8782
  ] }) }) : null
7127
8783
  ] }),
7128
- /* @__PURE__ */ jsx3(
8784
+ /* @__PURE__ */ jsx4(
7129
8785
  ControlButton,
7130
8786
  {
7131
8787
  label: "Leave",
@@ -7134,7 +8790,7 @@ function ControlBar({ onLeave }) {
7134
8790
  void room.leave();
7135
8791
  onLeave?.();
7136
8792
  },
7137
- children: /* @__PURE__ */ jsx3(PhoneOffIcon, {})
8793
+ children: /* @__PURE__ */ jsx4(PhoneOffIcon, {})
7138
8794
  }
7139
8795
  )
7140
8796
  ] })
@@ -7144,13 +8800,13 @@ function useUnreadChat(open) {
7144
8800
  const snapshot = useMeetSnapshot();
7145
8801
  const chat = snapshot?.chat ?? [];
7146
8802
  const local = snapshot?.localIdentity ?? null;
7147
- const [seen, setSeen] = useState3(0);
7148
- useEffect3(() => {
8803
+ const [seen, setSeen] = useState4(0);
8804
+ useEffect4(() => {
7149
8805
  if (open) setSeen(chat.length);
7150
8806
  }, [open, chat.length]);
7151
8807
  const loaded = snapshot?.chatLoaded === true;
7152
- const [baseline, setBaseline] = useState3(null);
7153
- useEffect3(() => {
8808
+ const [baseline, setBaseline] = useState4(null);
8809
+ useEffect4(() => {
7154
8810
  if (loaded && baseline === null) setBaseline(chat.length);
7155
8811
  }, [loaded, baseline, chat.length]);
7156
8812
  if (open) return 0;
@@ -7163,8 +8819,8 @@ function Popover({
7163
8819
  children,
7164
8820
  placement = "up"
7165
8821
  }) {
7166
- const ref = useRef3(null);
7167
- const [style, setStyle] = useState3({
8822
+ const ref = useRef4(null);
8823
+ const [style, setStyle] = useState4({
7168
8824
  position: "fixed",
7169
8825
  top: 0,
7170
8826
  left: 0,
@@ -7215,7 +8871,7 @@ function Popover({
7215
8871
  window.removeEventListener("scroll", place, true);
7216
8872
  };
7217
8873
  }, [placement]);
7218
- useEffect3(() => {
8874
+ useEffect4(() => {
7219
8875
  const onKey = (event) => {
7220
8876
  if (event.key === "Escape") onClose();
7221
8877
  };
@@ -7230,14 +8886,14 @@ function Popover({
7230
8886
  window.removeEventListener("pointerdown", onPointer);
7231
8887
  };
7232
8888
  }, [onClose]);
7233
- 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 });
7234
8890
  }
7235
8891
  function MenuItem({
7236
8892
  onSelect,
7237
8893
  danger = false,
7238
8894
  children
7239
8895
  }) {
7240
- return /* @__PURE__ */ jsx3(
8896
+ return /* @__PURE__ */ jsx4(
7241
8897
  "button",
7242
8898
  {
7243
8899
  type: "button",
@@ -7249,28 +8905,28 @@ function MenuItem({
7249
8905
  );
7250
8906
  }
7251
8907
  function Toast({ text: text3, failed, onDone }) {
7252
- useEffect3(() => {
8908
+ useEffect4(() => {
7253
8909
  const timer = setTimeout(onDone, failed ? 7e3 : 4e3);
7254
8910
  return () => clearTimeout(timer);
7255
8911
  }, [text3, failed, onDone]);
7256
- return /* @__PURE__ */ jsxs2("div", { className: failed ? "mx-meet__toast mx-meet__toast--failed" : "mx-meet__toast", role: "status", children: [
7257
- /* @__PURE__ */ jsx3("span", { children: text3 }),
7258
- /* @__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 }) })
7259
8915
  ] });
7260
8916
  }
7261
8917
  function MeetingOverlays() {
7262
8918
  const reactions = useReactions();
7263
8919
  const { notice, dismiss } = useModerationNotice();
7264
8920
  const room = useRoom();
7265
- return /* @__PURE__ */ jsxs2(Fragment, { children: [
7266
- /* @__PURE__ */ jsx3(ReactionOverlay, { reactions }),
8921
+ return /* @__PURE__ */ jsxs3(Fragment, { children: [
8922
+ /* @__PURE__ */ jsx4(ReactionOverlay, { reactions }),
7267
8923
  notice !== null && notice.kind !== "removed" ? (
7268
8924
  // A host's request ("the host is asking you to unmute"), not an error:
7269
8925
  // an assertive status, so it is announced at once without being filed
7270
8926
  // as a failure (design-system error-box census).
7271
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__notice-bar", role: "status", "aria-live": "assertive", children: [
7272
- /* @__PURE__ */ jsx3("span", { children: notice.text }),
7273
- 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(
7274
8930
  "button",
7275
8931
  {
7276
8932
  type: "button",
@@ -7282,20 +8938,20 @@ function MeetingOverlays() {
7282
8938
  children: "Unmute"
7283
8939
  }
7284
8940
  ) : null,
7285
- /* @__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 }) })
7286
8942
  ] })
7287
8943
  ) : null
7288
8944
  ] });
7289
8945
  }
7290
8946
  function ShortcutsSheet({ onClose }) {
7291
- useEffect3(() => {
8947
+ useEffect4(() => {
7292
8948
  const onKey = (event) => {
7293
8949
  if (event.key === "Escape") onClose();
7294
8950
  };
7295
8951
  window.addEventListener("keydown", onKey);
7296
8952
  return () => window.removeEventListener("keydown", onKey);
7297
8953
  }, [onClose]);
7298
- 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(
7299
8955
  "div",
7300
8956
  {
7301
8957
  className: "mx-meet__sheet",
@@ -7303,13 +8959,13 @@ function ShortcutsSheet({ onClose }) {
7303
8959
  "aria-label": "Keyboard shortcuts",
7304
8960
  onClick: (event) => event.stopPropagation(),
7305
8961
  children: [
7306
- /* @__PURE__ */ jsxs2("header", { className: "mx-meet__panel-head", children: [
7307
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__panel-title", children: "Keyboard shortcuts" }),
7308
- /* @__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 }) })
7309
8965
  ] }),
7310
- /* @__PURE__ */ jsx3("dl", { className: "mx-meet__shortcuts", children: MEET_SHORTCUTS.map((shortcut) => /* @__PURE__ */ jsxs2("div", { className: "mx-meet__shortcut", children: [
7311
- /* @__PURE__ */ jsx3("dt", { children: shortcut.label }),
7312
- /* @__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 }) })
7313
8969
  ] }, shortcut.id)) })
7314
8970
  ]
7315
8971
  }
@@ -7319,19 +8975,19 @@ function AiControl({ active, onToggle }) {
7319
8975
  const snapshot = useMeetSnapshot();
7320
8976
  const meeting = snapshot?.meeting ?? null;
7321
8977
  if (meeting === null || !meeting.aiEnabled) return null;
7322
- 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, {}) });
7323
8979
  }
7324
8980
  function PanelShell({
7325
8981
  title,
7326
8982
  onClose,
7327
8983
  children
7328
8984
  }) {
7329
- return /* @__PURE__ */ jsxs2("aside", { className: "mx-meet__panel", "aria-label": title, children: [
7330
- /* @__PURE__ */ jsxs2("header", { className: "mx-meet__panel-head", children: [
7331
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__panel-title", children: title }),
7332
- /* @__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 }) })
7333
8989
  ] }),
7334
- /* @__PURE__ */ jsx3("div", { className: "mx-meet__panel-body", children })
8990
+ /* @__PURE__ */ jsx4("div", { className: "mx-meet__panel-body", children })
7335
8991
  ] });
7336
8992
  }
7337
8993
  function ChatPanel({
@@ -7341,17 +8997,17 @@ function ChatPanel({
7341
8997
  }) {
7342
8998
  const snapshot = useMeetSnapshot();
7343
8999
  const room = useRoom();
7344
- const [draft, setDraft] = useState3("");
7345
- const [recipient, setRecipient] = useState3(to);
7346
- const listRef = useRef3(null);
9000
+ const [draft, setDraft] = useState4("");
9001
+ const [recipient, setRecipient] = useState4(to);
9002
+ const listRef = useRef4(null);
7347
9003
  const messages = snapshot?.chat ?? [];
7348
9004
  const local = snapshot?.localIdentity ?? null;
7349
9005
  const people = (snapshot?.participants ?? []).filter(
7350
9006
  (participant) => !participant.isLocal && !participant.isAgent
7351
9007
  );
7352
9008
  const recipientName = recipient === null ? null : people.find((p) => p.identity === recipient)?.displayName ?? null;
7353
- useEffect3(() => setRecipient(to), [to]);
7354
- useEffect3(() => {
9009
+ useEffect4(() => setRecipient(to), [to]);
9010
+ useEffect4(() => {
7355
9011
  const list = listRef.current;
7356
9012
  if (list !== null) list.scrollTop = list.scrollHeight;
7357
9013
  }, [messages.length]);
@@ -7359,13 +9015,13 @@ function ChatPanel({
7359
9015
  setRecipient(next);
7360
9016
  onTo?.(next);
7361
9017
  };
7362
- return /* @__PURE__ */ jsxs2(PanelShell, { title: "Chat", onClose, children: [
7363
- /* @__PURE__ */ jsxs2("ul", { className: "mx-meet__chat", ref: listRef, children: [
7364
- snapshot?.chatHistoryError != null ? /* @__PURE__ */ jsx3("li", { className: "mx-meet__panel-note", children: snapshot.chatHistoryError }) : null,
7365
- 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,
7366
- 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))
7367
9023
  ] }),
7368
- /* @__PURE__ */ jsxs2(
9024
+ /* @__PURE__ */ jsxs3(
7369
9025
  "form",
7370
9026
  {
7371
9027
  className: "mx-meet__composer mx-meet__composer--chat",
@@ -7378,7 +9034,7 @@ function ChatPanel({
7378
9034
  else void room.sendPrivateChat(recipient, text3);
7379
9035
  },
7380
9036
  children: [
7381
- people.length > 0 ? /* @__PURE__ */ jsxs2(
9037
+ people.length > 0 ? /* @__PURE__ */ jsxs3(
7382
9038
  "select",
7383
9039
  {
7384
9040
  className: "mx-meet__select mx-meet__select--compact",
@@ -7386,16 +9042,16 @@ function ChatPanel({
7386
9042
  value: recipient ?? "",
7387
9043
  onChange: (event) => choose(event.target.value === "" ? null : event.target.value),
7388
9044
  children: [
7389
- /* @__PURE__ */ jsx3("option", { value: "", children: "Everyone" }),
7390
- 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: [
7391
9047
  participant.displayName,
7392
9048
  " (private)"
7393
9049
  ] }, participant.identity))
7394
9050
  ]
7395
9051
  }
7396
9052
  ) : null,
7397
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__composer-row", children: [
7398
- /* @__PURE__ */ jsx3(
9053
+ /* @__PURE__ */ jsxs3("div", { className: "mx-meet__composer-row", children: [
9054
+ /* @__PURE__ */ jsx4(
7399
9055
  "input",
7400
9056
  {
7401
9057
  className: "mx-meet__input",
@@ -7406,9 +9062,9 @@ function ChatPanel({
7406
9062
  maxLength: 4e3
7407
9063
  }
7408
9064
  ),
7409
- /* @__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" })
7410
9066
  ] }),
7411
- recipientName !== null ? /* @__PURE__ */ jsxs2("p", { className: "mx-meet__panel-note", children: [
9067
+ recipientName !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
7412
9068
  "Only ",
7413
9069
  recipientName,
7414
9070
  " sees this. Private messages are not saved."
@@ -7426,7 +9082,7 @@ function ChatLine({
7426
9082
  const mine = message.identity === local;
7427
9083
  const privateTo = message.to ?? null;
7428
9084
  const counterpart = privateTo === null ? null : mine ? people.find((p) => p.identity === privateTo)?.displayName ?? "them" : "you";
7429
- return /* @__PURE__ */ jsxs2(
9085
+ return /* @__PURE__ */ jsxs3(
7430
9086
  "li",
7431
9087
  {
7432
9088
  className: [
@@ -7435,17 +9091,17 @@ function ChatLine({
7435
9091
  message.failed !== void 0 ? "mx-meet__chat-line--failed" : ""
7436
9092
  ].filter(Boolean).join(" "),
7437
9093
  children: [
7438
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__chat-meta", children: [
7439
- /* @__PURE__ */ jsx3("strong", { children: mine ? "You" : message.displayName }),
7440
- 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: [
7441
9097
  "to ",
7442
9098
  counterpart,
7443
9099
  " \xB7 private"
7444
9100
  ] }) : null,
7445
- /* @__PURE__ */ jsx3("time", { dateTime: message.at, children: clockOf(message.at) })
9101
+ /* @__PURE__ */ jsx4("time", { dateTime: message.at, children: clockOf(message.at) })
7446
9102
  ] }),
7447
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__chat-text", children: message.text }),
7448
- 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
7449
9105
  ]
7450
9106
  }
7451
9107
  );
@@ -7457,22 +9113,22 @@ function PeoplePanel({
7457
9113
  const snapshot = useMeetSnapshot();
7458
9114
  const controls = useHostControls();
7459
9115
  const queue = useHandQueue();
7460
- const [query, setQuery] = useState3("");
7461
- const [menuFor, setMenuFor] = useState3(null);
9116
+ const [query, setQuery] = useState4("");
9117
+ const [menuFor, setMenuFor] = useState4(null);
7462
9118
  const myRole = useRole();
7463
9119
  const local = snapshot?.localIdentity ?? null;
7464
9120
  const everyone = snapshot?.participants ?? [];
7465
9121
  const needle = query.trim().toLowerCase();
7466
9122
  const shown = needle.length === 0 ? everyone : everyone.filter((participant) => participant.displayName.toLowerCase().includes(needle));
7467
- return /* @__PURE__ */ jsxs2(PanelShell, { title: `People (${everyone.length})`, onClose, children: [
7468
- /* @__PURE__ */ jsx3(LobbyPanel, {}),
7469
- queue.length > 0 ? /* @__PURE__ */ jsxs2("section", { className: "mx-meet__section", "aria-label": "Raised hands", children: [
7470
- /* @__PURE__ */ jsxs2("header", { className: "mx-meet__section-head", children: [
7471
- /* @__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: [
7472
9128
  "Raised hands \xB7 ",
7473
9129
  queue.length
7474
9130
  ] }),
7475
- controls.isHost ? /* @__PURE__ */ jsx3(
9131
+ controls.isHost ? /* @__PURE__ */ jsx4(
7476
9132
  "button",
7477
9133
  {
7478
9134
  type: "button",
@@ -7482,13 +9138,13 @@ function PeoplePanel({
7482
9138
  }
7483
9139
  ) : null
7484
9140
  ] }),
7485
- /* @__PURE__ */ jsx3("ol", { className: "mx-meet__queue", children: queue.map((participant) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__person", children: [
7486
- /* @__PURE__ */ jsx3(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 28 }),
7487
- /* @__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: [
7488
9144
  participant.displayName,
7489
- 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
7490
9146
  ] }),
7491
- controls.isHost || participant.identity === local ? /* @__PURE__ */ jsx3(
9147
+ controls.isHost || participant.identity === local ? /* @__PURE__ */ jsx4(
7492
9148
  "button",
7493
9149
  {
7494
9150
  type: "button",
@@ -7499,27 +9155,27 @@ function PeoplePanel({
7499
9155
  ) : null
7500
9156
  ] }, participant.identity)) })
7501
9157
  ] }) : null,
7502
- controls.isHost && everyone.length > 1 ? /* @__PURE__ */ jsxs2("div", { className: "mx-meet__bulk", children: [
7503
- /* @__PURE__ */ jsxs2("button", { type: "button", className: "mx-meet__chip", onClick: () => void controls.run({ action: "mute_all" }), children: [
7504
- /* @__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 }),
7505
9161
  " Mute all"
7506
9162
  ] }),
7507
- /* @__PURE__ */ jsxs2(
9163
+ /* @__PURE__ */ jsxs3(
7508
9164
  "button",
7509
9165
  {
7510
9166
  type: "button",
7511
9167
  className: "mx-meet__chip",
7512
9168
  onClick: () => void controls.run({ action: "ask_all_unmute" }),
7513
9169
  children: [
7514
- /* @__PURE__ */ jsx3(MicIcon, { width: 14, height: 14 }),
9170
+ /* @__PURE__ */ jsx4(MicIcon, { width: 14, height: 14 }),
7515
9171
  " Ask all to unmute"
7516
9172
  ]
7517
9173
  }
7518
9174
  )
7519
9175
  ] }) : null,
7520
- everyone.length > 4 ? /* @__PURE__ */ jsxs2("label", { className: "mx-meet__search", children: [
7521
- /* @__PURE__ */ jsx3(SearchIcon, { width: 16, height: 16 }),
7522
- /* @__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(
7523
9179
  "input",
7524
9180
  {
7525
9181
  className: "mx-meet__input mx-meet__input--bare",
@@ -7530,31 +9186,31 @@ function PeoplePanel({
7530
9186
  }
7531
9187
  )
7532
9188
  ] }) : null,
7533
- controls.notice !== null ? /* @__PURE__ */ jsx3("p", { className: controls.notice.failed ? "mx-meet__error" : "mx-meet__notice", role: "status", children: controls.notice.text }) : null,
7534
- /* @__PURE__ */ jsxs2("ul", { className: "mx-meet__people", children: [
7535
- shown.map((participant) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__person", children: [
7536
- /* @__PURE__ */ jsx3(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 32 }),
7537
- /* @__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: [
7538
9194
  participant.displayName,
7539
- participant.identity === local ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__you", children: " (you)" }) : null,
7540
- /* @__PURE__ */ jsx3(RoleBadge, { role: participant.identity === local ? myRole : participant.role }),
7541
- isNoteTaker(participant) ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null,
7542
- 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
7543
9199
  ] }),
7544
- participant.handRaised ? /* @__PURE__ */ jsx3(HandIcon, { width: 14, height: 14 }) : null,
7545
- !participant.micEnabled && !isNoteTaker(participant) ? /* @__PURE__ */ jsx3(MicOffIcon, { width: 14, height: 14 }) : null,
7546
- /* @__PURE__ */ jsx3(QualityBars, { quality: participant.quality }),
7547
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__anchor", children: [
7548
- /* @__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(
7549
9205
  ControlButton,
7550
9206
  {
7551
9207
  label: `More for ${participant.displayName}`,
7552
9208
  active: menuFor === participant.identity,
7553
9209
  onClick: () => setMenuFor(menuFor === participant.identity ? null : participant.identity),
7554
- children: /* @__PURE__ */ jsx3(MoreIcon, { width: 16, height: 16 })
9210
+ children: /* @__PURE__ */ jsx4(MoreIcon, { width: 16, height: 16 })
7555
9211
  }
7556
9212
  ),
7557
- menuFor === participant.identity ? /* @__PURE__ */ jsx3(
9213
+ menuFor === participant.identity ? /* @__PURE__ */ jsx4(
7558
9214
  PersonMenu,
7559
9215
  {
7560
9216
  participant,
@@ -7565,13 +9221,13 @@ function PeoplePanel({
7565
9221
  ) : null
7566
9222
  ] })
7567
9223
  ] }, participant.identity)),
7568
- 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: [
7569
9225
  "Nobody matches \u201C",
7570
9226
  query,
7571
9227
  "\u201D."
7572
9228
  ] }) : null
7573
9229
  ] }),
7574
- 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
7575
9231
  ] });
7576
9232
  }
7577
9233
  function PersonMenu({
@@ -7583,14 +9239,14 @@ function PersonMenu({
7583
9239
  const host = useMeetHost();
7584
9240
  const snapshot = useMeetSnapshot();
7585
9241
  const controls = useHostControls();
7586
- const [mode, setMode] = useState3("menu");
7587
- const [text3, setText] = useState3("");
9242
+ const [mode, setMode] = useState4("menu");
9243
+ const [text3, setText] = useState4("");
7588
9244
  const self = participant.identity === snapshot?.localIdentity;
7589
9245
  const moderate = controls.canModerate(participant);
7590
9246
  const pinned = snapshot?.pinned === participant.identity;
7591
9247
  const spotlit = snapshot?.spotlight === participant.identity;
7592
9248
  const hasAccount = participant.userId !== null;
7593
- const [refused, setRefused] = useState3(false);
9249
+ const [refused, setRefused] = useState4(false);
7594
9250
  const act = (request) => {
7595
9251
  setRefused(false);
7596
9252
  void controls.run(request).then((result) => {
@@ -7598,10 +9254,10 @@ function PersonMenu({
7598
9254
  else setRefused(true);
7599
9255
  });
7600
9256
  };
7601
- 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;
7602
9258
  if (mode === "rename" || mode === "report") {
7603
9259
  const renaming = mode === "rename";
7604
- 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(
7605
9261
  "form",
7606
9262
  {
7607
9263
  className: "mx-meet__menu-form",
@@ -7613,9 +9269,9 @@ function PersonMenu({
7613
9269
  );
7614
9270
  },
7615
9271
  children: [
7616
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
7617
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: renaming ? "Name shown in this meeting" : `What did ${participant.displayName} do?` }),
7618
- 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(
7619
9275
  "input",
7620
9276
  {
7621
9277
  className: "mx-meet__input",
@@ -7624,7 +9280,7 @@ function PersonMenu({
7624
9280
  value: text3,
7625
9281
  onChange: (event) => setText(event.target.value)
7626
9282
  }
7627
- ) : /* @__PURE__ */ jsx3(
9283
+ ) : /* @__PURE__ */ jsx4(
7628
9284
  "textarea",
7629
9285
  {
7630
9286
  className: "mx-meet__input",
@@ -7637,9 +9293,9 @@ function PersonMenu({
7637
9293
  )
7638
9294
  ] }),
7639
9295
  refusal2,
7640
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__menu-actions", children: [
7641
- /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Back" }),
7642
- /* @__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" })
7643
9299
  ] })
7644
9300
  ]
7645
9301
  }
@@ -7647,12 +9303,12 @@ function PersonMenu({
7647
9303
  }
7648
9304
  if (mode === "remove" || mode === "transfer") {
7649
9305
  const removing = mode === "remove";
7650
- return /* @__PURE__ */ jsx3(Popover, { label: removing ? "Remove" : "Make host", onClose, placement, children: /* @__PURE__ */ jsxs2("div", { className: "mx-meet__menu-form", children: [
7651
- /* @__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.` }),
7652
9308
  refusal2,
7653
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__menu-actions", children: [
7654
- /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Cancel" }),
7655
- /* @__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(
7656
9312
  "button",
7657
9313
  {
7658
9314
  type: "button",
@@ -7665,8 +9321,8 @@ function PersonMenu({
7665
9321
  ] })
7666
9322
  ] }) });
7667
9323
  }
7668
- return /* @__PURE__ */ jsx3(Popover, { label: `Options for ${participant.displayName}`, onClose, placement, children: /* @__PURE__ */ jsxs2("div", { className: "mx-meet__menu", role: "menu", children: [
7669
- /* @__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(
7670
9326
  MenuItem,
7671
9327
  {
7672
9328
  onSelect: () => {
@@ -7674,13 +9330,13 @@ function PersonMenu({
7674
9330
  onClose();
7675
9331
  },
7676
9332
  children: [
7677
- /* @__PURE__ */ jsx3(PinIcon, { width: 16, height: 16 }),
9333
+ /* @__PURE__ */ jsx4(PinIcon, { width: 16, height: 16 }),
7678
9334
  " ",
7679
9335
  pinned ? "Unpin" : "Pin for me"
7680
9336
  ]
7681
9337
  }
7682
9338
  ),
7683
- !self && !participant.isAgent && (onMessage !== void 0 || host !== null) ? /* @__PURE__ */ jsxs2(
9339
+ !self && !participant.isAgent && (onMessage !== void 0 || host !== null) ? /* @__PURE__ */ jsxs3(
7684
9340
  MenuItem,
7685
9341
  {
7686
9342
  onSelect: () => {
@@ -7692,42 +9348,42 @@ function PersonMenu({
7692
9348
  onClose();
7693
9349
  },
7694
9350
  children: [
7695
- /* @__PURE__ */ jsx3(ChatIcon, { width: 16, height: 16 }),
9351
+ /* @__PURE__ */ jsx4(ChatIcon, { width: 16, height: 16 }),
7696
9352
  " Message privately"
7697
9353
  ]
7698
9354
  }
7699
9355
  ) : null,
7700
- controls.isHost ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "spotlight", identity: spotlit ? null : participant.identity }), children: [
7701
- /* @__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 }),
7702
9358
  " ",
7703
9359
  spotlit ? "Remove spotlight" : "Spotlight for everyone"
7704
9360
  ] }) : null,
7705
- moderate ? /* @__PURE__ */ jsxs2(Fragment, { children: [
7706
- /* @__PURE__ */ jsx3("div", { className: "mx-meet__menu-sep", role: "separator" }),
7707
- participant.micEnabled ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "mute", identity: participant.identity }), children: [
7708
- /* @__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 }),
7709
9365
  " Mute"
7710
- ] }) : !participant.isAgent ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "ask_unmute", identity: participant.identity }), children: [
7711
- /* @__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 }),
7712
9368
  " Ask to unmute"
7713
9369
  ] }) : null,
7714
- participant.cameraEnabled ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "stop_video", identity: participant.identity }), children: [
7715
- /* @__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 }),
7716
9372
  " Stop video"
7717
9373
  ] }) : null,
7718
- participant.screenSharing ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "stop_screen", identity: participant.identity }), children: [
7719
- /* @__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 }),
7720
9376
  " Stop screen share"
7721
9377
  ] }) : null,
7722
- participant.handRaised ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "lower_hand", identity: participant.identity }), children: [
7723
- /* @__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 }),
7724
9380
  " Lower hand"
7725
9381
  ] }) : null,
7726
- hasAccount && !participant.isAgent && participant.role !== "cohost" ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "make_cohost", identity: participant.identity }), children: [
7727
- /* @__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 }),
7728
9384
  " Make co-host"
7729
9385
  ] }) : null,
7730
- !participant.isAgent ? /* @__PURE__ */ jsxs2(
9386
+ !participant.isAgent ? /* @__PURE__ */ jsxs3(
7731
9387
  MenuItem,
7732
9388
  {
7733
9389
  onSelect: () => {
@@ -7735,21 +9391,21 @@ function PersonMenu({
7735
9391
  setMode("rename");
7736
9392
  },
7737
9393
  children: [
7738
- /* @__PURE__ */ jsx3(PencilIcon, { width: 16, height: 16 }),
9394
+ /* @__PURE__ */ jsx4(PencilIcon, { width: 16, height: 16 }),
7739
9395
  " Rename"
7740
9396
  ]
7741
9397
  }
7742
9398
  ) : null
7743
9399
  ] }) : null,
7744
- controls.isOwner && participant.role === "cohost" ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => act({ action: "revoke_cohost", identity: participant.identity }), children: [
7745
- /* @__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 }),
7746
9402
  " Remove co-host"
7747
9403
  ] }) : null,
7748
- controls.isOwner && !self && hasAccount && !participant.isAgent ? /* @__PURE__ */ jsxs2(MenuItem, { onSelect: () => setMode("transfer"), children: [
7749
- /* @__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 }),
7750
9406
  " Make host"
7751
9407
  ] }) : null,
7752
- self ? /* @__PURE__ */ jsxs2(
9408
+ self ? /* @__PURE__ */ jsxs3(
7753
9409
  MenuItem,
7754
9410
  {
7755
9411
  onSelect: () => {
@@ -7757,12 +9413,12 @@ function PersonMenu({
7757
9413
  setMode("rename");
7758
9414
  },
7759
9415
  children: [
7760
- /* @__PURE__ */ jsx3(PencilIcon, { width: 16, height: 16 }),
9416
+ /* @__PURE__ */ jsx4(PencilIcon, { width: 16, height: 16 }),
7761
9417
  " Rename yourself"
7762
9418
  ]
7763
9419
  }
7764
9420
  ) : null,
7765
- !self && !participant.isAgent ? /* @__PURE__ */ jsxs2(
9421
+ !self && !participant.isAgent ? /* @__PURE__ */ jsxs3(
7766
9422
  MenuItem,
7767
9423
  {
7768
9424
  onSelect: () => {
@@ -7770,21 +9426,21 @@ function PersonMenu({
7770
9426
  setMode("report");
7771
9427
  },
7772
9428
  children: [
7773
- /* @__PURE__ */ jsx3(FlagIcon, { width: 16, height: 16 }),
9429
+ /* @__PURE__ */ jsx4(FlagIcon, { width: 16, height: 16 }),
7774
9430
  " Report"
7775
9431
  ]
7776
9432
  }
7777
9433
  ) : null,
7778
- moderate && !participant.isAgent ? /* @__PURE__ */ jsxs2(MenuItem, { danger: true, onSelect: () => setMode("remove"), children: [
7779
- /* @__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 }),
7780
9436
  " Remove from meeting"
7781
9437
  ] }) : null
7782
9438
  ] }) });
7783
9439
  }
7784
9440
  function SettingsPanel({ onClose }) {
7785
9441
  const host = useRequiredMeetHost();
7786
- return /* @__PURE__ */ jsxs2(PanelShell, { title: "Audio, video and effects", onClose, children: [
7787
- /* @__PURE__ */ jsx3(
9442
+ return /* @__PURE__ */ jsxs3(PanelShell, { title: "Settings", onClose, children: [
9443
+ /* @__PURE__ */ jsx4(
7788
9444
  DeviceSettings,
7789
9445
  {
7790
9446
  onPick: (kind, deviceId2) => {
@@ -7793,7 +9449,8 @@ function SettingsPanel({ onClose }) {
7793
9449
  }
7794
9450
  }
7795
9451
  ),
7796
- /* @__PURE__ */ jsx3(EffectsSettings, {})
9452
+ /* @__PURE__ */ jsx4(EffectsSettings, {}),
9453
+ /* @__PURE__ */ jsx4(CaptionLanguageSettings, {})
7797
9454
  ] });
7798
9455
  }
7799
9456
  function DeviceSettings({
@@ -7805,15 +9462,15 @@ function DeviceSettings({
7805
9462
  const speaker = devices?.selected.audiooutput ?? host.devices.resolve("audiooutput");
7806
9463
  const stream = useMicrophoneStream(microphone);
7807
9464
  const level = useAudioLevel(stream);
7808
- const [testing, setTesting] = useState3(false);
7809
- useEffect3(() => {
9465
+ const [testing, setTesting] = useState4(false);
9466
+ useEffect4(() => {
7810
9467
  void host.devices.refresh();
7811
9468
  }, [host]);
7812
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__section", "aria-label": "Devices", children: [
7813
- /* @__PURE__ */ jsx3(DevicePicker, { kind: "audioinput", label: "Microphone", onPick }),
7814
- /* @__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))}%` } }) }),
7815
- /* @__PURE__ */ jsx3(DevicePicker, { kind: "audiooutput", label: "Speaker", onPick }),
7816
- /* @__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(
7817
9474
  "button",
7818
9475
  {
7819
9476
  type: "button",
@@ -7824,19 +9481,19 @@ function DeviceSettings({
7824
9481
  void playTestSound(speaker).finally(() => setTesting(false));
7825
9482
  },
7826
9483
  children: [
7827
- /* @__PURE__ */ jsx3(SpeakerIcon, { width: 14, height: 14 }),
9484
+ /* @__PURE__ */ jsx4(SpeakerIcon, { width: 14, height: 14 }),
7828
9485
  " ",
7829
9486
  testing ? "Playing\u2026" : "Test speaker"
7830
9487
  ]
7831
9488
  }
7832
9489
  ),
7833
- /* @__PURE__ */ jsx3(DevicePicker, { kind: "videoinput", label: "Camera", onPick })
9490
+ /* @__PURE__ */ jsx4(DevicePicker, { kind: "videoinput", label: "Camera", onPick })
7834
9491
  ] });
7835
9492
  }
7836
9493
  function EffectsSettings({ preview }) {
7837
9494
  const effects = useMediaEffects();
7838
- const [error, setError] = useState3(null);
7839
- const fileRef = useRef3(null);
9495
+ const [error, setError] = useState4(null);
9496
+ const fileRef = useRef4(null);
7840
9497
  const supported = effects.backgroundsSupported || preview != null || videoEffectsSupported();
7841
9498
  const apply = (next) => {
7842
9499
  setError(null);
@@ -7848,9 +9505,9 @@ function EffectsSettings({ preview }) {
7848
9505
  );
7849
9506
  }
7850
9507
  };
7851
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__section", "aria-label": "Effects", children: [
7852
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
7853
- /* @__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(
7854
9511
  "input",
7855
9512
  {
7856
9513
  type: "checkbox",
@@ -7859,11 +9516,11 @@ function EffectsSettings({ preview }) {
7859
9516
  }
7860
9517
  ),
7861
9518
  "Noise suppression",
7862
- /* @__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." })
7863
9520
  ] }),
7864
- supported ? /* @__PURE__ */ jsxs2("div", { className: "mx-meet__field", children: [
7865
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "Background" }),
7866
- /* @__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(
7867
9524
  "button",
7868
9525
  {
7869
9526
  type: "button",
@@ -7881,7 +9538,7 @@ function EffectsSettings({ preview }) {
7881
9538
  },
7882
9539
  kind
7883
9540
  )) }),
7884
- /* @__PURE__ */ jsx3(
9541
+ /* @__PURE__ */ jsx4(
7885
9542
  "input",
7886
9543
  {
7887
9544
  ref: fileRef,
@@ -7896,7 +9553,7 @@ function EffectsSettings({ preview }) {
7896
9553
  }
7897
9554
  }
7898
9555
  ),
7899
- 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
7900
9557
  ] }) : null
7901
9558
  ] });
7902
9559
  }
@@ -7955,8 +9612,8 @@ async function playTestSound(sinkId) {
7955
9612
  await context.close();
7956
9613
  }
7957
9614
  function useMicrophoneStream(deviceId2) {
7958
- const [stream, setStream] = useState3(null);
7959
- useEffect3(() => {
9615
+ const [stream, setStream] = useState4(null);
9616
+ useEffect4(() => {
7960
9617
  if (deviceId2 === "off") return void 0;
7961
9618
  let live = true;
7962
9619
  let opened = null;
@@ -7981,25 +9638,25 @@ function useMicrophoneStream(deviceId2) {
7981
9638
  function LobbyPanel() {
7982
9639
  const lobby = useLobby();
7983
9640
  if (!lobby.canAdmit || lobby.waiting.length === 0) return null;
7984
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__lobby", "aria-label": "Waiting room", children: [
7985
- /* @__PURE__ */ jsxs2("header", { className: "mx-meet__lobby-head", children: [
7986
- /* @__PURE__ */ jsx3("h3", { className: "mx-meet__lobby-title", children: lobby.waiting.length === 1 ? "1 person is waiting" : `${lobby.waiting.length} people are waiting` }),
7987
- /* @__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" })
7988
9645
  ] }),
7989
- /* @__PURE__ */ jsx3("ul", { className: "mx-meet__lobby-list", children: lobby.waiting.map((entry) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__lobby-row", children: [
7990
- /* @__PURE__ */ jsx3(Avatar, { name: entry.displayName, url: entry.avatarUrl, size: 32 }),
7991
- /* @__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: [
7992
9649
  entry.displayName,
7993
- 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
7994
9651
  ] }),
7995
- /* @__PURE__ */ jsx3(ControlButton, { label: `Admit ${entry.displayName}`, onClick: () => void lobby.admit(entry), children: /* @__PURE__ */ jsx3(CheckIcon, { width: 16, height: 16 }) }),
7996
- /* @__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(
7997
9654
  ControlButton,
7998
9655
  {
7999
9656
  label: `Deny ${entry.displayName}`,
8000
9657
  danger: true,
8001
9658
  onClick: () => void lobby.deny(entry),
8002
- children: /* @__PURE__ */ jsx3(CloseIcon, { width: 16, height: 16 })
9659
+ children: /* @__PURE__ */ jsx4(CloseIcon, { width: 16, height: 16 })
8003
9660
  }
8004
9661
  )
8005
9662
  ] }, entry.identity)) })
@@ -8009,21 +9666,21 @@ function NoteTakerRow() {
8009
9666
  const ai = useMeetAi();
8010
9667
  const status = ai.noteTaker;
8011
9668
  const duplicateError = status.refusal !== null && ai.error !== null && status.refusal.reason === ai.error.message && status.refusal.remedy === ai.error.remedy;
8012
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__note-taker", "aria-label": "Note-taker", children: [
8013
- /* @__PURE__ */ jsxs2("p", { className: `mx-meet__note-taker-state mx-meet__note-taker-state--${status.state}`, children: [
8014
- /* @__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" }),
8015
9672
  ai.noteTakerLabel
8016
9673
  ] }),
8017
- status.detail !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: status.detail }) : null,
8018
- status.refusal !== null ? /* @__PURE__ */ jsxs2(ErrorBox, { as: "div", className: "mx-meet__refusal", error: status.refusal, operation: "Join this meeting", origin: "meet/components", children: [
8019
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-reason", children: status.refusal.reason }),
8020
- 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
8021
9678
  ] }) : null,
8022
- 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: [
8023
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
8024
- /* @__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 })
8025
9682
  ] }) : null,
8026
- 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(
8027
9684
  "button",
8028
9685
  {
8029
9686
  type: "button",
@@ -8031,7 +9688,7 @@ function NoteTakerRow() {
8031
9688
  onClick: () => void ai.stopNoteTaker(),
8032
9689
  children: "Dismiss the note-taker"
8033
9690
  }
8034
- ) : /* @__PURE__ */ jsx3(
9691
+ ) : /* @__PURE__ */ jsx4(
8035
9692
  "button",
8036
9693
  {
8037
9694
  type: "button",
@@ -8047,24 +9704,24 @@ function NoteList({
8047
9704
  notes,
8048
9705
  empty
8049
9706
  }) {
8050
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__note-group", "aria-label": title, children: [
8051
- /* @__PURE__ */ jsx3("h3", { className: "mx-meet__note-group-title", children: title }),
8052
- 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: [
8053
9710
  note.text,
8054
- 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
8055
9712
  ] }, note.id)) })
8056
9713
  ] });
8057
9714
  }
8058
9715
  function AiPanel({ onClose }) {
8059
9716
  const ai = useMeetAi();
8060
- const [question, setQuestion] = useState3("");
8061
- return /* @__PURE__ */ jsxs2(PanelShell, { title: "Meeting assistant", onClose, children: [
8062
- /* @__PURE__ */ jsx3(NoteTakerRow, {}),
8063
- ai.summary !== null ? /* @__PURE__ */ jsxs2("section", { className: "mx-meet__note-group", "aria-label": "Summary", children: [
8064
- /* @__PURE__ */ jsx3("h3", { className: "mx-meet__note-group-title", children: "Summary" }),
8065
- /* @__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 })
8066
9723
  ] }) : null,
8067
- 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: [
8068
9725
  "The wrap-up is written \u2014 ",
8069
9726
  ai.wrapUp.noteIds.length,
8070
9727
  " ",
@@ -8076,7 +9733,7 @@ function AiPanel({ onClose }) {
8076
9733
  ai.wrapUp.segmentCount === 1 ? "transcript line" : "transcript lines",
8077
9734
  "."
8078
9735
  ] }) : null,
8079
- /* @__PURE__ */ jsx3(
9736
+ /* @__PURE__ */ jsx4(
8080
9737
  NoteList,
8081
9738
  {
8082
9739
  title: "Notes",
@@ -8084,7 +9741,7 @@ function AiPanel({ onClose }) {
8084
9741
  empty: "Notes appear here as the meeting goes on."
8085
9742
  }
8086
9743
  ),
8087
- /* @__PURE__ */ jsx3(
9744
+ /* @__PURE__ */ jsx4(
8088
9745
  NoteList,
8089
9746
  {
8090
9747
  title: "Decisions",
@@ -8092,7 +9749,7 @@ function AiPanel({ onClose }) {
8092
9749
  empty: "Nothing has been decided yet."
8093
9750
  }
8094
9751
  ),
8095
- /* @__PURE__ */ jsx3(
9752
+ /* @__PURE__ */ jsx4(
8096
9753
  NoteList,
8097
9754
  {
8098
9755
  title: "Action items",
@@ -8100,21 +9757,21 @@ function AiPanel({ onClose }) {
8100
9757
  empty: "No action items yet."
8101
9758
  }
8102
9759
  ),
8103
- ai.transcript.length > 0 ? /* @__PURE__ */ jsxs2("section", { className: "mx-meet__note-group", "aria-label": "Transcript", children: [
8104
- /* @__PURE__ */ jsx3("h3", { className: "mx-meet__note-group-title", children: "Transcript" }),
8105
- /* @__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(
8106
9763
  "li",
8107
9764
  {
8108
9765
  className: line.final && line.source === "record" ? "mx-meet__line" : "mx-meet__line mx-meet__line--interim",
8109
9766
  children: [
8110
- /* @__PURE__ */ jsx3("strong", { children: line.speaker }),
8111
- /* @__PURE__ */ jsx3("span", { children: line.text })
9767
+ /* @__PURE__ */ jsx4("strong", { children: line.speaker }),
9768
+ /* @__PURE__ */ jsx4("span", { children: line.text })
8112
9769
  ]
8113
9770
  },
8114
9771
  line.id
8115
9772
  )) })
8116
9773
  ] }) : null,
8117
- /* @__PURE__ */ jsxs2(
9774
+ /* @__PURE__ */ jsxs3(
8118
9775
  "form",
8119
9776
  {
8120
9777
  className: "mx-meet__composer",
@@ -8125,7 +9782,7 @@ function AiPanel({ onClose }) {
8125
9782
  void ai.ask(asked);
8126
9783
  },
8127
9784
  children: [
8128
- /* @__PURE__ */ jsx3(
9785
+ /* @__PURE__ */ jsx4(
8129
9786
  "input",
8130
9787
  {
8131
9788
  className: "mx-meet__input",
@@ -8135,13 +9792,13 @@ function AiPanel({ onClose }) {
8135
9792
  "aria-label": "Ask about this meeting"
8136
9793
  }
8137
9794
  ),
8138
- /* @__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" })
8139
9796
  ]
8140
9797
  }
8141
9798
  ),
8142
- ai.asking && ai.phase !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", role: "status", children: ai.phase }) : null,
8143
- ai.answer !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__answer", children: ai.answer }) : null,
8144
- 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: [
8145
9802
  "Answered from ",
8146
9803
  ai.coverage.segmentsUsed,
8147
9804
  " of ",
@@ -8150,48 +9807,56 @@ function AiPanel({ onClose }) {
8150
9807
  ai.coverage.truncated ? " (the oldest were left out)" : "",
8151
9808
  "."
8152
9809
  ] }) : null,
8153
- ai.error !== null ? /* @__PURE__ */ jsxs2(ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
8154
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
8155
- /* @__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 })
8156
9813
  ] }) : null
8157
9814
  ] });
8158
9815
  }
8159
9816
  function Captions({ lines = 3 }) {
8160
9817
  const ai = useMeetAi();
8161
9818
  const visible = ai.transcript.slice(-lines);
9819
+ const translation = useCaptionTranslation(visible);
8162
9820
  if (visible.length === 0) return null;
8163
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet__captions", "aria-live": "polite", "aria-label": "Live captions", children: visible.map((line) => /* @__PURE__ */ jsxs2(
8164
- "p",
8165
- {
8166
- className: line.final ? "mx-meet__caption" : "mx-meet__caption mx-meet__caption--interim",
8167
- children: [
8168
- /* @__PURE__ */ jsx3("strong", { children: line.speaker }),
8169
- " ",
8170
- line.text
8171
- ]
8172
- },
8173
- line.id
8174
- )) });
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
+ ] });
8175
9840
  }
8176
9841
  function ConsentNotice() {
8177
9842
  const notice = useConsentNotice();
8178
9843
  if (notice === null) return null;
8179
- 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 });
8180
9845
  }
8181
9846
  function AttendanceNotice() {
8182
9847
  const media = useLocalMedia();
8183
9848
  const notice = listenOnlyNotice(media);
8184
9849
  if (notice === null) return null;
8185
9850
  const refused = media.microphone.unavailable;
8186
- 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: [
8187
9852
  notice,
8188
- 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 })
8189
9854
  ] });
8190
9855
  }
8191
9856
  function PreJoin(props) {
8192
9857
  const host = useMeetHost();
8193
- if (host === null) return /* @__PURE__ */ jsx3(InertNotice, { what: "This meeting" });
8194
- return /* @__PURE__ */ jsx3(PreJoinBody, { ...props, host });
9858
+ if (host === null) return /* @__PURE__ */ jsx4(InertNotice, { what: "This meeting" });
9859
+ return /* @__PURE__ */ jsx4(PreJoinBody, { ...props, host });
8195
9860
  }
8196
9861
  function PreJoinBody({
8197
9862
  roomName,
@@ -8205,21 +9870,21 @@ function PreJoinBody({
8205
9870
  const recording = useRecording();
8206
9871
  const effects = useMediaEffects();
8207
9872
  const { notice } = useModerationNotice();
8208
- const [mode, setMode] = useState3("video");
8209
- const [microphone, setMicrophone] = useState3(true);
8210
- const [joining, setJoining] = useState3(false);
9873
+ const [mode, setMode] = useState4("video");
9874
+ const [microphone, setMicrophone] = useState4(true);
9875
+ const [joining, setJoining] = useState4(false);
8211
9876
  const camera = devices?.selected.videoinput ?? host.devices.resolve("videoinput");
8212
9877
  const mic = devices?.selected.audioinput ?? host.devices.resolve("audioinput");
8213
9878
  const preview = useCameraPreview(mode === "video" ? camera : void 0, effects.effects);
8214
9879
  const micStream = useMicrophoneStream(microphone ? mic : "off");
8215
9880
  const level = useAudioLevel(micStream);
8216
- const [speakerTesting, setSpeakerTesting] = useState3(false);
8217
- useEffect3(() => {
9881
+ const [speakerTesting, setSpeakerTesting] = useState4(false);
9882
+ useEffect4(() => {
8218
9883
  void host.devices.refresh();
8219
9884
  }, [host]);
8220
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__prejoin", children: [
8221
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__preview", children: [
8222
- 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(
8223
9888
  "video",
8224
9889
  {
8225
9890
  className: "mx-meet__video mx-meet__video--mirror",
@@ -8230,16 +9895,16 @@ function PreJoinBody({
8230
9895
  if (element !== null) preview.preview?.attach(element);
8231
9896
  }
8232
9897
  }
8233
- ) : /* @__PURE__ */ jsx3("div", { className: "mx-meet__tile-placeholder", children: /* @__PURE__ */ jsx3(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 96 }) }),
8234
- mode === "video" && preview.error !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__preview-note", children: preview.error }) : null,
8235
- 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
8236
9901
  ] }),
8237
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__prejoin-panel", children: [
8238
- /* @__PURE__ */ jsx3("h1", { className: "mx-meet__prejoin-title", children: "Ready to join?" }),
8239
- notice?.kind === "removed" ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__warning", children: notice.text }) : null,
8240
- 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: [
8241
9906
  "Your browser is hiding device names until you allow camera and microphone access.",
8242
- /* @__PURE__ */ jsx3(
9907
+ /* @__PURE__ */ jsx4(
8243
9908
  "button",
8244
9909
  {
8245
9910
  type: "button",
@@ -8251,11 +9916,11 @@ function PreJoinBody({
8251
9916
  }
8252
9917
  )
8253
9918
  ] }) : null,
8254
- devices?.fallbackNotice != null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__warning", children: devices.fallbackNotice }) : null,
8255
- /* @__PURE__ */ jsx3(DevicePicker, { kind: "audioinput", label: "Microphone" }),
8256
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__field-row", children: [
8257
- /* @__PURE__ */ jsx3(DevicePicker, { kind: "audiooutput", label: "Speaker" }),
8258
- /* @__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(
8259
9924
  "button",
8260
9925
  {
8261
9926
  type: "button",
@@ -8268,19 +9933,19 @@ function PreJoinBody({
8268
9933
  );
8269
9934
  },
8270
9935
  children: [
8271
- /* @__PURE__ */ jsx3(SpeakerIcon, { width: 14, height: 14 }),
9936
+ /* @__PURE__ */ jsx4(SpeakerIcon, { width: 14, height: 14 }),
8272
9937
  " ",
8273
9938
  speakerTesting ? "Playing\u2026" : "Test"
8274
9939
  ]
8275
9940
  }
8276
9941
  )
8277
9942
  ] }),
8278
- /* @__PURE__ */ jsx3(DevicePicker, { kind: "videoinput", label: "Camera" }),
8279
- /* @__PURE__ */ jsx3(EffectsSettings, { preview: preview.preview }),
8280
- recording.consentNotice !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__consent", children: recording.consentNotice }) : null,
8281
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__prejoin-actions", children: [
8282
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
8283
- /* @__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(
8284
9949
  "input",
8285
9950
  {
8286
9951
  type: "checkbox",
@@ -8290,8 +9955,8 @@ function PreJoinBody({
8290
9955
  ),
8291
9956
  "Join with video"
8292
9957
  ] }),
8293
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
8294
- /* @__PURE__ */ jsx3(
9958
+ /* @__PURE__ */ jsxs3("label", { className: "mx-meet__toggle", children: [
9959
+ /* @__PURE__ */ jsx4(
8295
9960
  "input",
8296
9961
  {
8297
9962
  type: "checkbox",
@@ -8301,7 +9966,7 @@ function PreJoinBody({
8301
9966
  ),
8302
9967
  "Join with microphone"
8303
9968
  ] }),
8304
- /* @__PURE__ */ jsx3(
9969
+ /* @__PURE__ */ jsx4(
8305
9970
  "button",
8306
9971
  {
8307
9972
  type: "button",
@@ -8321,20 +9986,20 @@ function PreJoinBody({
8321
9986
  }
8322
9987
  )
8323
9988
  ] }),
8324
- room.failure !== null ? /* @__PURE__ */ jsxs2("p", { className: "mx-meet__error", children: [
9989
+ room.failure !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__error", children: [
8325
9990
  room.failure.message,
8326
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__remedy", children: room.failure.remedy })
9991
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet__remedy", children: room.failure.remedy })
8327
9992
  ] }) : null
8328
9993
  ] })
8329
9994
  ] });
8330
9995
  }
8331
9996
  function useCameraPreview(deviceId2, effects) {
8332
- const [preview, setPreview] = useState3(null);
8333
- const [error, setError] = useState3(null);
8334
- const current = useRef3(null);
8335
- 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));
8336
10001
  initialEffect.current = toVideoEffect(effects);
8337
- useEffect3(() => {
10002
+ useEffect4(() => {
8338
10003
  if (deviceId2 === void 0) return void 0;
8339
10004
  let live = true;
8340
10005
  setError(null);
@@ -8378,9 +10043,9 @@ function DevicePicker({
8378
10043
  const devices = useDeviceSnapshot();
8379
10044
  const list = devices?.devices[kind] ?? [];
8380
10045
  if (list.length === 0) return null;
8381
- return /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
8382
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: label }),
8383
- /* @__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(
8384
10049
  "select",
8385
10050
  {
8386
10051
  className: "mx-meet__select",
@@ -8389,7 +10054,7 @@ function DevicePicker({
8389
10054
  if (onPick !== void 0) onPick(kind, event.target.value);
8390
10055
  else host.devices.select(kind, event.target.value);
8391
10056
  },
8392
- 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))
8393
10058
  }
8394
10059
  )
8395
10060
  ] });
@@ -8397,9 +10062,9 @@ function DevicePicker({
8397
10062
  function MeetingRoom(props) {
8398
10063
  const host = useMeetHost();
8399
10064
  if (host === null) {
8400
- 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" }) });
8401
10066
  }
8402
- return /* @__PURE__ */ jsx3(MeetingRoomBody, { ...props, host });
10067
+ return /* @__PURE__ */ jsx4(MeetingRoomBody, { ...props, host });
8403
10068
  }
8404
10069
  function MeetingRoomBody({
8405
10070
  roomName,
@@ -8414,25 +10079,25 @@ function MeetingRoomBody({
8414
10079
  const isHost = useIsHost();
8415
10080
  const elapsed = useElapsed(snapshot?.meeting?.startedAt ?? null);
8416
10081
  const phase = snapshot?.phase ?? "idle";
8417
- useEffect3(() => {
10082
+ useEffect4(() => {
8418
10083
  host.meetings.watch(roomName);
8419
10084
  }, [host, roomName]);
8420
- useEffect3(() => {
10085
+ useEffect4(() => {
8421
10086
  if (given === void 0) return;
8422
10087
  if (host.store.snapshot().meeting !== null) return;
8423
10088
  host.store.patch({ meeting: given, locked: given.locked });
8424
10089
  }, [host, given]);
8425
10090
  const watchedId = meetingId ?? snapshot?.meeting?.id ?? null;
8426
- useEffect3(() => {
10091
+ useEffect4(() => {
8427
10092
  if (watchedId === null) return;
8428
10093
  host.meetings.watchMeeting(asMeetingId(watchedId));
8429
10094
  }, [host, watchedId]);
8430
10095
  const record = snapshot?.meeting ?? given ?? null;
8431
10096
  if (hasEnded(record) && phase !== "connected" && phase !== "reconnecting") {
8432
- return /* @__PURE__ */ jsx3(MeetingRecordView, { meeting: record });
10097
+ return /* @__PURE__ */ jsx4(MeetingRecordView, { meeting: record });
8433
10098
  }
8434
10099
  if (phase === "idle" || phase === "failed" || phase === "left") {
8435
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet", children: /* @__PURE__ */ jsx3(
10100
+ return /* @__PURE__ */ jsx4("div", { className: "mx-meet", children: /* @__PURE__ */ jsx4(
8436
10101
  PreJoin,
8437
10102
  {
8438
10103
  roomName,
@@ -8442,42 +10107,42 @@ function MeetingRoomBody({
8442
10107
  ) });
8443
10108
  }
8444
10109
  if (phase === "lobby") {
8445
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet mx-meet--lobby", children: /* @__PURE__ */ jsx3(WaitingRoom, { roomName, host }) });
8446
- }
8447
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet", children: [
8448
- /* @__PURE__ */ jsx3(ConsentNotice, {}),
8449
- /* @__PURE__ */ jsx3(AttendanceNotice, {}),
8450
- /* @__PURE__ */ jsxs2("header", { className: "mx-meet__header", children: [
8451
- /* @__PURE__ */ jsx3("h1", { className: "mx-meet__title", children: snapshot?.meeting?.title ?? "Meeting" }),
8452
- /* @__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: [
8453
10118
  participantSummary(snapshot?.participants ?? []),
8454
10119
  elapsed > 0 ? ` \xB7 ${formatDurationMs3(elapsed)}` : ""
8455
10120
  ] }),
8456
- /* @__PURE__ */ jsx3(RecordingIndicator, {}),
8457
- snapshot?.locked === true ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__badge", children: [
8458
- /* @__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 }),
8459
10124
  " Locked"
8460
10125
  ] }) : null,
8461
- headerControls !== void 0 && headerControls !== null ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__header-controls", "data-meet-header-controls": "", children: headerControls }) : null,
8462
- 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
8463
10128
  ] }),
8464
- phase === "reconnecting" ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__banner", role: "status", children: "Reconnecting\u2026" }) : null,
8465
- /* @__PURE__ */ jsx3(Stage, {}),
8466
- /* @__PURE__ */ jsx3(Captions, {}),
8467
- /* @__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 } : {} })
8468
10133
  ] });
8469
10134
  }
8470
10135
  function WaitingRoom({ roomName, host }) {
8471
- const knocked = useRef3(false);
8472
- useEffect3(() => {
10136
+ const knocked = useRef4(false);
10137
+ useEffect4(() => {
8473
10138
  if (knocked.current) return;
8474
10139
  knocked.current = true;
8475
10140
  host.meetings.knock(roomName);
8476
10141
  }, [host, roomName]);
8477
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__waiting", children: [
8478
- /* @__PURE__ */ jsx3(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 72 }),
8479
- /* @__PURE__ */ jsx3("h1", { className: "mx-meet__prejoin-title", children: "Waiting for the host to let you in" }),
8480
- /* @__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: [
8481
10146
  "You are in the waiting room as ",
8482
10147
  host.identity.displayName,
8483
10148
  ". You will join automatically once you are admitted."
@@ -8488,10 +10153,10 @@ function HostMenu() {
8488
10153
  const host = useRequiredMeetHost();
8489
10154
  const snapshot = useMeetSnapshot();
8490
10155
  const end = useEndMeeting();
8491
- const [confirmingEnd, setConfirmingEnd] = useState3(false);
10156
+ const [confirmingEnd, setConfirmingEnd] = useState4(false);
8492
10157
  const locked = snapshot?.locked === true;
8493
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__host-menu", children: [
8494
- /* @__PURE__ */ jsx3(
10158
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__host-menu", children: [
10159
+ /* @__PURE__ */ jsx4(
8495
10160
  "button",
8496
10161
  {
8497
10162
  type: "button",
@@ -8502,9 +10167,9 @@ function HostMenu() {
8502
10167
  children: locked ? "Unlock meeting" : "Lock meeting"
8503
10168
  }
8504
10169
  ),
8505
- end.canEnd ? confirmingEnd ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__confirm", role: "group", "aria-label": "End this meeting?", children: [
8506
- /* @__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." }),
8507
- /* @__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(
8508
10173
  "button",
8509
10174
  {
8510
10175
  type: "button",
@@ -8516,7 +10181,7 @@ function HostMenu() {
8516
10181
  children: "End it"
8517
10182
  }
8518
10183
  ),
8519
- /* @__PURE__ */ jsx3(
10184
+ /* @__PURE__ */ jsx4(
8520
10185
  "button",
8521
10186
  {
8522
10187
  type: "button",
@@ -8525,7 +10190,7 @@ function HostMenu() {
8525
10190
  children: "Keep it running"
8526
10191
  }
8527
10192
  )
8528
- ] }) : /* @__PURE__ */ jsx3(
10193
+ ] }) : /* @__PURE__ */ jsx4(
8529
10194
  "button",
8530
10195
  {
8531
10196
  type: "button",
@@ -8534,7 +10199,7 @@ function HostMenu() {
8534
10199
  children: end.ending ? "Ending\u2026" : "End meeting for everyone"
8535
10200
  }
8536
10201
  ) : null,
8537
- 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
8538
10203
  ] });
8539
10204
  }
8540
10205
  function CallButton({
@@ -8544,7 +10209,7 @@ function CallButton({
8544
10209
  }) {
8545
10210
  const calls = useCalls();
8546
10211
  if (!calls.canCall) return null;
8547
- return /* @__PURE__ */ jsx3(
10212
+ return /* @__PURE__ */ jsx4(
8548
10213
  "button",
8549
10214
  {
8550
10215
  type: "button",
@@ -8553,55 +10218,55 @@ function CallButton({
8553
10218
  void calls.call([person.userId], mode);
8554
10219
  },
8555
10220
  "aria-label": `Call ${person.displayName}`,
8556
- children: children ?? /* @__PURE__ */ jsx3(PhoneIcon, { width: 18, height: 18 })
10221
+ children: children ?? /* @__PURE__ */ jsx4(PhoneIcon, { width: 18, height: 18 })
8557
10222
  }
8558
10223
  );
8559
10224
  }
8560
10225
  function IncomingCallHost() {
8561
10226
  const calls = useCalls();
8562
10227
  if (calls.incoming.length === 0) return null;
8563
- 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)) });
8564
10229
  }
8565
10230
  function IncomingCallCard({ invite }) {
8566
10231
  const calls = useCalls();
8567
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__ringing", role: "alertdialog", "aria-label": "Incoming call", children: [
8568
- /* @__PURE__ */ jsx3(Avatar, { name: invite.callerName, url: invite.callerAvatarUrl, size: 56 }),
8569
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__ringing-text", children: [
8570
- /* @__PURE__ */ jsx3("strong", { children: invite.callerName }),
8571
- /* @__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" })
8572
10237
  ] }),
8573
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__ringing-actions", children: [
8574
- /* @__PURE__ */ jsx3(ControlButton, { label: "Decline", danger: true, onClick: () => void calls.decline(invite), children: /* @__PURE__ */ jsx3(PhoneOffIcon, {}) }),
8575
- 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(
8576
10241
  ControlButton,
8577
10242
  {
8578
10243
  label: "Accept without video",
8579
10244
  onClick: () => void calls.accept({ ...invite, mode: "audio" }),
8580
- children: /* @__PURE__ */ jsx3(CameraOffIcon, {})
10245
+ children: /* @__PURE__ */ jsx4(CameraOffIcon, {})
8581
10246
  }
8582
10247
  ) : null,
8583
- /* @__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, {}) })
8584
10249
  ] })
8585
10250
  ] });
8586
10251
  }
8587
10252
  function ScheduleMeeting(props) {
8588
10253
  const host = useMeetHost();
8589
- if (host === null) return /* @__PURE__ */ jsx3(InertNotice, { what: "Scheduling a meeting" });
8590
- 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 });
8591
10256
  }
8592
10257
  function ScheduleMeetingBody({
8593
10258
  appBaseUrl,
8594
10259
  onScheduled,
8595
10260
  host
8596
10261
  }) {
8597
- const [title, setTitle] = useState3("");
8598
- const [when2, setWhen] = useState3("");
8599
- const [kind, setKind] = useState3("scheduled");
8600
- const [busy, setBusy] = useState3(false);
8601
- const [link, setLink] = useState3(null);
8602
- 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);
8603
10268
  const disabled = useMemo3(() => title.trim().length === 0 || busy, [title, busy]);
8604
- return /* @__PURE__ */ jsxs2(
10269
+ return /* @__PURE__ */ jsxs3(
8605
10270
  "form",
8606
10271
  {
8607
10272
  className: "mx-meet__schedule",
@@ -8626,9 +10291,9 @@ function ScheduleMeetingBody({
8626
10291
  }).finally(() => setBusy(false));
8627
10292
  },
8628
10293
  children: [
8629
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
8630
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "Title" }),
8631
- /* @__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(
8632
10297
  "input",
8633
10298
  {
8634
10299
  className: "mx-meet__input",
@@ -8638,9 +10303,9 @@ function ScheduleMeetingBody({
8638
10303
  }
8639
10304
  )
8640
10305
  ] }),
8641
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
8642
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "When" }),
8643
- /* @__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(
8644
10309
  "input",
8645
10310
  {
8646
10311
  className: "mx-meet__input",
@@ -8650,27 +10315,27 @@ function ScheduleMeetingBody({
8650
10315
  }
8651
10316
  )
8652
10317
  ] }),
8653
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
8654
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "Repeats" }),
8655
- /* @__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(
8656
10321
  "select",
8657
10322
  {
8658
10323
  className: "mx-meet__select",
8659
10324
  value: kind,
8660
10325
  onChange: (event) => setKind(event.target.value),
8661
10326
  children: [
8662
- /* @__PURE__ */ jsx3("option", { value: "scheduled", children: "Once" }),
8663
- /* @__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" })
8664
10329
  ]
8665
10330
  }
8666
10331
  )
8667
10332
  ] }),
8668
- /* @__PURE__ */ jsx3("button", { type: "submit", className: "mx-meet__primary", disabled, children: busy ? "Creating\u2026" : "Create meeting" }),
8669
- link !== null ? /* @__PURE__ */ jsxs2("p", { className: "mx-meet__link-out", children: [
8670
- /* @__PURE__ */ jsx3("span", { children: "Anyone with this link can join \u2014 no account needed." }),
8671
- /* @__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 })
8672
10337
  ] }) : null,
8673
- 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
8674
10339
  ]
8675
10340
  }
8676
10341
  );
@@ -8679,7 +10344,7 @@ function ReactionOverlay({
8679
10344
  reactions
8680
10345
  }) {
8681
10346
  if (reactions.length === 0) return null;
8682
- 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)) });
8683
10348
  }
8684
10349
  function GuestRecordAccessControl({
8685
10350
  meeting
@@ -8691,11 +10356,11 @@ function GuestRecordAccessControl({
8691
10356
  const isHost = inRoomHost || viewerId !== null && meeting.hostUserId === viewerId;
8692
10357
  if (host === null || !isHost) return null;
8693
10358
  const resolved = access.setting === "default" && access.effective !== null ? ` Right now that means: ${guestRecordAccessLabel(access.effective.level).toLowerCase()}.` : "";
8694
- return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "What guests may read", children: [
8695
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "What guests may read" }),
8696
- /* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
8697
- /* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "People who attended by link, without an account" }),
8698
- /* @__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(
8699
10364
  "select",
8700
10365
  {
8701
10366
  className: "mx-meet__select",
@@ -8706,18 +10371,18 @@ function GuestRecordAccessControl({
8706
10371
  event.target.value
8707
10372
  );
8708
10373
  },
8709
- 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))
8710
10375
  }
8711
10376
  )
8712
10377
  ] }),
8713
- /* @__PURE__ */ jsxs2("p", { className: "mx-meet__panel-note", children: [
10378
+ /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
8714
10379
  guestRecordAccessExplanation(access.setting),
8715
10380
  resolved
8716
10381
  ] }),
8717
- access.saving ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", role: "status", children: "Saving what guests may read\u2026" }) : null,
8718
- access.error !== null ? /* @__PURE__ */ jsxs2(ErrorBox, { as: "div", className: "mx-meet__refusal", error: access.error, operation: "Change who can join", origin: "meet/components", children: [
8719
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-reason", children: access.error.message }),
8720
- /* @__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 })
8721
10386
  ] }) : null
8722
10387
  ] });
8723
10388
  }
@@ -8727,9 +10392,9 @@ function MeetingRecordView({
8727
10392
  }) {
8728
10393
  const host = useMeetHost();
8729
10394
  if (host === null) {
8730
- 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" }) });
8731
10396
  }
8732
- return /* @__PURE__ */ jsx3(MeetingRecordBody, { meeting, ...onRejoin !== void 0 ? { onRejoin } : {} });
10397
+ return /* @__PURE__ */ jsx4(MeetingRecordBody, { meeting, ...onRejoin !== void 0 ? { onRejoin } : {} });
8733
10398
  }
8734
10399
  function MeetingRecordBody({
8735
10400
  meeting,
@@ -8737,19 +10402,19 @@ function MeetingRecordBody({
8737
10402
  }) {
8738
10403
  const host = useRequiredMeetHost();
8739
10404
  const record = useMeetingRecord(meeting);
8740
- const [question, setQuestion] = useState3("");
8741
- const [tab, setTab] = useState3("summary");
10405
+ const [question, setQuestion] = useState4("");
10406
+ const [tab, setTab] = useState4("summary");
8742
10407
  if (record.failure !== null) {
8743
- 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: [
8744
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-title", children: "This meeting record could not be opened" }),
8745
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-body", children: record.failure.message }),
8746
- /* @__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 })
8747
10412
  ] }) });
8748
10413
  }
8749
10414
  if (record.loading || record.record === null) {
8750
- return /* @__PURE__ */ jsx3("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsxs2("div", { className: "mx-meet__empty", role: "status", children: [
8751
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-title", children: "Opening the meeting record\u2026" }),
8752
- /* @__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." })
8753
10418
  ] }) });
8754
10419
  }
8755
10420
  const bundle = record.record;
@@ -8768,44 +10433,44 @@ function MeetingRecordBody({
8768
10433
  );
8769
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;
8770
10435
  if (entirelyRestricted) {
8771
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet mx-meet--record", children: [
8772
- /* @__PURE__ */ jsx3("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ jsxs2("div", { className: "mx-meet__record-head-inner", children: [
8773
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
8774
- /* @__PURE__ */ jsx3("h1", { className: "mx-meet__record-title", children: meeting.title }),
8775
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
8776
- 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
8777
10442
  ] }) }),
8778
- /* @__PURE__ */ jsx3("div", { className: "mx-meet__record-body", children: restrictionNotices.map((notice2) => /* @__PURE__ */ jsxs2("div", { className: "mx-meet__record-access", role: "status", children: [
8779
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-access-title", children: "About this record" }),
8780
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-access-message", children: notice2.message }),
8781
- /* @__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 })
8782
10447
  ] }, notice2.parts.join("-"))) })
8783
10448
  ] });
8784
10449
  }
8785
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet mx-meet--record", children: [
8786
- /* @__PURE__ */ jsx3("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ jsxs2("div", { className: "mx-meet__record-head-inner", children: [
8787
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
8788
- /* @__PURE__ */ jsx3("h1", { className: "mx-meet__record-title", children: meeting.title }),
8789
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
8790
- 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
8791
10456
  ] }) }),
8792
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet__record-body", children: [
8793
- restrictionNotices.map((notice2) => /* @__PURE__ */ jsxs2("div", { className: "mx-meet__record-access", role: "status", children: [
8794
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-access-title", children: "About this record" }),
8795
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__record-access-message", children: notice2.message }),
8796
- /* @__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 })
8797
10462
  ] }, notice2.parts.join("-"))),
8798
10463
  attended.length === 0 ? (
8799
10464
  /* NOT SILENCE. A refused attendance read used to remove the whole
8800
10465
  section, so the reader could not tell "nobody" from "not shown". */
8801
- /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
8802
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
8803
- /* @__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.") })
8804
10469
  ] })
8805
- ) : /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
8806
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
8807
- /* @__PURE__ */ jsx3("ul", { className: "mx-meet__record-attendees", children: attended.map((person) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__record-attendee", children: [
8808
- /* @__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(
8809
10474
  Avatar,
8810
10475
  {
8811
10476
  name: displayNameFor(bundle.names, person.identity, person.displayName),
@@ -8813,26 +10478,26 @@ function MeetingRecordBody({
8813
10478
  size: 28
8814
10479
  }
8815
10480
  ),
8816
- /* @__PURE__ */ jsxs2("span", { className: "mx-meet__person-name", children: [
10481
+ /* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
8817
10482
  displayNameFor(bundle.names, person.identity, person.displayName),
8818
- person.role === "host" ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Host" }) : null,
8819
- person.role === "guest" ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Guest" }) : null,
8820
- 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
8821
10486
  ] })
8822
10487
  ] }, person.id)) })
8823
10488
  ] }),
8824
- bundle.recording !== null ? /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section mx-meet__recording-card", "aria-label": "Recording", children: [
8825
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
8826
- fileId !== null ? /* @__PURE__ */ jsxs2(Fragment, { children: [
8827
- /* @__PURE__ */ jsx3(RecordingPlayer, { fileId }),
8828
- notice !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: notice }) : null
8829
- ] }) : /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: notice ?? "This recording has no file." })
8830
- ] }) : wasRefused(bundle, "recording") ? /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "Recording", children: [
8831
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
8832
- /* @__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 })
8833
10498
  ] }) : null,
8834
- /* @__PURE__ */ jsxs2("nav", { className: "mx-meet__record-tabs", "aria-label": "Meeting record sections", children: [
8835
- /* @__PURE__ */ jsx3(
10499
+ /* @__PURE__ */ jsxs3("nav", { className: "mx-meet__record-tabs", "aria-label": "Meeting record sections", children: [
10500
+ /* @__PURE__ */ jsx4(
8836
10501
  "button",
8837
10502
  {
8838
10503
  type: "button",
@@ -8842,7 +10507,7 @@ function MeetingRecordBody({
8842
10507
  children: "Summary & decisions"
8843
10508
  }
8844
10509
  ),
8845
- /* @__PURE__ */ jsx3(
10510
+ /* @__PURE__ */ jsx4(
8846
10511
  "button",
8847
10512
  {
8848
10513
  type: "button",
@@ -8852,7 +10517,7 @@ function MeetingRecordBody({
8852
10517
  children: "Notes as it happened"
8853
10518
  }
8854
10519
  ),
8855
- /* @__PURE__ */ jsx3(
10520
+ /* @__PURE__ */ jsx4(
8856
10521
  "button",
8857
10522
  {
8858
10523
  type: "button",
@@ -8863,15 +10528,15 @@ function MeetingRecordBody({
8863
10528
  }
8864
10529
  )
8865
10530
  ] }),
8866
- tab === "summary" ? /* @__PURE__ */ jsxs2(Fragment, { children: [
8867
- /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "Summary", children: [
8868
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "Summary" }),
8869
- 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: [
8870
- /* @__PURE__ */ jsx3("p", { children: wrapUp.message }),
8871
- /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: record.reload, children: "Check again" })
8872
- ] }) : /* @__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 })
8873
10538
  ] }),
8874
- /* @__PURE__ */ jsx3(
10539
+ /* @__PURE__ */ jsx4(
8875
10540
  NoteList,
8876
10541
  {
8877
10542
  title: "Decisions",
@@ -8883,7 +10548,7 @@ function MeetingRecordBody({
8883
10548
  )
8884
10549
  }
8885
10550
  ),
8886
- /* @__PURE__ */ jsx3(
10551
+ /* @__PURE__ */ jsx4(
8887
10552
  NoteList,
8888
10553
  {
8889
10554
  title: "Action items",
@@ -8896,42 +10561,42 @@ function MeetingRecordBody({
8896
10561
  }
8897
10562
  )
8898
10563
  ] }) : null,
8899
- tab === "notes" ? /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "Notes as it happened", children: [
8900
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "Notes as it happened" }),
8901
- 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(
8902
10567
  bundle,
8903
10568
  "notes",
8904
10569
  "No live notes are available for this meeting."
8905
- ) }) : /* @__PURE__ */ jsx3("ul", { className: "mx-meet__notes", children: bundle.liveNotes.map((note) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__note", children: [
8906
- 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: [
8907
10572
  "Window ",
8908
10573
  note.window
8909
10574
  ] }) : null,
8910
10575
  note.text
8911
10576
  ] }, note.id)) })
8912
10577
  ] }) : null,
8913
- tab === "transcript" ? /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "Transcript", children: [
8914
- /* @__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: [
8915
10580
  "Transcript",
8916
- /* @__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` })
8917
10582
  ] }),
8918
- 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(
8919
10584
  bundle,
8920
10585
  "transcript",
8921
10586
  "No transcript is available for this meeting."
8922
- ) }) : /* @__PURE__ */ jsx3("ol", { className: "mx-meet__record-transcript", children: blocks.map((block) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__record-block", children: [
8923
- /* @__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: [
8924
10589
  block.speaker,
8925
- /* @__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) })
8926
10591
  ] }),
8927
- 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))
8928
10593
  ] }, block.id)) })
8929
10594
  ] }) : null,
8930
- /* @__PURE__ */ jsx3(GuestRecordAccessControl, { meeting }),
8931
- /* @__PURE__ */ jsxs2("section", { className: "mx-meet__record-section", "aria-label": "Ask about this meeting", children: [
8932
- /* @__PURE__ */ jsx3("h2", { className: "mx-meet__record-section-title", children: "Ask about this meeting" }),
8933
- 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: [
8934
- /* @__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(
8935
10600
  "form",
8936
10601
  {
8937
10602
  className: "mx-meet__composer",
@@ -8942,7 +10607,7 @@ function MeetingRecordBody({
8942
10607
  void record.ask(trimmed);
8943
10608
  },
8944
10609
  children: [
8945
- /* @__PURE__ */ jsx3(
10610
+ /* @__PURE__ */ jsx4(
8946
10611
  "input",
8947
10612
  {
8948
10613
  className: "mx-meet__input",
@@ -8952,7 +10617,7 @@ function MeetingRecordBody({
8952
10617
  "aria-label": "Ask about this meeting"
8953
10618
  }
8954
10619
  ),
8955
- /* @__PURE__ */ jsx3(
10620
+ /* @__PURE__ */ jsx4(
8956
10621
  "button",
8957
10622
  {
8958
10623
  type: "submit",
@@ -8964,8 +10629,8 @@ function MeetingRecordBody({
8964
10629
  ]
8965
10630
  }
8966
10631
  ),
8967
- record.answer !== null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__answer", children: record.answer }) : null,
8968
- 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: [
8969
10634
  "Answered from ",
8970
10635
  record.coverage.segmentsUsed,
8971
10636
  " of ",
@@ -8976,9 +10641,9 @@ function MeetingRecordBody({
8976
10641
  record.coverage.truncated ? " (the oldest were left out)" : "",
8977
10642
  "."
8978
10643
  ] }) : null,
8979
- record.askError !== null ? /* @__PURE__ */ jsxs2(ErrorBox, { as: "div", className: "mx-meet__refusal", error: record.askError, operation: "Ask about this meeting", origin: "meet/components", children: [
8980
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-reason", children: record.askError.message }),
8981
- /* @__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 })
8982
10647
  ] }) : null
8983
10648
  ] })
8984
10649
  ] })
@@ -8989,21 +10654,21 @@ var STREAM_REFUSED = "Streaming playback did not start, so this recording was do
8989
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.";
8990
10655
  function RecordingPlayer(props) {
8991
10656
  const host = useMeetHost();
8992
- if (host === null) return /* @__PURE__ */ jsx3(InertNotice, { what: "This recording" });
8993
- return /* @__PURE__ */ jsx3(RecordingPlayerBody, { ...props, host });
10657
+ if (host === null) return /* @__PURE__ */ jsx4(InertNotice, { what: "This recording" });
10658
+ return /* @__PURE__ */ jsx4(RecordingPlayerBody, { ...props, host });
8994
10659
  }
8995
10660
  function RecordingPlayerBody({ fileId, host }) {
8996
- const [media, setMedia] = useState3(null);
8997
- const [loading, setLoading] = useState3(false);
8998
- const [error, setError] = useState3(null);
8999
- useEffect3(() => {
10661
+ const [media, setMedia] = useState4(null);
10662
+ const [loading, setLoading] = useState4(false);
10663
+ const [error, setError] = useState4(null);
10664
+ useEffect4(() => {
9000
10665
  if (media === null || media.kind !== "bytes") return void 0;
9001
10666
  const url = media.url;
9002
10667
  return () => URL.revokeObjectURL(url);
9003
10668
  }, [media]);
9004
10669
  if (media !== null) {
9005
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__record-section", children: [
9006
- /* @__PURE__ */ jsx3(
10670
+ return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-section", children: [
10671
+ /* @__PURE__ */ jsx4(
9007
10672
  "video",
9008
10673
  {
9009
10674
  className: "mx-meet__record-player",
@@ -9045,15 +10710,15 @@ function RecordingPlayerBody({ fileId, host }) {
9045
10710
  }
9046
10711
  }
9047
10712
  ),
9048
- 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
9049
10714
  ] });
9050
10715
  }
9051
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__record-section", children: [
9052
- error !== null ? /* @__PURE__ */ jsxs2(ErrorBox, { as: "div", className: "mx-meet__refusal", error, operation: "Complete this meeting action", origin: "meet/components", children: [
9053
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__refusal-reason", children: error.message }),
9054
- /* @__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 })
9055
10720
  ] }) : null,
9056
- /* @__PURE__ */ jsx3(
10721
+ /* @__PURE__ */ jsx4(
9057
10722
  "button",
9058
10723
  {
9059
10724
  type: "button",
@@ -9089,35 +10754,35 @@ function clockOf(iso) {
9089
10754
  function MeetingList({ baseUrl }) {
9090
10755
  const host = useMeetHost();
9091
10756
  const list = useMeetings();
9092
- if (host === null) return /* @__PURE__ */ jsx3(InertNotice, { what: "Your meetings" });
10757
+ if (host === null) return /* @__PURE__ */ jsx4(InertNotice, { what: "Your meetings" });
9093
10758
  if (list.failure !== null) {
9094
- return /* @__PURE__ */ jsxs2(ErrorBox, { as: "div", className: "mx-meet__empty", error: list.failure, operation: "List your meetings", origin: "meet/components", children: [
9095
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-title", children: "Your meetings could not be listed" }),
9096
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-body", children: list.failure.message }),
9097
- /* @__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 })
9098
10763
  ] });
9099
10764
  }
9100
10765
  if (list.loading) {
9101
- 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" }) });
9102
10767
  }
9103
10768
  if (list.meetings.length === 0) {
9104
- return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__empty", role: "status", children: [
9105
- /* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-title", children: "No meetings yet" }),
9106
- /* @__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." })
9107
10772
  ] });
9108
10773
  }
9109
10774
  const origin = baseUrl ?? (typeof window === "undefined" ? "" : window.location.origin);
9110
- 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) => {
9111
10776
  const ended = meeting.endedAt !== null;
9112
- return /* @__PURE__ */ jsxs2("li", { className: "mx-meet-list__row", children: [
9113
- /* @__PURE__ */ jsxs2("div", { className: "mx-meet-list__main", children: [
9114
- /* @__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: [
9115
10780
  meeting.title,
9116
- ended ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__badge", children: "Ended" }) : null
10781
+ ended ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Ended" }) : null
9117
10782
  ] }),
9118
- /* @__PURE__ */ jsx3("span", { className: "mx-meet-list__when", children: meetingWhen(meeting) })
10783
+ /* @__PURE__ */ jsx4("span", { className: "mx-meet-list__when", children: meetingWhen(meeting) })
9119
10784
  ] }),
9120
- /* @__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" })
9121
10786
  ] }, meeting.id);
9122
10787
  }) });
9123
10788
  }
@@ -9274,15 +10939,22 @@ async function pushMeetingToGoogleCalendar(api, meetingId, target) {
9274
10939
  }
9275
10940
  export {
9276
10941
  ATTENDANCE_CSV_HEADER,
10942
+ ActivitiesControl,
10943
+ ActivitiesIcon,
9277
10944
  AiPanel,
9278
10945
  AttendanceNotice,
9279
10946
  Avatar,
10947
+ BreakoutBanner,
10948
+ BreakoutIcon,
10949
+ BreakoutsPanel,
9280
10950
  CALL_INVITE_KIND,
9281
10951
  CALL_INVITE_VERSION,
10952
+ CAPTION_LANGUAGES,
9282
10953
  CONSENT_NOTICE_ATTRIBUTE,
9283
10954
  CallButton,
9284
10955
  CameraIcon,
9285
10956
  CameraOffIcon,
10957
+ CaptionLanguageSettings,
9286
10958
  Captions,
9287
10959
  ChatIcon,
9288
10960
  ChatPanel,
@@ -9295,6 +10967,7 @@ export {
9295
10967
  DATA_TOPICS,
9296
10968
  DEFAULT_EFFECTS,
9297
10969
  DEFAULT_PAGE_SIZE,
10970
+ EMPTY_COLLAB,
9298
10971
  END_MEETING_NOT_SERVED,
9299
10972
  FILE_SESSION_PATH,
9300
10973
  FlagIcon,
@@ -9347,8 +11020,12 @@ export {
9347
11020
  PhoneIcon,
9348
11021
  PhoneOffIcon,
9349
11022
  PinIcon,
11023
+ PollIcon,
11024
+ PollsPanel,
9350
11025
  PreJoin,
11026
+ QaPanel,
9351
11027
  QualityBars,
11028
+ QuestionIcon,
9352
11029
  REACTION_TTL_MS,
9353
11030
  REFUSED_ABSENCE,
9354
11031
  ROLE_RANK,
@@ -9375,10 +11052,13 @@ export {
9375
11052
  TABLES,
9376
11053
  TRANSCRIPTION_ATTRIBUTES,
9377
11054
  TRANSCRIPTION_TOPIC,
11055
+ WhiteboardIcon,
11056
+ WhiteboardPanel,
9378
11057
  WifiLowIcon,
9379
11058
  absenceSentence,
9380
11059
  activeWrapUpSummary,
9381
11060
  announceMeeting,
11061
+ applyCollabPacket,
9382
11062
  applyRoomEvent,
9383
11063
  asCallId,
9384
11064
  asMeetingId,
@@ -9386,10 +11066,13 @@ export {
9386
11066
  asParticipantIdentity,
9387
11067
  asRoomName,
9388
11068
  asUserId,
11069
+ assignedRoom,
9389
11070
  attendanceCsv,
9390
11071
  attendanceReport,
9391
11072
  attendanceTotals,
9392
11073
  attendeeKey,
11074
+ autoAssign,
11075
+ breakoutRemainingMs,
9393
11076
  callInviteAction,
9394
11077
  callInviteText,
9395
11078
  callStateLabel,
@@ -9399,6 +11082,7 @@ export {
9399
11082
  captionSegment,
9400
11083
  changesPatch,
9401
11084
  clockPosition,
11085
+ collabFromState,
9402
11086
  computeStage,
9403
11087
  countLabel,
9404
11088
  createCallCenter,
@@ -9419,6 +11103,7 @@ export {
9419
11103
  createWebDeviceStorage,
9420
11104
  createWebEffectsStorage,
9421
11105
  createWebRoomTokenStorage,
11106
+ defaultCaptionLanguage,
9422
11107
  displayNameFor,
9423
11108
  fileDownloadPath,
9424
11109
  gridColumns,
@@ -9441,6 +11126,7 @@ export {
9441
11126
  listenOnlyNotice,
9442
11127
  loadFollowUpDraft,
9443
11128
  loadGuestMeetingRecord,
11129
+ loadMeetingActivities,
9444
11130
  loadMeetingChat,
9445
11131
  loadMeetingRecord,
9446
11132
  mapConnectionState,
@@ -9495,9 +11181,13 @@ export {
9495
11181
  unavailableFrom,
9496
11182
  uniqueAttendees,
9497
11183
  useAudioLevel,
11184
+ useAvailableActivities,
9498
11185
  useCalls,
9499
11186
  useCanModerate,
9500
11187
  useCanRecord,
11188
+ useCaptionTranslation,
11189
+ useCollab,
11190
+ useCollabPanelRequest,
9501
11191
  useConsentNotice,
9502
11192
  useDeviceSnapshot,
9503
11193
  useElapsed,
@@ -9529,6 +11219,7 @@ export {
9529
11219
  useTrack,
9530
11220
  userTopic,
9531
11221
  wasRefused,
11222
+ withItem,
9532
11223
  wrapUpStatus
9533
11224
  };
9534
11225
  //# sourceMappingURL=react.js.map