@iblai/web-utils 1.11.12 → 1.12.1
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/auth/index.d.ts +3 -1
- package/dist/auth/index.esm.js +62 -2
- package/dist/auth/index.esm.js.map +1 -1
- package/dist/auth/index.js +63 -1
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/web-utils/src/features/tracking/time-tracker.d.ts +55 -4
- package/dist/auth/web-utils/src/providers/auth-provider.d.ts +0 -1
- package/dist/auth/web-utils/src/utils/auth.d.ts +2 -0
- package/dist/index.d.ts +58 -6
- package/dist/index.esm.js +341 -134
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +341 -133
- package/dist/index.js.map +1 -1
- package/dist/package.json +1 -1
- package/dist/web-utils/src/features/tracking/time-tracker.d.ts +55 -4
- package/dist/web-utils/src/providers/auth-provider.d.ts +0 -1
- package/dist/web-utils/src/utils/auth.d.ts +2 -0
- package/dist/web-utils/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -7,6 +7,103 @@ import { jsx, Fragment } from 'react/jsx-runtime';
|
|
|
7
7
|
import { MentorVisibilityEnum } from '@iblai/iblai-api';
|
|
8
8
|
import axios from 'axios';
|
|
9
9
|
|
|
10
|
+
const MENTOR_CHAT_DOCUMENTS_EXTENSIONS = [
|
|
11
|
+
// Media types
|
|
12
|
+
"video/*",
|
|
13
|
+
"audio/*",
|
|
14
|
+
"image/*",
|
|
15
|
+
// Document types
|
|
16
|
+
".docx",
|
|
17
|
+
".xlsx",
|
|
18
|
+
".pptx",
|
|
19
|
+
".csv",
|
|
20
|
+
".md",
|
|
21
|
+
".txt",
|
|
22
|
+
".pdf",
|
|
23
|
+
];
|
|
24
|
+
const ANONYMOUS_USERNAME = "anonymous";
|
|
25
|
+
const DEFAULT_DISCLAIMER_CONTENT = `By accessing and using the [ibl.ai](http://ibl.ai/) MentorAI platform (“Platform”), you agree to the following terms. The Platform provides AI-powered mentorship and educational support. You understand that AI responses may contain inaccuracies, and you are responsible for independently verifying any information before relying on it for academic, professional, or personal decisions. Do not input confidential, sensitive, or personally identifiable information of yourself or others.
|
|
26
|
+
All content, code, and data processed through the Platform remain the property of their respective owners. [ibl.ai](http://ibl.ai/) retains all rights to the Platform’s underlying technology and intellectual property. You are granted a limited, non-exclusive, revocable license to use the Platform for personal or institutional learning purposes only.
|
|
27
|
+
Your use must comply with applicable laws and institutional policies. Misuse—including attempting to bypass security, copy source code, or use the service for unlawful activity—may result in suspension or termination of access. Continued use constitutes acceptance of these terms.`;
|
|
28
|
+
const MAX_INITIAL_WEBSOCKET_CONNECTION_ATTEMPTS = 3;
|
|
29
|
+
const LOCAL_STORAGE_KEYS = {
|
|
30
|
+
CURRENT_TENANT: "current_tenant",
|
|
31
|
+
TENANTS: "tenants",
|
|
32
|
+
REDIRECT_TO: "redirect-to",
|
|
33
|
+
AUTH_TOKEN: "axd_token",
|
|
34
|
+
TOKEN_EXPIRY: "axd_token_expires",
|
|
35
|
+
USER_DATA: "userData",
|
|
36
|
+
USER_TENANTS: "tenants",
|
|
37
|
+
VISITING_TENANT: "visiting_tenant",
|
|
38
|
+
SESSION_ID: "session_id",
|
|
39
|
+
EDX_TOKEN_KEY: "edx_jwt_token",
|
|
40
|
+
DM_TOKEN_KEY: "dm_token",
|
|
41
|
+
DM_TOKEN_EXPIRES: "dm_token_expires",
|
|
42
|
+
DM_TOKEN_EXPIRY: "dm_token_expires",
|
|
43
|
+
AXD_TOKEN_KEY: "axd_token",
|
|
44
|
+
DEFAULT_TENANT: "tenant",
|
|
45
|
+
MODEL_DOWNLOAD_STATE: "model_download_state",
|
|
46
|
+
MODEL_DOWNLOAD_PROMPT_DISMISSED: "model_download_prompt_dismissed",
|
|
47
|
+
};
|
|
48
|
+
const TOOLS = {
|
|
49
|
+
WEB_SEARCH: "web-search",
|
|
50
|
+
WIKIPEDIA_SEARCH: "wikipedia-search",
|
|
51
|
+
COURSE_CREATION: "course-creation",
|
|
52
|
+
MCP: "mcp",
|
|
53
|
+
IMAGE_GENERATION: "image-generation",
|
|
54
|
+
IBL_PATHWAY_DOCUMENTS_RETRIEVER: "ibl-pathway-documents-retriever",
|
|
55
|
+
TRAINED_DOCUMENTS: "trained-documents",
|
|
56
|
+
IBL_SESSION_DOCUMENTS_RETRIEVER: "ibl-session-documents-retriever",
|
|
57
|
+
PLAYWRIGHT_BROWSER: "playwright-browser",
|
|
58
|
+
HUMAN_SUPPORT: "human-support",
|
|
59
|
+
CODE_INTERPRETER: "code-interpreter",
|
|
60
|
+
DEEP_RESEARCH: "deep-research",
|
|
61
|
+
STUDY_MODE: "study-mode",
|
|
62
|
+
MEMORY: "memory",
|
|
63
|
+
SCREEN_SHARE: "screen-share",
|
|
64
|
+
POWERPOINT: "powerpoint",
|
|
65
|
+
PROMPT: "prompt",
|
|
66
|
+
QUIZ: "quiz",
|
|
67
|
+
RUBRIC: "rubric",
|
|
68
|
+
RESOURCE: "resource",
|
|
69
|
+
LESSON_PLAN: "lesson-plan",
|
|
70
|
+
SYLLABUS: "syllabus",
|
|
71
|
+
CANVAS: "canvas",
|
|
72
|
+
GOOGLE_SLIDES: "google-slides",
|
|
73
|
+
GOOGLE_DOCUMENT: "google-docs",
|
|
74
|
+
};
|
|
75
|
+
// Maps WebSocket tool_call type names to human-readable UI labels
|
|
76
|
+
const TOOL_NAME_MAP = {
|
|
77
|
+
web_search_call: "Searching the web",
|
|
78
|
+
vector_search: "Searching knowledge base",
|
|
79
|
+
calculator: "Calculating",
|
|
80
|
+
file_reader: "Reading file",
|
|
81
|
+
code_executor: "Running code",
|
|
82
|
+
wikipedia: "Searching Wikipedia",
|
|
83
|
+
};
|
|
84
|
+
const REQUIRED_ACTIONS_FOR_GROUPS = {
|
|
85
|
+
NOTIFICATIONS: "Ibl.Notifications/Notification/action",
|
|
86
|
+
};
|
|
87
|
+
const MENTOR_VISIBILITY_VALUES = {
|
|
88
|
+
ADMINISTRATORS: "viewable_by_tenant_admins",
|
|
89
|
+
STUDENTS: "viewable_by_tenant_students",
|
|
90
|
+
ANYONE: "viewable_by_anyone",
|
|
91
|
+
};
|
|
92
|
+
const MENTOR_VISIBILITY = [
|
|
93
|
+
{
|
|
94
|
+
label: "Administrators",
|
|
95
|
+
value: MENTOR_VISIBILITY_VALUES.ADMINISTRATORS,
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
label: "Users",
|
|
99
|
+
value: MENTOR_VISIBILITY_VALUES.STUDENTS,
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
label: "Anyone",
|
|
103
|
+
value: MENTOR_VISIBILITY_VALUES.ANYONE,
|
|
104
|
+
},
|
|
105
|
+
];
|
|
106
|
+
|
|
10
107
|
/**
|
|
11
108
|
* Authentication and Authorization Utilities
|
|
12
109
|
*
|
|
@@ -43,6 +140,61 @@ function deleteCookie(name, path, domain) {
|
|
|
43
140
|
const domainValue = domain ? `domain=${domain};` : "";
|
|
44
141
|
document.cookie = cookieValue + expires + pathValue + domainValue;
|
|
45
142
|
}
|
|
143
|
+
/* Reads a JWT's `exp` claim and reports whether it is in the past. A token that
|
|
144
|
+
* cannot be decoded (or is malformed) is treated as expired; a token with no
|
|
145
|
+
* `exp` claim is treated as non-expiring (mirrors the axd "no expiry" case).
|
|
146
|
+
*/
|
|
147
|
+
function isJwtExpired(token) {
|
|
148
|
+
try {
|
|
149
|
+
const payload = token.split(".")[1];
|
|
150
|
+
if (!payload)
|
|
151
|
+
return true;
|
|
152
|
+
const normalized = payload.replace(/-/g, "+").replace(/_/g, "/");
|
|
153
|
+
const padded = normalized.padEnd(normalized.length + ((4 - (normalized.length % 4)) % 4), "=");
|
|
154
|
+
const claims = JSON.parse(atob(padded));
|
|
155
|
+
if (typeof claims.exp !== "number")
|
|
156
|
+
return false;
|
|
157
|
+
return claims.exp * 1000 <= Date.now();
|
|
158
|
+
}
|
|
159
|
+
catch (_a) {
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
function hasNonExpiredAuthToken() {
|
|
164
|
+
// The edx JWT is stored alongside the axd token at SSO login; a valid session
|
|
165
|
+
// requires it to be present and unexpired too, so re-auth is triggered when
|
|
166
|
+
// it is missing or its `exp` has passed.
|
|
167
|
+
const edxToken = window.localStorage.getItem(LOCAL_STORAGE_KEYS.EDX_TOKEN_KEY);
|
|
168
|
+
if (!edxToken) {
|
|
169
|
+
console.log("################### [hasNonExpiredAuthToken] edx_jwt_token is not defined", edxToken);
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
if (isJwtExpired(edxToken)) {
|
|
173
|
+
console.log("################### [hasNonExpiredAuthToken] edx_jwt_token is expired");
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
const token = window.localStorage.getItem(LOCAL_STORAGE_KEYS.AUTH_TOKEN);
|
|
177
|
+
if (!token) {
|
|
178
|
+
console.log("################### [hasNonExpiredAuthToken] axd token is not defined", token);
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
const tokenExpiry = window.localStorage.getItem(LOCAL_STORAGE_KEYS.TOKEN_EXPIRY);
|
|
182
|
+
if (!tokenExpiry) {
|
|
183
|
+
console.log("################### [hasNonExpiredAuthToken] axd token expiry is not defined", tokenExpiry);
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
const expiryDate = new Date(tokenExpiry);
|
|
187
|
+
if (isNaN(expiryDate.getTime())) {
|
|
188
|
+
console.log("################### [hasNonExpiredAuthToken] axd token expiry date", expiryDate);
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
const currentDate = new Date();
|
|
192
|
+
if (expiryDate <= currentDate) {
|
|
193
|
+
console.log("################### [hasNonExpiredAuthToken] axd token expiry date is less than current date ", expiryDate, currentDate);
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
46
198
|
/**
|
|
47
199
|
* Get all possible domain parts for cookie deletion
|
|
48
200
|
* @param domain - The domain to split
|
|
@@ -190,7 +342,7 @@ async function redirectToAuthSpa(options) {
|
|
|
190
342
|
logoutTimestamp: "ibl_logout_timestamp",
|
|
191
343
|
loginTimestamp: "ibl_login_timestamp",
|
|
192
344
|
tenantSwitching: "ibl_tenant_switching",
|
|
193
|
-
},
|
|
345
|
+
}, isOffline, preserveTokenKey, authRedirectProxy, isNativeApp, scheme = "iblai-mentor", forceRedirect = false, } = options;
|
|
194
346
|
console.log("[redirectToAuthSpa] starting redirect to auth spa", redirectTo, platformKey, logout, saveRedirect, forceRedirect);
|
|
195
347
|
// Skip if a tenant switch is already in progress
|
|
196
348
|
if (!forceRedirect &&
|
|
@@ -1265,103 +1417,6 @@ const advancedTabs = Object.keys(advancedTabsProperties).map((tab) => {
|
|
|
1265
1417
|
});
|
|
1266
1418
|
const translatePrompt = (language) => `Please translate the summarized content into ${language}`;
|
|
1267
1419
|
|
|
1268
|
-
const MENTOR_CHAT_DOCUMENTS_EXTENSIONS = [
|
|
1269
|
-
// Media types
|
|
1270
|
-
"video/*",
|
|
1271
|
-
"audio/*",
|
|
1272
|
-
"image/*",
|
|
1273
|
-
// Document types
|
|
1274
|
-
".docx",
|
|
1275
|
-
".xlsx",
|
|
1276
|
-
".pptx",
|
|
1277
|
-
".csv",
|
|
1278
|
-
".md",
|
|
1279
|
-
".txt",
|
|
1280
|
-
".pdf",
|
|
1281
|
-
];
|
|
1282
|
-
const ANONYMOUS_USERNAME = "anonymous";
|
|
1283
|
-
const DEFAULT_DISCLAIMER_CONTENT = `By accessing and using the [ibl.ai](http://ibl.ai/) MentorAI platform (“Platform”), you agree to the following terms. The Platform provides AI-powered mentorship and educational support. You understand that AI responses may contain inaccuracies, and you are responsible for independently verifying any information before relying on it for academic, professional, or personal decisions. Do not input confidential, sensitive, or personally identifiable information of yourself or others.
|
|
1284
|
-
All content, code, and data processed through the Platform remain the property of their respective owners. [ibl.ai](http://ibl.ai/) retains all rights to the Platform’s underlying technology and intellectual property. You are granted a limited, non-exclusive, revocable license to use the Platform for personal or institutional learning purposes only.
|
|
1285
|
-
Your use must comply with applicable laws and institutional policies. Misuse—including attempting to bypass security, copy source code, or use the service for unlawful activity—may result in suspension or termination of access. Continued use constitutes acceptance of these terms.`;
|
|
1286
|
-
const MAX_INITIAL_WEBSOCKET_CONNECTION_ATTEMPTS = 3;
|
|
1287
|
-
const LOCAL_STORAGE_KEYS = {
|
|
1288
|
-
CURRENT_TENANT: "current_tenant",
|
|
1289
|
-
TENANTS: "tenants",
|
|
1290
|
-
REDIRECT_TO: "redirect-to",
|
|
1291
|
-
AUTH_TOKEN: "axd_token",
|
|
1292
|
-
TOKEN_EXPIRY: "axd_token_expires",
|
|
1293
|
-
USER_DATA: "userData",
|
|
1294
|
-
USER_TENANTS: "tenants",
|
|
1295
|
-
VISITING_TENANT: "visiting_tenant",
|
|
1296
|
-
SESSION_ID: "session_id",
|
|
1297
|
-
EDX_TOKEN_KEY: "edx_jwt_token",
|
|
1298
|
-
DM_TOKEN_KEY: "dm_token",
|
|
1299
|
-
DM_TOKEN_EXPIRES: "dm_token_expires",
|
|
1300
|
-
DM_TOKEN_EXPIRY: "dm_token_expires",
|
|
1301
|
-
AXD_TOKEN_KEY: "axd_token",
|
|
1302
|
-
DEFAULT_TENANT: "tenant",
|
|
1303
|
-
MODEL_DOWNLOAD_STATE: "model_download_state",
|
|
1304
|
-
MODEL_DOWNLOAD_PROMPT_DISMISSED: "model_download_prompt_dismissed",
|
|
1305
|
-
};
|
|
1306
|
-
const TOOLS = {
|
|
1307
|
-
WEB_SEARCH: "web-search",
|
|
1308
|
-
WIKIPEDIA_SEARCH: "wikipedia-search",
|
|
1309
|
-
COURSE_CREATION: "course-creation",
|
|
1310
|
-
MCP: "mcp",
|
|
1311
|
-
IMAGE_GENERATION: "image-generation",
|
|
1312
|
-
IBL_PATHWAY_DOCUMENTS_RETRIEVER: "ibl-pathway-documents-retriever",
|
|
1313
|
-
TRAINED_DOCUMENTS: "trained-documents",
|
|
1314
|
-
IBL_SESSION_DOCUMENTS_RETRIEVER: "ibl-session-documents-retriever",
|
|
1315
|
-
PLAYWRIGHT_BROWSER: "playwright-browser",
|
|
1316
|
-
HUMAN_SUPPORT: "human-support",
|
|
1317
|
-
CODE_INTERPRETER: "code-interpreter",
|
|
1318
|
-
DEEP_RESEARCH: "deep-research",
|
|
1319
|
-
STUDY_MODE: "study-mode",
|
|
1320
|
-
MEMORY: "memory",
|
|
1321
|
-
SCREEN_SHARE: "screen-share",
|
|
1322
|
-
POWERPOINT: "powerpoint",
|
|
1323
|
-
PROMPT: "prompt",
|
|
1324
|
-
QUIZ: "quiz",
|
|
1325
|
-
RUBRIC: "rubric",
|
|
1326
|
-
RESOURCE: "resource",
|
|
1327
|
-
LESSON_PLAN: "lesson-plan",
|
|
1328
|
-
SYLLABUS: "syllabus",
|
|
1329
|
-
CANVAS: "canvas",
|
|
1330
|
-
GOOGLE_SLIDES: "google-slides",
|
|
1331
|
-
GOOGLE_DOCUMENT: "google-docs",
|
|
1332
|
-
};
|
|
1333
|
-
// Maps WebSocket tool_call type names to human-readable UI labels
|
|
1334
|
-
const TOOL_NAME_MAP = {
|
|
1335
|
-
web_search_call: "Searching the web",
|
|
1336
|
-
vector_search: "Searching knowledge base",
|
|
1337
|
-
calculator: "Calculating",
|
|
1338
|
-
file_reader: "Reading file",
|
|
1339
|
-
code_executor: "Running code",
|
|
1340
|
-
wikipedia: "Searching Wikipedia",
|
|
1341
|
-
};
|
|
1342
|
-
const REQUIRED_ACTIONS_FOR_GROUPS = {
|
|
1343
|
-
NOTIFICATIONS: "Ibl.Notifications/Notification/action",
|
|
1344
|
-
};
|
|
1345
|
-
const MENTOR_VISIBILITY_VALUES = {
|
|
1346
|
-
ADMINISTRATORS: "viewable_by_tenant_admins",
|
|
1347
|
-
STUDENTS: "viewable_by_tenant_students",
|
|
1348
|
-
ANYONE: "viewable_by_anyone",
|
|
1349
|
-
};
|
|
1350
|
-
const MENTOR_VISIBILITY = [
|
|
1351
|
-
{
|
|
1352
|
-
label: "Administrators",
|
|
1353
|
-
value: MENTOR_VISIBILITY_VALUES.ADMINISTRATORS,
|
|
1354
|
-
},
|
|
1355
|
-
{
|
|
1356
|
-
label: "Users",
|
|
1357
|
-
value: MENTOR_VISIBILITY_VALUES.STUDENTS,
|
|
1358
|
-
},
|
|
1359
|
-
{
|
|
1360
|
-
label: "Anyone",
|
|
1361
|
-
value: MENTOR_VISIBILITY_VALUES.ANYONE,
|
|
1362
|
-
},
|
|
1363
|
-
];
|
|
1364
|
-
|
|
1365
1420
|
/**
|
|
1366
1421
|
* Reads the cached user_nicename from the LOCAL_STORAGE_KEYS.USER_DATA blob.
|
|
1367
1422
|
*/
|
|
@@ -9177,29 +9232,6 @@ async function syncAuthToCookies(storageService) {
|
|
|
9177
9232
|
console.error("[syncAuthToCookies] Error syncing to cookies:", error);
|
|
9178
9233
|
}
|
|
9179
9234
|
}
|
|
9180
|
-
function hasNonExpiredAuthToken() {
|
|
9181
|
-
const token = window.localStorage.getItem(LOCAL_STORAGE_KEYS.AUTH_TOKEN);
|
|
9182
|
-
if (!token) {
|
|
9183
|
-
console.log("################### [hasNonExpiredAuthToken] axd token is not defined", token);
|
|
9184
|
-
return false;
|
|
9185
|
-
}
|
|
9186
|
-
const tokenExpiry = window.localStorage.getItem(LOCAL_STORAGE_KEYS.TOKEN_EXPIRY);
|
|
9187
|
-
if (!tokenExpiry) {
|
|
9188
|
-
console.log("################### [hasNonExpiredAuthToken] axd token expiry is not defined", tokenExpiry);
|
|
9189
|
-
return true;
|
|
9190
|
-
}
|
|
9191
|
-
const expiryDate = new Date(tokenExpiry);
|
|
9192
|
-
if (isNaN(expiryDate.getTime())) {
|
|
9193
|
-
console.log("################### [hasNonExpiredAuthToken] axd token expiry date", expiryDate);
|
|
9194
|
-
return false;
|
|
9195
|
-
}
|
|
9196
|
-
const currentDate = new Date();
|
|
9197
|
-
if (expiryDate <= currentDate) {
|
|
9198
|
-
console.log("################### [hasNonExpiredAuthToken] axd token expiry date is less than current date ", expiryDate, currentDate);
|
|
9199
|
-
return false;
|
|
9200
|
-
}
|
|
9201
|
-
return true;
|
|
9202
|
-
}
|
|
9203
9235
|
/**
|
|
9204
9236
|
* Clear current tenant cookie only (web only)
|
|
9205
9237
|
* Should be called before tenant switching
|
|
@@ -11894,46 +11926,117 @@ const selectIsReasoning = (state) => state.chatSliceShared.currentStreamingMessa
|
|
|
11894
11926
|
// NEW: Get streaming tool calls
|
|
11895
11927
|
const selectStreamingToolCalls = (state) => state.chatSliceShared.currentStreamingMessage.toolCalls;
|
|
11896
11928
|
|
|
11929
|
+
const DEFAULT_IDLE_TIMEOUT_SECONDS = 120;
|
|
11930
|
+
// Minimum gap between idle-timer resets. Interaction events like mousemove fire
|
|
11931
|
+
// rapidly; there's no need to restart the (minutes-long) idle countdown more
|
|
11932
|
+
// than once per second.
|
|
11933
|
+
const ACTIVITY_THROTTLE_MS = 1000;
|
|
11934
|
+
// User interactions that count as activity and keep the user "present".
|
|
11935
|
+
const ACTIVITY_EVENTS = [
|
|
11936
|
+
"mousemove",
|
|
11937
|
+
"mousedown",
|
|
11938
|
+
"keydown",
|
|
11939
|
+
"wheel",
|
|
11940
|
+
"scroll",
|
|
11941
|
+
"touchstart",
|
|
11942
|
+
"pointerdown",
|
|
11943
|
+
];
|
|
11897
11944
|
class TimeTracker {
|
|
11898
11945
|
constructor(config) {
|
|
11946
|
+
var _a, _b, _c;
|
|
11899
11947
|
this.state = {
|
|
11900
11948
|
currentUrl: "",
|
|
11901
|
-
startTime: 0,
|
|
11902
11949
|
intervalId: null,
|
|
11903
11950
|
routeUnsubscribe: null,
|
|
11951
|
+
accumulatedMs: 0,
|
|
11952
|
+
activeSince: null,
|
|
11953
|
+
isVisible: true,
|
|
11954
|
+
isFocused: true,
|
|
11955
|
+
isIdle: false,
|
|
11956
|
+
idleTimerId: null,
|
|
11904
11957
|
};
|
|
11958
|
+
// Timestamp of the last activity that reset the idle timer (for throttling).
|
|
11959
|
+
this.lastActivityAt = 0;
|
|
11960
|
+
// Bound listeners kept so they can be removed on destroy.
|
|
11961
|
+
this.handleActivity = () => this.onActivity();
|
|
11962
|
+
this.handleVisibilityChange = () => this.onVisibilityChange();
|
|
11963
|
+
this.handleWindowFocus = () => this.onWindowFocus();
|
|
11964
|
+
this.handleWindowBlur = () => this.onWindowBlur();
|
|
11905
11965
|
this.config = config;
|
|
11966
|
+
this.idleTimeoutMs =
|
|
11967
|
+
((_a = config.idleTimeoutSeconds) !== null && _a !== void 0 ? _a : DEFAULT_IDLE_TIMEOUT_SECONDS) * 1000;
|
|
11968
|
+
this.pauseOnHidden = (_b = config.pauseOnHidden) !== null && _b !== void 0 ? _b : true;
|
|
11969
|
+
this.pauseOnBlur = (_c = config.pauseOnBlur) !== null && _c !== void 0 ? _c : true;
|
|
11970
|
+
this.idleDetectionEnabled =
|
|
11971
|
+
this.idleTimeoutMs > 0 &&
|
|
11972
|
+
typeof window !== "undefined" &&
|
|
11973
|
+
typeof document !== "undefined";
|
|
11906
11974
|
this.initialize();
|
|
11907
11975
|
}
|
|
11908
11976
|
initialize() {
|
|
11909
11977
|
this.state.currentUrl = this.config.getCurrentUrl();
|
|
11978
|
+
// Seed activity signals from the current environment.
|
|
11979
|
+
if (this.pauseOnHidden && typeof document !== "undefined") {
|
|
11980
|
+
this.state.isVisible = !document.hidden;
|
|
11981
|
+
}
|
|
11982
|
+
this.state.isFocused = true;
|
|
11983
|
+
this.state.isIdle = false;
|
|
11984
|
+
this.attachActivityListeners();
|
|
11910
11985
|
this.startTracking();
|
|
11986
|
+
this.startIdleTimer();
|
|
11911
11987
|
if (this.config.onRouteChange) {
|
|
11912
11988
|
this.state.routeUnsubscribe = this.config.onRouteChange(() => {
|
|
11913
11989
|
this.handleRouteChange();
|
|
11914
11990
|
});
|
|
11915
11991
|
}
|
|
11916
11992
|
}
|
|
11993
|
+
// --- Active time accounting -------------------------------------------------
|
|
11994
|
+
/** Whether time should currently be counted. */
|
|
11995
|
+
isActive() {
|
|
11996
|
+
return this.state.isVisible && this.state.isFocused && !this.state.isIdle;
|
|
11997
|
+
}
|
|
11998
|
+
/**
|
|
11999
|
+
* Reconcile the active window with the current activity signals: open a new
|
|
12000
|
+
* window when the user becomes active, or bank the elapsed time when they
|
|
12001
|
+
* become inactive.
|
|
12002
|
+
*/
|
|
12003
|
+
syncActiveWindow() {
|
|
12004
|
+
const active = this.isActive();
|
|
12005
|
+
if (active && this.state.activeSince === null) {
|
|
12006
|
+
this.state.activeSince = Date.now();
|
|
12007
|
+
}
|
|
12008
|
+
else if (!active && this.state.activeSince !== null) {
|
|
12009
|
+
this.state.accumulatedMs += Date.now() - this.state.activeSince;
|
|
12010
|
+
this.state.activeSince = null;
|
|
12011
|
+
}
|
|
12012
|
+
}
|
|
12013
|
+
getTimeSpent() {
|
|
12014
|
+
let total = this.state.accumulatedMs;
|
|
12015
|
+
if (this.state.activeSince !== null) {
|
|
12016
|
+
total += Date.now() - this.state.activeSince;
|
|
12017
|
+
}
|
|
12018
|
+
return total;
|
|
12019
|
+
}
|
|
12020
|
+
resetTimer() {
|
|
12021
|
+
this.state.accumulatedMs = 0;
|
|
12022
|
+
this.state.activeSince = this.isActive() ? Date.now() : null;
|
|
12023
|
+
}
|
|
11917
12024
|
startTracking() {
|
|
11918
|
-
this.
|
|
11919
|
-
this.
|
|
12025
|
+
this.clearTrackingInterval();
|
|
12026
|
+
this.resetTimer();
|
|
12027
|
+
if (typeof window === "undefined")
|
|
12028
|
+
return;
|
|
11920
12029
|
this.state.intervalId = window.setInterval(() => {
|
|
11921
12030
|
this.sendTimeUpdate();
|
|
11922
12031
|
this.resetTimer();
|
|
11923
12032
|
}, this.config.intervalSeconds * 1000);
|
|
11924
12033
|
}
|
|
11925
|
-
|
|
12034
|
+
clearTrackingInterval() {
|
|
11926
12035
|
if (this.state.intervalId !== null) {
|
|
11927
12036
|
clearInterval(this.state.intervalId);
|
|
11928
12037
|
this.state.intervalId = null;
|
|
11929
12038
|
}
|
|
11930
12039
|
}
|
|
11931
|
-
resetTimer() {
|
|
11932
|
-
this.state.startTime = Date.now();
|
|
11933
|
-
}
|
|
11934
|
-
getTimeSpent() {
|
|
11935
|
-
return Date.now() - this.state.startTime;
|
|
11936
|
-
}
|
|
11937
12040
|
sendTimeUpdate() {
|
|
11938
12041
|
const timeSpent = this.getTimeSpent();
|
|
11939
12042
|
if (timeSpent > 0) {
|
|
@@ -11948,16 +12051,116 @@ class TimeTracker {
|
|
|
11948
12051
|
this.resetTimer();
|
|
11949
12052
|
}
|
|
11950
12053
|
}
|
|
12054
|
+
// --- Activity / inactivity detection ---------------------------------------
|
|
12055
|
+
attachActivityListeners() {
|
|
12056
|
+
if (typeof window !== "undefined" && window.addEventListener) {
|
|
12057
|
+
if (this.idleDetectionEnabled) {
|
|
12058
|
+
for (const event of ACTIVITY_EVENTS) {
|
|
12059
|
+
window.addEventListener(event, this.handleActivity, {
|
|
12060
|
+
passive: true,
|
|
12061
|
+
});
|
|
12062
|
+
}
|
|
12063
|
+
}
|
|
12064
|
+
if (this.pauseOnBlur) {
|
|
12065
|
+
window.addEventListener("focus", this.handleWindowFocus);
|
|
12066
|
+
window.addEventListener("blur", this.handleWindowBlur);
|
|
12067
|
+
}
|
|
12068
|
+
}
|
|
12069
|
+
if (this.pauseOnHidden &&
|
|
12070
|
+
typeof document !== "undefined" &&
|
|
12071
|
+
document.addEventListener) {
|
|
12072
|
+
document.addEventListener("visibilitychange", this.handleVisibilityChange);
|
|
12073
|
+
}
|
|
12074
|
+
}
|
|
12075
|
+
detachActivityListeners() {
|
|
12076
|
+
if (typeof window !== "undefined" && window.removeEventListener) {
|
|
12077
|
+
for (const event of ACTIVITY_EVENTS) {
|
|
12078
|
+
window.removeEventListener(event, this.handleActivity);
|
|
12079
|
+
}
|
|
12080
|
+
window.removeEventListener("focus", this.handleWindowFocus);
|
|
12081
|
+
window.removeEventListener("blur", this.handleWindowBlur);
|
|
12082
|
+
}
|
|
12083
|
+
if (typeof document !== "undefined" && document.removeEventListener) {
|
|
12084
|
+
document.removeEventListener("visibilitychange", this.handleVisibilityChange);
|
|
12085
|
+
}
|
|
12086
|
+
}
|
|
12087
|
+
startIdleTimer() {
|
|
12088
|
+
if (!this.idleDetectionEnabled)
|
|
12089
|
+
return;
|
|
12090
|
+
this.clearIdleTimer();
|
|
12091
|
+
this.lastActivityAt = Date.now();
|
|
12092
|
+
this.state.idleTimerId = window.setTimeout(() => {
|
|
12093
|
+
this.markIdle();
|
|
12094
|
+
}, this.idleTimeoutMs);
|
|
12095
|
+
}
|
|
12096
|
+
clearIdleTimer() {
|
|
12097
|
+
if (this.state.idleTimerId !== null) {
|
|
12098
|
+
clearTimeout(this.state.idleTimerId);
|
|
12099
|
+
this.state.idleTimerId = null;
|
|
12100
|
+
}
|
|
12101
|
+
}
|
|
12102
|
+
markIdle() {
|
|
12103
|
+
if (this.state.isIdle)
|
|
12104
|
+
return;
|
|
12105
|
+
this.state.isIdle = true;
|
|
12106
|
+
this.syncActiveWindow();
|
|
12107
|
+
}
|
|
12108
|
+
onActivity() {
|
|
12109
|
+
// Returning from idle must always restart the countdown immediately.
|
|
12110
|
+
if (this.state.isIdle) {
|
|
12111
|
+
this.state.isIdle = false;
|
|
12112
|
+
this.syncActiveWindow();
|
|
12113
|
+
this.startIdleTimer();
|
|
12114
|
+
return;
|
|
12115
|
+
}
|
|
12116
|
+
// Otherwise throttle: no need to reset a minutes-long timer on every
|
|
12117
|
+
// mousemove.
|
|
12118
|
+
if (Date.now() - this.lastActivityAt < ACTIVITY_THROTTLE_MS)
|
|
12119
|
+
return;
|
|
12120
|
+
this.startIdleTimer();
|
|
12121
|
+
}
|
|
12122
|
+
onVisibilityChange() {
|
|
12123
|
+
if (typeof document === "undefined")
|
|
12124
|
+
return;
|
|
12125
|
+
this.state.isVisible = !document.hidden;
|
|
12126
|
+
if (this.state.isVisible) {
|
|
12127
|
+
// Returning to the tab counts as being present again.
|
|
12128
|
+
this.state.isIdle = false;
|
|
12129
|
+
this.startIdleTimer();
|
|
12130
|
+
}
|
|
12131
|
+
this.syncActiveWindow();
|
|
12132
|
+
}
|
|
12133
|
+
onWindowFocus() {
|
|
12134
|
+
this.state.isFocused = true;
|
|
12135
|
+
this.state.isIdle = false;
|
|
12136
|
+
this.startIdleTimer();
|
|
12137
|
+
this.syncActiveWindow();
|
|
12138
|
+
}
|
|
12139
|
+
onWindowBlur() {
|
|
12140
|
+
this.state.isFocused = false;
|
|
12141
|
+
this.syncActiveWindow();
|
|
12142
|
+
}
|
|
12143
|
+
// --- Public API -------------------------------------------------------------
|
|
11951
12144
|
pause() {
|
|
11952
12145
|
this.sendTimeUpdate();
|
|
11953
|
-
this.
|
|
12146
|
+
this.clearTrackingInterval();
|
|
12147
|
+
this.clearIdleTimer();
|
|
12148
|
+
// Stop accounting until resumed.
|
|
12149
|
+
this.state.accumulatedMs = 0;
|
|
12150
|
+
this.state.activeSince = null;
|
|
11954
12151
|
}
|
|
11955
12152
|
resume() {
|
|
12153
|
+
// Treat resume as a fresh, present start so a stale idle flag can't keep
|
|
12154
|
+
// the tracker from counting.
|
|
12155
|
+
this.state.isIdle = false;
|
|
11956
12156
|
this.startTracking();
|
|
12157
|
+
this.startIdleTimer();
|
|
11957
12158
|
}
|
|
11958
12159
|
destroy() {
|
|
11959
12160
|
this.sendTimeUpdate();
|
|
11960
|
-
this.
|
|
12161
|
+
this.clearTrackingInterval();
|
|
12162
|
+
this.clearIdleTimer();
|
|
12163
|
+
this.detachActivityListeners();
|
|
11961
12164
|
if (this.state.routeUnsubscribe) {
|
|
11962
12165
|
this.state.routeUnsubscribe();
|
|
11963
12166
|
this.state.routeUnsubscribe = null;
|
|
@@ -11969,6 +12172,10 @@ class TimeTracker {
|
|
|
11969
12172
|
getTimeSpentSinceLastReset() {
|
|
11970
12173
|
return this.getTimeSpent();
|
|
11971
12174
|
}
|
|
12175
|
+
/** Whether the user is currently considered active (present & interacting). */
|
|
12176
|
+
getIsActive() {
|
|
12177
|
+
return this.isActive();
|
|
12178
|
+
}
|
|
11972
12179
|
}
|
|
11973
12180
|
|
|
11974
12181
|
function useTimeTracker(config) {
|
|
@@ -18953,5 +19160,5 @@ const checkRbacPermission = (rbacPermissions, rbacResource, enableRBAC = true) =
|
|
|
18953
19160
|
return checkRbacPermissionInternal(rbacPermissions, rbacResource);
|
|
18954
19161
|
};
|
|
18955
19162
|
|
|
18956
|
-
export { ALPHANUMERIC_32_REGEX, ANONYMOUS_USERNAME, AuthContext, AuthContextProvider, AuthProvider, CHAT_AREA_SIZE, CacheKeys, DEFAULT_DISCLAIMER_CONTENT, DEFAULT_TENANT_SWITCH_LOCK_TTL_MS, LOCAL_STORAGE_KEYS, MAX_INITIAL_WEBSOCKET_CONNECTION_ATTEMPTS, MENTOR_CHAT_DOCUMENTS_EXTENSIONS, MENTOR_VISIBILITY, MENTOR_VISIBILITY_VALUES, METADATAS, MentorProvider, REQUIRED_ACTIONS_FOR_GROUPS, RemoteEvents, STREAMING_CONTENT_BUFFER_THRESHOLD, STREAMING_CONTENT_FLUSH_INTERVAL, SUBSCRIPTION_MESSAGES, SUBSCRIPTION_PACKAGES, SUBSCRIPTION_PACKAGES_V2, SUBSCRIPTION_TRIGGERS, SUBSCRIPTION_V2_TRIGGERS, ServiceWorkerProvider, SubscriptionFlow, SubscriptionFlowV2, TENANT_SWITCH_CHANNEL, TENANT_SWITCH_LOCK_KEY, TOOLS, TOOL_NAME_MAP, TenantContext, TenantContextProvider, TenantProvider, TimeTracker, WithFormPermissions, WithPermissions, addFiles, addMessage, addProtocolToUrl, advancedTabs, advancedTabsProperties, appleRestrictionReducer, appleRestrictionSlice, chatActions, chatInputSlice, chatInputSliceActions, chatInputSliceReducer, chatInputSliceSelectors, chatSliceReducerShared, checkModelAvailable, checkOllamaHealth, checkRbacPermission, clearAllCaches, clearApiCache, clearAuthCookies, clearCookies, clearCurrentTenantCookie, clearFiles, clearMessages, clearTenantSwitchLock, combineCSVData, convertToOllamaMessages, createFileReference, createMultipleFileReferences, csvDataToText, defaultSessionIds, deleteCookie, deleteCookieOnAllDomains, enableChatActionsPopup, eventBus, fetchWithCache, filesReducer, filesSlice, formatRelativeTime, getAuthSpaJoinUrl, getCacheStatus, getCachedApiResponse, getCookieValue, getDomainParts, getFileInfo, getInitials, getLocalLLMSystemPrompt, getNextNavigation, getParentDomain, getPlatform, getPlatformKey, getServiceWorkerStatus, getStoredUserName, getTabId, getTimeAgo, getUserEmail, getUserName, handleLogout, handleTenantSwitch, hasNonExpiredAuthToken, hostChatReducer, hostChatSlice, initServiceWorker, isAlphaNumeric32, isExpo, isFileAccepted, isInIframe, isJSON, isLoggedIn, isNode, isReactNative, isSafariBrowser, isServiceWorkerSupported, isStripeActivated, isTauri, isTauriOfflineMode, isTenantSwitchInProgress, isWeb$2 as isWeb, loadMetadataConfig, markdownToPlainText, monetizationSlice, onStatusChange, onUpdate, openExternalUrl, parseCSV, preCacheMentorData, rbacReducer, readTenantSwitchLock, redirectToAuthSpa, redirectToAuthSpaJoinTenant, refreshTenantSwitchLock, registerServiceWorker, removeFile, requestPresignedUrl, safeRequire, selectActiveChatMessages, selectActiveTab, selectArtifactsEnabled, selectAttachedFiles, selectChats, selectCurrentStreamingArtifact, selectCurrentStreamingMessage, selectDocumentFilter, selectEnableChatActionsPopup, selectIframeContext, selectIsError, selectIsPending, selectIsReasoning, selectIsStopped, selectIsTyping, selectLastArtifactContentFlushTime, selectMetadata, selectNumberOfActiveChatMessages, selectRbacPermissions, selectSessionId, selectSessionIds, selectShouldStartNewChat, selectShowingSharedChat, selectStatus, selectStreaming, selectStreamingArtifactContentBuffer, selectStreamingArtifactFullContent, selectStreamingReasoningContent, selectStreamingToolCalls, selectToken, selectTokenEnabled, selectTools, sendMessageToParentWebsite, setAccessCheckResponse, setAdvancedDisplayMonetizationCheckoutModal, setCachedApiResponse, setCookieForAuth, setDisplayMonetizationCheckoutModal, setError402Detected, setFreeTrialUsageOptions, setOfflineStatus, setOpenAppleRestrictionModal, setOpenPricingModal, setPricingModalData, setSubscriptionStatus, setTauriMode, setTopBannerOptions, setupNetworkListeners, showMonetizationCheckoutModal, skipWaiting, streamOllamaChat, subscriptionReducer, subscriptionSlice, syncAuthToCookies, tenantKeySchema, tenantSchema, topBannerReducer, topBannerSlice, translatePrompt, unregisterServiceWorker, updateFileMetadata, updateFileProgress, updateFileRetryCount, updateFileStatus, updateFileUrl, updateFileUrlFromWebSocket, updateRbacPermissions, uploadToS3, use402ErrorCheck, useAccessingPublicRoute, useAdvancedChat, useAuthContext, useAuthProvider, useAxdToken, useCachedSessionId, useChat, useChatFileUpload, useCurrentTenant, useDayJs, useDmToken, useEmbedMode, useEventCallback, useEventListener, useExternalPricingPlan, useFileDragDrop, useIsAdmin, useIsomorphicLayoutEffect, useLocalStorage, useMentorSettings, useMentorTools, useModelFileUploadCapabilities, useOS, useProfileImageUpload, useResponsive, useServiceWorker, useShowAttachment, useShowFreeTrialDialog, useShowVoiceCall, useShowVoiceRecorder, useStripeUpgrade, useSubscriptionHandler, useSubscriptionHandlerV2, useTenantContext, useTenantMetadata, useTenantSwitchSync, useTimeTracker, useTimeTrackerNative, useTimer, useUserAgreement, useUserData, useUserProfileUpdate, useUserTenants, useUsername, useVisitingTenant, useVoiceChat, useWelcome as useWelcomeMessage, userDataSchema, validateFile, writeTenantSwitchLock };
|
|
19163
|
+
export { ALPHANUMERIC_32_REGEX, ANONYMOUS_USERNAME, AuthContext, AuthContextProvider, AuthProvider, CHAT_AREA_SIZE, CacheKeys, DEFAULT_DISCLAIMER_CONTENT, DEFAULT_TENANT_SWITCH_LOCK_TTL_MS, LOCAL_STORAGE_KEYS, MAX_INITIAL_WEBSOCKET_CONNECTION_ATTEMPTS, MENTOR_CHAT_DOCUMENTS_EXTENSIONS, MENTOR_VISIBILITY, MENTOR_VISIBILITY_VALUES, METADATAS, MentorProvider, REQUIRED_ACTIONS_FOR_GROUPS, RemoteEvents, STREAMING_CONTENT_BUFFER_THRESHOLD, STREAMING_CONTENT_FLUSH_INTERVAL, SUBSCRIPTION_MESSAGES, SUBSCRIPTION_PACKAGES, SUBSCRIPTION_PACKAGES_V2, SUBSCRIPTION_TRIGGERS, SUBSCRIPTION_V2_TRIGGERS, ServiceWorkerProvider, SubscriptionFlow, SubscriptionFlowV2, TENANT_SWITCH_CHANNEL, TENANT_SWITCH_LOCK_KEY, TOOLS, TOOL_NAME_MAP, TenantContext, TenantContextProvider, TenantProvider, TimeTracker, WithFormPermissions, WithPermissions, addFiles, addMessage, addProtocolToUrl, advancedTabs, advancedTabsProperties, appleRestrictionReducer, appleRestrictionSlice, chatActions, chatInputSlice, chatInputSliceActions, chatInputSliceReducer, chatInputSliceSelectors, chatSliceReducerShared, checkModelAvailable, checkOllamaHealth, checkRbacPermission, clearAllCaches, clearApiCache, clearAuthCookies, clearCookies, clearCurrentTenantCookie, clearFiles, clearMessages, clearTenantSwitchLock, combineCSVData, convertToOllamaMessages, createFileReference, createMultipleFileReferences, csvDataToText, defaultSessionIds, deleteCookie, deleteCookieOnAllDomains, enableChatActionsPopup, eventBus, fetchWithCache, filesReducer, filesSlice, formatRelativeTime, getAuthSpaJoinUrl, getCacheStatus, getCachedApiResponse, getCookieValue, getDomainParts, getFileInfo, getInitials, getLocalLLMSystemPrompt, getNextNavigation, getParentDomain, getPlatform, getPlatformKey, getServiceWorkerStatus, getStoredUserName, getTabId, getTimeAgo, getUserEmail, getUserName, handleLogout, handleTenantSwitch, hasNonExpiredAuthToken, hostChatReducer, hostChatSlice, initServiceWorker, isAlphaNumeric32, isExpo, isFileAccepted, isInIframe, isJSON, isJwtExpired, isLoggedIn, isNode, isReactNative, isSafariBrowser, isServiceWorkerSupported, isStripeActivated, isTauri, isTauriOfflineMode, isTenantSwitchInProgress, isWeb$2 as isWeb, loadMetadataConfig, markdownToPlainText, monetizationSlice, onStatusChange, onUpdate, openExternalUrl, parseCSV, preCacheMentorData, rbacReducer, readTenantSwitchLock, redirectToAuthSpa, redirectToAuthSpaJoinTenant, refreshTenantSwitchLock, registerServiceWorker, removeFile, requestPresignedUrl, safeRequire, selectActiveChatMessages, selectActiveTab, selectArtifactsEnabled, selectAttachedFiles, selectChats, selectCurrentStreamingArtifact, selectCurrentStreamingMessage, selectDocumentFilter, selectEnableChatActionsPopup, selectIframeContext, selectIsError, selectIsPending, selectIsReasoning, selectIsStopped, selectIsTyping, selectLastArtifactContentFlushTime, selectMetadata, selectNumberOfActiveChatMessages, selectRbacPermissions, selectSessionId, selectSessionIds, selectShouldStartNewChat, selectShowingSharedChat, selectStatus, selectStreaming, selectStreamingArtifactContentBuffer, selectStreamingArtifactFullContent, selectStreamingReasoningContent, selectStreamingToolCalls, selectToken, selectTokenEnabled, selectTools, sendMessageToParentWebsite, setAccessCheckResponse, setAdvancedDisplayMonetizationCheckoutModal, setCachedApiResponse, setCookieForAuth, setDisplayMonetizationCheckoutModal, setError402Detected, setFreeTrialUsageOptions, setOfflineStatus, setOpenAppleRestrictionModal, setOpenPricingModal, setPricingModalData, setSubscriptionStatus, setTauriMode, setTopBannerOptions, setupNetworkListeners, showMonetizationCheckoutModal, skipWaiting, streamOllamaChat, subscriptionReducer, subscriptionSlice, syncAuthToCookies, tenantKeySchema, tenantSchema, topBannerReducer, topBannerSlice, translatePrompt, unregisterServiceWorker, updateFileMetadata, updateFileProgress, updateFileRetryCount, updateFileStatus, updateFileUrl, updateFileUrlFromWebSocket, updateRbacPermissions, uploadToS3, use402ErrorCheck, useAccessingPublicRoute, useAdvancedChat, useAuthContext, useAuthProvider, useAxdToken, useCachedSessionId, useChat, useChatFileUpload, useCurrentTenant, useDayJs, useDmToken, useEmbedMode, useEventCallback, useEventListener, useExternalPricingPlan, useFileDragDrop, useIsAdmin, useIsomorphicLayoutEffect, useLocalStorage, useMentorSettings, useMentorTools, useModelFileUploadCapabilities, useOS, useProfileImageUpload, useResponsive, useServiceWorker, useShowAttachment, useShowFreeTrialDialog, useShowVoiceCall, useShowVoiceRecorder, useStripeUpgrade, useSubscriptionHandler, useSubscriptionHandlerV2, useTenantContext, useTenantMetadata, useTenantSwitchSync, useTimeTracker, useTimeTrackerNative, useTimer, useUserAgreement, useUserData, useUserProfileUpdate, useUserTenants, useUsername, useVisitingTenant, useVoiceChat, useWelcome as useWelcomeMessage, userDataSchema, validateFile, writeTenantSwitchLock };
|
|
18957
19164
|
//# sourceMappingURL=index.esm.js.map
|