@vertesia/ui 1.6.0-dev.20261008.064737Z → 1.6.0-dev.20261014.015055Z

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.
Files changed (204) hide show
  1. package/README.md +24 -0
  2. package/lib/boot/index.d.ts +12 -1
  3. package/lib/boot/index.d.ts.map +1 -1
  4. package/lib/boot/index.js +65 -10
  5. package/lib/boot/index.js.map +1 -1
  6. package/lib/boot/text.d.ts +13 -0
  7. package/lib/boot/text.d.ts.map +1 -0
  8. package/lib/boot/text.js +68 -0
  9. package/lib/boot/text.js.map +1 -0
  10. package/lib/core/components/shadcn/button.d.ts +1 -0
  11. package/lib/core/components/shadcn/button.d.ts.map +1 -1
  12. package/lib/core/components/shadcn/button.js +2 -2
  13. package/lib/core/components/shadcn/button.js.map +1 -1
  14. package/lib/core/components/shadcn/selectBox.d.ts.map +1 -1
  15. package/lib/core/components/shadcn/selectBox.js +2 -2
  16. package/lib/core/components/shadcn/selectBox.js.map +1 -1
  17. package/lib/env/index.d.ts +1 -1
  18. package/lib/env/index.d.ts.map +1 -1
  19. package/lib/env/index.js +1 -1
  20. package/lib/env/index.js.map +1 -1
  21. package/lib/features/agent/PayloadBuilder.d.ts +6 -0
  22. package/lib/features/agent/PayloadBuilder.d.ts.map +1 -1
  23. package/lib/features/agent/chat/AskUserWidget.d.ts.map +1 -1
  24. package/lib/features/agent/chat/AskUserWidget.js +2 -1
  25. package/lib/features/agent/chat/AskUserWidget.js.map +1 -1
  26. package/lib/features/agent/chat/ModernAgentConversation.js +6 -4
  27. package/lib/features/agent/chat/ModernAgentConversation.js.map +1 -1
  28. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
  29. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +2 -253
  30. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
  31. package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.d.ts +1 -3
  32. package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.d.ts.map +1 -1
  33. package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.js +2 -8
  34. package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.js.map +1 -1
  35. package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.d.ts.map +1 -1
  36. package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.js +58 -0
  37. package/lib/features/agent/chat/ModernAgentOutput/SummaryConversation.js.map +1 -1
  38. package/lib/features/agent/chat/ModernAgentOutput/agentMarkdownStyles.d.ts +4 -0
  39. package/lib/features/agent/chat/ModernAgentOutput/agentMarkdownStyles.d.ts.map +1 -0
  40. package/lib/features/agent/chat/ModernAgentOutput/agentMarkdownStyles.js +248 -0
  41. package/lib/features/agent/chat/ModernAgentOutput/agentMarkdownStyles.js.map +1 -0
  42. package/lib/features/agent/chat/SkillWidgetProvider.d.ts.map +1 -1
  43. package/lib/features/agent/chat/SkillWidgetProvider.js +3 -2
  44. package/lib/features/agent/chat/SkillWidgetProvider.js.map +1 -1
  45. package/lib/i18n/LanguageProvider.d.ts +9 -1
  46. package/lib/i18n/LanguageProvider.d.ts.map +1 -1
  47. package/lib/i18n/LanguageProvider.js +7 -4
  48. package/lib/i18n/LanguageProvider.js.map +1 -1
  49. package/lib/i18n/locales/ar.json +6 -1
  50. package/lib/i18n/locales/de.json +6 -1
  51. package/lib/i18n/locales/en.json +6 -1
  52. package/lib/i18n/locales/es.json +6 -1
  53. package/lib/i18n/locales/fr.json +6 -1
  54. package/lib/i18n/locales/it.json +6 -1
  55. package/lib/i18n/locales/ja.json +6 -1
  56. package/lib/i18n/locales/ko.json +6 -1
  57. package/lib/i18n/locales/pt.json +6 -1
  58. package/lib/i18n/locales/ru.json +6 -1
  59. package/lib/i18n/locales/tr.json +6 -1
  60. package/lib/i18n/locales/zh-TW.json +6 -1
  61. package/lib/i18n/locales/zh.json +6 -1
  62. package/lib/i18n/rtl.d.ts +4 -2
  63. package/lib/i18n/rtl.d.ts.map +1 -1
  64. package/lib/i18n/rtl.js +4 -2
  65. package/lib/i18n/rtl.js.map +1 -1
  66. package/lib/session/UserSessionProvider.d.ts.map +1 -1
  67. package/lib/session/UserSessionProvider.js +10 -4
  68. package/lib/session/UserSessionProvider.js.map +1 -1
  69. package/lib/session/auth/composable.d.ts +1 -5
  70. package/lib/session/auth/composable.d.ts.map +1 -1
  71. package/lib/session/auth/composable.js +1 -10
  72. package/lib/session/auth/composable.js.map +1 -1
  73. package/lib/session/auth/firebase.d.ts.map +1 -1
  74. package/lib/session/auth/firebase.js +8 -5
  75. package/lib/session/auth/firebase.js.map +1 -1
  76. package/lib/session/auth/oauth.d.ts.map +1 -1
  77. package/lib/session/auth/oauth.js +53 -25
  78. package/lib/session/auth/oauth.js.map +1 -1
  79. package/lib/session/auth/vertesiaHosts.d.ts +0 -40
  80. package/lib/session/auth/vertesiaHosts.d.ts.map +1 -1
  81. package/lib/session/auth/vertesiaHosts.js +2 -45
  82. package/lib/session/auth/vertesiaHosts.js.map +1 -1
  83. package/lib/session/index.d.ts +1 -1
  84. package/lib/session/index.d.ts.map +1 -1
  85. package/lib/session/index.js +1 -1
  86. package/lib/session/index.js.map +1 -1
  87. package/lib/session/scopeSelection.d.ts +4 -0
  88. package/lib/session/scopeSelection.d.ts.map +1 -1
  89. package/lib/session/scopeSelection.js +11 -0
  90. package/lib/session/scopeSelection.js.map +1 -1
  91. package/lib/shell/VertesiaShell.d.ts +7 -2
  92. package/lib/shell/VertesiaShell.d.ts.map +1 -1
  93. package/lib/shell/VertesiaShell.js +2 -2
  94. package/lib/shell/VertesiaShell.js.map +1 -1
  95. package/lib/shell/login/InviteAcceptModal.d.ts.map +1 -1
  96. package/lib/shell/login/InviteAcceptModal.js +83 -42
  97. package/lib/shell/login/InviteAcceptModal.js.map +1 -1
  98. package/lib/vertesia-ui-boot.js +52 -15
  99. package/lib/vertesia-ui-boot.js.map +1 -1
  100. package/lib/vertesia-ui-core.js +44 -44
  101. package/lib/vertesia-ui-core.js.map +1 -1
  102. package/lib/vertesia-ui-env.js +1 -1
  103. package/lib/vertesia-ui-env.js.map +1 -1
  104. package/lib/vertesia-ui-features.js +570 -585
  105. package/lib/vertesia-ui-features.js.map +1 -1
  106. package/lib/vertesia-ui-i18n.B1Nd8-dE.chunk.js +5 -0
  107. package/lib/vertesia-ui-i18n.B1Nd8-dE.chunk.js.map +1 -0
  108. package/lib/vertesia-ui-i18n.B2Z7mx1x.chunk.js +5 -0
  109. package/lib/vertesia-ui-i18n.B2Z7mx1x.chunk.js.map +1 -0
  110. package/lib/vertesia-ui-i18n.B756-YtS.chunk.js +5 -0
  111. package/lib/vertesia-ui-i18n.B756-YtS.chunk.js.map +1 -0
  112. package/lib/vertesia-ui-i18n.BICdgAEn.chunk.js +5 -0
  113. package/lib/vertesia-ui-i18n.BICdgAEn.chunk.js.map +1 -0
  114. package/lib/vertesia-ui-i18n.B_yx0c2A.chunk.js +5 -0
  115. package/lib/vertesia-ui-i18n.B_yx0c2A.chunk.js.map +1 -0
  116. package/lib/vertesia-ui-i18n.BwPrGiQn.chunk.js +5 -0
  117. package/lib/vertesia-ui-i18n.BwPrGiQn.chunk.js.map +1 -0
  118. package/lib/vertesia-ui-i18n.CfQbOHm3.chunk.js +5 -0
  119. package/lib/vertesia-ui-i18n.CfQbOHm3.chunk.js.map +1 -0
  120. package/lib/vertesia-ui-i18n.DMISlF16.chunk.js +5 -0
  121. package/lib/vertesia-ui-i18n.DMISlF16.chunk.js.map +1 -0
  122. package/lib/vertesia-ui-i18n.D_WA36Yq.chunk.js +5 -0
  123. package/lib/vertesia-ui-i18n.D_WA36Yq.chunk.js.map +1 -0
  124. package/lib/vertesia-ui-i18n.Dp3KuMs-.chunk.js +5 -0
  125. package/lib/vertesia-ui-i18n.Dp3KuMs-.chunk.js.map +1 -0
  126. package/lib/vertesia-ui-i18n.DsioKoQ3.chunk.js +5 -0
  127. package/lib/vertesia-ui-i18n.DsioKoQ3.chunk.js.map +1 -0
  128. package/lib/vertesia-ui-i18n.QEIqEPlv.chunk.js +5 -0
  129. package/lib/vertesia-ui-i18n.QEIqEPlv.chunk.js.map +1 -0
  130. package/lib/vertesia-ui-i18n.js +2 -2
  131. package/lib/vertesia-ui-i18n.js.map +1 -1
  132. package/lib/vertesia-ui-layout.js +15 -15
  133. package/lib/vertesia-ui-layout.js.map +1 -1
  134. package/lib/vertesia-ui-rich-text.js +44 -44
  135. package/lib/vertesia-ui-rich-text.js.map +1 -1
  136. package/lib/vertesia-ui-session.js +1 -1
  137. package/lib/vertesia-ui-session.js.map +1 -1
  138. package/lib/vertesia-ui-shell.js +51 -51
  139. package/lib/vertesia-ui-shell.js.map +1 -1
  140. package/lib/vertesia-ui-widgets.js +51 -51
  141. package/lib/vertesia-ui-widgets.js.map +1 -1
  142. package/package.json +20 -20
  143. package/src/boot/index.ts +74 -11
  144. package/src/boot/text.ts +80 -0
  145. package/src/core/components/shadcn/button.tsx +3 -2
  146. package/src/core/components/shadcn/selectBox.tsx +12 -4
  147. package/src/css/index.css +1 -1
  148. package/src/css/typography.css +111 -88
  149. package/src/env/index.ts +0 -2
  150. package/src/features/agent/chat/AskUserWidget.tsx +3 -1
  151. package/src/features/agent/chat/ModernAgentConversation.tsx +7 -4
  152. package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +2 -253
  153. package/src/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.tsx +2 -8
  154. package/src/features/agent/chat/ModernAgentOutput/SummaryConversation.ts +60 -0
  155. package/src/features/agent/chat/ModernAgentOutput/agentMarkdownStyles.ts +248 -0
  156. package/src/features/agent/chat/SkillWidgetProvider.tsx +3 -2
  157. package/src/i18n/LanguageProvider.tsx +16 -4
  158. package/src/i18n/locales/ar.json +6 -1
  159. package/src/i18n/locales/de.json +6 -1
  160. package/src/i18n/locales/en.json +6 -1
  161. package/src/i18n/locales/es.json +6 -1
  162. package/src/i18n/locales/fr.json +6 -1
  163. package/src/i18n/locales/it.json +6 -1
  164. package/src/i18n/locales/ja.json +6 -1
  165. package/src/i18n/locales/ko.json +6 -1
  166. package/src/i18n/locales/pt.json +6 -1
  167. package/src/i18n/locales/ru.json +6 -1
  168. package/src/i18n/locales/tr.json +6 -1
  169. package/src/i18n/locales/zh-TW.json +6 -1
  170. package/src/i18n/locales/zh.json +6 -1
  171. package/src/i18n/rtl.ts +5 -2
  172. package/src/session/UserSessionProvider.tsx +11 -4
  173. package/src/session/auth/composable.ts +1 -11
  174. package/src/session/auth/firebase.ts +9 -6
  175. package/src/session/auth/oauth.ts +65 -25
  176. package/src/session/auth/vertesiaHosts.ts +2 -47
  177. package/src/session/index.ts +1 -1
  178. package/src/session/scopeSelection.ts +13 -0
  179. package/src/shell/VertesiaShell.tsx +8 -2
  180. package/src/shell/login/InviteAcceptModal.tsx +112 -65
  181. package/lib/vertesia-ui-i18n.B0orbJb6.chunk.js +0 -5
  182. package/lib/vertesia-ui-i18n.B0orbJb6.chunk.js.map +0 -1
  183. package/lib/vertesia-ui-i18n.BChwIQVA.chunk.js +0 -5
  184. package/lib/vertesia-ui-i18n.BChwIQVA.chunk.js.map +0 -1
  185. package/lib/vertesia-ui-i18n.BTEcAVQm.chunk.js +0 -5
  186. package/lib/vertesia-ui-i18n.BTEcAVQm.chunk.js.map +0 -1
  187. package/lib/vertesia-ui-i18n.BeJQKbv7.chunk.js +0 -5
  188. package/lib/vertesia-ui-i18n.BeJQKbv7.chunk.js.map +0 -1
  189. package/lib/vertesia-ui-i18n.BpGr0-5g.chunk.js +0 -5
  190. package/lib/vertesia-ui-i18n.BpGr0-5g.chunk.js.map +0 -1
  191. package/lib/vertesia-ui-i18n.Bs8x-1wI.chunk.js +0 -5
  192. package/lib/vertesia-ui-i18n.Bs8x-1wI.chunk.js.map +0 -1
  193. package/lib/vertesia-ui-i18n.BymQoOm0.chunk.js +0 -5
  194. package/lib/vertesia-ui-i18n.BymQoOm0.chunk.js.map +0 -1
  195. package/lib/vertesia-ui-i18n.CNT_wabV.chunk.js +0 -5
  196. package/lib/vertesia-ui-i18n.CNT_wabV.chunk.js.map +0 -1
  197. package/lib/vertesia-ui-i18n.Cxh1iVk0.chunk.js +0 -5
  198. package/lib/vertesia-ui-i18n.Cxh1iVk0.chunk.js.map +0 -1
  199. package/lib/vertesia-ui-i18n.DLYCM9fV.chunk.js +0 -5
  200. package/lib/vertesia-ui-i18n.DLYCM9fV.chunk.js.map +0 -1
  201. package/lib/vertesia-ui-i18n.QvAVguDs.chunk.js +0 -5
  202. package/lib/vertesia-ui-i18n.QvAVguDs.chunk.js.map +0 -1
  203. package/lib/vertesia-ui-i18n.smozeSmI.chunk.js +0 -5
  204. package/lib/vertesia-ui-i18n.smozeSmI.chunk.js.map +0 -1
@@ -2,68 +2,109 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Button, Modal, ModalBody, ModalTitle } from '@vertesia/ui/core';
3
3
  import { useUITranslation } from '@vertesia/ui/i18n';
4
4
  import { useUserSession } from '@vertesia/ui/session';
5
- import { useEffect, useState } from 'react';
5
+ import { useCallback, useEffect, useState } from 'react';
6
+ // Legacy invites have no account data and cannot be shown or accepted here.
7
+ function withAccount(invites) {
8
+ return invites.filter((i) => i.data.account);
9
+ }
6
10
  export function InviteAcceptModal() {
7
11
  const session = useUserSession();
8
12
  const { client } = session;
9
13
  const { t } = useUITranslation();
10
14
  const [showModal, setShowModal] = useState(false);
11
15
  const [invites, setInvites] = useState([]);
16
+ const [pendingId, setPendingId] = useState();
17
+ const [error, setError] = useState();
18
+ const [acceptedAccountIds, setAcceptedAccountIds] = useState([]);
19
+ const isOpen = showModal && invites.length > 0;
20
+ const loadInvites = useCallback(async () => {
21
+ const valid = withAccount(await client.account.listInvites());
22
+ setInvites(valid);
23
+ return valid;
24
+ }, [client]);
12
25
  useEffect(() => {
13
- client.account
14
- .listInvites()
15
- .then((invites) => {
16
- if (invites.length > 0) {
17
- // Filter out legacy invites that do not have account data
18
- const notLegacyInvites = invites.filter((i) => i.data.account);
19
- if (notLegacyInvites.length === 0) {
20
- console.log('No valid invites found, closing modal');
21
- return;
22
- }
23
- // If we have valid invites, show the modal
24
- console.log('Found valid invites', notLegacyInvites.length);
26
+ loadInvites()
27
+ .then((valid) => {
28
+ if (valid.length > 0) {
29
+ console.log('Found valid invites', valid.length);
25
30
  setShowModal(true);
26
- setInvites(notLegacyInvites);
27
- }
28
- else {
29
- console.log('No invites found, closing modal');
30
- setShowModal(false);
31
31
  }
32
32
  })
33
33
  .catch((err) => {
34
34
  console.error('Error fetching invites', err);
35
35
  });
36
- }, [client.account.listInvites]);
36
+ }, [loadInvites]);
37
37
  const closeModal = () => setShowModal(false);
38
+ // Refreshing the session re-renders the app around the modal, so it waits until the modal has closed and
39
+ // then picks up every accepted invite at once.
40
+ useEffect(() => {
41
+ if (isOpen || acceptedAccountIds.length === 0)
42
+ return;
43
+ setAcceptedAccountIds([]);
44
+ void (async () => {
45
+ try {
46
+ // The current token predates the new memberships and does not list the new accounts, so the
47
+ // server rejects reads of them until a fresh token is minted.
48
+ await session.refreshAuthToken();
49
+ await session.fetchAccounts();
50
+ }
51
+ catch (err) {
52
+ console.error('Failed to refresh the session after accepting invites', err);
53
+ return;
54
+ }
55
+ // Each account loads on its own, so one failure does not hide the others.
56
+ for (const accountId of new Set(acceptedAccountIds)) {
57
+ await session.fetchProjects(accountId).catch((err) => {
58
+ console.error('Failed to load projects for an accepted invite', err);
59
+ });
60
+ }
61
+ })();
62
+ }, [isOpen, acceptedAccountIds, session]);
63
+ const removeInvite = (inviteId) => setInvites((current) => current.filter((i) => i.id !== inviteId));
64
+ // An accept or reject can fail because the invite was already used, e.g. from another tab: show the server's list.
65
+ const recoverFromFailure = async (action, err) => {
66
+ console.error(`Failed to ${action} invite`, err);
67
+ setError(t('login.inviteActionFailed'));
68
+ return loadInvites().catch((reloadErr) => {
69
+ console.error('Error fetching invites', reloadErr);
70
+ return undefined;
71
+ });
72
+ };
38
73
  const accept = async (invite) => {
39
- await client.account.acceptInvite(invite.id);
40
- await session.authCallback;
41
- await session.fetchAccounts();
42
- await session.fetchProjects(invite.data.account.id);
43
- const remainingInvites = invites.filter((i) => i.id !== invite.id);
44
- const notLegacyInvites = remainingInvites.filter((i) => i.data.account);
45
- if (notLegacyInvites.length > 0) {
46
- setInvites(notLegacyInvites);
74
+ setPendingId(invite.id);
75
+ setError(undefined);
76
+ try {
77
+ await client.account.acceptInvite(invite.id);
78
+ removeInvite(invite.id);
79
+ setAcceptedAccountIds((current) => [...current, invite.data.account.id]);
80
+ }
81
+ catch (err) {
82
+ const remaining = await recoverFromFailure('accept', err);
83
+ // A gone invite was most likely accepted after all (e.g. the response was lost), so its account
84
+ // still needs loading. If it was rejected elsewhere instead, that load fails harmlessly.
85
+ if (remaining && !remaining.some((i) => i.id === invite.id)) {
86
+ setAcceptedAccountIds((current) => [...current, invite.data.account.id]);
87
+ }
47
88
  }
48
- else {
49
- closeModal();
89
+ finally {
90
+ setPendingId(undefined);
50
91
  }
51
92
  };
52
93
  const reject = async (invite) => {
53
- await client.account.rejectInvite(invite.id);
54
- const remainingInvites = invites.filter((i) => i.id !== invite.id);
55
- setInvites(remainingInvites);
56
- if (remainingInvites.length === 0) {
57
- closeModal();
94
+ setPendingId(invite.id);
95
+ setError(undefined);
96
+ try {
97
+ await client.account.rejectInvite(invite.id);
98
+ removeInvite(invite.id);
58
99
  }
59
- };
60
- const inviteList = invites.map((invite) => {
61
- if (!invite.data.account) {
62
- console.warn('Invite has no account data', invite);
63
- return null; // Skip rendering this invite
100
+ catch (err) {
101
+ await recoverFromFailure('reject', err);
102
+ }
103
+ finally {
104
+ setPendingId(undefined);
64
105
  }
65
- return (_jsxs("div", { className: "flex flex-row w-full justify-between border rounded-sm px-2 py-2 ", children: [_jsxs("div", { className: "flex flex-col", children: [_jsx("div", { className: "w-full font-semibold", children: invite.data.account.name ?? invite.data.account }), invite.data.project && _jsxs("div", { className: "w-full text-base", children: ["- ", invite.data.project.name] }), _jsxs("div", { className: "text-xs", children: ["Role: ", invite.data.role] }), invite.data.invited_by && (_jsxs("div", { className: "text-xs", children: ["by ", invite.data.invited_by.name ?? invite.data.invited_by] }))] }), _jsxs("div", { className: "flex flex-col gap-4", children: [_jsx(Button, { size: 'xs', onClick: () => accept(invite), children: t('login.accept') }), ' ', _jsx(Button, { size: 'xs', variant: "secondary", onClick: () => reject(invite), children: t('login.reject') })] })] }, invite.id));
66
- });
67
- return (_jsx("div", { children: _jsxs(Modal, { isOpen: showModal, onClose: closeModal, children: [_jsx(ModalTitle, { children: t('login.reviewInvites') }), _jsxs(ModalBody, { children: [_jsx("div", { className: "text-sm pb-4", children: "You have received the following invites to join other accounts. Please review and accept or declined them." }), inviteList] })] }) }));
106
+ };
107
+ const inviteList = invites.map((invite) => (_jsxs("div", { className: "flex flex-row w-full justify-between border rounded-sm px-2 py-2 ", children: [_jsxs("div", { className: "flex flex-col", children: [_jsx("div", { className: "w-full font-semibold", children: invite.data.account.name }), invite.data.project && _jsxs("div", { className: "w-full text-base", children: ["- ", invite.data.project.name] }), _jsx("div", { className: "text-xs", children: t('login.inviteRole', { role: invite.data.role }) }), invite.data.invited_by && (_jsx("div", { className: "text-xs", children: t('login.invitedBy', { name: invite.data.invited_by.name }) }))] }), _jsxs("div", { className: "flex flex-col gap-4", children: [_jsx(Button, { size: 'xs', isDisabled: !!pendingId, isLoading: pendingId === invite.id, onClick: () => void accept(invite), children: t('login.accept') }), ' ', _jsx(Button, { size: 'xs', variant: "secondary", isDisabled: !!pendingId, onClick: () => void reject(invite), children: t('login.reject') })] })] }, invite.id)));
108
+ return (_jsx("div", { children: _jsxs(Modal, { isOpen: isOpen, onClose: closeModal, children: [_jsx(ModalTitle, { children: t('login.reviewInvites') }), _jsxs(ModalBody, { children: [_jsx("div", { className: "text-sm pb-4", children: t('login.invitesIntro') }), error && (_jsx("div", { role: "alert", className: "text-sm text-destructive pb-4", children: error })), inviteList] })] }) }));
68
109
  }
69
110
  //# sourceMappingURL=InviteAcceptModal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"InviteAcceptModal.js","sourceRoot":"","sources":["../../../src/shell/login/InviteAcceptModal.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"InviteAcceptModal.js","sourceRoot":"","sources":["../../../src/shell/login/InviteAcceptModal.tsx"],"names":[],"mappings":"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"}
@@ -1,12 +1,12 @@
1
- function e(e){return e}function t(e){return e.replace(/[&<>"']/g,e=>({"&":`&amp;`,"<":`&lt;`,">":`&gt;`,'"':`&quot;`,"'":`&#39;`})[e]??e)}function n(e){return JSON.stringify(e).replace(/</g,`\\3c `)}function r(e){let t={background:[`--background`,`--color-background`,`--vb-bg`],foreground:[`--foreground`,`--color-foreground`,`--vb-fg`],accent:[`--info`,`--info-foreground`,`--color-info`,`--color-info-foreground`],button:[`--primary`,`--color-primary`,`--vb-primary`,`--auth-button`],buttonText:[`--primary-foreground`,`--color-primary-foreground`,`--vb-primary-fg`,`--auth-button-text`]};return Object.entries(e??{}).map(([e,n])=>{if(!Object.hasOwn(t,e)||/[;{}<>]/.test(n))throw Error(`Invalid branding color: ${e}`);return t[e].map(e=>`${e}:${n};`).join(``)}).join(``)}function i(e,t=`.vbrand`){let i=e.loadingIcon?.animation,a=e.loadingIcon?.keyframes??``;if(i!==void 0&&/[;{}<>]/.test(i))throw Error(`Invalid loading icon animation`);if(/[<>]/.test(a))throw Error(`Invalid loading icon keyframes`);let o=i===void 0?``:`--vertesia-loading-animation:${i};--vertesia-loading-pulse-animation:none;`,s=e.font;return`${s?`@font-face { font-family:${n(s.family)};src:url(${n(s.regular)});font-weight:400;font-display:swap; }
2
- ${s.bold?`@font-face { font-family:${n(s.family)};src:url(${n(s.bold)});font-weight:700;font-display:swap; }`:``}`:``}
3
- ${a}
4
- ${t} { ${o}${r(e.colors?.light)}${s?`font-family:${n(s.family)};`:``} }
5
- .dark ${t},${t}.vboot-dark { ${r(e.colors?.dark)} }
6
- `}function a(e){return{iconSrc:e.loadingIcon?.light,darkIconSrc:e.loadingIcon?.dark,loadingLabel:e.copy?.loading,slowLoadingLabel:e.copy?.slowLoading,reloadLabel:e.copy?.reload,html:e.boot?.html,styles:`${i(e,`#loading-indicator`)}
1
+ const e=[`ar`,`de`,`en`,`es`,`fr`,`it`,`ja`,`ko`,`pt`,`ru`,`tr`,`zh`,`zh-TW`],t=/* @__PURE__ */ new Set([`ar`,`he`,`fa`,`ur`]);function n(e){return e?t.has(e.split(`-`)[0].toLowerCase()):!1}function r(e){return e}function i(e){return e.replace(/[&<>"']/g,e=>({"&":`&amp;`,"<":`&lt;`,">":`&gt;`,'"':`&quot;`,"'":`&#39;`})[e]??e)}function a(e){return JSON.stringify(e).replace(/</g,`\\3c `)}function o(e){let t={background:[`--background`,`--color-background`,`--vb-bg`],foreground:[`--foreground`,`--color-foreground`,`--vb-fg`],accent:[`--info`,`--info-foreground`,`--color-info`,`--color-info-foreground`],button:[`--primary`,`--color-primary`,`--vb-primary`,`--auth-button`],buttonText:[`--primary-foreground`,`--color-primary-foreground`,`--vb-primary-fg`,`--auth-button-text`]};return Object.entries(e??{}).map(([e,n])=>{if(!Object.hasOwn(t,e)||/[;{}<>]/.test(n))throw Error(`Invalid branding color: ${e}`);return t[e].map(e=>`${e}:${n};`).join(``)}).join(``)}function s(e,t=`.vbrand`){let n=e.loadingIcon?.animation,r=e.loadingIcon?.keyframes??``;if(n!==void 0&&/[;{}<>]/.test(n))throw Error(`Invalid loading icon animation`);if(/[<>]/.test(r))throw Error(`Invalid loading icon keyframes`);let i=n===void 0?``:`--vertesia-loading-animation:${n};--vertesia-loading-pulse-animation:none;`,s=e.font;return`${s?`@font-face { font-family:${a(s.family)};src:url(${a(s.regular)});font-weight:400;font-display:swap; }
2
+ ${s.bold?`@font-face { font-family:${a(s.family)};src:url(${a(s.bold)});font-weight:700;font-display:swap; }`:``}`:``}
3
+ ${r}
4
+ ${t} { ${i}${o(e.colors?.light)}${s?`font-family:${a(s.family)};`:``} }
5
+ .dark ${t},${t}.vboot-dark { ${o(e.colors?.dark)} }
6
+ `}function c(e){return{iconSrc:e.loadingIcon?.light,darkIconSrc:e.loadingIcon?.dark,loadingLabel:e.copy?.loading,slowLoadingLabel:e.copy?.slowLoading,reloadLabel:e.copy?.reload,html:e.boot?.html,styles:`${s(e,`#loading-indicator`)}
7
7
  ${e.colors?.light?.background?`:root{--vertesia-boot-background:${e.colors.light.background}}`:``}
8
8
  ${e.colors?.dark?.background?`:root.dark{--vertesia-boot-background:${e.colors.dark.background}}`:``}
9
- ${e.boot?.styles??``}`}}const o={name:`Vertesia`,logo:{light:`/logo-light.png`,dark:`/logo-dark.png`,alt:`Vertesia`},loadingIcon:{light:`/icon.svg`},favicon:`/icon.svg`},s=o.loadingIcon.light,c=`
9
+ ${e.boot?.styles??``}`}}const l={name:`Vertesia`,logo:{light:`/logo-light.png`,dark:`/logo-dark.png`,alt:`Vertesia`},loadingIcon:{light:`/icon.svg`},favicon:`/icon.svg`},u={ar:{loading:`جارٍ التحميل`,slowLoading:`لا يزال التحميل جاريًا — يستغرق الأمر وقتًا أطول من المعتاد.`,reload:`إعادة تحميل الصفحة`},de:{loading:`Wird geladen`,slowLoading:`Wird noch geladen – das dauert länger als üblich.`,reload:`Seite neu laden`},en:{loading:`Loading`,slowLoading:`Still loading — this is taking longer than usual.`,reload:`Reload page`},es:{loading:`Cargando`,slowLoading:`Todavía cargando: está tardando más de lo habitual.`,reload:`Recargar la página`},fr:{loading:`Chargement`,slowLoading:`Chargement en cours — cela prend plus de temps que d’habitude.`,reload:`Recharger la page`},it:{loading:`Caricamento`,slowLoading:`Caricamento ancora in corso: ci vuole più tempo del solito.`,reload:`Ricarica la pagina`},ja:{loading:`読み込み中`,slowLoading:`読み込み中です。通常より時間がかかっています。`,reload:`ページを再読み込み`},ko:{loading:`로드 중`,slowLoading:`아직 로드 중입니다. 평소보다 시간이 더 걸리고 있습니다.`,reload:`페이지 새로고침`},pt:{loading:`Carregando`,slowLoading:`Ainda carregando — está demorando mais do que o normal.`,reload:`Recarregar a página`},ru:{loading:`Загрузка`,slowLoading:`Загрузка продолжается — это занимает больше времени, чем обычно.`,reload:`Перезагрузить страницу`},tr:{loading:`Yükleniyor`,slowLoading:`Hâlâ yükleniyor — bu, normalden uzun sürüyor.`,reload:`Sayfayı yeniden yükle`},zh:{loading:`正在加载`,slowLoading:`仍在加载,所需时间比平时更长。`,reload:`重新加载页面`},"zh-TW":{loading:`載入中`,slowLoading:`仍在載入,所需時間比平常更長。`,reload:`重新載入頁面`}},d=l.loadingIcon.light,f=`
10
10
 
11
11
  @keyframes vertesia-loading-spin {
12
12
  from { transform: rotate(0deg); }
@@ -107,13 +107,45 @@ ${e.boot?.styles??``}`}}const o={name:`Vertesia`,logo:{light:`/logo-light.png`,d
107
107
  .vboot-btn:hover {
108
108
  opacity: 0.9;
109
109
  }
110
- `;function l(e){return JSON.stringify(e).replaceAll(`<`,`\\u003c`)}function u(e){return{storageKey:e.storageKey??`vite-ui-theme`,iconSrc:e.iconSrc??s,loadingLabel:e.loadingLabel??`Loading`,autoStart:e.autoStart??!0,html:e.html,styles:e.styles}}function d(e={}){let t=e=>e.replace(/[&<>"']/g,e=>({"&":`&amp;`,"<":`&lt;`,">":`&gt;`,'"':`&quot;`,"'":`&#39;`})[e]??e),{iconSrc:n,loadingLabel:r}=u(e),i=(e,n=``)=>`<img class="vboot-spinner vertesia-loading-icon vertesia-loading-motion ${n}" width="40" height="40" src="${t(e)}" alt="${t(r)}" />`;return`<div class="vboot-overlay" role="status" aria-live="polite">${e.darkIconSrc?i(n,`vboot-icon-light`)+i(e.darkIconSrc,`vboot-icon-dark`):i(n)}
110
+ `;function p(e){return JSON.stringify(e).replaceAll(`<`,`\\u003c`)}function m(e){return{...e,storageKey:e.storageKey??`vite-ui-theme`,iconSrc:e.iconSrc??d,language:e.language??`auto`,autoStart:e.autoStart??!0}}function h(e,t){return{loading:e.loadingLabel??u[t].loading,slowLoading:e.slowLoadingLabel??u[t].slowLoading,reload:e.reloadLabel??u[t].reload}}function g(t){let n=t.language&&t.language!==`auto`?[t.language]:e;return Object.fromEntries(n.map(e=>[e,h(t,e)]))}function _(e={}){let t=e=>e.replace(/[&<>"']/g,e=>({"&":`&amp;`,"<":`&lt;`,">":`&gt;`,'"':`&quot;`,"'":`&#39;`})[e]??e),{iconSrc:n,language:r}=m(e),i=h(e,r===`auto`?`en`:r),a=(e,n=``)=>`<img class="vboot-spinner vertesia-loading-icon vertesia-loading-motion ${n}" width="40" height="40" src="${t(e)}" alt="${t(i.loading)}" data-boot-alt="loading" />`;return`<div class="vboot-overlay" role="status" aria-live="polite">${e.darkIconSrc?a(n,`vboot-icon-light`)+a(e.darkIconSrc,`vboot-icon-dark`):a(n)}
111
111
  <div id="loading-slow-notice" class="vboot-slow" style="display: none;">
112
- <p>${t(e.slowLoadingLabel??`Still loading — this is taking longer than usual.`)}</p>
113
- <div id="loading-slow-reload" style="display: none;"><button type="button" class="vboot-btn" data-boot-reload>${t(e.reloadLabel??`Reload page`)}</button></div></div></div>`}function f(e={}){let{storageKey:t,html:n}=u(e),r=d(e);return`(() => {
114
- const storageKey = ${l(t)};
112
+ <p data-boot-text="slowLoading">${t(i.slowLoading)}</p>
113
+ <div id="loading-slow-reload" style="display: none;"><button type="button" class="vboot-btn" data-boot-reload data-boot-text="reload">${t(i.reload)}</button></div></div></div>`}function v(t={}){let{storageKey:r,html:i,language:a}=m(t),o=_(t);return`(() => {
114
+ const storageKey = ${p(r)};
115
115
 
116
- const customHtml = ${n===void 0?`undefined`:l(n)};
116
+ const customHtml = ${i===void 0?`undefined`:p(i)};
117
+ const bootText = ${p(g(t))};
118
+ // Mirrors resolveLanguage and LanguageProvider's initial read (i18n/rtl.ts, i18n/LanguageProvider.tsx).
119
+ const hasText = (code) => Object.prototype.hasOwnProperty.call(bootText, code);
120
+ const resolveLanguage = (raw) => {
121
+ if (!raw) return 'en';
122
+ if (hasText(raw)) return raw;
123
+ const base = String(raw).split('-')[0];
124
+ return hasText(base) ? base : 'en';
125
+ };
126
+ const language = (() => {
127
+ const pinned = ${p(a)};
128
+ if (pinned !== 'auto') return pinned;
129
+ try {
130
+ const stored = window.localStorage.getItem(${p(`vertesia-ui-language`)});
131
+ if (stored) return resolveLanguage(stored);
132
+ } catch (_error) {
133
+ // Storage can be unavailable in private or restricted browsing contexts.
134
+ }
135
+ return resolveLanguage(window.navigator && window.navigator.language);
136
+ })();
137
+ const direction = ${p(e.filter(e=>n(e)))}.includes(language) ? 'rtl' : 'ltr';
138
+ const localize = (container) => {
139
+ const text = bootText[language];
140
+ container.querySelectorAll('[data-boot-text]').forEach((node) => {
141
+ const value = text[node.getAttribute('data-boot-text')];
142
+ if (value) node.textContent = value;
143
+ });
144
+ container.querySelectorAll('[data-boot-alt]').forEach((node) => {
145
+ const value = text[node.getAttribute('data-boot-alt')];
146
+ if (value) node.setAttribute('alt', value);
147
+ });
148
+ };
117
149
  let slowNoticeTimer;
118
150
  let slowReloadTimer;
119
151
  const previewTheme = (() => {
@@ -169,7 +201,10 @@ ${e.boot?.styles??``}`}}const o={name:`Vertesia`,logo:{light:`/logo-light.png`,d
169
201
  const loading = document.createElement('div');
170
202
  loading.id = 'loading-indicator';
171
203
  loading.className = bootThemeClass();
172
- loading.innerHTML = customHtml ?? ${l(r)};
204
+ loading.lang = language;
205
+ loading.dir = direction;
206
+ loading.innerHTML = customHtml ?? ${p(o)};
207
+ localize(loading);
173
208
  loading.querySelectorAll('[data-boot-title]').forEach((heading) => {
174
209
  if (document.title) heading.textContent = document.title;
175
210
  });
@@ -224,6 +259,8 @@ ${e.boot?.styles??``}`}}const o={name:`Vertesia`,logo:{light:`/logo-light.png`,d
224
259
  }, 30000);
225
260
  };
226
261
  window.__vertesiaBoot = {
262
+ direction,
263
+ language,
227
264
  scheduleSlowLoadingNotice,
228
265
  applyTheme,
229
266
  bootThemeClass,
@@ -236,6 +273,6 @@ ${e.boot?.styles??``}`}}const o={name:`Vertesia`,logo:{light:`/logo-light.png`,d
236
273
  restoreDocumentBackground,
237
274
  };
238
275
  paintDocumentBackground();
239
- })();`}function p(e={}){return`<style id="vertesia-boot-styles">${c}\n${e.styles??``}</style>\n<script>${f(e)}<\/script>`}function m(){return`<script>window.__vertesiaBoot.ensureLoadingIndicator(); window.__vertesiaBoot.hideLoadingIndicatorOnFirstRender(); window.__vertesiaBoot.scheduleSlowLoadingNotice();<\/script>`}function h(e){return e===` `||e===` `||e===`
240
- `||e===`\r`||e===`\f`}function g(e,t){let n=e.toLowerCase(),r=0;for(;r<n.length;){let e=n.indexOf(t,r);if(e===-1)return!1;let i=n[e-1],a=e+t.length;for(;h(n[a]);)a+=1;if(h(i)&&n[a]===`=`)return!0;r=e+t.length}return!1}function _(e,t,n){let r=e.toLowerCase(),i=`<${t}`,a=0;for(;a<r.length;){let e=r.indexOf(i,a);if(e===-1)return;let t=r[e+i.length];if(t===`>`||h(t)){let t=r.indexOf(`>`,e+i.length);if(t===-1)return;if(!n||g(r.slice(e,t+1),n))return t+1;a=t+1}else a=e+i.length}}function v(e,t,n){return`${e.slice(0,t)}${n}${e.slice(t)}`}function y(e,t={}){let n=u(t),r=p(n),i=_(e,`meta`,`charset`)??_(e,`head`),a=i===void 0?e:v(e,i,`\n${r}`);if(!n.autoStart)return a;let o=a.toLowerCase().indexOf(`</body>`);return o===-1?a:v(a,o,`${m()}\n`)}function b(e={}){return{name:`vertesia-boot-screen`,transformIndexHtml:t=>y(t,e)}}export{c as BOOT_SCREEN_STYLES,a as brandedBootOptions,b as createBootScreenVitePlugin,e as defineAppBranding,t as escapeBrandHtml,y as injectBootScreenHtml,p as renderBootScreenHead,m as renderBootScreenInitializer,f as renderBootScreenRuntime,i as renderBrandStyles,d as renderDefaultBootContent,o as vertesiaBranding};
276
+ })();`}function y(e={}){return`<style id="vertesia-boot-styles">${f}\n${e.styles??``}</style>\n<script>${v(e)}<\/script>`}function b(){return`<script>window.__vertesiaBoot.ensureLoadingIndicator(); window.__vertesiaBoot.hideLoadingIndicatorOnFirstRender(); window.__vertesiaBoot.scheduleSlowLoadingNotice();<\/script>`}function x(e){return e===` `||e===` `||e===`
277
+ `||e===`\r`||e===`\f`}function S(e,t){let n=e.toLowerCase(),r=0;for(;r<n.length;){let e=n.indexOf(t,r);if(e===-1)return!1;let i=n[e-1],a=e+t.length;for(;x(n[a]);)a+=1;if(x(i)&&n[a]===`=`)return!0;r=e+t.length}return!1}function C(e,t,n){let r=e.toLowerCase(),i=`<${t}`,a=0;for(;a<r.length;){let e=r.indexOf(i,a);if(e===-1)return;let t=r[e+i.length];if(t===`>`||x(t)){let t=r.indexOf(`>`,e+i.length);if(t===-1)return;if(!n||S(r.slice(e,t+1),n))return t+1;a=t+1}else a=e+i.length}}function w(e,t,n){return`${e.slice(0,t)}${n}${e.slice(t)}`}function T(e,t={}){let n=m(t),r=y(n),i=C(e,`meta`,`charset`)??C(e,`head`),a=i===void 0?e:w(e,i,`\n${r}`);if(!n.autoStart)return a;let o=a.toLowerCase().indexOf(`</body>`);return o===-1?a:w(a,o,`${b()}\n`)}function E(e={}){return{name:`vertesia-boot-screen`,transformIndexHtml:t=>T(t,e)}}export{f as BOOT_SCREEN_STYLES,c as brandedBootOptions,E as createBootScreenVitePlugin,r as defineAppBranding,i as escapeBrandHtml,T as injectBootScreenHtml,y as renderBootScreenHead,b as renderBootScreenInitializer,v as renderBootScreenRuntime,s as renderBrandStyles,_ as renderDefaultBootContent,l as vertesiaBranding};
241
278
  //# sourceMappingURL=vertesia-ui-boot.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"vertesia-ui-boot.js","names":["defineAppBranding","branding","escapeBrandHtml","value","char","cssString","colorDeclarations","variables","colors","key","name","renderBrandStyles","animation","brand","keyframes","motion","font","selector","brandedBootOptions","vertesiaBranding","DEFAULT_ICON_SRC","BOOT_SCREEN_STYLES","inlineJson","normalizedOptions","options","renderDefaultBootContent","escapeMarkup","icon","className","src","loadingLabel","iconSrc","renderBootScreenRuntime","defaultHtml","storageKey","html","renderBootScreenHead","renderBootScreenInitializer","isHtmlWhitespace","character","hasAttribute","lowerTag","openingTag","searchFrom","attributeIndex","attributeName","before","afterIndex","findOpeningTagEnd","lowerHtml","tagStart","tagName","start","boundary","end","insertAt","index","content","injectBootScreenHtml","normalized","head","insertionPoint","withHead","bodyEnd","createBootScreenVitePlugin"],"sources":["boot/branding.js","boot/loading.js","boot/index.js"],"sourcesContent":["export function defineAppBranding(branding) {\n return branding;\n}\nexport function escapeBrandHtml(value) {\n return value.replace(/[&<>\"']/g, (char) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' })[char] ?? char);\n}\nfunction cssString(value) {\n return JSON.stringify(value).replace(/</g, '\\\\3c ');\n}\nfunction colorDeclarations(colors) {\n const variables = {\n background: ['--background', '--color-background', '--vb-bg'],\n foreground: ['--foreground', '--color-foreground', '--vb-fg'],\n accent: ['--info', '--info-foreground', '--color-info', '--color-info-foreground'],\n button: ['--primary', '--color-primary', '--vb-primary', '--auth-button'],\n buttonText: ['--primary-foreground', '--color-primary-foreground', '--vb-primary-fg', '--auth-button-text'],\n };\n return Object.entries(colors ?? {})\n .map(([key, value]) => {\n if (!Object.hasOwn(variables, key) || /[;{}<>]/.test(value))\n throw new Error(`Invalid branding color: ${key}`);\n return variables[key].map((name) => `${name}:${value};`).join('');\n })\n .join('');\n}\n/** Theme tokens only: branding must never replace the shared page layout. */\nexport function renderBrandStyles(brand, selector = '.vbrand') {\n const animation = brand.loadingIcon?.animation;\n const keyframes = brand.loadingIcon?.keyframes ?? '';\n if (animation !== undefined && /[;{}<>]/.test(animation))\n throw new Error('Invalid loading icon animation');\n if (/[<>]/.test(keyframes))\n throw new Error('Invalid loading icon keyframes');\n const motion = animation === undefined\n ? ''\n : `--vertesia-loading-animation:${animation};--vertesia-loading-pulse-animation:none;`;\n const font = brand.font;\n const faces = font\n ? `@font-face { font-family:${cssString(font.family)};src:url(${cssString(font.regular)});font-weight:400;font-display:swap; }\n${font.bold ? `@font-face { font-family:${cssString(font.family)};src:url(${cssString(font.bold)});font-weight:700;font-display:swap; }` : ''}`\n : '';\n return `${faces}\n${keyframes}\n${selector} { ${motion}${colorDeclarations(brand.colors?.light)}${font ? `font-family:${cssString(font.family)};` : ''} }\n.dark ${selector},${selector}.vboot-dark { ${colorDeclarations(brand.colors?.dark)} }\n`;\n}\nexport function brandedBootOptions(brand) {\n return {\n iconSrc: brand.loadingIcon?.light,\n darkIconSrc: brand.loadingIcon?.dark,\n loadingLabel: brand.copy?.loading,\n slowLoadingLabel: brand.copy?.slowLoading,\n reloadLabel: brand.copy?.reload,\n html: brand.boot?.html,\n styles: `${renderBrandStyles(brand, '#loading-indicator')}\n${brand.colors?.light?.background ? `:root{--vertesia-boot-background:${brand.colors.light.background}}` : ''}\n${brand.colors?.dark?.background ? `:root.dark{--vertesia-boot-background:${brand.colors.dark.background}}` : ''}\n${brand.boot?.styles ?? ''}`,\n };\n}\n/** Platform defaults shared by boot markup and Firebase/OAuth React screens. */\nexport const vertesiaBranding = {\n name: 'Vertesia',\n logo: { light: '/logo-light.png', dark: '/logo-dark.png', alt: 'Vertesia' },\n loadingIcon: { light: '/icon.svg' },\n favicon: '/icon.svg',\n};\n//# sourceMappingURL=branding.js.map","/** Shared by server-rendered boot markup and React auth loaders. No React dependency. */\nexport const LOADING_ICON_SIZE = 40;\nexport const LOADING_INDICATOR_STYLES = `\n@keyframes vertesia-loading-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n}\n.vertesia-loading-motion {\n animation: var(--vertesia-loading-animation, vertesia-loading-spin 2s linear infinite);\n}\n.vertesia-loading-icon {\n width: ${LOADING_ICON_SIZE}px !important;\n min-width: ${LOADING_ICON_SIZE}px !important;\n max-width: ${LOADING_ICON_SIZE}px !important;\n height: ${LOADING_ICON_SIZE}px !important;\n min-height: ${LOADING_ICON_SIZE}px !important;\n max-height: ${LOADING_ICON_SIZE}px !important;\n margin: 0;\n padding: 0;\n object-fit: contain;\n flex: none;\n border-radius: 100% !important;\n}\n@media (prefers-reduced-motion: reduce) {\n .vertesia-loading-motion { animation: none !important; }\n}\n`;\n//# sourceMappingURL=loading.js.map","import { vertesiaBranding } from './branding.js';\nimport { LOADING_ICON_SIZE, LOADING_INDICATOR_STYLES } from './loading.js';\nconst DEFAULT_STORAGE_KEY = 'vite-ui-theme';\nconst DEFAULT_ICON_SRC = vertesiaBranding.loadingIcon.light;\nconst DEFAULT_LOADING_LABEL = 'Loading';\nexport const BOOT_SCREEN_STYLES = `\n${LOADING_INDICATOR_STYLES}\n .vboot {\n --vb-bg: #ffffff;\n --vb-fg: #0a0a0a;\n --vb-muted: #636363;\n --vb-muted-bg: #f5f5f5;\n --vb-border: #e5e5e5;\n --vb-primary: #0048bd;\n --vb-primary-fg: #ffffff;\n --vb-glow: rgba(50, 49, 189, 0.12);\n font-family: Inter, ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;\n color: var(--vb-fg);\n }\n .vboot.vboot-dark {\n --vb-bg: #0a0a0a;\n --vb-fg: #fafafa;\n --vb-muted: #a1a1a1;\n --vb-muted-bg: #262626;\n --vb-border: rgba(255, 255, 255, 0.1);\n --vb-primary: #2b69d1;\n --vb-primary-fg: #fafafa;\n --vb-glow: rgba(79, 70, 229, 0.2);\n }\n .vboot-overlay {\n position: absolute !important;\n inset: 0 !important;\n box-sizing: border-box !important;\n width: 100% !important;\n height: 100% !important;\n margin: 0 !important;\n padding: 0 !important;\n display: flex !important;\n flex-direction: column !important;\n align-items: center !important;\n justify-content: center !important;\n gap: 1.5rem !important;\n transform: none !important;\n background: var(--vb-bg) !important;\n }\n #loading-indicator {\n position: fixed !important;\n inset: 0 !important;\n z-index: 2147483647 !important;\n box-sizing: border-box !important;\n width: 100vw !important;\n height: 100vh !important;\n margin: 0 !important;\n padding: 0 !important;\n transform: none !important;\n }\n .vboot-icon-dark { display: none; }\n .vboot-dark .vboot-icon-light { display: none; }\n .vboot-dark .vboot-icon-dark { display: block; }\n .vboot-slow {\n text-align: center;\n }\n .vboot-slow p {\n color: var(--vb-muted);\n font-size: 0.875rem;\n margin: 0 0 0.75rem;\n }\n .vboot-btn {\n display: inline-block;\n padding: 0.5rem 1rem;\n background: var(--vb-primary);\n color: var(--vb-primary-fg);\n border: none;\n border-radius: 0.375rem;\n font: inherit;\n font-size: 0.875rem;\n font-weight: 500;\n cursor: pointer;\n }\n .vboot-btn:hover {\n opacity: 0.9;\n }\n`;\nfunction inlineJson(value) {\n return JSON.stringify(value).replaceAll('<', '\\\\u003c');\n}\nfunction normalizedOptions(options) {\n return {\n storageKey: options.storageKey ?? DEFAULT_STORAGE_KEY,\n iconSrc: options.iconSrc ?? DEFAULT_ICON_SRC,\n loadingLabel: options.loadingLabel ?? DEFAULT_LOADING_LABEL,\n autoStart: options.autoStart ?? true,\n html: options.html,\n styles: options.styles,\n };\n}\n/** Default markup shared by Studio and configurable applications. */\nexport function renderDefaultBootContent(options = {}) {\n const escapeMarkup = (value) => value.replace(/[&<>\"']/g, (char) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' })[char] ?? char);\n const { iconSrc, loadingLabel } = normalizedOptions(options);\n const icon = (src, className = '') => `<img class=\"vboot-spinner vertesia-loading-icon vertesia-loading-motion ${className}\" width=\"${LOADING_ICON_SIZE}\" height=\"${LOADING_ICON_SIZE}\" src=\"${escapeMarkup(src)}\" alt=\"${escapeMarkup(loadingLabel)}\" />`;\n return `<div class=\"vboot-overlay\" role=\"status\" aria-live=\"polite\">${options.darkIconSrc ? icon(iconSrc, 'vboot-icon-light') + icon(options.darkIconSrc, 'vboot-icon-dark') : icon(iconSrc)}\n<div id=\"loading-slow-notice\" class=\"vboot-slow\" style=\"display: none;\">\n<p>${escapeMarkup(options.slowLoadingLabel ?? 'Still loading — this is taking longer than usual.')}</p>\n<div id=\"loading-slow-reload\" style=\"display: none;\"><button type=\"button\" class=\"vboot-btn\" data-boot-reload>${escapeMarkup(options.reloadLabel ?? 'Reload page')}</button></div></div></div>`;\n}\nexport function renderBootScreenRuntime(options = {}) {\n const { storageKey, html } = normalizedOptions(options);\n const defaultHtml = renderDefaultBootContent(options);\n return `(() => {\n const storageKey = ${inlineJson(storageKey)};\n\n const customHtml = ${html === undefined ? 'undefined' : inlineJson(html)};\n let slowNoticeTimer;\n let slowReloadTimer;\n const previewTheme = (() => {\n try {\n const value = new URL(window.location.href).searchParams.get('__vertesia_boot_theme');\n return value === 'dark' || value === 'light' ? value : null;\n } catch (_error) {\n return null;\n }\n })();\n const prefersDarkTheme = () => {\n if (previewTheme) return previewTheme === 'dark';\n try {\n const stored = window.localStorage.getItem(storageKey);\n if (stored === 'dark') return true;\n if (stored === 'light') return false;\n } catch (_error) {\n // Storage can be unavailable in private or restricted browsing contexts.\n }\n try {\n return typeof window.matchMedia === 'function' && window.matchMedia('(prefers-color-scheme: dark)').matches;\n } catch (_error) {\n return false;\n }\n };\n const applyTheme = () => {\n const dark = prefersDarkTheme();\n const root = document.documentElement;\n root.classList.remove('light', 'dark');\n root.classList.add(dark ? 'dark' : 'light');\n return dark;\n };\n const paintDocumentBackground = () => {\n const dark = applyTheme();\n const root = document.documentElement;\n const background = window.getComputedStyle(root).getPropertyValue('--vertesia-boot-background').trim()\n || (dark ? '#0a0a0a' : '#ffffff');\n root.style.backgroundColor = background;\n root.style.colorScheme = dark ? 'dark' : 'light';\n if (document.body) document.body.style.backgroundColor = background;\n };\n const restoreDocumentBackground = () => {\n applyTheme();\n const root = document.documentElement;\n root.style.removeProperty('background-color');\n root.style.removeProperty('color-scheme');\n if (document.body) document.body.style.removeProperty('background-color');\n };\n const bootThemeClass = () => prefersDarkTheme() ? 'vboot vboot-dark' : 'vboot';\n const ensureLoadingIndicator = () => {\n if (document.getElementById('loading-indicator') || !document.body) return;\n paintDocumentBackground();\n const loading = document.createElement('div');\n loading.id = 'loading-indicator';\n loading.className = bootThemeClass();\n loading.innerHTML = customHtml ?? ${inlineJson(defaultHtml)};\n loading.querySelectorAll('[data-boot-title]').forEach((heading) => {\n if (document.title) heading.textContent = document.title;\n });\n loading.querySelectorAll('[data-boot-reload]').forEach((button) => {\n button.addEventListener('click', () => window.location.reload());\n });\n // Custom landmarks and controls must stay in body to enter the accessibility tree.\n const loadingParent = customHtml === undefined && typeof document.documentElement.appendChild === 'function'\n ? document.documentElement\n : document.body;\n loadingParent.appendChild(loading);\n };\n const hideLoadingIndicator = () => {\n clearTimeout(slowNoticeTimer);\n clearTimeout(slowReloadTimer);\n const loading = document.getElementById('loading-indicator');\n if (loading) loading.style.display = 'none';\n };\n const hasAppRendered = (rootId = 'root') => {\n const root = document.getElementById(rootId);\n return Boolean(root && root.innerHTML && root.innerHTML.trim() !== '');\n };\n const hideLoadingIndicatorOnFirstRender = (rootId = 'root') => {\n if (typeof MutationObserver !== 'function') return;\n const root = document.getElementById(rootId);\n if (!root) return;\n if (hasAppRendered(rootId)) {\n hideLoadingIndicator();\n restoreDocumentBackground();\n return;\n }\n const observer = new MutationObserver(() => {\n if (!hasAppRendered(rootId)) return;\n hideLoadingIndicator();\n restoreDocumentBackground();\n observer.disconnect();\n });\n observer.observe(root, { childList: true });\n };\n // Used by standalone apps. Hosts with their own error handler keep autoStart disabled.\n const scheduleSlowLoadingNotice = () => {\n clearTimeout(slowNoticeTimer);\n clearTimeout(slowReloadTimer);\n if (hasAppRendered()) return;\n slowNoticeTimer = setTimeout(() => {\n const notice = document.getElementById('loading-slow-notice');\n if (notice) notice.style.display = '';\n }, 10000);\n slowReloadTimer = setTimeout(() => {\n const reload = document.getElementById('loading-slow-reload');\n if (reload) reload.style.display = '';\n }, 30000);\n };\n window.__vertesiaBoot = {\n scheduleSlowLoadingNotice,\n applyTheme,\n bootThemeClass,\n ensureLoadingIndicator,\n hasAppRendered,\n hideLoadingIndicator,\n hideLoadingIndicatorOnFirstRender,\n paintDocumentBackground,\n prefersDarkTheme,\n restoreDocumentBackground,\n };\n paintDocumentBackground();\n})();`;\n}\nexport function renderBootScreenHead(options = {}) {\n return `<style id=\"vertesia-boot-styles\">${BOOT_SCREEN_STYLES}\\n${options.styles ?? ''}</style>\\n<script>${renderBootScreenRuntime(options)}</script>`;\n}\nexport function renderBootScreenInitializer() {\n return `<script>window.__vertesiaBoot.ensureLoadingIndicator(); window.__vertesiaBoot.hideLoadingIndicatorOnFirstRender(); window.__vertesiaBoot.scheduleSlowLoadingNotice();</script>`;\n}\nfunction isHtmlWhitespace(character) {\n return character === ' ' || character === '\\t' || character === '\\n' || character === '\\r' || character === '\\f';\n}\nfunction hasAttribute(openingTag, attributeName) {\n const lowerTag = openingTag.toLowerCase();\n let searchFrom = 0;\n while (searchFrom < lowerTag.length) {\n const attributeIndex = lowerTag.indexOf(attributeName, searchFrom);\n if (attributeIndex === -1)\n return false;\n const before = lowerTag[attributeIndex - 1];\n let afterIndex = attributeIndex + attributeName.length;\n while (isHtmlWhitespace(lowerTag[afterIndex]))\n afterIndex += 1;\n if (isHtmlWhitespace(before) && lowerTag[afterIndex] === '=')\n return true;\n searchFrom = attributeIndex + attributeName.length;\n }\n return false;\n}\nfunction findOpeningTagEnd(html, tagName, attributeName) {\n const lowerHtml = html.toLowerCase();\n const tagStart = `<${tagName}`;\n let searchFrom = 0;\n while (searchFrom < lowerHtml.length) {\n const start = lowerHtml.indexOf(tagStart, searchFrom);\n if (start === -1)\n return undefined;\n const boundary = lowerHtml[start + tagStart.length];\n if (boundary === '>' || isHtmlWhitespace(boundary)) {\n const end = lowerHtml.indexOf('>', start + tagStart.length);\n if (end === -1)\n return undefined;\n if (!attributeName || hasAttribute(lowerHtml.slice(start, end + 1), attributeName))\n return end + 1;\n searchFrom = end + 1;\n }\n else {\n searchFrom = start + tagStart.length;\n }\n }\n return undefined;\n}\nfunction insertAt(html, index, content) {\n return `${html.slice(0, index)}${content}${html.slice(index)}`;\n}\nexport function injectBootScreenHtml(html, options = {}) {\n const normalized = normalizedOptions(options);\n const head = renderBootScreenHead(normalized);\n const insertionPoint = findOpeningTagEnd(html, 'meta', 'charset') ?? findOpeningTagEnd(html, 'head');\n const withHead = insertionPoint === undefined ? html : insertAt(html, insertionPoint, `\\n${head}`);\n if (!normalized.autoStart)\n return withHead;\n const bodyEnd = withHead.toLowerCase().indexOf('</body>');\n return bodyEnd === -1 ? withHead : insertAt(withHead, bodyEnd, `${renderBootScreenInitializer()}\\n`);\n}\nexport function createBootScreenVitePlugin(options = {}) {\n return {\n name: 'vertesia-boot-screen',\n transformIndexHtml: (html) => injectBootScreenHtml(html, options),\n };\n}\nexport * from './branding.js';\n//# sourceMappingURL=index.js.map"],"mappings":"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"}
1
+ {"version":3,"file":"vertesia-ui-boot.js","names":["SUPPORTED_LANGUAGES","RTL_LANGUAGES","isRTL","lng","defineAppBranding","branding","escapeBrandHtml","value","char","cssString","colorDeclarations","variables","colors","key","name","renderBrandStyles","animation","brand","keyframes","motion","font","selector","brandedBootOptions","vertesiaBranding","BOOT_TEXT","DEFAULT_ICON_SRC","BOOT_SCREEN_STYLES","inlineJson","normalizedOptions","options","bootText","language","bootTexts","languages","renderDefaultBootContent","escapeMarkup","text","icon","className","src","iconSrc","renderBootScreenRuntime","defaultHtml","storageKey","html","code","renderBootScreenHead","renderBootScreenInitializer","isHtmlWhitespace","character","hasAttribute","lowerTag","openingTag","searchFrom","attributeIndex","attributeName","before","afterIndex","findOpeningTagEnd","lowerHtml","tagStart","tagName","start","boundary","end","insertAt","index","content","injectBootScreenHtml","normalized","head","insertionPoint","withHead","bodyEnd","createBootScreenVitePlugin"],"sources":["i18n/rtl.js","boot/branding.js","boot/loading.js","boot/text.js","boot/index.js"],"sourcesContent":["/**\n * RTL detection and language resolution for the @vertesia/ui locale set.\n *\n * SUPPORTED_LANGUAGES is the single source of truth for what locales the\n * switcher offers, and must stay in sync with the resources registered in\n * `./instance.ts`. A divergence-guard test (`./rtl.test.ts`) fails the build\n * if the two diverge.\n *\n * RTL_LANGUAGES is deliberately broader than SUPPORTED_LANGUAGES so that\n * dir=\"rtl\" handling is forward-compatible when new RTL locales (he, fa, ur,\n * ...) are added to instance.ts later.\n */\nexport const SUPPORTED_LANGUAGES = [\n 'ar',\n 'de',\n 'en',\n 'es',\n 'fr',\n 'it',\n 'ja',\n 'ko',\n 'pt',\n 'ru',\n 'tr',\n 'zh',\n 'zh-TW',\n];\n/** Where `LanguageProvider` persists the chosen language; the boot runtime reads it too. */\nexport const LANGUAGE_STORAGE_KEY = 'vertesia-ui-language';\nexport const RTL_LANGUAGES = new Set(['ar', 'he', 'fa', 'ur']);\nexport function isRTL(lng) {\n if (!lng)\n return false;\n return RTL_LANGUAGES.has(lng.split('-')[0].toLowerCase());\n}\n/**\n * Resolve any raw language code (BCP-47 or bare) to a SupportedLanguage:\n * 1. exact match against SUPPORTED_LANGUAGES (preserves `zh-TW` vs `zh`)\n * 2. base-language fallback (`pt-BR` -> `pt`)\n * 3. `'en'` fallback\n *\n * The pre-React boot runtime (`../boot/index.ts`) reimplements this same logic\n * in its inline script, which runs before any bundle loads.\n */\nexport function resolveLanguage(raw) {\n if (!raw)\n return 'en';\n const list = SUPPORTED_LANGUAGES;\n if (list.includes(raw))\n return raw;\n const base = raw.split('-')[0];\n if (list.includes(base))\n return base;\n return 'en';\n}\n//# sourceMappingURL=rtl.js.map","export function defineAppBranding(branding) {\n return branding;\n}\nexport function escapeBrandHtml(value) {\n return value.replace(/[&<>\"']/g, (char) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' })[char] ?? char);\n}\nfunction cssString(value) {\n return JSON.stringify(value).replace(/</g, '\\\\3c ');\n}\nfunction colorDeclarations(colors) {\n const variables = {\n background: ['--background', '--color-background', '--vb-bg'],\n foreground: ['--foreground', '--color-foreground', '--vb-fg'],\n accent: ['--info', '--info-foreground', '--color-info', '--color-info-foreground'],\n button: ['--primary', '--color-primary', '--vb-primary', '--auth-button'],\n buttonText: ['--primary-foreground', '--color-primary-foreground', '--vb-primary-fg', '--auth-button-text'],\n };\n return Object.entries(colors ?? {})\n .map(([key, value]) => {\n if (!Object.hasOwn(variables, key) || /[;{}<>]/.test(value))\n throw new Error(`Invalid branding color: ${key}`);\n return variables[key].map((name) => `${name}:${value};`).join('');\n })\n .join('');\n}\n/** Theme tokens only: branding must never replace the shared page layout. */\nexport function renderBrandStyles(brand, selector = '.vbrand') {\n const animation = brand.loadingIcon?.animation;\n const keyframes = brand.loadingIcon?.keyframes ?? '';\n if (animation !== undefined && /[;{}<>]/.test(animation))\n throw new Error('Invalid loading icon animation');\n if (/[<>]/.test(keyframes))\n throw new Error('Invalid loading icon keyframes');\n const motion = animation === undefined\n ? ''\n : `--vertesia-loading-animation:${animation};--vertesia-loading-pulse-animation:none;`;\n const font = brand.font;\n const faces = font\n ? `@font-face { font-family:${cssString(font.family)};src:url(${cssString(font.regular)});font-weight:400;font-display:swap; }\n${font.bold ? `@font-face { font-family:${cssString(font.family)};src:url(${cssString(font.bold)});font-weight:700;font-display:swap; }` : ''}`\n : '';\n return `${faces}\n${keyframes}\n${selector} { ${motion}${colorDeclarations(brand.colors?.light)}${font ? `font-family:${cssString(font.family)};` : ''} }\n.dark ${selector},${selector}.vboot-dark { ${colorDeclarations(brand.colors?.dark)} }\n`;\n}\nexport function brandedBootOptions(brand) {\n return {\n iconSrc: brand.loadingIcon?.light,\n darkIconSrc: brand.loadingIcon?.dark,\n loadingLabel: brand.copy?.loading,\n slowLoadingLabel: brand.copy?.slowLoading,\n reloadLabel: brand.copy?.reload,\n html: brand.boot?.html,\n styles: `${renderBrandStyles(brand, '#loading-indicator')}\n${brand.colors?.light?.background ? `:root{--vertesia-boot-background:${brand.colors.light.background}}` : ''}\n${brand.colors?.dark?.background ? `:root.dark{--vertesia-boot-background:${brand.colors.dark.background}}` : ''}\n${brand.boot?.styles ?? ''}`,\n };\n}\n/** Platform defaults shared by boot markup and Firebase/OAuth React screens. */\nexport const vertesiaBranding = {\n name: 'Vertesia',\n logo: { light: '/logo-light.png', dark: '/logo-dark.png', alt: 'Vertesia' },\n loadingIcon: { light: '/icon.svg' },\n favicon: '/icon.svg',\n};\n//# sourceMappingURL=branding.js.map","/** Shared by server-rendered boot markup and React auth loaders. No React dependency. */\nexport const LOADING_ICON_SIZE = 40;\nexport const LOADING_INDICATOR_STYLES = `\n@keyframes vertesia-loading-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n}\n.vertesia-loading-motion {\n animation: var(--vertesia-loading-animation, vertesia-loading-spin 2s linear infinite);\n}\n.vertesia-loading-icon {\n width: ${LOADING_ICON_SIZE}px !important;\n min-width: ${LOADING_ICON_SIZE}px !important;\n max-width: ${LOADING_ICON_SIZE}px !important;\n height: ${LOADING_ICON_SIZE}px !important;\n min-height: ${LOADING_ICON_SIZE}px !important;\n max-height: ${LOADING_ICON_SIZE}px !important;\n margin: 0;\n padding: 0;\n object-fit: contain;\n flex: none;\n border-radius: 100% !important;\n}\n@media (prefers-reduced-motion: reduce) {\n .vertesia-loading-motion { animation: none !important; }\n}\n`;\n//# sourceMappingURL=loading.js.map","export const BOOT_TEXT = {\n ar: {\n loading: 'جارٍ التحميل',\n slowLoading: 'لا يزال التحميل جاريًا — يستغرق الأمر وقتًا أطول من المعتاد.',\n reload: 'إعادة تحميل الصفحة',\n },\n de: {\n loading: 'Wird geladen',\n slowLoading: 'Wird noch geladen – das dauert länger als üblich.',\n reload: 'Seite neu laden',\n },\n en: {\n loading: 'Loading',\n slowLoading: 'Still loading — this is taking longer than usual.',\n reload: 'Reload page',\n },\n es: {\n loading: 'Cargando',\n slowLoading: 'Todavía cargando: está tardando más de lo habitual.',\n reload: 'Recargar la página',\n },\n fr: {\n loading: 'Chargement',\n slowLoading: 'Chargement en cours — cela prend plus de temps que d’habitude.',\n reload: 'Recharger la page',\n },\n it: {\n loading: 'Caricamento',\n slowLoading: 'Caricamento ancora in corso: ci vuole più tempo del solito.',\n reload: 'Ricarica la pagina',\n },\n ja: {\n loading: '読み込み中',\n slowLoading: '読み込み中です。通常より時間がかかっています。',\n reload: 'ページを再読み込み',\n },\n ko: {\n loading: '로드 중',\n slowLoading: '아직 로드 중입니다. 평소보다 시간이 더 걸리고 있습니다.',\n reload: '페이지 새로고침',\n },\n pt: {\n loading: 'Carregando',\n slowLoading: 'Ainda carregando — está demorando mais do que o normal.',\n reload: 'Recarregar a página',\n },\n ru: {\n loading: 'Загрузка',\n slowLoading: 'Загрузка продолжается — это занимает больше времени, чем обычно.',\n reload: 'Перезагрузить страницу',\n },\n tr: {\n loading: 'Yükleniyor',\n slowLoading: 'Hâlâ yükleniyor — bu, normalden uzun sürüyor.',\n reload: 'Sayfayı yeniden yükle',\n },\n zh: {\n loading: '正在加载',\n slowLoading: '仍在加载,所需时间比平时更长。',\n reload: '重新加载页面',\n },\n 'zh-TW': {\n loading: '載入中',\n slowLoading: '仍在載入,所需時間比平常更長。',\n reload: '重新載入頁面',\n },\n};\n//# sourceMappingURL=text.js.map","import { isRTL, LANGUAGE_STORAGE_KEY, SUPPORTED_LANGUAGES } from '../i18n/rtl.js';\nimport { vertesiaBranding } from './branding.js';\nimport { LOADING_ICON_SIZE, LOADING_INDICATOR_STYLES } from './loading.js';\nimport { BOOT_TEXT } from './text.js';\nconst DEFAULT_STORAGE_KEY = 'vite-ui-theme';\nconst DEFAULT_ICON_SRC = vertesiaBranding.loadingIcon.light;\nexport const BOOT_SCREEN_STYLES = `\n${LOADING_INDICATOR_STYLES}\n .vboot {\n --vb-bg: #ffffff;\n --vb-fg: #0a0a0a;\n --vb-muted: #636363;\n --vb-muted-bg: #f5f5f5;\n --vb-border: #e5e5e5;\n --vb-primary: #0048bd;\n --vb-primary-fg: #ffffff;\n --vb-glow: rgba(50, 49, 189, 0.12);\n font-family: Inter, ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;\n color: var(--vb-fg);\n }\n .vboot.vboot-dark {\n --vb-bg: #0a0a0a;\n --vb-fg: #fafafa;\n --vb-muted: #a1a1a1;\n --vb-muted-bg: #262626;\n --vb-border: rgba(255, 255, 255, 0.1);\n --vb-primary: #2b69d1;\n --vb-primary-fg: #fafafa;\n --vb-glow: rgba(79, 70, 229, 0.2);\n }\n .vboot-overlay {\n position: absolute !important;\n inset: 0 !important;\n box-sizing: border-box !important;\n width: 100% !important;\n height: 100% !important;\n margin: 0 !important;\n padding: 0 !important;\n display: flex !important;\n flex-direction: column !important;\n align-items: center !important;\n justify-content: center !important;\n gap: 1.5rem !important;\n transform: none !important;\n background: var(--vb-bg) !important;\n }\n #loading-indicator {\n position: fixed !important;\n inset: 0 !important;\n z-index: 2147483647 !important;\n box-sizing: border-box !important;\n width: 100vw !important;\n height: 100vh !important;\n margin: 0 !important;\n padding: 0 !important;\n transform: none !important;\n }\n .vboot-icon-dark { display: none; }\n .vboot-dark .vboot-icon-light { display: none; }\n .vboot-dark .vboot-icon-dark { display: block; }\n .vboot-slow {\n text-align: center;\n }\n .vboot-slow p {\n color: var(--vb-muted);\n font-size: 0.875rem;\n margin: 0 0 0.75rem;\n }\n .vboot-btn {\n display: inline-block;\n padding: 0.5rem 1rem;\n background: var(--vb-primary);\n color: var(--vb-primary-fg);\n border: none;\n border-radius: 0.375rem;\n font: inherit;\n font-size: 0.875rem;\n font-weight: 500;\n cursor: pointer;\n }\n .vboot-btn:hover {\n opacity: 0.9;\n }\n`;\nfunction inlineJson(value) {\n return JSON.stringify(value).replaceAll('<', '\\\\u003c');\n}\nfunction normalizedOptions(options) {\n return {\n ...options,\n storageKey: options.storageKey ?? DEFAULT_STORAGE_KEY,\n iconSrc: options.iconSrc ?? DEFAULT_ICON_SRC,\n language: options.language ?? 'auto',\n autoStart: options.autoStart ?? true,\n };\n}\n/** An app-supplied label wins in every language. */\nfunction bootText(options, language) {\n return {\n loading: options.loadingLabel ?? BOOT_TEXT[language].loading,\n slowLoading: options.slowLoadingLabel ?? BOOT_TEXT[language].slowLoading,\n reload: options.reloadLabel ?? BOOT_TEXT[language].reload,\n };\n}\n/** The copy of every language the runtime may pick: only the pinned one, or all of them. */\nfunction bootTexts(options) {\n const languages = options.language && options.language !== 'auto' ? [options.language] : SUPPORTED_LANGUAGES;\n return Object.fromEntries(languages.map((language) => [language, bootText(options, language)]));\n}\n/**\n * Default markup shared by Studio and configurable applications. It carries the copy of the pinned\n * language (English under `'auto'`); `data-boot-text` and `data-boot-alt` let the runtime swap in\n * the language it resolves at page load. Custom `html` may use the same attributes.\n */\nexport function renderDefaultBootContent(options = {}) {\n const escapeMarkup = (value) => value.replace(/[&<>\"']/g, (char) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' })[char] ?? char);\n const { iconSrc, language } = normalizedOptions(options);\n const text = bootText(options, language === 'auto' ? 'en' : language);\n const icon = (src, className = '') => `<img class=\"vboot-spinner vertesia-loading-icon vertesia-loading-motion ${className}\" width=\"${LOADING_ICON_SIZE}\" height=\"${LOADING_ICON_SIZE}\" src=\"${escapeMarkup(src)}\" alt=\"${escapeMarkup(text.loading)}\" data-boot-alt=\"loading\" />`;\n return `<div class=\"vboot-overlay\" role=\"status\" aria-live=\"polite\">${options.darkIconSrc ? icon(iconSrc, 'vboot-icon-light') + icon(options.darkIconSrc, 'vboot-icon-dark') : icon(iconSrc)}\n<div id=\"loading-slow-notice\" class=\"vboot-slow\" style=\"display: none;\">\n<p data-boot-text=\"slowLoading\">${escapeMarkup(text.slowLoading)}</p>\n<div id=\"loading-slow-reload\" style=\"display: none;\"><button type=\"button\" class=\"vboot-btn\" data-boot-reload data-boot-text=\"reload\">${escapeMarkup(text.reload)}</button></div></div></div>`;\n}\nexport function renderBootScreenRuntime(options = {}) {\n const { storageKey, html, language } = normalizedOptions(options);\n const defaultHtml = renderDefaultBootContent(options);\n return `(() => {\n const storageKey = ${inlineJson(storageKey)};\n\n const customHtml = ${html === undefined ? 'undefined' : inlineJson(html)};\n const bootText = ${inlineJson(bootTexts(options))};\n // Mirrors resolveLanguage and LanguageProvider's initial read (i18n/rtl.ts, i18n/LanguageProvider.tsx).\n const hasText = (code) => Object.prototype.hasOwnProperty.call(bootText, code);\n const resolveLanguage = (raw) => {\n if (!raw) return 'en';\n if (hasText(raw)) return raw;\n const base = String(raw).split('-')[0];\n return hasText(base) ? base : 'en';\n };\n const language = (() => {\n const pinned = ${inlineJson(language)};\n if (pinned !== 'auto') return pinned;\n try {\n const stored = window.localStorage.getItem(${inlineJson(LANGUAGE_STORAGE_KEY)});\n if (stored) return resolveLanguage(stored);\n } catch (_error) {\n // Storage can be unavailable in private or restricted browsing contexts.\n }\n return resolveLanguage(window.navigator && window.navigator.language);\n })();\n const direction = ${inlineJson(SUPPORTED_LANGUAGES.filter((code) => isRTL(code)))}.includes(language) ? 'rtl' : 'ltr';\n const localize = (container) => {\n const text = bootText[language];\n container.querySelectorAll('[data-boot-text]').forEach((node) => {\n const value = text[node.getAttribute('data-boot-text')];\n if (value) node.textContent = value;\n });\n container.querySelectorAll('[data-boot-alt]').forEach((node) => {\n const value = text[node.getAttribute('data-boot-alt')];\n if (value) node.setAttribute('alt', value);\n });\n };\n let slowNoticeTimer;\n let slowReloadTimer;\n const previewTheme = (() => {\n try {\n const value = new URL(window.location.href).searchParams.get('__vertesia_boot_theme');\n return value === 'dark' || value === 'light' ? value : null;\n } catch (_error) {\n return null;\n }\n })();\n const prefersDarkTheme = () => {\n if (previewTheme) return previewTheme === 'dark';\n try {\n const stored = window.localStorage.getItem(storageKey);\n if (stored === 'dark') return true;\n if (stored === 'light') return false;\n } catch (_error) {\n // Storage can be unavailable in private or restricted browsing contexts.\n }\n try {\n return typeof window.matchMedia === 'function' && window.matchMedia('(prefers-color-scheme: dark)').matches;\n } catch (_error) {\n return false;\n }\n };\n const applyTheme = () => {\n const dark = prefersDarkTheme();\n const root = document.documentElement;\n root.classList.remove('light', 'dark');\n root.classList.add(dark ? 'dark' : 'light');\n return dark;\n };\n const paintDocumentBackground = () => {\n const dark = applyTheme();\n const root = document.documentElement;\n const background = window.getComputedStyle(root).getPropertyValue('--vertesia-boot-background').trim()\n || (dark ? '#0a0a0a' : '#ffffff');\n root.style.backgroundColor = background;\n root.style.colorScheme = dark ? 'dark' : 'light';\n if (document.body) document.body.style.backgroundColor = background;\n };\n const restoreDocumentBackground = () => {\n applyTheme();\n const root = document.documentElement;\n root.style.removeProperty('background-color');\n root.style.removeProperty('color-scheme');\n if (document.body) document.body.style.removeProperty('background-color');\n };\n const bootThemeClass = () => prefersDarkTheme() ? 'vboot vboot-dark' : 'vboot';\n const ensureLoadingIndicator = () => {\n if (document.getElementById('loading-indicator') || !document.body) return;\n paintDocumentBackground();\n const loading = document.createElement('div');\n loading.id = 'loading-indicator';\n loading.className = bootThemeClass();\n loading.lang = language;\n loading.dir = direction;\n loading.innerHTML = customHtml ?? ${inlineJson(defaultHtml)};\n localize(loading);\n loading.querySelectorAll('[data-boot-title]').forEach((heading) => {\n if (document.title) heading.textContent = document.title;\n });\n loading.querySelectorAll('[data-boot-reload]').forEach((button) => {\n button.addEventListener('click', () => window.location.reload());\n });\n // Custom landmarks and controls must stay in body to enter the accessibility tree.\n const loadingParent = customHtml === undefined && typeof document.documentElement.appendChild === 'function'\n ? document.documentElement\n : document.body;\n loadingParent.appendChild(loading);\n };\n const hideLoadingIndicator = () => {\n clearTimeout(slowNoticeTimer);\n clearTimeout(slowReloadTimer);\n const loading = document.getElementById('loading-indicator');\n if (loading) loading.style.display = 'none';\n };\n const hasAppRendered = (rootId = 'root') => {\n const root = document.getElementById(rootId);\n return Boolean(root && root.innerHTML && root.innerHTML.trim() !== '');\n };\n const hideLoadingIndicatorOnFirstRender = (rootId = 'root') => {\n if (typeof MutationObserver !== 'function') return;\n const root = document.getElementById(rootId);\n if (!root) return;\n if (hasAppRendered(rootId)) {\n hideLoadingIndicator();\n restoreDocumentBackground();\n return;\n }\n const observer = new MutationObserver(() => {\n if (!hasAppRendered(rootId)) return;\n hideLoadingIndicator();\n restoreDocumentBackground();\n observer.disconnect();\n });\n observer.observe(root, { childList: true });\n };\n // Used by standalone apps. Hosts with their own error handler keep autoStart disabled.\n const scheduleSlowLoadingNotice = () => {\n clearTimeout(slowNoticeTimer);\n clearTimeout(slowReloadTimer);\n if (hasAppRendered()) return;\n slowNoticeTimer = setTimeout(() => {\n const notice = document.getElementById('loading-slow-notice');\n if (notice) notice.style.display = '';\n }, 10000);\n slowReloadTimer = setTimeout(() => {\n const reload = document.getElementById('loading-slow-reload');\n if (reload) reload.style.display = '';\n }, 30000);\n };\n window.__vertesiaBoot = {\n direction,\n language,\n scheduleSlowLoadingNotice,\n applyTheme,\n bootThemeClass,\n ensureLoadingIndicator,\n hasAppRendered,\n hideLoadingIndicator,\n hideLoadingIndicatorOnFirstRender,\n paintDocumentBackground,\n prefersDarkTheme,\n restoreDocumentBackground,\n };\n paintDocumentBackground();\n})();`;\n}\nexport function renderBootScreenHead(options = {}) {\n return `<style id=\"vertesia-boot-styles\">${BOOT_SCREEN_STYLES}\\n${options.styles ?? ''}</style>\\n<script>${renderBootScreenRuntime(options)}</script>`;\n}\nexport function renderBootScreenInitializer() {\n return `<script>window.__vertesiaBoot.ensureLoadingIndicator(); window.__vertesiaBoot.hideLoadingIndicatorOnFirstRender(); window.__vertesiaBoot.scheduleSlowLoadingNotice();</script>`;\n}\nfunction isHtmlWhitespace(character) {\n return character === ' ' || character === '\\t' || character === '\\n' || character === '\\r' || character === '\\f';\n}\nfunction hasAttribute(openingTag, attributeName) {\n const lowerTag = openingTag.toLowerCase();\n let searchFrom = 0;\n while (searchFrom < lowerTag.length) {\n const attributeIndex = lowerTag.indexOf(attributeName, searchFrom);\n if (attributeIndex === -1)\n return false;\n const before = lowerTag[attributeIndex - 1];\n let afterIndex = attributeIndex + attributeName.length;\n while (isHtmlWhitespace(lowerTag[afterIndex]))\n afterIndex += 1;\n if (isHtmlWhitespace(before) && lowerTag[afterIndex] === '=')\n return true;\n searchFrom = attributeIndex + attributeName.length;\n }\n return false;\n}\nfunction findOpeningTagEnd(html, tagName, attributeName) {\n const lowerHtml = html.toLowerCase();\n const tagStart = `<${tagName}`;\n let searchFrom = 0;\n while (searchFrom < lowerHtml.length) {\n const start = lowerHtml.indexOf(tagStart, searchFrom);\n if (start === -1)\n return undefined;\n const boundary = lowerHtml[start + tagStart.length];\n if (boundary === '>' || isHtmlWhitespace(boundary)) {\n const end = lowerHtml.indexOf('>', start + tagStart.length);\n if (end === -1)\n return undefined;\n if (!attributeName || hasAttribute(lowerHtml.slice(start, end + 1), attributeName))\n return end + 1;\n searchFrom = end + 1;\n }\n else {\n searchFrom = start + tagStart.length;\n }\n }\n return undefined;\n}\nfunction insertAt(html, index, content) {\n return `${html.slice(0, index)}${content}${html.slice(index)}`;\n}\nexport function injectBootScreenHtml(html, options = {}) {\n const normalized = normalizedOptions(options);\n const head = renderBootScreenHead(normalized);\n const insertionPoint = findOpeningTagEnd(html, 'meta', 'charset') ?? findOpeningTagEnd(html, 'head');\n const withHead = insertionPoint === undefined ? html : insertAt(html, insertionPoint, `\\n${head}`);\n if (!normalized.autoStart)\n return withHead;\n const bodyEnd = withHead.toLowerCase().indexOf('</body>');\n return bodyEnd === -1 ? withHead : insertAt(withHead, bodyEnd, `${renderBootScreenInitializer()}\\n`);\n}\nexport function createBootScreenVitePlugin(options = {}) {\n return {\n name: 'vertesia-boot-screen',\n transformIndexHtml: (html) => injectBootScreenHtml(html, options),\n };\n}\nexport * from './branding.js';\n//# sourceMappingURL=index.js.map"],"mappings":"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"}