@semiont/cli 0.5.4 → 0.5.5

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 (75) hide show
  1. package/dist/cli.mjs +27 -12
  2. package/dist/frontend/dist/assets/{CookiePreferences-CMgprW9V.js → CookiePreferences-Vt05bBY7.js} +2 -2
  3. package/dist/frontend/dist/assets/{CookiePreferences-CMgprW9V.js.map → CookiePreferences-Vt05bBY7.js.map} +1 -1
  4. package/dist/frontend/dist/assets/{KeyboardShortcutsContext-BRLeqQUj.js → KeyboardShortcutsContext-CK7NFEft.js} +2 -2
  5. package/dist/frontend/dist/assets/{KeyboardShortcutsContext-BRLeqQUj.js.map → KeyboardShortcutsContext-CK7NFEft.js.map} +1 -1
  6. package/dist/frontend/dist/assets/{PdfAnnotationCanvas.client-CN3C3S55-DsCya3j0.js → PdfAnnotationCanvas.client-CN3C3S55-DZ2osbg-.js} +2 -2
  7. package/dist/frontend/dist/assets/{PdfAnnotationCanvas.client-CN3C3S55-DsCya3j0.js.map → PdfAnnotationCanvas.client-CN3C3S55-DZ2osbg-.js.map} +1 -1
  8. package/dist/frontend/dist/assets/{ToolbarPanels-CRGQDX-L.js → ToolbarPanels-wzZqAqCQ.js} +2 -2
  9. package/dist/frontend/dist/assets/{ToolbarPanels-CRGQDX-L.js.map → ToolbarPanels-wzZqAqCQ.js.map} +1 -1
  10. package/dist/frontend/dist/assets/{client-DvALJ3DL.js → client-C54EWgTc.js} +2 -2
  11. package/dist/frontend/dist/assets/{client-DvALJ3DL.js.map → client-C54EWgTc.js.map} +1 -1
  12. package/dist/frontend/dist/assets/{client-uEoQ8iJO.js → client-D5yyxFbt.js} +2 -2
  13. package/dist/frontend/dist/assets/{client-uEoQ8iJO.js.map → client-D5yyxFbt.js.map} +1 -1
  14. package/dist/frontend/dist/assets/{client-DkMJxPA7.js → client-DgzjF497.js} +2 -2
  15. package/dist/frontend/dist/assets/{client-DkMJxPA7.js.map → client-DgzjF497.js.map} +1 -1
  16. package/dist/frontend/dist/assets/{client-DxlEW_QJ.js → client-myF3ozNf.js} +2 -2
  17. package/dist/frontend/dist/assets/{client-DxlEW_QJ.js.map → client-myF3ozNf.js.map} +1 -1
  18. package/dist/frontend/dist/assets/{index-DjtRDlfn.js → index-DojEUBpq.js} +6 -6
  19. package/dist/frontend/dist/assets/index-DojEUBpq.js.map +1 -0
  20. package/dist/frontend/dist/assets/{layout-xDEqzpvE.js → layout-CpxxVgZl.js} +2 -2
  21. package/dist/frontend/dist/assets/{layout-xDEqzpvE.js.map → layout-CpxxVgZl.js.map} +1 -1
  22. package/dist/frontend/dist/assets/{layout-BhnmJA6O.js → layout-DGddEk2F.js} +2 -2
  23. package/dist/frontend/dist/assets/{layout-BhnmJA6O.js.map → layout-DGddEk2F.js.map} +1 -1
  24. package/dist/frontend/dist/assets/{layout-e6QyrD0Y.js → layout-WUjhuEFR.js} +2 -2
  25. package/dist/frontend/dist/assets/{layout-e6QyrD0Y.js.map → layout-WUjhuEFR.js.map} +1 -1
  26. package/dist/frontend/dist/assets/{layout-DolG9tOf.js → layout-osn4jTJF.js} +2 -2
  27. package/dist/frontend/dist/assets/{layout-DolG9tOf.js.map → layout-osn4jTJF.js.map} +1 -1
  28. package/dist/frontend/dist/assets/{not-found-4iuCkpA7.js → not-found-CXjr3aHk.js} +2 -2
  29. package/dist/frontend/dist/assets/{not-found-4iuCkpA7.js.map → not-found-CXjr3aHk.js.map} +1 -1
  30. package/dist/frontend/dist/assets/{page-DVCVvH_S.js → page-3_orURnj.js} +2 -2
  31. package/dist/frontend/dist/assets/{page-DVCVvH_S.js.map → page-3_orURnj.js.map} +1 -1
  32. package/dist/frontend/dist/assets/{page-CXhfUrZM.js → page-A0bP7R9_.js} +2 -2
  33. package/dist/frontend/dist/assets/{page-CXhfUrZM.js.map → page-A0bP7R9_.js.map} +1 -1
  34. package/dist/frontend/dist/assets/{page-BrSlkHj9.js → page-BXDwcCLI.js} +2 -2
  35. package/dist/frontend/dist/assets/{page-BrSlkHj9.js.map → page-BXDwcCLI.js.map} +1 -1
  36. package/dist/frontend/dist/assets/{page-D0bYoQZI.js → page-CR97hIaP.js} +2 -2
  37. package/dist/frontend/dist/assets/{page-D0bYoQZI.js.map → page-CR97hIaP.js.map} +1 -1
  38. package/dist/frontend/dist/assets/{page-C5gTlI4M.js → page-ClOO6d4L.js} +2 -2
  39. package/dist/frontend/dist/assets/{page-C5gTlI4M.js.map → page-ClOO6d4L.js.map} +1 -1
  40. package/dist/frontend/dist/assets/{page-8sXDEos5.js → page-CoU19X7P.js} +2 -2
  41. package/dist/frontend/dist/assets/{page-8sXDEos5.js.map → page-CoU19X7P.js.map} +1 -1
  42. package/dist/frontend/dist/assets/{page-CXVPWK3i.js → page-Crea7MLa.js} +2 -2
  43. package/dist/frontend/dist/assets/{page-CXVPWK3i.js.map → page-Crea7MLa.js.map} +1 -1
  44. package/dist/frontend/dist/assets/{page-7cCGgkUd.js → page-D3vt40lt.js} +2 -2
  45. package/dist/frontend/dist/assets/{page-7cCGgkUd.js.map → page-D3vt40lt.js.map} +1 -1
  46. package/dist/frontend/dist/assets/{page-6YupxiP8.js → page-D74-p81B.js} +2 -2
  47. package/dist/frontend/dist/assets/{page-6YupxiP8.js.map → page-D74-p81B.js.map} +1 -1
  48. package/dist/frontend/dist/assets/{page-CkHE2rPM.js → page-D9VjQ4Ci.js} +2 -2
  49. package/dist/frontend/dist/assets/{page-CkHE2rPM.js.map → page-D9VjQ4Ci.js.map} +1 -1
  50. package/dist/frontend/dist/assets/{page-BioSV21A.js → page-DAaiG0_S.js} +2 -2
  51. package/dist/frontend/dist/assets/{page-BioSV21A.js.map → page-DAaiG0_S.js.map} +1 -1
  52. package/dist/frontend/dist/assets/{page-BOhOKDMk.js → page-DGGXDS8h.js} +2 -2
  53. package/dist/frontend/dist/assets/{page-BOhOKDMk.js.map → page-DGGXDS8h.js.map} +1 -1
  54. package/dist/frontend/dist/assets/{page-A6_MoyUb2.js → page-DWTT4pP82.js} +2 -2
  55. package/dist/frontend/dist/assets/{page-A6_MoyUb2.js.map → page-DWTT4pP82.js.map} +1 -1
  56. package/dist/frontend/dist/assets/{page-D1veR3Kp.js → page-Db8QDovL.js} +2 -2
  57. package/dist/frontend/dist/assets/{page-D1veR3Kp.js.map → page-Db8QDovL.js.map} +1 -1
  58. package/dist/frontend/dist/assets/{page-DbwiMF1N.js → page-V3GB89Xa.js} +2 -2
  59. package/dist/frontend/dist/assets/{page-DbwiMF1N.js.map → page-V3GB89Xa.js.map} +1 -1
  60. package/dist/frontend/dist/assets/{page-Bl8sZu8k.js → page-pid5J2JR.js} +2 -2
  61. package/dist/frontend/dist/assets/{page-Bl8sZu8k.js.map → page-pid5J2JR.js.map} +1 -1
  62. package/dist/frontend/dist/assets/{page-D6oe9LkY.js → page-vxSCIznX.js} +2 -2
  63. package/dist/frontend/dist/assets/{page-D6oe9LkY.js.map → page-vxSCIznX.js.map} +1 -1
  64. package/dist/frontend/dist/assets/{page-B9EYfbrY.js → page-yaV9evoV.js} +2 -2
  65. package/dist/frontend/dist/assets/{page-B9EYfbrY.js.map → page-yaV9evoV.js.map} +1 -1
  66. package/dist/frontend/dist/assets/{routing-DW1ehi64.js → routing-CcetIVef.js} +2 -2
  67. package/dist/frontend/dist/assets/{routing-DW1ehi64.js.map → routing-CcetIVef.js.map} +1 -1
  68. package/dist/frontend/dist/assets/{routing-Bcj1FhkC.js → routing-Dqgz2rV4.js} +2 -2
  69. package/dist/frontend/dist/assets/{routing-Bcj1FhkC.js.map → routing-Dqgz2rV4.js.map} +1 -1
  70. package/dist/frontend/dist/assets/{web-Dr6mdA1A.js → web-DAgGdiC_.js} +2 -2
  71. package/dist/frontend/dist/assets/{web-Dr6mdA1A.js.map → web-DAgGdiC_.js.map} +1 -1
  72. package/dist/frontend/dist/index.html +1 -1
  73. package/dist/frontend/package.json +1 -1
  74. package/package.json +8 -8
  75. package/dist/frontend/dist/assets/index-DjtRDlfn.js.map +0 -1
@@ -1,2 +1,2 @@
1
- import{n as e}from"./rolldown-runtime-jpDsebLB.js";import{i as t,n}from"./i18n-B53Yefbh.js";import{t as r}from"./vendor-0HjOURbh.js";import{M as i,Pt as a,X as o,Z as s,et as c,f as l,nt as u,ot as d,q as f,s as p,u as m,v as h}from"./index-DjtRDlfn.js";import{t as g}from"./KeyboardShortcutsContext-BRLeqQUj.js";import{t as _}from"./CookiePreferences-CMgprW9V.js";import{n as v,t as y}from"./ToolbarPanels-CRGQDX-L.js";import{n as b,t as x}from"./ChevronLeftIcon-QLs1eT1j.js";import{t as S}from"./XMarkIcon-CddZGiiz.js";import{i as C,r as w,t as T}from"./routing-Bcj1FhkC.js";import{n as E,t as D}from"./routing-DW1ehi64.js";var O=e(t()),k=r(),A=({className:e})=>(0,k.jsx)(`span`,{className:e,style:{fontSize:`1.25rem`,lineHeight:`1`},children:`🔭`});function j({href:e,to:t,...n}){return(0,k.jsx)(T,{to:e??``,...n})}function M({isCollapsed:e,toggleCollapsed:t,navigationMenu:r}){let{t:i}=n(),a=(e,t)=>i(`Sidebar.${e}`,t),o=w(),c=C(),l=d(),u=s(l.openResources$)??[],m=l.removeOpenResource.bind(l),h=l.reorderOpenResources.bind(l),g=[{name:a(`discover`),href:`/know/discover`,icon:A,description:a(`searchAndBrowse`)},{name:a(`compose`),href:`/know/compose`,icon:v,description:a(`composeNewResource`)}];return f({"shell:sidebar-toggle":(0,O.useCallback)(()=>{t()},[t]),"tabs:close":(0,O.useCallback)(({resourceId:e})=>{m(e),o===`/know/resource/${e}`&&c.push(`/know/discover`)},[m,o,c]),"tabs:reorder":(0,O.useCallback)(({oldIndex:e,newIndex:t})=>{h(e,t)},[h])}),(0,k.jsx)(`div`,{className:`flex flex-col h-full`,children:(0,k.jsx)(`div`,{className:`flex-1 min-h-0 overflow-y-auto`,children:(0,k.jsx)(p,{fixedItems:g,resources:u,isCollapsed:e,currentPath:o,LinkComponent:j,onNavigate:e=>{c.push(e)},getResourceHref:e=>`/know/resource/${e}`,className:`knowledge-navigation`,translations:{title:a(`title`)},icons:{chevronLeft:x,bars:b,close:S},navigationMenu:r})})})}function N(){let{t:e}=n(),t=(t,n)=>e(`Navigation.${t}`,n),{t:r}=n(),i=(e,t)=>r(`Home.${e}`,t),a=s(s(d().activeSession$)?.user$);return(0,k.jsx)(l,{Link:D,routes:E,t,tHome:i,brandingLink:`/`,collapsible:!0,storageKey:`knowledgeNavCollapsed`,isAuthenticated:!!a,isAdmin:a?.isAdmin??!1,isModerator:a?.isModerator??!1,children:(e,t,n)=>(0,k.jsx)(M,{isCollapsed:e,toggleCollapsed:t,navigationMenu:n})})}function P(){return null}function F(){let{t:e}=n(),t=t=>e(`DiscoverEmptyState.${t}`),r=d(),i=s(r.kbs$)??[],a=s(r.activeSession$)?.kb??null,o=a?r.getKbSessionStatus(a.id):null;return i.length===0?(0,k.jsxs)(`div`,{style:{textAlign:`center`,maxWidth:`28rem`},children:[(0,k.jsx)(`h2`,{style:{fontSize:`1.1rem`,fontWeight:600,marginBottom:`0.5rem`},children:t(`noKnowledgeBases`)}),(0,k.jsx)(`p`,{style:{color:`var(--semiont-color-neutral-400)`,fontSize:`0.85rem`,lineHeight:1.5,marginBottom:`0.75rem`},children:t(`noKnowledgeBasesHint`)}),(0,k.jsxs)(`p`,{style:{color:`var(--semiont-color-neutral-400)`,fontSize:`0.85rem`,lineHeight:1.5},children:[(0,k.jsx)(`a`,{href:`https://github.com/The-AI-Alliance/semiont`,target:`_blank`,rel:`noopener noreferrer`,style:{color:`var(--semiont-color-primary-500)`},children:t(`findKnowledgeBases`)}),` · `,(0,k.jsx)(`a`,{href:`https://github.com/The-AI-Alliance/semiont-template-kb`,target:`_blank`,rel:`noopener noreferrer`,style:{color:`var(--semiont-color-primary-500)`},children:t(`createNew`)})]})]}):o===`authenticated`?null:(0,k.jsxs)(`div`,{style:{textAlign:`center`,maxWidth:`24rem`},children:[(0,k.jsx)(`h2`,{style:{fontSize:`1.1rem`,fontWeight:600,marginBottom:`0.5rem`},children:a?.label??``}),(0,k.jsxs)(`p`,{style:{color:`var(--semiont-color-neutral-400)`,fontSize:`0.85rem`,lineHeight:1.5},children:[t(o===`expired`?`sessionExpired`:`signedOut`),` `,t(`signInHint`)]})]})}function I({t:e,keyboardContext:t}){let n=s(c().activePanel$)??null,{theme:r}=u(),{showLineNumbers:a}=o();return(0,k.jsxs)(`div`,{className:`h-screen semiont-knowledge-layout semiont-layout-with-footer flex flex-col overflow-hidden`,children:[(0,k.jsxs)(`div`,{className:`flex flex-1 overflow-hidden`,children:[(0,k.jsx)(`main`,{className:`flex-1 w-full px-2 pb-6 flex flex-col overflow-hidden`,children:(0,k.jsx)(`div`,{className:`w-full mx-auto flex-1 flex flex-col h-full overflow-hidden items-center justify-center`,children:(0,k.jsx)(F,{})})}),(0,k.jsx)(y,{activePanel:n,showLineNumbers:a,theme:r}),(0,k.jsx)(i,{activePanel:n,context:`simple`})]}),(0,k.jsx)(m,{Link:D,routes:E,t:(t,n)=>e(`Footer.${t}`,n),CookiePreferences:_,showPolicyLinks:!(`__TAURI_INTERNALS__`in window),...t?.openKeyboardHelp&&{onOpenKeyboardHelp:t.openKeyboardHelp}})]})}function L(){let{t:e}=n(),t=(0,O.useContext)(g),r=d(),i=s(r.activeKbId$),o=s(r.activeSession$),c=s(r.sessionActivating$),l=s(o?.token$),u=o?.kb??null;return i!=null&&o==null&&c?(0,k.jsx)(`div`,{className:`h-screen flex items-center justify-center`,children:(0,k.jsxs)(`div`,{className:`text-center`,children:[(0,k.jsx)(`div`,{className:`animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4`}),(0,k.jsx)(`p`,{className:`text-gray-600 dark:text-gray-400`,children:`Loading...`})]})}):!u||!l?(0,k.jsx)(I,{t:(t,n)=>e(t,n),keyboardContext:t}):(0,k.jsxs)(h,{children:[(0,k.jsx)(P,{}),(0,k.jsxs)(`div`,{className:`h-screen semiont-knowledge-layout semiont-layout-with-footer flex flex-col overflow-hidden`,children:[(0,k.jsxs)(`div`,{className:`flex flex-1 overflow-hidden`,children:[(0,k.jsx)(N,{}),(0,k.jsx)(`main`,{className:`flex-1 w-full px-2 pb-6 flex flex-col overflow-hidden`,children:(0,k.jsx)(`div`,{className:`w-full mx-auto flex-1 flex flex-col h-full overflow-hidden`,children:(0,k.jsx)(a,{})})})]}),(0,k.jsx)(m,{Link:D,routes:E,t:(t,n)=>e(`Footer.${t}`,n),CookiePreferences:_,showPolicyLinks:!(`__TAURI_INTERNALS__`in window),...t?.openKeyboardHelp&&{onOpenKeyboardHelp:t.openKeyboardHelp}})]})]})}function R(){return(0,k.jsx)(L,{})}export{R as default};
2
- //# sourceMappingURL=layout-xDEqzpvE.js.map
1
+ import{n as e}from"./rolldown-runtime-jpDsebLB.js";import{i as t,n}from"./i18n-B53Yefbh.js";import{t as r}from"./vendor-0HjOURbh.js";import{M as i,Pt as a,X as o,Z as s,et as c,f as l,nt as u,ot as d,q as f,s as p,u as m,v as h}from"./index-DojEUBpq.js";import{t as g}from"./KeyboardShortcutsContext-CK7NFEft.js";import{t as _}from"./CookiePreferences-Vt05bBY7.js";import{n as v,t as y}from"./ToolbarPanels-wzZqAqCQ.js";import{n as b,t as x}from"./ChevronLeftIcon-QLs1eT1j.js";import{t as S}from"./XMarkIcon-CddZGiiz.js";import{i as C,r as w,t as T}from"./routing-Dqgz2rV4.js";import{n as E,t as D}from"./routing-CcetIVef.js";var O=e(t()),k=r(),A=({className:e})=>(0,k.jsx)(`span`,{className:e,style:{fontSize:`1.25rem`,lineHeight:`1`},children:`🔭`});function j({href:e,to:t,...n}){return(0,k.jsx)(T,{to:e??``,...n})}function M({isCollapsed:e,toggleCollapsed:t,navigationMenu:r}){let{t:i}=n(),a=(e,t)=>i(`Sidebar.${e}`,t),o=w(),c=C(),l=d(),u=s(l.openResources$)??[],m=l.removeOpenResource.bind(l),h=l.reorderOpenResources.bind(l),g=[{name:a(`discover`),href:`/know/discover`,icon:A,description:a(`searchAndBrowse`)},{name:a(`compose`),href:`/know/compose`,icon:v,description:a(`composeNewResource`)}];return f({"shell:sidebar-toggle":(0,O.useCallback)(()=>{t()},[t]),"tabs:close":(0,O.useCallback)(({resourceId:e})=>{m(e),o===`/know/resource/${e}`&&c.push(`/know/discover`)},[m,o,c]),"tabs:reorder":(0,O.useCallback)(({oldIndex:e,newIndex:t})=>{h(e,t)},[h])}),(0,k.jsx)(`div`,{className:`flex flex-col h-full`,children:(0,k.jsx)(`div`,{className:`flex-1 min-h-0 overflow-y-auto`,children:(0,k.jsx)(p,{fixedItems:g,resources:u,isCollapsed:e,currentPath:o,LinkComponent:j,onNavigate:e=>{c.push(e)},getResourceHref:e=>`/know/resource/${e}`,className:`knowledge-navigation`,translations:{title:a(`title`)},icons:{chevronLeft:x,bars:b,close:S},navigationMenu:r})})})}function N(){let{t:e}=n(),t=(t,n)=>e(`Navigation.${t}`,n),{t:r}=n(),i=(e,t)=>r(`Home.${e}`,t),a=s(s(d().activeSession$)?.user$);return(0,k.jsx)(l,{Link:D,routes:E,t,tHome:i,brandingLink:`/`,collapsible:!0,storageKey:`knowledgeNavCollapsed`,isAuthenticated:!!a,isAdmin:a?.isAdmin??!1,isModerator:a?.isModerator??!1,children:(e,t,n)=>(0,k.jsx)(M,{isCollapsed:e,toggleCollapsed:t,navigationMenu:n})})}function P(){return null}function F(){let{t:e}=n(),t=t=>e(`DiscoverEmptyState.${t}`),r=d(),i=s(r.kbs$)??[],a=s(r.activeSession$)?.kb??null,o=a?r.getKbSessionStatus(a.id):null;return i.length===0?(0,k.jsxs)(`div`,{style:{textAlign:`center`,maxWidth:`28rem`},children:[(0,k.jsx)(`h2`,{style:{fontSize:`1.1rem`,fontWeight:600,marginBottom:`0.5rem`},children:t(`noKnowledgeBases`)}),(0,k.jsx)(`p`,{style:{color:`var(--semiont-color-neutral-400)`,fontSize:`0.85rem`,lineHeight:1.5,marginBottom:`0.75rem`},children:t(`noKnowledgeBasesHint`)}),(0,k.jsxs)(`p`,{style:{color:`var(--semiont-color-neutral-400)`,fontSize:`0.85rem`,lineHeight:1.5},children:[(0,k.jsx)(`a`,{href:`https://github.com/The-AI-Alliance/semiont`,target:`_blank`,rel:`noopener noreferrer`,style:{color:`var(--semiont-color-primary-500)`},children:t(`findKnowledgeBases`)}),` · `,(0,k.jsx)(`a`,{href:`https://github.com/The-AI-Alliance/semiont-template-kb`,target:`_blank`,rel:`noopener noreferrer`,style:{color:`var(--semiont-color-primary-500)`},children:t(`createNew`)})]})]}):o===`authenticated`?null:(0,k.jsxs)(`div`,{style:{textAlign:`center`,maxWidth:`24rem`},children:[(0,k.jsx)(`h2`,{style:{fontSize:`1.1rem`,fontWeight:600,marginBottom:`0.5rem`},children:a?.label??``}),(0,k.jsxs)(`p`,{style:{color:`var(--semiont-color-neutral-400)`,fontSize:`0.85rem`,lineHeight:1.5},children:[t(o===`expired`?`sessionExpired`:`signedOut`),` `,t(`signInHint`)]})]})}function I({t:e,keyboardContext:t}){let n=s(c().activePanel$)??null,{theme:r}=u(),{showLineNumbers:a}=o();return(0,k.jsxs)(`div`,{className:`h-screen semiont-knowledge-layout semiont-layout-with-footer flex flex-col overflow-hidden`,children:[(0,k.jsxs)(`div`,{className:`flex flex-1 overflow-hidden`,children:[(0,k.jsx)(`main`,{className:`flex-1 w-full px-2 pb-6 flex flex-col overflow-hidden`,children:(0,k.jsx)(`div`,{className:`w-full mx-auto flex-1 flex flex-col h-full overflow-hidden items-center justify-center`,children:(0,k.jsx)(F,{})})}),(0,k.jsx)(y,{activePanel:n,showLineNumbers:a,theme:r}),(0,k.jsx)(i,{activePanel:n,context:`simple`})]}),(0,k.jsx)(m,{Link:D,routes:E,t:(t,n)=>e(`Footer.${t}`,n),CookiePreferences:_,showPolicyLinks:!(`__TAURI_INTERNALS__`in window),...t?.openKeyboardHelp&&{onOpenKeyboardHelp:t.openKeyboardHelp}})]})}function L(){let{t:e}=n(),t=(0,O.useContext)(g),r=d(),i=s(r.activeKbId$),o=s(r.activeSession$),c=s(r.sessionActivating$),l=s(o?.token$),u=o?.kb??null;return i!=null&&o==null&&c?(0,k.jsx)(`div`,{className:`h-screen flex items-center justify-center`,children:(0,k.jsxs)(`div`,{className:`text-center`,children:[(0,k.jsx)(`div`,{className:`animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4`}),(0,k.jsx)(`p`,{className:`text-gray-600 dark:text-gray-400`,children:`Loading...`})]})}):!u||!l?(0,k.jsx)(I,{t:(t,n)=>e(t,n),keyboardContext:t}):(0,k.jsxs)(h,{children:[(0,k.jsx)(P,{}),(0,k.jsxs)(`div`,{className:`h-screen semiont-knowledge-layout semiont-layout-with-footer flex flex-col overflow-hidden`,children:[(0,k.jsxs)(`div`,{className:`flex flex-1 overflow-hidden`,children:[(0,k.jsx)(N,{}),(0,k.jsx)(`main`,{className:`flex-1 w-full px-2 pb-6 flex flex-col overflow-hidden`,children:(0,k.jsx)(`div`,{className:`w-full mx-auto flex-1 flex flex-col h-full overflow-hidden`,children:(0,k.jsx)(a,{})})})]}),(0,k.jsx)(m,{Link:D,routes:E,t:(t,n)=>e(`Footer.${t}`,n),CookiePreferences:_,showPolicyLinks:!(`__TAURI_INTERNALS__`in window),...t?.openKeyboardHelp&&{onOpenKeyboardHelp:t.openKeyboardHelp}})]})]})}function R(){return(0,k.jsx)(L,{})}export{R as default};
2
+ //# sourceMappingURL=layout-CpxxVgZl.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"layout-xDEqzpvE.js","names":[],"sources":["../../src/components/knowledge/KnowledgeNavigation.tsx","../../src/components/knowledge/KnowledgeSidebarWrapper.tsx","../../src/app/[locale]/know/layout.tsx"],"sourcesContent":["import React, { useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Link } from '@/i18n/routing';\nimport { usePathname, useRouter } from '@/i18n/routing';\nimport { PlusIcon, ChevronLeftIcon, Bars3Icon, XMarkIcon } from '@heroicons/react/24/outline';\nimport {\n useSemiont,\n useObservable,\n useEventSubscriptions,\n CollapsibleResourceNavigation,\n type NavigationItem,\n} from '@semiont/react-ui';\nimport type { OpenResource } from '@semiont/sdk';\n// Custom telescope icon component\nconst TelescopeIcon = ({ className }: { className?: string }) => (\n <span className={className} style={{ fontSize: '1.25rem', lineHeight: '1' }}>🔭</span>\n);\n\ninterface KnowledgeNavigationProps {\n isCollapsed: boolean;\n toggleCollapsed: () => void;\n navigationMenu?: (onClose: () => void) => React.ReactNode;\n}\n\n// Adapter: CollapsibleResourceNavigation passes href, but our Link uses `to`\nfunction HrefLink({ href, to: _to, ...props }: React.ComponentProps<typeof Link> & { href?: string }) {\n return <Link to={(href ?? '') as string} {...props} />;\n}\n\nexport function KnowledgeNavigation({ isCollapsed, toggleCollapsed, navigationMenu }: KnowledgeNavigationProps) {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`Sidebar.${k}`, p as any) as string;\n const pathname = usePathname();\n const router = useRouter();\n const semiont = useSemiont();\n const openResources = useObservable(semiont.openResources$) ?? [];\n const removeResource = semiont.removeOpenResource.bind(semiont);\n const reorderResources = semiont.reorderOpenResources.bind(semiont);\n\n const fixedNavigation: NavigationItem[] = [\n {\n name: t('discover'),\n href: '/know/discover',\n icon: TelescopeIcon,\n description: t('searchAndBrowse')\n },\n {\n name: t('compose'),\n href: '/know/compose',\n icon: PlusIcon,\n description: t('composeNewResource')\n }\n ];\n\n // Handle sidebar toggle events\n const handleSidebarToggle = useCallback(() => {\n toggleCollapsed();\n }, [toggleCollapsed]);\n\n // Handle resource close events\n const handleResourceClose = useCallback(({ resourceId }: { resourceId: string }) => {\n removeResource(resourceId);\n\n // If we're closing the currently viewed document, navigate to Discover\n if (pathname === `/know/resource/${resourceId}`) {\n router.push('/know/discover');\n }\n }, [removeResource, pathname, router]);\n\n // Handle resource reorder events\n const handleResourceReorder = useCallback(({ oldIndex, newIndex }: { oldIndex: number; newIndex: number }) => {\n reorderResources(oldIndex, newIndex);\n }, [reorderResources]);\n\n // Subscribe to navigation events\n useEventSubscriptions({\n 'shell:sidebar-toggle': handleSidebarToggle,\n 'tabs:close': handleResourceClose,\n 'tabs:reorder': handleResourceReorder,\n });\n\n // Handle navigation\n const handleNavigate = (path: string) => {\n router.push(path);\n };\n\n // Build resource href\n const getResourceHref = (resourceId: string) => {\n return `/know/resource/${resourceId}`;\n };\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"flex-1 min-h-0 overflow-y-auto\">\n <CollapsibleResourceNavigation\n fixedItems={fixedNavigation}\n resources={openResources as OpenResource[]}\n isCollapsed={isCollapsed}\n currentPath={pathname}\n LinkComponent={HrefLink as any}\n onNavigate={handleNavigate}\n getResourceHref={getResourceHref}\n className=\"knowledge-navigation\"\n translations={{\n title: t('title')\n }}\n icons={{\n chevronLeft: ChevronLeftIcon,\n bars: Bars3Icon,\n close: XMarkIcon\n }}\n navigationMenu={navigationMenu}\n />\n </div>\n </div>\n );\n}","import React from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { LeftSidebar, useSemiont, useObservable } from '@semiont/react-ui';\nimport { KnowledgeNavigation } from './KnowledgeNavigation';\nimport { Link, routes } from '@/lib/routing';\n\nexport function KnowledgeSidebarWrapper() {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`Navigation.${k}`, p as any) as string;\n const { t: _tHome } = useTranslation();\n const tHome = (k: string, p?: Record<string, unknown>) => _tHome(`Home.${k}`, p as any) as string;\n const session = useObservable(useSemiont().activeSession$);\n const user = useObservable(session?.user$);\n const isAuthenticated = !!user;\n const isAdmin = user?.isAdmin ?? false;\n const isModerator = user?.isModerator ?? false;\n\n return (\n <LeftSidebar\n Link={Link}\n routes={routes}\n t={t}\n tHome={tHome}\n brandingLink=\"/\"\n collapsible={true}\n storageKey=\"knowledgeNavCollapsed\"\n isAuthenticated={isAuthenticated}\n isAdmin={isAdmin}\n isModerator={isModerator}\n >\n {(isCollapsed, toggleCollapsed, navigationMenu) => (\n <KnowledgeNavigation\n isCollapsed={isCollapsed}\n toggleCollapsed={toggleCollapsed}\n navigationMenu={navigationMenu}\n />\n )}\n </LeftSidebar>\n );\n}\n","import { useContext } from 'react';\nimport { Outlet } from 'react-router-dom';\nimport { useTranslation } from 'react-i18next';\nimport { KnowledgeSidebarWrapper } from '@/components/knowledge/KnowledgeSidebarWrapper';\nimport {\n Footer,\n ResourceAnnotationsProvider,\n Toolbar,\n useSemiont,\n useShellStateUnit,\n useObservable,\n useTheme,\n useLineNumbers,\n} from '@semiont/react-ui';\nimport { ToolbarPanels } from '@/components/toolbar/ToolbarPanels';\nimport { CookiePreferences } from '@/components/CookiePreferences';\nimport { KeyboardShortcutsContext } from '@/contexts/KeyboardShortcutsContext';\nimport { Link, routes } from '@/lib/routing';\n\nfunction GlobalEventsConnector() {\n return null;\n}\n\n/**\n * Empty state for the main content area when no KB is connected or authenticated.\n * Shows contextual guidance based on whether any KBs exist.\n */\nfunction DiscoverEmptyState() {\n const { t: _t } = useTranslation();\n const t = (k: string) => _t(`DiscoverEmptyState.${k}`) as string;\n const semiont = useSemiont();\n const knowledgeBases = useObservable(semiont.kbs$) ?? [];\n const activeKnowledgeBase = useObservable(semiont.activeSession$)?.kb ?? null;\n const status = activeKnowledgeBase\n ? semiont.getKbSessionStatus(activeKnowledgeBase.id)\n : null;\n\n if (knowledgeBases.length === 0) {\n return (\n <div style={{ textAlign: 'center', maxWidth: '28rem' }}>\n <h2 style={{ fontSize: '1.1rem', fontWeight: 600, marginBottom: '0.5rem' }}>{t('noKnowledgeBases')}</h2>\n <p style={{ color: 'var(--semiont-color-neutral-400)', fontSize: '0.85rem', lineHeight: 1.5, marginBottom: '0.75rem' }}>\n {t('noKnowledgeBasesHint')}\n </p>\n <p style={{ color: 'var(--semiont-color-neutral-400)', fontSize: '0.85rem', lineHeight: 1.5 }}>\n <a href=\"https://github.com/The-AI-Alliance/semiont\" target=\"_blank\" rel=\"noopener noreferrer\" style={{ color: 'var(--semiont-color-primary-500)' }}>{t('findKnowledgeBases')}</a>\n {' · '}\n <a href=\"https://github.com/The-AI-Alliance/semiont-template-kb\" target=\"_blank\" rel=\"noopener noreferrer\" style={{ color: 'var(--semiont-color-primary-500)' }}>{t('createNew')}</a>\n </p>\n </div>\n );\n }\n\n if (status === 'authenticated') {\n return null;\n }\n\n return (\n <div style={{ textAlign: 'center', maxWidth: '24rem' }}>\n <h2 style={{ fontSize: '1.1rem', fontWeight: 600, marginBottom: '0.5rem' }}>\n {activeKnowledgeBase?.label ?? ''}\n </h2>\n <p style={{ color: 'var(--semiont-color-neutral-400)', fontSize: '0.85rem', lineHeight: 1.5 }}>\n {status === 'expired' ? t('sessionExpired') : t('signedOut')}\n {' '}{t('signInHint')}\n </p>\n </div>\n );\n}\n\nfunction UnauthenticatedKnowledgeLayout({ t, keyboardContext }: { t: (key: string, params?: Record<string, unknown>) => string; keyboardContext: { openKeyboardHelp?: () => void } | null }) {\n const browseStateUnit = useShellStateUnit();\n const activePanel = useObservable(browseStateUnit.activePanel$) ?? null;\n const { theme } = useTheme();\n const { showLineNumbers } = useLineNumbers();\n\n return (\n <div className=\"h-screen semiont-knowledge-layout semiont-layout-with-footer flex flex-col overflow-hidden\">\n <div className=\"flex flex-1 overflow-hidden\">\n <main className=\"flex-1 w-full px-2 pb-6 flex flex-col overflow-hidden\">\n <div className=\"w-full mx-auto flex-1 flex flex-col h-full overflow-hidden items-center justify-center\">\n <DiscoverEmptyState />\n </div>\n </main>\n <ToolbarPanels\n activePanel={activePanel}\n showLineNumbers={showLineNumbers}\n theme={theme}\n />\n <Toolbar activePanel={activePanel} context=\"simple\" />\n </div>\n <Footer\n Link={Link}\n routes={routes}\n t={(key: string, params?: Record<string, unknown>) => t(`Footer.${key}`, params as any) as string}\n CookiePreferences={CookiePreferences}\n showPolicyLinks={!('__TAURI_INTERNALS__' in window)}\n {...(keyboardContext?.openKeyboardHelp && { onOpenKeyboardHelp: keyboardContext.openKeyboardHelp })}\n />\n </div>\n );\n}\n\nfunction KnowledgeLayoutBody() {\n const { t } = useTranslation();\n const keyboardContext = useContext(KeyboardShortcutsContext);\n const semiont = useSemiont();\n const activeKbId = useObservable(semiont.activeKbId$);\n const session = useObservable(semiont.activeSession$);\n const sessionActivating = useObservable(semiont.sessionActivating$);\n const token = useObservable(session?.token$);\n const activeKnowledgeBase = session?.kb ?? null;\n // \"Loading\" = a session construction is actively in flight. Without\n // the `sessionActivating` guard we'd sit on the spinner forever after\n // any `signOut`, which also leaves `activeKbId` set but `session`\n // null.\n const isLoading = activeKbId != null && session == null && sessionActivating;\n\n if (isLoading) {\n return (\n <div className=\"h-screen flex items-center justify-center\">\n <div className=\"text-center\">\n <div className=\"animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4\"></div>\n <p className=\"text-gray-600 dark:text-gray-400\">Loading...</p>\n </div>\n </div>\n );\n }\n\n if (!activeKnowledgeBase || !token) {\n return (\n <UnauthenticatedKnowledgeLayout t={(key: string, params?: Record<string, unknown>) => t(key, params as any) as string} keyboardContext={keyboardContext} />\n );\n }\n\n return (\n <ResourceAnnotationsProvider>\n <GlobalEventsConnector />\n <div className=\"h-screen semiont-knowledge-layout semiont-layout-with-footer flex flex-col overflow-hidden\">\n <div className=\"flex flex-1 overflow-hidden\">\n <KnowledgeSidebarWrapper />\n <main className=\"flex-1 w-full px-2 pb-6 flex flex-col overflow-hidden\">\n <div className=\"w-full mx-auto flex-1 flex flex-col h-full overflow-hidden\">\n <Outlet />\n </div>\n </main>\n </div>\n <Footer\n Link={Link}\n routes={routes}\n t={(key: string, params?: Record<string, unknown>) => t(`Footer.${key}`, params as any) as string}\n CookiePreferences={CookiePreferences}\n showPolicyLinks={!('__TAURI_INTERNALS__' in window)}\n {...(keyboardContext?.openKeyboardHelp && { onOpenKeyboardHelp: keyboardContext.openKeyboardHelp })}\n />\n </div>\n </ResourceAnnotationsProvider>\n );\n}\n\nexport default function KnowledgeLayout() {\n // AuthShell is mounted by the parent ProtectedLayout in App.tsx so it\n // survives navigation between know/, admin/, and moderate/ sections.\n return <KnowledgeLayoutBody />;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"layout-CpxxVgZl.js","names":[],"sources":["../../src/components/knowledge/KnowledgeNavigation.tsx","../../src/components/knowledge/KnowledgeSidebarWrapper.tsx","../../src/app/[locale]/know/layout.tsx"],"sourcesContent":["import React, { useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Link } from '@/i18n/routing';\nimport { usePathname, useRouter } from '@/i18n/routing';\nimport { PlusIcon, ChevronLeftIcon, Bars3Icon, XMarkIcon } from '@heroicons/react/24/outline';\nimport {\n useSemiont,\n useObservable,\n useEventSubscriptions,\n CollapsibleResourceNavigation,\n type NavigationItem,\n} from '@semiont/react-ui';\nimport type { OpenResource } from '@semiont/sdk';\n// Custom telescope icon component\nconst TelescopeIcon = ({ className }: { className?: string }) => (\n <span className={className} style={{ fontSize: '1.25rem', lineHeight: '1' }}>🔭</span>\n);\n\ninterface KnowledgeNavigationProps {\n isCollapsed: boolean;\n toggleCollapsed: () => void;\n navigationMenu?: (onClose: () => void) => React.ReactNode;\n}\n\n// Adapter: CollapsibleResourceNavigation passes href, but our Link uses `to`\nfunction HrefLink({ href, to: _to, ...props }: React.ComponentProps<typeof Link> & { href?: string }) {\n return <Link to={(href ?? '') as string} {...props} />;\n}\n\nexport function KnowledgeNavigation({ isCollapsed, toggleCollapsed, navigationMenu }: KnowledgeNavigationProps) {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`Sidebar.${k}`, p as any) as string;\n const pathname = usePathname();\n const router = useRouter();\n const semiont = useSemiont();\n const openResources = useObservable(semiont.openResources$) ?? [];\n const removeResource = semiont.removeOpenResource.bind(semiont);\n const reorderResources = semiont.reorderOpenResources.bind(semiont);\n\n const fixedNavigation: NavigationItem[] = [\n {\n name: t('discover'),\n href: '/know/discover',\n icon: TelescopeIcon,\n description: t('searchAndBrowse')\n },\n {\n name: t('compose'),\n href: '/know/compose',\n icon: PlusIcon,\n description: t('composeNewResource')\n }\n ];\n\n // Handle sidebar toggle events\n const handleSidebarToggle = useCallback(() => {\n toggleCollapsed();\n }, [toggleCollapsed]);\n\n // Handle resource close events\n const handleResourceClose = useCallback(({ resourceId }: { resourceId: string }) => {\n removeResource(resourceId);\n\n // If we're closing the currently viewed document, navigate to Discover\n if (pathname === `/know/resource/${resourceId}`) {\n router.push('/know/discover');\n }\n }, [removeResource, pathname, router]);\n\n // Handle resource reorder events\n const handleResourceReorder = useCallback(({ oldIndex, newIndex }: { oldIndex: number; newIndex: number }) => {\n reorderResources(oldIndex, newIndex);\n }, [reorderResources]);\n\n // Subscribe to navigation events\n useEventSubscriptions({\n 'shell:sidebar-toggle': handleSidebarToggle,\n 'tabs:close': handleResourceClose,\n 'tabs:reorder': handleResourceReorder,\n });\n\n // Handle navigation\n const handleNavigate = (path: string) => {\n router.push(path);\n };\n\n // Build resource href\n const getResourceHref = (resourceId: string) => {\n return `/know/resource/${resourceId}`;\n };\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"flex-1 min-h-0 overflow-y-auto\">\n <CollapsibleResourceNavigation\n fixedItems={fixedNavigation}\n resources={openResources as OpenResource[]}\n isCollapsed={isCollapsed}\n currentPath={pathname}\n LinkComponent={HrefLink as any}\n onNavigate={handleNavigate}\n getResourceHref={getResourceHref}\n className=\"knowledge-navigation\"\n translations={{\n title: t('title')\n }}\n icons={{\n chevronLeft: ChevronLeftIcon,\n bars: Bars3Icon,\n close: XMarkIcon\n }}\n navigationMenu={navigationMenu}\n />\n </div>\n </div>\n );\n}","import React from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { LeftSidebar, useSemiont, useObservable } from '@semiont/react-ui';\nimport { KnowledgeNavigation } from './KnowledgeNavigation';\nimport { Link, routes } from '@/lib/routing';\n\nexport function KnowledgeSidebarWrapper() {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`Navigation.${k}`, p as any) as string;\n const { t: _tHome } = useTranslation();\n const tHome = (k: string, p?: Record<string, unknown>) => _tHome(`Home.${k}`, p as any) as string;\n const session = useObservable(useSemiont().activeSession$);\n const user = useObservable(session?.user$);\n const isAuthenticated = !!user;\n const isAdmin = user?.isAdmin ?? false;\n const isModerator = user?.isModerator ?? false;\n\n return (\n <LeftSidebar\n Link={Link}\n routes={routes}\n t={t}\n tHome={tHome}\n brandingLink=\"/\"\n collapsible={true}\n storageKey=\"knowledgeNavCollapsed\"\n isAuthenticated={isAuthenticated}\n isAdmin={isAdmin}\n isModerator={isModerator}\n >\n {(isCollapsed, toggleCollapsed, navigationMenu) => (\n <KnowledgeNavigation\n isCollapsed={isCollapsed}\n toggleCollapsed={toggleCollapsed}\n navigationMenu={navigationMenu}\n />\n )}\n </LeftSidebar>\n );\n}\n","import { useContext } from 'react';\nimport { Outlet } from 'react-router-dom';\nimport { useTranslation } from 'react-i18next';\nimport { KnowledgeSidebarWrapper } from '@/components/knowledge/KnowledgeSidebarWrapper';\nimport {\n Footer,\n ResourceAnnotationsProvider,\n Toolbar,\n useSemiont,\n useShellStateUnit,\n useObservable,\n useTheme,\n useLineNumbers,\n} from '@semiont/react-ui';\nimport { ToolbarPanels } from '@/components/toolbar/ToolbarPanels';\nimport { CookiePreferences } from '@/components/CookiePreferences';\nimport { KeyboardShortcutsContext } from '@/contexts/KeyboardShortcutsContext';\nimport { Link, routes } from '@/lib/routing';\n\nfunction GlobalEventsConnector() {\n return null;\n}\n\n/**\n * Empty state for the main content area when no KB is connected or authenticated.\n * Shows contextual guidance based on whether any KBs exist.\n */\nfunction DiscoverEmptyState() {\n const { t: _t } = useTranslation();\n const t = (k: string) => _t(`DiscoverEmptyState.${k}`) as string;\n const semiont = useSemiont();\n const knowledgeBases = useObservable(semiont.kbs$) ?? [];\n const activeKnowledgeBase = useObservable(semiont.activeSession$)?.kb ?? null;\n const status = activeKnowledgeBase\n ? semiont.getKbSessionStatus(activeKnowledgeBase.id)\n : null;\n\n if (knowledgeBases.length === 0) {\n return (\n <div style={{ textAlign: 'center', maxWidth: '28rem' }}>\n <h2 style={{ fontSize: '1.1rem', fontWeight: 600, marginBottom: '0.5rem' }}>{t('noKnowledgeBases')}</h2>\n <p style={{ color: 'var(--semiont-color-neutral-400)', fontSize: '0.85rem', lineHeight: 1.5, marginBottom: '0.75rem' }}>\n {t('noKnowledgeBasesHint')}\n </p>\n <p style={{ color: 'var(--semiont-color-neutral-400)', fontSize: '0.85rem', lineHeight: 1.5 }}>\n <a href=\"https://github.com/The-AI-Alliance/semiont\" target=\"_blank\" rel=\"noopener noreferrer\" style={{ color: 'var(--semiont-color-primary-500)' }}>{t('findKnowledgeBases')}</a>\n {' · '}\n <a href=\"https://github.com/The-AI-Alliance/semiont-template-kb\" target=\"_blank\" rel=\"noopener noreferrer\" style={{ color: 'var(--semiont-color-primary-500)' }}>{t('createNew')}</a>\n </p>\n </div>\n );\n }\n\n if (status === 'authenticated') {\n return null;\n }\n\n return (\n <div style={{ textAlign: 'center', maxWidth: '24rem' }}>\n <h2 style={{ fontSize: '1.1rem', fontWeight: 600, marginBottom: '0.5rem' }}>\n {activeKnowledgeBase?.label ?? ''}\n </h2>\n <p style={{ color: 'var(--semiont-color-neutral-400)', fontSize: '0.85rem', lineHeight: 1.5 }}>\n {status === 'expired' ? t('sessionExpired') : t('signedOut')}\n {' '}{t('signInHint')}\n </p>\n </div>\n );\n}\n\nfunction UnauthenticatedKnowledgeLayout({ t, keyboardContext }: { t: (key: string, params?: Record<string, unknown>) => string; keyboardContext: { openKeyboardHelp?: () => void } | null }) {\n const browseStateUnit = useShellStateUnit();\n const activePanel = useObservable(browseStateUnit.activePanel$) ?? null;\n const { theme } = useTheme();\n const { showLineNumbers } = useLineNumbers();\n\n return (\n <div className=\"h-screen semiont-knowledge-layout semiont-layout-with-footer flex flex-col overflow-hidden\">\n <div className=\"flex flex-1 overflow-hidden\">\n <main className=\"flex-1 w-full px-2 pb-6 flex flex-col overflow-hidden\">\n <div className=\"w-full mx-auto flex-1 flex flex-col h-full overflow-hidden items-center justify-center\">\n <DiscoverEmptyState />\n </div>\n </main>\n <ToolbarPanels\n activePanel={activePanel}\n showLineNumbers={showLineNumbers}\n theme={theme}\n />\n <Toolbar activePanel={activePanel} context=\"simple\" />\n </div>\n <Footer\n Link={Link}\n routes={routes}\n t={(key: string, params?: Record<string, unknown>) => t(`Footer.${key}`, params as any) as string}\n CookiePreferences={CookiePreferences}\n showPolicyLinks={!('__TAURI_INTERNALS__' in window)}\n {...(keyboardContext?.openKeyboardHelp && { onOpenKeyboardHelp: keyboardContext.openKeyboardHelp })}\n />\n </div>\n );\n}\n\nfunction KnowledgeLayoutBody() {\n const { t } = useTranslation();\n const keyboardContext = useContext(KeyboardShortcutsContext);\n const semiont = useSemiont();\n const activeKbId = useObservable(semiont.activeKbId$);\n const session = useObservable(semiont.activeSession$);\n const sessionActivating = useObservable(semiont.sessionActivating$);\n const token = useObservable(session?.token$);\n const activeKnowledgeBase = session?.kb ?? null;\n // \"Loading\" = a session construction is actively in flight. Without\n // the `sessionActivating` guard we'd sit on the spinner forever after\n // any `signOut`, which also leaves `activeKbId` set but `session`\n // null.\n const isLoading = activeKbId != null && session == null && sessionActivating;\n\n if (isLoading) {\n return (\n <div className=\"h-screen flex items-center justify-center\">\n <div className=\"text-center\">\n <div className=\"animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4\"></div>\n <p className=\"text-gray-600 dark:text-gray-400\">Loading...</p>\n </div>\n </div>\n );\n }\n\n if (!activeKnowledgeBase || !token) {\n return (\n <UnauthenticatedKnowledgeLayout t={(key: string, params?: Record<string, unknown>) => t(key, params as any) as string} keyboardContext={keyboardContext} />\n );\n }\n\n return (\n <ResourceAnnotationsProvider>\n <GlobalEventsConnector />\n <div className=\"h-screen semiont-knowledge-layout semiont-layout-with-footer flex flex-col overflow-hidden\">\n <div className=\"flex flex-1 overflow-hidden\">\n <KnowledgeSidebarWrapper />\n <main className=\"flex-1 w-full px-2 pb-6 flex flex-col overflow-hidden\">\n <div className=\"w-full mx-auto flex-1 flex flex-col h-full overflow-hidden\">\n <Outlet />\n </div>\n </main>\n </div>\n <Footer\n Link={Link}\n routes={routes}\n t={(key: string, params?: Record<string, unknown>) => t(`Footer.${key}`, params as any) as string}\n CookiePreferences={CookiePreferences}\n showPolicyLinks={!('__TAURI_INTERNALS__' in window)}\n {...(keyboardContext?.openKeyboardHelp && { onOpenKeyboardHelp: keyboardContext.openKeyboardHelp })}\n />\n </div>\n </ResourceAnnotationsProvider>\n );\n}\n\nexport default function KnowledgeLayout() {\n // AuthShell is mounted by the parent ProtectedLayout in App.tsx so it\n // survives navigation between know/, admin/, and moderate/ sections.\n return <KnowledgeLayoutBody />;\n}\n"],"mappings":"qoBAcM,GAAiB,CAAE,gBACvB,EAAA,EAAA,KAAC,OAAD,CAAiB,YAAW,MAAO,CAAE,SAAU,UAAW,WAAY,IAAK,UAAE,KAAS,CAAA,CAUxF,SAAS,EAAS,CAAE,OAAM,GAAI,EAAK,GAAG,GAAgE,CACpG,OAAO,EAAA,EAAA,KAAC,EAAD,CAAM,GAAK,GAAQ,GAAe,GAAI,EAAS,CAAA,CAGxD,SAAgB,EAAoB,CAAE,cAAa,kBAAiB,kBAA4C,CAC9G,GAAM,CAAE,EAAG,GAAO,GAAgB,CAC5B,GAAK,EAAW,IAAgC,EAAG,WAAW,IAAK,EAAS,CAC5E,EAAW,GAAa,CACxB,EAAS,GAAW,CACpB,EAAU,GAAY,CACtB,EAAgB,EAAc,EAAQ,eAAe,EAAI,EAAE,CAC3D,EAAiB,EAAQ,mBAAmB,KAAK,EAAQ,CACzD,EAAmB,EAAQ,qBAAqB,KAAK,EAAQ,CAE7D,EAAoC,CACxC,CACE,KAAM,EAAE,WAAW,CACnB,KAAM,iBACN,KAAM,EACN,YAAa,EAAE,kBAAkB,CAClC,CACD,CACE,KAAM,EAAE,UAAU,CAClB,KAAM,gBACN,KAAM,EACN,YAAa,EAAE,qBAAqB,CACrC,CACF,CAuCD,OAhBA,EAAsB,CACpB,wBAAA,EAAA,EAAA,iBArB4C,CAC5C,GAAiB,EAChB,CAAC,EAAgB,CAmBM,CACxB,cAAA,EAAA,EAAA,cAjBuC,CAAE,gBAAyC,CAClF,EAAe,EAAW,CAGtB,IAAa,kBAAkB,KACjC,EAAO,KAAK,iBAAiB,EAE9B,CAAC,EAAgB,EAAU,EAAO,CAUrB,CACd,gBAAA,EAAA,EAAA,cARyC,CAAE,WAAU,cAAuD,CAC5G,EAAiB,EAAU,EAAS,EACnC,CAAC,EAAiB,CAMH,CACjB,CAAC,EAaA,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,iCACb,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,2CACb,EAAA,EAAA,KAAC,EAAD,CACE,WAAY,EACZ,UAAW,EACE,cACb,YAAa,EACb,cAAe,EACf,WAlBgB,GAAiB,CACvC,EAAO,KAAK,EAAK,EAkBM,gBAdA,GAChB,kBAAkB,IAcnB,UAAU,uBACV,aAAc,CACZ,MAAO,EAAE,QAAQ,CAClB,CACD,MAAO,CACL,YAAa,EACb,KAAM,EACN,MAAO,EACR,CACe,iBAChB,CAAA,CACE,CAAA,CACF,CAAA,CC5GV,SAAgB,GAA0B,CACxC,GAAM,CAAE,EAAG,GAAO,GAAgB,CAC5B,GAAK,EAAW,IAAgC,EAAG,cAAc,IAAK,EAAS,CAC/E,CAAE,EAAG,GAAW,GAAgB,CAChC,GAAS,EAAW,IAAgC,EAAO,QAAQ,IAAK,EAAS,CAEjF,EAAO,EADG,EAAc,GAAY,CAAC,eAChB,EAAS,MAAM,CAK1C,OACE,EAAA,EAAA,KAAC,EAAD,CACQ,KAAA,EACE,SACL,EACI,QACP,aAAa,IACb,YAAa,GACb,WAAW,wBACM,gBAAA,CAbI,CAAC,EAcb,QAbG,GAAM,SAAW,GAchB,YAbG,GAAM,aAAe,aAenC,EAAa,EAAiB,KAC9B,EAAA,EAAA,KAAC,EAAD,CACe,cACI,kBACD,iBAChB,CAAA,CAEQ,CAAA,CClBlB,SAAS,GAAwB,CAC/B,OAAO,KAOT,SAAS,GAAqB,CAC5B,GAAM,CAAE,EAAG,GAAO,GAAgB,CAC5B,EAAK,GAAc,EAAG,sBAAsB,IAAI,CAChD,EAAU,GAAY,CACtB,EAAiB,EAAc,EAAQ,KAAK,EAAI,EAAE,CAClD,EAAsB,EAAc,EAAQ,eAAe,EAAE,IAAM,KACnE,EAAS,EACX,EAAQ,mBAAmB,EAAoB,GAAG,CAClD,KAsBJ,OApBI,EAAe,SAAW,GAE1B,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,CAAE,UAAW,SAAU,SAAU,QAAS,UAAtD,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,MAAO,CAAE,SAAU,SAAU,WAAY,IAAK,aAAc,SAAU,UAAG,EAAE,mBAAmB,CAAM,CAAA,EACxG,EAAA,EAAA,KAAC,IAAD,CAAG,MAAO,CAAE,MAAO,mCAAoC,SAAU,UAAW,WAAY,IAAK,aAAc,UAAW,UACnH,EAAE,uBAAuB,CACxB,CAAA,EACJ,EAAA,EAAA,MAAC,IAAD,CAAG,MAAO,CAAE,MAAO,mCAAoC,SAAU,UAAW,WAAY,IAAK,UAA7F,EACE,EAAA,EAAA,KAAC,IAAD,CAAG,KAAK,6CAA6C,OAAO,SAAS,IAAI,sBAAsB,MAAO,CAAE,MAAO,mCAAoC,UAAG,EAAE,qBAAqB,CAAK,CAAA,CACjL,OACD,EAAA,EAAA,KAAC,IAAD,CAAG,KAAK,yDAAyD,OAAO,SAAS,IAAI,sBAAsB,MAAO,CAAE,MAAO,mCAAoC,UAAG,EAAE,YAAY,CAAK,CAAA,CACnL,GACA,GAIN,IAAW,gBACN,MAIP,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,CAAE,UAAW,SAAU,SAAU,QAAS,UAAtD,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,MAAO,CAAE,SAAU,SAAU,WAAY,IAAK,aAAc,SAAU,UACvE,GAAqB,OAAS,GAC5B,CAAA,EACL,EAAA,EAAA,MAAC,IAAD,CAAG,MAAO,CAAE,MAAO,mCAAoC,SAAU,UAAW,WAAY,IAAK,UAA7F,CAC0B,EAAvB,IAAW,UAAc,iBAAsB,YAAY,CAC3D,IAAK,EAAE,aAAa,CACnB,GACA,GAIV,SAAS,EAA+B,CAAE,IAAG,mBAAgJ,CAE3L,IAAM,EAAc,EADI,GACU,CAAgB,aAAa,EAAI,KAC7D,CAAE,SAAU,GAAU,CACtB,CAAE,mBAAoB,GAAgB,CAE5C,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,sGAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,uCAAf,EACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,kEACd,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,mGACb,EAAA,EAAA,KAAC,EAAD,EAAsB,CAAA,CAClB,CAAA,CACD,CAAA,EACP,EAAA,EAAA,KAAC,EAAD,CACe,cACI,kBACV,QACP,CAAA,EACF,EAAA,EAAA,KAAC,EAAD,CAAsB,cAAa,QAAQ,SAAW,CAAA,CAClD,IACN,EAAA,EAAA,KAAC,EAAD,CACQ,KAAA,EACE,SACR,GAAI,EAAa,IAAqC,EAAE,UAAU,IAAO,EAAc,CACpE,oBACnB,gBAAiB,EAAE,wBAAyB,QAC5C,GAAK,GAAiB,kBAAoB,CAAE,mBAAoB,EAAgB,iBAAkB,CAClG,CAAA,CACE,GAIV,SAAS,GAAsB,CAC7B,GAAM,CAAE,KAAM,GAAgB,CACxB,GAAA,EAAA,EAAA,YAA6B,EAAyB,CACtD,EAAU,GAAY,CACtB,EAAa,EAAc,EAAQ,YAAY,CAC/C,EAAU,EAAc,EAAQ,eAAe,CAC/C,EAAoB,EAAc,EAAQ,mBAAmB,CAC7D,EAAQ,EAAc,GAAS,OAAO,CACtC,EAAsB,GAAS,IAAM,KAwB3C,OAnBkB,GAAc,MAAQ,GAAW,MAAQ,GAIvD,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,sDACb,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,uBAAf,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,8EAAoF,CAAA,EACnG,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,4CAAmC,aAAc,CAAA,CAC1D,GACF,CAAA,CAIN,CAAC,GAAuB,CAAC,GAEzB,EAAA,EAAA,KAAC,EAAD,CAAgC,GAAI,EAAa,IAAqC,EAAE,EAAK,EAAc,CAA6B,kBAAmB,CAAA,EAK7J,EAAA,EAAA,MAAC,EAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAD,EAAyB,CAAA,EACzB,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,sGAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,uCAAf,EACE,EAAA,EAAA,KAAC,EAAD,EAA2B,CAAA,EAC3B,EAAA,EAAA,KAAC,OAAD,CAAM,UAAU,kEACd,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,uEACb,EAAA,EAAA,KAAC,EAAD,EAAU,CAAA,CACN,CAAA,CACD,CAAA,CACH,IACN,EAAA,EAAA,KAAC,EAAD,CACQ,KAAA,EACE,SACR,GAAI,EAAa,IAAqC,EAAE,UAAU,IAAO,EAAc,CACpE,oBACnB,gBAAiB,EAAE,wBAAyB,QAC5C,GAAK,GAAiB,kBAAoB,CAAE,mBAAoB,EAAgB,iBAAkB,CAClG,CAAA,CACE,GACsB,CAAA,CAAA,CAIlC,SAAwB,GAAkB,CAGxC,OAAO,EAAA,EAAA,KAAC,EAAD,EAAuB,CAAA"}
@@ -1,2 +1,2 @@
1
- import{n as e}from"./rolldown-runtime-jpDsebLB.js";import{i as t,n}from"./i18n-B53Yefbh.js";import{t as r}from"./vendor-0HjOURbh.js";import{D as i,Pt as a,Z as o,f as s,ot as c,q as l,u}from"./index-DjtRDlfn.js";import{t as d}from"./KeyboardShortcutsContext-BRLeqQUj.js";import{n as f,t as p}from"./CookiePreferences-CMgprW9V.js";import{t as m}from"./ArrowsRightLeftIcon-eQUXtsyS.js";import{n as h,t as g}from"./ChevronLeftIcon-QLs1eT1j.js";import{t as _}from"./CommandLineIcon-BEeeWFhQ.js";import{i as v,r as y,t as b}from"./routing-Bcj1FhkC.js";import{n as x,t as S}from"./routing-DW1ehi64.js";var C=e(t());function w({title:e,titleId:t,...n},r){return C.createElement(`svg`,Object.assign({xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,strokeWidth:1.5,stroke:`currentColor`,"aria-hidden":`true`,"data-slot":`icon`,ref:r,"aria-labelledby":t},n),e?C.createElement(`title`,{id:t},e):null,C.createElement(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z`}))}var T=C.forwardRef(w),E=r();function D({href:e,to:t,...n}){return(0,E.jsx)(b,{to:e??``,...n})}function O({isCollapsed:e,toggleCollapsed:t,navigationMenu:r}){let{t:a}=n(),o=(e,t)=>a(`Administration.${e}`,t),{t:s}=n(),c=(e,t)=>s(`Sidebar.${e}`,t),u=y();l({"shell:sidebar-toggle":(0,C.useCallback)(()=>{t()},[t])});let d=[{name:o(`users`),href:`/admin/users`,icon:T,description:o(`usersDescription`)},{name:o(`oauthSettings`),href:`/admin/security`,icon:f,description:o(`oauthSettingsDescription`)},{name:o(`exchange`),href:`/admin/exchange`,icon:m,description:o(`exchangeDescription`)},{name:o(`devops`),href:`/admin/devops`,icon:_,description:o(`devopsDescription`)}];return(0,E.jsx)(i,{title:o(`title`),items:d,currentPath:u,LinkComponent:D,...r&&{dropdownContent:r},isCollapsed:e,icons:{chevronLeft:g,bars:h},collapseSidebarLabel:c(`collapseSidebar`),expandSidebarLabel:c(`expandSidebar`)})}function k(){let{t:e}=n(),t=(0,C.useContext)(d),r=o(c().activeSession$),i=o(r?.user$),l=r?.kb??null,f=v();return l?(0,E.jsxs)(`div`,{className:`min-h-screen bg-gray-50 dark:bg-gray-900 flex flex-col`,children:[(0,E.jsxs)(`div`,{className:`flex flex-1`,children:[(0,E.jsx)(s,{Link:S,routes:x,t:t=>e(`Navigation.${t}`),tHome:t=>e(`Home.${t}`),brandingLink:`/`,collapsible:!0,storageKey:`admin-sidebar-collapsed`,isAuthenticated:!!i,isAdmin:i?.isAdmin??!1,isModerator:i?.isModerator??!1,children:(e,t,n)=>(0,E.jsx)(O,{isCollapsed:e,toggleCollapsed:t,navigationMenu:n})}),(0,E.jsx)(`main`,{className:`flex-1 p-6 flex flex-col`,children:(0,E.jsx)(`div`,{className:`max-w-7xl mx-auto flex-1 flex flex-col w-full`,children:(0,E.jsx)(a,{})})})]}),(0,E.jsx)(u,{Link:S,routes:x,t:(t,n)=>e(`Footer.${t}`,n),CookiePreferences:p,...t?.openKeyboardHelp&&{onOpenKeyboardHelp:t.openKeyboardHelp}})]}):(f.push(`/know`),null)}function A(){return(0,E.jsx)(k,{})}export{A as default};
2
- //# sourceMappingURL=layout-BhnmJA6O.js.map
1
+ import{n as e}from"./rolldown-runtime-jpDsebLB.js";import{i as t,n}from"./i18n-B53Yefbh.js";import{t as r}from"./vendor-0HjOURbh.js";import{D as i,Pt as a,Z as o,f as s,ot as c,q as l,u}from"./index-DojEUBpq.js";import{t as d}from"./KeyboardShortcutsContext-CK7NFEft.js";import{n as f,t as p}from"./CookiePreferences-Vt05bBY7.js";import{t as m}from"./ArrowsRightLeftIcon-eQUXtsyS.js";import{n as h,t as g}from"./ChevronLeftIcon-QLs1eT1j.js";import{t as _}from"./CommandLineIcon-BEeeWFhQ.js";import{i as v,r as y,t as b}from"./routing-Dqgz2rV4.js";import{n as x,t as S}from"./routing-CcetIVef.js";var C=e(t());function w({title:e,titleId:t,...n},r){return C.createElement(`svg`,Object.assign({xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,strokeWidth:1.5,stroke:`currentColor`,"aria-hidden":`true`,"data-slot":`icon`,ref:r,"aria-labelledby":t},n),e?C.createElement(`title`,{id:t},e):null,C.createElement(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z`}))}var T=C.forwardRef(w),E=r();function D({href:e,to:t,...n}){return(0,E.jsx)(b,{to:e??``,...n})}function O({isCollapsed:e,toggleCollapsed:t,navigationMenu:r}){let{t:a}=n(),o=(e,t)=>a(`Administration.${e}`,t),{t:s}=n(),c=(e,t)=>s(`Sidebar.${e}`,t),u=y();l({"shell:sidebar-toggle":(0,C.useCallback)(()=>{t()},[t])});let d=[{name:o(`users`),href:`/admin/users`,icon:T,description:o(`usersDescription`)},{name:o(`oauthSettings`),href:`/admin/security`,icon:f,description:o(`oauthSettingsDescription`)},{name:o(`exchange`),href:`/admin/exchange`,icon:m,description:o(`exchangeDescription`)},{name:o(`devops`),href:`/admin/devops`,icon:_,description:o(`devopsDescription`)}];return(0,E.jsx)(i,{title:o(`title`),items:d,currentPath:u,LinkComponent:D,...r&&{dropdownContent:r},isCollapsed:e,icons:{chevronLeft:g,bars:h},collapseSidebarLabel:c(`collapseSidebar`),expandSidebarLabel:c(`expandSidebar`)})}function k(){let{t:e}=n(),t=(0,C.useContext)(d),r=o(c().activeSession$),i=o(r?.user$),l=r?.kb??null,f=v();return l?(0,E.jsxs)(`div`,{className:`min-h-screen bg-gray-50 dark:bg-gray-900 flex flex-col`,children:[(0,E.jsxs)(`div`,{className:`flex flex-1`,children:[(0,E.jsx)(s,{Link:S,routes:x,t:t=>e(`Navigation.${t}`),tHome:t=>e(`Home.${t}`),brandingLink:`/`,collapsible:!0,storageKey:`admin-sidebar-collapsed`,isAuthenticated:!!i,isAdmin:i?.isAdmin??!1,isModerator:i?.isModerator??!1,children:(e,t,n)=>(0,E.jsx)(O,{isCollapsed:e,toggleCollapsed:t,navigationMenu:n})}),(0,E.jsx)(`main`,{className:`flex-1 p-6 flex flex-col`,children:(0,E.jsx)(`div`,{className:`max-w-7xl mx-auto flex-1 flex flex-col w-full`,children:(0,E.jsx)(a,{})})})]}),(0,E.jsx)(u,{Link:S,routes:x,t:(t,n)=>e(`Footer.${t}`,n),CookiePreferences:p,...t?.openKeyboardHelp&&{onOpenKeyboardHelp:t.openKeyboardHelp}})]}):(f.push(`/know`),null)}function A(){return(0,E.jsx)(k,{})}export{A as default};
2
+ //# sourceMappingURL=layout-DGddEk2F.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"layout-BhnmJA6O.js","names":[],"sources":["../../../../node_modules/@heroicons/react/24/outline/esm/UsersIcon.js","../../src/components/admin/AdminNavigation.tsx","../../src/app/[locale]/admin/layout.tsx"],"sourcesContent":["import * as React from \"react\";\nfunction UsersIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(UsersIcon);\nexport default ForwardRef;","import React, { useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Link } from '@/i18n/routing';\nimport { usePathname } from '@/i18n/routing';\nimport { SimpleNavigation, useEventSubscriptions } from '@semiont/react-ui';\nimport type { SimpleNavigationItem } from '@semiont/react-ui';\nimport {\n UsersIcon,\n ShieldCheckIcon,\n CommandLineIcon,\n ArrowsRightLeftIcon,\n ChevronLeftIcon,\n Bars3Icon\n} from '@heroicons/react/24/outline';\n\ninterface AdminNavigationProps {\n isCollapsed: boolean;\n toggleCollapsed: () => void;\n navigationMenu?: (onClose: () => void) => React.ReactNode;\n}\n\n// Adapter: SimpleNavigation passes href, but our Link uses `to`\nfunction HrefLink({ href, to: _to, ...props }: React.ComponentProps<typeof Link> & { href?: string }) {\n return <Link to={(href ?? '') as string} {...props} />;\n}\n\nexport function AdminNavigation({ isCollapsed, toggleCollapsed, navigationMenu }: AdminNavigationProps) {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`Administration.${k}`, p as any) as string;\n const { t: _tSidebar } = useTranslation();\n const tSidebar = (k: string, p?: Record<string, unknown>) => _tSidebar(`Sidebar.${k}`, p as any) as string;\n const pathname = usePathname();\n\n // Handle sidebar toggle events\n const handleSidebarToggle = useCallback(() => {\n toggleCollapsed();\n }, [toggleCollapsed]);\n\n // Subscribe to sidebar toggle events\n useEventSubscriptions({\n 'shell:sidebar-toggle': handleSidebarToggle,\n });\n\n const navigation: SimpleNavigationItem[] = [\n {\n name: t('users'),\n href: '/admin/users',\n icon: UsersIcon,\n description: t('usersDescription')\n },\n {\n name: t('oauthSettings'),\n href: '/admin/security',\n icon: ShieldCheckIcon,\n description: t('oauthSettingsDescription')\n },\n {\n name: t('exchange'),\n href: '/admin/exchange',\n icon: ArrowsRightLeftIcon,\n description: t('exchangeDescription')\n },\n {\n name: t('devops'),\n href: '/admin/devops',\n icon: CommandLineIcon,\n description: t('devopsDescription')\n },\n ];\n\n return (\n <SimpleNavigation\n title={t('title')}\n items={navigation}\n currentPath={pathname}\n LinkComponent={HrefLink as any}\n {...(navigationMenu && { dropdownContent: navigationMenu })}\n isCollapsed={isCollapsed}\n icons={{\n chevronLeft: ChevronLeftIcon as React.ComponentType<{ className?: string }>,\n bars: Bars3Icon as React.ComponentType<{ className?: string }>\n }}\n collapseSidebarLabel={tSidebar('collapseSidebar')}\n expandSidebarLabel={tSidebar('expandSidebar')}\n />\n );\n}","import { useContext } from 'react';\nimport { Outlet } from 'react-router-dom';\nimport { useTranslation } from 'react-i18next';\nimport { AdminNavigation } from '@/components/admin/AdminNavigation';\nimport {\n LeftSidebar,\n Footer,\n useSemiont,\n useObservable,\n} from '@semiont/react-ui';\nimport { CookiePreferences } from '@/components/CookiePreferences';\nimport { KeyboardShortcutsContext } from '@/contexts/KeyboardShortcutsContext';\nimport { Link, routes } from '@/lib/routing';\nimport { useRouter } from '@/i18n/routing';\n\nfunction AdminLayoutBody() {\n const { t } = useTranslation();\n const keyboardContext = useContext(KeyboardShortcutsContext);\n const semiont = useSemiont();\n const session = useObservable(semiont.activeSession$);\n const user = useObservable(session?.user$);\n const activeKnowledgeBase = session?.kb ?? null;\n const router = useRouter();\n\n if (!activeKnowledgeBase) {\n router.push('/know');\n return null;\n }\n\n const isAuthenticated = !!user;\n const isAdmin = user?.isAdmin ?? false;\n const isModerator = user?.isModerator ?? false;\n\n return (\n <div className=\"min-h-screen bg-gray-50 dark:bg-gray-900 flex flex-col\">\n <div className=\"flex flex-1\">\n <LeftSidebar\n Link={Link}\n routes={routes}\n t={(key: string) => t(`Navigation.${key}`)}\n tHome={(key: string) => t(`Home.${key}`)}\n brandingLink=\"/\"\n collapsible={true}\n storageKey=\"admin-sidebar-collapsed\"\n isAuthenticated={isAuthenticated}\n isAdmin={isAdmin}\n isModerator={isModerator}\n >\n {(isCollapsed, toggleCollapsed, navigationMenu) => (\n <AdminNavigation\n isCollapsed={isCollapsed}\n toggleCollapsed={toggleCollapsed}\n navigationMenu={navigationMenu}\n />\n )}\n </LeftSidebar>\n <main className=\"flex-1 p-6 flex flex-col\">\n <div className=\"max-w-7xl mx-auto flex-1 flex flex-col w-full\">\n <Outlet />\n </div>\n </main>\n </div>\n <Footer\n Link={Link}\n routes={routes}\n t={(key: string, params?: Record<string, unknown>) => t(`Footer.${key}`, params as any) as string}\n CookiePreferences={CookiePreferences}\n {...(keyboardContext?.openKeyboardHelp && { onOpenKeyboardHelp: keyboardContext.openKeyboardHelp })}\n />\n </div>\n );\n}\n\nexport default function AdminLayout() {\n // AuthShell is mounted by the parent ProtectedLayout in App.tsx so it\n // survives navigation between know/, admin/, and moderate/ sections.\n return <AdminLayoutBody />;\n}\n"],"x_google_ignoreList":[0],"mappings":"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"}
1
+ {"version":3,"file":"layout-DGddEk2F.js","names":[],"sources":["../../../../node_modules/@heroicons/react/24/outline/esm/UsersIcon.js","../../src/components/admin/AdminNavigation.tsx","../../src/app/[locale]/admin/layout.tsx"],"sourcesContent":["import * as React from \"react\";\nfunction UsersIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(UsersIcon);\nexport default ForwardRef;","import React, { useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Link } from '@/i18n/routing';\nimport { usePathname } from '@/i18n/routing';\nimport { SimpleNavigation, useEventSubscriptions } from '@semiont/react-ui';\nimport type { SimpleNavigationItem } from '@semiont/react-ui';\nimport {\n UsersIcon,\n ShieldCheckIcon,\n CommandLineIcon,\n ArrowsRightLeftIcon,\n ChevronLeftIcon,\n Bars3Icon\n} from '@heroicons/react/24/outline';\n\ninterface AdminNavigationProps {\n isCollapsed: boolean;\n toggleCollapsed: () => void;\n navigationMenu?: (onClose: () => void) => React.ReactNode;\n}\n\n// Adapter: SimpleNavigation passes href, but our Link uses `to`\nfunction HrefLink({ href, to: _to, ...props }: React.ComponentProps<typeof Link> & { href?: string }) {\n return <Link to={(href ?? '') as string} {...props} />;\n}\n\nexport function AdminNavigation({ isCollapsed, toggleCollapsed, navigationMenu }: AdminNavigationProps) {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`Administration.${k}`, p as any) as string;\n const { t: _tSidebar } = useTranslation();\n const tSidebar = (k: string, p?: Record<string, unknown>) => _tSidebar(`Sidebar.${k}`, p as any) as string;\n const pathname = usePathname();\n\n // Handle sidebar toggle events\n const handleSidebarToggle = useCallback(() => {\n toggleCollapsed();\n }, [toggleCollapsed]);\n\n // Subscribe to sidebar toggle events\n useEventSubscriptions({\n 'shell:sidebar-toggle': handleSidebarToggle,\n });\n\n const navigation: SimpleNavigationItem[] = [\n {\n name: t('users'),\n href: '/admin/users',\n icon: UsersIcon,\n description: t('usersDescription')\n },\n {\n name: t('oauthSettings'),\n href: '/admin/security',\n icon: ShieldCheckIcon,\n description: t('oauthSettingsDescription')\n },\n {\n name: t('exchange'),\n href: '/admin/exchange',\n icon: ArrowsRightLeftIcon,\n description: t('exchangeDescription')\n },\n {\n name: t('devops'),\n href: '/admin/devops',\n icon: CommandLineIcon,\n description: t('devopsDescription')\n },\n ];\n\n return (\n <SimpleNavigation\n title={t('title')}\n items={navigation}\n currentPath={pathname}\n LinkComponent={HrefLink as any}\n {...(navigationMenu && { dropdownContent: navigationMenu })}\n isCollapsed={isCollapsed}\n icons={{\n chevronLeft: ChevronLeftIcon as React.ComponentType<{ className?: string }>,\n bars: Bars3Icon as React.ComponentType<{ className?: string }>\n }}\n collapseSidebarLabel={tSidebar('collapseSidebar')}\n expandSidebarLabel={tSidebar('expandSidebar')}\n />\n );\n}","import { useContext } from 'react';\nimport { Outlet } from 'react-router-dom';\nimport { useTranslation } from 'react-i18next';\nimport { AdminNavigation } from '@/components/admin/AdminNavigation';\nimport {\n LeftSidebar,\n Footer,\n useSemiont,\n useObservable,\n} from '@semiont/react-ui';\nimport { CookiePreferences } from '@/components/CookiePreferences';\nimport { KeyboardShortcutsContext } from '@/contexts/KeyboardShortcutsContext';\nimport { Link, routes } from '@/lib/routing';\nimport { useRouter } from '@/i18n/routing';\n\nfunction AdminLayoutBody() {\n const { t } = useTranslation();\n const keyboardContext = useContext(KeyboardShortcutsContext);\n const semiont = useSemiont();\n const session = useObservable(semiont.activeSession$);\n const user = useObservable(session?.user$);\n const activeKnowledgeBase = session?.kb ?? null;\n const router = useRouter();\n\n if (!activeKnowledgeBase) {\n router.push('/know');\n return null;\n }\n\n const isAuthenticated = !!user;\n const isAdmin = user?.isAdmin ?? false;\n const isModerator = user?.isModerator ?? false;\n\n return (\n <div className=\"min-h-screen bg-gray-50 dark:bg-gray-900 flex flex-col\">\n <div className=\"flex flex-1\">\n <LeftSidebar\n Link={Link}\n routes={routes}\n t={(key: string) => t(`Navigation.${key}`)}\n tHome={(key: string) => t(`Home.${key}`)}\n brandingLink=\"/\"\n collapsible={true}\n storageKey=\"admin-sidebar-collapsed\"\n isAuthenticated={isAuthenticated}\n isAdmin={isAdmin}\n isModerator={isModerator}\n >\n {(isCollapsed, toggleCollapsed, navigationMenu) => (\n <AdminNavigation\n isCollapsed={isCollapsed}\n toggleCollapsed={toggleCollapsed}\n navigationMenu={navigationMenu}\n />\n )}\n </LeftSidebar>\n <main className=\"flex-1 p-6 flex flex-col\">\n <div className=\"max-w-7xl mx-auto flex-1 flex flex-col w-full\">\n <Outlet />\n </div>\n </main>\n </div>\n <Footer\n Link={Link}\n routes={routes}\n t={(key: string, params?: Record<string, unknown>) => t(`Footer.${key}`, params as any) as string}\n CookiePreferences={CookiePreferences}\n {...(keyboardContext?.openKeyboardHelp && { onOpenKeyboardHelp: keyboardContext.openKeyboardHelp })}\n />\n </div>\n );\n}\n\nexport default function AdminLayout() {\n // AuthShell is mounted by the parent ProtectedLayout in App.tsx so it\n // survives navigation between know/, admin/, and moderate/ sections.\n return <AdminLayoutBody />;\n}\n"],"x_google_ignoreList":[0],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{n as e}from"./rolldown-runtime-jpDsebLB.js";import{i as t,n}from"./i18n-B53Yefbh.js";import{t as r}from"./vendor-0HjOURbh.js";import{D as i,Pt as a,Z as o,f as s,ot as c,q as l,u}from"./index-DjtRDlfn.js";import{t as d}from"./KeyboardShortcutsContext-BRLeqQUj.js";import{t as f}from"./CookiePreferences-CMgprW9V.js";import{t as p}from"./ArrowsRightLeftIcon-eQUXtsyS.js";import{n as m,t as h}from"./ChevronLeftIcon-QLs1eT1j.js";import{i as g,r as _,t as v}from"./routing-Bcj1FhkC.js";import{n as y,t as b}from"./routing-DW1ehi64.js";var x=e(t());function S({title:e,titleId:t,...n},r){return x.createElement(`svg`,Object.assign({xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,strokeWidth:1.5,stroke:`currentColor`,"aria-hidden":`true`,"data-slot":`icon`,ref:r,"aria-labelledby":t},n),e?x.createElement(`title`,{id:t},e):null,x.createElement(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M12 6.042A8.967 8.967 0 0 0 6 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 0 1 6 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 0 1 6-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0 0 18 18a8.967 8.967 0 0 0-6 2.292m0-14.25v14.25`}))}var C=x.forwardRef(S);function w({title:e,titleId:t,...n},r){return x.createElement(`svg`,Object.assign({xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,strokeWidth:1.5,stroke:`currentColor`,"aria-hidden":`true`,"data-slot":`icon`,ref:r,"aria-labelledby":t},n),e?x.createElement(`title`,{id:t},e):null,x.createElement(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z`}))}var T=x.forwardRef(w);function E({title:e,titleId:t,...n},r){return x.createElement(`svg`,Object.assign({xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,strokeWidth:1.5,stroke:`currentColor`,"aria-hidden":`true`,"data-slot":`icon`,ref:r,"aria-labelledby":t},n),e?x.createElement(`title`,{id:t},e):null,x.createElement(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M9.568 3H5.25A2.25 2.25 0 0 0 3 5.25v4.318c0 .597.237 1.17.659 1.591l9.581 9.581c.699.699 1.78.872 2.607.33a18.095 18.095 0 0 0 5.223-5.223c.542-.827.369-1.908-.33-2.607L11.16 3.66A2.25 2.25 0 0 0 9.568 3Z`}),x.createElement(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M6 6h.008v.008H6V6Z`}))}var D=x.forwardRef(E),O=r();function k({href:e,to:t,...n}){return(0,O.jsx)(v,{to:e??``,...n})}function A({isCollapsed:e,toggleCollapsed:t,navigationMenu:r}){let{t:a}=n(),o=(e,t)=>a(`Moderation.${e}`,t),{t:s}=n(),c=(e,t)=>s(`Sidebar.${e}`,t),u=_();l({"shell:sidebar-toggle":(0,x.useCallback)(()=>{t()},[t])});let d=[{name:o(`recentResources`),href:`/moderate/recent`,icon:T,description:o(`recentResourcesDescription`)},{name:o(`entityTags`),href:`/moderate/entity-tags`,icon:D,description:o(`entityTagsDescription`)},{name:o(`tagSchemas`),href:`/moderate/tag-schemas`,icon:C,description:o(`tagSchemasDescription`)},{name:o(`linkedData`),href:`/moderate/linked-data`,icon:p,description:o(`linkedDataDescription`)}];return(0,O.jsx)(i,{title:o(`title`),items:d,currentPath:u,LinkComponent:k,...r&&{dropdownContent:r},isCollapsed:e,icons:{chevronLeft:h,bars:m},collapseSidebarLabel:c(`collapseSidebar`),expandSidebarLabel:c(`expandSidebar`)})}function j(){let{t:e}=n(),t=(0,x.useContext)(d),r=o(c().activeSession$),i=o(r?.user$),l=r?.kb??null,p=g();return l?(0,O.jsxs)(`div`,{className:`min-h-screen bg-gray-50 dark:bg-gray-900 flex flex-col`,children:[(0,O.jsxs)(`div`,{className:`flex flex-1`,children:[(0,O.jsx)(s,{Link:b,routes:y,t:t=>e(`Navigation.${t}`),tHome:t=>e(`Home.${t}`),brandingLink:`/`,collapsible:!0,storageKey:`moderation-sidebar-collapsed`,isAuthenticated:!!i,isAdmin:i?.isAdmin??!1,isModerator:i?.isModerator??!1,children:(e,t,n)=>(0,O.jsx)(A,{isCollapsed:e,toggleCollapsed:t,navigationMenu:n})}),(0,O.jsx)(`main`,{className:`flex-1 p-6 flex flex-col`,children:(0,O.jsx)(`div`,{className:`max-w-7xl mx-auto flex-1 flex flex-col w-full`,children:(0,O.jsx)(a,{})})})]}),(0,O.jsx)(u,{Link:b,routes:y,t:(t,n)=>e(`Footer.${t}`,n),CookiePreferences:f,...t?.openKeyboardHelp&&{onOpenKeyboardHelp:t.openKeyboardHelp}})]}):(p.push(`/know`),null)}function M(){return(0,O.jsx)(j,{})}export{M as default};
2
- //# sourceMappingURL=layout-e6QyrD0Y.js.map
1
+ import{n as e}from"./rolldown-runtime-jpDsebLB.js";import{i as t,n}from"./i18n-B53Yefbh.js";import{t as r}from"./vendor-0HjOURbh.js";import{D as i,Pt as a,Z as o,f as s,ot as c,q as l,u}from"./index-DojEUBpq.js";import{t as d}from"./KeyboardShortcutsContext-CK7NFEft.js";import{t as f}from"./CookiePreferences-Vt05bBY7.js";import{t as p}from"./ArrowsRightLeftIcon-eQUXtsyS.js";import{n as m,t as h}from"./ChevronLeftIcon-QLs1eT1j.js";import{i as g,r as _,t as v}from"./routing-Dqgz2rV4.js";import{n as y,t as b}from"./routing-CcetIVef.js";var x=e(t());function S({title:e,titleId:t,...n},r){return x.createElement(`svg`,Object.assign({xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,strokeWidth:1.5,stroke:`currentColor`,"aria-hidden":`true`,"data-slot":`icon`,ref:r,"aria-labelledby":t},n),e?x.createElement(`title`,{id:t},e):null,x.createElement(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M12 6.042A8.967 8.967 0 0 0 6 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 0 1 6 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 0 1 6-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0 0 18 18a8.967 8.967 0 0 0-6 2.292m0-14.25v14.25`}))}var C=x.forwardRef(S);function w({title:e,titleId:t,...n},r){return x.createElement(`svg`,Object.assign({xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,strokeWidth:1.5,stroke:`currentColor`,"aria-hidden":`true`,"data-slot":`icon`,ref:r,"aria-labelledby":t},n),e?x.createElement(`title`,{id:t},e):null,x.createElement(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z`}))}var T=x.forwardRef(w);function E({title:e,titleId:t,...n},r){return x.createElement(`svg`,Object.assign({xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,strokeWidth:1.5,stroke:`currentColor`,"aria-hidden":`true`,"data-slot":`icon`,ref:r,"aria-labelledby":t},n),e?x.createElement(`title`,{id:t},e):null,x.createElement(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M9.568 3H5.25A2.25 2.25 0 0 0 3 5.25v4.318c0 .597.237 1.17.659 1.591l9.581 9.581c.699.699 1.78.872 2.607.33a18.095 18.095 0 0 0 5.223-5.223c.542-.827.369-1.908-.33-2.607L11.16 3.66A2.25 2.25 0 0 0 9.568 3Z`}),x.createElement(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M6 6h.008v.008H6V6Z`}))}var D=x.forwardRef(E),O=r();function k({href:e,to:t,...n}){return(0,O.jsx)(v,{to:e??``,...n})}function A({isCollapsed:e,toggleCollapsed:t,navigationMenu:r}){let{t:a}=n(),o=(e,t)=>a(`Moderation.${e}`,t),{t:s}=n(),c=(e,t)=>s(`Sidebar.${e}`,t),u=_();l({"shell:sidebar-toggle":(0,x.useCallback)(()=>{t()},[t])});let d=[{name:o(`recentResources`),href:`/moderate/recent`,icon:T,description:o(`recentResourcesDescription`)},{name:o(`entityTags`),href:`/moderate/entity-tags`,icon:D,description:o(`entityTagsDescription`)},{name:o(`tagSchemas`),href:`/moderate/tag-schemas`,icon:C,description:o(`tagSchemasDescription`)},{name:o(`linkedData`),href:`/moderate/linked-data`,icon:p,description:o(`linkedDataDescription`)}];return(0,O.jsx)(i,{title:o(`title`),items:d,currentPath:u,LinkComponent:k,...r&&{dropdownContent:r},isCollapsed:e,icons:{chevronLeft:h,bars:m},collapseSidebarLabel:c(`collapseSidebar`),expandSidebarLabel:c(`expandSidebar`)})}function j(){let{t:e}=n(),t=(0,x.useContext)(d),r=o(c().activeSession$),i=o(r?.user$),l=r?.kb??null,p=g();return l?(0,O.jsxs)(`div`,{className:`min-h-screen bg-gray-50 dark:bg-gray-900 flex flex-col`,children:[(0,O.jsxs)(`div`,{className:`flex flex-1`,children:[(0,O.jsx)(s,{Link:b,routes:y,t:t=>e(`Navigation.${t}`),tHome:t=>e(`Home.${t}`),brandingLink:`/`,collapsible:!0,storageKey:`moderation-sidebar-collapsed`,isAuthenticated:!!i,isAdmin:i?.isAdmin??!1,isModerator:i?.isModerator??!1,children:(e,t,n)=>(0,O.jsx)(A,{isCollapsed:e,toggleCollapsed:t,navigationMenu:n})}),(0,O.jsx)(`main`,{className:`flex-1 p-6 flex flex-col`,children:(0,O.jsx)(`div`,{className:`max-w-7xl mx-auto flex-1 flex flex-col w-full`,children:(0,O.jsx)(a,{})})})]}),(0,O.jsx)(u,{Link:b,routes:y,t:(t,n)=>e(`Footer.${t}`,n),CookiePreferences:f,...t?.openKeyboardHelp&&{onOpenKeyboardHelp:t.openKeyboardHelp}})]}):(p.push(`/know`),null)}function M(){return(0,O.jsx)(j,{})}export{M as default};
2
+ //# sourceMappingURL=layout-WUjhuEFR.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"layout-e6QyrD0Y.js","names":["ForwardRef","ForwardRef"],"sources":["../../../../node_modules/@heroicons/react/24/outline/esm/BookOpenIcon.js","../../../../node_modules/@heroicons/react/24/outline/esm/ClockIcon.js","../../../../node_modules/@heroicons/react/24/outline/esm/TagIcon.js","../../src/components/moderation/ModerationNavigation.tsx","../../src/app/[locale]/moderate/layout.tsx"],"sourcesContent":["import * as React from \"react\";\nfunction BookOpenIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"M12 6.042A8.967 8.967 0 0 0 6 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 0 1 6 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 0 1 6-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0 0 18 18a8.967 8.967 0 0 0-6 2.292m0-14.25v14.25\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(BookOpenIcon);\nexport default ForwardRef;","import * as React from \"react\";\nfunction ClockIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(ClockIcon);\nexport default ForwardRef;","import * as React from \"react\";\nfunction TagIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"M9.568 3H5.25A2.25 2.25 0 0 0 3 5.25v4.318c0 .597.237 1.17.659 1.591l9.581 9.581c.699.699 1.78.872 2.607.33a18.095 18.095 0 0 0 5.223-5.223c.542-.827.369-1.908-.33-2.607L11.16 3.66A2.25 2.25 0 0 0 9.568 3Z\"\n }), /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"M6 6h.008v.008H6V6Z\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(TagIcon);\nexport default ForwardRef;","import React, { useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Link } from '@/i18n/routing';\nimport { usePathname } from '@/i18n/routing';\nimport { SimpleNavigation, useEventSubscriptions } from '@semiont/react-ui';\nimport type { SimpleNavigationItem } from '@semiont/react-ui';\nimport {\n ClockIcon,\n TagIcon,\n BookOpenIcon,\n ArrowsRightLeftIcon,\n ChevronLeftIcon,\n Bars3Icon\n} from '@heroicons/react/24/outline';\n\ninterface ModerationNavigationProps {\n isCollapsed: boolean;\n toggleCollapsed: () => void;\n navigationMenu?: (onClose: () => void) => React.ReactNode;\n}\n\n// Adapter: SimpleNavigation passes href, but our Link uses `to`\nfunction HrefLink({ href, to: _to, ...props }: React.ComponentProps<typeof Link> & { href?: string }) {\n return <Link to={(href ?? '') as string} {...props} />;\n}\n\nexport function ModerationNavigation({ isCollapsed, toggleCollapsed, navigationMenu }: ModerationNavigationProps) {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`Moderation.${k}`, p as any) as string;\n const { t: _tSidebar } = useTranslation();\n const tSidebar = (k: string, p?: Record<string, unknown>) => _tSidebar(`Sidebar.${k}`, p as any) as string;\n const pathname = usePathname();\n\n // Handle sidebar toggle events\n const handleSidebarToggle = useCallback(() => {\n toggleCollapsed();\n }, [toggleCollapsed]);\n\n // Subscribe to sidebar toggle events\n useEventSubscriptions({\n 'shell:sidebar-toggle': handleSidebarToggle,\n });\n\n const navigation: SimpleNavigationItem[] = [\n {\n name: t('recentResources'),\n href: '/moderate/recent',\n icon: ClockIcon,\n description: t('recentResourcesDescription')\n },\n {\n name: t('entityTags'),\n href: '/moderate/entity-tags',\n icon: TagIcon,\n description: t('entityTagsDescription')\n },\n {\n name: t('tagSchemas'),\n href: '/moderate/tag-schemas',\n icon: BookOpenIcon,\n description: t('tagSchemasDescription')\n },\n {\n name: t('linkedData'),\n href: '/moderate/linked-data',\n icon: ArrowsRightLeftIcon,\n description: t('linkedDataDescription')\n }\n ];\n\n return (\n <SimpleNavigation\n title={t('title')}\n items={navigation}\n currentPath={pathname}\n LinkComponent={HrefLink as any}\n {...(navigationMenu && { dropdownContent: navigationMenu })}\n isCollapsed={isCollapsed}\n icons={{\n chevronLeft: ChevronLeftIcon as React.ComponentType<{ className?: string }>,\n bars: Bars3Icon as React.ComponentType<{ className?: string }>\n }}\n collapseSidebarLabel={tSidebar('collapseSidebar')}\n expandSidebarLabel={tSidebar('expandSidebar')}\n />\n );\n}","import { useContext } from 'react';\nimport { Outlet } from 'react-router-dom';\nimport { useTranslation } from 'react-i18next';\nimport {\n LeftSidebar,\n Footer,\n useSemiont,\n useObservable,\n} from '@semiont/react-ui';\nimport { ModerationNavigation } from '@/components/moderation/ModerationNavigation';\nimport { CookiePreferences } from '@/components/CookiePreferences';\nimport { KeyboardShortcutsContext } from '@/contexts/KeyboardShortcutsContext';\nimport { Link, routes } from '@/lib/routing';\nimport { useRouter } from '@/i18n/routing';\n\nfunction ModerateLayoutBody() {\n const { t } = useTranslation();\n const keyboardContext = useContext(KeyboardShortcutsContext);\n const semiont = useSemiont();\n const session = useObservable(semiont.activeSession$);\n const user = useObservable(session?.user$);\n const activeKnowledgeBase = session?.kb ?? null;\n const router = useRouter();\n\n if (!activeKnowledgeBase) {\n router.push('/know');\n return null;\n }\n\n const isAuthenticated = !!user;\n const isAdmin = user?.isAdmin ?? false;\n const isModerator = user?.isModerator ?? false;\n\n return (\n <div className=\"min-h-screen bg-gray-50 dark:bg-gray-900 flex flex-col\">\n <div className=\"flex flex-1\">\n <LeftSidebar\n Link={Link}\n routes={routes}\n t={(key: string) => t(`Navigation.${key}`)}\n tHome={(key: string) => t(`Home.${key}`)}\n brandingLink=\"/\"\n collapsible={true}\n storageKey=\"moderation-sidebar-collapsed\"\n isAuthenticated={isAuthenticated}\n isAdmin={isAdmin}\n isModerator={isModerator}\n >\n {(isCollapsed, toggleCollapsed, navigationMenu) => (\n <ModerationNavigation\n isCollapsed={isCollapsed}\n toggleCollapsed={toggleCollapsed}\n navigationMenu={navigationMenu}\n />\n )}\n </LeftSidebar>\n <main className=\"flex-1 p-6 flex flex-col\">\n <div className=\"max-w-7xl mx-auto flex-1 flex flex-col w-full\">\n <Outlet />\n </div>\n </main>\n </div>\n <Footer\n Link={Link}\n routes={routes}\n t={(key: string, params?: Record<string, unknown>) => t(`Footer.${key}`, params as any) as string}\n CookiePreferences={CookiePreferences}\n {...(keyboardContext?.openKeyboardHelp && { onOpenKeyboardHelp: keyboardContext.openKeyboardHelp })}\n />\n </div>\n );\n}\n\nexport default function ModerateLayout() {\n // AuthShell is mounted by the parent ProtectedLayout in App.tsx so it\n // survives navigation between know/, admin/, and moderate/ sections.\n return <ModerateLayoutBody />;\n}\n"],"x_google_ignoreList":[0,1,2],"mappings":"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"}
1
+ {"version":3,"file":"layout-WUjhuEFR.js","names":["ForwardRef","ForwardRef"],"sources":["../../../../node_modules/@heroicons/react/24/outline/esm/BookOpenIcon.js","../../../../node_modules/@heroicons/react/24/outline/esm/ClockIcon.js","../../../../node_modules/@heroicons/react/24/outline/esm/TagIcon.js","../../src/components/moderation/ModerationNavigation.tsx","../../src/app/[locale]/moderate/layout.tsx"],"sourcesContent":["import * as React from \"react\";\nfunction BookOpenIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"M12 6.042A8.967 8.967 0 0 0 6 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 0 1 6 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 0 1 6-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0 0 18 18a8.967 8.967 0 0 0-6 2.292m0-14.25v14.25\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(BookOpenIcon);\nexport default ForwardRef;","import * as React from \"react\";\nfunction ClockIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(ClockIcon);\nexport default ForwardRef;","import * as React from \"react\";\nfunction TagIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"M9.568 3H5.25A2.25 2.25 0 0 0 3 5.25v4.318c0 .597.237 1.17.659 1.591l9.581 9.581c.699.699 1.78.872 2.607.33a18.095 18.095 0 0 0 5.223-5.223c.542-.827.369-1.908-.33-2.607L11.16 3.66A2.25 2.25 0 0 0 9.568 3Z\"\n }), /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"M6 6h.008v.008H6V6Z\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(TagIcon);\nexport default ForwardRef;","import React, { useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Link } from '@/i18n/routing';\nimport { usePathname } from '@/i18n/routing';\nimport { SimpleNavigation, useEventSubscriptions } from '@semiont/react-ui';\nimport type { SimpleNavigationItem } from '@semiont/react-ui';\nimport {\n ClockIcon,\n TagIcon,\n BookOpenIcon,\n ArrowsRightLeftIcon,\n ChevronLeftIcon,\n Bars3Icon\n} from '@heroicons/react/24/outline';\n\ninterface ModerationNavigationProps {\n isCollapsed: boolean;\n toggleCollapsed: () => void;\n navigationMenu?: (onClose: () => void) => React.ReactNode;\n}\n\n// Adapter: SimpleNavigation passes href, but our Link uses `to`\nfunction HrefLink({ href, to: _to, ...props }: React.ComponentProps<typeof Link> & { href?: string }) {\n return <Link to={(href ?? '') as string} {...props} />;\n}\n\nexport function ModerationNavigation({ isCollapsed, toggleCollapsed, navigationMenu }: ModerationNavigationProps) {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`Moderation.${k}`, p as any) as string;\n const { t: _tSidebar } = useTranslation();\n const tSidebar = (k: string, p?: Record<string, unknown>) => _tSidebar(`Sidebar.${k}`, p as any) as string;\n const pathname = usePathname();\n\n // Handle sidebar toggle events\n const handleSidebarToggle = useCallback(() => {\n toggleCollapsed();\n }, [toggleCollapsed]);\n\n // Subscribe to sidebar toggle events\n useEventSubscriptions({\n 'shell:sidebar-toggle': handleSidebarToggle,\n });\n\n const navigation: SimpleNavigationItem[] = [\n {\n name: t('recentResources'),\n href: '/moderate/recent',\n icon: ClockIcon,\n description: t('recentResourcesDescription')\n },\n {\n name: t('entityTags'),\n href: '/moderate/entity-tags',\n icon: TagIcon,\n description: t('entityTagsDescription')\n },\n {\n name: t('tagSchemas'),\n href: '/moderate/tag-schemas',\n icon: BookOpenIcon,\n description: t('tagSchemasDescription')\n },\n {\n name: t('linkedData'),\n href: '/moderate/linked-data',\n icon: ArrowsRightLeftIcon,\n description: t('linkedDataDescription')\n }\n ];\n\n return (\n <SimpleNavigation\n title={t('title')}\n items={navigation}\n currentPath={pathname}\n LinkComponent={HrefLink as any}\n {...(navigationMenu && { dropdownContent: navigationMenu })}\n isCollapsed={isCollapsed}\n icons={{\n chevronLeft: ChevronLeftIcon as React.ComponentType<{ className?: string }>,\n bars: Bars3Icon as React.ComponentType<{ className?: string }>\n }}\n collapseSidebarLabel={tSidebar('collapseSidebar')}\n expandSidebarLabel={tSidebar('expandSidebar')}\n />\n );\n}","import { useContext } from 'react';\nimport { Outlet } from 'react-router-dom';\nimport { useTranslation } from 'react-i18next';\nimport {\n LeftSidebar,\n Footer,\n useSemiont,\n useObservable,\n} from '@semiont/react-ui';\nimport { ModerationNavigation } from '@/components/moderation/ModerationNavigation';\nimport { CookiePreferences } from '@/components/CookiePreferences';\nimport { KeyboardShortcutsContext } from '@/contexts/KeyboardShortcutsContext';\nimport { Link, routes } from '@/lib/routing';\nimport { useRouter } from '@/i18n/routing';\n\nfunction ModerateLayoutBody() {\n const { t } = useTranslation();\n const keyboardContext = useContext(KeyboardShortcutsContext);\n const semiont = useSemiont();\n const session = useObservable(semiont.activeSession$);\n const user = useObservable(session?.user$);\n const activeKnowledgeBase = session?.kb ?? null;\n const router = useRouter();\n\n if (!activeKnowledgeBase) {\n router.push('/know');\n return null;\n }\n\n const isAuthenticated = !!user;\n const isAdmin = user?.isAdmin ?? false;\n const isModerator = user?.isModerator ?? false;\n\n return (\n <div className=\"min-h-screen bg-gray-50 dark:bg-gray-900 flex flex-col\">\n <div className=\"flex flex-1\">\n <LeftSidebar\n Link={Link}\n routes={routes}\n t={(key: string) => t(`Navigation.${key}`)}\n tHome={(key: string) => t(`Home.${key}`)}\n brandingLink=\"/\"\n collapsible={true}\n storageKey=\"moderation-sidebar-collapsed\"\n isAuthenticated={isAuthenticated}\n isAdmin={isAdmin}\n isModerator={isModerator}\n >\n {(isCollapsed, toggleCollapsed, navigationMenu) => (\n <ModerationNavigation\n isCollapsed={isCollapsed}\n toggleCollapsed={toggleCollapsed}\n navigationMenu={navigationMenu}\n />\n )}\n </LeftSidebar>\n <main className=\"flex-1 p-6 flex flex-col\">\n <div className=\"max-w-7xl mx-auto flex-1 flex flex-col w-full\">\n <Outlet />\n </div>\n </main>\n </div>\n <Footer\n Link={Link}\n routes={routes}\n t={(key: string, params?: Record<string, unknown>) => t(`Footer.${key}`, params as any) as string}\n CookiePreferences={CookiePreferences}\n {...(keyboardContext?.openKeyboardHelp && { onOpenKeyboardHelp: keyboardContext.openKeyboardHelp })}\n />\n </div>\n );\n}\n\nexport default function ModerateLayout() {\n // AuthShell is mounted by the parent ProtectedLayout in App.tsx so it\n // survives navigation between know/, admin/, and moderate/ sections.\n return <ModerateLayoutBody />;\n}\n"],"x_google_ignoreList":[0,1,2],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{n as e}from"./rolldown-runtime-jpDsebLB.js";import{i as t,n}from"./i18n-B53Yefbh.js";import{t as r}from"./vendor-0HjOURbh.js";import{O as i,Pt as a,at as o,it as s,j as c,m as l,q as u,rt as d}from"./index-DjtRDlfn.js";import{a as f,c as p,l as m,n as h,o as g,u as _}from"./KeyboardShortcutsContext-BRLeqQUj.js";import{i as v}from"./routing-Bcj1FhkC.js";var y=e(t());function b({title:e,titleId:t,...n},r){return y.createElement(`svg`,Object.assign({xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,strokeWidth:1.5,stroke:`currentColor`,"aria-hidden":`true`,"data-slot":`icon`,ref:r,"aria-labelledby":t},n),e?y.createElement(`title`,{id:t},e):null,y.createElement(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`m19.5 8.25-7.5 7.5-7.5-7.5`}))}var x=y.forwardRef(b);function S({title:e,titleId:t,...n},r){return y.createElement(`svg`,Object.assign({xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,strokeWidth:1.5,stroke:`currentColor`,"aria-hidden":`true`,"data-slot":`icon`,ref:r,"aria-labelledby":t},n),e?y.createElement(`title`,{id:t},e):null,y.createElement(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`m4.5 15.75 7.5-7.5 7.5 7.5`}))}var C=y.forwardRef(S);function w(){let e=v();return u({"nav:external":(0,y.useCallback)(({url:t,cancelFallback:n})=>{n(),e.push(t)},[e]),"nav:push":(0,y.useCallback)(({path:t})=>{e.push(t)},[e])}),null}function T(e,t){let n=e.match(/\{(\w+),\s*plural,\s*/);if(!n)return e;let r=t[n[1]];if(r===void 0)return e;let i=n[0].length+n.index,a=1,o=i;for(let t=i;t<e.length;t++)if(e[t]===`{`)a++;else if(e[t]===`}`&&(a--,a===0)){o=t;break}let s=e.substring(i,o),c={},l=/(?:=(\d+)|(\w+))\s*\{([^}]+)\}/g,u;for(;(u=l.exec(s))!==null;){let[,e,t,n]=u,r=e===void 0?t:`=${e}`;c[r]=n}let d=c[`=${r}`];if(d!==void 0){let t=d.replace(/#/g,String(r));return e.substring(0,n.index)+t+e.substring(o+1)}let f=c.other;if(f!==void 0){let t=f.replace(/#/g,String(r));return e.substring(0,n.index)+t+e.substring(o+1)}return e}function E(e,t){let n=T(e,t);return Object.entries(t).forEach(([e,t])=>{n=n.replace(RegExp(`\\{\\{${e}\\}\\}`,`g`),String(t))}),n}function D(){let{i18n:e}=n();return(0,y.useMemo)(()=>({t:(t,n,r)=>{let i=e.getResourceBundle(e.language,`translation`)?.[t]?.[n];return i?r&&typeof i==`string`?E(i,r):i:`${t}.${n}`}}),[e,e.language])}var O=r();function k({children:e}){return(0,O.jsx)(o,{translationManager:D(),children:(0,O.jsx)(d,{children:(0,O.jsx)(s,{children:(0,O.jsx)(l,{children:(0,O.jsx)(h,{children:(0,O.jsxs)(c,{children:[(0,O.jsx)(w,{}),e]})})})})})})}function A({className:e=``}){let{t}=n(),r=(e,n)=>t(`CookieBanner.${e}`,n),[i,a]=(0,y.useState)(!1),[o,s]=(0,y.useState)(!1),[c,l]=(0,y.useState)(!1),[u,d]=(0,y.useState)(`GENERAL`),[h,v]=(0,y.useState)({necessary:!0,analytics:!1,marketing:!1,preferences:!1});(0,y.useEffect)(()=>{(async()=>{if(m()){a(!0);try{let[e,t]=await Promise.all([g(),f()]);d(e?`GDPR`:t?`CCPA`:`GENERAL`)}catch(e){console.error(`Failed to detect region:`,e),d(`GENERAL`)}}})()},[]);let b=async()=>{l(!0);try{await Promise.resolve(p({necessary:!0,analytics:!0,marketing:!0,preferences:!0})),a(!1)}catch(e){console.error(`Failed to save cookie consent:`,e)}finally{l(!1)}},S=async()=>{l(!0);try{await Promise.resolve(p({necessary:!0,analytics:!1,marketing:!1,preferences:!1})),a(!1)}catch(e){console.error(`Failed to save cookie consent:`,e)}finally{l(!1)}},w=async()=>{l(!0);try{await Promise.resolve(p(h)),a(!1)}catch(e){console.error(`Failed to save cookie consent:`,e)}finally{l(!1)}},T=e=>{e!==`necessary`&&v(t=>({...t,[e]:!t[e]}))},E=()=>{switch(u){case`GDPR`:return{title:r(`gdprTitle`),description:r(`gdprDescription`),learnMore:r(`gdprLearnMore`)};case`CCPA`:return{title:r(`ccpaTitle`),description:r(`ccpaDescription`),learnMore:r(`ccpaLearnMore`)};default:return{title:r(`generalTitle`),description:r(`generalDescription`),learnMore:r(`generalLearnMore`)}}};if(!i)return null;let D=E();return(0,O.jsx)(`div`,{className:e,style:{position:`fixed`,bottom:0,left:0,right:0,zIndex:50,backgroundColor:`var(--semiont-bg-primary)`,borderTop:`1px solid var(--semiont-border-primary)`,boxShadow:`var(--semiont-shadow-lg)`},children:(0,O.jsx)(`div`,{style:{maxWidth:`80rem`,margin:`0 auto`,padding:`1rem 1.5rem`},children:(0,O.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:`1rem`},children:[(0,O.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,gap:`1.5rem`,flexWrap:`wrap`},children:[(0,O.jsxs)(`div`,{style:{flex:1,minWidth:`300px`},children:[(0,O.jsx)(`h3`,{style:{fontSize:`1.125rem`,fontWeight:600,color:`var(--semiont-text-primary)`,marginBottom:`0.5rem`},children:D.title}),(0,O.jsx)(`p`,{style:{fontSize:`var(--semiont-text-sm, 0.875rem)`,color:`var(--semiont-text-secondary)`,marginBottom:`0.25rem`},children:D.description}),(0,O.jsx)(`p`,{style:{fontSize:`var(--semiont-text-xs, 0.75rem)`,color:`var(--semiont-text-tertiary)`},children:D.learnMore})]}),(0,O.jsxs)(`div`,{style:{display:`flex`,gap:`0.75rem`,alignItems:`center`,flexWrap:`wrap`},children:[(0,O.jsxs)(`button`,{type:`button`,onClick:()=>s(!o),className:`semiont-button--secondary`,style:{display:`flex`,alignItems:`center`,gap:`0.25rem`},children:[r(`customize`),o?(0,O.jsx)(C,{style:{width:`1rem`,height:`1rem`}}):(0,O.jsx)(x,{style:{width:`1rem`,height:`1rem`}})]}),u!==`GDPR`&&(0,O.jsx)(`button`,{type:`button`,onClick:S,disabled:c,className:`semiont-button--secondary`,children:r(c?`saving`:`rejectAll`)}),(0,O.jsx)(`button`,{type:`button`,onClick:b,disabled:c,className:`semiont-button--primary`,children:r(c?`saving`:`acceptAll`)})]})]}),o&&(0,O.jsx)(`div`,{style:{borderTop:`1px solid var(--semiont-border-primary)`,paddingTop:`1rem`},children:(0,O.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:`1rem`},children:[(0,O.jsx)(`h4`,{style:{fontSize:`1rem`,fontWeight:500,color:`var(--semiont-text-primary)`},children:r(`cookiePreferences`)}),(0,O.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:`0.75rem`},children:_.map(e=>(0,O.jsxs)(`div`,{style:{display:`flex`,alignItems:`flex-start`,gap:`0.75rem`},children:[(0,O.jsx)(`div`,{style:{display:`flex`,alignItems:`center`,height:`1.25rem`},children:(0,O.jsx)(`input`,{id:`cookie-${e.id}`,type:`checkbox`,checked:h[e.id]||!1,onChange:()=>T(e.id),disabled:e.required||c,style:{accentColor:`var(--semiont-color-primary-600, #2563eb)`}})}),(0,O.jsxs)(`div`,{style:{flex:1,minWidth:0},children:[(0,O.jsxs)(`label`,{htmlFor:`cookie-${e.id}`,style:{fontSize:`var(--semiont-text-sm, 0.875rem)`,fontWeight:500,color:`var(--semiont-text-primary)`,cursor:`pointer`},children:[e.name,e.required&&(0,O.jsx)(`span`,{style:{fontSize:`var(--semiont-text-xs, 0.75rem)`,color:`var(--semiont-text-tertiary)`,marginLeft:`0.25rem`},children:r(`required`)})]}),(0,O.jsx)(`p`,{style:{fontSize:`var(--semiont-text-xs, 0.75rem)`,color:`var(--semiont-text-secondary)`,marginTop:`0.25rem`},children:e.description}),(0,O.jsxs)(`details`,{style:{marginTop:`0.25rem`},children:[(0,O.jsx)(`summary`,{style:{fontSize:`var(--semiont-text-xs, 0.75rem)`,color:`var(--semiont-color-primary-600, #2563eb)`,cursor:`pointer`},children:r(`viewCookies`)}),(0,O.jsx)(`div`,{style:{marginTop:`0.25rem`,fontSize:`var(--semiont-text-xs, 0.75rem)`,color:`var(--semiont-text-tertiary)`},children:e.cookies.join(`, `)})]})]})]},e.id))}),(0,O.jsxs)(`div`,{style:{display:`flex`,justifyContent:`flex-end`,gap:`0.75rem`,paddingTop:`1rem`},children:[(0,O.jsx)(`button`,{type:`button`,onClick:()=>s(!1),className:`semiont-button--secondary`,children:r(`cancel`)}),(0,O.jsx)(`button`,{type:`button`,onClick:w,disabled:c,className:`semiont-button--primary`,children:r(c?`saving`:`savePreferences`)})]})]})})]})})})}function j(){return(0,O.jsxs)(k,{children:[(0,O.jsx)(i,{}),(0,O.jsx)(a,{}),(0,O.jsx)(A,{})]})}export{j as default};
2
- //# sourceMappingURL=layout-DolG9tOf.js.map
1
+ import{n as e}from"./rolldown-runtime-jpDsebLB.js";import{i as t,n}from"./i18n-B53Yefbh.js";import{t as r}from"./vendor-0HjOURbh.js";import{O as i,Pt as a,at as o,it as s,j as c,m as l,q as u,rt as d}from"./index-DojEUBpq.js";import{a as f,c as p,l as m,n as h,o as g,u as _}from"./KeyboardShortcutsContext-CK7NFEft.js";import{i as v}from"./routing-Dqgz2rV4.js";var y=e(t());function b({title:e,titleId:t,...n},r){return y.createElement(`svg`,Object.assign({xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,strokeWidth:1.5,stroke:`currentColor`,"aria-hidden":`true`,"data-slot":`icon`,ref:r,"aria-labelledby":t},n),e?y.createElement(`title`,{id:t},e):null,y.createElement(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`m19.5 8.25-7.5 7.5-7.5-7.5`}))}var x=y.forwardRef(b);function S({title:e,titleId:t,...n},r){return y.createElement(`svg`,Object.assign({xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,strokeWidth:1.5,stroke:`currentColor`,"aria-hidden":`true`,"data-slot":`icon`,ref:r,"aria-labelledby":t},n),e?y.createElement(`title`,{id:t},e):null,y.createElement(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`m4.5 15.75 7.5-7.5 7.5 7.5`}))}var C=y.forwardRef(S);function w(){let e=v();return u({"nav:external":(0,y.useCallback)(({url:t,cancelFallback:n})=>{n(),e.push(t)},[e]),"nav:push":(0,y.useCallback)(({path:t})=>{e.push(t)},[e])}),null}function T(e,t){let n=e.match(/\{(\w+),\s*plural,\s*/);if(!n)return e;let r=t[n[1]];if(r===void 0)return e;let i=n[0].length+n.index,a=1,o=i;for(let t=i;t<e.length;t++)if(e[t]===`{`)a++;else if(e[t]===`}`&&(a--,a===0)){o=t;break}let s=e.substring(i,o),c={},l=/(?:=(\d+)|(\w+))\s*\{([^}]+)\}/g,u;for(;(u=l.exec(s))!==null;){let[,e,t,n]=u,r=e===void 0?t:`=${e}`;c[r]=n}let d=c[`=${r}`];if(d!==void 0){let t=d.replace(/#/g,String(r));return e.substring(0,n.index)+t+e.substring(o+1)}let f=c.other;if(f!==void 0){let t=f.replace(/#/g,String(r));return e.substring(0,n.index)+t+e.substring(o+1)}return e}function E(e,t){let n=T(e,t);return Object.entries(t).forEach(([e,t])=>{n=n.replace(RegExp(`\\{\\{${e}\\}\\}`,`g`),String(t))}),n}function D(){let{i18n:e}=n();return(0,y.useMemo)(()=>({t:(t,n,r)=>{let i=e.getResourceBundle(e.language,`translation`)?.[t]?.[n];return i?r&&typeof i==`string`?E(i,r):i:`${t}.${n}`}}),[e,e.language])}var O=r();function k({children:e}){return(0,O.jsx)(o,{translationManager:D(),children:(0,O.jsx)(d,{children:(0,O.jsx)(s,{children:(0,O.jsx)(l,{children:(0,O.jsx)(h,{children:(0,O.jsxs)(c,{children:[(0,O.jsx)(w,{}),e]})})})})})})}function A({className:e=``}){let{t}=n(),r=(e,n)=>t(`CookieBanner.${e}`,n),[i,a]=(0,y.useState)(!1),[o,s]=(0,y.useState)(!1),[c,l]=(0,y.useState)(!1),[u,d]=(0,y.useState)(`GENERAL`),[h,v]=(0,y.useState)({necessary:!0,analytics:!1,marketing:!1,preferences:!1});(0,y.useEffect)(()=>{(async()=>{if(m()){a(!0);try{let[e,t]=await Promise.all([g(),f()]);d(e?`GDPR`:t?`CCPA`:`GENERAL`)}catch(e){console.error(`Failed to detect region:`,e),d(`GENERAL`)}}})()},[]);let b=async()=>{l(!0);try{await Promise.resolve(p({necessary:!0,analytics:!0,marketing:!0,preferences:!0})),a(!1)}catch(e){console.error(`Failed to save cookie consent:`,e)}finally{l(!1)}},S=async()=>{l(!0);try{await Promise.resolve(p({necessary:!0,analytics:!1,marketing:!1,preferences:!1})),a(!1)}catch(e){console.error(`Failed to save cookie consent:`,e)}finally{l(!1)}},w=async()=>{l(!0);try{await Promise.resolve(p(h)),a(!1)}catch(e){console.error(`Failed to save cookie consent:`,e)}finally{l(!1)}},T=e=>{e!==`necessary`&&v(t=>({...t,[e]:!t[e]}))},E=()=>{switch(u){case`GDPR`:return{title:r(`gdprTitle`),description:r(`gdprDescription`),learnMore:r(`gdprLearnMore`)};case`CCPA`:return{title:r(`ccpaTitle`),description:r(`ccpaDescription`),learnMore:r(`ccpaLearnMore`)};default:return{title:r(`generalTitle`),description:r(`generalDescription`),learnMore:r(`generalLearnMore`)}}};if(!i)return null;let D=E();return(0,O.jsx)(`div`,{className:e,style:{position:`fixed`,bottom:0,left:0,right:0,zIndex:50,backgroundColor:`var(--semiont-bg-primary)`,borderTop:`1px solid var(--semiont-border-primary)`,boxShadow:`var(--semiont-shadow-lg)`},children:(0,O.jsx)(`div`,{style:{maxWidth:`80rem`,margin:`0 auto`,padding:`1rem 1.5rem`},children:(0,O.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:`1rem`},children:[(0,O.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,justifyContent:`space-between`,gap:`1.5rem`,flexWrap:`wrap`},children:[(0,O.jsxs)(`div`,{style:{flex:1,minWidth:`300px`},children:[(0,O.jsx)(`h3`,{style:{fontSize:`1.125rem`,fontWeight:600,color:`var(--semiont-text-primary)`,marginBottom:`0.5rem`},children:D.title}),(0,O.jsx)(`p`,{style:{fontSize:`var(--semiont-text-sm, 0.875rem)`,color:`var(--semiont-text-secondary)`,marginBottom:`0.25rem`},children:D.description}),(0,O.jsx)(`p`,{style:{fontSize:`var(--semiont-text-xs, 0.75rem)`,color:`var(--semiont-text-tertiary)`},children:D.learnMore})]}),(0,O.jsxs)(`div`,{style:{display:`flex`,gap:`0.75rem`,alignItems:`center`,flexWrap:`wrap`},children:[(0,O.jsxs)(`button`,{type:`button`,onClick:()=>s(!o),className:`semiont-button--secondary`,style:{display:`flex`,alignItems:`center`,gap:`0.25rem`},children:[r(`customize`),o?(0,O.jsx)(C,{style:{width:`1rem`,height:`1rem`}}):(0,O.jsx)(x,{style:{width:`1rem`,height:`1rem`}})]}),u!==`GDPR`&&(0,O.jsx)(`button`,{type:`button`,onClick:S,disabled:c,className:`semiont-button--secondary`,children:r(c?`saving`:`rejectAll`)}),(0,O.jsx)(`button`,{type:`button`,onClick:b,disabled:c,className:`semiont-button--primary`,children:r(c?`saving`:`acceptAll`)})]})]}),o&&(0,O.jsx)(`div`,{style:{borderTop:`1px solid var(--semiont-border-primary)`,paddingTop:`1rem`},children:(0,O.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:`1rem`},children:[(0,O.jsx)(`h4`,{style:{fontSize:`1rem`,fontWeight:500,color:`var(--semiont-text-primary)`},children:r(`cookiePreferences`)}),(0,O.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:`0.75rem`},children:_.map(e=>(0,O.jsxs)(`div`,{style:{display:`flex`,alignItems:`flex-start`,gap:`0.75rem`},children:[(0,O.jsx)(`div`,{style:{display:`flex`,alignItems:`center`,height:`1.25rem`},children:(0,O.jsx)(`input`,{id:`cookie-${e.id}`,type:`checkbox`,checked:h[e.id]||!1,onChange:()=>T(e.id),disabled:e.required||c,style:{accentColor:`var(--semiont-color-primary-600, #2563eb)`}})}),(0,O.jsxs)(`div`,{style:{flex:1,minWidth:0},children:[(0,O.jsxs)(`label`,{htmlFor:`cookie-${e.id}`,style:{fontSize:`var(--semiont-text-sm, 0.875rem)`,fontWeight:500,color:`var(--semiont-text-primary)`,cursor:`pointer`},children:[e.name,e.required&&(0,O.jsx)(`span`,{style:{fontSize:`var(--semiont-text-xs, 0.75rem)`,color:`var(--semiont-text-tertiary)`,marginLeft:`0.25rem`},children:r(`required`)})]}),(0,O.jsx)(`p`,{style:{fontSize:`var(--semiont-text-xs, 0.75rem)`,color:`var(--semiont-text-secondary)`,marginTop:`0.25rem`},children:e.description}),(0,O.jsxs)(`details`,{style:{marginTop:`0.25rem`},children:[(0,O.jsx)(`summary`,{style:{fontSize:`var(--semiont-text-xs, 0.75rem)`,color:`var(--semiont-color-primary-600, #2563eb)`,cursor:`pointer`},children:r(`viewCookies`)}),(0,O.jsx)(`div`,{style:{marginTop:`0.25rem`,fontSize:`var(--semiont-text-xs, 0.75rem)`,color:`var(--semiont-text-tertiary)`},children:e.cookies.join(`, `)})]})]})]},e.id))}),(0,O.jsxs)(`div`,{style:{display:`flex`,justifyContent:`flex-end`,gap:`0.75rem`,paddingTop:`1rem`},children:[(0,O.jsx)(`button`,{type:`button`,onClick:()=>s(!1),className:`semiont-button--secondary`,children:r(`cancel`)}),(0,O.jsx)(`button`,{type:`button`,onClick:w,disabled:c,className:`semiont-button--primary`,children:r(c?`saving`:`savePreferences`)})]})]})})]})})})}function j(){return(0,O.jsxs)(k,{children:[(0,O.jsx)(i,{}),(0,O.jsx)(a,{}),(0,O.jsx)(A,{})]})}export{j as default};
2
+ //# sourceMappingURL=layout-osn4jTJF.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"layout-DolG9tOf.js","names":["ForwardRef"],"sources":["../../../../node_modules/@heroicons/react/24/outline/esm/ChevronDownIcon.js","../../../../node_modules/@heroicons/react/24/outline/esm/ChevronUpIcon.js","../../src/components/knowledge/NavigationHandler.tsx","../../src/hooks/useMergedTranslationManager.ts","../../src/app/providers.tsx","../../src/components/CookieBanner.tsx","../../src/app/[locale]/layout.tsx"],"sourcesContent":["import * as React from \"react\";\nfunction ChevronDownIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"m19.5 8.25-7.5 7.5-7.5-7.5\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(ChevronDownIcon);\nexport default ForwardRef;","import * as React from \"react\";\nfunction ChevronUpIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"m4.5 15.75 7.5-7.5 7.5 7.5\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(ChevronUpIcon);\nexport default ForwardRef;","import { useCallback } from 'react';\nimport { useRouter } from '@/i18n/routing';\nimport { useEventSubscriptions } from '@semiont/react-ui';\n\n/**\n * NavigationHandler - Connects NavigationEventBus to Next.js router\n *\n * This component subscribes to navigation events from @semiont/react-ui\n * components and handles them using Next.js client-side routing.\n *\n * Benefits:\n * - Client-side navigation (no page reload)\n * - Preserves React state\n * - Faster navigation\n * - Better UX\n *\n * Must be mounted in app layout to handle all navigation requests.\n */\nexport function NavigationHandler() {\n const router = useRouter();\n\n // Handle external navigation events\n const handleExternalNavigate = useCallback(({ url, cancelFallback }: { url: string; resourceId?: string; cancelFallback: () => void }) => {\n cancelFallback(); // Prevent window.location fallback since we're handling with client-side routing\n router.push(url);\n }, [router]);\n\n // Handle router push events\n const handleRouterPush = useCallback(({ path }: { path: string; reason?: string }) => {\n router.push(path);\n }, [router]);\n\n useEventSubscriptions({\n 'nav:external': handleExternalNavigate,\n 'nav:push': handleRouterPush,\n });\n\n // This component only manages navigation, doesn't render anything\n return null;\n}\n","import { useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport type { TranslationManager } from '@semiont/react-ui';\n\ntype Messages = Record<string, Record<string, string>>;\n\n/**\n * Process ICU MessageFormat plural syntax.\n * Supports: `{count, plural, =0 {text} =1 {text} other {text}}` with `#` as\n * the count placeholder inside each branch.\n *\n * Mirrors the reference implementation in\n * `packages/react-ui/src/contexts/TranslationContext.tsx`. Kept in sync\n * deliberately — diverging the two managers is what produced the\n * literal-plural-format render bug in the Tags panel.\n */\nexport function processPluralFormat(text: string, params: Record<string, unknown>): string {\n const pluralMatch = text.match(/\\{(\\w+),\\s*plural,\\s*/);\n if (!pluralMatch) return text;\n\n const paramName = pluralMatch[1]!;\n const count = params[paramName];\n if (count === undefined) return text;\n\n // Find the matching closing brace by counting nested pairs.\n const startPos = pluralMatch[0].length + pluralMatch.index!;\n let braceCount = 1;\n let endPos = startPos;\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) { endPos = i; break; }\n }\n }\n\n const pluralCases = text.substring(startPos, endPos);\n const cases: Record<string, string> = {};\n const caseRegex = /(?:=(\\d+)|(\\w+))\\s*\\{([^}]+)\\}/g;\n let caseMatch;\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 const exactMatch = cases[`=${count}`];\n if (exactMatch !== undefined) {\n const replaced = exactMatch.replace(/#/g, String(count));\n return text.substring(0, pluralMatch.index!) + replaced + text.substring(endPos + 1);\n }\n const otherCase = cases['other'];\n if (otherCase !== undefined) {\n const replaced = otherCase.replace(/#/g, String(count));\n return text.substring(0, pluralMatch.index!) + replaced + text.substring(endPos + 1);\n }\n return text;\n}\n\n/**\n * Run a translation string through the standard interpolation pipeline:\n * plural format first (since it may consume more of the string), then\n * `{{paramKey}}` parameter substitution. Exported for unit testing.\n */\nexport function interpolateTranslation(\n translation: string,\n params: Record<string, unknown>,\n): string {\n let result = processPluralFormat(translation, params);\n Object.entries(params).forEach(([paramKey, paramValue]) => {\n result = result.replace(new RegExp(`\\\\{\\\\{${paramKey}\\\\}\\\\}`, 'g'), String(paramValue));\n });\n return result;\n}\n\n/**\n * Translation Manager for Frontend\n *\n * Wraps react-i18next. The messages JSON (loaded by i18next-http-backend) has\n * the same flat namespace structure: { \"Namespace\": { \"key\": \"value\" } }.\n * TranslationManager.t(namespace, key) maps directly to this structure.\n *\n * Interpolation supports two syntaxes, in this precedence order:\n *\n * 1. ICU MessageFormat plural — `{count, plural, =0 {…} =1 {…} other {…}}`\n * — used for count-sensitive strings like \"1 category selected\" /\n * \"3 categories selected\".\n * 2. Double-brace parameter substitution — `{{paramKey}}` — used for\n * everything else (`{{mode}}`, `{{delay}}`, etc.).\n *\n * The two managers (this one and the reference in\n * `@semiont/react-ui/contexts/TranslationContext`) implement the same\n * interpolation contract; keep them aligned when changing either.\n */\nexport function useMergedTranslationManager(): TranslationManager {\n const { i18n } = useTranslation();\n\n return useMemo(() => {\n return {\n t: (namespace: string, key: string, params?: Record<string, unknown>): string => {\n const messages = i18n.getResourceBundle(i18n.language, 'translation') as Messages | undefined;\n const translation = messages?.[namespace]?.[key];\n\n if (!translation) {\n if (process.env.NODE_ENV === 'development') {\n console.warn(`Translation not found: ${namespace}.${key} (locale: ${i18n.language})`);\n }\n return `${namespace}.${key}`;\n }\n\n if (params && typeof translation === 'string') {\n return interpolateTranslation(translation, params);\n }\n\n return translation;\n },\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [i18n, i18n.language]);\n}\n","import React from 'react';\nimport {\n ToastProvider,\n LiveRegionProvider,\n TranslationProvider,\n ThemeProvider,\n SemiontProvider,\n} from '@semiont/react-ui';\nimport { KeyboardShortcutsProvider } from '@/contexts/KeyboardShortcutsContext';\nimport { NavigationHandler } from '@/components/knowledge/NavigationHandler';\nimport { useMergedTranslationManager } from '@/hooks/useMergedTranslationManager';\n\n/**\n * Root Provider Composition for Semiont Frontend.\n *\n * Wires up GLOBAL contexts that every page needs.\n *\n * The module-scoped `SemiontBrowser` singleton (KB list, active KB,\n * per-KB SemiontSession) is made available via `<SemiontProvider>` at\n * the app root — mounting it here is cheap because the singleton itself\n * survives every React re-render and route change.\n *\n * Auth-dependent UI (ProtectedErrorBoundary, SessionExpiredModal,\n * PermissionDeniedModal) is bundled in `AuthShell` and mounted only in\n * protected layouts (know/, admin/, moderate/, auth/welcome/). Pre-app\n * routes (landing, OAuth flow) intentionally do NOT mount AuthShell —\n * they have no session UI.\n *\n * The `SemiontClient` is owned by the per-KB `SemiontSession`, which\n * `SemiontBrowser` constructs on demand. Components read\n * `useObservable(useSemiont().activeSession$)?.client`.\n *\n * The event bus lives inside the client (owned by `SemiontSession`).\n * Components emit via `session?.emit(...)` and subscribe via\n * `useEventSubscription[s]`.\n *\n * Provider order — outer to inner:\n * 1. TranslationProvider — i18n\n * 2. SemiontProvider — SemiontBrowser singleton\n * 3. ToastProvider — toast notifications\n * 4. LiveRegionProvider — a11y live region\n * 5. KeyboardShortcutsProvider — keyboard shortcuts\n * 6. ThemeProvider — theme\n * + NavigationHandler\n */\nexport function Providers({ children }: { children: React.ReactNode }) {\n const translationManager = useMergedTranslationManager();\n\n return (\n <TranslationProvider translationManager={translationManager}>\n <SemiontProvider>\n <ToastProvider>\n <LiveRegionProvider>\n <KeyboardShortcutsProvider>\n <ThemeProvider>\n <NavigationHandler />\n {children}\n </ThemeProvider>\n </KeyboardShortcutsProvider>\n </LiveRegionProvider>\n </ToastProvider>\n </SemiontProvider>\n </TranslationProvider>\n );\n}\n","\"use client\";\n\nimport React, { useState, useEffect } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport {\n getCookieConsent,\n setCookieConsent,\n shouldShowBanner,\n COOKIE_CATEGORIES,\n CookieConsent,\n isCCPAApplicable,\n isGDPRApplicable,\n type CookieCategory\n} from '@/lib/cookies';\nimport { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/24/outline';\n\ninterface CookieBannerProps {\n className?: string;\n}\n\nexport function CookieBanner({ className = '' }: CookieBannerProps) {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`CookieBanner.${k}`, p as any) as string;\n const [isVisible, setIsVisible] = useState(false);\n const [showDetails, setShowDetails] = useState(false);\n const [isLoading, setIsLoading] = useState(false);\n const [region, setRegion] = useState<'GDPR' | 'CCPA' | 'GENERAL'>('GENERAL');\n const [consent, setConsent] = useState<Partial<CookieConsent>>({\n necessary: true,\n analytics: false,\n marketing: false,\n preferences: false\n });\n\n useEffect(() => {\n const checkVisibility = async () => {\n if (shouldShowBanner()) {\n setIsVisible(true);\n\n try {\n // Determine applicable regulation\n const [isGDPR, isCCPA] = await Promise.all([\n isGDPRApplicable(),\n isCCPAApplicable()\n ]);\n\n if (isGDPR) {\n setRegion('GDPR');\n } else if (isCCPA) {\n setRegion('CCPA');\n } else {\n setRegion('GENERAL');\n }\n } catch (error) {\n // If region detection fails, default to GENERAL\n console.error('Failed to detect region:', error);\n setRegion('GENERAL');\n }\n }\n };\n\n checkVisibility();\n }, []);\n\n const handleAcceptAll = async () => {\n setIsLoading(true);\n\n try {\n const fullConsent = {\n necessary: true,\n analytics: true,\n marketing: true,\n preferences: true\n };\n\n await Promise.resolve(setCookieConsent(fullConsent));\n setIsVisible(false);\n } catch (error) {\n console.error('Failed to save cookie consent:', error);\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleRejectAll = async () => {\n setIsLoading(true);\n\n try {\n const minimalConsent = {\n necessary: true,\n analytics: false,\n marketing: false,\n preferences: false\n };\n\n await Promise.resolve(setCookieConsent(minimalConsent));\n setIsVisible(false);\n } catch (error) {\n console.error('Failed to save cookie consent:', error);\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleSavePreferences = async () => {\n setIsLoading(true);\n\n try {\n await Promise.resolve(setCookieConsent(consent));\n setIsVisible(false);\n } catch (error) {\n console.error('Failed to save cookie consent:', error);\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleCategoryToggle = (categoryId: keyof Omit<CookieConsent, 'timestamp' | 'version'>) => {\n if (categoryId === 'necessary') return; // Can't toggle necessary cookies\n\n setConsent(prev => ({\n ...prev,\n [categoryId]: !prev[categoryId]\n }));\n };\n\n const getBannerText = () => {\n switch (region) {\n case 'GDPR':\n return {\n title: t('gdprTitle'),\n description: t('gdprDescription'),\n learnMore: t('gdprLearnMore')\n };\n case 'CCPA':\n return {\n title: t('ccpaTitle'),\n description: t('ccpaDescription'),\n learnMore: t('ccpaLearnMore')\n };\n default:\n return {\n title: t('generalTitle'),\n description: t('generalDescription'),\n learnMore: t('generalLearnMore')\n };\n }\n };\n\n if (!isVisible) return null;\n\n const bannerText = getBannerText();\n\n return (\n <div\n className={className}\n style={{\n position: 'fixed',\n bottom: 0,\n left: 0,\n right: 0,\n zIndex: 50,\n backgroundColor: 'var(--semiont-bg-primary)',\n borderTop: '1px solid var(--semiont-border-primary)',\n boxShadow: 'var(--semiont-shadow-lg)',\n }}\n >\n <div style={{ maxWidth: '80rem', margin: '0 auto', padding: '1rem 1.5rem' }}>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n {/* Main banner content */}\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: '1.5rem', flexWrap: 'wrap' }}>\n <div style={{ flex: 1, minWidth: '300px' }}>\n <h3 style={{\n fontSize: '1.125rem',\n fontWeight: 600,\n color: 'var(--semiont-text-primary)',\n marginBottom: '0.5rem',\n }}>\n {bannerText.title}\n </h3>\n <p style={{\n fontSize: 'var(--semiont-text-sm, 0.875rem)',\n color: 'var(--semiont-text-secondary)',\n marginBottom: '0.25rem',\n }}>\n {bannerText.description}\n </p>\n <p style={{\n fontSize: 'var(--semiont-text-xs, 0.75rem)',\n color: 'var(--semiont-text-tertiary)',\n }}>\n {bannerText.learnMore}\n </p>\n </div>\n\n {/* Action buttons */}\n <div style={{ display: 'flex', gap: '0.75rem', alignItems: 'center', flexWrap: 'wrap' }}>\n <button\n type=\"button\"\n onClick={() => setShowDetails(!showDetails)}\n className=\"semiont-button--secondary\"\n style={{ display: 'flex', alignItems: 'center', gap: '0.25rem' }}\n >\n {t('customize')}\n {showDetails ? (\n <ChevronUpIcon style={{ width: '1rem', height: '1rem' }} />\n ) : (\n <ChevronDownIcon style={{ width: '1rem', height: '1rem' }} />\n )}\n </button>\n\n {region !== 'GDPR' && (\n <button\n type=\"button\"\n onClick={handleRejectAll}\n disabled={isLoading}\n className=\"semiont-button--secondary\"\n >\n {isLoading ? t('saving') : t('rejectAll')}\n </button>\n )}\n\n <button\n type=\"button\"\n onClick={handleAcceptAll}\n disabled={isLoading}\n className=\"semiont-button--primary\"\n >\n {isLoading ? t('saving') : t('acceptAll')}\n </button>\n </div>\n </div>\n\n {/* Detailed preferences */}\n {showDetails && (\n <div style={{\n borderTop: '1px solid var(--semiont-border-primary)',\n paddingTop: '1rem',\n }}>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n <h4 style={{\n fontSize: '1rem',\n fontWeight: 500,\n color: 'var(--semiont-text-primary)',\n }}>\n {t('cookiePreferences')}\n </h4>\n\n <div style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem' }}>\n {COOKIE_CATEGORIES.map((category: CookieCategory) => (\n <div key={category.id} style={{ display: 'flex', alignItems: 'flex-start', gap: '0.75rem' }}>\n <div style={{ display: 'flex', alignItems: 'center', height: '1.25rem' }}>\n <input\n id={`cookie-${category.id}`}\n type=\"checkbox\"\n checked={consent[category.id] || false}\n onChange={() => handleCategoryToggle(category.id)}\n disabled={category.required || isLoading}\n style={{ accentColor: 'var(--semiont-color-primary-600, #2563eb)' }}\n />\n </div>\n <div style={{ flex: 1, minWidth: 0 }}>\n <label\n htmlFor={`cookie-${category.id}`}\n style={{\n fontSize: 'var(--semiont-text-sm, 0.875rem)',\n fontWeight: 500,\n color: 'var(--semiont-text-primary)',\n cursor: 'pointer',\n }}\n >\n {category.name}\n {category.required && (\n <span style={{\n fontSize: 'var(--semiont-text-xs, 0.75rem)',\n color: 'var(--semiont-text-tertiary)',\n marginLeft: '0.25rem',\n }}>\n {t('required')}\n </span>\n )}\n </label>\n <p style={{\n fontSize: 'var(--semiont-text-xs, 0.75rem)',\n color: 'var(--semiont-text-secondary)',\n marginTop: '0.25rem',\n }}>\n {category.description}\n </p>\n <details style={{ marginTop: '0.25rem' }}>\n <summary style={{\n fontSize: 'var(--semiont-text-xs, 0.75rem)',\n color: 'var(--semiont-color-primary-600, #2563eb)',\n cursor: 'pointer',\n }}>\n {t('viewCookies')}\n </summary>\n <div style={{\n marginTop: '0.25rem',\n fontSize: 'var(--semiont-text-xs, 0.75rem)',\n color: 'var(--semiont-text-tertiary)',\n }}>\n {category.cookies.join(', ')}\n </div>\n </details>\n </div>\n </div>\n ))}\n </div>\n\n <div style={{\n display: 'flex',\n justifyContent: 'flex-end',\n gap: '0.75rem',\n paddingTop: '1rem',\n }}>\n <button\n type=\"button\"\n onClick={() => setShowDetails(false)}\n className=\"semiont-button--secondary\"\n >\n {t('cancel')}\n </button>\n <button\n type=\"button\"\n onClick={handleSavePreferences}\n disabled={isLoading}\n className=\"semiont-button--primary\"\n >\n {isLoading ? t('saving') : t('savePreferences')}\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n\nexport default CookieBanner;\n","import { Outlet } from 'react-router-dom';\nimport { Providers } from '../providers';\nimport { CookieBanner } from '@/components/CookieBanner';\nimport { SkipLinks } from '@semiont/react-ui';\n\n/**\n * Locale Layout — root layout for all /:locale/* routes.\n *\n * Mounts only auth-independent providers. Auth-dependent providers\n * (KnowledgeBaseProvider, AuthProvider, SessionProvider, modals)\n * are mounted via AuthShell in protected layouts (know/, admin/,\n * moderate/, auth/welcome/).\n */\nexport default function LocaleLayout() {\n return (\n <Providers>\n <SkipLinks />\n <Outlet />\n <CookieBanner />\n </Providers>\n );\n}\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
1
+ {"version":3,"file":"layout-osn4jTJF.js","names":["ForwardRef"],"sources":["../../../../node_modules/@heroicons/react/24/outline/esm/ChevronDownIcon.js","../../../../node_modules/@heroicons/react/24/outline/esm/ChevronUpIcon.js","../../src/components/knowledge/NavigationHandler.tsx","../../src/hooks/useMergedTranslationManager.ts","../../src/app/providers.tsx","../../src/components/CookieBanner.tsx","../../src/app/[locale]/layout.tsx"],"sourcesContent":["import * as React from \"react\";\nfunction ChevronDownIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"m19.5 8.25-7.5 7.5-7.5-7.5\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(ChevronDownIcon);\nexport default ForwardRef;","import * as React from \"react\";\nfunction ChevronUpIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"m4.5 15.75 7.5-7.5 7.5 7.5\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(ChevronUpIcon);\nexport default ForwardRef;","import { useCallback } from 'react';\nimport { useRouter } from '@/i18n/routing';\nimport { useEventSubscriptions } from '@semiont/react-ui';\n\n/**\n * NavigationHandler - Connects NavigationEventBus to Next.js router\n *\n * This component subscribes to navigation events from @semiont/react-ui\n * components and handles them using Next.js client-side routing.\n *\n * Benefits:\n * - Client-side navigation (no page reload)\n * - Preserves React state\n * - Faster navigation\n * - Better UX\n *\n * Must be mounted in app layout to handle all navigation requests.\n */\nexport function NavigationHandler() {\n const router = useRouter();\n\n // Handle external navigation events\n const handleExternalNavigate = useCallback(({ url, cancelFallback }: { url: string; resourceId?: string; cancelFallback: () => void }) => {\n cancelFallback(); // Prevent window.location fallback since we're handling with client-side routing\n router.push(url);\n }, [router]);\n\n // Handle router push events\n const handleRouterPush = useCallback(({ path }: { path: string; reason?: string }) => {\n router.push(path);\n }, [router]);\n\n useEventSubscriptions({\n 'nav:external': handleExternalNavigate,\n 'nav:push': handleRouterPush,\n });\n\n // This component only manages navigation, doesn't render anything\n return null;\n}\n","import { useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport type { TranslationManager } from '@semiont/react-ui';\n\ntype Messages = Record<string, Record<string, string>>;\n\n/**\n * Process ICU MessageFormat plural syntax.\n * Supports: `{count, plural, =0 {text} =1 {text} other {text}}` with `#` as\n * the count placeholder inside each branch.\n *\n * Mirrors the reference implementation in\n * `packages/react-ui/src/contexts/TranslationContext.tsx`. Kept in sync\n * deliberately — diverging the two managers is what produced the\n * literal-plural-format render bug in the Tags panel.\n */\nexport function processPluralFormat(text: string, params: Record<string, unknown>): string {\n const pluralMatch = text.match(/\\{(\\w+),\\s*plural,\\s*/);\n if (!pluralMatch) return text;\n\n const paramName = pluralMatch[1]!;\n const count = params[paramName];\n if (count === undefined) return text;\n\n // Find the matching closing brace by counting nested pairs.\n const startPos = pluralMatch[0].length + pluralMatch.index!;\n let braceCount = 1;\n let endPos = startPos;\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) { endPos = i; break; }\n }\n }\n\n const pluralCases = text.substring(startPos, endPos);\n const cases: Record<string, string> = {};\n const caseRegex = /(?:=(\\d+)|(\\w+))\\s*\\{([^}]+)\\}/g;\n let caseMatch;\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 const exactMatch = cases[`=${count}`];\n if (exactMatch !== undefined) {\n const replaced = exactMatch.replace(/#/g, String(count));\n return text.substring(0, pluralMatch.index!) + replaced + text.substring(endPos + 1);\n }\n const otherCase = cases['other'];\n if (otherCase !== undefined) {\n const replaced = otherCase.replace(/#/g, String(count));\n return text.substring(0, pluralMatch.index!) + replaced + text.substring(endPos + 1);\n }\n return text;\n}\n\n/**\n * Run a translation string through the standard interpolation pipeline:\n * plural format first (since it may consume more of the string), then\n * `{{paramKey}}` parameter substitution. Exported for unit testing.\n */\nexport function interpolateTranslation(\n translation: string,\n params: Record<string, unknown>,\n): string {\n let result = processPluralFormat(translation, params);\n Object.entries(params).forEach(([paramKey, paramValue]) => {\n result = result.replace(new RegExp(`\\\\{\\\\{${paramKey}\\\\}\\\\}`, 'g'), String(paramValue));\n });\n return result;\n}\n\n/**\n * Translation Manager for Frontend\n *\n * Wraps react-i18next. The messages JSON (loaded by i18next-http-backend) has\n * the same flat namespace structure: { \"Namespace\": { \"key\": \"value\" } }.\n * TranslationManager.t(namespace, key) maps directly to this structure.\n *\n * Interpolation supports two syntaxes, in this precedence order:\n *\n * 1. ICU MessageFormat plural — `{count, plural, =0 {…} =1 {…} other {…}}`\n * — used for count-sensitive strings like \"1 category selected\" /\n * \"3 categories selected\".\n * 2. Double-brace parameter substitution — `{{paramKey}}` — used for\n * everything else (`{{mode}}`, `{{delay}}`, etc.).\n *\n * The two managers (this one and the reference in\n * `@semiont/react-ui/contexts/TranslationContext`) implement the same\n * interpolation contract; keep them aligned when changing either.\n */\nexport function useMergedTranslationManager(): TranslationManager {\n const { i18n } = useTranslation();\n\n return useMemo(() => {\n return {\n t: (namespace: string, key: string, params?: Record<string, unknown>): string => {\n const messages = i18n.getResourceBundle(i18n.language, 'translation') as Messages | undefined;\n const translation = messages?.[namespace]?.[key];\n\n if (!translation) {\n if (process.env.NODE_ENV === 'development') {\n console.warn(`Translation not found: ${namespace}.${key} (locale: ${i18n.language})`);\n }\n return `${namespace}.${key}`;\n }\n\n if (params && typeof translation === 'string') {\n return interpolateTranslation(translation, params);\n }\n\n return translation;\n },\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [i18n, i18n.language]);\n}\n","import React from 'react';\nimport {\n ToastProvider,\n LiveRegionProvider,\n TranslationProvider,\n ThemeProvider,\n SemiontProvider,\n} from '@semiont/react-ui';\nimport { KeyboardShortcutsProvider } from '@/contexts/KeyboardShortcutsContext';\nimport { NavigationHandler } from '@/components/knowledge/NavigationHandler';\nimport { useMergedTranslationManager } from '@/hooks/useMergedTranslationManager';\n\n/**\n * Root Provider Composition for Semiont Frontend.\n *\n * Wires up GLOBAL contexts that every page needs.\n *\n * The module-scoped `SemiontBrowser` singleton (KB list, active KB,\n * per-KB SemiontSession) is made available via `<SemiontProvider>` at\n * the app root — mounting it here is cheap because the singleton itself\n * survives every React re-render and route change.\n *\n * Auth-dependent UI (ProtectedErrorBoundary, SessionExpiredModal,\n * PermissionDeniedModal) is bundled in `AuthShell` and mounted only in\n * protected layouts (know/, admin/, moderate/, auth/welcome/). Pre-app\n * routes (landing, OAuth flow) intentionally do NOT mount AuthShell —\n * they have no session UI.\n *\n * The `SemiontClient` is owned by the per-KB `SemiontSession`, which\n * `SemiontBrowser` constructs on demand. Components read\n * `useObservable(useSemiont().activeSession$)?.client`.\n *\n * The event bus lives inside the client (owned by `SemiontSession`).\n * Components emit via `session?.emit(...)` and subscribe via\n * `useEventSubscription[s]`.\n *\n * Provider order — outer to inner:\n * 1. TranslationProvider — i18n\n * 2. SemiontProvider — SemiontBrowser singleton\n * 3. ToastProvider — toast notifications\n * 4. LiveRegionProvider — a11y live region\n * 5. KeyboardShortcutsProvider — keyboard shortcuts\n * 6. ThemeProvider — theme\n * + NavigationHandler\n */\nexport function Providers({ children }: { children: React.ReactNode }) {\n const translationManager = useMergedTranslationManager();\n\n return (\n <TranslationProvider translationManager={translationManager}>\n <SemiontProvider>\n <ToastProvider>\n <LiveRegionProvider>\n <KeyboardShortcutsProvider>\n <ThemeProvider>\n <NavigationHandler />\n {children}\n </ThemeProvider>\n </KeyboardShortcutsProvider>\n </LiveRegionProvider>\n </ToastProvider>\n </SemiontProvider>\n </TranslationProvider>\n );\n}\n","\"use client\";\n\nimport React, { useState, useEffect } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport {\n getCookieConsent,\n setCookieConsent,\n shouldShowBanner,\n COOKIE_CATEGORIES,\n CookieConsent,\n isCCPAApplicable,\n isGDPRApplicable,\n type CookieCategory\n} from '@/lib/cookies';\nimport { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/24/outline';\n\ninterface CookieBannerProps {\n className?: string;\n}\n\nexport function CookieBanner({ className = '' }: CookieBannerProps) {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`CookieBanner.${k}`, p as any) as string;\n const [isVisible, setIsVisible] = useState(false);\n const [showDetails, setShowDetails] = useState(false);\n const [isLoading, setIsLoading] = useState(false);\n const [region, setRegion] = useState<'GDPR' | 'CCPA' | 'GENERAL'>('GENERAL');\n const [consent, setConsent] = useState<Partial<CookieConsent>>({\n necessary: true,\n analytics: false,\n marketing: false,\n preferences: false\n });\n\n useEffect(() => {\n const checkVisibility = async () => {\n if (shouldShowBanner()) {\n setIsVisible(true);\n\n try {\n // Determine applicable regulation\n const [isGDPR, isCCPA] = await Promise.all([\n isGDPRApplicable(),\n isCCPAApplicable()\n ]);\n\n if (isGDPR) {\n setRegion('GDPR');\n } else if (isCCPA) {\n setRegion('CCPA');\n } else {\n setRegion('GENERAL');\n }\n } catch (error) {\n // If region detection fails, default to GENERAL\n console.error('Failed to detect region:', error);\n setRegion('GENERAL');\n }\n }\n };\n\n checkVisibility();\n }, []);\n\n const handleAcceptAll = async () => {\n setIsLoading(true);\n\n try {\n const fullConsent = {\n necessary: true,\n analytics: true,\n marketing: true,\n preferences: true\n };\n\n await Promise.resolve(setCookieConsent(fullConsent));\n setIsVisible(false);\n } catch (error) {\n console.error('Failed to save cookie consent:', error);\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleRejectAll = async () => {\n setIsLoading(true);\n\n try {\n const minimalConsent = {\n necessary: true,\n analytics: false,\n marketing: false,\n preferences: false\n };\n\n await Promise.resolve(setCookieConsent(minimalConsent));\n setIsVisible(false);\n } catch (error) {\n console.error('Failed to save cookie consent:', error);\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleSavePreferences = async () => {\n setIsLoading(true);\n\n try {\n await Promise.resolve(setCookieConsent(consent));\n setIsVisible(false);\n } catch (error) {\n console.error('Failed to save cookie consent:', error);\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleCategoryToggle = (categoryId: keyof Omit<CookieConsent, 'timestamp' | 'version'>) => {\n if (categoryId === 'necessary') return; // Can't toggle necessary cookies\n\n setConsent(prev => ({\n ...prev,\n [categoryId]: !prev[categoryId]\n }));\n };\n\n const getBannerText = () => {\n switch (region) {\n case 'GDPR':\n return {\n title: t('gdprTitle'),\n description: t('gdprDescription'),\n learnMore: t('gdprLearnMore')\n };\n case 'CCPA':\n return {\n title: t('ccpaTitle'),\n description: t('ccpaDescription'),\n learnMore: t('ccpaLearnMore')\n };\n default:\n return {\n title: t('generalTitle'),\n description: t('generalDescription'),\n learnMore: t('generalLearnMore')\n };\n }\n };\n\n if (!isVisible) return null;\n\n const bannerText = getBannerText();\n\n return (\n <div\n className={className}\n style={{\n position: 'fixed',\n bottom: 0,\n left: 0,\n right: 0,\n zIndex: 50,\n backgroundColor: 'var(--semiont-bg-primary)',\n borderTop: '1px solid var(--semiont-border-primary)',\n boxShadow: 'var(--semiont-shadow-lg)',\n }}\n >\n <div style={{ maxWidth: '80rem', margin: '0 auto', padding: '1rem 1.5rem' }}>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n {/* Main banner content */}\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: '1.5rem', flexWrap: 'wrap' }}>\n <div style={{ flex: 1, minWidth: '300px' }}>\n <h3 style={{\n fontSize: '1.125rem',\n fontWeight: 600,\n color: 'var(--semiont-text-primary)',\n marginBottom: '0.5rem',\n }}>\n {bannerText.title}\n </h3>\n <p style={{\n fontSize: 'var(--semiont-text-sm, 0.875rem)',\n color: 'var(--semiont-text-secondary)',\n marginBottom: '0.25rem',\n }}>\n {bannerText.description}\n </p>\n <p style={{\n fontSize: 'var(--semiont-text-xs, 0.75rem)',\n color: 'var(--semiont-text-tertiary)',\n }}>\n {bannerText.learnMore}\n </p>\n </div>\n\n {/* Action buttons */}\n <div style={{ display: 'flex', gap: '0.75rem', alignItems: 'center', flexWrap: 'wrap' }}>\n <button\n type=\"button\"\n onClick={() => setShowDetails(!showDetails)}\n className=\"semiont-button--secondary\"\n style={{ display: 'flex', alignItems: 'center', gap: '0.25rem' }}\n >\n {t('customize')}\n {showDetails ? (\n <ChevronUpIcon style={{ width: '1rem', height: '1rem' }} />\n ) : (\n <ChevronDownIcon style={{ width: '1rem', height: '1rem' }} />\n )}\n </button>\n\n {region !== 'GDPR' && (\n <button\n type=\"button\"\n onClick={handleRejectAll}\n disabled={isLoading}\n className=\"semiont-button--secondary\"\n >\n {isLoading ? t('saving') : t('rejectAll')}\n </button>\n )}\n\n <button\n type=\"button\"\n onClick={handleAcceptAll}\n disabled={isLoading}\n className=\"semiont-button--primary\"\n >\n {isLoading ? t('saving') : t('acceptAll')}\n </button>\n </div>\n </div>\n\n {/* Detailed preferences */}\n {showDetails && (\n <div style={{\n borderTop: '1px solid var(--semiont-border-primary)',\n paddingTop: '1rem',\n }}>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n <h4 style={{\n fontSize: '1rem',\n fontWeight: 500,\n color: 'var(--semiont-text-primary)',\n }}>\n {t('cookiePreferences')}\n </h4>\n\n <div style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem' }}>\n {COOKIE_CATEGORIES.map((category: CookieCategory) => (\n <div key={category.id} style={{ display: 'flex', alignItems: 'flex-start', gap: '0.75rem' }}>\n <div style={{ display: 'flex', alignItems: 'center', height: '1.25rem' }}>\n <input\n id={`cookie-${category.id}`}\n type=\"checkbox\"\n checked={consent[category.id] || false}\n onChange={() => handleCategoryToggle(category.id)}\n disabled={category.required || isLoading}\n style={{ accentColor: 'var(--semiont-color-primary-600, #2563eb)' }}\n />\n </div>\n <div style={{ flex: 1, minWidth: 0 }}>\n <label\n htmlFor={`cookie-${category.id}`}\n style={{\n fontSize: 'var(--semiont-text-sm, 0.875rem)',\n fontWeight: 500,\n color: 'var(--semiont-text-primary)',\n cursor: 'pointer',\n }}\n >\n {category.name}\n {category.required && (\n <span style={{\n fontSize: 'var(--semiont-text-xs, 0.75rem)',\n color: 'var(--semiont-text-tertiary)',\n marginLeft: '0.25rem',\n }}>\n {t('required')}\n </span>\n )}\n </label>\n <p style={{\n fontSize: 'var(--semiont-text-xs, 0.75rem)',\n color: 'var(--semiont-text-secondary)',\n marginTop: '0.25rem',\n }}>\n {category.description}\n </p>\n <details style={{ marginTop: '0.25rem' }}>\n <summary style={{\n fontSize: 'var(--semiont-text-xs, 0.75rem)',\n color: 'var(--semiont-color-primary-600, #2563eb)',\n cursor: 'pointer',\n }}>\n {t('viewCookies')}\n </summary>\n <div style={{\n marginTop: '0.25rem',\n fontSize: 'var(--semiont-text-xs, 0.75rem)',\n color: 'var(--semiont-text-tertiary)',\n }}>\n {category.cookies.join(', ')}\n </div>\n </details>\n </div>\n </div>\n ))}\n </div>\n\n <div style={{\n display: 'flex',\n justifyContent: 'flex-end',\n gap: '0.75rem',\n paddingTop: '1rem',\n }}>\n <button\n type=\"button\"\n onClick={() => setShowDetails(false)}\n className=\"semiont-button--secondary\"\n >\n {t('cancel')}\n </button>\n <button\n type=\"button\"\n onClick={handleSavePreferences}\n disabled={isLoading}\n className=\"semiont-button--primary\"\n >\n {isLoading ? t('saving') : t('savePreferences')}\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n\nexport default CookieBanner;\n","import { Outlet } from 'react-router-dom';\nimport { Providers } from '../providers';\nimport { CookieBanner } from '@/components/CookieBanner';\nimport { SkipLinks } from '@semiont/react-ui';\n\n/**\n * Locale Layout — root layout for all /:locale/* routes.\n *\n * Mounts only auth-independent providers. Auth-dependent providers\n * (KnowledgeBaseProvider, AuthProvider, SessionProvider, modals)\n * are mounted via AuthShell in protected layouts (know/, admin/,\n * moderate/, auth/welcome/).\n */\nexport default function LocaleLayout() {\n return (\n <Providers>\n <SkipLinks />\n <Outlet />\n <CookieBanner />\n </Providers>\n );\n}\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import"./rolldown-runtime-jpDsebLB.js";import{i as e,n as t}from"./i18n-B53Yefbh.js";import{t as n}from"./vendor-0HjOURbh.js";import{n as r,t as i}from"./routing-Bcj1FhkC.js";e();var a=n();function o(){let{t:e}=t(),n=(t,n)=>e(`NotFound.${t}`,n),o=r();return(0,a.jsx)(`div`,{className:`flex min-h-screen items-center justify-center bg-gray-50 dark:bg-gray-900`,children:(0,a.jsxs)(`div`,{className:`text-center px-4`,children:[(0,a.jsx)(`h1`,{className:`text-6xl font-bold text-gray-900 dark:text-white mb-4`,children:n(`title`)}),(0,a.jsx)(`h2`,{className:`text-2xl font-semibold text-gray-700 dark:text-gray-300 mb-4`,children:n(`heading`)}),(0,a.jsx)(`p`,{className:`text-gray-600 dark:text-gray-400 mb-8`,children:n(`message`)}),(0,a.jsx)(i,{to:`/${o}`,className:`inline-block px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors`,children:n(`goHome`)})]})})}export{o as default};
2
- //# sourceMappingURL=not-found-4iuCkpA7.js.map
1
+ import"./rolldown-runtime-jpDsebLB.js";import{i as e,n as t}from"./i18n-B53Yefbh.js";import{t as n}from"./vendor-0HjOURbh.js";import{n as r,t as i}from"./routing-Dqgz2rV4.js";e();var a=n();function o(){let{t:e}=t(),n=(t,n)=>e(`NotFound.${t}`,n),o=r();return(0,a.jsx)(`div`,{className:`flex min-h-screen items-center justify-center bg-gray-50 dark:bg-gray-900`,children:(0,a.jsxs)(`div`,{className:`text-center px-4`,children:[(0,a.jsx)(`h1`,{className:`text-6xl font-bold text-gray-900 dark:text-white mb-4`,children:n(`title`)}),(0,a.jsx)(`h2`,{className:`text-2xl font-semibold text-gray-700 dark:text-gray-300 mb-4`,children:n(`heading`)}),(0,a.jsx)(`p`,{className:`text-gray-600 dark:text-gray-400 mb-8`,children:n(`message`)}),(0,a.jsx)(i,{to:`/${o}`,className:`inline-block px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors`,children:n(`goHome`)})]})})}export{o as default};
2
+ //# sourceMappingURL=not-found-CXjr3aHk.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"not-found-4iuCkpA7.js","names":[],"sources":["../../src/app/[locale]/not-found.tsx"],"sourcesContent":["import React from 'react';\nimport { Link } from '@/i18n/routing';\nimport { useTranslation } from 'react-i18next';\nimport { useLocale } from '@/i18n/routing';\n\nexport default function NotFound() {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`NotFound.${k}`, p as any) as string;\n const locale = useLocale();\n\n return (\n <div className=\"flex min-h-screen items-center justify-center bg-gray-50 dark:bg-gray-900\">\n <div className=\"text-center px-4\">\n <h1 className=\"text-6xl font-bold text-gray-900 dark:text-white mb-4\">{t('title')}</h1>\n <h2 className=\"text-2xl font-semibold text-gray-700 dark:text-gray-300 mb-4\">\n {t('heading')}\n </h2>\n <p className=\"text-gray-600 dark:text-gray-400 mb-8\">\n {t('message')}\n </p>\n <Link\n to={`/${locale}`}\n className=\"inline-block px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors\"\n >\n {t('goHome')}\n </Link>\n </div>\n </div>\n );\n}\n"],"mappings":"6LAKA,SAAwB,GAAW,CACjC,GAAM,CAAE,EAAG,GAAO,GAAgB,CAC5B,GAAK,EAAW,IAAgC,EAAG,YAAY,IAAK,EAAS,CAC7E,EAAS,GAAW,CAE1B,OACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,sFACb,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,4BAAf,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,iEAAyD,EAAE,QAAQ,CAAM,CAAA,EACvF,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,wEACX,EAAE,UAAU,CACV,CAAA,EACL,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,iDACV,EAAE,UAAU,CACX,CAAA,EACJ,EAAA,EAAA,KAAC,EAAD,CACE,GAAI,IAAI,IACR,UAAU,wGAET,EAAE,SAAS,CACP,CAAA,CACH,GACF,CAAA"}
1
+ {"version":3,"file":"not-found-CXjr3aHk.js","names":[],"sources":["../../src/app/[locale]/not-found.tsx"],"sourcesContent":["import React from 'react';\nimport { Link } from '@/i18n/routing';\nimport { useTranslation } from 'react-i18next';\nimport { useLocale } from '@/i18n/routing';\n\nexport default function NotFound() {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`NotFound.${k}`, p as any) as string;\n const locale = useLocale();\n\n return (\n <div className=\"flex min-h-screen items-center justify-center bg-gray-50 dark:bg-gray-900\">\n <div className=\"text-center px-4\">\n <h1 className=\"text-6xl font-bold text-gray-900 dark:text-white mb-4\">{t('title')}</h1>\n <h2 className=\"text-2xl font-semibold text-gray-700 dark:text-gray-300 mb-4\">\n {t('heading')}\n </h2>\n <p className=\"text-gray-600 dark:text-gray-400 mb-8\">\n {t('message')}\n </p>\n <Link\n to={`/${locale}`}\n className=\"inline-block px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors\"\n >\n {t('goHome')}\n </Link>\n </div>\n </div>\n );\n}\n"],"mappings":"6LAKA,SAAwB,GAAW,CACjC,GAAM,CAAE,EAAG,GAAO,GAAgB,CAC5B,GAAK,EAAW,IAAgC,EAAG,YAAY,IAAK,EAAS,CAC7E,EAAS,GAAW,CAE1B,OACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,sFACb,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,4BAAf,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,iEAAyD,EAAE,QAAQ,CAAM,CAAA,EACvF,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,wEACX,EAAE,UAAU,CACV,CAAA,EACL,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,iDACV,EAAE,UAAU,CACX,CAAA,EACJ,EAAA,EAAA,KAAC,EAAD,CACE,GAAI,IAAI,IACR,UAAU,wGAET,EAAE,SAAS,CACP,CAAA,CACH,GACF,CAAA"}
@@ -1,2 +1,2 @@
1
- import{n as e}from"./rolldown-runtime-jpDsebLB.js";import{i as t}from"./i18n-B53Yefbh.js";import{t as n}from"./vendor-0HjOURbh.js";import{At as r,Lt as i,S as a,V as o,Z as s,ot as c,tt as l,x as u}from"./index-DjtRDlfn.js";import{t as d}from"./ToolbarPanels-CRGQDX-L.js";import{n as f}from"./routing-Bcj1FhkC.js";import{n as p,t as m}from"./routing-DW1ehi64.js";var h=e(t()),g=n();function _(){let e=r(i()?.id);return(0,g.jsx)(v,{rId:e},e)}function v({rId:e}){let t=f(),n=s(c().activeSession$),i=s(n?.streamState$)??`initial`,_=n?.kb??null,v=n?.client,y=l(()=>o(v,e)),b=s(y.resource$),x=s(y.isLoading$)??!0;(0,h.useEffect)(()=>{!x&&!b&&console.error(`[Document] Resource ${e} not found`)},[x,e,b]);let S=(0,h.useCallback)(async()=>{y.invalidate()},[y]);if(x||!b)return(0,g.jsx)(u,{});let C=b;return(0,g.jsx)(a,{resource:C,rUri:r(C[`@id`]),locale:t,Link:m,routes:p,ToolbarPanels:d,refetchDocument:S,streamStatus:i,knowledgeBaseName:_?.label})}export{_ as default};
2
- //# sourceMappingURL=page-DVCVvH_S.js.map
1
+ import{n as e}from"./rolldown-runtime-jpDsebLB.js";import{i as t}from"./i18n-B53Yefbh.js";import{t as n}from"./vendor-0HjOURbh.js";import{At as r,Lt as i,S as a,V as o,Z as s,ot as c,tt as l,x as u}from"./index-DojEUBpq.js";import{t as d}from"./ToolbarPanels-wzZqAqCQ.js";import{n as f}from"./routing-Dqgz2rV4.js";import{n as p,t as m}from"./routing-CcetIVef.js";var h=e(t()),g=n();function _(){let e=r(i()?.id);return(0,g.jsx)(v,{rId:e},e)}function v({rId:e}){let t=f(),n=s(c().activeSession$),i=s(n?.streamState$)??`initial`,_=n?.kb??null,v=n?.client,y=l(()=>o(v,e)),b=s(y.resource$),x=s(y.isLoading$)??!0;(0,h.useEffect)(()=>{!x&&!b&&console.error(`[Document] Resource ${e} not found`)},[x,e,b]);let S=(0,h.useCallback)(async()=>{y.invalidate()},[y]);if(x||!b)return(0,g.jsx)(u,{});let C=b;return(0,g.jsx)(a,{resource:C,rUri:r(C[`@id`]),locale:t,Link:m,routes:p,ToolbarPanels:d,refetchDocument:S,streamStatus:i,knowledgeBaseName:_?.label})}export{_ as default};
2
+ //# sourceMappingURL=page-3_orURnj.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"page-DVCVvH_S.js","names":[],"sources":["../../src/app/[locale]/know/resource/[id]/page.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * Resource Viewer Page - Minimal Next.js routing wrapper\n *\n * Handles only Next.js routing and initial resource loading.\n * All other concerns (data loading, events, UI state) are handled by ResourceViewerPage.\n */\n\nimport { useEffect, useCallback } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useLocale } from '@/i18n/routing';\nimport { useSemiont, useObservable, useStateUnit, createResourceLoaderStateUnit } from '@semiont/react-ui';\nimport { resourceId } from '@semiont/core';\nimport { Link, routes } from '@/lib/routing';\n\n// Feature components\nimport { ResourceLoadingState, ResourceErrorState, ResourceViewerPage } from '@semiont/react-ui';\nimport { ToolbarPanels } from '@/components/toolbar/ToolbarPanels';\nimport type { SemiontResource } from '@semiont/react-ui';\n\n/**\n * Main page component - handles only routing and initial resource load.\n *\n * The inner component is keyed on `rId` so that navigation between\n * resources (URL-param change without component unmount) forces a full\n * remount. Without this, `useStateUnit`'s factory closes over the\n * initial `rId` and never re-runs, and the URL changes but the content\n * stays on the first-loaded resource.\n */\nexport default function KnowledgeResourcePage() {\n const params = useParams();\n const rId = resourceId(params?.id as string);\n return <KnowledgeResourcePageInner key={rId} rId={rId} />;\n}\n\nfunction KnowledgeResourcePageInner({ rId }: { rId: ReturnType<typeof resourceId> }) {\n const locale = useLocale();\n\n const session = useObservable(useSemiont().activeSession$);\n const streamStatus = useObservable(session?.streamState$) ?? 'initial';\n const activeKnowledgeBase = session?.kb ?? null;\n\n const semiont = session?.client;\n const loader = useStateUnit(() => createResourceLoaderStateUnit(semiont!, rId));\n const resourceData = useObservable(loader.resource$);\n const isLoading = useObservable(loader.isLoading$) ?? true;\n\n // Log error for debugging\n useEffect(() => {\n if (!isLoading && !resourceData) {\n console.error(`[Document] Resource ${rId} not found`);\n }\n }, [isLoading, rId, resourceData]);\n\n const refetchDocument = useCallback(async () => {\n loader.invalidate();\n }, [loader]);\n\n // Early return: Loading state\n if (isLoading || !resourceData) {\n return <ResourceLoadingState />;\n }\n\n const resource = resourceData as SemiontResource;\n // resource['@id'] is now a bare ID\n const canonicalId = resourceId(resource['@id']);\n\n // Render with minimal props - all data loading/events handled inside ResourceViewerPage\n return (\n <ResourceViewerPage\n resource={resource}\n rUri={canonicalId}\n locale={locale}\n Link={Link}\n routes={routes}\n ToolbarPanels={ToolbarPanels}\n refetchDocument={refetchDocument}\n streamStatus={streamStatus}\n knowledgeBaseName={activeKnowledgeBase?.label}\n />\n );\n}\n"],"mappings":"8XA8BA,SAAwB,GAAwB,CAE9C,IAAM,EAAM,EADG,GACQ,EAAQ,GAAa,CAC5C,OAAO,EAAA,EAAA,KAAC,EAAD,CAA2C,MAAO,CAAjB,EAAiB,CAG3D,SAAS,EAA2B,CAAE,OAA+C,CACnF,IAAM,EAAS,GAAW,CAEpB,EAAU,EAAc,GAAY,CAAC,eAAe,CACpD,EAAe,EAAc,GAAS,aAAa,EAAI,UACvD,EAAsB,GAAS,IAAM,KAErC,EAAU,GAAS,OACnB,EAAS,MAAmB,EAA8B,EAAU,EAAI,CAAC,CACzE,EAAe,EAAc,EAAO,UAAU,CAC9C,EAAY,EAAc,EAAO,WAAW,EAAI,IAGtD,EAAA,EAAA,eAAgB,CACV,CAAC,GAAa,CAAC,GACjB,QAAQ,MAAM,uBAAuB,EAAI,YAAY,EAEtD,CAAC,EAAW,EAAK,EAAa,CAAC,CAElC,IAAM,GAAA,EAAA,EAAA,aAA8B,SAAY,CAC9C,EAAO,YAAY,EAClB,CAAC,EAAO,CAAC,CAGZ,GAAI,GAAa,CAAC,EAChB,OAAO,EAAA,EAAA,KAAC,EAAD,EAAwB,CAAA,CAGjC,IAAM,EAAW,EAKjB,OACE,EAAA,EAAA,KAAC,EAAD,CACY,WACV,KANgB,EAAW,EAAS,OAM9B,CACE,SACF,OACE,SACO,gBACE,kBACH,eACd,kBAAmB,GAAqB,MACxC,CAAA"}
1
+ {"version":3,"file":"page-3_orURnj.js","names":[],"sources":["../../src/app/[locale]/know/resource/[id]/page.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * Resource Viewer Page - Minimal Next.js routing wrapper\n *\n * Handles only Next.js routing and initial resource loading.\n * All other concerns (data loading, events, UI state) are handled by ResourceViewerPage.\n */\n\nimport { useEffect, useCallback } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useLocale } from '@/i18n/routing';\nimport { useSemiont, useObservable, useStateUnit, createResourceLoaderStateUnit } from '@semiont/react-ui';\nimport { resourceId } from '@semiont/core';\nimport { Link, routes } from '@/lib/routing';\n\n// Feature components\nimport { ResourceLoadingState, ResourceErrorState, ResourceViewerPage } from '@semiont/react-ui';\nimport { ToolbarPanels } from '@/components/toolbar/ToolbarPanels';\nimport type { SemiontResource } from '@semiont/react-ui';\n\n/**\n * Main page component - handles only routing and initial resource load.\n *\n * The inner component is keyed on `rId` so that navigation between\n * resources (URL-param change without component unmount) forces a full\n * remount. Without this, `useStateUnit`'s factory closes over the\n * initial `rId` and never re-runs, and the URL changes but the content\n * stays on the first-loaded resource.\n */\nexport default function KnowledgeResourcePage() {\n const params = useParams();\n const rId = resourceId(params?.id as string);\n return <KnowledgeResourcePageInner key={rId} rId={rId} />;\n}\n\nfunction KnowledgeResourcePageInner({ rId }: { rId: ReturnType<typeof resourceId> }) {\n const locale = useLocale();\n\n const session = useObservable(useSemiont().activeSession$);\n const streamStatus = useObservable(session?.streamState$) ?? 'initial';\n const activeKnowledgeBase = session?.kb ?? null;\n\n const semiont = session?.client;\n const loader = useStateUnit(() => createResourceLoaderStateUnit(semiont!, rId));\n const resourceData = useObservable(loader.resource$);\n const isLoading = useObservable(loader.isLoading$) ?? true;\n\n // Log error for debugging\n useEffect(() => {\n if (!isLoading && !resourceData) {\n console.error(`[Document] Resource ${rId} not found`);\n }\n }, [isLoading, rId, resourceData]);\n\n const refetchDocument = useCallback(async () => {\n loader.invalidate();\n }, [loader]);\n\n // Early return: Loading state\n if (isLoading || !resourceData) {\n return <ResourceLoadingState />;\n }\n\n const resource = resourceData as SemiontResource;\n // resource['@id'] is now a bare ID\n const canonicalId = resourceId(resource['@id']);\n\n // Render with minimal props - all data loading/events handled inside ResourceViewerPage\n return (\n <ResourceViewerPage\n resource={resource}\n rUri={canonicalId}\n locale={locale}\n Link={Link}\n routes={routes}\n ToolbarPanels={ToolbarPanels}\n refetchDocument={refetchDocument}\n streamStatus={streamStatus}\n knowledgeBaseName={activeKnowledgeBase?.label}\n />\n );\n}\n"],"mappings":"8XA8BA,SAAwB,GAAwB,CAE9C,IAAM,EAAM,EADG,GACQ,EAAQ,GAAa,CAC5C,OAAO,EAAA,EAAA,KAAC,EAAD,CAA2C,MAAO,CAAjB,EAAiB,CAG3D,SAAS,EAA2B,CAAE,OAA+C,CACnF,IAAM,EAAS,GAAW,CAEpB,EAAU,EAAc,GAAY,CAAC,eAAe,CACpD,EAAe,EAAc,GAAS,aAAa,EAAI,UACvD,EAAsB,GAAS,IAAM,KAErC,EAAU,GAAS,OACnB,EAAS,MAAmB,EAA8B,EAAU,EAAI,CAAC,CACzE,EAAe,EAAc,EAAO,UAAU,CAC9C,EAAY,EAAc,EAAO,WAAW,EAAI,IAGtD,EAAA,EAAA,eAAgB,CACV,CAAC,GAAa,CAAC,GACjB,QAAQ,MAAM,uBAAuB,EAAI,YAAY,EAEtD,CAAC,EAAW,EAAK,EAAa,CAAC,CAElC,IAAM,GAAA,EAAA,EAAA,aAA8B,SAAY,CAC9C,EAAO,YAAY,EAClB,CAAC,EAAO,CAAC,CAGZ,GAAI,GAAa,CAAC,EAChB,OAAO,EAAA,EAAA,KAAC,EAAD,EAAwB,CAAA,CAGjC,IAAM,EAAW,EAKjB,OACE,EAAA,EAAA,KAAC,EAAD,CACY,WACV,KANgB,EAAW,EAAS,OAM9B,CACE,SACF,OACE,SACO,gBACE,kBACH,eACd,kBAAmB,GAAqB,MACxC,CAAA"}
@@ -1,2 +1,2 @@
1
- import{n as e}from"./rolldown-runtime-jpDsebLB.js";import{i as t,n}from"./i18n-B53Yefbh.js";import{t as r}from"./vendor-0HjOURbh.js";import{A as i,M as a,X as o,Z as s,et as c,nt as l,ot as u,q as d}from"./index-DjtRDlfn.js";import{t as f}from"./ToolbarPanels-CRGQDX-L.js";var p=e(t()),m=r();function h(){let{t:e}=n(),t=(t,n)=>e(`ModerateTagSchemas.${t}`,n),r=s(c().activePanel$)??null,{theme:h,setTheme:g}=l(),{showLineNumbers:_,toggleLineNumbers:v}=o();d({"settings:theme-changed":(0,p.useCallback)(({theme:e})=>{g(e)},[g]),"settings:line-numbers-toggled":(0,p.useCallback)(()=>{v()},[v])});let y=s(u().activeSession$),b=s((0,p.useMemo)(()=>y?.client.browse.tagSchemas()??null,[y]));return(0,m.jsx)(i,{schemas:b??[],isLoading:b===void 0,theme:h,showLineNumbers:_,activePanel:r,translations:{pageTitle:t(`pageTitle`),pageDescription:t(`pageDescription`),categories:t(`categories`),loading:t(`loading`)},ToolbarPanels:f,Toolbar:a})}export{h as default};
2
- //# sourceMappingURL=page-CXhfUrZM.js.map
1
+ import{n as e}from"./rolldown-runtime-jpDsebLB.js";import{i as t,n}from"./i18n-B53Yefbh.js";import{t as r}from"./vendor-0HjOURbh.js";import{A as i,M as a,X as o,Z as s,et as c,nt as l,ot as u,q as d}from"./index-DojEUBpq.js";import{t as f}from"./ToolbarPanels-wzZqAqCQ.js";var p=e(t()),m=r();function h(){let{t:e}=n(),t=(t,n)=>e(`ModerateTagSchemas.${t}`,n),r=s(c().activePanel$)??null,{theme:h,setTheme:g}=l(),{showLineNumbers:_,toggleLineNumbers:v}=o();d({"settings:theme-changed":(0,p.useCallback)(({theme:e})=>{g(e)},[g]),"settings:line-numbers-toggled":(0,p.useCallback)(()=>{v()},[v])});let y=s(u().activeSession$),b=s((0,p.useMemo)(()=>y?.client.browse.tagSchemas()??null,[y]));return(0,m.jsx)(i,{schemas:b??[],isLoading:b===void 0,theme:h,showLineNumbers:_,activePanel:r,translations:{pageTitle:t(`pageTitle`),pageDescription:t(`pageDescription`),categories:t(`categories`),loading:t(`loading`)},ToolbarPanels:f,Toolbar:a})}export{h as default};
2
+ //# sourceMappingURL=page-A0bP7R9_.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"page-CXhfUrZM.js","names":[],"sources":["../../src/app/[locale]/moderate/tag-schemas/page.tsx"],"sourcesContent":["import { useCallback, useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Toolbar } from '@semiont/react-ui';\nimport { ToolbarPanels } from '@/components/toolbar/ToolbarPanels';\nimport { useTheme, useShellStateUnit, useObservable, useLineNumbers, useEventSubscriptions, useSemiont } from '@semiont/react-ui';\nimport { TagSchemasPage } from '@semiont/react-ui';\n\n// Authentication is handled by middleware (proxy.ts)\n// Only authenticated moderators/admins can reach this page\n\nexport default function TagSchemasPageWrapper() {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`ModerateTagSchemas.${k}`, p as any) as string;\n\n // Toolbar and settings state\n const browseStateUnit = useShellStateUnit();\n const activePanel = useObservable(browseStateUnit.activePanel$) ?? null;\n const { theme, setTheme } = useTheme();\n const { showLineNumbers, toggleLineNumbers } = useLineNumbers();\n\n const handleThemeChanged = useCallback(({ theme }: { theme: 'light' | 'dark' | 'system' }) => {\n setTheme(theme);\n }, [setTheme]);\n\n const handleLineNumbersToggled = useCallback(() => {\n toggleLineNumbers();\n }, [toggleLineNumbers]);\n\n useEventSubscriptions({\n 'settings:theme-changed': handleThemeChanged,\n 'settings:line-numbers-toggled': handleLineNumbersToggled,\n });\n\n // Subscribe to the per-KB tag-schema registry. Schemas are runtime-\n // registered by the KB at session start (frame.addTagSchema). The\n // observable yields `undefined` during the initial fetch — surfaced as\n // `isLoading` to the page component.\n const session = useObservable(useSemiont().activeSession$);\n const tagSchemas$ = useMemo(\n () => session?.client.browse.tagSchemas() ?? null,\n [session],\n );\n const schemasObserved = useObservable(tagSchemas$);\n const schemas = schemasObserved ?? [];\n const isLoading = schemasObserved === undefined;\n\n return (\n <TagSchemasPage\n schemas={schemas}\n isLoading={isLoading}\n theme={theme}\n showLineNumbers={showLineNumbers}\n activePanel={activePanel}\n translations={{\n pageTitle: t('pageTitle'),\n pageDescription: t('pageDescription'),\n categories: t('categories'),\n loading: t('loading'),\n }}\n ToolbarPanels={ToolbarPanels}\n Toolbar={Toolbar}\n />\n );\n}\n"],"mappings":"oSAUA,SAAwB,GAAwB,CAC9C,GAAM,CAAE,EAAG,GAAO,GAAgB,CAC5B,GAAK,EAAW,IAAgC,EAAG,sBAAsB,IAAK,EAAS,CAIvF,EAAc,EADI,GACU,CAAgB,aAAa,EAAI,KAC7D,CAAE,QAAO,YAAa,GAAU,CAChC,CAAE,kBAAiB,qBAAsB,GAAgB,CAU/D,EAAsB,CACpB,0BAAA,EAAA,EAAA,cATsC,CAAE,WAAoD,CAC5F,EAAS,EAAM,EACd,CAAC,EAAS,CAOe,CAC1B,iCAAA,EAAA,EAAA,iBANiD,CACjD,GAAmB,EAClB,CAAC,EAAkB,CAIa,CAClC,CAAC,CAMF,IAAM,EAAU,EAAc,GAAY,CAAC,eAAe,CAKpD,EAAkB,GAAA,EAAA,EAAA,aAHhB,GAAS,OAAO,OAAO,YAAY,EAAI,KAC7C,CAAC,EAAQ,CAE2B,CAAY,CAIlD,OACE,EAAA,EAAA,KAAC,EAAD,CACW,QALG,GAAmB,EAAE,CAMtB,UALG,IAAoB,IAAA,GAM3B,QACU,kBACJ,cACb,aAAc,CACZ,UAAW,EAAE,YAAY,CACzB,gBAAiB,EAAE,kBAAkB,CACrC,WAAY,EAAE,aAAa,CAC3B,QAAS,EAAE,UAAU,CACtB,CACc,gBACN,UACT,CAAA"}
1
+ {"version":3,"file":"page-A0bP7R9_.js","names":[],"sources":["../../src/app/[locale]/moderate/tag-schemas/page.tsx"],"sourcesContent":["import { useCallback, useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Toolbar } from '@semiont/react-ui';\nimport { ToolbarPanels } from '@/components/toolbar/ToolbarPanels';\nimport { useTheme, useShellStateUnit, useObservable, useLineNumbers, useEventSubscriptions, useSemiont } from '@semiont/react-ui';\nimport { TagSchemasPage } from '@semiont/react-ui';\n\n// Authentication is handled by middleware (proxy.ts)\n// Only authenticated moderators/admins can reach this page\n\nexport default function TagSchemasPageWrapper() {\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`ModerateTagSchemas.${k}`, p as any) as string;\n\n // Toolbar and settings state\n const browseStateUnit = useShellStateUnit();\n const activePanel = useObservable(browseStateUnit.activePanel$) ?? null;\n const { theme, setTheme } = useTheme();\n const { showLineNumbers, toggleLineNumbers } = useLineNumbers();\n\n const handleThemeChanged = useCallback(({ theme }: { theme: 'light' | 'dark' | 'system' }) => {\n setTheme(theme);\n }, [setTheme]);\n\n const handleLineNumbersToggled = useCallback(() => {\n toggleLineNumbers();\n }, [toggleLineNumbers]);\n\n useEventSubscriptions({\n 'settings:theme-changed': handleThemeChanged,\n 'settings:line-numbers-toggled': handleLineNumbersToggled,\n });\n\n // Subscribe to the per-KB tag-schema registry. Schemas are runtime-\n // registered by the KB at session start (frame.addTagSchema). The\n // observable yields `undefined` during the initial fetch — surfaced as\n // `isLoading` to the page component.\n const session = useObservable(useSemiont().activeSession$);\n const tagSchemas$ = useMemo(\n () => session?.client.browse.tagSchemas() ?? null,\n [session],\n );\n const schemasObserved = useObservable(tagSchemas$);\n const schemas = schemasObserved ?? [];\n const isLoading = schemasObserved === undefined;\n\n return (\n <TagSchemasPage\n schemas={schemas}\n isLoading={isLoading}\n theme={theme}\n showLineNumbers={showLineNumbers}\n activePanel={activePanel}\n translations={{\n pageTitle: t('pageTitle'),\n pageDescription: t('pageDescription'),\n categories: t('categories'),\n loading: t('loading'),\n }}\n ToolbarPanels={ToolbarPanels}\n Toolbar={Toolbar}\n />\n );\n}\n"],"mappings":"oSAUA,SAAwB,GAAwB,CAC9C,GAAM,CAAE,EAAG,GAAO,GAAgB,CAC5B,GAAK,EAAW,IAAgC,EAAG,sBAAsB,IAAK,EAAS,CAIvF,EAAc,EADI,GACU,CAAgB,aAAa,EAAI,KAC7D,CAAE,QAAO,YAAa,GAAU,CAChC,CAAE,kBAAiB,qBAAsB,GAAgB,CAU/D,EAAsB,CACpB,0BAAA,EAAA,EAAA,cATsC,CAAE,WAAoD,CAC5F,EAAS,EAAM,EACd,CAAC,EAAS,CAOe,CAC1B,iCAAA,EAAA,EAAA,iBANiD,CACjD,GAAmB,EAClB,CAAC,EAAkB,CAIa,CAClC,CAAC,CAMF,IAAM,EAAU,EAAc,GAAY,CAAC,eAAe,CAKpD,EAAkB,GAAA,EAAA,EAAA,aAHhB,GAAS,OAAO,OAAO,YAAY,EAAI,KAC7C,CAAC,EAAQ,CAE2B,CAAY,CAIlD,OACE,EAAA,EAAA,KAAC,EAAD,CACW,QALG,GAAmB,EAAE,CAMtB,UALG,IAAoB,IAAA,GAM3B,QACU,kBACJ,cACb,aAAc,CACZ,UAAW,EAAE,YAAY,CACzB,gBAAiB,EAAE,kBAAkB,CACrC,WAAY,EAAE,aAAa,CAC3B,QAAS,EAAE,UAAU,CACtB,CACc,gBACN,UACT,CAAA"}