@iblai/iblai-js 2.2.7 → 2.2.9

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.
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import React__default, { useRef, useEffect, useState, useCallback, useLayoutEffect, forwardRef, createElement as createElement$1, createContext, useContext, useMemo, useReducer, useImperativeHandle, isValidElement, Children, PureComponent, cloneElement, Component, useId as useId$2, useDebugValue, lazy, Suspense } from 'react';
3
3
  import { useDispatch, useSelector } from 'react-redux';
4
- import { selectSessionId, selectActiveChatMessages, useCachedSessionId, chatActions, LOCAL_STORAGE_KEYS, TimeTracker, getInitials, useTenantMetadata, WithPermissions, useStripeUpgrade, openExternalUrl, CHAT_AREA_SIZE, isAlphaNumeric32, checkRbacPermission, getTimeAgo, REQUIRED_ACTIONS_FOR_GROUPS, formatRelativeTime as formatRelativeTime$2, ANONYMOUS_USERNAME, combineCSVData, redirectToAuthSpaJoinTenant, redirectToAuthSpa, getAuthSpaJoinUrl, useOS, selectNumberOfActiveChatMessages, useUsername, selectStreaming, isLoggedIn, TOOLS, isSafariBrowser, useShowAttachment, useShowVoiceCall, useShowVoiceRecorder, useMentorSettings, selectShowingSharedChat, selectRbacPermissions, useShowFreeTrialDialog, useEmbedMode, chatInputSliceSelectors, useResponsive, useAccessingPublicRoute, useVisitingTenant, useModelFileUploadCapabilities, useChatFileUpload, useVoiceChat, selectAttachedFiles, MENTOR_CHAT_DOCUMENTS_EXTENSIONS, removeFile, chatInputSliceActions, WithFormPermissions, MENTOR_VISIBILITY } from '@iblai/web-utils';
4
+ import { selectSessionId, selectActiveChatMessages, useCachedSessionId, chatActions, LOCAL_STORAGE_KEYS, TimeTracker, getInitials, useTenantMetadata, WithPermissions, useStripeUpgrade, openExternalUrl, CHAT_AREA_SIZE, isAlphaNumeric32, checkRbacPermission, getTimeAgo, REQUIRED_ACTIONS_FOR_GROUPS, formatRelativeTime as formatRelativeTime$2, ANONYMOUS_USERNAME, combineCSVData, redirectToAuthSpaJoinTenant, redirectToAuthSpa, getAuthSpaJoinUrl, useOS, selectNumberOfActiveChatMessages, useUsername, selectStreaming, isLoggedIn, TOOLS, hasRemoteAiConfig, isSafariBrowser, useShowAttachment, useShowVoiceCall, useShowVoiceRecorder, useMentorSettings, selectShowingSharedChat, selectRbacPermissions, useShowFreeTrialDialog, useEmbedMode, chatInputSliceSelectors, useResponsive, useAccessingPublicRoute, useVisitingTenant, useModelFileUploadCapabilities, useChatFileUpload, useVoiceChat, selectAttachedFiles, MENTOR_CHAT_DOCUMENTS_EXTENSIONS, removeFile, chatInputSliceActions, WithFormPermissions, MENTOR_VISIBILITY } from '@iblai/web-utils';
5
5
  import * as dataLayer from '@iblai/data-layer';
6
6
  import { useCreateSessionIdMutation, useTimeTrackingMutation, useGetUserMetadataQuery, useGetUserMetadataEdxQuery, useUpdateUserMetadataMutation, useUpdateUserMetadataEdxMutation, useUploadProfileImageMutation, useResetPasswordMutation, useSelfRetireMutation, useCreateUserInstitutionMutation, useGetUserInstitutionsQuery, useCreateUserEducationMutation, useUpdateUserEducationMutation, useDeleteUserEducationMutation, useGetUserEducationQuery, useCreateUserCompanyMutation, useGetUserCompaniesQuery, useCreateUserExperienceMutation, useUpdateUserExperienceMutation, useDeleteUserExperienceMutation, useGetUserExperienceQuery, useGetUserResumeQuery, useCreateUserResumeMutation, useGetMySubscriptionsQuery, useGetItemSubscriptionQuery, useCancelSubscriptionMutation, useGetLearnerDetailsQuery, useGetUserEnrolledCoursesQuery, useGetUserEnrolledProgramsQuery, useGetUserCatalogPathwaysQuery, useGetUsersAsAssertionsQuery, useGetUserEarnedSkillsQuery, useGetUserReportedSkillsQuery, useGetUserDesiredSkillsQuery, useCreateGlobalMemoryMutation, useGetMemsearchStatusQuery, useGetUserMemorySettingsQuery, useUpdateUserMemorySettingsMutation, useGetGlobalMemoriesQuery, useDeleteGlobalMemoryMutation, useInviteUserMutation, usePlatformInvitationsQuery, useCreateCatalogInvitationCourseBulkMutation, useGetCatalogInvitationsCourseQuery, useLazyPlatformUsersQuery, useLazyPlatformUserGroupsQuery, useGetPersonnalizedSearchQuery, useCreateCatalogInvitationProgramBulkMutation, useGetCatalogInvitationsProgramQuery, useUpdateUserRoleMutation, useUpdateUserStatusMutation, useUpdatePlatformUserRoleWithPoliciesMutation, usePlatformUsersQuery, isPoliciesResponse, platformApiSlice, featureTags, useLazyGetRbacTeamsAccessListQuery, useCreateRbacTeamsAccessMutation, useGetRbacGroupsQuery, usePlatformUserGroupsQuery, useCreateRbacGroupMutation, useUpdateRbacGroupMutation, useDeleteRbacGroupMutation, useCreatePlatformUserGroupMutation, useUpdatePlatformUserGroupMutation, useDeletePlatformUserGroupMutation, useGetRbacGroupDetailsQuery, useGetPlatformUserGroupDetailsQuery, useGetRbacPermissionsMutation, useGetRbacRolesQuery, useCreateRbacRoleMutation, useUpdateRbacRoleMutation, useDeleteRbacRoleMutation, useGetRbacRoleDetailsQuery, useGetRbacActionsDefinitionQuery, useGetRbacResourceDiscoveryQuery, useGetRbacResourceListQuery, useGetRbacPoliciesQuery, useCreateRbacPolicyMutation, useUpdateRbacPolicyMutation, useDeleteRbacPolicyMutation, useGetRbacPolicyDetailsQuery, useGetWatchedGroupsQuery, useCreateWatchedGroupMutation, useUpdateWatchedGroupMutation, useDeleteWatchedGroupMutation, useAddWatchedUserMutation, useRemoveWatchedUserMutation, useAddWatcherMutation, useUpdateWatcherMutation, useDeleteWatcherMutation, useGetWatchedUsersQuery, useGetWatchersQuery, WATCHER_NOTIFICATION_EVENTS, WATCHER_NOTIFICATION_EVENT_LABELS, useGetApplicationFormsQuery, useGetApplicationFormDetailQuery, useCreateApplicationFormMutation, useUpdateApplicationFormMutation, useGetApplicationAdminDetailQuery, useInviteApplicationCandidateMutation, useLazyGetApplicationAttachmentFileQuery, useCreateApplicationWaiverMutation, useDeleteApplicationWaiverMutation, useSubmitApplicationOverrideMutation, useUpdateApplicationPlacementMutation, useDeleteApplicationCourseAssignmentMutation, useCreateApplicationNoteMutation, useUpdateApplicationNoteMutation, useDeleteApplicationNoteMutation, useTransitionApplicationMutation, useLinkApplicationCandidateMutation, useCreateApplicationPlacementsMutation, useGetCustomMentorsQuery, useCreateApplicationCourseAssignmentsMutation, useGetApplicationBlocksQuery, useDeleteApplicationBlockMutation, useGetApplicationsPipelineStatsQuery, useGetApplicationsPipelineQuery, useDeleteApiKeyMutation, useGetApiKeysQuery, useCreateApiKeyMutation, useCreateLLMCredentialMutation, useGetCredentialsSchemaQuery, useGetMaskedLLMCredentialsQuery, useGetLlmsQuery, useDeleteIntegrationCredentialMutation, useDeleteCredentialMutation, useCreateIntegrationCredentialMutation, useGetIntegrationCredentialsSchemaQuery, useGetMaskedIntegrationCredentialsQuery, useGetAccountBillingInfoQuery, useUpdateAutoRechargeInfoMutation, useTriggerAutoRechargeMutation, useCreateStripeCustomerPortalMutation, useSetPlatformConfigurationsMutation, useGetPlatformConfigurationsQuery, useUpdatePlatformMembershipMutation, useGetPlatformMembershipQuery, useGetCustomDomainsQuery, useCreateCustomDomainMutation, useDeleteCustomDomainMutation, useGetStudentMentorCreationStatusQuery, useSetStudentMentorCreationStatusMutation, coreApiSlice, recommendationPromptTypeEnum, useGetRecommendedPromptsListQuery, useCreateRecommendedPromptMutation, useUpdateRecommendedPromptMutation, useDeleteRecommendedPromptMutation, useLazyGetPublicPlatformImageAssetFileUrlQuery, useUpdateTenantMetadataMutation, useCreatePlatformImageAssetMutation, useGetProviderConfigQuery, useCreateProviderConfigMutation, useDeleteProviderConfigMutation, useGetExternalMappingQuery, useGetCredentialsListQuery, useCreateExternalMappingMutation, useDeleteExternalMappingMutation, useGetMemsearchConfigQuery, useUpdateMemsearchConfigMutation, useGetStripeConnectStatusQuery, useStartStripeConnectOnboardingMutation, useLazyGetStripeConnectDashboardQuery, useGetAiSearchMentorsQuery, useListPaywallsQuery, useListPricesQuery, useCreatePriceMutation, useUpdatePriceMutation, useDeletePriceMutation, useGetPaywallConfigQuery, useEnablePaywallMutation, useUpdatePaywallMutation, useGetNotificationsCountQuery, useLazyGetNotificationsQuery, useMarkAllAsReadMutation, useCreateNotificationPreviewMutation, useSendNotificationMutation, useGetMentorsQuery, useUpdateTemplateMutation, useGetTemplateDetailsQuery, useGetTemplatesQuery, useLazyGetTemplateDetailsQuery, useToggleTemplateMutation, useGetTopicsStatsQuery, useGetUsersStatsQuery, useGetSessionStatsQuery, useGetTopicsDetailsStatsQuery, useGetAccessTimeHeatmapQuery, useGetUserDetailsStatsQuery, useGetTranscriptsConversationHeadlineQuery, useGetAverageRatingQuery, useGetFinancialStatsQuery, useGetDetailedFinancialStatsQuery, useGetTranscriptsMessagesDetailsQuery, useGetTranscriptsMessagesQuery, useGetReportDetailQuery, useLazyGetDownloadReportFromURLQuery, useGetMentorPublicSettingsQuery, useGetReportsQuery, useCreateReportMutation, useGetContentAnalyticsQuery, useGetContentAnalyticsDetailsQuery, useGetRevenueQuery, useListSubscribersQuery, useGetAuditLogsQuery, useLazyGetCourseMetaDataQuery, useLazyGetCourseCompletionOutlinesQuery, useLazyGetCourseEligibilityQuery, useLazyGetUserEnrolledCoursesQuery, useLazyGetUserAssignedCoursesQuery, useLazyGetUserCredentialsQuery, useLazyGetOverTimeActivityQuery, useLazyGetCatalogSearchQuery, useCreateOrUpdateUserReportedSkillMutation, useCreateOrUpdateUserDesiredSkillMutation, useLazyGetPathwayListQuery, useLazyGetUserAssignedPathwaysQuery, useLazyGetUserEnrolledPathwaysQuery, useLazyGetPathwayCompletionQuery, useLazyGetProgramListQuery, useLazyGetProgramCompletionQuery, useLazyGetUserEnrolledProgramsQuery, useLazyGetAssignedProgramsQuery, useLazyGetUserSkillsPointsQuery, useLazyGetUserReportedSkillsQuery, useLazyGetUserDesiredSkillsQuery, useLazyGetUserCatalogPathwaysQuery, useLazyGetPerLearnerInfoQuery, useLazyGetEdxSSOTokenQuery, useCreateCourseEnrollmentMutation, useCreateStripeCheckoutSessionMutation, useLazyGetCourseProgressQuery, useLazyGetCourseCompletionQuery, useLazyGetPersonnalizedSearchQuery, useUpdateExamAttemptMutation, useStartExamMutation, useLazyGetExamInfoQuery, useGetClawMentorConfigQuery, useGetClawInstancesQuery, useGetAgentConfigQuery, useUpdateClawMentorConfigMutation, useCreateClawMentorConfigMutation, useDeleteClawMentorConfigMutation, usePushClawConfigMutation, useCreateClawInstanceMutation, useDeleteClawInstanceMutation, useUpdateAgentConfigMutation, useHealthCheckClawInstanceMutation, useTestConnectivityClawInstanceMutation, useUpdateClawInstanceMutation, useGetAgentSkillsQuery, useGetMentorSkillAssignmentsQuery, useCreateMentorSkillAssignmentMutation, useUpdateMentorSkillAssignmentMutation, useDeleteMentorSkillAssignmentMutation, useCreateAgentSkillMutation, useUpdateAgentSkillMutation, useDeleteAgentSkillMutation, useCreateCheckoutMutation, useGetUserProjectsQuery, useUpdateUserProjectMutation, useGetTrainingDocumentsQuery, useGetVectorDocumentsQuery, useGetMentorMemoriesListQuery, useGetMemoryCategoriesAdminQuery, useDeleteMentorMemoryMutation, useUpdateMentorMemoryMutation, useCreateMentorMemoryMutation, useLazyGetConnectedServiceAuthUrlQuery, useCreateUserProjectMutation, useDeleteUserProjectMutation, useGetUserProjectDetailsQuery, useEditTrainingDocumentMutation, useAddTrainingDocumentMutation, useLazyGetCredentialsQuery, useGetMentorSettingsQuery, useEditMentorMutation, useGetMentorCategoriesQuery, useCreateMentorMutation, useUpdateUserPlatformMetadataMutation, useGetApplicationStatusQuery, useListOwnApplicationsQuery, useGetApplicationFormQuery, useWithdrawApplicationMutation, useRenewApplicationMutation, useCreateApplicationDraftMutation, useSubmitApplicationMutation, useUpdateApplicationMutation, useUploadApplicationAttachmentMutation, useDeleteApplicationAttachmentMutation, useGetPromptCategoriesQuery, useCreatePromptMutation, useDeletePromptMutation, useGetPromptsSearchQuery, useUpdatePromptMutation, useDeleteTrainingDocumentMutation, useGetTrainingDocumentRetrainScheduleQuery, useCreateTrainingDocumentRetrainScheduleMutation } from '@iblai/data-layer';
7
7
  import { toast } from 'sonner';
@@ -427,18 +427,18 @@ const TAURI_COMMANDS = {
427
427
  LOG_STDOUT: 'log_stdout',
428
428
  };
429
429
  // ============================================================================
430
- // System Control (GhostOS)
430
+ // Cowork (GhostOS)
431
431
  // ----------------------------------------------------------------------------
432
- // Contract for the "System Control" manager, which installs and sets up GhostOS
432
+ // Contract for the Cowork manager, which installs and sets up GhostOS
433
433
  // (https://github.com/ghostwright/ghost-os) on-device via the Tauri host. This
434
434
  // mirrors the Local Models (Ollama) contract above: the web layer ships the
435
435
  // presentational card + types, while the Tauri host (e.g. the ghost-os desktop
436
436
  // app) implements the native install/setup/status commands.
437
437
  // ============================================================================
438
- /** GitHub repository the System Control manager installs and sets up. */
438
+ /** GitHub repository the Cowork manager installs and sets up. */
439
439
  const GHOST_OS_REPO_URL = 'https://github.com/ghostwright/ghost-os';
440
440
  /**
441
- * Initial state for the System Control install flow.
441
+ * Initial state for the Cowork install flow.
442
442
  */
443
443
  const initialGhostOsInstallState = {
444
444
  status: 'idle',
@@ -470,7 +470,7 @@ const GHOST_OS_TAURI_COMMANDS = {
470
470
  /**
471
471
  * Tauri command strings exposed by `tauri-plugin-macos-permissions`
472
472
  * (https://github.com/ayangweb/tauri-plugin-macos-permissions). GhostOS needs
473
- * macOS Accessibility permission to control the device, so the System Control
473
+ * macOS Accessibility permission to control the device, so the Cowork
474
474
  * card surfaces it. These are invoked directly via `useTauri().invoke(...)` —
475
475
  * no extra npm dependency. The host must register the plugin in its Tauri app
476
476
  * (`tauri_plugin_macos_permissions::init()`). Each `CHECK_*` returns a boolean;
@@ -54758,7 +54758,7 @@ const createLucideIcon = (iconName, iconNode) => {
54758
54758
  */
54759
54759
 
54760
54760
 
54761
- const __iconNode$2l = [
54761
+ const __iconNode$2k = [
54762
54762
  [
54763
54763
  "path",
54764
54764
  {
@@ -54767,7 +54767,7 @@ const __iconNode$2l = [
54767
54767
  }
54768
54768
  ]
54769
54769
  ];
54770
- const Activity = createLucideIcon("activity", __iconNode$2l);
54770
+ const Activity = createLucideIcon("activity", __iconNode$2k);
54771
54771
 
54772
54772
  /**
54773
54773
  * @license lucide-react v0.528.0 - ISC
@@ -54777,12 +54777,12 @@ const Activity = createLucideIcon("activity", __iconNode$2l);
54777
54777
  */
54778
54778
 
54779
54779
 
54780
- const __iconNode$2k = [
54780
+ const __iconNode$2j = [
54781
54781
  ["path", { d: "M17 12H7", key: "16if0g" }],
54782
54782
  ["path", { d: "M19 18H5", key: "18s9l3" }],
54783
54783
  ["path", { d: "M21 6H3", key: "1jwq7v" }]
54784
54784
  ];
54785
- const AlignCenter = createLucideIcon("align-center", __iconNode$2k);
54785
+ const AlignCenter = createLucideIcon("align-center", __iconNode$2j);
54786
54786
 
54787
54787
  /**
54788
54788
  * @license lucide-react v0.528.0 - ISC
@@ -54792,12 +54792,12 @@ const AlignCenter = createLucideIcon("align-center", __iconNode$2k);
54792
54792
  */
54793
54793
 
54794
54794
 
54795
- const __iconNode$2j = [
54795
+ const __iconNode$2i = [
54796
54796
  ["path", { d: "M15 12H3", key: "6jk70r" }],
54797
54797
  ["path", { d: "M17 18H3", key: "1amg6g" }],
54798
54798
  ["path", { d: "M21 6H3", key: "1jwq7v" }]
54799
54799
  ];
54800
- const AlignLeft = createLucideIcon("align-left", __iconNode$2j);
54800
+ const AlignLeft = createLucideIcon("align-left", __iconNode$2i);
54801
54801
 
54802
54802
  /**
54803
54803
  * @license lucide-react v0.528.0 - ISC
@@ -54807,12 +54807,12 @@ const AlignLeft = createLucideIcon("align-left", __iconNode$2j);
54807
54807
  */
54808
54808
 
54809
54809
 
54810
- const __iconNode$2i = [
54810
+ const __iconNode$2h = [
54811
54811
  ["path", { d: "M21 12H9", key: "dn1m92" }],
54812
54812
  ["path", { d: "M21 18H7", key: "1ygte8" }],
54813
54813
  ["path", { d: "M21 6H3", key: "1jwq7v" }]
54814
54814
  ];
54815
- const AlignRight = createLucideIcon("align-right", __iconNode$2i);
54815
+ const AlignRight = createLucideIcon("align-right", __iconNode$2h);
54816
54816
 
54817
54817
  /**
54818
54818
  * @license lucide-react v0.528.0 - ISC
@@ -54822,12 +54822,12 @@ const AlignRight = createLucideIcon("align-right", __iconNode$2i);
54822
54822
  */
54823
54823
 
54824
54824
 
54825
- const __iconNode$2h = [
54825
+ const __iconNode$2g = [
54826
54826
  ["rect", { width: "20", height: "5", x: "2", y: "3", rx: "1", key: "1wp1u1" }],
54827
54827
  ["path", { d: "M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8", key: "1s80jp" }],
54828
54828
  ["path", { d: "M10 12h4", key: "a56b0p" }]
54829
54829
  ];
54830
- const Archive = createLucideIcon("archive", __iconNode$2h);
54830
+ const Archive = createLucideIcon("archive", __iconNode$2g);
54831
54831
 
54832
54832
  /**
54833
54833
  * @license lucide-react v0.528.0 - ISC
@@ -54837,11 +54837,11 @@ const Archive = createLucideIcon("archive", __iconNode$2h);
54837
54837
  */
54838
54838
 
54839
54839
 
54840
- const __iconNode$2g = [
54840
+ const __iconNode$2f = [
54841
54841
  ["path", { d: "M12 5v14", key: "s699le" }],
54842
54842
  ["path", { d: "m19 12-7 7-7-7", key: "1idqje" }]
54843
54843
  ];
54844
- const ArrowDown = createLucideIcon("arrow-down", __iconNode$2g);
54844
+ const ArrowDown = createLucideIcon("arrow-down", __iconNode$2f);
54845
54845
 
54846
54846
  /**
54847
54847
  * @license lucide-react v0.528.0 - ISC
@@ -54851,11 +54851,11 @@ const ArrowDown = createLucideIcon("arrow-down", __iconNode$2g);
54851
54851
  */
54852
54852
 
54853
54853
 
54854
- const __iconNode$2f = [
54854
+ const __iconNode$2e = [
54855
54855
  ["path", { d: "m12 19-7-7 7-7", key: "1l729n" }],
54856
54856
  ["path", { d: "M19 12H5", key: "x3x0zl" }]
54857
54857
  ];
54858
- const ArrowLeft = createLucideIcon("arrow-left", __iconNode$2f);
54858
+ const ArrowLeft = createLucideIcon("arrow-left", __iconNode$2e);
54859
54859
 
54860
54860
  /**
54861
54861
  * @license lucide-react v0.528.0 - ISC
@@ -54865,11 +54865,11 @@ const ArrowLeft = createLucideIcon("arrow-left", __iconNode$2f);
54865
54865
  */
54866
54866
 
54867
54867
 
54868
- const __iconNode$2e = [
54868
+ const __iconNode$2d = [
54869
54869
  ["path", { d: "M5 12h14", key: "1ays0h" }],
54870
54870
  ["path", { d: "m12 5 7 7-7 7", key: "xquz4c" }]
54871
54871
  ];
54872
- const ArrowRight = createLucideIcon("arrow-right", __iconNode$2e);
54872
+ const ArrowRight = createLucideIcon("arrow-right", __iconNode$2d);
54873
54873
 
54874
54874
  /**
54875
54875
  * @license lucide-react v0.528.0 - ISC
@@ -54879,11 +54879,11 @@ const ArrowRight = createLucideIcon("arrow-right", __iconNode$2e);
54879
54879
  */
54880
54880
 
54881
54881
 
54882
- const __iconNode$2d = [
54882
+ const __iconNode$2c = [
54883
54883
  ["path", { d: "m5 12 7-7 7 7", key: "hav0vg" }],
54884
54884
  ["path", { d: "M12 19V5", key: "x0mq9r" }]
54885
54885
  ];
54886
- const ArrowUp = createLucideIcon("arrow-up", __iconNode$2d);
54886
+ const ArrowUp = createLucideIcon("arrow-up", __iconNode$2c);
54887
54887
 
54888
54888
  /**
54889
54889
  * @license lucide-react v0.528.0 - ISC
@@ -54893,7 +54893,7 @@ const ArrowUp = createLucideIcon("arrow-up", __iconNode$2d);
54893
54893
  */
54894
54894
 
54895
54895
 
54896
- const __iconNode$2c = [
54896
+ const __iconNode$2b = [
54897
54897
  [
54898
54898
  "path",
54899
54899
  {
@@ -54903,7 +54903,7 @@ const __iconNode$2c = [
54903
54903
  ],
54904
54904
  ["circle", { cx: "12", cy: "8", r: "6", key: "1vp47v" }]
54905
54905
  ];
54906
- const Award = createLucideIcon("award", __iconNode$2c);
54906
+ const Award = createLucideIcon("award", __iconNode$2b);
54907
54907
 
54908
54908
  /**
54909
54909
  * @license lucide-react v0.528.0 - ISC
@@ -54913,11 +54913,11 @@ const Award = createLucideIcon("award", __iconNode$2c);
54913
54913
  */
54914
54914
 
54915
54915
 
54916
- const __iconNode$2b = [
54916
+ const __iconNode$2a = [
54917
54917
  ["path", { d: "M4.929 4.929 19.07 19.071", key: "196cmz" }],
54918
54918
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }]
54919
54919
  ];
54920
- const Ban = createLucideIcon("ban", __iconNode$2b);
54920
+ const Ban = createLucideIcon("ban", __iconNode$2a);
54921
54921
 
54922
54922
  /**
54923
54923
  * @license lucide-react v0.528.0 - ISC
@@ -54927,12 +54927,12 @@ const Ban = createLucideIcon("ban", __iconNode$2b);
54927
54927
  */
54928
54928
 
54929
54929
 
54930
- const __iconNode$2a = [
54930
+ const __iconNode$29 = [
54931
54931
  ["rect", { width: "20", height: "12", x: "2", y: "6", rx: "2", key: "9lu3g6" }],
54932
54932
  ["circle", { cx: "12", cy: "12", r: "2", key: "1c9p78" }],
54933
54933
  ["path", { d: "M6 12h.01M18 12h.01", key: "113zkx" }]
54934
54934
  ];
54935
- const Banknote = createLucideIcon("banknote", __iconNode$2a);
54935
+ const Banknote = createLucideIcon("banknote", __iconNode$29);
54936
54936
 
54937
54937
  /**
54938
54938
  * @license lucide-react v0.528.0 - ISC
@@ -54942,7 +54942,7 @@ const Banknote = createLucideIcon("banknote", __iconNode$2a);
54942
54942
  */
54943
54943
 
54944
54944
 
54945
- const __iconNode$29 = [
54945
+ const __iconNode$28 = [
54946
54946
  ["path", { d: "M10.268 21a2 2 0 0 0 3.464 0", key: "vwvbt9" }],
54947
54947
  ["path", { d: "M22 8c0-2.3-.8-4.3-2-6", key: "5bb3ad" }],
54948
54948
  [
@@ -54954,7 +54954,7 @@ const __iconNode$29 = [
54954
54954
  ],
54955
54955
  ["path", { d: "M4 2C2.8 3.7 2 5.7 2 8", key: "tap9e0" }]
54956
54956
  ];
54957
- const BellRing = createLucideIcon("bell-ring", __iconNode$29);
54957
+ const BellRing = createLucideIcon("bell-ring", __iconNode$28);
54958
54958
 
54959
54959
  /**
54960
54960
  * @license lucide-react v0.528.0 - ISC
@@ -54964,7 +54964,7 @@ const BellRing = createLucideIcon("bell-ring", __iconNode$29);
54964
54964
  */
54965
54965
 
54966
54966
 
54967
- const __iconNode$28 = [
54967
+ const __iconNode$27 = [
54968
54968
  ["path", { d: "M10.268 21a2 2 0 0 0 3.464 0", key: "vwvbt9" }],
54969
54969
  [
54970
54970
  "path",
@@ -54974,7 +54974,7 @@ const __iconNode$28 = [
54974
54974
  }
54975
54975
  ]
54976
54976
  ];
54977
- const Bell = createLucideIcon("bell", __iconNode$28);
54977
+ const Bell = createLucideIcon("bell", __iconNode$27);
54978
54978
 
54979
54979
  /**
54980
54980
  * @license lucide-react v0.528.0 - ISC
@@ -54984,13 +54984,13 @@ const Bell = createLucideIcon("bell", __iconNode$28);
54984
54984
  */
54985
54985
 
54986
54986
 
54987
- const __iconNode$27 = [
54987
+ const __iconNode$26 = [
54988
54988
  [
54989
54989
  "path",
54990
54990
  { d: "M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8", key: "mg9rjx" }
54991
54991
  ]
54992
54992
  ];
54993
- const Bold$1 = createLucideIcon("bold", __iconNode$27);
54993
+ const Bold$1 = createLucideIcon("bold", __iconNode$26);
54994
54994
 
54995
54995
  /**
54996
54996
  * @license lucide-react v0.528.0 - ISC
@@ -55000,7 +55000,7 @@ const Bold$1 = createLucideIcon("bold", __iconNode$27);
55000
55000
  */
55001
55001
 
55002
55002
 
55003
- const __iconNode$26 = [
55003
+ const __iconNode$25 = [
55004
55004
  ["path", { d: "M12 7v14", key: "1akyts" }],
55005
55005
  [
55006
55006
  "path",
@@ -55010,7 +55010,7 @@ const __iconNode$26 = [
55010
55010
  }
55011
55011
  ]
55012
55012
  ];
55013
- const BookOpen = createLucideIcon("book-open", __iconNode$26);
55013
+ const BookOpen = createLucideIcon("book-open", __iconNode$25);
55014
55014
 
55015
55015
  /**
55016
55016
  * @license lucide-react v0.528.0 - ISC
@@ -55020,7 +55020,7 @@ const BookOpen = createLucideIcon("book-open", __iconNode$26);
55020
55020
  */
55021
55021
 
55022
55022
 
55023
- const __iconNode$25 = [
55023
+ const __iconNode$24 = [
55024
55024
  ["path", { d: "M12 8V4H8", key: "hb8ula" }],
55025
55025
  ["rect", { width: "16", height: "12", x: "4", y: "8", rx: "2", key: "enze0r" }],
55026
55026
  ["path", { d: "M2 14h2", key: "vft8re" }],
@@ -55028,7 +55028,7 @@ const __iconNode$25 = [
55028
55028
  ["path", { d: "M15 13v2", key: "1xurst" }],
55029
55029
  ["path", { d: "M9 13v2", key: "rq6x2g" }]
55030
55030
  ];
55031
- const Bot = createLucideIcon("bot", __iconNode$25);
55031
+ const Bot = createLucideIcon("bot", __iconNode$24);
55032
55032
 
55033
55033
  /**
55034
55034
  * @license lucide-react v0.528.0 - ISC
@@ -55038,11 +55038,11 @@ const Bot = createLucideIcon("bot", __iconNode$25);
55038
55038
  */
55039
55039
 
55040
55040
 
55041
- const __iconNode$24 = [
55041
+ const __iconNode$23 = [
55042
55042
  ["path", { d: "M16 20V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16", key: "jecpp" }],
55043
55043
  ["rect", { width: "20", height: "14", x: "2", y: "6", rx: "2", key: "i6l2r4" }]
55044
55044
  ];
55045
- const Briefcase = createLucideIcon("briefcase", __iconNode$24);
55045
+ const Briefcase = createLucideIcon("briefcase", __iconNode$23);
55046
55046
 
55047
55047
  /**
55048
55048
  * @license lucide-react v0.528.0 - ISC
@@ -55052,7 +55052,7 @@ const Briefcase = createLucideIcon("briefcase", __iconNode$24);
55052
55052
  */
55053
55053
 
55054
55054
 
55055
- const __iconNode$23 = [
55055
+ const __iconNode$22 = [
55056
55056
  ["path", { d: "M6 22V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v18Z", key: "1b4qmf" }],
55057
55057
  ["path", { d: "M6 12H4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2", key: "i71pzd" }],
55058
55058
  ["path", { d: "M18 9h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-2", key: "10jefs" }],
@@ -55061,7 +55061,7 @@ const __iconNode$23 = [
55061
55061
  ["path", { d: "M10 14h4", key: "kelpxr" }],
55062
55062
  ["path", { d: "M10 18h4", key: "1ulq68" }]
55063
55063
  ];
55064
- const Building2 = createLucideIcon("building-2", __iconNode$23);
55064
+ const Building2 = createLucideIcon("building-2", __iconNode$22);
55065
55065
 
55066
55066
  /**
55067
55067
  * @license lucide-react v0.528.0 - ISC
@@ -55071,13 +55071,13 @@ const Building2 = createLucideIcon("building-2", __iconNode$23);
55071
55071
  */
55072
55072
 
55073
55073
 
55074
- const __iconNode$22 = [
55074
+ const __iconNode$21 = [
55075
55075
  ["path", { d: "M8 2v4", key: "1cmpym" }],
55076
55076
  ["path", { d: "M16 2v4", key: "4m81vk" }],
55077
55077
  ["rect", { width: "18", height: "18", x: "3", y: "4", rx: "2", key: "1hopcy" }],
55078
55078
  ["path", { d: "M3 10h18", key: "8toen8" }]
55079
55079
  ];
55080
- const Calendar$1 = createLucideIcon("calendar", __iconNode$22);
55080
+ const Calendar$1 = createLucideIcon("calendar", __iconNode$21);
55081
55081
 
55082
55082
  /**
55083
55083
  * @license lucide-react v0.528.0 - ISC
@@ -55087,11 +55087,11 @@ const Calendar$1 = createLucideIcon("calendar", __iconNode$22);
55087
55087
  */
55088
55088
 
55089
55089
 
55090
- const __iconNode$21 = [
55090
+ const __iconNode$20 = [
55091
55091
  ["path", { d: "M18 6 7 17l-5-5", key: "116fxf" }],
55092
55092
  ["path", { d: "m22 10-7.5 7.5L13 16", key: "ke71qq" }]
55093
55093
  ];
55094
- const CheckCheck = createLucideIcon("check-check", __iconNode$21);
55094
+ const CheckCheck = createLucideIcon("check-check", __iconNode$20);
55095
55095
 
55096
55096
  /**
55097
55097
  * @license lucide-react v0.528.0 - ISC
@@ -55101,8 +55101,8 @@ const CheckCheck = createLucideIcon("check-check", __iconNode$21);
55101
55101
  */
55102
55102
 
55103
55103
 
55104
- const __iconNode$20 = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]];
55105
- const Check = createLucideIcon("check", __iconNode$20);
55104
+ const __iconNode$1$ = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]];
55105
+ const Check = createLucideIcon("check", __iconNode$1$);
55106
55106
 
55107
55107
  /**
55108
55108
  * @license lucide-react v0.528.0 - ISC
@@ -55112,8 +55112,8 @@ const Check = createLucideIcon("check", __iconNode$20);
55112
55112
  */
55113
55113
 
55114
55114
 
55115
- const __iconNode$1$ = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
55116
- const ChevronDown = createLucideIcon("chevron-down", __iconNode$1$);
55115
+ const __iconNode$1_ = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
55116
+ const ChevronDown = createLucideIcon("chevron-down", __iconNode$1_);
55117
55117
 
55118
55118
  /**
55119
55119
  * @license lucide-react v0.528.0 - ISC
@@ -55123,11 +55123,11 @@ const ChevronDown = createLucideIcon("chevron-down", __iconNode$1$);
55123
55123
  */
55124
55124
 
55125
55125
 
55126
- const __iconNode$1_ = [
55126
+ const __iconNode$1Z = [
55127
55127
  ["path", { d: "m17 18-6-6 6-6", key: "1yerx2" }],
55128
55128
  ["path", { d: "M7 6v12", key: "1p53r6" }]
55129
55129
  ];
55130
- const ChevronFirst = createLucideIcon("chevron-first", __iconNode$1_);
55130
+ const ChevronFirst = createLucideIcon("chevron-first", __iconNode$1Z);
55131
55131
 
55132
55132
  /**
55133
55133
  * @license lucide-react v0.528.0 - ISC
@@ -55137,11 +55137,11 @@ const ChevronFirst = createLucideIcon("chevron-first", __iconNode$1_);
55137
55137
  */
55138
55138
 
55139
55139
 
55140
- const __iconNode$1Z = [
55140
+ const __iconNode$1Y = [
55141
55141
  ["path", { d: "m7 18 6-6-6-6", key: "lwmzdw" }],
55142
55142
  ["path", { d: "M17 6v12", key: "1o0aio" }]
55143
55143
  ];
55144
- const ChevronLast = createLucideIcon("chevron-last", __iconNode$1Z);
55144
+ const ChevronLast = createLucideIcon("chevron-last", __iconNode$1Y);
55145
55145
 
55146
55146
  /**
55147
55147
  * @license lucide-react v0.528.0 - ISC
@@ -55151,8 +55151,8 @@ const ChevronLast = createLucideIcon("chevron-last", __iconNode$1Z);
55151
55151
  */
55152
55152
 
55153
55153
 
55154
- const __iconNode$1Y = [["path", { d: "m15 18-6-6 6-6", key: "1wnfg3" }]];
55155
- const ChevronLeft = createLucideIcon("chevron-left", __iconNode$1Y);
55154
+ const __iconNode$1X = [["path", { d: "m15 18-6-6 6-6", key: "1wnfg3" }]];
55155
+ const ChevronLeft = createLucideIcon("chevron-left", __iconNode$1X);
55156
55156
 
55157
55157
  /**
55158
55158
  * @license lucide-react v0.528.0 - ISC
@@ -55162,8 +55162,8 @@ const ChevronLeft = createLucideIcon("chevron-left", __iconNode$1Y);
55162
55162
  */
55163
55163
 
55164
55164
 
55165
- const __iconNode$1X = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
55166
- const ChevronRight = createLucideIcon("chevron-right", __iconNode$1X);
55165
+ const __iconNode$1W = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
55166
+ const ChevronRight = createLucideIcon("chevron-right", __iconNode$1W);
55167
55167
 
55168
55168
  /**
55169
55169
  * @license lucide-react v0.528.0 - ISC
@@ -55173,8 +55173,8 @@ const ChevronRight = createLucideIcon("chevron-right", __iconNode$1X);
55173
55173
  */
55174
55174
 
55175
55175
 
55176
- const __iconNode$1W = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]];
55177
- const ChevronUp = createLucideIcon("chevron-up", __iconNode$1W);
55176
+ const __iconNode$1V = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]];
55177
+ const ChevronUp = createLucideIcon("chevron-up", __iconNode$1V);
55178
55178
 
55179
55179
  /**
55180
55180
  * @license lucide-react v0.528.0 - ISC
@@ -55184,11 +55184,11 @@ const ChevronUp = createLucideIcon("chevron-up", __iconNode$1W);
55184
55184
  */
55185
55185
 
55186
55186
 
55187
- const __iconNode$1V = [
55187
+ const __iconNode$1U = [
55188
55188
  ["path", { d: "m11 17-5-5 5-5", key: "13zhaf" }],
55189
55189
  ["path", { d: "m18 17-5-5 5-5", key: "h8a8et" }]
55190
55190
  ];
55191
- const ChevronsLeft = createLucideIcon("chevrons-left", __iconNode$1V);
55191
+ const ChevronsLeft = createLucideIcon("chevrons-left", __iconNode$1U);
55192
55192
 
55193
55193
  /**
55194
55194
  * @license lucide-react v0.528.0 - ISC
@@ -55198,11 +55198,11 @@ const ChevronsLeft = createLucideIcon("chevrons-left", __iconNode$1V);
55198
55198
  */
55199
55199
 
55200
55200
 
55201
- const __iconNode$1U = [
55201
+ const __iconNode$1T = [
55202
55202
  ["path", { d: "m6 17 5-5-5-5", key: "xnjwq" }],
55203
55203
  ["path", { d: "m13 17 5-5-5-5", key: "17xmmf" }]
55204
55204
  ];
55205
- const ChevronsRight = createLucideIcon("chevrons-right", __iconNode$1U);
55205
+ const ChevronsRight = createLucideIcon("chevrons-right", __iconNode$1T);
55206
55206
 
55207
55207
  /**
55208
55208
  * @license lucide-react v0.528.0 - ISC
@@ -55212,11 +55212,11 @@ const ChevronsRight = createLucideIcon("chevrons-right", __iconNode$1U);
55212
55212
  */
55213
55213
 
55214
55214
 
55215
- const __iconNode$1T = [
55215
+ const __iconNode$1S = [
55216
55216
  ["path", { d: "m7 15 5 5 5-5", key: "1hf1tw" }],
55217
55217
  ["path", { d: "m7 9 5-5 5 5", key: "sgt6xg" }]
55218
55218
  ];
55219
- const ChevronsUpDown = createLucideIcon("chevrons-up-down", __iconNode$1T);
55219
+ const ChevronsUpDown = createLucideIcon("chevrons-up-down", __iconNode$1S);
55220
55220
 
55221
55221
  /**
55222
55222
  * @license lucide-react v0.528.0 - ISC
@@ -55226,27 +55226,12 @@ const ChevronsUpDown = createLucideIcon("chevrons-up-down", __iconNode$1T);
55226
55226
  */
55227
55227
 
55228
55228
 
55229
- const __iconNode$1S = [
55229
+ const __iconNode$1R = [
55230
55230
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
55231
55231
  ["line", { x1: "12", x2: "12", y1: "8", y2: "12", key: "1pkeuh" }],
55232
55232
  ["line", { x1: "12", x2: "12.01", y1: "16", y2: "16", key: "4dfq90" }]
55233
55233
  ];
55234
- const CircleAlert = createLucideIcon("circle-alert", __iconNode$1S);
55235
-
55236
- /**
55237
- * @license lucide-react v0.528.0 - ISC
55238
- *
55239
- * This source code is licensed under the ISC license.
55240
- * See the LICENSE file in the root directory of this source tree.
55241
- */
55242
-
55243
-
55244
- const __iconNode$1R = [
55245
- ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
55246
- ["path", { d: "m16 12-4-4-4 4", key: "177agl" }],
55247
- ["path", { d: "M12 16V8", key: "1sbj14" }]
55248
- ];
55249
- const CircleArrowUp = createLucideIcon("circle-arrow-up", __iconNode$1R);
55234
+ const CircleAlert = createLucideIcon("circle-alert", __iconNode$1R);
55250
55235
 
55251
55236
  /**
55252
55237
  * @license lucide-react v0.528.0 - ISC
@@ -55363,24 +55348,11 @@ const Clock = createLucideIcon("clock", __iconNode$1K);
55363
55348
 
55364
55349
 
55365
55350
  const __iconNode$1J = [
55366
- ["path", { d: "M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z", key: "p7xjir" }]
55367
- ];
55368
- const Cloud = createLucideIcon("cloud", __iconNode$1J);
55369
-
55370
- /**
55371
- * @license lucide-react v0.528.0 - ISC
55372
- *
55373
- * This source code is licensed under the ISC license.
55374
- * See the LICENSE file in the root directory of this source tree.
55375
- */
55376
-
55377
-
55378
- const __iconNode$1I = [
55379
55351
  ["path", { d: "m18 16 4-4-4-4", key: "1inbqp" }],
55380
55352
  ["path", { d: "m6 8-4 4 4 4", key: "15zrgr" }],
55381
55353
  ["path", { d: "m14.5 4-5 16", key: "e7oirm" }]
55382
55354
  ];
55383
- const CodeXml = createLucideIcon("code-xml", __iconNode$1I);
55355
+ const CodeXml = createLucideIcon("code-xml", __iconNode$1J);
55384
55356
 
55385
55357
  /**
55386
55358
  * @license lucide-react v0.528.0 - ISC
@@ -55390,11 +55362,11 @@ const CodeXml = createLucideIcon("code-xml", __iconNode$1I);
55390
55362
  */
55391
55363
 
55392
55364
 
55393
- const __iconNode$1H = [
55365
+ const __iconNode$1I = [
55394
55366
  ["path", { d: "m16 18 6-6-6-6", key: "eg8j8" }],
55395
55367
  ["path", { d: "m8 6-6 6 6 6", key: "ppft3o" }]
55396
55368
  ];
55397
- const Code$1 = createLucideIcon("code", __iconNode$1H);
55369
+ const Code$1 = createLucideIcon("code", __iconNode$1I);
55398
55370
 
55399
55371
  /**
55400
55372
  * @license lucide-react v0.528.0 - ISC
@@ -55404,11 +55376,11 @@ const Code$1 = createLucideIcon("code", __iconNode$1H);
55404
55376
  */
55405
55377
 
55406
55378
 
55407
- const __iconNode$1G = [
55379
+ const __iconNode$1H = [
55408
55380
  ["rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2", key: "17jyea" }],
55409
55381
  ["path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2", key: "zix9uf" }]
55410
55382
  ];
55411
- const Copy = createLucideIcon("copy", __iconNode$1G);
55383
+ const Copy = createLucideIcon("copy", __iconNode$1H);
55412
55384
 
55413
55385
  /**
55414
55386
  * @license lucide-react v0.528.0 - ISC
@@ -55418,11 +55390,11 @@ const Copy = createLucideIcon("copy", __iconNode$1G);
55418
55390
  */
55419
55391
 
55420
55392
 
55421
- const __iconNode$1F = [
55393
+ const __iconNode$1G = [
55422
55394
  ["rect", { width: "20", height: "14", x: "2", y: "5", rx: "2", key: "ynyp8z" }],
55423
55395
  ["line", { x1: "2", x2: "22", y1: "10", y2: "10", key: "1b3vmo" }]
55424
55396
  ];
55425
- const CreditCard = createLucideIcon("credit-card", __iconNode$1F);
55397
+ const CreditCard = createLucideIcon("credit-card", __iconNode$1G);
55426
55398
 
55427
55399
  /**
55428
55400
  * @license lucide-react v0.528.0 - ISC
@@ -55432,12 +55404,12 @@ const CreditCard = createLucideIcon("credit-card", __iconNode$1F);
55432
55404
  */
55433
55405
 
55434
55406
 
55435
- const __iconNode$1E = [
55407
+ const __iconNode$1F = [
55436
55408
  ["ellipse", { cx: "12", cy: "5", rx: "9", ry: "3", key: "msslwz" }],
55437
55409
  ["path", { d: "M3 5V19A9 3 0 0 0 21 19V5", key: "1wlel7" }],
55438
55410
  ["path", { d: "M3 12A9 3 0 0 0 21 12", key: "mv7ke4" }]
55439
55411
  ];
55440
- const Database = createLucideIcon("database", __iconNode$1E);
55412
+ const Database = createLucideIcon("database", __iconNode$1F);
55441
55413
 
55442
55414
  /**
55443
55415
  * @license lucide-react v0.528.0 - ISC
@@ -55447,11 +55419,11 @@ const Database = createLucideIcon("database", __iconNode$1E);
55447
55419
  */
55448
55420
 
55449
55421
 
55450
- const __iconNode$1D = [
55422
+ const __iconNode$1E = [
55451
55423
  ["line", { x1: "12", x2: "12", y1: "2", y2: "22", key: "7eqyqh" }],
55452
55424
  ["path", { d: "M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6", key: "1b0p4s" }]
55453
55425
  ];
55454
- const DollarSign = createLucideIcon("dollar-sign", __iconNode$1D);
55426
+ const DollarSign = createLucideIcon("dollar-sign", __iconNode$1E);
55455
55427
 
55456
55428
  /**
55457
55429
  * @license lucide-react v0.528.0 - ISC
@@ -55461,7 +55433,7 @@ const DollarSign = createLucideIcon("dollar-sign", __iconNode$1D);
55461
55433
  */
55462
55434
 
55463
55435
 
55464
- const __iconNode$1C = [
55436
+ const __iconNode$1D = [
55465
55437
  ["path", { d: "M11 20H2", key: "nlcfvz" }],
55466
55438
  [
55467
55439
  "path",
@@ -55474,7 +55446,7 @@ const __iconNode$1C = [
55474
55446
  ["path", { d: "M14 12h.01", key: "1jfl7z" }],
55475
55447
  ["path", { d: "M22 20h-3", key: "vhrsz" }]
55476
55448
  ];
55477
- const DoorOpen = createLucideIcon("door-open", __iconNode$1C);
55449
+ const DoorOpen = createLucideIcon("door-open", __iconNode$1D);
55478
55450
 
55479
55451
  /**
55480
55452
  * @license lucide-react v0.528.0 - ISC
@@ -55484,12 +55456,12 @@ const DoorOpen = createLucideIcon("door-open", __iconNode$1C);
55484
55456
  */
55485
55457
 
55486
55458
 
55487
- const __iconNode$1B = [
55459
+ const __iconNode$1C = [
55488
55460
  ["path", { d: "M12 15V3", key: "m9g1x1" }],
55489
55461
  ["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4", key: "ih7n3h" }],
55490
55462
  ["path", { d: "m7 10 5 5 5-5", key: "brsn70" }]
55491
55463
  ];
55492
- const Download = createLucideIcon("download", __iconNode$1B);
55464
+ const Download = createLucideIcon("download", __iconNode$1C);
55493
55465
 
55494
55466
  /**
55495
55467
  * @license lucide-react v0.528.0 - ISC
@@ -55499,12 +55471,12 @@ const Download = createLucideIcon("download", __iconNode$1B);
55499
55471
  */
55500
55472
 
55501
55473
 
55502
- const __iconNode$1A = [
55474
+ const __iconNode$1B = [
55503
55475
  ["circle", { cx: "12", cy: "12", r: "1", key: "41hilf" }],
55504
55476
  ["circle", { cx: "12", cy: "5", r: "1", key: "gxeob9" }],
55505
55477
  ["circle", { cx: "12", cy: "19", r: "1", key: "lyex9k" }]
55506
55478
  ];
55507
- const EllipsisVertical = createLucideIcon("ellipsis-vertical", __iconNode$1A);
55479
+ const EllipsisVertical = createLucideIcon("ellipsis-vertical", __iconNode$1B);
55508
55480
 
55509
55481
  /**
55510
55482
  * @license lucide-react v0.528.0 - ISC
@@ -55514,12 +55486,12 @@ const EllipsisVertical = createLucideIcon("ellipsis-vertical", __iconNode$1A);
55514
55486
  */
55515
55487
 
55516
55488
 
55517
- const __iconNode$1z = [
55489
+ const __iconNode$1A = [
55518
55490
  ["circle", { cx: "12", cy: "12", r: "1", key: "41hilf" }],
55519
55491
  ["circle", { cx: "19", cy: "12", r: "1", key: "1wjl8i" }],
55520
55492
  ["circle", { cx: "5", cy: "12", r: "1", key: "1pcz8c" }]
55521
55493
  ];
55522
- const Ellipsis = createLucideIcon("ellipsis", __iconNode$1z);
55494
+ const Ellipsis = createLucideIcon("ellipsis", __iconNode$1A);
55523
55495
 
55524
55496
  /**
55525
55497
  * @license lucide-react v0.528.0 - ISC
@@ -55529,12 +55501,12 @@ const Ellipsis = createLucideIcon("ellipsis", __iconNode$1z);
55529
55501
  */
55530
55502
 
55531
55503
 
55532
- const __iconNode$1y = [
55504
+ const __iconNode$1z = [
55533
55505
  ["path", { d: "M15 3h6v6", key: "1q9fwt" }],
55534
55506
  ["path", { d: "M10 14 21 3", key: "gplh6r" }],
55535
55507
  ["path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6", key: "a6xqqp" }]
55536
55508
  ];
55537
- const ExternalLink = createLucideIcon("external-link", __iconNode$1y);
55509
+ const ExternalLink = createLucideIcon("external-link", __iconNode$1z);
55538
55510
 
55539
55511
  /**
55540
55512
  * @license lucide-react v0.528.0 - ISC
@@ -55544,7 +55516,7 @@ const ExternalLink = createLucideIcon("external-link", __iconNode$1y);
55544
55516
  */
55545
55517
 
55546
55518
 
55547
- const __iconNode$1x = [
55519
+ const __iconNode$1y = [
55548
55520
  [
55549
55521
  "path",
55550
55522
  {
@@ -55562,7 +55534,7 @@ const __iconNode$1x = [
55562
55534
  ],
55563
55535
  ["path", { d: "m2 2 20 20", key: "1ooewy" }]
55564
55536
  ];
55565
- const EyeOff = createLucideIcon("eye-off", __iconNode$1x);
55537
+ const EyeOff = createLucideIcon("eye-off", __iconNode$1y);
55566
55538
 
55567
55539
  /**
55568
55540
  * @license lucide-react v0.528.0 - ISC
@@ -55572,7 +55544,7 @@ const EyeOff = createLucideIcon("eye-off", __iconNode$1x);
55572
55544
  */
55573
55545
 
55574
55546
 
55575
- const __iconNode$1w = [
55547
+ const __iconNode$1x = [
55576
55548
  [
55577
55549
  "path",
55578
55550
  {
@@ -55582,7 +55554,7 @@ const __iconNode$1w = [
55582
55554
  ],
55583
55555
  ["circle", { cx: "12", cy: "12", r: "3", key: "1v7zrd" }]
55584
55556
  ];
55585
- const Eye = createLucideIcon("eye", __iconNode$1w);
55557
+ const Eye = createLucideIcon("eye", __iconNode$1x);
55586
55558
 
55587
55559
  /**
55588
55560
  * @license lucide-react v0.528.0 - ISC
@@ -55592,7 +55564,7 @@ const Eye = createLucideIcon("eye", __iconNode$1w);
55592
55564
  */
55593
55565
 
55594
55566
 
55595
- const __iconNode$1v = [
55567
+ const __iconNode$1w = [
55596
55568
  ["path", { d: "M10 12v-1", key: "v7bkov" }],
55597
55569
  ["path", { d: "M10 18v-2", key: "1cjy8d" }],
55598
55570
  ["path", { d: "M10 7V6", key: "dljcrl" }],
@@ -55603,7 +55575,7 @@ const __iconNode$1v = [
55603
55575
  ],
55604
55576
  ["circle", { cx: "10", cy: "20", r: "2", key: "1xzdoj" }]
55605
55577
  ];
55606
- const FileArchive = createLucideIcon("file-archive", __iconNode$1v);
55578
+ const FileArchive = createLucideIcon("file-archive", __iconNode$1w);
55607
55579
 
55608
55580
  /**
55609
55581
  * @license lucide-react v0.528.0 - ISC
@@ -55613,7 +55585,7 @@ const FileArchive = createLucideIcon("file-archive", __iconNode$1v);
55613
55585
  */
55614
55586
 
55615
55587
 
55616
- const __iconNode$1u = [
55588
+ const __iconNode$1v = [
55617
55589
  ["path", { d: "M17.5 22h.5a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v3", key: "rslqgf" }],
55618
55590
  ["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }],
55619
55591
  [
@@ -55624,7 +55596,7 @@ const __iconNode$1u = [
55624
55596
  }
55625
55597
  ]
55626
55598
  ];
55627
- const FileAudio = createLucideIcon("file-audio", __iconNode$1u);
55599
+ const FileAudio = createLucideIcon("file-audio", __iconNode$1v);
55628
55600
 
55629
55601
  /**
55630
55602
  * @license lucide-react v0.528.0 - ISC
@@ -55634,13 +55606,13 @@ const FileAudio = createLucideIcon("file-audio", __iconNode$1u);
55634
55606
  */
55635
55607
 
55636
55608
 
55637
- const __iconNode$1t = [
55609
+ const __iconNode$1u = [
55638
55610
  ["path", { d: "M10 12.5 8 15l2 2.5", key: "1tg20x" }],
55639
55611
  ["path", { d: "m14 12.5 2 2.5-2 2.5", key: "yinavb" }],
55640
55612
  ["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }],
55641
55613
  ["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z", key: "1mlx9k" }]
55642
55614
  ];
55643
- const FileCode = createLucideIcon("file-code", __iconNode$1t);
55615
+ const FileCode = createLucideIcon("file-code", __iconNode$1u);
55644
55616
 
55645
55617
  /**
55646
55618
  * @license lucide-react v0.528.0 - ISC
@@ -55650,13 +55622,13 @@ const FileCode = createLucideIcon("file-code", __iconNode$1t);
55650
55622
  */
55651
55623
 
55652
55624
 
55653
- const __iconNode$1s = [
55625
+ const __iconNode$1t = [
55654
55626
  ["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z", key: "1rqfz7" }],
55655
55627
  ["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }],
55656
55628
  ["path", { d: "M12 18v-6", key: "17g6i2" }],
55657
55629
  ["path", { d: "m9 15 3 3 3-3", key: "1npd3o" }]
55658
55630
  ];
55659
- const FileDown = createLucideIcon("file-down", __iconNode$1s);
55631
+ const FileDown = createLucideIcon("file-down", __iconNode$1t);
55660
55632
 
55661
55633
  /**
55662
55634
  * @license lucide-react v0.528.0 - ISC
@@ -55666,13 +55638,13 @@ const FileDown = createLucideIcon("file-down", __iconNode$1s);
55666
55638
  */
55667
55639
 
55668
55640
 
55669
- const __iconNode$1r = [
55641
+ const __iconNode$1s = [
55670
55642
  ["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z", key: "1rqfz7" }],
55671
55643
  ["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }],
55672
55644
  ["circle", { cx: "10", cy: "12", r: "2", key: "737tya" }],
55673
55645
  ["path", { d: "m20 17-1.296-1.296a2.41 2.41 0 0 0-3.408 0L9 22", key: "wt3hpn" }]
55674
55646
  ];
55675
- const FileImage = createLucideIcon("file-image", __iconNode$1r);
55647
+ const FileImage = createLucideIcon("file-image", __iconNode$1s);
55676
55648
 
55677
55649
  /**
55678
55650
  * @license lucide-react v0.528.0 - ISC
@@ -55682,7 +55654,7 @@ const FileImage = createLucideIcon("file-image", __iconNode$1r);
55682
55654
  */
55683
55655
 
55684
55656
 
55685
- const __iconNode$1q = [
55657
+ const __iconNode$1r = [
55686
55658
  ["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }],
55687
55659
  ["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z", key: "1mlx9k" }],
55688
55660
  [
@@ -55693,7 +55665,7 @@ const __iconNode$1q = [
55693
55665
  }
55694
55666
  ]
55695
55667
  ];
55696
- const FilePlay = createLucideIcon("file-play", __iconNode$1q);
55668
+ const FilePlay = createLucideIcon("file-play", __iconNode$1r);
55697
55669
 
55698
55670
  /**
55699
55671
  * @license lucide-react v0.528.0 - ISC
@@ -55703,7 +55675,7 @@ const FilePlay = createLucideIcon("file-play", __iconNode$1q);
55703
55675
  */
55704
55676
 
55705
55677
 
55706
- const __iconNode$1p = [
55678
+ const __iconNode$1q = [
55707
55679
  ["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z", key: "1rqfz7" }],
55708
55680
  ["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }],
55709
55681
  ["path", { d: "M8 13h2", key: "yr2amv" }],
@@ -55711,7 +55683,7 @@ const __iconNode$1p = [
55711
55683
  ["path", { d: "M8 17h2", key: "2yhykz" }],
55712
55684
  ["path", { d: "M14 17h2", key: "10kma7" }]
55713
55685
  ];
55714
- const FileSpreadsheet = createLucideIcon("file-spreadsheet", __iconNode$1p);
55686
+ const FileSpreadsheet = createLucideIcon("file-spreadsheet", __iconNode$1q);
55715
55687
 
55716
55688
  /**
55717
55689
  * @license lucide-react v0.528.0 - ISC
@@ -55721,14 +55693,14 @@ const FileSpreadsheet = createLucideIcon("file-spreadsheet", __iconNode$1p);
55721
55693
  */
55722
55694
 
55723
55695
 
55724
- const __iconNode$1o = [
55696
+ const __iconNode$1p = [
55725
55697
  ["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z", key: "1rqfz7" }],
55726
55698
  ["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }],
55727
55699
  ["path", { d: "M10 9H8", key: "b1mrlr" }],
55728
55700
  ["path", { d: "M16 13H8", key: "t4e002" }],
55729
55701
  ["path", { d: "M16 17H8", key: "z1uh3a" }]
55730
55702
  ];
55731
- const FileText = createLucideIcon("file-text", __iconNode$1o);
55703
+ const FileText = createLucideIcon("file-text", __iconNode$1p);
55732
55704
 
55733
55705
  /**
55734
55706
  * @license lucide-react v0.528.0 - ISC
@@ -55738,11 +55710,11 @@ const FileText = createLucideIcon("file-text", __iconNode$1o);
55738
55710
  */
55739
55711
 
55740
55712
 
55741
- const __iconNode$1n = [
55713
+ const __iconNode$1o = [
55742
55714
  ["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z", key: "1rqfz7" }],
55743
55715
  ["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }]
55744
55716
  ];
55745
- const File$1 = createLucideIcon("file", __iconNode$1n);
55717
+ const File$1 = createLucideIcon("file", __iconNode$1o);
55746
55718
 
55747
55719
  /**
55748
55720
  * @license lucide-react v0.528.0 - ISC
@@ -55752,7 +55724,7 @@ const File$1 = createLucideIcon("file", __iconNode$1n);
55752
55724
  */
55753
55725
 
55754
55726
 
55755
- const __iconNode$1m = [
55727
+ const __iconNode$1n = [
55756
55728
  [
55757
55729
  "path",
55758
55730
  {
@@ -55770,7 +55742,7 @@ const __iconNode$1m = [
55770
55742
  ["path", { d: "M3 5a2 2 0 0 0 2 2h3", key: "f2jnh7" }],
55771
55743
  ["path", { d: "M3 3v13a2 2 0 0 0 2 2h3", key: "k8epm1" }]
55772
55744
  ];
55773
- const FolderTree = createLucideIcon("folder-tree", __iconNode$1m);
55745
+ const FolderTree = createLucideIcon("folder-tree", __iconNode$1n);
55774
55746
 
55775
55747
  /**
55776
55748
  * @license lucide-react v0.528.0 - ISC
@@ -55780,14 +55752,14 @@ const FolderTree = createLucideIcon("folder-tree", __iconNode$1m);
55780
55752
  */
55781
55753
 
55782
55754
 
55783
- const __iconNode$1l = [
55755
+ const __iconNode$1m = [
55784
55756
  ["path", { d: "m14.5 12.5-8 8a2.119 2.119 0 1 1-3-3l8-8", key: "15492f" }],
55785
55757
  ["path", { d: "m16 16 6-6", key: "vzrcl6" }],
55786
55758
  ["path", { d: "m8 8 6-6", key: "18bi4p" }],
55787
55759
  ["path", { d: "m9 7 8 8", key: "5jnvq1" }],
55788
55760
  ["path", { d: "m21 11-8-8", key: "z4y7zo" }]
55789
55761
  ];
55790
- const Gavel = createLucideIcon("gavel", __iconNode$1l);
55762
+ const Gavel = createLucideIcon("gavel", __iconNode$1m);
55791
55763
 
55792
55764
  /**
55793
55765
  * @license lucide-react v0.528.0 - ISC
@@ -55797,13 +55769,13 @@ const Gavel = createLucideIcon("gavel", __iconNode$1l);
55797
55769
  */
55798
55770
 
55799
55771
 
55800
- const __iconNode$1k = [
55772
+ const __iconNode$1l = [
55801
55773
  ["line", { x1: "6", x2: "6", y1: "3", y2: "15", key: "17qcm7" }],
55802
55774
  ["circle", { cx: "18", cy: "6", r: "3", key: "1h7g24" }],
55803
55775
  ["circle", { cx: "6", cy: "18", r: "3", key: "fqmcym" }],
55804
55776
  ["path", { d: "M18 9a9 9 0 0 1-9 9", key: "n2h4wq" }]
55805
55777
  ];
55806
- const GitBranch = createLucideIcon("git-branch", __iconNode$1k);
55778
+ const GitBranch = createLucideIcon("git-branch", __iconNode$1l);
55807
55779
 
55808
55780
  /**
55809
55781
  * @license lucide-react v0.528.0 - ISC
@@ -55813,12 +55785,12 @@ const GitBranch = createLucideIcon("git-branch", __iconNode$1k);
55813
55785
  */
55814
55786
 
55815
55787
 
55816
- const __iconNode$1j = [
55788
+ const __iconNode$1k = [
55817
55789
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
55818
55790
  ["path", { d: "M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20", key: "13o1zl" }],
55819
55791
  ["path", { d: "M2 12h20", key: "9i4pu4" }]
55820
55792
  ];
55821
- const Globe = createLucideIcon("globe", __iconNode$1j);
55793
+ const Globe = createLucideIcon("globe", __iconNode$1k);
55822
55794
 
55823
55795
  /**
55824
55796
  * @license lucide-react v0.528.0 - ISC
@@ -55828,7 +55800,7 @@ const Globe = createLucideIcon("globe", __iconNode$1j);
55828
55800
  */
55829
55801
 
55830
55802
 
55831
- const __iconNode$1i = [
55803
+ const __iconNode$1j = [
55832
55804
  [
55833
55805
  "path",
55834
55806
  {
@@ -55839,7 +55811,7 @@ const __iconNode$1i = [
55839
55811
  ["path", { d: "M22 10v6", key: "1lu8f3" }],
55840
55812
  ["path", { d: "M6 12.5V16a6 3 0 0 0 12 0v-3.5", key: "1r8lef" }]
55841
55813
  ];
55842
- const GraduationCap = createLucideIcon("graduation-cap", __iconNode$1i);
55814
+ const GraduationCap = createLucideIcon("graduation-cap", __iconNode$1j);
55843
55815
 
55844
55816
  /**
55845
55817
  * @license lucide-react v0.528.0 - ISC
@@ -55849,7 +55821,7 @@ const GraduationCap = createLucideIcon("graduation-cap", __iconNode$1i);
55849
55821
  */
55850
55822
 
55851
55823
 
55852
- const __iconNode$1h = [
55824
+ const __iconNode$1i = [
55853
55825
  ["path", { d: "M14 18a2 2 0 0 0-4 0", key: "1v8fkw" }],
55854
55826
  [
55855
55827
  "path",
@@ -55862,7 +55834,7 @@ const __iconNode$1h = [
55862
55834
  ["circle", { cx: "17", cy: "18", r: "3", key: "82mm0e" }],
55863
55835
  ["circle", { cx: "7", cy: "18", r: "3", key: "lvkj7j" }]
55864
55836
  ];
55865
- const HatGlasses = createLucideIcon("hat-glasses", __iconNode$1h);
55837
+ const HatGlasses = createLucideIcon("hat-glasses", __iconNode$1i);
55866
55838
 
55867
55839
  /**
55868
55840
  * @license lucide-react v0.528.0 - ISC
@@ -55872,13 +55844,13 @@ const HatGlasses = createLucideIcon("hat-glasses", __iconNode$1h);
55872
55844
  */
55873
55845
 
55874
55846
 
55875
- const __iconNode$1g = [
55847
+ const __iconNode$1h = [
55876
55848
  ["path", { d: "M4 12h8", key: "17cfdx" }],
55877
55849
  ["path", { d: "M4 18V6", key: "1rz3zl" }],
55878
55850
  ["path", { d: "M12 18V6", key: "zqpxq5" }],
55879
55851
  ["path", { d: "m17 12 3-2v8", key: "1hhhft" }]
55880
55852
  ];
55881
- const Heading1 = createLucideIcon("heading-1", __iconNode$1g);
55853
+ const Heading1 = createLucideIcon("heading-1", __iconNode$1h);
55882
55854
 
55883
55855
  /**
55884
55856
  * @license lucide-react v0.528.0 - ISC
@@ -55888,13 +55860,13 @@ const Heading1 = createLucideIcon("heading-1", __iconNode$1g);
55888
55860
  */
55889
55861
 
55890
55862
 
55891
- const __iconNode$1f = [
55863
+ const __iconNode$1g = [
55892
55864
  ["path", { d: "M4 12h8", key: "17cfdx" }],
55893
55865
  ["path", { d: "M4 18V6", key: "1rz3zl" }],
55894
55866
  ["path", { d: "M12 18V6", key: "zqpxq5" }],
55895
55867
  ["path", { d: "M21 18h-4c0-4 4-3 4-6 0-1.5-2-2.5-4-1", key: "9jr5yi" }]
55896
55868
  ];
55897
- const Heading2 = createLucideIcon("heading-2", __iconNode$1f);
55869
+ const Heading2 = createLucideIcon("heading-2", __iconNode$1g);
55898
55870
 
55899
55871
  /**
55900
55872
  * @license lucide-react v0.528.0 - ISC
@@ -55904,14 +55876,14 @@ const Heading2 = createLucideIcon("heading-2", __iconNode$1f);
55904
55876
  */
55905
55877
 
55906
55878
 
55907
- const __iconNode$1e = [
55879
+ const __iconNode$1f = [
55908
55880
  ["path", { d: "M4 12h8", key: "17cfdx" }],
55909
55881
  ["path", { d: "M4 18V6", key: "1rz3zl" }],
55910
55882
  ["path", { d: "M12 18V6", key: "zqpxq5" }],
55911
55883
  ["path", { d: "M17.5 10.5c1.7-1 3.5 0 3.5 1.5a2 2 0 0 1-2 2", key: "68ncm8" }],
55912
55884
  ["path", { d: "M17 17.5c2 1.5 4 .3 4-1.5a2 2 0 0 0-2-2", key: "1ejuhz" }]
55913
55885
  ];
55914
- const Heading3 = createLucideIcon("heading-3", __iconNode$1e);
55886
+ const Heading3 = createLucideIcon("heading-3", __iconNode$1f);
55915
55887
 
55916
55888
  /**
55917
55889
  * @license lucide-react v0.528.0 - ISC
@@ -55921,12 +55893,12 @@ const Heading3 = createLucideIcon("heading-3", __iconNode$1e);
55921
55893
  */
55922
55894
 
55923
55895
 
55924
- const __iconNode$1d = [
55896
+ const __iconNode$1e = [
55925
55897
  ["path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8", key: "1357e3" }],
55926
55898
  ["path", { d: "M3 3v5h5", key: "1xhq8a" }],
55927
55899
  ["path", { d: "M12 7v5l4 2", key: "1fdv2h" }]
55928
55900
  ];
55929
- const History = createLucideIcon("history", __iconNode$1d);
55901
+ const History = createLucideIcon("history", __iconNode$1e);
55930
55902
 
55931
55903
  /**
55932
55904
  * @license lucide-react v0.528.0 - ISC
@@ -55936,12 +55908,12 @@ const History = createLucideIcon("history", __iconNode$1d);
55936
55908
  */
55937
55909
 
55938
55910
 
55939
- const __iconNode$1c = [
55911
+ const __iconNode$1d = [
55940
55912
  ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2", key: "1m3agn" }],
55941
55913
  ["circle", { cx: "9", cy: "9", r: "2", key: "af1f0g" }],
55942
55914
  ["path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21", key: "1xmnt7" }]
55943
55915
  ];
55944
- const Image$3 = createLucideIcon("image", __iconNode$1c);
55916
+ const Image$3 = createLucideIcon("image", __iconNode$1d);
55945
55917
 
55946
55918
  /**
55947
55919
  * @license lucide-react v0.528.0 - ISC
@@ -55951,7 +55923,7 @@ const Image$3 = createLucideIcon("image", __iconNode$1c);
55951
55923
  */
55952
55924
 
55953
55925
 
55954
- const __iconNode$1b = [
55926
+ const __iconNode$1c = [
55955
55927
  ["polyline", { points: "22 12 16 12 14 15 10 15 8 12 2 12", key: "o97t9d" }],
55956
55928
  [
55957
55929
  "path",
@@ -55961,7 +55933,7 @@ const __iconNode$1b = [
55961
55933
  }
55962
55934
  ]
55963
55935
  ];
55964
- const Inbox = createLucideIcon("inbox", __iconNode$1b);
55936
+ const Inbox = createLucideIcon("inbox", __iconNode$1c);
55965
55937
 
55966
55938
  /**
55967
55939
  * @license lucide-react v0.528.0 - ISC
@@ -55971,12 +55943,12 @@ const Inbox = createLucideIcon("inbox", __iconNode$1b);
55971
55943
  */
55972
55944
 
55973
55945
 
55974
- const __iconNode$1a = [
55946
+ const __iconNode$1b = [
55975
55947
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
55976
55948
  ["path", { d: "M12 16v-4", key: "1dtifu" }],
55977
55949
  ["path", { d: "M12 8h.01", key: "e9boi3" }]
55978
55950
  ];
55979
- const Info$3 = createLucideIcon("info", __iconNode$1a);
55951
+ const Info$3 = createLucideIcon("info", __iconNode$1b);
55980
55952
 
55981
55953
  /**
55982
55954
  * @license lucide-react v0.528.0 - ISC
@@ -55986,12 +55958,12 @@ const Info$3 = createLucideIcon("info", __iconNode$1a);
55986
55958
  */
55987
55959
 
55988
55960
 
55989
- const __iconNode$19 = [
55961
+ const __iconNode$1a = [
55990
55962
  ["line", { x1: "19", x2: "10", y1: "4", y2: "4", key: "15jd3p" }],
55991
55963
  ["line", { x1: "14", x2: "5", y1: "20", y2: "20", key: "bu0au3" }],
55992
55964
  ["line", { x1: "15", x2: "9", y1: "4", y2: "20", key: "uljnxc" }]
55993
55965
  ];
55994
- const Italic$1 = createLucideIcon("italic", __iconNode$19);
55966
+ const Italic$1 = createLucideIcon("italic", __iconNode$1a);
55995
55967
 
55996
55968
  /**
55997
55969
  * @license lucide-react v0.528.0 - ISC
@@ -56001,7 +55973,7 @@ const Italic$1 = createLucideIcon("italic", __iconNode$19);
56001
55973
  */
56002
55974
 
56003
55975
 
56004
- const __iconNode$18 = [
55976
+ const __iconNode$19 = [
56005
55977
  [
56006
55978
  "path",
56007
55979
  {
@@ -56011,7 +55983,7 @@ const __iconNode$18 = [
56011
55983
  ],
56012
55984
  ["circle", { cx: "16.5", cy: "7.5", r: ".5", fill: "currentColor", key: "w0ekpg" }]
56013
55985
  ];
56014
- const KeyRound = createLucideIcon("key-round", __iconNode$18);
55986
+ const KeyRound = createLucideIcon("key-round", __iconNode$19);
56015
55987
 
56016
55988
  /**
56017
55989
  * @license lucide-react v0.528.0 - ISC
@@ -56021,7 +55993,7 @@ const KeyRound = createLucideIcon("key-round", __iconNode$18);
56021
55993
  */
56022
55994
 
56023
55995
 
56024
- const __iconNode$17 = [
55996
+ const __iconNode$18 = [
56025
55997
  ["path", { d: "M10 18v-7", key: "wt116b" }],
56026
55998
  [
56027
55999
  "path",
@@ -56035,7 +56007,7 @@ const __iconNode$17 = [
56035
56007
  ["path", { d: "M3 22h18", key: "8prr45" }],
56036
56008
  ["path", { d: "M6 18v-7", key: "1ivflk" }]
56037
56009
  ];
56038
- const Landmark = createLucideIcon("landmark", __iconNode$17);
56010
+ const Landmark = createLucideIcon("landmark", __iconNode$18);
56039
56011
 
56040
56012
  /**
56041
56013
  * @license lucide-react v0.528.0 - ISC
@@ -56045,7 +56017,7 @@ const Landmark = createLucideIcon("landmark", __iconNode$17);
56045
56017
  */
56046
56018
 
56047
56019
 
56048
- const __iconNode$16 = [
56020
+ const __iconNode$17 = [
56049
56021
  [
56050
56022
  "path",
56051
56023
  {
@@ -56068,7 +56040,7 @@ const __iconNode$16 = [
56068
56040
  }
56069
56041
  ]
56070
56042
  ];
56071
- const Layers = createLucideIcon("layers", __iconNode$16);
56043
+ const Layers = createLucideIcon("layers", __iconNode$17);
56072
56044
 
56073
56045
  /**
56074
56046
  * @license lucide-react v0.528.0 - ISC
@@ -56078,12 +56050,12 @@ const Layers = createLucideIcon("layers", __iconNode$16);
56078
56050
  */
56079
56051
 
56080
56052
 
56081
- const __iconNode$15 = [
56053
+ const __iconNode$16 = [
56082
56054
  ["path", { d: "M9 17H7A5 5 0 0 1 7 7h2", key: "8i5ue5" }],
56083
56055
  ["path", { d: "M15 7h2a5 5 0 1 1 0 10h-2", key: "1b9ql8" }],
56084
56056
  ["line", { x1: "8", x2: "16", y1: "12", y2: "12", key: "1jonct" }]
56085
56057
  ];
56086
- const Link2 = createLucideIcon("link-2", __iconNode$15);
56058
+ const Link2 = createLucideIcon("link-2", __iconNode$16);
56087
56059
 
56088
56060
  /**
56089
56061
  * @license lucide-react v0.528.0 - ISC
@@ -56093,11 +56065,11 @@ const Link2 = createLucideIcon("link-2", __iconNode$15);
56093
56065
  */
56094
56066
 
56095
56067
 
56096
- const __iconNode$14 = [
56068
+ const __iconNode$15 = [
56097
56069
  ["path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71", key: "1cjeqo" }],
56098
56070
  ["path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71", key: "19qd67" }]
56099
56071
  ];
56100
- const Link$1 = createLucideIcon("link", __iconNode$14);
56072
+ const Link$1 = createLucideIcon("link", __iconNode$15);
56101
56073
 
56102
56074
  /**
56103
56075
  * @license lucide-react v0.528.0 - ISC
@@ -56107,7 +56079,7 @@ const Link$1 = createLucideIcon("link", __iconNode$14);
56107
56079
  */
56108
56080
 
56109
56081
 
56110
- const __iconNode$13 = [
56082
+ const __iconNode$14 = [
56111
56083
  ["path", { d: "M10 12h11", key: "6m4ad9" }],
56112
56084
  ["path", { d: "M10 18h11", key: "11hvi2" }],
56113
56085
  ["path", { d: "M10 6h11", key: "c7qv1k" }],
@@ -56115,7 +56087,7 @@ const __iconNode$13 = [
56115
56087
  ["path", { d: "M4 6h1v4", key: "cnovpq" }],
56116
56088
  ["path", { d: "M6 18H4c0-1 2-2 2-3s-1-1.5-2-1", key: "m9a95d" }]
56117
56089
  ];
56118
- const ListOrdered = createLucideIcon("list-ordered", __iconNode$13);
56090
+ const ListOrdered = createLucideIcon("list-ordered", __iconNode$14);
56119
56091
 
56120
56092
  /**
56121
56093
  * @license lucide-react v0.528.0 - ISC
@@ -56125,7 +56097,7 @@ const ListOrdered = createLucideIcon("list-ordered", __iconNode$13);
56125
56097
  */
56126
56098
 
56127
56099
 
56128
- const __iconNode$12 = [
56100
+ const __iconNode$13 = [
56129
56101
  ["path", { d: "M3 12h.01", key: "nlz23k" }],
56130
56102
  ["path", { d: "M3 18h.01", key: "1tta3j" }],
56131
56103
  ["path", { d: "M3 6h.01", key: "1rqtza" }],
@@ -56133,7 +56105,7 @@ const __iconNode$12 = [
56133
56105
  ["path", { d: "M8 18h13", key: "1lx6n3" }],
56134
56106
  ["path", { d: "M8 6h13", key: "ik3vkj" }]
56135
56107
  ];
56136
- const List$1 = createLucideIcon("list", __iconNode$12);
56108
+ const List$1 = createLucideIcon("list", __iconNode$13);
56137
56109
 
56138
56110
  /**
56139
56111
  * @license lucide-react v0.528.0 - ISC
@@ -56143,8 +56115,8 @@ const List$1 = createLucideIcon("list", __iconNode$12);
56143
56115
  */
56144
56116
 
56145
56117
 
56146
- const __iconNode$11 = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
56147
- const LoaderCircle = createLucideIcon("loader-circle", __iconNode$11);
56118
+ const __iconNode$12 = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
56119
+ const LoaderCircle = createLucideIcon("loader-circle", __iconNode$12);
56148
56120
 
56149
56121
  /**
56150
56122
  * @license lucide-react v0.528.0 - ISC
@@ -56154,11 +56126,11 @@ const LoaderCircle = createLucideIcon("loader-circle", __iconNode$11);
56154
56126
  */
56155
56127
 
56156
56128
 
56157
- const __iconNode$10 = [
56129
+ const __iconNode$11 = [
56158
56130
  ["rect", { width: "18", height: "11", x: "3", y: "11", rx: "2", ry: "2", key: "1w4ew1" }],
56159
56131
  ["path", { d: "M7 11V7a5 5 0 0 1 10 0v4", key: "fwvmzm" }]
56160
56132
  ];
56161
- const Lock = createLucideIcon("lock", __iconNode$10);
56133
+ const Lock = createLucideIcon("lock", __iconNode$11);
56162
56134
 
56163
56135
  /**
56164
56136
  * @license lucide-react v0.528.0 - ISC
@@ -56168,11 +56140,11 @@ const Lock = createLucideIcon("lock", __iconNode$10);
56168
56140
  */
56169
56141
 
56170
56142
 
56171
- const __iconNode$$ = [
56143
+ const __iconNode$10 = [
56172
56144
  ["path", { d: "m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7", key: "132q7q" }],
56173
56145
  ["rect", { x: "2", y: "4", width: "20", height: "16", rx: "2", key: "izxlao" }]
56174
56146
  ];
56175
- const Mail = createLucideIcon("mail", __iconNode$$);
56147
+ const Mail = createLucideIcon("mail", __iconNode$10);
56176
56148
 
56177
56149
  /**
56178
56150
  * @license lucide-react v0.528.0 - ISC
@@ -56182,10 +56154,10 @@ const Mail = createLucideIcon("mail", __iconNode$$);
56182
56154
  */
56183
56155
 
56184
56156
 
56185
- const __iconNode$_ = [
56157
+ const __iconNode$$ = [
56186
56158
  ["path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z", key: "1lielz" }]
56187
56159
  ];
56188
- const MessageSquare = createLucideIcon("message-square", __iconNode$_);
56160
+ const MessageSquare = createLucideIcon("message-square", __iconNode$$);
56189
56161
 
56190
56162
  /**
56191
56163
  * @license lucide-react v0.528.0 - ISC
@@ -56195,12 +56167,27 @@ const MessageSquare = createLucideIcon("message-square", __iconNode$_);
56195
56167
  */
56196
56168
 
56197
56169
 
56198
- const __iconNode$Z = [
56170
+ const __iconNode$_ = [
56199
56171
  ["path", { d: "M12 19v3", key: "npa21l" }],
56200
56172
  ["path", { d: "M19 10v2a7 7 0 0 1-14 0v-2", key: "1vc78b" }],
56201
56173
  ["rect", { x: "9", y: "2", width: "6", height: "13", rx: "3", key: "s6n7sd" }]
56202
56174
  ];
56203
- const Mic = createLucideIcon("mic", __iconNode$Z);
56175
+ const Mic = createLucideIcon("mic", __iconNode$_);
56176
+
56177
+ /**
56178
+ * @license lucide-react v0.528.0 - ISC
56179
+ *
56180
+ * This source code is licensed under the ISC license.
56181
+ * See the LICENSE file in the root directory of this source tree.
56182
+ */
56183
+
56184
+
56185
+ const __iconNode$Z = [
56186
+ ["rect", { width: "20", height: "14", x: "2", y: "3", rx: "2", key: "48i651" }],
56187
+ ["line", { x1: "8", x2: "16", y1: "21", y2: "21", key: "1svkeh" }],
56188
+ ["line", { x1: "12", x2: "12", y1: "17", y2: "21", key: "vw1qmm" }]
56189
+ ];
56190
+ const Monitor = createLucideIcon("monitor", __iconNode$Z);
56204
56191
 
56205
56192
  /**
56206
56193
  * @license lucide-react v0.528.0 - ISC
@@ -61024,6 +61011,118 @@ var gradebookGradebookTab$3 = {
61024
61011
  previousPage: "Previous",
61025
61012
  nextPage: "Next"
61026
61013
  };
61014
+ var graderTabLabels$3 = {
61015
+ header: {
61016
+ title: "Grader",
61017
+ description: "Set up how your agent grades work against a rubric you define."
61018
+ },
61019
+ capability: {
61020
+ title: "Grading",
61021
+ description: "Let your agent grade work. When this is on, the agent scores what people submit against the rubric you set up below and shares the result as feedback — great for essays, projects, and practice exercises.",
61022
+ offHint: "Turn it on to write grading instructions and build your rubric. Anything you set up here is kept safe if you later turn it off."
61023
+ },
61024
+ subTabs: {
61025
+ setup: "Grading setup",
61026
+ rubric: "Rubric"
61027
+ },
61028
+ denied: {
61029
+ title: "No access to grading settings",
61030
+ description: "You don't have permission to view this agent's grading setup. Ask an administrator for access."
61031
+ },
61032
+ warnings: {
61033
+ noConfig: "Grading is on but not set up yet — the agent will fail when asked to grade. Save your grading instructions in Grading setup to finish.",
61034
+ noCriteria: "Grading is on but the rubric is empty — the agent will fail when asked to grade. Add at least one criterion in the Rubric tab."
61035
+ },
61036
+ config: {
61037
+ sectionTitle: "Grading setup",
61038
+ gradingMode: {
61039
+ label: "What gets graded",
61040
+ options: {
61041
+ submission: "A submission",
61042
+ conversation: "The conversation"
61043
+ },
61044
+ help: {
61045
+ submission: "The agent grades a piece of work the person hands in, like an essay or answer.",
61046
+ conversation: "The agent grades how the whole conversation went."
61047
+ }
61048
+ },
61049
+ feedbackMode: {
61050
+ label: "Feedback shared with the person",
61051
+ options: {
61052
+ overall: "Overall feedback only",
61053
+ perCriteria: "Feedback per criterion",
61054
+ both: "Overall + per criterion"
61055
+ },
61056
+ help: "The overall score is always calculated — this only controls how much detail is shared back."
61057
+ },
61058
+ instructions: {
61059
+ label: "Grading instructions",
61060
+ placeholder: "Describe what's being graded and anything the grader should know beyond the rubric. E.g. 'You are grading a 500-word persuasive essay on climate policy written by a high-school student. Be encouraging but honest.'",
61061
+ help: "Required. This is the context the agent uses every time it grades."
61062
+ },
61063
+ saveButton: "Save",
61064
+ savingButton: "Saving…"
61065
+ },
61066
+ criteria: {
61067
+ sectionTitle: "Rubric",
61068
+ description: "Each row is one thing the agent looks for and how many points it is worth. The overall score is points earned out of the total.",
61069
+ needsConfigHint: "Save your grading setup first, then add rubric criteria here.",
61070
+ emptyState: "No criteria yet. Add your first one — for example \"Clarity\", 10 points.",
61071
+ addButton: "Add criterion",
61072
+ columns: {
61073
+ name: "Name",
61074
+ criteria: "Criteria",
61075
+ points: "Points"
61076
+ },
61077
+ actionsAria: "Actions for {name}",
61078
+ edit: "Edit",
61079
+ "delete": "Delete",
61080
+ totalPoints: "Total possible points: {total}",
61081
+ scoreHint: "Overall score = points earned ÷ {total}.",
61082
+ lastCriterionHint: "A rubric needs at least one criterion — add another before removing this one.",
61083
+ modal: {
61084
+ addTitle: "Add criterion",
61085
+ editTitle: "Edit criterion",
61086
+ name: {
61087
+ label: "Name",
61088
+ placeholder: "e.g. Clarity",
61089
+ required: "Name is required"
61090
+ },
61091
+ criteria: {
61092
+ label: "Criteria",
61093
+ placeholder: "e.g. The argument is easy to follow and each paragraph makes one clear point.",
61094
+ required: "Criteria is required"
61095
+ },
61096
+ points: {
61097
+ label: "Points",
61098
+ placeholder: "10",
61099
+ positive: "Points must be a positive number"
61100
+ },
61101
+ save: "Save",
61102
+ saving: "Saving…",
61103
+ cancel: "Cancel"
61104
+ },
61105
+ deleteModal: {
61106
+ title: "Delete criterion",
61107
+ confirmationPrefix: "Are you sure you want to remove",
61108
+ confirmationSuffix: " from the rubric?",
61109
+ cancel: "Cancel",
61110
+ "delete": "Delete",
61111
+ deleting: "Deleting…"
61112
+ }
61113
+ },
61114
+ toasts: {
61115
+ toggleOn: "Grading turned on",
61116
+ toggleOff: "Grading turned off — your rubric is kept for next time",
61117
+ toggleError: "Couldn't update grading",
61118
+ configSaved: "Grading setup saved",
61119
+ configError: "Couldn't save grading setup",
61120
+ criterionAdded: "Criterion added",
61121
+ criterionUpdated: "Criterion updated",
61122
+ criterionDeleted: "Criterion deleted",
61123
+ criterionError: "Couldn't update the rubric"
61124
+ }
61125
+ };
61027
61126
  var careerExperienceDialog$3 = {
61028
61127
  pleaseSelectACompany: "Please select a company",
61029
61128
  endDateCannotBeBeforeStartDate: "End date cannot be before start date",
@@ -61177,6 +61276,9 @@ var chatInputFormInsideButtons$3 = {
61177
61276
  studyMode: "Study Mode",
61178
61277
  deepResearch: "Deep Research",
61179
61278
  memory: "Memory",
61279
+ cowork: "Cowork",
61280
+ coworkNeedsBackend: "Enable a large local model or sign in to a workspace to use Cowork.",
61281
+ coworkModelTooSmall: "Your local model is too small for Cowork. Pick a model of at least 14GB in Local Models.",
61180
61282
  moreOptions: "More options"
61181
61283
  };
61182
61284
  var chatInputFormMemoryMenu$3 = {
@@ -65588,6 +65690,7 @@ var en = {
65588
65690
  careerEducationDialog: careerEducationDialog$3,
65589
65691
  careerEducationTab: careerEducationTab$3,
65590
65692
  gradebookGradebookTab: gradebookGradebookTab$3,
65693
+ graderTabLabels: graderTabLabels$3,
65591
65694
  careerExperienceDialog: careerExperienceDialog$3,
65592
65695
  careerExperienceTab: careerExperienceTab$3,
65593
65696
  careerInstitutionDialog: careerInstitutionDialog$3,
@@ -67029,6 +67132,118 @@ var gradebookGradebookTab$2 = {
67029
67132
  previousPage: "Précédent",
67030
67133
  nextPage: "Suivant"
67031
67134
  };
67135
+ var graderTabLabels$2 = {
67136
+ header: {
67137
+ title: "Évaluateur",
67138
+ description: "Configurez la façon dont votre agent note le travail selon une grille que vous définissez."
67139
+ },
67140
+ capability: {
67141
+ title: "Notation",
67142
+ description: "Laissez votre agent noter le travail. Lorsque cette option est activée, l'agent évalue ce que les personnes soumettent selon la grille que vous configurez ci-dessous et partage le résultat sous forme de retour — idéal pour les dissertations, projets et exercices d'entraînement.",
67143
+ offHint: "Activez-la pour rédiger des consignes de notation et construire votre grille. Tout ce que vous configurez ici est conservé si vous la désactivez plus tard."
67144
+ },
67145
+ subTabs: {
67146
+ setup: "Configuration de la notation",
67147
+ rubric: "Grille d'évaluation"
67148
+ },
67149
+ denied: {
67150
+ title: "Pas d'accès aux paramètres de notation",
67151
+ description: "Vous n'avez pas la permission de voir la configuration de notation de cet agent. Demandez l'accès à un administrateur."
67152
+ },
67153
+ warnings: {
67154
+ noConfig: "La notation est activée mais pas encore configurée — l'agent échouera lorsqu'on lui demandera de noter. Enregistrez vos consignes dans Configuration de la notation pour terminer.",
67155
+ noCriteria: "La notation est activée mais la grille est vide — l'agent échouera lorsqu'on lui demandera de noter. Ajoutez au moins un critère dans l'onglet Grille d'évaluation."
67156
+ },
67157
+ config: {
67158
+ sectionTitle: "Configuration de la notation",
67159
+ gradingMode: {
67160
+ label: "Ce qui est noté",
67161
+ options: {
67162
+ submission: "Un travail remis",
67163
+ conversation: "La conversation"
67164
+ },
67165
+ help: {
67166
+ submission: "L'agent note un travail remis par la personne, comme une dissertation ou une réponse.",
67167
+ conversation: "L'agent note le déroulement de toute la conversation."
67168
+ }
67169
+ },
67170
+ feedbackMode: {
67171
+ label: "Retour partagé avec la personne",
67172
+ options: {
67173
+ overall: "Retour global uniquement",
67174
+ perCriteria: "Retour par critère",
67175
+ both: "Global + par critère"
67176
+ },
67177
+ help: "La note globale est toujours calculée — ceci contrôle seulement le niveau de détail partagé."
67178
+ },
67179
+ instructions: {
67180
+ label: "Consignes de notation",
67181
+ placeholder: "Décrivez ce qui est noté et tout ce que l'évaluateur doit savoir au-delà de la grille. Par ex. 'Vous notez une dissertation persuasive de 500 mots sur la politique climatique écrite par un lycéen. Soyez encourageant mais honnête.'",
67182
+ help: "Obligatoire. C'est le contexte que l'agent utilise à chaque notation."
67183
+ },
67184
+ saveButton: "Enregistrer",
67185
+ savingButton: "Enregistrement…"
67186
+ },
67187
+ criteria: {
67188
+ sectionTitle: "Grille d'évaluation",
67189
+ description: "Chaque ligne est un élément que l'agent recherche et le nombre de points qu'il vaut. La note globale correspond aux points obtenus sur le total.",
67190
+ needsConfigHint: "Enregistrez d'abord votre configuration de notation, puis ajoutez des critères ici.",
67191
+ emptyState: "Aucun critère pour l'instant. Ajoutez le premier — par exemple \"Clarté\", 10 points.",
67192
+ addButton: "Ajouter un critère",
67193
+ columns: {
67194
+ name: "Nom",
67195
+ criteria: "Critères",
67196
+ points: "Points"
67197
+ },
67198
+ actionsAria: "Actions pour {name}",
67199
+ edit: "Modifier",
67200
+ "delete": "Supprimer",
67201
+ totalPoints: "Total de points possibles : {total}",
67202
+ scoreHint: "Note globale = points obtenus ÷ {total}.",
67203
+ lastCriterionHint: "Une grille doit contenir au moins un critère — ajoutez-en un autre avant de supprimer celui-ci.",
67204
+ modal: {
67205
+ addTitle: "Ajouter un critère",
67206
+ editTitle: "Modifier le critère",
67207
+ name: {
67208
+ label: "Nom",
67209
+ placeholder: "par ex. Clarté",
67210
+ required: "Le nom est obligatoire"
67211
+ },
67212
+ criteria: {
67213
+ label: "Critères",
67214
+ placeholder: "par ex. L'argumentation est facile à suivre et chaque paragraphe avance une idée claire.",
67215
+ required: "Les critères sont obligatoires"
67216
+ },
67217
+ points: {
67218
+ label: "Points",
67219
+ placeholder: "10",
67220
+ positive: "Les points doivent être un nombre positif"
67221
+ },
67222
+ save: "Enregistrer",
67223
+ saving: "Enregistrement…",
67224
+ cancel: "Annuler"
67225
+ },
67226
+ deleteModal: {
67227
+ title: "Supprimer le critère",
67228
+ confirmationPrefix: "Voulez-vous vraiment supprimer",
67229
+ confirmationSuffix: " de la grille ?",
67230
+ cancel: "Annuler",
67231
+ "delete": "Supprimer",
67232
+ deleting: "Suppression…"
67233
+ }
67234
+ },
67235
+ toasts: {
67236
+ toggleOn: "Notation activée",
67237
+ toggleOff: "Notation désactivée — votre grille est conservée pour la prochaine fois",
67238
+ toggleError: "Impossible de mettre à jour la notation",
67239
+ configSaved: "Configuration de notation enregistrée",
67240
+ configError: "Impossible d'enregistrer la configuration de notation",
67241
+ criterionAdded: "Critère ajouté",
67242
+ criterionUpdated: "Critère mis à jour",
67243
+ criterionDeleted: "Critère supprimé",
67244
+ criterionError: "Impossible de mettre à jour la grille"
67245
+ }
67246
+ };
67032
67247
  var careerExperienceDialog$2 = {
67033
67248
  pleaseSelectACompany: "Veuillez sélectionner une entreprise",
67034
67249
  endDateCannotBeBeforeStartDate: "La date de fin ne peut pas être antérieure à la date de début",
@@ -67182,6 +67397,9 @@ var chatInputFormInsideButtons$2 = {
67182
67397
  studyMode: "Mode Étude",
67183
67398
  deepResearch: "Recherche Approfondie",
67184
67399
  memory: "Mémoire",
67400
+ cowork: "Cowork",
67401
+ coworkNeedsBackend: "Activez un grand modèle local ou connectez-vous à un espace de travail pour utiliser Cowork.",
67402
+ coworkModelTooSmall: "Votre modèle local est trop petit pour Cowork. Choisissez un modèle d’au moins 14 Go dans Modèles Locaux.",
67185
67403
  moreOptions: "Plus d'options"
67186
67404
  };
67187
67405
  var chatInputFormMemoryMenu$2 = {
@@ -71593,6 +71811,7 @@ var fr = {
71593
71811
  careerEducationDialog: careerEducationDialog$2,
71594
71812
  careerEducationTab: careerEducationTab$2,
71595
71813
  gradebookGradebookTab: gradebookGradebookTab$2,
71814
+ graderTabLabels: graderTabLabels$2,
71596
71815
  careerExperienceDialog: careerExperienceDialog$2,
71597
71816
  careerExperienceTab: careerExperienceTab$2,
71598
71817
  careerInstitutionDialog: careerInstitutionDialog$2,
@@ -73034,6 +73253,118 @@ var gradebookGradebookTab$1 = {
73034
73253
  previousPage: "Anterior",
73035
73254
  nextPage: "Siguiente"
73036
73255
  };
73256
+ var graderTabLabels$1 = {
73257
+ header: {
73258
+ title: "Calificador",
73259
+ description: "Configura cómo tu agente califica el trabajo según una rúbrica que tú defines."
73260
+ },
73261
+ capability: {
73262
+ title: "Calificación",
73263
+ description: "Permite que tu agente califique trabajos. Cuando está activado, el agente puntúa lo que las personas envían según la rúbrica que configures abajo y comparte el resultado como retroalimentación — ideal para ensayos, proyectos y ejercicios de práctica.",
73264
+ offHint: "Actívalo para escribir instrucciones de calificación y crear tu rúbrica. Todo lo que configures aquí se conserva si luego lo desactivas."
73265
+ },
73266
+ subTabs: {
73267
+ setup: "Configuración de calificación",
73268
+ rubric: "Rúbrica"
73269
+ },
73270
+ denied: {
73271
+ title: "Sin acceso a la configuración de calificación",
73272
+ description: "No tienes permiso para ver la configuración de calificación de este agente. Pide acceso a un administrador."
73273
+ },
73274
+ warnings: {
73275
+ noConfig: "La calificación está activada pero aún no está configurada — el agente fallará cuando se le pida calificar. Guarda tus instrucciones en Configuración de calificación para terminar.",
73276
+ noCriteria: "La calificación está activada pero la rúbrica está vacía — el agente fallará cuando se le pida calificar. Agrega al menos un criterio en la pestaña Rúbrica."
73277
+ },
73278
+ config: {
73279
+ sectionTitle: "Configuración de calificación",
73280
+ gradingMode: {
73281
+ label: "Qué se califica",
73282
+ options: {
73283
+ submission: "Una entrega",
73284
+ conversation: "La conversación"
73285
+ },
73286
+ help: {
73287
+ submission: "El agente califica un trabajo que la persona entrega, como un ensayo o una respuesta.",
73288
+ conversation: "El agente califica cómo fue toda la conversación."
73289
+ }
73290
+ },
73291
+ feedbackMode: {
73292
+ label: "Retroalimentación compartida con la persona",
73293
+ options: {
73294
+ overall: "Solo retroalimentación general",
73295
+ perCriteria: "Retroalimentación por criterio",
73296
+ both: "General + por criterio"
73297
+ },
73298
+ help: "La puntuación general siempre se calcula — esto solo controla cuánto detalle se comparte."
73299
+ },
73300
+ instructions: {
73301
+ label: "Instrucciones de calificación",
73302
+ placeholder: "Describe qué se está calificando y todo lo que el calificador deba saber más allá de la rúbrica. P. ej. 'Estás calificando un ensayo persuasivo de 500 palabras sobre política climática escrito por un estudiante de secundaria. Sé alentador pero honesto.'",
73303
+ help: "Obligatorio. Este es el contexto que el agente usa cada vez que califica."
73304
+ },
73305
+ saveButton: "Guardar",
73306
+ savingButton: "Guardando…"
73307
+ },
73308
+ criteria: {
73309
+ sectionTitle: "Rúbrica",
73310
+ description: "Cada fila es algo que el agente evalúa y cuántos puntos vale. La puntuación general son los puntos obtenidos sobre el total.",
73311
+ needsConfigHint: "Primero guarda tu configuración de calificación y luego agrega criterios aquí.",
73312
+ emptyState: "Aún no hay criterios. Agrega el primero — por ejemplo \"Claridad\", 10 puntos.",
73313
+ addButton: "Agregar criterio",
73314
+ columns: {
73315
+ name: "Nombre",
73316
+ criteria: "Criterios",
73317
+ points: "Puntos"
73318
+ },
73319
+ actionsAria: "Acciones para {name}",
73320
+ edit: "Editar",
73321
+ "delete": "Eliminar",
73322
+ totalPoints: "Total de puntos posibles: {total}",
73323
+ scoreHint: "Puntuación general = puntos obtenidos ÷ {total}.",
73324
+ lastCriterionHint: "Una rúbrica necesita al menos un criterio — agrega otro antes de eliminar este.",
73325
+ modal: {
73326
+ addTitle: "Agregar criterio",
73327
+ editTitle: "Editar criterio",
73328
+ name: {
73329
+ label: "Nombre",
73330
+ placeholder: "p. ej. Claridad",
73331
+ required: "El nombre es obligatorio"
73332
+ },
73333
+ criteria: {
73334
+ label: "Criterios",
73335
+ placeholder: "p. ej. El argumento es fácil de seguir y cada párrafo plantea una idea clara.",
73336
+ required: "Los criterios son obligatorios"
73337
+ },
73338
+ points: {
73339
+ label: "Puntos",
73340
+ placeholder: "10",
73341
+ positive: "Los puntos deben ser un número positivo"
73342
+ },
73343
+ save: "Guardar",
73344
+ saving: "Guardando…",
73345
+ cancel: "Cancelar"
73346
+ },
73347
+ deleteModal: {
73348
+ title: "Eliminar criterio",
73349
+ confirmationPrefix: "¿Seguro que quieres eliminar",
73350
+ confirmationSuffix: " de la rúbrica?",
73351
+ cancel: "Cancelar",
73352
+ "delete": "Eliminar",
73353
+ deleting: "Eliminando…"
73354
+ }
73355
+ },
73356
+ toasts: {
73357
+ toggleOn: "Calificación activada",
73358
+ toggleOff: "Calificación desactivada — tu rúbrica se conserva para la próxima vez",
73359
+ toggleError: "No se pudo actualizar la calificación",
73360
+ configSaved: "Configuración de calificación guardada",
73361
+ configError: "No se pudo guardar la configuración de calificación",
73362
+ criterionAdded: "Criterio agregado",
73363
+ criterionUpdated: "Criterio actualizado",
73364
+ criterionDeleted: "Criterio eliminado",
73365
+ criterionError: "No se pudo actualizar la rúbrica"
73366
+ }
73367
+ };
73037
73368
  var careerExperienceDialog$1 = {
73038
73369
  pleaseSelectACompany: "Por favor, selecciona una empresa",
73039
73370
  endDateCannotBeBeforeStartDate: "La fecha de fin no puede ser anterior a la fecha de inicio",
@@ -73187,6 +73518,9 @@ var chatInputFormInsideButtons$1 = {
73187
73518
  studyMode: "Modo Estudio",
73188
73519
  deepResearch: "Investigación Profunda",
73189
73520
  memory: "Memoria",
73521
+ cowork: "Cowork",
73522
+ coworkNeedsBackend: "Activa un modelo local grande o inicia sesión en un espacio de trabajo para usar Cowork.",
73523
+ coworkModelTooSmall: "Tu modelo local es demasiado pequeño para Cowork. Elige un modelo de al menos 14 GB en Modelos Locales.",
73190
73524
  moreOptions: "Más opciones"
73191
73525
  };
73192
73526
  var chatInputFormMemoryMenu$1 = {
@@ -77598,6 +77932,7 @@ var es = {
77598
77932
  careerEducationDialog: careerEducationDialog$1,
77599
77933
  careerEducationTab: careerEducationTab$1,
77600
77934
  gradebookGradebookTab: gradebookGradebookTab$1,
77935
+ graderTabLabels: graderTabLabels$1,
77601
77936
  careerExperienceDialog: careerExperienceDialog$1,
77602
77937
  careerExperienceTab: careerExperienceTab$1,
77603
77938
  careerInstitutionDialog: careerInstitutionDialog$1,
@@ -79039,6 +79374,118 @@ var gradebookGradebookTab = {
79039
79374
  previousPage: "上一页",
79040
79375
  nextPage: "下一页"
79041
79376
  };
79377
+ var graderTabLabels = {
79378
+ header: {
79379
+ title: "评分器",
79380
+ description: "设置您的智能体如何按照您定义的评分标准来评分。"
79381
+ },
79382
+ capability: {
79383
+ title: "评分",
79384
+ description: "让您的智能体为作业评分。开启后,智能体会根据您在下方设置的评分标准为提交的内容打分,并以反馈的形式分享结果 — 非常适合作文、项目和练习。",
79385
+ offHint: "开启后即可编写评分说明并创建评分标准。即使之后关闭,您在此设置的内容也会被保留。"
79386
+ },
79387
+ subTabs: {
79388
+ setup: "评分设置",
79389
+ rubric: "评分标准"
79390
+ },
79391
+ denied: {
79392
+ title: "无权访问评分设置",
79393
+ description: "您没有权限查看此智能体的评分设置。请向管理员申请访问权限。"
79394
+ },
79395
+ warnings: {
79396
+ noConfig: "评分已开启但尚未设置 — 智能体在被要求评分时会失败。请在评分设置中保存评分说明以完成设置。",
79397
+ noCriteria: "评分已开启但评分标准为空 — 智能体在被要求评分时会失败。请在评分标准页签中添加至少一条标准。"
79398
+ },
79399
+ config: {
79400
+ sectionTitle: "评分设置",
79401
+ gradingMode: {
79402
+ label: "评分对象",
79403
+ options: {
79404
+ submission: "一次提交",
79405
+ conversation: "整个对话"
79406
+ },
79407
+ help: {
79408
+ submission: "智能体为提交的作业评分,例如一篇作文或一个答案。",
79409
+ conversation: "智能体为整个对话的表现评分。"
79410
+ }
79411
+ },
79412
+ feedbackMode: {
79413
+ label: "与用户分享的反馈",
79414
+ options: {
79415
+ overall: "仅总体反馈",
79416
+ perCriteria: "按标准逐项反馈",
79417
+ both: "总体 + 逐项"
79418
+ },
79419
+ help: "总分始终会被计算 — 此设置仅控制分享反馈的详细程度。"
79420
+ },
79421
+ instructions: {
79422
+ label: "评分说明",
79423
+ placeholder: "描述评分的内容以及评分标准之外评分者需要了解的信息。例如:'你正在为一名高中生撰写的 500 字气候政策议论文评分。要鼓励但诚实。'",
79424
+ help: "必填。这是智能体每次评分时使用的上下文。"
79425
+ },
79426
+ saveButton: "保存",
79427
+ savingButton: "保存中…"
79428
+ },
79429
+ criteria: {
79430
+ sectionTitle: "评分标准",
79431
+ description: "每一行是智能体考察的一个方面及其分值。总分为获得的分数除以总分值。",
79432
+ needsConfigHint: "请先保存评分设置,然后在此添加评分标准。",
79433
+ emptyState: "还没有标准。请添加第一条 — 例如\"清晰度\",10 分。",
79434
+ addButton: "添加标准",
79435
+ columns: {
79436
+ name: "名称",
79437
+ criteria: "标准",
79438
+ points: "分数"
79439
+ },
79440
+ actionsAria: "{name} 的操作",
79441
+ edit: "编辑",
79442
+ "delete": "删除",
79443
+ totalPoints: "总分值:{total}",
79444
+ scoreHint: "总分 = 获得的分数 ÷ {total}。",
79445
+ lastCriterionHint: "评分标准至少需要一条 — 请先添加另一条再删除这一条。",
79446
+ modal: {
79447
+ addTitle: "添加标准",
79448
+ editTitle: "编辑标准",
79449
+ name: {
79450
+ label: "名称",
79451
+ placeholder: "例如:清晰度",
79452
+ required: "名称为必填项"
79453
+ },
79454
+ criteria: {
79455
+ label: "标准",
79456
+ placeholder: "例如:论点易于理解,每段都有一个明确的观点。",
79457
+ required: "标准为必填项"
79458
+ },
79459
+ points: {
79460
+ label: "分数",
79461
+ placeholder: "10",
79462
+ positive: "分数必须为正数"
79463
+ },
79464
+ save: "保存",
79465
+ saving: "保存中…",
79466
+ cancel: "取消"
79467
+ },
79468
+ deleteModal: {
79469
+ title: "删除标准",
79470
+ confirmationPrefix: "确定要从评分标准中删除",
79471
+ confirmationSuffix: " 吗?",
79472
+ cancel: "取消",
79473
+ "delete": "删除",
79474
+ deleting: "删除中…"
79475
+ }
79476
+ },
79477
+ toasts: {
79478
+ toggleOn: "评分已开启",
79479
+ toggleOff: "评分已关闭 — 您的评分标准已保留,下次可继续使用",
79480
+ toggleError: "无法更新评分",
79481
+ configSaved: "评分设置已保存",
79482
+ configError: "无法保存评分设置",
79483
+ criterionAdded: "标准已添加",
79484
+ criterionUpdated: "标准已更新",
79485
+ criterionDeleted: "标准已删除",
79486
+ criterionError: "无法更新评分标准"
79487
+ }
79488
+ };
79042
79489
  var careerExperienceDialog = {
79043
79490
  pleaseSelectACompany: "请选择一家公司",
79044
79491
  endDateCannotBeBeforeStartDate: "结束日期不能早于开始日期",
@@ -79192,6 +79639,9 @@ var chatInputFormInsideButtons = {
79192
79639
  studyMode: "学习模式",
79193
79640
  deepResearch: "深度研究",
79194
79641
  memory: "记忆",
79642
+ cowork: "Cowork",
79643
+ coworkNeedsBackend: "启用大型本地模型或登录工作区即可使用 Cowork。",
79644
+ coworkModelTooSmall: "您的本地模型太小,无法用于 Cowork。请在“本地模型”中选择至少 14GB 的模型。",
79195
79645
  moreOptions: "更多选项"
79196
79646
  };
79197
79647
  var chatInputFormMemoryMenu = {
@@ -83603,6 +84053,7 @@ var zh = {
83603
84053
  careerEducationDialog: careerEducationDialog,
83604
84054
  careerEducationTab: careerEducationTab,
83605
84055
  gradebookGradebookTab: gradebookGradebookTab,
84056
+ graderTabLabels: graderTabLabels,
83606
84057
  careerExperienceDialog: careerExperienceDialog,
83607
84058
  careerExperienceTab: careerExperienceTab,
83608
84059
  careerInstitutionDialog: careerInstitutionDialog,
@@ -89965,173 +90416,6 @@ var Indicator$2 = ProgressIndicator;
89965
90416
  const Progress = React.forwardRef(({ className, value, ...props }, ref) => (jsx(Root$7, { ref: ref, className: cn('bg-secondary relative h-4 w-full overflow-hidden rounded-full', className), ...props, children: jsx(Indicator$2, { className: "bg-primary h-full w-full flex-1 transition-all", style: { transform: `translateX(-${100 - (value || 0)}%)` } }) })));
89966
90417
  Progress.displayName = Root$7.displayName;
89967
90418
 
89968
- var SLOTTABLE_IDENTIFIER = Symbol("radix.slottable");
89969
- // @__NO_SIDE_EFFECTS__
89970
- function createSlottable(ownerName) {
89971
- const Slottable2 = ({ children }) => {
89972
- return /* @__PURE__ */ jsx(Fragment$1, { children });
89973
- };
89974
- Slottable2.displayName = `${ownerName}.Slottable`;
89975
- Slottable2.__radixId = SLOTTABLE_IDENTIFIER;
89976
- return Slottable2;
89977
- }
89978
-
89979
- var ROOT_NAME = "AlertDialog";
89980
- var [createAlertDialogContext] = createContextScope$1(ROOT_NAME, [
89981
- createDialogScope
89982
- ]);
89983
- var useDialogScope = createDialogScope();
89984
- var AlertDialog$1 = (props) => {
89985
- const { __scopeAlertDialog, ...alertDialogProps } = props;
89986
- const dialogScope = useDialogScope(__scopeAlertDialog);
89987
- return /* @__PURE__ */ jsx(DialogPrimitive.Root, { ...dialogScope, ...alertDialogProps, modal: true });
89988
- };
89989
- AlertDialog$1.displayName = ROOT_NAME;
89990
- var TRIGGER_NAME$3 = "AlertDialogTrigger";
89991
- var AlertDialogTrigger = React.forwardRef(
89992
- (props, forwardedRef) => {
89993
- const { __scopeAlertDialog, ...triggerProps } = props;
89994
- const dialogScope = useDialogScope(__scopeAlertDialog);
89995
- return /* @__PURE__ */ jsx(DialogPrimitive.Trigger, { ...dialogScope, ...triggerProps, ref: forwardedRef });
89996
- }
89997
- );
89998
- AlertDialogTrigger.displayName = TRIGGER_NAME$3;
89999
- var PORTAL_NAME$3 = "AlertDialogPortal";
90000
- var AlertDialogPortal$1 = (props) => {
90001
- const { __scopeAlertDialog, ...portalProps } = props;
90002
- const dialogScope = useDialogScope(__scopeAlertDialog);
90003
- return /* @__PURE__ */ jsx(DialogPrimitive.Portal, { ...dialogScope, ...portalProps });
90004
- };
90005
- AlertDialogPortal$1.displayName = PORTAL_NAME$3;
90006
- var OVERLAY_NAME = "AlertDialogOverlay";
90007
- var AlertDialogOverlay$1 = React.forwardRef(
90008
- (props, forwardedRef) => {
90009
- const { __scopeAlertDialog, ...overlayProps } = props;
90010
- const dialogScope = useDialogScope(__scopeAlertDialog);
90011
- return /* @__PURE__ */ jsx(DialogPrimitive.Overlay, { ...dialogScope, ...overlayProps, ref: forwardedRef });
90012
- }
90013
- );
90014
- AlertDialogOverlay$1.displayName = OVERLAY_NAME;
90015
- var CONTENT_NAME$4 = "AlertDialogContent";
90016
- var [AlertDialogContentProvider, useAlertDialogContentContext] = createAlertDialogContext(CONTENT_NAME$4);
90017
- var Slottable = createSlottable("AlertDialogContent");
90018
- var AlertDialogContent$1 = React.forwardRef(
90019
- (props, forwardedRef) => {
90020
- const { __scopeAlertDialog, children, ...contentProps } = props;
90021
- const dialogScope = useDialogScope(__scopeAlertDialog);
90022
- const contentRef = React.useRef(null);
90023
- const composedRefs = useComposedRefs$1(forwardedRef, contentRef);
90024
- const cancelRef = React.useRef(null);
90025
- return /* @__PURE__ */ jsx(
90026
- DialogPrimitive.WarningProvider,
90027
- {
90028
- contentName: CONTENT_NAME$4,
90029
- titleName: TITLE_NAME,
90030
- docsSlug: "alert-dialog",
90031
- children: /* @__PURE__ */ jsx(AlertDialogContentProvider, { scope: __scopeAlertDialog, cancelRef, children: /* @__PURE__ */ jsxs(
90032
- DialogPrimitive.Content,
90033
- {
90034
- role: "alertdialog",
90035
- ...dialogScope,
90036
- ...contentProps,
90037
- ref: composedRefs,
90038
- onOpenAutoFocus: composeEventHandlers$2(contentProps.onOpenAutoFocus, (event) => {
90039
- event.preventDefault();
90040
- cancelRef.current?.focus({ preventScroll: true });
90041
- }),
90042
- onPointerDownOutside: (event) => event.preventDefault(),
90043
- onInteractOutside: (event) => event.preventDefault(),
90044
- children: [
90045
- /* @__PURE__ */ jsx(Slottable, { children }),
90046
- /* @__PURE__ */ jsx(DescriptionWarning, { contentRef })
90047
- ]
90048
- }
90049
- ) })
90050
- }
90051
- );
90052
- }
90053
- );
90054
- AlertDialogContent$1.displayName = CONTENT_NAME$4;
90055
- var TITLE_NAME = "AlertDialogTitle";
90056
- var AlertDialogTitle$1 = React.forwardRef(
90057
- (props, forwardedRef) => {
90058
- const { __scopeAlertDialog, ...titleProps } = props;
90059
- const dialogScope = useDialogScope(__scopeAlertDialog);
90060
- return /* @__PURE__ */ jsx(DialogPrimitive.Title, { ...dialogScope, ...titleProps, ref: forwardedRef });
90061
- }
90062
- );
90063
- AlertDialogTitle$1.displayName = TITLE_NAME;
90064
- var DESCRIPTION_NAME = "AlertDialogDescription";
90065
- var AlertDialogDescription$1 = React.forwardRef((props, forwardedRef) => {
90066
- const { __scopeAlertDialog, ...descriptionProps } = props;
90067
- const dialogScope = useDialogScope(__scopeAlertDialog);
90068
- return /* @__PURE__ */ jsx(DialogPrimitive.Description, { ...dialogScope, ...descriptionProps, ref: forwardedRef });
90069
- });
90070
- AlertDialogDescription$1.displayName = DESCRIPTION_NAME;
90071
- var ACTION_NAME = "AlertDialogAction";
90072
- var AlertDialogAction$1 = React.forwardRef(
90073
- (props, forwardedRef) => {
90074
- const { __scopeAlertDialog, ...actionProps } = props;
90075
- const dialogScope = useDialogScope(__scopeAlertDialog);
90076
- return /* @__PURE__ */ jsx(DialogPrimitive.Close, { ...dialogScope, ...actionProps, ref: forwardedRef });
90077
- }
90078
- );
90079
- AlertDialogAction$1.displayName = ACTION_NAME;
90080
- var CANCEL_NAME = "AlertDialogCancel";
90081
- var AlertDialogCancel$1 = React.forwardRef(
90082
- (props, forwardedRef) => {
90083
- const { __scopeAlertDialog, ...cancelProps } = props;
90084
- const { cancelRef } = useAlertDialogContentContext(CANCEL_NAME, __scopeAlertDialog);
90085
- const dialogScope = useDialogScope(__scopeAlertDialog);
90086
- const ref = useComposedRefs$1(forwardedRef, cancelRef);
90087
- return /* @__PURE__ */ jsx(DialogPrimitive.Close, { ...dialogScope, ...cancelProps, ref });
90088
- }
90089
- );
90090
- AlertDialogCancel$1.displayName = CANCEL_NAME;
90091
- var DescriptionWarning = ({ contentRef }) => {
90092
- const MESSAGE = `\`${CONTENT_NAME$4}\` requires a description for the component to be accessible for screen reader users.
90093
-
90094
- You can add a description to the \`${CONTENT_NAME$4}\` by passing a \`${DESCRIPTION_NAME}\` component as a child, which also benefits sighted users by adding visible context to the dialog.
90095
-
90096
- Alternatively, you can use your own component as a description by assigning it an \`id\` and passing the same value to the \`aria-describedby\` prop in \`${CONTENT_NAME$4}\`. If the description is confusing or duplicative for sighted users, you can use the \`@radix-ui/react-visually-hidden\` primitive as a wrapper around your description component.
90097
-
90098
- For more information, see https://radix-ui.com/primitives/docs/components/alert-dialog`;
90099
- React.useEffect(() => {
90100
- const hasDescription = document.getElementById(
90101
- contentRef.current?.getAttribute("aria-describedby")
90102
- );
90103
- if (!hasDescription) console.warn(MESSAGE);
90104
- }, [MESSAGE, contentRef]);
90105
- return null;
90106
- };
90107
- var Root2$3 = AlertDialog$1;
90108
- var Portal2$1 = AlertDialogPortal$1;
90109
- var Overlay2 = AlertDialogOverlay$1;
90110
- var Content2$3 = AlertDialogContent$1;
90111
- var Action = AlertDialogAction$1;
90112
- var Cancel = AlertDialogCancel$1;
90113
- var Title2 = AlertDialogTitle$1;
90114
- var Description2 = AlertDialogDescription$1;
90115
-
90116
- const AlertDialog = Root2$3;
90117
- const AlertDialogPortal = Portal2$1;
90118
- const AlertDialogOverlay = React.forwardRef(({ className, ...props }, ref) => (jsx(Overlay2, { className: cn('data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80', className), ...props, ref: ref })));
90119
- AlertDialogOverlay.displayName = Overlay2.displayName;
90120
- const AlertDialogContent = React.forwardRef(({ className, ...props }, ref) => (jsxs(AlertDialogPortal, { children: [jsx(AlertDialogOverlay, {}), jsx(Content2$3, { ref: ref, className: cn('bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg', className), ...props })] })));
90121
- AlertDialogContent.displayName = Content2$3.displayName;
90122
- const AlertDialogHeader = ({ className, ...props }) => (jsx("div", { className: cn('flex flex-col space-y-2 text-center sm:text-left', className), ...props }));
90123
- AlertDialogHeader.displayName = 'AlertDialogHeader';
90124
- const AlertDialogFooter = ({ className, ...props }) => (jsx("div", { className: cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', className), ...props }));
90125
- AlertDialogFooter.displayName = 'AlertDialogFooter';
90126
- const AlertDialogTitle = React.forwardRef(({ className, ...props }, ref) => (jsx(Title2, { ref: ref, className: cn('text-lg font-semibold', className), ...props })));
90127
- AlertDialogTitle.displayName = Title2.displayName;
90128
- const AlertDialogDescription = React.forwardRef(({ className, ...props }, ref) => (jsx(Description2, { ref: ref, className: cn('text-muted-foreground text-sm', className), ...props })));
90129
- AlertDialogDescription.displayName = Description2.displayName;
90130
- const AlertDialogAction = React.forwardRef(({ className, ...props }, ref) => (jsx(Action, { ref: ref, className: cn(buttonVariants(), className), ...props })));
90131
- AlertDialogAction.displayName = Action.displayName;
90132
- const AlertDialogCancel = React.forwardRef(({ className, ...props }, ref) => (jsx(Cancel, { ref: ref, className: cn(buttonVariants({ variant: 'outline' }), 'mt-2 sm:mt-0', className), ...props })));
90133
- AlertDialogCancel.displayName = Cancel.displayName;
90134
-
90135
90419
  const LOCAL_LLM_ENABLED_KEY = 'ibl_local_llm_enabled';
90136
90420
  const LOCAL_LLM_MODEL_KEY = 'ibl_local_llm_model';
90137
90421
  const LOCAL_LLM_TOOL_SUPPORT_KEY = 'ibl_local_llm_tool_support';
@@ -90167,8 +90451,8 @@ const LOCAL_MODELS = [
90167
90451
  },
90168
90452
  { name: 'Granite 4.1', provider: 'IBM', id: 'granite4.1:8b', size: '5.3 GB', tool_support: true },
90169
90453
  { name: 'GPT-OSS 20B', provider: 'OpenAI', id: 'gpt-oss:20b', size: '14 GB', tool_support: true },
90170
- // Larger models. Sizes use "GB" so they parse for the System Control size gate
90171
- // (only models above the configured gate can use System Control).
90454
+ // Larger models. Sizes use "GB" so they parse for the Cowork size gate
90455
+ // (only models above the configured gate can use Cowork).
90172
90456
  {
90173
90457
  name: 'Qwen 3.6',
90174
90458
  provider: 'Alibaba',
@@ -90192,34 +90476,6 @@ const LOCAL_MODELS = [
90192
90476
  tool_support: true,
90193
90477
  },
90194
90478
  ];
90195
- /** The model wired to the existing single-model download flow (default selection). */
90196
- const PRIMARY_MODEL_ID = 'phi4-mini:latest';
90197
- /**
90198
- * Whether a catalog model id (e.g. "llama3.2", "phi3:mini") is present among the
90199
- * installed Ollama tags reported by the backend (e.g. "llama3.2:latest"). Matches
90200
- * an exact tag or the same base model with any tag suffix, so a model pulled as
90201
- * `<id>:latest` still counts as installed.
90202
- */
90203
- function isModelInstalled(modelId, installedTags) {
90204
- if (!installedTags)
90205
- return false;
90206
- return installedTags.some((tag) => tag === modelId || tag.startsWith(`${modelId}:`));
90207
- }
90208
- /**
90209
- * Whether a model id is an Ollama cloud-hosted model — either the plain ":cloud"
90210
- * tag (e.g. "glm-5.2:cloud") or a sized cloud tag (e.g. "gemma4:31b-cloud").
90211
- * Cloud models run on Ollama's servers, so they are available by default — never
90212
- * downloaded, no local memory required, always "ready".
90213
- */
90214
- function isCloudModelId(modelId) {
90215
- return modelId.endsWith(':cloud') || (modelId.includes(':') && modelId.endsWith('-cloud'));
90216
- }
90217
- /**
90218
- * Fraction of the machine's memory above which a model is treated as "too large"
90219
- * and a confirmation is required before downloading. TESTING VALUE — set low (1%)
90220
- * so the warning is easy to trigger; raise toward real capacity (e.g. 0.8) later.
90221
- */
90222
- const MODEL_SIZE_WARN_FRACTION = 0.01;
90223
90479
  /** Multipliers for the size units used in the catalog (binary / 1024-based). */
90224
90480
  const SIZE_UNIT_BYTES = {
90225
90481
  B: 1,
@@ -90241,54 +90497,19 @@ function parseModelSizeBytes(size) {
90241
90497
  return null;
90242
90498
  return value * ((_a = SIZE_UNIT_BYTES[match[2].toUpperCase()]) !== null && _a !== void 0 ? _a : 1);
90243
90499
  }
90244
- /** Format a byte count as a short, human-readable size (e.g. "16.0 GB"). */
90245
- function formatBytes(bytes) {
90246
- if (bytes <= 0)
90247
- return '0 GB';
90248
- const gb = bytes / 1024 ** 3;
90249
- if (gb >= 1)
90250
- return `${gb.toFixed(1)} GB`;
90251
- return `${Math.round(bytes / 1024 ** 2)} MB`;
90252
- }
90253
- /**
90254
- * The memory a model can use on this machine: the larger of system RAM and GPU
90255
- * VRAM (a model runs in one or the other). Returns 0 when memory is unknown.
90256
- */
90257
- function usableMemoryBytes(systemMemory) {
90258
- if (!systemMemory)
90259
- return 0;
90260
- return Math.max(systemMemory.ram_total, systemMemory.vram_total);
90261
- }
90262
90500
  /**
90263
- * Whether `model` is large enough relative to this machine's memory to warrant a
90264
- * "might not run" confirmation. False when memory or the model size is unknown,
90265
- * so the download simply proceeds rather than warning on incomplete data.
90266
- */
90267
- function modelExceedsCapacity(model, systemMemory) {
90268
- const capacity = usableMemoryBytes(systemMemory);
90269
- const modelBytes = parseModelSizeBytes(model.size);
90270
- if (modelBytes == null)
90271
- return false;
90272
- // Unknown memory (capacity 0) → don't warn; the download simply proceeds
90273
- // rather than blocking on incomplete data.
90274
- if (capacity <= 0)
90275
- return false;
90276
- return modelBytes > capacity * MODEL_SIZE_WARN_FRACTION;
90277
- }
90278
- /**
90279
- * Default minimum model size (GB) that can use the System Control Manager
90501
+ * Default minimum model size (GB) that can use the Cowork
90280
90502
  * (GhostOS MCP/tools). Smaller models don't support tools/MCP well, so the
90281
- * manager is gated to models above this size. Per-app overridable via the
90282
- * System Control card's `requiredSizeGb` prop (see SystemControlTabProps).
90503
+ * manager is gated to models above this size.
90283
90504
  */
90284
- const DEFAULT_SYSTEM_CONTROL_REQUIRED_SIZE_GB = 12;
90505
+ const DEFAULT_COWORK_REQUIRED_SIZE_GB = 12;
90285
90506
  /**
90286
90507
  * Whether the given model (by Ollama id) is large enough to use the System
90287
90508
  * Control Manager — i.e. its catalog size exceeds `gb` (default
90288
- * {@link DEFAULT_SYSTEM_CONTROL_REQUIRED_SIZE_GB}). Unknown ids or unparseable
90509
+ * {@link DEFAULT_COWORK_REQUIRED_SIZE_GB}). Unknown ids or unparseable
90289
90510
  * sizes return false (gated off).
90290
90511
  */
90291
- function modelSupportsSystemControl(modelId, gb = DEFAULT_SYSTEM_CONTROL_REQUIRED_SIZE_GB) {
90512
+ function modelSupportsCowork(modelId, gb = DEFAULT_COWORK_REQUIRED_SIZE_GB) {
90292
90513
  if (!modelId)
90293
90514
  return false;
90294
90515
  const model = LOCAL_MODELS.find((m) => m.id === modelId);
@@ -90300,12 +90521,12 @@ function modelSupportsSystemControl(modelId, gb = DEFAULT_SYSTEM_CONTROL_REQUIRE
90300
90521
  return bytes > gb * 1024 ** 3;
90301
90522
  }
90302
90523
  /**
90303
- * The smallest catalog model that can use the System Control Manager (size
90524
+ * The smallest catalog model that can use the Cowork (size
90304
90525
  * exceeds `gb`), or null if none qualify. Used by the "Upgrade" action to pick
90305
90526
  * the lightest capable model. Ties / unparseable sizes sort last.
90306
90527
  */
90307
- function smallestSystemControlModel(gb = DEFAULT_SYSTEM_CONTROL_REQUIRED_SIZE_GB) {
90308
- const usable = LOCAL_MODELS.filter((m) => modelSupportsSystemControl(m.id, gb));
90528
+ function smallestCoworkModel(gb = DEFAULT_COWORK_REQUIRED_SIZE_GB) {
90529
+ const usable = LOCAL_MODELS.filter((m) => modelSupportsCowork(m.id, gb));
90309
90530
  if (usable.length === 0)
90310
90531
  return null;
90311
90532
  return usable.reduce((smallest, m) => {
@@ -90366,41 +90587,21 @@ function setLocalLLMToolSupport(toolSupport) {
90366
90587
  return;
90367
90588
  localStorage.setItem(LOCAL_LLM_TOOL_SUPPORT_KEY, String(toolSupport));
90368
90589
  }
90369
- function LocalLLMTab({ isAvailable, state, ollamaStatus, systemMemory, isUsingFoundry = false, foundryModels = [], selectedFoundryModel = null, foundryStatus, onStartDownload, onCancelDownload, onInstallOllama, onStopManager, onInstallFoundry, onCheckStatus, onResetState, onSelectFoundryModel, }) {
90370
- var _a, _b, _c, _d, _e, _f, _g;
90590
+ function LocalLLMTab({ isAvailable, state, ollamaStatus, isUsingFoundry = false, foundryModels = [], selectedFoundryModel = null, foundryStatus, onInstallOllama, onStopManager, onInstallFoundry, onCheckStatus, onSelectFoundryModel, }) {
90591
+ var _a, _b, _c, _d, _e;
90371
90592
  const t = useT();
90372
- // Direct Tauri access so the model-size check can read system memory fresh at
90373
- // download-click time (the threaded `systemMemory` prop is only a fast path).
90374
- const { invoke } = useTauri();
90375
90593
  const isDownloading = state.status === 'downloading';
90376
90594
  const isManagerInstalling = state.managerInstalling || (ollamaStatus === null || ollamaStatus === void 0 ? void 0 : ollamaStatus.installing);
90377
90595
  // User preference state - independent of whether model is installed
90378
90596
  const [isEnabled, setIsEnabled] = useState(() => isLocalLLMEnabled());
90379
- // Which model the shared download flow currently targets. Prefer the model
90380
- // recorded in the persisted download state, so the correct row shows progress
90381
- // even after the dialog is closed and reopened mid-download; fall back to a
90382
- // local value for immediate feedback the instant a Download button is clicked.
90383
- const [localActiveModelId, setLocalActiveModelId] = useState(PRIMARY_MODEL_ID);
90384
- const activeModelId = state.status === 'downloading' && state.activeModel ? state.activeModel : localActiveModelId;
90385
- // Which model the user has chosen to chat with (exclusive selection).
90386
- const [selectedModelId, setSelectedModelId] = useState(() => getLocalLLMModel() || PRIMARY_MODEL_ID);
90387
- // A model the user asked to download that is large relative to this machine's
90388
- // memory. Set when we need the user to confirm a "might not run" warning before
90389
- // starting the download; null when no confirmation is pending.
90390
- const [pendingModel, setPendingModel] = useState(null);
90391
90597
  // "Enable Local Models" === run the model manager (Ollama). The toggle is a
90392
90598
  // user preference that is always operable: turning it on installs (if needed)
90393
- // and starts the manager; turning it off stops it. The card + model table are
90394
- // shown whenever the toggle is on (or mid-install), independent of install
90395
- // state, so the user always gets feedback for their choice.
90599
+ // and starts the manager; turning it off stops it. Only the manager status
90600
+ // card is shown here (whenever the toggle is on or mid-install) the per-model
90601
+ // list lives in Agent settings LLM tab, where local models are picked and
90602
+ // downloaded alongside cloud models.
90396
90603
  const managerRunning = (ollamaStatus === null || ollamaStatus === void 0 ? void 0 : ollamaStatus.running) === true;
90397
90604
  const localModelsEnabled = isEnabled || isManagerInstalling;
90398
- // A model can be chosen for chat only once it is downloaded/ready. The backend
90399
- // reports every installed model tag, so any downloaded model qualifies.
90400
- const selectedModelReady = isCloudModelId(selectedModelId) ||
90401
- isModelInstalled(selectedModelId, ollamaStatus === null || ollamaStatus === void 0 ? void 0 : ollamaStatus.installed_models) ||
90402
- (selectedModelId === PRIMARY_MODEL_ID &&
90403
- (state.status === 'completed' || (ollamaStatus === null || ollamaStatus === void 0 ? void 0 : ollamaStatus.model_installed) === true));
90404
90605
  // Track previous model installation state to detect when it first becomes installed
90405
90606
  const [, setWasModelInstalled] = useState(() => {
90406
90607
  return (ollamaStatus === null || ollamaStatus === void 0 ? void 0 : ollamaStatus.model_installed) === true;
@@ -90514,62 +90715,6 @@ function LocalLLMTab({ isAvailable, state, ollamaStatus, systemMemory, isUsingFo
90514
90715
  onStopManager === null || onStopManager === void 0 ? void 0 : onStopManager();
90515
90716
  }
90516
90717
  };
90517
- const startDownloadNow = (modelId) => {
90518
- setLocalActiveModelId(modelId);
90519
- onStartDownload(modelId);
90520
- };
90521
- const handleDownloadModel = async (modelId) => {
90522
- // Always read system memory FIRST — this is the call that hits the backend
90523
- // `get_system_memory`. Doing it before the catalog lookup guarantees it runs
90524
- // on every Download click (falling back to the value fetched on mount).
90525
- const model = LOCAL_MODELS.find((m) => modelId.startsWith(m.id));
90526
- if (!model) {
90527
- await invoke(TAURI_COMMANDS.LOG_STDOUT, {
90528
- s: `[Local Models] -> Download: bad download request, model ${model}`,
90529
- });
90530
- console.log(`[Local Models] -> Download: bad download request, model ${model}`);
90531
- return;
90532
- }
90533
- let mem = null;
90534
- try {
90535
- mem = await invoke(TAURI_COMMANDS.GET_SYSTEM_MEMORY);
90536
- }
90537
- catch (e) {
90538
- await invoke(TAURI_COMMANDS.LOG_STDOUT, {
90539
- s: `[Local Models] -> Download: couldn't detect system memory ${modelId} ${e}`,
90540
- });
90541
- console.log(`[Local Models] -> Download: couldn't detect system memory {e}`);
90542
- return;
90543
- }
90544
- const exceeds = modelExceedsCapacity(model, mem);
90545
- console.warn('[Local Models] -> Download: download click', {
90546
- modelId,
90547
- systemMemory: mem,
90548
- capacityBytes: usableMemoryBytes(mem),
90549
- modelBytes: parseModelSizeBytes(model.size),
90550
- thresholdBytes: usableMemoryBytes(mem) * MODEL_SIZE_WARN_FRACTION,
90551
- exceeds,
90552
- });
90553
- if (exceeds) {
90554
- setPendingModel(model);
90555
- return;
90556
- }
90557
- startDownloadNow(modelId);
90558
- };
90559
- const confirmPendingDownload = () => {
90560
- if (pendingModel) {
90561
- startDownloadNow(pendingModel.id);
90562
- }
90563
- setPendingModel(null);
90564
- };
90565
- const handleSelectModel = (modelId) => {
90566
- var _a, _b;
90567
- setSelectedModelId(modelId);
90568
- setLocalLLMModel(modelId);
90569
- // Persist the model's tool-calling support so the host can route chat to the
90570
- // MCP/tool proxy (:8000) vs plain Ollama (:11434).
90571
- setLocalLLMToolSupport((_b = (_a = LOCAL_MODELS.find((m) => m.id === modelId)) === null || _a === void 0 ? void 0 : _a.tool_support) !== null && _b !== void 0 ? _b : false);
90572
- };
90573
90718
  // For Ollama the switch reflects the user's toggle preference (always
90574
90719
  // operable, so it can be turned off). Foundry additionally requires a
90575
90720
  // downloaded model to be considered "on".
@@ -90583,54 +90728,16 @@ function LocalLLMTab({ isAvailable, state, ollamaStatus, systemMemory, isUsingFo
90583
90728
  const switchDisabled = isUsingFoundry
90584
90729
  ? !hasDownloadedFoundryModel || isDownloading || state.status === 'checking'
90585
90730
  : isDownloading || isManagerInstalling || state.status === 'checking';
90586
- return (jsxs("div", { className: "space-y-6", children: [jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between rounded-lg border px-6 py-4", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { className: "text-sm font-medium text-[#646464]", children: t('localLlmLocalLlmTab.enableLocalLlm') }), jsx(TooltipProvider, { children: jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { "aria-label": t('localLlmLocalLlmTab.moreInfoAriaLabel'), className: "hidden sm:block", children: jsx(Info$3, { className: "h-4 w-4 text-gray-400" }) }), jsx(TooltipContent, { className: "rounded-lg bg-gray-700 px-3 py-2 text-sm font-medium max-w-xs text-white shadow-sm transition-opacity duration-300 z-50", children: jsxs("div", { className: "space-y-2", children: [jsx("p", { children: t('localLlmLocalLlmTab.tooltipWorkOffline') }), (foundryStatus === null || foundryStatus === void 0 ? void 0 : foundryStatus.is_supported) && (jsx("p", { className: "text-xs text-gray-300", children: t('localLlmLocalLlmTab.tooltipFoundrySupported') }))] }) })] }) })] }), jsxs("div", { className: "flex items-center gap-2", children: [isManagerInstalling && !isUsingFoundry && (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin text-blue-500", "aria-label": t('localLlmLocalLlmTab.startingModelManagerAriaLabel') })), jsx(Switch, { checked: switchChecked, onCheckedChange: handleToggle, disabled: switchDisabled, "aria-label": t('localLlmLocalLlmTab.switchAriaLabel', {
90587
- state: switchChecked
90588
- ? t('localLlmLocalLlmTab.switchStateEnabled')
90589
- : t('localLlmLocalLlmTab.switchStateDisabled'),
90590
- }), className: "cursor-pointer data-[state=checked]:bg-blue-500" })] })] }), shouldShowFoundryInstall ? (jsx("div", { className: "rounded-lg border px-6 py-4 bg-blue-50/30 dark:bg-blue-950/10", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs("div", { className: "space-y-4", children: [jsx("div", { className: "flex items-start gap-3", children: jsxs("div", { className: "flex items-center gap-2 flex-shrink-0 mt-0.5", children: [jsx(Star$1, { className: "h-5 w-5 text-blue-600 fill-blue-600" }), jsx("span", { className: "px-2 py-0.5 text-xs font-semibold bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300 rounded-full", children: t('localLlmLocalLlmTab.preferredBadge') })] }) }), jsxs("div", { className: "flex items-start gap-3", children: [jsx(Info$3, { className: "h-5 w-5 text-blue-500 flex-shrink-0 mt-0.5" }), jsxs("div", { className: "flex-1", children: [jsx("h3", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: t('localLlmLocalLlmTab.settingUpOfflineAi') }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: t('localLlmLocalLlmTab.foundryInstallDescription') })] })] }), state.status === 'downloading' || state.status === 'checking' ? (jsxs("div", { className: "space-y-2", children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx(LoaderCircle, { className: "h-4 w-4 animate-spin text-blue-500" }), jsx("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: state.message || t('localLlmLocalLlmTab.preparingDownload') })] }), state.progress > 0 && jsx(Progress, { value: state.progress, className: "h-2" })] })) : state.status === 'error' ? (jsxs("div", { className: "space-y-2", children: [jsxs("div", { className: "flex items-center gap-2 text-red-600 dark:text-red-400", children: [jsx(CircleX, { className: "h-4 w-4" }), jsx("span", { className: "text-sm", children: state.error || t('localLlmLocalLlmTab.downloadFailed') })] }), jsx("div", { className: "flex gap-2", children: jsxs(Button$1, { onClick: onInstallFoundry, size: "sm", variant: "outline", children: [jsx(RefreshCw, { className: "h-4 w-4 mr-2" }), t('localLlmLocalLlmTab.tryAgain')] }) })] })) : (jsx("div", { className: "space-y-2", children: jsxs("div", { className: "flex items-center gap-2", children: [jsx(LoaderCircle, { className: "h-4 w-4 animate-spin text-blue-500" }), jsx("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: t('localLlmLocalLlmTab.startingDownload') })] }) })), jsxs("div", { className: "text-xs text-gray-500 dark:text-gray-400", children: [jsx("p", { className: "font-medium mb-1", children: t('localLlmLocalLlmTab.downloadSize') }), jsx("p", { children: t('localLlmLocalLlmTab.oneTimeSetup') })] })] }) })) : /* Requirements Table - Hidden when using Foundry Local */ !isUsingFoundry ? (jsxs(Fragment$1, { children: [(foundryStatus === null || foundryStatus === void 0 ? void 0 : foundryStatus.is_supported) && (jsx("div", { className: "rounded-lg border px-4 py-3 bg-blue-50/20 dark:bg-blue-950/10", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs("div", { className: "flex items-start gap-2", children: [jsx(Info$3, { className: "h-4 w-4 text-blue-600 flex-shrink-0 mt-0.5" }), jsxs("div", { className: "text-xs text-gray-600 dark:text-gray-400", children: [jsx("span", { className: "font-medium text-gray-900 dark:text-gray-100", children: t('localLlmLocalLlmTab.noteLabel') }), ' ', t('localLlmLocalLlmTab.foundryAlternativeNote')] })] }) })), localModelsEnabled && (jsxs("div", { className: "rounded-lg border px-6 py-4", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsxs("div", { className: "flex items-center gap-3", children: [jsx(Server, { className: "h-5 w-5 text-gray-400", "aria-hidden": "true" }), jsxs("div", { children: [jsx("div", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: t('localLlmLocalLlmTab.modelManagerName') }), jsx("div", { className: "text-xs text-gray-500 dark:text-gray-400", children: t('localLlmLocalLlmTab.modelManagerDescription') })] })] }), jsx("div", { className: "flex items-center gap-2", children: managerRunning ? (jsxs(Fragment$1, { children: [jsxs("span", { className: "inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300 rounded-full", children: [jsx(CircleCheckBig, { className: "h-3 w-3" }), t('localLlmLocalLlmTab.running')] }), jsx(Button$1, { onClick: onCheckStatus, variant: "ghost", size: "sm", "aria-label": t('localLlmLocalLlmTab.refreshManagerStatusAriaLabel'), children: jsx(RefreshCw, { className: "h-4 w-4" }) })] })) : (jsxs(Fragment$1, { children: [jsxs("span", { className: "inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300 rounded-full", children: [jsx(LoaderCircle, { className: "h-3 w-3 animate-spin" }), t('localLlmLocalLlmTab.starting')] }), jsx(Button$1, { onClick: onCheckStatus, variant: "ghost", size: "sm", "aria-label": t('localLlmLocalLlmTab.refreshManagerStatusAriaLabel'), children: jsx(RefreshCw, { className: "h-4 w-4" }) })] })) })] }), isManagerInstalling && (jsx("div", { className: "mt-3 w-full max-w-[240px]", children: jsx(Progress, { value: state.managerInstallProgress || 0, className: "h-1.5" }) }))] })), localModelsEnabled && (jsxs("div", { className: "rounded-lg border overflow-hidden", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("table", { className: "w-full", children: [jsx("thead", { children: jsxs("tr", { className: "bg-gray-50 dark:bg-gray-800/50", children: [jsx("th", { className: "px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider w-12", children: t('localLlmLocalLlmTab.tableHeaderUse') }), jsx("th", { className: "px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider", children: t('localLlmLocalLlmTab.tableHeaderModel') }), jsx("th", { className: "px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider", children: t('localLlmLocalLlmTab.tableHeaderStatus') }), jsx("th", { className: "px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider", children: t('localLlmLocalLlmTab.tableHeaderAction') })] }) }), jsx("tbody", { className: "bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-800", children: LOCAL_MODELS.map((model) => {
90591
- const isPrimary = model.id === PRIMARY_MODEL_ID;
90592
- const isActive = activeModelId === model.id;
90593
- // Cloud-hosted models are always available — they run on
90594
- // Ollama's cloud, so there's nothing to download.
90595
- const isCloud = isCloudModelId(model.id);
90596
- // A model is ready once Ollama reports its tag as installed.
90597
- // Fall back to (a) this row's own download having just
90598
- // completed — so it flips to "Ready" before the status
90599
- // refresh lands — and (b) the primary-model status flag.
90600
- // Cloud models are ready by default.
90601
- const isInstalled = isCloud ||
90602
- isModelInstalled(model.id, ollamaStatus === null || ollamaStatus === void 0 ? void 0 : ollamaStatus.installed_models) ||
90603
- (isActive && state.status === 'completed') ||
90604
- (isPrimary && (ollamaStatus === null || ollamaStatus === void 0 ? void 0 : ollamaStatus.model_installed) === true);
90605
- // An installed model must never render a download/cancel
90606
- // state — guards against a stale persisted "downloading"
90607
- // status making an already-ready model look like it's
90608
- // still downloading (and wrongly cancellable) on reopen.
90609
- const rowDownloading = isActive && isDownloading && !isInstalled;
90610
- const rowChecking = isActive && state.status === 'checking';
90611
- const rowError = isActive && state.status === 'error';
90612
- const rowCancelled = isActive && state.status === 'cancelled';
90613
- const canDownload = !!(ollamaStatus === null || ollamaStatus === void 0 ? void 0 : ollamaStatus.installed) &&
90614
- !isInstalled &&
90615
- !rowDownloading &&
90616
- !rowChecking;
90617
- const isSelected = selectedModelId === model.id;
90618
- return (jsxs("tr", { className: isSelected ? 'bg-blue-50/40 dark:bg-blue-950/20' : undefined, children: [jsx("td", { className: "px-6 py-4", children: jsx("input", { type: "radio", name: "local-llm-model", checked: isSelected, disabled: !isInstalled, onChange: () => handleSelectModel(model.id), "aria-label": t('localLlmLocalLlmTab.useModelForChatAriaLabel', {
90619
- name: model.name,
90620
- }), title: isInstalled
90621
- ? undefined
90622
- : t('localLlmLocalLlmTab.downloadToChatTitle'), className: isInstalled
90623
- ? 'h-4 w-4 cursor-pointer accent-blue-500'
90624
- : 'h-4 w-4 cursor-not-allowed opacity-40' }) }), jsxs("td", { className: "px-6 py-4 whitespace-nowrap", children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: model.name }), jsx("span", { className: "text-xs text-gray-400 dark:text-gray-500", children: model.size })] }), jsx("div", { className: "text-xs text-gray-500 dark:text-gray-400", children: model.provider })] }), jsx("td", { className: "px-6 py-4", children: jsx("div", { className: "space-y-2", children: isCloud ? (jsxs("span", { className: "inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300 rounded-full", children: [jsx(Cloud, { className: "h-3 w-3" }), t('localLlmLocalLlmTab.cloud')] })) : rowDownloading ? (jsxs("div", { className: "space-y-2", children: [jsxs("span", { className: "inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300 rounded-full", children: [jsx(LoaderCircle, { className: "h-3 w-3 animate-spin" }), Math.round(state.progress), "%"] }), jsx("div", { className: "w-full max-w-[200px]", children: jsx(Progress, { value: state.progress, className: "h-1.5" }) })] })) : rowChecking ? (jsxs("span", { className: "inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-300 rounded-full", children: [jsx(LoaderCircle, { className: "h-3 w-3 animate-spin" }), t('localLlmLocalLlmTab.checking')] })) : isInstalled ? (jsxs("span", { className: "inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300 rounded-full", children: [jsx(CircleCheckBig, { className: "h-3 w-3" }), t('localLlmLocalLlmTab.ready')] })) : rowError ? (jsxs("div", { className: "space-y-1", children: [jsxs("span", { className: "inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-300 rounded-full", children: [jsx(CircleX, { className: "h-3 w-3" }), t('localLlmLocalLlmTab.error')] }), state.error && (jsx("p", { className: "text-xs text-red-600 dark:text-red-400 max-w-[200px]", children: state.error }))] })) : rowCancelled ? (jsxs("span", { className: "inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-300 rounded-full", children: [jsx(X$1, { className: "h-3 w-3" }), t('localLlmLocalLlmTab.cancelled')] })) : (jsx("span", { className: "inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-300 rounded-full", children: t('localLlmLocalLlmTab.notDownloaded') })) }) }), jsx("td", { className: "px-6 py-4 text-right", children: jsxs("div", { className: "flex items-center justify-end gap-2", children: [rowDownloading && (jsxs(Button$1, { onClick: onCancelDownload, variant: "outline", size: "sm", children: [jsx(X$1, { className: "h-4 w-4 mr-2" }), t('localLlmLocalLlmTab.cancel')] })), canDownload && (jsxs(Button$1, { onClick: () => handleDownloadModel(model.id), size: "sm", variant: "outline", children: [jsx(Download, { className: "h-4 w-4 mr-2" }), t('localLlmLocalLlmTab.download')] })), rowError && (jsx(Button$1, { onClick: onResetState, variant: "ghost", size: "sm", children: t('localLlmLocalLlmTab.reset') })), isInstalled && !isCloud && (jsx(Button$1, { onClick: onCheckStatus, variant: "ghost", size: "sm", children: jsx(RefreshCw, { className: "h-4 w-4" }) }))] }) })] }, model.id));
90625
- }) })] }), jsx("div", { className: "px-6 py-3 border-t text-xs text-gray-500 dark:text-gray-400", style: { borderColor: 'oklch(.922 0 0)' }, children: selectedModelReady ? (jsxs(Fragment$1, { children: [t('localLlmLocalLlmTab.chattingWith'), ' ', jsx("span", { className: "font-medium text-gray-900 dark:text-gray-100", children: (_c = (_b = LOCAL_MODELS.find((m) => m.id === selectedModelId)) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : selectedModelId })] })) : (jsx(Fragment$1, { children: t('localLlmLocalLlmTab.noModelSelectedHint') })) })] }))] })) : (jsx("div", { className: "rounded-lg border px-6 py-4 bg-green-50/30 dark:bg-green-950/10", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs("div", { className: "space-y-4", children: [jsx("div", { className: "flex items-center justify-between", children: jsxs("div", { className: "flex items-center gap-3", children: [jsx(CircleCheckBig, { className: "h-8 w-8 text-green-500 flex-shrink-0" }), jsxs("div", { className: "flex-1", children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("h3", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: t('localLlmLocalLlmTab.offlineAiReady') }), jsxs("span", { className: "inline-flex items-center gap-1 px-2 py-0.5 text-xs font-semibold bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300 rounded-full", children: [jsx(Star$1, { className: "h-3 w-3 fill-blue-700 dark:fill-blue-300" }), t('localLlmLocalLlmTab.preferredBadge')] })] }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: t('localLlmLocalLlmTab.foundryReadyDescription') })] })] }) }), foundryModels.length > 0 && (jsxs("div", { className: "space-y-2", children: [jsx("label", { className: "text-xs font-medium text-gray-700 dark:text-gray-300", children: t('localLlmLocalLlmTab.selectModelLabel') }), jsxs(Select$1, { value: selectedFoundryModel || ((_d = foundryModels[0]) === null || _d === void 0 ? void 0 : _d.id), onValueChange: (value) => onSelectFoundryModel === null || onSelectFoundryModel === void 0 ? void 0 : onSelectFoundryModel(value), children: [jsx(SelectTrigger, { className: "w-full bg-gray-50 border-gray-200 dark:bg-gray-800 dark:border-gray-700", children: jsx(SelectValue, { placeholder: t('localLlmLocalLlmTab.selectModelPlaceholder') }) }), jsx(SelectContent, { children: foundryModels.map((model) => (jsx(SelectItem, { value: model.id, children: jsxs("div", { className: "flex items-center justify-between w-full gap-4", children: [jsx("span", { className: "font-medium", children: model.name || model.id }), jsxs("div", { className: "flex items-center gap-2 text-xs text-gray-500", children: [model.device && (jsx("span", { className: "px-2 py-0.5 bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300 rounded", children: model.device })), model.size && jsx("span", { children: model.size }), !model.is_downloaded && (jsx("span", { className: "px-2 py-0.5 bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-300 rounded", children: t('localLlmLocalLlmTab.notDownloaded') })), model.is_downloaded && (jsx("span", { className: "px-2 py-0.5 bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300 rounded", children: t('localLlmLocalLlmTab.downloaded') }))] })] }) }, model.id))) })] }), jsxs("div", { className: "flex flex-col gap-1", children: [jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: t('localLlmLocalLlmTab.modelsAvailable', { count: foundryModels.length }) }), selectedFoundryModel && (jsxs("div", { className: "flex items-center gap-1.5 text-xs text-green-600 dark:text-green-400", children: [jsx(CircleCheckBig, { className: "h-3.5 w-3.5" }), jsxs("span", { children: [t('localLlmLocalLlmTab.usingModelPrefix'), ' ', ((_e = foundryModels.find((m) => m.id === selectedFoundryModel)) === null || _e === void 0 ? void 0 : _e.name) ||
90626
- selectedFoundryModel, ((_f = foundryModels.find((m) => m.id === selectedFoundryModel)) === null || _f === void 0 ? void 0 : _f.device) && (jsxs("span", { className: "ml-1 text-gray-500 dark:text-gray-400", children: ["(", (_g = foundryModels.find((m) => m.id === selectedFoundryModel)) === null || _g === void 0 ? void 0 : _g.device, ")"] }))] })] }))] })] })), state.status === 'downloading' && (jsxs("div", { className: "mt-4 p-4 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg", children: [jsxs("div", { className: "flex items-center gap-3", children: [jsx("div", { className: "animate-spin h-5 w-5 border-2 border-blue-600 dark:border-blue-400 border-t-transparent rounded-full" }), jsxs("div", { className: "flex-1", children: [jsx("p", { className: "text-sm font-medium text-blue-900 dark:text-blue-100", children: state.message }), state.progress > 0 && (jsx("div", { className: "mt-2 w-full bg-blue-200 dark:bg-blue-800 rounded-full h-2", children: jsx("div", { className: "bg-blue-600 dark:bg-blue-400 h-2 rounded-full transition-all duration-300", style: { width: `${state.progress}%` } }) }))] })] }), state.logs.length > 0 && (jsx("div", { className: "mt-3 max-h-32 overflow-y-auto bg-white dark:bg-gray-800 rounded border border-blue-200 dark:border-blue-700 p-2", children: state.logs.slice(-10).map((log, idx) => (jsx("div", { className: `text-xs font-mono ${log.level === 'error'
90627
- ? 'text-red-600 dark:text-red-400'
90628
- : log.level === 'warn'
90629
- ? 'text-yellow-600 dark:text-yellow-400'
90630
- : 'text-gray-700 dark:text-gray-300'}`, children: log.message }, idx))) }))] }))] }) }))] }), jsx(AlertDialog, { open: !!pendingModel, onOpenChange: (open) => {
90631
- if (!open)
90632
- setPendingModel(null);
90633
- }, children: jsxs(AlertDialogContent, { children: [jsxs(AlertDialogHeader, { children: [jsx(AlertDialogTitle, { children: "This model may be too large for your system" }), jsxs(AlertDialogDescription, { children: [pendingModel === null || pendingModel === void 0 ? void 0 : pendingModel.name, " needs about ", pendingModel === null || pendingModel === void 0 ? void 0 : pendingModel.size, ", but your system has", ' ', formatBytes(usableMemoryBytes(systemMemory)), " of memory available to run it. It may run very slowly or fail to load. Download anyway?"] })] }), jsxs(AlertDialogFooter, { children: [jsx(AlertDialogCancel, { onClick: () => setPendingModel(null), children: "Cancel" }), jsx(AlertDialogAction, { onClick: confirmPendingDownload, children: "Download anyway" })] })] }) })] }));
90731
+ return (jsx("div", { className: "space-y-6", children: jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between rounded-lg border px-6 py-4", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { className: "text-sm font-medium text-[#646464]", children: t('localLlmLocalLlmTab.enableLocalLlm') }), jsx(TooltipProvider, { children: jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { "aria-label": t('localLlmLocalLlmTab.moreInfoAriaLabel'), className: "hidden sm:block", children: jsx(Info$3, { className: "h-4 w-4 text-gray-400" }) }), jsx(TooltipContent, { className: "rounded-lg bg-gray-700 px-3 py-2 text-sm font-medium max-w-xs text-white shadow-sm transition-opacity duration-300 z-50", children: jsxs("div", { className: "space-y-2", children: [jsx("p", { children: t('localLlmLocalLlmTab.tooltipWorkOffline') }), (foundryStatus === null || foundryStatus === void 0 ? void 0 : foundryStatus.is_supported) && (jsx("p", { className: "text-xs text-gray-300", children: t('localLlmLocalLlmTab.tooltipFoundrySupported') }))] }) })] }) })] }), jsxs("div", { className: "flex items-center gap-2", children: [isManagerInstalling && !isUsingFoundry && (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin text-blue-500", "aria-label": t('localLlmLocalLlmTab.startingModelManagerAriaLabel') })), jsx(Switch, { checked: switchChecked, onCheckedChange: handleToggle, disabled: switchDisabled, "aria-label": t('localLlmLocalLlmTab.switchAriaLabel', {
90732
+ state: switchChecked
90733
+ ? t('localLlmLocalLlmTab.switchStateEnabled')
90734
+ : t('localLlmLocalLlmTab.switchStateDisabled'),
90735
+ }), className: "cursor-pointer data-[state=checked]:bg-blue-500" })] })] }), shouldShowFoundryInstall ? (jsx("div", { className: "rounded-lg border px-6 py-4 bg-blue-50/30 dark:bg-blue-950/10", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs("div", { className: "space-y-4", children: [jsx("div", { className: "flex items-start gap-3", children: jsxs("div", { className: "flex items-center gap-2 flex-shrink-0 mt-0.5", children: [jsx(Star$1, { className: "h-5 w-5 text-blue-600 fill-blue-600" }), jsx("span", { className: "px-2 py-0.5 text-xs font-semibold bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300 rounded-full", children: t('localLlmLocalLlmTab.preferredBadge') })] }) }), jsxs("div", { className: "flex items-start gap-3", children: [jsx(Info$3, { className: "h-5 w-5 text-blue-500 flex-shrink-0 mt-0.5" }), jsxs("div", { className: "flex-1", children: [jsx("h3", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: t('localLlmLocalLlmTab.settingUpOfflineAi') }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: t('localLlmLocalLlmTab.foundryInstallDescription') })] })] }), state.status === 'downloading' || state.status === 'checking' ? (jsxs("div", { className: "space-y-2", children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx(LoaderCircle, { className: "h-4 w-4 animate-spin text-blue-500" }), jsx("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: state.message || t('localLlmLocalLlmTab.preparingDownload') })] }), state.progress > 0 && jsx(Progress, { value: state.progress, className: "h-2" })] })) : state.status === 'error' ? (jsxs("div", { className: "space-y-2", children: [jsxs("div", { className: "flex items-center gap-2 text-red-600 dark:text-red-400", children: [jsx(CircleX, { className: "h-4 w-4" }), jsx("span", { className: "text-sm", children: state.error || t('localLlmLocalLlmTab.downloadFailed') })] }), jsx("div", { className: "flex gap-2", children: jsxs(Button$1, { onClick: onInstallFoundry, size: "sm", variant: "outline", children: [jsx(RefreshCw, { className: "h-4 w-4 mr-2" }), t('localLlmLocalLlmTab.tryAgain')] }) })] })) : (jsx("div", { className: "space-y-2", children: jsxs("div", { className: "flex items-center gap-2", children: [jsx(LoaderCircle, { className: "h-4 w-4 animate-spin text-blue-500" }), jsx("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: t('localLlmLocalLlmTab.startingDownload') })] }) })), jsxs("div", { className: "text-xs text-gray-500 dark:text-gray-400", children: [jsx("p", { className: "font-medium mb-1", children: t('localLlmLocalLlmTab.downloadSize') }), jsx("p", { children: t('localLlmLocalLlmTab.oneTimeSetup') })] })] }) })) : /* Requirements Table - Hidden when using Foundry Local */ !isUsingFoundry ? (jsxs(Fragment$1, { children: [(foundryStatus === null || foundryStatus === void 0 ? void 0 : foundryStatus.is_supported) && (jsx("div", { className: "rounded-lg border px-4 py-3 bg-blue-50/20 dark:bg-blue-950/10", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs("div", { className: "flex items-start gap-2", children: [jsx(Info$3, { className: "h-4 w-4 text-blue-600 flex-shrink-0 mt-0.5" }), jsxs("div", { className: "text-xs text-gray-600 dark:text-gray-400", children: [jsx("span", { className: "font-medium text-gray-900 dark:text-gray-100", children: t('localLlmLocalLlmTab.noteLabel') }), ' ', t('localLlmLocalLlmTab.foundryAlternativeNote')] })] }) })), localModelsEnabled && (jsxs("div", { className: "rounded-lg border px-6 py-4", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsxs("div", { className: "flex items-center gap-3", children: [jsx(Server, { className: "h-5 w-5 text-gray-400", "aria-hidden": "true" }), jsxs("div", { children: [jsx("div", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: t('localLlmLocalLlmTab.modelManagerName') }), jsx("div", { className: "text-xs text-gray-500 dark:text-gray-400", children: t('localLlmLocalLlmTab.modelManagerDescription') })] })] }), jsx("div", { className: "flex items-center gap-2", children: managerRunning ? (jsxs(Fragment$1, { children: [jsxs("span", { className: "inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300 rounded-full", children: [jsx(CircleCheckBig, { className: "h-3 w-3" }), t('localLlmLocalLlmTab.running')] }), jsx(Button$1, { onClick: onCheckStatus, variant: "ghost", size: "sm", "aria-label": t('localLlmLocalLlmTab.refreshManagerStatusAriaLabel'), children: jsx(RefreshCw, { className: "h-4 w-4" }) })] })) : (jsxs(Fragment$1, { children: [jsxs("span", { className: "inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300 rounded-full", children: [jsx(LoaderCircle, { className: "h-3 w-3 animate-spin" }), t('localLlmLocalLlmTab.starting')] }), jsx(Button$1, { onClick: onCheckStatus, variant: "ghost", size: "sm", "aria-label": t('localLlmLocalLlmTab.refreshManagerStatusAriaLabel'), children: jsx(RefreshCw, { className: "h-4 w-4" }) })] })) })] }), isManagerInstalling && (jsx("div", { className: "mt-3 w-full max-w-[240px]", children: jsx(Progress, { value: state.managerInstallProgress || 0, className: "h-1.5" }) }))] }))] })) : (jsx("div", { className: "rounded-lg border px-6 py-4 bg-green-50/30 dark:bg-green-950/10", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs("div", { className: "space-y-4", children: [jsx("div", { className: "flex items-center justify-between", children: jsxs("div", { className: "flex items-center gap-3", children: [jsx(CircleCheckBig, { className: "h-8 w-8 text-green-500 flex-shrink-0" }), jsxs("div", { className: "flex-1", children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("h3", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: t('localLlmLocalLlmTab.offlineAiReady') }), jsxs("span", { className: "inline-flex items-center gap-1 px-2 py-0.5 text-xs font-semibold bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300 rounded-full", children: [jsx(Star$1, { className: "h-3 w-3 fill-blue-700 dark:fill-blue-300" }), t('localLlmLocalLlmTab.preferredBadge')] })] }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: t('localLlmLocalLlmTab.foundryReadyDescription') })] })] }) }), foundryModels.length > 0 && (jsxs("div", { className: "space-y-2", children: [jsx("label", { className: "text-xs font-medium text-gray-700 dark:text-gray-300", children: t('localLlmLocalLlmTab.selectModelLabel') }), jsxs(Select$1, { value: selectedFoundryModel || ((_b = foundryModels[0]) === null || _b === void 0 ? void 0 : _b.id), onValueChange: (value) => onSelectFoundryModel === null || onSelectFoundryModel === void 0 ? void 0 : onSelectFoundryModel(value), children: [jsx(SelectTrigger, { className: "w-full bg-gray-50 border-gray-200 dark:bg-gray-800 dark:border-gray-700", children: jsx(SelectValue, { placeholder: t('localLlmLocalLlmTab.selectModelPlaceholder') }) }), jsx(SelectContent, { children: foundryModels.map((model) => (jsx(SelectItem, { value: model.id, children: jsxs("div", { className: "flex items-center justify-between w-full gap-4", children: [jsx("span", { className: "font-medium", children: model.name || model.id }), jsxs("div", { className: "flex items-center gap-2 text-xs text-gray-500", children: [model.device && (jsx("span", { className: "px-2 py-0.5 bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300 rounded", children: model.device })), model.size && jsx("span", { children: model.size }), !model.is_downloaded && (jsx("span", { className: "px-2 py-0.5 bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-300 rounded", children: t('localLlmLocalLlmTab.notDownloaded') })), model.is_downloaded && (jsx("span", { className: "px-2 py-0.5 bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300 rounded", children: t('localLlmLocalLlmTab.downloaded') }))] })] }) }, model.id))) })] }), jsxs("div", { className: "flex flex-col gap-1", children: [jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: t('localLlmLocalLlmTab.modelsAvailable', { count: foundryModels.length }) }), selectedFoundryModel && (jsxs("div", { className: "flex items-center gap-1.5 text-xs text-green-600 dark:text-green-400", children: [jsx(CircleCheckBig, { className: "h-3.5 w-3.5" }), jsxs("span", { children: [t('localLlmLocalLlmTab.usingModelPrefix'), ' ', ((_c = foundryModels.find((m) => m.id === selectedFoundryModel)) === null || _c === void 0 ? void 0 : _c.name) ||
90736
+ selectedFoundryModel, ((_d = foundryModels.find((m) => m.id === selectedFoundryModel)) === null || _d === void 0 ? void 0 : _d.device) && (jsxs("span", { className: "ml-1 text-gray-500 dark:text-gray-400", children: ["(", (_e = foundryModels.find((m) => m.id === selectedFoundryModel)) === null || _e === void 0 ? void 0 : _e.device, ")"] }))] })] }))] })] })), state.status === 'downloading' && (jsxs("div", { className: "mt-4 p-4 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg", children: [jsxs("div", { className: "flex items-center gap-3", children: [jsx("div", { className: "animate-spin h-5 w-5 border-2 border-blue-600 dark:border-blue-400 border-t-transparent rounded-full" }), jsxs("div", { className: "flex-1", children: [jsx("p", { className: "text-sm font-medium text-blue-900 dark:text-blue-100", children: state.message }), state.progress > 0 && (jsx("div", { className: "mt-2 w-full bg-blue-200 dark:bg-blue-800 rounded-full h-2", children: jsx("div", { className: "bg-blue-600 dark:bg-blue-400 h-2 rounded-full transition-all duration-300", style: { width: `${state.progress}%` } }) }))] })] }), state.logs.length > 0 && (jsx("div", { className: "mt-3 max-h-32 overflow-y-auto bg-white dark:bg-gray-800 rounded border border-blue-200 dark:border-blue-700 p-2", children: state.logs.slice(-10).map((log, idx) => (jsx("div", { className: `text-xs font-mono ${log.level === 'error'
90737
+ ? 'text-red-600 dark:text-red-400'
90738
+ : log.level === 'warn'
90739
+ ? 'text-yellow-600 dark:text-yellow-400'
90740
+ : 'text-gray-700 dark:text-gray-300'}`, children: log.message }, idx))) }))] }))] }) }))] }) }));
90634
90741
  }
90635
90742
 
90636
90743
  function LocalModelsContent(props) {
@@ -90641,195 +90748,6 @@ function LocalModelsContent(props) {
90641
90748
  return (jsxs("div", { className: "rounded-lg px-6 py-5 border border-gray-200 dark:border-gray-700", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex items-center justify-between", children: [jsxs("div", { className: "flex items-center gap-3", children: [jsx("span", { className: "text-sm font-medium text-[#646464]", children: "Local Models" }), jsx(TooltipProvider, { children: jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { "aria-label": "More info about Local Models", className: "hidden sm:block", children: jsx(Info$3, { className: "h-4 w-4 text-gray-400" }) }), jsx(TooltipContent, { className: "rounded-lg bg-gray-700 px-3 py-2 text-sm font-medium max-w-xs text-white shadow-sm transition-opacity duration-300 z-50", children: jsx("p", { children: "Manage on-device AI models for offline use." }) })] }) })] }), jsx("button", { type: "button", onClick: () => setIsCollapsed((previous) => !previous), className: "p-1 rounded hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-1", "aria-label": isCollapsed ? 'Expand Local Models' : 'Collapse Local Models', children: isCollapsed ? (jsx(ChevronDown, { className: "h-5 w-5 text-gray-400", "aria-hidden": "true" })) : (jsx(ChevronUp, { className: "h-5 w-5 text-gray-400", "aria-hidden": "true" })) })] }), !isCollapsed && (jsx("div", { className: "mt-4", children: jsx(LocalLLMTab, { ...props }) }))] }));
90642
90749
  }
90643
90750
 
90644
- const SYSTEM_CONTROL_ENABLED_KEY = 'ibl_system_control_enabled';
90645
- /**
90646
- * Whether the Computer Assistant is enabled, read from localStorage. This is a
90647
- * user preference (mirrors {@link isLocalLLMEnabled}); it reflects the toggle the
90648
- * user last chose, independent of whether the helper is installed yet.
90649
- */
90650
- function isSystemControlEnabled() {
90651
- if (typeof window === 'undefined')
90652
- return false;
90653
- return localStorage.getItem(SYSTEM_CONTROL_ENABLED_KEY) === 'true';
90654
- }
90655
- /**
90656
- * Persist the Computer Assistant enabled preference to localStorage.
90657
- */
90658
- function setSystemControlEnabled(enabled) {
90659
- if (typeof window === 'undefined')
90660
- return;
90661
- localStorage.setItem(SYSTEM_CONTROL_ENABLED_KEY, String(enabled));
90662
- }
90663
- /** Green "done" pill. */
90664
- function DonePill({ children }) {
90665
- return (jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-green-100 px-2 py-0.5 text-xs font-medium text-green-800 dark:bg-green-900/30 dark:text-green-300", children: [jsx(Check, { className: "h-3 w-3" }), children] }));
90666
- }
90667
- /** Blue "in progress" pill. */
90668
- function WorkingPill({ children }) {
90669
- return (jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-blue-100 px-2 py-0.5 text-xs font-medium text-blue-800 dark:bg-blue-900/30 dark:text-blue-300", children: [jsx(LoaderCircle, { className: "h-3 w-3 animate-spin" }), children] }));
90670
- }
90671
- /** A single numbered step row. */
90672
- function Step$2({ number, done, title, description, action, }) {
90673
- return (jsxs("div", { className: "flex items-start justify-between gap-3", children: [jsxs("div", { className: "flex items-start gap-3", children: [jsx("span", { className: `flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full text-xs font-semibold ${done
90674
- ? 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300'
90675
- : 'bg-gray-100 text-gray-500 dark:bg-gray-800 dark:text-gray-400'}`, "aria-hidden": "true", children: done ? jsx(Check, { className: "h-3.5 w-3.5" }) : number }), jsxs("div", { children: [jsx("div", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: title }), jsx("div", { className: "mt-0.5 text-xs text-gray-500 dark:text-gray-400", children: description })] })] }), jsx("div", { className: "flex-shrink-0", children: action })] }));
90676
- }
90677
- /**
90678
- * Body of the "Computer Assistant" card: a plain-language on/off with two simple
90679
- * steps — set up, then allow control — so non-technical users can follow along.
90680
- * Mirrors the Local Models tab so the two cards behave the same.
90681
- */
90682
- function SystemControlTab({ isAvailable, state, status, requiredSizeGb = DEFAULT_SYSTEM_CONTROL_REQUIRED_SIZE_GB, ollamaStatus, systemMemory, accessibilityPermission, onInstall, onStop, onCheckStatus, onResetState, onRequestAccessibilityPermission, onDownloadModel, }) {
90683
- const isInstalling = state.status === 'installing' || (status === null || status === void 0 ? void 0 : status.installing) === true;
90684
- // User preference — independent of whether the helper is installed. Always
90685
- // operable so the user can turn it off again.
90686
- const [isEnabled, setIsEnabled] = useState(() => isSystemControlEnabled());
90687
- // The currently-selected local model (persisted by the Local Models card).
90688
- // Polled so a selection change in the sibling card is reflected here without a
90689
- // remount. The assistant only works well with larger models, so it's gated to
90690
- // a selected model above the size threshold.
90691
- const [selectedModel, setSelectedModel] = useState(() => getLocalLLMModel());
90692
- // Whether "Local Models" is turned on. The assistant runs on a local model, so
90693
- // it's gated off until Local Models is enabled. Polled alongside the model so a
90694
- // toggle in the sibling card is reflected without a remount.
90695
- const [localModelsEnabled, setLocalModelsEnabled] = useState(() => isLocalLLMEnabled());
90696
- useEffect(() => {
90697
- const id = setInterval(() => {
90698
- setSelectedModel(getLocalLLMModel());
90699
- setLocalModelsEnabled(isLocalLLMEnabled());
90700
- }, 1500);
90701
- return () => clearInterval(id);
90702
- }, []);
90703
- const localModelsOff = !localModelsEnabled;
90704
- const modelTooSmall = !modelSupportsSystemControl(selectedModel, requiredSizeGb);
90705
- // "Upgrade" target: the smallest catalog model that clears the size gate.
90706
- const upgradeTarget = smallestSystemControlModel(requiredSizeGb);
90707
- // Set while an upgrade is downloading a model, before we auto-enable.
90708
- const [pendingEnableModelId, setPendingEnableModelId] = useState(null);
90709
- // Model awaiting a RAM/VRAM "may be too large" confirmation before download.
90710
- const [pendingCapacityModel, setPendingCapacityModel] = useState(null);
90711
- const isUpgrading = pendingEnableModelId !== null;
90712
- const managerRunning = (status === null || status === void 0 ? void 0 : status.running) === true;
90713
- // Steps are shown whenever the toggle is on (or mid-setup), so the user always
90714
- // gets feedback for their choice.
90715
- const managerEnabled = isEnabled || isInstalling;
90716
- // Permission is known (macOS + plugin wired) and granted.
90717
- const permissionKnown = typeof accessibilityPermission === 'boolean';
90718
- const permissionGranted = accessibilityPermission === true;
90719
- const allSet = managerRunning && (!permissionKnown || permissionGranted);
90720
- // Keep the app-facing preference flag in sync with the toggle.
90721
- useEffect(() => {
90722
- setSystemControlEnabled(isEnabled);
90723
- }, [isEnabled]);
90724
- // While enabled but not yet running, keep polling so the step flips to "Ready"
90725
- // as soon as the host reports the helper is up.
90726
- useEffect(() => {
90727
- if (!isEnabled || managerRunning)
90728
- return;
90729
- const id = setInterval(() => onCheckStatus(), 2500);
90730
- return () => clearInterval(id);
90731
- }, [isEnabled, managerRunning, onCheckStatus]);
90732
- // While permission isn't granted yet, keep re-checking (the grant happens in
90733
- // System Settings) so the step flips to "Allowed" on its own.
90734
- useEffect(() => {
90735
- if (accessibilityPermission !== false)
90736
- return;
90737
- const id = setInterval(() => onCheckStatus(), 2500);
90738
- return () => clearInterval(id);
90739
- }, [accessibilityPermission, onCheckStatus]);
90740
- // After an upgrade kicks off a download, turn the assistant on once the model
90741
- // finishes downloading (it shows up in the installed list).
90742
- useEffect(() => {
90743
- if (!pendingEnableModelId)
90744
- return;
90745
- if (isModelInstalled(pendingEnableModelId, ollamaStatus === null || ollamaStatus === void 0 ? void 0 : ollamaStatus.installed_models)) {
90746
- setPendingEnableModelId(null);
90747
- setIsEnabled(true);
90748
- onInstall();
90749
- }
90750
- }, [pendingEnableModelId, ollamaStatus, onInstall]);
90751
- if (!isAvailable) {
90752
- return (jsx("div", { className: "text-sm text-gray-500 dark:text-gray-400", children: "The Computer Assistant is only available in the desktop app." }));
90753
- }
90754
- const handleToggle = (checked) => {
90755
- // Guard: needs Local Models on and a large-enough model.
90756
- if (checked && (localModelsOff || modelTooSmall))
90757
- return;
90758
- setIsEnabled(checked);
90759
- if (checked) {
90760
- if (!isInstalling)
90761
- onInstall();
90762
- }
90763
- else {
90764
- onStop === null || onStop === void 0 ? void 0 : onStop();
90765
- }
90766
- };
90767
- // Upgrade = switch to the smallest usable model: select it, then (if it isn't
90768
- // already downloaded) download it and auto-enable the assistant once it's
90769
- // ready. The RAM/VRAM check is preserved via the confirm below.
90770
- const runUpgrade = (model) => {
90771
- setLocalLLMModel(model.id);
90772
- setLocalLLMToolSupport(model.tool_support);
90773
- setLocalLLMEnabled(true);
90774
- setSelectedModel(model.id); // recompute the size gate immediately
90775
- if (isModelInstalled(model.id, ollamaStatus === null || ollamaStatus === void 0 ? void 0 : ollamaStatus.installed_models)) {
90776
- // Already downloaded → enable now.
90777
- setIsEnabled(true);
90778
- if (!isInstalling)
90779
- onInstall();
90780
- }
90781
- else {
90782
- // Not downloaded → download, then auto-enable when it lands (effect above).
90783
- setPendingEnableModelId(model.id);
90784
- onDownloadModel === null || onDownloadModel === void 0 ? void 0 : onDownloadModel(model.id);
90785
- }
90786
- };
90787
- const handleUpgrade = () => {
90788
- if (!upgradeTarget)
90789
- return;
90790
- // Keep the RAM/VRAM check: confirm before pulling a model that may not fit.
90791
- if (modelExceedsCapacity(upgradeTarget, systemMemory)) {
90792
- setPendingCapacityModel(upgradeTarget);
90793
- return;
90794
- }
90795
- runUpgrade(upgradeTarget);
90796
- };
90797
- const switchChecked = isEnabled;
90798
- const switchDisabled = isInstalling ||
90799
- state.status === 'checking' ||
90800
- ((localModelsOff || modelTooSmall) && !isEnabled);
90801
- return (jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between gap-4 rounded-lg border px-6 py-4", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { children: [jsx("div", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "Let your assistant control this computer" }), jsx("div", { className: "mt-0.5 text-xs text-gray-500 dark:text-gray-400", children: "It can click, type, and open apps to do tasks for you. You stay in control and can turn this off anytime." })] }), jsxs("div", { className: "flex flex-shrink-0 items-center gap-2", children: [isInstalling && (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin text-blue-500", "aria-label": "Setting up" })), jsx(Switch, { checked: switchChecked, onCheckedChange: handleToggle, disabled: switchDisabled, "aria-label": "Let your assistant control this computer", className: "cursor-pointer data-[state=checked]:bg-blue-500" })] })] }), localModelsOff && (jsxs("div", { className: "flex items-start gap-2 rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 dark:border-amber-900/40 dark:bg-amber-900/10", children: [jsx(Info$3, { className: "mt-0.5 h-4 w-4 flex-shrink-0 text-amber-600", "aria-hidden": "true" }), jsx("p", { className: "text-xs text-amber-800 dark:text-amber-300", children: "Turn on \u201CLocal Models\u201D above first \u2014 the Computer Assistant uses a local AI model to do its work." })] })), !localModelsOff && modelTooSmall && (jsxs("div", { className: "flex items-start gap-2 rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 dark:border-amber-900/40 dark:bg-amber-900/10", children: [jsx(Info$3, { className: "mt-0.5 h-4 w-4 flex-shrink-0 text-amber-600", "aria-hidden": "true" }), jsxs("div", { className: "flex-1", children: [jsxs("p", { className: "text-xs text-amber-800 dark:text-amber-300", children: ["Your current AI model is too small for this.", ' ', upgradeTarget && onDownloadModel
90802
- ? `Upgrade to ${upgradeTarget.name} (${upgradeTarget.size}) to use it.`
90803
- : 'Pick a larger one under “Local Models” above, then come back.'] }), upgradeTarget && onDownloadModel && (jsx(Button$1, { onClick: handleUpgrade, size: "sm", className: "mt-2", disabled: isUpgrading, "aria-label": `Upgrade to ${upgradeTarget.name}`, children: isUpgrading ? (jsxs(Fragment$1, { children: [jsx(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), "Upgrading\u2026"] })) : (jsxs(Fragment$1, { children: [jsx(CircleArrowUp, { className: "mr-2 h-4 w-4" }), "Upgrade to ", upgradeTarget.name] })) }))] })] })), isUpgrading && !modelTooSmall && (jsxs("div", { className: "flex items-start gap-2 rounded-lg border px-4 py-3", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx(LoaderCircle, { className: "mt-0.5 h-4 w-4 flex-shrink-0 animate-spin text-blue-500", "aria-hidden": "true" }), jsx("p", { className: "text-xs text-gray-600 dark:text-gray-300", children: "Downloading your new model\u2026 it\u2019ll turn on automatically when it\u2019s ready. You can watch progress under \u201CLocal Models\u201D above." })] })), managerEnabled && (jsxs("div", { className: "space-y-4 rounded-lg border px-6 py-5", style: { borderColor: 'oklch(.922 0 0)' }, children: [allSet ? (jsxs("div", { className: "flex items-start gap-2", children: [jsx(Check, { className: "mt-0.5 h-4 w-4 flex-shrink-0 text-green-600", "aria-hidden": "true" }), jsx("p", { className: "text-sm text-gray-700 dark:text-gray-300", children: "You\u2019re all set \u2014 your assistant can now help out on this computer." })] })) : (jsx("div", { className: "text-xs font-medium uppercase tracking-wide text-gray-400", children: "A couple of quick steps" })), jsx(Step$2, { number: 1, done: managerRunning, title: "Set up your assistant", description: "A quick, one-time setup so it can work on this computer.", action: managerRunning ? (jsx(DonePill, { children: "Ready" })) : (jsx(WorkingPill, { children: isInstalling ? 'Setting up…' : 'Starting…' })) }), (state.status === 'installing' || state.status === 'checking') && state.progress > 0 && (jsx(Progress, { value: state.progress, className: "h-1.5" })), permissionKnown && (jsx(Step$2, { number: 2, done: permissionGranted, title: "Allow it to control the computer", description: "Your Mac will ask you to confirm. This lets your assistant move the mouse and type for you.", action: permissionGranted ? (jsx(DonePill, { children: "Allowed" })) : onRequestAccessibilityPermission ? (jsx(Button$1, { onClick: onRequestAccessibilityPermission, size: "sm", "aria-label": "Allow your assistant to control the computer", children: "Allow" })) : (jsx("span", { className: "inline-flex items-center rounded-full bg-amber-100 px-2 py-0.5 text-xs font-medium text-amber-800 dark:bg-amber-900/30 dark:text-amber-300", children: "Needed" })) }))] })), state.status === 'error' && (jsxs("div", { className: "rounded-lg border border-red-200 bg-red-50 px-4 py-3 dark:border-red-900/40 dark:bg-red-900/10", children: [jsxs("div", { className: "flex items-center gap-2 text-sm text-red-700 dark:text-red-300", children: [jsx(CircleX, { className: "h-4 w-4 flex-shrink-0" }), jsx("span", { children: "Something went wrong while setting up. Please try again." })] }), jsxs(Button$1, { onClick: () => {
90804
- onResetState();
90805
- onInstall();
90806
- }, size: "sm", variant: "outline", className: "mt-3", children: [jsx(RefreshCw, { className: "mr-2 h-4 w-4" }), "Try again"] })] })), jsx(AlertDialog, { open: pendingCapacityModel !== null, onOpenChange: (open) => {
90807
- if (!open)
90808
- setPendingCapacityModel(null);
90809
- }, children: jsxs(AlertDialogContent, { children: [jsxs(AlertDialogHeader, { children: [jsx(AlertDialogTitle, { children: "This model may be large for your computer" }), jsxs(AlertDialogDescription, { children: [pendingCapacityModel === null || pendingCapacityModel === void 0 ? void 0 : pendingCapacityModel.name, " (", pendingCapacityModel === null || pendingCapacityModel === void 0 ? void 0 : pendingCapacityModel.size, ") may be more than your computer\u2019s memory can handle, so it could run slowly or fail to load. Download and use it anyway?"] })] }), jsxs(AlertDialogFooter, { children: [jsx(AlertDialogCancel, { children: "Cancel" }), jsx(AlertDialogAction, { onClick: () => {
90810
- const model = pendingCapacityModel;
90811
- setPendingCapacityModel(null);
90812
- if (model)
90813
- runUpgrade(model);
90814
- }, children: "Download anyway" })] })] }) })] }));
90815
- }
90816
-
90817
- /**
90818
- * Collapsible "System Control" card for the UserProfile → Advanced section.
90819
- * Mirrors {@link LocalModelsContent}: a purely presentational, titled,
90820
- * collapsible container whose body is the {@link SystemControlTab}. Availability
90821
- * and handlers are threaded in (see UserProfileDropdown, which falls back to
90822
- * {@link useGhostOs} when the host doesn't supply them). Renders nothing outside
90823
- * the desktop app.
90824
- */
90825
- function SystemControlContent(props) {
90826
- const [isCollapsed, setIsCollapsed] = useState(true);
90827
- if (!props.isAvailable) {
90828
- return null;
90829
- }
90830
- return (jsxs("div", { className: "rounded-lg px-6 py-5 border border-gray-200 dark:border-gray-700", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex items-center justify-between", children: [jsxs("div", { className: "flex items-center gap-3", children: [jsx("span", { className: "text-sm font-medium text-[#646464]", children: "Computer Assistant" }), jsx(TooltipProvider, { children: jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { "aria-label": "More info about the Computer Assistant", className: "hidden sm:block", children: jsx(Info$3, { className: "h-4 w-4 text-gray-400" }) }), jsx(TooltipContent, { className: "rounded-lg bg-gray-700 px-3 py-2 text-sm font-medium max-w-xs text-white shadow-sm transition-opacity duration-300 z-50", children: jsx("p", { children: "Let your assistant do things on your computer \u2014 click, type, and open apps. You stay in control and can turn it off anytime." }) })] }) })] }), jsx("button", { type: "button", onClick: () => setIsCollapsed((previous) => !previous), className: "p-1 rounded hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-1", "aria-label": isCollapsed ? 'Expand Computer Assistant' : 'Collapse Computer Assistant', children: isCollapsed ? (jsx(ChevronDown, { className: "h-5 w-5 text-gray-400", "aria-hidden": "true" })) : (jsx(ChevronUp, { className: "h-5 w-5 text-gray-400", "aria-hidden": "true" })) })] }), !isCollapsed && (jsx("div", { className: "mt-4", children: jsx(SystemControlTab, { ...props }) }))] }));
90831
- }
90832
-
90833
90751
  // src/primitive.tsx
90834
90752
  var NODES = [
90835
90753
  "a",
@@ -141411,6 +141329,26 @@ function ChatPrivacyTab({ org, username }) {
141411
141329
  }) })] }));
141412
141330
  }
141413
141331
 
141332
+ const COWORK_ENABLED_KEY = 'ibl_cowork_enabled';
141333
+ /**
141334
+ * Whether Cowork is enabled, read from localStorage. This is a user preference
141335
+ * (mirrors isLocalLLMEnabled); it reflects the toggle the user last chose,
141336
+ * independent of whether the assistant is installed yet.
141337
+ */
141338
+ function isCoworkEnabled() {
141339
+ if (typeof window === 'undefined')
141340
+ return false;
141341
+ return localStorage.getItem(COWORK_ENABLED_KEY) === 'true';
141342
+ }
141343
+ /**
141344
+ * Persist the Cowork enabled preference to localStorage.
141345
+ */
141346
+ function setCoworkEnabled(enabled) {
141347
+ if (typeof window === 'undefined')
141348
+ return;
141349
+ localStorage.setItem(COWORK_ENABLED_KEY, String(enabled));
141350
+ }
141351
+
141414
141352
  const renderLucideIcon = (Icon) => function RenderedIcon(props) {
141415
141353
  return jsx(Icon, { ...props });
141416
141354
  };
@@ -141437,7 +141375,7 @@ const TAB_DESC_PREVIEW_KEYS = {
141437
141375
  memory: 'descMemoryPreview',
141438
141376
  privacy: 'descPrivacyPreview',
141439
141377
  };
141440
- function Profile({ tenant, username, tenants, onClose, customization = {}, isAdmin = false, targetTab = 'basic', onAccountDeleted, enableMemoryTab = false, localLLMProps, systemControlProps, currentSPA = '', }) {
141378
+ function Profile({ tenant, username, tenants, onClose, customization = {}, isAdmin = false, targetTab = 'basic', onAccountDeleted, enableMemoryTab = false, localLLMProps, currentSPA = '', }) {
141441
141379
  var _a, _b, _c, _d, _e, _f, _g, _h;
141442
141380
  const t = useT();
141443
141381
  const { data: memsearchStatus, isError: isMemsearchStatusError } = useGetMemsearchStatusQuery({ org: tenant, userId: username }, { skip: !enableMemoryTab });
@@ -141514,9 +141452,8 @@ function Profile({ tenant, username, tenants, onClose, customization = {}, isAdm
141514
141452
  ]
141515
141453
  : []),
141516
141454
  ];
141517
- // Add Advanced tab only when in Tauri app (Local Models or System Control is
141518
- // provided and available)
141519
- const isAdvancedAvailable = (localLLMProps === null || localLLMProps === void 0 ? void 0 : localLLMProps.isAvailable) === true || (systemControlProps === null || systemControlProps === void 0 ? void 0 : systemControlProps.isAvailable) === true;
141455
+ // Add Advanced tab only when in Tauri app (Local Models is provided and available)
141456
+ const isAdvancedAvailable = (localLLMProps === null || localLLMProps === void 0 ? void 0 : localLLMProps.isAvailable) === true;
141520
141457
  const TABS = isAdvancedAvailable
141521
141458
  ? [
141522
141459
  ...baseTabs,
@@ -141682,7 +141619,7 @@ function Profile({ tenant, username, tenants, onClose, customization = {}, isAdm
141682
141619
  var _a;
141683
141620
  return (jsxs(Fragment$1, { children: [jsxs("div", { className: "relative mb-0", children: [jsx("div", { className: "absolute inset-y-0 left-4 flex items-center pointer-events-none", "aria-hidden": "true", children: jsx("div", { className: "bg-black text-white rounded w-8 h-8 flex items-center justify-center", children: jsx("span", { className: "font-bold text-sm", children: "X" }) }) }), jsx(Input, { id: "x", className: "w-full bg-gray-50 border-gray-200 focus:ring-blue-500 focus:border-blue-500 text-base py-3 pl-16 h-10", placeholder: t('profileIndex.placeholderX'), value: field.state.value, onChange: (e) => handleSocialLinkChange(e.target.value, field.handleChange, X_URL_PREFIX), disabled: socialForm.state.isSubmitting || isReadOnly })] }), jsx("p", { className: "text-red-500 dark:text-gray-400 text-sm", role: ((_a = field.state.meta.errors) === null || _a === void 0 ? void 0 : _a.length) ? 'alert' : undefined, "aria-live": "polite", children: field.state.meta.errors })] }));
141684
141621
  },
141685
- })] })] }) })), activeTab === 'education' && (jsxs(Tabs, { value: educationSubTab, onValueChange: setEducationSubTab, className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsxs(TabsList, { children: [jsx(TabsTrigger, { value: "education", children: t('profileIndex.tabEducation') }), jsx(TabsTrigger, { value: "credentials", children: t('gradebookGradebookTab.typeCredentials') }), jsx(TabsTrigger, { value: "skills", children: t('gradebookGradebookTab.typeSkills') })] }), headerAddButton] }), jsx(TabsContent, { value: "education", children: jsx(EducationTab, { org: tenant, username: username }) }), jsx(TabsContent, { value: "credentials", children: jsx(CredentialsList, { org: tenant, username: username }) }), jsx(TabsContent, { value: "skills", children: jsx(SkillsList, { org: tenant, username: username }) })] })), activeTab === 'gradebook' && jsx(GradebookTab, { org: tenant, username: username }), activeTab === 'experience' && (jsxs(Tabs, { value: experienceSubTab, onValueChange: setExperienceSubTab, className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsxs(TabsList, { children: [jsx(TabsTrigger, { value: "experience", children: t('profileIndex.tabExperience') }), jsx(TabsTrigger, { value: "resume", children: t('profileIndex.tabResume') })] }), headerAddButton] }), jsx(TabsContent, { value: "experience", children: jsx(ExperienceTab, { org: tenant, username: username }) }), jsx(TabsContent, { value: "resume", children: jsx(ResumeTab, { org: tenant, username: username }) })] })), activeTab === 'purchases' && jsx(PurchasesTab, { org: tenant, username: username }), activeTab === 'memory' && jsx(MemoryTab, { org: tenant, username: username }), activeTab === 'privacy' && jsx(ChatPrivacyTab, { org: tenant, username: username }), !isReadOnly && activeTab === 'security' && (jsx(Security, { app: currentSPA || '', email: (userMetadata === null || userMetadata === void 0 ? void 0 : userMetadata.email) || '', platformKey: tenant, onAccountDeleted: onAccountDeleted })), activeTab === 'advanced' && (localLLMProps || systemControlProps) && (jsxs("div", { className: "space-y-6", children: [localLLMProps && (jsx(LocalModelsContent, { isAvailable: localLLMProps.isAvailable, state: localLLMProps.state, ollamaStatus: localLLMProps.ollamaStatus, systemMemory: localLLMProps.systemMemory, isUsingFoundry: localLLMProps.isUsingFoundry, foundryModels: localLLMProps.foundryModels, selectedFoundryModel: localLLMProps.selectedFoundryModel, foundryStatus: localLLMProps.foundryStatus, onStartDownload: localLLMProps.onStartDownload, onCancelDownload: localLLMProps.onCancelDownload, onInstallOllama: localLLMProps.onInstallOllama, onStopManager: localLLMProps.onStopManager, onInstallFoundry: localLLMProps.onInstallFoundry, onCheckStatus: localLLMProps.onCheckStatus, onResetState: localLLMProps.onResetState, onSelectFoundryModel: localLLMProps.onSelectFoundryModel })), systemControlProps && (jsx(SystemControlContent, { isAvailable: systemControlProps.isAvailable, state: systemControlProps.state, status: systemControlProps.status, requiredSizeGb: systemControlProps.requiredSizeGb, ollamaStatus: systemControlProps.ollamaStatus, systemMemory: systemControlProps.systemMemory, accessibilityPermission: systemControlProps.accessibilityPermission, onInstall: systemControlProps.onInstall, onStop: systemControlProps.onStop, onCheckStatus: systemControlProps.onCheckStatus, onResetState: systemControlProps.onResetState, onRequestAccessibilityPermission: systemControlProps.onRequestAccessibilityPermission, onDownloadModel: systemControlProps.onDownloadModel }))] }))] }), !isReadOnly && ['basic', 'social'].includes(activeTab) && (jsx("div", { className: "flex-shrink-0 border-t border-gray-200 p-6 bg-white dark:bg-gray-900", children: jsxs("div", { className: "flex justify-end gap-3", children: [jsx(Button$1, { onClick: onClose, variant: "outline", children: t('profileIndex.buttonCancel') }), jsx(Button$1, { onClick: () => {
141622
+ })] })] }) })), activeTab === 'education' && (jsxs(Tabs, { value: educationSubTab, onValueChange: setEducationSubTab, className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsxs(TabsList, { children: [jsx(TabsTrigger, { value: "education", children: t('profileIndex.tabEducation') }), jsx(TabsTrigger, { value: "credentials", children: t('gradebookGradebookTab.typeCredentials') }), jsx(TabsTrigger, { value: "skills", children: t('gradebookGradebookTab.typeSkills') })] }), headerAddButton] }), jsx(TabsContent, { value: "education", children: jsx(EducationTab, { org: tenant, username: username }) }), jsx(TabsContent, { value: "credentials", children: jsx(CredentialsList, { org: tenant, username: username }) }), jsx(TabsContent, { value: "skills", children: jsx(SkillsList, { org: tenant, username: username }) })] })), activeTab === 'gradebook' && jsx(GradebookTab, { org: tenant, username: username }), activeTab === 'experience' && (jsxs(Tabs, { value: experienceSubTab, onValueChange: setExperienceSubTab, className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsxs(TabsList, { children: [jsx(TabsTrigger, { value: "experience", children: t('profileIndex.tabExperience') }), jsx(TabsTrigger, { value: "resume", children: t('profileIndex.tabResume') })] }), headerAddButton] }), jsx(TabsContent, { value: "experience", children: jsx(ExperienceTab, { org: tenant, username: username }) }), jsx(TabsContent, { value: "resume", children: jsx(ResumeTab, { org: tenant, username: username }) })] })), activeTab === 'purchases' && jsx(PurchasesTab, { org: tenant, username: username }), activeTab === 'memory' && jsx(MemoryTab, { org: tenant, username: username }), activeTab === 'privacy' && jsx(ChatPrivacyTab, { org: tenant, username: username }), !isReadOnly && activeTab === 'security' && (jsx(Security, { app: currentSPA || '', email: (userMetadata === null || userMetadata === void 0 ? void 0 : userMetadata.email) || '', platformKey: tenant, onAccountDeleted: onAccountDeleted })), activeTab === 'advanced' && localLLMProps && (jsx("div", { className: "space-y-6", children: jsx(LocalModelsContent, { isAvailable: localLLMProps.isAvailable, state: localLLMProps.state, ollamaStatus: localLLMProps.ollamaStatus, systemMemory: localLLMProps.systemMemory, isUsingFoundry: localLLMProps.isUsingFoundry, foundryModels: localLLMProps.foundryModels, selectedFoundryModel: localLLMProps.selectedFoundryModel, foundryStatus: localLLMProps.foundryStatus, onStartDownload: localLLMProps.onStartDownload, onCancelDownload: localLLMProps.onCancelDownload, onInstallOllama: localLLMProps.onInstallOllama, onStopManager: localLLMProps.onStopManager, onInstallFoundry: localLLMProps.onInstallFoundry, onCheckStatus: localLLMProps.onCheckStatus, onResetState: localLLMProps.onResetState, onSelectFoundryModel: localLLMProps.onSelectFoundryModel }) }))] }), !isReadOnly && ['basic', 'social'].includes(activeTab) && (jsx("div", { className: "flex-shrink-0 border-t border-gray-200 p-6 bg-white dark:bg-gray-900", children: jsxs("div", { className: "flex justify-end gap-3", children: [jsx(Button$1, { onClick: onClose, variant: "outline", children: t('profileIndex.buttonCancel') }), jsx(Button$1, { onClick: () => {
141686
141623
  if (activeTab === 'basic') {
141687
141624
  basicForm.handleSubmit();
141688
141625
  }
@@ -143161,11 +143098,11 @@ var PopoverAnchor$1 = React.forwardRef(
143161
143098
  }
143162
143099
  );
143163
143100
  PopoverAnchor$1.displayName = ANCHOR_NAME$1;
143164
- var TRIGGER_NAME$2 = "PopoverTrigger";
143101
+ var TRIGGER_NAME$3 = "PopoverTrigger";
143165
143102
  var PopoverTrigger$1 = React.forwardRef(
143166
143103
  (props, forwardedRef) => {
143167
143104
  const { __scopePopover, ...triggerProps } = props;
143168
- const context = usePopoverContext(TRIGGER_NAME$2, __scopePopover);
143105
+ const context = usePopoverContext(TRIGGER_NAME$3, __scopePopover);
143169
143106
  const popperScope = usePopperScope$1(__scopePopover);
143170
143107
  const composedTriggerRef = useComposedRefs$1(forwardedRef, context.triggerRef);
143171
143108
  const trigger = /* @__PURE__ */ jsx(
@@ -143184,31 +143121,31 @@ var PopoverTrigger$1 = React.forwardRef(
143184
143121
  return context.hasCustomAnchor ? trigger : /* @__PURE__ */ jsx(Anchor$1, { asChild: true, ...popperScope, children: trigger });
143185
143122
  }
143186
143123
  );
143187
- PopoverTrigger$1.displayName = TRIGGER_NAME$2;
143188
- var PORTAL_NAME$2 = "PopoverPortal";
143189
- var [PortalProvider$1, usePortalContext$1] = createPopoverContext(PORTAL_NAME$2, {
143124
+ PopoverTrigger$1.displayName = TRIGGER_NAME$3;
143125
+ var PORTAL_NAME$3 = "PopoverPortal";
143126
+ var [PortalProvider$1, usePortalContext$1] = createPopoverContext(PORTAL_NAME$3, {
143190
143127
  forceMount: void 0
143191
143128
  });
143192
143129
  var PopoverPortal = (props) => {
143193
143130
  const { __scopePopover, forceMount, children, container } = props;
143194
- const context = usePopoverContext(PORTAL_NAME$2, __scopePopover);
143131
+ const context = usePopoverContext(PORTAL_NAME$3, __scopePopover);
143195
143132
  return /* @__PURE__ */ jsx(PortalProvider$1, { scope: __scopePopover, forceMount, children: /* @__PURE__ */ jsx(Presence$2, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(Portal$6, { asChild: true, container, children }) }) });
143196
143133
  };
143197
- PopoverPortal.displayName = PORTAL_NAME$2;
143198
- var CONTENT_NAME$3 = "PopoverContent";
143134
+ PopoverPortal.displayName = PORTAL_NAME$3;
143135
+ var CONTENT_NAME$4 = "PopoverContent";
143199
143136
  var PopoverContent$1 = React.forwardRef(
143200
143137
  (props, forwardedRef) => {
143201
- const portalContext = usePortalContext$1(CONTENT_NAME$3, props.__scopePopover);
143138
+ const portalContext = usePortalContext$1(CONTENT_NAME$4, props.__scopePopover);
143202
143139
  const { forceMount = portalContext.forceMount, ...contentProps } = props;
143203
- const context = usePopoverContext(CONTENT_NAME$3, props.__scopePopover);
143140
+ const context = usePopoverContext(CONTENT_NAME$4, props.__scopePopover);
143204
143141
  return /* @__PURE__ */ jsx(Presence$2, { present: forceMount || context.open, children: context.modal ? /* @__PURE__ */ jsx(PopoverContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx(PopoverContentNonModal, { ...contentProps, ref: forwardedRef }) });
143205
143142
  }
143206
143143
  );
143207
- PopoverContent$1.displayName = CONTENT_NAME$3;
143144
+ PopoverContent$1.displayName = CONTENT_NAME$4;
143208
143145
  var Slot$1 = createSlot$1("PopoverContent.RemoveScroll");
143209
143146
  var PopoverContentModal = React.forwardRef(
143210
143147
  (props, forwardedRef) => {
143211
- const context = usePopoverContext(CONTENT_NAME$3, props.__scopePopover);
143148
+ const context = usePopoverContext(CONTENT_NAME$4, props.__scopePopover);
143212
143149
  const contentRef = React.useRef(null);
143213
143150
  const composedRefs = useComposedRefs$1(forwardedRef, contentRef);
143214
143151
  const isRightClickOutsideRef = React.useRef(false);
@@ -143248,7 +143185,7 @@ var PopoverContentModal = React.forwardRef(
143248
143185
  );
143249
143186
  var PopoverContentNonModal = React.forwardRef(
143250
143187
  (props, forwardedRef) => {
143251
- const context = usePopoverContext(CONTENT_NAME$3, props.__scopePopover);
143188
+ const context = usePopoverContext(CONTENT_NAME$4, props.__scopePopover);
143252
143189
  const hasInteractedOutsideRef = React.useRef(false);
143253
143190
  const hasPointerDownOutsideRef = React.useRef(false);
143254
143191
  return /* @__PURE__ */ jsx(
@@ -143300,7 +143237,7 @@ var PopoverContentImpl = React.forwardRef(
143300
143237
  onInteractOutside,
143301
143238
  ...contentProps
143302
143239
  } = props;
143303
- const context = usePopoverContext(CONTENT_NAME$3, __scopePopover);
143240
+ const context = usePopoverContext(CONTENT_NAME$4, __scopePopover);
143304
143241
  const popperScope = usePopperScope$1(__scopePopover);
143305
143242
  useFocusGuards();
143306
143243
  return /* @__PURE__ */ jsx(
@@ -143378,26 +143315,26 @@ PopoverArrow.displayName = ARROW_NAME$2;
143378
143315
  function getState$2(open) {
143379
143316
  return open ? "open" : "closed";
143380
143317
  }
143381
- var Root2$2 = Popover$1;
143318
+ var Root2$3 = Popover$1;
143382
143319
  var Anchor2$1 = PopoverAnchor$1;
143383
143320
  var Trigger$1 = PopoverTrigger$1;
143384
143321
  var Portal$1 = PopoverPortal;
143385
- var Content2$2 = PopoverContent$1;
143322
+ var Content2$3 = PopoverContent$1;
143386
143323
 
143387
- const Popover = Root2$2;
143324
+ const Popover = Root2$3;
143388
143325
  const PopoverTrigger = Trigger$1;
143389
143326
  const PopoverAnchor = Anchor2$1;
143390
143327
  const PopoverContent = React.forwardRef(({ className, align = 'center', sideOffset = 4, portalled = true, container, ...props }, ref) => {
143391
143328
  var _a;
143392
143329
  const portalContainer = useFloatingPortalContainer();
143393
143330
  const resolvedContainer = (_a = container !== null && container !== void 0 ? container : portalContainer) !== null && _a !== void 0 ? _a : undefined;
143394
- const content = (jsx(Content2$2, { ref: ref, "data-iblai-dialog-interaction-layer": true, align: align, sideOffset: sideOffset, className: cn('bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 rounded-md border p-4 shadow-md outline-none', className), ...props }));
143331
+ const content = (jsx(Content2$3, { ref: ref, "data-iblai-dialog-interaction-layer": true, align: align, sideOffset: sideOffset, className: cn('bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 rounded-md border p-4 shadow-md outline-none', className), ...props }));
143395
143332
  if (!portalled) {
143396
143333
  return content;
143397
143334
  }
143398
143335
  return jsx(Portal$1, { container: resolvedContainer, children: content });
143399
143336
  });
143400
- PopoverContent.displayName = Content2$2.displayName;
143337
+ PopoverContent.displayName = Content2$3.displayName;
143401
143338
 
143402
143339
  function UsersTab({ tenant, onInviteClick, currentSpa, showGradebookTab = false, }) {
143403
143340
  const t = useT();
@@ -145279,11 +145216,11 @@ var Collapsible$1 = React.forwardRef(
145279
145216
  }
145280
145217
  );
145281
145218
  Collapsible$1.displayName = COLLAPSIBLE_NAME;
145282
- var TRIGGER_NAME$1 = "CollapsibleTrigger";
145219
+ var TRIGGER_NAME$2 = "CollapsibleTrigger";
145283
145220
  var CollapsibleTrigger$1 = React.forwardRef(
145284
145221
  (props, forwardedRef) => {
145285
145222
  const { __scopeCollapsible, ...triggerProps } = props;
145286
- const context = useCollapsibleContext(TRIGGER_NAME$1, __scopeCollapsible);
145223
+ const context = useCollapsibleContext(TRIGGER_NAME$2, __scopeCollapsible);
145287
145224
  return /* @__PURE__ */ jsx(
145288
145225
  Primitive$3.button,
145289
145226
  {
@@ -145300,19 +145237,19 @@ var CollapsibleTrigger$1 = React.forwardRef(
145300
145237
  );
145301
145238
  }
145302
145239
  );
145303
- CollapsibleTrigger$1.displayName = TRIGGER_NAME$1;
145304
- var CONTENT_NAME$2 = "CollapsibleContent";
145240
+ CollapsibleTrigger$1.displayName = TRIGGER_NAME$2;
145241
+ var CONTENT_NAME$3 = "CollapsibleContent";
145305
145242
  var CollapsibleContent$1 = React.forwardRef(
145306
145243
  (props, forwardedRef) => {
145307
145244
  const { forceMount, ...contentProps } = props;
145308
- const context = useCollapsibleContext(CONTENT_NAME$2, props.__scopeCollapsible);
145245
+ const context = useCollapsibleContext(CONTENT_NAME$3, props.__scopeCollapsible);
145309
145246
  return /* @__PURE__ */ jsx(Presence$3, { present: forceMount || context.open, children: ({ present }) => /* @__PURE__ */ jsx(CollapsibleContentImpl, { ...contentProps, ref: forwardedRef, present }) });
145310
145247
  }
145311
145248
  );
145312
- CollapsibleContent$1.displayName = CONTENT_NAME$2;
145249
+ CollapsibleContent$1.displayName = CONTENT_NAME$3;
145313
145250
  var CollapsibleContentImpl = React.forwardRef((props, forwardedRef) => {
145314
145251
  const { __scopeCollapsible, present, children, ...contentProps } = props;
145315
- const context = useCollapsibleContext(CONTENT_NAME$2, __scopeCollapsible);
145252
+ const context = useCollapsibleContext(CONTENT_NAME$3, __scopeCollapsible);
145316
145253
  const [isPresent, setIsPresent] = React.useState(present);
145317
145254
  const ref = React.useRef(null);
145318
145255
  const composedRefs = useComposedRefs$1(forwardedRef, ref);
@@ -168596,7 +168533,7 @@ var joinTextblockForward = () => ({ state, dispatch }) => {
168596
168533
  };
168597
168534
 
168598
168535
  // src/utilities/isMacOS.ts
168599
- function isMacOS() {
168536
+ function isMacOS$1() {
168600
168537
  return typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false;
168601
168538
  }
168602
168539
 
@@ -168622,7 +168559,7 @@ function normalizeKeyName(name) {
168622
168559
  } else if (/^s(hift)?$/i.test(mod)) {
168623
168560
  shift = true;
168624
168561
  } else if (/^mod$/i.test(mod)) {
168625
- if (isiOS() || isMacOS()) {
168562
+ if (isiOS() || isMacOS$1()) {
168626
168563
  meta = true;
168627
168564
  } else {
168628
168565
  ctrl = true;
@@ -171599,7 +171536,7 @@ var Keymap = Extension.create({
171599
171536
  "Ctrl-a": () => this.editor.commands.selectTextblockStart(),
171600
171537
  "Ctrl-e": () => this.editor.commands.selectTextblockEnd()
171601
171538
  };
171602
- if (isiOS() || isMacOS()) {
171539
+ if (isiOS() || isMacOS$1()) {
171603
171540
  return macKeymap;
171604
171541
  }
171605
171542
  return pcKeymap;
@@ -181637,30 +181574,30 @@ var MenuAnchor = React.forwardRef(
181637
181574
  }
181638
181575
  );
181639
181576
  MenuAnchor.displayName = ANCHOR_NAME;
181640
- var PORTAL_NAME$1 = "MenuPortal";
181641
- var [PortalProvider, usePortalContext] = createMenuContext(PORTAL_NAME$1, {
181577
+ var PORTAL_NAME$2 = "MenuPortal";
181578
+ var [PortalProvider, usePortalContext] = createMenuContext(PORTAL_NAME$2, {
181642
181579
  forceMount: void 0
181643
181580
  });
181644
181581
  var MenuPortal = (props) => {
181645
181582
  const { __scopeMenu, forceMount, children, container } = props;
181646
- const context = useMenuContext(PORTAL_NAME$1, __scopeMenu);
181583
+ const context = useMenuContext(PORTAL_NAME$2, __scopeMenu);
181647
181584
  return /* @__PURE__ */ jsx(PortalProvider, { scope: __scopeMenu, forceMount, children: /* @__PURE__ */ jsx(Presence$2, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(Portal$6, { asChild: true, container, children }) }) });
181648
181585
  };
181649
- MenuPortal.displayName = PORTAL_NAME$1;
181650
- var CONTENT_NAME$1 = "MenuContent";
181651
- var [MenuContentProvider, useMenuContentContext] = createMenuContext(CONTENT_NAME$1);
181586
+ MenuPortal.displayName = PORTAL_NAME$2;
181587
+ var CONTENT_NAME$2 = "MenuContent";
181588
+ var [MenuContentProvider, useMenuContentContext] = createMenuContext(CONTENT_NAME$2);
181652
181589
  var MenuContent = React.forwardRef(
181653
181590
  (props, forwardedRef) => {
181654
- const portalContext = usePortalContext(CONTENT_NAME$1, props.__scopeMenu);
181591
+ const portalContext = usePortalContext(CONTENT_NAME$2, props.__scopeMenu);
181655
181592
  const { forceMount = portalContext.forceMount, ...contentProps } = props;
181656
- const context = useMenuContext(CONTENT_NAME$1, props.__scopeMenu);
181657
- const rootContext = useMenuRootContext(CONTENT_NAME$1, props.__scopeMenu);
181593
+ const context = useMenuContext(CONTENT_NAME$2, props.__scopeMenu);
181594
+ const rootContext = useMenuRootContext(CONTENT_NAME$2, props.__scopeMenu);
181658
181595
  return /* @__PURE__ */ jsx(Collection$1.Provider, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx(Presence$2, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(Collection$1.Slot, { scope: props.__scopeMenu, children: rootContext.modal ? /* @__PURE__ */ jsx(MenuRootContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx(MenuRootContentNonModal, { ...contentProps, ref: forwardedRef }) }) }) });
181659
181596
  }
181660
181597
  );
181661
181598
  var MenuRootContentModal = React.forwardRef(
181662
181599
  (props, forwardedRef) => {
181663
- const context = useMenuContext(CONTENT_NAME$1, props.__scopeMenu);
181600
+ const context = useMenuContext(CONTENT_NAME$2, props.__scopeMenu);
181664
181601
  const ref = React.useRef(null);
181665
181602
  const composedRefs = useComposedRefs$1(forwardedRef, ref);
181666
181603
  React.useEffect(() => {
@@ -181686,7 +181623,7 @@ var MenuRootContentModal = React.forwardRef(
181686
181623
  }
181687
181624
  );
181688
181625
  var MenuRootContentNonModal = React.forwardRef((props, forwardedRef) => {
181689
- const context = useMenuContext(CONTENT_NAME$1, props.__scopeMenu);
181626
+ const context = useMenuContext(CONTENT_NAME$2, props.__scopeMenu);
181690
181627
  return /* @__PURE__ */ jsx(
181691
181628
  MenuContentImpl,
181692
181629
  {
@@ -181718,8 +181655,8 @@ var MenuContentImpl = React.forwardRef(
181718
181655
  disableOutsideScroll,
181719
181656
  ...contentProps
181720
181657
  } = props;
181721
- const context = useMenuContext(CONTENT_NAME$1, __scopeMenu);
181722
- const rootContext = useMenuRootContext(CONTENT_NAME$1, __scopeMenu);
181658
+ const context = useMenuContext(CONTENT_NAME$2, __scopeMenu);
181659
+ const rootContext = useMenuRootContext(CONTENT_NAME$2, __scopeMenu);
181723
181660
  const popperScope = usePopperScope(__scopeMenu);
181724
181661
  const rovingFocusGroupScope = useRovingFocusGroupScope$1(__scopeMenu);
181725
181662
  const getItems = useCollection$1(__scopeMenu);
@@ -181882,7 +181819,7 @@ var MenuContentImpl = React.forwardRef(
181882
181819
  );
181883
181820
  }
181884
181821
  );
181885
- MenuContent.displayName = CONTENT_NAME$1;
181822
+ MenuContent.displayName = CONTENT_NAME$2;
181886
181823
  var GROUP_NAME$2 = "MenuGroup";
181887
181824
  var MenuGroup = React.forwardRef(
181888
181825
  (props, forwardedRef) => {
@@ -182256,10 +182193,10 @@ MenuSubTrigger.displayName = SUB_TRIGGER_NAME$1;
182256
182193
  var SUB_CONTENT_NAME$1 = "MenuSubContent";
182257
182194
  var MenuSubContent = React.forwardRef(
182258
182195
  (props, forwardedRef) => {
182259
- const portalContext = usePortalContext(CONTENT_NAME$1, props.__scopeMenu);
182196
+ const portalContext = usePortalContext(CONTENT_NAME$2, props.__scopeMenu);
182260
182197
  const { forceMount = portalContext.forceMount, ...subContentProps } = props;
182261
- const context = useMenuContext(CONTENT_NAME$1, props.__scopeMenu);
182262
- const rootContext = useMenuRootContext(CONTENT_NAME$1, props.__scopeMenu);
182198
+ const context = useMenuContext(CONTENT_NAME$2, props.__scopeMenu);
182199
+ const rootContext = useMenuRootContext(CONTENT_NAME$2, props.__scopeMenu);
182263
182200
  const subContext = useMenuSubContext(SUB_CONTENT_NAME$1, props.__scopeMenu);
182264
182201
  const ref = React.useRef(null);
182265
182202
  const composedRefs = useComposedRefs$1(forwardedRef, ref);
@@ -182357,7 +182294,7 @@ function whenMouse(handler) {
182357
182294
  var Root3 = Menu;
182358
182295
  var Anchor2 = MenuAnchor;
182359
182296
  var Portal = MenuPortal;
182360
- var Content2$1 = MenuContent;
182297
+ var Content2$2 = MenuContent;
182361
182298
  var Group = MenuGroup;
182362
182299
  var Label = MenuLabel;
182363
182300
  var Item2$2 = MenuItem;
@@ -182411,11 +182348,11 @@ var DropdownMenu$1 = (props) => {
182411
182348
  );
182412
182349
  };
182413
182350
  DropdownMenu$1.displayName = DROPDOWN_MENU_NAME;
182414
- var TRIGGER_NAME = "DropdownMenuTrigger";
182351
+ var TRIGGER_NAME$1 = "DropdownMenuTrigger";
182415
182352
  var DropdownMenuTrigger$1 = React.forwardRef(
182416
182353
  (props, forwardedRef) => {
182417
182354
  const { __scopeDropdownMenu, disabled = false, ...triggerProps } = props;
182418
- const context = useDropdownMenuContext(TRIGGER_NAME, __scopeDropdownMenu);
182355
+ const context = useDropdownMenuContext(TRIGGER_NAME$1, __scopeDropdownMenu);
182419
182356
  const menuScope = useMenuScope(__scopeDropdownMenu);
182420
182357
  return /* @__PURE__ */ jsx(Anchor2, { asChild: true, ...menuScope, children: /* @__PURE__ */ jsx(
182421
182358
  Primitive$4.button,
@@ -182446,23 +182383,23 @@ var DropdownMenuTrigger$1 = React.forwardRef(
182446
182383
  ) });
182447
182384
  }
182448
182385
  );
182449
- DropdownMenuTrigger$1.displayName = TRIGGER_NAME;
182450
- var PORTAL_NAME = "DropdownMenuPortal";
182386
+ DropdownMenuTrigger$1.displayName = TRIGGER_NAME$1;
182387
+ var PORTAL_NAME$1 = "DropdownMenuPortal";
182451
182388
  var DropdownMenuPortal$1 = (props) => {
182452
182389
  const { __scopeDropdownMenu, ...portalProps } = props;
182453
182390
  const menuScope = useMenuScope(__scopeDropdownMenu);
182454
182391
  return /* @__PURE__ */ jsx(Portal, { ...menuScope, ...portalProps });
182455
182392
  };
182456
- DropdownMenuPortal$1.displayName = PORTAL_NAME;
182457
- var CONTENT_NAME = "DropdownMenuContent";
182393
+ DropdownMenuPortal$1.displayName = PORTAL_NAME$1;
182394
+ var CONTENT_NAME$1 = "DropdownMenuContent";
182458
182395
  var DropdownMenuContent$1 = React.forwardRef(
182459
182396
  (props, forwardedRef) => {
182460
182397
  const { __scopeDropdownMenu, ...contentProps } = props;
182461
- const context = useDropdownMenuContext(CONTENT_NAME, __scopeDropdownMenu);
182398
+ const context = useDropdownMenuContext(CONTENT_NAME$1, __scopeDropdownMenu);
182462
182399
  const menuScope = useMenuScope(__scopeDropdownMenu);
182463
182400
  const hasInteractedOutsideRef = React.useRef(false);
182464
182401
  return /* @__PURE__ */ jsx(
182465
- Content2$1,
182402
+ Content2$2,
182466
182403
  {
182467
182404
  id: context.contentId,
182468
182405
  "aria-labelledby": context.triggerId,
@@ -182495,7 +182432,7 @@ var DropdownMenuContent$1 = React.forwardRef(
182495
182432
  );
182496
182433
  }
182497
182434
  );
182498
- DropdownMenuContent$1.displayName = CONTENT_NAME;
182435
+ DropdownMenuContent$1.displayName = CONTENT_NAME$1;
182499
182436
  var GROUP_NAME$1 = "DropdownMenuGroup";
182500
182437
  var DropdownMenuGroup$1 = React.forwardRef(
182501
182438
  (props, forwardedRef) => {
@@ -182609,10 +182546,10 @@ var DropdownMenuSubContent$1 = React.forwardRef((props, forwardedRef) => {
182609
182546
  );
182610
182547
  });
182611
182548
  DropdownMenuSubContent$1.displayName = SUB_CONTENT_NAME;
182612
- var Root2$1 = DropdownMenu$1;
182549
+ var Root2$2 = DropdownMenu$1;
182613
182550
  var Trigger = DropdownMenuTrigger$1;
182614
- var Portal2 = DropdownMenuPortal$1;
182615
- var Content2 = DropdownMenuContent$1;
182551
+ var Portal2$1 = DropdownMenuPortal$1;
182552
+ var Content2$1 = DropdownMenuContent$1;
182616
182553
  var Group2 = DropdownMenuGroup$1;
182617
182554
  var Label2 = DropdownMenuLabel$1;
182618
182555
  var Item2$1 = DropdownMenuItem$1;
@@ -182626,17 +182563,17 @@ var SubTrigger2 = DropdownMenuSubTrigger$1;
182626
182563
  var SubContent2 = DropdownMenuSubContent$1;
182627
182564
 
182628
182565
  function DropdownMenu({ ...props }) {
182629
- return jsx(Root2$1, { "data-slot": "dropdown-menu", ...props });
182566
+ return jsx(Root2$2, { "data-slot": "dropdown-menu", ...props });
182630
182567
  }
182631
182568
  function DropdownMenuPortal({ ...props }) {
182632
- return jsx(Portal2, { "data-slot": "dropdown-menu-portal", ...props });
182569
+ return jsx(Portal2$1, { "data-slot": "dropdown-menu-portal", ...props });
182633
182570
  }
182634
182571
  function DropdownMenuTrigger({ ...props }) {
182635
182572
  return jsx(Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
182636
182573
  }
182637
182574
  function DropdownMenuContent({ className, sideOffset = 4, ...props }) {
182638
182575
  const portalContainer = useFloatingPortalContainer();
182639
- return (jsx(Portal2, { container: portalContainer !== null && portalContainer !== void 0 ? portalContainer : undefined, children: jsx(Content2, { "data-slot": "dropdown-menu-content", "data-iblai-dialog-interaction-layer": true, sideOffset: sideOffset, className: cn('bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md', className), ...props }) }));
182576
+ return (jsx(Portal2$1, { container: portalContainer !== null && portalContainer !== void 0 ? portalContainer : undefined, children: jsx(Content2$1, { "data-slot": "dropdown-menu-content", "data-iblai-dialog-interaction-layer": true, sideOffset: sideOffset, className: cn('bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md', className), ...props }) }));
182640
182577
  }
182641
182578
  function DropdownMenuGroup({ ...props }) {
182642
182579
  return jsx(Group2, { "data-slot": "dropdown-menu-group", ...props });
@@ -183478,12 +183415,12 @@ var RadioGroupIndicator = React.forwardRef(
183478
183415
  }
183479
183416
  );
183480
183417
  RadioGroupIndicator.displayName = INDICATOR_NAME2;
183481
- var Root2 = RadioGroup$1;
183418
+ var Root2$1 = RadioGroup$1;
183482
183419
  var Item2 = RadioGroupItem$1;
183483
183420
  var Indicator = RadioGroupIndicator;
183484
183421
 
183485
183422
  function RadioGroup({ className, ...props }) {
183486
- return (jsx(Root2, { "data-slot": "radio-group", className: cn('grid gap-3', className), ...props }));
183423
+ return (jsx(Root2$1, { "data-slot": "radio-group", className: cn('grid gap-3', className), ...props }));
183487
183424
  }
183488
183425
  function RadioGroupItem({ className, ...props }) {
183489
183426
  return (jsx(Item2, { "data-slot": "radio-group-item", className: cn('border-input text-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 aspect-square size-4 shrink-0 rounded-full border shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50', className), ...props, children: jsx(Indicator, { "data-slot": "radio-group-indicator", className: "relative flex items-center justify-center", children: jsx(Circle, { className: "fill-primary absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2" }) }) }));
@@ -185019,6 +184956,173 @@ function NotificationDisplay({ org, userId, isAdmin = false, selectedNotificatio
185019
184956
  } }), jsx(Dialog, { open: isMobileModalOpen, onOpenChange: setIsMobileModalOpen, children: jsx(DialogContent, { className: "max-h-[85vh] overflow-y-auto max-w-[95vw]", children: selectedNotification && (jsxs(Fragment$1, { children: [jsxs(DialogHeader, { children: [jsx(DialogTitle, { className: "text-xl font-semibold text-gray-900 pr-6", children: selectedNotification.title }), jsxs("div", { className: "flex items-center gap-2 text-sm text-gray-500 pt-2", children: [jsx(Clock, { className: "h-4 w-4", "aria-hidden": "true" }), jsx("time", { dateTime: selectedNotification.timestamp.toISOString(), children: format$1(selectedNotification.timestamp, "MMMM d, yyyy 'at' h:mm a") })] })] }), jsx("div", { className: "prose prose-sm max-w-none text-gray-700 mt-4", dangerouslySetInnerHTML: { __html: sanitizeHtml(selectedNotification.body) }, "aria-labelledby": "mobile-notification-title" })] })) }) })] }));
185020
184957
  }
185021
184958
 
184959
+ var SLOTTABLE_IDENTIFIER = Symbol("radix.slottable");
184960
+ // @__NO_SIDE_EFFECTS__
184961
+ function createSlottable(ownerName) {
184962
+ const Slottable2 = ({ children }) => {
184963
+ return /* @__PURE__ */ jsx(Fragment$1, { children });
184964
+ };
184965
+ Slottable2.displayName = `${ownerName}.Slottable`;
184966
+ Slottable2.__radixId = SLOTTABLE_IDENTIFIER;
184967
+ return Slottable2;
184968
+ }
184969
+
184970
+ var ROOT_NAME = "AlertDialog";
184971
+ var [createAlertDialogContext] = createContextScope$1(ROOT_NAME, [
184972
+ createDialogScope
184973
+ ]);
184974
+ var useDialogScope = createDialogScope();
184975
+ var AlertDialog$1 = (props) => {
184976
+ const { __scopeAlertDialog, ...alertDialogProps } = props;
184977
+ const dialogScope = useDialogScope(__scopeAlertDialog);
184978
+ return /* @__PURE__ */ jsx(DialogPrimitive.Root, { ...dialogScope, ...alertDialogProps, modal: true });
184979
+ };
184980
+ AlertDialog$1.displayName = ROOT_NAME;
184981
+ var TRIGGER_NAME = "AlertDialogTrigger";
184982
+ var AlertDialogTrigger = React.forwardRef(
184983
+ (props, forwardedRef) => {
184984
+ const { __scopeAlertDialog, ...triggerProps } = props;
184985
+ const dialogScope = useDialogScope(__scopeAlertDialog);
184986
+ return /* @__PURE__ */ jsx(DialogPrimitive.Trigger, { ...dialogScope, ...triggerProps, ref: forwardedRef });
184987
+ }
184988
+ );
184989
+ AlertDialogTrigger.displayName = TRIGGER_NAME;
184990
+ var PORTAL_NAME = "AlertDialogPortal";
184991
+ var AlertDialogPortal$1 = (props) => {
184992
+ const { __scopeAlertDialog, ...portalProps } = props;
184993
+ const dialogScope = useDialogScope(__scopeAlertDialog);
184994
+ return /* @__PURE__ */ jsx(DialogPrimitive.Portal, { ...dialogScope, ...portalProps });
184995
+ };
184996
+ AlertDialogPortal$1.displayName = PORTAL_NAME;
184997
+ var OVERLAY_NAME = "AlertDialogOverlay";
184998
+ var AlertDialogOverlay$1 = React.forwardRef(
184999
+ (props, forwardedRef) => {
185000
+ const { __scopeAlertDialog, ...overlayProps } = props;
185001
+ const dialogScope = useDialogScope(__scopeAlertDialog);
185002
+ return /* @__PURE__ */ jsx(DialogPrimitive.Overlay, { ...dialogScope, ...overlayProps, ref: forwardedRef });
185003
+ }
185004
+ );
185005
+ AlertDialogOverlay$1.displayName = OVERLAY_NAME;
185006
+ var CONTENT_NAME = "AlertDialogContent";
185007
+ var [AlertDialogContentProvider, useAlertDialogContentContext] = createAlertDialogContext(CONTENT_NAME);
185008
+ var Slottable = createSlottable("AlertDialogContent");
185009
+ var AlertDialogContent$1 = React.forwardRef(
185010
+ (props, forwardedRef) => {
185011
+ const { __scopeAlertDialog, children, ...contentProps } = props;
185012
+ const dialogScope = useDialogScope(__scopeAlertDialog);
185013
+ const contentRef = React.useRef(null);
185014
+ const composedRefs = useComposedRefs$1(forwardedRef, contentRef);
185015
+ const cancelRef = React.useRef(null);
185016
+ return /* @__PURE__ */ jsx(
185017
+ DialogPrimitive.WarningProvider,
185018
+ {
185019
+ contentName: CONTENT_NAME,
185020
+ titleName: TITLE_NAME,
185021
+ docsSlug: "alert-dialog",
185022
+ children: /* @__PURE__ */ jsx(AlertDialogContentProvider, { scope: __scopeAlertDialog, cancelRef, children: /* @__PURE__ */ jsxs(
185023
+ DialogPrimitive.Content,
185024
+ {
185025
+ role: "alertdialog",
185026
+ ...dialogScope,
185027
+ ...contentProps,
185028
+ ref: composedRefs,
185029
+ onOpenAutoFocus: composeEventHandlers$2(contentProps.onOpenAutoFocus, (event) => {
185030
+ event.preventDefault();
185031
+ cancelRef.current?.focus({ preventScroll: true });
185032
+ }),
185033
+ onPointerDownOutside: (event) => event.preventDefault(),
185034
+ onInteractOutside: (event) => event.preventDefault(),
185035
+ children: [
185036
+ /* @__PURE__ */ jsx(Slottable, { children }),
185037
+ /* @__PURE__ */ jsx(DescriptionWarning, { contentRef })
185038
+ ]
185039
+ }
185040
+ ) })
185041
+ }
185042
+ );
185043
+ }
185044
+ );
185045
+ AlertDialogContent$1.displayName = CONTENT_NAME;
185046
+ var TITLE_NAME = "AlertDialogTitle";
185047
+ var AlertDialogTitle$1 = React.forwardRef(
185048
+ (props, forwardedRef) => {
185049
+ const { __scopeAlertDialog, ...titleProps } = props;
185050
+ const dialogScope = useDialogScope(__scopeAlertDialog);
185051
+ return /* @__PURE__ */ jsx(DialogPrimitive.Title, { ...dialogScope, ...titleProps, ref: forwardedRef });
185052
+ }
185053
+ );
185054
+ AlertDialogTitle$1.displayName = TITLE_NAME;
185055
+ var DESCRIPTION_NAME = "AlertDialogDescription";
185056
+ var AlertDialogDescription$1 = React.forwardRef((props, forwardedRef) => {
185057
+ const { __scopeAlertDialog, ...descriptionProps } = props;
185058
+ const dialogScope = useDialogScope(__scopeAlertDialog);
185059
+ return /* @__PURE__ */ jsx(DialogPrimitive.Description, { ...dialogScope, ...descriptionProps, ref: forwardedRef });
185060
+ });
185061
+ AlertDialogDescription$1.displayName = DESCRIPTION_NAME;
185062
+ var ACTION_NAME = "AlertDialogAction";
185063
+ var AlertDialogAction$1 = React.forwardRef(
185064
+ (props, forwardedRef) => {
185065
+ const { __scopeAlertDialog, ...actionProps } = props;
185066
+ const dialogScope = useDialogScope(__scopeAlertDialog);
185067
+ return /* @__PURE__ */ jsx(DialogPrimitive.Close, { ...dialogScope, ...actionProps, ref: forwardedRef });
185068
+ }
185069
+ );
185070
+ AlertDialogAction$1.displayName = ACTION_NAME;
185071
+ var CANCEL_NAME = "AlertDialogCancel";
185072
+ var AlertDialogCancel$1 = React.forwardRef(
185073
+ (props, forwardedRef) => {
185074
+ const { __scopeAlertDialog, ...cancelProps } = props;
185075
+ const { cancelRef } = useAlertDialogContentContext(CANCEL_NAME, __scopeAlertDialog);
185076
+ const dialogScope = useDialogScope(__scopeAlertDialog);
185077
+ const ref = useComposedRefs$1(forwardedRef, cancelRef);
185078
+ return /* @__PURE__ */ jsx(DialogPrimitive.Close, { ...dialogScope, ...cancelProps, ref });
185079
+ }
185080
+ );
185081
+ AlertDialogCancel$1.displayName = CANCEL_NAME;
185082
+ var DescriptionWarning = ({ contentRef }) => {
185083
+ const MESSAGE = `\`${CONTENT_NAME}\` requires a description for the component to be accessible for screen reader users.
185084
+
185085
+ You can add a description to the \`${CONTENT_NAME}\` by passing a \`${DESCRIPTION_NAME}\` component as a child, which also benefits sighted users by adding visible context to the dialog.
185086
+
185087
+ Alternatively, you can use your own component as a description by assigning it an \`id\` and passing the same value to the \`aria-describedby\` prop in \`${CONTENT_NAME}\`. If the description is confusing or duplicative for sighted users, you can use the \`@radix-ui/react-visually-hidden\` primitive as a wrapper around your description component.
185088
+
185089
+ For more information, see https://radix-ui.com/primitives/docs/components/alert-dialog`;
185090
+ React.useEffect(() => {
185091
+ const hasDescription = document.getElementById(
185092
+ contentRef.current?.getAttribute("aria-describedby")
185093
+ );
185094
+ if (!hasDescription) console.warn(MESSAGE);
185095
+ }, [MESSAGE, contentRef]);
185096
+ return null;
185097
+ };
185098
+ var Root2 = AlertDialog$1;
185099
+ var Portal2 = AlertDialogPortal$1;
185100
+ var Overlay2 = AlertDialogOverlay$1;
185101
+ var Content2 = AlertDialogContent$1;
185102
+ var Action = AlertDialogAction$1;
185103
+ var Cancel = AlertDialogCancel$1;
185104
+ var Title2 = AlertDialogTitle$1;
185105
+ var Description2 = AlertDialogDescription$1;
185106
+
185107
+ const AlertDialog = Root2;
185108
+ const AlertDialogPortal = Portal2;
185109
+ const AlertDialogOverlay = React.forwardRef(({ className, ...props }, ref) => (jsx(Overlay2, { className: cn('data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80', className), ...props, ref: ref })));
185110
+ AlertDialogOverlay.displayName = Overlay2.displayName;
185111
+ const AlertDialogContent = React.forwardRef(({ className, ...props }, ref) => (jsxs(AlertDialogPortal, { children: [jsx(AlertDialogOverlay, {}), jsx(Content2, { ref: ref, className: cn('bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg', className), ...props })] })));
185112
+ AlertDialogContent.displayName = Content2.displayName;
185113
+ const AlertDialogHeader = ({ className, ...props }) => (jsx("div", { className: cn('flex flex-col space-y-2 text-center sm:text-left', className), ...props }));
185114
+ AlertDialogHeader.displayName = 'AlertDialogHeader';
185115
+ const AlertDialogFooter = ({ className, ...props }) => (jsx("div", { className: cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', className), ...props }));
185116
+ AlertDialogFooter.displayName = 'AlertDialogFooter';
185117
+ const AlertDialogTitle = React.forwardRef(({ className, ...props }, ref) => (jsx(Title2, { ref: ref, className: cn('text-lg font-semibold', className), ...props })));
185118
+ AlertDialogTitle.displayName = Title2.displayName;
185119
+ const AlertDialogDescription = React.forwardRef(({ className, ...props }, ref) => (jsx(Description2, { ref: ref, className: cn('text-muted-foreground text-sm', className), ...props })));
185120
+ AlertDialogDescription.displayName = Description2.displayName;
185121
+ const AlertDialogAction = React.forwardRef(({ className, ...props }, ref) => (jsx(Action, { ref: ref, className: cn(buttonVariants(), className), ...props })));
185122
+ AlertDialogAction.displayName = Action.displayName;
185123
+ const AlertDialogCancel = React.forwardRef(({ className, ...props }, ref) => (jsx(Cancel, { ref: ref, className: cn(buttonVariants({ variant: 'outline' }), 'mt-2 sm:mt-0', className), ...props })));
185124
+ AlertDialogCancel.displayName = Cancel.displayName;
185125
+
185022
185126
  /**
185023
185127
  * **Private mode** toggle for the platform nav-bar. A single pill that
185024
185128
  * collapses to an icon-only chip when off, and expands with a cool
@@ -228936,8 +229040,53 @@ function MemoryButton({ mentorId, tenantKey, username }) {
228936
229040
  } }))] }) }), jsx(PopoverContent, { className: "w-96 rounded-lg border border-gray-200 bg-white p-0 shadow-xl", children: jsx(MemoryMenu, { onClose: () => setIsOpen(false), mentorId: mentorId, tenantKey: tenantKey, username: username }) })] }));
228937
229041
  }
228938
229042
 
229043
+ // Cowork is macOS-only in prod; the env flag bypasses the OS check so the
229044
+ // toggle can be exercised on Linux/Windows desktop builds during testing.
229045
+ const isMacOS = () => {
229046
+ if (typeof navigator === 'undefined')
229047
+ return false;
229048
+ return /mac/i.test(navigator.userAgent || '');
229049
+ };
229050
+ const allowNonMacOSCowork = () => process.env.NEXT_PUBLIC_ALLOW_NON_MACOS_COMPUTER_USE_TOGGLE === 'true';
229051
+ // 14GB floor per spec; modelSupportsCowork gates size > gb, so a model of
229052
+ // exactly 14GB is also off (no 14.0GB model in the catalog). Only the local-model
229053
+ // backend needs this; the remote AI has no size requirement.
229054
+ const COWORK_MIN_MODEL_GB = 14;
228939
229055
  const InsideButtons = ({ activeOptions, onOptionClick, deepResearch, studyMode, artifactsEnabled, containerWidth, disabled = false, onOpenPromptGallery, embedMode = false, promptsIsEnabled = false, memoryEnabled = false, mentorId, tenantKey, username, }) => {
228940
229056
  const t = useT();
229057
+ // Cowork = the Tauri GhostOS assistant. GhostOS runs the tools on-device;
229058
+ // the "brain" is EITHER a large local model (Local Models / Ollama) OR the
229059
+ // remote AI (DM OpenAI-compatible endpoint), whichever is set up. useGhostOs
229060
+ // handles install/stop; the localStorage pref (isCoworkEnabled) is read
229061
+ // by the chat hook to route the turn. Reads the pref on mount.
229062
+ // Local state is `coworkOn` so it doesn't shadow the imported setCoworkEnabled.
229063
+ const ghostOs = useGhostOs();
229064
+ const [coworkOn, setCoworkOn] = useState(isCoworkEnabled);
229065
+ const toggleCowork = () => {
229066
+ const next = !coworkOn;
229067
+ // Guard only when turning on. Cowork runs on either a large local model
229068
+ // or the remote AI — allow enabling when either backend is ready (the local
229069
+ // model + Cowork combo still works). The chatbox has no inline notice
229070
+ // space, so remind via toast. (RBAC is enforced separately: this button is
229071
+ // `disabled` when the user lacks the mentor `#chat` permission — see
229072
+ // chat-input-form's isChatDisabledByRbac.)
229073
+ if (next) {
229074
+ const localReady = isLocalLLMEnabled() &&
229075
+ modelSupportsCowork(getLocalLLMModel(), COWORK_MIN_MODEL_GB);
229076
+ if (!localReady && !hasRemoteAiConfig()) {
229077
+ toast.warning(isLocalLLMEnabled()
229078
+ ? t('chatInputFormInsideButtons.coworkModelTooSmall')
229079
+ : t('chatInputFormInsideButtons.coworkNeedsBackend'));
229080
+ return;
229081
+ }
229082
+ }
229083
+ setCoworkOn(next);
229084
+ setCoworkEnabled(next);
229085
+ if (next)
229086
+ ghostOs.install();
229087
+ else
229088
+ ghostOs.stop();
229089
+ };
228941
229090
  const allInsideButtons = [
228942
229091
  {
228943
229092
  name: 'Canvas',
@@ -228981,6 +229130,14 @@ const InsideButtons = ({ activeOptions, onOptionClick, deepResearch, studyMode,
228981
229130
  action: /* istanbul ignore next */ () => onOptionClick(TOOLS.MEMORY),
228982
229131
  isEnabled: memoryEnabled && !embedMode && !!username,
228983
229132
  },
229133
+ {
229134
+ name: 'Cowork',
229135
+ label: t('chatInputFormInsideButtons.cowork'),
229136
+ icon: jsx(Monitor, { className: "h-4 w-4" }),
229137
+ isActive: coworkOn,
229138
+ action: toggleCowork,
229139
+ isEnabled: ghostOs.isAvailable && (isMacOS() || allowNonMacOSCowork()),
229140
+ },
228984
229141
  ].filter((item) => item.isEnabled);
228985
229142
  // Get visible inside buttons based on screen size
228986
229143
  // Active buttons are always visible, inactive ones are hidden based on available width
@@ -233755,5 +233912,5 @@ var trainOrDeleteModal = /*#__PURE__*/Object.freeze({
233755
233912
  TrainOrDeleteModal: TrainOrDeleteModal
233756
233913
  });
233757
233914
 
233758
- export { ACCESS_COURSE_LABEL, AccessTimeHeatmap, AccessiblePaginate, AddMentorToProjectModal, AddSkillDialog, Admin, AdvancedTab, AgentConfigPrompts, AgentSkills, AlertsTab, AnalyticsAuditLogStats, AnalyticsCourseDetail, AnalyticsCourses, AnalyticsFinancialStats, AnalyticsLayout, AnalyticsMonetizationStats, AnalyticsOverview, AnalyticsProgramDetail, AnalyticsPrograms, AnalyticsReportDownload, AnalyticsReports, AnalyticsSettingsProvider, AnalyticsTopicsStats, AnalyticsTranscriptsStats, AnalyticsUsersStats, AppleRestrictionModal, ApplyWizard, BUY_NOW_LABEL, BillingTab, CATALOGS, CREATE_AGENT_LABELS, CategorizedDropdownMenu, ChartCardWrapper, ChartFiltersProvider, ChartLoading, ChatContext, ChatPrivacyToggle, ChatProvider, CompanyDialog, ConnectorManagementDialog, CopyButtonIcon, CourseAccessGuard, CourseCardSkeleton, CourseContentLoading, CourseOutline, CourseOutlineContext, CourseOutlineDrawer, CreateAgentForm, CreateAgentModal, CreateProjectModal, CreateWorkflowModal, CredentialBox, CredentialMiniBoxSkeleton, CredentialsList, CreditBalance, CustomDateRangePicker, CustomTooltip, DEFAULT_LOCALE, DEFAULT_SYSTEM_CONTROL_REQUIRED_SIZE_GB, DefaultEmptyBox, DeleteProjectModal, DeleteWorkflowModal, DiscoverContentCard, DiscoverFacetsFilter, DiscoverFilterDrawer, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, ENROLL_NOW_COURSE_STARTING_SOON_LABEL, ENROLL_NOW_LABEL, EditAlertDialog, EducationBox, EducationDialog, EducationTab, EdxIframeContext, EmptyStats, ExperienceBox, ExperienceDialog, ExperienceTab, FacetFilterContext, Footer, GHOST_OS_REPO_URL, GHOST_OS_TAURI_COMMANDS, GHOST_OS_TAURI_EVENTS, GradebookTab, GroupsFilterDropdown, INVITATION_ONLY_LABEL, InstitutionDialog, IntegrationsTab, InviteUserContent, InviteUserDialog, InvitedUsersDialog, LOCAL_MODELS, Loader, LocalLLMTab, LocalModelsContent, LoginButton, MACOS_PERMISSIONS_COMMANDS, Markdown, MinimumMentorAlert, MonetizationTab, NotificationDisplay, NotificationDropdown, ONBOARDING_SECTORS, OnboardingShell, OnboardingWizard, PaywallModal, PlacementExam, PlacementExamsDropdown, PlatformNavbar, PlatformNavbarSearch, Profile, ProfileTimeChart, ProgressDots, ProjectActionButtons, ProjectFilesModal, ProjectInstructionsModal, ProjectLandingPage, ProjectMentorsList, ProjectsPage, REQUEST_ACCESS_COURSE_STARTING_SOON_LABEL, REQUEST_ACCESS_LABEL, RenameProjectModal, ResumeBox, ResumeTab, RichTextEditor, SUPPORTED_LOCALES, SandboxConfig, SearchableMultiSelect, SendNotificationDialog, SignupButton, SkeletonActivityStatBox, SkeletonAddSkillsLoading, SkeletonCreatePathwaySearchList, SkeletonDiscoverFilterBox, SkeletonEducationBox, SkeletonMultiplier, SkeletonPathwayBox, SkeletonProfileInfoCard, SkeletonSkillBox, SkillBox, SkillDetailModal, SkillLeaderboardChart, SkillsBox, SkillsList, Spinner, StatCard, StepHeader, SystemControlContent, SystemControlTab, TAURI_COMMANDS, TAURI_EVENTS, TenantSwitcher, TimeFilter, TimeTrackingProvider, TimedExam, ToolDialogs, TopBanner, UpgradePackageModal, UserAvatar, Version, WebContainersI18nProvider, WorkflowSidebar, addBookmarksTab, availablePlacementExams, findLastResumeBlock, findSequentialParent, flattenVerticalBlocks, getCatalog, getFirstAvailableUnit, getLocalLLMModel, getLocalLLMToolSupport, getNextUnitIframe, getOrg, getParentBlockById, getParentsInfosFromSublessonId, getPreviousUnitIframe, getRandomCourseImage, getSectorById, getTenant, getUnitToIframe, getUserId, getUserName, inBrowserPrint, inIframe, initialGhostOsInstallState, initialModelDownloadState, isLocalLLMEnabled, isPlatformNavbarCreditBalanceVisible, isSystemControlEnabled, isTauriApp, isValidLocale, components as markdownComponents, modelSupportsSystemControl, onboardingPrimaryButtonClass, onboardingSecondaryButtonClass, resolveCreateAgentLabels, sanitizeCss, setLocalLLMEnabled, setLocalLLMModel, setLocalLLMToolSupport, setSystemControlEnabled, smallestSystemControlModel, useAnalyticsSettings, useAuditLog, useCatalogSearch, useChartFilters, useChatPrivacy, useChatState, useCourseDetail, useCourseMetadata, useCourses, useDiscover, useEdxIframe, useFinancial, useGhostOs, useIframeMessageHandler, useLocalStorage, useModelDownload, useMonetization, useOverview, useProfileActivityStats, useProfileCredentials, useProfilePathways, useProfilePrograms, useProfileSkills, useProfileTimeSpent, usePrograms, useReports, useT, useTauri, useTimeTracking, useTopics, useTranscripts, useUserCourses, useUserMetadata, useUsers, useWebContainersI18n, useWebContainersLocale };
233915
+ export { ACCESS_COURSE_LABEL, AccessTimeHeatmap, AccessiblePaginate, AddMentorToProjectModal, AddSkillDialog, Admin, AdvancedTab, AgentConfigPrompts, AgentSkills, AlertsTab, AnalyticsAuditLogStats, AnalyticsCourseDetail, AnalyticsCourses, AnalyticsFinancialStats, AnalyticsLayout, AnalyticsMonetizationStats, AnalyticsOverview, AnalyticsProgramDetail, AnalyticsPrograms, AnalyticsReportDownload, AnalyticsReports, AnalyticsSettingsProvider, AnalyticsTopicsStats, AnalyticsTranscriptsStats, AnalyticsUsersStats, AppleRestrictionModal, ApplyWizard, BUY_NOW_LABEL, BillingTab, CATALOGS, CREATE_AGENT_LABELS, CategorizedDropdownMenu, ChartCardWrapper, ChartFiltersProvider, ChartLoading, ChatContext, ChatPrivacyToggle, ChatProvider, CompanyDialog, ConnectorManagementDialog, CopyButtonIcon, CourseAccessGuard, CourseCardSkeleton, CourseContentLoading, CourseOutline, CourseOutlineContext, CourseOutlineDrawer, CreateAgentForm, CreateAgentModal, CreateProjectModal, CreateWorkflowModal, CredentialBox, CredentialMiniBoxSkeleton, CredentialsList, CreditBalance, CustomDateRangePicker, CustomTooltip, DEFAULT_COWORK_REQUIRED_SIZE_GB, DEFAULT_LOCALE, DefaultEmptyBox, DeleteProjectModal, DeleteWorkflowModal, DiscoverContentCard, DiscoverFacetsFilter, DiscoverFilterDrawer, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, ENROLL_NOW_COURSE_STARTING_SOON_LABEL, ENROLL_NOW_LABEL, EditAlertDialog, EducationBox, EducationDialog, EducationTab, EdxIframeContext, EmptyStats, ExperienceBox, ExperienceDialog, ExperienceTab, FacetFilterContext, Footer, GHOST_OS_REPO_URL, GHOST_OS_TAURI_COMMANDS, GHOST_OS_TAURI_EVENTS, GradebookTab, GroupsFilterDropdown, INVITATION_ONLY_LABEL, InstitutionDialog, IntegrationsTab, InviteUserContent, InviteUserDialog, InvitedUsersDialog, LOCAL_MODELS, Loader, LocalLLMTab, LocalModelsContent, LoginButton, MACOS_PERMISSIONS_COMMANDS, Markdown, MinimumMentorAlert, MonetizationTab, NotificationDisplay, NotificationDropdown, ONBOARDING_SECTORS, OnboardingShell, OnboardingWizard, PaywallModal, PlacementExam, PlacementExamsDropdown, PlatformNavbar, PlatformNavbarSearch, Profile, ProfileTimeChart, ProgressDots, ProjectActionButtons, ProjectFilesModal, ProjectInstructionsModal, ProjectLandingPage, ProjectMentorsList, ProjectsPage, REQUEST_ACCESS_COURSE_STARTING_SOON_LABEL, REQUEST_ACCESS_LABEL, RenameProjectModal, ResumeBox, ResumeTab, RichTextEditor, SUPPORTED_LOCALES, SandboxConfig, SearchableMultiSelect, SendNotificationDialog, SignupButton, SkeletonActivityStatBox, SkeletonAddSkillsLoading, SkeletonCreatePathwaySearchList, SkeletonDiscoverFilterBox, SkeletonEducationBox, SkeletonMultiplier, SkeletonPathwayBox, SkeletonProfileInfoCard, SkeletonSkillBox, SkillBox, SkillDetailModal, SkillLeaderboardChart, SkillsBox, SkillsList, Spinner, StatCard, StepHeader, TAURI_COMMANDS, TAURI_EVENTS, TenantSwitcher, TimeFilter, TimeTrackingProvider, TimedExam, ToolDialogs, TopBanner, UpgradePackageModal, UserAvatar, Version, WebContainersI18nProvider, WorkflowSidebar, addBookmarksTab, availablePlacementExams, findLastResumeBlock, findSequentialParent, flattenVerticalBlocks, getCatalog, getFirstAvailableUnit, getLocalLLMModel, getLocalLLMToolSupport, getNextUnitIframe, getOrg, getParentBlockById, getParentsInfosFromSublessonId, getPreviousUnitIframe, getRandomCourseImage, getSectorById, getTenant, getUnitToIframe, getUserId, getUserName, inBrowserPrint, inIframe, initialGhostOsInstallState, initialModelDownloadState, isCoworkEnabled, isLocalLLMEnabled, isPlatformNavbarCreditBalanceVisible, isTauriApp, isValidLocale, components as markdownComponents, modelSupportsCowork, onboardingPrimaryButtonClass, onboardingSecondaryButtonClass, resolveCreateAgentLabels, sanitizeCss, setCoworkEnabled, setLocalLLMEnabled, setLocalLLMModel, setLocalLLMToolSupport, smallestCoworkModel, useAnalyticsSettings, useAuditLog, useCatalogSearch, useChartFilters, useChatPrivacy, useChatState, useCourseDetail, useCourseMetadata, useCourses, useDiscover, useEdxIframe, useFinancial, useGhostOs, useIframeMessageHandler, useLocalStorage, useModelDownload, useMonetization, useOverview, useProfileActivityStats, useProfileCredentials, useProfilePathways, useProfilePrograms, useProfileSkills, useProfileTimeSpent, usePrograms, useReports, useT, useTauri, useTimeTracking, useTopics, useTranscripts, useUserCourses, useUserMetadata, useUsers, useWebContainersI18n, useWebContainersLocale };
233759
233916
  //# sourceMappingURL=index.esm.js.map