@semiont/react-ui 0.2.33-build.81 → 0.2.33-build.83

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/{PdfAnnotationCanvas.client-RAJRPQLU.mjs → PdfAnnotationCanvas.client-FGV33CWN.mjs} +9 -14
  2. package/dist/PdfAnnotationCanvas.client-FGV33CWN.mjs.map +1 -0
  3. package/dist/chunk-FC6SGLLT.mjs +141 -0
  4. package/dist/chunk-FC6SGLLT.mjs.map +1 -0
  5. package/dist/chunk-XS27QKGP.mjs +55 -0
  6. package/dist/chunk-XS27QKGP.mjs.map +1 -0
  7. package/dist/{chunk-QB52Q7EQ.mjs → chunk-YPYLOBA2.mjs} +31 -81
  8. package/dist/chunk-YPYLOBA2.mjs.map +1 -0
  9. package/dist/index.css +16 -0
  10. package/dist/index.css.map +1 -1
  11. package/dist/index.d.mts +70 -28
  12. package/dist/index.mjs +564 -621
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/test-utils.mjs +5 -3
  15. package/dist/test-utils.mjs.map +1 -1
  16. package/package.json +1 -1
  17. package/src/components/CodeMirrorRenderer.tsx +8 -8
  18. package/src/components/annotation/AnnotateToolbar.tsx +4 -1
  19. package/src/components/image-annotation/AnnotationOverlay.tsx +6 -17
  20. package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +6 -17
  21. package/src/components/resource/BrowseView.tsx +8 -8
  22. package/src/components/resource/__tests__/BrowseView.test.tsx +20 -12
  23. package/src/components/resource/panels/AssessmentEntry.tsx +3 -6
  24. package/src/components/resource/panels/CommentEntry.tsx +3 -6
  25. package/src/components/resource/panels/HighlightEntry.tsx +3 -6
  26. package/src/components/resource/panels/ReferenceEntry.tsx +3 -6
  27. package/src/components/resource/panels/TagEntry.tsx +3 -6
  28. package/src/components/resource/panels/TaggingPanel.tsx +5 -0
  29. package/src/components/resource/panels/__tests__/CommentEntry.test.tsx +42 -4
  30. package/src/components/resource/panels/__tests__/TaggingPanel.test.tsx +44 -0
  31. package/src/components/toolbar/Toolbar.css +20 -0
  32. package/src/features/resource-viewer/__tests__/AnnotationCreationPending.test.tsx +312 -0
  33. package/src/features/resource-viewer/__tests__/GenerationFlowIntegration.test.tsx +4 -8
  34. package/src/features/resource-viewer/__tests__/ResolutionFlowIntegration.test.tsx +266 -0
  35. package/src/features/resource-viewer/components/ResourceViewerPage.tsx +5 -3
  36. package/dist/PdfAnnotationCanvas.client-RAJRPQLU.mjs.map +0 -1
  37. package/dist/chunk-QB52Q7EQ.mjs.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,22 +1,32 @@
1
1
  'use client';
2
+ import {
3
+ HOVER_DELAY_MS,
4
+ createHoverHandlers,
5
+ useAttentionFlow,
6
+ useEventSubscription,
7
+ useEventSubscriptions,
8
+ useHoverEmitter
9
+ } from "./chunk-FC6SGLLT.mjs";
2
10
  import {
3
11
  AVAILABLE_LOCALES,
4
12
  ApiClientProvider,
5
- EventBusProvider,
6
13
  OpenResourcesProvider,
7
14
  SessionProvider,
8
15
  ToastContainer,
9
16
  ToastProvider,
10
17
  TranslationProvider,
11
- resetEventBusForTesting,
12
18
  useApiClient,
13
- useEventBus,
14
19
  useOpenResources,
15
20
  usePreloadTranslations,
16
21
  useSessionContext,
17
22
  useToast,
18
23
  useTranslations
19
- } from "./chunk-QB52Q7EQ.mjs";
24
+ } from "./chunk-YPYLOBA2.mjs";
25
+ import {
26
+ EventBusProvider,
27
+ resetEventBusForTesting,
28
+ useEventBus
29
+ } from "./chunk-XS27QKGP.mjs";
20
30
  import "./chunk-D7NBW4RV.mjs";
21
31
  import {
22
32
  __commonJS,
@@ -18930,123 +18940,11 @@ function useCacheManager() {
18930
18940
  return context;
18931
18941
  }
18932
18942
 
18933
- // src/contexts/useResolutionFlow.ts
18934
- import { useCallback as useCallback8, useEffect as useEffect10, useRef as useRef7, useState as useState8 } from "react";
18935
- import { resourceAnnotationUri, accessToken as accessToken3 } from "@semiont/api-client";
18936
- import { uriToAnnotationIdOrPassthrough } from "@semiont/core";
18937
- function toAccessToken2(token) {
18938
- return token ? accessToken3(token) : void 0;
18939
- }
18940
- function useResolutionFlow(emitter, config) {
18941
- const token = useAuthToken();
18942
- const [searchModalOpen, setSearchModalOpen] = useState8(false);
18943
- const [pendingReferenceId, setPendingReferenceId] = useState8(null);
18944
- const onCloseSearchModal = useCallback8(() => {
18945
- setSearchModalOpen(false);
18946
- }, []);
18947
- const configRef = useRef7(config);
18948
- useEffect10(() => {
18949
- configRef.current = config;
18950
- });
18951
- useEffect10(() => {
18952
- const getCurrentConfig = () => configRef.current;
18953
- const handleAnnotationUpdateBody = async (event) => {
18954
- try {
18955
- const { client: currentClient, resourceUri: currentResourceUri } = getCurrentConfig();
18956
- const annotationIdSegment = uriToAnnotationIdOrPassthrough(event.annotationUri);
18957
- const nestedUri = resourceAnnotationUri(`${currentResourceUri}/annotations/${annotationIdSegment}`);
18958
- await currentClient.updateAnnotationBody(nestedUri, {
18959
- resourceId: event.resourceId,
18960
- operations: event.operations
18961
- }, { auth: toAccessToken2(token) });
18962
- emitter.emit("annotation:body-updated", { annotationUri: event.annotationUri });
18963
- } catch (error) {
18964
- console.error("Failed to update annotation body:", error);
18965
- emitter.emit("annotation:body-update-failed", { error });
18966
- }
18967
- };
18968
- const handleReferenceLink = (event) => {
18969
- emitter.emit("resolution:search-requested", {
18970
- referenceId: event.annotationUri,
18971
- searchTerm: event.searchTerm
18972
- });
18973
- };
18974
- emitter.on("annotation:update-body", handleAnnotationUpdateBody);
18975
- emitter.on("reference:link", handleReferenceLink);
18976
- return () => {
18977
- emitter.off("annotation:update-body", handleAnnotationUpdateBody);
18978
- emitter.off("reference:link", handleReferenceLink);
18979
- };
18980
- }, [emitter, token]);
18981
- useEffect10(() => {
18982
- const handleResolutionSearchRequested = (event) => {
18983
- setPendingReferenceId(event.referenceId);
18984
- setSearchModalOpen(true);
18985
- };
18986
- emitter.on("resolution:search-requested", handleResolutionSearchRequested);
18987
- return () => {
18988
- emitter.off("resolution:search-requested", handleResolutionSearchRequested);
18989
- };
18990
- }, [emitter]);
18991
- return { searchModalOpen, pendingReferenceId, onCloseSearchModal };
18992
- }
18993
-
18994
- // src/contexts/useEventSubscription.ts
18995
- import { useEffect as useEffect11, useRef as useRef8, useMemo } from "react";
18996
- function useEventSubscription(eventName, handler) {
18997
- const eventBus = useEventBus();
18998
- const handlerRef = useRef8(handler);
18999
- useEffect11(() => {
19000
- handlerRef.current = handler;
19001
- });
19002
- useEffect11(() => {
19003
- const stableHandler = (payload) => {
19004
- handlerRef.current(payload);
19005
- };
19006
- eventBus.on(eventName, stableHandler);
19007
- return () => {
19008
- eventBus.off(eventName, stableHandler);
19009
- };
19010
- }, [eventName]);
19011
- }
19012
- function useEventSubscriptions(subscriptions) {
19013
- const eventBus = useEventBus();
19014
- const handlersRef = useRef8(subscriptions);
19015
- useEffect11(() => {
19016
- handlersRef.current = subscriptions;
19017
- });
19018
- const eventNames = useMemo(
19019
- () => Object.keys(subscriptions).sort(),
19020
- // eslint-disable-next-line react-hooks/exhaustive-deps
19021
- [Object.keys(subscriptions).sort().join(",")]
19022
- );
19023
- useEffect11(() => {
19024
- const stableHandlers = /* @__PURE__ */ new Map();
19025
- for (const eventName of eventNames) {
19026
- const stableHandler = (payload) => {
19027
- const currentHandler = handlersRef.current[eventName];
19028
- if (currentHandler) {
19029
- currentHandler(payload);
19030
- } else {
19031
- console.warn("[useEventSubscriptions] No current handler found for:", eventName);
19032
- }
19033
- };
19034
- stableHandlers.set(eventName, stableHandler);
19035
- eventBus.on(eventName, stableHandler);
19036
- }
19037
- return () => {
19038
- for (const [eventName, stableHandler] of stableHandlers) {
19039
- eventBus.off(eventName, stableHandler);
19040
- }
19041
- };
19042
- }, [eventNames]);
19043
- }
19044
-
19045
18943
  // src/contexts/ResourceAnnotationsContext.tsx
19046
- import { createContext as createContext6, useContext as useContext6, useState as useState10, useCallback as useCallback10, useMemo as useMemo2 } from "react";
18944
+ import { createContext as createContext6, useContext as useContext6, useState as useState9, useCallback as useCallback9, useMemo } from "react";
19047
18945
 
19048
18946
  // src/components/LiveRegion.tsx
19049
- import { useState as useState9, createContext as createContext5, useContext as useContext5, useCallback as useCallback9 } from "react";
18947
+ import { useState as useState8, createContext as createContext5, useContext as useContext5, useCallback as useCallback8 } from "react";
19050
18948
  import { jsx as jsx5, jsxs } from "react/jsx-runtime";
19051
18949
  var LiveRegionContext = createContext5(null);
19052
18950
  function useLiveRegion() {
@@ -19058,9 +18956,9 @@ function useLiveRegion() {
19058
18956
  return context;
19059
18957
  }
19060
18958
  function LiveRegionProvider({ children }) {
19061
- const [politeMessage, setPoliteMessage] = useState9("");
19062
- const [assertiveMessage, setAssertiveMessage] = useState9("");
19063
- const announce = useCallback9((message, priority = "polite") => {
18959
+ const [politeMessage, setPoliteMessage] = useState8("");
18960
+ const [assertiveMessage, setAssertiveMessage] = useState8("");
18961
+ const announce = useCallback8((message, priority = "polite") => {
19064
18962
  if (priority === "assertive") {
19065
18963
  setAssertiveMessage(message);
19066
18964
  setTimeout(() => setAssertiveMessage(""), 1e3);
@@ -19095,14 +18993,14 @@ function LiveRegionProvider({ children }) {
19095
18993
  }
19096
18994
  function useSearchAnnouncements() {
19097
18995
  const { announce } = useLiveRegion();
19098
- const announceSearchResults = useCallback9((count2, query) => {
18996
+ const announceSearchResults = useCallback8((count2, query) => {
19099
18997
  if (count2 === 0) {
19100
18998
  announce(`No results found for ${query}`, "polite");
19101
18999
  } else {
19102
19000
  announce(`${count2} result${count2 === 1 ? "" : "s"} found for ${query}`, "polite");
19103
19001
  }
19104
19002
  }, [announce]);
19105
- const announceSearching = useCallback9(() => {
19003
+ const announceSearching = useCallback8(() => {
19106
19004
  announce("Searching...", "polite");
19107
19005
  }, [announce]);
19108
19006
  return {
@@ -19112,26 +19010,26 @@ function useSearchAnnouncements() {
19112
19010
  }
19113
19011
  function useDocumentAnnouncements(annotators) {
19114
19012
  const { announce } = useLiveRegion();
19115
- const announceDocumentSaved = useCallback9(() => {
19013
+ const announceDocumentSaved = useCallback8(() => {
19116
19014
  announce("Document saved successfully", "polite");
19117
19015
  }, [announce]);
19118
- const announceDocumentDeleted = useCallback9(() => {
19016
+ const announceDocumentDeleted = useCallback8(() => {
19119
19017
  announce("Document deleted", "polite");
19120
19018
  }, [announce]);
19121
- const announceAnnotationCreated = useCallback9((annotation) => {
19019
+ const announceAnnotationCreated = useCallback8((annotation) => {
19122
19020
  const metadata = annotators ? Object.values(annotators).find((a15) => a15.matchesAnnotation(annotation)) : null;
19123
19021
  const message = metadata?.announceOnCreate ?? "Annotation created";
19124
19022
  announce(message, "polite");
19125
19023
  }, [announce, annotators]);
19126
- const announceAnnotationDeleted = useCallback9(() => {
19024
+ const announceAnnotationDeleted = useCallback8(() => {
19127
19025
  announce("Annotation deleted", "polite");
19128
19026
  }, [announce]);
19129
- const announceAnnotationUpdated = useCallback9((annotation) => {
19027
+ const announceAnnotationUpdated = useCallback8((annotation) => {
19130
19028
  const metadata = annotators ? Object.values(annotators).find((a15) => a15.matchesAnnotation(annotation)) : null;
19131
19029
  const message = `${metadata?.displayName ?? "Annotation"} updated`;
19132
19030
  announce(message, "polite");
19133
19031
  }, [announce, annotators]);
19134
- const announceError = useCallback9((message) => {
19032
+ const announceError = useCallback8((message) => {
19135
19033
  announce(`Error: ${message}`, "assertive");
19136
19034
  }, [announce]);
19137
19035
  return {
@@ -19145,18 +19043,18 @@ function useDocumentAnnouncements(annotators) {
19145
19043
  }
19146
19044
  function useResourceLoadingAnnouncements() {
19147
19045
  const { announce } = useLiveRegion();
19148
- const announceResourceLoading = useCallback9((resourceName) => {
19046
+ const announceResourceLoading = useCallback8((resourceName) => {
19149
19047
  const message = resourceName ? `Loading ${resourceName}...` : "Loading resource...";
19150
19048
  announce(message, "polite");
19151
19049
  }, [announce]);
19152
- const announceResourceLoaded = useCallback9((resourceName) => {
19050
+ const announceResourceLoaded = useCallback8((resourceName) => {
19153
19051
  announce(`${resourceName} loaded successfully`, "polite");
19154
19052
  }, [announce]);
19155
- const announceResourceLoadError = useCallback9((resourceName) => {
19053
+ const announceResourceLoadError = useCallback8((resourceName) => {
19156
19054
  const message = resourceName ? `Failed to load ${resourceName}` : "Failed to load resource";
19157
19055
  announce(message, "assertive");
19158
19056
  }, [announce]);
19159
- const announceResourceUpdating = useCallback9((resourceName) => {
19057
+ const announceResourceUpdating = useCallback8((resourceName) => {
19160
19058
  announce(`Updating ${resourceName}...`, "polite");
19161
19059
  }, [announce]);
19162
19060
  return {
@@ -19168,16 +19066,16 @@ function useResourceLoadingAnnouncements() {
19168
19066
  }
19169
19067
  function useFormAnnouncements() {
19170
19068
  const { announce } = useLiveRegion();
19171
- const announceFormSubmitting = useCallback9(() => {
19069
+ const announceFormSubmitting = useCallback8(() => {
19172
19070
  announce("Submitting form...", "polite");
19173
19071
  }, [announce]);
19174
- const announceFormSuccess = useCallback9((message) => {
19072
+ const announceFormSuccess = useCallback8((message) => {
19175
19073
  announce(message || "Form submitted successfully", "polite");
19176
19074
  }, [announce]);
19177
- const announceFormError = useCallback9((message) => {
19075
+ const announceFormError = useCallback8((message) => {
19178
19076
  announce(message || "Form submission failed. Please check your entries and try again.", "assertive");
19179
19077
  }, [announce]);
19180
- const announceFormValidationError = useCallback9((fieldCount) => {
19078
+ const announceFormValidationError = useCallback8((fieldCount) => {
19181
19079
  const message = fieldCount === 1 ? "There is 1 field with an error" : `There are ${fieldCount} fields with errors`;
19182
19080
  announce(message, "assertive");
19183
19081
  }, [announce]);
@@ -19190,10 +19088,10 @@ function useFormAnnouncements() {
19190
19088
  }
19191
19089
  function useLanguageChangeAnnouncements() {
19192
19090
  const { announce } = useLiveRegion();
19193
- const announceLanguageChanging = useCallback9((newLanguage) => {
19091
+ const announceLanguageChanging = useCallback8((newLanguage) => {
19194
19092
  announce(`Changing language to ${newLanguage}...`, "polite");
19195
19093
  }, [announce]);
19196
- const announceLanguageChanged = useCallback9((newLanguage) => {
19094
+ const announceLanguageChanged = useCallback8((newLanguage) => {
19197
19095
  announce(`Language changed to ${newLanguage}`, "polite");
19198
19096
  }, [announce]);
19199
19097
  return {
@@ -19206,11 +19104,11 @@ function useLanguageChangeAnnouncements() {
19206
19104
  import { jsx as jsx6 } from "react/jsx-runtime";
19207
19105
  var ResourceAnnotationsContext = createContext6(void 0);
19208
19106
  function ResourceAnnotationsProvider({ children }) {
19209
- const [newAnnotationIds, setNewAnnotationIds] = useState10(/* @__PURE__ */ new Set());
19107
+ const [newAnnotationIds, setNewAnnotationIds] = useState9(/* @__PURE__ */ new Set());
19210
19108
  const { announceAnnotationCreated, announceError } = useDocumentAnnouncements();
19211
19109
  const annotations = useAnnotations();
19212
19110
  const createAnnotationMutation = annotations.create.useMutation();
19213
- const createAnnotation = useCallback10(async (rUri, motivation, selector, body = []) => {
19111
+ const createAnnotation = useCallback9(async (rUri, motivation, selector, body = []) => {
19214
19112
  try {
19215
19113
  const createData = {
19216
19114
  motivation,
@@ -19242,14 +19140,14 @@ function ResourceAnnotationsProvider({ children }) {
19242
19140
  throw err;
19243
19141
  }
19244
19142
  }, [createAnnotationMutation, announceAnnotationCreated, announceError]);
19245
- const clearNewAnnotationId = useCallback10((id2) => {
19143
+ const clearNewAnnotationId = useCallback9((id2) => {
19246
19144
  setNewAnnotationIds((prev) => {
19247
19145
  const next = new Set(prev);
19248
19146
  next.delete(id2);
19249
19147
  return next;
19250
19148
  });
19251
19149
  }, []);
19252
- const triggerSparkleAnimation = useCallback10((annotationId) => {
19150
+ const triggerSparkleAnimation = useCallback9((annotationId) => {
19253
19151
  setNewAnnotationIds((prev) => new Set(prev).add(annotationId));
19254
19152
  setTimeout(() => {
19255
19153
  setNewAnnotationIds((prev) => {
@@ -19259,7 +19157,7 @@ function ResourceAnnotationsProvider({ children }) {
19259
19157
  });
19260
19158
  }, 6e3);
19261
19159
  }, []);
19262
- const contextValue = useMemo2(
19160
+ const contextValue = useMemo(
19263
19161
  () => ({
19264
19162
  newAnnotationIds,
19265
19163
  createAnnotation,
@@ -19279,7 +19177,7 @@ function useResourceAnnotations() {
19279
19177
  }
19280
19178
 
19281
19179
  // src/components/CodeMirrorRenderer.tsx
19282
- import { useEffect as useEffect12, useRef as useRef9 } from "react";
19180
+ import { useEffect as useEffect10, useRef as useRef7 } from "react";
19283
19181
 
19284
19182
  // ../../node_modules/@codemirror/autocomplete/dist/index.js
19285
19183
  var CompletionContext = class {
@@ -26754,18 +26652,18 @@ function CodeMirrorRenderer({
26754
26652
  getTargetDocumentName,
26755
26653
  generatingReferenceId
26756
26654
  }) {
26757
- const containerRef = useRef9(null);
26758
- const viewRef = useRef9(null);
26759
- const contentRef = useRef9(content4);
26655
+ const containerRef = useRef7(null);
26656
+ const viewRef = useRef7(null);
26657
+ const contentRef = useRef7(content4);
26760
26658
  const convertedSegments = convertSegmentPositions(segments, content4);
26761
- const segmentsRef = useRef9(convertedSegments);
26762
- const lineNumbersCompartment = useRef9(new Compartment());
26763
- const eventBusRef = useRef9(eventBus);
26764
- const getTargetDocumentNameRef = useRef9(getTargetDocumentName);
26659
+ const segmentsRef = useRef7(convertedSegments);
26660
+ const lineNumbersCompartment = useRef7(new Compartment());
26661
+ const eventBusRef = useRef7(eventBus);
26662
+ const getTargetDocumentNameRef = useRef7(getTargetDocumentName);
26765
26663
  segmentsRef.current = segments;
26766
26664
  eventBusRef.current = eventBus;
26767
26665
  getTargetDocumentNameRef.current = getTargetDocumentName;
26768
- useEffect12(() => {
26666
+ useEffect10(() => {
26769
26667
  if (!containerRef.current || viewRef.current) return;
26770
26668
  const annotationDecorationsField = createAnnotationDecorationsField();
26771
26669
  const state = EditorState.create({
@@ -26855,31 +26753,31 @@ function CodeMirrorRenderer({
26855
26753
  contentRef.current = content4;
26856
26754
  containerRef.current.__cmView = view;
26857
26755
  const container = view.dom;
26756
+ const { handleMouseEnter, handleMouseLeave, cleanup: cleanupHover } = createHoverHandlers(
26757
+ (annotationId) => eventBusRef.current?.emit("annotation:hover", { annotationId })
26758
+ );
26858
26759
  const handleMouseOver = (e6) => {
26859
26760
  const target = e6.target;
26860
26761
  const annotationElement = target.closest("[data-annotation-id]");
26861
26762
  const annotationId = annotationElement?.getAttribute("data-annotation-id");
26862
- if (annotationId && eventBusRef.current) {
26863
- eventBusRef.current.emit("annotation:hover", { annotationId });
26864
- }
26763
+ if (annotationId) handleMouseEnter(annotationId);
26865
26764
  };
26866
26765
  const handleMouseOut = (e6) => {
26867
26766
  const target = e6.target;
26868
26767
  const annotationElement = target.closest("[data-annotation-id]");
26869
- if (annotationElement && eventBusRef.current) {
26870
- eventBusRef.current.emit("annotation:hover", { annotationId: null });
26871
- }
26768
+ if (annotationElement) handleMouseLeave();
26872
26769
  };
26873
26770
  container.addEventListener("mouseover", handleMouseOver);
26874
26771
  container.addEventListener("mouseout", handleMouseOut);
26875
26772
  return () => {
26876
26773
  container.removeEventListener("mouseover", handleMouseOver);
26877
26774
  container.removeEventListener("mouseout", handleMouseOut);
26775
+ cleanupHover();
26878
26776
  view.destroy();
26879
26777
  viewRef.current = null;
26880
26778
  };
26881
26779
  }, []);
26882
- useEffect12(() => {
26780
+ useEffect10(() => {
26883
26781
  if (!viewRef.current) return;
26884
26782
  const currentContent = viewRef.current.state.doc.toString();
26885
26783
  if (content4 === currentContent) return;
@@ -26895,19 +26793,19 @@ function CodeMirrorRenderer({
26895
26793
  });
26896
26794
  contentRef.current = content4;
26897
26795
  }, [content4]);
26898
- useEffect12(() => {
26796
+ useEffect10(() => {
26899
26797
  if (!viewRef.current) return;
26900
26798
  viewRef.current.dispatch({
26901
26799
  effects: lineNumbersCompartment.current.reconfigure(showLineNumbers ? lineNumbers() : [])
26902
26800
  });
26903
26801
  }, [showLineNumbers]);
26904
- useEffect12(() => {
26802
+ useEffect10(() => {
26905
26803
  if (!viewRef.current) return;
26906
26804
  viewRef.current.dispatch({
26907
26805
  effects: updateAnnotationsEffect.of({ segments: convertedSegments, ...newAnnotationIds && { newAnnotationIds } })
26908
26806
  });
26909
26807
  }, [convertedSegments, newAnnotationIds]);
26910
- useEffect12(() => {
26808
+ useEffect10(() => {
26911
26809
  if (!viewRef.current || !enableWidgets) return;
26912
26810
  viewRef.current.dispatch({
26913
26811
  effects: updateWidgetsEffect.of({
@@ -26919,7 +26817,7 @@ function CodeMirrorRenderer({
26919
26817
  })
26920
26818
  });
26921
26819
  }, [content4, convertedSegments, enableWidgets, generatingReferenceId]);
26922
- useEffect12(() => {
26820
+ useEffect10(() => {
26923
26821
  if (!viewRef.current || !hoveredAnnotationId) return void 0;
26924
26822
  const view = viewRef.current;
26925
26823
  const element2 = view.contentDOM.querySelector(
@@ -26947,7 +26845,7 @@ function CodeMirrorRenderer({
26947
26845
  element2.classList.remove("annotation-pulse");
26948
26846
  };
26949
26847
  }, [hoveredAnnotationId]);
26950
- useEffect12(() => {
26848
+ useEffect10(() => {
26951
26849
  if (!viewRef.current || !hoveredCommentId) return void 0;
26952
26850
  const view = viewRef.current;
26953
26851
  const element2 = view.contentDOM.querySelector(
@@ -26975,7 +26873,7 @@ function CodeMirrorRenderer({
26975
26873
  element2.classList.remove("annotation-pulse");
26976
26874
  };
26977
26875
  }, [hoveredCommentId]);
26978
- useEffect12(() => {
26876
+ useEffect10(() => {
26979
26877
  if (!viewRef.current || !scrollToAnnotationId) return;
26980
26878
  const view = viewRef.current;
26981
26879
  const element2 = view.contentDOM.querySelector(
@@ -27174,7 +27072,7 @@ function AsyncErrorBoundary({ children }) {
27174
27072
  }
27175
27073
 
27176
27074
  // src/components/ResizeHandle.tsx
27177
- import { useRef as useRef10, useCallback as useCallback11, useEffect as useEffect13, useState as useState11 } from "react";
27075
+ import { useRef as useRef8, useCallback as useCallback10, useEffect as useEffect11, useState as useState10 } from "react";
27178
27076
  import { jsx as jsx11 } from "react/jsx-runtime";
27179
27077
  function ResizeHandle({
27180
27078
  onResize,
@@ -27183,14 +27081,14 @@ function ResizeHandle({
27183
27081
  position: position3 = "left",
27184
27082
  ariaLabel = "Resize panel"
27185
27083
  }) {
27186
- const [isDragging, setIsDragging] = useState11(false);
27187
- const startXRef = useRef10(0);
27188
- const startWidthRef = useRef10(0);
27189
- const onResizeRef = useRef10(onResize);
27190
- useEffect13(() => {
27084
+ const [isDragging, setIsDragging] = useState10(false);
27085
+ const startXRef = useRef8(0);
27086
+ const startWidthRef = useRef8(0);
27087
+ const onResizeRef = useRef8(onResize);
27088
+ useEffect11(() => {
27191
27089
  onResizeRef.current = onResize;
27192
27090
  });
27193
- const handleMouseDown = useCallback11((e6) => {
27091
+ const handleMouseDown = useCallback10((e6) => {
27194
27092
  e6.preventDefault();
27195
27093
  setIsDragging(true);
27196
27094
  startXRef.current = e6.clientX;
@@ -27199,7 +27097,7 @@ function ResizeHandle({
27199
27097
  startWidthRef.current = parent.offsetWidth;
27200
27098
  }
27201
27099
  }, []);
27202
- const handleMouseMove = useCallback11((e6) => {
27100
+ const handleMouseMove = useCallback10((e6) => {
27203
27101
  if (!isDragging) return;
27204
27102
  const deltaX = e6.clientX - startXRef.current;
27205
27103
  const widthDelta = position3 === "left" ? -deltaX : deltaX;
@@ -27207,10 +27105,10 @@ function ResizeHandle({
27207
27105
  const constrainedWidth = Math.max(minWidth, Math.min(maxWidth, newWidth));
27208
27106
  onResizeRef.current(constrainedWidth);
27209
27107
  }, [isDragging, minWidth, maxWidth, position3]);
27210
- const handleMouseUp = useCallback11(() => {
27108
+ const handleMouseUp = useCallback10(() => {
27211
27109
  setIsDragging(false);
27212
27110
  }, []);
27213
- const handleKeyDown = useCallback11((e6) => {
27111
+ const handleKeyDown = useCallback10((e6) => {
27214
27112
  const parent = e6.target.parentElement;
27215
27113
  if (!parent) return;
27216
27114
  const currentWidth = parent.offsetWidth;
@@ -27238,7 +27136,7 @@ function ResizeHandle({
27238
27136
  onResizeRef.current(constrainedWidth);
27239
27137
  }
27240
27138
  }, [minWidth, maxWidth, position3]);
27241
- useEffect13(() => {
27139
+ useEffect11(() => {
27242
27140
  if (isDragging) {
27243
27141
  document.addEventListener("mousemove", handleMouseMove);
27244
27142
  document.addEventListener("mouseup", handleMouseUp);
@@ -27396,7 +27294,7 @@ function Toolbar({
27396
27294
  }
27397
27295
 
27398
27296
  // src/components/settings/SettingsPanel.tsx
27399
- import React6, { useEffect as useEffect14 } from "react";
27297
+ import React6, { useEffect as useEffect12 } from "react";
27400
27298
  import { LOCALES } from "@semiont/api-client";
27401
27299
  import { jsx as jsx14, jsxs as jsxs5 } from "react/jsx-runtime";
27402
27300
  function SettingsPanel({
@@ -27414,7 +27312,7 @@ function SettingsPanel({
27414
27312
  announceLanguageChanging(localeName);
27415
27313
  eventBus.emit("settings:locale-changed", { locale: newLocale });
27416
27314
  };
27417
- useEffect14(() => {
27315
+ useEffect12(() => {
27418
27316
  if (locale !== previousLocale && !isPendingLocaleChange) {
27419
27317
  const localeName = LOCALES.find((l10) => l10.code === locale)?.nativeName || locale;
27420
27318
  announceLanguageChanged(localeName);
@@ -27511,7 +27409,7 @@ function SettingsPanel({
27511
27409
  }
27512
27410
 
27513
27411
  // src/components/annotation/AnnotateToolbar.tsx
27514
- import React7, { useState as useState12, useRef as useRef11, useEffect as useEffect15 } from "react";
27412
+ import React7, { useState as useState11, useRef as useRef9, useEffect as useEffect13 } from "react";
27515
27413
  import { Fragment as Fragment2, jsx as jsx15, jsxs as jsxs6 } from "react/jsx-runtime";
27516
27414
  function DropdownGroup({
27517
27415
  label,
@@ -27522,7 +27420,7 @@ function DropdownGroup({
27522
27420
  onPin,
27523
27421
  containerRef
27524
27422
  }) {
27525
- const dropdownRef = useRef11(null);
27423
+ const dropdownRef = useRef9(null);
27526
27424
  const handleKeyDown = (event) => {
27527
27425
  if (event.key === "Enter" || event.key === " ") {
27528
27426
  event.preventDefault();
@@ -27585,23 +27483,23 @@ function AnnotateToolbar({
27585
27483
  const annotator = Object.values(annotators).find((a15) => a15.motivation === motivation);
27586
27484
  return annotator?.iconEmoji || "\u2753";
27587
27485
  };
27588
- const [modeHovered, setModeHovered] = useState12(false);
27589
- const [modePinned, setModePinned] = useState12(false);
27590
- const [clickHovered, setClickHovered] = useState12(false);
27591
- const [clickPinned, setClickPinned] = useState12(false);
27592
- const [selectionHovered, setSelectionHovered] = useState12(false);
27593
- const [selectionPinned, setSelectionPinned] = useState12(false);
27594
- const [shapeHovered, setShapeHovered] = useState12(false);
27595
- const [shapePinned, setShapePinned] = useState12(false);
27596
- const modeRef = useRef11(null);
27597
- const clickRef = useRef11(null);
27598
- const selectionRef = useRef11(null);
27599
- const shapeRef = useRef11(null);
27486
+ const [modeHovered, setModeHovered] = useState11(false);
27487
+ const [modePinned, setModePinned] = useState11(false);
27488
+ const [clickHovered, setClickHovered] = useState11(false);
27489
+ const [clickPinned, setClickPinned] = useState11(false);
27490
+ const [selectionHovered, setSelectionHovered] = useState11(false);
27491
+ const [selectionPinned, setSelectionPinned] = useState11(false);
27492
+ const [shapeHovered, setShapeHovered] = useState11(false);
27493
+ const [shapePinned, setShapePinned] = useState11(false);
27494
+ const modeRef = useRef9(null);
27495
+ const clickRef = useRef9(null);
27496
+ const selectionRef = useRef9(null);
27497
+ const shapeRef = useRef9(null);
27600
27498
  const modeExpanded = modeHovered || modePinned;
27601
27499
  const clickExpanded = clickHovered || clickPinned;
27602
27500
  const selectionExpanded = selectionHovered || selectionPinned;
27603
27501
  const shapeExpanded = shapeHovered || shapePinned;
27604
- useEffect15(() => {
27502
+ useEffect13(() => {
27605
27503
  const handleClickOutside = (event) => {
27606
27504
  if (modePinned && modeRef.current && !modeRef.current.contains(event.target)) {
27607
27505
  setModePinned(false);
@@ -27619,7 +27517,7 @@ function AnnotateToolbar({
27619
27517
  document.addEventListener("mousedown", handleClickOutside);
27620
27518
  return () => document.removeEventListener("mousedown", handleClickOutside);
27621
27519
  }, [modePinned, clickPinned, selectionPinned, shapePinned]);
27622
- useEffect15(() => {
27520
+ useEffect13(() => {
27623
27521
  const handleEscape = (event) => {
27624
27522
  if (event.key === "Escape") {
27625
27523
  setModePinned(false);
@@ -27719,10 +27617,17 @@ function AnnotateToolbar({
27719
27617
  onHoverChange: setClickHovered,
27720
27618
  onPin: () => setClickPinned(!clickPinned),
27721
27619
  containerRef: clickRef,
27722
- collapsedContent: /* @__PURE__ */ jsxs6("div", { className: "semiont-dropdown-display", children: [
27723
- /* @__PURE__ */ jsx15("span", { className: "semiont-dropdown-icon", children: clickActions.find((a15) => a15.action === selectedClick)?.icon }),
27724
- /* @__PURE__ */ jsx15("span", { className: "semiont-dropdown-label", children: clickActions.find((a15) => a15.action === selectedClick)?.label })
27725
- ] }),
27620
+ collapsedContent: /* @__PURE__ */ jsxs6(
27621
+ "div",
27622
+ {
27623
+ className: "semiont-dropdown-display",
27624
+ "data-delete": clickActions.find((a15) => a15.action === selectedClick)?.isDelete ? "true" : "false",
27625
+ children: [
27626
+ /* @__PURE__ */ jsx15("span", { className: "semiont-dropdown-icon", children: clickActions.find((a15) => a15.action === selectedClick)?.icon }),
27627
+ /* @__PURE__ */ jsx15("span", { className: "semiont-dropdown-label", children: clickActions.find((a15) => a15.action === selectedClick)?.label })
27628
+ ]
27629
+ }
27630
+ ),
27726
27631
  expandedContent: /* @__PURE__ */ jsx15(Fragment2, { children: clickActions.map(({ action, icon, label, isDelete }) => /* @__PURE__ */ jsx15(React7.Fragment, { children: renderButton(icon, label, selectedClick === action, () => handleClickClick(action), isDelete) }, action)) })
27727
27632
  }
27728
27633
  ),
@@ -27794,7 +27699,7 @@ function AnnotateToolbar({
27794
27699
  }
27795
27700
 
27796
27701
  // src/components/annotation-popups/JsonLdView.tsx
27797
- import { useEffect as useEffect16, useRef as useRef12 } from "react";
27702
+ import { useEffect as useEffect14, useRef as useRef10 } from "react";
27798
27703
 
27799
27704
  // ../../node_modules/@lezer/json/dist/index.js
27800
27705
  var jsonHighlighting = styleTags({
@@ -27998,14 +27903,14 @@ var oneDark = [oneDarkTheme, /* @__PURE__ */ syntaxHighlighting(oneDarkHighlight
27998
27903
  // src/components/annotation-popups/JsonLdView.tsx
27999
27904
  import { jsx as jsx16, jsxs as jsxs7 } from "react/jsx-runtime";
28000
27905
  function JsonLdView({ annotation, onBack }) {
28001
- const editorRef = useRef12(null);
28002
- const viewRef = useRef12(null);
27906
+ const editorRef = useRef10(null);
27907
+ const viewRef = useRef10(null);
28003
27908
  const { showLineNumbers } = useLineNumbers();
28004
- const onBackRef = useRef12(onBack);
28005
- useEffect16(() => {
27909
+ const onBackRef = useRef10(onBack);
27910
+ useEffect14(() => {
28006
27911
  onBackRef.current = onBack;
28007
27912
  });
28008
- useEffect16(() => {
27913
+ useEffect14(() => {
28009
27914
  const handleKeyDown = (e6) => {
28010
27915
  if (e6.key === "Escape") {
28011
27916
  onBackRef.current();
@@ -28014,7 +27919,7 @@ function JsonLdView({ annotation, onBack }) {
28014
27919
  window.addEventListener("keydown", handleKeyDown);
28015
27920
  return () => window.removeEventListener("keydown", handleKeyDown);
28016
27921
  }, []);
28017
- useEffect16(() => {
27922
+ useEffect14(() => {
28018
27923
  if (!editorRef.current) return;
28019
27924
  const isDarkMode = document.documentElement.classList.contains("dark");
28020
27925
  const jsonContent = JSON.stringify(annotation, null, 2);
@@ -29684,7 +29589,7 @@ function PopupContainer({ children, position: position3, onClose, isOpen, wide =
29684
29589
  }
29685
29590
 
29686
29591
  // src/components/image-annotation/AnnotationOverlay.tsx
29687
- import { useRef as useRef13 } from "react";
29592
+ import { useMemo as useMemo2 } from "react";
29688
29593
  import { getSvgSelector, isHighlight as isHighlight3, isReference as isReference3, isAssessment as isAssessment2, isComment as isComment3, isTag as isTag4, isBodyResolved, isResolvedReference as isResolvedReference3 } from "@semiont/api-client";
29689
29594
  import { parseSvgSelector } from "@semiont/api-client";
29690
29595
  import { jsx as jsx18, jsxs as jsxs9 } from "react/jsx-runtime";
@@ -29730,19 +29635,10 @@ function AnnotationOverlay({
29730
29635
  }) {
29731
29636
  const scaleX = displayWidth / imageWidth;
29732
29637
  const scaleY = displayHeight / imageHeight;
29733
- const currentHover = useRef13(null);
29734
- const handleMouseEnter = (annotationId) => {
29735
- if (currentHover.current !== annotationId) {
29736
- currentHover.current = annotationId;
29737
- eventBus?.emit("annotation:hover", { annotationId });
29738
- }
29739
- };
29740
- const handleMouseLeave = () => {
29741
- if (currentHover.current !== null) {
29742
- currentHover.current = null;
29743
- eventBus?.emit("annotation:hover", { annotationId: null });
29744
- }
29745
- };
29638
+ const { handleMouseEnter, handleMouseLeave } = useMemo2(
29639
+ () => createHoverHandlers((annotationId) => eventBus?.emit("annotation:hover", { annotationId })),
29640
+ [eventBus]
29641
+ );
29746
29642
  return /* @__PURE__ */ jsx18(
29747
29643
  "svg",
29748
29644
  {
@@ -29908,7 +29804,7 @@ function AnnotationOverlay({
29908
29804
  }
29909
29805
 
29910
29806
  // src/components/image-annotation/SvgDrawingCanvas.tsx
29911
- import { useRef as useRef14, useState as useState14, useEffect as useEffect18, useCallback as useCallback12, useMemo as useMemo3 } from "react";
29807
+ import { useRef as useRef11, useState as useState13, useEffect as useEffect16, useCallback as useCallback11, useMemo as useMemo3 } from "react";
29912
29808
  import { createRectangleSvg, createCircleSvg, createPolygonSvg, scaleSvgToNative, parseSvgSelector as parseSvgSelector2 } from "@semiont/api-client";
29913
29809
  import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
29914
29810
  function getMotivationColor(motivation) {
@@ -29945,14 +29841,14 @@ function SvgDrawingCanvas({
29945
29841
  const resourceId = resourceUri2.split("/").pop();
29946
29842
  return `/api/resources/${resourceId}`;
29947
29843
  }, [resourceUri2]);
29948
- const containerRef = useRef14(null);
29949
- const imageRef = useRef14(null);
29950
- const [imageDimensions, setImageDimensions] = useState14(null);
29951
- const [displayDimensions, setDisplayDimensions] = useState14(null);
29952
- const [isDrawing, setIsDrawing] = useState14(false);
29953
- const [startPoint, setStartPoint] = useState14(null);
29954
- const [currentPoint, setCurrentPoint] = useState14(null);
29955
- useEffect18(() => {
29844
+ const containerRef = useRef11(null);
29845
+ const imageRef = useRef11(null);
29846
+ const [imageDimensions, setImageDimensions] = useState13(null);
29847
+ const [displayDimensions, setDisplayDimensions] = useState13(null);
29848
+ const [isDrawing, setIsDrawing] = useState13(false);
29849
+ const [startPoint, setStartPoint] = useState13(null);
29850
+ const [currentPoint, setCurrentPoint] = useState13(null);
29851
+ useEffect16(() => {
29956
29852
  const img = new Image();
29957
29853
  img.onload = () => {
29958
29854
  setImageDimensions({
@@ -29962,7 +29858,7 @@ function SvgDrawingCanvas({
29962
29858
  };
29963
29859
  img.src = imageUrl;
29964
29860
  }, [imageUrl]);
29965
- useEffect18(() => {
29861
+ useEffect16(() => {
29966
29862
  const updateDisplayDimensions = () => {
29967
29863
  if (imageRef.current) {
29968
29864
  setDisplayDimensions({
@@ -29990,7 +29886,7 @@ function SvgDrawingCanvas({
29990
29886
  }
29991
29887
  };
29992
29888
  }, []);
29993
- const getRelativeCoordinates = useCallback12((e6) => {
29889
+ const getRelativeCoordinates = useCallback11((e6) => {
29994
29890
  if (!imageRef.current) return null;
29995
29891
  const rect = imageRef.current.getBoundingClientRect();
29996
29892
  return {
@@ -29998,7 +29894,7 @@ function SvgDrawingCanvas({
29998
29894
  y: e6.clientY - rect.top
29999
29895
  };
30000
29896
  }, []);
30001
- const handleMouseDown = useCallback12((e6) => {
29897
+ const handleMouseDown = useCallback11((e6) => {
30002
29898
  if (!drawingMode) return;
30003
29899
  const point4 = getRelativeCoordinates(e6);
30004
29900
  if (point4) {
@@ -30007,14 +29903,14 @@ function SvgDrawingCanvas({
30007
29903
  setCurrentPoint(point4);
30008
29904
  }
30009
29905
  }, [drawingMode, getRelativeCoordinates]);
30010
- const handleMouseMove = useCallback12((e6) => {
29906
+ const handleMouseMove = useCallback11((e6) => {
30011
29907
  if (!isDrawing || !startPoint) return;
30012
29908
  const point4 = getRelativeCoordinates(e6);
30013
29909
  if (point4) {
30014
29910
  setCurrentPoint(point4);
30015
29911
  }
30016
29912
  }, [isDrawing, startPoint, getRelativeCoordinates]);
30017
- const handleMouseUp = useCallback12((e6) => {
29913
+ const handleMouseUp = useCallback11((e6) => {
30018
29914
  if (!isDrawing || !startPoint || !drawingMode) return;
30019
29915
  const endPoint = getRelativeCoordinates(e6);
30020
29916
  if (!endPoint || !displayDimensions || !imageDimensions) return;
@@ -30110,7 +30006,7 @@ function SvgDrawingCanvas({
30110
30006
  setStartPoint(null);
30111
30007
  setCurrentPoint(null);
30112
30008
  }, [isDrawing, startPoint, drawingMode, displayDimensions, imageDimensions, getRelativeCoordinates, selectedMotivation, existingAnnotations]);
30113
- const handleMouseLeave = useCallback12(() => {
30009
+ const handleMouseLeave = useCallback11(() => {
30114
30010
  if (isDrawing) {
30115
30011
  setIsDrawing(false);
30116
30012
  setStartPoint(null);
@@ -30398,7 +30294,7 @@ function KeyboardShortcutsHelpModal({ isOpen, onClose }) {
30398
30294
  }
30399
30295
 
30400
30296
  // src/components/modals/ProposeEntitiesModal.tsx
30401
- import { useEffect as useEffect19, useState as useState15, Fragment as Fragment5 } from "react";
30297
+ import { useEffect as useEffect17, useState as useState14, Fragment as Fragment5 } from "react";
30402
30298
  import { jsx as jsx21, jsxs as jsxs12 } from "react/jsx-runtime";
30403
30299
  var STORAGE_KEY = "userPreferredEntityTypes";
30404
30300
  function ProposeEntitiesModal({
@@ -30406,11 +30302,11 @@ function ProposeEntitiesModal({
30406
30302
  onConfirm,
30407
30303
  onCancel
30408
30304
  }) {
30409
- const [selectedTypes, setSelectedTypes] = useState15([]);
30305
+ const [selectedTypes, setSelectedTypes] = useState14([]);
30410
30306
  const entityTypesAPI = useEntityTypes();
30411
30307
  const { data: entityTypesData } = entityTypesAPI.list.useQuery();
30412
30308
  const allEntityTypes = entityTypesData?.entityTypes || [];
30413
- useEffect19(() => {
30309
+ useEffect17(() => {
30414
30310
  if (isOpen) {
30415
30311
  try {
30416
30312
  const saved = sessionStorage.getItem(STORAGE_KEY);
@@ -30520,11 +30416,11 @@ function ProposeEntitiesModal({
30520
30416
  }
30521
30417
 
30522
30418
  // src/components/resource/AnnotateView.tsx
30523
- import { useRef as useRef15, useEffect as useEffect20, useCallback as useCallback13, lazy, Suspense } from "react";
30419
+ import { useRef as useRef12, useEffect as useEffect18, useCallback as useCallback12, lazy, Suspense } from "react";
30524
30420
  import { getTextPositionSelector, getTextQuoteSelector, getTargetSelector, getMimeCategory, isPdfMimeType as isPdfMimeType2, resourceUri as toResourceUri } from "@semiont/api-client";
30525
30421
  import { findTextWithContext } from "@semiont/api-client";
30526
30422
  import { jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
30527
- var PdfAnnotationCanvas = lazy(() => import("./PdfAnnotationCanvas.client-RAJRPQLU.mjs").then((mod) => ({ default: mod.PdfAnnotationCanvas })));
30423
+ var PdfAnnotationCanvas = lazy(() => import("./PdfAnnotationCanvas.client-FGV33CWN.mjs").then((mod) => ({ default: mod.PdfAnnotationCanvas })));
30528
30424
  function extractContext(content4, start2, end) {
30529
30425
  const CONTEXT_LENGTH = 32;
30530
30426
  const result = {};
@@ -30606,25 +30502,25 @@ function AnnotateView({
30606
30502
  annotateMode
30607
30503
  }) {
30608
30504
  const { newAnnotationIds } = useResourceAnnotations();
30609
- const containerRef = useRef15(null);
30505
+ const containerRef = useRef12(null);
30610
30506
  const eventBus = useEventBus();
30611
30507
  const category = getMimeCategory(mimeType);
30612
30508
  const { highlights, references, assessments, comments, tags: tags3 } = annotations;
30613
30509
  const allAnnotations = [...highlights, ...references, ...assessments, ...comments, ...tags3];
30614
30510
  const segments = segmentTextWithAnnotations(content4, allAnnotations);
30615
30511
  const { selectedMotivation, selectedClick, selectedShape, hoveredAnnotationId, hoveredCommentId, scrollToAnnotationId } = uiState;
30616
- const onUIStateChangeRef = useRef15(onUIStateChange);
30512
+ const onUIStateChangeRef = useRef12(onUIStateChange);
30617
30513
  onUIStateChangeRef.current = onUIStateChange;
30618
- const handleToolbarSelectionChanged = useCallback13(({ motivation }) => {
30514
+ const handleToolbarSelectionChanged = useCallback12(({ motivation }) => {
30619
30515
  onUIStateChangeRef.current?.({ selectedMotivation: motivation });
30620
30516
  }, []);
30621
- const handleToolbarClickChanged = useCallback13(({ action }) => {
30517
+ const handleToolbarClickChanged = useCallback12(({ action }) => {
30622
30518
  onUIStateChangeRef.current?.({ selectedClick: action });
30623
30519
  }, []);
30624
- const handleToolbarShapeChanged = useCallback13(({ shape }) => {
30520
+ const handleToolbarShapeChanged = useCallback12(({ shape }) => {
30625
30521
  onUIStateChangeRef.current?.({ selectedShape: shape });
30626
30522
  }, []);
30627
- const handleAnnotationHover = useCallback13(({ annotationId }) => {
30523
+ const handleAnnotationHover = useCallback12(({ annotationId }) => {
30628
30524
  onUIStateChangeRef.current?.({ hoveredAnnotationId: annotationId });
30629
30525
  }, []);
30630
30526
  useEventSubscriptions({
@@ -30633,7 +30529,7 @@ function AnnotateView({
30633
30529
  "toolbar:shape-changed": handleToolbarShapeChanged,
30634
30530
  "annotation:hover": handleAnnotationHover
30635
30531
  });
30636
- useEffect20(() => {
30532
+ useEffect18(() => {
30637
30533
  const container = containerRef.current;
30638
30534
  if (!container) return;
30639
30535
  let clickedOnAnnotation = false;
@@ -30830,11 +30726,11 @@ function AnnotateView({
30830
30726
  }
30831
30727
 
30832
30728
  // src/components/resource/AnnotationHistory.tsx
30833
- import { useEffect as useEffect22, useRef as useRef17 } from "react";
30729
+ import { useEffect as useEffect20, useRef as useRef14 } from "react";
30834
30730
  import { getAnnotationUriFromEvent as getAnnotationUriFromEvent2 } from "@semiont/core";
30835
30731
 
30836
30732
  // src/components/resource/HistoryEvent.tsx
30837
- import { useRef as useRef16, useCallback as useCallback14, useEffect as useEffect21 } from "react";
30733
+ import { useRef as useRef13, useCallback as useCallback13, useEffect as useEffect19 } from "react";
30838
30734
  import { getAnnotationUriFromEvent } from "@semiont/core";
30839
30735
 
30840
30736
  // src/components/resource/event-formatting.ts
@@ -31074,12 +30970,12 @@ function HistoryEvent({
31074
30970
  const annotationUri2 = getAnnotationUriFromEvent(event);
31075
30971
  const creationDetails = getResourceCreationDetails(event);
31076
30972
  const entityTypes = getEventEntityTypes(event);
31077
- const hoverTimeoutRef = useRef16(null);
31078
- const onEventHoverRef = useRef16(onEventHover);
31079
- useEffect21(() => {
30973
+ const hoverTimeoutRef = useRef13(null);
30974
+ const onEventHoverRef = useRef13(onEventHover);
30975
+ useEffect19(() => {
31080
30976
  onEventHoverRef.current = onEventHover;
31081
30977
  });
31082
- const handleEmojiMouseEnter = useCallback14(() => {
30978
+ const handleEmojiMouseEnter = useCallback13(() => {
31083
30979
  if (!annotationUri2 || !onEventHoverRef.current) return;
31084
30980
  if (hoverTimeoutRef.current) {
31085
30981
  clearTimeout(hoverTimeoutRef.current);
@@ -31088,7 +30984,7 @@ function HistoryEvent({
31088
30984
  onEventHoverRef.current?.(annotationUri2);
31089
30985
  }, 300);
31090
30986
  }, [annotationUri2]);
31091
- const handleEmojiMouseLeave = useCallback14(() => {
30987
+ const handleEmojiMouseLeave = useCallback13(() => {
31092
30988
  if (hoverTimeoutRef.current) {
31093
30989
  clearTimeout(hoverTimeoutRef.current);
31094
30990
  hoverTimeoutRef.current = null;
@@ -31180,15 +31076,15 @@ function AnnotationHistory({ rUri, hoveredAnnotationId, onEventHover, onEventCli
31180
31076
  const { data: eventsData, isLoading: loading, isError: error } = resources.events.useQuery(rUri);
31181
31077
  const { data: annotationsData } = resources.annotations.useQuery(rUri);
31182
31078
  const annotations = annotationsData?.annotations || [];
31183
- const eventRefs = useRef17(/* @__PURE__ */ new Map());
31184
- const containerRef = useRef17(null);
31079
+ const eventRefs = useRef14(/* @__PURE__ */ new Map());
31080
+ const containerRef = useRef14(null);
31185
31081
  const events2 = !eventsData?.events ? [] : [...eventsData.events].filter((e6) => {
31186
31082
  const eventType = e6.event.type;
31187
31083
  return eventType !== "job.started" && eventType !== "job.progress" && eventType !== "job.completed";
31188
31084
  }).sort(
31189
31085
  (a15, b8) => a15.metadata.sequenceNumber - b8.metadata.sequenceNumber
31190
31086
  );
31191
- useEffect22(() => {
31087
+ useEffect20(() => {
31192
31088
  if (containerRef.current && events2.length > 0) {
31193
31089
  requestAnimationFrame(() => {
31194
31090
  if (containerRef.current) {
@@ -31197,7 +31093,7 @@ function AnnotationHistory({ rUri, hoveredAnnotationId, onEventHover, onEventCli
31197
31093
  });
31198
31094
  }
31199
31095
  }, [events2.length]);
31200
- useEffect22(() => {
31096
+ useEffect20(() => {
31201
31097
  if (!hoveredAnnotationId) return;
31202
31098
  const eventElement = eventRefs.current.get(hoveredAnnotationId);
31203
31099
  if (eventElement && containerRef.current) {
@@ -31255,7 +31151,7 @@ function AnnotationHistory({ rUri, hoveredAnnotationId, onEventHover, onEventCli
31255
31151
  }
31256
31152
 
31257
31153
  // src/components/resource/BrowseView.tsx
31258
- import { useEffect as useEffect24, useRef as useRef18, useCallback as useCallback15, lazy as lazy2, Suspense as Suspense2 } from "react";
31154
+ import { useEffect as useEffect22, useRef as useRef15, useCallback as useCallback14, lazy as lazy2, Suspense as Suspense2 } from "react";
31259
31155
 
31260
31156
  // ../../node_modules/devlop/lib/default.js
31261
31157
  function ok2() {
@@ -33130,7 +33026,7 @@ var urlAttributes = {
33130
33026
 
33131
33027
  // ../../node_modules/react-markdown/lib/index.js
33132
33028
  import { Fragment as Fragment6, jsx as jsx25, jsxs as jsxs16 } from "react/jsx-runtime";
33133
- import { useEffect as useEffect23, useState as useState16 } from "react";
33029
+ import { useEffect as useEffect21, useState as useState15 } from "react";
33134
33030
 
33135
33031
  // ../../node_modules/mdast-util-to-string/lib/index.js
33136
33032
  var emptyOptions2 = {};
@@ -45588,7 +45484,7 @@ function ImageViewer({ resourceUri: resourceUri2, alt = "Resource image" }) {
45588
45484
 
45589
45485
  // src/components/resource/BrowseView.tsx
45590
45486
  import { jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
45591
- var PdfAnnotationCanvas2 = lazy2(() => import("./PdfAnnotationCanvas.client-RAJRPQLU.mjs").then((mod) => ({ default: mod.PdfAnnotationCanvas })));
45487
+ var PdfAnnotationCanvas2 = lazy2(() => import("./PdfAnnotationCanvas.client-FGV33CWN.mjs").then((mod) => ({ default: mod.PdfAnnotationCanvas })));
45592
45488
  function prepareAnnotations(annotations) {
45593
45489
  return annotations.map((ann) => {
45594
45490
  const targetSelector = getTargetSelector3(ann.target);
@@ -45618,12 +45514,12 @@ function BrowseView({
45618
45514
  }) {
45619
45515
  const { newAnnotationIds } = useResourceAnnotations();
45620
45516
  const eventBus = useEventBus();
45621
- const containerRef = useRef18(null);
45517
+ const containerRef = useRef15(null);
45622
45518
  const category = getMimeCategory2(mimeType);
45623
45519
  const { highlights, references, assessments, comments, tags: tags3 } = annotations;
45624
45520
  const allAnnotations = [...highlights, ...references, ...assessments, ...comments, ...tags3];
45625
45521
  const preparedAnnotations = prepareAnnotations(allAnnotations);
45626
- useEffect24(() => {
45522
+ useEffect22(() => {
45627
45523
  if (!containerRef.current) return;
45628
45524
  const container = containerRef.current;
45629
45525
  const handleClick = (e6) => {
@@ -45639,20 +45535,19 @@ function BrowseView({
45639
45535
  }
45640
45536
  }
45641
45537
  };
45538
+ const { handleMouseEnter, handleMouseLeave, cleanup: cleanupHover } = createHoverHandlers(
45539
+ (annotationId) => eventBus.emit("annotation:hover", { annotationId })
45540
+ );
45642
45541
  const handleMouseOver = (e6) => {
45643
45542
  const target = e6.target;
45644
45543
  const annotationElement = target.closest("[data-annotation-id]");
45645
45544
  const annotationId = annotationElement?.getAttribute("data-annotation-id");
45646
- if (annotationId) {
45647
- eventBus.emit("annotation:hover", { annotationId });
45648
- }
45545
+ if (annotationId) handleMouseEnter(annotationId);
45649
45546
  };
45650
45547
  const handleMouseOut = (e6) => {
45651
45548
  const target = e6.target;
45652
45549
  const annotationElement = target.closest("[data-annotation-id]");
45653
- if (annotationElement) {
45654
- eventBus.emit("annotation:hover", { annotationId: null });
45655
- }
45550
+ if (annotationElement) handleMouseLeave();
45656
45551
  };
45657
45552
  if (newAnnotationIds) {
45658
45553
  const annotationSpans = container.querySelectorAll("[data-annotation-id]");
@@ -45670,9 +45565,10 @@ function BrowseView({
45670
45565
  container.removeEventListener("click", handleClick);
45671
45566
  container.removeEventListener("mouseover", handleMouseOver);
45672
45567
  container.removeEventListener("mouseout", handleMouseOut);
45568
+ cleanupHover();
45673
45569
  };
45674
45570
  }, [content4, allAnnotations, newAnnotationIds]);
45675
- const scrollToAnnotation = useCallback15((annotationId, removePulse = false) => {
45571
+ const scrollToAnnotation = useCallback14((annotationId, removePulse = false) => {
45676
45572
  if (!containerRef.current || !annotationId) return;
45677
45573
  const element2 = containerRef.current.querySelector(
45678
45574
  `[data-annotation-id="${CSS.escape(annotationId)}"]`
@@ -45698,10 +45594,10 @@ function BrowseView({
45698
45594
  }, 2e3);
45699
45595
  }
45700
45596
  }, []);
45701
- const handleAnnotationHover = useCallback15(({ annotationId }) => {
45597
+ const handleAnnotationHover = useCallback14(({ annotationId }) => {
45702
45598
  scrollToAnnotation(annotationId);
45703
45599
  }, [scrollToAnnotation]);
45704
- const handleAnnotationFocus = useCallback15(({ annotationId }) => {
45600
+ const handleAnnotationFocus = useCallback14(({ annotationId }) => {
45705
45601
  scrollToAnnotation(annotationId, true);
45706
45602
  }, [scrollToAnnotation]);
45707
45603
  useEventSubscriptions({
@@ -45802,7 +45698,7 @@ function BrowseView({
45802
45698
  }
45803
45699
 
45804
45700
  // src/components/resource/ResourceViewer.tsx
45805
- import { useState as useState17, useEffect as useEffect25, useCallback as useCallback16, useRef as useRef19 } from "react";
45701
+ import { useState as useState16, useEffect as useEffect23, useCallback as useCallback15, useRef as useRef16 } from "react";
45806
45702
  import { getExactText as getExactText3, getTargetSelector as getTargetSelector4, resourceUri, isHighlight as isHighlight4, isAssessment as isAssessment3, isReference as isReference4, isComment as isComment4, isTag as isTag5, getBodySource as getBodySource4 } from "@semiont/api-client";
45807
45703
  import { jsx as jsx28, jsxs as jsxs18 } from "react/jsx-runtime";
45808
45704
  function ResourceViewer({
@@ -45813,7 +45709,7 @@ function ResourceViewer({
45813
45709
  hoveredAnnotationId: hoveredAnnotationIdProp
45814
45710
  }) {
45815
45711
  const t12 = useTranslations("ResourceViewer");
45816
- const documentViewerRef = useRef19(null);
45712
+ const documentViewerRef = useRef16(null);
45817
45713
  const eventBus = useEventBus();
45818
45714
  const navigate = useObservableExternalNavigation();
45819
45715
  const { highlights, references, assessments, comments, tags: tags3 } = annotations;
@@ -45829,38 +45725,38 @@ function ResourceViewer({
45829
45725
  return "text/plain";
45830
45726
  };
45831
45727
  const mimeType = getMimeType();
45832
- const [annotateMode, setAnnotateMode] = useState17(() => {
45728
+ const [annotateMode, setAnnotateMode] = useState16(() => {
45833
45729
  if (typeof window !== "undefined") {
45834
45730
  return localStorage.getItem("annotateMode") === "true";
45835
45731
  }
45836
45732
  return false;
45837
45733
  });
45838
- useEffect25(() => {
45734
+ useEffect23(() => {
45839
45735
  if (typeof window !== "undefined") {
45840
45736
  localStorage.setItem("annotateMode", annotateMode.toString());
45841
45737
  }
45842
45738
  }, [annotateMode]);
45843
- const handleViewModeToggle = useCallback16(() => {
45739
+ const handleViewModeToggle = useCallback15(() => {
45844
45740
  setAnnotateMode((prev) => !prev);
45845
45741
  }, []);
45846
45742
  const activeView = annotateMode ? "annotate" : "browse";
45847
45743
  const cacheManager = useCacheManager();
45848
- const handleAnnotationAdded = useCallback16(() => {
45744
+ const handleAnnotationAdded = useCallback15(() => {
45849
45745
  if (cacheManager) {
45850
45746
  cacheManager.invalidateAnnotations(rUri);
45851
45747
  }
45852
45748
  }, [cacheManager, rUri]);
45853
- const handleAnnotationRemoved = useCallback16(() => {
45749
+ const handleAnnotationRemoved = useCallback15(() => {
45854
45750
  if (cacheManager) {
45855
45751
  cacheManager.invalidateAnnotations(rUri);
45856
45752
  }
45857
45753
  }, [cacheManager, rUri]);
45858
- const handleAnnotationUpdated = useCallback16(() => {
45754
+ const handleAnnotationUpdated = useCallback15(() => {
45859
45755
  if (cacheManager) {
45860
45756
  cacheManager.invalidateAnnotations(rUri);
45861
45757
  }
45862
45758
  }, [cacheManager, rUri]);
45863
- const [selectedMotivation, setSelectedMotivation] = useState17(() => {
45759
+ const [selectedMotivation, setSelectedMotivation] = useState16(() => {
45864
45760
  if (typeof window !== "undefined") {
45865
45761
  const stored = localStorage.getItem("semiont-toolbar-selection");
45866
45762
  if (stored === "null") return null;
@@ -45870,7 +45766,7 @@ function ResourceViewer({
45870
45766
  }
45871
45767
  return "linking";
45872
45768
  });
45873
- const [selectedClick, setSelectedClick] = useState17(() => {
45769
+ const [selectedClick, setSelectedClick] = useState16(() => {
45874
45770
  if (typeof window !== "undefined") {
45875
45771
  const stored = localStorage.getItem("semiont-toolbar-click");
45876
45772
  if (stored && ["detail", "follow", "jsonld", "deleting"].includes(stored)) {
@@ -45880,45 +45776,45 @@ function ResourceViewer({
45880
45776
  return "detail";
45881
45777
  });
45882
45778
  const selectorType = getSelectorType(mimeType);
45883
- const [selectedShape, setSelectedShape] = useState17(() => {
45779
+ const [selectedShape, setSelectedShape] = useState16(() => {
45884
45780
  return getSelectedShapeForSelectorType(selectorType);
45885
45781
  });
45886
- const handleToolbarSelectionChanged = useCallback16(({ motivation }) => {
45782
+ const handleToolbarSelectionChanged = useCallback15(({ motivation }) => {
45887
45783
  setSelectedMotivation(motivation);
45888
45784
  }, []);
45889
- const handleToolbarClickChanged = useCallback16(({ action }) => {
45785
+ const handleToolbarClickChanged = useCallback15(({ action }) => {
45890
45786
  setSelectedClick(action);
45891
45787
  }, []);
45892
- const handleToolbarShapeChanged = useCallback16(({ shape }) => {
45788
+ const handleToolbarShapeChanged = useCallback15(({ shape }) => {
45893
45789
  setSelectedShape(shape);
45894
45790
  }, []);
45895
- useEffect25(() => {
45791
+ useEffect23(() => {
45896
45792
  if (selectedMotivation === null) {
45897
45793
  localStorage.setItem("semiont-toolbar-selection", "null");
45898
45794
  } else {
45899
45795
  localStorage.setItem("semiont-toolbar-selection", selectedMotivation);
45900
45796
  }
45901
45797
  }, [selectedMotivation]);
45902
- useEffect25(() => {
45798
+ useEffect23(() => {
45903
45799
  localStorage.setItem("semiont-toolbar-click", selectedClick);
45904
45800
  }, [selectedClick]);
45905
- useEffect25(() => {
45801
+ useEffect23(() => {
45906
45802
  saveSelectedShapeForSelectorType(selectorType, selectedShape);
45907
45803
  }, [selectorType, selectedShape]);
45908
- useEffect25(() => {
45804
+ useEffect23(() => {
45909
45805
  const shapeForType = getSelectedShapeForSelectorType(selectorType);
45910
45806
  if (shapeForType !== selectedShape) {
45911
45807
  setSelectedShape(shapeForType);
45912
45808
  }
45913
45809
  }, [selectorType]);
45914
- const [showJsonLdView, setShowJsonLdView] = useState17(false);
45915
- const [jsonLdAnnotation, setJsonLdAnnotation] = useState17(null);
45916
- const [deleteConfirmation, setDeleteConfirmation] = useState17(null);
45810
+ const [showJsonLdView, setShowJsonLdView] = useState16(false);
45811
+ const [jsonLdAnnotation, setJsonLdAnnotation] = useState16(null);
45812
+ const [deleteConfirmation, setDeleteConfirmation] = useState16(null);
45917
45813
  const hoveredAnnotationId = hoveredAnnotationIdProp ?? null;
45918
- const [hoveredCommentId, _setHoveredCommentId] = useState17(null);
45919
- const [scrollToAnnotationId, setScrollToAnnotationId] = useState17(null);
45920
- const [_focusedAnnotationId, setFocusedAnnotationId] = useState17(null);
45921
- const focusAnnotation = useCallback16((annotationId) => {
45814
+ const [hoveredCommentId, _setHoveredCommentId] = useState16(null);
45815
+ const [scrollToAnnotationId, setScrollToAnnotationId] = useState16(null);
45816
+ const [_focusedAnnotationId, setFocusedAnnotationId] = useState16(null);
45817
+ const focusAnnotation = useCallback15((annotationId) => {
45922
45818
  setFocusedAnnotationId(annotationId);
45923
45819
  setScrollToAnnotationId(annotationId);
45924
45820
  setTimeout(() => setFocusedAnnotationId(null), 3e3);
@@ -45932,10 +45828,10 @@ function ResourceViewer({
45932
45828
  y: Math.max(0, (window.innerHeight - popupHeight) / 2)
45933
45829
  };
45934
45830
  };
45935
- const handleDeleteAnnotation = useCallback16((id2) => {
45831
+ const handleDeleteAnnotation = useCallback15((id2) => {
45936
45832
  eventBus.emit("annotation:delete", { annotationId: id2 });
45937
45833
  }, []);
45938
- const handleAnnotationClick = useCallback16((annotation, event) => {
45834
+ const handleAnnotationClick = useCallback15((annotation, event) => {
45939
45835
  const metadata = Object.values(ANNOTATORS).find((a15) => a15.matchesAnnotation(annotation));
45940
45836
  if (metadata?.hasSidePanel) {
45941
45837
  if (selectedClick === "detail") {
@@ -45969,7 +45865,7 @@ function ResourceViewer({
45969
45865
  return;
45970
45866
  }
45971
45867
  }, [annotateMode, selectedClick, focusAnnotation]);
45972
- const handleAnnotationClickEvent = useCallback16(({ annotationId, motivation }) => {
45868
+ const handleAnnotationClickEvent = useCallback15(({ annotationId, motivation }) => {
45973
45869
  const metadata = Object.values(ANNOTATORS).find((a15) => a15.matchesAnnotation({ motivation }));
45974
45870
  if (!metadata?.hasSidePanel) {
45975
45871
  const allAnnotations = [...highlights, ...references, ...assessments, ...comments, ...tags3];
@@ -46011,7 +45907,7 @@ function ResourceViewer({
46011
45907
  hoveredAnnotationId,
46012
45908
  scrollToAnnotationId
46013
45909
  };
46014
- const getTargetDocumentName = useCallback16((documentId) => {
45910
+ const getTargetDocumentName = useCallback15((documentId) => {
46015
45911
  const referencedResource = references.find((a15) => getBodySource4(a15.body) === documentId);
46016
45912
  return referencedResource ? getExactText3(getTargetSelector4(referencedResource.target)) : void 0;
46017
45913
  }, [references]);
@@ -46156,6 +46052,7 @@ var AssessmentEntry = forwardRef(
46156
46052
  isHovered = false
46157
46053
  }, ref) {
46158
46054
  const eventBus = useEventBus();
46055
+ const hoverProps = useHoverEmitter(assessment.id);
46159
46056
  const selectedText = getAnnotationExactText(assessment);
46160
46057
  const assessmentText = getAssessmentText(assessment);
46161
46058
  return /* @__PURE__ */ jsxs19(
@@ -46168,12 +46065,7 @@ var AssessmentEntry = forwardRef(
46168
46065
  onClick: () => {
46169
46066
  eventBus.emit("annotation:click", { annotationId: assessment.id, motivation: assessment.motivation });
46170
46067
  },
46171
- onMouseEnter: () => {
46172
- eventBus.emit("annotation:hover", { annotationId: assessment.id });
46173
- },
46174
- onMouseLeave: () => {
46175
- eventBus.emit("annotation:hover", { annotationId: null });
46176
- },
46068
+ ...hoverProps,
46177
46069
  children: [
46178
46070
  selectedText && /* @__PURE__ */ jsxs19("div", { className: "semiont-annotation-entry__quote", "data-type": "assessment", children: [
46179
46071
  '"',
@@ -46195,11 +46087,11 @@ var AssessmentEntry = forwardRef(
46195
46087
  );
46196
46088
 
46197
46089
  // src/components/resource/panels/AssessmentPanel.tsx
46198
- import { useState as useState19, useEffect as useEffect27, useRef as useRef20, useCallback as useCallback18, useMemo as useMemo4 } from "react";
46090
+ import { useState as useState18, useEffect as useEffect25, useRef as useRef17, useCallback as useCallback17, useMemo as useMemo4 } from "react";
46199
46091
  import { getTextPositionSelector as getTextPositionSelector3, getTargetSelector as getTargetSelector5 } from "@semiont/api-client";
46200
46092
 
46201
46093
  // src/components/resource/panels/DetectSection.tsx
46202
- import { useState as useState18, useEffect as useEffect26, useCallback as useCallback17 } from "react";
46094
+ import { useState as useState17, useEffect as useEffect24, useCallback as useCallback16 } from "react";
46203
46095
  import { Fragment as Fragment7, jsx as jsx30, jsxs as jsxs20 } from "react/jsx-runtime";
46204
46096
  function DetectSection({
46205
46097
  annotationType,
@@ -46209,21 +46101,21 @@ function DetectSection({
46209
46101
  const panelName = annotationType === "highlight" ? "HighlightPanel" : annotationType === "assessment" ? "AssessmentPanel" : "CommentsPanel";
46210
46102
  const t12 = useTranslations(panelName);
46211
46103
  const eventBus = useEventBus();
46212
- const [instructions, setInstructions] = useState18("");
46213
- const [tone, setTone] = useState18("");
46104
+ const [instructions, setInstructions] = useState17("");
46105
+ const [tone, setTone] = useState17("");
46214
46106
  const defaultDensity = annotationType === "comment" ? 5 : annotationType === "assessment" ? 4 : annotationType === "highlight" ? 5 : 5;
46215
- const [density, setDensity] = useState18(defaultDensity);
46216
- const [useDensity, setUseDensity] = useState18(true);
46217
- const [isExpanded, setIsExpanded] = useState18(() => {
46107
+ const [density, setDensity] = useState17(defaultDensity);
46108
+ const [useDensity, setUseDensity] = useState17(true);
46109
+ const [isExpanded, setIsExpanded] = useState17(() => {
46218
46110
  if (typeof window === "undefined") return true;
46219
46111
  const stored = localStorage.getItem(`detect-section-expanded-${annotationType}`);
46220
46112
  return stored ? stored === "true" : true;
46221
46113
  });
46222
- useEffect26(() => {
46114
+ useEffect24(() => {
46223
46115
  if (typeof window === "undefined") return;
46224
46116
  localStorage.setItem(`detect-section-expanded-${annotationType}`, String(isExpanded));
46225
46117
  }, [isExpanded, annotationType]);
46226
- const handleDetect = useCallback17(() => {
46118
+ const handleDetect = useCallback16(() => {
46227
46119
  const motivation = annotationType === "highlight" ? "highlighting" : annotationType === "assessment" ? "assessing" : "commenting";
46228
46120
  eventBus.emit("detection:start", {
46229
46121
  motivation,
@@ -46236,7 +46128,7 @@ function DetectSection({
46236
46128
  setInstructions("");
46237
46129
  setTone("");
46238
46130
  }, [annotationType, instructions, tone, useDensity, density]);
46239
- const handleDismissProgress = useCallback17(() => {
46131
+ const handleDismissProgress = useCallback16(() => {
46240
46132
  eventBus.emit("detection:dismiss-progress", void 0);
46241
46133
  }, []);
46242
46134
  return /* @__PURE__ */ jsxs20("div", { className: "semiont-panel__section", children: [
@@ -46441,10 +46333,10 @@ function AssessmentPanel({
46441
46333
  }) {
46442
46334
  const t12 = useTranslations("AssessmentPanel");
46443
46335
  const eventBus = useEventBus();
46444
- const [newAssessmentText, setNewAssessmentText] = useState19("");
46445
- const [focusedAnnotationId, setFocusedAnnotationId] = useState19(null);
46446
- const containerRef = useRef20(null);
46447
- const entryRefs = useRef20(/* @__PURE__ */ new Map());
46336
+ const [newAssessmentText, setNewAssessmentText] = useState18("");
46337
+ const [focusedAnnotationId, setFocusedAnnotationId] = useState18(null);
46338
+ const containerRef = useRef17(null);
46339
+ const entryRefs = useRef17(/* @__PURE__ */ new Map());
46448
46340
  const sortedAnnotations = useMemo4(() => {
46449
46341
  return [...annotations].sort((a15, b8) => {
46450
46342
  const aSelector = getTextPositionSelector3(getTargetSelector5(a15.target));
@@ -46453,14 +46345,14 @@ function AssessmentPanel({
46453
46345
  return aSelector.start - bSelector.start;
46454
46346
  });
46455
46347
  }, [annotations]);
46456
- const setEntryRef = useCallback18((id2, element2) => {
46348
+ const setEntryRef = useCallback17((id2, element2) => {
46457
46349
  if (element2) {
46458
46350
  entryRefs.current.set(id2, element2);
46459
46351
  } else {
46460
46352
  entryRefs.current.delete(id2);
46461
46353
  }
46462
46354
  }, []);
46463
- useEffect27(() => {
46355
+ useEffect25(() => {
46464
46356
  if (!scrollToAnnotationId) return;
46465
46357
  const element2 = entryRefs.current.get(scrollToAnnotationId);
46466
46358
  if (element2 && containerRef.current) {
@@ -46475,7 +46367,7 @@ function AssessmentPanel({
46475
46367
  if (onScrollCompleted) onScrollCompleted();
46476
46368
  }
46477
46369
  }, [scrollToAnnotationId]);
46478
- useEffect27(() => {
46370
+ useEffect25(() => {
46479
46371
  if (!hoveredAnnotationId) return;
46480
46372
  const element2 = entryRefs.current.get(hoveredAnnotationId);
46481
46373
  if (!element2 || !containerRef.current) return;
@@ -46502,7 +46394,7 @@ function AssessmentPanel({
46502
46394
  setNewAssessmentText("");
46503
46395
  }
46504
46396
  };
46505
- useEffect27(() => {
46397
+ useEffect25(() => {
46506
46398
  if (!pendingAnnotation) return;
46507
46399
  const handleEscape = (e6) => {
46508
46400
  if (e6.key === "Escape") {
@@ -46513,7 +46405,7 @@ function AssessmentPanel({
46513
46405
  document.addEventListener("keydown", handleEscape);
46514
46406
  return () => document.removeEventListener("keydown", handleEscape);
46515
46407
  }, [pendingAnnotation]);
46516
- const handleAnnotationClick = useCallback18(({ annotationId }) => {
46408
+ const handleAnnotationClick = useCallback17(({ annotationId }) => {
46517
46409
  setFocusedAnnotationId(annotationId);
46518
46410
  setTimeout(() => setFocusedAnnotationId(null), 3e3);
46519
46411
  }, []);
@@ -46674,7 +46566,7 @@ function CollaborationPanel({
46674
46566
  }
46675
46567
 
46676
46568
  // src/components/resource/panels/CommentEntry.tsx
46677
- import { useState as useState20, useEffect as useEffect28, useRef as useRef21, forwardRef as forwardRef2, useImperativeHandle } from "react";
46569
+ import { useState as useState19, useEffect as useEffect26, useRef as useRef18, forwardRef as forwardRef2, useImperativeHandle } from "react";
46678
46570
  import { getAnnotationExactText as getAnnotationExactText2, getCommentText } from "@semiont/api-client";
46679
46571
  import { jsx as jsx34, jsxs as jsxs24 } from "react/jsx-runtime";
46680
46572
  function formatRelativeTime3(isoString) {
@@ -46700,13 +46592,14 @@ var CommentEntry = forwardRef2(
46700
46592
  }, ref) {
46701
46593
  const t12 = useTranslations("CommentsPanel");
46702
46594
  const eventBus = useEventBus();
46703
- const [isEditing, setIsEditing] = useState20(false);
46704
- const [editText, setEditText] = useState20("");
46705
- const internalRef = useRef21(null);
46595
+ const hoverProps = useHoverEmitter(comment2.id);
46596
+ const [isEditing, setIsEditing] = useState19(false);
46597
+ const [editText, setEditText] = useState19("");
46598
+ const internalRef = useRef18(null);
46706
46599
  useImperativeHandle(ref, () => internalRef.current);
46707
46600
  const commentText = getCommentText(comment2) || "";
46708
46601
  const selectedText = getAnnotationExactText2(comment2);
46709
- useEffect28(() => {
46602
+ useEffect26(() => {
46710
46603
  if (isFocused && internalRef.current) {
46711
46604
  internalRef.current.scrollIntoView({
46712
46605
  behavior: "smooth",
@@ -46735,12 +46628,7 @@ var CommentEntry = forwardRef2(
46735
46628
  onClick: () => {
46736
46629
  eventBus.emit("annotation:click", { annotationId: comment2.id, motivation: comment2.motivation });
46737
46630
  },
46738
- onMouseEnter: () => {
46739
- eventBus.emit("annotation:hover", { annotationId: comment2.id });
46740
- },
46741
- onMouseLeave: () => {
46742
- eventBus.emit("annotation:hover", { annotationId: null });
46743
- },
46631
+ ...hoverProps,
46744
46632
  children: [
46745
46633
  selectedText && /* @__PURE__ */ jsxs24("div", { className: "semiont-annotation-entry__quote", "data-type": "comment", children: [
46746
46634
  '"',
@@ -46810,7 +46698,7 @@ var CommentEntry = forwardRef2(
46810
46698
  );
46811
46699
 
46812
46700
  // src/components/resource/panels/CommentsPanel.tsx
46813
- import { useState as useState21, useEffect as useEffect29, useRef as useRef22, useCallback as useCallback19, useMemo as useMemo5 } from "react";
46701
+ import { useState as useState20, useEffect as useEffect27, useRef as useRef19, useCallback as useCallback18, useMemo as useMemo5 } from "react";
46814
46702
  import { getTextPositionSelector as getTextPositionSelector4, getTargetSelector as getTargetSelector6 } from "@semiont/api-client";
46815
46703
  import { jsx as jsx35, jsxs as jsxs25 } from "react/jsx-runtime";
46816
46704
  function getSelectorDisplayText2(selector) {
@@ -46838,10 +46726,10 @@ function CommentsPanel({
46838
46726
  }) {
46839
46727
  const t12 = useTranslations("CommentsPanel");
46840
46728
  const eventBus = useEventBus();
46841
- const [newCommentText, setNewCommentText] = useState21("");
46842
- const [focusedAnnotationId, setFocusedAnnotationId] = useState21(null);
46843
- const containerRef = useRef22(null);
46844
- const entryRefs = useRef22(/* @__PURE__ */ new Map());
46729
+ const [newCommentText, setNewCommentText] = useState20("");
46730
+ const [focusedAnnotationId, setFocusedAnnotationId] = useState20(null);
46731
+ const containerRef = useRef19(null);
46732
+ const entryRefs = useRef19(/* @__PURE__ */ new Map());
46845
46733
  const sortedAnnotations = useMemo5(() => {
46846
46734
  return [...annotations].sort((a15, b8) => {
46847
46735
  const aSelector = getTextPositionSelector4(getTargetSelector6(a15.target));
@@ -46850,14 +46738,14 @@ function CommentsPanel({
46850
46738
  return aSelector.start - bSelector.start;
46851
46739
  });
46852
46740
  }, [annotations]);
46853
- const setEntryRef = useCallback19((id2, element2) => {
46741
+ const setEntryRef = useCallback18((id2, element2) => {
46854
46742
  if (element2) {
46855
46743
  entryRefs.current.set(id2, element2);
46856
46744
  } else {
46857
46745
  entryRefs.current.delete(id2);
46858
46746
  }
46859
46747
  }, []);
46860
- useEffect29(() => {
46748
+ useEffect27(() => {
46861
46749
  if (!scrollToAnnotationId) return;
46862
46750
  const element2 = entryRefs.current.get(scrollToAnnotationId);
46863
46751
  if (element2 && containerRef.current) {
@@ -46874,7 +46762,7 @@ function CommentsPanel({
46874
46762
  }
46875
46763
  }
46876
46764
  }, [scrollToAnnotationId]);
46877
- useEffect29(() => {
46765
+ useEffect27(() => {
46878
46766
  if (!hoveredAnnotationId) return;
46879
46767
  const element2 = entryRefs.current.get(hoveredAnnotationId);
46880
46768
  if (!element2 || !containerRef.current) return;
@@ -46890,7 +46778,7 @@ function CommentsPanel({
46890
46778
  container.scrollTo({ top: scrollTo, behavior: "smooth" });
46891
46779
  }
46892
46780
  }, [hoveredAnnotationId]);
46893
- const handleAnnotationClick = useCallback19(({ annotationId }) => {
46781
+ const handleAnnotationClick = useCallback18(({ annotationId }) => {
46894
46782
  setFocusedAnnotationId(annotationId);
46895
46783
  setTimeout(() => setFocusedAnnotationId(null), 3e3);
46896
46784
  }, []);
@@ -46907,7 +46795,7 @@ function CommentsPanel({
46907
46795
  setNewCommentText("");
46908
46796
  }
46909
46797
  };
46910
- useEffect29(() => {
46798
+ useEffect27(() => {
46911
46799
  if (!pendingAnnotation) return;
46912
46800
  const handleEscape = (e6) => {
46913
46801
  if (e6.key === "Escape") {
@@ -47020,6 +46908,7 @@ var HighlightEntry = forwardRef3(
47020
46908
  isHovered = false
47021
46909
  }, ref) {
47022
46910
  const eventBus = useEventBus();
46911
+ const hoverProps = useHoverEmitter(highlight.id);
47023
46912
  const selectedText = getAnnotationExactText3(highlight);
47024
46913
  return /* @__PURE__ */ jsxs26(
47025
46914
  "div",
@@ -47031,12 +46920,7 @@ var HighlightEntry = forwardRef3(
47031
46920
  onClick: () => {
47032
46921
  eventBus.emit("annotation:click", { annotationId: highlight.id, motivation: highlight.motivation });
47033
46922
  },
47034
- onMouseEnter: () => {
47035
- eventBus.emit("annotation:hover", { annotationId: highlight.id });
47036
- },
47037
- onMouseLeave: () => {
47038
- eventBus.emit("annotation:hover", { annotationId: null });
47039
- },
46923
+ ...hoverProps,
47040
46924
  children: [
47041
46925
  selectedText && /* @__PURE__ */ jsxs26("div", { className: "semiont-annotation-entry__quote", "data-type": "highlight", children: [
47042
46926
  '"',
@@ -47057,7 +46941,7 @@ var HighlightEntry = forwardRef3(
47057
46941
  );
47058
46942
 
47059
46943
  // src/components/resource/panels/HighlightPanel.tsx
47060
- import { useEffect as useEffect30, useState as useState22, useRef as useRef23, useCallback as useCallback20, useMemo as useMemo6 } from "react";
46944
+ import { useEffect as useEffect28, useState as useState21, useRef as useRef20, useCallback as useCallback19, useMemo as useMemo6 } from "react";
47061
46945
  import { getTextPositionSelector as getTextPositionSelector5, getTargetSelector as getTargetSelector7 } from "@semiont/api-client";
47062
46946
  import { jsx as jsx36, jsxs as jsxs27 } from "react/jsx-runtime";
47063
46947
  function HighlightPanel({
@@ -47072,9 +46956,9 @@ function HighlightPanel({
47072
46956
  }) {
47073
46957
  const t12 = useTranslations("HighlightPanel");
47074
46958
  const eventBus = useEventBus();
47075
- const [focusedAnnotationId, setFocusedAnnotationId] = useState22(null);
47076
- const containerRef = useRef23(null);
47077
- const entryRefs = useRef23(/* @__PURE__ */ new Map());
46959
+ const [focusedAnnotationId, setFocusedAnnotationId] = useState21(null);
46960
+ const containerRef = useRef20(null);
46961
+ const entryRefs = useRef20(/* @__PURE__ */ new Map());
47078
46962
  const sortedAnnotations = useMemo6(() => {
47079
46963
  return [...annotations].sort((a15, b8) => {
47080
46964
  const aSelector = getTextPositionSelector5(getTargetSelector7(a15.target));
@@ -47083,14 +46967,14 @@ function HighlightPanel({
47083
46967
  return aSelector.start - bSelector.start;
47084
46968
  });
47085
46969
  }, [annotations]);
47086
- const setEntryRef = useCallback20((id2, element2) => {
46970
+ const setEntryRef = useCallback19((id2, element2) => {
47087
46971
  if (element2) {
47088
46972
  entryRefs.current.set(id2, element2);
47089
46973
  } else {
47090
46974
  entryRefs.current.delete(id2);
47091
46975
  }
47092
46976
  }, []);
47093
- useEffect30(() => {
46977
+ useEffect28(() => {
47094
46978
  if (!scrollToAnnotationId) return;
47095
46979
  const element2 = entryRefs.current.get(scrollToAnnotationId);
47096
46980
  if (element2 && containerRef.current) {
@@ -47105,7 +46989,7 @@ function HighlightPanel({
47105
46989
  if (onScrollCompleted) onScrollCompleted();
47106
46990
  }
47107
46991
  }, [scrollToAnnotationId]);
47108
- useEffect30(() => {
46992
+ useEffect28(() => {
47109
46993
  if (!hoveredAnnotationId) return;
47110
46994
  const element2 = entryRefs.current.get(hoveredAnnotationId);
47111
46995
  if (!element2 || !containerRef.current) return;
@@ -47121,14 +47005,14 @@ function HighlightPanel({
47121
47005
  container.scrollTo({ top: scrollTo, behavior: "smooth" });
47122
47006
  }
47123
47007
  }, [hoveredAnnotationId]);
47124
- const handleAnnotationClick = useCallback20(({ annotationId }) => {
47008
+ const handleAnnotationClick = useCallback19(({ annotationId }) => {
47125
47009
  setFocusedAnnotationId(annotationId);
47126
47010
  setTimeout(() => setFocusedAnnotationId(null), 3e3);
47127
47011
  }, []);
47128
47012
  useEventSubscriptions({
47129
47013
  "annotation:click": handleAnnotationClick
47130
47014
  });
47131
- useEffect30(() => {
47015
+ useEffect28(() => {
47132
47016
  if (pendingAnnotation && pendingAnnotation.motivation === "highlighting") {
47133
47017
  eventBus.emit("annotation:create", {
47134
47018
  motivation: "highlighting",
@@ -47163,13 +47047,13 @@ function HighlightPanel({
47163
47047
  }
47164
47048
 
47165
47049
  // src/components/resource/panels/JsonLdPanel.tsx
47166
- import { useEffect as useEffect31, useRef as useRef24 } from "react";
47050
+ import { useEffect as useEffect29, useRef as useRef21 } from "react";
47167
47051
  import { jsx as jsx37, jsxs as jsxs28 } from "react/jsx-runtime";
47168
47052
  function JsonLdPanel({ resource: semiontResource }) {
47169
- const editorRef = useRef24(null);
47170
- const viewRef = useRef24(null);
47053
+ const editorRef = useRef21(null);
47054
+ const viewRef = useRef21(null);
47171
47055
  const { showLineNumbers } = useLineNumbers();
47172
- useEffect31(() => {
47056
+ useEffect29(() => {
47173
47057
  if (!editorRef.current) return;
47174
47058
  const isDarkMode = document.documentElement?.classList.contains("dark") ?? false;
47175
47059
  const jsonLdContent = JSON.stringify(semiontResource, null, 2);
@@ -47247,6 +47131,7 @@ var ReferenceEntry = forwardRef4(
47247
47131
  const t12 = useTranslations("ReferencesPanel");
47248
47132
  const eventBus = useEventBus();
47249
47133
  const navigate = useObservableExternalNavigation();
47134
+ const hoverProps = useHoverEmitter(reference.id);
47250
47135
  const selectedText = getAnnotationExactText4(reference) || "";
47251
47136
  const isResolved = isBodyResolved2(reference.body);
47252
47137
  const resolvedResourceUri = isResolved ? getBodySource5(reference.body) : null;
@@ -47309,12 +47194,7 @@ var ReferenceEntry = forwardRef4(
47309
47194
  onClick: () => {
47310
47195
  eventBus.emit("annotation:click", { annotationId: reference.id, motivation: reference.motivation });
47311
47196
  },
47312
- onMouseEnter: () => {
47313
- eventBus.emit("annotation:hover", { annotationId: reference.id });
47314
- },
47315
- onMouseLeave: () => {
47316
- eventBus.emit("annotation:hover", { annotationId: null });
47317
- },
47197
+ ...hoverProps,
47318
47198
  children: [
47319
47199
  /* @__PURE__ */ jsxs29("div", { className: "semiont-annotation-entry__header", children: [
47320
47200
  /* @__PURE__ */ jsx38("span", { className: "semiont-reference-icon", title: isResolved ? t12("resolved") : t12("stub"), children: isResolved ? "\u{1F517}" : "\u2753" }),
@@ -47405,7 +47285,7 @@ var ReferenceEntry = forwardRef4(
47405
47285
  );
47406
47286
 
47407
47287
  // src/components/resource/panels/ReferencesPanel.tsx
47408
- import { useState as useState23, useRef as useRef25, useEffect as useEffect32, useCallback as useCallback21, useMemo as useMemo7 } from "react";
47288
+ import { useState as useState22, useRef as useRef22, useEffect as useEffect30, useCallback as useCallback20, useMemo as useMemo7 } from "react";
47409
47289
  import { getTextPositionSelector as getTextPositionSelector6, getTargetSelector as getTargetSelector9 } from "@semiont/api-client";
47410
47290
  import { Fragment as Fragment8, jsx as jsx39, jsxs as jsxs30 } from "react/jsx-runtime";
47411
47291
  function getSelectorDisplayText3(selector) {
@@ -47440,22 +47320,22 @@ function ReferencesPanel({
47440
47320
  const t12 = useTranslations("DetectPanel");
47441
47321
  const tRef = useTranslations("ReferencesPanel");
47442
47322
  const eventBus = useEventBus();
47443
- const [selectedEntityTypes, setSelectedEntityTypes] = useState23([]);
47444
- const [lastDetectionLog, setLastDetectionLog] = useState23(null);
47445
- const [pendingEntityTypes, setPendingEntityTypes] = useState23([]);
47446
- const [includeDescriptiveReferences, setIncludeDescriptiveReferences] = useState23(false);
47447
- const [focusedAnnotationId, setFocusedAnnotationId] = useState23(null);
47448
- const containerRef = useRef25(null);
47449
- const [isDetectExpanded, setIsDetectExpanded] = useState23(() => {
47323
+ const [selectedEntityTypes, setSelectedEntityTypes] = useState22([]);
47324
+ const [lastDetectionLog, setLastDetectionLog] = useState22(null);
47325
+ const [pendingEntityTypes, setPendingEntityTypes] = useState22([]);
47326
+ const [includeDescriptiveReferences, setIncludeDescriptiveReferences] = useState22(false);
47327
+ const [focusedAnnotationId, setFocusedAnnotationId] = useState22(null);
47328
+ const containerRef = useRef22(null);
47329
+ const [isDetectExpanded, setIsDetectExpanded] = useState22(() => {
47450
47330
  if (typeof window === "undefined") return true;
47451
47331
  const stored = localStorage.getItem("detect-section-expanded-reference");
47452
47332
  return stored ? stored === "true" : true;
47453
47333
  });
47454
- useEffect32(() => {
47334
+ useEffect30(() => {
47455
47335
  if (typeof window === "undefined") return;
47456
47336
  localStorage.setItem("detect-section-expanded-reference", String(isDetectExpanded));
47457
47337
  }, [isDetectExpanded]);
47458
- const entryRefs = useRef25(/* @__PURE__ */ new Map());
47338
+ const entryRefs = useRef22(/* @__PURE__ */ new Map());
47459
47339
  const sortedAnnotations = useMemo7(() => {
47460
47340
  return [...annotations].sort((a15, b8) => {
47461
47341
  const aSelector = getTextPositionSelector6(getTargetSelector9(a15.target));
@@ -47464,14 +47344,14 @@ function ReferencesPanel({
47464
47344
  return aSelector.start - bSelector.start;
47465
47345
  });
47466
47346
  }, [annotations]);
47467
- const setEntryRef = useCallback21((id2, element2) => {
47347
+ const setEntryRef = useCallback20((id2, element2) => {
47468
47348
  if (element2) {
47469
47349
  entryRefs.current.set(id2, element2);
47470
47350
  } else {
47471
47351
  entryRefs.current.delete(id2);
47472
47352
  }
47473
47353
  }, []);
47474
- useEffect32(() => {
47354
+ useEffect30(() => {
47475
47355
  if (!scrollToAnnotationId) return;
47476
47356
  const element2 = entryRefs.current.get(scrollToAnnotationId);
47477
47357
  if (element2 && containerRef.current) {
@@ -47490,7 +47370,7 @@ function ReferencesPanel({
47490
47370
  console.warn("[ReferencesPanel] Element not found for scrollToAnnotationId:", scrollToAnnotationId);
47491
47371
  }
47492
47372
  }, [scrollToAnnotationId]);
47493
- useEffect32(() => {
47373
+ useEffect30(() => {
47494
47374
  if (!hoveredAnnotationId) return;
47495
47375
  const element2 = entryRefs.current.get(hoveredAnnotationId);
47496
47376
  if (!element2 || !containerRef.current) return;
@@ -47506,7 +47386,7 @@ function ReferencesPanel({
47506
47386
  container.scrollTo({ top: scrollTo, behavior: "smooth" });
47507
47387
  }
47508
47388
  }, [hoveredAnnotationId]);
47509
- const handleAnnotationClick = useCallback21(({ annotationId }) => {
47389
+ const handleAnnotationClick = useCallback20(({ annotationId }) => {
47510
47390
  setFocusedAnnotationId(annotationId);
47511
47391
  setTimeout(() => setFocusedAnnotationId(null), 3e3);
47512
47392
  }, []);
@@ -47523,8 +47403,8 @@ function ReferencesPanel({
47523
47403
  }
47524
47404
  });
47525
47405
  };
47526
- const hasSavedLogRef = useRef25(false);
47527
- useEffect32(() => {
47406
+ const hasSavedLogRef = useRef22(false);
47407
+ useEffect30(() => {
47528
47408
  if (isDetecting) {
47529
47409
  hasSavedLogRef.current = false;
47530
47410
  return;
@@ -47551,7 +47431,7 @@ function ReferencesPanel({
47551
47431
  setPendingEntityTypes([]);
47552
47432
  }
47553
47433
  };
47554
- useEffect32(() => {
47434
+ useEffect30(() => {
47555
47435
  if (!pendingAnnotation) return;
47556
47436
  const handleEscape = (e6) => {
47557
47437
  if (e6.key === "Escape") {
@@ -47942,6 +47822,7 @@ var TagEntry = forwardRef5(
47942
47822
  isHovered = false
47943
47823
  }, ref) {
47944
47824
  const eventBus = useEventBus();
47825
+ const hoverProps = useHoverEmitter(tag.id);
47945
47826
  const selectedText = getAnnotationExactText5(tag);
47946
47827
  const category = getTagCategory(tag);
47947
47828
  const schemaId = getTagSchemaId(tag);
@@ -47953,12 +47834,7 @@ var TagEntry = forwardRef5(
47953
47834
  onClick: () => {
47954
47835
  eventBus.emit("annotation:click", { annotationId: tag.id, motivation: tag.motivation });
47955
47836
  },
47956
- onMouseEnter: () => {
47957
- eventBus.emit("annotation:hover", { annotationId: tag.id });
47958
- },
47959
- onMouseLeave: () => {
47960
- eventBus.emit("annotation:hover", { annotationId: null });
47961
- },
47837
+ ...hoverProps,
47962
47838
  className: `semiont-annotation-entry${isHovered ? " semiont-annotation-pulse" : ""}`,
47963
47839
  "data-type": "tag",
47964
47840
  "data-focused": isFocused ? "true" : "false",
@@ -47980,7 +47856,7 @@ var TagEntry = forwardRef5(
47980
47856
  );
47981
47857
 
47982
47858
  // src/components/resource/panels/TaggingPanel.tsx
47983
- import { useState as useState24, useEffect as useEffect33, useRef as useRef26, useCallback as useCallback22, useMemo as useMemo8 } from "react";
47859
+ import { useState as useState23, useEffect as useEffect31, useRef as useRef23, useCallback as useCallback21, useMemo as useMemo8 } from "react";
47984
47860
  import { getTextPositionSelector as getTextPositionSelector7, getTargetSelector as getTargetSelector10 } from "@semiont/api-client";
47985
47861
  import { Fragment as Fragment10, jsx as jsx43, jsxs as jsxs34 } from "react/jsx-runtime";
47986
47862
  function getSelectorDisplayText4(selector) {
@@ -48008,27 +47884,27 @@ function TaggingPanel({
48008
47884
  }) {
48009
47885
  const t12 = useTranslations("TaggingPanel");
48010
47886
  const eventBus = useEventBus();
48011
- const [selectedSchemaId, setSelectedSchemaId] = useState24("legal-irac");
48012
- const [selectedCategories, setSelectedCategories] = useState24(/* @__PURE__ */ new Set());
48013
- const [focusedAnnotationId, setFocusedAnnotationId] = useState24(null);
48014
- const containerRef = useRef26(null);
48015
- const [isDetectExpanded, setIsDetectExpanded] = useState24(() => {
47887
+ const [selectedSchemaId, setSelectedSchemaId] = useState23("legal-irac");
47888
+ const [selectedCategories, setSelectedCategories] = useState23(/* @__PURE__ */ new Set());
47889
+ const [focusedAnnotationId, setFocusedAnnotationId] = useState23(null);
47890
+ const containerRef = useRef23(null);
47891
+ const [isDetectExpanded, setIsDetectExpanded] = useState23(() => {
48016
47892
  if (typeof window === "undefined") return true;
48017
47893
  const stored = localStorage.getItem("detect-section-expanded-tag");
48018
47894
  return stored ? stored === "true" : true;
48019
47895
  });
48020
- useEffect33(() => {
47896
+ useEffect31(() => {
48021
47897
  if (typeof window === "undefined") return;
48022
47898
  localStorage.setItem("detect-section-expanded-tag", String(isDetectExpanded));
48023
47899
  }, [isDetectExpanded]);
48024
- const handleAnnotationClick = useCallback22(({ annotationId }) => {
47900
+ const handleAnnotationClick = useCallback21(({ annotationId }) => {
48025
47901
  setFocusedAnnotationId(annotationId);
48026
47902
  setTimeout(() => setFocusedAnnotationId(null), 3e3);
48027
47903
  }, []);
48028
47904
  useEventSubscriptions({
48029
47905
  "annotation:click": handleAnnotationClick
48030
47906
  });
48031
- const entryRefs = useRef26(/* @__PURE__ */ new Map());
47907
+ const entryRefs = useRef23(/* @__PURE__ */ new Map());
48032
47908
  const sortedAnnotations = useMemo8(() => {
48033
47909
  return [...annotations].sort((a15, b8) => {
48034
47910
  const aSelector = getTextPositionSelector7(getTargetSelector10(a15.target));
@@ -48037,14 +47913,14 @@ function TaggingPanel({
48037
47913
  return aSelector.start - bSelector.start;
48038
47914
  });
48039
47915
  }, [annotations]);
48040
- const setEntryRef = useCallback22((id2, element2) => {
47916
+ const setEntryRef = useCallback21((id2, element2) => {
48041
47917
  if (element2) {
48042
47918
  entryRefs.current.set(id2, element2);
48043
47919
  } else {
48044
47920
  entryRefs.current.delete(id2);
48045
47921
  }
48046
47922
  }, []);
48047
- useEffect33(() => {
47923
+ useEffect31(() => {
48048
47924
  if (!scrollToAnnotationId) return;
48049
47925
  const element2 = entryRefs.current.get(scrollToAnnotationId);
48050
47926
  if (element2 && containerRef.current) {
@@ -48059,7 +47935,7 @@ function TaggingPanel({
48059
47935
  if (onScrollCompleted) onScrollCompleted();
48060
47936
  }
48061
47937
  }, [scrollToAnnotationId]);
48062
- useEffect33(() => {
47938
+ useEffect31(() => {
48063
47939
  if (!hoveredAnnotationId) return;
48064
47940
  const element2 = entryRefs.current.get(hoveredAnnotationId);
48065
47941
  if (!element2 || !containerRef.current) return;
@@ -48110,7 +47986,7 @@ function TaggingPanel({
48110
47986
  setSelectedCategories(/* @__PURE__ */ new Set());
48111
47987
  }
48112
47988
  };
48113
- useEffect33(() => {
47989
+ useEffect31(() => {
48114
47990
  if (!pendingAnnotation) return;
48115
47991
  const handleEscape = (e6) => {
48116
47992
  if (e6.key === "Escape") {
@@ -48160,6 +48036,11 @@ function TaggingPanel({
48160
48036
  type: "TextualBody",
48161
48037
  value: e6.target.value,
48162
48038
  purpose: "tagging"
48039
+ },
48040
+ {
48041
+ type: "TextualBody",
48042
+ value: selectedSchemaId,
48043
+ purpose: "classifying"
48163
48044
  }
48164
48045
  ]
48165
48046
  });
@@ -48332,7 +48213,7 @@ function TaggingPanel({
48332
48213
  }
48333
48214
 
48334
48215
  // src/components/resource/panels/UnifiedAnnotationsPanel.tsx
48335
- import { useState as useState25, useEffect as useEffect34 } from "react";
48216
+ import { useState as useState24, useEffect as useEffect32 } from "react";
48336
48217
  import { jsx as jsx44, jsxs as jsxs35 } from "react/jsx-runtime";
48337
48218
  var TAB_ORDER = ["statistics", "reference", "highlight", "assessment", "comment", "tag"];
48338
48219
  function UnifiedAnnotationsPanel(props) {
@@ -48354,7 +48235,7 @@ function UnifiedAnnotationsPanel(props) {
48354
48235
  }
48355
48236
  }
48356
48237
  const grouped = groups;
48357
- const [activeTab, setActiveTab] = useState25(() => {
48238
+ const [activeTab, setActiveTab] = useState24(() => {
48358
48239
  if (typeof window === "undefined") return props.initialTab || "statistics";
48359
48240
  const storageKey = props.resourceId ? `annotations-tab-${props.resourceId}` : "annotations-tab-global";
48360
48241
  const stored = localStorage.getItem(storageKey);
@@ -48363,17 +48244,17 @@ function UnifiedAnnotationsPanel(props) {
48363
48244
  }
48364
48245
  return props.initialTab || "statistics";
48365
48246
  });
48366
- useEffect34(() => {
48247
+ useEffect32(() => {
48367
48248
  if (typeof window === "undefined") return;
48368
48249
  const storageKey = props.resourceId ? `annotations-tab-${props.resourceId}` : "annotations-tab-global";
48369
48250
  localStorage.setItem(storageKey, activeTab);
48370
48251
  }, [activeTab, props.resourceId]);
48371
- useEffect34(() => {
48252
+ useEffect32(() => {
48372
48253
  if (props.initialTab && props.initialTabGeneration !== void 0) {
48373
48254
  setActiveTab(props.initialTab);
48374
48255
  }
48375
48256
  }, [props.initialTabGeneration]);
48376
- useEffect34(() => {
48257
+ useEffect32(() => {
48377
48258
  if (props.pendingAnnotation) {
48378
48259
  const motivationToTab = {
48379
48260
  "linking": "reference",
@@ -48513,7 +48394,7 @@ function UnifiedAnnotationsPanel(props) {
48513
48394
  }
48514
48395
 
48515
48396
  // src/components/navigation/Footer.tsx
48516
- import { useState as useState26 } from "react";
48397
+ import { useState as useState25 } from "react";
48517
48398
  import { Fragment as Fragment11, jsx as jsx45, jsxs as jsxs36 } from "react/jsx-runtime";
48518
48399
  function Footer({
48519
48400
  Link,
@@ -48524,7 +48405,7 @@ function Footer({
48524
48405
  apiDocsUrl = "/api/docs",
48525
48406
  sourceCodeUrl = "https://github.com/The-AI-Alliance/semiont"
48526
48407
  }) {
48527
- const [showCookiePreferences, setShowCookiePreferences] = useState26(false);
48408
+ const [showCookiePreferences, setShowCookiePreferences] = useState25(false);
48528
48409
  return /* @__PURE__ */ jsxs36(Fragment11, { children: [
48529
48410
  /* @__PURE__ */ jsx45("footer", { role: "contentinfo", className: "semiont-footer", children: /* @__PURE__ */ jsx45("div", { className: "semiont-footer__container", children: /* @__PURE__ */ jsxs36("div", { className: "semiont-footer__content", children: [
48530
48411
  /* @__PURE__ */ jsx45("div", { className: "semiont-footer__copyright", children: t12("copyright", { year: (/* @__PURE__ */ new Date()).getFullYear() }) }),
@@ -48662,7 +48543,7 @@ function NavigationMenu({
48662
48543
  }
48663
48544
 
48664
48545
  // src/components/navigation/ObservableLink.tsx
48665
- import { useCallback as useCallback23, useRef as useRef27, useEffect as useEffect35 } from "react";
48546
+ import { useCallback as useCallback22, useRef as useRef24, useEffect as useEffect33 } from "react";
48666
48547
  import { jsx as jsx47 } from "react/jsx-runtime";
48667
48548
  function ObservableLink({
48668
48549
  href,
@@ -48672,11 +48553,11 @@ function ObservableLink({
48672
48553
  ...anchorProps
48673
48554
  }) {
48674
48555
  const eventBus = useEventBus();
48675
- const onClickRef = useRef27(onClick);
48676
- useEffect35(() => {
48556
+ const onClickRef = useRef24(onClick);
48557
+ useEffect33(() => {
48677
48558
  onClickRef.current = onClick;
48678
48559
  });
48679
- const handleClick = useCallback23((e6) => {
48560
+ const handleClick = useCallback22((e6) => {
48680
48561
  eventBus.emit("navigation:link-clicked", {
48681
48562
  href,
48682
48563
  label
@@ -48695,7 +48576,7 @@ function ObservableLink({
48695
48576
  }
48696
48577
 
48697
48578
  // src/components/navigation/SimpleNavigation.tsx
48698
- import { useState as useState27, useRef as useRef28, useEffect as useEffect36 } from "react";
48579
+ import { useState as useState26, useRef as useRef25, useEffect as useEffect34 } from "react";
48699
48580
  import { jsx as jsx48, jsxs as jsxs38 } from "react/jsx-runtime";
48700
48581
  function SimpleNavigation({
48701
48582
  title,
@@ -48710,12 +48591,12 @@ function SimpleNavigation({
48710
48591
  }) {
48711
48592
  const ChevronLeftIcon = icons.chevronLeft;
48712
48593
  const BarsIcon = icons.bars;
48713
- const [isDropdownOpen, setIsDropdownOpen] = useState27(false);
48714
- const dropdownRef = useRef28(null);
48594
+ const [isDropdownOpen, setIsDropdownOpen] = useState26(false);
48595
+ const dropdownRef = useRef25(null);
48715
48596
  const eventBus = useEventBus();
48716
48597
  const toggleDropdown = () => setIsDropdownOpen(!isDropdownOpen);
48717
48598
  const closeDropdown = () => setIsDropdownOpen(false);
48718
- useEffect36(() => {
48599
+ useEffect34(() => {
48719
48600
  const handleClickOutside = (event) => {
48720
48601
  if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
48721
48602
  closeDropdown();
@@ -48791,14 +48672,14 @@ function SimpleNavigation({
48791
48672
  }
48792
48673
 
48793
48674
  // src/components/navigation/CollapsibleResourceNavigation.tsx
48794
- import { useCallback as useCallback29, useState as useState31, useRef as useRef33, useEffect as useEffect41 } from "react";
48675
+ import { useCallback as useCallback28, useState as useState30, useRef as useRef30, useEffect as useEffect39 } from "react";
48795
48676
 
48796
48677
  // ../../node_modules/@dnd-kit/core/dist/core.esm.js
48797
- import React20, { createContext as createContext7, useContext as useContext7, useEffect as useEffect38, useState as useState29, useCallback as useCallback26, useMemo as useMemo10, useRef as useRef30, memo, useReducer, cloneElement, forwardRef as forwardRef6 } from "react";
48678
+ import React20, { createContext as createContext7, useContext as useContext7, useEffect as useEffect36, useState as useState28, useCallback as useCallback25, useMemo as useMemo10, useRef as useRef27, memo, useReducer, cloneElement, forwardRef as forwardRef6 } from "react";
48798
48679
  import { createPortal, unstable_batchedUpdates } from "react-dom";
48799
48680
 
48800
48681
  // ../../node_modules/@dnd-kit/utilities/dist/utilities.esm.js
48801
- import { useMemo as useMemo9, useLayoutEffect, useEffect as useEffect37, useRef as useRef29, useCallback as useCallback24 } from "react";
48682
+ import { useMemo as useMemo9, useLayoutEffect, useEffect as useEffect35, useRef as useRef26, useCallback as useCallback23 } from "react";
48802
48683
  function useCombinedRefs() {
48803
48684
  for (var _len = arguments.length, refs = new Array(_len), _key = 0; _key < _len; _key++) {
48804
48685
  refs[_key] = arguments[_key];
@@ -48866,13 +48747,13 @@ function getOwnerDocument(target) {
48866
48747
  }
48867
48748
  return document;
48868
48749
  }
48869
- var useIsomorphicLayoutEffect = canUseDOM ? useLayoutEffect : useEffect37;
48750
+ var useIsomorphicLayoutEffect = canUseDOM ? useLayoutEffect : useEffect35;
48870
48751
  function useEvent(handler) {
48871
- const handlerRef = useRef29(handler);
48752
+ const handlerRef = useRef26(handler);
48872
48753
  useIsomorphicLayoutEffect(() => {
48873
48754
  handlerRef.current = handler;
48874
48755
  });
48875
- return useCallback24(function() {
48756
+ return useCallback23(function() {
48876
48757
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
48877
48758
  args[_key] = arguments[_key];
48878
48759
  }
@@ -48880,11 +48761,11 @@ function useEvent(handler) {
48880
48761
  }, []);
48881
48762
  }
48882
48763
  function useInterval() {
48883
- const intervalRef = useRef29(null);
48884
- const set = useCallback24((listener, duration) => {
48764
+ const intervalRef = useRef26(null);
48765
+ const set = useCallback23((listener, duration) => {
48885
48766
  intervalRef.current = setInterval(listener, duration);
48886
48767
  }, []);
48887
- const clear = useCallback24(() => {
48768
+ const clear = useCallback23(() => {
48888
48769
  if (intervalRef.current !== null) {
48889
48770
  clearInterval(intervalRef.current);
48890
48771
  intervalRef.current = null;
@@ -48896,7 +48777,7 @@ function useLatestValue(value, dependencies) {
48896
48777
  if (dependencies === void 0) {
48897
48778
  dependencies = [value];
48898
48779
  }
48899
- const valueRef = useRef29(value);
48780
+ const valueRef = useRef26(value);
48900
48781
  useIsomorphicLayoutEffect(() => {
48901
48782
  if (valueRef.current !== value) {
48902
48783
  valueRef.current = value;
@@ -48905,7 +48786,7 @@ function useLatestValue(value, dependencies) {
48905
48786
  return valueRef;
48906
48787
  }
48907
48788
  function useLazyMemo(callback, dependencies) {
48908
- const valueRef = useRef29();
48789
+ const valueRef = useRef26();
48909
48790
  return useMemo9(
48910
48791
  () => {
48911
48792
  const newValue = callback(valueRef.current);
@@ -48918,8 +48799,8 @@ function useLazyMemo(callback, dependencies) {
48918
48799
  }
48919
48800
  function useNodeRef(onChange) {
48920
48801
  const onChangeHandler = useEvent(onChange);
48921
- const node2 = useRef29(null);
48922
- const setNodeRef = useCallback24(
48802
+ const node2 = useRef26(null);
48803
+ const setNodeRef = useCallback23(
48923
48804
  (element2) => {
48924
48805
  if (element2 !== node2.current) {
48925
48806
  onChangeHandler == null ? void 0 : onChangeHandler(element2, node2.current);
@@ -48932,8 +48813,8 @@ function useNodeRef(onChange) {
48932
48813
  return [node2, setNodeRef];
48933
48814
  }
48934
48815
  function usePrevious(value) {
48935
- const ref = useRef29();
48936
- useEffect37(() => {
48816
+ const ref = useRef26();
48817
+ useEffect35(() => {
48937
48818
  ref.current = value;
48938
48819
  }, [value]);
48939
48820
  return ref.current;
@@ -49074,7 +48955,7 @@ function findFirstFocusableNode(element2) {
49074
48955
  }
49075
48956
 
49076
48957
  // ../../node_modules/@dnd-kit/accessibility/dist/accessibility.esm.js
49077
- import React19, { useState as useState28, useCallback as useCallback25 } from "react";
48958
+ import React19, { useState as useState27, useCallback as useCallback24 } from "react";
49078
48959
  var hiddenStyles = {
49079
48960
  display: "none"
49080
48961
  };
@@ -49117,8 +48998,8 @@ function LiveRegion(_ref) {
49117
48998
  }, announcement);
49118
48999
  }
49119
49000
  function useAnnouncement() {
49120
- const [announcement, setAnnouncement] = useState28("");
49121
- const announce = useCallback25((value) => {
49001
+ const [announcement, setAnnouncement] = useState27("");
49002
+ const announce = useCallback24((value) => {
49122
49003
  if (value != null) {
49123
49004
  setAnnouncement(value);
49124
49005
  }
@@ -49133,7 +49014,7 @@ function useAnnouncement() {
49133
49014
  var DndMonitorContext = /* @__PURE__ */ createContext7(null);
49134
49015
  function useDndMonitor(listener) {
49135
49016
  const registerListener = useContext7(DndMonitorContext);
49136
- useEffect38(() => {
49017
+ useEffect36(() => {
49137
49018
  if (!registerListener) {
49138
49019
  throw new Error("useDndMonitor must be used within a children of <DndContext>");
49139
49020
  }
@@ -49142,12 +49023,12 @@ function useDndMonitor(listener) {
49142
49023
  }, [listener, registerListener]);
49143
49024
  }
49144
49025
  function useDndMonitorProvider() {
49145
- const [listeners] = useState29(() => /* @__PURE__ */ new Set());
49146
- const registerListener = useCallback26((listener) => {
49026
+ const [listeners] = useState28(() => /* @__PURE__ */ new Set());
49027
+ const registerListener = useCallback25((listener) => {
49147
49028
  listeners.add(listener);
49148
49029
  return () => listeners.delete(listener);
49149
49030
  }, [listeners]);
49150
- const dispatch = useCallback26((_ref) => {
49031
+ const dispatch = useCallback25((_ref) => {
49151
49032
  let {
49152
49033
  type,
49153
49034
  event
@@ -49208,8 +49089,8 @@ function Accessibility(_ref) {
49208
49089
  announcement
49209
49090
  } = useAnnouncement();
49210
49091
  const liveRegionId = useUniqueId("DndLiveRegion");
49211
- const [mounted, setMounted] = useState29(false);
49212
- useEffect38(() => {
49092
+ const [mounted, setMounted] = useState28(false);
49093
+ useEffect36(() => {
49213
49094
  setMounted(true);
49214
49095
  }, []);
49215
49096
  useDndMonitor(useMemo10(() => ({
@@ -50545,11 +50426,11 @@ function useAutoScroller(_ref) {
50545
50426
  disabled: !enabled
50546
50427
  });
50547
50428
  const [setAutoScrollInterval, clearAutoScrollInterval] = useInterval();
50548
- const scrollSpeed = useRef30({
50429
+ const scrollSpeed = useRef27({
50549
50430
  x: 0,
50550
50431
  y: 0
50551
50432
  });
50552
- const scrollDirection = useRef30({
50433
+ const scrollDirection = useRef27({
50553
50434
  x: 0,
50554
50435
  y: 0
50555
50436
  });
@@ -50566,8 +50447,8 @@ function useAutoScroller(_ref) {
50566
50447
  return draggingRect;
50567
50448
  }
50568
50449
  }, [activator, draggingRect, pointerCoordinates]);
50569
- const scrollContainerRef = useRef30(null);
50570
- const autoScroll = useCallback26(() => {
50450
+ const scrollContainerRef = useRef27(null);
50451
+ const autoScroll = useCallback25(() => {
50571
50452
  const scrollContainer = scrollContainerRef.current;
50572
50453
  if (!scrollContainer) {
50573
50454
  return;
@@ -50577,7 +50458,7 @@ function useAutoScroller(_ref) {
50577
50458
  scrollContainer.scrollBy(scrollLeft, scrollTop);
50578
50459
  }, []);
50579
50460
  const sortedScrollableAncestors = useMemo10(() => order2 === TraversalOrder.TreeOrder ? [...scrollableAncestors].reverse() : scrollableAncestors, [order2, scrollableAncestors]);
50580
- useEffect38(
50461
+ useEffect36(
50581
50462
  () => {
50582
50463
  if (!enabled || !scrollableAncestors.length || !rect) {
50583
50464
  clearAutoScrollInterval();
@@ -50718,16 +50599,16 @@ function useDroppableMeasuring(containers, _ref) {
50718
50599
  dependencies,
50719
50600
  config
50720
50601
  } = _ref;
50721
- const [queue, setQueue] = useState29(null);
50602
+ const [queue, setQueue] = useState28(null);
50722
50603
  const {
50723
50604
  frequency,
50724
50605
  measure,
50725
50606
  strategy
50726
50607
  } = config;
50727
- const containersRef = useRef30(containers);
50608
+ const containersRef = useRef27(containers);
50728
50609
  const disabled = isDisabled();
50729
50610
  const disabledRef = useLatestValue(disabled);
50730
- const measureDroppableContainers = useCallback26(function(ids2) {
50611
+ const measureDroppableContainers = useCallback25(function(ids2) {
50731
50612
  if (ids2 === void 0) {
50732
50613
  ids2 = [];
50733
50614
  }
@@ -50741,7 +50622,7 @@ function useDroppableMeasuring(containers, _ref) {
50741
50622
  return value.concat(ids2.filter((id2) => !value.includes(id2)));
50742
50623
  });
50743
50624
  }, [disabledRef]);
50744
- const timeoutId = useRef30(null);
50625
+ const timeoutId = useRef27(null);
50745
50626
  const droppableRects = useLazyMemo((previousValue) => {
50746
50627
  if (disabled && !dragging) {
50747
50628
  return defaultValue;
@@ -50767,10 +50648,10 @@ function useDroppableMeasuring(containers, _ref) {
50767
50648
  }
50768
50649
  return previousValue;
50769
50650
  }, [containers, queue, dragging, disabled, measure]);
50770
- useEffect38(() => {
50651
+ useEffect36(() => {
50771
50652
  containersRef.current = containers;
50772
50653
  }, [containers]);
50773
- useEffect38(
50654
+ useEffect36(
50774
50655
  () => {
50775
50656
  if (disabled) {
50776
50657
  return;
@@ -50780,7 +50661,7 @@ function useDroppableMeasuring(containers, _ref) {
50780
50661
  // eslint-disable-next-line react-hooks/exhaustive-deps
50781
50662
  [dragging, disabled]
50782
50663
  );
50783
- useEffect38(
50664
+ useEffect36(
50784
50665
  () => {
50785
50666
  if (queue && queue.length > 0) {
50786
50667
  setQueue(null);
@@ -50789,7 +50670,7 @@ function useDroppableMeasuring(containers, _ref) {
50789
50670
  //eslint-disable-next-line react-hooks/exhaustive-deps
50790
50671
  [JSON.stringify(queue)]
50791
50672
  );
50792
- useEffect38(
50673
+ useEffect36(
50793
50674
  () => {
50794
50675
  if (disabled || typeof frequency !== "number" || timeoutId.current !== null) {
50795
50676
  return;
@@ -50847,7 +50728,7 @@ function useMutationObserver(_ref) {
50847
50728
  } = window;
50848
50729
  return new MutationObserver2(handleMutations);
50849
50730
  }, [handleMutations, disabled]);
50850
- useEffect38(() => {
50731
+ useEffect36(() => {
50851
50732
  return () => mutationObserver == null ? void 0 : mutationObserver.disconnect();
50852
50733
  }, [mutationObserver]);
50853
50734
  return mutationObserver;
@@ -50871,7 +50752,7 @@ function useResizeObserver(_ref) {
50871
50752
  // eslint-disable-next-line react-hooks/exhaustive-deps
50872
50753
  [disabled]
50873
50754
  );
50874
- useEffect38(() => {
50755
+ useEffect36(() => {
50875
50756
  return () => resizeObserver == null ? void 0 : resizeObserver.disconnect();
50876
50757
  }, [resizeObserver]);
50877
50758
  return resizeObserver;
@@ -50883,7 +50764,7 @@ function useRect(element2, measure, fallbackRect2) {
50883
50764
  if (measure === void 0) {
50884
50765
  measure = defaultMeasure;
50885
50766
  }
50886
- const [rect, setRect] = useState29(null);
50767
+ const [rect, setRect] = useState28(null);
50887
50768
  function measureRect() {
50888
50769
  setRect((currentRect) => {
50889
50770
  if (!element2) {
@@ -50941,7 +50822,7 @@ function useRectDelta(rect) {
50941
50822
  }
50942
50823
  var defaultValue$1 = [];
50943
50824
  function useScrollableAncestors(node2) {
50944
- const previousNode = useRef30(node2);
50825
+ const previousNode = useRef27(node2);
50945
50826
  const ancestors = useLazyMemo((previousValue) => {
50946
50827
  if (!node2) {
50947
50828
  return defaultValue$1;
@@ -50951,15 +50832,15 @@ function useScrollableAncestors(node2) {
50951
50832
  }
50952
50833
  return getScrollableAncestors(node2);
50953
50834
  }, [node2]);
50954
- useEffect38(() => {
50835
+ useEffect36(() => {
50955
50836
  previousNode.current = node2;
50956
50837
  }, [node2]);
50957
50838
  return ancestors;
50958
50839
  }
50959
50840
  function useScrollOffsets(elements) {
50960
- const [scrollCoordinates, setScrollCoordinates] = useState29(null);
50961
- const prevElements = useRef30(elements);
50962
- const handleScroll = useCallback26((event) => {
50841
+ const [scrollCoordinates, setScrollCoordinates] = useState28(null);
50842
+ const prevElements = useRef27(elements);
50843
+ const handleScroll = useCallback25((event) => {
50963
50844
  const scrollingElement = getScrollableElement(event.target);
50964
50845
  if (!scrollingElement) {
50965
50846
  return;
@@ -50972,7 +50853,7 @@ function useScrollOffsets(elements) {
50972
50853
  return new Map(scrollCoordinates2);
50973
50854
  });
50974
50855
  }, []);
50975
- useEffect38(() => {
50856
+ useEffect36(() => {
50976
50857
  const previousElements = prevElements.current;
50977
50858
  if (elements !== previousElements) {
50978
50859
  cleanup(previousElements);
@@ -51011,15 +50892,15 @@ function useScrollOffsetsDelta(scrollOffsets, dependencies) {
51011
50892
  if (dependencies === void 0) {
51012
50893
  dependencies = [];
51013
50894
  }
51014
- const initialScrollOffsets = useRef30(null);
51015
- useEffect38(
50895
+ const initialScrollOffsets = useRef27(null);
50896
+ useEffect36(
51016
50897
  () => {
51017
50898
  initialScrollOffsets.current = null;
51018
50899
  },
51019
50900
  // eslint-disable-next-line react-hooks/exhaustive-deps
51020
50901
  dependencies
51021
50902
  );
51022
- useEffect38(() => {
50903
+ useEffect36(() => {
51023
50904
  const hasScrollOffsets = scrollOffsets !== defaultCoordinates;
51024
50905
  if (hasScrollOffsets && !initialScrollOffsets.current) {
51025
50906
  initialScrollOffsets.current = scrollOffsets;
@@ -51031,7 +50912,7 @@ function useScrollOffsetsDelta(scrollOffsets, dependencies) {
51031
50912
  return initialScrollOffsets.current ? subtract(scrollOffsets, initialScrollOffsets.current) : defaultCoordinates;
51032
50913
  }
51033
50914
  function useSensorSetup(sensors) {
51034
- useEffect38(
50915
+ useEffect36(
51035
50916
  () => {
51036
50917
  if (!canUseDOM) {
51037
50918
  return;
@@ -51082,7 +50963,7 @@ function useRects(elements, measure) {
51082
50963
  }
51083
50964
  const [firstElement] = elements;
51084
50965
  const windowRect2 = useWindowRect(firstElement ? getWindow(firstElement) : null);
51085
- const [rects, setRects] = useState29(defaultValue$2);
50966
+ const [rects, setRects] = useState28(defaultValue$2);
51086
50967
  function measureRects() {
51087
50968
  setRects(() => {
51088
50969
  if (!elements.length) {
@@ -51115,8 +50996,8 @@ function useDragOverlayMeasuring(_ref) {
51115
50996
  let {
51116
50997
  measure
51117
50998
  } = _ref;
51118
- const [rect, setRect] = useState29(null);
51119
- const handleResize = useCallback26((entries) => {
50999
+ const [rect, setRect] = useState28(null);
51000
+ const handleResize = useCallback25((entries) => {
51120
51001
  for (const {
51121
51002
  target
51122
51003
  } of entries) {
@@ -51136,7 +51017,7 @@ function useDragOverlayMeasuring(_ref) {
51136
51017
  const resizeObserver = useResizeObserver({
51137
51018
  callback: handleResize
51138
51019
  });
51139
- const handleNodeChange = useCallback26((element2) => {
51020
+ const handleNodeChange = useCallback25((element2) => {
51140
51021
  const node2 = getMeasurableNode(element2);
51141
51022
  resizeObserver == null ? void 0 : resizeObserver.disconnect();
51142
51023
  if (node2) {
@@ -51371,7 +51252,7 @@ function RestoreFocus(_ref) {
51371
51252
  } = useContext7(InternalContext);
51372
51253
  const previousActivatorEvent = usePrevious(activatorEvent);
51373
51254
  const previousActiveId = usePrevious(active == null ? void 0 : active.id);
51374
- useEffect38(() => {
51255
+ useEffect36(() => {
51375
51256
  if (disabled) {
51376
51257
  return;
51377
51258
  }
@@ -51448,7 +51329,7 @@ function useLayoutShiftScrollCompensation(_ref) {
51448
51329
  initialRect,
51449
51330
  config = true
51450
51331
  } = _ref;
51451
- const initialized = useRef30(false);
51332
+ const initialized = useRef27(false);
51452
51333
  const {
51453
51334
  x: x8,
51454
51335
  y: y4
@@ -51516,7 +51397,7 @@ var DndContext = /* @__PURE__ */ memo(function DndContext2(_ref) {
51516
51397
  const store = useReducer(reducer, void 0, getInitialState);
51517
51398
  const [state, dispatch] = store;
51518
51399
  const [dispatchMonitorEvent, registerMonitorListener] = useDndMonitorProvider();
51519
- const [status, setStatus] = useState29(Status.Uninitialized);
51400
+ const [status, setStatus] = useState28(Status.Uninitialized);
51520
51401
  const isInitialized = status === Status.Initialized;
51521
51402
  const {
51522
51403
  draggable: {
@@ -51529,7 +51410,7 @@ var DndContext = /* @__PURE__ */ memo(function DndContext2(_ref) {
51529
51410
  }
51530
51411
  } = state;
51531
51412
  const node2 = activeId != null ? draggableNodes.get(activeId) : null;
51532
- const activeRects = useRef30({
51413
+ const activeRects = useRef27({
51533
51414
  initial: null,
51534
51415
  translated: null
51535
51416
  });
@@ -51542,9 +51423,9 @@ var DndContext = /* @__PURE__ */ memo(function DndContext2(_ref) {
51542
51423
  rect: activeRects
51543
51424
  } : null;
51544
51425
  }, [activeId, node2]);
51545
- const activeRef = useRef30(null);
51546
- const [activeSensor, setActiveSensor] = useState29(null);
51547
- const [activatorEvent, setActivatorEvent] = useState29(null);
51426
+ const activeRef = useRef27(null);
51427
+ const [activeSensor, setActiveSensor] = useState28(null);
51428
+ const [activatorEvent, setActivatorEvent] = useState28(null);
51548
51429
  const latestProps = useLatestValue(props, Object.values(props));
51549
51430
  const draggableDescribedById = useUniqueId("DndDescribedBy", id2);
51550
51431
  const enabledDroppableContainers = useMemo10(() => droppableContainers.getEnabled(), [droppableContainers]);
@@ -51570,7 +51451,7 @@ var DndContext = /* @__PURE__ */ memo(function DndContext2(_ref) {
51570
51451
  });
51571
51452
  const activeNodeRect = useRect(activeNode, measuringConfiguration.draggable.measure, initialActiveNodeRect);
51572
51453
  const containerNodeRect = useRect(activeNode ? activeNode.parentElement : null);
51573
- const sensorContext = useRef30({
51454
+ const sensorContext = useRef27({
51574
51455
  activatorEvent: null,
51575
51456
  active: null,
51576
51457
  activeNode,
@@ -51628,11 +51509,11 @@ var DndContext = /* @__PURE__ */ memo(function DndContext2(_ref) {
51628
51509
  pointerCoordinates
51629
51510
  }) : null;
51630
51511
  const overId = getFirstCollision(collisions, "id");
51631
- const [over, setOver] = useState29(null);
51512
+ const [over, setOver] = useState28(null);
51632
51513
  const appliedTranslate = usesDragOverlay ? modifiedTranslate : add(modifiedTranslate, activeNodeScrollDelta);
51633
51514
  const transform = adjustScale(appliedTranslate, (_over$rect = over == null ? void 0 : over.rect) != null ? _over$rect : null, activeNodeRect);
51634
- const activeSensorRef = useRef30(null);
51635
- const instantiateSensor = useCallback26(
51515
+ const activeSensorRef = useRef27(null);
51516
+ const instantiateSensor = useCallback25(
51636
51517
  (event, _ref2) => {
51637
51518
  let {
51638
51519
  sensor: Sensor,
@@ -51790,7 +51671,7 @@ var DndContext = /* @__PURE__ */ memo(function DndContext2(_ref) {
51790
51671
  // eslint-disable-next-line react-hooks/exhaustive-deps
51791
51672
  [draggableNodes]
51792
51673
  );
51793
- const bindActivatorToSensorInstantiator = useCallback26((handler, sensor) => {
51674
+ const bindActivatorToSensorInstantiator = useCallback25((handler, sensor) => {
51794
51675
  return (event, active2) => {
51795
51676
  const nativeEvent = event.nativeEvent;
51796
51677
  const activeDraggableNode = draggableNodes.get(active2);
@@ -51822,7 +51703,7 @@ var DndContext = /* @__PURE__ */ memo(function DndContext2(_ref) {
51822
51703
  setStatus(Status.Initialized);
51823
51704
  }
51824
51705
  }, [activeNodeRect, status]);
51825
- useEffect38(
51706
+ useEffect36(
51826
51707
  () => {
51827
51708
  const {
51828
51709
  onDragMove
@@ -51857,7 +51738,7 @@ var DndContext = /* @__PURE__ */ memo(function DndContext2(_ref) {
51857
51738
  // eslint-disable-next-line react-hooks/exhaustive-deps
51858
51739
  [scrollAdjustedTranslate.x, scrollAdjustedTranslate.y]
51859
51740
  );
51860
- useEffect38(
51741
+ useEffect36(
51861
51742
  () => {
51862
51743
  const {
51863
51744
  active: active2,
@@ -52090,12 +51971,12 @@ function useDroppable(_ref) {
52090
51971
  over,
52091
51972
  measureDroppableContainers
52092
51973
  } = useContext7(InternalContext);
52093
- const previous3 = useRef30({
51974
+ const previous3 = useRef27({
52094
51975
  disabled
52095
51976
  });
52096
- const resizeObserverConnected = useRef30(false);
52097
- const rect = useRef30(null);
52098
- const callbackId = useRef30(null);
51977
+ const resizeObserverConnected = useRef27(false);
51978
+ const rect = useRef27(null);
51979
+ const callbackId = useRef27(null);
52099
51980
  const {
52100
51981
  disabled: resizeObserverDisabled,
52101
51982
  updateMeasurementsFor,
@@ -52105,7 +51986,7 @@ function useDroppable(_ref) {
52105
51986
  ...resizeObserverConfig
52106
51987
  };
52107
51988
  const ids2 = useLatestValue(updateMeasurementsFor != null ? updateMeasurementsFor : id2);
52108
- const handleResize = useCallback26(
51989
+ const handleResize = useCallback25(
52109
51990
  () => {
52110
51991
  if (!resizeObserverConnected.current) {
52111
51992
  resizeObserverConnected.current = true;
@@ -52126,7 +52007,7 @@ function useDroppable(_ref) {
52126
52007
  callback: handleResize,
52127
52008
  disabled: resizeObserverDisabled || !active
52128
52009
  });
52129
- const handleNodeChange = useCallback26((newElement, previousElement) => {
52010
+ const handleNodeChange = useCallback25((newElement, previousElement) => {
52130
52011
  if (!resizeObserver) {
52131
52012
  return;
52132
52013
  }
@@ -52140,7 +52021,7 @@ function useDroppable(_ref) {
52140
52021
  }, [resizeObserver]);
52141
52022
  const [nodeRef, setNodeRef] = useNodeRef(handleNodeChange);
52142
52023
  const dataRef = useLatestValue(data2);
52143
- useEffect38(() => {
52024
+ useEffect36(() => {
52144
52025
  if (!resizeObserver || !nodeRef.current) {
52145
52026
  return;
52146
52027
  }
@@ -52148,7 +52029,7 @@ function useDroppable(_ref) {
52148
52029
  resizeObserverConnected.current = false;
52149
52030
  resizeObserver.observe(nodeRef.current);
52150
52031
  }, [nodeRef, resizeObserver]);
52151
- useEffect38(
52032
+ useEffect36(
52152
52033
  () => {
52153
52034
  dispatch({
52154
52035
  type: Action.RegisterDroppable,
@@ -52170,7 +52051,7 @@ function useDroppable(_ref) {
52170
52051
  // eslint-disable-next-line react-hooks/exhaustive-deps
52171
52052
  [id2]
52172
52053
  );
52173
- useEffect38(() => {
52054
+ useEffect36(() => {
52174
52055
  if (disabled !== previous3.current.disabled) {
52175
52056
  dispatch({
52176
52057
  type: Action.SetDroppableDisabled,
@@ -52192,7 +52073,7 @@ function useDroppable(_ref) {
52192
52073
  }
52193
52074
 
52194
52075
  // ../../node_modules/@dnd-kit/sortable/dist/sortable.esm.js
52195
- import React21, { useMemo as useMemo11, useRef as useRef31, useEffect as useEffect39, useState as useState30, useContext as useContext8 } from "react";
52076
+ import React21, { useMemo as useMemo11, useRef as useRef28, useEffect as useEffect37, useState as useState29, useContext as useContext8 } from "react";
52196
52077
  function arrayMove(array, from, to) {
52197
52078
  const newArray = array.slice();
52198
52079
  newArray.splice(to < 0 ? newArray.length + to : to, 0, newArray.splice(from, 1)[0]);
@@ -52350,7 +52231,7 @@ function SortableContext(_ref) {
52350
52231
  const isDragging = active != null;
52351
52232
  const activeIndex = active ? items.indexOf(active.id) : -1;
52352
52233
  const overIndex = over ? items.indexOf(over.id) : -1;
52353
- const previousItemsRef = useRef31(items);
52234
+ const previousItemsRef = useRef28(items);
52354
52235
  const itemsHaveChanged = !itemsEqual(items, previousItemsRef.current);
52355
52236
  const disableTransforms = overIndex !== -1 && activeIndex === -1 || itemsHaveChanged;
52356
52237
  const disabled = normalizeDisabled(disabledProp);
@@ -52359,7 +52240,7 @@ function SortableContext(_ref) {
52359
52240
  measureDroppableContainers(items);
52360
52241
  }
52361
52242
  }, [itemsHaveChanged, items, isDragging, measureDroppableContainers]);
52362
- useEffect39(() => {
52243
+ useEffect37(() => {
52363
52244
  previousItemsRef.current = items;
52364
52245
  }, [items]);
52365
52246
  const contextValue = useMemo11(
@@ -52433,8 +52314,8 @@ function useDerivedTransform(_ref) {
52433
52314
  node: node2,
52434
52315
  rect
52435
52316
  } = _ref;
52436
- const [derivedTransform, setDerivedtransform] = useState30(null);
52437
- const previousIndex = useRef31(index2);
52317
+ const [derivedTransform, setDerivedtransform] = useState29(null);
52318
+ const previousIndex = useRef28(index2);
52438
52319
  useIsomorphicLayoutEffect(() => {
52439
52320
  if (!disabled && index2 !== previousIndex.current && node2.current) {
52440
52321
  const initial = rect.current;
@@ -52457,7 +52338,7 @@ function useDerivedTransform(_ref) {
52457
52338
  previousIndex.current = index2;
52458
52339
  }
52459
52340
  }, [disabled, index2, node2, rect]);
52460
- useEffect39(() => {
52341
+ useEffect37(() => {
52461
52342
  if (derivedTransform) {
52462
52343
  setDerivedtransform(null);
52463
52344
  }
@@ -52552,7 +52433,7 @@ function useSortable(_ref) {
52552
52433
  overIndex
52553
52434
  }) : index2;
52554
52435
  const activeId = active == null ? void 0 : active.id;
52555
- const previous3 = useRef31({
52436
+ const previous3 = useRef28({
52556
52437
  activeId,
52557
52438
  items,
52558
52439
  newIndex,
@@ -52579,7 +52460,7 @@ function useSortable(_ref) {
52579
52460
  node: node2,
52580
52461
  rect
52581
52462
  });
52582
- useEffect39(() => {
52463
+ useEffect37(() => {
52583
52464
  if (isSorting && previous3.current.newIndex !== newIndex) {
52584
52465
  previous3.current.newIndex = newIndex;
52585
52466
  }
@@ -52590,7 +52471,7 @@ function useSortable(_ref) {
52590
52471
  previous3.current.items = items;
52591
52472
  }
52592
52473
  }, [isSorting, newIndex, containerId, items]);
52593
- useEffect39(() => {
52474
+ useEffect37(() => {
52594
52475
  if (activeId === previous3.current.activeId) {
52595
52476
  return;
52596
52477
  }
@@ -52775,7 +52656,7 @@ function isAfter(a15, b8) {
52775
52656
  }
52776
52657
 
52777
52658
  // src/components/navigation/SortableResourceTab.tsx
52778
- import { useCallback as useCallback27, useRef as useRef32, useEffect as useEffect40 } from "react";
52659
+ import { useCallback as useCallback26, useRef as useRef29, useEffect as useEffect38 } from "react";
52779
52660
  import { jsx as jsx49, jsxs as jsxs39 } from "react/jsx-runtime";
52780
52661
  function SortableResourceTab({
52781
52662
  resource,
@@ -52798,8 +52679,8 @@ function SortableResourceTab({
52798
52679
  transition,
52799
52680
  isDragging: isSortableDragging
52800
52681
  } = useSortable({ id: resource.id });
52801
- const onReorderRef = useRef32(onReorder);
52802
- useEffect40(() => {
52682
+ const onReorderRef = useRef29(onReorder);
52683
+ useEffect38(() => {
52803
52684
  onReorderRef.current = onReorder;
52804
52685
  });
52805
52686
  const style = {
@@ -52809,7 +52690,7 @@ function SortableResourceTab({
52809
52690
  };
52810
52691
  const iconEmoji = getResourceIcon(resource.mediaType);
52811
52692
  const isCurrentlyDragging = isSortableDragging || isDragging;
52812
- const handleKeyDown = useCallback27((e6) => {
52693
+ const handleKeyDown = useCallback26((e6) => {
52813
52694
  if (onReorderRef.current && e6.altKey) {
52814
52695
  if (e6.key === "ArrowUp") {
52815
52696
  e6.preventDefault();
@@ -52862,37 +52743,37 @@ function SortableResourceTab({
52862
52743
  }
52863
52744
 
52864
52745
  // src/hooks/useDragAnnouncements.ts
52865
- import { useCallback as useCallback28 } from "react";
52746
+ import { useCallback as useCallback27 } from "react";
52866
52747
  function useDragAnnouncements() {
52867
52748
  const { announce } = useLiveRegion();
52868
- const announceReorder = useCallback28((message) => {
52749
+ const announceReorder = useCallback27((message) => {
52869
52750
  announce(message, "assertive");
52870
52751
  }, [announce]);
52871
- const announcePickup = useCallback28((resourceName, position3, total) => {
52752
+ const announcePickup = useCallback27((resourceName, position3, total) => {
52872
52753
  announce(
52873
52754
  `Picked up ${resourceName}. Position ${position3} of ${total}. Use arrow keys to move, space to drop.`,
52874
52755
  "assertive"
52875
52756
  );
52876
52757
  }, [announce]);
52877
- const announceDrop = useCallback28((resourceName, newPosition, total) => {
52758
+ const announceDrop = useCallback27((resourceName, newPosition, total) => {
52878
52759
  announce(
52879
52760
  `Dropped ${resourceName} at position ${newPosition} of ${total}.`,
52880
52761
  "assertive"
52881
52762
  );
52882
52763
  }, [announce]);
52883
- const announceMove = useCallback28((resourceName, direction, newPosition, total) => {
52764
+ const announceMove = useCallback27((resourceName, direction, newPosition, total) => {
52884
52765
  announce(
52885
52766
  `Moved ${resourceName} ${direction} to position ${newPosition} of ${total}.`,
52886
52767
  "polite"
52887
52768
  );
52888
52769
  }, [announce]);
52889
- const announceKeyboardReorder = useCallback28((resourceName, direction, newPosition, total) => {
52770
+ const announceKeyboardReorder = useCallback27((resourceName, direction, newPosition, total) => {
52890
52771
  announce(
52891
52772
  `${resourceName} moved ${direction} to position ${newPosition} of ${total}.`,
52892
52773
  "assertive"
52893
52774
  );
52894
52775
  }, [announce]);
52895
- const announceCannotMove = useCallback28((direction) => {
52776
+ const announceCannotMove = useCallback27((direction) => {
52896
52777
  announce(
52897
52778
  `Cannot move ${direction}. Already at the ${direction === "up" ? "top" : "bottom"} of the list.`,
52898
52779
  "polite"
@@ -52925,8 +52806,8 @@ function CollapsibleResourceNavigation({
52925
52806
  }) {
52926
52807
  const ChevronLeftIcon = icons.chevronLeft;
52927
52808
  const BarsIcon = icons.bars;
52928
- const [isDropdownOpen, setIsDropdownOpen] = useState31(false);
52929
- const dropdownRef = useRef33(null);
52809
+ const [isDropdownOpen, setIsDropdownOpen] = useState30(false);
52810
+ const dropdownRef = useRef30(null);
52930
52811
  const { announcePickup, announceDrop, announceKeyboardReorder, announceCannotMove } = useDragAnnouncements();
52931
52812
  const t12 = useTranslations("CollapsibleResourceNavigation");
52932
52813
  const eventBus = useEventBus();
@@ -52941,7 +52822,7 @@ function CollapsibleResourceNavigation({
52941
52822
  };
52942
52823
  const toggleDropdown = () => setIsDropdownOpen(!isDropdownOpen);
52943
52824
  const closeDropdown = () => setIsDropdownOpen(false);
52944
- useEffect41(() => {
52825
+ useEffect39(() => {
52945
52826
  const handleClickOutside = (event) => {
52946
52827
  if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
52947
52828
  closeDropdown();
@@ -52963,7 +52844,7 @@ function CollapsibleResourceNavigation({
52963
52844
  coordinateGetter: sortableKeyboardCoordinates
52964
52845
  })
52965
52846
  );
52966
- const handleKeyboardReorder = useCallback29((resourceId, direction) => {
52847
+ const handleKeyboardReorder = useCallback28((resourceId, direction) => {
52967
52848
  const currentIndex = resources.findIndex((r14) => r14.id === resourceId);
52968
52849
  if (currentIndex === -1) return;
52969
52850
  const newIndex = direction === "up" ? currentIndex - 1 : currentIndex + 1;
@@ -53139,16 +53020,16 @@ function CollapsibleResourceNavigation({
53139
53020
  }
53140
53021
 
53141
53022
  // src/components/modals/SearchModal.tsx
53142
- import { useState as useState32, useEffect as useEffect42, Fragment as Fragment13 } from "react";
53023
+ import { useState as useState31, useEffect as useEffect40, Fragment as Fragment13 } from "react";
53143
53024
 
53144
53025
  // src/hooks/useSearchAnnouncements.ts
53145
- import { useCallback as useCallback30 } from "react";
53026
+ import { useCallback as useCallback29 } from "react";
53146
53027
  function useSearchAnnouncements2() {
53147
53028
  const { announce } = useLiveRegion();
53148
- const announceSearching = useCallback30(() => {
53029
+ const announceSearching = useCallback29(() => {
53149
53030
  announce("Searching...", "polite");
53150
53031
  }, [announce]);
53151
- const announceSearchResults = useCallback30((count2, query) => {
53032
+ const announceSearchResults = useCallback29((count2, query) => {
53152
53033
  if (count2 === 0) {
53153
53034
  announce(`No results found for ${query}`, "polite");
53154
53035
  } else if (count2 === 1) {
@@ -53157,10 +53038,10 @@ function useSearchAnnouncements2() {
53157
53038
  announce(`${count2} results found for ${query}`, "polite");
53158
53039
  }
53159
53040
  }, [announce]);
53160
- const announceSelection = useCallback30((name3, type) => {
53041
+ const announceSelection = useCallback29((name3, type) => {
53161
53042
  announce(`Selected ${type}: ${name3}. Press Enter to navigate.`, "polite");
53162
53043
  }, [announce]);
53163
- const announceNavigation = useCallback30((name3, type) => {
53044
+ const announceNavigation = useCallback29((name3, type) => {
53164
53045
  announce(`Navigating to ${type}: ${name3}`, "assertive");
53165
53046
  }, [announce]);
53166
53047
  return {
@@ -53181,10 +53062,10 @@ function SearchModal({
53181
53062
  translations = {}
53182
53063
  }) {
53183
53064
  const { announceSearchResults, announceSearching } = useSearchAnnouncements2();
53184
- const [query, setQuery] = useState32("");
53185
- const [debouncedQuery, setDebouncedQuery] = useState32("");
53186
- const [results, setResults] = useState32([]);
53187
- const [selectedIndex, setSelectedIndex] = useState32(0);
53065
+ const [query, setQuery] = useState31("");
53066
+ const [debouncedQuery, setDebouncedQuery] = useState31("");
53067
+ const [results, setResults] = useState31([]);
53068
+ const [selectedIndex, setSelectedIndex] = useState31(0);
53188
53069
  const t12 = {
53189
53070
  placeholder: translations.placeholder || "Search resources, entities...",
53190
53071
  searching: translations.searching || "Searching...",
@@ -53196,7 +53077,7 @@ function SearchModal({
53196
53077
  enter: translations.enter || "Enter",
53197
53078
  esc: translations.esc || "ESC"
53198
53079
  };
53199
- useEffect42(() => {
53080
+ useEffect40(() => {
53200
53081
  const timer = setTimeout(() => {
53201
53082
  setDebouncedQuery(query);
53202
53083
  }, 300);
@@ -53204,7 +53085,7 @@ function SearchModal({
53204
53085
  }, [query]);
53205
53086
  const searchData = { resources: [], entities: [] };
53206
53087
  const loading = false;
53207
- useEffect42(() => {
53088
+ useEffect40(() => {
53208
53089
  if (isOpen) {
53209
53090
  setQuery("");
53210
53091
  setDebouncedQuery("");
@@ -53212,7 +53093,7 @@ function SearchModal({
53212
53093
  setSelectedIndex(0);
53213
53094
  }
53214
53095
  }, [isOpen]);
53215
- useEffect42(() => {
53096
+ useEffect40(() => {
53216
53097
  if (!debouncedQuery.trim()) {
53217
53098
  setResults([]);
53218
53099
  return;
@@ -53343,7 +53224,7 @@ function SearchModal({
53343
53224
  }
53344
53225
 
53345
53226
  // src/components/modals/ResourceSearchModal.tsx
53346
- import { useState as useState33, useEffect as useEffect43, Fragment as Fragment14 } from "react";
53227
+ import { useState as useState32, useEffect as useEffect41, Fragment as Fragment14 } from "react";
53347
53228
  import { jsx as jsx52, jsxs as jsxs42 } from "react/jsx-runtime";
53348
53229
  function ResourceSearchModal({
53349
53230
  isOpen,
@@ -53353,8 +53234,8 @@ function ResourceSearchModal({
53353
53234
  translations = {}
53354
53235
  }) {
53355
53236
  const { announceSearchResults, announceSearching, announceNavigation } = useSearchAnnouncements2();
53356
- const [search2, setSearch] = useState33(searchTerm);
53357
- const [debouncedSearch, setDebouncedSearch] = useState33(searchTerm);
53237
+ const [search2, setSearch] = useState32(searchTerm);
53238
+ const [debouncedSearch, setDebouncedSearch] = useState32(searchTerm);
53358
53239
  const t12 = {
53359
53240
  title: translations.title || "Search Resources",
53360
53241
  placeholder: translations.placeholder || "Search for resources...",
@@ -53362,7 +53243,7 @@ function ResourceSearchModal({
53362
53243
  noResults: translations.noResults || "No documents found",
53363
53244
  close: translations.close || "\u2715"
53364
53245
  };
53365
- useEffect43(() => {
53246
+ useEffect41(() => {
53366
53247
  const timer = setTimeout(() => {
53367
53248
  setDebouncedSearch(search2);
53368
53249
  }, 300);
@@ -53384,17 +53265,17 @@ function ResourceSearchModal({
53384
53265
  mediaType
53385
53266
  };
53386
53267
  }) || [];
53387
- useEffect43(() => {
53268
+ useEffect41(() => {
53388
53269
  if (!loading && debouncedSearch) {
53389
53270
  announceSearchResults(results.length, debouncedSearch);
53390
53271
  }
53391
53272
  }, [loading, results.length, debouncedSearch]);
53392
- useEffect43(() => {
53273
+ useEffect41(() => {
53393
53274
  if (loading && debouncedSearch) {
53394
53275
  announceSearching();
53395
53276
  }
53396
53277
  }, [loading, debouncedSearch]);
53397
- useEffect43(() => {
53278
+ useEffect41(() => {
53398
53279
  if (isOpen && searchTerm) {
53399
53280
  setSearch(searchTerm);
53400
53281
  setDebouncedSearch(searchTerm);
@@ -53598,11 +53479,11 @@ function SessionTimer() {
53598
53479
  }
53599
53480
 
53600
53481
  // src/components/SessionExpiryBanner.tsx
53601
- import { useState as useState34 } from "react";
53482
+ import { useState as useState33 } from "react";
53602
53483
  import { jsx as jsx55, jsxs as jsxs46 } from "react/jsx-runtime";
53603
53484
  function SessionExpiryBanner() {
53604
53485
  const { timeRemaining, isExpiringSoon } = useSessionExpiry();
53605
- const [dismissed, setDismissed] = useState34(false);
53486
+ const [dismissed, setDismissed] = useState33(false);
53606
53487
  const formattedTime = formatTime(timeRemaining);
53607
53488
  if (!isExpiringSoon || dismissed || !formattedTime) {
53608
53489
  return null;
@@ -53823,7 +53704,7 @@ function UnifiedHeader({
53823
53704
  }
53824
53705
 
53825
53706
  // src/components/layout/LeftSidebar.tsx
53826
- import { useState as useState35, useEffect as useEffect44 } from "react";
53707
+ import { useState as useState34, useEffect as useEffect42 } from "react";
53827
53708
  import { jsx as jsx59, jsxs as jsxs49 } from "react/jsx-runtime";
53828
53709
  function LeftSidebar({
53829
53710
  Link,
@@ -53838,7 +53719,7 @@ function LeftSidebar({
53838
53719
  isModerator = false,
53839
53720
  currentPath
53840
53721
  }) {
53841
- const [isCollapsed, setIsCollapsed] = useState35(false);
53722
+ const [isCollapsed, setIsCollapsed] = useState34(false);
53842
53723
  const { width, setWidth, minWidth, maxWidth } = usePanelWidth({
53843
53724
  defaultWidth: 256,
53844
53725
  // 16rem
@@ -53848,7 +53729,7 @@ function LeftSidebar({
53848
53729
  // 25rem
53849
53730
  storageKey: "semiont-left-sidebar-width"
53850
53731
  });
53851
- useEffect44(() => {
53732
+ useEffect42(() => {
53852
53733
  if (collapsible) {
53853
53734
  const saved = localStorage.getItem(storageKey);
53854
53735
  if (saved === "true") {
@@ -55062,7 +54943,7 @@ function AdminSecurityPage({
55062
54943
  }
55063
54944
 
55064
54945
  // src/features/admin-users/components/AdminUsersPage.tsx
55065
- import { useState as useState36 } from "react";
54946
+ import { useState as useState35 } from "react";
55066
54947
  import { Fragment as Fragment15, jsx as jsx68, jsxs as jsxs56 } from "react/jsx-runtime";
55067
54948
  function UserTableRow({
55068
54949
  user,
@@ -55144,9 +55025,9 @@ function AdminUsersPage({
55144
55025
  Toolbar: Toolbar2,
55145
55026
  buttonStyles: buttonStyles2
55146
55027
  }) {
55147
- const [searchTerm, setSearchTerm] = useState36("");
55148
- const [selectedRole, setSelectedRole] = useState36("all");
55149
- const [selectedStatus, setSelectedStatus] = useState36("all");
55028
+ const [searchTerm, setSearchTerm] = useState35("");
55029
+ const [selectedRole, setSelectedRole] = useState35("all");
55030
+ const [selectedStatus, setSelectedStatus] = useState35("all");
55150
55031
  const filteredUsers = users.filter((user) => {
55151
55032
  const matchesSearch = (user.name || "").toLowerCase().includes(searchTerm.toLowerCase()) || user.email.toLowerCase().includes(searchTerm.toLowerCase());
55152
55033
  const userRole = user.isAdmin ? "admin" : "user";
@@ -55461,7 +55342,7 @@ function SignInForm({
55461
55342
  }
55462
55343
 
55463
55344
  // src/features/auth/components/SignUpForm.tsx
55464
- import { useState as useState37 } from "react";
55345
+ import { useState as useState36 } from "react";
55465
55346
  import { jsx as jsx70, jsxs as jsxs58 } from "react/jsx-runtime";
55466
55347
  function GoogleIcon2() {
55467
55348
  return /* @__PURE__ */ jsxs58("svg", { className: "semiont-icon semiont-icon--small semiont-icon--inline", viewBox: "0 0 24 24", children: [
@@ -55496,7 +55377,7 @@ function GoogleIcon2() {
55496
55377
  ] });
55497
55378
  }
55498
55379
  function SignUpForm({ onSignUp, Link, translations: t12 }) {
55499
- const [isLoading, setIsLoading] = useState37(false);
55380
+ const [isLoading, setIsLoading] = useState36(false);
55500
55381
  const handleSignUp = async () => {
55501
55382
  setIsLoading(true);
55502
55383
  try {
@@ -55953,7 +55834,7 @@ function TagSchemasPage({
55953
55834
  }
55954
55835
 
55955
55836
  // src/features/resource-compose/components/ResourceComposePage.tsx
55956
- import { useState as useState38, useEffect as useEffect45 } from "react";
55837
+ import { useState as useState37, useEffect as useEffect43 } from "react";
55957
55838
  import { isImageMimeType, isPdfMimeType as isPdfMimeType4, LOCALES as LOCALES2 } from "@semiont/api-client";
55958
55839
  import { jsx as jsx76, jsxs as jsxs64 } from "react/jsx-runtime";
55959
55840
  function ResourceComposePage({
@@ -55972,19 +55853,19 @@ function ResourceComposePage({
55972
55853
  Toolbar: Toolbar2
55973
55854
  }) {
55974
55855
  const { announceFormSubmitting, announceFormSuccess, announceFormError } = useFormAnnouncements();
55975
- const [newResourceName, setNewResourceName] = useState38("");
55976
- const [newResourceContent, setNewResourceContent] = useState38("");
55977
- const [selectedEntityTypes, setSelectedEntityTypes] = useState38([]);
55978
- const [isCreating, setIsCreating] = useState38(false);
55979
- const [inputMethod, setInputMethod] = useState38("write");
55980
- const [uploadedFile, setUploadedFile] = useState38(null);
55981
- const [fileMimeType, setFileMimeType] = useState38("text/markdown");
55982
- const [filePreviewUrl, setFilePreviewUrl] = useState38(null);
55983
- const [selectedFormat, setSelectedFormat] = useState38("text/markdown");
55984
- const [selectedLanguage, setSelectedLanguage] = useState38(initialLocale);
55985
- const [selectedCharset, setSelectedCharset] = useState38("");
55986
- const [archiveOriginal, setArchiveOriginal] = useState38(true);
55987
- useEffect45(() => {
55856
+ const [newResourceName, setNewResourceName] = useState37("");
55857
+ const [newResourceContent, setNewResourceContent] = useState37("");
55858
+ const [selectedEntityTypes, setSelectedEntityTypes] = useState37([]);
55859
+ const [isCreating, setIsCreating] = useState37(false);
55860
+ const [inputMethod, setInputMethod] = useState37("write");
55861
+ const [uploadedFile, setUploadedFile] = useState37(null);
55862
+ const [fileMimeType, setFileMimeType] = useState37("text/markdown");
55863
+ const [filePreviewUrl, setFilePreviewUrl] = useState37(null);
55864
+ const [selectedFormat, setSelectedFormat] = useState37("text/markdown");
55865
+ const [selectedLanguage, setSelectedLanguage] = useState37(initialLocale);
55866
+ const [selectedCharset, setSelectedCharset] = useState37("");
55867
+ const [archiveOriginal, setArchiveOriginal] = useState37(true);
55868
+ useEffect43(() => {
55988
55869
  if (mode === "clone" && cloneData) {
55989
55870
  setNewResourceName(cloneData.sourceResource.name);
55990
55871
  setNewResourceContent(cloneData.sourceContent);
@@ -56017,7 +55898,7 @@ function ResourceComposePage({
56017
55898
  reader.readAsText(file);
56018
55899
  }
56019
55900
  };
56020
- useEffect45(() => {
55901
+ useEffect43(() => {
56021
55902
  return () => {
56022
55903
  if (filePreviewUrl) {
56023
55904
  URL.revokeObjectURL(filePreviewUrl);
@@ -56365,7 +56246,7 @@ function ResourceComposePage({
56365
56246
  }
56366
56247
 
56367
56248
  // src/features/resource-discovery/components/ResourceDiscoveryPage.tsx
56368
- import { useState as useState39, useCallback as useCallback31, useRef as useRef34 } from "react";
56249
+ import { useState as useState38, useCallback as useCallback30, useRef as useRef31 } from "react";
56369
56250
  import { getResourceId as getResourceId2 } from "@semiont/api-client";
56370
56251
 
56371
56252
  // src/features/resource-discovery/components/ResourceCard.tsx
@@ -56438,8 +56319,8 @@ function ResourceDiscoveryPage({
56438
56319
  translations: t12,
56439
56320
  ToolbarPanels
56440
56321
  }) {
56441
- const [searchQuery2, setSearchQuery] = useState39("");
56442
- const [selectedEntityType, setSelectedEntityType] = useState39("");
56322
+ const [searchQuery2, setSearchQuery] = useState38("");
56323
+ const [selectedEntityType, setSelectedEntityType] = useState38("");
56443
56324
  const hasSearchQuery = searchQuery2.trim() !== "";
56444
56325
  const hasSearchResults = searchDocuments.length > 0;
56445
56326
  const baseDocuments = hasSearchResults ? searchDocuments : recentDocuments;
@@ -56456,18 +56337,18 @@ function ResourceDiscoveryPage({
56456
56337
  { orientation: "grid", cols: 2 }
56457
56338
  // 2 columns on medium+ screens
56458
56339
  );
56459
- const onNavigateToResourceRef = useRef34(onNavigateToResource);
56340
+ const onNavigateToResourceRef = useRef31(onNavigateToResource);
56460
56341
  onNavigateToResourceRef.current = onNavigateToResource;
56461
- const handleEntityTypeFilter = useCallback31((entityType4) => {
56342
+ const handleEntityTypeFilter = useCallback30((entityType4) => {
56462
56343
  setSelectedEntityType(entityType4);
56463
56344
  }, []);
56464
- const openResource = useCallback31((resource) => {
56345
+ const openResource = useCallback30((resource) => {
56465
56346
  const resourceId = getResourceId2(resource);
56466
56347
  if (resourceId) {
56467
56348
  onNavigateToResourceRef.current(resourceId);
56468
56349
  }
56469
56350
  }, []);
56470
- const handleSearchSubmit = useCallback31((e6) => {
56351
+ const handleSearchSubmit = useCallback30((e6) => {
56471
56352
  e6.preventDefault();
56472
56353
  }, []);
56473
56354
  if (isLoadingRecent) {
@@ -56599,13 +56480,82 @@ function ResourceDiscoveryPage({
56599
56480
  }
56600
56481
 
56601
56482
  // src/features/resource-viewer/components/ResourceViewerPage.tsx
56602
- import { useState as useState44, useEffect as useEffect50, useCallback as useCallback35, useMemo as useMemo12 } from "react";
56483
+ import { useState as useState44, useEffect as useEffect49, useCallback as useCallback35, useMemo as useMemo12 } from "react";
56603
56484
  import { useQueryClient as useQueryClient2 } from "@tanstack/react-query";
56604
56485
  import { getLanguage, getPrimaryRepresentation, resourceAnnotationUri as resourceAnnotationUri3, getPrimaryMediaType as getPrimaryMediaType2 } from "@semiont/api-client";
56605
56486
  import { uriToAnnotationId as uriToAnnotationId2 } from "@semiont/core";
56606
56487
 
56488
+ // src/hooks/useResolutionFlow.ts
56489
+ import { useCallback as useCallback31, useEffect as useEffect44, useRef as useRef32, useState as useState39 } from "react";
56490
+ import { resourceAnnotationUri, accessToken as accessToken3 } from "@semiont/api-client";
56491
+ import { uriToAnnotationIdOrPassthrough } from "@semiont/core";
56492
+ function toAccessToken2(token) {
56493
+ return token ? accessToken3(token) : void 0;
56494
+ }
56495
+ function useResolutionFlow(rUri) {
56496
+ const eventBus = useEventBus();
56497
+ const client = useApiClient();
56498
+ const token = useAuthToken();
56499
+ const [searchModalOpen, setSearchModalOpen] = useState39(false);
56500
+ const [pendingReferenceId, setPendingReferenceId] = useState39(null);
56501
+ const onCloseSearchModal = useCallback31(() => {
56502
+ setSearchModalOpen(false);
56503
+ }, []);
56504
+ const rUriRef = useRef32(rUri);
56505
+ useEffect44(() => {
56506
+ rUriRef.current = rUri;
56507
+ });
56508
+ const clientRef = useRef32(client);
56509
+ useEffect44(() => {
56510
+ clientRef.current = client;
56511
+ });
56512
+ const tokenRef = useRef32(token);
56513
+ useEffect44(() => {
56514
+ tokenRef.current = token;
56515
+ });
56516
+ useEffect44(() => {
56517
+ const handleAnnotationUpdateBody = async (event) => {
56518
+ try {
56519
+ const annotationIdSegment = uriToAnnotationIdOrPassthrough(event.annotationUri);
56520
+ const nestedUri = resourceAnnotationUri(`${rUriRef.current}/annotations/${annotationIdSegment}`);
56521
+ await clientRef.current.updateAnnotationBody(nestedUri, {
56522
+ resourceId: event.resourceId,
56523
+ operations: event.operations
56524
+ }, { auth: toAccessToken2(tokenRef.current) });
56525
+ eventBus.emit("annotation:body-updated", { annotationUri: event.annotationUri });
56526
+ } catch (error) {
56527
+ console.error("Failed to update annotation body:", error);
56528
+ eventBus.emit("annotation:body-update-failed", { error });
56529
+ }
56530
+ };
56531
+ const handleReferenceLink = (event) => {
56532
+ eventBus.emit("resolution:search-requested", {
56533
+ referenceId: event.annotationUri,
56534
+ searchTerm: event.searchTerm
56535
+ });
56536
+ };
56537
+ eventBus.on("annotation:update-body", handleAnnotationUpdateBody);
56538
+ eventBus.on("reference:link", handleReferenceLink);
56539
+ return () => {
56540
+ eventBus.off("annotation:update-body", handleAnnotationUpdateBody);
56541
+ eventBus.off("reference:link", handleReferenceLink);
56542
+ };
56543
+ }, [eventBus]);
56544
+ useEffect44(() => {
56545
+ const handleResolutionSearchRequested = (event) => {
56546
+ setPendingReferenceId(event.referenceId);
56547
+ setSearchModalOpen(true);
56548
+ };
56549
+ eventBus.on("resolution:search-requested", handleResolutionSearchRequested);
56550
+ return () => {
56551
+ eventBus.off("resolution:search-requested", handleResolutionSearchRequested);
56552
+ };
56553
+ }, [eventBus]);
56554
+ return { searchModalOpen, pendingReferenceId, onCloseSearchModal };
56555
+ }
56556
+
56607
56557
  // src/hooks/useDetectionFlow.ts
56608
- import { useState as useState40, useRef as useRef35, useEffect as useEffect46, useCallback as useCallback32 } from "react";
56558
+ import { useState as useState40, useRef as useRef33, useEffect as useEffect45, useCallback as useCallback32 } from "react";
56609
56559
  import { resourceAnnotationUri as resourceAnnotationUri2, accessToken as accessToken4, entityType as entityType3 } from "@semiont/api-client";
56610
56560
  import { uriToAnnotationIdOrPassthrough as uriToAnnotationIdOrPassthrough2 } from "@semiont/core";
56611
56561
  function toAccessToken3(token) {
@@ -56615,20 +56565,19 @@ function useDetectionFlow(rUri) {
56615
56565
  const eventBus = useEventBus();
56616
56566
  const client = useApiClient();
56617
56567
  const token = useAuthToken();
56618
- const clientRef = useRef35(client);
56619
- const rUriRef = useRef35(rUri);
56620
- const tokenRef = useRef35(token);
56621
- useEffect46(() => {
56568
+ const clientRef = useRef33(client);
56569
+ const rUriRef = useRef33(rUri);
56570
+ const tokenRef = useRef33(token);
56571
+ useEffect45(() => {
56622
56572
  clientRef.current = client;
56623
56573
  });
56624
- useEffect46(() => {
56574
+ useEffect45(() => {
56625
56575
  rUriRef.current = rUri;
56626
56576
  });
56627
- useEffect46(() => {
56577
+ useEffect45(() => {
56628
56578
  tokenRef.current = token;
56629
56579
  });
56630
56580
  const [pendingAnnotation, setPendingAnnotation] = useState40(null);
56631
- const [hoveredAnnotationId, setHoveredAnnotationId] = useState40(null);
56632
56581
  const handleAnnotationRequested = useCallback32((pending) => {
56633
56582
  const MOTIVATION_TO_TAB = {
56634
56583
  highlighting: "annotations",
@@ -56695,19 +56644,10 @@ function useDetectionFlow(rUri) {
56695
56644
  const handleAnnotationCancelPending = useCallback32(() => {
56696
56645
  setPendingAnnotation(null);
56697
56646
  }, []);
56698
- const handleAnnotationHover = useCallback32(({ annotationId }) => {
56699
- setHoveredAnnotationId(annotationId);
56700
- if (annotationId) {
56701
- eventBus.emit("annotation:sparkle", { annotationId });
56702
- }
56703
- }, []);
56704
- const handleAnnotationClick = useCallback32(({ annotationId }) => {
56705
- eventBus.emit("annotation:focus", { annotationId });
56706
- }, []);
56707
56647
  const [detectingMotivation, setDetectingMotivation] = useState40(null);
56708
56648
  const [detectionProgress, setDetectionProgress] = useState40(null);
56709
- const detectionStreamRef = useRef35(null);
56710
- const progressDismissTimeoutRef = useRef35(null);
56649
+ const detectionStreamRef = useRef33(null);
56650
+ const progressDismissTimeoutRef = useRef33(null);
56711
56651
  const handleDetectionProgress = useCallback32((chunk) => {
56712
56652
  setDetectionProgress(chunk);
56713
56653
  }, []);
@@ -56741,7 +56681,7 @@ function useDetectionFlow(rUri) {
56741
56681
  }
56742
56682
  setDetectionProgress(null);
56743
56683
  }, []);
56744
- useEffect46(() => {
56684
+ useEffect45(() => {
56745
56685
  const handleAnnotationCreate = async (event) => {
56746
56686
  const currentClient = clientRef.current;
56747
56687
  const currentRUri = rUriRef.current;
@@ -56756,6 +56696,7 @@ function useDetectionFlow(rUri) {
56756
56696
  body: event.body
56757
56697
  }, { auth: toAccessToken3(tokenRef.current) });
56758
56698
  if (result.annotation) {
56699
+ setPendingAnnotation(null);
56759
56700
  eventBus.emit("annotation:created", { annotation: result.annotation });
56760
56701
  }
56761
56702
  } catch (error) {
@@ -56921,15 +56862,13 @@ function useDetectionFlow(rUri) {
56921
56862
  "selection:assessment-requested": handleAssessmentRequested,
56922
56863
  "selection:reference-requested": handleReferenceRequested,
56923
56864
  "annotation:cancel-pending": handleAnnotationCancelPending,
56924
- "annotation:hover": handleAnnotationHover,
56925
- "annotation:click": handleAnnotationClick,
56926
56865
  // AI detection state updates
56927
56866
  "detection:progress": handleDetectionProgress,
56928
56867
  "detection:complete": handleDetectionComplete,
56929
56868
  "detection:failed": handleDetectionFailed,
56930
56869
  "detection:dismiss-progress": handleDetectionDismissProgress
56931
56870
  });
56932
- useEffect46(() => {
56871
+ useEffect45(() => {
56933
56872
  return () => {
56934
56873
  if (progressDismissTimeoutRef.current) {
56935
56874
  clearTimeout(progressDismissTimeoutRef.current);
@@ -56938,7 +56877,6 @@ function useDetectionFlow(rUri) {
56938
56877
  }, []);
56939
56878
  return {
56940
56879
  pendingAnnotation,
56941
- hoveredAnnotationId,
56942
56880
  detectingMotivation,
56943
56881
  detectionProgress,
56944
56882
  detectionStreamRef
@@ -56946,7 +56884,7 @@ function useDetectionFlow(rUri) {
56946
56884
  }
56947
56885
 
56948
56886
  // src/hooks/usePanelNavigation.ts
56949
- import { useState as useState41, useCallback as useCallback33, useEffect as useEffect47 } from "react";
56887
+ import { useState as useState41, useCallback as useCallback33, useEffect as useEffect46 } from "react";
56950
56888
  function usePanelNavigation() {
56951
56889
  const [activePanel, setActivePanel] = useState41(() => {
56952
56890
  if (typeof window !== "undefined") {
@@ -56957,7 +56895,7 @@ function usePanelNavigation() {
56957
56895
  });
56958
56896
  const [scrollToAnnotationId, setScrollToAnnotationId] = useState41(null);
56959
56897
  const [panelInitialTab, setPanelInitialTab] = useState41(null);
56960
- useEffect47(() => {
56898
+ useEffect46(() => {
56961
56899
  if (typeof window === "undefined") return;
56962
56900
  if (activePanel) {
56963
56901
  localStorage.setItem("activeToolbarPanel", activePanel);
@@ -57005,7 +56943,7 @@ function usePanelNavigation() {
57005
56943
  }
57006
56944
 
57007
56945
  // src/hooks/useGenerationFlow.ts
57008
- import { useState as useState42, useCallback as useCallback34, useEffect as useEffect48, useRef as useRef36 } from "react";
56946
+ import { useState as useState42, useCallback as useCallback34, useEffect as useEffect47, useRef as useRef34 } from "react";
57009
56947
  import { annotationUri, accessToken as accessToken5 } from "@semiont/api-client";
57010
56948
  function toAccessToken4(token) {
57011
56949
  return token ? accessToken5(token) : void 0;
@@ -57014,15 +56952,15 @@ function useGenerationFlow(locale, resourceId, showSuccess, showError, cacheMana
57014
56952
  const eventBus = useEventBus();
57015
56953
  const client = useApiClient();
57016
56954
  const token = useAuthToken();
57017
- const clientRef = useRef36(client);
57018
- const tokenRef = useRef36(token);
57019
- useEffect48(() => {
56955
+ const clientRef = useRef34(client);
56956
+ const tokenRef = useRef34(token);
56957
+ useEffect47(() => {
57020
56958
  clientRef.current = client;
57021
56959
  });
57022
- useEffect48(() => {
56960
+ useEffect47(() => {
57023
56961
  tokenRef.current = token;
57024
56962
  });
57025
- const generationStreamRef = useRef36(null);
56963
+ const generationStreamRef = useRef34(null);
57026
56964
  const [isGenerating, setIsGenerating] = useState42(false);
57027
56965
  const [generationProgress, setGenerationProgress] = useState42(null);
57028
56966
  const handleProgressEvent = useCallback34((chunk) => {
@@ -57083,7 +57021,7 @@ function useGenerationFlow(locale, resourceId, showSuccess, showError, cacheMana
57083
57021
  setIsGenerating(false);
57084
57022
  showError(`Resource generation failed: ${error.message}`);
57085
57023
  }, [showError]);
57086
- useEffect48(() => {
57024
+ useEffect47(() => {
57087
57025
  const handleGenerationStart = async (event) => {
57088
57026
  console.log("[useGenerationFlow] handleGenerationStart called", { annotationUri: event.annotationUri, options: event.options });
57089
57027
  try {
@@ -57164,7 +57102,7 @@ function useGenerationFlow(locale, resourceId, showSuccess, showError, cacheMana
57164
57102
  }
57165
57103
 
57166
57104
  // src/hooks/useContextRetrievalFlow.ts
57167
- import { useState as useState43, useEffect as useEffect49, useRef as useRef37 } from "react";
57105
+ import { useState as useState43, useEffect as useEffect48, useRef as useRef35 } from "react";
57168
57106
  import { accessToken as accessToken6 } from "@semiont/api-client";
57169
57107
  function toAccessToken5(token) {
57170
57108
  return token ? accessToken6(token) : void 0;
@@ -57175,15 +57113,15 @@ function useContextRetrievalFlow(emitter, config) {
57175
57113
  const [retrievalLoading, setRetrievalLoading] = useState43(false);
57176
57114
  const [retrievalError, setRetrievalError] = useState43(null);
57177
57115
  const [retrievalAnnotationUri, setRetrievalAnnotationUri] = useState43(null);
57178
- const configRef = useRef37(config);
57179
- const tokenRef = useRef37(token);
57180
- useEffect49(() => {
57116
+ const configRef = useRef35(config);
57117
+ const tokenRef = useRef35(token);
57118
+ useEffect48(() => {
57181
57119
  configRef.current = config;
57182
57120
  });
57183
- useEffect49(() => {
57121
+ useEffect48(() => {
57184
57122
  tokenRef.current = token;
57185
57123
  });
57186
- useEffect49(() => {
57124
+ useEffect48(() => {
57187
57125
  const handleContextRetrievalRequested = async (event) => {
57188
57126
  setRetrievalLoading(true);
57189
57127
  setRetrievalError(null);
@@ -57258,9 +57196,10 @@ function ResourceViewerPage({
57258
57196
  const referencedBy = referencedByData?.referencedBy || [];
57259
57197
  const { data: entityTypesData } = entityTypesAPI.list.useQuery();
57260
57198
  const allEntityTypes = entityTypesData?.entityTypes || [];
57261
- const { detectingMotivation, detectionProgress, pendingAnnotation, hoveredAnnotationId } = useDetectionFlow(rUri);
57199
+ const { hoveredAnnotationId } = useAttentionFlow();
57200
+ const { detectingMotivation, detectionProgress, pendingAnnotation } = useDetectionFlow(rUri);
57262
57201
  const { activePanel, scrollToAnnotationId, panelInitialTab, onScrollCompleted } = usePanelNavigation();
57263
- const { searchModalOpen, pendingReferenceId, onCloseSearchModal } = useResolutionFlow(eventBus, { client, resourceUri: rUri });
57202
+ const { searchModalOpen, pendingReferenceId, onCloseSearchModal } = useResolutionFlow(rUri);
57264
57203
  const {
57265
57204
  generationProgress,
57266
57205
  generationModalOpen,
@@ -57277,7 +57216,7 @@ function ResourceViewerPage({
57277
57216
  },
57278
57217
  500
57279
57218
  );
57280
- useEffect50(() => {
57219
+ useEffect49(() => {
57281
57220
  if (resource && rUri) {
57282
57221
  const resourceIdSegment = rUri.split("/").pop() || "";
57283
57222
  const mediaType = getPrimaryMediaType2(resource);
@@ -57446,7 +57385,7 @@ function ResourceViewerPage({
57446
57385
  announceResourceLoading,
57447
57386
  announceResourceLoaded
57448
57387
  } = useResourceLoadingAnnouncements();
57449
- useEffect50(() => {
57388
+ useEffect49(() => {
57450
57389
  if (contentLoading) {
57451
57390
  announceResourceLoading(resource.name);
57452
57391
  } else if (content4) {
@@ -57684,6 +57623,7 @@ export {
57684
57623
  ErrorBoundary,
57685
57624
  EventBusProvider,
57686
57625
  Footer,
57626
+ HOVER_DELAY_MS,
57687
57627
  HighlightEntry,
57688
57628
  HighlightPanel,
57689
57629
  HistoryEvent,
@@ -57752,6 +57692,7 @@ export {
57752
57692
  buttonStyles,
57753
57693
  createCancelDetectionHandler,
57754
57694
  createDetectionHandler,
57695
+ createHoverHandlers,
57755
57696
  cssVariables,
57756
57697
  dispatch401Error,
57757
57698
  dispatch403Error,
@@ -57784,6 +57725,7 @@ export {
57784
57725
  useAnnotationManager,
57785
57726
  useAnnotations,
57786
57727
  useApiClient,
57728
+ useAttentionFlow,
57787
57729
  useAuthApi,
57788
57730
  useAuthToken,
57789
57731
  useCacheManager,
@@ -57801,6 +57743,7 @@ export {
57801
57743
  useFormAnnouncements,
57802
57744
  useGenerationFlow,
57803
57745
  useHealth,
57746
+ useHoverEmitter,
57804
57747
  useIsTyping,
57805
57748
  useKeyboardShortcuts,
57806
57749
  useLanguageChangeAnnouncements,