@conduction/nextcloud-vue 2.78.0 → 2.80.0

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 (259) hide show
  1. package/dist/bundled-packages.json +0 -2
  2. package/dist/esm/bundled-packages.json +0 -2
  3. package/dist/esm/components/CnActionButtons/CnActionButtons.vue2.js.map +1 -1
  4. package/dist/esm/components/CnActionButtons/CnActionButtons.vue3.js +3 -1
  5. package/dist/esm/components/CnActionButtons/CnActionButtons.vue3.js.map +1 -1
  6. package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js +32 -3
  7. package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js.map +1 -1
  8. package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js +115 -104
  9. package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js.map +1 -1
  10. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +12 -2
  11. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
  12. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
  13. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js +39 -3
  14. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js.map +1 -1
  15. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue3.js.map +1 -1
  16. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js +158 -0
  17. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
  18. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js +157 -96
  19. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js.map +1 -1
  20. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +139 -1
  21. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
  22. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +140 -92
  23. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
  24. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +77 -0
  25. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  26. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +5 -2
  27. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  28. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +62 -4
  29. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  30. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  31. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js +85 -1
  32. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
  33. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js +43 -4
  34. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
  35. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue.js +11 -0
  36. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue.js.map +1 -0
  37. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js +736 -0
  38. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js.map +1 -0
  39. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js +238 -0
  40. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js.map +1 -0
  41. package/dist/esm/components/CnFactsWidget/index.js +30 -0
  42. package/dist/esm/components/CnFactsWidget/index.js.map +1 -0
  43. package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue.js +10 -0
  44. package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue.js.map +1 -0
  45. package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue2.js +551 -0
  46. package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue2.js.map +1 -0
  47. package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue3.js +183 -0
  48. package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue3.js.map +1 -0
  49. package/dist/esm/components/CnFieldListWidget/index.js +29 -0
  50. package/dist/esm/components/CnFieldListWidget/index.js.map +1 -0
  51. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +173 -5
  52. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
  53. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +181 -99
  54. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
  55. package/dist/esm/components/CnFilesBrowser/filesBrowser.js +29 -11
  56. package/dist/esm/components/CnFilesBrowser/filesBrowser.js.map +1 -1
  57. package/dist/esm/components/CnFilesBrowser/openRegisterSource.js +252 -0
  58. package/dist/esm/components/CnFilesBrowser/openRegisterSource.js.map +1 -0
  59. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js +66 -18
  60. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js.map +1 -1
  61. package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js +4 -4
  62. package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js.map +1 -1
  63. package/dist/esm/components/CnFormPage/CnFormPage.vue2.js +18 -3
  64. package/dist/esm/components/CnFormPage/CnFormPage.vue2.js.map +1 -1
  65. package/dist/esm/components/CnFormPage/CnFormPage.vue3.js.map +1 -1
  66. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +330 -74
  67. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  68. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +34 -15
  69. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  70. package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue.js +10 -0
  71. package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue.js.map +1 -0
  72. package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue2.js +99 -0
  73. package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue2.js.map +1 -0
  74. package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue3.js +48 -0
  75. package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue3.js.map +1 -0
  76. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js +100 -3
  77. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js.map +1 -1
  78. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js +4 -2
  79. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js.map +1 -1
  80. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue2.js +29 -1
  81. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue2.js.map +1 -1
  82. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue3.js.map +1 -1
  83. package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js +3 -2
  84. package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js.map +1 -1
  85. package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue3.js.map +1 -1
  86. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +10 -0
  87. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js.map +1 -0
  88. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +387 -0
  89. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -0
  90. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js +169 -0
  91. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -0
  92. package/dist/esm/components/CnRecordListWidget/index.js +31 -0
  93. package/dist/esm/components/CnRecordListWidget/index.js.map +1 -0
  94. package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue2.js.map +1 -1
  95. package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue3.js +1 -1
  96. package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue3.js.map +1 -1
  97. package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue.js +10 -0
  98. package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue.js.map +1 -0
  99. package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue2.js +351 -0
  100. package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue2.js.map +1 -0
  101. package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue3.js +71 -0
  102. package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue3.js.map +1 -0
  103. package/dist/esm/components/CnSectionsWidget/index.js +35 -0
  104. package/dist/esm/components/CnSectionsWidget/index.js.map +1 -0
  105. package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js +81 -2
  106. package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js.map +1 -1
  107. package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue3.js.map +1 -1
  108. package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js.map +1 -1
  109. package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js +1 -0
  110. package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js.map +1 -1
  111. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +152 -8
  112. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
  113. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +84 -23
  114. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
  115. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +4 -0
  116. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
  117. package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue2.js +13 -0
  118. package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue2.js.map +1 -1
  119. package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue3.js.map +1 -1
  120. package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue2.js +106 -2
  121. package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue2.js.map +1 -1
  122. package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue3.js +105 -53
  123. package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue3.js.map +1 -1
  124. package/dist/esm/composables/useAppManifest.js +8 -3
  125. package/dist/esm/composables/useAppManifest.js.map +1 -1
  126. package/dist/esm/composables/useFormDraft.js +140 -9
  127. package/dist/esm/composables/useFormDraft.js.map +1 -1
  128. package/dist/esm/index.js +5 -0
  129. package/dist/esm/index.js.map +1 -1
  130. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue2.js +28 -20
  131. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue2.js.map +1 -1
  132. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue3.js +9 -0
  133. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue3.js.map +1 -1
  134. package/dist/esm/integrations/builtin/field-inspection.js +21 -0
  135. package/dist/esm/integrations/builtin/field-inspection.js.map +1 -1
  136. package/dist/esm/integrations/offline/checklistSubmission.js +141 -0
  137. package/dist/esm/integrations/offline/checklistSubmission.js.map +1 -0
  138. package/dist/esm/integrations/offline/fieldCollectionHelpers.js +70 -5
  139. package/dist/esm/integrations/offline/fieldCollectionHelpers.js.map +1 -1
  140. package/dist/esm/integrations/offline/index.js +2 -1
  141. package/dist/esm/integrations/offline/index.js.map +1 -1
  142. package/dist/esm/integrations/offline/offlineDb.js +6 -1
  143. package/dist/esm/integrations/offline/offlineDb.js.map +1 -1
  144. package/dist/esm/integrations/offline/syncReplayService.js +8 -2
  145. package/dist/esm/integrations/offline/syncReplayService.js.map +1 -1
  146. package/dist/esm/l10n/en.json.js +72 -1
  147. package/dist/esm/l10n/en.json.js.map +1 -1
  148. package/dist/esm/l10n/nl.json.js +120 -2
  149. package/dist/esm/l10n/nl.json.js.map +1 -1
  150. package/dist/esm/nextcloud-vue.css +1314 -74
  151. package/dist/esm/utils/boardDate.js +193 -0
  152. package/dist/esm/utils/boardDate.js.map +1 -0
  153. package/dist/esm/utils/detailActionModel.js +60 -3
  154. package/dist/esm/utils/detailActionModel.js.map +1 -1
  155. package/dist/esm/utils/dynamicProperties.js +5 -1
  156. package/dist/esm/utils/dynamicProperties.js.map +1 -1
  157. package/dist/esm/utils/fillTemplate.js +114 -0
  158. package/dist/esm/utils/fillTemplate.js.map +1 -0
  159. package/dist/esm/utils/libraryWidgetKeys.js +4 -0
  160. package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
  161. package/dist/esm/utils/queryPresets.js +96 -0
  162. package/dist/esm/utils/queryPresets.js.map +1 -0
  163. package/dist/esm/utils/resolveFilterTokens.js +11 -0
  164. package/dist/esm/utils/resolveFilterTokens.js.map +1 -1
  165. package/dist/esm/utils/schema.js +21 -0
  166. package/dist/esm/utils/schema.js.map +1 -1
  167. package/dist/esm/utils/sentinelTokens.js +3 -3
  168. package/dist/esm/utils/sentinelTokens.js.map +1 -1
  169. package/dist/esm/utils/validateManifestV2.compiled.js +57 -6
  170. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  171. package/dist/esm/utils/widgetDispatch.js +7 -1
  172. package/dist/esm/utils/widgetDispatch.js.map +1 -1
  173. package/dist/nextcloud-vue.cjs.js +14278 -8169
  174. package/dist/nextcloud-vue.cjs.js.map +2 -2
  175. package/dist/nextcloud-vue.css +1314 -74
  176. package/l10n/en.json +72 -1
  177. package/l10n/nl.json +120 -2
  178. package/package.json +1 -1
  179. package/scripts/build-validators.js +26 -0
  180. package/src/components/CnActionButtons/CnActionButtons.vue +2 -0
  181. package/src/components/CnActionsBar/CnActionsBar.md +4 -0
  182. package/src/components/CnActionsBar/CnActionsBar.vue +83 -42
  183. package/src/components/CnAppRoot/CnAppRoot.vue +12 -2
  184. package/src/components/CnBannerWidget/CnBannerWidget.vue +39 -3
  185. package/src/components/CnCellRenderer/CnCellRenderer.vue +306 -2
  186. package/src/components/CnDashboardPage/CnDashboardPage.vue +219 -4
  187. package/src/components/CnDataTable/CnDataTable.md +2 -0
  188. package/src/components/CnDataTable/CnDataTable.vue +82 -2
  189. package/src/components/CnDetailPage/CnDetailPage.md +1 -1
  190. package/src/components/CnDetailPage/CnDetailPage.vue +63 -3
  191. package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +127 -1
  192. package/src/components/CnFactsWidget/CnFactsWidget.vue +1050 -0
  193. package/src/components/CnFactsWidget/index.js +29 -0
  194. package/src/components/CnFieldListWidget/CnFieldListWidget.vue +746 -0
  195. package/src/components/CnFieldListWidget/index.js +28 -0
  196. package/src/components/CnFilesBrowser/CnFilesBrowser.vue +232 -11
  197. package/src/components/CnFilesBrowser/filesBrowser.js +43 -2
  198. package/src/components/CnFilesBrowser/index.js +1 -0
  199. package/src/components/CnFilesBrowser/openRegisterSource.js +248 -0
  200. package/src/components/CnFormDialog/CnFormDialog.md +9 -3
  201. package/src/components/CnFormDialog/CnFormDialog.vue +70 -22
  202. package/src/components/CnFormPage/CnFormPage.vue +18 -3
  203. package/src/components/CnIndexPage/CnIndexPage.vue +281 -9
  204. package/src/components/CnIndexPage/CnIndexPageWidgets.vue +169 -0
  205. package/src/components/CnObjectSidebar/CnFilesTab.vue +103 -4
  206. package/src/components/CnPageRenderer/CnPageRenderer.vue +29 -1
  207. package/src/components/CnQuickFilterBar/CnQuickFilterBar.vue +3 -2
  208. package/src/components/CnRecordListWidget/CnRecordListWidget.vue +603 -0
  209. package/src/components/CnRecordListWidget/index.js +30 -0
  210. package/src/components/CnSavedViewsControl/CnSavedViewsControl.vue +1 -1
  211. package/src/components/CnSectionsWidget/CnSectionsWidget.vue +489 -0
  212. package/src/components/CnSectionsWidget/index.js +34 -0
  213. package/src/components/CnStagesWidget/CnStagesWidget.vue +81 -2
  214. package/src/components/CnStatWidget/CnStatWidget.vue +1 -1
  215. package/src/components/CnTabsWidget/CnTabsWidget.vue +214 -9
  216. package/src/components/CnWidgetGrid/registerDashboardWidgets.js +4 -0
  217. package/src/components/CnWidgetObjectTable/CnWidgetObjectTable.vue +13 -0
  218. package/src/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue +188 -4
  219. package/src/components/index.js +5 -1
  220. package/src/composables/__tests__/useFormDraft.spec.js +69 -0
  221. package/src/composables/useAppManifest.js +8 -3
  222. package/src/composables/useFormDraft.js +139 -8
  223. package/src/css/form-field.css +14 -0
  224. package/src/css/index-page.css +71 -0
  225. package/src/css/kpi-card.css +32 -0
  226. package/src/css/look-board-detail.css +87 -0
  227. package/src/css/look-board-index.css +143 -14
  228. package/src/css/look-board.css +114 -2
  229. package/src/css/table.css +56 -0
  230. package/src/index.js +8 -0
  231. package/src/integrations/builtin/field-inspection/CnFieldInspectionCard.vue +35 -20
  232. package/src/integrations/builtin/field-inspection.js +21 -0
  233. package/src/integrations/offline/checklistSubmission.js +137 -0
  234. package/src/integrations/offline/fieldCollectionHelpers.js +69 -4
  235. package/src/integrations/offline/index.js +3 -0
  236. package/src/integrations/offline/offlineDb.js +6 -1
  237. package/src/integrations/offline/syncReplayService.js +8 -2
  238. package/src/schemas/app-manifest-v2.schema.json +149 -5
  239. package/src/utils/boardDate.js +189 -0
  240. package/src/utils/detailActionModel.js +59 -2
  241. package/src/utils/dynamicProperties.js +5 -1
  242. package/src/utils/fillTemplate.js +110 -0
  243. package/src/utils/libraryWidgetKeys.js +4 -0
  244. package/src/utils/queryPresets.js +93 -0
  245. package/src/utils/resolveFilterTokens.js +11 -0
  246. package/src/utils/schema.js +21 -0
  247. package/src/utils/sentinelTokens.js +3 -3
  248. package/src/utils/validateManifestV2.compiled.js +57 -2
  249. package/src/utils/widgetDispatch.js +7 -1
  250. package/dist/esm/_virtual/equal.js +0 -4
  251. package/dist/esm/_virtual/equal.js.map +0 -1
  252. package/dist/esm/_virtual/ucs2length.js +0 -4
  253. package/dist/esm/_virtual/ucs2length.js.map +0 -1
  254. package/dist/esm/node_modules/ajv/dist/runtime/equal.js +0 -9
  255. package/dist/esm/node_modules/ajv/dist/runtime/equal.js.map +0 -1
  256. package/dist/esm/node_modules/ajv/dist/runtime/ucs2length.js +0 -25
  257. package/dist/esm/node_modules/ajv/dist/runtime/ucs2length.js.map +0 -1
  258. package/dist/esm/node_modules/fast-deep-equal/index.js +0 -47
  259. package/dist/esm/node_modules/fast-deep-equal/index.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sources":["../../../src/utils/schema.js"],"sourcesContent":["/**\n * Schema utility functions for auto-generating table columns, cell formatting,\n * form field definitions, and faceted filter definitions from OpenRegister\n * schema property definitions.\n *\n * @module utils/schema\n */\n\nimport { schemaRefSlug } from './schemaRefSlug.js'\n\n/**\n * Default column widths per property type/format.\n */\nconst DEFAULT_WIDTHS = {\n\tboolean: '80px',\n\tinteger: '100px',\n\tnumber: '100px',\n\t'string:uuid': '140px',\n\t'string:date-time': '180px',\n\t'string:email': '200px',\n}\n\n/**\n * Get default width for a property type + format combination.\n *\n * @param {string} type Property type\n * @param {string} [format] Property format\n * @return {string|undefined} CSS width or undefined\n */\nfunction getDefaultWidth(type, format) {\n\tif (format) {\n\t\treturn DEFAULT_WIDTHS[`${type}:${format}`]\n\t}\n\treturn DEFAULT_WIDTHS[type]\n}\n\n/**\n * Generate CnDataTable column definitions from a schema's properties.\n *\n * Reads `schema.properties` and creates column objects sorted by the `order`\n * hint (if present) then alphabetically. Filters out properties marked\n * `visible: false`. Supports include/exclude lists and per-column overrides.\n *\n * @param {object} schema The schema object with a `properties` field\n * @param {object} [options] Configuration options\n * @param {string[]} [options.exclude] Property keys to exclude\n * @param {string[]} [options.include] Property keys to include (whitelist mode)\n * @param {object} [options.overrides] Per-key column overrides, e.g. `{ status: { width: '200px' } }`\n * @param {(text: string) => string} [options.translate] Optional display-layer translation function applied to each column label. Schema property titles are authored in English as the canonical source; consumers pass their bound `t()` (via the injected `cnTranslate`) so the visible header follows the user's language. When omitted, the label is the English source string unchanged (pure, backward-compatible).\n * @return {Array<{key: string, label: string, sortable: boolean, type: string, format: string, width: string}>}\n */\nexport function columnsFromSchema(schema, options = {}) {\n\tconst { exclude = [], include = null, overrides = {}, translate } = options\n\tconst tr = typeof translate === 'function' ? translate : (text) => text\n\n\tif (!schema || !schema.properties) {\n\t\treturn []\n\t}\n\n\tconst entries = Object.entries(schema.properties)\n\t\t.filter(([key, prop]) => {\n\t\t\t// Skip properties marked as not visible\n\t\t\tif (prop.visible === false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Apply exclude list\n\t\t\tif (exclude.includes(key)) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Apply include whitelist\n\t\t\tif (include && !include.includes(key)) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Skip complex object types by default (they don't render well in tables)\n\t\t\tif (prop.type === 'object') {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn true\n\t\t})\n\t\t.sort(([keyA, propA], [keyB, propB]) => {\n\t\t\t// Sort by order hint first, then alphabetically\n\t\t\tconst orderA = typeof propA.order === 'number' ? propA.order : Infinity\n\t\t\tconst orderB = typeof propB.order === 'number' ? propB.order : Infinity\n\t\t\tif (orderA !== orderB) {\n\t\t\t\treturn orderA - orderB\n\t\t\t}\n\t\t\treturn keyA.localeCompare(keyB)\n\t\t})\n\n\treturn entries.map(([key, prop]) => {\n\t\tconst column = {\n\t\t\tkey,\n\t\t\tlabel: tr(prop.title || key),\n\t\t\t// The schema already explains what the property MEANS; carrying that\n\t\t\t// through as the header tooltip means a column like \"Maturity\" or a\n\t\t\t// computed score explains itself in place, instead of the description\n\t\t\t// living only in the schema editor where no reader of the table looks.\n\t\t\tdescription: prop.description ? tr(prop.description) : '',\n\t\t\tsortable: true,\n\t\t\ttype: prop.type || 'string',\n\t\t\tformat: prop.format || null,\n\t\t}\n\n\t\t// Apply default width\n\t\tconst defaultWidth = getDefaultWidth(column.type, column.format)\n\t\tif (defaultWidth) {\n\t\t\tcolumn.width = defaultWidth\n\t\t}\n\n\t\t// Store enum values for cell renderer\n\t\tif (prop.enum) {\n\t\t\tcolumn.enum = prop.enum\n\t\t}\n\n\t\t// Store items type for arrays\n\t\tif (prop.items) {\n\t\t\tcolumn.items = prop.items\n\t\t}\n\n\t\t// Apply per-column overrides\n\t\tif (overrides[key]) {\n\t\t\tObject.assign(column, overrides[key])\n\t\t}\n\n\t\treturn column\n\t})\n}\n\n/**\n * Format a cell value based on its schema property definition.\n *\n * Handles dates, booleans, arrays, numbers, UUIDs, emails, and markdown.\n * Returns a plain string suitable for display in a table cell.\n *\n * @param {unknown} value The raw value\n * @param {object} [property] The schema property definition `{ type, format, enum, items }`\n * @param {object} [options] Formatting options\n * @param {number} [options.truncate] Maximum string length before truncation\n * @return {string} Formatted display string\n */\nexport function formatValue(value, property = {}, options = {}) {\n\tconst { truncate = 100 } = options\n\n\t// Null/undefined/empty\n\tif (value === null || value === undefined || value === '') {\n\t\treturn '—'\n\t}\n\n\tconst { type = 'string', format } = property\n\n\t// Boolean\n\tif (type === 'boolean' || typeof value === 'boolean') {\n\t\treturn value ? '✓' : '—'\n\t}\n\n\t// Number/Integer\n\tif (type === 'integer' || type === 'number') {\n\t\tconst num = Number(value)\n\t\tif (Number.isNaN(num)) {\n\t\t\treturn String(value)\n\t\t}\n\t\treturn num.toLocaleString()\n\t}\n\n\t// Array\n\tif (type === 'array' || Array.isArray(value)) {\n\t\tif (!Array.isArray(value)) {\n\t\t\treturn String(value)\n\t\t}\n\t\tif (value.length === 0) {\n\t\t\treturn '—'\n\t\t}\n\t\t// Stringify each entry so an array of OBJECTS never collapses to the\n\t\t// useless \"[object Object]\" that `Array.prototype.join` produces — a\n\t\t// nested object renders as compact JSON instead (ADR-062: a value cell\n\t\t// must never show \"[object Object]\"). Rich array rendering (inline\n\t\t// tables / chips) lives in CnObjectDataWidget; this is the flat-string\n\t\t// fallback used by tables and truncated cells.\n\t\tconst parts = value.map((v) => {\n\t\t\tif (v !== null && typeof v === 'object') {\n\t\t\t\ttry {\n\t\t\t\t\treturn JSON.stringify(v)\n\t\t\t\t} catch {\n\t\t\t\t\treturn '[Object]'\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn String(v)\n\t\t})\n\t\t// For short arrays, join values\n\t\tif (parts.length <= 3) {\n\t\t\treturn parts.join(', ')\n\t\t}\n\t\treturn `${parts.slice(0, 3).join(', ')} +${parts.length - 3}`\n\t}\n\n\t// Object — render as JSON; tables truncate, multi-line value cells wrap with `<pre>`.\n\tif (type === 'object' || (typeof value === 'object' && value !== null)) {\n\t\ttry {\n\t\t\treturn truncateString(JSON.stringify(value, null, 2), truncate)\n\t\t} catch {\n\t\t\treturn '[Object]'\n\t\t}\n\t}\n\n\t// String types\n\tconst str = String(value)\n\n\t// Date-time\n\tif (format === 'date-time' || format === 'date') {\n\t\ttry {\n\t\t\tconst date = new Date(str)\n\t\t\tif (Number.isNaN(date.getTime())) {\n\t\t\t\treturn str\n\t\t\t}\n\t\t\tif (format === 'date') {\n\t\t\t\treturn date.toLocaleDateString(undefined, {\n\t\t\t\t\tday: '2-digit',\n\t\t\t\t\tmonth: '2-digit',\n\t\t\t\t\tyear: 'numeric',\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn date.toLocaleDateString(undefined, {\n\t\t\t\tday: '2-digit',\n\t\t\t\tmonth: '2-digit',\n\t\t\t\tyear: 'numeric',\n\t\t\t}) + ', ' + date.toLocaleTimeString(undefined, {\n\t\t\t\thour: '2-digit',\n\t\t\t\tminute: '2-digit',\n\t\t\t\tsecond: '2-digit',\n\t\t\t})\n\t\t} catch {\n\t\t\treturn str\n\t\t}\n\t}\n\n\t// UUID — truncate to first 8 chars\n\tif (format === 'uuid') {\n\t\tif (str.length > 8) {\n\t\t\treturn str.substring(0, 8) + '...'\n\t\t}\n\t\treturn str\n\t}\n\n\t// URI — show truncated\n\tif (format === 'uri' || format === 'url') {\n\t\ttry {\n\t\t\tconst url = new URL(str)\n\t\t\treturn url.hostname + url.pathname.substring(0, 20)\n\t\t} catch {\n\t\t\treturn truncateString(str, truncate)\n\t\t}\n\t}\n\n\t// Markdown — strip formatting\n\tif (format === 'markdown') {\n\t\tconst stripped = str\n\t\t\t.replace(/#{1,6}\\s+/g, '') // headings\n\t\t\t.replace(/[*_]{1,3}([^*_]+)[*_]{1,3}/g, '$1') // bold/italic\n\t\t\t.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1') // links\n\t\t\t.replace(/`{1,3}[^`]*`{1,3}/g, '') // code\n\t\t\t.replace(/\\n+/g, ' ') // newlines\n\t\t\t.trim()\n\t\treturn truncateString(stripped, truncate)\n\t}\n\n\t// Email — display as-is (no truncation)\n\tif (format === 'email') {\n\t\treturn str\n\t}\n\n\t// Plain string — truncate if needed\n\treturn truncateString(str, truncate)\n}\n\n/**\n * Truncate a string to the given length, adding ellipsis if needed.\n *\n * @param {string} str The string to truncate\n * @param {number} maxLength Maximum length\n * @return {string} Truncated string\n */\nfunction truncateString(str, maxLength) {\n\tif (str.length <= maxLength) {\n\t\treturn str\n\t}\n\treturn str.substring(0, maxLength) + '...'\n}\n\n/**\n * Resolve the form widget type for a JSON Schema property.\n *\n * Resolution priority (first match wins):\n * 1. Explicit `prop.widget` — pass-through custom widget name\n * 2. `prop.enum` → `'select'`\n * 3. OpenRegister object reference: `prop.$ref` (a string schema slug) →\n * `'select'`; `array` + `items.$ref` → `'multiselect'`. The consuming\n * surface (CnFormDialog) resolves the reference to a searchable dropdown\n * of the referenced objects (label = human name, value = UUID).\n * 4. Nextcloud user reference: `referenceType: 'nextcloud-user'` (or\n * `format: 'user'`/`'username'`/`'nc-user'`) → `'user'`; an array of such\n * properties → `'user-multiselect'`. CnFormDialog resolves these to a\n * searchable dropdown of real Nextcloud users (label = display name,\n * value = UID). A Nextcloud group (`referenceType: 'nextcloud-group'` or\n * `format: 'nc-group'`) → `'group'`, an array of groups →\n * `'group-multiselect'`. `format: 'language'` → `'language'` and\n * `format: 'timezone'` → `'timezone'` (both searchable code lists).\n * 5. Type-based: `boolean` → `'checkbox'`, `integer`/`number` → `'number'`,\n * `array` + `items.enum` → `'multiselect'`, `array` → `'tags'`\n * 6. Format-based: `date-time` → `'datetime'`, `date` → `'date'`,\n * `email` → `'email'`, `uri`/`url` → `'url'`,\n * `markdown`/`textarea` → `'textarea'`\n * 7. Long text: `maxLength > 255` → `'textarea'`\n * 8. Fallback → `'text'`\n *\n * @param {object} prop The schema property definition (type, format, enum, widget, items, maxLength)\n * @return {string} Widget identifier: 'text'|'email'|'url'|'number'|'checkbox'|'select'|'multiselect'|'user'|'user-multiselect'|'tags'|'textarea'|'date'|'datetime' or a custom string\n */\n/**\n * Normalise a JSON-Schema `$ref` value into an OpenRegister schema reference\n * identifier. OpenRegister authors a `$ref` as a schema *slug* (string) but\n * persists/serves it as the numeric schema *id* (e.g. `85`). Both forms are\n * valid object-reference targets (the objects API resolves either).\n *\n * The schema editor writes the JSON-Pointer form — `#/components/schemas/<slug>`\n * — so a `$ref` reaching here may be a pointer rather than a bare slug. Passing\n * the whole pointer through as the schema identifier made the object picker query\n * a schema literally named \"#/components/schemas/cow\", which matches nothing: the\n * dropdown rendered but came back empty. Take the tail after the last `/`, which\n * is what the editor itself does when it resolves a $ref back to a schema.\n *\n * A `$ref` is authored as the schema's PascalCase (or spaced) *title*, not\n * its slug (`ReportPeriod`, not `report-period`); the objects API 404s on\n * the title for any multi-word schema (defect 7, learniq round 1). Routing\n * the tail through {@link schemaRefSlug} fixes that once here, for every\n * consumer of `reference.schema` built below.\n *\n * @param {unknown} ref A `$ref` value (`prop.$ref` or `prop.items.$ref`).\n * @return {string|number|null} The reference identifier, or null.\n */\nfunction normalizeRef(ref) {\n\tif (typeof ref === 'string' && ref !== '') {\n\t\tconst tail = ref.includes('/') ? ref.substring(ref.lastIndexOf('/') + 1) : ref\n\t\tif (tail === '') {\n\t\t\treturn null\n\t\t}\n\t\tconst slug = schemaRefSlug(tail)\n\t\treturn slug !== '' ? slug : null\n\t}\n\tif (typeof ref === 'number' && !Number.isNaN(ref)) {\n\t\treturn ref\n\t}\n\treturn null\n}\n\n/**\n * Whether a (single-value) schema property represents a Nextcloud user.\n *\n * A property is a user field when it declares `referenceType: 'nextcloud-user'`\n * (preferred) OR `format: 'user'` / `format: 'username'`. The consuming surface\n * (CnFormDialog) renders such a property as a searchable dropdown of real\n * Nextcloud users (label = display name, value = UID) instead of a free-text box.\n *\n * @param {object} prop A schema property definition (or `items` for an array).\n * @return {boolean} True when the property marks a Nextcloud user.\n */\nfunction isUserProp(prop) {\n\tif (!prop || typeof prop !== 'object') {\n\t\treturn false\n\t}\n\tif (prop.referenceType === 'nextcloud-user' || prop.widget === 'user') {\n\t\treturn true\n\t}\n\tconst format = prop.format || ''\n\treturn format === 'user' || format === 'username' || format === 'nc-user'\n}\n\n/**\n * Whether a (single-value) schema property represents a Nextcloud group.\n *\n * A property is a group field when it declares `referenceType: 'nextcloud-group'`\n * or `format: 'nc-group'`. CnFormDialog renders it as a searchable dropdown of\n * Nextcloud groups (label = display name, value = group id).\n *\n * @spec openspec/changes/form-pickers-from-schema/specs/schema-utilities/spec.md\n * @param {object} prop A schema property definition (or `items` for an array).\n * @return {boolean} True when the property marks a Nextcloud group.\n */\nexport function isGroupProp(prop) {\n\tif (!prop || typeof prop !== 'object') {\n\t\treturn false\n\t}\n\treturn prop.referenceType === 'nextcloud-group' || prop.format === 'nc-group' || prop.widget === 'group'\n}\n\n/**\n * Make a manifest field override that names a picker widget behave exactly\n * like the schema format that triggers it.\n *\n * OpenRegister refuses formats it does not know (`nc-group`, `language`,\n * `timezone`) at import, so an app cannot always put them in its schema. It\n * declares `fieldOverrides.<key>.widget: 'group' | 'language' | 'timezone'`\n * (or `'user'`) instead. The widget alone is not enough for the user and\n * group pickers, which CnFormDialog recognises by `userPicker` /\n * `groupPicker`, so set those here. An override may also carry its own\n * `x-default` (`current-language`, `current-timezone`), which becomes the\n * field's `defaultToken` just as the schema key does.\n *\n * Mutates `field` in place.\n *\n * @spec openspec/changes/review-round-two/specs/schema-utilities/spec.md\n * @param {object} field The field descriptor, overrides already merged in.\n * @param {object} override The raw override for this key.\n * @return {void}\n */\nfunction applyPickerOverride(field, override) {\n\tif (!override || typeof override !== 'object') {\n\t\treturn\n\t}\n\tconst widget = override.widget\n\tif (widget === 'group' || widget === 'group-multiselect') {\n\t\tfield.groupPicker = { multiple: widget === 'group-multiselect' }\n\t\tfield.userPicker = null\n\t} else if (widget === 'user' || widget === 'user-multiselect') {\n\t\tfield.userPicker = { multiple: widget === 'user-multiselect' }\n\t\tfield.groupPicker = null\n\t}\n\tif (typeof override['x-default'] === 'string' && override['x-default'] !== '') {\n\t\tfield.defaultToken = override['x-default']\n\t}\n}\n\n/**\n * Read a property's `x-openregister-property-source` declaration.\n *\n * @spec openspec/changes/form-field-property-source/tasks.md#task-1\n * @param {object} prop The schema property definition.\n * @return {{provider: string, mode: string, config: object}|null} The declaration, or null when absent or without a provider.\n */\nfunction propertySourceOf(prop) {\n\tconst decl = prop && prop['x-openregister-property-source']\n\tif (!decl || typeof decl !== 'object' || typeof decl.provider !== 'string' || decl.provider === '') {\n\t\treturn null\n\t}\n\treturn {\n\t\tprovider: decl.provider,\n\t\tmode: decl.mode === 'default' ? 'default' : 'live',\n\t\tconfig: (decl.config && typeof decl.config === 'object') ? decl.config : {},\n\t}\n}\n\n/**\n * The concept-scheme binding of a property, alone or as the items of an array.\n *\n * Two spellings, read by OpenRegister alike: `conceptScheme` (a string) and\n * `x-openregister-concepts` (an object with `scheme`, `store`, `contextProperty`).\n *\n * @param {object} prop The schema property definition.\n * @return {{multiple: boolean, store: string, contextProperty: string|null}|null} The binding, or null when the property is not bound.\n */\nfunction codedBindingOf(prop) {\n\tconst read = (p) => {\n\t\tif (!p || typeof p !== 'object') {\n\t\t\treturn null\n\t\t}\n\t\tconst ann = p['x-openregister-concepts']\n\t\tif (ann && typeof ann === 'object' && ann.scheme) {\n\t\t\treturn { store: typeof ann.store === 'string' && ann.store !== '' ? ann.store : 'uri', contextProperty: typeof ann.contextProperty === 'string' && ann.contextProperty !== '' ? ann.contextProperty : null }\n\t\t}\n\t\tif (typeof p.conceptScheme === 'string' && p.conceptScheme !== '') {\n\t\t\treturn { store: 'uri', contextProperty: null }\n\t\t}\n\t\treturn null\n\t}\n\tif (prop && prop.type === 'array') {\n\t\tconst binding = read(prop.items) || read(prop)\n\t\treturn binding ? { ...binding, multiple: true } : null\n\t}\n\tconst binding = read(prop)\n\treturn binding ? { ...binding, multiple: false } : null\n}\n\n/**\n * Whether a schema property holds a file (`type: \"file\"`) or several\n * (an array whose items are files).\n *\n * @param {object} prop The schema property definition.\n * @return {boolean} True for a file or array-of-files property.\n */\nfunction isFileProperty(prop) {\n\treturn prop.type === 'file' || (prop.type === 'array' && !!prop.items && prop.items.type === 'file')\n}\n\n/**\n * The file field's own settings, from the property (or its items): the\n * accepted types, the size limit and whether it takes several.\n *\n * @param {object} prop The schema property definition.\n * @return {{accept: string, maxSize: number|undefined, multiple: boolean, capture: string}} The settings.\n */\nfunction fileSettings(prop) {\n\tconst source = prop.type === 'array' && prop.items ? prop.items : prop\n\tconst allowed = prop.allowedTypes || source.allowedTypes\n\tconst accept = Array.isArray(allowed) ? allowed.join(',') : (typeof prop.accept === 'string' ? prop.accept : '')\n\tconst maxSize = Number(prop.maxSize ?? source.maxSize)\n\treturn {\n\t\taccept,\n\t\tmaxSize: Number.isFinite(maxSize) && maxSize > 0 ? maxSize : undefined,\n\t\tmultiple: prop.type === 'array',\n\t\tcapture: prop.capture === 'environment' || prop.capture === 'user' ? prop.capture : '',\n\t}\n}\n\n/**\n * @spec openspec/changes/form-pickers-from-schema/specs/schema-utilities/spec.md\n * @param {object} prop The schema property definition.\n * @return {string} The widget identifier (see the block above).\n */\nfunction resolveWidget(prop) {\n\t// Explicit widget hint takes priority\n\tif (prop.widget) {\n\t\treturn prop.widget\n\t}\n\n\t// A file property, or an array of files, is the file field.\n\tif (isFileProperty(prop)) {\n\t\treturn 'file'\n\t}\n\n\t// Registry-backed property (x-openregister-property-source) → type-ahead\n\tif (propertySourceOf(prop)) {\n\t\treturn 'property-source'\n\t}\n\n\t// Array of objects edited as a table (opt-in; the default is unchanged)\n\tif (prop['x-widget'] === 'sub-objects' && prop.type === 'array' && prop.items && prop.items.type === 'object') {\n\t\treturn 'sub-objects'\n\t}\n\n\t// Bound to an OpenRegister concept scheme: a select over the options\n\t// OpenRegister serves (a multiselect for an array).\n\t{\n\t\tconst coded = codedBindingOf(prop)\n\t\tif (coded) {\n\t\t\treturn coded.multiple ? 'multiselect' : 'select'\n\t\t}\n\t}\n\n\t// Editable table of another schema's records: an array of references whose\n\t// property carries `inversedBy` (the child's property pointing back).\n\tif (prop.type === 'array' && prop.items && normalizeRef(prop.items.$ref) !== null && typeof prop.inversedBy === 'string' && prop.inversedBy !== '') {\n\t\treturn 'child-records'\n\t}\n\n\t// ISO 8601 duration → number and unit\n\tif ((prop.type || 'string') === 'string' && prop.format === 'duration' && !prop.enum) {\n\t\treturn 'duration'\n\t}\n\n\t// Enum → select\n\tif (prop.enum) {\n\t\treturn 'select'\n\t}\n\n\tconst type = prop.type || 'string'\n\tconst format = prop.format || ''\n\n\t// OpenRegister object reference (`$ref` is a schema slug or numeric id) →\n\t// a searchable dropdown of the referenced objects. An array of\n\t// references (`items.$ref`) → a multi-select. Checked before the\n\t// plain type/format fallback so a `{ type: 'string', format: 'uuid',\n\t// $ref: '<slug-or-id>' }` property renders as a dropdown, not a UUID box.\n\tif (normalizeRef(prop.$ref) !== null) {\n\t\treturn 'select'\n\t}\n\tif (type === 'array' && prop.items && normalizeRef(prop.items.$ref) !== null) {\n\t\treturn 'multiselect'\n\t}\n\n\t// Nextcloud user reference (referenceType 'nextcloud-user' or\n\t// format 'user'/'username'): a searchable dropdown of real Nextcloud\n\t// users (label = display name, value = UID). An array of users is a\n\t// multi-select. Checked before the plain type/format fallback so a\n\t// user-marked property renders as a picker, not a free-text box.\n\tif (isUserProp(prop)) {\n\t\treturn 'user'\n\t}\n\tif (type === 'array' && isUserProp(prop.items)) {\n\t\treturn 'user-multiselect'\n\t}\n\n\t// Nextcloud group (`format: 'nc-group'` / `referenceType: 'nextcloud-group'`):\n\t// a searchable dropdown of groups storing the group id.\n\tif (isGroupProp(prop)) {\n\t\treturn 'group'\n\t}\n\tif (type === 'array' && isGroupProp(prop.items)) {\n\t\treturn 'group-multiselect'\n\t}\n\n\t// Language and time zone codes: a searchable list instead of a free-text\n\t// box, so a person picks \"Dutch\" and the record stores `nl`.\n\tif (type === 'string' && format === 'language') {\n\t\treturn 'language'\n\t}\n\tif (type === 'string' && format === 'timezone') {\n\t\treturn 'timezone'\n\t}\n\n\t// Boolean → switch/checkbox\n\tif (type === 'boolean') {\n\t\treturn 'checkbox'\n\t}\n\n\t// Number types\n\tif (type === 'integer' || type === 'number') {\n\t\treturn 'number'\n\t}\n\n\t// Array types\n\tif (type === 'array') {\n\t\tif (prop.items && prop.items.enum) {\n\t\t\treturn 'multiselect'\n\t\t}\n\t\treturn 'tags'\n\t}\n\n\t// Format-based widgets\n\tif (format === 'date-time') {\n\t\treturn 'datetime'\n\t}\n\tif (format === 'date') {\n\t\treturn 'date'\n\t}\n\tif (format === 'email') {\n\t\treturn 'email'\n\t}\n\tif (format === 'uri' || format === 'url') {\n\t\treturn 'url'\n\t}\n\tif (format === 'markdown' || format === 'textarea') {\n\t\treturn 'textarea'\n\t}\n\n\t// Long text → textarea\n\tif (prop.maxLength && prop.maxLength > 255) {\n\t\treturn 'textarea'\n\t}\n\n\treturn 'text'\n}\n\n/**\n * Longest description rendered inline as helper text. Beyond this a field's\n * description is split — a short lead-in stays under the input, the full text\n * moves behind the info popover — because some schema properties document a\n * whole adapter dispatch table and would otherwise dwarf the field itself.\n */\nconst DESCRIPTION_INLINE_MAX = 120\n\n/** Tokens ending in a period that do not end a sentence. */\nconst NON_TERMINAL_ABBREVIATIONS = ['e.g', 'i.e', 'etc', 'vs', 'cf', 'incl', 'approx', 'resp', 'no']\n\n/**\n * The first sentence of `text`, or '' when it has no sentence boundary.\n *\n * @param {string} text The text to scan.\n * @return {string} The first sentence including its terminator.\n */\nfunction firstSentenceOf(text) {\n\tconst boundary = /[.!?](?=\\s|$)/g\n\tlet match\n\twhile ((match = boundary.exec(text)) !== null) {\n\t\tconst lastWord = text.slice(0, match.index).split(/\\s+/).pop().toLowerCase()\n\t\t// \"e.g.\" and single-letter initials carry a period mid-sentence.\n\t\tif (NON_TERMINAL_ABBREVIATIONS.includes(lastWord) || /^[a-z]$/i.test(lastWord)) {\n\t\t\tcontinue\n\t\t}\n\t\treturn text.slice(0, match.index + 1)\n\t}\n\treturn ''\n}\n\n/**\n * Truncate to `max` characters on a word boundary, with an ellipsis.\n *\n * @param {string} text The text to clamp.\n * @param {number} max The maximum length before the ellipsis.\n * @return {string} The clamped text.\n */\nfunction clampToWord(text, max) {\n\tconst cut = text.slice(0, max)\n\tconst lastSpace = cut.lastIndexOf(' ')\n\t// Only honour the word boundary when it isn't hacking off most of the clamp.\n\treturn `${(lastSpace > max * 0.6 ? cut.slice(0, lastSpace) : cut).trimEnd()}…`\n}\n\n/**\n * Split a description into the part rendered inline and the full text.\n *\n * Short descriptions (the overwhelming majority — \"Human-readable name\") pass\n * through untouched with no long form. Longer ones yield their first sentence\n * as `short` when that alone fits, else a word-clamped prefix, and the whole\n * original as `long` for the caller to put behind an info affordance.\n *\n * @param {string} text The raw description.\n * @param {number} [max] Longest text kept inline.\n * @return {{short: string, long: string}} The inline text and the full text ('' when nothing was split off).\n */\nexport function splitDescription(text, max = DESCRIPTION_INLINE_MAX) {\n\tconst full = typeof text === 'string' ? text.trim() : ''\n\tif (!full || full.length <= max) {\n\t\treturn { short: full, long: '' }\n\t}\n\n\tconst sentence = firstSentenceOf(full)\n\treturn {\n\t\tshort: sentence && sentence.length <= max ? sentence : clampToWord(full, max),\n\t\tlong: full,\n\t}\n}\n\n/**\n * Property names that carry the tenant a record belongs to, compared after\n * lower-casing and dropping `_` / `-`, so `tenant_id`, `tenantId` and\n * `tenant-id` all match.\n *\n * @type {Set<string>}\n */\nconst TENANT_PROPERTY_NAMES = new Set(['tenant', 'tenantid', 'tenantuuid'])\n\n/**\n * Whether a schema property holds the tenant a record belongs to.\n *\n * Tenant is set by the platform, never by the person filling in a form, so\n * a create form must not ask for it. OpenRegister marks no such property\n * itself: learniq's work group ships `tenant_id` as a plain required string\n * with no format, no `readOnly` and no flag, which is why the create dialog\n * showed a required \"Tenant *\" box. So the test reads the property's\n * semantics in this order:\n *\n * 1. An explicit opt-out, `x-openregister-tenant: false`, keeps it a normal field.\n * 2. An explicit marker makes it a tenant field whatever it is called:\n * `x-openregister-tenant: true`, `x-platform-managed: true`,\n * `x-managed-by: 'platform'`, `format: 'tenant'` or `referenceType: 'tenant'`.\n * 3. Otherwise its name decides: `tenant`, `tenant_id` / `tenantId` or `tenant_uuid`.\n *\n * `organisation` is deliberately NOT matched by name: plenty of schemas let a\n * person pick an organisation (a contact's employer, a supplier), and hiding\n * that would take a real question away. A schema whose `organisation`\n * property is the tenant says so with one of the markers above.\n *\n * @param {string} key The property key.\n * @param {object} prop The property definition.\n * @return {boolean} True when the property is platform-managed tenancy.\n */\nexport function isTenantProperty(key, prop) {\n\tconst p = (prop && typeof prop === 'object') ? prop : {}\n\tif (p['x-openregister-tenant'] === false) {\n\t\treturn false\n\t}\n\tif (p['x-openregister-tenant'] === true\n\t\t|| p['x-platform-managed'] === true\n\t\t|| p['x-managed-by'] === 'platform'\n\t\t|| p.format === 'tenant'\n\t\t|| p.referenceType === 'tenant') {\n\t\treturn true\n\t}\n\tconst name = typeof key === 'string' ? key.toLowerCase().replace(/[-_]/g, '') : ''\n\treturn TENANT_PROPERTY_NAMES.has(name)\n}\n\nconst warnedHelp = new Set()\n\n/**\n * Read a property's `x-help`: a string, or a map of language codes to strings.\n * Anything else is ignored with one warning naming the property.\n *\n * @param {string} key The property key (named in the warning).\n * @param {unknown} value The raw `x-help` value.\n * @param {string} language The user's language, e.g. `nl` or `en_GB`.\n * @param {(text: string) => string} tr Display-layer translation, applied to a plain string only.\n * @return {string} The explanation, or ''.\n */\nfunction readHelp(key, value, language, tr) {\n\tif (value === undefined || value === null) {\n\t\treturn ''\n\t}\n\tif (typeof value === 'string') {\n\t\treturn value.trim() !== '' ? tr(value.trim()) : ''\n\t}\n\tif (typeof value === 'object' && !Array.isArray(value)) {\n\t\tconst usable = Object.entries(value).filter(([, text]) => typeof text === 'string' && text.trim() !== '')\n\t\tconst byCode = new Map(usable.map(([code, text]) => [code.toLowerCase().replace('_', '-'), text.trim()]))\n\t\tconst wanted = String(language || '').toLowerCase().replace('_', '-')\n\t\treturn byCode.get(wanted) || byCode.get(wanted.split('-')[0]) || byCode.get('en') || (usable[0] ? usable[0][1].trim() : '')\n\t}\n\tif (!warnedHelp.has(key)) {\n\t\twarnedHelp.add(key)\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.warn(`[fieldsFromSchema] \"x-help\" on \"${key}\" must be a string or a map of language codes to strings; ignored.`)\n\t}\n\treturn ''\n}\n\n/**\n * Generate form field definitions from a schema's properties.\n *\n * Reads `schema.properties` and creates field descriptor objects suitable\n * for auto-generating form UIs. Follows the same pattern as\n * `columnsFromSchema()` — filters, sorts, and supports overrides.\n *\n * @param {object} schema The schema object with a `properties` field\n * @param {object} [options] Configuration options\n * @param {string[]} [options.exclude] Property keys to exclude\n * @param {string[]} [options.include] Property keys to include (whitelist mode)\n * @param {object} [options.overrides] Per-key field overrides, e.g. `{ status: { widget: 'select' } }`. Recognised keys: `hidden` (true → drop the field), `order` (number → wins over the schema property's `order` for sorting), `readOnly` (false on a schema-readOnly key un-skips it), plus any field props to merge (`label`, `widget`, `enum`, …). A single overrides map therefore controls visibility, ordering and rendering on every surface that consumes this pipeline (data widget + form dialog).\n * @param {boolean} [options.includeReadOnly] Whether to include readOnly properties\n * @param {boolean} [options.hideTenant] Drop properties that hold the record's tenant (see `isTenantProperty`). Off by default, so a detail page still shows the tenant; CnFormDialog turns it on because nobody should be asked for it. `overrides[key].hidden === false` keeps one visible.\n * @param {string} [options.language] The user's language (e.g. `nl`, `en_GB`) used to pick from a language map in `x-help`; falls back to the base language, `en`, then the first entry.\n * @param {(text: string) => string} [options.translate] Optional display-layer translation function applied to each field's `label` and `description`. Schema property titles/descriptions are authored in English as the canonical source; consumers pass their bound `t()` (via the injected `cnTranslate`) so the rendered field label follows the user's language. When omitted, label/description are the English source strings unchanged (pure, backward-compatible).\n * @spec openspec/changes/form-pickers-from-schema/specs/schema-utilities/spec.md\n * @return {Array<{key: string, label: string, description: string, descriptionLong: string, help: string, type: string, format: string|null, widget: string, required: boolean, readOnly: boolean, default: unknown, enum: Array|null, enumLabels: object|null, items: object|null, referenceType: string|null, referenceSemanticType: string|null, referenceSemanticApp: string|null, reference: {schema: string|number, multiple: boolean, register?: string, labelField?: string}|null, allowCreate: boolean, userPicker: {multiple: boolean}|null, groupPicker: {multiple: boolean}|null, defaultToken: string|null, propertySource: {provider: string, mode: string, config: object}|null, fillFrom: object|null, validation: object, order: number}>} `description` is the inline helper text (see `splitDescription`); `help` is the property's `x-help` explanation in the user's language ('' when absent or malformed); `descriptionLong` carries it too when present, else the full description when it was too long to render inline, else ''. `enumLabels` maps each raw enum value to its English display label (from the property's `x-enum-labels`), or null.\n */\nexport function fieldsFromSchema(schema, options = {}) {\n\tconst { exclude = [], include = null, overrides = {}, includeReadOnly = false, hideTenant = false, translate, language = '' } = options\n\tconst tr = typeof translate === 'function' ? translate : (text) => text\n\n\tif (!schema || !schema.properties) {\n\t\treturn []\n\t}\n\n\tconst requiredKeys = Array.isArray(schema.required) ? schema.required : []\n\n\tconst entries = Object.entries(schema.properties)\n\t\t.filter(([key, prop]) => {\n\t\t\t// Skip properties marked as not visible\n\t\t\tif (prop.visible === false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Per-key override visibility: `overrides[key].hidden === true` hides\n\t\t\t// the field on every surface that consumes this pipeline (data widget\n\t\t\t// + form dialog), so a single config map controls both.\n\t\t\tif (overrides[key]?.hidden === true) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Platform-managed tenancy (`tenant_id` and friends): nobody is\n\t\t\t// asked for it on a form. An explicit `hidden: false` override\n\t\t\t// brings it back for the rare surface that does need it.\n\t\t\tif (hideTenant && overrides[key]?.hidden !== false && isTenantProperty(key, prop)) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Skip readOnly properties by default — UNLESS a per-key override\n\t\t\t// explicitly re-enables the field (`overrides[key].readOnly === false`).\n\t\t\t// This lets a consumer surface a schema-readOnly field (e.g. a\n\t\t\t// denormalised name that's read-only on edit but must be collected\n\t\t\t// on create) without flipping the whole form to includeReadOnly.\n\t\t\tif (prop.readOnly === true && !includeReadOnly && overrides[key]?.readOnly !== false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Apply exclude list\n\t\t\tif (exclude.includes(key)) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Apply include whitelist\n\t\t\tif (include && !include.includes(key)) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Skip complex object types unless the caller opts in with an explicit widget\n\t\t\t// (e.g. `widget: 'json'` or `widget: 'code'` in CnFormDialog) — or unless the\n\t\t\t// property is an OpenRegister object REFERENCE (`$ref`). A reference is a\n\t\t\t// relation to another schema's object, which resolveWidget maps to a\n\t\t\t// searchable 'select'; dropping it here meant a related-object property\n\t\t\t// (e.g. cow.barn → barn) silently never rendered in the form at all.\n\t\t\tif (prop.type === 'object' && !prop.widget && normalizeRef(prop.$ref) === null) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn true\n\t\t})\n\t\t.sort(([keyA, propA], [keyB, propB]) => {\n\t\t\t// Sort by EFFECTIVE order: a per-key `overrides[key].order` wins over\n\t\t\t// the schema property's own `order`, then alphabetically. Honouring the\n\t\t\t// override here means every consumer (data widget + form dialog) gets\n\t\t\t// the same ordering from one map — no per-component re-sort needed.\n\t\t\tconst orderA = typeof overrides[keyA]?.order === 'number'\n\t\t\t\t? overrides[keyA].order\n\t\t\t\t: (typeof propA.order === 'number' ? propA.order : Infinity)\n\t\t\tconst orderB = typeof overrides[keyB]?.order === 'number'\n\t\t\t\t? overrides[keyB].order\n\t\t\t\t: (typeof propB.order === 'number' ? propB.order : Infinity)\n\t\t\tif (orderA !== orderB) {\n\t\t\t\treturn orderA - orderB\n\t\t\t}\n\t\t\treturn keyA.localeCompare(keyB)\n\t\t})\n\n\treturn entries.map(([key, prop]) => {\n\t\tconst description = splitDescription(prop.description ? tr(prop.description) : '')\n\t\t// `x-help` is the long explanation behind the toggletip; `description` stays the short helper line.\n\t\tconst help = readHelp(key, prop['x-help'], language, tr)\n\t\tconst labelField = prop['x-label-field']\n\t\t\t|| (prop.items && prop.items['x-label-field'])\n\t\t\t|| null\n\t\tconst field = {\n\t\t\tkey,\n\t\t\tlabel: tr(prop.title || key),\n\t\t\tdescription: description.short,\n\t\t\tdescriptionLong: help || description.long,\n\t\t\thelp,\n\t\t\ttype: prop.type || 'string',\n\t\t\tformat: prop.format || null,\n\t\t\twidget: resolveWidget(prop),\n\t\t\t// File field settings (widget `file`): accepted types, size limit, several files, camera.\n\t\t\t...(isFileProperty(prop) ? { file: fileSettings(prop) } : {}),\n\t\t\t// Icon picker (`widget: 'icon'`) config forwarded to CnIconBrowser via\n\t\t\t// CnFormDialog: which sources to offer (`iconSources`), consumer icon\n\t\t\t// catalogues (JSON entries — FontAwesome/OpenGemeenten data is usually\n\t\t\t// supplied via a fieldOverride instead), and whether custom-SVG is\n\t\t\t// enabled. `searchable` is obsolete — the browser always searches.\n\t\t\t// Omitted keys fall back to CnIconBrowser's own defaults, which include\n\t\t\t// the bundled NL-government sets.\n\t\t\ticonSources: prop.iconSources || undefined,\n\t\t\tcatalogues: prop.catalogues || undefined,\n\t\t\tallowCustomSvg: prop.allowCustomSvg || undefined,\n\t\t\tsearchable: prop.searchable,\n\t\t\trequired: requiredKeys.includes(key),\n\t\t\treadOnly: prop.readOnly || false,\n\t\t\tdefault: prop.default !== undefined ? prop.default : null,\n\t\t\t// A default that depends on who opens the form (`x-default:\n\t\t\t// 'current-language'` / `'current-timezone'`). Resolved by the\n\t\t\t// consuming form on a NEW object only; never on edit.\n\t\t\tdefaultToken: typeof prop['x-default'] === 'string' ? prop['x-default'] : null,\n\t\t\tenum: prop.enum || null,\n\t\t\t// Display labels for the enum CODES, keyed by raw value. An enum\n\t\t\t// value is a stored contract value, not display text — several are\n\t\t\t// non-English by design (`ingediend`) — so a schema declares the\n\t\t\t// English label here and the consumer surface translates THAT.\n\t\t\t// Without it the only thing a form can show is the raw code.\n\t\t\tenumLabels: prop.enumLabels\n\t\t\t\t|| prop['x-enum-labels']\n\t\t\t\t|| (prop.items && (prop.items.enumLabels || prop.items['x-enum-labels']))\n\t\t\t\t|| null,\n\t\t\titems: prop.items || null,\n\t\t\t// Pluggable integration registry marker (AD-18): a property\n\t\t\t// can declare `referenceType: '<integration-id>'` so consumer\n\t\t\t// surfaces (CnFormDialog, CnDetailGrid) render that\n\t\t\t// integration's single-entity widget instead of a plain input.\n\t\t\treferenceType: prop.referenceType || null,\n\t\t\t// Cross-app semantic reference (ADR-048): a property can declare\n\t\t\t// `referenceSemanticType: '<canonical-uri>'` (e.g.\n\t\t\t// 'https://schema.org/Organization') plus an optional\n\t\t\t// `referenceSemanticApp: '<appid>'` naming the app expected to\n\t\t\t// provide it. The consuming surface (CnFormDialog) resolves the\n\t\t\t// URI against OpenRegister's discovery endpoint: when SOME\n\t\t\t// installed schema implements it, the field renders as a\n\t\t\t// searchable object picker over that provider schema's register;\n\t\t\t// when NONE does, the field renders DISABLED with a tooltip. This\n\t\t\t// is the semantic sibling of `referenceType` (integration id).\n\t\t\t// `null` when the keys are absent (no behaviour change). Pure: no\n\t\t\t// resolution happens here.\n\t\t\treferenceSemanticType: prop.referenceSemanticType || null,\n\t\t\treferenceSemanticApp: prop.referenceSemanticApp || null,\n\t\t\t// OpenRegister object reference (`$ref`): when a property points\n\t\t\t// at another schema (`$ref: '<slug>'`, or `items.$ref` for an\n\t\t\t// array), record the referenced schema slug + whether it is a\n\t\t\t// multi-value reference. The consuming surface (CnFormDialog)\n\t\t\t// resolves this to a searchable dropdown of the referenced\n\t\t\t// objects, storing the chosen UUID(s). `null` for non-reference\n\t\t\t// properties. Pure: no fetching happens here.\n\t\t\t//\n\t\t\t// Cross-app object relation (ADR-066): a reference property may\n\t\t\t// carry `x-external-register: '<app>'` naming the register the\n\t\t\t// referenced schema lives in — a link into ANOTHER fleet app\n\t\t\t// (e.g. a procest case referencing a decidesk decision). When\n\t\t\t// present it is recorded as `reference.register` so the picker\n\t\t\t// resolves/scopes/creates against that register instead of the\n\t\t\t// form's own; absent, the reference stays same-register (the form's\n\t\t\t// `register` prop is used). Consolidates the ad-hoc caseReference /\n\t\t\t// approvalDecisionId / x-mirror-of variants onto one convention.\n\t\t\t//\n\t\t\t// `x-label-field` names the referenced object's property that labels\n\t\t\t// an option and that an inline create writes the typed term to\n\t\t\t// (`reference.labelField`, default `name` at the consumer).\n\t\t\treference: (normalizeRef(prop.$ref) !== null)\n\t\t\t\t? { schema: normalizeRef(prop.$ref), multiple: false, ...(prop['x-external-register'] ? { register: prop['x-external-register'] } : {}), ...(labelField ? { labelField } : {}) }\n\t\t\t\t: (prop.type === 'array' && prop.items && normalizeRef(prop.items.$ref) !== null)\n\t\t\t\t\t\t? { schema: normalizeRef(prop.items.$ref), multiple: true, ...((prop.items['x-external-register'] || prop['x-external-register']) ? { register: prop.items['x-external-register'] || prop['x-external-register'] } : {}), ...(labelField ? { labelField } : {}) }\n\t\t\t\t\t\t: null,\n\t\t\t// Concept-scheme binding: what the form needs to ask OpenRegister\n\t\t\t// for the options (it fetches nothing here).\n\t\t\tcodeList: (() => {\n\t\t\t\tconst coded = codedBindingOf(prop)\n\t\t\t\treturn coded ? { property: key, multiple: coded.multiple, store: coded.store, contextProperty: coded.contextProperty } : null\n\t\t\t})(),\n\t\t\t// Child-records table (widget `child-records`): the child schema,\n\t\t\t// the child property that points back, and the columns shown. From\n\t\t\t// `items.$ref` + `inversedBy`, or named on the property.\n\t\t\tchildRecords: resolveWidget(prop) === 'child-records'\n\t\t\t\t? {\n\t\t\t\t\t\tschema: typeof prop.schema === 'string' && prop.schema !== '' ? prop.schema : (normalizeRef(prop.items && prop.items.$ref) ?? ''),\n\t\t\t\t\t\tparentField: prop.parentField || prop.inversedBy || '',\n\t\t\t\t\t\tcolumns: Array.isArray(prop.columns) ? prop.columns : [],\n\t\t\t\t\t}\n\t\t\t\t: null,\n\t\t\t// Select OR create (`x-allow-create: true`, on the property or on\n\t\t\t// its `items` for an array): the picker offers \"Create\" next to the\n\t\t\t// existing objects. Only meaningful on a reference.\n\t\t\tallowCreate: prop['x-allow-create'] === true\n\t\t\t\t|| (prop.type === 'array' && !!prop.items && prop.items['x-allow-create'] === true),\n\t\t\t// Template copy (`x-fill-from: { formKey: sourceKey }`): choosing a\n\t\t\t// referenced object copies those of its values into this form.\n\t\t\t// Registry-backed lookup (`x-openregister-property-source`).\n\t\t\tpropertySource: propertySourceOf(prop),\n\t\t\tfillFrom: (prop['x-fill-from'] && typeof prop['x-fill-from'] === 'object') ? prop['x-fill-from'] : null,\n\t\t\t// Nextcloud user reference: when a property marks a NC user\n\t\t\t// (`referenceType: 'nextcloud-user'`, or `format: 'user'`/\n\t\t\t// `'username'`), tag it so CnFormDialog renders a searchable\n\t\t\t// dropdown of real Nextcloud users (label = display name,\n\t\t\t// value = UID) instead of a free-text box. `multiple` is true\n\t\t\t// for an array of users (`items` marks the user). `null` for\n\t\t\t// non-user properties. Pure: no fetching happens here.\n\t\t\tuserPicker: isUserProp(prop)\n\t\t\t\t? { multiple: false }\n\t\t\t\t: (prop.type === 'array' && isUserProp(prop.items))\n\t\t\t\t\t\t? { multiple: true }\n\t\t\t\t\t\t: null,\n\t\t\t// Nextcloud group reference (`format: 'nc-group'` or\n\t\t\t// `referenceType: 'nextcloud-group'`): the form stores the group id.\n\t\t\tgroupPicker: isGroupProp(prop)\n\t\t\t\t? { multiple: false }\n\t\t\t\t: (prop.type === 'array' && isGroupProp(prop.items))\n\t\t\t\t\t\t? { multiple: true }\n\t\t\t\t\t\t: null,\n\t\t\t// Conditional immutability (AD: x-openregister-readonly-when): a\n\t\t\t// property can declare it becomes read-only when another field on the\n\t\t\t// same object holds a given value — e.g. a hybrid app's identity\n\t\t\t// fields. Consumers (CnObjectDataWidget) evaluate this against the\n\t\t\t// object's current data. Shape: `{ field, equals }` or `{ field, in: [] }`.\n\t\t\treadOnlyWhen: prop['x-openregister-readonly-when'] || prop.readOnlyWhen || null,\n\t\t\tvalidation: {\n\t\t\t\tminLength: prop.minLength,\n\t\t\t\tmaxLength: prop.maxLength,\n\t\t\t\tminimum: prop.minimum,\n\t\t\t\tmaximum: prop.maximum,\n\t\t\t\tpattern: prop.pattern,\n\t\t\t},\n\t\t\torder: typeof prop.order === 'number' ? prop.order : Infinity,\n\t\t}\n\n\t\t// Apply per-field overrides\n\t\tif (overrides[key]) {\n\t\t\tObject.assign(field, overrides[key])\n\t\t\tapplyPickerOverride(field, overrides[key])\n\t\t}\n\n\t\treturn field\n\t})\n}\n\n/**\n * Generate faceted filter definitions from a schema's facetable properties.\n *\n * Reads `schema.properties` and creates filter definitions for properties\n * marked with `facetable: true`. Maps property types to appropriate filter\n * widget types (select, checkbox, text).\n *\n * A property may say how it wants to be asked for, with `inputControl` —\n * the same word openregister answers under `?_facetable=true`. One of\n * `text`, `select`, `multiselect`, `range`, `date-range`, `boolean` or\n * `reference`. It wins over the type guess; an unknown one falls back to it.\n *\n * @param {object} schema The schema object with a `properties` field\n * @param {object} [options] Configuration options\n * @param {(text: string) => string} [options.translate] Optional display-layer translation function applied to each filter's `label` and `description`. Schema property titles are authored in English as the canonical source; consumers pass their bound `t()` (via the injected `cnTranslate`) so the rendered filter label follows the user's language. When omitted, label/description are the English source strings unchanged (pure, backward-compatible).\n * @return {Array<{key: string, label: string, type: string, propertyType: string, options: Array}>}\n */\nexport function filtersFromSchema(schema, options = {}) {\n\tif (!schema || !schema.properties) {\n\t\treturn []\n\t}\n\n\tconst { translate } = options\n\tconst tr = typeof translate === 'function' ? translate : (text) => text\n\n\treturn Object.entries(schema.properties)\n\t\t.filter(([, prop]) => {\n\t\t\tif (prop.facetable !== true) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn true\n\t\t})\n\t\t.sort(([keyA, propA], [keyB, propB]) => {\n\t\t\tconst orderA = typeof propA.order === 'number' ? propA.order : Infinity\n\t\t\tconst orderB = typeof propB.order === 'number' ? propB.order : Infinity\n\t\t\tif (orderA !== orderB) {\n\t\t\t\treturn orderA - orderB\n\t\t\t}\n\t\t\treturn keyA.localeCompare(keyB)\n\t\t})\n\t\t.map(([key, prop]) => {\n\t\t\tconst filter = {\n\t\t\t\tkey,\n\t\t\t\tlabel: tr(prop.title || key),\n\t\t\t\tdescription: prop.description ? tr(prop.description) : '',\n\t\t\t\tpropertyType: prop.type || 'string',\n\t\t\t\toptions: [],\n\t\t\t\tvalue: null,\n\t\t\t}\n\n\t\t\t// Map property type to filter widget type\n\t\t\tif (prop.type === 'boolean') {\n\t\t\t\tfilter.type = 'checkbox'\n\t\t\t} else if (prop.enum) {\n\t\t\t\tfilter.type = 'select'\n\t\t\t\tconst enumLabels = prop.enumLabels || prop['x-enum-labels'] || {}\n\t\t\t\tfilter.options = prop.enum.map((val) => ({\n\t\t\t\t\tid: val,\n\t\t\t\t\t// The filter VALUE stays the raw schema code (it is what the\n\t\t\t\t\t// query sends); only the label follows the user's language.\n\t\t\t\t\tlabel: tr(enumLabels[val] || String(val)),\n\t\t\t\t}))\n\t\t\t} else {\n\t\t\t\t// Default to select — options loaded dynamically from facet API\n\t\t\t\tfilter.type = 'select'\n\t\t\t}\n\n\t\t\t// 🔑 `inputControl` IS THE PROPERTY'S OWN ANSWER TO \"HOW DO I ASK\n\t\t\t// FOR THIS\", and it wins over the type guess above. It is the same\n\t\t\t// word openregister's PropertySearchProfile reads\n\t\t\t// (`searchable_fields[<prop>].inputControl` under `?_facetable=true`),\n\t\t\t// so a property declared once is asked for the same way on the\n\t\t\t// list, the facet, the API and the portal. Before this, a date\n\t\t\t// property rendered as a multi-select of nothing: the sidebar had\n\t\t\t// exactly two widgets and every non-boolean landed on one of them.\n\t\t\t//\n\t\t\t// An unknown control falls through to the type guess rather than\n\t\t\t// rendering nothing, because a widget this version has not learned\n\t\t\t// yet must degrade to a working one, not to an empty box.\n\t\t\tconst control = String(prop.inputControl || '').trim()\n\t\t\tif (control === 'date-range' || control === 'range') {\n\t\t\t\tfilter.type = 'date-range'\n\t\t\t\tif (Array.isArray(prop.presets)) {\n\t\t\t\t\tfilter.presets = prop.presets.map((preset) => ({\n\t\t\t\t\t\t...preset,\n\t\t\t\t\t\tlabel: tr(preset.label || preset.id),\n\t\t\t\t\t}))\n\t\t\t\t}\n\t\t\t} else if (control === 'text') {\n\t\t\t\tfilter.type = 'text'\n\t\t\t} else if (control === 'reference') {\n\t\t\t\t// A picker over another list. `optionsSource` says where the\n\t\t\t\t// rows come from; the VALUE is the referenced object's uuid,\n\t\t\t\t// never its title.\n\t\t\t\tfilter.type = 'reference'\n\t\t\t} else if (control === 'boolean') {\n\t\t\t\tfilter.type = 'checkbox'\n\t\t\t}\n\n\t\t\tif (prop.optionsSource && typeof prop.optionsSource === 'object') {\n\t\t\t\tfilter.optionsSource = prop.optionsSource\n\t\t\t}\n\n\t\t\t// A single-valued filter is one the server answers with ONE\n\t\t\t// argument (`priority`, `objectUuid`). Declared rather than\n\t\t\t// inferred: `multiselect` and `select` differ in nothing a widget\n\t\t\t// can see, and sending two values to an endpoint that reads one\n\t\t\t// silently answers about the last of them.\n\t\t\tfilter.multiple = control !== 'select' && control !== 'reference'\n\n\t\t\treturn filter\n\t\t})\n}\n\n/**\n * URL-like string formats — values must parse as a `URL` to be considered valid.\n */\nconst URL_FORMATS = new Set([\n\t'url',\n\t'uri',\n\t'uri-reference',\n\t'iri',\n\t'iri-reference',\n\t'uri-template',\n\t'accessUrl',\n\t'shareUrl',\n\t'downloadUrl',\n])\n\n/**\n * Regex-based validators for additional standard string formats.\n */\nconst FORMAT_PATTERNS = {\n\temail: /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/i,\n\t'idn-email': /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/i,\n\tuuid: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,\n\tipv4: /^((25[0-5]|(2[0-4]|1\\d|[1-9]|)\\d)\\.?\\b){4}$/,\n\tipv6: /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/i,\n\thostname: /^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i,\n\tsemver: /^\\d+\\.\\d+\\.\\d+(?:[-+][0-9A-Za-z.-]+)?$/,\n\t'color-hex': /^#[0-9a-f]{6}$/i,\n\t'color-hex-alpha': /^#[0-9a-f]{8}$/i,\n\t'color-rgb': /^rgb\\(\\s*\\d{1,3}\\s*,\\s*\\d{1,3}\\s*,\\s*\\d{1,3}\\s*\\)$/i,\n\t'color-rgba': /^rgba\\(\\s*\\d{1,3}\\s*,\\s*\\d{1,3}\\s*,\\s*\\d{1,3}\\s*,\\s*[\\d.]+\\s*\\)$/i,\n\t'color-hsl': /^hsl\\(\\s*\\d{1,3}\\s*,\\s*\\d{1,3}%\\s*,\\s*\\d{1,3}%\\s*\\)$/i,\n\t'color-hsla': /^hsla\\(\\s*\\d{1,3}\\s*,\\s*\\d{1,3}%\\s*,\\s*\\d{1,3}%\\s*,\\s*[\\d.]+\\s*\\)$/i,\n}\n\n/**\n * Validate a single value against a JSON-Schema-style property definition.\n *\n * Returns null when the value is valid, otherwise a short English error\n * message describing the violation (caller is responsible for translation).\n * An empty value (`null`/`undefined`/`''`) is considered valid here unless\n * `options.required` is set; required-ness is typically enforced separately\n * by the form so an empty input doesn't show a redundant inline error.\n *\n * @param {unknown} value The value to validate.\n * @param {object} [property] The schema property definition.\n * @param {object} [options] Extra checks.\n * @param {boolean} [options.required] When true, an empty value is reported.\n * @return {string|null}\n */\nexport function validateValue(value, property = {}, options = {}) {\n\tconst { required = false } = options\n\tconst empty = value === null || value === undefined || value === ''\n\t\t|| (Array.isArray(value) && value.length === 0)\n\tif (empty) {\n\t\treturn required ? 'This field is required.' : null\n\t}\n\tconst type = property.type || 'string'\n\tif (type === 'integer') {\n\t\tif (typeof value !== 'number' || !Number.isInteger(value)) {\n\t\t\treturn 'Value must be an integer.'\n\t\t}\n\t} else if (type === 'number') {\n\t\tif (typeof value !== 'number' || Number.isNaN(value)) {\n\t\t\treturn 'Value must be a number.'\n\t\t}\n\t}\n\tif (type === 'integer' || type === 'number') {\n\t\tif (typeof property.minimum === 'number' && value < property.minimum) {\n\t\t\treturn `Value must be at least ${property.minimum}.`\n\t\t}\n\t\tif (typeof property.maximum === 'number' && value > property.maximum) {\n\t\t\treturn `Value must be at most ${property.maximum}.`\n\t\t}\n\t}\n\tif (type === 'string') {\n\t\tif (typeof value !== 'string') {\n\t\t\treturn 'Value must be a string.'\n\t\t}\n\t\tif (typeof property.minLength === 'number' && value.length < property.minLength) {\n\t\t\treturn `Must be at least ${property.minLength} characters.`\n\t\t}\n\t\tif (typeof property.maxLength === 'number' && value.length > property.maxLength) {\n\t\t\treturn `Must be at most ${property.maxLength} characters.`\n\t\t}\n\t\tif (property.pattern) {\n\t\t\ttry {\n\t\t\t\tif (!new RegExp(property.pattern).test(value)) {\n\t\t\t\t\treturn 'Value does not match the required pattern.'\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Ignore broken schema patterns.\n\t\t\t}\n\t\t}\n\t\tif (property.const !== undefined && value !== property.const) {\n\t\t\treturn `Value must be '${property.const}'.`\n\t\t}\n\t\tconst fmtErr = validateStringFormat(property.format, value)\n\t\tif (fmtErr) {\n\t\t\treturn fmtErr\n\t\t}\n\t}\n\tif (type === 'array') {\n\t\tif (!Array.isArray(value)) {\n\t\t\treturn 'Value must be a list.'\n\t\t}\n\t\tif (typeof property.minItems === 'number' && value.length < property.minItems) {\n\t\t\treturn `Select at least ${property.minItems} items.`\n\t\t}\n\t\tif (typeof property.maxItems === 'number' && value.length > property.maxItems) {\n\t\t\treturn `Select at most ${property.maxItems} items.`\n\t\t}\n\t\tif (property.items && typeof property.items === 'object') {\n\t\t\tfor (let i = 0; i < value.length; i++) {\n\t\t\t\tconst itemErr = validateValue(value[i], property.items)\n\t\t\t\tif (itemErr) {\n\t\t\t\t\treturn `Item ${i + 1}: ${itemErr}`\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif (type === 'boolean' && typeof value !== 'boolean') {\n\t\treturn 'Value must be a boolean.'\n\t}\n\tif (Array.isArray(property.enum) && property.enum.length > 0 && !property.enum.includes(value)) {\n\t\treturn 'Value must be one of the allowed options.'\n\t}\n\treturn null\n}\n\n/**\n * Validate a string value against a JSON-Schema `format`.\n *\n * @param {string} format Schema format identifier.\n * @param {string} value String value to validate.\n * @return {string|null} Error message or null when valid.\n */\nfunction validateStringFormat(format, value) {\n\tif (!format) {\n\t\treturn null\n\t}\n\tif (format === 'time') {\n\t\t// HTML5 `<input type=\"time\">` produces `HH:MM` or `HH:MM:SS[.sss]`.\n\t\t// `new Date()` won't parse a bare time, so check the shape directly.\n\t\treturn /^([01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?$/.test(value)\n\t\t\t? null\n\t\t\t: 'Value must be a valid time.'\n\t}\n\tif (format === 'date' || format === 'date-time') {\n\t\treturn Number.isNaN(new Date(value).getTime()) ? `Value must be a valid ${format}.` : null\n\t}\n\tif (URL_FORMATS.has(format)) {\n\t\t// Accept fully-qualified URLs (`https://example.com`) and protocol-less\n\t\t// shorthand (`example.com/path`) by retrying with an `https://` prefix.\n\t\t// Reject obviously non-URL inputs (whitespace, missing dots / authority).\n\t\tif (/\\s/.test(value)) {\n\t\t\treturn 'Value must be a valid URL.'\n\t\t}\n\t\ttry {\n\t\t\tnew URL(value)\n\t\t\treturn null\n\t\t} catch {\n\t\t\t// Fall through to the prefix retry.\n\t\t}\n\t\ttry {\n\t\t\tconst parsed = new URL('https://' + value)\n\t\t\tif (parsed.hostname && parsed.hostname.includes('.')) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t} catch {\n\t\t\t// Fall through to the rejection below.\n\t\t}\n\t\treturn 'Value must be a valid URL.'\n\t}\n\tconst re = FORMAT_PATTERNS[format]\n\tif (re && !re.test(value)) {\n\t\treturn `Value must be a valid '${format}'.`\n\t}\n\treturn null\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sources":["../../../src/utils/schema.js"],"sourcesContent":["/**\n * Schema utility functions for auto-generating table columns, cell formatting,\n * form field definitions, and faceted filter definitions from OpenRegister\n * schema property definitions.\n *\n * @module utils/schema\n */\n\nimport { schemaRefSlug } from './schemaRefSlug.js'\n\n/**\n * Default column widths per property type/format.\n */\nconst DEFAULT_WIDTHS = {\n\tboolean: '80px',\n\tinteger: '100px',\n\tnumber: '100px',\n\t'string:uuid': '140px',\n\t'string:date-time': '180px',\n\t'string:email': '200px',\n}\n\n/**\n * Get default width for a property type + format combination.\n *\n * @param {string} type Property type\n * @param {string} [format] Property format\n * @return {string|undefined} CSS width or undefined\n */\nfunction getDefaultWidth(type, format) {\n\tif (format) {\n\t\treturn DEFAULT_WIDTHS[`${type}:${format}`]\n\t}\n\treturn DEFAULT_WIDTHS[type]\n}\n\n/**\n * Generate CnDataTable column definitions from a schema's properties.\n *\n * Reads `schema.properties` and creates column objects sorted by the `order`\n * hint (if present) then alphabetically. Filters out properties marked\n * `visible: false`. Supports include/exclude lists and per-column overrides.\n *\n * @param {object} schema The schema object with a `properties` field\n * @param {object} [options] Configuration options\n * @param {string[]} [options.exclude] Property keys to exclude\n * @param {string[]} [options.include] Property keys to include (whitelist mode)\n * @param {object} [options.overrides] Per-key column overrides, e.g. `{ status: { width: '200px' } }`\n * @param {(text: string) => string} [options.translate] Optional display-layer translation function applied to each column label. Schema property titles are authored in English as the canonical source; consumers pass their bound `t()` (via the injected `cnTranslate`) so the visible header follows the user's language. When omitted, the label is the English source string unchanged (pure, backward-compatible).\n * @return {Array<{key: string, label: string, sortable: boolean, type: string, format: string, width: string}>}\n */\nexport function columnsFromSchema(schema, options = {}) {\n\tconst { exclude = [], include = null, overrides = {}, translate } = options\n\tconst tr = typeof translate === 'function' ? translate : (text) => text\n\n\tif (!schema || !schema.properties) {\n\t\treturn []\n\t}\n\n\tconst entries = Object.entries(schema.properties)\n\t\t.filter(([key, prop]) => {\n\t\t\t// Skip properties marked as not visible\n\t\t\tif (prop.visible === false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Apply exclude list\n\t\t\tif (exclude.includes(key)) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Apply include whitelist\n\t\t\tif (include && !include.includes(key)) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Skip complex object types by default (they don't render well in tables)\n\t\t\tif (prop.type === 'object') {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn true\n\t\t})\n\t\t.sort(([keyA, propA], [keyB, propB]) => {\n\t\t\t// Sort by order hint first, then alphabetically\n\t\t\tconst orderA = typeof propA.order === 'number' ? propA.order : Infinity\n\t\t\tconst orderB = typeof propB.order === 'number' ? propB.order : Infinity\n\t\t\tif (orderA !== orderB) {\n\t\t\t\treturn orderA - orderB\n\t\t\t}\n\t\t\treturn keyA.localeCompare(keyB)\n\t\t})\n\n\treturn entries.map(([key, prop]) => {\n\t\tconst column = {\n\t\t\tkey,\n\t\t\tlabel: tr(prop.title || key),\n\t\t\t// The schema already explains what the property MEANS; carrying that\n\t\t\t// through as the header tooltip means a column like \"Maturity\" or a\n\t\t\t// computed score explains itself in place, instead of the description\n\t\t\t// living only in the schema editor where no reader of the table looks.\n\t\t\tdescription: prop.description ? tr(prop.description) : '',\n\t\t\tsortable: true,\n\t\t\ttype: prop.type || 'string',\n\t\t\tformat: prop.format || null,\n\t\t}\n\n\t\t// Apply default width\n\t\tconst defaultWidth = getDefaultWidth(column.type, column.format)\n\t\tif (defaultWidth) {\n\t\t\tcolumn.width = defaultWidth\n\t\t}\n\n\t\t// Store enum values for cell renderer\n\t\tif (prop.enum) {\n\t\t\tcolumn.enum = prop.enum\n\t\t}\n\n\t\t// Store items type for arrays\n\t\tif (prop.items) {\n\t\t\tcolumn.items = prop.items\n\t\t}\n\n\t\t// Apply per-column overrides\n\t\tif (overrides[key]) {\n\t\t\tObject.assign(column, overrides[key])\n\t\t}\n\n\t\treturn column\n\t})\n}\n\n/**\n * Format a cell value based on its schema property definition.\n *\n * Handles dates, booleans, arrays, numbers, UUIDs, emails, and markdown.\n * Returns a plain string suitable for display in a table cell.\n *\n * @param {unknown} value The raw value\n * @param {object} [property] The schema property definition `{ type, format, enum, items }`\n * @param {object} [options] Formatting options\n * @param {number} [options.truncate] Maximum string length before truncation\n * @return {string} Formatted display string\n */\nexport function formatValue(value, property = {}, options = {}) {\n\tconst { truncate = 100 } = options\n\n\t// Null/undefined/empty\n\tif (value === null || value === undefined || value === '') {\n\t\treturn '—'\n\t}\n\n\tconst { type = 'string', format } = property\n\n\t// Boolean\n\tif (type === 'boolean' || typeof value === 'boolean') {\n\t\treturn value ? '✓' : '—'\n\t}\n\n\t// Number/Integer\n\tif (type === 'integer' || type === 'number') {\n\t\tconst num = Number(value)\n\t\tif (Number.isNaN(num)) {\n\t\t\treturn String(value)\n\t\t}\n\t\treturn num.toLocaleString()\n\t}\n\n\t// Array\n\tif (type === 'array' || Array.isArray(value)) {\n\t\tif (!Array.isArray(value)) {\n\t\t\treturn String(value)\n\t\t}\n\t\tif (value.length === 0) {\n\t\t\treturn '—'\n\t\t}\n\t\t// Stringify each entry so an array of OBJECTS never collapses to the\n\t\t// useless \"[object Object]\" that `Array.prototype.join` produces — a\n\t\t// nested object renders as compact JSON instead (ADR-062: a value cell\n\t\t// must never show \"[object Object]\"). Rich array rendering (inline\n\t\t// tables / chips) lives in CnObjectDataWidget; this is the flat-string\n\t\t// fallback used by tables and truncated cells.\n\t\tconst parts = value.map((v) => {\n\t\t\tif (v !== null && typeof v === 'object') {\n\t\t\t\ttry {\n\t\t\t\t\treturn JSON.stringify(v)\n\t\t\t\t} catch {\n\t\t\t\t\treturn '[Object]'\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn String(v)\n\t\t})\n\t\t// For short arrays, join values\n\t\tif (parts.length <= 3) {\n\t\t\treturn parts.join(', ')\n\t\t}\n\t\treturn `${parts.slice(0, 3).join(', ')} +${parts.length - 3}`\n\t}\n\n\t// Object — render as JSON; tables truncate, multi-line value cells wrap with `<pre>`.\n\tif (type === 'object' || (typeof value === 'object' && value !== null)) {\n\t\ttry {\n\t\t\treturn truncateString(JSON.stringify(value, null, 2), truncate)\n\t\t} catch {\n\t\t\treturn '[Object]'\n\t\t}\n\t}\n\n\t// String types\n\tconst str = String(value)\n\n\t// Date-time\n\tif (format === 'date-time' || format === 'date') {\n\t\ttry {\n\t\t\tconst date = new Date(str)\n\t\t\tif (Number.isNaN(date.getTime())) {\n\t\t\t\treturn str\n\t\t\t}\n\t\t\tif (format === 'date') {\n\t\t\t\treturn date.toLocaleDateString(undefined, {\n\t\t\t\t\tday: '2-digit',\n\t\t\t\t\tmonth: '2-digit',\n\t\t\t\t\tyear: 'numeric',\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn date.toLocaleDateString(undefined, {\n\t\t\t\tday: '2-digit',\n\t\t\t\tmonth: '2-digit',\n\t\t\t\tyear: 'numeric',\n\t\t\t}) + ', ' + date.toLocaleTimeString(undefined, {\n\t\t\t\thour: '2-digit',\n\t\t\t\tminute: '2-digit',\n\t\t\t\tsecond: '2-digit',\n\t\t\t})\n\t\t} catch {\n\t\t\treturn str\n\t\t}\n\t}\n\n\t// UUID — truncate to first 8 chars\n\tif (format === 'uuid') {\n\t\tif (str.length > 8) {\n\t\t\treturn str.substring(0, 8) + '...'\n\t\t}\n\t\treturn str\n\t}\n\n\t// URI — show truncated\n\tif (format === 'uri' || format === 'url') {\n\t\ttry {\n\t\t\tconst url = new URL(str)\n\t\t\treturn url.hostname + url.pathname.substring(0, 20)\n\t\t} catch {\n\t\t\treturn truncateString(str, truncate)\n\t\t}\n\t}\n\n\t// Markdown — strip formatting\n\tif (format === 'markdown') {\n\t\tconst stripped = str\n\t\t\t.replace(/#{1,6}\\s+/g, '') // headings\n\t\t\t.replace(/[*_]{1,3}([^*_]+)[*_]{1,3}/g, '$1') // bold/italic\n\t\t\t.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1') // links\n\t\t\t.replace(/`{1,3}[^`]*`{1,3}/g, '') // code\n\t\t\t.replace(/\\n+/g, ' ') // newlines\n\t\t\t.trim()\n\t\treturn truncateString(stripped, truncate)\n\t}\n\n\t// Email — display as-is (no truncation)\n\tif (format === 'email') {\n\t\treturn str\n\t}\n\n\t// Plain string — truncate if needed\n\treturn truncateString(str, truncate)\n}\n\n/**\n * Truncate a string to the given length, adding ellipsis if needed.\n *\n * @param {string} str The string to truncate\n * @param {number} maxLength Maximum length\n * @return {string} Truncated string\n */\nfunction truncateString(str, maxLength) {\n\tif (str.length <= maxLength) {\n\t\treturn str\n\t}\n\treturn str.substring(0, maxLength) + '...'\n}\n\n/**\n * Resolve the form widget type for a JSON Schema property.\n *\n * Resolution priority (first match wins):\n * 1. Explicit `prop.widget` — pass-through custom widget name\n * 2. `prop.enum` → `'select'`\n * 3. OpenRegister object reference: `prop.$ref` (a string schema slug) →\n * `'select'`; `array` + `items.$ref` → `'multiselect'`. The consuming\n * surface (CnFormDialog) resolves the reference to a searchable dropdown\n * of the referenced objects (label = human name, value = UUID).\n * 4. Nextcloud user reference: `referenceType: 'nextcloud-user'` (or\n * `format: 'user'`/`'username'`/`'nc-user'`) → `'user'`; an array of such\n * properties → `'user-multiselect'`. CnFormDialog resolves these to a\n * searchable dropdown of real Nextcloud users (label = display name,\n * value = UID). A Nextcloud group (`referenceType: 'nextcloud-group'` or\n * `format: 'nc-group'`) → `'group'`, an array of groups →\n * `'group-multiselect'`. `format: 'language'` → `'language'` and\n * `format: 'timezone'` → `'timezone'` (both searchable code lists).\n * 5. Type-based: `boolean` → `'checkbox'`, `integer`/`number` → `'number'`,\n * `array` + `items.enum` → `'multiselect'`, `array` → `'tags'`\n * 6. Format-based: `date-time` → `'datetime'`, `date` → `'date'`,\n * `email` → `'email'`, `uri`/`url` → `'url'`,\n * `markdown`/`textarea` → `'textarea'`\n * 7. Long text: `maxLength > 255` → `'textarea'`\n * 8. Fallback → `'text'`\n *\n * @param {object} prop The schema property definition (type, format, enum, widget, items, maxLength)\n * @return {string} Widget identifier: 'text'|'email'|'url'|'number'|'checkbox'|'select'|'multiselect'|'user'|'user-multiselect'|'tags'|'textarea'|'date'|'datetime' or a custom string\n */\n/**\n * Normalise a JSON-Schema `$ref` value into an OpenRegister schema reference\n * identifier. OpenRegister authors a `$ref` as a schema *slug* (string) but\n * persists/serves it as the numeric schema *id* (e.g. `85`). Both forms are\n * valid object-reference targets (the objects API resolves either).\n *\n * The schema editor writes the JSON-Pointer form — `#/components/schemas/<slug>`\n * — so a `$ref` reaching here may be a pointer rather than a bare slug. Passing\n * the whole pointer through as the schema identifier made the object picker query\n * a schema literally named \"#/components/schemas/cow\", which matches nothing: the\n * dropdown rendered but came back empty. Take the tail after the last `/`, which\n * is what the editor itself does when it resolves a $ref back to a schema.\n *\n * A `$ref` is authored as the schema's PascalCase (or spaced) *title*, not\n * its slug (`ReportPeriod`, not `report-period`); the objects API 404s on\n * the title for any multi-word schema (defect 7, learniq round 1). Routing\n * the tail through {@link schemaRefSlug} fixes that once here, for every\n * consumer of `reference.schema` built below.\n *\n * @param {unknown} ref A `$ref` value (`prop.$ref` or `prop.items.$ref`).\n * @return {string|number|null} The reference identifier, or null.\n */\nfunction normalizeRef(ref) {\n\tif (typeof ref === 'string' && ref !== '') {\n\t\tconst tail = ref.includes('/') ? ref.substring(ref.lastIndexOf('/') + 1) : ref\n\t\tif (tail === '') {\n\t\t\treturn null\n\t\t}\n\t\tconst slug = schemaRefSlug(tail)\n\t\treturn slug !== '' ? slug : null\n\t}\n\tif (typeof ref === 'number' && !Number.isNaN(ref)) {\n\t\treturn ref\n\t}\n\treturn null\n}\n\n/**\n * Whether a (single-value) schema property represents a Nextcloud user.\n *\n * A property is a user field when it declares `referenceType: 'nextcloud-user'`\n * (preferred) OR `format: 'user'` / `format: 'username'`. The consuming surface\n * (CnFormDialog) renders such a property as a searchable dropdown of real\n * Nextcloud users (label = display name, value = UID) instead of a free-text box.\n *\n * @param {object} prop A schema property definition (or `items` for an array).\n * @return {boolean} True when the property marks a Nextcloud user.\n */\nfunction isUserProp(prop) {\n\tif (!prop || typeof prop !== 'object') {\n\t\treturn false\n\t}\n\tif (prop.referenceType === 'nextcloud-user' || prop.widget === 'user') {\n\t\treturn true\n\t}\n\tconst format = prop.format || ''\n\treturn format === 'user' || format === 'username' || format === 'nc-user'\n}\n\n/**\n * Whether a (single-value) schema property represents a Nextcloud group.\n *\n * A property is a group field when it declares `referenceType: 'nextcloud-group'`\n * or `format: 'nc-group'`. CnFormDialog renders it as a searchable dropdown of\n * Nextcloud groups (label = display name, value = group id).\n *\n * @spec openspec/changes/form-pickers-from-schema/specs/schema-utilities/spec.md\n * @param {object} prop A schema property definition (or `items` for an array).\n * @return {boolean} True when the property marks a Nextcloud group.\n */\nexport function isGroupProp(prop) {\n\tif (!prop || typeof prop !== 'object') {\n\t\treturn false\n\t}\n\treturn prop.referenceType === 'nextcloud-group' || prop.format === 'nc-group' || prop.widget === 'group'\n}\n\n/**\n * Make a manifest field override that names a picker widget behave exactly\n * like the schema format that triggers it.\n *\n * OpenRegister refuses formats it does not know (`nc-group`, `language`,\n * `timezone`) at import, so an app cannot always put them in its schema. It\n * declares `fieldOverrides.<key>.widget: 'group' | 'language' | 'timezone'`\n * (or `'user'`) instead. The widget alone is not enough for the user and\n * group pickers, which CnFormDialog recognises by `userPicker` /\n * `groupPicker`, so set those here. An override may also carry its own\n * `x-default` (`current-language`, `current-timezone`), which becomes the\n * field's `defaultToken` just as the schema key does.\n *\n * Mutates `field` in place.\n *\n * @spec openspec/changes/review-round-two/specs/schema-utilities/spec.md\n * @param {object} field The field descriptor, overrides already merged in.\n * @param {object} override The raw override for this key.\n * @return {void}\n */\nfunction applyPickerOverride(field, override) {\n\tif (!override || typeof override !== 'object') {\n\t\treturn\n\t}\n\tconst widget = override.widget\n\tif (widget === 'group' || widget === 'group-multiselect') {\n\t\tfield.groupPicker = { multiple: widget === 'group-multiselect' }\n\t\tfield.userPicker = null\n\t} else if (widget === 'user' || widget === 'user-multiselect') {\n\t\tfield.userPicker = { multiple: widget === 'user-multiselect' }\n\t\tfield.groupPicker = null\n\t}\n\tif (typeof override['x-default'] === 'string' && override['x-default'] !== '') {\n\t\tfield.defaultToken = override['x-default']\n\t}\n}\n\n/**\n * Read a property's `x-openregister-property-source` declaration.\n *\n * @spec openspec/changes/form-field-property-source/tasks.md#task-1\n * @param {object} prop The schema property definition.\n * @return {{provider: string, mode: string, config: object}|null} The declaration, or null when absent or without a provider.\n */\nfunction propertySourceOf(prop) {\n\tconst decl = prop && prop['x-openregister-property-source']\n\tif (!decl || typeof decl !== 'object' || typeof decl.provider !== 'string' || decl.provider === '') {\n\t\treturn null\n\t}\n\treturn {\n\t\tprovider: decl.provider,\n\t\tmode: decl.mode === 'default' ? 'default' : 'live',\n\t\tconfig: (decl.config && typeof decl.config === 'object') ? decl.config : {},\n\t}\n}\n\n/**\n * The concept-scheme binding of a property, alone or as the items of an array.\n *\n * Two spellings, read by OpenRegister alike: `conceptScheme` (a string) and\n * `x-openregister-concepts` (an object with `scheme`, `store`, `contextProperty`).\n *\n * @param {object} prop The schema property definition.\n * @return {{multiple: boolean, store: string, contextProperty: string|null}|null} The binding, or null when the property is not bound.\n */\nfunction codedBindingOf(prop) {\n\tconst read = (p) => {\n\t\tif (!p || typeof p !== 'object') {\n\t\t\treturn null\n\t\t}\n\t\tconst ann = p['x-openregister-concepts']\n\t\tif (ann && typeof ann === 'object' && ann.scheme) {\n\t\t\treturn { store: typeof ann.store === 'string' && ann.store !== '' ? ann.store : 'uri', contextProperty: typeof ann.contextProperty === 'string' && ann.contextProperty !== '' ? ann.contextProperty : null }\n\t\t}\n\t\tif (typeof p.conceptScheme === 'string' && p.conceptScheme !== '') {\n\t\t\treturn { store: 'uri', contextProperty: null }\n\t\t}\n\t\treturn null\n\t}\n\tif (prop && prop.type === 'array') {\n\t\tconst binding = read(prop.items) || read(prop)\n\t\treturn binding ? { ...binding, multiple: true } : null\n\t}\n\tconst binding = read(prop)\n\treturn binding ? { ...binding, multiple: false } : null\n}\n\n/**\n * Whether a schema property holds a file (`type: \"file\"`) or several\n * (an array whose items are files).\n *\n * @param {object} prop The schema property definition.\n * @return {boolean} True for a file or array-of-files property.\n */\nfunction isFileProperty(prop) {\n\treturn prop.type === 'file' || (prop.type === 'array' && !!prop.items && prop.items.type === 'file')\n}\n\n/**\n * The file field's own settings, from the property (or its items): the\n * accepted types, the size limit and whether it takes several.\n *\n * @param {object} prop The schema property definition.\n * @return {{accept: string, maxSize: number|undefined, multiple: boolean, capture: string}} The settings.\n */\nfunction fileSettings(prop) {\n\tconst source = prop.type === 'array' && prop.items ? prop.items : prop\n\tconst allowed = prop.allowedTypes || source.allowedTypes\n\tconst accept = Array.isArray(allowed) ? allowed.join(',') : (typeof prop.accept === 'string' ? prop.accept : '')\n\tconst maxSize = Number(prop.maxSize ?? source.maxSize)\n\treturn {\n\t\taccept,\n\t\tmaxSize: Number.isFinite(maxSize) && maxSize > 0 ? maxSize : undefined,\n\t\tmultiple: prop.type === 'array',\n\t\tcapture: prop.capture === 'environment' || prop.capture === 'user' ? prop.capture : '',\n\t}\n}\n\n/**\n * @spec openspec/changes/form-pickers-from-schema/specs/schema-utilities/spec.md\n * @param {object} prop The schema property definition.\n * @return {string} The widget identifier (see the block above).\n */\nfunction resolveWidget(prop) {\n\t// Explicit widget hint takes priority\n\tif (prop.widget) {\n\t\treturn prop.widget\n\t}\n\n\t// A file property, or an array of files, is the file field.\n\tif (isFileProperty(prop)) {\n\t\treturn 'file'\n\t}\n\n\t// Registry-backed property (x-openregister-property-source) → type-ahead\n\tif (propertySourceOf(prop)) {\n\t\treturn 'property-source'\n\t}\n\n\t// Array of objects edited as a table (opt-in; the default is unchanged)\n\tif (prop['x-widget'] === 'sub-objects' && prop.type === 'array' && prop.items && prop.items.type === 'object') {\n\t\treturn 'sub-objects'\n\t}\n\n\t// Bound to an OpenRegister concept scheme: a select over the options\n\t// OpenRegister serves (a multiselect for an array).\n\t{\n\t\tconst coded = codedBindingOf(prop)\n\t\tif (coded) {\n\t\t\treturn coded.multiple ? 'multiselect' : 'select'\n\t\t}\n\t}\n\n\t// Editable table of another schema's records: an array of references whose\n\t// property carries `inversedBy` (the child's property pointing back).\n\tif (prop.type === 'array' && prop.items && normalizeRef(prop.items.$ref) !== null && typeof prop.inversedBy === 'string' && prop.inversedBy !== '') {\n\t\treturn 'child-records'\n\t}\n\n\t// ISO 8601 duration → number and unit\n\tif ((prop.type || 'string') === 'string' && prop.format === 'duration' && !prop.enum) {\n\t\treturn 'duration'\n\t}\n\n\t// Enum → select\n\tif (prop.enum) {\n\t\treturn 'select'\n\t}\n\n\tconst type = prop.type || 'string'\n\tconst format = prop.format || ''\n\n\t// OpenRegister object reference (`$ref` is a schema slug or numeric id) →\n\t// a searchable dropdown of the referenced objects. An array of\n\t// references (`items.$ref`) → a multi-select. Checked before the\n\t// plain type/format fallback so a `{ type: 'string', format: 'uuid',\n\t// $ref: '<slug-or-id>' }` property renders as a dropdown, not a UUID box.\n\tif (normalizeRef(prop.$ref) !== null) {\n\t\treturn 'select'\n\t}\n\tif (type === 'array' && prop.items && normalizeRef(prop.items.$ref) !== null) {\n\t\treturn 'multiselect'\n\t}\n\n\t// Nextcloud user reference (referenceType 'nextcloud-user' or\n\t// format 'user'/'username'): a searchable dropdown of real Nextcloud\n\t// users (label = display name, value = UID). An array of users is a\n\t// multi-select. Checked before the plain type/format fallback so a\n\t// user-marked property renders as a picker, not a free-text box.\n\tif (isUserProp(prop)) {\n\t\treturn 'user'\n\t}\n\tif (type === 'array' && isUserProp(prop.items)) {\n\t\treturn 'user-multiselect'\n\t}\n\n\t// Nextcloud group (`format: 'nc-group'` / `referenceType: 'nextcloud-group'`):\n\t// a searchable dropdown of groups storing the group id.\n\tif (isGroupProp(prop)) {\n\t\treturn 'group'\n\t}\n\tif (type === 'array' && isGroupProp(prop.items)) {\n\t\treturn 'group-multiselect'\n\t}\n\n\t// Language and time zone codes: a searchable list instead of a free-text\n\t// box, so a person picks \"Dutch\" and the record stores `nl`.\n\tif (type === 'string' && format === 'language') {\n\t\treturn 'language'\n\t}\n\tif (type === 'string' && format === 'timezone') {\n\t\treturn 'timezone'\n\t}\n\n\t// Boolean → switch/checkbox\n\tif (type === 'boolean') {\n\t\treturn 'checkbox'\n\t}\n\n\t// Number types\n\tif (type === 'integer' || type === 'number') {\n\t\treturn 'number'\n\t}\n\n\t// Array types\n\tif (type === 'array') {\n\t\tif (prop.items && prop.items.enum) {\n\t\t\treturn 'multiselect'\n\t\t}\n\t\treturn 'tags'\n\t}\n\n\t// Format-based widgets\n\tif (format === 'date-time') {\n\t\treturn 'datetime'\n\t}\n\tif (format === 'date') {\n\t\treturn 'date'\n\t}\n\tif (format === 'email') {\n\t\treturn 'email'\n\t}\n\tif (format === 'uri' || format === 'url') {\n\t\treturn 'url'\n\t}\n\tif (format === 'markdown' || format === 'textarea') {\n\t\treturn 'textarea'\n\t}\n\n\t// Long text → textarea\n\tif (prop.maxLength && prop.maxLength > 255) {\n\t\treturn 'textarea'\n\t}\n\n\treturn 'text'\n}\n\n/**\n * Longest description rendered inline as helper text. Beyond this a field's\n * description is split — a short lead-in stays under the input, the full text\n * moves behind the info popover — because some schema properties document a\n * whole adapter dispatch table and would otherwise dwarf the field itself.\n */\nconst DESCRIPTION_INLINE_MAX = 120\n\n/** Tokens ending in a period that do not end a sentence. */\nconst NON_TERMINAL_ABBREVIATIONS = ['e.g', 'i.e', 'etc', 'vs', 'cf', 'incl', 'approx', 'resp', 'no']\n\n/**\n * The first sentence of `text`, or '' when it has no sentence boundary.\n *\n * @param {string} text The text to scan.\n * @return {string} The first sentence including its terminator.\n */\nfunction firstSentenceOf(text) {\n\tconst boundary = /[.!?](?=\\s|$)/g\n\tlet match\n\twhile ((match = boundary.exec(text)) !== null) {\n\t\tconst lastWord = text.slice(0, match.index).split(/\\s+/).pop().toLowerCase()\n\t\t// \"e.g.\" and single-letter initials carry a period mid-sentence.\n\t\tif (NON_TERMINAL_ABBREVIATIONS.includes(lastWord) || /^[a-z]$/i.test(lastWord)) {\n\t\t\tcontinue\n\t\t}\n\t\treturn text.slice(0, match.index + 1)\n\t}\n\treturn ''\n}\n\n/**\n * Truncate to `max` characters on a word boundary, with an ellipsis.\n *\n * @param {string} text The text to clamp.\n * @param {number} max The maximum length before the ellipsis.\n * @return {string} The clamped text.\n */\nfunction clampToWord(text, max) {\n\tconst cut = text.slice(0, max)\n\tconst lastSpace = cut.lastIndexOf(' ')\n\t// Only honour the word boundary when it isn't hacking off most of the clamp.\n\treturn `${(lastSpace > max * 0.6 ? cut.slice(0, lastSpace) : cut).trimEnd()}…`\n}\n\n/**\n * Split a description into the part rendered inline and the full text.\n *\n * Short descriptions (the overwhelming majority — \"Human-readable name\") pass\n * through untouched with no long form. Longer ones yield their first sentence\n * as `short` when that alone fits, else a word-clamped prefix, and the whole\n * original as `long` for the caller to put behind an info affordance.\n *\n * @param {string} text The raw description.\n * @param {number} [max] Longest text kept inline.\n * @return {{short: string, long: string}} The inline text and the full text ('' when nothing was split off).\n */\nexport function splitDescription(text, max = DESCRIPTION_INLINE_MAX) {\n\tconst full = typeof text === 'string' ? text.trim() : ''\n\tif (!full || full.length <= max) {\n\t\treturn { short: full, long: '' }\n\t}\n\n\tconst sentence = firstSentenceOf(full)\n\treturn {\n\t\tshort: sentence && sentence.length <= max ? sentence : clampToWord(full, max),\n\t\tlong: full,\n\t}\n}\n\n/**\n * Property names that carry the tenant a record belongs to, compared after\n * lower-casing and dropping `_` / `-`, so `tenant_id`, `tenantId` and\n * `tenant-id` all match.\n *\n * @type {Set<string>}\n */\nconst TENANT_PROPERTY_NAMES = new Set(['tenant', 'tenantid', 'tenantuuid'])\n\n/**\n * Whether a schema property holds the tenant a record belongs to.\n *\n * Tenant is set by the platform, never by the person filling in a form, so\n * a create form must not ask for it. OpenRegister marks no such property\n * itself: learniq's work group ships `tenant_id` as a plain required string\n * with no format, no `readOnly` and no flag, which is why the create dialog\n * showed a required \"Tenant *\" box. So the test reads the property's\n * semantics in this order:\n *\n * 1. An explicit opt-out, `x-openregister-tenant: false`, keeps it a normal field.\n * 2. An explicit marker makes it a tenant field whatever it is called:\n * `x-openregister-tenant: true`, `x-platform-managed: true`,\n * `x-managed-by: 'platform'`, `format: 'tenant'` or `referenceType: 'tenant'`.\n * 3. Otherwise its name decides: `tenant`, `tenant_id` / `tenantId` or `tenant_uuid`.\n *\n * `organisation` is deliberately NOT matched by name: plenty of schemas let a\n * person pick an organisation (a contact's employer, a supplier), and hiding\n * that would take a real question away. A schema whose `organisation`\n * property is the tenant says so with one of the markers above.\n *\n * @param {string} key The property key.\n * @param {object} prop The property definition.\n * @return {boolean} True when the property is platform-managed tenancy.\n */\nexport function isTenantProperty(key, prop) {\n\tconst p = (prop && typeof prop === 'object') ? prop : {}\n\tif (p['x-openregister-tenant'] === false) {\n\t\treturn false\n\t}\n\tif (p['x-openregister-tenant'] === true\n\t\t|| p['x-platform-managed'] === true\n\t\t|| p['x-managed-by'] === 'platform'\n\t\t|| p.format === 'tenant'\n\t\t|| p.referenceType === 'tenant') {\n\t\treturn true\n\t}\n\tconst name = typeof key === 'string' ? key.toLowerCase().replace(/[-_]/g, '') : ''\n\treturn TENANT_PROPERTY_NAMES.has(name)\n}\n\nconst warnedHelp = new Set()\n\n/**\n * Read a property's `x-help`: a string, or a map of language codes to strings.\n * Anything else is ignored with one warning naming the property.\n *\n * @param {string} key The property key (named in the warning).\n * @param {unknown} value The raw `x-help` value.\n * @param {string} language The user's language, e.g. `nl` or `en_GB`.\n * @param {(text: string) => string} tr Display-layer translation, applied to a plain string only.\n * @return {string} The explanation, or ''.\n */\nfunction readHelp(key, value, language, tr) {\n\tif (value === undefined || value === null) {\n\t\treturn ''\n\t}\n\tif (typeof value === 'string') {\n\t\treturn value.trim() !== '' ? tr(value.trim()) : ''\n\t}\n\tif (typeof value === 'object' && !Array.isArray(value)) {\n\t\tconst usable = Object.entries(value).filter(([, text]) => typeof text === 'string' && text.trim() !== '')\n\t\tconst byCode = new Map(usable.map(([code, text]) => [code.toLowerCase().replace('_', '-'), text.trim()]))\n\t\tconst wanted = String(language || '').toLowerCase().replace('_', '-')\n\t\treturn byCode.get(wanted) || byCode.get(wanted.split('-')[0]) || byCode.get('en') || (usable[0] ? usable[0][1].trim() : '')\n\t}\n\tif (!warnedHelp.has(key)) {\n\t\twarnedHelp.add(key)\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.warn(`[fieldsFromSchema] \"x-help\" on \"${key}\" must be a string or a map of language codes to strings; ignored.`)\n\t}\n\treturn ''\n}\n\n/**\n * Generate form field definitions from a schema's properties.\n *\n * Reads `schema.properties` and creates field descriptor objects suitable\n * for auto-generating form UIs. Follows the same pattern as\n * `columnsFromSchema()` — filters, sorts, and supports overrides.\n *\n * @param {object} schema The schema object with a `properties` field\n * @param {object} [options] Configuration options\n * @param {string[]} [options.exclude] Property keys to exclude\n * @param {string[]} [options.include] Property keys to include (whitelist mode)\n * @param {object} [options.overrides] Per-key field overrides, e.g. `{ status: { widget: 'select' } }`. Recognised keys: `hidden` (true → drop the field), `order` (number → wins over the schema property's `order` for sorting), `readOnly` (false on a schema-readOnly key un-skips it), plus any field props to merge (`label`, `widget`, `enum`, …). A single overrides map therefore controls visibility, ordering and rendering on every surface that consumes this pipeline (data widget + form dialog).\n * @param {boolean} [options.includeReadOnly] Whether to include readOnly properties\n * @param {boolean} [options.hideTenant] Drop properties that hold the record's tenant (see `isTenantProperty`). Off by default, so a detail page still shows the tenant; CnFormDialog turns it on because nobody should be asked for it. `overrides[key].hidden === false` keeps one visible.\n * @param {string} [options.language] The user's language (e.g. `nl`, `en_GB`) used to pick from a language map in `x-help`; falls back to the base language, `en`, then the first entry.\n * @param {(text: string) => string} [options.translate] Optional display-layer translation function applied to each field's `label` and `description`. Schema property titles/descriptions are authored in English as the canonical source; consumers pass their bound `t()` (via the injected `cnTranslate`) so the rendered field label follows the user's language. When omitted, label/description are the English source strings unchanged (pure, backward-compatible).\n * @spec openspec/changes/form-pickers-from-schema/specs/schema-utilities/spec.md\n * @return {Array<{key: string, label: string, description: string, descriptionLong: string, help: string, type: string, format: string|null, widget: string, required: boolean, readOnly: boolean, default: unknown, enum: Array|null, enumLabels: object|null, items: object|null, referenceType: string|null, referenceSemanticType: string|null, referenceSemanticApp: string|null, reference: {schema: string|number, multiple: boolean, register?: string, labelField?: string}|null, allowCreate: boolean, userPicker: {multiple: boolean}|null, groupPicker: {multiple: boolean}|null, defaultToken: string|null, propertySource: {provider: string, mode: string, config: object}|null, fillFrom: object|null, validation: object, order: number}>} `description` is the inline helper text (see `splitDescription`); `help` is the property's `x-help` explanation in the user's language ('' when absent or malformed); `descriptionLong` carries it too when present, else the full description when it was too long to render inline, else ''. `enumLabels` maps each raw enum value to its English display label (from the property's `x-enum-labels`), or null.\n */\nexport function fieldsFromSchema(schema, options = {}) {\n\tconst { exclude = [], include = null, overrides = {}, includeReadOnly = false, hideTenant = false, translate, language = '' } = options\n\tconst tr = typeof translate === 'function' ? translate : (text) => text\n\n\tif (!schema || !schema.properties) {\n\t\treturn []\n\t}\n\n\tconst requiredKeys = Array.isArray(schema.required) ? schema.required : []\n\n\tconst entries = Object.entries(schema.properties)\n\t\t.filter(([key, prop]) => {\n\t\t\t// Skip properties marked as not visible\n\t\t\tif (prop.visible === false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Per-key override visibility: `overrides[key].hidden === true` hides\n\t\t\t// the field on every surface that consumes this pipeline (data widget\n\t\t\t// + form dialog), so a single config map controls both.\n\t\t\tif (overrides[key]?.hidden === true) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Platform-managed tenancy (`tenant_id` and friends): nobody is\n\t\t\t// asked for it on a form. An explicit `hidden: false` override\n\t\t\t// brings it back for the rare surface that does need it.\n\t\t\tif (hideTenant && overrides[key]?.hidden !== false && isTenantProperty(key, prop)) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Skip readOnly properties by default — UNLESS a per-key override\n\t\t\t// explicitly re-enables the field (`overrides[key].readOnly === false`).\n\t\t\t// This lets a consumer surface a schema-readOnly field (e.g. a\n\t\t\t// denormalised name that's read-only on edit but must be collected\n\t\t\t// on create) without flipping the whole form to includeReadOnly.\n\t\t\tif (prop.readOnly === true && !includeReadOnly && overrides[key]?.readOnly !== false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Apply exclude list\n\t\t\tif (exclude.includes(key)) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Apply include whitelist\n\t\t\tif (include && !include.includes(key)) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Skip complex object types unless the caller opts in with an explicit widget\n\t\t\t// (e.g. `widget: 'json'` or `widget: 'code'` in CnFormDialog) — or unless the\n\t\t\t// property is an OpenRegister object REFERENCE (`$ref`). A reference is a\n\t\t\t// relation to another schema's object, which resolveWidget maps to a\n\t\t\t// searchable 'select'; dropping it here meant a related-object property\n\t\t\t// (e.g. cow.barn → barn) silently never rendered in the form at all.\n\t\t\tif (prop.type === 'object' && !prop.widget && normalizeRef(prop.$ref) === null) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn true\n\t\t})\n\t\t.sort(([keyA, propA], [keyB, propB]) => {\n\t\t\t// Sort by EFFECTIVE order: a per-key `overrides[key].order` wins over\n\t\t\t// the schema property's own `order`, then alphabetically. Honouring the\n\t\t\t// override here means every consumer (data widget + form dialog) gets\n\t\t\t// the same ordering from one map — no per-component re-sort needed.\n\t\t\tconst orderA = typeof overrides[keyA]?.order === 'number'\n\t\t\t\t? overrides[keyA].order\n\t\t\t\t: (typeof propA.order === 'number' ? propA.order : Infinity)\n\t\t\tconst orderB = typeof overrides[keyB]?.order === 'number'\n\t\t\t\t? overrides[keyB].order\n\t\t\t\t: (typeof propB.order === 'number' ? propB.order : Infinity)\n\t\t\tif (orderA !== orderB) {\n\t\t\t\treturn orderA - orderB\n\t\t\t}\n\t\t\treturn keyA.localeCompare(keyB)\n\t\t})\n\n\treturn entries.map(([key, prop]) => {\n\t\tconst description = splitDescription(prop.description ? tr(prop.description) : '')\n\t\t// `x-help` is the long explanation behind the toggletip; `description` stays the short helper line.\n\t\tconst help = readHelp(key, prop['x-help'], language, tr)\n\t\tconst labelField = prop['x-label-field']\n\t\t\t|| (prop.items && prop.items['x-label-field'])\n\t\t\t|| null\n\t\tconst field = {\n\t\t\tkey,\n\t\t\tlabel: tr(prop.title || key),\n\t\t\tdescription: description.short,\n\t\t\tdescriptionLong: help || description.long,\n\t\t\thelp,\n\t\t\ttype: prop.type || 'string',\n\t\t\tformat: prop.format || null,\n\t\t\twidget: resolveWidget(prop),\n\t\t\t// File field settings (widget `file`): accepted types, size limit, several files, camera.\n\t\t\t...(isFileProperty(prop) ? { file: fileSettings(prop) } : {}),\n\t\t\t// Icon picker (`widget: 'icon'`) config forwarded to CnIconBrowser via\n\t\t\t// CnFormDialog: which sources to offer (`iconSources`), consumer icon\n\t\t\t// catalogues (JSON entries — FontAwesome/OpenGemeenten data is usually\n\t\t\t// supplied via a fieldOverride instead), and whether custom-SVG is\n\t\t\t// enabled. `searchable` is obsolete — the browser always searches.\n\t\t\t// Omitted keys fall back to CnIconBrowser's own defaults, which include\n\t\t\t// the bundled NL-government sets.\n\t\t\ticonSources: prop.iconSources || undefined,\n\t\t\tcatalogues: prop.catalogues || undefined,\n\t\t\tallowCustomSvg: prop.allowCustomSvg || undefined,\n\t\t\tsearchable: prop.searchable,\n\t\t\trequired: requiredKeys.includes(key),\n\t\t\treadOnly: prop.readOnly || false,\n\t\t\tdefault: prop.default !== undefined ? prop.default : null,\n\t\t\t// A default that depends on who opens the form (`x-default:\n\t\t\t// 'current-language'` / `'current-timezone'`). Resolved by the\n\t\t\t// consuming form on a NEW object only; never on edit.\n\t\t\tdefaultToken: typeof prop['x-default'] === 'string' ? prop['x-default'] : null,\n\t\t\tenum: prop.enum || null,\n\t\t\t// Display labels for the enum CODES, keyed by raw value. An enum\n\t\t\t// value is a stored contract value, not display text — several are\n\t\t\t// non-English by design (`ingediend`) — so a schema declares the\n\t\t\t// English label here and the consumer surface translates THAT.\n\t\t\t// Without it the only thing a form can show is the raw code.\n\t\t\tenumLabels: prop.enumLabels\n\t\t\t\t|| prop['x-enum-labels']\n\t\t\t\t|| (prop.items && (prop.items.enumLabels || prop.items['x-enum-labels']))\n\t\t\t\t|| null,\n\t\t\titems: prop.items || null,\n\t\t\t// Pluggable integration registry marker (AD-18): a property\n\t\t\t// can declare `referenceType: '<integration-id>'` so consumer\n\t\t\t// surfaces (CnFormDialog, CnDetailGrid) render that\n\t\t\t// integration's single-entity widget instead of a plain input.\n\t\t\treferenceType: prop.referenceType || null,\n\t\t\t// Cross-app semantic reference (ADR-048): a property can declare\n\t\t\t// `referenceSemanticType: '<canonical-uri>'` (e.g.\n\t\t\t// 'https://schema.org/Organization') plus an optional\n\t\t\t// `referenceSemanticApp: '<appid>'` naming the app expected to\n\t\t\t// provide it. The consuming surface (CnFormDialog) resolves the\n\t\t\t// URI against OpenRegister's discovery endpoint: when SOME\n\t\t\t// installed schema implements it, the field renders as a\n\t\t\t// searchable object picker over that provider schema's register;\n\t\t\t// when NONE does, the field renders DISABLED with a tooltip. This\n\t\t\t// is the semantic sibling of `referenceType` (integration id).\n\t\t\t// `null` when the keys are absent (no behaviour change). Pure: no\n\t\t\t// resolution happens here.\n\t\t\treferenceSemanticType: prop.referenceSemanticType || null,\n\t\t\treferenceSemanticApp: prop.referenceSemanticApp || null,\n\t\t\t// OpenRegister object reference (`$ref`): when a property points\n\t\t\t// at another schema (`$ref: '<slug>'`, or `items.$ref` for an\n\t\t\t// array), record the referenced schema slug + whether it is a\n\t\t\t// multi-value reference. The consuming surface (CnFormDialog)\n\t\t\t// resolves this to a searchable dropdown of the referenced\n\t\t\t// objects, storing the chosen UUID(s). `null` for non-reference\n\t\t\t// properties. Pure: no fetching happens here.\n\t\t\t//\n\t\t\t// Cross-app object relation (ADR-066): a reference property may\n\t\t\t// carry `x-external-register: '<app>'` naming the register the\n\t\t\t// referenced schema lives in — a link into ANOTHER fleet app\n\t\t\t// (e.g. a procest case referencing a decidesk decision). When\n\t\t\t// present it is recorded as `reference.register` so the picker\n\t\t\t// resolves/scopes/creates against that register instead of the\n\t\t\t// form's own; absent, the reference stays same-register (the form's\n\t\t\t// `register` prop is used). Consolidates the ad-hoc caseReference /\n\t\t\t// approvalDecisionId / x-mirror-of variants onto one convention.\n\t\t\t//\n\t\t\t// `x-label-field` names the referenced object's property that labels\n\t\t\t// an option and that an inline create writes the typed term to\n\t\t\t// (`reference.labelField`, default `name` at the consumer).\n\t\t\treference: (normalizeRef(prop.$ref) !== null)\n\t\t\t\t? { schema: normalizeRef(prop.$ref), multiple: false, ...(prop['x-external-register'] ? { register: prop['x-external-register'] } : {}), ...(labelField ? { labelField } : {}) }\n\t\t\t\t: (prop.type === 'array' && prop.items && normalizeRef(prop.items.$ref) !== null)\n\t\t\t\t\t\t? { schema: normalizeRef(prop.items.$ref), multiple: true, ...((prop.items['x-external-register'] || prop['x-external-register']) ? { register: prop.items['x-external-register'] || prop['x-external-register'] } : {}), ...(labelField ? { labelField } : {}) }\n\t\t\t\t\t\t: null,\n\t\t\t// Concept-scheme binding: what the form needs to ask OpenRegister\n\t\t\t// for the options (it fetches nothing here).\n\t\t\tcodeList: (() => {\n\t\t\t\tconst coded = codedBindingOf(prop)\n\t\t\t\treturn coded ? { property: key, multiple: coded.multiple, store: coded.store, contextProperty: coded.contextProperty } : null\n\t\t\t})(),\n\t\t\t// Child-records table (widget `child-records`): the child schema,\n\t\t\t// the child property that points back, and the columns shown. From\n\t\t\t// `items.$ref` + `inversedBy`, or named on the property.\n\t\t\tchildRecords: resolveWidget(prop) === 'child-records'\n\t\t\t\t? {\n\t\t\t\t\t\tschema: typeof prop.schema === 'string' && prop.schema !== '' ? prop.schema : (normalizeRef(prop.items && prop.items.$ref) ?? ''),\n\t\t\t\t\t\tparentField: prop.parentField || prop.inversedBy || '',\n\t\t\t\t\t\tcolumns: Array.isArray(prop.columns) ? prop.columns : [],\n\t\t\t\t\t}\n\t\t\t\t: null,\n\t\t\t// Select OR create (`x-allow-create: true`, on the property or on\n\t\t\t// its `items` for an array): the picker offers \"Create\" next to the\n\t\t\t// existing objects. Only meaningful on a reference.\n\t\t\tallowCreate: prop['x-allow-create'] === true\n\t\t\t\t|| (prop.type === 'array' && !!prop.items && prop.items['x-allow-create'] === true),\n\t\t\t// Template copy (`x-fill-from: { formKey: sourceKey }`): choosing a\n\t\t\t// referenced object copies those of its values into this form.\n\t\t\t// Registry-backed lookup (`x-openregister-property-source`).\n\t\t\tpropertySource: propertySourceOf(prop),\n\t\t\tfillFrom: (prop['x-fill-from'] && typeof prop['x-fill-from'] === 'object') ? prop['x-fill-from'] : null,\n\t\t\t// Nextcloud user reference: when a property marks a NC user\n\t\t\t// (`referenceType: 'nextcloud-user'`, or `format: 'user'`/\n\t\t\t// `'username'`), tag it so CnFormDialog renders a searchable\n\t\t\t// dropdown of real Nextcloud users (label = display name,\n\t\t\t// value = UID) instead of a free-text box. `multiple` is true\n\t\t\t// for an array of users (`items` marks the user). `null` for\n\t\t\t// non-user properties. Pure: no fetching happens here.\n\t\t\tuserPicker: isUserProp(prop)\n\t\t\t\t? { multiple: false }\n\t\t\t\t: (prop.type === 'array' && isUserProp(prop.items))\n\t\t\t\t\t\t? { multiple: true }\n\t\t\t\t\t\t: null,\n\t\t\t// Nextcloud group reference (`format: 'nc-group'` or\n\t\t\t// `referenceType: 'nextcloud-group'`): the form stores the group id.\n\t\t\tgroupPicker: isGroupProp(prop)\n\t\t\t\t? { multiple: false }\n\t\t\t\t: (prop.type === 'array' && isGroupProp(prop.items))\n\t\t\t\t\t\t? { multiple: true }\n\t\t\t\t\t\t: null,\n\t\t\t// Conditional immutability (AD: x-openregister-readonly-when): a\n\t\t\t// property can declare it becomes read-only when another field on the\n\t\t\t// same object holds a given value — e.g. a hybrid app's identity\n\t\t\t// fields. Consumers (CnObjectDataWidget) evaluate this against the\n\t\t\t// object's current data. Shape: `{ field, equals }` or `{ field, in: [] }`.\n\t\t\treadOnlyWhen: prop['x-openregister-readonly-when'] || prop.readOnlyWhen || null,\n\t\t\tvalidation: {\n\t\t\t\tminLength: prop.minLength,\n\t\t\t\tmaxLength: prop.maxLength,\n\t\t\t\tminimum: prop.minimum,\n\t\t\t\tmaximum: prop.maximum,\n\t\t\t\tpattern: prop.pattern,\n\t\t\t},\n\t\t\torder: typeof prop.order === 'number' ? prop.order : Infinity,\n\t\t}\n\n\t\t// Apply per-field overrides\n\t\tif (overrides[key]) {\n\t\t\tObject.assign(field, overrides[key])\n\t\t\tapplyPickerOverride(field, overrides[key])\n\t\t\ttranslateOverrideText(field, overrides[key], tr)\n\t\t}\n\n\t\treturn field\n\t})\n}\n\n/**\n * Run an override's display text through the translate function, as the\n * schema's own title and description are. A manifest writes `label`,\n * `description` and `placeholder` in its source language; without this a\n * form showed \"Requester\" to a Dutch user whose catalogue holds \"Aanvrager\".\n *\n * @param {object} field The field, with the override already merged in.\n * @param {object} override The per-key override.\n * @param {(text: string) => string} tr The translate function (identity when none).\n * @return {void}\n * @spec openspec/changes/screens-form-override-labels-parity/specs/form-override-labels/spec.md#requirement-override-text-reads-in-the-users-language\n */\nfunction translateOverrideText(field, override, tr) {\n\tfor (const name of ['label', 'description', 'placeholder']) {\n\t\tif (typeof override[name] === 'string' && override[name] !== '') {\n\t\t\tfield[name] = tr(override[name])\n\t\t}\n\t}\n}\n\n/**\n * Generate faceted filter definitions from a schema's facetable properties.\n *\n * Reads `schema.properties` and creates filter definitions for properties\n * marked with `facetable: true`. Maps property types to appropriate filter\n * widget types (select, checkbox, text).\n *\n * A property may say how it wants to be asked for, with `inputControl` —\n * the same word openregister answers under `?_facetable=true`. One of\n * `text`, `select`, `multiselect`, `range`, `date-range`, `boolean` or\n * `reference`. It wins over the type guess; an unknown one falls back to it.\n *\n * @param {object} schema The schema object with a `properties` field\n * @param {object} [options] Configuration options\n * @param {(text: string) => string} [options.translate] Optional display-layer translation function applied to each filter's `label` and `description`. Schema property titles are authored in English as the canonical source; consumers pass their bound `t()` (via the injected `cnTranslate`) so the rendered filter label follows the user's language. When omitted, label/description are the English source strings unchanged (pure, backward-compatible).\n * @return {Array<{key: string, label: string, type: string, propertyType: string, options: Array}>}\n */\nexport function filtersFromSchema(schema, options = {}) {\n\tif (!schema || !schema.properties) {\n\t\treturn []\n\t}\n\n\tconst { translate } = options\n\tconst tr = typeof translate === 'function' ? translate : (text) => text\n\n\treturn Object.entries(schema.properties)\n\t\t.filter(([, prop]) => {\n\t\t\tif (prop.facetable !== true) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn true\n\t\t})\n\t\t.sort(([keyA, propA], [keyB, propB]) => {\n\t\t\tconst orderA = typeof propA.order === 'number' ? propA.order : Infinity\n\t\t\tconst orderB = typeof propB.order === 'number' ? propB.order : Infinity\n\t\t\tif (orderA !== orderB) {\n\t\t\t\treturn orderA - orderB\n\t\t\t}\n\t\t\treturn keyA.localeCompare(keyB)\n\t\t})\n\t\t.map(([key, prop]) => {\n\t\t\tconst filter = {\n\t\t\t\tkey,\n\t\t\t\tlabel: tr(prop.title || key),\n\t\t\t\tdescription: prop.description ? tr(prop.description) : '',\n\t\t\t\tpropertyType: prop.type || 'string',\n\t\t\t\toptions: [],\n\t\t\t\tvalue: null,\n\t\t\t}\n\n\t\t\t// Map property type to filter widget type\n\t\t\tif (prop.type === 'boolean') {\n\t\t\t\tfilter.type = 'checkbox'\n\t\t\t} else if (prop.enum) {\n\t\t\t\tfilter.type = 'select'\n\t\t\t\tconst enumLabels = prop.enumLabels || prop['x-enum-labels'] || {}\n\t\t\t\tfilter.options = prop.enum.map((val) => ({\n\t\t\t\t\tid: val,\n\t\t\t\t\t// The filter VALUE stays the raw schema code (it is what the\n\t\t\t\t\t// query sends); only the label follows the user's language.\n\t\t\t\t\tlabel: tr(enumLabels[val] || String(val)),\n\t\t\t\t}))\n\t\t\t} else {\n\t\t\t\t// Default to select — options loaded dynamically from facet API\n\t\t\t\tfilter.type = 'select'\n\t\t\t}\n\n\t\t\t// 🔑 `inputControl` IS THE PROPERTY'S OWN ANSWER TO \"HOW DO I ASK\n\t\t\t// FOR THIS\", and it wins over the type guess above. It is the same\n\t\t\t// word openregister's PropertySearchProfile reads\n\t\t\t// (`searchable_fields[<prop>].inputControl` under `?_facetable=true`),\n\t\t\t// so a property declared once is asked for the same way on the\n\t\t\t// list, the facet, the API and the portal. Before this, a date\n\t\t\t// property rendered as a multi-select of nothing: the sidebar had\n\t\t\t// exactly two widgets and every non-boolean landed on one of them.\n\t\t\t//\n\t\t\t// An unknown control falls through to the type guess rather than\n\t\t\t// rendering nothing, because a widget this version has not learned\n\t\t\t// yet must degrade to a working one, not to an empty box.\n\t\t\tconst control = String(prop.inputControl || '').trim()\n\t\t\tif (control === 'date-range' || control === 'range') {\n\t\t\t\tfilter.type = 'date-range'\n\t\t\t\tif (Array.isArray(prop.presets)) {\n\t\t\t\t\tfilter.presets = prop.presets.map((preset) => ({\n\t\t\t\t\t\t...preset,\n\t\t\t\t\t\tlabel: tr(preset.label || preset.id),\n\t\t\t\t\t}))\n\t\t\t\t}\n\t\t\t} else if (control === 'text') {\n\t\t\t\tfilter.type = 'text'\n\t\t\t} else if (control === 'reference') {\n\t\t\t\t// A picker over another list. `optionsSource` says where the\n\t\t\t\t// rows come from; the VALUE is the referenced object's uuid,\n\t\t\t\t// never its title.\n\t\t\t\tfilter.type = 'reference'\n\t\t\t} else if (control === 'boolean') {\n\t\t\t\tfilter.type = 'checkbox'\n\t\t\t}\n\n\t\t\tif (prop.optionsSource && typeof prop.optionsSource === 'object') {\n\t\t\t\tfilter.optionsSource = prop.optionsSource\n\t\t\t}\n\n\t\t\t// A single-valued filter is one the server answers with ONE\n\t\t\t// argument (`priority`, `objectUuid`). Declared rather than\n\t\t\t// inferred: `multiselect` and `select` differ in nothing a widget\n\t\t\t// can see, and sending two values to an endpoint that reads one\n\t\t\t// silently answers about the last of them.\n\t\t\tfilter.multiple = control !== 'select' && control !== 'reference'\n\n\t\t\treturn filter\n\t\t})\n}\n\n/**\n * URL-like string formats — values must parse as a `URL` to be considered valid.\n */\nconst URL_FORMATS = new Set([\n\t'url',\n\t'uri',\n\t'uri-reference',\n\t'iri',\n\t'iri-reference',\n\t'uri-template',\n\t'accessUrl',\n\t'shareUrl',\n\t'downloadUrl',\n])\n\n/**\n * Regex-based validators for additional standard string formats.\n */\nconst FORMAT_PATTERNS = {\n\temail: /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/i,\n\t'idn-email': /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/i,\n\tuuid: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,\n\tipv4: /^((25[0-5]|(2[0-4]|1\\d|[1-9]|)\\d)\\.?\\b){4}$/,\n\tipv6: /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/i,\n\thostname: /^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i,\n\tsemver: /^\\d+\\.\\d+\\.\\d+(?:[-+][0-9A-Za-z.-]+)?$/,\n\t'color-hex': /^#[0-9a-f]{6}$/i,\n\t'color-hex-alpha': /^#[0-9a-f]{8}$/i,\n\t'color-rgb': /^rgb\\(\\s*\\d{1,3}\\s*,\\s*\\d{1,3}\\s*,\\s*\\d{1,3}\\s*\\)$/i,\n\t'color-rgba': /^rgba\\(\\s*\\d{1,3}\\s*,\\s*\\d{1,3}\\s*,\\s*\\d{1,3}\\s*,\\s*[\\d.]+\\s*\\)$/i,\n\t'color-hsl': /^hsl\\(\\s*\\d{1,3}\\s*,\\s*\\d{1,3}%\\s*,\\s*\\d{1,3}%\\s*\\)$/i,\n\t'color-hsla': /^hsla\\(\\s*\\d{1,3}\\s*,\\s*\\d{1,3}%\\s*,\\s*\\d{1,3}%\\s*,\\s*[\\d.]+\\s*\\)$/i,\n}\n\n/**\n * Validate a single value against a JSON-Schema-style property definition.\n *\n * Returns null when the value is valid, otherwise a short English error\n * message describing the violation (caller is responsible for translation).\n * An empty value (`null`/`undefined`/`''`) is considered valid here unless\n * `options.required` is set; required-ness is typically enforced separately\n * by the form so an empty input doesn't show a redundant inline error.\n *\n * @param {unknown} value The value to validate.\n * @param {object} [property] The schema property definition.\n * @param {object} [options] Extra checks.\n * @param {boolean} [options.required] When true, an empty value is reported.\n * @return {string|null}\n */\nexport function validateValue(value, property = {}, options = {}) {\n\tconst { required = false } = options\n\tconst empty = value === null || value === undefined || value === ''\n\t\t|| (Array.isArray(value) && value.length === 0)\n\tif (empty) {\n\t\treturn required ? 'This field is required.' : null\n\t}\n\tconst type = property.type || 'string'\n\tif (type === 'integer') {\n\t\tif (typeof value !== 'number' || !Number.isInteger(value)) {\n\t\t\treturn 'Value must be an integer.'\n\t\t}\n\t} else if (type === 'number') {\n\t\tif (typeof value !== 'number' || Number.isNaN(value)) {\n\t\t\treturn 'Value must be a number.'\n\t\t}\n\t}\n\tif (type === 'integer' || type === 'number') {\n\t\tif (typeof property.minimum === 'number' && value < property.minimum) {\n\t\t\treturn `Value must be at least ${property.minimum}.`\n\t\t}\n\t\tif (typeof property.maximum === 'number' && value > property.maximum) {\n\t\t\treturn `Value must be at most ${property.maximum}.`\n\t\t}\n\t}\n\tif (type === 'string') {\n\t\tif (typeof value !== 'string') {\n\t\t\treturn 'Value must be a string.'\n\t\t}\n\t\tif (typeof property.minLength === 'number' && value.length < property.minLength) {\n\t\t\treturn `Must be at least ${property.minLength} characters.`\n\t\t}\n\t\tif (typeof property.maxLength === 'number' && value.length > property.maxLength) {\n\t\t\treturn `Must be at most ${property.maxLength} characters.`\n\t\t}\n\t\tif (property.pattern) {\n\t\t\ttry {\n\t\t\t\tif (!new RegExp(property.pattern).test(value)) {\n\t\t\t\t\treturn 'Value does not match the required pattern.'\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Ignore broken schema patterns.\n\t\t\t}\n\t\t}\n\t\tif (property.const !== undefined && value !== property.const) {\n\t\t\treturn `Value must be '${property.const}'.`\n\t\t}\n\t\tconst fmtErr = validateStringFormat(property.format, value)\n\t\tif (fmtErr) {\n\t\t\treturn fmtErr\n\t\t}\n\t}\n\tif (type === 'array') {\n\t\tif (!Array.isArray(value)) {\n\t\t\treturn 'Value must be a list.'\n\t\t}\n\t\tif (typeof property.minItems === 'number' && value.length < property.minItems) {\n\t\t\treturn `Select at least ${property.minItems} items.`\n\t\t}\n\t\tif (typeof property.maxItems === 'number' && value.length > property.maxItems) {\n\t\t\treturn `Select at most ${property.maxItems} items.`\n\t\t}\n\t\tif (property.items && typeof property.items === 'object') {\n\t\t\tfor (let i = 0; i < value.length; i++) {\n\t\t\t\tconst itemErr = validateValue(value[i], property.items)\n\t\t\t\tif (itemErr) {\n\t\t\t\t\treturn `Item ${i + 1}: ${itemErr}`\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif (type === 'boolean' && typeof value !== 'boolean') {\n\t\treturn 'Value must be a boolean.'\n\t}\n\tif (Array.isArray(property.enum) && property.enum.length > 0 && !property.enum.includes(value)) {\n\t\treturn 'Value must be one of the allowed options.'\n\t}\n\treturn null\n}\n\n/**\n * Validate a string value against a JSON-Schema `format`.\n *\n * @param {string} format Schema format identifier.\n * @param {string} value String value to validate.\n * @return {string|null} Error message or null when valid.\n */\nfunction validateStringFormat(format, value) {\n\tif (!format) {\n\t\treturn null\n\t}\n\tif (format === 'time') {\n\t\t// HTML5 `<input type=\"time\">` produces `HH:MM` or `HH:MM:SS[.sss]`.\n\t\t// `new Date()` won't parse a bare time, so check the shape directly.\n\t\treturn /^([01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?$/.test(value)\n\t\t\t? null\n\t\t\t: 'Value must be a valid time.'\n\t}\n\tif (format === 'date' || format === 'date-time') {\n\t\treturn Number.isNaN(new Date(value).getTime()) ? `Value must be a valid ${format}.` : null\n\t}\n\tif (URL_FORMATS.has(format)) {\n\t\t// Accept fully-qualified URLs (`https://example.com`) and protocol-less\n\t\t// shorthand (`example.com/path`) by retrying with an `https://` prefix.\n\t\t// Reject obviously non-URL inputs (whitespace, missing dots / authority).\n\t\tif (/\\s/.test(value)) {\n\t\t\treturn 'Value must be a valid URL.'\n\t\t}\n\t\ttry {\n\t\t\tnew URL(value)\n\t\t\treturn null\n\t\t} catch {\n\t\t\t// Fall through to the prefix retry.\n\t\t}\n\t\ttry {\n\t\t\tconst parsed = new URL('https://' + value)\n\t\t\tif (parsed.hostname && parsed.hostname.includes('.')) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t} catch {\n\t\t\t// Fall through to the rejection below.\n\t\t}\n\t\treturn 'Value must be a valid URL.'\n\t}\n\tconst re = FORMAT_PATTERNS[format]\n\tif (re && !re.test(value)) {\n\t\treturn `Value must be a valid '${format}'.`\n\t}\n\treturn null\n}\n"],"names":[],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA,MAAM,cAAc,GAAG;AACvB,CAAC,OAAO,EAAE,MAAM;AAChB,CAAC,OAAO,EAAE,OAAO;AACjB,CAAC,MAAM,EAAE,OAAO;AAChB,CAAC,aAAa,EAAE,OAAO;AACvB,CAAC,kBAAkB,EAAE,OAAO;AAC5B,CAAC,cAAc,EAAE,OAAO;AACxB,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE;AACvC,CAAC,IAAI,MAAM,EAAE;AACb,EAAE,OAAO,cAAc,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAC5C,EAAE;AACF,CAAC,OAAO,cAAc,CAAC,IAAI,CAAC;AAC5B,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,EAAE,EAAE;AACxD,CAAC,MAAM,EAAE,OAAO,GAAG,EAAE,EAAE,OAAO,GAAG,IAAI,EAAE,SAAS,GAAG,EAAE,EAAE,SAAS,EAAE,GAAG,QAAO;AAC5E,CAAC,MAAM,EAAE,GAAG,OAAO,SAAS,KAAK,UAAU,GAAG,SAAS,GAAG,CAAC,IAAI,KAAK,KAAI;AACxE;AACA,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE;AACpC,EAAE,OAAO,EAAE;AACX,EAAE;AACF;AACA,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC;AAClD,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK;AAC3B;AACA,GAAG,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK,EAAE;AAC/B,IAAI,OAAO,KAAK;AAChB,IAAI;AACJ;AACA,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AAC9B,IAAI,OAAO,KAAK;AAChB,IAAI;AACJ;AACA,GAAG,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AAC1C,IAAI,OAAO,KAAK;AAChB,IAAI;AACJ;AACA,GAAG,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE;AAC/B,IAAI,OAAO,KAAK;AAChB,IAAI;AACJ,GAAG,OAAO,IAAI;AACd,GAAG,CAAC;AACJ,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK;AAC1C;AACA,GAAG,MAAM,MAAM,GAAG,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,GAAG,KAAK,CAAC,KAAK,GAAG,SAAQ;AAC1E,GAAG,MAAM,MAAM,GAAG,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,GAAG,KAAK,CAAC,KAAK,GAAG,SAAQ;AAC1E,GAAG,IAAI,MAAM,KAAK,MAAM,EAAE;AAC1B,IAAI,OAAO,MAAM,GAAG,MAAM;AAC1B,IAAI;AACJ,GAAG,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;AAClC,GAAG,EAAC;AACJ;AACA,CAAC,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK;AACrC,EAAE,MAAM,MAAM,GAAG;AACjB,GAAG,GAAG;AACN,GAAG,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,GAAG,CAAC;AAC/B;AACA;AACA;AACA;AACA,GAAG,WAAW,EAAE,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE;AAC5D,GAAG,QAAQ,EAAE,IAAI;AACjB,GAAG,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,QAAQ;AAC9B,GAAG,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI;AAC9B,IAAG;AACH;AACA;AACA,EAAE,MAAM,YAAY,GAAG,eAAe,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAC;AAClE,EAAE,IAAI,YAAY,EAAE;AACpB,GAAG,MAAM,CAAC,KAAK,GAAG,aAAY;AAC9B,GAAG;AACH;AACA;AACA,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE;AACjB,GAAG,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,KAAI;AAC1B,GAAG;AACH;AACA;AACA,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE;AAClB,GAAG,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,MAAK;AAC5B,GAAG;AACH;AACA;AACA,EAAE,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE;AACtB,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,EAAC;AACxC,GAAG;AACH;AACA,EAAE,OAAO,MAAM;AACf,EAAE,CAAC;AACH,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG,EAAE,EAAE,OAAO,GAAG,EAAE,EAAE;AAChE,CAAC,MAAM,EAAE,QAAQ,GAAG,GAAG,EAAE,GAAG,QAAO;AACnC;AACA;AACA,CAAC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE;AAC5D,EAAE,OAAO,GAAG;AACZ,EAAE;AACF;AACA,CAAC,MAAM,EAAE,IAAI,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,SAAQ;AAC7C;AACA;AACA,CAAC,IAAI,IAAI,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE;AACvD,EAAE,OAAO,KAAK,GAAG,GAAG,GAAG,GAAG;AAC1B,EAAE;AACF;AACA;AACA,CAAC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,QAAQ,EAAE;AAC9C,EAAE,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,EAAC;AAC3B,EAAE,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;AACzB,GAAG,OAAO,MAAM,CAAC,KAAK,CAAC;AACvB,GAAG;AACH,EAAE,OAAO,GAAG,CAAC,cAAc,EAAE;AAC7B,EAAE;AACF;AACA;AACA,CAAC,IAAI,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AAC/C,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AAC7B,GAAG,OAAO,MAAM,CAAC,KAAK,CAAC;AACvB,GAAG;AACH,EAAE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;AAC1B,GAAG,OAAO,GAAG;AACb,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK;AACjC,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE;AAC5C,IAAI,IAAI;AACR,KAAK,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;AAC7B,KAAK,CAAC,MAAM;AACZ,KAAK,OAAO,UAAU;AACtB,KAAK;AACL,IAAI;AACJ,GAAG,OAAO,MAAM,CAAC,CAAC,CAAC;AACnB,GAAG,EAAC;AACJ;AACA,EAAE,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE;AACzB,GAAG,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;AAC1B,GAAG;AACH,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAC/D,EAAE;AACF;AACA;AACA,CAAC,IAAI,IAAI,KAAK,QAAQ,KAAK,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,EAAE;AACzE,EAAE,IAAI;AACN,GAAG,OAAO,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC;AAClE,GAAG,CAAC,MAAM;AACV,GAAG,OAAO,UAAU;AACpB,GAAG;AACH,EAAE;AACF;AACA;AACA,CAAC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,EAAC;AAC1B;AACA;AACA,CAAC,IAAI,MAAM,KAAK,WAAW,IAAI,MAAM,KAAK,MAAM,EAAE;AAClD,EAAE,IAAI;AACN,GAAG,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,EAAC;AAC7B,GAAG,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;AACrC,IAAI,OAAO,GAAG;AACd,IAAI;AACJ,GAAG,IAAI,MAAM,KAAK,MAAM,EAAE;AAC1B,IAAI,OAAO,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE;AAC9C,KAAK,GAAG,EAAE,SAAS;AACnB,KAAK,KAAK,EAAE,SAAS;AACrB,KAAK,IAAI,EAAE,SAAS;AACpB,KAAK,CAAC;AACN,IAAI;AACJ,GAAG,OAAO,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE;AAC7C,IAAI,GAAG,EAAE,SAAS;AAClB,IAAI,KAAK,EAAE,SAAS;AACpB,IAAI,IAAI,EAAE,SAAS;AACnB,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE;AAClD,IAAI,IAAI,EAAE,SAAS;AACnB,IAAI,MAAM,EAAE,SAAS;AACrB,IAAI,MAAM,EAAE,SAAS;AACrB,IAAI,CAAC;AACL,GAAG,CAAC,MAAM;AACV,GAAG,OAAO,GAAG;AACb,GAAG;AACH,EAAE;AACF;AACA;AACA,CAAC,IAAI,MAAM,KAAK,MAAM,EAAE;AACxB,EAAE,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE;AACtB,GAAG,OAAO,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK;AACrC,GAAG;AACH,EAAE,OAAO,GAAG;AACZ,EAAE;AACF;AACA;AACA,CAAC,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,KAAK,EAAE;AAC3C,EAAE,IAAI;AACN,GAAG,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,EAAC;AAC3B,GAAG,OAAO,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC;AACtD,GAAG,CAAC,MAAM;AACV,GAAG,OAAO,cAAc,CAAC,GAAG,EAAE,QAAQ,CAAC;AACvC,GAAG;AACH,EAAE;AACF;AACA;AACA,CAAC,IAAI,MAAM,KAAK,UAAU,EAAE;AAC5B,EAAE,MAAM,QAAQ,GAAG,GAAG;AACtB,IAAI,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;AAC7B,IAAI,OAAO,CAAC,6BAA6B,EAAE,IAAI,CAAC;AAChD,IAAI,OAAO,CAAC,wBAAwB,EAAE,IAAI,CAAC;AAC3C,IAAI,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC;AACrC,IAAI,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;AACxB,IAAI,IAAI,GAAE;AACV,EAAE,OAAO,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC;AAC3C,EAAE;AACF;AACA;AACA,CAAC,IAAI,MAAM,KAAK,OAAO,EAAE;AACzB,EAAE,OAAO,GAAG;AACZ,EAAE;AACF;AACA;AACA,CAAC,OAAO,cAAc,CAAC,GAAG,EAAE,QAAQ,CAAC;AACrC,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,cAAc,CAAC,GAAG,EAAE,SAAS,EAAE;AACxC,CAAC,IAAI,GAAG,CAAC,MAAM,IAAI,SAAS,EAAE;AAC9B,EAAE,OAAO,GAAG;AACZ,EAAE;AACF,CAAC,OAAO,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,KAAK;AAC3C,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,YAAY,CAAC,GAAG,EAAE;AAC3B,CAAC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,EAAE,EAAE;AAC5C,EAAE,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,IAAG;AAChF,EAAE,IAAI,IAAI,KAAK,EAAE,EAAE;AACnB,GAAG,OAAO,IAAI;AACd,GAAG;AACH,EAAE,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,EAAC;AAClC,EAAE,OAAO,IAAI,KAAK,EAAE,GAAG,IAAI,GAAG,IAAI;AAClC,EAAE;AACF,CAAC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;AACpD,EAAE,OAAO,GAAG;AACZ,EAAE;AACF,CAAC,OAAO,IAAI;AACZ,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,UAAU,CAAC,IAAI,EAAE;AAC1B,CAAC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;AACxC,EAAE,OAAO,KAAK;AACd,EAAE;AACF,CAAC,IAAI,IAAI,CAAC,aAAa,KAAK,gBAAgB,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE;AACxE,EAAE,OAAO,IAAI;AACb,EAAE;AACF,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,GAAE;AACjC,CAAC,OAAO,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,UAAU,IAAI,MAAM,KAAK,SAAS;AAC1E,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,WAAW,CAAC,IAAI,EAAE;AAClC,CAAC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;AACxC,EAAE,OAAO,KAAK;AACd,EAAE;AACF,CAAC,OAAO,IAAI,CAAC,aAAa,KAAK,iBAAiB,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO;AACzG,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,mBAAmB,CAAC,KAAK,EAAE,QAAQ,EAAE;AAC9C,CAAC,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE;AAChD,EAAE,MAAM;AACR,EAAE;AACF,CAAC,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAM;AAC/B,CAAC,IAAI,MAAM,KAAK,OAAO,IAAI,MAAM,KAAK,mBAAmB,EAAE;AAC3D,EAAE,KAAK,CAAC,WAAW,GAAG,EAAE,QAAQ,EAAE,MAAM,KAAK,mBAAmB,GAAE;AAClE,EAAE,KAAK,CAAC,UAAU,GAAG,KAAI;AACzB,EAAE,MAAM,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,kBAAkB,EAAE;AAChE,EAAE,KAAK,CAAC,UAAU,GAAG,EAAE,QAAQ,EAAE,MAAM,KAAK,kBAAkB,GAAE;AAChE,EAAE,KAAK,CAAC,WAAW,GAAG,KAAI;AAC1B,EAAE;AACF,CAAC,IAAI,OAAO,QAAQ,CAAC,WAAW,CAAC,KAAK,QAAQ,IAAI,QAAQ,CAAC,WAAW,CAAC,KAAK,EAAE,EAAE;AAChF,EAAE,KAAK,CAAC,YAAY,GAAG,QAAQ,CAAC,WAAW,EAAC;AAC5C,EAAE;AACF,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,gBAAgB,CAAC,IAAI,EAAE;AAChC,CAAC,MAAM,IAAI,GAAG,IAAI,IAAI,IAAI,CAAC,gCAAgC,EAAC;AAC5D,CAAC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,IAAI,IAAI,CAAC,QAAQ,KAAK,EAAE,EAAE;AACrG,EAAE,OAAO,IAAI;AACb,EAAE;AACF,CAAC,OAAO;AACR,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ;AACzB,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,SAAS,GAAG,SAAS,GAAG,MAAM;AACpD,EAAE,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE;AAC7E,EAAE;AACF,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,cAAc,CAAC,IAAI,EAAE;AAC9B,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK;AACrB,EAAE,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE;AACnC,GAAG,OAAO,IAAI;AACd,GAAG;AACH,EAAE,MAAM,GAAG,GAAG,CAAC,CAAC,yBAAyB,EAAC;AAC1C,EAAE,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,EAAE;AACpD,GAAG,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,IAAI,GAAG,CAAC,KAAK,KAAK,EAAE,GAAG,GAAG,CAAC,KAAK,GAAG,KAAK,EAAE,eAAe,EAAE,OAAO,GAAG,CAAC,eAAe,KAAK,QAAQ,IAAI,GAAG,CAAC,eAAe,KAAK,EAAE,GAAG,GAAG,CAAC,eAAe,GAAG,IAAI,EAAE;AAC/M,GAAG;AACH,EAAE,IAAI,OAAO,CAAC,CAAC,aAAa,KAAK,QAAQ,IAAI,CAAC,CAAC,aAAa,KAAK,EAAE,EAAE;AACrE,GAAG,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE;AACjD,GAAG;AACH,EAAE,OAAO,IAAI;AACb,GAAE;AACF,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE;AACpC,EAAE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,EAAC;AAChD,EAAE,OAAO,OAAO,GAAG,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,IAAI;AACxD,EAAE;AACF,CAAC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAC;AAC3B,CAAC,OAAO,OAAO,GAAG,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,IAAI;AACxD,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,cAAc,CAAC,IAAI,EAAE;AAC9B,CAAC,OAAO,IAAI,CAAC,IAAI,KAAK,MAAM,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC;AACrG,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,YAAY,CAAC,IAAI,EAAE;AAC5B,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,KAAI;AACvE,CAAC,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,IAAI,MAAM,CAAC,aAAY;AACzD,CAAC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,GAAG,IAAI,CAAC,MAAM,GAAG,EAAE,EAAC;AACjH,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,EAAC;AACvD,CAAC,OAAO;AACR,EAAE,MAAM;AACR,EAAE,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC,GAAG,OAAO,GAAG,SAAS;AACxE,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,KAAK,OAAO;AACjC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,KAAK,aAAa,IAAI,IAAI,CAAC,OAAO,KAAK,MAAM,GAAG,IAAI,CAAC,OAAO,GAAG,EAAE;AACxF,EAAE;AACF,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,aAAa,CAAC,IAAI,EAAE;AAC7B;AACA,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE;AAClB,EAAE,OAAO,IAAI,CAAC,MAAM;AACpB,EAAE;AACF;AACA;AACA,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE;AAC3B,EAAE,OAAO,MAAM;AACf,EAAE;AACF;AACA;AACA,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,EAAE;AAC7B,EAAE,OAAO,iBAAiB;AAC1B,EAAE;AACF;AACA;AACA,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,aAAa,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE;AAChH,EAAE,OAAO,aAAa;AACtB,EAAE;AACF;AACA;AACA;AACA,CAAC;AACD,EAAE,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,EAAC;AACpC,EAAE,IAAI,KAAK,EAAE;AACb,GAAG,OAAO,KAAK,CAAC,QAAQ,GAAG,aAAa,GAAG,QAAQ;AACnD,GAAG;AACH,EAAE;AACF;AACA;AACA;AACA,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,KAAK,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,IAAI,IAAI,CAAC,UAAU,KAAK,EAAE,EAAE;AACrJ,EAAE,OAAO,eAAe;AACxB,EAAE;AACF;AACA;AACA,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,QAAQ,MAAM,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;AACvF,EAAE,OAAO,UAAU;AACnB,EAAE;AACF;AACA;AACA,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE;AAChB,EAAE,OAAO,QAAQ;AACjB,EAAE;AACF;AACA,CAAC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,SAAQ;AACnC,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,GAAE;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;AACvC,EAAE,OAAO,QAAQ;AACjB,EAAE;AACF,CAAC,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,KAAK,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;AAC/E,EAAE,OAAO,aAAa;AACtB,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE;AACvB,EAAE,OAAO,MAAM;AACf,EAAE;AACF,CAAC,IAAI,IAAI,KAAK,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;AACjD,EAAE,OAAO,kBAAkB;AAC3B,EAAE;AACF;AACA;AACA;AACA,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE;AACxB,EAAE,OAAO,OAAO;AAChB,EAAE;AACF,CAAC,IAAI,IAAI,KAAK,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;AAClD,EAAE,OAAO,mBAAmB;AAC5B,EAAE;AACF;AACA;AACA;AACA,CAAC,IAAI,IAAI,KAAK,QAAQ,IAAI,MAAM,KAAK,UAAU,EAAE;AACjD,EAAE,OAAO,UAAU;AACnB,EAAE;AACF,CAAC,IAAI,IAAI,KAAK,QAAQ,IAAI,MAAM,KAAK,UAAU,EAAE;AACjD,EAAE,OAAO,UAAU;AACnB,EAAE;AACF;AACA;AACA,CAAC,IAAI,IAAI,KAAK,SAAS,EAAE;AACzB,EAAE,OAAO,UAAU;AACnB,EAAE;AACF;AACA;AACA,CAAC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,QAAQ,EAAE;AAC9C,EAAE,OAAO,QAAQ;AACjB,EAAE;AACF;AACA;AACA,CAAC,IAAI,IAAI,KAAK,OAAO,EAAE;AACvB,EAAE,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;AACrC,GAAG,OAAO,aAAa;AACvB,GAAG;AACH,EAAE,OAAO,MAAM;AACf,EAAE;AACF;AACA;AACA,CAAC,IAAI,MAAM,KAAK,WAAW,EAAE;AAC7B,EAAE,OAAO,UAAU;AACnB,EAAE;AACF,CAAC,IAAI,MAAM,KAAK,MAAM,EAAE;AACxB,EAAE,OAAO,MAAM;AACf,EAAE;AACF,CAAC,IAAI,MAAM,KAAK,OAAO,EAAE;AACzB,EAAE,OAAO,OAAO;AAChB,EAAE;AACF,CAAC,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,KAAK,EAAE;AAC3C,EAAE,OAAO,KAAK;AACd,EAAE;AACF,CAAC,IAAI,MAAM,KAAK,UAAU,IAAI,MAAM,KAAK,UAAU,EAAE;AACrD,EAAE,OAAO,UAAU;AACnB,EAAE;AACF;AACA;AACA,CAAC,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,GAAG,GAAG,EAAE;AAC7C,EAAE,OAAO,UAAU;AACnB,EAAE;AACF;AACA,CAAC,OAAO,MAAM;AACd,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,sBAAsB,GAAG,IAAG;AAClC;AACA;AACA,MAAM,0BAA0B,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAC;AACpG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,eAAe,CAAC,IAAI,EAAE;AAC/B,CAAC,MAAM,QAAQ,GAAG,iBAAgB;AAClC,CAAC,IAAI,MAAK;AACV,CAAC,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE;AAChD,EAAE,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,WAAW,GAAE;AAC9E;AACA,EAAE,IAAI,0BAA0B,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;AAClF,GAAG,QAAQ;AACX,GAAG;AACH,EAAE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC;AACvC,EAAE;AACF,CAAC,OAAO,EAAE;AACV,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,WAAW,CAAC,IAAI,EAAE,GAAG,EAAE;AAChC,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,EAAC;AAC/B,CAAC,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,EAAC;AACvC;AACA,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;AAC/E,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gBAAgB,CAAC,IAAI,EAAE,GAAG,GAAG,sBAAsB,EAAE;AACrE,CAAC,MAAM,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,GAAE;AACzD,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG,EAAE;AAClC,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE;AAClC,EAAE;AACF;AACA,CAAC,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,EAAC;AACvC,CAAC,OAAO;AACR,EAAE,KAAK,EAAE,QAAQ,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,GAAG,QAAQ,GAAG,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC;AAC/E,EAAE,IAAI,EAAE,IAAI;AACZ,EAAE;AACF,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,UAAU,EAAE,YAAY,CAAC,EAAC;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gBAAgB,CAAC,GAAG,EAAE,IAAI,EAAE;AAC5C,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,GAAG,GAAE;AACzD,CAAC,IAAI,CAAC,CAAC,uBAAuB,CAAC,KAAK,KAAK,EAAE;AAC3C,EAAE,OAAO,KAAK;AACd,EAAE;AACF,CAAC,IAAI,CAAC,CAAC,uBAAuB,CAAC,KAAK,IAAI;AACxC,KAAK,CAAC,CAAC,oBAAoB,CAAC,KAAK,IAAI;AACrC,KAAK,CAAC,CAAC,cAAc,CAAC,KAAK,UAAU;AACrC,KAAK,CAAC,CAAC,MAAM,KAAK,QAAQ;AAC1B,KAAK,CAAC,CAAC,aAAa,KAAK,QAAQ,EAAE;AACnC,EAAE,OAAO,IAAI;AACb,EAAE;AACF,CAAC,MAAM,IAAI,GAAG,OAAO,GAAG,KAAK,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,GAAE;AACnF,CAAC,OAAO,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC;AACvC,CAAC;AACD;AACA,MAAM,UAAU,GAAG,IAAI,GAAG,GAAE;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,QAAQ,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE;AAC5C,CAAC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE;AAC5C,EAAE,OAAO,EAAE;AACX,EAAE;AACF,CAAC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;AAChC,EAAE,OAAO,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE;AACpD,EAAE;AACF,CAAC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AACzD,EAAE,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAC;AAC3G,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,EAAC;AAC3G,EAAE,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAC;AACvE,EAAE,OAAO,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC;AAC7H,EAAE;AACF,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;AAC3B,EAAE,UAAU,CAAC,GAAG,CAAC,GAAG,EAAC;AACrB;AACA,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,gCAAgC,EAAE,GAAG,CAAC,kEAAkE,CAAC,EAAC;AAC1H,EAAE;AACF,CAAC,OAAO,EAAE;AACV,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gBAAgB,CAAC,MAAM,EAAE,OAAO,GAAG,EAAE,EAAE;AACvD,CAAC,MAAM,EAAE,OAAO,GAAG,EAAE,EAAE,OAAO,GAAG,IAAI,EAAE,SAAS,GAAG,EAAE,EAAE,eAAe,GAAG,KAAK,EAAE,UAAU,GAAG,KAAK,EAAE,SAAS,EAAE,QAAQ,GAAG,EAAE,EAAE,GAAG,QAAO;AACxI,CAAC,MAAM,EAAE,GAAG,OAAO,SAAS,KAAK,UAAU,GAAG,SAAS,GAAG,CAAC,IAAI,KAAK,KAAI;AACxE;AACA,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE;AACpC,EAAE,OAAO,EAAE;AACX,EAAE;AACF;AACA,CAAC,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC,QAAQ,GAAG,GAAE;AAC3E;AACA,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC;AAClD,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK;AAC3B;AACA,GAAG,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK,EAAE;AAC/B,IAAI,OAAO,KAAK;AAChB,IAAI;AACJ;AACA;AACA;AACA,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,IAAI,EAAE;AACxC,IAAI,OAAO,KAAK;AAChB,IAAI;AACJ;AACA;AACA;AACA,GAAG,IAAI,UAAU,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,KAAK,IAAI,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE;AACtF,IAAI,OAAO,KAAK;AAChB,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA,GAAG,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,IAAI,CAAC,eAAe,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,QAAQ,KAAK,KAAK,EAAE;AACzF,IAAI,OAAO,KAAK;AAChB,IAAI;AACJ;AACA,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AAC9B,IAAI,OAAO,KAAK;AAChB,IAAI;AACJ;AACA,GAAG,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AAC1C,IAAI,OAAO,KAAK;AAChB,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA,GAAG,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;AACnF,IAAI,OAAO,KAAK;AAChB,IAAI;AACJ,GAAG,OAAO,IAAI;AACd,GAAG,CAAC;AACJ,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK;AAC1C;AACA;AACA;AACA;AACA,GAAG,MAAM,MAAM,GAAG,OAAO,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,KAAK,QAAQ;AAC5D,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK;AAC3B,OAAO,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,GAAG,KAAK,CAAC,KAAK,GAAG,QAAQ,EAAC;AAChE,GAAG,MAAM,MAAM,GAAG,OAAO,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,KAAK,QAAQ;AAC5D,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK;AAC3B,OAAO,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,GAAG,KAAK,CAAC,KAAK,GAAG,QAAQ,EAAC;AAChE,GAAG,IAAI,MAAM,KAAK,MAAM,EAAE;AAC1B,IAAI,OAAO,MAAM,GAAG,MAAM;AAC1B,IAAI;AACJ,GAAG,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;AAClC,GAAG,EAAC;AACJ;AACA,CAAC,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK;AACrC,EAAE,MAAM,WAAW,GAAG,gBAAgB,CAAC,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,EAAC;AACpF;AACA,EAAE,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAC;AAC1D,EAAE,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC;AAC1C,OAAO,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;AACjD,MAAM,KAAI;AACV,EAAE,MAAM,KAAK,GAAG;AAChB,GAAG,GAAG;AACN,GAAG,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,GAAG,CAAC;AAC/B,GAAG,WAAW,EAAE,WAAW,CAAC,KAAK;AACjC,GAAG,eAAe,EAAE,IAAI,IAAI,WAAW,CAAC,IAAI;AAC5C,GAAG,IAAI;AACP,GAAG,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,QAAQ;AAC9B,GAAG,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI;AAC9B,GAAG,MAAM,EAAE,aAAa,CAAC,IAAI,CAAC;AAC9B;AACA,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,SAAS;AAC7C,GAAG,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,SAAS;AAC3C,GAAG,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,SAAS;AACnD,GAAG,UAAU,EAAE,IAAI,CAAC,UAAU;AAC9B,GAAG,QAAQ,EAAE,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC;AACvC,GAAG,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,KAAK;AACnC,GAAG,OAAO,EAAE,IAAI,CAAC,OAAO,KAAK,SAAS,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI;AAC5D;AACA;AACA;AACA,GAAG,YAAY,EAAE,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,IAAI;AACjF,GAAG,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI;AAC1B;AACA;AACA;AACA;AACA;AACA,GAAG,UAAU,EAAE,IAAI,CAAC,UAAU;AAC9B,OAAO,IAAI,CAAC,eAAe,CAAC;AAC5B,QAAQ,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;AAC7E,OAAO,IAAI;AACX,GAAG,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI;AAC5B;AACA;AACA;AACA;AACA,GAAG,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG,qBAAqB,EAAE,IAAI,CAAC,qBAAqB,IAAI,IAAI;AAC5D,GAAG,oBAAoB,EAAE,IAAI,CAAC,oBAAoB,IAAI,IAAI;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG,SAAS,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI;AAC/C,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,qBAAqB,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,UAAU,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,EAAE;AACpL,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,KAAK,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI;AACpF,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,IAAI,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,IAAI,IAAI,CAAC,qBAAqB,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,UAAU,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,EAAE;AACvQ,QAAQ,IAAI;AACZ;AACA;AACA,GAAG,QAAQ,EAAE,CAAC,MAAM;AACpB,IAAI,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,EAAC;AACtC,IAAI,OAAO,KAAK,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,eAAe,EAAE,KAAK,CAAC,eAAe,EAAE,GAAG,IAAI;AACjI,IAAI,GAAG;AACP;AACA;AACA;AACA,GAAG,YAAY,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,eAAe;AACxD,MAAM;AACN,MAAM,MAAM,EAAE,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,EAAE,GAAG,IAAI,CAAC,MAAM,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;AACvI,MAAM,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,UAAU,IAAI,EAAE;AAC5D,MAAM,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,EAAE;AAC9D,MAAM;AACN,MAAM,IAAI;AACV;AACA;AACA;AACA,GAAG,WAAW,EAAE,IAAI,CAAC,gBAAgB,CAAC,KAAK,IAAI;AAC/C,QAAQ,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;AACvF;AACA;AACA;AACA,GAAG,cAAc,EAAE,gBAAgB,CAAC,IAAI,CAAC;AACzC,GAAG,QAAQ,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,IAAI;AAC1G;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG,UAAU,EAAE,UAAU,CAAC,IAAI,CAAC;AAC/B,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;AACzB,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC;AACtD,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;AAC1B,QAAQ,IAAI;AACZ;AACA;AACA,GAAG,WAAW,EAAE,WAAW,CAAC,IAAI,CAAC;AACjC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;AACzB,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC;AACvD,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;AAC1B,QAAQ,IAAI;AACZ;AACA;AACA;AACA;AACA;AACA,GAAG,YAAY,EAAE,IAAI,CAAC,8BAA8B,CAAC,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI;AAClF,GAAG,UAAU,EAAE;AACf,IAAI,SAAS,EAAE,IAAI,CAAC,SAAS;AAC7B,IAAI,SAAS,EAAE,IAAI,CAAC,SAAS;AAC7B,IAAI,OAAO,EAAE,IAAI,CAAC,OAAO;AACzB,IAAI,OAAO,EAAE,IAAI,CAAC,OAAO;AACzB,IAAI,OAAO,EAAE,IAAI,CAAC,OAAO;AACzB,IAAI;AACJ,GAAG,KAAK,EAAE,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,GAAG,IAAI,CAAC,KAAK,GAAG,QAAQ;AAChE,IAAG;AACH;AACA;AACA,EAAE,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE;AACtB,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,EAAC;AACvC,GAAG,mBAAmB,CAAC,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,EAAC;AAC7C,GAAG,qBAAqB,CAAC,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,EAAC;AACnD,GAAG;AACH;AACA,EAAE,OAAO,KAAK;AACd,EAAE,CAAC;AACH,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,qBAAqB,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE;AACpD,CAAC,KAAK,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,aAAa,CAAC,EAAE;AAC7D,EAAE,IAAI,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,QAAQ,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE;AACnE,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAC;AACnC,GAAG;AACH,EAAE;AACF,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,EAAE,EAAE;AACxD,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE;AACpC,EAAE,OAAO,EAAE;AACX,EAAE;AACF;AACA,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,QAAO;AAC9B,CAAC,MAAM,EAAE,GAAG,OAAO,SAAS,KAAK,UAAU,GAAG,SAAS,GAAG,CAAC,IAAI,KAAK,KAAI;AACxE;AACA,CAAC,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC;AACzC,GAAG,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK;AACxB,GAAG,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE;AAChC,IAAI,OAAO,KAAK;AAChB,IAAI;AACJ,GAAG,OAAO,IAAI;AACd,GAAG,CAAC;AACJ,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK;AAC1C,GAAG,MAAM,MAAM,GAAG,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,GAAG,KAAK,CAAC,KAAK,GAAG,SAAQ;AAC1E,GAAG,MAAM,MAAM,GAAG,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,GAAG,KAAK,CAAC,KAAK,GAAG,SAAQ;AAC1E,GAAG,IAAI,MAAM,KAAK,MAAM,EAAE;AAC1B,IAAI,OAAO,MAAM,GAAG,MAAM;AAC1B,IAAI;AACJ,GAAG,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;AAClC,GAAG,CAAC;AACJ,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK;AACxB,GAAG,MAAM,MAAM,GAAG;AAClB,IAAI,GAAG;AACP,IAAI,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,GAAG,CAAC;AAChC,IAAI,WAAW,EAAE,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE;AAC7D,IAAI,YAAY,EAAE,IAAI,CAAC,IAAI,IAAI,QAAQ;AACvC,IAAI,OAAO,EAAE,EAAE;AACf,IAAI,KAAK,EAAE,IAAI;AACf,KAAI;AACJ;AACA;AACA,GAAG,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE;AAChC,IAAI,MAAM,CAAC,IAAI,GAAG,WAAU;AAC5B,IAAI,MAAM,IAAI,IAAI,CAAC,IAAI,EAAE;AACzB,IAAI,MAAM,CAAC,IAAI,GAAG,SAAQ;AAC1B,IAAI,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,GAAE;AACrE,IAAI,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM;AAC7C,KAAK,EAAE,EAAE,GAAG;AACZ;AACA;AACA,KAAK,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;AAC9C,KAAK,CAAC,EAAC;AACP,IAAI,MAAM;AACV;AACA,IAAI,MAAM,CAAC,IAAI,GAAG,SAAQ;AAC1B,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,IAAI,GAAE;AACzD,GAAG,IAAI,OAAO,KAAK,YAAY,IAAI,OAAO,KAAK,OAAO,EAAE;AACxD,IAAI,MAAM,CAAC,IAAI,GAAG,aAAY;AAC9B,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;AACrC,KAAK,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,MAAM;AACpD,MAAM,GAAG,MAAM;AACf,MAAM,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,EAAE,CAAC;AAC1C,MAAM,CAAC,EAAC;AACR,KAAK;AACL,IAAI,MAAM,IAAI,OAAO,KAAK,MAAM,EAAE;AAClC,IAAI,MAAM,CAAC,IAAI,GAAG,OAAM;AACxB,IAAI,MAAM,IAAI,OAAO,KAAK,WAAW,EAAE;AACvC;AACA;AACA;AACA,IAAI,MAAM,CAAC,IAAI,GAAG,YAAW;AAC7B,IAAI,MAAM,IAAI,OAAO,KAAK,SAAS,EAAE;AACrC,IAAI,MAAM,CAAC,IAAI,GAAG,WAAU;AAC5B,IAAI;AACJ;AACA,GAAG,IAAI,IAAI,CAAC,aAAa,IAAI,OAAO,IAAI,CAAC,aAAa,KAAK,QAAQ,EAAE;AACrE,IAAI,MAAM,CAAC,aAAa,GAAG,IAAI,CAAC,cAAa;AAC7C,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA,GAAG,MAAM,CAAC,QAAQ,GAAG,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,YAAW;AACpE;AACA,GAAG,OAAO,MAAM;AAChB,GAAG,CAAC;AACJ,CAAC;AACD;AACA;AACA;AACA;AACA,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC;AAC5B,CAAC,KAAK;AACN,CAAC,KAAK;AACN,CAAC,eAAe;AAChB,CAAC,KAAK;AACN,CAAC,eAAe;AAChB,CAAC,cAAc;AACf,CAAC,WAAW;AACZ,CAAC,UAAU;AACX,CAAC,aAAa;AACd,CAAC,EAAC;AACF;AACA;AACA;AACA;AACA,MAAM,eAAe,GAAG;AACxB,CAAC,KAAK,EAAE,6BAA6B;AACrC,CAAC,WAAW,EAAE,6BAA6B;AAC3C,CAAC,IAAI,EAAE,iEAAiE;AACxE,CAAC,IAAI,EAAE,6CAA6C;AACpD,CAAC,IAAI,EAAE,wpBAAwpB;AAC/pB,CAAC,QAAQ,EAAE,iGAAiG;AAC5G,CAAC,MAAM,EAAE,wCAAwC;AACjD,CAAC,WAAW,EAAE,iBAAiB;AAC/B,CAAC,iBAAiB,EAAE,iBAAiB;AACrC,CAAC,WAAW,EAAE,qDAAqD;AACnE,CAAC,YAAY,EAAE,mEAAmE;AAClF,CAAC,WAAW,EAAE,uDAAuD;AACrE,CAAC,YAAY,EAAE,qEAAqE;AACpF,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,aAAa,CAAC,KAAK,EAAE,QAAQ,GAAG,EAAE,EAAE,OAAO,GAAG,EAAE,EAAE;AAClE,CAAC,MAAM,EAAE,QAAQ,GAAG,KAAK,EAAE,GAAG,QAAO;AACrC,CAAC,MAAM,KAAK,GAAG,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;AACpE,MAAM,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAC;AACjD,CAAC,IAAI,KAAK,EAAE;AACZ,EAAE,OAAO,QAAQ,GAAG,yBAAyB,GAAG,IAAI;AACpD,EAAE;AACF,CAAC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,IAAI,SAAQ;AACvC,CAAC,IAAI,IAAI,KAAK,SAAS,EAAE;AACzB,EAAE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE;AAC7D,GAAG,OAAO,2BAA2B;AACrC,GAAG;AACH,EAAE,MAAM,IAAI,IAAI,KAAK,QAAQ,EAAE;AAC/B,EAAE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;AACxD,GAAG,OAAO,yBAAyB;AACnC,GAAG;AACH,EAAE;AACF,CAAC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,QAAQ,EAAE;AAC9C,EAAE,IAAI,OAAO,QAAQ,CAAC,OAAO,KAAK,QAAQ,IAAI,KAAK,GAAG,QAAQ,CAAC,OAAO,EAAE;AACxE,GAAG,OAAO,CAAC,uBAAuB,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;AACvD,GAAG;AACH,EAAE,IAAI,OAAO,QAAQ,CAAC,OAAO,KAAK,QAAQ,IAAI,KAAK,GAAG,QAAQ,CAAC,OAAO,EAAE;AACxE,GAAG,OAAO,CAAC,sBAAsB,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;AACtD,GAAG;AACH,EAAE;AACF,CAAC,IAAI,IAAI,KAAK,QAAQ,EAAE;AACxB,EAAE,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;AACjC,GAAG,OAAO,yBAAyB;AACnC,GAAG;AACH,EAAE,IAAI,OAAO,QAAQ,CAAC,SAAS,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,SAAS,EAAE;AACnF,GAAG,OAAO,CAAC,iBAAiB,EAAE,QAAQ,CAAC,SAAS,CAAC,YAAY,CAAC;AAC9D,GAAG;AACH,EAAE,IAAI,OAAO,QAAQ,CAAC,SAAS,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,SAAS,EAAE;AACnF,GAAG,OAAO,CAAC,gBAAgB,EAAE,QAAQ,CAAC,SAAS,CAAC,YAAY,CAAC;AAC7D,GAAG;AACH,EAAE,IAAI,QAAQ,CAAC,OAAO,EAAE;AACxB,GAAG,IAAI;AACP,IAAI,IAAI,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;AACnD,KAAK,OAAO,4CAA4C;AACxD,KAAK;AACL,IAAI,CAAC,MAAM;AACX;AACA,IAAI;AACJ,GAAG;AACH,EAAE,IAAI,QAAQ,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,QAAQ,CAAC,KAAK,EAAE;AAChE,GAAG,OAAO,CAAC,eAAe,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;AAC9C,GAAG;AACH,EAAE,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAC;AAC7D,EAAE,IAAI,MAAM,EAAE;AACd,GAAG,OAAO,MAAM;AAChB,GAAG;AACH,EAAE;AACF,CAAC,IAAI,IAAI,KAAK,OAAO,EAAE;AACvB,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AAC7B,GAAG,OAAO,uBAAuB;AACjC,GAAG;AACH,EAAE,IAAI,OAAO,QAAQ,CAAC,QAAQ,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,QAAQ,EAAE;AACjF,GAAG,OAAO,CAAC,gBAAgB,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;AACvD,GAAG;AACH,EAAE,IAAI,OAAO,QAAQ,CAAC,QAAQ,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,QAAQ,EAAE;AACjF,GAAG,OAAO,CAAC,eAAe,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;AACtD,GAAG;AACH,EAAE,IAAI,QAAQ,CAAC,KAAK,IAAI,OAAO,QAAQ,CAAC,KAAK,KAAK,QAAQ,EAAE;AAC5D,GAAG,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AAC1C,IAAI,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,KAAK,EAAC;AAC3D,IAAI,IAAI,OAAO,EAAE;AACjB,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;AACvC,KAAK;AACL,IAAI;AACJ,GAAG;AACH,EAAE;AACF,CAAC,IAAI,IAAI,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE;AACvD,EAAE,OAAO,0BAA0B;AACnC,EAAE;AACF,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;AACjG,EAAE,OAAO,2CAA2C;AACpD,EAAE;AACF,CAAC,OAAO,IAAI;AACZ,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,oBAAoB,CAAC,MAAM,EAAE,KAAK,EAAE;AAC7C,CAAC,IAAI,CAAC,MAAM,EAAE;AACd,EAAE,OAAO,IAAI;AACb,EAAE;AACF,CAAC,IAAI,MAAM,KAAK,MAAM,EAAE;AACxB;AACA;AACA,EAAE,OAAO,kDAAkD,CAAC,IAAI,CAAC,KAAK,CAAC;AACvE,KAAK,IAAI;AACT,KAAK,6BAA6B;AAClC,EAAE;AACF,CAAC,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,WAAW,EAAE;AAClD,EAAE,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI;AAC5F,EAAE;AACF,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;AAC9B;AACA;AACA;AACA,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;AACxB,GAAG,OAAO,4BAA4B;AACtC,GAAG;AACH,EAAE,IAAI;AACN,GAAG,IAAI,GAAG,CAAC,KAAK,EAAC;AACjB,GAAG,OAAO,IAAI;AACd,GAAG,CAAC,MAAM;AACV;AACA,GAAG;AACH,EAAE,IAAI;AACN,GAAG,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,UAAU,GAAG,KAAK,EAAC;AAC7C,GAAG,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AACzD,IAAI,OAAO,IAAI;AACf,IAAI;AACJ,GAAG,CAAC,MAAM;AACV;AACA,GAAG;AACH,EAAE,OAAO,4BAA4B;AACrC,EAAE;AACF,CAAC,MAAM,EAAE,GAAG,eAAe,CAAC,MAAM,EAAC;AACnC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;AAC5B,EAAE,OAAO,CAAC,uBAAuB,EAAE,MAAM,CAAC,EAAE,CAAC;AAC7C,EAAE;AACF,CAAC,OAAO,IAAI;AACZ;;;;"}
@@ -26,7 +26,7 @@
26
26
  * A token is valid only in the context whose resolver runs on it:
27
27
  *
28
28
  * - **filter** — `resolveFilterTokens`, resolved at fetch time:
29
- * `@me`, `@myGroups`, `@now`, `@today`, `@today±Nd`, `@monthStart`,
29
+ * `@me`, `@myGroups`, `@now`, `@today`, `@today±Nd`, `@monthStart`, `@monthEnd`, `@nextMonthStart`,
30
30
  * `@quarterStart`, `@yearStart`.
31
31
  * - **config** — `IAppConfig`-sourced: `@resolve:<key>`, `@config.<key>`
32
32
  * (trailing `?` marks optional).
@@ -67,7 +67,7 @@
67
67
  * @type {Readonly<Record<string, string>>}
68
68
  */
69
69
  const SENTINEL_TOKEN_PATTERNS = Object.freeze({
70
- filter: '^@(?:me(?:\\.(?:displayName|email))?|myGroups|now|today|monthStart|quarterStart|yearStart)$|^@today[+-][0-9]+d$',
70
+ filter: '^@(?:me(?:\\.(?:displayName|email))?|myGroups|now|today|monthStart|monthEnd|nextMonthStart|quarterStart|yearStart)$|^@today[+-][0-9]+d$',
71
71
  config: '^@resolve:[a-z][a-z0-9_-]*$|^@config\\.[A-Za-z][A-Za-z0-9_.]*\\??$',
72
72
  object: '^@objectId$|^@object\\.[A-Za-z][A-Za-z0-9_]*$',
73
73
  workspace: '^@workspace\\.[A-Za-z][A-Za-z0-9_]*\\??$',
@@ -117,7 +117,7 @@ const SENTINEL_VOCABULARY = Object.freeze({
117
117
  filter: {
118
118
  resolver: 'resolveFilterTokens',
119
119
  description: 'Relative fetch-time tokens (current user, the current user\'s groups as an IN list, relative dates).',
120
- members: ['@me', '@me.displayName', '@me.email', '@myGroups', '@now', '@today', '@today±Nd', '@monthStart', '@quarterStart', '@yearStart'],
120
+ members: ['@me', '@me.displayName', '@me.email', '@myGroups', '@now', '@today', '@today±Nd', '@monthStart', '@monthEnd', '@nextMonthStart', '@quarterStart', '@yearStart'],
121
121
  },
122
122
  config: {
123
123
  resolver: 'resolveManifestSentinels / resolveFilterTokens',