@techzyapp/ui-library 1.0.21 → 1.0.23

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 (335) hide show
  1. package/dist/{AdminRoot-BDRLuMX6.cjs → AdminRoot-C7Idu7FQ.cjs} +2 -2
  2. package/dist/AdminRoot-C7Idu7FQ.cjs.map +1 -0
  3. package/dist/{AdminRoot-DvF0js0q.js → AdminRoot-aDy6rNqI.js} +4 -4
  4. package/dist/AdminRoot-aDy6rNqI.js.map +1 -0
  5. package/dist/{Alert-CwoRkKq4.cjs → Alert-Cl1zxmX9.cjs} +2 -2
  6. package/dist/{Alert-CwoRkKq4.cjs.map → Alert-Cl1zxmX9.cjs.map} +1 -1
  7. package/dist/{Alert-DPYmdaWs.js → Alert-D6VL2C-E.js} +3 -3
  8. package/dist/{Alert-DPYmdaWs.js.map → Alert-D6VL2C-E.js.map} +1 -1
  9. package/dist/{Breadcrumbs-CknDBLMw.cjs → Breadcrumbs-BnFW4LgK.cjs} +2 -2
  10. package/dist/{Breadcrumbs-CknDBLMw.cjs.map → Breadcrumbs-BnFW4LgK.cjs.map} +1 -1
  11. package/dist/{Breadcrumbs-l0PlUpQ4.js → Breadcrumbs-CicfjfIu.js} +3 -3
  12. package/dist/{Breadcrumbs-l0PlUpQ4.js.map → Breadcrumbs-CicfjfIu.js.map} +1 -1
  13. package/dist/{Button-RljTGqHl.js → Button-Cfxd7qhd.js} +2 -2
  14. package/dist/{Button-RljTGqHl.js.map → Button-Cfxd7qhd.js.map} +1 -1
  15. package/dist/{Button-BdihbLYJ.cjs → Button-ZplrHYKw.cjs} +2 -2
  16. package/dist/{Button-BdihbLYJ.cjs.map → Button-ZplrHYKw.cjs.map} +1 -1
  17. package/dist/{Calendar-CKCikOQL.js → Calendar-DTxCT-ki.js} +3 -3
  18. package/dist/{Calendar-CKCikOQL.js.map → Calendar-DTxCT-ki.js.map} +1 -1
  19. package/dist/{Calendar-DVg1uQuj.cjs → Calendar-S9vyp-qv.cjs} +2 -2
  20. package/dist/{Calendar-DVg1uQuj.cjs.map → Calendar-S9vyp-qv.cjs.map} +1 -1
  21. package/dist/{Card-BYFuYD-a.cjs → Card-BeE2ohcn.cjs} +2 -2
  22. package/dist/{Card-BYFuYD-a.cjs.map → Card-BeE2ohcn.cjs.map} +1 -1
  23. package/dist/{Card-B0bYi4g2.js → Card-eXJfA4rU.js} +2 -2
  24. package/dist/{Card-B0bYi4g2.js.map → Card-eXJfA4rU.js.map} +1 -1
  25. package/dist/{Chip-CdKUtUGE.cjs → Chip-B4XERWb_.cjs} +2 -2
  26. package/dist/{Chip-CdKUtUGE.cjs.map → Chip-B4XERWb_.cjs.map} +1 -1
  27. package/dist/{Chip-BiqfnRUi.js → Chip-BOXXdzap.js} +2 -2
  28. package/dist/{Chip-BiqfnRUi.js.map → Chip-BOXXdzap.js.map} +1 -1
  29. package/dist/{CodeBlock-CAAggVXS.cjs → CodeBlock-C7_A6CTT.cjs} +2 -2
  30. package/dist/{CodeBlock-CAAggVXS.cjs.map → CodeBlock-C7_A6CTT.cjs.map} +1 -1
  31. package/dist/{CodeBlock-BX_0tpk3.js → CodeBlock-D_PRiWMq.js} +3 -3
  32. package/dist/{CodeBlock-BX_0tpk3.js.map → CodeBlock-D_PRiWMq.js.map} +1 -1
  33. package/dist/{ColorPicker-BCSaT1A-.cjs → ColorPicker-ClVpWf77.cjs} +2 -2
  34. package/dist/{ColorPicker-BCSaT1A-.cjs.map → ColorPicker-ClVpWf77.cjs.map} +1 -1
  35. package/dist/{ColorPicker-DhSlvwNj.js → ColorPicker-DAjs7PmR.js} +3 -3
  36. package/dist/{ColorPicker-DhSlvwNj.js.map → ColorPicker-DAjs7PmR.js.map} +1 -1
  37. package/dist/{ColorPickerPanel-D4t3b9bB.js → ColorPickerPanel-BGzm2had.js} +2 -2
  38. package/dist/{ColorPickerPanel-D4t3b9bB.js.map → ColorPickerPanel-BGzm2had.js.map} +1 -1
  39. package/dist/{ColorPickerPanel-BOGYXXF1.cjs → ColorPickerPanel-Dk6bI0Xy.cjs} +2 -2
  40. package/dist/{ColorPickerPanel-BOGYXXF1.cjs.map → ColorPickerPanel-Dk6bI0Xy.cjs.map} +1 -1
  41. package/dist/{ConfigProvider-DT0yrgmd.js → ConfigProvider-Blhvj6UQ.js} +2 -2
  42. package/dist/ConfigProvider-Blhvj6UQ.js.map +1 -0
  43. package/dist/{ConfigProvider-C7DUWHrb.cjs → ConfigProvider-CUG8Mfy2.cjs} +2 -2
  44. package/dist/ConfigProvider-CUG8Mfy2.cjs.map +1 -0
  45. package/dist/{CopyButton-BEY1gJzK.js → CopyButton-Bv7L4xJf.js} +3 -3
  46. package/dist/{CopyButton-BEY1gJzK.js.map → CopyButton-Bv7L4xJf.js.map} +1 -1
  47. package/dist/{CopyButton-3585thVM.cjs → CopyButton-COF3hIV-.cjs} +2 -2
  48. package/dist/{CopyButton-3585thVM.cjs.map → CopyButton-COF3hIV-.cjs.map} +1 -1
  49. package/dist/{DatePicker-CEFGgXLF.js → DatePicker-DZfOvxUR.js} +4 -4
  50. package/dist/{DatePicker-CEFGgXLF.js.map → DatePicker-DZfOvxUR.js.map} +1 -1
  51. package/dist/{DatePicker-Dyj2halw.cjs → DatePicker-kA-xn5ET.cjs} +2 -2
  52. package/dist/{DatePicker-Dyj2halw.cjs.map → DatePicker-kA-xn5ET.cjs.map} +1 -1
  53. package/dist/{DateTimePicker-hmYBEuUM.js → DateTimePicker-BxBXhSN_.js} +7 -7
  54. package/dist/{DateTimePicker-hmYBEuUM.js.map → DateTimePicker-BxBXhSN_.js.map} +1 -1
  55. package/dist/{DateTimePicker-CjX4-8PP.cjs → DateTimePicker-DEGmn5UX.cjs} +2 -2
  56. package/dist/{DateTimePicker-CjX4-8PP.cjs.map → DateTimePicker-DEGmn5UX.cjs.map} +1 -1
  57. package/dist/{EmptyState-Bj-vX_UV.cjs → EmptyState-DlX-BLLI.cjs} +2 -2
  58. package/dist/{EmptyState-Bj-vX_UV.cjs.map → EmptyState-DlX-BLLI.cjs.map} +1 -1
  59. package/dist/{EmptyState-DJDNLKT7.js → EmptyState-Du4vA3bC.js} +2 -2
  60. package/dist/{EmptyState-DJDNLKT7.js.map → EmptyState-Du4vA3bC.js.map} +1 -1
  61. package/dist/{FileCard-C9Ncifnu.js → FileCard-juQ1fWbG.js} +3 -3
  62. package/dist/{FileCard-C9Ncifnu.js.map → FileCard-juQ1fWbG.js.map} +1 -1
  63. package/dist/{FileCard-Dr5-z1R3.cjs → FileCard-zyCpTrJ-.cjs} +2 -2
  64. package/dist/{FileCard-Dr5-z1R3.cjs.map → FileCard-zyCpTrJ-.cjs.map} +1 -1
  65. package/dist/{FileUploader-XFmBNkA0.js → FileUploader-DL9atihI.js} +5 -5
  66. package/dist/{FileUploader-XFmBNkA0.js.map → FileUploader-DL9atihI.js.map} +1 -1
  67. package/dist/{FileUploader-DeyZENqq.cjs → FileUploader-DOe3CyJB.cjs} +2 -2
  68. package/dist/{FileUploader-DeyZENqq.cjs.map → FileUploader-DOe3CyJB.cjs.map} +1 -1
  69. package/dist/{Flag-Bs0xNP-P.js → Flag-BxRrjCTB.js} +2 -2
  70. package/dist/{Flag-Bs0xNP-P.js.map → Flag-BxRrjCTB.js.map} +1 -1
  71. package/dist/{Flag-Bxnx26DM.cjs → Flag-DFKHYnqk.cjs} +2 -2
  72. package/dist/{Flag-Bxnx26DM.cjs.map → Flag-DFKHYnqk.cjs.map} +1 -1
  73. package/dist/{FullscreenToggle-DMlp05UN.js → FullscreenToggle-BMCNsyzb.js} +3 -3
  74. package/dist/{FullscreenToggle-DMlp05UN.js.map → FullscreenToggle-BMCNsyzb.js.map} +1 -1
  75. package/dist/{FullscreenToggle-BncatGKj.cjs → FullscreenToggle-BNK7RcRq.cjs} +2 -2
  76. package/dist/{FullscreenToggle-BncatGKj.cjs.map → FullscreenToggle-BNK7RcRq.cjs.map} +1 -1
  77. package/dist/{IconButton-Lv0sDDR9.cjs → IconButton-B9eVM18U.cjs} +2 -2
  78. package/dist/{IconButton-Lv0sDDR9.cjs.map → IconButton-B9eVM18U.cjs.map} +1 -1
  79. package/dist/{IconButton-DXMmtuLA.js → IconButton-CfvsE_p3.js} +2 -2
  80. package/dist/{IconButton-DXMmtuLA.js.map → IconButton-CfvsE_p3.js.map} +1 -1
  81. package/dist/Link-BQlvsu9V.js +48 -0
  82. package/dist/Link-BQlvsu9V.js.map +1 -0
  83. package/dist/Link-GZT51mKx.cjs +2 -0
  84. package/dist/Link-GZT51mKx.cjs.map +1 -0
  85. package/dist/{Loader-53HFNMVX.cjs → Loader-CxLrhAz9.cjs} +2 -2
  86. package/dist/{Loader-53HFNMVX.cjs.map → Loader-CxLrhAz9.cjs.map} +1 -1
  87. package/dist/{Loader-WsjQFl4p.js → Loader-DwmyJFwG.js} +2 -2
  88. package/dist/{Loader-WsjQFl4p.js.map → Loader-DwmyJFwG.js.map} +1 -1
  89. package/dist/{Modal-DBYcoCbJ.js → Modal-Cx0JEQ-j.js} +3 -3
  90. package/dist/{Modal-DBYcoCbJ.js.map → Modal-Cx0JEQ-j.js.map} +1 -1
  91. package/dist/{Modal-V6eyGSzW.cjs → Modal-DXZdMmJh.cjs} +2 -2
  92. package/dist/{Modal-V6eyGSzW.cjs.map → Modal-DXZdMmJh.cjs.map} +1 -1
  93. package/dist/{MultiSelect-DS2DRpaP.cjs → MultiSelect-DfhyGxDU.cjs} +2 -2
  94. package/dist/{MultiSelect-DS2DRpaP.cjs.map → MultiSelect-DfhyGxDU.cjs.map} +1 -1
  95. package/dist/{MultiSelect-BsYPr3LD.js → MultiSelect-yGlvweEq.js} +4 -4
  96. package/dist/{MultiSelect-BsYPr3LD.js.map → MultiSelect-yGlvweEq.js.map} +1 -1
  97. package/dist/{NumberField-DC3TdGTt.cjs → NumberField-B7yPXIw_.cjs} +2 -2
  98. package/dist/{NumberField-DC3TdGTt.cjs.map → NumberField-B7yPXIw_.cjs.map} +1 -1
  99. package/dist/{NumberField-mFb9pKCx.js → NumberField-cAjPU1P5.js} +3 -3
  100. package/dist/{NumberField-mFb9pKCx.js.map → NumberField-cAjPU1P5.js.map} +1 -1
  101. package/dist/{OtpField-BYj9SDHb.cjs → OtpField-BujZAy2A.cjs} +2 -2
  102. package/dist/{OtpField-BYj9SDHb.cjs.map → OtpField-BujZAy2A.cjs.map} +1 -1
  103. package/dist/{OtpField-1ullIIZQ.js → OtpField-D0eTOLtg.js} +2 -2
  104. package/dist/{OtpField-1ullIIZQ.js.map → OtpField-D0eTOLtg.js.map} +1 -1
  105. package/dist/{PageLayout-pYL43wI9.cjs → PageLayout-BSHyKoQ4.cjs} +2 -2
  106. package/dist/{PageLayout-pYL43wI9.cjs.map → PageLayout-BSHyKoQ4.cjs.map} +1 -1
  107. package/dist/{PageLayout-qf0H_EmS.js → PageLayout-C9Je7kfF.js} +2 -2
  108. package/dist/{PageLayout-qf0H_EmS.js.map → PageLayout-C9Je7kfF.js.map} +1 -1
  109. package/dist/{PageNotFound-YGVMVvyG.js → PageNotFound-CUN2OntP.js} +5 -5
  110. package/dist/{PageNotFound-YGVMVvyG.js.map → PageNotFound-CUN2OntP.js.map} +1 -1
  111. package/dist/{PageNotFound-D1795gJ7.cjs → PageNotFound-voB9ylPF.cjs} +2 -2
  112. package/dist/{PageNotFound-D1795gJ7.cjs.map → PageNotFound-voB9ylPF.cjs.map} +1 -1
  113. package/dist/{Pagination-WJq_7QNi.cjs → Pagination-BUGaylZa.cjs} +2 -2
  114. package/dist/{Pagination-WJq_7QNi.cjs.map → Pagination-BUGaylZa.cjs.map} +1 -1
  115. package/dist/{Pagination-BTvUJiee.js → Pagination-BaVHgIWT.js} +2 -2
  116. package/dist/{Pagination-BTvUJiee.js.map → Pagination-BaVHgIWT.js.map} +1 -1
  117. package/dist/QrCode-Bcj9_Emc.js +70 -0
  118. package/dist/QrCode-Bcj9_Emc.js.map +1 -0
  119. package/dist/QrCode-DfDfGhG-.cjs +2 -0
  120. package/dist/QrCode-DfDfGhG-.cjs.map +1 -0
  121. package/dist/{RemoveDialog-BSQ6EMW-.js → RemoveDialog-BpL2-gnz.js} +4 -4
  122. package/dist/{RemoveDialog-BSQ6EMW-.js.map → RemoveDialog-BpL2-gnz.js.map} +1 -1
  123. package/dist/{RemoveDialog-BhcwsY0q.cjs → RemoveDialog-DGt_72we.cjs} +2 -2
  124. package/dist/{RemoveDialog-BhcwsY0q.cjs.map → RemoveDialog-DGt_72we.cjs.map} +1 -1
  125. package/dist/{RichTextEditor-Bc1fhvzn.cjs → RichTextEditor-BuoywqBu.cjs} +2 -2
  126. package/dist/{RichTextEditor-Bc1fhvzn.cjs.map → RichTextEditor-BuoywqBu.cjs.map} +1 -1
  127. package/dist/{RichTextEditor-CaGPtwXe.js → RichTextEditor-C_6pzqYY.js} +7 -7
  128. package/dist/{RichTextEditor-CaGPtwXe.js.map → RichTextEditor-C_6pzqYY.js.map} +1 -1
  129. package/dist/RootLayout-1am1CwPQ.cjs +2 -0
  130. package/dist/RootLayout-1am1CwPQ.cjs.map +1 -0
  131. package/dist/RootLayout-x7qWzXPc.js +479 -0
  132. package/dist/RootLayout-x7qWzXPc.js.map +1 -0
  133. package/dist/{Select-Cx1Yl8nq.cjs → Select-CVy5BnKe.cjs} +2 -2
  134. package/dist/{Select-Cx1Yl8nq.cjs.map → Select-CVy5BnKe.cjs.map} +1 -1
  135. package/dist/{Select-vKZzS9K4.js → Select-ChT-6_bM.js} +3 -3
  136. package/dist/{Select-vKZzS9K4.js.map → Select-ChT-6_bM.js.map} +1 -1
  137. package/dist/Sidebar-D2MsR33k.cjs +2 -0
  138. package/dist/Sidebar-D2MsR33k.cjs.map +1 -0
  139. package/dist/Sidebar-ZA1wxCez.js +553 -0
  140. package/dist/Sidebar-ZA1wxCez.js.map +1 -0
  141. package/dist/{SpeedDial-D6sO-9ES.cjs → SpeedDial-B9JTNNUU.cjs} +2 -2
  142. package/dist/{SpeedDial-D6sO-9ES.cjs.map → SpeedDial-B9JTNNUU.cjs.map} +1 -1
  143. package/dist/{SpeedDial-Bb0ioXaO.js → SpeedDial-DUYQMDCY.js} +2 -2
  144. package/dist/{SpeedDial-Bb0ioXaO.js.map → SpeedDial-DUYQMDCY.js.map} +1 -1
  145. package/dist/{Stepper-CVY8NJEI.cjs → Stepper-BaC934rb.cjs} +2 -2
  146. package/dist/{Stepper-CVY8NJEI.cjs.map → Stepper-BaC934rb.cjs.map} +1 -1
  147. package/dist/{Stepper-BaEOUnYe.js → Stepper-D89I17pC.js} +2 -2
  148. package/dist/{Stepper-BaEOUnYe.js.map → Stepper-D89I17pC.js.map} +1 -1
  149. package/dist/{Table-wn-B7iLj.js → Table-CdIQ5Wfh.js} +15 -15
  150. package/dist/{Table-wn-B7iLj.js.map → Table-CdIQ5Wfh.js.map} +1 -1
  151. package/dist/{Table-AQ7yJhtW.cjs → Table-DvgBWTLx.cjs} +2 -2
  152. package/dist/{Table-AQ7yJhtW.cjs.map → Table-DvgBWTLx.cjs.map} +1 -1
  153. package/dist/{Tabs-DJMfAUni.js → Tabs-8-klG-y-.js} +2 -2
  154. package/dist/{Tabs-DJMfAUni.js.map → Tabs-8-klG-y-.js.map} +1 -1
  155. package/dist/{Tabs-BtcJ2jBl.cjs → Tabs-CejCwV3O.cjs} +2 -2
  156. package/dist/{Tabs-BtcJ2jBl.cjs.map → Tabs-CejCwV3O.cjs.map} +1 -1
  157. package/dist/{TagsField-Bvh6Fm5Y.js → TagsField-BQLqUckB.js} +4 -4
  158. package/dist/{TagsField-Bvh6Fm5Y.js.map → TagsField-BQLqUckB.js.map} +1 -1
  159. package/dist/{TagsField-4x3RmGwt.cjs → TagsField-BSAd4eUr.cjs} +2 -2
  160. package/dist/{TagsField-4x3RmGwt.cjs.map → TagsField-BSAd4eUr.cjs.map} +1 -1
  161. package/dist/{TextField-DcdwUA9d.js → TextField-B4YtjNUs.js} +3 -3
  162. package/dist/{TextField-DcdwUA9d.js.map → TextField-B4YtjNUs.js.map} +1 -1
  163. package/dist/{TextField-DNqnpAWB.cjs → TextField-DzYGA_St.cjs} +2 -2
  164. package/dist/{TextField-DNqnpAWB.cjs.map → TextField-DzYGA_St.cjs.map} +1 -1
  165. package/dist/{ThemeToggle-BVQmSMsj.js → ThemeToggle-B4_zRHJY.js} +3 -3
  166. package/dist/{ThemeToggle-BVQmSMsj.js.map → ThemeToggle-B4_zRHJY.js.map} +1 -1
  167. package/dist/{ThemeToggle-isboxfZk.cjs → ThemeToggle-BKk0eFiB.cjs} +2 -2
  168. package/dist/{ThemeToggle-isboxfZk.cjs.map → ThemeToggle-BKk0eFiB.cjs.map} +1 -1
  169. package/dist/{TimeColumns-DxFjjtc7.cjs → TimeColumns-BAzRrkqY.cjs} +2 -2
  170. package/dist/{TimeColumns-DxFjjtc7.cjs.map → TimeColumns-BAzRrkqY.cjs.map} +1 -1
  171. package/dist/{TimeColumns-CFy_PynH.js → TimeColumns-CAPyli9V.js} +2 -2
  172. package/dist/{TimeColumns-CFy_PynH.js.map → TimeColumns-CAPyli9V.js.map} +1 -1
  173. package/dist/{TimePicker-v1yA7Igl.cjs → TimePicker-BUnXYR5g.cjs} +2 -2
  174. package/dist/{TimePicker-v1yA7Igl.cjs.map → TimePicker-BUnXYR5g.cjs.map} +1 -1
  175. package/dist/{TimePicker-ZO7jOJVa.js → TimePicker-BebBSlQF.js} +5 -5
  176. package/dist/{TimePicker-ZO7jOJVa.js.map → TimePicker-BebBSlQF.js.map} +1 -1
  177. package/dist/{Toaster-Qnsq3guQ.cjs → Toaster-B2rO4BkG.cjs} +2 -2
  178. package/dist/{Toaster-Qnsq3guQ.cjs.map → Toaster-B2rO4BkG.cjs.map} +1 -1
  179. package/dist/{Toaster-C6UK_2TB.js → Toaster-ywqAKP8s.js} +2 -2
  180. package/dist/{Toaster-C6UK_2TB.js.map → Toaster-ywqAKP8s.js.map} +1 -1
  181. package/dist/{TranslatedFields-Bo5rZ7so.js → TranslatedFields-C-wlh51E.js} +5 -5
  182. package/dist/{TranslatedFields-Bo5rZ7so.js.map → TranslatedFields-C-wlh51E.js.map} +1 -1
  183. package/dist/{TranslatedFields-CLMvRpJi.cjs → TranslatedFields-DQQUb0RD.cjs} +2 -2
  184. package/dist/{TranslatedFields-CLMvRpJi.cjs.map → TranslatedFields-DQQUb0RD.cjs.map} +1 -1
  185. package/dist/{UserCard-CIjZz5xd.cjs → UserCard-Be1kl0TZ.cjs} +2 -2
  186. package/dist/{UserCard-CIjZz5xd.cjs.map → UserCard-Be1kl0TZ.cjs.map} +1 -1
  187. package/dist/{UserCard-454Kc7JS.js → UserCard-BqWt0S-c.js} +3 -3
  188. package/dist/{UserCard-454Kc7JS.js.map → UserCard-BqWt0S-c.js.map} +1 -1
  189. package/dist/app/AdminRoot.d.cts +4 -1
  190. package/dist/app/AdminRoot.d.ts +4 -1
  191. package/dist/components/Alert/index.cjs +1 -1
  192. package/dist/components/Alert/index.js +1 -1
  193. package/dist/components/Breadcrumbs/index.cjs +1 -1
  194. package/dist/components/Breadcrumbs/index.js +1 -1
  195. package/dist/components/Button/index.cjs +1 -1
  196. package/dist/components/Button/index.js +1 -1
  197. package/dist/components/Card/index.cjs +1 -1
  198. package/dist/components/Card/index.js +1 -1
  199. package/dist/components/Chip/index.cjs +1 -1
  200. package/dist/components/Chip/index.js +1 -1
  201. package/dist/components/CodeBlock/index.cjs +1 -1
  202. package/dist/components/CodeBlock/index.js +1 -1
  203. package/dist/components/ColorPicker/index.cjs +1 -1
  204. package/dist/components/ColorPicker/index.js +1 -1
  205. package/dist/components/CopyButton/index.cjs +1 -1
  206. package/dist/components/CopyButton/index.js +1 -1
  207. package/dist/components/DatePicker/index.cjs +1 -1
  208. package/dist/components/DatePicker/index.js +1 -1
  209. package/dist/components/DateTimePicker/index.cjs +1 -1
  210. package/dist/components/DateTimePicker/index.js +1 -1
  211. package/dist/components/EmptyState/index.cjs +1 -1
  212. package/dist/components/EmptyState/index.js +1 -1
  213. package/dist/components/FileCard/index.cjs +1 -1
  214. package/dist/components/FileCard/index.js +1 -1
  215. package/dist/components/FileUploader/index.cjs +1 -1
  216. package/dist/components/FileUploader/index.js +1 -1
  217. package/dist/components/Flag/index.cjs +1 -1
  218. package/dist/components/Flag/index.js +1 -1
  219. package/dist/components/FullscreenToggle/index.cjs +1 -1
  220. package/dist/components/FullscreenToggle/index.js +1 -1
  221. package/dist/components/IconButton/index.cjs +1 -1
  222. package/dist/components/IconButton/index.js +1 -1
  223. package/dist/components/Link/Link.d.cts +44 -0
  224. package/dist/components/Link/Link.d.ts +44 -0
  225. package/dist/components/Link/index.cjs +2 -0
  226. package/dist/components/Link/index.cjs.map +1 -0
  227. package/dist/components/Link/index.d.cts +3 -0
  228. package/dist/components/Link/index.d.ts +3 -0
  229. package/dist/components/Link/index.js +6 -0
  230. package/dist/components/Link/index.js.map +1 -0
  231. package/dist/components/Loader/index.cjs +1 -1
  232. package/dist/components/Loader/index.js +1 -1
  233. package/dist/components/Modal/index.cjs +1 -1
  234. package/dist/components/Modal/index.js +1 -1
  235. package/dist/components/MultiSelect/index.cjs +1 -1
  236. package/dist/components/MultiSelect/index.js +1 -1
  237. package/dist/components/NumberField/index.cjs +1 -1
  238. package/dist/components/NumberField/index.js +1 -1
  239. package/dist/components/OtpField/index.cjs +1 -1
  240. package/dist/components/OtpField/index.js +1 -1
  241. package/dist/components/PageLayout/index.cjs +1 -1
  242. package/dist/components/PageLayout/index.js +1 -1
  243. package/dist/components/PageNotFound/index.cjs +1 -1
  244. package/dist/components/PageNotFound/index.js +1 -1
  245. package/dist/components/Pagination/index.cjs +1 -1
  246. package/dist/components/Pagination/index.js +1 -1
  247. package/dist/components/QrCode/QrCode.d.cts +46 -0
  248. package/dist/components/QrCode/QrCode.d.ts +46 -0
  249. package/dist/components/QrCode/index.cjs +2 -0
  250. package/dist/components/QrCode/index.cjs.map +1 -0
  251. package/dist/components/QrCode/index.d.cts +2 -0
  252. package/dist/components/QrCode/index.d.ts +2 -0
  253. package/dist/components/QrCode/index.js +6 -0
  254. package/dist/components/QrCode/index.js.map +1 -0
  255. package/dist/components/RemoveDialog/index.cjs +1 -1
  256. package/dist/components/RemoveDialog/index.js +1 -1
  257. package/dist/components/RichTextEditor/index.cjs +1 -1
  258. package/dist/components/RichTextEditor/index.js +1 -1
  259. package/dist/components/RootLayout/ActionSet.d.cts +27 -0
  260. package/dist/components/RootLayout/ActionSet.d.ts +27 -0
  261. package/dist/components/RootLayout/index.cjs +1 -1
  262. package/dist/components/RootLayout/index.js +1 -1
  263. package/dist/components/Select/index.cjs +1 -1
  264. package/dist/components/Select/index.js +1 -1
  265. package/dist/components/Sidebar/Sidebar.d.cts +55 -3
  266. package/dist/components/Sidebar/Sidebar.d.ts +55 -3
  267. package/dist/components/Sidebar/index.cjs +1 -1
  268. package/dist/components/Sidebar/index.d.cts +1 -0
  269. package/dist/components/Sidebar/index.d.ts +1 -0
  270. package/dist/components/Sidebar/index.js +1 -1
  271. package/dist/components/SpeedDial/index.cjs +1 -1
  272. package/dist/components/SpeedDial/index.js +1 -1
  273. package/dist/components/Stepper/index.cjs +1 -1
  274. package/dist/components/Stepper/index.js +1 -1
  275. package/dist/components/Table/index.cjs +1 -1
  276. package/dist/components/Table/index.js +1 -1
  277. package/dist/components/Tabs/index.cjs +1 -1
  278. package/dist/components/Tabs/index.js +1 -1
  279. package/dist/components/TagsField/index.cjs +1 -1
  280. package/dist/components/TagsField/index.js +1 -1
  281. package/dist/components/TextField/index.cjs +1 -1
  282. package/dist/components/TextField/index.js +1 -1
  283. package/dist/components/ThemeToggle/index.cjs +1 -1
  284. package/dist/components/ThemeToggle/index.js +1 -1
  285. package/dist/components/TimePicker/index.cjs +1 -1
  286. package/dist/components/TimePicker/index.js +1 -1
  287. package/dist/components/Toast/index.cjs +1 -1
  288. package/dist/components/Toast/index.js +1 -1
  289. package/dist/components/TranslatedFields/index.cjs +1 -1
  290. package/dist/components/TranslatedFields/index.js +1 -1
  291. package/dist/components/UserCard/index.cjs +1 -1
  292. package/dist/components/UserCard/index.js +1 -1
  293. package/dist/components/index.d.cts +2 -0
  294. package/dist/components/index.d.ts +2 -0
  295. package/dist/entries/app.cjs +1 -1
  296. package/dist/entries/app.js +1 -1
  297. package/dist/entries/components.cjs +1 -1
  298. package/dist/entries/components.js +112 -108
  299. package/dist/entries/components.js.map +1 -1
  300. package/dist/entries/i18n.cjs +1 -1
  301. package/dist/entries/i18n.js +2 -2
  302. package/dist/entries/theme.cjs +1 -1
  303. package/dist/entries/theme.d.cts +1 -1
  304. package/dist/entries/theme.d.ts +1 -1
  305. package/dist/entries/theme.js +1 -1
  306. package/dist/i18n/messages.d.cts +1 -0
  307. package/dist/i18n/messages.d.ts +1 -0
  308. package/dist/index.cjs +1 -1
  309. package/dist/index.css +1 -1
  310. package/dist/index.js +115 -111
  311. package/dist/index.js.map +1 -1
  312. package/dist/{messages-CGHhwf6F.js → messages-CL8uoIRj.js} +8 -1
  313. package/dist/messages-CL8uoIRj.js.map +1 -0
  314. package/dist/messages-Dvn_tEp0.cjs +36 -0
  315. package/dist/messages-Dvn_tEp0.cjs.map +1 -0
  316. package/dist/theme/ConfigProvider.d.cts +22 -1
  317. package/dist/theme/ConfigProvider.d.ts +22 -1
  318. package/dist/theme/index.d.cts +1 -1
  319. package/dist/theme/index.d.ts +1 -1
  320. package/package.json +6 -1
  321. package/dist/AdminRoot-BDRLuMX6.cjs.map +0 -1
  322. package/dist/AdminRoot-DvF0js0q.js.map +0 -1
  323. package/dist/ConfigProvider-C7DUWHrb.cjs.map +0 -1
  324. package/dist/ConfigProvider-DT0yrgmd.js.map +0 -1
  325. package/dist/RootLayout-BNwHsuhC.js +0 -422
  326. package/dist/RootLayout-BNwHsuhC.js.map +0 -1
  327. package/dist/RootLayout-CB-3FgOp.cjs +0 -2
  328. package/dist/RootLayout-CB-3FgOp.cjs.map +0 -1
  329. package/dist/Sidebar-CJ7DtOqb.js +0 -513
  330. package/dist/Sidebar-CJ7DtOqb.js.map +0 -1
  331. package/dist/Sidebar-Cv95DJxZ.cjs +0 -2
  332. package/dist/Sidebar-Cv95DJxZ.cjs.map +0 -1
  333. package/dist/messages-CGHhwf6F.js.map +0 -1
  334. package/dist/messages-DZJyiaf9.cjs +0 -36
  335. package/dist/messages-DZJyiaf9.cjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages-Dvn_tEp0.cjs","sources":["../src/i18n/locales/en.ts","../src/i18n/locales/ka.ts","../src/i18n/locales/es.ts","../src/i18n/locales/de.ts","../src/i18n/locales/it.ts","../src/i18n/locales/fr.ts","../src/i18n/locales/ru.ts","../src/i18n/messages.ts"],"sourcesContent":["import type { Messages } from '../messages'\n\n/**\n * English — the **complete** baseline every other language falls back to, per key. When you add a new\n * key to the `Messages` interface (in `../messages`), fill it here first; the type makes this file the\n * one catalog that must stay exhaustive (the others are `Partial` and fall back here).\n */\nexport const EN_MESSAGES: Messages = {\n 'common.close': 'Close',\n 'common.cancel': 'Cancel',\n 'common.confirm': 'Confirm',\n 'common.delete': 'Delete',\n 'common.remove': 'Remove',\n 'common.loading': 'Loading…',\n 'common.clear': 'Clear',\n 'common.apply': 'Apply',\n 'common.search': 'Search…',\n 'common.all': 'All',\n 'common.any': 'Any',\n 'common.yes': 'Yes',\n 'common.no': 'No',\n 'common.save': 'Save',\n 'common.insert': 'Insert',\n 'common.update': 'Update',\n 'common.done': 'Done',\n 'common.min': 'Min',\n 'common.max': 'Max',\n 'common.from': 'From',\n 'common.to': 'To',\n 'select.placeholder': 'Select…',\n 'select.noOptions': 'No options',\n 'select.clear': 'Clear selection',\n 'multiSelect.clearAll': 'Clear all',\n 'pagination.previous': 'Go to previous page',\n 'pagination.next': 'Go to next page',\n 'pagination.first': 'Go to first page',\n 'pagination.last': 'Go to last page',\n 'pagination.page': 'Go to page {page}',\n 'emptyState.title': 'No Results Found',\n 'notFound.title': 'Page Not Found',\n 'notFound.description': \"The page you're looking for doesn't exist or may have moved.\",\n 'notFound.action': 'Back to Home',\n 'userCard.signOut': 'Sign out',\n 'userCard.welcome': 'Welcome',\n 'textField.fieldAction': 'Field action',\n 'textField.showPassword': 'Show password',\n 'textField.hidePassword': 'Hide password',\n 'textField.capsLock': 'Caps Lock is on',\n 'textField.strengthWeak': 'Weak',\n 'textField.strengthMedium': 'Medium',\n 'textField.strengthStrong': 'Strong',\n 'numberField.decrease': 'Decrease',\n 'numberField.increase': 'Increase',\n 'otpField.digit': 'Digit {index} of {total}',\n 'breadcrumbs.label': 'Breadcrumb',\n 'breadcrumbs.home': 'Home',\n 'pageTitle.back': 'Back',\n 'pageActions.label': 'Actions',\n 'themeToggle.label': 'Toggle color theme',\n 'fullscreenToggle.label': 'Toggle fullscreen',\n 'loader.label': 'Loading',\n 'tagsField.add': 'Add tag',\n 'removeDialog.title': 'Remove',\n 'removeDialog.message': 'Are you sure you want to delete?',\n 'colorPicker.pick': 'Pick a color',\n 'colorPicker.value': 'Color value',\n 'colorPicker.noColor': 'No color',\n 'colorPicker.saturation': 'Saturation and brightness',\n 'colorPicker.hue': 'Hue',\n 'colorPicker.opacity': 'Opacity',\n 'datePicker.clear': 'Clear date',\n 'datePicker.open': 'Open calendar',\n 'calendar.prevMonth': 'Previous month',\n 'calendar.nextMonth': 'Next month',\n 'timePicker.clear': 'Clear time',\n 'timePicker.open': 'Open time picker',\n 'dateTimePicker.clear': 'Clear value',\n 'dateTimePicker.open': 'Open date and time picker',\n 'dateTimePicker.label': 'Date and time',\n 'dateTimePicker.dateTab': 'Date',\n 'dateTimePicker.timeTab': 'Time',\n 'table.export': 'Export',\n 'table.sendOnEmail': 'Send On Email',\n 'table.sort': 'Sort',\n 'table.sortBy': 'Sort By',\n 'table.filters': 'Filters',\n 'table.filtersDescription': 'Narrow the table by the fields below.',\n 'table.dragHandle': 'Drag to reorder',\n 'table.range': '{from}–{to} of {total}',\n 'table.rowsPerPage': 'Rows per page',\n 'calendar.month0': 'January',\n 'calendar.month1': 'February',\n 'calendar.month2': 'March',\n 'calendar.month3': 'April',\n 'calendar.month4': 'May',\n 'calendar.month5': 'June',\n 'calendar.month6': 'July',\n 'calendar.month7': 'August',\n 'calendar.month8': 'September',\n 'calendar.month9': 'October',\n 'calendar.month10': 'November',\n 'calendar.month11': 'December',\n 'calendar.weekday0': 'Su',\n 'calendar.weekday1': 'Mo',\n 'calendar.weekday2': 'Tu',\n 'calendar.weekday3': 'We',\n 'calendar.weekday4': 'Th',\n 'calendar.weekday5': 'Fr',\n 'calendar.weekday6': 'Sa',\n 'calendar.selectYear': 'Select year',\n 'time.hour': 'Hour',\n 'time.minute': 'Minute',\n 'time.second': 'Second',\n 'time.meridiem': 'AM/PM',\n 'time.am': 'AM',\n 'time.pm': 'PM',\n 'settings.themeTitle': 'Theme',\n 'settings.themeDesc': 'Switch between the light and dark theme.',\n 'settings.light': 'Light',\n 'settings.lightDesc': 'Bright theme',\n 'settings.dark': 'Dark',\n 'settings.darkDesc': 'Dim theme',\n 'settings.languageDesc': 'Choose the admin panel language — saved for next time.',\n 'settings.accentTitle': 'Accent Color',\n 'settings.accentDesc':\n \"Pick an accent for each theme — it's saved and restored next time you open the panel.\",\n 'settings.lightTheme': 'Light theme',\n 'settings.darkTheme': 'Dark theme',\n 'settings.accentDefault': 'Default ({color})',\n 'settings.fontTitle': 'Font',\n 'settings.fontDesc':\n 'Pick a preset or type any Google Font — applied app-wide and saved for next time.',\n 'settings.fontFamily': 'Font family',\n 'settings.fontSearch': 'Search or type any Google Font…',\n 'settings.fontDefault': '{font} (Default)',\n 'settings.headerTitle': 'Header',\n 'settings.headerDesc':\n 'Keep the header fixed on scroll, or let it scroll away — saved for next time.',\n 'settings.scrollable': 'Scrollable',\n 'settings.scrollableDesc': 'Scrolls away',\n 'settings.fixed': 'Fixed',\n 'settings.fixedDesc': 'Stays on scroll',\n 'rte.placeholder': 'Write something…',\n 'rte.formatting': 'Formatting',\n 'rte.undo': 'Undo',\n 'rte.redo': 'Redo',\n 'rte.fontSize': 'Font size',\n 'rte.textColor': 'Text color',\n 'rte.bold': 'Bold',\n 'rte.italic': 'Italic',\n 'rte.underline': 'Underline',\n 'rte.bulletList': 'Bullet list',\n 'rte.numberedList': 'Numbered list',\n 'rte.quote': 'Quote',\n 'rte.alignLeft': 'Align left',\n 'rte.alignCenter': 'Align center',\n 'rte.alignRight': 'Align right',\n 'rte.link': 'Insert link',\n 'rte.insertImage': 'Insert image',\n 'rte.insertVideo': 'Insert video',\n 'rte.uploadImage': 'Upload image',\n 'rte.imageByUrl': 'By URL',\n 'rte.imageError': 'Could not add the image. Please try again.',\n 'rte.linkTitle': 'Insert Link',\n 'rte.linkUrl': 'Link URL',\n 'rte.imageTitle': 'Insert Image',\n 'rte.imageUrl': 'Image URL',\n 'rte.videoTitle': 'Insert Video',\n 'rte.videoUrl': 'Video URL',\n 'rte.videoUrlPlaceholder': 'YouTube, Vimeo, or a direct file URL',\n 'rte.embeddedVideo': 'Embedded video',\n 'fileUploader.choose': 'Choose a file',\n 'fileUploader.dropSuffix': 'or drag & drop it here',\n 'fileUploader.uploaded': 'Uploaded',\n 'fileUploader.hintUpToOne': 'Up to {count} file',\n 'fileUploader.hintUpToMany': 'Up to {count} files',\n 'fileUploader.hintMax': 'Max {size} each',\n 'fileUploader.exceedsLimit': 'Exceeds {size} limit',\n 'fileUploader.download': 'Download {name}',\n 'fileCard.download': 'Download {name}',\n 'fileUploader.remove': 'Remove {name}',\n 'fileUploader.crop': 'Crop {name}',\n 'fileUploader.editAlt': 'Edit alt text for {name}',\n 'fileUploader.preview': 'Preview {name}',\n 'fileUploader.closePreview': 'Close preview',\n 'fileUploader.duplicate': 'Some files are already added',\n 'fileUploader.wrongTypeOne': '\"{name}\" has an unsupported file type',\n 'fileUploader.wrongTypeMany': '{count} files have an unsupported type',\n 'fileUploader.tooLargeOne': '\"{name}\" exceeds the {size} limit',\n 'fileUploader.tooLargeMany': '{count} files exceed the {size} limit',\n 'fileUploader.cropTitle': 'Crop image',\n 'fileUploader.altTitle': 'Alt text',\n 'fileUploader.cropHint': 'Drag to select the area to keep',\n 'fileUploader.altPlaceholder': 'Describe the image for screen readers…',\n 'fileUploader.cropError':\n 'Couldn’t crop this image — it may be served cross-origin without CORS.',\n 'codeBlock.copy': 'Copy code',\n 'codeBlock.copied': 'Copied!',\n 'clipboard.copy': 'Copy',\n 'clipboard.copied': 'Copied!',\n 'sidebar.searchPages': 'Search pages',\n 'account.label': 'Account',\n 'settings.label': 'Settings',\n 'language.label': 'Language',\n}\n\n/** Flag for the English (US) UI language — rendered beside the language in the header switcher. */\nexport const EN_FLAG = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 480\">\n <path fill=\"#bd3d44\" d=\"M0 0h640v480H0\"/>\n <path stroke=\"#fff\" stroke-width=\"37\" d=\"M0 55.3h640M0 129h640M0 203h640M0 277h640M0 351h640M0 425h640\"/>\n <path fill=\"#192f5d\" d=\"M0 0h364.8v258.5H0\"/>\n <marker id=\"us-a\" markerHeight=\"30\" markerWidth=\"30\">\n <path fill=\"#fff\" d=\"m14 0 9 27L0 10h28L5 27z\"/>\n </marker>\n <path fill=\"none\" marker-mid=\"url(#us-a)\" d=\"m0 0 16 11h61 61 61 61 60L47 37h61 61 60 61L16 63h61 61 61 61 60L47 89h61 61 60 61L16 115h61 61 61 61 60L47 141h61 61 60 61L16 166h61 61 61 61 60L47 192h61 61 60 61L16 218h61 61 61 61 60z\"/>\n</svg>`\n","import type { MessageCatalog } from '../messages'\n\n/**\n * Georgian — shipped built-in (the maintainer's language). A `MessageCatalog` (`Partial<Messages>`),\n * so any key it omits falls back to English (`en.ts`) at resolve time.\n */\nexport const KA_MESSAGES: MessageCatalog = {\n 'common.close': 'დახურვა',\n 'common.cancel': 'გაუქმება',\n 'common.confirm': 'დადასტურება',\n 'common.delete': 'წაშლა',\n 'common.remove': 'მოცილება',\n 'common.loading': 'იტვირთება…',\n 'common.clear': 'გასუფთავება',\n 'common.apply': 'გამოყენება',\n 'common.search': 'ძებნა…',\n 'common.all': 'ყველა',\n 'common.any': 'ნებისმიერი',\n 'common.yes': 'დიახ',\n 'common.no': 'არა',\n 'common.save': 'შენახვა',\n 'common.insert': 'ჩასმა',\n 'common.update': 'განახლება',\n 'common.done': 'მზადაა',\n 'common.min': 'მინ.',\n 'common.max': 'მაქს.',\n 'common.from': 'დან',\n 'common.to': 'მდე',\n 'select.placeholder': 'აირჩიეთ…',\n 'select.noOptions': 'ვარიანტები არ არის',\n 'select.clear': 'არჩევანის გასუფთავება',\n 'multiSelect.clearAll': 'ყველას გასუფთავება',\n 'pagination.previous': 'წინა გვერდი',\n 'pagination.next': 'შემდეგი გვერდი',\n 'pagination.first': 'პირველი გვერდი',\n 'pagination.last': 'ბოლო გვერდი',\n 'pagination.page': 'გვერდი {page}',\n 'emptyState.title': 'შედეგები ვერ მოიძებნა',\n 'notFound.title': 'გვერდი ვერ მოიძებნა',\n 'notFound.description': 'თქვენ მიერ მოთხოვნილი გვერდი არ არსებობს ან გადატანილია.',\n 'notFound.action': 'მთავარ გვერდზე დაბრუნება',\n 'userCard.signOut': 'გასვლა',\n 'userCard.welcome': 'მოგესალმებით',\n 'textField.fieldAction': 'ველის მოქმედება',\n 'textField.showPassword': 'პაროლის ჩვენება',\n 'textField.hidePassword': 'პაროლის დამალვა',\n 'textField.capsLock': 'Caps Lock ჩართულია',\n 'textField.strengthWeak': 'სუსტი',\n 'textField.strengthMedium': 'საშუალო',\n 'textField.strengthStrong': 'ძლიერი',\n 'numberField.decrease': 'შემცირება',\n 'numberField.increase': 'გაზრდა',\n 'otpField.digit': 'ციფრი {index} / {total}',\n 'breadcrumbs.label': 'ნავიგაცია',\n 'breadcrumbs.home': 'მთავარი',\n 'pageTitle.back': 'უკან',\n 'pageActions.label': 'მოქმედებები',\n 'themeToggle.label': 'თემის გადართვა',\n 'fullscreenToggle.label': 'სრულ ეკრანზე გადართვა',\n 'loader.label': 'იტვირთება',\n 'tagsField.add': 'ჭდის დამატება',\n 'removeDialog.title': 'წაშლა',\n 'removeDialog.message': 'დარწმუნებული ხართ, რომ გსურთ წაშლა?',\n 'colorPicker.pick': 'აირჩიეთ ფერი',\n 'colorPicker.value': 'ფერის მნიშვნელობა',\n 'colorPicker.noColor': 'ფერის გარეშე',\n 'colorPicker.saturation': 'გაჯერება და სიკაშკაშე',\n 'colorPicker.hue': 'ტონი',\n 'colorPicker.opacity': 'გამჭვირვალობა',\n 'datePicker.clear': 'თარიღის გასუფთავება',\n 'datePicker.open': 'კალენდრის გახსნა',\n 'calendar.prevMonth': 'წინა თვე',\n 'calendar.nextMonth': 'შემდეგი თვე',\n 'timePicker.clear': 'დროის გასუფთავება',\n 'timePicker.open': 'დროის ამრჩევის გახსნა',\n 'dateTimePicker.clear': 'მნიშვნელობის გასუფთავება',\n 'dateTimePicker.open': 'თარიღისა და დროის ამრჩევის გახსნა',\n 'dateTimePicker.label': 'თარიღი და დრო',\n 'dateTimePicker.dateTab': 'თარიღი',\n 'dateTimePicker.timeTab': 'დრო',\n 'table.export': 'ექსპორტი',\n 'table.sendOnEmail': 'ელფოსტაზე გაგზავნა',\n 'table.sort': 'დახარისხება',\n 'table.sortBy': 'დახარისხება',\n 'table.filters': 'ფილტრები',\n 'table.filtersDescription': 'დაფილტრეთ ცხრილი ქვემოთ მოცემული ველებით.',\n 'table.dragHandle': 'გადასათრევად ჩავიჭიდე',\n 'table.range': '{from}–{to} / {total}',\n 'table.rowsPerPage': 'სტრიქონი გვერდზე',\n 'calendar.month0': 'იანვარი',\n 'calendar.month1': 'თებერვალი',\n 'calendar.month2': 'მარტი',\n 'calendar.month3': 'აპრილი',\n 'calendar.month4': 'მაისი',\n 'calendar.month5': 'ივნისი',\n 'calendar.month6': 'ივლისი',\n 'calendar.month7': 'აგვისტო',\n 'calendar.month8': 'სექტემბერი',\n 'calendar.month9': 'ოქტომბერი',\n 'calendar.month10': 'ნოემბერი',\n 'calendar.month11': 'დეკემბერი',\n 'calendar.weekday0': 'კვ',\n 'calendar.weekday1': 'ორ',\n 'calendar.weekday2': 'სა',\n 'calendar.weekday3': 'ოთ',\n 'calendar.weekday4': 'ხუ',\n 'calendar.weekday5': 'პა',\n 'calendar.weekday6': 'შა',\n 'calendar.selectYear': 'აირჩიეთ წელი',\n 'time.hour': 'საათი',\n 'time.minute': 'წუთი',\n 'time.second': 'წამი',\n 'time.meridiem': 'AM/PM',\n 'time.am': 'AM',\n 'time.pm': 'PM',\n 'settings.themeTitle': 'თემა',\n 'settings.themeDesc': 'გადართეთ ღია და მუქ თემას შორის.',\n 'settings.light': 'ღია',\n 'settings.lightDesc': 'ნათელი თემა',\n 'settings.dark': 'მუქი',\n 'settings.darkDesc': 'ბნელი თემა',\n 'settings.languageDesc': 'აირჩიეთ ადმინ პანელის ენა — შენახული შემდეგისთვის.',\n 'settings.accentTitle': 'აქცენტის ფერი',\n 'settings.accentDesc': 'აირჩიეთ აქცენტი თითოეული თემისთვის — ინახება და აღდგება შემდეგ ჯერზე.',\n 'settings.lightTheme': 'ღია თემა',\n 'settings.darkTheme': 'მუქი თემა',\n 'settings.accentDefault': 'ნაგულისხმევი ({color})',\n 'settings.fontTitle': 'შრიფტი',\n 'settings.fontDesc': 'აირჩიეთ presetი ან აკრიფეთ ნებისმიერი Google Font — გამოიყენება ყველგან.',\n 'settings.fontFamily': 'შრიფტის ოჯახი',\n 'settings.fontSearch': 'მოძებნეთ ან აკრიფეთ ნებისმიერი Google Font…',\n 'settings.fontDefault': '{font} (ნაგულისხმევი)',\n 'settings.headerTitle': 'ჰედერი',\n 'settings.headerDesc':\n 'ჰედერი დააფიქსირეთ სქროლზე, ან დაუშვით რომ გაქრეს — შენახული შემდეგისთვის.',\n 'settings.scrollable': 'მოძრავი',\n 'settings.scrollableDesc': 'სქროლზე ქრება',\n 'settings.fixed': 'ფიქსირებული',\n 'settings.fixedDesc': 'სქროლზე რჩება',\n 'rte.placeholder': 'დაწერეთ რაიმე…',\n 'rte.formatting': 'ფორმატირება',\n 'rte.undo': 'დაბრუნება',\n 'rte.redo': 'გამეორება',\n 'rte.fontSize': 'შრიფტის ზომა',\n 'rte.textColor': 'ტექსტის ფერი',\n 'rte.bold': 'მუქი',\n 'rte.italic': 'დახრილი',\n 'rte.underline': 'ხაზგასმული',\n 'rte.bulletList': 'მარკირებული სია',\n 'rte.numberedList': 'ნუმერირებული სია',\n 'rte.quote': 'ციტატა',\n 'rte.alignLeft': 'მარცხნივ სწორება',\n 'rte.alignCenter': 'ცენტრში სწორება',\n 'rte.alignRight': 'მარჯვნივ სწორება',\n 'rte.link': 'ბმულის ჩასმა',\n 'rte.insertImage': 'სურათის ჩასმა',\n 'rte.insertVideo': 'ვიდეოს ჩასმა',\n 'rte.uploadImage': 'სურათის ატვირთვა',\n 'rte.imageByUrl': 'URL-ით',\n 'rte.imageError': 'სურათის დამატება ვერ მოხერხდა. სცადეთ ხელახლა.',\n 'rte.linkTitle': 'ბმულის ჩასმა',\n 'rte.linkUrl': 'ბმულის URL',\n 'rte.imageTitle': 'სურათის ჩასმა',\n 'rte.imageUrl': 'სურათის URL',\n 'rte.videoTitle': 'ვიდეოს ჩასმა',\n 'rte.videoUrl': 'ვიდეოს URL',\n 'rte.videoUrlPlaceholder': 'YouTube, Vimeo, ან პირდაპირი ფაილის URL',\n 'rte.embeddedVideo': 'ჩართული ვიდეო',\n 'fileUploader.choose': 'აირჩიეთ ფაილი',\n 'fileUploader.dropSuffix': 'ან ჩააგდეთ აქ',\n 'fileUploader.uploaded': 'ატვირთულია',\n 'fileUploader.hintUpToOne': 'არაუმეტეს {count} ფაილისა',\n 'fileUploader.hintUpToMany': 'არაუმეტეს {count} ფაილისა',\n 'fileUploader.hintMax': 'მაქს. {size} თითო',\n 'fileUploader.exceedsLimit': 'აჭარბებს {size} ლიმიტს',\n 'fileUploader.download': 'ჩამოტვირთვა: {name}',\n 'fileCard.download': 'ჩამოტვირთვა: {name}',\n 'fileUploader.remove': 'წაშლა: {name}',\n 'fileUploader.crop': 'ჭრა: {name}',\n 'fileUploader.editAlt': 'alt-ტექსტის რედაქტირება: {name}',\n 'fileUploader.preview': 'გადახედვა: {name}',\n 'fileUploader.closePreview': 'გადახედვის დახურვა',\n 'fileUploader.duplicate': 'ზოგიერთი ფაილი უკვე დამატებულია',\n 'fileUploader.wrongTypeOne': '„{name}\"-ს აქვს მხარდაუჭერელი ტიპი',\n 'fileUploader.wrongTypeMany': '{count} ფაილს აქვს მხარდაუჭერელი ტიპი',\n 'fileUploader.tooLargeOne': '„{name}\" აჭარბებს {size} ლიმიტს',\n 'fileUploader.tooLargeMany': '{count} ფაილი აჭარბებს {size} ლიმიტს',\n 'fileUploader.cropTitle': 'სურათის ჭრა',\n 'fileUploader.altTitle': 'Alt ტექსტი',\n 'fileUploader.cropHint': 'გადაათრიეთ დასატოვებელი არის მოსანიშნად',\n 'fileUploader.altPlaceholder': 'აღწერეთ სურათი ეკრანის წამკითხველისთვის…',\n 'fileUploader.cropError': 'სურათის ჭრა ვერ მოხერხდა — შესაძლოა cross-origin იყოს CORS-ის გარეშე.',\n 'codeBlock.copy': 'კოდის კოპირება',\n 'codeBlock.copied': 'დაკოპირდა!',\n 'clipboard.copy': 'კოპირება',\n 'clipboard.copied': 'დაკოპირდა!',\n 'sidebar.searchPages': 'გვერდების ძებნა',\n 'account.label': 'ანგარიში',\n 'settings.label': 'პარამეტრები',\n 'language.label': 'ენა',\n}\n\n/** Flag for the Georgian UI language — rendered beside the language in the header switcher. */\nexport const KA_FLAG = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 480\">\n <path fill=\"#fff\" d=\"M0 0h640v480H0z\"/>\n <path fill=\"red\" d=\"M272 0h96v480h-96z\"/>\n <path fill=\"red\" d=\"M0 192h640v96H0z\"/>\n <path fill=\"red\" fill-rule=\"evenodd\" d=\"M146.8 373.1c1-16.8 4-31.1 4-31.1s-9.8 1-14.8 1-14.8-1-14.8-1 3 14.3 4 31.2c-16.9-1-31.2-4-31.2-4s1 7.4 1 14.8-1 14.8-1 14.8 14.3-3 31.2-4c-1 16.9-4 31.2-4 31.2s7.4-1 14.8-1 14.8 1 14.8 1-3-14.3-4-31.2c16.9 1 31.2 4 31.2 4s-1-9.8-1-14.8 1-14.8 1-14.8-14.3 3-31.1 4zm368-288c1-16.8 4-31.1 4-31.1s-9.8 1-14.8 1-14.8-1-14.8-1 3 14.3 4 31.1c-16.9-1-31.2-3.9-31.2-3.9s1 7.4 1 14.8-1 14.8-1 14.8 14.3-3 31.2-4c-1 16.9-4 31.2-4 31.2s7.4-1 14.8-1 14.8 1 14.8 1-3-14.3-4-31.1c16.9 1 31.2 4 31.2 4s-1-10-1-14.9 1-14.8 1-14.8-14.3 3-31.2 4zm-368 0c1-16.8 4-31.1 4-31.1s-9.8 1-14.8 1-14.8-1-14.8-1 3 14.3 4 31.2c-16.9-1-31.2-4-31.2-4s1 7.4 1 14.8-1 14.8-1 14.8 14.3-3 31.2-4c-1 16.9-4 31.2-4 31.2s7.4-1 14.8-1 14.8 1 14.8 1-3-14.3-4-31.2c16.9 1 31.2 4 31.2 4s-1-9.8-1-14.8 1-14.8 1-14.8-14.3 3-31.1 4zm368 288c1-16.8 4-31.1 4-31.1s-9.8 1-14.8 1-14.8-1-14.8-1 3 14.3 4 31.2c-16.9-1-31.2-4-31.2-4s1 7.4 1 14.8-1 14.8-1 14.8 14.3-3 31.2-4c-1 16.9-4 31.2-4 31.2s7.4-1 14.8-1 14.8 1 14.8 1-3-14.3-4-31.2c16.9 1 31.2 4 31.2 4s-1-9.8-1-14.8 1-14.8 1-14.8-14.3 3-31.2 4z\"/>\n</svg>`\n","import type { MessageCatalog } from '../messages'\n\n/** Spanish — translated from the English baseline (`en.ts`); omitted keys fall back to English. */\nexport const ES_MESSAGES: MessageCatalog = {\n 'common.close': 'Cerrar',\n 'common.cancel': 'Cancelar',\n 'common.confirm': 'Confirmar',\n 'common.delete': 'Eliminar',\n 'common.remove': 'Quitar',\n 'common.loading': 'Cargando…',\n 'common.clear': 'Borrar',\n 'common.apply': 'Aplicar',\n 'common.search': 'Buscar…',\n 'common.all': 'Todos',\n 'common.any': 'Cualquiera',\n 'common.yes': 'Sí',\n 'common.no': 'No',\n 'common.save': 'Guardar',\n 'common.insert': 'Insertar',\n 'common.update': 'Actualizar',\n 'common.done': 'Listo',\n 'common.min': 'Mín',\n 'common.max': 'Máx',\n 'common.from': 'Desde',\n 'common.to': 'Hasta',\n 'select.placeholder': 'Seleccionar…',\n 'select.noOptions': 'Sin opciones',\n 'select.clear': 'Borrar selección',\n 'multiSelect.clearAll': 'Borrar todo',\n 'pagination.previous': 'Ir a la página anterior',\n 'pagination.next': 'Ir a la página siguiente',\n 'pagination.first': 'Ir a la primera página',\n 'pagination.last': 'Ir a la última página',\n 'pagination.page': 'Ir a la página {page}',\n 'emptyState.title': 'No se encontraron resultados',\n 'notFound.title': 'Página no encontrada',\n 'notFound.description': 'La página que buscas no existe o puede haberse movido.',\n 'notFound.action': 'Volver al inicio',\n 'userCard.signOut': 'Cerrar sesión',\n 'userCard.welcome': 'Bienvenido',\n 'textField.fieldAction': 'Acción del campo',\n 'textField.showPassword': 'Mostrar contraseña',\n 'textField.hidePassword': 'Ocultar contraseña',\n 'textField.capsLock': 'Bloq Mayús está activado',\n 'textField.strengthWeak': 'Débil',\n 'textField.strengthMedium': 'Media',\n 'textField.strengthStrong': 'Fuerte',\n 'numberField.decrease': 'Disminuir',\n 'numberField.increase': 'Aumentar',\n 'otpField.digit': 'Dígito {index} de {total}',\n 'breadcrumbs.label': 'Ruta de navegación',\n 'breadcrumbs.home': 'Inicio',\n 'pageTitle.back': 'Atrás',\n 'pageActions.label': 'Acciones',\n 'themeToggle.label': 'Cambiar tema de color',\n 'fullscreenToggle.label': 'Alternar pantalla completa',\n 'loader.label': 'Cargando',\n 'tagsField.add': 'Añadir etiqueta',\n 'removeDialog.title': 'Quitar',\n 'removeDialog.message': '¿Seguro que quieres eliminar?',\n 'colorPicker.pick': 'Elegir un color',\n 'colorPicker.value': 'Valor de color',\n 'colorPicker.noColor': 'Sin color',\n 'colorPicker.saturation': 'Saturación y brillo',\n 'colorPicker.hue': 'Tono',\n 'colorPicker.opacity': 'Opacidad',\n 'datePicker.clear': 'Borrar fecha',\n 'datePicker.open': 'Abrir calendario',\n 'calendar.prevMonth': 'Mes anterior',\n 'calendar.nextMonth': 'Mes siguiente',\n 'timePicker.clear': 'Borrar hora',\n 'timePicker.open': 'Abrir selector de hora',\n 'dateTimePicker.clear': 'Borrar valor',\n 'dateTimePicker.open': 'Abrir selector de fecha y hora',\n 'dateTimePicker.label': 'Fecha y hora',\n 'dateTimePicker.dateTab': 'Fecha',\n 'dateTimePicker.timeTab': 'Hora',\n 'table.export': 'Exportar',\n 'table.sendOnEmail': 'Enviar por correo',\n 'table.sort': 'Ordenar',\n 'table.sortBy': 'Ordenar por',\n 'table.filters': 'Filtros',\n 'table.filtersDescription': 'Filtra la tabla con los campos de abajo.',\n 'table.dragHandle': 'Arrastra para reordenar',\n 'table.range': '{from}–{to} de {total}',\n 'table.rowsPerPage': 'Filas por página',\n 'calendar.month0': 'Enero',\n 'calendar.month1': 'Febrero',\n 'calendar.month2': 'Marzo',\n 'calendar.month3': 'Abril',\n 'calendar.month4': 'Mayo',\n 'calendar.month5': 'Junio',\n 'calendar.month6': 'Julio',\n 'calendar.month7': 'Agosto',\n 'calendar.month8': 'Septiembre',\n 'calendar.month9': 'Octubre',\n 'calendar.month10': 'Noviembre',\n 'calendar.month11': 'Diciembre',\n 'calendar.weekday0': 'Do',\n 'calendar.weekday1': 'Lu',\n 'calendar.weekday2': 'Ma',\n 'calendar.weekday3': 'Mi',\n 'calendar.weekday4': 'Ju',\n 'calendar.weekday5': 'Vi',\n 'calendar.weekday6': 'Sá',\n 'calendar.selectYear': 'Seleccionar año',\n 'time.hour': 'Hora',\n 'time.minute': 'Minuto',\n 'time.second': 'Segundo',\n 'time.meridiem': 'AM/PM',\n 'time.am': 'AM',\n 'time.pm': 'PM',\n 'settings.themeTitle': 'Tema',\n 'settings.themeDesc': 'Cambia entre el tema claro y oscuro.',\n 'settings.light': 'Claro',\n 'settings.lightDesc': 'Tema luminoso',\n 'settings.dark': 'Oscuro',\n 'settings.darkDesc': 'Tema tenue',\n 'settings.languageDesc': 'Elige el idioma del panel — se guarda para la próxima vez.',\n 'settings.accentTitle': 'Color de acento',\n 'settings.accentDesc':\n 'Elige un acento para cada tema — se guarda y se restaura la próxima vez que abras el panel.',\n 'settings.lightTheme': 'Tema claro',\n 'settings.darkTheme': 'Tema oscuro',\n 'settings.accentDefault': 'Predeterminado ({color})',\n 'settings.fontTitle': 'Fuente',\n 'settings.fontDesc':\n 'Elige una predefinida o escribe cualquier Google Font — se aplica en toda la app y se guarda.',\n 'settings.fontFamily': 'Familia tipográfica',\n 'settings.fontSearch': 'Busca o escribe cualquier Google Font…',\n 'settings.fontDefault': '{font} (predeterminada)',\n 'settings.headerTitle': 'Encabezado',\n 'settings.headerDesc':\n 'Mantén el encabezado fijo al desplazar, o deja que se desplace — se guarda para la próxima vez.',\n 'settings.scrollable': 'Desplazable',\n 'settings.scrollableDesc': 'Se desplaza',\n 'settings.fixed': 'Fijo',\n 'settings.fixedDesc': 'Permanece al desplazar',\n 'rte.placeholder': 'Escribe algo…',\n 'rte.formatting': 'Formato',\n 'rte.undo': 'Deshacer',\n 'rte.redo': 'Rehacer',\n 'rte.fontSize': 'Tamaño de fuente',\n 'rte.textColor': 'Color del texto',\n 'rte.bold': 'Negrita',\n 'rte.italic': 'Cursiva',\n 'rte.underline': 'Subrayado',\n 'rte.bulletList': 'Lista con viñetas',\n 'rte.numberedList': 'Lista numerada',\n 'rte.quote': 'Cita',\n 'rte.alignLeft': 'Alinear a la izquierda',\n 'rte.alignCenter': 'Centrar',\n 'rte.alignRight': 'Alinear a la derecha',\n 'rte.link': 'Insertar enlace',\n 'rte.insertImage': 'Insertar imagen',\n 'rte.insertVideo': 'Insertar vídeo',\n 'rte.uploadImage': 'Subir imagen',\n 'rte.imageByUrl': 'Por URL',\n 'rte.imageError': 'No se pudo añadir la imagen. Inténtalo de nuevo.',\n 'rte.linkTitle': 'Insertar enlace',\n 'rte.linkUrl': 'URL del enlace',\n 'rte.imageTitle': 'Insertar imagen',\n 'rte.imageUrl': 'URL de la imagen',\n 'rte.videoTitle': 'Insertar vídeo',\n 'rte.videoUrl': 'URL del vídeo',\n 'rte.videoUrlPlaceholder': 'YouTube, Vimeo o la URL de un archivo directo',\n 'rte.embeddedVideo': 'Vídeo insertado',\n 'fileUploader.choose': 'Elegir un archivo',\n 'fileUploader.dropSuffix': 'o arrástralo y suéltalo aquí',\n 'fileUploader.uploaded': 'Subido',\n 'fileUploader.hintUpToOne': 'Hasta {count} archivo',\n 'fileUploader.hintUpToMany': 'Hasta {count} archivos',\n 'fileUploader.hintMax': 'Máx. {size} cada uno',\n 'fileUploader.exceedsLimit': 'Supera el límite de {size}',\n 'fileUploader.download': 'Descargar {name}',\n 'fileCard.download': 'Descargar {name}',\n 'fileUploader.remove': 'Quitar {name}',\n 'fileUploader.crop': 'Recortar {name}',\n 'fileUploader.editAlt': 'Editar texto alternativo de {name}',\n 'fileUploader.preview': 'Vista previa de {name}',\n 'fileUploader.closePreview': 'Cerrar vista previa',\n 'fileUploader.duplicate': 'Algunos archivos ya se han añadido',\n 'fileUploader.wrongTypeOne': '«{name}» tiene un tipo de archivo no admitido',\n 'fileUploader.wrongTypeMany': '{count} archivos tienen un tipo no admitido',\n 'fileUploader.tooLargeOne': '«{name}» supera el límite de {size}',\n 'fileUploader.tooLargeMany': '{count} archivos superan el límite de {size}',\n 'fileUploader.cropTitle': 'Recortar imagen',\n 'fileUploader.altTitle': 'Texto alternativo',\n 'fileUploader.cropHint': 'Arrastra para seleccionar el área que quieres conservar',\n 'fileUploader.altPlaceholder': 'Describe la imagen para lectores de pantalla…',\n 'fileUploader.cropError':\n 'No se pudo recortar esta imagen — puede servirse desde otro origen sin CORS.',\n 'codeBlock.copy': 'Copiar código',\n 'codeBlock.copied': '¡Copiado!',\n 'clipboard.copy': 'Copiar',\n 'clipboard.copied': '¡Copiado!',\n 'sidebar.searchPages': 'Buscar páginas',\n 'account.label': 'Cuenta',\n 'settings.label': 'Ajustes',\n 'language.label': 'Idioma',\n}\n\n/** Flag for the Spanish UI language — rendered beside the language in the header switcher. */\nexport const ES_FLAG = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 480\">\n <path fill=\"#AA151B\" d=\"M0 0h640v480H0z\"/>\n <path fill=\"#F1BF00\" d=\"M0 120h640v240H0z\"/>\n</svg>`\n","import type { MessageCatalog } from '../messages'\n\n/** German — translated from the English baseline (`en.ts`); omitted keys fall back to English. */\nexport const DE_MESSAGES: MessageCatalog = {\n 'common.close': 'Schließen',\n 'common.cancel': 'Abbrechen',\n 'common.confirm': 'Bestätigen',\n 'common.delete': 'Löschen',\n 'common.remove': 'Entfernen',\n 'common.loading': 'Wird geladen…',\n 'common.clear': 'Leeren',\n 'common.apply': 'Anwenden',\n 'common.search': 'Suchen…',\n 'common.all': 'Alle',\n 'common.any': 'Beliebig',\n 'common.yes': 'Ja',\n 'common.no': 'Nein',\n 'common.save': 'Speichern',\n 'common.insert': 'Einfügen',\n 'common.update': 'Aktualisieren',\n 'common.done': 'Fertig',\n 'common.min': 'Min',\n 'common.max': 'Max',\n 'common.from': 'Von',\n 'common.to': 'Bis',\n 'select.placeholder': 'Auswählen…',\n 'select.noOptions': 'Keine Optionen',\n 'select.clear': 'Auswahl aufheben',\n 'multiSelect.clearAll': 'Alle entfernen',\n 'pagination.previous': 'Zur vorherigen Seite',\n 'pagination.next': 'Zur nächsten Seite',\n 'pagination.first': 'Zur ersten Seite',\n 'pagination.last': 'Zur letzten Seite',\n 'pagination.page': 'Zu Seite {page}',\n 'emptyState.title': 'Keine Ergebnisse gefunden',\n 'notFound.title': 'Seite nicht gefunden',\n 'notFound.description':\n 'Die gesuchte Seite existiert nicht oder wurde möglicherweise verschoben.',\n 'notFound.action': 'Zurück zur Startseite',\n 'userCard.signOut': 'Abmelden',\n 'userCard.welcome': 'Willkommen',\n 'textField.fieldAction': 'Feldaktion',\n 'textField.showPassword': 'Passwort anzeigen',\n 'textField.hidePassword': 'Passwort verbergen',\n 'textField.capsLock': 'Feststelltaste ist aktiviert',\n 'textField.strengthWeak': 'Schwach',\n 'textField.strengthMedium': 'Mittel',\n 'textField.strengthStrong': 'Stark',\n 'numberField.decrease': 'Verringern',\n 'numberField.increase': 'Erhöhen',\n 'otpField.digit': 'Ziffer {index} von {total}',\n 'breadcrumbs.label': 'Navigationspfad',\n 'breadcrumbs.home': 'Startseite',\n 'pageTitle.back': 'Zurück',\n 'pageActions.label': 'Aktionen',\n 'themeToggle.label': 'Farbschema umschalten',\n 'fullscreenToggle.label': 'Vollbild umschalten',\n 'loader.label': 'Wird geladen',\n 'tagsField.add': 'Tag hinzufügen',\n 'removeDialog.title': 'Entfernen',\n 'removeDialog.message': 'Möchten Sie wirklich löschen?',\n 'colorPicker.pick': 'Farbe auswählen',\n 'colorPicker.value': 'Farbwert',\n 'colorPicker.noColor': 'Keine Farbe',\n 'colorPicker.saturation': 'Sättigung und Helligkeit',\n 'colorPicker.hue': 'Farbton',\n 'colorPicker.opacity': 'Deckkraft',\n 'datePicker.clear': 'Datum löschen',\n 'datePicker.open': 'Kalender öffnen',\n 'calendar.prevMonth': 'Voriger Monat',\n 'calendar.nextMonth': 'Nächster Monat',\n 'timePicker.clear': 'Uhrzeit löschen',\n 'timePicker.open': 'Uhrzeitauswahl öffnen',\n 'dateTimePicker.clear': 'Wert löschen',\n 'dateTimePicker.open': 'Datums- und Uhrzeitauswahl öffnen',\n 'dateTimePicker.label': 'Datum und Uhrzeit',\n 'dateTimePicker.dateTab': 'Datum',\n 'dateTimePicker.timeTab': 'Uhrzeit',\n 'table.export': 'Exportieren',\n 'table.sendOnEmail': 'Per E-Mail senden',\n 'table.sort': 'Sortieren',\n 'table.sortBy': 'Sortieren nach',\n 'table.filters': 'Filter',\n 'table.filtersDescription': 'Grenzen Sie die Tabelle mit den folgenden Feldern ein.',\n 'table.dragHandle': 'Zum Umsortieren ziehen',\n 'table.range': '{from}–{to} von {total}',\n 'table.rowsPerPage': 'Zeilen pro Seite',\n 'calendar.month0': 'Januar',\n 'calendar.month1': 'Februar',\n 'calendar.month2': 'März',\n 'calendar.month3': 'April',\n 'calendar.month4': 'Mai',\n 'calendar.month5': 'Juni',\n 'calendar.month6': 'Juli',\n 'calendar.month7': 'August',\n 'calendar.month8': 'September',\n 'calendar.month9': 'Oktober',\n 'calendar.month10': 'November',\n 'calendar.month11': 'Dezember',\n 'calendar.weekday0': 'So',\n 'calendar.weekday1': 'Mo',\n 'calendar.weekday2': 'Di',\n 'calendar.weekday3': 'Mi',\n 'calendar.weekday4': 'Do',\n 'calendar.weekday5': 'Fr',\n 'calendar.weekday6': 'Sa',\n 'calendar.selectYear': 'Jahr auswählen',\n 'time.hour': 'Stunde',\n 'time.minute': 'Minute',\n 'time.second': 'Sekunde',\n 'time.meridiem': 'AM/PM',\n 'time.am': 'AM',\n 'time.pm': 'PM',\n 'settings.themeTitle': 'Design',\n 'settings.themeDesc': 'Zwischen hellem und dunklem Design wechseln.',\n 'settings.light': 'Hell',\n 'settings.lightDesc': 'Helles Design',\n 'settings.dark': 'Dunkel',\n 'settings.darkDesc': 'Gedämpftes Design',\n 'settings.languageDesc':\n 'Wählen Sie die Sprache des Admin-Panels — wird für das nächste Mal gespeichert.',\n 'settings.accentTitle': 'Akzentfarbe',\n 'settings.accentDesc':\n 'Wählen Sie einen Akzent für jedes Design — er wird gespeichert und beim nächsten Öffnen wiederhergestellt.',\n 'settings.lightTheme': 'Helles Design',\n 'settings.darkTheme': 'Dunkles Design',\n 'settings.accentDefault': 'Standard ({color})',\n 'settings.fontTitle': 'Schriftart',\n 'settings.fontDesc':\n 'Wählen Sie eine Vorgabe oder geben Sie eine beliebige Google Font ein — gilt app-weit und wird gespeichert.',\n 'settings.fontFamily': 'Schriftfamilie',\n 'settings.fontSearch': 'Suchen oder beliebige Google Font eingeben…',\n 'settings.fontDefault': '{font} (Standard)',\n 'settings.headerTitle': 'Kopfzeile',\n 'settings.headerDesc':\n 'Kopfzeile beim Scrollen fixieren oder mitscrollen lassen — wird für das nächste Mal gespeichert.',\n 'settings.scrollable': 'Scrollend',\n 'settings.scrollableDesc': 'Scrollt mit',\n 'settings.fixed': 'Fixiert',\n 'settings.fixedDesc': 'Bleibt beim Scrollen',\n 'rte.placeholder': 'Schreiben Sie etwas…',\n 'rte.formatting': 'Formatierung',\n 'rte.undo': 'Rückgängig',\n 'rte.redo': 'Wiederholen',\n 'rte.fontSize': 'Schriftgröße',\n 'rte.textColor': 'Textfarbe',\n 'rte.bold': 'Fett',\n 'rte.italic': 'Kursiv',\n 'rte.underline': 'Unterstrichen',\n 'rte.bulletList': 'Aufzählung',\n 'rte.numberedList': 'Nummerierte Liste',\n 'rte.quote': 'Zitat',\n 'rte.alignLeft': 'Linksbündig',\n 'rte.alignCenter': 'Zentriert',\n 'rte.alignRight': 'Rechtsbündig',\n 'rte.link': 'Link einfügen',\n 'rte.insertImage': 'Bild einfügen',\n 'rte.insertVideo': 'Video einfügen',\n 'rte.uploadImage': 'Bild hochladen',\n 'rte.imageByUrl': 'Über URL',\n 'rte.imageError': 'Das Bild konnte nicht hinzugefügt werden. Bitte versuchen Sie es erneut.',\n 'rte.linkTitle': 'Link einfügen',\n 'rte.linkUrl': 'Link-URL',\n 'rte.imageTitle': 'Bild einfügen',\n 'rte.imageUrl': 'Bild-URL',\n 'rte.videoTitle': 'Video einfügen',\n 'rte.videoUrl': 'Video-URL',\n 'rte.videoUrlPlaceholder': 'YouTube, Vimeo oder eine direkte Datei-URL',\n 'rte.embeddedVideo': 'Eingebettetes Video',\n 'fileUploader.choose': 'Datei auswählen',\n 'fileUploader.dropSuffix': 'oder hierher ziehen und ablegen',\n 'fileUploader.uploaded': 'Hochgeladen',\n 'fileUploader.hintUpToOne': 'Bis zu {count} Datei',\n 'fileUploader.hintUpToMany': 'Bis zu {count} Dateien',\n 'fileUploader.hintMax': 'Max. {size} pro Datei',\n 'fileUploader.exceedsLimit': 'Überschreitet das Limit von {size}',\n 'fileUploader.download': '{name} herunterladen',\n 'fileCard.download': '{name} herunterladen',\n 'fileUploader.remove': '{name} entfernen',\n 'fileUploader.crop': '{name} zuschneiden',\n 'fileUploader.editAlt': 'Alt-Text für {name} bearbeiten',\n 'fileUploader.preview': 'Vorschau von {name}',\n 'fileUploader.closePreview': 'Vorschau schließen',\n 'fileUploader.duplicate': 'Einige Dateien wurden bereits hinzugefügt',\n 'fileUploader.wrongTypeOne': '„{name}“ hat einen nicht unterstützten Dateityp',\n 'fileUploader.wrongTypeMany': '{count} Dateien haben einen nicht unterstützten Typ',\n 'fileUploader.tooLargeOne': '„{name}“ überschreitet das Limit von {size}',\n 'fileUploader.tooLargeMany': '{count} Dateien überschreiten das Limit von {size}',\n 'fileUploader.cropTitle': 'Bild zuschneiden',\n 'fileUploader.altTitle': 'Alt-Text',\n 'fileUploader.cropHint': 'Ziehen Sie, um den zu behaltenden Bereich auszuwählen',\n 'fileUploader.altPlaceholder': 'Beschreiben Sie das Bild für Screenreader…',\n 'fileUploader.cropError':\n 'Dieses Bild konnte nicht zugeschnitten werden — es wird möglicherweise ohne CORS von einer anderen Domain geladen.',\n 'codeBlock.copy': 'Code kopieren',\n 'codeBlock.copied': 'Kopiert!',\n 'clipboard.copy': 'Kopieren',\n 'clipboard.copied': 'Kopiert!',\n 'sidebar.searchPages': 'Seiten suchen',\n 'account.label': 'Konto',\n 'settings.label': 'Einstellungen',\n 'language.label': 'Sprache',\n}\n\n/** Flag for the German UI language — rendered beside the language in the header switcher. */\nexport const DE_FLAG = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 480\">\n <path fill=\"#fc0\" d=\"M0 320h640v160H0z\"/>\n <path fill=\"#000001\" d=\"M0 0h640v160H0z\"/>\n <path fill=\"red\" d=\"M0 160h640v160H0z\"/>\n</svg>`\n","import type { MessageCatalog } from '../messages'\n\n/** Italian — translated from the English baseline (`en.ts`); omitted keys fall back to English. */\nexport const IT_MESSAGES: MessageCatalog = {\n 'common.close': 'Chiudi',\n 'common.cancel': 'Annulla',\n 'common.confirm': 'Conferma',\n 'common.delete': 'Elimina',\n 'common.remove': 'Rimuovi',\n 'common.loading': 'Caricamento…',\n 'common.clear': 'Cancella',\n 'common.apply': 'Applica',\n 'common.search': 'Cerca…',\n 'common.all': 'Tutti',\n 'common.any': 'Qualsiasi',\n 'common.yes': 'Sì',\n 'common.no': 'No',\n 'common.save': 'Salva',\n 'common.insert': 'Inserisci',\n 'common.update': 'Aggiorna',\n 'common.done': 'Fatto',\n 'common.min': 'Min',\n 'common.max': 'Max',\n 'common.from': 'Da',\n 'common.to': 'A',\n 'select.placeholder': 'Seleziona…',\n 'select.noOptions': 'Nessuna opzione',\n 'select.clear': 'Cancella selezione',\n 'multiSelect.clearAll': 'Cancella tutto',\n 'pagination.previous': 'Vai alla pagina precedente',\n 'pagination.next': 'Vai alla pagina successiva',\n 'pagination.first': 'Vai alla prima pagina',\n 'pagination.last': 'Vai all’ultima pagina',\n 'pagination.page': 'Vai alla pagina {page}',\n 'emptyState.title': 'Nessun risultato trovato',\n 'notFound.title': 'Pagina non trovata',\n 'notFound.description':\n 'La pagina che stai cercando non esiste o potrebbe essere stata spostata.',\n 'notFound.action': 'Torna alla home',\n 'userCard.signOut': 'Esci',\n 'userCard.welcome': 'Benvenuto',\n 'textField.fieldAction': 'Azione campo',\n 'textField.showPassword': 'Mostra password',\n 'textField.hidePassword': 'Nascondi password',\n 'textField.capsLock': 'Bloc Maiusc è attivo',\n 'textField.strengthWeak': 'Debole',\n 'textField.strengthMedium': 'Media',\n 'textField.strengthStrong': 'Forte',\n 'numberField.decrease': 'Diminuisci',\n 'numberField.increase': 'Aumenta',\n 'otpField.digit': 'Cifra {index} di {total}',\n 'breadcrumbs.label': 'Percorso di navigazione',\n 'breadcrumbs.home': 'Home',\n 'pageTitle.back': 'Indietro',\n 'pageActions.label': 'Azioni',\n 'themeToggle.label': 'Cambia tema colore',\n 'fullscreenToggle.label': 'Attiva/disattiva schermo intero',\n 'loader.label': 'Caricamento',\n 'tagsField.add': 'Aggiungi tag',\n 'removeDialog.title': 'Rimuovi',\n 'removeDialog.message': 'Sei sicuro di voler eliminare?',\n 'colorPicker.pick': 'Scegli un colore',\n 'colorPicker.value': 'Valore colore',\n 'colorPicker.noColor': 'Nessun colore',\n 'colorPicker.saturation': 'Saturazione e luminosità',\n 'colorPicker.hue': 'Tonalità',\n 'colorPicker.opacity': 'Opacità',\n 'datePicker.clear': 'Cancella data',\n 'datePicker.open': 'Apri calendario',\n 'calendar.prevMonth': 'Mese precedente',\n 'calendar.nextMonth': 'Mese successivo',\n 'timePicker.clear': 'Cancella ora',\n 'timePicker.open': 'Apri selettore ora',\n 'dateTimePicker.clear': 'Cancella valore',\n 'dateTimePicker.open': 'Apri selettore data e ora',\n 'dateTimePicker.label': 'Data e ora',\n 'dateTimePicker.dateTab': 'Data',\n 'dateTimePicker.timeTab': 'Ora',\n 'table.export': 'Esporta',\n 'table.sendOnEmail': 'Invia via email',\n 'table.sort': 'Ordina',\n 'table.sortBy': 'Ordina per',\n 'table.filters': 'Filtri',\n 'table.filtersDescription': 'Restringi la tabella con i campi qui sotto.',\n 'table.dragHandle': 'Trascina per riordinare',\n 'table.range': '{from}–{to} di {total}',\n 'table.rowsPerPage': 'Righe per pagina',\n 'calendar.month0': 'Gennaio',\n 'calendar.month1': 'Febbraio',\n 'calendar.month2': 'Marzo',\n 'calendar.month3': 'Aprile',\n 'calendar.month4': 'Maggio',\n 'calendar.month5': 'Giugno',\n 'calendar.month6': 'Luglio',\n 'calendar.month7': 'Agosto',\n 'calendar.month8': 'Settembre',\n 'calendar.month9': 'Ottobre',\n 'calendar.month10': 'Novembre',\n 'calendar.month11': 'Dicembre',\n 'calendar.weekday0': 'Do',\n 'calendar.weekday1': 'Lu',\n 'calendar.weekday2': 'Ma',\n 'calendar.weekday3': 'Me',\n 'calendar.weekday4': 'Gi',\n 'calendar.weekday5': 'Ve',\n 'calendar.weekday6': 'Sa',\n 'calendar.selectYear': 'Seleziona anno',\n 'time.hour': 'Ora',\n 'time.minute': 'Minuto',\n 'time.second': 'Secondo',\n 'time.meridiem': 'AM/PM',\n 'time.am': 'AM',\n 'time.pm': 'PM',\n 'settings.themeTitle': 'Tema',\n 'settings.themeDesc': 'Passa dal tema chiaro a quello scuro.',\n 'settings.light': 'Chiaro',\n 'settings.lightDesc': 'Tema luminoso',\n 'settings.dark': 'Scuro',\n 'settings.darkDesc': 'Tema attenuato',\n 'settings.languageDesc': 'Scegli la lingua del pannello — salvata per la prossima volta.',\n 'settings.accentTitle': 'Colore accento',\n 'settings.accentDesc':\n 'Scegli un accento per ogni tema — viene salvato e ripristinato alla prossima apertura del pannello.',\n 'settings.lightTheme': 'Tema chiaro',\n 'settings.darkTheme': 'Tema scuro',\n 'settings.accentDefault': 'Predefinito ({color})',\n 'settings.fontTitle': 'Carattere',\n 'settings.fontDesc':\n 'Scegli un preset o digita un Google Font qualsiasi — applicato a tutta l’app e salvato.',\n 'settings.fontFamily': 'Famiglia di caratteri',\n 'settings.fontSearch': 'Cerca o digita un Google Font qualsiasi…',\n 'settings.fontDefault': '{font} (predefinito)',\n 'settings.headerTitle': 'Intestazione',\n 'settings.headerDesc':\n 'Mantieni l’intestazione fissa allo scorrimento o lasciala scorrere — salvato per la prossima volta.',\n 'settings.scrollable': 'Scorrevole',\n 'settings.scrollableDesc': 'Scorre via',\n 'settings.fixed': 'Fissa',\n 'settings.fixedDesc': 'Resta allo scorrimento',\n 'rte.placeholder': 'Scrivi qualcosa…',\n 'rte.formatting': 'Formattazione',\n 'rte.undo': 'Annulla',\n 'rte.redo': 'Ripeti',\n 'rte.fontSize': 'Dimensione carattere',\n 'rte.textColor': 'Colore testo',\n 'rte.bold': 'Grassetto',\n 'rte.italic': 'Corsivo',\n 'rte.underline': 'Sottolineato',\n 'rte.bulletList': 'Elenco puntato',\n 'rte.numberedList': 'Elenco numerato',\n 'rte.quote': 'Citazione',\n 'rte.alignLeft': 'Allinea a sinistra',\n 'rte.alignCenter': 'Allinea al centro',\n 'rte.alignRight': 'Allinea a destra',\n 'rte.link': 'Inserisci link',\n 'rte.insertImage': 'Inserisci immagine',\n 'rte.insertVideo': 'Inserisci video',\n 'rte.uploadImage': 'Carica immagine',\n 'rte.imageByUrl': 'Tramite URL',\n 'rte.imageError': 'Impossibile aggiungere l’immagine. Riprova.',\n 'rte.linkTitle': 'Inserisci link',\n 'rte.linkUrl': 'URL del link',\n 'rte.imageTitle': 'Inserisci immagine',\n 'rte.imageUrl': 'URL dell’immagine',\n 'rte.videoTitle': 'Inserisci video',\n 'rte.videoUrl': 'URL del video',\n 'rte.videoUrlPlaceholder': 'YouTube, Vimeo o l’URL di un file diretto',\n 'rte.embeddedVideo': 'Video incorporato',\n 'fileUploader.choose': 'Scegli un file',\n 'fileUploader.dropSuffix': 'o trascinalo qui',\n 'fileUploader.uploaded': 'Caricato',\n 'fileUploader.hintUpToOne': 'Fino a {count} file',\n 'fileUploader.hintUpToMany': 'Fino a {count} file',\n 'fileUploader.hintMax': 'Max {size} ciascuno',\n 'fileUploader.exceedsLimit': 'Supera il limite di {size}',\n 'fileUploader.download': 'Scarica {name}',\n 'fileCard.download': 'Scarica {name}',\n 'fileUploader.remove': 'Rimuovi {name}',\n 'fileUploader.crop': 'Ritaglia {name}',\n 'fileUploader.editAlt': 'Modifica testo alternativo per {name}',\n 'fileUploader.preview': 'Anteprima di {name}',\n 'fileUploader.closePreview': 'Chiudi anteprima',\n 'fileUploader.duplicate': 'Alcuni file sono già stati aggiunti',\n 'fileUploader.wrongTypeOne': '«{name}» ha un tipo di file non supportato',\n 'fileUploader.wrongTypeMany': '{count} file hanno un tipo non supportato',\n 'fileUploader.tooLargeOne': '«{name}» supera il limite di {size}',\n 'fileUploader.tooLargeMany': '{count} file superano il limite di {size}',\n 'fileUploader.cropTitle': 'Ritaglia immagine',\n 'fileUploader.altTitle': 'Testo alternativo',\n 'fileUploader.cropHint': 'Trascina per selezionare l’area da mantenere',\n 'fileUploader.altPlaceholder': 'Descrivi l’immagine per i lettori di schermo…',\n 'fileUploader.cropError':\n 'Impossibile ritagliare questa immagine — potrebbe essere servita da un’altra origine senza CORS.',\n 'codeBlock.copy': 'Copia codice',\n 'codeBlock.copied': 'Copiato!',\n 'clipboard.copy': 'Copia',\n 'clipboard.copied': 'Copiato!',\n 'sidebar.searchPages': 'Cerca pagine',\n 'account.label': 'Account',\n 'settings.label': 'Impostazioni',\n 'language.label': 'Lingua',\n}\n\n/** Flag for the Italian UI language — rendered beside the language in the header switcher. */\nexport const IT_FLAG = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 480\">\n <g fill-rule=\"evenodd\" stroke-width=\"1pt\">\n <path fill=\"#fff\" d=\"M0 0h640v480H0z\"/>\n <path fill=\"#009246\" d=\"M0 0h213.3v480H0z\"/>\n <path fill=\"#ce2b37\" d=\"M426.7 0H640v480H426.7z\"/>\n </g>\n</svg>`\n","import type { MessageCatalog } from '../messages'\n\n/** French — translated from the English baseline (`en.ts`); omitted keys fall back to English. */\nexport const FR_MESSAGES: MessageCatalog = {\n 'common.close': 'Fermer',\n 'common.cancel': 'Annuler',\n 'common.confirm': 'Confirmer',\n 'common.delete': 'Supprimer',\n 'common.remove': 'Retirer',\n 'common.loading': 'Chargement…',\n 'common.clear': 'Effacer',\n 'common.apply': 'Appliquer',\n 'common.search': 'Rechercher…',\n 'common.all': 'Tous',\n 'common.any': 'Peu importe',\n 'common.yes': 'Oui',\n 'common.no': 'Non',\n 'common.save': 'Enregistrer',\n 'common.insert': 'Insérer',\n 'common.update': 'Mettre à jour',\n 'common.done': 'Terminé',\n 'common.min': 'Min',\n 'common.max': 'Max',\n 'common.from': 'De',\n 'common.to': 'À',\n 'select.placeholder': 'Sélectionner…',\n 'select.noOptions': 'Aucune option',\n 'select.clear': 'Effacer la sélection',\n 'multiSelect.clearAll': 'Tout effacer',\n 'pagination.previous': 'Aller à la page précédente',\n 'pagination.next': 'Aller à la page suivante',\n 'pagination.first': 'Aller à la première page',\n 'pagination.last': 'Aller à la dernière page',\n 'pagination.page': 'Aller à la page {page}',\n 'emptyState.title': 'Aucun résultat trouvé',\n 'notFound.title': 'Page introuvable',\n 'notFound.description': \"La page que vous recherchez n'existe pas ou a peut-être été déplacée.\",\n 'notFound.action': \"Retour à l'accueil\",\n 'userCard.signOut': 'Se déconnecter',\n 'userCard.welcome': 'Bienvenue',\n 'textField.fieldAction': 'Action du champ',\n 'textField.showPassword': 'Afficher le mot de passe',\n 'textField.hidePassword': 'Masquer le mot de passe',\n 'textField.capsLock': 'Verr. Maj est activé',\n 'textField.strengthWeak': 'Faible',\n 'textField.strengthMedium': 'Moyen',\n 'textField.strengthStrong': 'Fort',\n 'numberField.decrease': 'Diminuer',\n 'numberField.increase': 'Augmenter',\n 'otpField.digit': 'Chiffre {index} sur {total}',\n 'breadcrumbs.label': 'Fil d’Ariane',\n 'breadcrumbs.home': 'Accueil',\n 'pageTitle.back': 'Retour',\n 'pageActions.label': 'Actions',\n 'themeToggle.label': 'Changer le thème de couleur',\n 'fullscreenToggle.label': 'Basculer en plein écran',\n 'loader.label': 'Chargement',\n 'tagsField.add': 'Ajouter une étiquette',\n 'removeDialog.title': 'Retirer',\n 'removeDialog.message': 'Voulez-vous vraiment supprimer ?',\n 'colorPicker.pick': 'Choisir une couleur',\n 'colorPicker.value': 'Valeur de couleur',\n 'colorPicker.noColor': 'Aucune couleur',\n 'colorPicker.saturation': 'Saturation et luminosité',\n 'colorPicker.hue': 'Teinte',\n 'colorPicker.opacity': 'Opacité',\n 'datePicker.clear': 'Effacer la date',\n 'datePicker.open': 'Ouvrir le calendrier',\n 'calendar.prevMonth': 'Mois précédent',\n 'calendar.nextMonth': 'Mois suivant',\n 'timePicker.clear': 'Effacer l’heure',\n 'timePicker.open': 'Ouvrir le sélecteur d’heure',\n 'dateTimePicker.clear': 'Effacer la valeur',\n 'dateTimePicker.open': 'Ouvrir le sélecteur de date et d’heure',\n 'dateTimePicker.label': 'Date et heure',\n 'dateTimePicker.dateTab': 'Date',\n 'dateTimePicker.timeTab': 'Heure',\n 'table.export': 'Exporter',\n 'table.sendOnEmail': 'Envoyer par e-mail',\n 'table.sort': 'Trier',\n 'table.sortBy': 'Trier par',\n 'table.filters': 'Filtres',\n 'table.filtersDescription': 'Affinez le tableau avec les champs ci-dessous.',\n 'table.dragHandle': 'Glisser pour réorganiser',\n 'table.range': '{from}–{to} sur {total}',\n 'table.rowsPerPage': 'Lignes par page',\n 'calendar.month0': 'Janvier',\n 'calendar.month1': 'Février',\n 'calendar.month2': 'Mars',\n 'calendar.month3': 'Avril',\n 'calendar.month4': 'Mai',\n 'calendar.month5': 'Juin',\n 'calendar.month6': 'Juillet',\n 'calendar.month7': 'Août',\n 'calendar.month8': 'Septembre',\n 'calendar.month9': 'Octobre',\n 'calendar.month10': 'Novembre',\n 'calendar.month11': 'Décembre',\n 'calendar.weekday0': 'Di',\n 'calendar.weekday1': 'Lu',\n 'calendar.weekday2': 'Ma',\n 'calendar.weekday3': 'Me',\n 'calendar.weekday4': 'Je',\n 'calendar.weekday5': 'Ve',\n 'calendar.weekday6': 'Sa',\n 'calendar.selectYear': 'Sélectionner l’année',\n 'time.hour': 'Heure',\n 'time.minute': 'Minute',\n 'time.second': 'Seconde',\n 'time.meridiem': 'AM/PM',\n 'time.am': 'AM',\n 'time.pm': 'PM',\n 'settings.themeTitle': 'Thème',\n 'settings.themeDesc': 'Basculez entre le thème clair et sombre.',\n 'settings.light': 'Clair',\n 'settings.lightDesc': 'Thème lumineux',\n 'settings.dark': 'Sombre',\n 'settings.darkDesc': 'Thème tamisé',\n 'settings.languageDesc': 'Choisissez la langue du panneau — enregistrée pour la prochaine fois.',\n 'settings.accentTitle': 'Couleur d’accent',\n 'settings.accentDesc':\n 'Choisissez un accent pour chaque thème — il est enregistré et restauré à la prochaine ouverture du panneau.',\n 'settings.lightTheme': 'Thème clair',\n 'settings.darkTheme': 'Thème sombre',\n 'settings.accentDefault': 'Par défaut ({color})',\n 'settings.fontTitle': 'Police',\n 'settings.fontDesc':\n 'Choisissez un préréglage ou saisissez n’importe quelle Google Font — appliquée à toute l’app et enregistrée.',\n 'settings.fontFamily': 'Famille de police',\n 'settings.fontSearch': 'Recherchez ou saisissez n’importe quelle Google Font…',\n 'settings.fontDefault': '{font} (par défaut)',\n 'settings.headerTitle': 'En-tête',\n 'settings.headerDesc':\n 'Gardez l’en-tête fixe au défilement, ou laissez-le défiler — enregistré pour la prochaine fois.',\n 'settings.scrollable': 'Défilant',\n 'settings.scrollableDesc': 'Défile',\n 'settings.fixed': 'Fixe',\n 'settings.fixedDesc': 'Reste au défilement',\n 'rte.placeholder': 'Écrivez quelque chose…',\n 'rte.formatting': 'Mise en forme',\n 'rte.undo': 'Annuler',\n 'rte.redo': 'Rétablir',\n 'rte.fontSize': 'Taille de police',\n 'rte.textColor': 'Couleur du texte',\n 'rte.bold': 'Gras',\n 'rte.italic': 'Italique',\n 'rte.underline': 'Souligné',\n 'rte.bulletList': 'Liste à puces',\n 'rte.numberedList': 'Liste numérotée',\n 'rte.quote': 'Citation',\n 'rte.alignLeft': 'Aligner à gauche',\n 'rte.alignCenter': 'Centrer',\n 'rte.alignRight': 'Aligner à droite',\n 'rte.link': 'Insérer un lien',\n 'rte.insertImage': 'Insérer une image',\n 'rte.insertVideo': 'Insérer une vidéo',\n 'rte.uploadImage': 'Importer une image',\n 'rte.imageByUrl': 'Par URL',\n 'rte.imageError': 'Impossible d’ajouter l’image. Veuillez réessayer.',\n 'rte.linkTitle': 'Insérer un lien',\n 'rte.linkUrl': 'URL du lien',\n 'rte.imageTitle': 'Insérer une image',\n 'rte.imageUrl': 'URL de l’image',\n 'rte.videoTitle': 'Insérer une vidéo',\n 'rte.videoUrl': 'URL de la vidéo',\n 'rte.videoUrlPlaceholder': 'YouTube, Vimeo ou l’URL d’un fichier direct',\n 'rte.embeddedVideo': 'Vidéo intégrée',\n 'fileUploader.choose': 'Choisir un fichier',\n 'fileUploader.dropSuffix': 'ou glissez-déposez-le ici',\n 'fileUploader.uploaded': 'Importé',\n 'fileUploader.hintUpToOne': 'Jusqu’à {count} fichier',\n 'fileUploader.hintUpToMany': 'Jusqu’à {count} fichiers',\n 'fileUploader.hintMax': '{size} max. chacun',\n 'fileUploader.exceedsLimit': 'Dépasse la limite de {size}',\n 'fileUploader.download': 'Télécharger {name}',\n 'fileCard.download': 'Télécharger {name}',\n 'fileUploader.remove': 'Retirer {name}',\n 'fileUploader.crop': 'Rogner {name}',\n 'fileUploader.editAlt': 'Modifier le texte alternatif de {name}',\n 'fileUploader.preview': 'Aperçu de {name}',\n 'fileUploader.closePreview': 'Fermer l’aperçu',\n 'fileUploader.duplicate': 'Certains fichiers sont déjà ajoutés',\n 'fileUploader.wrongTypeOne': '« {name} » a un type de fichier non pris en charge',\n 'fileUploader.wrongTypeMany': '{count} fichiers ont un type non pris en charge',\n 'fileUploader.tooLargeOne': '« {name} » dépasse la limite de {size}',\n 'fileUploader.tooLargeMany': '{count} fichiers dépassent la limite de {size}',\n 'fileUploader.cropTitle': 'Rogner l’image',\n 'fileUploader.altTitle': 'Texte alternatif',\n 'fileUploader.cropHint': 'Faites glisser pour sélectionner la zone à conserver',\n 'fileUploader.altPlaceholder': 'Décrivez l’image pour les lecteurs d’écran…',\n 'fileUploader.cropError':\n 'Impossible de rogner cette image — elle est peut-être servie depuis une autre origine sans CORS.',\n 'codeBlock.copy': 'Copier le code',\n 'codeBlock.copied': 'Copié !',\n 'clipboard.copy': 'Copier',\n 'clipboard.copied': 'Copié !',\n 'sidebar.searchPages': 'Rechercher des pages',\n 'account.label': 'Compte',\n 'settings.label': 'Paramètres',\n 'language.label': 'Langue',\n}\n\n/** Flag for the French UI language — rendered beside the language in the header switcher. */\nexport const FR_FLAG = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 480\">\n <path fill=\"#000091\" d=\"M0 0h213.3v480H0z\"/>\n <path fill=\"#fff\" d=\"M213.3 0h213.4v480H213.3z\"/>\n <path fill=\"#e1000f\" d=\"M426.7 0H640v480H426.7z\"/>\n</svg>`\n","import type { MessageCatalog } from '../messages'\n\n/** Russian — translated from the English baseline (`en.ts`); omitted keys fall back to English. */\nexport const RU_MESSAGES: MessageCatalog = {\n 'common.close': 'Закрыть',\n 'common.cancel': 'Отмена',\n 'common.confirm': 'Подтвердить',\n 'common.delete': 'Удалить',\n 'common.remove': 'Убрать',\n 'common.loading': 'Загрузка…',\n 'common.clear': 'Очистить',\n 'common.apply': 'Применить',\n 'common.search': 'Поиск…',\n 'common.all': 'Все',\n 'common.any': 'Любой',\n 'common.yes': 'Да',\n 'common.no': 'Нет',\n 'common.save': 'Сохранить',\n 'common.insert': 'Вставить',\n 'common.update': 'Обновить',\n 'common.done': 'Готово',\n 'common.min': 'Мин',\n 'common.max': 'Макс',\n 'common.from': 'От',\n 'common.to': 'До',\n 'select.placeholder': 'Выберите…',\n 'select.noOptions': 'Нет вариантов',\n 'select.clear': 'Очистить выбор',\n 'multiSelect.clearAll': 'Очистить всё',\n 'pagination.previous': 'Перейти на предыдущую страницу',\n 'pagination.next': 'Перейти на следующую страницу',\n 'pagination.first': 'Перейти на первую страницу',\n 'pagination.last': 'Перейти на последнюю страницу',\n 'pagination.page': 'Перейти на страницу {page}',\n 'emptyState.title': 'Ничего не найдено',\n 'notFound.title': 'Страница не найдена',\n 'notFound.description': 'Запрашиваемая страница не существует или была перемещена.',\n 'notFound.action': 'На главную',\n 'userCard.signOut': 'Выйти',\n 'userCard.welcome': 'Добро пожаловать',\n 'textField.fieldAction': 'Действие поля',\n 'textField.showPassword': 'Показать пароль',\n 'textField.hidePassword': 'Скрыть пароль',\n 'textField.capsLock': 'Включён Caps Lock',\n 'textField.strengthWeak': 'Слабый',\n 'textField.strengthMedium': 'Средний',\n 'textField.strengthStrong': 'Надёжный',\n 'numberField.decrease': 'Уменьшить',\n 'numberField.increase': 'Увеличить',\n 'otpField.digit': 'Цифра {index} из {total}',\n 'breadcrumbs.label': 'Хлебные крошки',\n 'breadcrumbs.home': 'Главная',\n 'pageTitle.back': 'Назад',\n 'pageActions.label': 'Действия',\n 'themeToggle.label': 'Переключить цветовую тему',\n 'fullscreenToggle.label': 'Полноэкранный режим',\n 'loader.label': 'Загрузка',\n 'tagsField.add': 'Добавить тег',\n 'removeDialog.title': 'Убрать',\n 'removeDialog.message': 'Вы уверены, что хотите удалить?',\n 'colorPicker.pick': 'Выберите цвет',\n 'colorPicker.value': 'Значение цвета',\n 'colorPicker.noColor': 'Без цвета',\n 'colorPicker.saturation': 'Насыщенность и яркость',\n 'colorPicker.hue': 'Оттенок',\n 'colorPicker.opacity': 'Прозрачность',\n 'datePicker.clear': 'Очистить дату',\n 'datePicker.open': 'Открыть календарь',\n 'calendar.prevMonth': 'Предыдущий месяц',\n 'calendar.nextMonth': 'Следующий месяц',\n 'timePicker.clear': 'Очистить время',\n 'timePicker.open': 'Открыть выбор времени',\n 'dateTimePicker.clear': 'Очистить значение',\n 'dateTimePicker.open': 'Открыть выбор даты и времени',\n 'dateTimePicker.label': 'Дата и время',\n 'dateTimePicker.dateTab': 'Дата',\n 'dateTimePicker.timeTab': 'Время',\n 'table.export': 'Экспорт',\n 'table.sendOnEmail': 'Отправить на почту',\n 'table.sort': 'Сортировка',\n 'table.sortBy': 'Сортировать по',\n 'table.filters': 'Фильтры',\n 'table.filtersDescription': 'Уточните таблицу по полям ниже.',\n 'table.dragHandle': 'Перетащите для изменения порядка',\n 'table.range': '{from}–{to} из {total}',\n 'table.rowsPerPage': 'Строк на странице',\n 'calendar.month0': 'Январь',\n 'calendar.month1': 'Февраль',\n 'calendar.month2': 'Март',\n 'calendar.month3': 'Апрель',\n 'calendar.month4': 'Май',\n 'calendar.month5': 'Июнь',\n 'calendar.month6': 'Июль',\n 'calendar.month7': 'Август',\n 'calendar.month8': 'Сентябрь',\n 'calendar.month9': 'Октябрь',\n 'calendar.month10': 'Ноябрь',\n 'calendar.month11': 'Декабрь',\n 'calendar.weekday0': 'Вс',\n 'calendar.weekday1': 'Пн',\n 'calendar.weekday2': 'Вт',\n 'calendar.weekday3': 'Ср',\n 'calendar.weekday4': 'Чт',\n 'calendar.weekday5': 'Пт',\n 'calendar.weekday6': 'Сб',\n 'calendar.selectYear': 'Выберите год',\n 'time.hour': 'Часы',\n 'time.minute': 'Минуты',\n 'time.second': 'Секунды',\n 'time.meridiem': 'AM/PM',\n 'time.am': 'AM',\n 'time.pm': 'PM',\n 'settings.themeTitle': 'Тема',\n 'settings.themeDesc': 'Переключение между светлой и тёмной темой.',\n 'settings.light': 'Светлая',\n 'settings.lightDesc': 'Светлая тема',\n 'settings.dark': 'Тёмная',\n 'settings.darkDesc': 'Приглушённая тема',\n 'settings.languageDesc': 'Выберите язык панели — сохранится на будущее.',\n 'settings.accentTitle': 'Акцентный цвет',\n 'settings.accentDesc':\n 'Выберите акцент для каждой темы — он сохранится и восстановится при следующем открытии панели.',\n 'settings.lightTheme': 'Светлая тема',\n 'settings.darkTheme': 'Тёмная тема',\n 'settings.accentDefault': 'По умолчанию ({color})',\n 'settings.fontTitle': 'Шрифт',\n 'settings.fontDesc':\n 'Выберите пресет или введите любой Google Font — применяется во всём приложении и сохраняется.',\n 'settings.fontFamily': 'Семейство шрифтов',\n 'settings.fontSearch': 'Найдите или введите любой Google Font…',\n 'settings.fontDefault': '{font} (по умолчанию)',\n 'settings.headerTitle': 'Шапка',\n 'settings.headerDesc':\n 'Закрепите шапку при прокрутке или дайте ей прокручиваться — сохранится на будущее.',\n 'settings.scrollable': 'Прокручиваемая',\n 'settings.scrollableDesc': 'Прокручивается',\n 'settings.fixed': 'Закреплённая',\n 'settings.fixedDesc': 'Остаётся при прокрутке',\n 'rte.placeholder': 'Напишите что-нибудь…',\n 'rte.formatting': 'Форматирование',\n 'rte.undo': 'Отменить',\n 'rte.redo': 'Повторить',\n 'rte.fontSize': 'Размер шрифта',\n 'rte.textColor': 'Цвет текста',\n 'rte.bold': 'Полужирный',\n 'rte.italic': 'Курсив',\n 'rte.underline': 'Подчёркнутый',\n 'rte.bulletList': 'Маркированный список',\n 'rte.numberedList': 'Нумерованный список',\n 'rte.quote': 'Цитата',\n 'rte.alignLeft': 'По левому краю',\n 'rte.alignCenter': 'По центру',\n 'rte.alignRight': 'По правому краю',\n 'rte.link': 'Вставить ссылку',\n 'rte.insertImage': 'Вставить изображение',\n 'rte.insertVideo': 'Вставить видео',\n 'rte.uploadImage': 'Загрузить изображение',\n 'rte.imageByUrl': 'По URL',\n 'rte.imageError': 'Не удалось добавить изображение. Попробуйте ещё раз.',\n 'rte.linkTitle': 'Вставить ссылку',\n 'rte.linkUrl': 'URL ссылки',\n 'rte.imageTitle': 'Вставить изображение',\n 'rte.imageUrl': 'URL изображения',\n 'rte.videoTitle': 'Вставить видео',\n 'rte.videoUrl': 'URL видео',\n 'rte.videoUrlPlaceholder': 'YouTube, Vimeo или прямая ссылка на файл',\n 'rte.embeddedVideo': 'Встроенное видео',\n 'fileUploader.choose': 'Выберите файл',\n 'fileUploader.dropSuffix': 'или перетащите его сюда',\n 'fileUploader.uploaded': 'Загружено',\n 'fileUploader.hintUpToOne': 'До {count} файла',\n 'fileUploader.hintUpToMany': 'До {count} файлов',\n 'fileUploader.hintMax': 'Макс. {size} каждый',\n 'fileUploader.exceedsLimit': 'Превышает лимит {size}',\n 'fileUploader.download': 'Скачать {name}',\n 'fileCard.download': 'Скачать {name}',\n 'fileUploader.remove': 'Убрать {name}',\n 'fileUploader.crop': 'Обрезать {name}',\n 'fileUploader.editAlt': 'Изменить альт-текст для {name}',\n 'fileUploader.preview': 'Предпросмотр {name}',\n 'fileUploader.closePreview': 'Закрыть предпросмотр',\n 'fileUploader.duplicate': 'Некоторые файлы уже добавлены',\n 'fileUploader.wrongTypeOne': '«{name}» имеет неподдерживаемый тип файла',\n 'fileUploader.wrongTypeMany': '{count} файлов имеют неподдерживаемый тип',\n 'fileUploader.tooLargeOne': '«{name}» превышает лимит {size}',\n 'fileUploader.tooLargeMany': '{count} файлов превышают лимит {size}',\n 'fileUploader.cropTitle': 'Обрезать изображение',\n 'fileUploader.altTitle': 'Альт-текст',\n 'fileUploader.cropHint': 'Перетащите, чтобы выбрать область для сохранения',\n 'fileUploader.altPlaceholder': 'Опишите изображение для программ чтения с экрана…',\n 'fileUploader.cropError':\n 'Не удалось обрезать это изображение — возможно, оно загружается с другого домена без CORS.',\n 'codeBlock.copy': 'Копировать код',\n 'codeBlock.copied': 'Скопировано!',\n 'clipboard.copy': 'Копировать',\n 'clipboard.copied': 'Скопировано!',\n 'sidebar.searchPages': 'Поиск страниц',\n 'account.label': 'Аккаунт',\n 'settings.label': 'Настройки',\n 'language.label': 'Язык',\n}\n\n/** Flag for the Russian UI language — rendered beside the language in the header switcher. */\nexport const RU_FLAG = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 480\">\n <path fill=\"#fff\" d=\"M0 0h640v160H0z\"/>\n <path fill=\"#0039a6\" d=\"M0 160h640v160H0z\"/>\n <path fill=\"#d52b1e\" d=\"M0 320h640v160H0z\"/>\n</svg>`\n","/**\n * The library's own static UI strings, shipped **pre-translated** so a consuming app gets a localized\n * admin panel with zero setup — it just lists the languages in `config.i18n`. This is deliberately a\n * tiny, dependency-free layer (no i18next): the string set is small and fixed, resolved by a plain\n * `createTranslator`. Apps translate their **own** content however they like (react-i18next, …); this\n * only covers the library's built-in labels.\n *\n * This module owns the **types + resolution logic**; the actual per-language catalogs live one file\n * each under `./locales/` (`en.ts`, `ka.ts`, …), so the file stays small as languages are added.\n * **To add a string:** add its key to the `Messages` interface below, fill it in `./locales/en.ts`\n * (the complete baseline), and translate it in the other catalogs you can. **To add a language:** drop\n * a `./locales/<base>.ts` (a `MessageCatalog`) and register it in `BUILTIN_MESSAGES`. Any language the\n * library doesn't ship can still be supplied by the consumer via `config.i18n.messages`, falling back\n * to English per key. `{name}` tokens are interpolated from the `vars` passed to `t`.\n */\nimport { EN_MESSAGES, EN_FLAG } from './locales/en'\nimport { KA_MESSAGES, KA_FLAG } from './locales/ka'\nimport { ES_MESSAGES, ES_FLAG } from './locales/es'\nimport { DE_MESSAGES, DE_FLAG } from './locales/de'\nimport { IT_MESSAGES, IT_FLAG } from './locales/it'\nimport { FR_MESSAGES, FR_FLAG } from './locales/fr'\nimport { RU_MESSAGES, RU_FLAG } from './locales/ru'\n\n// re-exported so `EN_MESSAGES` stays importable from `../i18n/messages` (its original home)\nexport { EN_MESSAGES }\n\nexport interface Messages {\n // shared / reused across components\n 'common.close': string\n 'common.cancel': string\n 'common.confirm': string\n 'common.delete': string\n 'common.remove': string\n 'common.loading': string\n 'common.clear': string\n 'common.apply': string\n 'common.search': string\n 'common.all': string\n 'common.any': string\n 'common.yes': string\n 'common.no': string\n 'common.save': string\n 'common.insert': string\n 'common.update': string\n 'common.done': string\n 'common.min': string\n 'common.max': string\n 'common.from': string\n 'common.to': string\n // Select / MultiSelect\n 'select.placeholder': string\n 'select.noOptions': string\n 'select.clear': string\n 'multiSelect.clearAll': string\n // Pagination\n 'pagination.previous': string\n 'pagination.next': string\n 'pagination.first': string\n 'pagination.last': string\n 'pagination.page': string\n // misc components\n 'emptyState.title': string\n 'notFound.title': string\n 'notFound.description': string\n 'notFound.action': string\n 'userCard.signOut': string\n 'userCard.welcome': string\n 'textField.fieldAction': string\n 'textField.showPassword': string\n 'textField.hidePassword': string\n 'textField.capsLock': string\n 'textField.strengthWeak': string\n 'textField.strengthMedium': string\n 'textField.strengthStrong': string\n 'numberField.decrease': string\n 'numberField.increase': string\n 'otpField.digit': string\n 'breadcrumbs.label': string\n 'breadcrumbs.home': string\n 'pageTitle.back': string\n 'pageActions.label': string\n 'themeToggle.label': string\n 'fullscreenToggle.label': string\n 'loader.label': string\n 'tagsField.add': string\n // RemoveDialog\n 'removeDialog.title': string\n 'removeDialog.message': string\n // ColorPicker\n 'colorPicker.pick': string\n 'colorPicker.value': string\n 'colorPicker.noColor': string\n 'colorPicker.saturation': string\n 'colorPicker.hue': string\n 'colorPicker.opacity': string\n // date / time pickers\n 'datePicker.clear': string\n 'datePicker.open': string\n 'calendar.prevMonth': string\n 'calendar.nextMonth': string\n 'timePicker.clear': string\n 'timePicker.open': string\n 'dateTimePicker.clear': string\n 'dateTimePicker.open': string\n 'dateTimePicker.label': string\n 'dateTimePicker.dateTab': string\n 'dateTimePicker.timeTab': string\n // Table\n 'table.export': string\n 'table.sendOnEmail': string\n 'table.sort': string\n 'table.sortBy': string\n 'table.filters': string\n 'table.filtersDescription': string\n 'table.dragHandle': string\n 'table.range': string\n 'table.rowsPerPage': string\n // calendar — full month names (0–11) + short weekday labels (0 = Sunday … 6 = Saturday)\n 'calendar.month0': string\n 'calendar.month1': string\n 'calendar.month2': string\n 'calendar.month3': string\n 'calendar.month4': string\n 'calendar.month5': string\n 'calendar.month6': string\n 'calendar.month7': string\n 'calendar.month8': string\n 'calendar.month9': string\n 'calendar.month10': string\n 'calendar.month11': string\n 'calendar.weekday0': string\n 'calendar.weekday1': string\n 'calendar.weekday2': string\n 'calendar.weekday3': string\n 'calendar.weekday4': string\n 'calendar.weekday5': string\n 'calendar.weekday6': string\n 'calendar.selectYear': string\n // time columns\n 'time.hour': string\n 'time.minute': string\n 'time.second': string\n 'time.meridiem': string\n 'time.am': string\n 'time.pm': string\n // SettingsDrawer\n 'settings.themeTitle': string\n 'settings.themeDesc': string\n 'settings.light': string\n 'settings.lightDesc': string\n 'settings.dark': string\n 'settings.darkDesc': string\n 'settings.languageDesc': string\n 'settings.accentTitle': string\n 'settings.accentDesc': string\n 'settings.lightTheme': string\n 'settings.darkTheme': string\n 'settings.accentDefault': string\n 'settings.fontTitle': string\n 'settings.fontDesc': string\n 'settings.fontFamily': string\n 'settings.fontSearch': string\n 'settings.fontDefault': string\n 'settings.headerTitle': string\n 'settings.headerDesc': string\n 'settings.scrollable': string\n 'settings.scrollableDesc': string\n 'settings.fixed': string\n 'settings.fixedDesc': string\n // RichTextEditor\n 'rte.placeholder': string\n 'rte.formatting': string\n 'rte.undo': string\n 'rte.redo': string\n 'rte.fontSize': string\n 'rte.textColor': string\n 'rte.bold': string\n 'rte.italic': string\n 'rte.underline': string\n 'rte.bulletList': string\n 'rte.numberedList': string\n 'rte.quote': string\n 'rte.alignLeft': string\n 'rte.alignCenter': string\n 'rte.alignRight': string\n 'rte.link': string\n 'rte.insertImage': string\n 'rte.insertVideo': string\n 'rte.uploadImage': string\n 'rte.imageByUrl': string\n 'rte.imageError': string\n 'rte.linkTitle': string\n 'rte.linkUrl': string\n 'rte.imageTitle': string\n 'rte.imageUrl': string\n 'rte.videoTitle': string\n 'rte.videoUrl': string\n 'rte.videoUrlPlaceholder': string\n 'rte.embeddedVideo': string\n // FileUploader\n 'fileUploader.choose': string\n 'fileUploader.dropSuffix': string\n 'fileUploader.uploaded': string\n 'fileUploader.hintUpToOne': string\n 'fileUploader.hintUpToMany': string\n 'fileUploader.hintMax': string\n 'fileUploader.exceedsLimit': string\n 'fileUploader.download': string\n 'fileCard.download': string\n 'fileUploader.remove': string\n 'fileUploader.crop': string\n 'fileUploader.editAlt': string\n 'fileUploader.preview': string\n 'fileUploader.closePreview': string\n 'fileUploader.duplicate': string\n 'fileUploader.wrongTypeOne': string\n 'fileUploader.wrongTypeMany': string\n 'fileUploader.tooLargeOne': string\n 'fileUploader.tooLargeMany': string\n 'fileUploader.cropTitle': string\n 'fileUploader.altTitle': string\n 'fileUploader.cropHint': string\n 'fileUploader.altPlaceholder': string\n 'fileUploader.cropError': string\n // CodeBlock\n 'codeBlock.copy': string\n 'codeBlock.copied': string\n 'clipboard.copy': string\n 'clipboard.copied': string\n // Sidebar / shell\n 'sidebar.searchPages': string\n 'account.label': string\n 'settings.label': string\n 'language.label': string\n}\n\n/** A message key (autocompleted + checked by `t`). */\nexport type MessageKey = keyof Messages\n/** A (possibly partial) catalog for one language. */\nexport type MessageCatalog = Partial<Messages>\n/** Consumer-supplied catalogs, keyed by language code (`'ka-GE'`) or base language (`'ka'`). */\nexport type MessageOverrides = Record<string, MessageCatalog>\n\n/** Built-in catalogs the library ships, keyed by **base** language code. */\nexport const BUILTIN_MESSAGES: Record<string, MessageCatalog> = {\n en: EN_MESSAGES,\n ka: KA_MESSAGES,\n es: ES_MESSAGES,\n de: DE_MESSAGES,\n it: IT_MESSAGES,\n fr: FR_MESSAGES,\n ru: RU_MESSAGES,\n}\n\n/**\n * Built-in flag SVGs (raw markup strings), keyed by **base** language code — shown beside each language\n * in the header switcher. A language with no flag here simply renders without one; each locale ships its\n * own flag from its `./locales/<base>.ts` file. (Coverage grows alongside the catalogs.)\n */\nexport const BUILTIN_FLAGS: Record<string, string> = {\n en: EN_FLAG,\n ka: KA_FLAG,\n es: ES_FLAG,\n de: DE_FLAG,\n it: IT_FLAG,\n fr: FR_FLAG,\n ru: RU_FLAG,\n}\n\n/** Base language of a locale code — `'ka-GE'` → `'ka'`. */\nconst baseLang = (locale: string): string => locale.split('-')[0].toLowerCase()\n\n/** The built-in flag SVG markup for a locale code (matched by base language), or `undefined` if none. */\nexport function flagFor(locale: string): string | undefined {\n return BUILTIN_FLAGS[baseLang(locale)]\n}\n\n/** A bound translator: `t('key')`, with optional `{name}` interpolation. */\nexport type Translator = (key: MessageKey, vars?: Record<string, string | number>) => string\n\n/**\n * Build a translator for `locale`. Resolution per key: consumer override (exact code, then base) →\n * built-in catalog for the base language → English baseline → the key itself. `{name}` tokens in the\n * resolved string are replaced from `vars`.\n */\nexport function createTranslator(locale: string, overrides?: MessageOverrides): Translator {\n const b = baseLang(locale)\n const consumer: MessageCatalog = { ...overrides?.[b], ...overrides?.[locale] }\n const builtin = BUILTIN_MESSAGES[b] ?? {}\n return (key, vars) => {\n const raw = consumer[key] ?? builtin[key] ?? EN_MESSAGES[key] ?? key\n return vars ? raw.replace(/\\{(\\w+)\\}/g, (_, k) => String(vars[k] ?? `{${k}}`)) : raw\n }\n}\n\n/**\n * Catalogs for the **consuming app's own** UI strings (used by `useTranslations()`), keyed by language\n * code or base language (`'ka-GE'` or `'ka'`), then by an arbitrary string key the app chooses. Unlike\n * {@link MessageOverrides} (which overrides the library's fixed `Messages`), these keys are free-form —\n * this is how an app localizes its own copy (section titles, labels) through the same language switcher.\n */\nexport type AppMessages = Record<string, Record<string, string>>\n\n/** A translator over the app's own `AppMessages` — any string key, optional `{name}` interpolation. */\nexport type AppTranslator = (key: string, vars?: Record<string, string | number>) => string\n\n/**\n * Build a translator over the consuming app's own `AppMessages` for `locale`. Resolution per key: exact\n * code → base language → English (`'en'`) → the key itself (so a missing translation renders the key\n * visibly rather than blank). `{name}` tokens are interpolated from `vars`. Powers `useTranslations()`.\n */\nexport function createAppTranslator(locale: string, appMessages?: AppMessages): AppTranslator {\n const b = baseLang(locale)\n const src = appMessages ?? {}\n return (key, vars) => {\n const raw = src[locale]?.[key] ?? src[b]?.[key] ?? src.en?.[key] ?? key\n return vars ? raw.replace(/\\{(\\w+)\\}/g, (_, k) => String(vars[k] ?? `{${k}}`)) : raw\n }\n}\n"],"names":["EN_MESSAGES","EN_FLAG","KA_MESSAGES","KA_FLAG","ES_MESSAGES","ES_FLAG","DE_MESSAGES","DE_FLAG","IT_MESSAGES","IT_FLAG","FR_MESSAGES","FR_FLAG","RU_MESSAGES","RU_FLAG","BUILTIN_MESSAGES","BUILTIN_FLAGS","baseLang","locale","flagFor","createTranslator","overrides","b","consumer","builtin","key","vars","raw","_","k","createAppTranslator","appMessages","src","_a","_b","_c"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { type ReactNode } from 'react';
2
- import { type ThemePalette } from './applyTheme';
2
+ import { type ThemeColor, type ThemePalette } from './applyTheme';
3
3
  import { type Breakpoint } from './breakpoints';
4
+ import type { IconName } from '../icons/names';
4
5
  import { type AppMessages, type AppTranslator, type MessageOverrides, type Translator } from '../i18n/messages';
5
6
  export type ThemeMode = 'light' | 'dark';
6
7
  export interface ThemeColors {
@@ -142,6 +143,19 @@ export interface HeaderUser {
142
143
  /** Avatar image URL (falls back to a user icon). */
143
144
  avatar?: string;
144
145
  }
146
+ /** One custom item in the header account menu (rendered between the user block and **Sign out**). */
147
+ export interface HeaderMenuItem {
148
+ /** Visible label. */
149
+ label: string;
150
+ /** Leading icon (`IconName`). Optional. */
151
+ icon?: IconName;
152
+ /** Runs on click; the menu closes afterwards. */
153
+ onClick: () => void;
154
+ /** Renders the item disabled. Optional. */
155
+ disabled?: boolean;
156
+ /** Tint, e.g. `'error'` for a destructive item. Default: inherit. */
157
+ color?: ThemeColor;
158
+ }
145
159
  /**
146
160
  * `RootLayout` header configuration — the shell's top-bar controls. Set it once app-wide in
147
161
  * `config.header`, or per shell via the `RootLayout` `header` prop (the prop wins, merged over config).
@@ -175,6 +189,13 @@ export interface HeaderConfig {
175
189
  onLogout?: () => void;
176
190
  /** Signed-in user — shown in the header avatar and as a header block atop the account menu. */
177
191
  user?: HeaderUser;
192
+ /**
193
+ * Extra items in the header account menu, rendered between the user block and **Sign out**, in order.
194
+ * Only shown when `onLogout` is set (the menu does not exist otherwise). A `Divider` separates them
195
+ * from **Sign out**. (When merging a `RootLayout`/`AdminRoot` `header` prop over `config.header`, the
196
+ * prop's `menu` array **replaces** the config's — arrays don't concatenate.)
197
+ */
198
+ menu?: HeaderMenuItem[];
178
199
  }
179
200
  /**
180
201
  * UI-language config for the admin panel's **own** static strings (labels, placeholders, aria-labels).
@@ -1,6 +1,7 @@
1
1
  import { type ReactNode } from 'react';
2
- import { type ThemePalette } from './applyTheme';
2
+ import { type ThemeColor, type ThemePalette } from './applyTheme';
3
3
  import { type Breakpoint } from './breakpoints';
4
+ import type { IconName } from '../icons/names';
4
5
  import { type AppMessages, type AppTranslator, type MessageOverrides, type Translator } from '../i18n/messages';
5
6
  export type ThemeMode = 'light' | 'dark';
6
7
  export interface ThemeColors {
@@ -142,6 +143,19 @@ export interface HeaderUser {
142
143
  /** Avatar image URL (falls back to a user icon). */
143
144
  avatar?: string;
144
145
  }
146
+ /** One custom item in the header account menu (rendered between the user block and **Sign out**). */
147
+ export interface HeaderMenuItem {
148
+ /** Visible label. */
149
+ label: string;
150
+ /** Leading icon (`IconName`). Optional. */
151
+ icon?: IconName;
152
+ /** Runs on click; the menu closes afterwards. */
153
+ onClick: () => void;
154
+ /** Renders the item disabled. Optional. */
155
+ disabled?: boolean;
156
+ /** Tint, e.g. `'error'` for a destructive item. Default: inherit. */
157
+ color?: ThemeColor;
158
+ }
145
159
  /**
146
160
  * `RootLayout` header configuration — the shell's top-bar controls. Set it once app-wide in
147
161
  * `config.header`, or per shell via the `RootLayout` `header` prop (the prop wins, merged over config).
@@ -175,6 +189,13 @@ export interface HeaderConfig {
175
189
  onLogout?: () => void;
176
190
  /** Signed-in user — shown in the header avatar and as a header block atop the account menu. */
177
191
  user?: HeaderUser;
192
+ /**
193
+ * Extra items in the header account menu, rendered between the user block and **Sign out**, in order.
194
+ * Only shown when `onLogout` is set (the menu does not exist otherwise). A `Divider` separates them
195
+ * from **Sign out**. (When merging a `RootLayout`/`AdminRoot` `header` prop over `config.header`, the
196
+ * prop's `menu` array **replaces** the config's — arrays don't concatenate.)
197
+ */
198
+ menu?: HeaderMenuItem[];
178
199
  }
179
200
  /**
180
201
  * UI-language config for the admin panel's **own** static strings (labels, placeholders, aria-labels).
@@ -3,5 +3,5 @@ export type { ThemePalette, ThemeColor } from './applyTheme';
3
3
  export { BREAKPOINTS, BREAKPOINT_ORDER, breakpointQuery, resolveResponsive } from './breakpoints';
4
4
  export type { Breakpoint, Responsive } from './breakpoints';
5
5
  export { ConfigProvider, useTheme, useLocales, useTranslationsNamespace, useTabsQueryKey, useNestedTabQueryKey, useStepQueryKey, useTableQueryConfig, useHeaderConfig, useT, useTranslations, useLanguage, DEFAULT_TABS_QUERY_KEY, DEFAULT_NESTED_TAB_QUERY_KEY, DEFAULT_STEP_QUERY_KEY, DEFAULT_FONT_FAMILY, } from './ConfigProvider';
6
- export type { Config, ThemeConfig, ThemeColors, ThemeMode, ConfigProviderProps, LocaleConfig, KeysConfig, TableConfig, TableQueryConfig, HeaderConfig, HeaderUser, I18nConfig, } from './ConfigProvider';
6
+ export type { Config, ThemeConfig, ThemeColors, ThemeMode, ConfigProviderProps, LocaleConfig, KeysConfig, TableConfig, TableQueryConfig, HeaderConfig, HeaderUser, HeaderMenuItem, I18nConfig, } from './ConfigProvider';
7
7
  export type { Messages, MessageKey, MessageCatalog, MessageOverrides, Translator, AppMessages, AppTranslator, } from '../i18n/messages';
@@ -3,5 +3,5 @@ export type { ThemePalette, ThemeColor } from './applyTheme';
3
3
  export { BREAKPOINTS, BREAKPOINT_ORDER, breakpointQuery, resolveResponsive } from './breakpoints';
4
4
  export type { Breakpoint, Responsive } from './breakpoints';
5
5
  export { ConfigProvider, useTheme, useLocales, useTranslationsNamespace, useTabsQueryKey, useNestedTabQueryKey, useStepQueryKey, useTableQueryConfig, useHeaderConfig, useT, useTranslations, useLanguage, DEFAULT_TABS_QUERY_KEY, DEFAULT_NESTED_TAB_QUERY_KEY, DEFAULT_STEP_QUERY_KEY, DEFAULT_FONT_FAMILY, } from './ConfigProvider';
6
- export type { Config, ThemeConfig, ThemeColors, ThemeMode, ConfigProviderProps, LocaleConfig, KeysConfig, TableConfig, TableQueryConfig, HeaderConfig, HeaderUser, I18nConfig, } from './ConfigProvider';
6
+ export type { Config, ThemeConfig, ThemeColors, ThemeMode, ConfigProviderProps, LocaleConfig, KeysConfig, TableConfig, TableQueryConfig, HeaderConfig, HeaderUser, HeaderMenuItem, I18nConfig, } from './ConfigProvider';
7
7
  export type { Messages, MessageKey, MessageCatalog, MessageOverrides, Translator, AppMessages, AppTranslator, } from '../i18n/messages';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@techzyapp/ui-library",
3
- "version": "1.0.21",
3
+ "version": "1.0.23",
4
4
  "description": "Techzy UI — reusable React component library for admin panels.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -154,6 +154,7 @@
154
154
  "@tanstack/react-table": ">=8.0.0",
155
155
  "dayjs": ">=1.11.0",
156
156
  "lexical": ">=0.45.0",
157
+ "qrcode.react": ">=4.0.0",
157
158
  "react": ">=18.0.0",
158
159
  "react-dom": ">=18.0.0",
159
160
  "react-dropzone": ">=14.0.0",
@@ -221,6 +222,9 @@
221
222
  },
222
223
  "shiki": {
223
224
  "optional": true
225
+ },
226
+ "qrcode.react": {
227
+ "optional": true
224
228
  }
225
229
  },
226
230
  "devDependencies": {
@@ -249,6 +253,7 @@
249
253
  "lexical": "^0.45.0",
250
254
  "prettier": "^3.8.3",
251
255
  "publint": "^0.3.14",
256
+ "qrcode.react": "^4.2.0",
252
257
  "react": "^19.2.6",
253
258
  "react-dom": "^19.2.6",
254
259
  "react-dropzone": "^15.0.0",
@@ -1 +0,0 @@
1
- {"version":3,"file":"AdminRoot-BDRLuMX6.cjs","sources":["../src/app/AdminRoot.tsx"],"sourcesContent":["import type { ReactNode } from 'react'\nimport { Outlet, useNavigate, useRouterState, type LinkProps } from '@tanstack/react-router'\nimport { RootLayout, UserCard, Toaster, type RootLayoutHeader } from '../components'\nimport { AuthGuard } from '../auth/AuthGuard'\n\n/** The minimal user shape `AdminRoot` reads — apps pass their own richer type via the generic. */\nexport interface AdminUser {\n name?: string\n email?: string\n avatar?: string\n}\n\nexport interface AdminRootProps<U extends AdminUser = AdminUser> {\n /** Brand mark for the sidebar top. */\n logo?: ReactNode\n /** Current user, or `null` when signed out. */\n getUser: () => U | null\n /** Clears the session; `AdminRoot` navigates to `loginPath` afterwards. */\n onLogout: () => void\n /** Route-id prefix for standalone public pages (rendered outside the shell). Default `'/_auth'`. */\n authRouteId?: string\n /** Guard target for signed-out visitors + post-logout redirect. Default `'/login'`. */\n loginPath?: string\n /** Show a `UserCard` in the sidebar footer. Default `true`. */\n showUserCard?: boolean\n /** Extra `RootLayout` header config, merged **over** the defaults (the app's fields win). */\n header?: RootLayoutHeader\n}\n\n/**\n * Root-route component for admin apps — it wires up the whole shell orchestration so an app only has to\n * supply `logo` + `getUser` + `onLogout`. Public pages (route id under `authRouteId`) render standalone;\n * everything else renders inside the guarded admin shell (`RootLayout` + a sidebar `UserCard`), gated by\n * `AuthGuard` (signed-out visitors bounce to `loginPath`). Logout clears the session and navigates to\n * `loginPath`. Mounts exactly one app-wide `<Toaster/>` (the inner `RootLayout` gets `toaster={false}`).\n *\n * `loginPath` is a plain string, cast loosely to the router's `to` type (the library can't know the\n * app's typed route tree). The generic `<U>` preserves the app's own user type through `getUser`.\n *\n * @example\n * // routes/__root.tsx\n * export const Route = createRootRoute({\n * component: () => <AdminRoot<AuthUser> logo={<Logo />} getUser={getUser} onLogout={logout} />,\n * })\n */\nexport const AdminRoot = <U extends AdminUser = AdminUser>({\n logo,\n getUser,\n onLogout,\n authRouteId = '/_auth',\n loginPath = '/login',\n showUserCard = true,\n header,\n}: AdminRootProps<U>) => {\n const navigate = useNavigate()\n const isAuthRoute = useRouterState({\n select: (s) => s.matches.some((m) => m.routeId.startsWith(authRouteId)),\n })\n const user = getUser()\n const handleLogout = () => {\n onLogout()\n navigate({ to: loginPath as LinkProps['to'] })\n }\n const content = isAuthRoute ? (\n <Outlet />\n ) : (\n <AuthGuard isAuthenticated={user != null} redirectTo={loginPath}>\n <RootLayout\n logo={logo}\n toaster={false}\n header={{\n user: user ? { name: user.name, email: user.email, avatar: user.avatar } : undefined,\n onLogout: handleLogout,\n ...header,\n }}\n sidebarFooter={\n showUserCard && user ? (\n <UserCard\n name={user.name}\n email={user.email}\n avatar={user.avatar}\n onLogout={handleLogout}\n />\n ) : undefined\n }\n >\n <Outlet />\n </RootLayout>\n </AuthGuard>\n )\n return (\n <>\n {content}\n <Toaster />\n </>\n )\n}\n"],"names":["AdminRoot","logo","getUser","onLogout","authRouteId","loginPath","showUserCard","header","navigate","useNavigate","isAuthRoute","useRouterState","s","m","user","handleLogout","content","jsx","Outlet","AuthGuard","RootLayout","UserCard","jsxs","Fragment","Toaster"],"mappings":"4OA6CaA,EAAY,CAAkC,CACzD,KAAAC,EACA,QAAAC,EACA,SAAAC,EACA,YAAAC,EAAc,SACd,UAAAC,EAAY,SACZ,aAAAC,EAAe,GACf,OAAAC,CACF,IAAyB,CACvB,MAAMC,EAAWC,EAAAA,YAAA,EACXC,EAAcC,EAAAA,eAAe,CACjC,OAASC,GAAMA,EAAE,QAAQ,KAAMC,GAAMA,EAAE,QAAQ,WAAWT,CAAW,CAAC,CAAA,CACvE,EACKU,EAAOZ,EAAA,EACPa,EAAe,IAAM,CACzBZ,EAAA,EACAK,EAAS,CAAE,GAAIH,EAA8B,CAC/C,EACMW,EAAUN,EACdO,EAAAA,IAACC,EAAAA,OAAA,CAAA,CAAO,EAERD,EAAAA,IAACE,EAAAA,UAAA,CAAU,gBAAiBL,GAAQ,KAAM,WAAYT,EACpD,SAAAY,EAAAA,IAACG,EAAAA,WAAA,CACC,KAAAnB,EACA,QAAS,GACT,OAAQ,CACN,KAAMa,EAAO,CAAE,KAAMA,EAAK,KAAM,MAAOA,EAAK,MAAO,OAAQA,EAAK,MAAA,EAAW,OAC3E,SAAUC,EACV,GAAGR,CAAA,EAEL,cACED,GAAgBQ,EACdG,EAAAA,IAACI,EAAAA,SAAA,CACC,KAAMP,EAAK,KACX,MAAOA,EAAK,MACZ,OAAQA,EAAK,OACb,SAAUC,CAAA,CAAA,EAEV,OAGN,eAACG,EAAAA,OAAA,CAAA,CAAO,CAAA,CAAA,EAEZ,EAEF,OACEI,EAAAA,KAAAC,WAAA,CACG,SAAA,CAAAP,QACAQ,EAAAA,QAAA,CAAA,CAAQ,CAAA,EACX,CAEJ"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"AdminRoot-DvF0js0q.js","sources":["../src/app/AdminRoot.tsx"],"sourcesContent":["import type { ReactNode } from 'react'\nimport { Outlet, useNavigate, useRouterState, type LinkProps } from '@tanstack/react-router'\nimport { RootLayout, UserCard, Toaster, type RootLayoutHeader } from '../components'\nimport { AuthGuard } from '../auth/AuthGuard'\n\n/** The minimal user shape `AdminRoot` reads — apps pass their own richer type via the generic. */\nexport interface AdminUser {\n name?: string\n email?: string\n avatar?: string\n}\n\nexport interface AdminRootProps<U extends AdminUser = AdminUser> {\n /** Brand mark for the sidebar top. */\n logo?: ReactNode\n /** Current user, or `null` when signed out. */\n getUser: () => U | null\n /** Clears the session; `AdminRoot` navigates to `loginPath` afterwards. */\n onLogout: () => void\n /** Route-id prefix for standalone public pages (rendered outside the shell). Default `'/_auth'`. */\n authRouteId?: string\n /** Guard target for signed-out visitors + post-logout redirect. Default `'/login'`. */\n loginPath?: string\n /** Show a `UserCard` in the sidebar footer. Default `true`. */\n showUserCard?: boolean\n /** Extra `RootLayout` header config, merged **over** the defaults (the app's fields win). */\n header?: RootLayoutHeader\n}\n\n/**\n * Root-route component for admin apps — it wires up the whole shell orchestration so an app only has to\n * supply `logo` + `getUser` + `onLogout`. Public pages (route id under `authRouteId`) render standalone;\n * everything else renders inside the guarded admin shell (`RootLayout` + a sidebar `UserCard`), gated by\n * `AuthGuard` (signed-out visitors bounce to `loginPath`). Logout clears the session and navigates to\n * `loginPath`. Mounts exactly one app-wide `<Toaster/>` (the inner `RootLayout` gets `toaster={false}`).\n *\n * `loginPath` is a plain string, cast loosely to the router's `to` type (the library can't know the\n * app's typed route tree). The generic `<U>` preserves the app's own user type through `getUser`.\n *\n * @example\n * // routes/__root.tsx\n * export const Route = createRootRoute({\n * component: () => <AdminRoot<AuthUser> logo={<Logo />} getUser={getUser} onLogout={logout} />,\n * })\n */\nexport const AdminRoot = <U extends AdminUser = AdminUser>({\n logo,\n getUser,\n onLogout,\n authRouteId = '/_auth',\n loginPath = '/login',\n showUserCard = true,\n header,\n}: AdminRootProps<U>) => {\n const navigate = useNavigate()\n const isAuthRoute = useRouterState({\n select: (s) => s.matches.some((m) => m.routeId.startsWith(authRouteId)),\n })\n const user = getUser()\n const handleLogout = () => {\n onLogout()\n navigate({ to: loginPath as LinkProps['to'] })\n }\n const content = isAuthRoute ? (\n <Outlet />\n ) : (\n <AuthGuard isAuthenticated={user != null} redirectTo={loginPath}>\n <RootLayout\n logo={logo}\n toaster={false}\n header={{\n user: user ? { name: user.name, email: user.email, avatar: user.avatar } : undefined,\n onLogout: handleLogout,\n ...header,\n }}\n sidebarFooter={\n showUserCard && user ? (\n <UserCard\n name={user.name}\n email={user.email}\n avatar={user.avatar}\n onLogout={handleLogout}\n />\n ) : undefined\n }\n >\n <Outlet />\n </RootLayout>\n </AuthGuard>\n )\n return (\n <>\n {content}\n <Toaster />\n </>\n )\n}\n"],"names":["AdminRoot","logo","getUser","onLogout","authRouteId","loginPath","showUserCard","header","navigate","useNavigate","isAuthRoute","useRouterState","s","m","user","handleLogout","content","jsx","Outlet","AuthGuard","RootLayout","UserCard","jsxs","Fragment","Toaster"],"mappings":";;;;;;AA6CO,MAAMA,IAAY,CAAkC;AAAA,EACzD,MAAAC;AAAA,EACA,SAAAC;AAAA,EACA,UAAAC;AAAA,EACA,aAAAC,IAAc;AAAA,EACd,WAAAC,IAAY;AAAA,EACZ,cAAAC,IAAe;AAAA,EACf,QAAAC;AACF,MAAyB;AACvB,QAAMC,IAAWC,EAAA,GACXC,IAAcC,EAAe;AAAA,IACjC,QAAQ,CAACC,MAAMA,EAAE,QAAQ,KAAK,CAACC,MAAMA,EAAE,QAAQ,WAAWT,CAAW,CAAC;AAAA,EAAA,CACvE,GACKU,IAAOZ,EAAA,GACPa,IAAe,MAAM;AACzB,IAAAZ,EAAA,GACAK,EAAS,EAAE,IAAIH,GAA8B;AAAA,EAC/C,GACMW,IAAUN,IACd,gBAAAO,EAACC,GAAA,CAAA,CAAO,IAER,gBAAAD,EAACE,GAAA,EAAU,iBAAiBL,KAAQ,MAAM,YAAYT,GACpD,UAAA,gBAAAY;AAAA,IAACG;AAAA,IAAA;AAAA,MACC,MAAAnB;AAAA,MACA,SAAS;AAAA,MACT,QAAQ;AAAA,QACN,MAAMa,IAAO,EAAE,MAAMA,EAAK,MAAM,OAAOA,EAAK,OAAO,QAAQA,EAAK,OAAA,IAAW;AAAA,QAC3E,UAAUC;AAAA,QACV,GAAGR;AAAA,MAAA;AAAA,MAEL,eACED,KAAgBQ,IACd,gBAAAG;AAAA,QAACI;AAAA,QAAA;AAAA,UACC,MAAMP,EAAK;AAAA,UACX,OAAOA,EAAK;AAAA,UACZ,QAAQA,EAAK;AAAA,UACb,UAAUC;AAAA,QAAA;AAAA,MAAA,IAEV;AAAA,MAGN,4BAACG,GAAA,CAAA,CAAO;AAAA,IAAA;AAAA,EAAA,GAEZ;AAEF,SACE,gBAAAI,EAAAC,GAAA,EACG,UAAA;AAAA,IAAAP;AAAA,sBACAQ,GAAA,CAAA,CAAQ;AAAA,EAAA,GACX;AAEJ;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ConfigProvider-C7DUWHrb.cjs","sources":["../src/theme/applyTheme.ts","../src/theme/ConfigProvider.tsx"],"sourcesContent":["export interface ThemePalette {\n primary: string\n /**\n * A free theme color (near-white by default) selectable via the `color` prop — it is **no longer**\n * the component surface (elevated panels use `--tz-color-surface`).\n */\n secondary: string\n /**\n * The rear-most page background — the `<body>` fill + the shell canvas that the floating panels sit\n * on; nothing else uses it. Built-in defaults: a soft off-white in light mode, a near-black in dark mode.\n */\n background: string\n /**\n * The elevated **panel surface** — cards, sidebar, inputs/forms, dropdowns, modals (the panels that\n * float over `--tz-color-background`). Built-in defaults: white in light mode, a touch lighter than\n * the canvas in dark mode. Configurable per mode like any theme color.\n */\n surface: string\n /** The single accent color — the default tint for controls (`Button`, `IconButton`, …). */\n accent: string\n success: string\n error: string\n info: string\n warning: string\n}\n\n/** Names of the theme palette tokens (maps to `--tz-color-<name>`). */\nexport type ThemeColor = keyof ThemePalette\n\nfunction hexToRgbTriplet(hex: string): string {\n let h = hex.trim().replace(/^#/, '')\n if (h.length === 3) {\n h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2]\n }\n const int = parseInt(h, 16)\n return `${(int >> 16) & 255}, ${(int >> 8) & 255}, ${int & 255}`\n}\n\n/**\n * Picks a readable text color (near-black or white) to sit on top of a solid\n * fill — used by `contained` controls so the label stays legible on light\n * colors (e.g. a light `primary` in dark mode).\n */\nfunction contrastColor(rgbTriplet: string): string {\n const [r, g, b] = rgbTriplet.split(',').map((n) => Number(n.trim()))\n const yiq = (r * 299 + g * 587 + b * 114) / 1000\n return yiq >= 150 ? '#04202b' : '#ffffff'\n}\n\n/**\n * Per-color overrides for the `contained` label color, where the automatic\n * luminance pick isn't the desired look:\n * - `secondary`: near-white fill that blends with the page, so the label uses\n * the primary color (flips with the mode) to stay readable without a border.\n * - `warning`: keep the plain white label by design.\n */\nconst CONTRAST_OVERRIDE: Readonly<Record<string, string>> = {\n secondary: 'rgb(var(--tz-color-primary-rgb))',\n warning: '#ffffff',\n}\n\nexport function applyTheme(\n theme: Partial<ThemePalette>,\n target: HTMLElement = document.documentElement,\n): void {\n for (const [name, value] of Object.entries(theme)) {\n if (!value) continue\n const triplet = hexToRgbTriplet(value)\n target.style.setProperty(`--tz-color-${name}-rgb`, triplet)\n target.style.setProperty(\n `--tz-color-${name}-contrast`,\n CONTRAST_OVERRIDE[name] ?? contrastColor(triplet),\n )\n }\n}\n","import {\n createContext,\n useCallback,\n useContext,\n useLayoutEffect,\n useMemo,\n useState,\n type ReactNode,\n} from 'react'\nimport { applyTheme, type ThemePalette } from './applyTheme'\nimport { setBreakpoints, type Breakpoint } from './breakpoints'\nimport { DEFAULT_TRANSLATIONS_NAMESPACE } from '../helpers/translations'\nimport {\n createAppTranslator,\n createTranslator,\n type AppMessages,\n type AppTranslator,\n type MessageOverrides,\n type Translator,\n} from '../i18n/messages'\n\nexport type ThemeMode = 'light' | 'dark'\n\nexport interface ThemeColors {\n /** Light-mode palette. Override any subset of the theme colors — the rest use the library defaults. */\n light?: Partial<ThemePalette>\n /** Dark-mode overrides, layered on the (merged) light palette + the library's dark defaults. */\n dark?: Partial<ThemePalette>\n}\n\n/** A content locale the app supports — a tab in `<TranslatedFields>`. */\nexport interface LocaleConfig {\n /** BCP-47 locale code, e.g. `'en-US'`. Namespaces the form field names and is the tab's fallback label. */\n code: string\n /** Human-readable tab label. Falls back to `code`. */\n label?: string\n}\n\n/** Theme settings — color overrides + initial mode. Lives under `Config.theme`. */\nexport interface ThemeConfig {\n /** Theme color overrides. Omit entirely to use the library's built-in theme. */\n colors?: ThemeColors\n /** Initial color mode. */\n mode?: ThemeMode\n /**\n * Default font family — the app-wide default the user's Settings choice overrides (persisted). One of\n * the pre-imported presets (`Inter` / `Roboto` / `Lato`) or any Google Font family name. Defaults to\n * `Inter`. A non-preset family is loaded on demand at runtime.\n */\n fontFamily?: string\n /**\n * Override the shared responsive **breakpoint** bounds (px, max-width). Keys are fixed\n * (`xxs`/`xs`/`sm`/`md`/`lg`/`xl`/`xxl`); pass any subset — the rest keep their defaults. Drives the\n * **JS** responsive layer (`useMediaQuery` tokens, `Flex`/`Grid`/`Masonry` responsive props); note\n * component CSS `@media` rules are compiled and don't follow a runtime override. E.g.\n * `breakpoints: { md: 1200, xl: 1600 }`.\n */\n breakpoints?: Partial<Record<Breakpoint, number>>\n}\n\n/**\n * The configurable key / param **names** the library's components read — grouped under `Config.keys`\n * so they live in one place. Each is overridable; omit one to use its built-in default. Grows over\n * time (e.g. `page` / `size` for paginated tables ⇒ `?page=1&size=10`).\n */\nexport interface KeysConfig {\n /**\n * URL query param name a **top-level** `<Tabs>` syncs its active tab to (e.g. `'view'` ⇒ `?view=…`),\n * unless that strip sets its own `queryKey` (or `queryKey={null}` to opt out). Defaults to `'tab'`.\n */\n tabQueryKey?: string\n /**\n * URL query param name a **nested** `<Tabs>` (one rendered inside another tab's panel) syncs to, so it\n * doesn't collide with the outer strip's `tabQueryKey` (e.g. `?tab=…&nestedTab=…`). Auto-applied by\n * nesting depth; overridable per strip via `queryKey`. Defaults to `'nestedTab'`.\n */\n nestedTabQueryKey?: string\n /**\n * URL query param name a `<Stepper queryKey>` (the bare/`true` form) syncs its active step to\n * (**1-based**, e.g. `?step=2`); a string `queryKey` overrides it per stepper. Defaults to `'step'`.\n * (The sync itself is **opt-in** — a stepper with no `queryKey` never touches the URL.)\n */\n stepQueryKey?: string\n /**\n * Top-level namespace word for `<TranslatedFields>`' form names + the nested object — e.g.\n * `'languages'` ⇒ `languages[en-US].title`. Defaults to `'translations'`.\n */\n translationsNamespace?: string\n}\n\n/**\n * How a `<Table>` builds its **server-request** params — the query it hands the consumer (as `params` /\n * `query`) in `onChange`, so a server-mode fetch doesn't hand-map page/size/search/sort every time. This is\n * the **backend transport** layer, distinct from `keys.*QueryKey` (the browser-URL sync, always page-based\n * for shareable links). Set once in `config.table.query`, override per table via the `queryMapping` prop.\n * Every field is optional; the defaults reproduce the browser-URL shape (`?page=1&size=10&search=…&sort=-key`).\n */\nexport interface TableQueryConfig {\n /** Request param name for the page / offset. Defaults to `'page'` (e.g. `'skip'` for an offset API). */\n pageParam?: string\n /** Request param name for the page size. Defaults to `'size'` (e.g. `'limit'`). */\n sizeParam?: string\n /** Request param name for the search query (omitted when the search is empty). Defaults to `'search'` (e.g. `'q'`). */\n searchParam?: string\n /**\n * Request param name holding the sort **key**. Defaults to `'sort'` (e.g. `'sortBy'`). With\n * `sortFormat: 'field'` this single param also carries the direction (`-key` = desc); with `'separate'`\n * the direction goes to `sortOrderParam`.\n */\n sortParam?: string\n /**\n * Pagination style. `'page'` (default) emits the **1-based page number** as-is (`page=2`); `'offset'`\n * emits a **zero-based offset** `(page - 1) * size` instead (`skip=10`), for skip/offset APIs.\n */\n pagination?: 'page' | 'offset'\n /**\n * Sort encoding. `'field'` (default) is a single param with a `-` prefix for descending (`sort=-price`);\n * `'separate'` splits into two params — the key in `sortParam` + the direction in `sortOrderParam`\n * (`sortBy=price&order=desc`); `'suffix'` appends the direction value to the key in a single param\n * (`sort=priceAsc` / `sort=priceDesc` with `ascValue: 'Asc'` / `descValue: 'Desc'`).\n */\n sortFormat?: 'field' | 'separate' | 'suffix'\n /** Direction param name when `sortFormat: 'separate'`. Defaults to `'order'`. */\n sortOrderParam?: string\n /**\n * Value emitted for an ascending sort — the `sortOrderParam` value when `sortFormat: 'separate'`, or the\n * suffix appended to the key when `sortFormat: 'suffix'`. Defaults to `'asc'`.\n */\n ascValue?: string\n /**\n * Value emitted for a descending sort — the `sortOrderParam` value when `sortFormat: 'separate'`, or the\n * suffix appended to the key when `sortFormat: 'suffix'`. Defaults to `'desc'`.\n */\n descValue?: string\n /**\n * What to emit for the size param when the **\"All\"** rows-per-page choice is active. A `string`/`number`\n * sets `size=<allValue>` (e.g. `0` for APIs where `limit=0` means \"all\"); omit it (default) to drop the\n * size param entirely (many APIs treat a missing limit as unbounded).\n */\n allValue?: string | number\n /**\n * How a **`multiSelect`** filter serializes into the request query: `'repeat'` (default — `cat=a&cat=b`),\n * `'csv'` (`cat=a,b`), or `'indexed'` (`cat[0]=a&cat[1]=b`).\n */\n multiSelectFormat?: 'repeat' | 'csv' | 'indexed'\n /**\n * Suffix appended to a **range** filter's param for its lower / upper bound — e.g. `Min`/`Max` (default)\n * → `priceMin`/`priceMax`; set `'_gte'`/`'_lte'`, `'[gte]'`/`'[lte]'`, `'From'`/`'To'`, … to match your API.\n */\n rangeMinSuffix?: string\n rangeMaxSuffix?: string\n}\n\n/** `<Table>`-specific configuration. Grows over time; today just the server-request query mapping. */\nexport interface TableConfig {\n /** How `<Table>` builds its server-request params (emitted as `params` / `query` in `onChange`). */\n query?: TableQueryConfig\n}\n\n/** Signed-in user shown in the shell header avatar + its account menu (see `HeaderConfig`). */\nexport interface HeaderUser {\n /** Full name — shown as the menu's name line. */\n name?: string\n /** Email shown under the name in the account menu. */\n email?: string\n /** Avatar image URL (falls back to a user icon). */\n avatar?: string\n}\n\n/**\n * `RootLayout` header configuration — the shell's top-bar controls. Set it once app-wide in\n * `config.header`, or per shell via the `RootLayout` `header` prop (the prop wins, merged over config).\n */\nexport interface HeaderConfig {\n /** Show the built-in light/dark theme toggle. Defaults to `true`. */\n theme?: boolean\n /**\n * Make the shell header **stick to the top on scroll** (fixed) instead of scrolling away (static).\n * This is the app-wide default; the user can flip it in the **Settings** drawer and their choice is\n * persisted (`localStorage['tz-header-sticky']`), overriding this. Defaults to `false` (static).\n */\n sticky?: boolean\n /** Show the browser-fullscreen toggle (auto-hides where the Fullscreen API is unavailable). Defaults to `false`. */\n fullscreen?: boolean\n /** Show the **Settings** button (opens the right-side drawer to pick the per-mode `accent`). Defaults to `true`. */\n settings?: boolean\n /** Show the nav search over the sidebar's pages (with suggestions). Defaults to `true`. */\n search?: boolean\n /**\n * Show the header **language switcher** (the `Global`-icon dropdown of `config.i18n.languages`).\n * Defaults to `true`, but it only renders when more than one UI language is configured — so pass\n * `false` to hide it even with several languages (the panel stays on its current/default language).\n */\n languages?: boolean\n /** Show the breadcrumb trail at the top of the content. Defaults to **`true`**. */\n breadcrumbs?: boolean\n /** Render the automatic page-title `h2` (the active route's `staticData.name`). Defaults to `true`. */\n pageTitle?: boolean\n /** When provided, an account `Avatar` appears; its menu has a **Sign out** item that calls this. */\n onLogout?: () => void\n /** Signed-in user — shown in the header avatar and as a header block atop the account menu. */\n user?: HeaderUser\n}\n\n/**\n * UI-language config for the admin panel's **own** static strings (labels, placeholders, aria-labels).\n * Distinct from `locales` (which is content-translation locales for `<TranslatedFields>`). The library\n * ships built-in translations (English + Georgian), so listing `languages` here is enough to get a\n * localized panel — no per-app setup. Any language the library doesn't ship is supplied via `messages`.\n */\nexport interface I18nConfig {\n /**\n * Active UI language on first load (a locale code, e.g. `'ka-GE'`). Defaults to English if listed in\n * `languages`, else the first `languages` entry, else `'en-US'`. The user's switcher choice (persisted)\n * overrides it.\n */\n language?: string\n /**\n * The UI languages the panel offers — drives the Settings language switcher. One entry = a fixed\n * language (no switcher). Defaults to English only. (Reuses the `{ code, label }` shape.)\n */\n languages?: LocaleConfig[]\n /**\n * Extra / override message catalogs for the **library's own** strings, merged **over** the built-ins\n * and keyed by language code or base language (`'ka-GE'` or `'ka'`). Use this to localize into a\n * language the library doesn't ship, or to tweak a built-in string. Unset keys fall back to English.\n */\n messages?: MessageOverrides\n /**\n * Catalogs for the **consuming app's own** UI strings — its section titles, labels, business copy —\n * keyed by language code/base then by any string key the app picks. Read via **`useTranslations()`**,\n * which binds to the active UI language, so the app's text switches together with the panel. Resolution\n * per key: exact code → base language → English (`'en'`) → the key itself. This is the app's own copy;\n * `messages` above is only for the library's built-in strings.\n */\n appMessages?: AppMessages\n}\n\n/**\n * App-level configuration passed to `<ConfigProvider config={…}>`. Groups theming under `theme`,\n * the configurable key/param names under `keys`, and keeps the rest (`locales`, …) at the top — a\n * single place to grow.\n */\nexport interface Config {\n /** Theme settings (color overrides + initial mode). Omit entirely to use the built-in theme. */\n theme?: ThemeConfig\n /** Content locales the app supports — drive `<TranslatedFields>`' tabs (one per locale). */\n locales?: LocaleConfig[]\n /** UI-language config for the panel's own strings (the library ships the translations). See `I18nConfig`. */\n i18n?: I18nConfig\n /**\n * Configurable key / query-param names the components read — e.g. the `<Tabs>` query keys\n * (`tabQueryKey` / `nestedTabQueryKey`) and the `<TranslatedFields>` namespace\n * (`translationsNamespace`). Grows over time (`page`, `size`, …).\n */\n keys?: KeysConfig\n /** `<Table>` config — today the server-request query mapping (`table.query`) shared by every table. */\n table?: TableConfig\n /**\n * `RootLayout` header config, app-wide — the shell top-bar toggles (`theme` / `fullscreen` /\n * `search` / `breadcrumbs` / `pageTitle`) + the account (`onLogout` / `user`). A `RootLayout`\n * `header` prop is merged over this (the prop wins), so a specific shell can override.\n */\n header?: HeaderConfig\n}\n\ninterface ThemeContextValue {\n mode: ThemeMode\n setMode: (mode: ThemeMode) => void\n toggleMode: () => void\n /** The persisted accent-color overrides **per mode** (a hex, or `null` when using that mode's default). */\n accentColors: Record<ThemeMode, string | null>\n /** The configured/default `accent` **per mode** (before any override) — the \"no override\" values. */\n defaultAccentColors: Record<ThemeMode, string>\n /** Set (or clear with `null`) the accent override for `mode` (defaults to the current) — persists + re-applies. */\n setAccentColor: (color: string | null, mode?: ThemeMode) => void\n locales: LocaleConfig[]\n /** Resolved translations namespace (`config.keys.translationsNamespace` ?? the built-in default). */\n translationsNamespace: string\n /** Resolved top-level tabs query key (`config.keys.tabQueryKey` ?? the built-in default). */\n tabQueryKey: string\n /** Resolved nested tabs query key (`config.keys.nestedTabQueryKey` ?? the built-in default). */\n nestedTabQueryKey: string\n /** Resolved stepper query key (`config.keys.stepQueryKey` ?? the built-in default). */\n stepQueryKey: string\n /** The `<Table>` server-request query mapping (`config.table.query` ?? `{}`). Defaults applied by `buildTableQuery`. */\n tableQuery: TableQueryConfig\n /** App-wide `RootLayout` header config (`config.header` ?? `{}`); the `RootLayout` prop merges over it. */\n header: HeaderConfig\n /** Whether the shell header sticks to the top on scroll (fixed) vs scrolls away (static). Persisted. */\n headerSticky: boolean\n /** Set + persist the header sticky/static preference (overrides `config.header.sticky`). */\n setHeaderSticky: (sticky: boolean) => void\n /** The active font family (drives `--tz-font-family`). Persisted; seeded from `config.theme.fontFamily`. */\n fontFamily: string\n /** Set + persist the font family (a preset or any Google Font name; loaded on demand). */\n setFontFamily: (family: string) => void\n /** Active UI language code (drives `t`). Persisted; seeded from `config.i18n.language` (default English). */\n language: string\n /** Set + persist the active UI language (must be one of `languages`). */\n setLanguage: (code: string) => void\n /** The UI languages the panel offers (from `config.i18n.languages`, default English only). */\n languages: LocaleConfig[]\n /** Translator for the library's built-in strings, bound to the active `language`. */\n t: Translator\n /** Translator for the **app's own** strings (`config.i18n.appMessages`), bound to the active `language`. */\n appT: AppTranslator\n}\n\nconst ThemeContext = createContext<ThemeContextValue | null>(null)\nconst STORAGE_KEY = 'tz-theme-mode'\n/** Where the user's picked accent-color override is persisted, **per mode** (survives reloads). */\nconst accentStorageKey = (mode: ThemeMode) => `tz-accent-color-${mode}`\n/** Where the user's header sticky/static choice is persisted (survives reloads). */\nconst HEADER_STICKY_KEY = 'tz-header-sticky'\n/** Where the user's chosen font family is persisted (survives reloads). */\nconst FONT_STORAGE_KEY = 'tz-font-family'\n/** Where the user's chosen UI language is persisted (survives reloads). */\nconst LOCALE_KEY = 'tz-locale'\n/** Default UI languages when `config.i18n.languages` is unset — English only. */\nconst DEFAULT_LANGUAGES: LocaleConfig[] = [{ code: 'en-US', label: 'English' }]\n/** The default font family (matches the `--tz-font-family` token's primary family). */\nexport const DEFAULT_FONT_FAMILY = 'Inter'\n/** Families already in the shipped CSS (only the default) — these skip the runtime `<link>` load. */\nconst BUNDLED_FONTS: readonly string[] = [DEFAULT_FONT_FAMILY]\n/** The full fallback stack applied to `--tz-font-family` for a chosen family (mirrors theme.css). */\nconst fontStack = (family: string) =>\n `'${family}', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif`\n\n/** Add the Google Fonts preconnect hints once, so the on-demand font fetch isn't delayed by DNS/TLS. */\nfunction ensureFontPreconnect() {\n if (typeof document === 'undefined' || document.getElementById('tz-font-preconnect')) return\n const api = document.createElement('link')\n api.id = 'tz-font-preconnect'\n api.rel = 'preconnect'\n api.href = 'https://fonts.googleapis.com'\n document.head.appendChild(api)\n const gstatic = document.createElement('link')\n gstatic.rel = 'preconnect'\n gstatic.href = 'https://fonts.gstatic.com'\n gstatic.crossOrigin = 'anonymous'\n document.head.appendChild(gstatic)\n}\n\n/**\n * Ensure a Google Fonts stylesheet `<link>` exists for `family` (deduped by id). Only the default\n * (`Inter`) ships pre-imported, so every other family — the Roboto/Lato presets and any custom pick —\n * is loaded here on first use. Bare family request (no weight axes) so it works for any font — Google\n * serves the available weights.\n */\nfunction ensureFontLoaded(family: string) {\n if (typeof document === 'undefined' || BUNDLED_FONTS.includes(family)) return\n const id = `tz-font-${family.trim().replace(/\\s+/g, '-').toLowerCase()}`\n if (document.getElementById(id)) return\n ensureFontPreconnect()\n const link = document.createElement('link')\n link.id = id\n link.rel = 'stylesheet'\n link.href = `https://fonts.googleapis.com/css2?family=${encodeURIComponent(family.trim()).replace(/%20/g, '+')}&display=swap`\n document.head.appendChild(link)\n}\n/** The built-in default URL query param name a **top-level** `<Tabs>` syncs to (no `queryKey`/config). */\nexport const DEFAULT_TABS_QUERY_KEY = 'tab'\n/** The built-in default URL query param name a **nested** `<Tabs>` syncs to (no `queryKey`/config). */\nexport const DEFAULT_NESTED_TAB_QUERY_KEY = 'nestedTab'\n/** The built-in default URL query param name a `<Stepper>` syncs to (no `queryKey`/config). */\nexport const DEFAULT_STEP_QUERY_KEY = 'step'\n/** Stable empty-locales fallback so the context value memo doesn't churn when no locales are configured. */\nconst EMPTY_LOCALES: LocaleConfig[] = []\n/** Stable empty table-query fallback so the context memo doesn't churn when no `table.query` is configured. */\nconst EMPTY_TABLE_QUERY: TableQueryConfig = {}\n/** Stable empty header fallback so the context memo doesn't churn when no `header` is configured. */\nconst EMPTY_HEADER: HeaderConfig = {}\n\n/**\n * The library's built-in light palette — the single source of truth for every theme color's default\n * value. Apps override any subset via `config.colors.light`; the rest fall back to these. (theme.css\n * holds only the structure that references these values, not the values themselves.)\n */\nconst DEFAULT_LIGHT_COLORS: ThemePalette = {\n primary: '#13404e',\n secondary: '#ffffff',\n background: '#f9f9f9', // the rear + shell canvas — a soft off-white behind the white panels\n surface: '#ffffff', // the elevated panels (cards, sidebar, inputs, dropdowns, modals)\n accent: '#056472',\n success: '#00a854',\n error: '#f04134',\n info: '#039aa1',\n warning: '#ffbf00',\n}\n\n/**\n * Built-in dark-mode overrides — only the colors that differ from light; everything else inherits the\n * (merged) light palette. Apps override any of these via `config.colors.dark`.\n */\nconst DEFAULT_DARK_COLORS: Partial<ThemePalette> = {\n primary: '#e6e8eb',\n secondary: '#191919',\n background: '#0f0f0f', // the near-black rear + canvas\n surface: '#191919', // a touch lighter than the canvas, for the elevated panels\n accent: '#16a6b4', // a brighter teal — the light-mode accent is too dark on the dark canvas\n success: '#00a854',\n error: '#f04134',\n info: '#039aa1',\n warning: '#ffbf00',\n}\n\nfunction getInitialMode(fallback: ThemeMode): ThemeMode {\n const stored = localStorage.getItem(STORAGE_KEY)\n return stored === 'light' || stored === 'dark' ? stored : fallback\n}\n\n/** The persisted per-mode accent-color overrides (a hex string per mode, or `null` when none picked). */\nfunction getInitialAccentByMode(): Record<ThemeMode, string | null> {\n return {\n light: localStorage.getItem(accentStorageKey('light')) || null,\n dark: localStorage.getItem(accentStorageKey('dark')) || null,\n }\n}\n\n/** The persisted header sticky choice (`fallback` = the app's `config.header.sticky` when unset). */\nfunction getInitialHeaderSticky(fallback: boolean): boolean {\n const stored = localStorage.getItem(HEADER_STICKY_KEY)\n return stored === '1' ? true : stored === '0' ? false : fallback\n}\n\n/** The persisted font family (`fallback` = `config.theme.fontFamily` ?? the default when unset). */\nfunction getInitialFont(fallback: string): string {\n return localStorage.getItem(FONT_STORAGE_KEY) || fallback\n}\n\n/**\n * The initial UI language: the persisted choice (if still offered), else `config.i18n.language`, else\n * English if it's among the offered languages, else the first offered, else `'en-US'`. Always clamped\n * to a code that's actually in `languages`.\n */\nfunction getInitialLanguage(languages: LocaleConfig[], configLanguage?: string): string {\n const codes = languages.map((l) => l.code)\n const stored = localStorage.getItem(LOCALE_KEY)\n if (stored && codes.includes(stored)) return stored\n if (configLanguage && codes.includes(configLanguage)) return configLanguage\n return codes.find((c) => c.toLowerCase().startsWith('en')) ?? codes[0] ?? 'en-US'\n}\n\nexport interface ConfigProviderProps {\n /** App config — theme overrides, initial mode, locales. Omit for the built-in defaults (light mode). */\n config?: Config\n children: ReactNode\n}\n\nexport function ConfigProvider({ config, children }: ConfigProviderProps) {\n const [mode, setModeState] = useState<ThemeMode>(() =>\n getInitialMode(config?.theme?.mode ?? 'light'),\n )\n // user-picked accents that override the configured/default `accent` — kept PER MODE; persisted\n const [accentByMode, setAccentByMode] =\n useState<Record<ThemeMode, string | null>>(getInitialAccentByMode)\n // user's header sticky/static choice — persisted; seeded from config.header.sticky (default static)\n const [headerSticky, setHeaderStickyState] = useState<boolean>(() =>\n getInitialHeaderSticky(config?.header?.sticky ?? false),\n )\n // user's chosen font family — persisted; seeded from config.theme.fontFamily (default Inter)\n const [fontFamily, setFontFamilyState] = useState<string>(() =>\n getInitialFont(config?.theme?.fontFamily ?? DEFAULT_FONT_FAMILY),\n )\n // UI languages offered + the active one (persisted; seeded from config.i18n, default English)\n const languages = config?.i18n?.languages ?? DEFAULT_LANGUAGES\n const i18nMessages = config?.i18n?.messages\n const appMessages = config?.i18n?.appMessages\n const [language, setLanguageState] = useState<string>(() =>\n getInitialLanguage(languages, config?.i18n?.language),\n )\n const colors = config?.theme?.colors\n\n // the configured/default palette for BOTH modes, before any accent override:\n // light = library defaults then the app's light overrides; dark = that, then the library dark deltas,\n // then the app's dark overrides. (Both computed so the Settings drawer can offer a picker per mode.)\n const basePalettes = useMemo(() => {\n const light = { ...DEFAULT_LIGHT_COLORS, ...colors?.light }\n const dark = { ...light, ...DEFAULT_DARK_COLORS, ...colors?.dark }\n return { light, dark }\n }, [colors])\n // the accent per mode when there's NO override — exposed so UI needn't hardcode it\n const defaultAccentColors = useMemo(\n () => ({ light: basePalettes.light.accent, dark: basePalettes.dark.accent }),\n [basePalettes],\n )\n\n // Commit a mode's resolved theme straight to `<html>` (CSS vars + attrs + persisted mode). Called\n // **eagerly** on change (so the DOM updates the instant you toggle, NOT after React re-renders the\n // whole subtree — which is what made the switch feel ~1s late) and from the effect below (initial\n // mount / accent change / external `setMode`). Idempotent, so applying twice is harmless.\n const applyMode = useCallback(\n (nextMode: ThemeMode, accent: string | null = accentByMode[nextMode]) => {\n const base = basePalettes[nextMode]\n applyTheme(accent ? { ...base, accent } : base)\n const root = document.documentElement\n root.setAttribute('data-tz-theme', nextMode)\n root.style.setProperty('color-scheme', nextMode)\n localStorage.setItem(STORAGE_KEY, nextMode)\n },\n [basePalettes, accentByMode],\n )\n\n useLayoutEffect(() => {\n applyMode(mode)\n }, [applyMode, mode])\n\n // commit the app's breakpoint overrides to the shared store (before paint, so token media queries\n // resolve to the configured bounds without a flash). Serialized dep so an inline object doesn't refire.\n const breakpointsConfig = config?.theme?.breakpoints\n useLayoutEffect(() => {\n setBreakpoints(breakpointsConfig)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [JSON.stringify(breakpointsConfig ?? null)])\n\n const setMode = useCallback(\n (next: ThemeMode) => {\n applyMode(next) // eager DOM update — don't wait for the re-render/commit\n setModeState(next)\n },\n [applyMode],\n )\n\n const toggleMode = useCallback(\n () => setMode(mode === 'light' ? 'dark' : 'light'),\n [mode, setMode],\n )\n\n // set (or clear with `null`) the accent override for `target` (defaults to the current mode); persists\n const setAccentColor = useCallback(\n (color: string | null, target?: ThemeMode) => {\n const m = target ?? mode\n setAccentByMode((prev) => ({ ...prev, [m]: color }))\n if (color) localStorage.setItem(accentStorageKey(m), color)\n else localStorage.removeItem(accentStorageKey(m))\n if (m === mode) applyMode(mode, color) // eager for the active mode\n },\n [mode, applyMode],\n )\n\n // set + persist the header sticky preference (overrides config.header.sticky)\n const setHeaderSticky = useCallback((sticky: boolean) => {\n setHeaderStickyState(sticky)\n localStorage.setItem(HEADER_STICKY_KEY, sticky ? '1' : '0')\n }, [])\n\n // apply the font: load it (if not preloaded) + write the stack to --tz-font-family on <html>.\n // Eager on change + in a layout effect (mount / external change), like the mode/accent commit.\n const applyFont = useCallback((family: string) => {\n ensureFontLoaded(family)\n document.documentElement.style.setProperty('--tz-font-family', fontStack(family))\n }, [])\n useLayoutEffect(() => {\n applyFont(fontFamily)\n }, [applyFont, fontFamily])\n // set + persist the chosen font family (overrides config.theme.fontFamily)\n const setFontFamily = useCallback(\n (family: string) => {\n const next = family.trim() || DEFAULT_FONT_FAMILY\n applyFont(next) // eager — don't wait for the re-render\n setFontFamilyState(next)\n localStorage.setItem(FONT_STORAGE_KEY, next)\n },\n [applyFont],\n )\n\n // set + persist the active UI language\n const setLanguage = useCallback((code: string) => {\n setLanguageState(code)\n localStorage.setItem(LOCALE_KEY, code)\n }, [])\n // the translator bound to the active language (rebuilt only when the language or overrides change)\n const t = useMemo<Translator>(\n () => createTranslator(language, i18nMessages),\n [language, i18nMessages],\n )\n // the app's-own-strings translator, bound to the same active language (rebuilt on language/catalog change)\n const appT = useMemo<AppTranslator>(\n () => createAppTranslator(language, appMessages),\n [language, appMessages],\n )\n\n const locales = config?.locales ?? EMPTY_LOCALES\n const translationsNamespace =\n config?.keys?.translationsNamespace ?? DEFAULT_TRANSLATIONS_NAMESPACE\n const tabQueryKey = config?.keys?.tabQueryKey ?? DEFAULT_TABS_QUERY_KEY\n const nestedTabQueryKey = config?.keys?.nestedTabQueryKey ?? DEFAULT_NESTED_TAB_QUERY_KEY\n const stepQueryKey = config?.keys?.stepQueryKey ?? DEFAULT_STEP_QUERY_KEY\n const tableQuery = config?.table?.query ?? EMPTY_TABLE_QUERY\n const headerConfig = config?.header ?? EMPTY_HEADER\n\n const value = useMemo<ThemeContextValue>(\n () => ({\n mode,\n setMode,\n toggleMode,\n accentColors: accentByMode,\n defaultAccentColors,\n setAccentColor,\n locales,\n translationsNamespace,\n tabQueryKey,\n nestedTabQueryKey,\n stepQueryKey,\n tableQuery,\n header: headerConfig,\n headerSticky,\n setHeaderSticky,\n fontFamily,\n setFontFamily,\n language,\n setLanguage,\n languages,\n t,\n appT,\n }),\n [\n mode,\n setMode,\n toggleMode,\n accentByMode,\n defaultAccentColors,\n setAccentColor,\n locales,\n translationsNamespace,\n tabQueryKey,\n nestedTabQueryKey,\n stepQueryKey,\n tableQuery,\n headerConfig,\n headerSticky,\n setHeaderSticky,\n fontFamily,\n setFontFamily,\n language,\n setLanguage,\n languages,\n t,\n appT,\n ],\n )\n\n return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>\n}\n\nexport function useTheme(): ThemeContextValue {\n const value = useContext(ThemeContext)\n if (!value) {\n throw new Error('useTheme must be used within a <ConfigProvider>')\n }\n return value\n}\n\n/**\n * The content locales configured on `<ConfigProvider config={{ locales }}>`. Lenient — returns `[]`\n * outside a provider (locales are optional), so `<TranslatedFields>` can also take a `locales` prop.\n */\nexport function useLocales(): LocaleConfig[] {\n return useContext(ThemeContext)?.locales ?? EMPTY_LOCALES\n}\n\n/** Fallback English translator so a component used **without** a `<ConfigProvider>` still shows text. */\nconst DEFAULT_TRANSLATOR: Translator = createTranslator('en')\n/** Fallback app translator (no catalogs) — returns the key itself, so `useTranslations()` is safe anywhere. */\nconst DEFAULT_APP_TRANSLATOR: AppTranslator = createAppTranslator('en')\n\n/**\n * The translator for the library's built-in UI strings, bound to the active `config.i18n` language.\n * **Lenient** — outside a provider it returns an English translator, so components render standalone\n * (and in tests) with their default English labels. Use it for any built-in string:\n * `t('select.noOptions')`.\n */\nexport function useT(): Translator {\n return useContext(ThemeContext)?.t ?? DEFAULT_TRANSLATOR\n}\n\n/**\n * Translator for the **consuming app's own** strings — the catalogs passed to\n * `<ConfigProvider config={{ i18n: { appMessages } }}>` — bound to the active UI language, so the app's\n * copy switches together with the panel. Free-form string keys; per key it resolves exact code → base\n * language → English (`'en'`) → the key itself, with `{name}` interpolation:\n *\n * ```tsx\n * const t = useTranslations()\n * <PageLayout title={t('customer-transactions.title')} />\n * <p>{t('customer-transactions.count', { count: 128 })}</p>\n * ```\n *\n * **Lenient** — outside a provider (or with no `appMessages`) it echoes the key back, so it's safe\n * anywhere. Use `useT()` for the library's built-in strings; use this for your own.\n */\nexport function useTranslations(): AppTranslator {\n return useContext(ThemeContext)?.appT ?? DEFAULT_APP_TRANSLATOR\n}\n\n/**\n * The active UI language + switcher data: `{ language, setLanguage, languages }`. Lenient outside a\n * provider (English, single language, no-op setter) so it's safe to call anywhere.\n */\nexport function useLanguage(): {\n language: string\n setLanguage: (code: string) => void\n languages: LocaleConfig[]\n} {\n const ctx = useContext(ThemeContext)\n return {\n language: ctx?.language ?? 'en-US',\n setLanguage: ctx?.setLanguage ?? (() => {}),\n languages: ctx?.languages ?? DEFAULT_LANGUAGES,\n }\n}\n\n/**\n * The translations namespace configured on `<ConfigProvider config={{ keys: { translationsNamespace } }}>`,\n * resolved against the built-in default (`'translations'`). Lenient outside a provider. Use it to pass\n * the same namespace to the helpers, e.g. `buildTranslations(codes, fields, useTranslationsNamespace())`.\n */\nexport function useTranslationsNamespace(): string {\n return useContext(ThemeContext)?.translationsNamespace ?? DEFAULT_TRANSLATIONS_NAMESPACE\n}\n\n/**\n * The default top-level tabs query key configured on `<ConfigProvider config={{ keys: { tabQueryKey } }}>`,\n * resolved against the built-in default (`'tab'`). Lenient outside a provider. A top-level `<Tabs>` reads\n * it as the fallback for an omitted `queryKey`, so every tab strip URL-syncs out of the box.\n */\nexport function useTabsQueryKey(): string {\n return useContext(ThemeContext)?.tabQueryKey ?? DEFAULT_TABS_QUERY_KEY\n}\n\n/**\n * The default nested tabs query key configured on\n * `<ConfigProvider config={{ keys: { nestedTabQueryKey } }}>`, resolved against the built-in default\n * (`'nestedTab'`). Lenient outside a provider. A `<Tabs>` nested inside another tab's panel uses this\n * (instead of `tabQueryKey`) so the two strips don't collide on the same URL param.\n */\nexport function useNestedTabQueryKey(): string {\n return useContext(ThemeContext)?.nestedTabQueryKey ?? DEFAULT_NESTED_TAB_QUERY_KEY\n}\n\n/**\n * The default stepper query key configured on `<ConfigProvider config={{ keys: { stepQueryKey } }}>`,\n * resolved against the built-in default (`'step'`). Lenient outside a provider. A `<Stepper queryKey>`\n * (the bare/`true` opt-in form) reads it as the param name; a string `queryKey` overrides it.\n */\nexport function useStepQueryKey(): string {\n return useContext(ThemeContext)?.stepQueryKey ?? DEFAULT_STEP_QUERY_KEY\n}\n\n/**\n * The `<Table>` server-request query mapping configured on `<ConfigProvider config={{ table: { query } }}>`\n * (`{}` when unset / outside a provider). `<Table>` merges its own `queryMapping` prop over this, then feeds\n * the result to `buildTableQuery`, which applies the field defaults — so an unconfigured table emits the\n * default page-based `?page=…&size=…&search=…&sort=…` shape.\n */\nexport function useTableQueryConfig(): TableQueryConfig {\n return useContext(ThemeContext)?.tableQuery ?? EMPTY_TABLE_QUERY\n}\n\n/**\n * The app-wide `RootLayout` header config set on `<ConfigProvider config={{ header }}>` (`{}` when\n * unset / outside a provider). `RootLayout` merges its own `header` prop over this (the prop wins), so\n * a specific shell can override the app-wide defaults.\n */\nexport function useHeaderConfig(): HeaderConfig {\n return useContext(ThemeContext)?.header ?? EMPTY_HEADER\n}\n"],"names":["hexToRgbTriplet","hex","h","int","contrastColor","rgbTriplet","r","g","b","n","CONTRAST_OVERRIDE","applyTheme","theme","target","name","value","triplet","ThemeContext","createContext","STORAGE_KEY","accentStorageKey","mode","HEADER_STICKY_KEY","FONT_STORAGE_KEY","LOCALE_KEY","DEFAULT_LANGUAGES","DEFAULT_FONT_FAMILY","BUNDLED_FONTS","fontStack","family","ensureFontPreconnect","api","gstatic","ensureFontLoaded","id","link","DEFAULT_TABS_QUERY_KEY","DEFAULT_NESTED_TAB_QUERY_KEY","DEFAULT_STEP_QUERY_KEY","EMPTY_LOCALES","EMPTY_TABLE_QUERY","EMPTY_HEADER","DEFAULT_LIGHT_COLORS","DEFAULT_DARK_COLORS","getInitialMode","fallback","stored","getInitialAccentByMode","getInitialHeaderSticky","getInitialFont","getInitialLanguage","languages","configLanguage","codes","l","c","ConfigProvider","config","children","setModeState","useState","_a","accentByMode","setAccentByMode","headerSticky","setHeaderStickyState","fontFamily","setFontFamilyState","i18nMessages","_b","appMessages","_c","language","setLanguageState","colors","_d","basePalettes","useMemo","light","dark","defaultAccentColors","applyMode","useCallback","nextMode","accent","base","root","useLayoutEffect","breakpointsConfig","_e","setBreakpoints","setMode","next","toggleMode","setAccentColor","color","m","prev","setHeaderSticky","sticky","applyFont","setFontFamily","setLanguage","code","t","createTranslator","appT","createAppTranslator","locales","translationsNamespace","_f","DEFAULT_TRANSLATIONS_NAMESPACE","tabQueryKey","_g","nestedTabQueryKey","_h","stepQueryKey","_i","tableQuery","_j","headerConfig","jsx","useTheme","useContext","useLocales","DEFAULT_TRANSLATOR","DEFAULT_APP_TRANSLATOR","useT","useTranslations","useLanguage","ctx","useTranslationsNamespace","useTabsQueryKey","useNestedTabQueryKey","useStepQueryKey","useTableQueryConfig","useHeaderConfig"],"mappings":"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"}