@semiont/react-ui 0.5.27 → 0.5.29

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 (192) hide show
  1. package/README.md +3 -3
  2. package/dist/{PdfAnnotationCanvas.client-EVUPTUWZ.js → PdfAnnotationCanvas.client-LSH3PZPY.js} +32 -5
  3. package/dist/{ar-OU3DQGC6.js → ar-AZBRADEB.js} +43 -23
  4. package/dist/{bn-PHWCR6AZ.js → bn-CCEW6AOS.js} +43 -23
  5. package/dist/{chunk-VXASXU4K.js → chunk-3ZBKCWUZ.js} +1 -1
  6. package/dist/{chunk-5VDTWRXJ.js → chunk-G4VHL4UA.js} +31 -31
  7. package/dist/{chunk-PCRRBU7H.js → chunk-SDKFZLEX.js} +43 -23
  8. package/dist/{cs-NEXYZ62I.js → cs-HXPF2CTE.js} +43 -23
  9. package/dist/{da-FAT43YCU.js → da-K5NTK7LH.js} +43 -23
  10. package/dist/{de-KRQ3WBCU.js → de-GMRQEDZI.js} +43 -23
  11. package/dist/{el-Q4IU3EKC.js → el-EUB4CI4G.js} +43 -23
  12. package/dist/{en-2KADE7N4.js → en-R5XA26NF.js} +2 -2
  13. package/dist/{es-2IO3R2MK.js → es-Z32DAZ6W.js} +43 -23
  14. package/dist/{fa-Q5GOQFXX.js → fa-G7HN6B32.js} +43 -23
  15. package/dist/{fi-R6NMRWBE.js → fi-3YBLZO7I.js} +43 -23
  16. package/dist/{fr-QY4D5E6J.js → fr-VUBH7BBS.js} +43 -23
  17. package/dist/{he-X6Y77XHY.js → he-WQQEY26B.js} +43 -23
  18. package/dist/{hi-XL7IOEQM.js → hi-HJZ6W4JB.js} +43 -23
  19. package/dist/{id-QZ4ZZS67.js → id-ZOGZ37MI.js} +43 -23
  20. package/dist/index.css +279 -74
  21. package/dist/index.d.ts +318 -393
  22. package/dist/index.js +2619 -2687
  23. package/dist/{it-ME2Q7OB6.js → it-DT6UW66F.js} +43 -23
  24. package/dist/{ja-HX7QASRI.js → ja-RUKQCOLO.js} +43 -23
  25. package/dist/{ko-EQO5AHAV.js → ko-ZH5ADKZM.js} +43 -23
  26. package/dist/{ms-UILFSF3I.js → ms-Y2AFPZTU.js} +43 -23
  27. package/dist/{nl-NNI45PMK.js → nl-OQEWIXNA.js} +43 -23
  28. package/dist/{no-MAL5F6P6.js → no-KPAYJZWY.js} +43 -23
  29. package/dist/{pl-4RMY6JAJ.js → pl-WSXK2UUD.js} +43 -23
  30. package/dist/{pt-VQH2X3QQ.js → pt-NWRJRUCK.js} +43 -23
  31. package/dist/{ro-XXCQO2OG.js → ro-3CGVMOC6.js} +43 -23
  32. package/dist/{sv-7Z6EJ6U4.js → sv-HGSEBA7S.js} +43 -23
  33. package/dist/test-utils.js +16 -7
  34. package/dist/{th-L3DXXYVQ.js → th-NZ4G352Z.js} +43 -23
  35. package/dist/{tr-P3DFVLFJ.js → tr-LGGS4DLW.js} +43 -23
  36. package/dist/{uk-7C5D3PXS.js → uk-AIX536L4.js} +43 -23
  37. package/dist/{vi-ZLTLEO7P.js → vi-V6CVQZLQ.js} +43 -23
  38. package/dist/{zh-5FHVWDIN.js → zh-AGKPGI3L.js} +43 -23
  39. package/package.json +16 -15
  40. package/src/components/AssistProgress.tsx +36 -2
  41. package/src/components/CodeMirrorRenderer.tsx +8 -8
  42. package/src/components/StatusDisplay.tsx +13 -13
  43. package/src/components/__tests__/AssistProgress.test.tsx +59 -0
  44. package/src/components/__tests__/StatusDisplay.test.tsx +9 -9
  45. package/src/components/modals/ComposeStep.tsx +233 -0
  46. package/src/components/modals/ConfigureGatherStep.tsx +10 -18
  47. package/src/components/modals/ConfigureGenerationStep.tsx +178 -34
  48. package/src/components/modals/ConfigureSearchStep.tsx +19 -0
  49. package/src/components/modals/ContextSummary.tsx +185 -72
  50. package/src/components/modals/CorpusPane.tsx +75 -0
  51. package/src/components/modals/DiscardPrompt.tsx +38 -0
  52. package/src/components/modals/GatherContextStep.tsx +237 -107
  53. package/src/components/modals/ReferenceWizardModal.tsx +252 -59
  54. package/src/components/modals/ResourceGenerateModal.tsx +225 -112
  55. package/src/components/modals/SearchModal.css +337 -101
  56. package/src/components/modals/SearchResultsStep.tsx +61 -68
  57. package/src/components/modals/WizardFooter.tsx +7 -1
  58. package/src/components/modals/__tests__/ComposeStep.test.tsx +152 -0
  59. package/src/components/modals/__tests__/ConfigureGatherStep.test.tsx +14 -26
  60. package/src/components/modals/__tests__/ConfigureGenerationStep.test.tsx +206 -8
  61. package/src/components/modals/__tests__/ConfigureSearchStep.test.tsx +24 -1
  62. package/src/components/modals/__tests__/GatherContextStep.resource.test.tsx +463 -25
  63. package/src/components/modals/__tests__/ReferenceWizardModal.test.tsx +442 -39
  64. package/src/components/modals/__tests__/ResourceGenerateModal.test.tsx +300 -86
  65. package/src/components/modals/__tests__/SearchResultsStep.test.tsx +61 -0
  66. package/src/components/modals/__tests__/WizardFooter.test.tsx +116 -9
  67. package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +34 -1
  68. package/src/components/pdf-annotation/__tests__/PdfAnnotationCanvas.test.tsx +38 -1
  69. package/src/components/resource/AnnotateView.tsx +3 -3
  70. package/src/components/resource/BrowseView.tsx +8 -8
  71. package/src/components/resource/DownloadFileLink.tsx +1 -1
  72. package/src/components/resource/ResourceViewer.tsx +4 -4
  73. package/src/components/resource/__tests__/AnnotateView.embeddable.test.tsx +1 -1
  74. package/src/components/resource/__tests__/BrowseView.embeddable.test.tsx +1 -1
  75. package/src/components/resource/__tests__/BrowseView.reference-hover.test.tsx +1 -1
  76. package/src/components/resource/__tests__/BrowseView.test.tsx +11 -11
  77. package/src/components/resource/__tests__/download-link.test.tsx +6 -6
  78. package/src/components/resource/annotate-renderers.tsx +3 -3
  79. package/src/components/resource/panels/AssistSection.css +35 -0
  80. package/src/components/resource/panels/ReferenceEntry.tsx +11 -4
  81. package/src/components/resource/panels/ReferencesPanel.tsx +9 -1
  82. package/src/components/resource/panels/ResourceInfoPanel.tsx +89 -20
  83. package/src/components/resource/panels/UnifiedAnnotationsPanel.tsx +7 -2
  84. package/src/components/resource/panels/__tests__/ReferenceEntry.test.tsx +41 -0
  85. package/src/components/resource/panels/__tests__/ReferencesPanel.observable-flow.test.tsx +1 -1
  86. package/src/components/resource/panels/__tests__/ReferencesPanel.test.tsx +84 -3
  87. package/src/components/resource/panels/__tests__/ResourceInfoPanel.test.tsx +149 -7
  88. package/src/features/auth/__tests__/SignInForm.a11y.test.tsx +12 -12
  89. package/src/features/auth/components/SignInForm.tsx +53 -53
  90. package/src/features/auth-welcome/state/__tests__/welcome-state-unit.test.ts +2 -2
  91. package/src/features/resource-compose/__tests__/ResourceComposePage.test.tsx +0 -65
  92. package/src/features/resource-compose/components/ResourceComposePage.tsx +35 -133
  93. package/src/features/resource-compose/state/__tests__/compose-page-state-unit.test.ts +1 -100
  94. package/src/features/resource-compose/state/compose-page-state-unit.ts +5 -57
  95. package/src/features/resource-discovery/__tests__/ResourceDiscoveryPage.test.tsx +1 -1
  96. package/src/features/resource-discovery/components/ResourceDiscoveryPage.tsx +2 -2
  97. package/src/features/resource-discovery/state/discover-state-unit.ts +1 -1
  98. package/src/features/resource-viewer/__tests__/ResourceViewerPage.test.tsx +73 -17
  99. package/src/features/resource-viewer/__tests__/generation-options.test.ts +53 -0
  100. package/src/features/resource-viewer/components/ResourceViewerPage.tsx +148 -83
  101. package/src/features/resource-viewer/generation-options.ts +29 -0
  102. package/src/styles/core/forms.css +35 -8
  103. package/src/styles/features/resource-viewer.css +0 -22
  104. package/src/styles/features/resource.css +0 -4
  105. package/src/styles/index.css +0 -1
  106. package/translations/ar.json +42 -22
  107. package/translations/bn.json +42 -22
  108. package/translations/cs.json +42 -22
  109. package/translations/da.json +42 -22
  110. package/translations/de.json +42 -22
  111. package/translations/el.json +42 -22
  112. package/translations/en.json +42 -22
  113. package/translations/es.json +42 -22
  114. package/translations/fa.json +42 -22
  115. package/translations/fi.json +42 -22
  116. package/translations/fr.json +42 -22
  117. package/translations/he.json +42 -22
  118. package/translations/hi.json +42 -22
  119. package/translations/id.json +42 -22
  120. package/translations/it.json +42 -22
  121. package/translations/ja.json +42 -22
  122. package/translations/ko.json +42 -22
  123. package/translations/ms.json +42 -22
  124. package/translations/nl.json +42 -22
  125. package/translations/no.json +42 -22
  126. package/translations/pl.json +42 -22
  127. package/translations/pt.json +42 -22
  128. package/translations/ro.json +42 -22
  129. package/translations/sv.json +42 -22
  130. package/translations/th.json +42 -22
  131. package/translations/tr.json +42 -22
  132. package/translations/uk.json +42 -22
  133. package/translations/vi.json +42 -22
  134. package/translations/zh.json +42 -22
  135. package/dist/PdfAnnotationCanvas.client-EVUPTUWZ.js.map +0 -1
  136. package/dist/PdfAnnotationCanvas.client-TGDPPGXJ.css.map +0 -1
  137. package/dist/ar-OU3DQGC6.js.map +0 -1
  138. package/dist/bn-PHWCR6AZ.js.map +0 -1
  139. package/dist/chunk-5VDTWRXJ.js.map +0 -1
  140. package/dist/chunk-BTUG3VJJ.js.map +0 -1
  141. package/dist/chunk-O23TLLXW.js.map +0 -1
  142. package/dist/chunk-PCRRBU7H.js.map +0 -1
  143. package/dist/chunk-QT7LYM72.js.map +0 -1
  144. package/dist/chunk-VXASXU4K.js.map +0 -1
  145. package/dist/cs-NEXYZ62I.js.map +0 -1
  146. package/dist/da-FAT43YCU.js.map +0 -1
  147. package/dist/de-KRQ3WBCU.js.map +0 -1
  148. package/dist/el-Q4IU3EKC.js.map +0 -1
  149. package/dist/en-2KADE7N4.js.map +0 -1
  150. package/dist/es-2IO3R2MK.js.map +0 -1
  151. package/dist/fa-Q5GOQFXX.js.map +0 -1
  152. package/dist/fi-R6NMRWBE.js.map +0 -1
  153. package/dist/fr-QY4D5E6J.js.map +0 -1
  154. package/dist/he-X6Y77XHY.js.map +0 -1
  155. package/dist/hi-XL7IOEQM.js.map +0 -1
  156. package/dist/id-QZ4ZZS67.js.map +0 -1
  157. package/dist/index.css.map +0 -1
  158. package/dist/index.js.map +0 -1
  159. package/dist/integrations/css-modules-helper.js.map +0 -1
  160. package/dist/integrations/styled-components-theme.js.map +0 -1
  161. package/dist/it-ME2Q7OB6.js.map +0 -1
  162. package/dist/ja-HX7QASRI.js.map +0 -1
  163. package/dist/ko-EQO5AHAV.js.map +0 -1
  164. package/dist/ms-UILFSF3I.js.map +0 -1
  165. package/dist/nl-NNI45PMK.js.map +0 -1
  166. package/dist/no-MAL5F6P6.js.map +0 -1
  167. package/dist/pl-4RMY6JAJ.js.map +0 -1
  168. package/dist/pt-VQH2X3QQ.js.map +0 -1
  169. package/dist/ro-XXCQO2OG.js.map +0 -1
  170. package/dist/sv-7Z6EJ6U4.js.map +0 -1
  171. package/dist/test-utils.css.map +0 -1
  172. package/dist/test-utils.js.map +0 -1
  173. package/dist/th-L3DXXYVQ.js.map +0 -1
  174. package/dist/tr-P3DFVLFJ.js.map +0 -1
  175. package/dist/uk-7C5D3PXS.js.map +0 -1
  176. package/dist/vi-ZLTLEO7P.js.map +0 -1
  177. package/dist/zh-5FHVWDIN.js.map +0 -1
  178. package/src/components/modals/ResourceSearchModal.tsx +0 -224
  179. package/src/components/modals/__tests__/ResourceSearchModal.test.tsx +0 -163
  180. package/src/features/admin-exchange/__tests__/AdminExchangePage.test.tsx +0 -137
  181. package/src/features/admin-exchange/__tests__/ExportCard.test.tsx +0 -41
  182. package/src/features/admin-exchange/__tests__/ImportCard.test.tsx +0 -148
  183. package/src/features/admin-exchange/__tests__/ImportProgress.test.tsx +0 -117
  184. package/src/features/admin-exchange/components/AdminExchangePage.tsx +0 -117
  185. package/src/features/admin-exchange/components/ExportCard.tsx +0 -35
  186. package/src/features/admin-exchange/components/ImportCard.tsx +0 -183
  187. package/src/features/admin-exchange/components/ImportProgress.tsx +0 -80
  188. package/src/features/admin-exchange/state/__tests__/exchange-state-unit.test.ts +0 -185
  189. package/src/features/admin-exchange/state/exchange-state-unit.ts +0 -133
  190. package/src/features/moderation-linked-data/__tests__/LinkedDataPage.test.tsx +0 -118
  191. package/src/features/moderation-linked-data/components/LinkedDataPage.tsx +0 -118
  192. package/src/styles/features/exchange.css +0 -374
@@ -10,6 +10,8 @@
10
10
  "codeCompleteCreated": "已创建 {{count}} 个{{kind}}",
11
11
  "codeGeneratingResource": "生成中…",
12
12
  "codeCreatingResource": "正在创建资源…",
13
+ "codeCompleteGenerated": "已创建资源",
14
+ "codeCompleteGeneratedTruncated": "已创建资源 — 在长度限制处被截断",
13
15
  "kindHighlight": "高亮",
14
16
  "kindComment": "评论",
15
17
  "kindAssessment": "评估",
@@ -244,6 +246,7 @@
244
246
  "noIncomingReferences": "无传入引用",
245
247
  "stub": "存根引用(未链接)",
246
248
  "resolved": "已解析引用(已链接)",
249
+ "derived": "派生",
247
250
  "open": "打开",
248
251
  "unlink": "取消链接",
249
252
  "resolve": "解析引用",
@@ -251,7 +254,6 @@
251
254
  "createReference": "创建引用",
252
255
  "entityTypesOptional": "实体类型(可选)",
253
256
  "fragmentSelected": "已选择片段",
254
- "imageRegionSelected": "已选择图像区域",
255
257
  "annotateReferences": "注释引用",
256
258
  "selectEntityTypes": "实体类型:",
257
259
  "select": "选择",
@@ -262,8 +264,6 @@
262
264
  "annotating": "正在注释...",
263
265
  "includeDescriptiveReferences": "包含描述性引用",
264
266
  "descriptiveReferencesTooltip": "同时查找诸如「首席执行官」、「科技巨头」、「物理学家」等短语(除名称外)",
265
- "annotationProgressTitle": "正在注释实体引用",
266
- "cancelAnnotation": "取消注释",
267
267
  "found": "找到 {{count}} 个",
268
268
  "complete": "注释完成!",
269
269
  "failed": "注释失败",
@@ -378,19 +378,14 @@
378
378
  },
379
379
  "AnnotateView": {},
380
380
  "ResourceGenerate": {
381
- "gatherTitle": "配置收集",
382
- "reviewTitle": "查看上下文",
383
- "configureTitle": "配置生成",
384
- "next": "下一步",
385
- "back": "返回",
386
- "cancel": "取消",
387
381
  "gatherIntro": "选择要包含在收集的上下文中的内容。",
388
382
  "includeContent": "包含资源内容",
389
383
  "includeSummary": "包含摘要",
390
384
  "gatherDepth": "深度",
391
385
  "gatherMaxResources": "最大资源数",
392
386
  "gatherButton": "收集",
393
- "excludeLabel": "从召回中排除",
387
+ "editGather": "更改收集设置",
388
+ "recallLabel": "已包含在召回中 — 取消选择以排除",
394
389
  "loadingContext": "正在收集上下文...",
395
390
  "failedContext": "收集上下文失败",
396
391
  "sourceContextLabel": "资源",
@@ -408,18 +403,24 @@
408
403
  "maxLength": "最大长度",
409
404
  "maxLengthHelp": "最大令牌数",
410
405
  "generate": "生成",
411
- "progressTitle": "正在生成资源",
412
- "progressCancel": "取消生成",
413
- "progressInProgress": "正在生成…",
414
- "progressComplete": "生成完成!",
415
- "progressFailed": "生成失败",
416
- "maxLengthCeiling": "受 {{model}} 限制为 {{maxOutputTokens}} 个词元。"
406
+ "maxLengthCeiling": "受 {{model}} 限制为 {{maxOutputTokens}} 个词元。",
407
+ "outputFormat": "格式",
408
+ "formatExtensionMismatch": "保存位置必须以 {{extension}} 结尾,以匹配所选格式。",
409
+ "graphPaneTitle": "周边",
410
+ "graphEmpty": "尚无链接。",
411
+ "resourceLinkLabel": "资源链接",
412
+ "corpusPaneTitle": "相似段落",
413
+ "corpusEmpty": "未找到相似段落。",
414
+ "excludedReceipt": "{{types}} 已从本次召回中排除",
415
+ "machineRead": "OCR",
416
+ "score": "评分",
417
+ "saveLocation": "保存位置",
418
+ "discardDraftPrompt": "放弃此草稿?",
419
+ "discardDraft": "放弃",
420
+ "keepEditing": "继续编辑",
421
+ "title": "从此资源生成"
417
422
  },
418
423
  "ReferenceWizard": {
419
- "gatherTitle": "已收集的上下文",
420
- "configureGenerationTitle": "配置生成",
421
- "configureSearchTitle": "配置搜索",
422
- "searchResultsTitle": "搜索结果",
423
424
  "sourceContextLabel": "资源中的注释上下文",
424
425
  "connectionsLabel": "对等注释",
425
426
  "citedByLabel": "资源被引用",
@@ -427,7 +428,6 @@
427
428
  "userHintPlaceholder": "描述此注释所指的内容...",
428
429
  "loadingContext": "正在收集上下文...",
429
430
  "failedContext": "收集上下文失败",
430
- "cancel": "取消",
431
431
  "generate": "生成",
432
432
  "compose": "编写",
433
433
  "resolutionStrategyLabel": "解析策略",
@@ -450,8 +450,28 @@
450
450
  "semanticScoring": "语义评分",
451
451
  "semanticScoringHelp": "使用 AI 按语义相关性对结果进行评分",
452
452
  "searching": "搜索中...",
453
+ "searchFailed": "搜索失败",
453
454
  "search": "搜索",
454
- "maxLengthCeiling": "受 {{model}} 限制为 {{maxOutputTokens}} 个词元。"
455
+ "maxLengthCeiling": "受 {{model}} 限制为 {{maxOutputTokens}} 个词元。",
456
+ "outputFormat": "格式",
457
+ "formatExtensionMismatch": "保存位置必须以 {{extension}} 结尾,以匹配所选格式。",
458
+ "graphPaneTitle": "周边",
459
+ "graphEmpty": "尚无链接 — 解析此引用将创建第一个。",
460
+ "resourceLinkLabel": "资源链接",
461
+ "corpusPaneTitle": "相似段落",
462
+ "corpusEmpty": "未找到相似段落 — 搜索不太可能有结果。",
463
+ "excludedReceipt": "{{types}} 已从本次召回中排除",
464
+ "machineRead": "OCR",
465
+ "userHintEffect": "引导搜索与生成",
466
+ "saveLocation": "保存位置",
467
+ "entityTypes": "实体类型",
468
+ "contentLabel": "内容",
469
+ "createAndLink": "创建并链接",
470
+ "creatingAndLinking": "正在创建并链接…",
471
+ "discardDraftPrompt": "放弃此草稿?",
472
+ "discardDraft": "放弃",
473
+ "keepEditing": "继续编辑",
474
+ "resolveTitle": "解析引用"
455
475
  },
456
476
  "OutcomeToasts": {
457
477
  "createFailed": "无法创建批注:{{detail}}",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/pdf-annotation/PdfAnnotationCanvas.tsx","../src/components/pdf-annotation/rects-for-page.ts","../src/components/pdf-annotation/estimate-slot-height.ts","../src/lib/pdf-coordinates.ts"],"sourcesContent":["'use client';\n\nimport React, { useRef, useState, useCallback, useEffect, useMemo } from 'react';\nimport type { Annotation, AnchorRect, AnchoredText } from '@semiont/core';\nimport { resourceId as toResourceId } from '@semiont/core';\nimport { toViewportAnchorRect } from '../../lib/anchor-rect';\nimport { createFragmentSelector, anchorRuns, isTextRun, textUnder } from '@semiont/core';\nimport { rectsForPage } from './rects-for-page';\nimport { estimateSlotHeight } from './estimate-slot-height';\nimport { useTranslations } from '../../contexts/TranslationContext';\nimport { createHoverHandlers, type SemiontSession } from '@semiont/sdk';\nimport type { SelectionMotivation } from '../annotation/AnnotateToolbar';\nimport {\n canvasToPdfCoordinates,\n pdfToCanvasCoordinates,\n type CanvasRectangle\n} from '../../lib/pdf-coordinates';\nimport {\n loadPdfDocument,\n renderPdfPageToDataUrl,\n type PDFDocumentProxy\n} from '../../lib/browser-pdfjs';\nimport './PdfAnnotationCanvas.css';\n\nexport type DrawingMode = 'rectangle' | 'circle' | 'polygon' | null;\n\n/**\n * How the document's pages are laid out.\n *\n * `paged` is one page with Previous/Next. `scroll` is a virtualized column:\n * every page gets a slot so the scrollbar tells the truth about the\n * document's length, but only the pages near the viewport are mounted.\n *\n * Declared explicitly rather than inferred from `drawingMode`, which does NOT\n * distinguish the modes — AnnotateView passes `drawingMode={null}` whenever no\n * motivation is selected, so keying layout on it would flip a reader between\n * scrolling and paged views as they picked up and put down a tool.\n * See .plans/PDF-CONTINUOUS-SCROLL.md D3.\n */\nexport type PageLayout = 'paged' | 'scroll';\n\n/** How far outside the viewport a page starts loading, and stays loaded. */\nconst PRELOAD_MARGIN = '100% 0px';\n\n/** Width of one page rectangle in the strip, in CSS px. Height follows the\n * document's own aspect ratio, so the strip looks like the document — wide\n * enough to carry a three-digit page number, which is what makes the strip\n * useful rather than merely positional on a long document. */\nconst STRIP_PAGE_WIDTH = 30;\n\n/**\n * The axis pages advance along.\n *\n * ONE source for two consumers: the column scrolls along it, and the page\n * strip runs parallel to it. A strip that ran across the scroll direction\n * would read as a control for a movement the document does not make.\n *\n * Constant today because scrolling is vertical. The horizontal-scrolling\n * setting turns this into a value read from preferences — both consumers\n * follow automatically, which is the point of routing them through one name.\n */\nconst SCROLL_AXIS: 'vertical' | 'horizontal' = 'vertical';\n\n/**\n * Scroll an element into view where the environment supports it.\n *\n * Same posture as this file's guarded observers: jsdom implements no layout\n * and therefore no `scrollIntoView`, and a viewer that throws in a test\n * harness (or an exotic embedding host) is worse than one that simply does\n * not scroll.\n */\nfunction scrollElementIntoView(el: Element | null | undefined, options: ScrollIntoViewOptions): void {\n if (typeof el?.scrollIntoView === 'function') el.scrollIntoView(options);\n}\n\n/**\n * Get color for annotation based on motivation\n */\nfunction getMotivationColor(motivation: SelectionMotivation | null): { stroke: string; fill: string } {\n if (!motivation) {\n return { stroke: 'rgb(156, 163, 175)', fill: 'rgba(156, 163, 175, 0.2)' };\n }\n\n switch (motivation) {\n case 'highlighting':\n return { stroke: 'rgb(250, 204, 21)', fill: 'rgba(250, 204, 21, 0.3)' };\n case 'linking':\n return { stroke: 'rgb(59, 130, 246)', fill: 'rgba(59, 130, 246, 0.2)' };\n case 'assessing':\n return { stroke: 'rgb(239, 68, 68)', fill: 'rgba(239, 68, 68, 0.2)' };\n case 'commenting':\n return { stroke: 'rgb(255, 255, 255)', fill: 'rgba(255, 255, 255, 0.2)' };\n default:\n return { stroke: 'rgb(156, 163, 175)', fill: 'rgba(156, 163, 175, 0.2)' };\n }\n}\n\ninterface PdfPageViewProps {\n doc: PDFDocumentProxy;\n pageNumber: number;\n /** Raster scale. Display-only: the overlay's geometry never reads it. */\n scale: number;\n resourceUri: string;\n existingAnnotations: Annotation[];\n drawingMode: DrawingMode;\n selectedMotivation?: SelectionMotivation | null;\n session?: SemiontSession | null | undefined;\n hoveredAnnotationId?: string | null;\n selectedAnnotationId?: string | null;\n hoverDelayMs: number;\n /** The document-wide server map, fetched once per resource by the parent. */\n fetchResourceAnchored: () => Promise<AnchoredText | null>;\n}\n\n/**\n * One rendered page: its raster, its text map, its annotation overlay, and\n * the drag that draws on it.\n *\n * Everything a page needs lives HERE rather than in the parent, which is what\n * makes a scrolling column possible: mounting a page loads it, and unmounting\n * releases it. The raster is a data-URL string, so the last reference going\n * away IS the memory release — no eviction bookkeeping, no object-URL revoke.\n * The drag lives here too because it needs this page's display dimensions and\n * this page's text; a drag can no more span pages than a rectangle can.\n */\nfunction PdfPageView({\n doc,\n pageNumber,\n scale,\n resourceUri,\n existingAnnotations,\n drawingMode,\n selectedMotivation,\n session,\n hoveredAnnotationId,\n selectedAnnotationId,\n hoverDelayMs,\n fetchResourceAnchored,\n}: PdfPageViewProps) {\n const [pageImageUrl, setPageImageUrl] = useState<string | null>(null);\n const [pageDimensions, setPageDimensions] = useState<{ width: number; height: number } | null>(null);\n /**\n * This page's text and per-run geometry, read once when the page loads so a\n * drag can be quoted without a round trip. Null while loading; `items` is\n * empty on a scanned page, which has no text layer for the browser to read.\n */\n const [pageAnchored, setPageAnchored] = useState<AnchoredText | null>(null);\n const [displayDimensions, setDisplayDimensions] = useState<{ width: number; height: number } | null>(null);\n /** Translation KEY, not text: `t` is a new closure each render, so keeping\n * it out of the load effect's deps is what stops a reload loop. */\n const [errorKey, setErrorKey] = useState<string | null>(null);\n const t = useTranslations('PdfViewer');\n\n const [isDrawing, setIsDrawing] = useState(false);\n const [selection, setSelection] = useState<CanvasRectangle | null>(null);\n\n const imageRef = useRef<HTMLImageElement>(null);\n\n useEffect(() => {\n let cancelled = false;\n\n /**\n * The map a rectangle on this page quotes from, or null when there is\n * none to be had.\n *\n * Never rejects, which is what lets the render run alongside it: quoting\n * is the optional half of loading a page, so a failure here degrades to\n * geometry-only rather than reaching the caller's error path. It is also\n * the only reason `Promise.all` below is safe — a rejection from either\n * side would leave the other promise dangling, and only the render can\n * reject.\n */\n async function resolveAnchored(page: Awaited<ReturnType<typeof doc.getPage>>): Promise<AnchoredText | null> {\n try {\n // The page's text layer, read once here rather than at drag time —\n // `handleMouseUp` stays synchronous, and a native page costs nothing\n // extra since pdf.js already parsed it to draw the page.\n const runs = (await page.getTextContent()).items.filter(isTextRun);\n if (runs.length > 0) return anchorRuns(runs, pageNumber);\n\n // No runs means a scanned page: the characters exist only as pixels\n // and pdf.js has nothing to give. The server derived a map at ingest,\n // so ask for it rather than leaving the annotation anonymous.\n // Whole-resource — served once per document by the parent's cache —\n // and `textUnder` filters by page: the same shape the native branch\n // produces, so nothing downstream branches.\n //\n // `null` is the ordinary answer for a document that has no map and\n // never will; a failure is equally non-fatal. Either way the\n // annotation ships with geometry only, which is what shipped before\n // this existed. The served record is the full extraction outcome\n // (PERSIST-ANCHORS D1); a stored decline means extraction ran and\n // found nothing to anchor — for this canvas the same degradation as\n // no map at all.\n return await fetchResourceAnchored();\n } catch {\n return null;\n }\n }\n\n async function loadPage() {\n try {\n const page = await doc.getPage(pageNumber);\n if (cancelled) return;\n\n // Get page dimensions (at scale 1.0)\n const viewport = page.getViewport({ scale: 1.0 });\n setPageDimensions({ width: viewport.width, height: viewport.height });\n\n // Anchoring and rendering are independent, and only one of them the\n // reader is waiting on. Sequencing them put a network round-trip in\n // front of the pixels on exactly the documents that need it most: a\n // scanned page fetches its map from the server, and rendering behind\n // that await is how \"failing to quote it must not fail to show it\"\n // became true of errors but not of latency. Started together, the\n // page appears on its own schedule.\n const [anchored, { dataUrl }] = await Promise.all([\n resolveAnchored(page),\n renderPdfPageToDataUrl(page, scale),\n ]);\n\n if (cancelled) return;\n\n setPageAnchored(anchored);\n setPageImageUrl(dataUrl);\n } catch (err) {\n if (cancelled) return;\n\n console.error('Error loading page:', err);\n setErrorKey('pageLoadFailed');\n }\n }\n\n loadPage();\n\n return () => {\n cancelled = true;\n };\n }, [doc, pageNumber, scale, fetchResourceAnchored]);\n\n // Update display dimensions on resize\n useEffect(() => {\n const updateDisplayDimensions = () => {\n if (imageRef.current) {\n setDisplayDimensions({\n width: imageRef.current.clientWidth,\n height: imageRef.current.clientHeight\n });\n }\n };\n\n updateDisplayDimensions();\n\n // Use ResizeObserver to detect image element size changes\n // This catches: sidebar open/close, window resize, font size changes, etc.\n let resizeObserver: ResizeObserver | null = null;\n\n try {\n resizeObserver = new ResizeObserver(updateDisplayDimensions);\n if (imageRef.current) {\n resizeObserver.observe(imageRef.current);\n }\n } catch (error) {\n // Fallback for browsers without ResizeObserver support\n console.warn('ResizeObserver not supported, falling back to window resize listener');\n window.addEventListener('resize', updateDisplayDimensions);\n }\n\n return () => {\n if (resizeObserver) {\n resizeObserver.disconnect();\n } else {\n window.removeEventListener('resize', updateDisplayDimensions);\n }\n };\n }, [pageImageUrl]);\n\n // Mouse event handlers for drawing\n const handleMouseDown = useCallback((e: React.MouseEvent) => {\n if (!drawingMode) return;\n if (!imageRef.current) return;\n\n const rect = imageRef.current.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n\n // Clear any previous selection when starting new drawing\n setIsDrawing(true);\n setSelection({\n startX: x,\n startY: y,\n endX: x,\n endY: y\n });\n }, [drawingMode]);\n\n const handleMouseMove = useCallback((e: React.MouseEvent) => {\n if (!isDrawing || !selection || !imageRef.current) return;\n\n const rect = imageRef.current.getBoundingClientRect();\n\n setSelection({\n ...selection,\n endX: e.clientX - rect.left,\n endY: e.clientY - rect.top\n });\n }, [isDrawing, selection]);\n\n const handleMouseUp = useCallback(() => {\n if (!isDrawing || !selection || !pageDimensions || !displayDimensions || !session) {\n setIsDrawing(false);\n setSelection(null);\n return;\n }\n\n // Calculate drag distance\n const dragDistance = Math.sqrt(\n Math.pow(selection.endX - selection.startX, 2) +\n Math.pow(selection.endY - selection.startY, 2)\n );\n\n // Minimum drag threshold in pixels (10px)\n const MIN_DRAG_DISTANCE = 10;\n\n if (dragDistance < MIN_DRAG_DISTANCE) {\n // This was a click, not a drag - check if we clicked an existing annotation\n if (existingAnnotations.length > 0) {\n // The hit-test owns the coordinate transform — capture the hit\n // annotation's viewport rect for the emission below (A1 anchor).\n let hitRect: AnchorRect | undefined;\n const hit = rectsForPage(existingAnnotations, pageNumber).find(r => {\n const rect = pdfToCanvasCoordinates(r.coord, pageDimensions.height, 1.0);\n\n // Scale to display coordinates\n const scaleX = displayDimensions.width / pageDimensions.width;\n const scaleY = displayDimensions.height / pageDimensions.height;\n\n const displayX = rect.x * scaleX;\n const displayY = rect.y * scaleY;\n const displayWidth = rect.width * scaleX;\n const displayHeight = rect.height * scaleY;\n\n const inside = (\n selection.endX >= displayX &&\n selection.endX <= displayX + displayWidth &&\n selection.endY >= displayY &&\n selection.endY <= displayY + displayHeight\n );\n if (inside && imageRef.current) {\n hitRect = toViewportAnchorRect(imageRef.current.getBoundingClientRect(), displayX, displayY, displayWidth, displayHeight);\n }\n return inside;\n });\n\n if (hit) {\n session?.client.browse.click(hit.annId, hitRect);\n setIsDrawing(false);\n setSelection(null);\n return;\n }\n }\n\n // Click on empty space - do nothing\n setIsDrawing(false);\n setSelection(null);\n return;\n }\n\n // This was a drag - create new annotation\n // Scale selection from display coordinates to native page coordinates\n const scaleX = pageDimensions.width / displayDimensions.width;\n const scaleY = pageDimensions.height / displayDimensions.height;\n\n const nativeSelection: CanvasRectangle = {\n startX: selection.startX * scaleX,\n startY: selection.startY * scaleY,\n endX: selection.endX * scaleX,\n endY: selection.endY * scaleY\n };\n\n // Convert canvas coordinates to PDF coordinates\n const pdfCoord = canvasToPdfCoordinates(\n nativeSelection,\n pageNumber,\n pageDimensions.width,\n pageDimensions.height,\n 1.0 // Use scale 1.0 since we already scaled to native coords\n );\n\n // Create FragmentSelector\n const fragmentSelector = createFragmentSelector(pdfCoord);\n\n // What the box was drawn around. Without it the annotation is a rectangle\n // with no memory of its own content: the panel entry is blank, search over\n // annotation text misses it, and an export has nothing to print. Empty on a\n // scanned page or over an image — emit no quote at all rather than an empty\n // one, which would assert the box was drawn around nothing.\n const quoted = pageAnchored ? textUnder(pageAnchored, pdfCoord) : '';\n\n // Emit annotation:requested event with FragmentSelector\n if (selectedMotivation) {\n session.client.mark.request(\n toResourceId(resourceUri),\n [\n {\n type: 'FragmentSelector',\n conformsTo: 'http://tools.ietf.org/rfc/rfc3778',\n value: fragmentSelector,\n },\n ...(quoted ? [{ type: 'TextQuoteSelector' as const, exact: quoted }] : []),\n ],\n selectedMotivation,\n );\n }\n\n // Keep drawing state active to show preview until annotation is persisted\n // The parent component should clear this by changing drawingMode after save\n setIsDrawing(false);\n // Note: We keep selection so the preview remains visible\n // It will be cleared when drawingMode changes or user starts new selection\n }, [isDrawing, selection, pageNumber, pageDimensions, displayDimensions, selectedMotivation, existingAnnotations, session, resourceUri, pageAnchored]);\n\n // Every FragmentSelector rect on this page — one per line for a multi-line\n // (multi-selector) annotation, exactly one for a manual annotation.\n const pageRects = rectsForPage(existingAnnotations, pageNumber);\n\n // Hover handlers with currentHover guard and dwell delay\n const { handleMouseEnter, handleMouseLeave } = useMemo(\n () => createHoverHandlers((id) => session?.client.beckon.hover(id), hoverDelayMs),\n [session, hoverDelayMs]\n );\n\n // Calculate motivation color\n const { stroke, fill } = getMotivationColor(selectedMotivation ?? null);\n\n if (errorKey) {\n return <div className=\"semiont-pdf-annotation-canvas__error\">{t(errorKey)}</div>;\n }\n\n return (\n <div\n className=\"semiont-pdf-annotation-canvas__container\"\n onMouseDown={handleMouseDown}\n onMouseMove={handleMouseMove}\n onMouseUp={handleMouseUp}\n onMouseLeave={() => {\n if (isDrawing) {\n setIsDrawing(false);\n setSelection(null);\n }\n }}\n data-drawing-mode={drawingMode || 'none'}\n >\n {/* PDF page rendered as image */}\n {pageImageUrl && (\n <img\n ref={imageRef}\n src={pageImageUrl}\n alt={`PDF page ${pageNumber}`}\n className=\"semiont-pdf-annotation-canvas__image\"\n draggable={false}\n style={{ pointerEvents: 'none' }}\n onLoad={() => {\n // Use double RAF to ensure layout is complete even in onLoad\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n if (imageRef.current) {\n setDisplayDimensions({\n width: imageRef.current.clientWidth,\n height: imageRef.current.clientHeight\n });\n }\n });\n });\n }}\n />\n )}\n\n {/* SVG overlay for annotations */}\n {displayDimensions && pageDimensions && (\n <div className=\"semiont-pdf-annotation-canvas__overlay-container\">\n <div className=\"semiont-pdf-annotation-canvas__overlay\">\n <svg\n className=\"semiont-pdf-annotation-canvas__svg\"\n width={displayDimensions.width}\n height={displayDimensions.height}\n >\n {/* Render existing annotations for this page */}\n {pageRects.map(r => {\n const rect = pdfToCanvasCoordinates(r.coord, pageDimensions.height, 1.0);\n\n // Scale to display coordinates\n const scaleX = displayDimensions.width / pageDimensions.width;\n const scaleY = displayDimensions.height / pageDimensions.height;\n\n const isHovered = r.annId === hoveredAnnotationId;\n const isSelected = r.annId === selectedAnnotationId;\n\n // Colour by the annotation's own motivation (not the toolbar's).\n const annMotivation = r.annotation.motivation as SelectionMotivation | null;\n const { stroke: annStroke, fill: annFill } = getMotivationColor(annMotivation);\n\n return (\n <rect\n key={`${r.annId}:${r.selectorIndex}`}\n x={rect.x * scaleX}\n y={rect.y * scaleY}\n width={rect.width * scaleX}\n height={rect.height * scaleY}\n stroke={annStroke}\n strokeWidth={isSelected ? 4 : isHovered ? 3 : 2}\n fill={annFill}\n style={{\n pointerEvents: 'auto',\n cursor: 'pointer',\n opacity: isSelected ? 1 : isHovered ? 0.9 : 0.7\n }}\n onClick={(e) => session?.client.browse.click(r.annId, e.currentTarget.getBoundingClientRect())}\n onMouseEnter={() => handleMouseEnter(r.annId)}\n onMouseLeave={handleMouseLeave}\n />\n );\n })}\n\n {/* Render current selection while drawing or awaiting save */}\n {selection && (() => {\n const rectX = Math.min(selection.startX, selection.endX);\n const rectY = Math.min(selection.startY, selection.endY);\n const rectWidth = Math.abs(selection.endX - selection.startX);\n const rectHeight = Math.abs(selection.endY - selection.startY);\n\n // PDF only supports rectangle shapes (FragmentSelector with viewrect)\n // Circle/polygon are disabled in the UI for PDF media types\n return (\n <rect\n x={rectX}\n y={rectY}\n width={rectWidth}\n height={rectHeight}\n stroke={stroke}\n strokeWidth={2}\n strokeDasharray=\"5,5\"\n fill={fill}\n pointerEvents=\"none\"\n />\n );\n })()}\n </svg>\n </div>\n </div>\n )}\n </div>\n );\n}\n\ninterface PdfAnnotationCanvasProps {\n pdfUrl: string;\n /** The '@id' of the annotated resource — stamped as `source` on mark:requested (multi-viewer routing). */\n resourceUri: string;\n existingAnnotations?: Annotation[];\n drawingMode: DrawingMode;\n selectedMotivation?: SelectionMotivation | null;\n session?: SemiontSession | null | undefined;\n hoveredAnnotationId?: string | null;\n selectedAnnotationId?: string | null;\n hoverDelayMs?: number;\n /** `paged` (default) or the virtualized `scroll` column. See `PageLayout`. */\n pageLayout?: PageLayout;\n}\n\n/**\n * PDF annotation canvas with page navigation and rectangle drawing\n *\n * @emits browse:click - Annotation clicked on PDF. Payload: { annotationId: string, motivation: Motivation }\n * @emits mark:requested - New annotation drawn on PDF. Payload: { selector: [FragmentSelector, TextQuoteSelector?], motivation: SelectionMotivation } — the quote is the text under the rectangle, omitted when the page has no text layer\n * @emits beckon:hover - Annotation hovered or unhovered. Payload: { annotationId: string | null }\n */\nexport function PdfAnnotationCanvas({\n pdfUrl,\n resourceUri,\n existingAnnotations = [],\n drawingMode,\n selectedMotivation,\n session,\n hoveredAnnotationId,\n selectedAnnotationId,\n hoverDelayMs = 150,\n pageLayout = 'paged'\n}: PdfAnnotationCanvasProps) {\n // PDF state\n const [pdfDoc, setPdfDoc] = useState<PDFDocumentProxy | null>(null);\n const [numPages, setNumPages] = useState<number>(0);\n const [pageNumber, setPageNumber] = useState(1);\n const [isLoading, setIsLoading] = useState(true);\n const [errorKey, setErrorKey] = useState<string | null>(null);\n const t = useTranslations('PdfViewer');\n /**\n * Page 1's shape, for reserving space in slots that have not mounted yet:\n * its aspect ratio and its raster width. NOT its raster height — the image\n * renders under `max-width: 100%; height: auto`, so its displayed height\n * depends on the column's width, and reserving raster pixels made the\n * column's height lurch on every mount (S1b).\n * See .plans/PDF-CONTINUOUS-SCROLL.md D4 + S1b.\n */\n const [pageShape, setPageShape] = useState<{ aspect: number; rasterWidth: number } | null>(null);\n /** Measured inner width of the column — the other half of the reservation. */\n const [columnWidth, setColumnWidth] = useState<number | null>(null);\n const columnRef = useRef<HTMLDivElement>(null);\n const [scale] = useState(1.5); // Fixed scale for better quality\n\n /** Pages currently intersecting the viewport (plus the preload margin). */\n const [visiblePages, setVisiblePages] = useState<Set<number>>(new Set());\n /** Pages genuinely in view — observed with NO preload margin, so it answers\n * \"what is the reader looking at\" rather than \"what should be loaded\".\n * Drives the indicator and the rail; never the mount window. */\n const [onscreenPages, setOnscreenPages] = useState<Set<number>>(new Set());\n const slotRefs = useRef(new Map<number, HTMLElement>());\n const observerRef = useRef<IntersectionObserver | null>(null);\n const onscreenRef = useRef<IntersectionObserver | null>(null);\n\n // Load PDF document on mount\n useEffect(() => {\n let cancelled = false;\n\n async function loadPdf() {\n try {\n setIsLoading(true);\n setErrorKey(null);\n\n const doc = await loadPdfDocument(pdfUrl);\n\n if (cancelled) return;\n\n setPdfDoc(doc);\n setNumPages(doc.numPages);\n setIsLoading(false);\n\n // One extra getPage, for slot sizing (D4). Failure is not fatal:\n // unsized slots still scroll, just less faithfully.\n try {\n const first = await doc.getPage(1);\n if (cancelled) return;\n const natural = first.getViewport({ scale: 1.0 });\n setPageShape({\n aspect: natural.height / natural.width,\n rasterWidth: first.getViewport({ scale }).width,\n });\n } catch {\n /* leave unsized — an unsized slot is stable; a mis-sized one moves */\n }\n } catch (err) {\n if (cancelled) return;\n\n console.error('Error loading PDF:', err);\n setErrorKey('loadFailed');\n setIsLoading(false);\n }\n }\n\n loadPdf();\n\n return () => {\n cancelled = true;\n };\n }, [pdfUrl, scale]);\n\n /**\n * The server-derived map, fetched once per document rather than once per\n * page (PERSIST-ANCHORS P4). The map is WHOLE-RESOURCE — one artifact\n * covering every page — so re-reading it per page meant a full refetch and\n * re-decode on every page turn; on a 400-page scan that is one decode per\n * interaction instead of one per document. Living on the parent is also\n * what lets a scrolling column mount many pages against a single fetch.\n *\n * The cache holds the in-flight promise so concurrent page loads share one\n * fetch. Answers cache — including \"no map\" and a stored decline, which are\n * definitive — but a transport failure clears the entry, so the next page\n * load retries instead of pinning the whole document to geometry-only.\n */\n const resourceAnchoredRef = useRef<{ uri: string; outcome: Promise<AnchoredText | null> } | null>(null);\n const fetchResourceAnchored = useCallback((): Promise<AnchoredText | null> => {\n if (!session) return Promise.resolve(null); // no session yet — don't cache its absence\n const cached = resourceAnchoredRef.current;\n if (cached && cached.uri === resourceUri) return cached.outcome;\n\n const uri = resourceUri;\n const outcome = session.client.browse.resourceAnchoredText(toResourceId(uri)).then(\n (served) => (served && !('declined' in served) ? served : null),\n () => {\n if (resourceAnchoredRef.current?.uri === uri) resourceAnchoredRef.current = null;\n return null;\n },\n );\n resourceAnchoredRef.current = { uri, outcome };\n return outcome;\n }, [session, resourceUri]);\n\n // The column's width decides every page's displayed height, so the\n // reservation cannot be computed without it.\n useEffect(() => {\n if (pageLayout !== 'scroll') return;\n const measure = () => {\n if (columnRef.current) setColumnWidth(columnRef.current.clientWidth);\n };\n measure();\n let observer: ResizeObserver | null = null;\n try {\n observer = new ResizeObserver(measure);\n if (columnRef.current) observer.observe(columnRef.current);\n } catch {\n window.addEventListener('resize', measure);\n }\n return () => {\n if (observer) observer.disconnect();\n else window.removeEventListener('resize', measure);\n };\n }, [pageLayout]);\n\n const slotHeight = estimateSlotHeight(columnWidth, pageShape?.rasterWidth ?? null, pageShape?.aspect ?? null)\n // Before the column has been measured there is still a sane reservation:\n // the raster's own height. Wrong in a narrow column, but every slot is\n // wrong by the SAME amount, so the column is at least internally\n // consistent until the first measurement lands.\n ?? (pageShape ? Math.round(pageShape.rasterWidth * pageShape.aspect) : null);\n\n // The mount window. Slots report their own visibility; a page is mounted\n // while its slot intersects (widened by PRELOAD_MARGIN so the next page is\n // ready before it is reached), and unmounting is what frees its raster.\n useEffect(() => {\n if (pageLayout !== 'scroll' || numPages === 0) return;\n\n let observer: IntersectionObserver | null = null;\n try {\n observer = new IntersectionObserver(\n (entries) => {\n setVisiblePages((prev) => {\n const next = new Set(prev);\n for (const entry of entries) {\n const page = Number((entry.target as HTMLElement).dataset.page);\n if (!page) continue;\n if (entry.isIntersecting) next.add(page);\n else next.delete(page);\n }\n return next;\n });\n },\n { rootMargin: PRELOAD_MARGIN },\n );\n } catch {\n // No IntersectionObserver: mount every page rather than none. Correct,\n // simply not virtualized — the same posture as the ResizeObserver\n // fallback in PdfPageView.\n setVisiblePages(new Set(Array.from({ length: numPages }, (_, i) => i + 1)));\n return;\n }\n\n observerRef.current = observer;\n for (const el of slotRefs.current.values()) observer.observe(el);\n\n // A SECOND observer, with no preload margin, answers a different question:\n // which pages the reader can actually see. Two observers rather than one\n // set doing both jobs, because widening the mount window must never move\n // the page indicator.\n let onscreen: IntersectionObserver | null = null;\n try {\n onscreen = new IntersectionObserver((entries) => {\n setOnscreenPages((prev) => {\n const next = new Set(prev);\n for (const entry of entries) {\n const page = Number((entry.target as HTMLElement).dataset.page);\n if (!page) continue;\n if (entry.isIntersecting) next.add(page);\n else next.delete(page);\n }\n return next;\n });\n });\n onscreenRef.current = onscreen;\n for (const el of slotRefs.current.values()) onscreen.observe(el);\n } catch {\n // Without an observer there is no notion of \"on screen\"; fall back to\n // page 1 so the indicator names something rather than nothing.\n setOnscreenPages(new Set([1]));\n }\n\n return () => {\n observer.disconnect();\n observerRef.current = null;\n onscreen?.disconnect();\n onscreenRef.current = null;\n };\n }, [pageLayout, numPages]);\n\n const registerSlot = useCallback((page: number) => (el: HTMLDivElement | null) => {\n const previous = slotRefs.current.get(page);\n if (previous) {\n observerRef.current?.unobserve(previous);\n onscreenRef.current?.unobserve(previous);\n }\n if (el) {\n slotRefs.current.set(page, el);\n observerRef.current?.observe(el);\n onscreenRef.current?.observe(el);\n } else {\n slotRefs.current.delete(page);\n }\n }, []);\n\n /** Keeps the current page's rectangle in view as the reader scrolls. */\n const currentTickRef = useRef<HTMLButtonElement>(null);\n\n const scrollToPage = useCallback((page: number) => {\n scrollElementIntoView(slotRefs.current.get(page), { block: 'start' });\n }, []);\n\n // In the column the reader decides which page they are on by scrolling, so\n // the indicator reports rather than controls: the topmost page actually ON\n // SCREEN. NOT `visiblePages` — that set is deliberately widened by\n // PRELOAD_MARGIN to mount pages before they are reached, so reading it here\n // would name a page still a viewport away.\n const currentPage = pageLayout === 'scroll'\n ? (onscreenPages.size > 0 ? Math.min(...onscreenPages) : 1)\n : pageNumber;\n\n /**\n * Left/Right step pages (S1a).\n *\n * Bound to the window rather than a focusable wrapper so it works without\n * the reader hunting for the viewer's focus — but that reach is exactly why\n * the guards matter more than the feature: a viewer that eats arrow keys\n * while someone is editing an annotation body, or mid-drag, is worse than\n * one with no shortcut at all.\n */\n useEffect(() => {\n if (numPages === 0) return;\n const BACK = ['ArrowLeft', 'PageUp'];\n const FORWARD = ['ArrowRight', 'PageDown'];\n const onKeyDown = (e: KeyboardEvent) => {\n // PageUp/PageDown jump a page; Left/Right do too, because they have no\n // native meaning in a vertical layout so taking them costs nothing.\n //\n // Up/Down are deliberately NOT here. They are the scroller's fine\n // movement, and a page can be taller than the viewport — taking them\n // would leave no keyboard way to reach the bottom of one. This is the\n // split Preview, Chrome's PDF viewer and Acrobat all use.\n if (!BACK.includes(e.key) && !FORWARD.includes(e.key)) return;\n if (e.metaKey || e.ctrlKey || e.altKey) return; // browser/OS navigation\n const el = e.target as HTMLElement | null;\n const tag = el?.tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT' || el?.isContentEditable) return;\n\n const next = FORWARD.includes(e.key) ? currentPage + 1 : currentPage - 1;\n if (next < 1 || next > numPages) return;\n e.preventDefault();\n if (pageLayout === 'scroll') scrollToPage(next);\n else setPageNumber(next);\n };\n window.addEventListener('keydown', onKeyDown);\n return () => window.removeEventListener('keydown', onKeyDown);\n }, [numPages, currentPage, pageLayout, scrollToPage]);\n\n const stripRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n // `nearest` so following the reader never yanks the strip around; it\n // scrolls only when the current rectangle would otherwise leave view.\n scrollElementIntoView(currentTickRef.current, { block: 'nearest', inline: 'nearest' });\n\n // Move focus with the current page, but ONLY when the strip already owns\n // focus. Otherwise a clicked rectangle keeps focus while the current-page\n // marker moves on, and the focus ring — which appears as soon as the\n // reader touches an arrow key and the browser switches to keyboard\n // modality — sits on a page that is no longer current: two rectangles\n // claiming to be \"here\". Guarding on ownership means scrolling with the\n // mouse never snatches focus from whatever the reader was doing.\n const active = typeof document !== 'undefined' ? document.activeElement : null;\n if (active && stripRef.current?.contains(active) && active !== currentTickRef.current) {\n currentTickRef.current?.focus();\n }\n }, [currentPage]);\n\n const pageProps = {\n scale,\n resourceUri,\n existingAnnotations,\n drawingMode,\n selectedMotivation,\n session,\n hoveredAnnotationId,\n selectedAnnotationId,\n hoverDelayMs,\n fetchResourceAnchored,\n };\n\n if (errorKey) {\n return <div className=\"semiont-pdf-annotation-canvas__error\">{t(errorKey)}</div>;\n }\n\n return (\n <div className=\"semiont-pdf-annotation-canvas\">\n {isLoading && <div className=\"semiont-pdf-annotation-canvas__loading\">{t('loading')}</div>}\n\n {pdfDoc && pageLayout === 'scroll' ? (\n <div className=\"semiont-pdf-annotation-canvas__viewport\" data-axis={SCROLL_AXIS}>\n {numPages > 0 && pageShape && (\n <div\n className=\"semiont-pdf-annotation-canvas__strip\"\n data-axis={SCROLL_AXIS}\n data-scroller=\"true\"\n aria-orientation={SCROLL_AXIS}\n ref={stripRef}\n >\n {Array.from({ length: numPages }, (_, i) => i + 1).map((page) => (\n <button\n key={page}\n type=\"button\"\n data-page={page}\n className=\"semiont-pdf-annotation-canvas__strip-page\"\n style={{ height: `${Math.round(STRIP_PAGE_WIDTH * pageShape.aspect)}px` }}\n aria-label={t('pageOf', { page, total: numPages })}\n tabIndex={page === currentPage ? 0 : -1}\n {...(page === currentPage ? { 'aria-current': 'page' as const } : {})}\n ref={page === currentPage ? currentTickRef : undefined}\n onClick={() => scrollToPage(page)}\n >\n {page}\n </button>\n ))}\n </div>\n )}\n <div className=\"semiont-pdf-annotation-canvas__column\" data-axis={SCROLL_AXIS} ref={columnRef}>\n {Array.from({ length: numPages }, (_, i) => i + 1).map((page) => (\n <div\n key={page}\n ref={registerSlot(page)}\n data-page={page}\n className=\"semiont-pdf-annotation-canvas__slot\"\n // min-height, and applied whether or not the page is mounted:\n // releasing it on mount is what made the scrollbar jump. `min`\n // rather than a fixed height so a page that renders slightly\n // taller expands instead of clipping.\n style={slotHeight ? { minHeight: slotHeight } : undefined}\n >\n {visiblePages.has(page) && (\n <PdfPageView doc={pdfDoc} pageNumber={page} {...pageProps} />\n )}\n </div>\n ))}\n </div>\n </div>\n ) : (\n pdfDoc && !isLoading && (\n // `key` is load-bearing: without it React reuses this instance\n // across page changes, so the previous page's raster, text map and\n // load error survive into the next page — a stale overlay, a quote\n // taken from the wrong page, and an error that never clears. Each\n // page is a different thing; mounting it as one resets all of it.\n <PdfPageView key={pageNumber} doc={pdfDoc} pageNumber={pageNumber} {...pageProps} />\n )\n )}\n\n {/* Page navigation controls */}\n {numPages > 0 && (\n <nav className=\"semiont-pdf-annotation-canvas__controls\" aria-label={t('pagination')}>\n <button\n disabled={currentPage <= 1}\n onClick={() => (pageLayout === 'scroll' ? scrollToPage(currentPage - 1) : setPageNumber(pageNumber - 1))}\n className=\"semiont-pdf-annotation-canvas__button\"\n >\n {t('previous')}\n </button>\n {/*\n aria-live: the page number is the only feedback a page change gives,\n and in the scrolling column it changes without any control being\n activated at all — so a screen-reader user who scrolls would\n otherwise get silence.\n */}\n <span className=\"semiont-pdf-annotation-canvas__page-info\" aria-live=\"polite\">\n {t('pageOf', { page: currentPage, total: numPages })}\n </span>\n <button\n disabled={currentPage >= numPages}\n onClick={() => (pageLayout === 'scroll' ? scrollToPage(currentPage + 1) : setPageNumber(pageNumber + 1))}\n className=\"semiont-pdf-annotation-canvas__button\"\n >\n {t('next')}\n </button>\n </nav>\n )}\n </div>\n );\n}\n","import type { Annotation, PdfCoordinate } from '@semiont/core';\nimport { getTargetSelector, parseFragmentSelector } from '@semiont/core';\n\n/** One FragmentSelector rectangle to paint on a PDF page. */\nexport interface PageRect {\n /** Owning annotation id — shared by every rect of a multi-line annotation (hover/click routing). */\n annId: Annotation['id'];\n /** Index within the annotation's FragmentSelectors — the stable half of the React key. */\n selectorIndex: number;\n /** PDF-point geometry for this rect. */\n coord: PdfCoordinate;\n /** Owning annotation (motivation colour, etc.). */\n annotation: Annotation;\n}\n\n/** Every FragmentSelector on a target, in order (`target.selector` may be one or an array). */\nfunction fragmentSelectors(target: Annotation['target']): { value: string }[] {\n const selector = getTargetSelector(target);\n if (!selector) return [];\n const selectors = Array.isArray(selector) ? selector : [selector];\n return selectors\n .filter(s => s.type === 'FragmentSelector')\n .map(s => s as { type: 'FragmentSelector'; value: string });\n}\n\n/**\n * The rectangles to paint on `pageNumber`: one entry per FragmentSelector whose\n * viewrect page matches. A multi-line (multi-selector) annotation therefore yields\n * one rect per line; a single-selector (manual) annotation yields exactly one.\n *\n * Pure — no React/DOM. `PdfAnnotationCanvas` maps this to `<rect>` keyed\n * `${annId}:${selectorIndex}`, and the rects-for-page axioms exercise it directly.\n * Geometry stays deferred: each `coord` still goes through `pdfToCanvasCoordinates`\n * at paint time (itself covered by the coordinate-transform axioms).\n */\nexport function rectsForPage(annotations: Annotation[], pageNumber: number): PageRect[] {\n const rects: PageRect[] = [];\n for (const annotation of annotations) {\n fragmentSelectors(annotation.target).forEach((sel, selectorIndex) => {\n const coord = parseFragmentSelector(sel.value);\n if (coord && coord.page === pageNumber) {\n rects.push({ annId: annotation.id, selectorIndex, coord, annotation });\n }\n });\n }\n return rects;\n}\n","/**\n * The height a page will occupy once rendered, computed BEFORE rendering it.\n *\n * The scrolling column reserves space for pages it has not mounted. If the\n * reserved height differs from the height the page actually takes, every mount\n * and unmount changes the column's total height and the scrollbar jumps under\n * the reader's cursor — the defect S1 shipped by reserving the *raster* height\n * (`getViewport({ scale }).height`) instead of the *displayed* one.\n *\n * This models the CSS the image is under exactly:\n *\n * .semiont-pdf-annotation-canvas__image { max-width: 100%; height: auto; }\n *\n * `max-width` shrinks but never upscales, so the displayed width is\n * `min(columnWidth, rasterWidth)` and the height follows the page's aspect\n * ratio. Aspect is scale-invariant, so it can come from any viewport.\n *\n * @param columnWidth Measured inner width of the scroll column, in CSS px.\n * @param rasterWidth Width of the rendered raster, in px (`viewport(scale).width`).\n * @param aspect Page height ÷ width, from any viewport scale.\n * @returns Reserved height in CSS px, or null when a measurement is not in yet.\n */\nexport function estimateSlotHeight(\n columnWidth: number | null,\n rasterWidth: number | null,\n aspect: number | null,\n): number | null {\n if (!columnWidth || !rasterWidth || !aspect) return null;\n if (columnWidth <= 0 || rasterWidth <= 0 || aspect <= 0) return null;\n return Math.round(Math.min(columnWidth, rasterWidth) * aspect);\n}\n","/**\n * PDF Canvas Coordinate Transforms\n *\n * Converts between canvas space (pixels, top-left origin, Y increases downward)\n * and PDF space (points, bottom-left origin, Y increases upward) — the Y-flip and\n * scale. UI-only: the server has no canvas.\n *\n * `PdfCoordinate` and the viewrect FragmentSelector codec live in `@semiont/core`.\n *\n * Based on RFC 3778 PDF Fragment Identifiers:\n * https://tools.ietf.org/html/rfc3778\n */\n\nimport type { PdfCoordinate } from '@semiont/core';\n\nexport interface Rectangle {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface CanvasRectangle {\n startX: number;\n startY: number;\n endX: number;\n endY: number;\n}\n\n/**\n * Convert canvas coordinates to PDF coordinates\n *\n * Canvas: Origin at top-left, Y increases downward\n * PDF: Origin at bottom-left, Y increases upward\n *\n * @param canvasRect - Rectangle in canvas pixel coordinates\n * @param page - PDF page number (1-indexed)\n * @param pageWidth - PDF page width in points\n * @param pageHeight - PDF page height in points\n * @param scale - Current canvas scale factor\n */\nexport function canvasToPdfCoordinates(\n canvasRect: CanvasRectangle,\n page: number,\n _pageWidth: number,\n pageHeight: number,\n scale: number = 1\n): PdfCoordinate {\n // Normalize rectangle (handle drag in any direction)\n const x1 = Math.min(canvasRect.startX, canvasRect.endX);\n const y1 = Math.min(canvasRect.startY, canvasRect.endY);\n const x2 = Math.max(canvasRect.startX, canvasRect.endX);\n const y2 = Math.max(canvasRect.startY, canvasRect.endY);\n\n // Convert from canvas pixels to PDF points\n const pdfX = x1 / scale;\n const pdfWidth = (x2 - x1) / scale;\n\n // Flip Y coordinate (canvas top-left to PDF bottom-left)\n const pdfY = pageHeight - (y2 / scale);\n const pdfHeight = (y2 - y1) / scale;\n\n return {\n page,\n x: Math.round(pdfX),\n y: Math.round(pdfY),\n width: Math.round(pdfWidth),\n height: Math.round(pdfHeight)\n };\n}\n\n/**\n * Convert PDF coordinates to canvas coordinates\n *\n * @param pdfCoord - Coordinates in PDF space\n * @param pageHeight - PDF page height in points\n * @param scale - Current canvas scale factor\n */\nexport function pdfToCanvasCoordinates(\n pdfCoord: PdfCoordinate,\n pageHeight: number,\n scale: number = 1\n): Rectangle {\n // Convert from PDF points to canvas pixels\n const canvasX = pdfCoord.x * scale;\n const canvasWidth = pdfCoord.width * scale;\n\n // Flip Y coordinate (PDF bottom-left to canvas top-left)\n const canvasY = (pageHeight - pdfCoord.y - pdfCoord.height) * scale;\n const canvasHeight = pdfCoord.height * scale;\n\n return {\n x: canvasX,\n y: canvasY,\n width: canvasWidth,\n height: canvasHeight\n };\n}\n"],"mappings":"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","names":["scaleX","scaleY"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/pdf-annotation/PdfAnnotationCanvas.css"],"sourcesContent":["/**\n * PDF Annotation Canvas Styles\n *\n * Provides consistent styling for PDF annotation interface,\n * following the same pattern as image annotation (SvgDrawingCanvas).\n */\n\n.semiont-pdf-annotation-canvas {\n position: relative;\n display: inline-block;\n}\n\n.semiont-pdf-annotation-canvas__loading,\n.semiont-pdf-annotation-canvas__error {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 2rem;\n}\n\n/* stylelint-disable semiont/accessibility -- Error indicator added by semantic-indicators.css */\n.semiont-pdf-annotation-canvas__error {\n color: var(--semiont-color-error);\n}\n\n[data-theme=\"dark\"] .semiont-pdf-annotation-canvas__error {\n color: var(--semiont-color-error);\n}\n/* stylelint-enable semiont/accessibility */\n\n/*\n * The scrolling column (PDF-CONTINUOUS-SCROLL S1). Every page owns a slot so\n * the scrollbar reflects the whole document; only pages near the viewport are\n * mounted, and an unmounted slot holds its space with an estimated height set\n * inline. `max-height` is what makes this a scroll container at all — without\n * it the column grows to its content and the page scrolls instead, which\n * still works but defeats the windowing.\n */\n/*\n * Viewport = the pages plus their strip, side by side. The strip LEADS — it\n * hugs the content's leading edge, where a page rail conventionally lives\n * (Preview, Acrobat), so the reader's eye finds it before the page.\n */\n.semiont-pdf-annotation-canvas__viewport {\n display: flex;\n gap: 0.5rem;\n align-items: stretch;\n}\n\n.semiont-pdf-annotation-canvas__viewport[data-axis=\"horizontal\"] {\n flex-direction: column;\n}\n\n.semiont-pdf-annotation-canvas__column {\n display: flex;\n flex: 1 1 auto;\n gap: 1rem;\n align-items: center;\n}\n\n/*\n * Both blocks below key off ONE attribute, so the strip can never end up\n * running across the direction the document scrolls.\n */\n/*\n * The column does NOT scroll. The pane the viewer sits in already does\n * (`flex: 1; min-height: 0`), and giving the column a viewport-relative\n * height of its own produced a scroller inside a scroller — two bars along\n * one axis, the inner one redundant with the page rail beside it.\n */\n.semiont-pdf-annotation-canvas__column[data-axis=\"vertical\"] {\n flex-direction: column;\n}\n\n.semiont-pdf-annotation-canvas__column[data-axis=\"horizontal\"] {\n flex-direction: row;\n}\n\n.semiont-pdf-annotation-canvas__slot {\n display: flex;\n justify-content: center;\n width: 100%;\n}\n\n/*\n * The page strip: the document's shape in miniature. Rectangles only — no\n * rasterization — so a 400-page scan costs 400 empty divs, not 400 renders.\n */\n/*\n * The strip scrolls — a 70-page document cannot fit its numbered rectangles in\n * one screen — but it must not show a scrollbar. Two scrollbars side by side\n * read as two controls for one thing, and the strip's own moves the strip\n * rather than the document, so it looks broken. Position is carried by the\n * highlighted page, and the strip follows the reader on its own.\n */\n.semiont-pdf-annotation-canvas__strip {\n display: flex;\n flex: 0 0 auto;\n gap: 2px;\n padding: 0.5rem;\n scrollbar-width: none; /* standard; Firefox + recent Chromium */\n}\n\n/*\n * WebKit/Safari, which has no `scrollbar-width` support to rely on.\n *\n * This hides a SCROLLBAR, not content: `scrollbar-width: none` above already\n * does the same for every other engine, the rail still scrolls by wheel and\n * drag, and each page is a focusable button — so tabbing through the rail\n * scrolls it, which is the keyboard path the rule is protecting.\n */\n.semiont-pdf-annotation-canvas__strip::-webkit-scrollbar {\n display: none; /* stylelint-disable-line semiont/accessibility */\n}\n\n/*\n * The rail hugs the leading edge of the content and stays put while the\n * document scrolls past it — `sticky` rather than a fixed-height box, so it\n * follows the reader without claiming a second scroll region in the layout.\n */\n.semiont-pdf-annotation-canvas__strip[data-axis=\"vertical\"] {\n position: sticky;\n top: 0;\n flex-direction: column;\n align-self: flex-start;\n align-items: center;\n max-height: 100vh;\n overflow-y: auto;\n border-right: 1px solid var(--semiont-border-secondary);\n}\n\n.semiont-pdf-annotation-canvas__strip[data-axis=\"horizontal\"] {\n position: sticky;\n top: 0;\n flex-direction: row;\n align-items: flex-end;\n max-width: 100%;\n overflow-x: auto;\n border-bottom: 1px solid var(--semiont-border-secondary);\n}\n\n.semiont-pdf-annotation-canvas__strip-page {\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n justify-content: center;\n width: 30px;\n padding: 0;\n border: 1px solid var(--semiont-border-primary);\n border-radius: 1px;\n background: var(--semiont-bg-secondary);\n color: var(--semiont-text-tertiary);\n font-size: var(--semiont-text-2xs);\n line-height: 1;\n cursor: pointer;\n}\n\n.semiont-pdf-annotation-canvas__strip-page:hover {\n background: var(--semiont-bg-hover);\n}\n\n/* The reader's position, legible at a glance across a long strip. */\n.semiont-pdf-annotation-canvas__strip-page[aria-current=\"page\"] {\n border-color: var(--semiont-color-primary-600);\n background: var(--semiont-color-primary-500);\n color: var(--semiont-color-neutral-0);\n font-weight: var(--semiont-font-semibold);\n}\n\n/*\n * Palette tokens are one fixed hue in both themes, so this marker needs a real\n * variant — the accent steps lighter against a dark surface (the treatment\n * `.semiont-checkbox:checked` uses), and the number flips to dark type, which\n * at this size reads far better on that lighter blue than white does.\n */\n[data-theme=\"dark\"] .semiont-pdf-annotation-canvas__strip-page[aria-current=\"page\"] {\n border-color: var(--semiont-color-primary-400);\n background: var(--semiont-color-primary-400);\n color: var(--semiont-color-neutral-900);\n}\n\n.semiont-pdf-annotation-canvas__strip-page:focus-visible {\n outline: 2px solid var(--semiont-focus-ring);\n outline-offset: 1px;\n}\n\n.semiont-pdf-annotation-canvas__container {\n position: relative;\n display: inline-block;\n cursor: crosshair;\n}\n\n.semiont-pdf-annotation-canvas__container[data-drawing-mode=\"none\"] {\n cursor: default;\n}\n\n.semiont-pdf-annotation-canvas__image {\n display: block;\n max-width: 100%;\n height: auto;\n box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n pointer-events: none;\n}\n\n[data-theme=\"dark\"] .semiont-pdf-annotation-canvas__image {\n box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.3), 0 1px 2px -1px rgb(0 0 0 / 0.3);\n}\n\n.semiont-pdf-annotation-canvas__overlay-container {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n\n.semiont-pdf-annotation-canvas__overlay {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n\n.semiont-pdf-annotation-canvas__svg {\n pointer-events: none;\n}\n\n.semiont-pdf-annotation-canvas__svg rect {\n pointer-events: auto;\n}\n\n.semiont-pdf-annotation-canvas__controls {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 1rem;\n padding: 1rem;\n border-top: 1px solid var(--semiont-border-primary);\n}\n\n.semiont-pdf-annotation-canvas__button {\n padding: 0.5rem 1rem;\n border: 1px solid var(--semiont-border-primary);\n border-radius: 4px;\n background: transparent;\n cursor: pointer;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n .semiont-pdf-annotation-canvas__button {\n transition: background-color 0.2s;\n }\n}\n\n.semiont-pdf-annotation-canvas__button:hover:not(:disabled) {\n background-color: var(--semiont-bg-hover);\n}\n\n.semiont-pdf-annotation-canvas__button:focus-visible {\n outline: 2px solid var(--semiont-focus-ring);\n outline-offset: 2px;\n}\n\n.semiont-pdf-annotation-canvas__button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.semiont-pdf-annotation-canvas__page-info {\n font-size: 0.875rem;\n min-width: 7rem;\n text-align: center;\n}\n\n/*# sourceMappingURL=src/components/pdf-annotation/PdfAnnotationCanvas.css.map */"],"mappings":";AAOA,CAAC;AACC,YAAU;AACV,WAAS;AACX;AAEA,CAAC;AACD,CAAC;AACC,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,WAAS;AACX;AAGA,CARC;AASC,SAAO,IAAI;AACb;AAEA,CAAC,iBAAmB,CAZnB;AAaC,SAAO,IAAI;AACb;AAgBA,CAAC;AACC,WAAS;AACT,OAAK;AACL,eAAa;AACf;AAEA,CANC,uCAMuC,CAAC;AACvC,kBAAgB;AAClB;AAEA,CAAC;AACC,WAAS;AACT,QAAM,EAAE,EAAE;AACV,OAAK;AACL,eAAa;AACf;AAYA,CAjBC,qCAiBqC,CAAC;AACrC,kBAAgB;AAClB;AAEA,CArBC,qCAqBqC,CAAC;AACrC,kBAAgB;AAClB;AAEA,CAAC;AACC,WAAS;AACT,mBAAiB;AACjB,SAAO;AACT;AAaA,CAAC;AACC,WAAS;AACT,QAAM,EAAE,EAAE;AACV,OAAK;AACL,WAAS;AACT,mBAAiB;AACnB;AAUA,CAhBC,oCAgBoC;AACnC,WAAS;AACX;AAOA,CAzBC,oCAyBoC,CAAC;AACpC,YAAU;AACV,OAAK;AACL,kBAAgB;AAChB,cAAY;AACZ,eAAa;AACb,cAAY;AACZ,cAAY;AACZ,gBAAc,IAAI,MAAM,IAAI;AAC9B;AAEA,CApCC,oCAoCoC,CAAC;AACpC,YAAU;AACV,OAAK;AACL,kBAAgB;AAChB,eAAa;AACb,aAAW;AACX,cAAY;AACZ,iBAAe,IAAI,MAAM,IAAI;AAC/B;AAEA,CAAC;AACC,WAAS;AACT,QAAM,EAAE,EAAE;AACV,eAAa;AACb,mBAAiB;AACjB,SAAO;AACP,WAAS;AACT,UAAQ,IAAI,MAAM,IAAI;AACtB,iBAAe;AACf,cAAY,IAAI;AAChB,SAAO,IAAI;AACX,aAAW,IAAI;AACf,eAAa;AACb,UAAQ;AACV;AAEA,CAhBC,yCAgByC;AACxC,cAAY,IAAI;AAClB;AAGA,CArBC,yCAqByC,CAAC;AACzC,gBAAc,IAAI;AAClB,cAAY,IAAI;AAChB,SAAO,IAAI;AACX,eAAa,IAAI;AACnB;AAQA,CAAC,iBAAmB,CAlCnB,yCAkC6D,CAAC;AAC7D,gBAAc,IAAI;AAClB,cAAY,IAAI;AAChB,SAAO,IAAI;AACb;AAEA,CAxCC,yCAwCyC;AACxC,WAAS,IAAI,MAAM,IAAI;AACvB,kBAAgB;AAClB;AAEA,CAAC;AACC,YAAU;AACV,WAAS;AACT,UAAQ;AACV;AAEA,CANC,wCAMwC,CAAC;AACxC,UAAQ;AACV;AAEA,CAAC;AACC,WAAS;AACT,aAAW;AACX,UAAQ;AACR,cAAY,EAAE,IAAI,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,IAAI,KAAK,IAAI,EAAE,EAAE,EAAE,EAAE;AACrE,uBAAqB;AAClB,oBAAkB;AACb,eAAa;AACrB,kBAAgB;AAClB;AAEA,CAAC,iBAAmB,CAXnB;AAYC,cAAY,EAAE,IAAI,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,IAAI,KAAK,IAAI,EAAE,EAAE,EAAE,EAAE;AACvE;AAEA,CAAC;AACC,YAAU;AACV,OAAK;AACL,QAAM;AACN,SAAO;AACP,UAAQ;AACR,kBAAgB;AAClB;AAEA,CAAC;AACC,YAAU;AACV,OAAK;AACL,QAAM;AACN,SAAO;AACP,UAAQ;AACR,kBAAgB;AAClB;AAEA,CAAC;AACC,kBAAgB;AAClB;AAEA,CAJC,mCAImC;AAClC,kBAAgB;AAClB;AAEA,CAAC;AACC,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,OAAK;AACL,WAAS;AACT,cAAY,IAAI,MAAM,IAAI;AAC5B;AAEA,CAAC;AACC,WAAS,OAAO;AAChB,UAAQ,IAAI,MAAM,IAAI;AACtB,iBAAe;AACf,cAAY;AACZ,UAAQ;AACV;AAEA,QAAO,wBAAyB;AAC9B,GATD;AAUG,gBAAY,iBAAiB;AAC/B;AACF;AAEA,CAdC,qCAcqC,MAAM,KAAK;AAC/C,oBAAkB,IAAI;AACxB;AAEA,CAlBC,qCAkBqC;AACpC,WAAS,IAAI,MAAM,IAAI;AACvB,kBAAgB;AAClB;AAEA,CAvBC,qCAuBqC;AACpC,WAAS;AACT,UAAQ;AACV;AAEA,CAAC;AACC,aAAW;AACX,aAAW;AACX,cAAY;AACd;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../translations/ar.json"],"sourcesContent":["{\n \"AssistProgress\": {\n \"close\": \"إغلاق\",\n \"codeLoading\": \"جارٍ التحميل…\",\n \"codeAnalyzing\": \"جارٍ التوسيم…\",\n \"codeAnalyzingTags\": \"توسيم الوسوم…\",\n \"codeDetectingEntities\": \"جارٍ التوسيم…\",\n \"codeCreatingAnnotations\": \"إنشاء {{count}} تعليقات توضيحية…\",\n \"codeCreatingTagAnnotations\": \"إنشاء {{count}} وسوم…\",\n \"codeCompleteCreated\": \"تم إنشاء {{count}} {{kind}}\",\n \"codeGeneratingResource\": \"جارٍ التوليد…\",\n \"codeCreatingResource\": \"إنشاء المورد…\",\n \"kindHighlight\": \"تظليلات\",\n \"kindComment\": \"تعليقات\",\n \"kindAssessment\": \"تقييمات\",\n \"kindReference\": \"مراجع\",\n \"kindTag\": \"وسوم\",\n \"subject\": \"{{kind}}: {{label}}\",\n \"subjectWithPosition\": \"{{kind}}: {{label}} ({{done}} من {{total}})\",\n \"paramEntityTypes\": \"أنواع الكيانات\",\n \"paramInstructions\": \"التعليمات\",\n \"paramTone\": \"النبرة\",\n \"paramDensity\": \"الكثافة\",\n \"subjectKindEntityType\": \"نوع الكيان\",\n \"subjectKindCategory\": \"فئة\",\n \"cancel\": \"إلغاء\",\n \"inProgress\": \"جارٍ التوضيح...\"\n },\n \"PdfViewer\": {\n \"loadFailed\": \"فشل تحميل ملف PDF\",\n \"loading\": \"جارٍ تحميل PDF...\",\n \"next\": \"التالي\",\n \"pageLoadFailed\": \"فشل تحميل الصفحة\",\n \"pageOf\": \"صفحة {{page}} من {{total}}\",\n \"pagination\": \"ترقيم الصفحات\",\n \"previous\": \"السابق\",\n \"viewerLoading\": \"جارٍ تحميل عارض PDF...\"\n },\n \"Toolbar\": {\n \"annotations\": \"التعليقات التوضيحية\",\n \"history\": \"السجل\",\n \"resourceInfo\": \"معلومات المورد\",\n \"collaboration\": \"التعاون\",\n \"userAccount\": \"حساب المستخدم\",\n \"settings\": \"الإعدادات\",\n \"knowledgeBase\": \"قاعدة المعرفة\"\n },\n \"ResourceInfoPanel\": {\n \"title\": \"معلومات المورد\",\n \"locale\": \"اللغة المحلية\",\n \"notSpecified\": \"غير محدد\",\n \"entityTypeTags\": \"علامات نوع الكيان\",\n \"representation\": \"التمثيل\",\n \"mediaType\": \"نوع الوسائط\",\n \"byteSize\": \"الحجم\",\n \"storageUri\": \"التخزين\",\n \"clone\": \"استنساخ\",\n \"cloneDescription\": \"إنشاء رابط استنساخ قابل للمشاركة لهذا المورد\",\n \"generate\": \"توليد\",\n \"generateDescription\": \"إنشاء مورد جديد من سياق هذا المورد\",\n \"archive\": \"أرشفة\",\n \"archiveDescription\": \"نقل هذا المورد إلى حالة الأرشيف\",\n \"unarchive\": \"إلغاء الأرشفة\",\n \"unarchiveDescription\": \"استعادة هذا المورد إلى الحالة النشطة\",\n \"provenance\": \"المصدر والسلسلة\",\n \"createdAt\": \"تاريخ الإنشاء\",\n \"modifiedAt\": \"تاريخ التعديل\",\n \"attributedTo\": \"منسوب إلى\",\n \"derivedFrom\": \"مشتق من\"\n },\n \"CollaborationPanel\": {\n \"title\": \"التعاون\",\n \"connectionStatus\": \"حالة الاتصال\",\n \"live\": \"مباشر\",\n \"disconnected\": \"غير متصل\",\n \"events\": \"{{count}} أحداث\",\n \"lastSync\": \"آخر مزامنة:\",\n \"noActivity\": \"لا يوجد نشاط بعد\",\n \"justNow\": \"الآن\",\n \"secondsAgo\": \"منذ {{count}} ثوانٍ\",\n \"minuteAgo\": \"منذ دقيقة واحدة\",\n \"minutesAgo\": \"منذ {{count}} دقائق\",\n \"hourAgo\": \"منذ ساعة واحدة\",\n \"hoursAgo\": \"منذ {{count}} ساعات\",\n \"realtimeActive\": \"التحديثات في الوقت الفعلي نشطة\",\n \"reconnecting\": \"جارٍ إعادة الاتصال بالخادم...\",\n \"sharing\": \"المشاركة\",\n \"collaborationComingSoon\": \"ميزات التعاون قادمة قريبًا\",\n \"collaborators\": \"المتعاونون\",\n \"ceilings\": \"{{contextTokens}} إدخال / {{maxOutputTokens}} إخراج\",\n \"sharedWindow\": \"نافذة {{contextTokens}}\"\n },\n \"AnnotationHistory\": {\n \"history\": \"السجل\",\n \"loading\": \"جارٍ التحميل...\",\n \"user\": \"المستخدم\",\n \"viewOriginal\": \"عرض الأصل\",\n \"viewAnnotation\": \"عرض التعليق التوضيحي: {{content}}\",\n \"resourceCreated\": \"تم إنشاء المورد\",\n \"resourceCloned\": \"تم الاستنساخ\",\n \"resourceArchived\": \"تمت الأرشفة\",\n \"resourceUnarchived\": \"تم إلغاء الأرشفة\",\n \"highlightAdded\": \"تمت إضافة تمييز\",\n \"highlightRemoved\": \"تمت إزالة التمييز\",\n \"referenceCreated\": \"تم إنشاء مرجع\",\n \"referenceResolved\": \"تم حل المرجع\",\n \"referenceDeleted\": \"تم حذف المرجع\",\n \"entitytagAdded\": \"تمت إضافة علامة\",\n \"entitytagRemoved\": \"تمت إزالة العلامة\",\n \"assessmentAdded\": \"تمت إضافة تقييم\",\n \"assessmentRemoved\": \"تمت إزالة التقييم\",\n \"annotationAdded\": \"تمت إضافة تعليق توضيحي\",\n \"annotationRemoved\": \"تمت إزالة التعليق التوضيحي\",\n \"annotationBodyUpdated\": \"تم تحديث التعليق التوضيحي\",\n \"jobEvent\": \"حدث مهمة\",\n \"embeddingComputed\": \"تم حساب التضمين\",\n \"justNow\": \"الآن\",\n \"minutesAgo\": \"منذ {{count}}د\",\n \"hoursAgo\": \"منذ {{count}}س\",\n \"daysAgo\": \"منذ {{count}}ي\",\n \"failed\": \"تعذّر تحميل السجل.\",\n \"retry\": \"إعادة المحاولة\"\n },\n \"CommentsPanel\": {\n \"title\": \"التعليقات\",\n \"noComments\": \"لا توجد تعليقات بعد. حدد نصًا وانقر على تعليق لإضافة واحد.\",\n \"commentPlaceholder\": \"اكتب تعليقك هنا...\",\n \"save\": \"حفظ\",\n \"cancel\": \"إلغاء\",\n \"edit\": \"تعديل\",\n \"annotateComments\": \"توضيح التعليقات\",\n \"instructions\": \"التعليمات\",\n \"optional\": \"(اختياري)\",\n \"instructionsPlaceholder\": \"مثال: التركيز على المصطلحات التقنية...\",\n \"annotate\": \"توضيح\",\n \"annotating\": \"جارٍ التوضيح...\",\n \"toneLabel\": \"النبرة\",\n \"toneOptional\": \"(اختياري)\",\n \"toneScholarly\": \"أكاديمي\",\n \"toneExplanatory\": \"توضيحي\",\n \"toneConversational\": \"حواري\",\n \"toneTechnical\": \"تقني\",\n \"densityLabel\": \"الكثافة\",\n \"densitySparse\": \"متفرق\",\n \"densityDense\": \"كثيف\",\n \"fragmentSelected\": \"تم تحديد جزء\",\n \"imageRegionSelected\": \"تم تحديد منطقة من الصورة\",\n \"complete\": \"اكتمل التوضيح!\",\n \"failed\": \"فشل التوضيح\",\n \"densityPerWords\": \"{{density}} لكل 2000 كلمة\"\n },\n \"HighlightPanel\": {\n \"title\": \"التمييزات\",\n \"noHighlights\": \"لا توجد تمييزات بعد. استخدم التوضيح بالذكاء الاصطناعي للعثور على الفقرات المهمة.\",\n \"annotateHighlights\": \"توضيح التمييزات\",\n \"instructions\": \"التعليمات\",\n \"optional\": \"(اختياري)\",\n \"instructionsPlaceholder\": \"مثال: التركيز على المفاهيم التقنية الرئيسية...\",\n \"annotate\": \"توضيح\",\n \"annotating\": \"جارٍ التوضيح...\",\n \"cancel\": \"إلغاء\",\n \"densityLabel\": \"الكثافة\",\n \"densitySparse\": \"متفرق\",\n \"densityDense\": \"كثيف\",\n \"complete\": \"اكتمل التوضيح!\",\n \"failed\": \"فشل التوضيح\",\n \"densityPerWords\": \"{{density}} لكل 2000 كلمة\"\n },\n \"AssessmentPanel\": {\n \"title\": \"التقييمات\",\n \"noAssessments\": \"لا توجد تقييمات بعد. استخدم التوضيح بالذكاء الاصطناعي لتقييم الفقرات.\",\n \"assessmentPlaceholder\": \"اكتب تقييمك هنا...\",\n \"save\": \"حفظ\",\n \"cancel\": \"إلغاء\",\n \"annotateAssessments\": \"توضيح التقييمات\",\n \"instructions\": \"التعليمات\",\n \"optional\": \"(اختياري)\",\n \"instructionsPlaceholder\": \"مثال: تقييم الادعاءات من حيث الدقة والأدلة...\",\n \"annotate\": \"توضيح\",\n \"annotating\": \"جارٍ التوضيح...\",\n \"toneLabel\": \"النبرة\",\n \"toneOptional\": \"(اختياري)\",\n \"toneAnalytical\": \"تحليلي\",\n \"toneCritical\": \"نقدي\",\n \"toneBalanced\": \"متوازن\",\n \"toneConstructive\": \"بنّاء\",\n \"densityLabel\": \"الكثافة\",\n \"densitySparse\": \"متفرق\",\n \"densityDense\": \"كثيف\",\n \"fragmentSelected\": \"تم تحديد جزء\",\n \"imageRegionSelected\": \"تم تحديد منطقة من الصورة\",\n \"complete\": \"اكتمل التوضيح!\",\n \"failed\": \"فشل التوضيح\",\n \"densityPerWords\": \"{{density}} لكل 2000 كلمة\"\n },\n \"TaggingPanel\": {\n \"title\": \"العلامات\",\n \"noTags\": \"لا توجد علامات بعد. استخدم التوضيح بالذكاء الاصطناعي لتحديد الأدوار الهيكلية.\",\n \"noSchemas\": \"لا توجد مخططات وسوم مسجلة لقاعدة المعارف هذه. يجب على مسؤول قاعدة المعارف تسجيل مخطط تحليل هيكلي واحد على الأقل (مثلاً عبر مهارة `register-tag-schemas`) قبل استخدام الوسم.\",\n \"annotateTags\": \"توضيح العلامات\",\n \"selectSchema\": \"اختيار الإطار\",\n \"selectCategories\": \"اختيار الفئات\",\n \"annotate\": \"توضيح\",\n \"annotating\": \"جارٍ التوضيح...\",\n \"cancel\": \"إلغاء\",\n \"selectAll\": \"تحديد الكل\",\n \"deselectAll\": \"إلغاء تحديد الكل\",\n \"categoriesSelected\": \"{count, plural, =0 {لم يتم تحديد فئات} =1 {فئة واحدة محددة} other {# فئات محددة}}\",\n \"createTagForSelection\": \"إنشاء علامة للتحديد\",\n \"selectCategory\": \"اختيار الفئة\",\n \"chooseCategory\": \"اختر فئة...\",\n \"fragmentSelected\": \"تم تحديد جزء\",\n \"imageRegionSelected\": \"تم تحديد منطقة من الصورة\",\n \"complete\": \"اكتمل التوضيح!\",\n \"failed\": \"فشل التوضيح\"\n },\n \"UnifiedAnnotationsPanel\": {\n \"title\": \"التعليقات التوضيحية\",\n \"statistics\": \"الإحصائيات\",\n \"highlight\": \"التمييزات\",\n \"reference\": \"المراجع\",\n \"assessment\": \"التقييمات\",\n \"comment\": \"التعليقات\",\n \"tag\": \"العلامات\",\n \"annotationsFailed\": \"تعذّر تحميل التعليقات التوضيحية.\",\n \"retry\": \"إعادة المحاولة\"\n },\n \"StatisticsPanel\": {\n \"title\": \"الإحصائيات\",\n \"highlights\": \"التمييزات\",\n \"comments\": \"التعليقات\",\n \"assessments\": \"التقييمات\",\n \"tags\": \"العلامات\",\n \"references\": \"المراجع\",\n \"stub\": \"مبدئي\",\n \"resolved\": \"محلول\",\n \"entityTypes\": \"أنواع الكيانات\"\n },\n \"ReferencesPanel\": {\n \"title\": \"المراجع\",\n \"noReferences\": \"لا توجد مراجع بعد. حدد نصًا لإنشاء مراجع لموارد أخرى.\",\n \"outgoingReferences\": \"المراجع الصادرة\",\n \"incomingReferences\": \"المراجع الواردة\",\n \"noIncomingReferences\": \"لا توجد مراجع واردة\",\n \"stub\": \"مرجع مبدئي (غير مربوط)\",\n \"resolved\": \"مرجع محلول (مربوط)\",\n \"open\": \"فتح\",\n \"unlink\": \"إلغاء الربط\",\n \"resolve\": \"حل المرجع\",\n \"cancel\": \"إلغاء\",\n \"createReference\": \"إنشاء مرجع\",\n \"entityTypesOptional\": \"أنواع الكيانات (اختياري)\",\n \"fragmentSelected\": \"تم تحديد جزء\",\n \"imageRegionSelected\": \"تم تحديد منطقة من الصورة\",\n \"annotateReferences\": \"توضيح المراجع\",\n \"selectEntityTypes\": \"أنواع الكيانات:\",\n \"select\": \"تحديد\",\n \"deselect\": \"إلغاء التحديد\",\n \"noEntityTypes\": \"لا توجد أنواع كيانات متاحة\",\n \"typesSelected\": \"{count, plural, =1 {نوع واحد محدد} other {# أنواع محددة}}\",\n \"annotate\": \"توضيح\",\n \"annotating\": \"جارٍ التوضيح...\",\n \"includeDescriptiveReferences\": \"تضمين المراجع الوصفية\",\n \"descriptiveReferencesTooltip\": \"البحث أيضًا عن عبارات مثل 'الرئيس التنفيذي'، 'عملاق التكنولوجيا'، 'الفيزيائي' (بالإضافة إلى الأسماء)\",\n \"annotationProgressTitle\": \"توضيح مراجع الكيانات\",\n \"cancelAnnotation\": \"إلغاء التوضيح\",\n \"found\": \"تم العثور على {{count}}\",\n \"complete\": \"اكتمل التوضيح!\",\n \"failed\": \"فشل التوضيح\",\n \"current\": \"الحالي: {{entityType}}\",\n \"loading\": \"جارٍ التحميل...\",\n \"loadingEllipsis\": \"جارٍ التحميل...\",\n \"untitledResource\": \"مورد بدون عنوان\",\n \"noText\": \"لا يوجد نص\",\n \"incomingReferencesFailed\": \"تعذّر تحميل المراجع الواردة.\",\n \"retry\": \"إعادة المحاولة\",\n \"entityTypesFailed\": \"تعذّر تحميل أنواع الكيانات.\"\n },\n \"KeyboardShortcuts\": {\n \"title\": \"اختصارات لوحة المفاتيح\",\n \"closeDialog\": \"إغلاق مربع الحوار\",\n \"or\": \"أو\",\n \"navigationTitle\": \"التنقل\",\n \"navOpenSearch\": \"فتح البحث الشامل\",\n \"navOpenSearchAlt\": \"فتح البحث الشامل (بديل)\",\n \"navCreateResource\": \"إنشاء مورد جديد\",\n \"navCloseOverlays\": \"إغلاق جميع الطبقات العلوية (ضغط مزدوج)\",\n \"navShowHelp\": \"عرض مساعدة اختصارات لوحة المفاتيح\",\n \"sidebarTitle\": \"الشريط الجانبي للمعرفة\",\n \"sidebarCollapse\": \"طي الشريط الجانبي\",\n \"sidebarExpand\": \"توسيع الشريط الجانبي\",\n \"sidebarPickup\": \"التقاط علامة تبويب المورد (عند التركيز)\",\n \"sidebarMove\": \"نقل علامة تبويب المورد (أثناء السحب)\",\n \"sidebarDrop\": \"إفلات علامة تبويب المورد (أثناء السحب)\",\n \"sidebarCancel\": \"إلغاء عملية السحب\",\n \"annotationsTitle\": \"تعليقات المورد التوضيحية\",\n \"annotHighlight\": \"إنشاء تمييز من التعليق التوضيحي (مباشر)\",\n \"annotReference\": \"فتح نافذة المرجع المنبثقة للتعليق التوضيحي\",\n \"annotDelete\": \"حذف التعليق التوضيحي المركّز عليه\",\n \"annotNavigate\": \"التنقل عبر التعليقات التوضيحية\",\n \"annotNavigateBack\": \"التنقل عبر التعليقات التوضيحية للخلف\",\n \"listsTitle\": \"القوائم والشبكات\",\n \"listsFilterNav\": \"التنقل بين مرشحات أنواع الكيانات\",\n \"listsGridNav\": \"التنقل في شبكة الموارد\",\n \"listsJumpFirst\": \"الانتقال إلى العنصر الأول\",\n \"listsJumpLast\": \"الانتقال إلى العنصر الأخير\",\n \"searchModalTitle\": \"في نافذة البحث\",\n \"searchNav\": \"التنقل في نتائج البحث\",\n \"searchSelect\": \"اختيار النتيجة\",\n \"searchClose\": \"إغلاق البحث\",\n \"modalTitle\": \"عناصر التحكم في النوافذ المنبثقة\",\n \"modalClose\": \"إغلاق النافذة المنبثقة النشطة\",\n \"modalNavForward\": \"التنقل للأمام عبر الأزرار\",\n \"modalNavBackward\": \"التنقل للخلف عبر الأزرار\",\n \"modalActivate\": \"تفعيل الزر المركّز عليه\",\n \"accessibilityTitle\": \"إمكانية الوصول\",\n \"a11ySkipLinks\": \"الانتقال إلى روابط التخطي (عند بداية الصفحة)\",\n \"a11yFollowLink\": \"اتباع رابط التخطي\",\n \"macNote\": \"استخدام اختصارات لوحة مفاتيح Mac. ⌘ هو مفتاح Command.\",\n \"windowsNote\": \"استخدام اختصارات لوحة مفاتيح Windows/Linux. Ctrl هو مفتاح التحكم.\",\n \"footerHint\": \"اضغط {{key}} في أي وقت لعرض هذه المساعدة\",\n \"close\": \"إغلاق\"\n },\n \"AnnotateToolbar\": {\n \"modeGroup\": \"الوضع\",\n \"browse\": \"تصفح\",\n \"annotate\": \"توضيح\",\n \"selectionGroup\": \"الدافع\",\n \"clickGroup\": \"النقر\",\n \"shapeGroup\": \"الشكل\",\n \"none\": \"لا شيء\",\n \"linking\": \"مرجع\",\n \"highlighting\": \"تمييز\",\n \"assessing\": \"تقييم\",\n \"commenting\": \"تعليق\",\n \"tagging\": \"علامة\",\n \"detail\": \"تفصيل\",\n \"follow\": \"متابعة\",\n \"deleting\": \"حذف\",\n \"jsonld\": \"JSON-LD\",\n \"rectangle\": \"مستطيل\",\n \"circle\": \"دائرة\",\n \"polygon\": \"مضلع\"\n },\n \"CollapsibleResourceNavigation\": {\n \"title\": \"التنقل\",\n \"collapseSidebar\": \"طي الشريط الجانبي\",\n \"expandSidebar\": \"توسيع الشريط الجانبي\",\n \"dragToReorder\": \"اسحب لإعادة الترتيب\",\n \"dragToReorderDoc\": \"اسحب لإعادة ترتيب {{name}}\",\n \"closeResource\": \"إغلاق المورد\",\n \"dragInstructions\": \"لإعادة ترتيب الموارد: استخدم Tab للانتقال إلى مورد. اضغط Alt+سهم لأعلى للتحريك لأعلى أو Alt+سهم لأسفل للتحريك لأسفل. للسحب والإفلات: اضغط على شريط المسافة لالتقاط العنصر. استخدم مفاتيح الأسهم لتحريكه. اضغط على شريط المسافة مرة أخرى للإفلات.\"\n },\n \"ResourceViewer\": {\n \"deleteConfirmationTitle\": \"حذف التعليق التوضيحي\",\n \"deleteConfirmationMessage\": \"هل أنت متأكد أنك تريد حذف هذا التعليق التوضيحي؟ لا يمكن التراجع عن هذا الإجراء.\",\n \"deleteConfirmationCancel\": \"إلغاء\",\n \"deleteConfirmationDelete\": \"حذف\"\n },\n \"Settings\": {\n \"title\": \"الإعدادات\",\n \"lineNumbers\": \"أرقام الأسطر\",\n \"lineNumbersVisible\": \"مرئية\",\n \"lineNumbersHidden\": \"مخفية\",\n \"theme\": \"السمة\",\n \"themeLight\": \"فاتح\",\n \"themeDark\": \"داكن\",\n \"themeSystem\": \"النظام\",\n \"themeSystemActive\": \"النظام ({{mode}})\",\n \"themeModeActive\": \"استخدام وضع {{mode}}\",\n \"language\": \"اللغة\",\n \"languageHint\": \"تغيير اللغة في شريط التنقل الرئيسي\",\n \"languageChanging\": \"جارٍ تغيير اللغة...\",\n \"hoverDelay\": \"تأخير التمرير\",\n \"hoverDelayFast\": \"سريع\",\n \"hoverDelaySlow\": \"بطيء\",\n \"hoverDelayDescription\": \"تأخير {{delay}} ميلي ثانية قبل ظهور تأثيرات التمرير\"\n },\n \"AnnotateView\": {},\n \"ResourceGenerate\": {\n \"gatherTitle\": \"تكوين الجمع\",\n \"reviewTitle\": \"مراجعة السياق\",\n \"configureTitle\": \"تكوين التوليد\",\n \"next\": \"التالي\",\n \"back\": \"رجوع\",\n \"cancel\": \"إلغاء\",\n \"gatherIntro\": \"اختر ما تريد تضمينه في السياق المُجمَّع.\",\n \"includeContent\": \"تضمين محتوى المورد\",\n \"includeSummary\": \"تضمين الملخص\",\n \"gatherDepth\": \"العمق\",\n \"gatherMaxResources\": \"الحد الأقصى للموارد\",\n \"gatherButton\": \"جمع\",\n \"excludeLabel\": \"استبعاد من الاسترجاع\",\n \"loadingContext\": \"جارٍ جمع السياق...\",\n \"failedContext\": \"فشل في جمع السياق\",\n \"sourceContextLabel\": \"المورد\",\n \"connectionsLabel\": \"الاتصالات\",\n \"citedByLabel\": \"مُستشهد به من قِبل\",\n \"resourceTitle\": \"عنوان المورد الجديد\",\n \"resourceTitlePlaceholder\": \"عنوان المورد المُولَّد...\",\n \"additionalInstructions\": \"تعليمات إضافية\",\n \"additionalInstructionsPlaceholder\": \"إرشادات اختيارية للتوليد...\",\n \"language\": \"اللغة\",\n \"languageHelp\": \"لغة المورد المُولَّد\",\n \"creativity\": \"الإبداع\",\n \"creativityFocused\": \"مركّز\",\n \"creativityCreative\": \"إبداعي\",\n \"maxLength\": \"الحد الأقصى للطول\",\n \"maxLengthHelp\": \"العدد الأقصى من الرموز\",\n \"generate\": \"توليد\",\n \"progressTitle\": \"جارٍ توليد المورد\",\n \"progressCancel\": \"إلغاء التوليد\",\n \"progressInProgress\": \"جارٍ التوليد…\",\n \"progressComplete\": \"اكتمل التوليد!\",\n \"progressFailed\": \"فشل التوليد\",\n \"maxLengthCeiling\": \"محدود بـ {{maxOutputTokens}} رمزًا بواسطة {{model}}.\"\n },\n \"ReferenceWizard\": {\n \"gatherTitle\": \"السياق المُجمَّع\",\n \"configureGenerationTitle\": \"تكوين التوليد\",\n \"configureSearchTitle\": \"إعدادات البحث\",\n \"searchResultsTitle\": \"نتائج البحث\",\n \"sourceContextLabel\": \"سياق التعليق التوضيحي في المورد\",\n \"connectionsLabel\": \"التعليقات التوضيحية للأقران\",\n \"citedByLabel\": \"المورد مُستشهد به من قِبل\",\n \"userHintLabel\": \"تلميح\",\n \"userHintPlaceholder\": \"صف ما يشير إليه هذا التعليق التوضيحي...\",\n \"loadingContext\": \"جارٍ جمع السياق...\",\n \"failedContext\": \"فشل في جمع السياق\",\n \"cancel\": \"إلغاء\",\n \"generate\": \"توليد\",\n \"compose\": \"تأليف\",\n \"resolutionStrategyLabel\": \"استراتيجية الحل\",\n \"back\": \"رجوع\",\n \"link\": \"رابط\",\n \"score\": \"درجة\",\n \"noResults\": \"لم يتم العثور على نتائج\",\n \"resourceTitle\": \"عنوان المورد\",\n \"resourceTitlePlaceholder\": \"أدخل عنوان المورد...\",\n \"additionalInstructions\": \"تعليمات إضافية\",\n \"additionalInstructionsPlaceholder\": \"أدخل تعليمات إضافية...\",\n \"language\": \"اللغة\",\n \"languageHelp\": \"لغة المحتوى المُولَّد\",\n \"creativity\": \"الإبداع\",\n \"creativityFocused\": \"مركّز\",\n \"creativityCreative\": \"إبداعي\",\n \"maxLength\": \"الحد الأقصى للطول\",\n \"maxLengthHelp\": \"العدد الأقصى من الرموز\",\n \"maxResults\": \"الحد الأقصى للنتائج\",\n \"semanticScoring\": \"التقييم الدلالي\",\n \"semanticScoringHelp\": \"استخدام الذكاء الاصطناعي لتقييم النتائج حسب الصلة الدلالية\",\n \"searching\": \"جاري البحث...\",\n \"search\": \"بحث\",\n \"maxLengthCeiling\": \"محدود بـ {{maxOutputTokens}} رمزًا بواسطة {{model}}.\"\n },\n \"OutcomeToasts\": {\n \"createFailed\": \"تعذّر إنشاء التعليق التوضيحي: {{detail}}\",\n \"deleteFailed\": \"تعذّر حذف التعليق التوضيحي: {{detail}}\",\n \"referenceUpdateFailed\": \"تعذّر تحديث المرجع: {{detail}}\",\n \"unknownError\": \"خطأ غير معروف\",\n \"assistQuiet\": \"لا يزال قيد التنفيذ — لا تحديث منذ عدة دقائق\",\n \"resourceCreatedNamed\": \"تم إنشاء «{{name}}»\",\n \"resourceCreated\": \"تم إنشاء المورد\",\n \"annotationComplete\": \"اكتمل التوسيم\",\n \"annotationFailed\": \"فشل التوسيم\",\n \"generationFailed\": \"فشل التوليد: {{detail}}\",\n \"decline_no-text-layer\": \"هذا الملف صورة ممسوحة تعذّر التعرّف على نصها.\",\n \"decline_encrypted\": \"هذا الملف محمي بكلمة مرور، ولا يمكن قراءة نصه.\",\n \"decline_corrupt\": \"تعذّرت قراءة هذا الملف — قد يكون تالفًا.\",\n \"decline_too-large\": \"هذا المستند أكبر من أن يُستخرج نصه.\",\n \"decline_empty\": \"لا يحتوي هذا المستند على نص لتوسيمه.\"\n }\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../translations/bn.json"],"sourcesContent":["{\n \"AssistProgress\": {\n \"close\": \"বন্ধ করুন\",\n \"codeLoading\": \"লোড হচ্ছে…\",\n \"codeAnalyzing\": \"চিহ্নিত করা হচ্ছে…\",\n \"codeAnalyzingTags\": \"ট্যাগ চিহ্নিত করা হচ্ছে…\",\n \"codeDetectingEntities\": \"চিহ্নিত করা হচ্ছে…\",\n \"codeCreatingAnnotations\": \"{{count}}টি টীকা তৈরি হচ্ছে…\",\n \"codeCreatingTagAnnotations\": \"{{count}}টি ট্যাগ তৈরি হচ্ছে…\",\n \"codeCompleteCreated\": \"{{count}}টি {{kind}} তৈরি হয়েছে\",\n \"codeGeneratingResource\": \"তৈরি হচ্ছে…\",\n \"codeCreatingResource\": \"রিসোর্স তৈরি হচ্ছে…\",\n \"kindHighlight\": \"হাইলাইট\",\n \"kindComment\": \"মন্তব্য\",\n \"kindAssessment\": \"মূল্যায়ন\",\n \"kindReference\": \"রেফারেন্স\",\n \"kindTag\": \"ট্যাগ\",\n \"subject\": \"{{kind}}: {{label}}\",\n \"subjectWithPosition\": \"{{kind}}: {{label}} ({{total}}টির {{done}})\",\n \"paramEntityTypes\": \"সত্তার ধরন\",\n \"paramInstructions\": \"নির্দেশনা\",\n \"paramTone\": \"সুর\",\n \"paramDensity\": \"ঘনত্ব\",\n \"subjectKindEntityType\": \"সত্তার ধরন\",\n \"subjectKindCategory\": \"বিভাগ\",\n \"cancel\": \"বাতিল করুন\",\n \"inProgress\": \"টীকাকরণ হচ্ছে...\"\n },\n \"PdfViewer\": {\n \"loadFailed\": \"PDF লোড করা যায়নি\",\n \"loading\": \"PDF লোড হচ্ছে...\",\n \"next\": \"পরবর্তী\",\n \"pageLoadFailed\": \"পৃষ্ঠা লোড করা যায়নি\",\n \"pageOf\": \"পৃষ্ঠা {{page}} / {{total}}\",\n \"pagination\": \"পৃষ্ঠা নেভিগেশন\",\n \"previous\": \"পূর্ববর্তী\",\n \"viewerLoading\": \"PDF ভিউয়ার লোড হচ্ছে...\"\n },\n \"Toolbar\": {\n \"annotations\": \"টীকাসমূহ\",\n \"history\": \"ইতিহাস\",\n \"resourceInfo\": \"সম্পদের তথ্য\",\n \"collaboration\": \"সহযোগিতা\",\n \"userAccount\": \"ব্যবহারকারীর অ্যাকাউন্ট\",\n \"settings\": \"সেটিংস\",\n \"knowledgeBase\": \"জ্ঞান ভান্ডার\"\n },\n \"ResourceInfoPanel\": {\n \"title\": \"সম্পদের তথ্য\",\n \"locale\": \"লোকেল\",\n \"notSpecified\": \"নির্দিষ্ট করা হয়নি\",\n \"entityTypeTags\": \"সত্তার ধরনের ট্যাগ\",\n \"representation\": \"উপস্থাপনা\",\n \"mediaType\": \"মিডিয়ার ধরন\",\n \"byteSize\": \"আকার\",\n \"storageUri\": \"সঞ্চয়স্থান\",\n \"clone\": \"ক্লোন\",\n \"cloneDescription\": \"এই সম্পদের জন্য একটি শেয়ারযোগ্য ক্লোন লিঙ্ক তৈরি করুন\",\n \"generate\": \"তৈরি করুন\",\n \"generateDescription\": \"এই সম্পদের প্রসঙ্গ থেকে একটি নতুন সম্পদ তৈরি করুন\",\n \"archive\": \"সংরক্ষণাগারভুক্ত করুন\",\n \"archiveDescription\": \"এই সম্পদটিকে সংরক্ষণাগারভুক্ত অবস্থায় স্থানান্তর করুন\",\n \"unarchive\": \"সংরক্ষণাগার থেকে পুনরুদ্ধার করুন\",\n \"unarchiveDescription\": \"এই সম্পদটিকে সক্রিয় অবস্থায় পুনরুদ্ধার করুন\",\n \"provenance\": \"উৎস ও উদ্ভব\",\n \"createdAt\": \"তৈরির তারিখ\",\n \"modifiedAt\": \"পরিবর্তনের তারিখ\",\n \"attributedTo\": \"সম্পাদককৃত\",\n \"derivedFrom\": \"থেকে উৎপন্ন\"\n },\n \"CollaborationPanel\": {\n \"title\": \"সহযোগিতা\",\n \"connectionStatus\": \"সংযোগের অবস্থা\",\n \"live\": \"সরাসরি\",\n \"disconnected\": \"সংযোগ বিচ্ছিন্ন\",\n \"events\": \"{{count}} ঘটনা\",\n \"lastSync\": \"সর্বশেষ সিঙ্ক:\",\n \"noActivity\": \"এখনো কোনো কার্যকলাপ নেই\",\n \"justNow\": \"এইমাত্র\",\n \"secondsAgo\": \"{{count}} সেকেন্ড আগে\",\n \"minuteAgo\": \"১ মিনিট আগে\",\n \"minutesAgo\": \"{{count}} মিনিট আগে\",\n \"hourAgo\": \"১ ঘণ্টা আগে\",\n \"hoursAgo\": \"{{count}} ঘণ্টা আগে\",\n \"realtimeActive\": \"রিয়েল-টাইম আপডেট সক্রিয় আছে\",\n \"reconnecting\": \"সার্ভারে পুনরায় সংযোগ হচ্ছে...\",\n \"sharing\": \"শেয়ারিং\",\n \"collaborationComingSoon\": \"সহযোগিতা বৈশিষ্ট্য শীঘ্রই আসছে\",\n \"collaborators\": \"সহযোগীরা\",\n \"ceilings\": \"{{contextTokens}} ইনপুট / {{maxOutputTokens}} আউটপুট\",\n \"sharedWindow\": \"{{contextTokens}} উইন্ডো\"\n },\n \"AnnotationHistory\": {\n \"history\": \"ইতিহাস\",\n \"loading\": \"লোড হচ্ছে...\",\n \"user\": \"ব্যবহারকারী\",\n \"viewOriginal\": \"মূল দেখুন\",\n \"viewAnnotation\": \"টীকা দেখুন: {{content}}\",\n \"resourceCreated\": \"সম্পদ তৈরি হয়েছে\",\n \"resourceCloned\": \"ক্লোন করা হয়েছে\",\n \"resourceArchived\": \"সংরক্ষণাগারভুক্ত\",\n \"resourceUnarchived\": \"সংরক্ষণাগার থেকে পুনরুদ্ধারকৃত\",\n \"highlightAdded\": \"হাইলাইট যোগ করা হয়েছে\",\n \"highlightRemoved\": \"হাইলাইট অপসারিত হয়েছে\",\n \"referenceCreated\": \"রেফারেন্স তৈরি হয়েছে\",\n \"referenceResolved\": \"রেফারেন্স সমাধান হয়েছে\",\n \"referenceDeleted\": \"রেফারেন্স মুছে ফেলা হয়েছে\",\n \"entitytagAdded\": \"ট্যাগ যোগ করা হয়েছে\",\n \"entitytagRemoved\": \"ট্যাগ অপসারিত হয়েছে\",\n \"assessmentAdded\": \"মূল্যায়ন যোগ করা হয়েছে\",\n \"assessmentRemoved\": \"মূল্যায়ন অপসারিত হয়েছে\",\n \"annotationAdded\": \"টীকা যোগ করা হয়েছে\",\n \"annotationRemoved\": \"টীকা অপসারিত হয়েছে\",\n \"annotationBodyUpdated\": \"টীকা আপডেট হয়েছে\",\n \"jobEvent\": \"কাজের ঘটনা\",\n \"embeddingComputed\": \"এমবেডিং গণনা করা হয়েছে\",\n \"justNow\": \"এইমাত্র\",\n \"minutesAgo\": \"{{count}} মি. আগে\",\n \"hoursAgo\": \"{{count}} ঘ. আগে\",\n \"daysAgo\": \"{{count}} দি. আগে\",\n \"failed\": \"ইতিহাস লোড করা যায়নি।\",\n \"retry\": \"আবার চেষ্টা করুন\"\n },\n \"CommentsPanel\": {\n \"title\": \"মন্তব্যসমূহ\",\n \"noComments\": \"এখনো কোনো মন্তব্য নেই। পাঠ্য নির্বাচন করুন এবং একটি যোগ করতে মন্তব্যে ক্লিক করুন।\",\n \"commentPlaceholder\": \"এখানে আপনার মন্তব্য লিখুন...\",\n \"save\": \"সংরক্ষণ করুন\",\n \"cancel\": \"বাতিল করুন\",\n \"edit\": \"সম্পাদনা করুন\",\n \"annotateComments\": \"মন্তব্য টীকাকরণ\",\n \"instructions\": \"নির্দেশনা\",\n \"optional\": \"(ঐচ্ছিক)\",\n \"instructionsPlaceholder\": \"যেমন, প্রযুক্তিগত পরিভাষায় মনোযোগ দিন...\",\n \"annotate\": \"টীকাকরণ\",\n \"annotating\": \"টীকাকরণ হচ্ছে...\",\n \"toneLabel\": \"সুর\",\n \"toneOptional\": \"(ঐচ্ছিক)\",\n \"toneScholarly\": \"পাণ্ডিত্যপূর্ণ\",\n \"toneExplanatory\": \"ব্যাখ্যামূলক\",\n \"toneConversational\": \"কথোপকথনমূলক\",\n \"toneTechnical\": \"প্রযুক্তিগত\",\n \"densityLabel\": \"ঘনত্ব\",\n \"densitySparse\": \"বিরল\",\n \"densityDense\": \"ঘন\",\n \"fragmentSelected\": \"অংশ নির্বাচিত\",\n \"imageRegionSelected\": \"ছবির অঞ্চল নির্বাচিত\",\n \"complete\": \"টীকাকরণ সম্পূর্ণ!\",\n \"failed\": \"টীকাকরণ ব্যর্থ\",\n \"densityPerWords\": \"প্রতি ২০০০ শব্দে {{density}}\"\n },\n \"HighlightPanel\": {\n \"title\": \"হাইলাইটসমূহ\",\n \"noHighlights\": \"এখনো কোনো হাইলাইট নেই। গুরুত্বপূর্ণ অনুচ্ছেদ খুঁজতে AI টীকাকরণ ব্যবহার করুন।\",\n \"annotateHighlights\": \"হাইলাইট টীকাকরণ\",\n \"instructions\": \"নির্দেশনা\",\n \"optional\": \"(ঐচ্ছিক)\",\n \"instructionsPlaceholder\": \"যেমন, মূল প্রযুক্তিগত ধারণাগুলিতে মনোযোগ দিন...\",\n \"annotate\": \"টীকাকরণ\",\n \"annotating\": \"টীকাকরণ হচ্ছে...\",\n \"cancel\": \"বাতিল করুন\",\n \"densityLabel\": \"ঘনত্ব\",\n \"densitySparse\": \"বিরল\",\n \"densityDense\": \"ঘন\",\n \"complete\": \"টীকাকরণ সম্পূর্ণ!\",\n \"failed\": \"টীকাকরণ ব্যর্থ\",\n \"densityPerWords\": \"প্রতি ২০০০ শব্দে {{density}}\"\n },\n \"AssessmentPanel\": {\n \"title\": \"মূল্যায়নসমূহ\",\n \"noAssessments\": \"এখনো কোনো মূল্যায়ন নেই। অনুচ্ছেদ মূল্যায়ন করতে AI টীকাকরণ ব্যবহার করুন।\",\n \"assessmentPlaceholder\": \"এখানে আপনার মূল্যায়ন লিখুন...\",\n \"save\": \"সংরক্ষণ করুন\",\n \"cancel\": \"বাতিল করুন\",\n \"annotateAssessments\": \"মূল্যায়ন টীকাকরণ\",\n \"instructions\": \"নির্দেশনা\",\n \"optional\": \"(ঐচ্ছিক)\",\n \"instructionsPlaceholder\": \"যেমন, সঠিকতা এবং প্রমাণের জন্য দাবিগুলি মূল্যায়ন করুন...\",\n \"annotate\": \"টীকাকরণ\",\n \"annotating\": \"টীকাকরণ হচ্ছে...\",\n \"toneLabel\": \"সুর\",\n \"toneOptional\": \"(ঐচ্ছিক)\",\n \"toneAnalytical\": \"বিশ্লেষণাত্মক\",\n \"toneCritical\": \"সমালোচনামূলক\",\n \"toneBalanced\": \"ভারসাম্যপূর্ণ\",\n \"toneConstructive\": \"গঠনমূলক\",\n \"densityLabel\": \"ঘনত্ব\",\n \"densitySparse\": \"বিরল\",\n \"densityDense\": \"ঘন\",\n \"fragmentSelected\": \"অংশ নির্বাচিত\",\n \"imageRegionSelected\": \"ছবির অঞ্চল নির্বাচিত\",\n \"complete\": \"টীকাকরণ সম্পূর্ণ!\",\n \"failed\": \"টীকাকরণ ব্যর্থ\",\n \"densityPerWords\": \"প্রতি ২০০০ শব্দে {{density}}\"\n },\n \"TaggingPanel\": {\n \"title\": \"ট্যাগসমূহ\",\n \"noTags\": \"এখনো কোনো ট্যাগ নেই। কাঠামোগত ভূমিকা শনাক্ত করতে AI টীকাকরণ ব্যবহার করুন।\",\n \"noSchemas\": \"এই জ্ঞান ভাণ্ডারের জন্য কোনো ট্যাগ স্কিমা নিবন্ধিত নেই। ট্যাগিং ব্যবহার করার আগে একজন KB প্রশাসককে কমপক্ষে একটি কাঠামোগত-বিশ্লেষণ স্কিমা নিবন্ধন করতে হবে (যেমন `register-tag-schemas` দক্ষতার মাধ্যমে)।\",\n \"annotateTags\": \"ট্যাগ টীকাকরণ\",\n \"selectSchema\": \"ফ্রেমওয়ার্ক নির্বাচন করুন\",\n \"selectCategories\": \"বিভাগ নির্বাচন করুন\",\n \"annotate\": \"টীকাকরণ\",\n \"annotating\": \"টীকাকরণ হচ্ছে...\",\n \"cancel\": \"বাতিল করুন\",\n \"selectAll\": \"সমস্ত নির্বাচন করুন\",\n \"deselectAll\": \"সমস্ত অনির্বাচন করুন\",\n \"categoriesSelected\": \"{count, plural, =0 {কোনো বিভাগ নির্বাচিত নয়} =1 {১টি বিভাগ নির্বাচিত} other {# টি বিভাগ নির্বাচিত}}\",\n \"createTagForSelection\": \"নির্বাচনের জন্য ট্যাগ তৈরি করুন\",\n \"selectCategory\": \"বিভাগ নির্বাচন করুন\",\n \"chooseCategory\": \"একটি বিভাগ বেছে নিন...\",\n \"fragmentSelected\": \"অংশ নির্বাচিত\",\n \"imageRegionSelected\": \"ছবির অঞ্চল নির্বাচিত\",\n \"complete\": \"টীকাকরণ সম্পূর্ণ!\",\n \"failed\": \"টীকাকরণ ব্যর্থ\"\n },\n \"UnifiedAnnotationsPanel\": {\n \"title\": \"টীকাসমূহ\",\n \"statistics\": \"পরিসংখ্যান\",\n \"highlight\": \"হাইলাইটসমূহ\",\n \"reference\": \"রেফারেন্সসমূহ\",\n \"assessment\": \"মূল্যায়নসমূহ\",\n \"comment\": \"মন্তব্যসমূহ\",\n \"tag\": \"ট্যাগসমূহ\",\n \"annotationsFailed\": \"টীকা লোড করা যায়নি।\",\n \"retry\": \"আবার চেষ্টা করুন\"\n },\n \"StatisticsPanel\": {\n \"title\": \"পরিসংখ্যান\",\n \"highlights\": \"হাইলাইটসমূহ\",\n \"comments\": \"মন্তব্যসমূহ\",\n \"assessments\": \"মূল্যায়নসমূহ\",\n \"tags\": \"ট্যাগসমূহ\",\n \"references\": \"রেফারেন্সসমূহ\",\n \"stub\": \"অসম্পূর্ণ\",\n \"resolved\": \"সমাধানকৃত\",\n \"entityTypes\": \"সত্তার ধরন\"\n },\n \"ReferencesPanel\": {\n \"title\": \"রেফারেন্সসমূহ\",\n \"noReferences\": \"এখনো কোনো রেফারেন্স নেই। অন্যান্য সম্পদের রেফারেন্স তৈরি করতে পাঠ্য নির্বাচন করুন।\",\n \"outgoingReferences\": \"বহির্গামী রেফারেন্স\",\n \"incomingReferences\": \"আগত রেফারেন্স\",\n \"noIncomingReferences\": \"কোনো আগত রেফারেন্স নেই\",\n \"stub\": \"অসম্পূর্ণ রেফারেন্স (সংযুক্ত নয়)\",\n \"resolved\": \"সমাধানকৃত রেফারেন্স (সংযুক্ত)\",\n \"open\": \"খুলুন\",\n \"unlink\": \"সংযোগ বিচ্ছিন্ন করুন\",\n \"resolve\": \"রেফারেন্স সমাধান করুন\",\n \"cancel\": \"বাতিল করুন\",\n \"createReference\": \"রেফারেন্স তৈরি করুন\",\n \"entityTypesOptional\": \"সত্তার ধরন (ঐচ্ছিক)\",\n \"fragmentSelected\": \"অংশ নির্বাচিত\",\n \"imageRegionSelected\": \"ছবির অঞ্চল নির্বাচিত\",\n \"annotateReferences\": \"রেফারেন্স টীকাকরণ\",\n \"selectEntityTypes\": \"সত্তার ধরন:\",\n \"select\": \"নির্বাচন করুন\",\n \"deselect\": \"অনির্বাচন করুন\",\n \"noEntityTypes\": \"কোনো সত্তার ধরন উপলব্ধ নেই\",\n \"typesSelected\": \"{count, plural, =1 {১টি ধরন নির্বাচিত} other {# টি ধরন নির্বাচিত}}\",\n \"annotate\": \"টীকাকরণ\",\n \"annotating\": \"টীকাকরণ হচ্ছে...\",\n \"includeDescriptiveReferences\": \"বর্ণনামূলক রেফারেন্স অন্তর্ভুক্ত করুন\",\n \"descriptiveReferencesTooltip\": \"নামের পাশাপাশি 'সিইও', 'প্রযুক্তি জায়ান্ট', 'পদার্থবিদ' এর মতো বাক্যাংশও খুঁজুন\",\n \"annotationProgressTitle\": \"সত্তা রেফারেন্স টীকাকরণ হচ্ছে\",\n \"cancelAnnotation\": \"টীকাকরণ বাতিল করুন\",\n \"found\": \"{{count}} টি পাওয়া গেছে\",\n \"complete\": \"টীকাকরণ সম্পূর্ণ!\",\n \"failed\": \"টীকাকরণ ব্যর্থ\",\n \"current\": \"বর্তমান: {{entityType}}\",\n \"loading\": \"লোড হচ্ছে...\",\n \"loadingEllipsis\": \"লোড হচ্ছে...\",\n \"untitledResource\": \"শিরোনামবিহীন সম্পদ\",\n \"noText\": \"কোনো পাঠ্য নেই\",\n \"incomingReferencesFailed\": \"ইনকামিং রেফারেন্স লোড করা যায়নি।\",\n \"retry\": \"আবার চেষ্টা করুন\",\n \"entityTypesFailed\": \"সত্তার ধরন লোড করা যায়নি।\"\n },\n \"KeyboardShortcuts\": {\n \"title\": \"কীবোর্ড শর্টকাট\",\n \"closeDialog\": \"ডায়ালগ বন্ধ করুন\",\n \"or\": \"অথবা\",\n \"navigationTitle\": \"নেভিগেশন\",\n \"navOpenSearch\": \"গ্লোবাল অনুসন্ধান খুলুন\",\n \"navOpenSearchAlt\": \"গ্লোবাল অনুসন্ধান খুলুন (বিকল্প)\",\n \"navCreateResource\": \"নতুন সম্পদ তৈরি করুন\",\n \"navCloseOverlays\": \"সমস্ত ওভারলে বন্ধ করুন (দুইবার চাপুন)\",\n \"navShowHelp\": \"কীবোর্ড শর্টকাট সাহায্য দেখান\",\n \"sidebarTitle\": \"জ্ঞান সাইডবার\",\n \"sidebarCollapse\": \"সাইডবার সংকুচিত করুন\",\n \"sidebarExpand\": \"সাইডবার প্রসারিত করুন\",\n \"sidebarPickup\": \"সম্পদ ট্যাব তুলে নিন (ফোকাসে থাকলে)\",\n \"sidebarMove\": \"সম্পদ ট্যাব সরান (টানাটানির সময়)\",\n \"sidebarDrop\": \"সম্পদ ট্যাব ছেড়ে দিন (টানাটানির সময়)\",\n \"sidebarCancel\": \"টানাটানি কার্যক্রম বাতিল করুন\",\n \"annotationsTitle\": \"সম্পদ টীকাসমূহ\",\n \"annotHighlight\": \"টীকা থেকে হাইলাইট তৈরি করুন (সরাসরি)\",\n \"annotReference\": \"টীকার জন্য রেফারেন্স পপআপ খুলুন\",\n \"annotDelete\": \"ফোকাসকৃত টীকা মুছে ফেলুন\",\n \"annotNavigate\": \"টীকাসমূহের মধ্যে নেভিগেট করুন\",\n \"annotNavigateBack\": \"টীকাসমূহে পেছনে নেভিগেট করুন\",\n \"listsTitle\": \"তালিকা এবং গ্রিড\",\n \"listsFilterNav\": \"সত্তার ধরনের ফিল্টার নেভিগেট করুন\",\n \"listsGridNav\": \"সম্পদ গ্রিড নেভিগেট করুন\",\n \"listsJumpFirst\": \"প্রথম আইটেমে যান\",\n \"listsJumpLast\": \"শেষ আইটেমে যান\",\n \"searchModalTitle\": \"অনুসন্ধান মোডালে\",\n \"searchNav\": \"অনুসন্ধান ফলাফল নেভিগেট করুন\",\n \"searchSelect\": \"ফলাফল নির্বাচন করুন\",\n \"searchClose\": \"অনুসন্ধান বন্ধ করুন\",\n \"modalTitle\": \"মোডাল নিয়ন্ত্রণ\",\n \"modalClose\": \"সক্রিয় মোডাল বন্ধ করুন\",\n \"modalNavForward\": \"বোতামগুলির মধ্যে সামনে নেভিগেট করুন\",\n \"modalNavBackward\": \"বোতামগুলির মধ্যে পেছনে নেভিগেট করুন\",\n \"modalActivate\": \"ফোকাসকৃত বোতাম সক্রিয় করুন\",\n \"accessibilityTitle\": \"অভিগম্যতা\",\n \"a11ySkipLinks\": \"স্কিপ লিঙ্কে নেভিগেট করুন (পৃষ্ঠার শুরুতে থাকলে)\",\n \"a11yFollowLink\": \"স্কিপ লিঙ্ক অনুসরণ করুন\",\n \"macNote\": \"Mac কীবোর্ড শর্টকাট ব্যবহার হচ্ছে। ⌘ হলো Command কী।\",\n \"windowsNote\": \"Windows/Linux কীবোর্ড শর্টকাট ব্যবহার হচ্ছে। Ctrl হলো Control কী।\",\n \"footerHint\": \"এই সাহায্য দেখাতে যেকোনো সময় {{key}} চাপুন\",\n \"close\": \"বন্ধ করুন\"\n },\n \"AnnotateToolbar\": {\n \"modeGroup\": \"মোড\",\n \"browse\": \"ব্রাউজ\",\n \"annotate\": \"টীকাকরণ\",\n \"selectionGroup\": \"উদ্দেশ্য\",\n \"clickGroup\": \"ক্লিক\",\n \"shapeGroup\": \"আকৃতি\",\n \"none\": \"কিছু নয়\",\n \"linking\": \"রেফারেন্স\",\n \"highlighting\": \"হাইলাইট\",\n \"assessing\": \"মূল্যায়ন\",\n \"commenting\": \"মন্তব্য\",\n \"tagging\": \"ট্যাগ\",\n \"detail\": \"বিস্তারিত\",\n \"follow\": \"অনুসরণ\",\n \"deleting\": \"মুছে ফেলুন\",\n \"jsonld\": \"JSON-LD\",\n \"rectangle\": \"আয়তক্ষেত্র\",\n \"circle\": \"বৃত্ত\",\n \"polygon\": \"বহুভুজ\"\n },\n \"CollapsibleResourceNavigation\": {\n \"title\": \"নেভিগেশন\",\n \"collapseSidebar\": \"সাইডবার সংকুচিত করুন\",\n \"expandSidebar\": \"সাইডবার প্রসারিত করুন\",\n \"dragToReorder\": \"পুনর্বিন্যাস করতে টানুন\",\n \"dragToReorderDoc\": \"{{name}} পুনর্বিন্যাস করতে টানুন\",\n \"closeResource\": \"সম্পদ বন্ধ করুন\",\n \"dragInstructions\": \"সম্পদ পুনর্বিন্যাস করতে: একটি সম্পদে নেভিগেট করতে Tab ব্যবহার করুন। উপরে যেতে Alt+উপরের তীর বা নিচে যেতে Alt+নিচের তীর চাপুন। টানা এবং ছাড়ার জন্য: আইটেম তুলে নিতে স্পেসবার চাপুন। সরাতে তীর কী ব্যবহার করুন। ছেড়ে দিতে আবার স্পেসবার চাপুন।\"\n },\n \"ResourceViewer\": {\n \"deleteConfirmationTitle\": \"টীকা মুছে ফেলুন\",\n \"deleteConfirmationMessage\": \"আপনি কি নিশ্চিতভাবে এই টীকাটি মুছে ফেলতে চান? এই কাজটি পূর্বাবস্থায় ফেরানো যাবে না।\",\n \"deleteConfirmationCancel\": \"বাতিল করুন\",\n \"deleteConfirmationDelete\": \"মুছে ফেলুন\"\n },\n \"Settings\": {\n \"title\": \"সেটিংস\",\n \"lineNumbers\": \"লাইন নম্বর\",\n \"lineNumbersVisible\": \"দৃশ্যমান\",\n \"lineNumbersHidden\": \"লুকানো\",\n \"theme\": \"থিম\",\n \"themeLight\": \"হালকা\",\n \"themeDark\": \"গাঢ়\",\n \"themeSystem\": \"সিস্টেম\",\n \"themeSystemActive\": \"সিস্টেম ({{mode}})\",\n \"themeModeActive\": \"{{mode}} মোড ব্যবহার হচ্ছে\",\n \"language\": \"ভাষা\",\n \"languageHint\": \"প্রধান নেভিগেশনে ভাষা পরিবর্তন করুন\",\n \"languageChanging\": \"ভাষা পরিবর্তন হচ্ছে...\",\n \"hoverDelay\": \"হোভার বিলম্ব\",\n \"hoverDelayFast\": \"দ্রুত\",\n \"hoverDelaySlow\": \"ধীর\",\n \"hoverDelayDescription\": \"হোভার প্রভাব প্রদর্শনের আগে {{delay}}মি.সে. বিলম্ব\"\n },\n \"AnnotateView\": {},\n \"ResourceGenerate\": {\n \"gatherTitle\": \"সংগ্রহ কনফিগার করুন\",\n \"reviewTitle\": \"প্রসঙ্গ পর্যালোচনা করুন\",\n \"configureTitle\": \"জেনারেশন কনফিগার করুন\",\n \"next\": \"পরবর্তী\",\n \"back\": \"পিছনে\",\n \"cancel\": \"বাতিল করুন\",\n \"gatherIntro\": \"সংগৃহীত প্রসঙ্গে কী অন্তর্ভুক্ত করবেন তা বেছে নিন।\",\n \"includeContent\": \"সম্পদের বিষয়বস্তু অন্তর্ভুক্ত করুন\",\n \"includeSummary\": \"সারসংক্ষেপ অন্তর্ভুক্ত করুন\",\n \"gatherDepth\": \"গভীরতা\",\n \"gatherMaxResources\": \"সর্বোচ্চ সম্পদ\",\n \"gatherButton\": \"সংগ্রহ করুন\",\n \"excludeLabel\": \"পুনরুদ্ধার থেকে বাদ দিন\",\n \"loadingContext\": \"প্রসঙ্গ সংগ্রহ হচ্ছে...\",\n \"failedContext\": \"প্রসঙ্গ সংগ্রহ ব্যর্থ\",\n \"sourceContextLabel\": \"সম্পদ\",\n \"connectionsLabel\": \"সংযোগসমূহ\",\n \"citedByLabel\": \"উদ্ধৃতকারী\",\n \"resourceTitle\": \"নতুন সম্পদের শিরোনাম\",\n \"resourceTitlePlaceholder\": \"তৈরি করা সম্পদের শিরোনাম...\",\n \"additionalInstructions\": \"অতিরিক্ত নির্দেশনা\",\n \"additionalInstructionsPlaceholder\": \"তৈরির জন্য ঐচ্ছিক নির্দেশনা...\",\n \"language\": \"ভাষা\",\n \"languageHelp\": \"তৈরি করা সম্পদের ভাষা\",\n \"creativity\": \"সৃজনশীলতা\",\n \"creativityFocused\": \"কেন্দ্রীভূত\",\n \"creativityCreative\": \"সৃজনশীল\",\n \"maxLength\": \"সর্বোচ্চ দৈর্ঘ্য\",\n \"maxLengthHelp\": \"সর্বোচ্চ টোকেন সংখ্যা\",\n \"generate\": \"তৈরি করুন\",\n \"progressTitle\": \"সম্পদ তৈরি হচ্ছে\",\n \"progressCancel\": \"তৈরি বাতিল করুন\",\n \"progressInProgress\": \"তৈরি হচ্ছে…\",\n \"progressComplete\": \"তৈরি সম্পূর্ণ!\",\n \"progressFailed\": \"তৈরি ব্যর্থ\",\n \"maxLengthCeiling\": \"{{model}} দ্বারা {{maxOutputTokens}} টোকেনে সীমিত।\"\n },\n \"ReferenceWizard\": {\n \"gatherTitle\": \"সংগৃহীত প্রসঙ্গ\",\n \"configureGenerationTitle\": \"জেনারেশন কনফিগার করুন\",\n \"configureSearchTitle\": \"অনুসন্ধান কনফিগার করুন\",\n \"searchResultsTitle\": \"অনুসন্ধান ফলাফল\",\n \"sourceContextLabel\": \"সম্পদে টীকার প্রসঙ্গ\",\n \"connectionsLabel\": \"সমকক্ষ টীকাসমূহ\",\n \"citedByLabel\": \"সম্পদ উদ্ধৃতকারী\",\n \"userHintLabel\": \"ইঙ্গিত\",\n \"userHintPlaceholder\": \"এই টীকাটি কী বোঝায় তা বর্ণনা করুন...\",\n \"loadingContext\": \"প্রসঙ্গ সংগ্রহ হচ্ছে...\",\n \"failedContext\": \"প্রসঙ্গ সংগ্রহ ব্যর্থ\",\n \"cancel\": \"বাতিল করুন\",\n \"generate\": \"তৈরি করুন\",\n \"compose\": \"রচনা করুন\",\n \"resolutionStrategyLabel\": \"রেজোলিউশন কৌশল\",\n \"back\": \"পিছনে\",\n \"link\": \"লিঙ্ক\",\n \"score\": \"স্কোর\",\n \"noResults\": \"কোনো ফলাফল পাওয়া যায়নি\",\n \"resourceTitle\": \"সম্পদের শিরোনাম\",\n \"resourceTitlePlaceholder\": \"সম্পদের শিরোনাম লিখুন...\",\n \"additionalInstructions\": \"অতিরিক্ত নির্দেশনা\",\n \"additionalInstructionsPlaceholder\": \"অতিরিক্ত নির্দেশনা লিখুন...\",\n \"language\": \"ভাষা\",\n \"languageHelp\": \"তৈরি করা বিষয়বস্তুর ভাষা\",\n \"creativity\": \"সৃজনশীলতা\",\n \"creativityFocused\": \"কেন্দ্রীভূত\",\n \"creativityCreative\": \"সৃজনশীল\",\n \"maxLength\": \"সর্বোচ্চ দৈর্ঘ্য\",\n \"maxLengthHelp\": \"সর্বোচ্চ টোকেন সংখ্যা\",\n \"maxResults\": \"সর্বোচ্চ ফলাফল\",\n \"semanticScoring\": \"অর্থগত স্কোরিং\",\n \"semanticScoringHelp\": \"অর্থগত প্রাসঙ্গিকতা অনুযায়ী ফলাফল স্কোর করতে AI ব্যবহার করুন\",\n \"searching\": \"অনুসন্ধান করা হচ্ছে...\",\n \"search\": \"অনুসন্ধান\",\n \"maxLengthCeiling\": \"{{model}} দ্বারা {{maxOutputTokens}} টোকেনে সীমিত।\"\n },\n \"OutcomeToasts\": {\n \"createFailed\": \"টীকা তৈরি করা যায়নি: {{detail}}\",\n \"deleteFailed\": \"টীকা মুছে ফেলা যায়নি: {{detail}}\",\n \"referenceUpdateFailed\": \"রেফারেন্স আপডেট করা যায়নি: {{detail}}\",\n \"unknownError\": \"অজানা ত্রুটি\",\n \"assistQuiet\": \"এখনও চলছে — কয়েক মিনিট ধরে কোনো আপডেট নেই\",\n \"resourceCreatedNamed\": \"“{{name}}” তৈরি হয়েছে\",\n \"resourceCreated\": \"রিসোর্স তৈরি হয়েছে\",\n \"annotationComplete\": \"টীকা সম্পূর্ণ\",\n \"annotationFailed\": \"টীকা ব্যর্থ হয়েছে\",\n \"generationFailed\": \"জেনারেশন ব্যর্থ: {{detail}}\",\n \"decline_no-text-layer\": \"এই PDF একটি স্ক্যান, এর লেখা শনাক্ত করা যায়নি।\",\n \"decline_encrypted\": \"এই PDF পাসওয়ার্ড-সুরক্ষিত, লেখা পড়া যাচ্ছে না।\",\n \"decline_corrupt\": \"এই PDF পড়া যায়নি — ফাইলটি ক্ষতিগ্রস্ত হতে পারে।\",\n \"decline_too-large\": \"এই নথিটি এত বড় যে লেখা বের করা যাচ্ছে না।\",\n \"decline_empty\": \"এই নথিতে টীকা দেওয়ার মতো কোনো লেখা নেই।\"\n }\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/contexts/TranslationContext.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, useContext, ReactNode, useState, useEffect, useMemo } from 'react';\nimport type { TranslationManager } from '../types/TranslationManager';\n\n// Static import for default English only - always needed as fallback\nimport enTranslations from '../../translations/en.json';\n\nconst TranslationContext = createContext<TranslationManager | null>(null);\n\n// Cache for dynamically loaded translations\nconst translationCache = new Map<string, any>();\n\n/**\n * Process ICU MessageFormat plural syntax\n * Supports: {count, plural, =0 {text} =1 {text} other {text}}\n */\nfunction processPluralFormat(text: string, params: Record<string, any>): string {\n // Match {paramName, plural, ...} with proper brace counting\n const pluralMatch = text.match(/\\{(\\w+),\\s*plural,\\s*/);\n if (!pluralMatch) {\n return text;\n }\n\n const paramName = pluralMatch[1];\n const count = params[paramName];\n if (count === undefined) {\n return text;\n }\n\n // Find the matching closing brace by counting\n let startPos = pluralMatch[0].length;\n let braceCount = 1; // We're inside the first {\n let endPos = startPos;\n\n for (let i = startPos; i < text.length; i++) {\n if (text[i] === '{') braceCount++;\n else if (text[i] === '}') {\n braceCount--;\n if (braceCount === 0) {\n endPos = i;\n break;\n }\n }\n }\n\n const pluralCases = text.substring(startPos, endPos);\n\n // Parse plural cases: =0 {text} =1 {text} other {text}\n const cases: Record<string, string> = {};\n const caseRegex = /(?:=(\\d+)|(\\w+))\\s*\\{([^}]+)\\}/g;\n let caseMatch;\n\n while ((caseMatch = caseRegex.exec(pluralCases)) !== null) {\n const [, exactNumber, keyword, textContent] = caseMatch;\n const key = exactNumber !== undefined ? `=${exactNumber}` : keyword;\n cases[key] = textContent;\n }\n\n // Select appropriate case\n const exactMatch = cases[`=${count}`];\n if (exactMatch !== undefined) {\n const result = exactMatch.replace(/#/g, String(count));\n return text.substring(0, pluralMatch.index!) + result + text.substring(endPos + 1);\n }\n\n const otherCase = cases['other'];\n if (otherCase !== undefined) {\n const result = otherCase.replace(/#/g, String(count));\n return text.substring(0, pluralMatch.index!) + result + text.substring(endPos + 1);\n }\n\n return text;\n}\n\n// List of available locales (can be extended without importing all files)\nexport const AVAILABLE_LOCALES = [\n 'ar', // Arabic\n 'bn', // Bengali\n 'cs', // Czech\n 'da', // Danish\n 'de', // German\n 'el', // Greek\n 'en', // English\n 'es', // Spanish\n 'fa', // Persian/Farsi\n 'fi', // Finnish\n 'fr', // French\n 'he', // Hebrew\n 'hi', // Hindi\n 'id', // Indonesian\n 'it', // Italian\n 'ja', // Japanese\n 'ko', // Korean\n 'ms', // Malay\n 'nl', // Dutch\n 'no', // Norwegian\n 'pl', // Polish\n 'pt', // Portuguese\n 'ro', // Romanian\n 'sv', // Swedish\n 'th', // Thai\n 'tr', // Turkish\n 'uk', // Ukrainian\n 'vi', // Vietnamese\n 'zh', // Chinese\n] as const;\nexport type AvailableLocale = typeof AVAILABLE_LOCALES[number];\n\n// Lazy load translations for a specific locale\nasync function loadTranslations(locale: string): Promise<any> {\n // Check cache first\n if (translationCache.has(locale)) {\n return translationCache.get(locale);\n }\n\n // English is already loaded statically\n if (locale === 'en') {\n translationCache.set('en', enTranslations);\n return enTranslations;\n }\n\n try {\n // Dynamic import for all other locales\n const translations = await import(`../../translations/${locale}.json`);\n const translationData = translations.default || translations;\n translationCache.set(locale, translationData);\n return translationData;\n } catch (error) {\n console.error(`Failed to load translations for locale: ${locale}`, error);\n // Fall back to English\n return enTranslations;\n }\n}\n\n// Default English translation manager (using static import)\nconst defaultTranslationManager: TranslationManager = {\n t: (namespace: string, key: string, params?: Record<string, any>) => {\n const translations = enTranslations as Record<string, Record<string, string>>;\n const translation = translations[namespace]?.[key];\n\n if (!translation) {\n console.warn(`Translation not found for ${namespace}.${key}`);\n return `${namespace}.${key}`;\n }\n\n // Handle parameter interpolation and plural format\n if (params && typeof translation === 'string') {\n let result = translation;\n // First process plural format\n result = processPluralFormat(result, params);\n // Then handle simple parameter interpolation\n Object.entries(params).forEach(([paramKey, paramValue]) => {\n result = result.replace(new RegExp(`\\\\{\\\\{${paramKey}\\\\}\\\\}`, 'g'), String(paramValue));\n });\n return result;\n }\n\n return translation;\n },\n};\n\nexport interface TranslationProviderProps {\n /**\n * Option 1: Provide a complete TranslationManager implementation\n */\n translationManager?: TranslationManager;\n\n /**\n * Option 2: Use built-in translations by specifying a locale\n * When adding new locales, just add the JSON file and update AVAILABLE_LOCALES\n */\n locale?: string;\n\n /**\n * Loading component to show while translations are being loaded\n * Only relevant when using dynamic locale loading\n */\n loadingComponent?: ReactNode;\n\n children: ReactNode;\n}\n\n/**\n * Provider for translation management with dynamic loading\n *\n * Three modes of operation:\n * 1. No provider: Components use default English strings\n * 2. With locale prop: Dynamically loads translations for that locale\n * 3. With translationManager: Use custom translation implementation\n */\nexport function TranslationProvider({\n translationManager,\n locale,\n loadingComponent = null,\n children,\n}: TranslationProviderProps) {\n const [loadedTranslations, setLoadedTranslations] = useState<any>(null);\n const [isLoading, setIsLoading] = useState(false);\n\n // Load translations when locale changes\n useEffect(() => {\n if (locale && !translationManager) {\n setIsLoading(true);\n loadTranslations(locale)\n .then(translations => {\n setLoadedTranslations(translations);\n setIsLoading(false);\n })\n .catch(error => {\n console.error('Failed to load translations:', error);\n setLoadedTranslations(enTranslations); // Fall back to English\n setIsLoading(false);\n });\n }\n }, [locale, translationManager]);\n\n // Create translation manager from loaded translations\n const localeManager = useMemo<TranslationManager | null>(() => {\n if (!loadedTranslations) return null;\n\n return {\n t: (namespace: string, key: string, params?: Record<string, any>) => {\n const translation = loadedTranslations[namespace]?.[key];\n\n if (!translation) {\n console.warn(`Translation not found for ${namespace}.${key} in locale ${locale}`);\n return `${namespace}.${key}`;\n }\n\n // Handle parameter interpolation and plural format\n if (params && typeof translation === 'string') {\n let result = translation;\n // First process plural format\n result = processPluralFormat(result, params);\n // Then handle simple parameter interpolation\n Object.entries(params).forEach(([paramKey, paramValue]) => {\n result = result.replace(new RegExp(`\\\\{\\\\{${paramKey}\\\\}\\\\}`, 'g'), String(paramValue));\n });\n return result;\n }\n\n return translation;\n },\n };\n }, [loadedTranslations, locale]);\n\n // If custom translation manager provided, use it\n if (translationManager) {\n return (\n <TranslationContext.Provider value={translationManager}>\n {children}\n </TranslationContext.Provider>\n );\n }\n\n // If locale provided and still loading, show loading component\n if (locale && isLoading) {\n return <>{loadingComponent}</>;\n }\n\n // If locale provided and translations loaded, use them\n if (locale && localeManager) {\n return (\n <TranslationContext.Provider value={localeManager}>\n {children}\n </TranslationContext.Provider>\n );\n }\n\n // Default: use English translations\n return (\n <TranslationContext.Provider value={defaultTranslationManager}>\n {children}\n </TranslationContext.Provider>\n );\n}\n\n/**\n * Hook to access translations within a namespace\n *\n * Works in three modes:\n * 1. Without provider: Returns default English translations\n * 2. With provider using locale: Returns dynamically loaded translations for that locale\n * 3. With custom provider: Uses the custom translation manager\n *\n * @param namespace - Translation namespace (e.g., 'Toolbar', 'ResourceViewer')\n * @returns Function to translate keys within the namespace\n */\nexport function useTranslations(namespace: string) {\n const context = useContext(TranslationContext);\n\n // If no context (no provider), use default English translations\n if (!context) {\n return (key: string, params?: Record<string, any>) => {\n const translations = enTranslations as Record<string, Record<string, string>>;\n const translation = translations[namespace]?.[key];\n\n if (!translation) {\n console.warn(`Translation not found for ${namespace}.${key}`);\n return `${namespace}.${key}`;\n }\n\n // Handle parameter interpolation and plural format\n if (params && typeof translation === 'string') {\n let result = translation;\n // First process plural format\n result = processPluralFormat(result, params);\n // Then handle simple parameter interpolation\n Object.entries(params).forEach(([paramKey, paramValue]) => {\n result = result.replace(new RegExp(`\\\\{\\\\{${paramKey}\\\\}\\\\}`, 'g'), String(paramValue));\n });\n return result;\n }\n\n return translation;\n };\n }\n\n // Return a function that translates keys within this namespace\n return (key: string, params?: Record<string, any>) => context.t(namespace, key, params);\n}\n\n/**\n * Hook to preload translations for a locale\n * Useful for preloading translations before navigation\n */\nexport function usePreloadTranslations() {\n return {\n preload: async (locale: string) => {\n try {\n await loadTranslations(locale);\n return true;\n } catch (error) {\n console.error(`Failed to preload translations for ${locale}:`, error);\n return false;\n }\n },\n isLoaded: (locale: string) => translationCache.has(locale),\n };\n}"],"mappings":"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","names":[]}