@strapi/upload 5.51.1 → 5.52.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 (369) hide show
  1. package/dist/admin/components/AssetCard/VideoPreview.js +1 -1
  2. package/dist/admin/components/AssetCard/VideoPreview.js.map +1 -1
  3. package/dist/admin/components/AssetCard/VideoPreview.mjs +1 -1
  4. package/dist/admin/components/AssetCard/VideoPreview.mjs.map +1 -1
  5. package/dist/admin/components/TableList/TableList.js +1 -1
  6. package/dist/admin/components/TableList/TableList.js.map +1 -1
  7. package/dist/admin/components/TableList/TableList.mjs +1 -1
  8. package/dist/admin/components/TableList/TableList.mjs.map +1 -1
  9. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js +21 -4
  10. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.js.map +1 -1
  11. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs +21 -4
  12. package/dist/admin/components/UploadAssetDialog/AddAssetStep/FromUrlForm.mjs.map +1 -1
  13. package/dist/admin/future/App.js +3 -3
  14. package/dist/admin/future/App.js.map +1 -1
  15. package/dist/admin/future/App.mjs +4 -4
  16. package/dist/admin/future/App.mjs.map +1 -1
  17. package/dist/admin/future/components/BetaNotice.js +72 -0
  18. package/dist/admin/future/components/BetaNotice.js.map +1 -0
  19. package/dist/admin/future/components/BetaNotice.mjs +70 -0
  20. package/dist/admin/future/components/BetaNotice.mjs.map +1 -0
  21. package/dist/admin/future/components/Drawer.js +18 -3
  22. package/dist/admin/future/components/Drawer.js.map +1 -1
  23. package/dist/admin/future/components/Drawer.mjs +18 -3
  24. package/dist/admin/future/components/Drawer.mjs.map +1 -1
  25. package/dist/admin/future/components/UploadProgressDialog.js +200 -27
  26. package/dist/admin/future/components/UploadProgressDialog.js.map +1 -1
  27. package/dist/admin/future/components/UploadProgressDialog.mjs +203 -30
  28. package/dist/admin/future/components/UploadProgressDialog.mjs.map +1 -1
  29. package/dist/admin/future/hooks/useAIMetadataEnabled.js +39 -0
  30. package/dist/admin/future/hooks/useAIMetadataEnabled.js.map +1 -0
  31. package/dist/admin/future/hooks/useAIMetadataEnabled.mjs +37 -0
  32. package/dist/admin/future/hooks/useAIMetadataEnabled.mjs.map +1 -0
  33. package/dist/admin/future/hooks/useMediaLibraryPermissions.js +35 -0
  34. package/dist/admin/future/hooks/useMediaLibraryPermissions.js.map +1 -0
  35. package/dist/admin/future/hooks/useMediaLibraryPermissions.mjs +33 -0
  36. package/dist/admin/future/hooks/useMediaLibraryPermissions.mjs.map +1 -0
  37. package/dist/admin/future/pages/Assets/AssetsPage.js +453 -170
  38. package/dist/admin/future/pages/Assets/AssetsPage.js.map +1 -1
  39. package/dist/admin/future/pages/Assets/AssetsPage.mjs +454 -171
  40. package/dist/admin/future/pages/Assets/AssetsPage.mjs.map +1 -1
  41. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.js +46 -0
  42. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.js.map +1 -0
  43. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.mjs +44 -0
  44. package/dist/admin/future/pages/Assets/components/ActionsMenuContent.mjs.map +1 -0
  45. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js +325 -0
  46. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.js.map +1 -0
  47. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs +323 -0
  48. package/dist/admin/future/pages/Assets/components/AssetActionsMenu.mjs.map +1 -0
  49. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js +110 -46
  50. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.js.map +1 -1
  51. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs +110 -46
  52. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetCropEditor.mjs.map +1 -1
  53. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js +95 -67
  54. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.js.map +1 -1
  55. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs +95 -68
  56. package/dist/admin/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.mjs.map +1 -1
  57. package/dist/admin/future/pages/Assets/components/AssetsGrid.js +94 -26
  58. package/dist/admin/future/pages/Assets/components/AssetsGrid.js.map +1 -1
  59. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs +96 -28
  60. package/dist/admin/future/pages/Assets/components/AssetsGrid.mjs.map +1 -1
  61. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js +112 -0
  62. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.js.map +1 -0
  63. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs +110 -0
  64. package/dist/admin/future/pages/Assets/components/AssetsSearchInput.mjs.map +1 -0
  65. package/dist/admin/future/pages/Assets/components/AssetsTable.js +172 -56
  66. package/dist/admin/future/pages/Assets/components/AssetsTable.js.map +1 -1
  67. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs +175 -59
  68. package/dist/admin/future/pages/Assets/components/AssetsTable.mjs.map +1 -1
  69. package/dist/admin/future/pages/Assets/components/BulkActionsBar.js +188 -138
  70. package/dist/admin/future/pages/Assets/components/BulkActionsBar.js.map +1 -1
  71. package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs +191 -141
  72. package/dist/admin/future/pages/Assets/components/BulkActionsBar.mjs.map +1 -1
  73. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js +123 -76
  74. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.js.map +1 -1
  75. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs +126 -79
  76. package/dist/admin/future/pages/Assets/components/BulkMoveDialog.mjs.map +1 -1
  77. package/dist/admin/future/pages/Assets/components/BusyOverlay.js +36 -0
  78. package/dist/admin/future/pages/Assets/components/BusyOverlay.js.map +1 -0
  79. package/dist/admin/future/pages/Assets/components/BusyOverlay.mjs +34 -0
  80. package/dist/admin/future/pages/Assets/components/BusyOverlay.mjs.map +1 -0
  81. package/dist/admin/future/pages/Assets/components/DateRangeCalendar.js +193 -0
  82. package/dist/admin/future/pages/Assets/components/DateRangeCalendar.js.map +1 -0
  83. package/dist/admin/future/pages/Assets/components/DateRangeCalendar.mjs +191 -0
  84. package/dist/admin/future/pages/Assets/components/DateRangeCalendar.mjs.map +1 -0
  85. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.js +131 -0
  86. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.js.map +1 -0
  87. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.mjs +129 -0
  88. package/dist/admin/future/pages/Assets/components/DeleteItemsDialog.mjs.map +1 -0
  89. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js +45 -18
  90. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.js.map +1 -1
  91. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs +46 -19
  92. package/dist/admin/future/pages/Assets/components/Dnd/AssetsDndProvider.mjs.map +1 -1
  93. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js +28 -31
  94. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.js.map +1 -1
  95. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs +28 -31
  96. package/dist/admin/future/pages/Assets/components/Dnd/buildDragSet.mjs.map +1 -1
  97. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js +10 -15
  98. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.js.map +1 -1
  99. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs +10 -15
  100. package/dist/admin/future/pages/Assets/components/Dnd/useAssetDnd.mjs.map +1 -1
  101. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.js +13 -3
  102. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.js.map +1 -1
  103. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.mjs +13 -3
  104. package/dist/admin/future/pages/Assets/components/DropZone/UploadDropZoneContext.mjs.map +1 -1
  105. package/dist/admin/future/pages/Assets/components/EmptyState.js +62 -3
  106. package/dist/admin/future/pages/Assets/components/EmptyState.js.map +1 -1
  107. package/dist/admin/future/pages/Assets/components/EmptyState.mjs +62 -4
  108. package/dist/admin/future/pages/Assets/components/EmptyState.mjs.map +1 -1
  109. package/dist/admin/future/pages/Assets/components/FilterBadges.js +417 -0
  110. package/dist/admin/future/pages/Assets/components/FilterBadges.js.map +1 -0
  111. package/dist/admin/future/pages/Assets/components/FilterBadges.mjs +415 -0
  112. package/dist/admin/future/pages/Assets/components/FilterBadges.mjs.map +1 -0
  113. package/dist/admin/future/pages/Assets/components/FilterMenu.js +453 -0
  114. package/dist/admin/future/pages/Assets/components/FilterMenu.js.map +1 -0
  115. package/dist/admin/future/pages/Assets/components/FilterMenu.mjs +447 -0
  116. package/dist/admin/future/pages/Assets/components/FilterMenu.mjs.map +1 -0
  117. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js +144 -0
  118. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.js.map +1 -0
  119. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs +142 -0
  120. package/dist/admin/future/pages/Assets/components/FolderActionsMenu.mjs.map +1 -0
  121. package/dist/admin/future/pages/Assets/components/{CreateFolderDialog.js → FolderFormDialog.js} +50 -16
  122. package/dist/admin/future/pages/Assets/components/FolderFormDialog.js.map +1 -0
  123. package/dist/admin/future/pages/Assets/components/{CreateFolderDialog.mjs → FolderFormDialog.mjs} +52 -18
  124. package/dist/admin/future/pages/Assets/components/FolderFormDialog.mjs.map +1 -0
  125. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js +125 -148
  126. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.js.map +1 -1
  127. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs +127 -150
  128. package/dist/admin/future/pages/Assets/components/FolderTree/FolderTree.mjs.map +1 -1
  129. package/dist/admin/future/pages/Assets/components/SortMenu.js +21 -32
  130. package/dist/admin/future/pages/Assets/components/SortMenu.js.map +1 -1
  131. package/dist/admin/future/pages/Assets/components/SortMenu.mjs +22 -33
  132. package/dist/admin/future/pages/Assets/components/SortMenu.mjs.map +1 -1
  133. package/dist/admin/future/pages/Assets/hooks/useAssetSearch.js +40 -0
  134. package/dist/admin/future/pages/Assets/hooks/useAssetSearch.js.map +1 -0
  135. package/dist/admin/future/pages/Assets/hooks/useAssetSearch.mjs +38 -0
  136. package/dist/admin/future/pages/Assets/hooks/useAssetSearch.mjs.map +1 -0
  137. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js +21 -5
  138. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.js.map +1 -1
  139. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs +21 -5
  140. package/dist/admin/future/pages/Assets/hooks/useAssetSelection.mjs.map +1 -1
  141. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.js +47 -0
  142. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.js.map +1 -0
  143. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.mjs +44 -0
  144. package/dist/admin/future/pages/Assets/hooks/useBusyAssets.mjs.map +1 -0
  145. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js +33 -12
  146. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.js.map +1 -1
  147. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs +33 -12
  148. package/dist/admin/future/pages/Assets/hooks/useFolderNavigation.mjs.map +1 -1
  149. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js +222 -45
  150. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.js.map +1 -1
  151. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs +223 -46
  152. package/dist/admin/future/pages/Assets/hooks/useInfiniteAssets.mjs.map +1 -1
  153. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.js +75 -0
  154. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.js.map +1 -0
  155. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.mjs +73 -0
  156. package/dist/admin/future/pages/Assets/hooks/useInfiniteScrollSentinel.mjs.map +1 -0
  157. package/dist/admin/future/pages/Assets/hooks/useListFilters.js +168 -0
  158. package/dist/admin/future/pages/Assets/hooks/useListFilters.js.map +1 -0
  159. package/dist/admin/future/pages/Assets/hooks/useListFilters.mjs +162 -0
  160. package/dist/admin/future/pages/Assets/hooks/useListFilters.mjs.map +1 -0
  161. package/dist/admin/future/pages/Assets/utils/buildAssetFilters.js +201 -0
  162. package/dist/admin/future/pages/Assets/utils/buildAssetFilters.js.map +1 -0
  163. package/dist/admin/future/pages/Assets/utils/buildAssetFilters.mjs +198 -0
  164. package/dist/admin/future/pages/Assets/utils/buildAssetFilters.mjs.map +1 -0
  165. package/dist/admin/future/pages/Assets/utils/listQueryKey.js +2 -2
  166. package/dist/admin/future/pages/Assets/utils/listQueryKey.js.map +1 -1
  167. package/dist/admin/future/pages/Assets/utils/listQueryKey.mjs +2 -2
  168. package/dist/admin/future/pages/Assets/utils/listQueryKey.mjs.map +1 -1
  169. package/dist/admin/future/services/api.js +187 -28
  170. package/dist/admin/future/services/api.js.map +1 -1
  171. package/dist/admin/future/services/api.mjs +187 -30
  172. package/dist/admin/future/services/api.mjs.map +1 -1
  173. package/dist/admin/future/services/assets.js +40 -17
  174. package/dist/admin/future/services/assets.js.map +1 -1
  175. package/dist/admin/future/services/assets.mjs +40 -17
  176. package/dist/admin/future/services/assets.mjs.map +1 -1
  177. package/dist/admin/future/services/folders.js +66 -19
  178. package/dist/admin/future/services/folders.js.map +1 -1
  179. package/dist/admin/future/services/folders.mjs +66 -20
  180. package/dist/admin/future/services/folders.mjs.map +1 -1
  181. package/dist/admin/future/services/settings.js +10 -3
  182. package/dist/admin/future/services/settings.js.map +1 -1
  183. package/dist/admin/future/services/settings.mjs +10 -3
  184. package/dist/admin/future/services/settings.mjs.map +1 -1
  185. package/dist/admin/future/store/uploadProgress.js +109 -2
  186. package/dist/admin/future/store/uploadProgress.js.map +1 -1
  187. package/dist/admin/future/store/uploadProgress.mjs +105 -3
  188. package/dist/admin/future/store/uploadProgress.mjs.map +1 -1
  189. package/dist/admin/future/utils/buildDragSetFromSelection.js +7 -5
  190. package/dist/admin/future/utils/buildDragSetFromSelection.js.map +1 -1
  191. package/dist/admin/future/utils/buildDragSetFromSelection.mjs +7 -5
  192. package/dist/admin/future/utils/buildDragSetFromSelection.mjs.map +1 -1
  193. package/dist/admin/future/utils/formatMoveSuccessMessage.js +12 -1
  194. package/dist/admin/future/utils/formatMoveSuccessMessage.js.map +1 -1
  195. package/dist/admin/future/utils/formatMoveSuccessMessage.mjs +12 -1
  196. package/dist/admin/future/utils/formatMoveSuccessMessage.mjs.map +1 -1
  197. package/dist/admin/future/utils/getRelationId.js +24 -0
  198. package/dist/admin/future/utils/getRelationId.js.map +1 -0
  199. package/dist/admin/future/utils/getRelationId.mjs +22 -0
  200. package/dist/admin/future/utils/getRelationId.mjs.map +1 -0
  201. package/dist/admin/future/utils/isEventFromWithin.js +14 -0
  202. package/dist/admin/future/utils/isEventFromWithin.js.map +1 -0
  203. package/dist/admin/future/utils/isEventFromWithin.mjs +12 -0
  204. package/dist/admin/future/utils/isEventFromWithin.mjs.map +1 -0
  205. package/dist/admin/future/utils/itemLocations.js +40 -0
  206. package/dist/admin/future/utils/itemLocations.js.map +1 -0
  207. package/dist/admin/future/utils/itemLocations.mjs +36 -0
  208. package/dist/admin/future/utils/itemLocations.mjs.map +1 -0
  209. package/dist/admin/future/utils/itemSource.js +36 -0
  210. package/dist/admin/future/utils/itemSource.js.map +1 -0
  211. package/dist/admin/future/utils/itemSource.mjs +32 -0
  212. package/dist/admin/future/utils/itemSource.mjs.map +1 -0
  213. package/dist/admin/future/utils/searchQueryParam.js +11 -0
  214. package/dist/admin/future/utils/searchQueryParam.js.map +1 -0
  215. package/dist/admin/future/utils/searchQueryParam.mjs +9 -0
  216. package/dist/admin/future/utils/searchQueryParam.mjs.map +1 -0
  217. package/dist/admin/hooks/useSelectionState.js +2 -4
  218. package/dist/admin/hooks/useSelectionState.js.map +1 -1
  219. package/dist/admin/hooks/useSelectionState.mjs +2 -4
  220. package/dist/admin/hooks/useSelectionState.mjs.map +1 -1
  221. package/dist/admin/index.js +11 -17
  222. package/dist/admin/index.js.map +1 -1
  223. package/dist/admin/index.mjs +12 -18
  224. package/dist/admin/index.mjs.map +1 -1
  225. package/dist/admin/shared/constants.js +43 -0
  226. package/dist/admin/shared/constants.js.map +1 -0
  227. package/dist/admin/shared/constants.mjs +38 -0
  228. package/dist/admin/shared/constants.mjs.map +1 -0
  229. package/dist/admin/src/future/App.d.ts +1 -1
  230. package/dist/admin/src/future/components/BetaNotice.d.ts +11 -0
  231. package/dist/admin/src/future/components/Drawer.d.ts +5 -1
  232. package/dist/admin/src/future/hooks/useAIMetadataEnabled.d.ts +26 -0
  233. package/dist/admin/src/future/hooks/useMediaLibraryPermissions.d.ts +21 -0
  234. package/dist/admin/src/future/pages/Assets/components/ActionsMenuContent.d.ts +33 -0
  235. package/dist/admin/src/future/pages/Assets/components/AssetActionsMenu.d.ts +24 -0
  236. package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetCropEditor.d.ts +7 -1
  237. package/dist/admin/src/future/pages/Assets/components/AssetDetails/AssetDetailsDrawer.d.ts +16 -0
  238. package/dist/admin/src/future/pages/Assets/components/AssetsSearchInput.d.ts +5 -0
  239. package/dist/admin/src/future/pages/Assets/components/BulkActionsBar.d.ts +21 -1
  240. package/dist/admin/src/future/pages/Assets/components/BulkMoveDialog.d.ts +17 -6
  241. package/dist/admin/src/future/pages/Assets/components/BusyOverlay.d.ts +9 -0
  242. package/dist/admin/src/future/pages/Assets/components/DateRangeCalendar.d.ts +8 -0
  243. package/dist/admin/src/future/pages/Assets/components/DeleteItemsDialog.d.ts +27 -0
  244. package/dist/admin/src/future/pages/Assets/components/Dnd/AssetsDndProvider.d.ts +8 -1
  245. package/dist/admin/src/future/pages/Assets/components/Dnd/buildDragSet.d.ts +18 -3
  246. package/dist/admin/src/future/pages/Assets/components/Dnd/useAssetDnd.d.ts +2 -1
  247. package/dist/admin/src/future/pages/Assets/components/DropZone/UploadDropZoneContext.d.ts +8 -1
  248. package/dist/admin/src/future/pages/Assets/components/EmptyState.d.ts +18 -1
  249. package/dist/admin/src/future/pages/Assets/components/FilterBadges.d.ts +8 -0
  250. package/dist/admin/src/future/pages/Assets/components/FilterMenu.d.ts +26 -0
  251. package/dist/admin/src/future/pages/Assets/components/FolderActionsMenu.d.ts +20 -0
  252. package/dist/admin/src/future/pages/Assets/components/FolderFormDialog.d.ts +16 -0
  253. package/dist/admin/src/future/pages/Assets/components/FolderTree/FolderTree.d.ts +13 -4
  254. package/dist/admin/src/future/pages/Assets/components/SortMenu.d.ts +6 -0
  255. package/dist/admin/src/future/pages/Assets/hooks/useAssetSearch.d.ts +12 -0
  256. package/dist/admin/src/future/pages/Assets/hooks/useAssetSelection.d.ts +8 -1
  257. package/dist/admin/src/future/pages/Assets/hooks/useBusyAssets.d.ts +38 -0
  258. package/dist/admin/src/future/pages/Assets/hooks/useInfiniteAssets.d.ts +27 -3
  259. package/dist/admin/src/future/pages/Assets/hooks/useInfiniteScrollSentinel.d.ts +41 -0
  260. package/dist/admin/src/future/pages/Assets/hooks/useListFilters.d.ts +69 -0
  261. package/dist/admin/src/future/pages/Assets/utils/buildAssetFilters.d.ts +46 -0
  262. package/dist/admin/src/future/pages/Assets/utils/listQueryKey.d.ts +3 -4
  263. package/dist/admin/src/future/services/api.d.ts +53 -5
  264. package/dist/admin/src/future/services/assets.d.ts +9 -1
  265. package/dist/admin/src/future/services/folders.d.ts +9 -1
  266. package/dist/admin/src/future/services/settings.d.ts +2 -2
  267. package/dist/admin/src/future/store/uploadProgress.d.ts +83 -1
  268. package/dist/admin/src/future/utils/buildDragSetFromSelection.d.ts +4 -3
  269. package/dist/admin/src/future/utils/formatMoveSuccessMessage.d.ts +7 -1
  270. package/dist/admin/src/future/utils/getRelationId.d.ts +11 -0
  271. package/dist/admin/src/future/utils/isEventFromWithin.d.ts +11 -0
  272. package/dist/admin/src/future/utils/itemLocations.d.ts +31 -0
  273. package/dist/admin/src/future/utils/itemSource.d.ts +22 -0
  274. package/dist/admin/src/future/utils/searchQueryParam.d.ts +7 -0
  275. package/dist/admin/src/hooks/useAiAvailability.d.ts +1 -1
  276. package/dist/admin/src/hooks/useEditAsset.d.ts +4 -4
  277. package/dist/admin/src/hooks/useEditFolder.d.ts +4 -4
  278. package/dist/admin/src/hooks/useSettings.d.ts +1 -0
  279. package/dist/admin/src/hooks/useTracking.d.ts +1 -1
  280. package/dist/admin/src/hooks/useUpload.d.ts +1 -1
  281. package/dist/admin/translations/en.json.js +73 -2
  282. package/dist/admin/translations/en.json.js.map +1 -1
  283. package/dist/admin/translations/en.json.mjs +73 -2
  284. package/dist/admin/translations/en.json.mjs.map +1 -1
  285. package/dist/admin/utils/urlYupSchema.js +33 -9
  286. package/dist/admin/utils/urlYupSchema.js.map +1 -1
  287. package/dist/admin/utils/urlYupSchema.mjs +33 -9
  288. package/dist/admin/utils/urlYupSchema.mjs.map +1 -1
  289. package/dist/server/config.js +13 -5
  290. package/dist/server/config.js.map +1 -1
  291. package/dist/server/config.mjs +13 -5
  292. package/dist/server/config.mjs.map +1 -1
  293. package/dist/server/constants.js.map +1 -1
  294. package/dist/server/constants.mjs.map +1 -1
  295. package/dist/server/controllers/admin-file.js +30 -0
  296. package/dist/server/controllers/admin-file.js.map +1 -1
  297. package/dist/server/controllers/admin-file.mjs +30 -0
  298. package/dist/server/controllers/admin-file.mjs.map +1 -1
  299. package/dist/server/controllers/admin-settings.js +20 -2
  300. package/dist/server/controllers/admin-settings.js.map +1 -1
  301. package/dist/server/controllers/admin-settings.mjs +21 -3
  302. package/dist/server/controllers/admin-settings.mjs.map +1 -1
  303. package/dist/server/controllers/content-api.js +1 -2
  304. package/dist/server/controllers/content-api.js.map +1 -1
  305. package/dist/server/controllers/content-api.mjs +2 -2
  306. package/dist/server/controllers/content-api.mjs.map +1 -1
  307. package/dist/server/controllers/validation/admin/ai-metadata.js +12 -0
  308. package/dist/server/controllers/validation/admin/ai-metadata.js.map +1 -0
  309. package/dist/server/controllers/validation/admin/ai-metadata.mjs +10 -0
  310. package/dist/server/controllers/validation/admin/ai-metadata.mjs.map +1 -0
  311. package/dist/server/controllers/validation/admin/settings.js +4 -1
  312. package/dist/server/controllers/validation/admin/settings.js.map +1 -1
  313. package/dist/server/controllers/validation/admin/settings.mjs +1 -1
  314. package/dist/server/controllers/validation/admin/settings.mjs.map +1 -1
  315. package/dist/server/routes/admin.js +18 -0
  316. package/dist/server/routes/admin.js.map +1 -1
  317. package/dist/server/routes/admin.mjs +18 -0
  318. package/dist/server/routes/admin.mjs.map +1 -1
  319. package/dist/server/services/ai-metadata.js +108 -11
  320. package/dist/server/services/ai-metadata.js.map +1 -1
  321. package/dist/server/services/ai-metadata.mjs +108 -11
  322. package/dist/server/services/ai-metadata.mjs.map +1 -1
  323. package/dist/server/services/file.js +86 -13
  324. package/dist/server/services/file.js.map +1 -1
  325. package/dist/server/services/file.mjs +87 -14
  326. package/dist/server/services/file.mjs.map +1 -1
  327. package/dist/server/services/image-manipulation.js +4 -4
  328. package/dist/server/services/image-manipulation.js.map +1 -1
  329. package/dist/server/services/image-manipulation.mjs +4 -4
  330. package/dist/server/services/image-manipulation.mjs.map +1 -1
  331. package/dist/server/shared/constants.js +43 -0
  332. package/dist/server/shared/constants.js.map +1 -0
  333. package/dist/server/shared/constants.mjs +38 -0
  334. package/dist/server/shared/constants.mjs.map +1 -0
  335. package/dist/server/src/config.d.ts +2 -0
  336. package/dist/server/src/config.d.ts.map +1 -1
  337. package/dist/server/src/constants.d.ts +2 -1
  338. package/dist/server/src/constants.d.ts.map +1 -1
  339. package/dist/server/src/controllers/admin-file.d.ts +10 -0
  340. package/dist/server/src/controllers/admin-file.d.ts.map +1 -1
  341. package/dist/server/src/controllers/admin-settings.d.ts.map +1 -1
  342. package/dist/server/src/controllers/index.d.ts +1 -0
  343. package/dist/server/src/controllers/index.d.ts.map +1 -1
  344. package/dist/server/src/controllers/validation/admin/ai-metadata.d.ts +2 -0
  345. package/dist/server/src/controllers/validation/admin/ai-metadata.d.ts.map +1 -0
  346. package/dist/server/src/controllers/validation/admin/settings.d.ts +1 -1
  347. package/dist/server/src/controllers/validation/admin/settings.d.ts.map +1 -1
  348. package/dist/server/src/index.d.ts +7 -1
  349. package/dist/server/src/index.d.ts.map +1 -1
  350. package/dist/server/src/routes/admin.d.ts.map +1 -1
  351. package/dist/server/src/services/ai-metadata.d.ts +19 -0
  352. package/dist/server/src/services/ai-metadata.d.ts.map +1 -1
  353. package/dist/server/src/services/file.d.ts +12 -2
  354. package/dist/server/src/services/file.d.ts.map +1 -1
  355. package/dist/server/src/services/image-manipulation.d.ts +0 -5
  356. package/dist/server/src/services/image-manipulation.d.ts.map +1 -1
  357. package/dist/server/src/services/index.d.ts +4 -1
  358. package/dist/server/src/services/index.d.ts.map +1 -1
  359. package/dist/server/src/types.d.ts +3 -0
  360. package/dist/server/src/types.d.ts.map +1 -1
  361. package/dist/shared/constants.d.ts +35 -0
  362. package/dist/shared/constants.d.ts.map +1 -0
  363. package/dist/shared/contracts/files.d.ts +25 -0
  364. package/dist/shared/contracts/files.d.ts.map +1 -1
  365. package/dist/shared/contracts/settings.d.ts +7 -0
  366. package/package.json +10 -10
  367. package/dist/admin/future/pages/Assets/components/CreateFolderDialog.js.map +0 -1
  368. package/dist/admin/future/pages/Assets/components/CreateFolderDialog.mjs.map +0 -1
  369. package/dist/admin/src/future/pages/Assets/components/CreateFolderDialog.d.ts +0 -8
@@ -47,6 +47,8 @@ const Overlay = styledComponents.styled(designSystem.Flex)`
47
47
  border-radius: ${({ theme })=>theme.borderRadius};
48
48
  border: 1px solid ${({ theme })=>theme.colors.neutral150};
49
49
  background: ${({ theme })=>theme.colors.neutral0};
50
+ /* Focused programmatically on open (tabIndex -1) — no visible ring needed. */
51
+ outline: none;
50
52
  `;
51
53
  const HeaderBar = styledComponents.styled(designSystem.Flex)`
52
54
  width: 100%;
@@ -56,6 +58,9 @@ const HeaderBar = styledComponents.styled(designSystem.Flex)`
56
58
  background: ${({ theme })=>theme.colors.neutral0};
57
59
  `;
58
60
  // Fills the remaining space between header/footer; checkerboard pattern.
61
+ // The horizontal padding keeps the image off the viewport edges — the corner
62
+ // handles overhang the image by half their size, and on narrow (mobile)
63
+ // screens an edge-to-edge image leaves nothing to grab.
59
64
  const Body = styledComponents.styled(designSystem.Box)`
60
65
  width: 100%;
61
66
  position: relative;
@@ -65,6 +70,7 @@ const Body = styledComponents.styled(designSystem.Box)`
65
70
  align-items: center;
66
71
  justify-content: center;
67
72
  overflow: hidden;
73
+ padding: 0 ${({ theme })=>theme.spaces[4]};
68
74
  background: repeating-conic-gradient(
69
75
  ${({ theme })=>theme.colors.neutral100} 0% 25%,
70
76
  ${({ theme })=>theme.colors.neutral0} 0% 50%
@@ -95,6 +101,9 @@ const CropOverlay = styledComponents.styled.div`
95
101
  border: 1px dashed ${({ theme })=>theme.colors.primary600};
96
102
  box-shadow: 0 0 0 9999px rgba(33, 33, 52, 0.5);
97
103
  cursor: move;
104
+ /* Without this, touch browsers claim the gesture for scrolling and fire
105
+ pointercancel mid-drag — the crop drag dies while the finger is down. */
106
+ touch-action: none;
98
107
  `;
99
108
  const ResizeHandle = styledComponents.styled.button`
100
109
  position: absolute;
@@ -106,6 +115,7 @@ const ResizeHandle = styledComponents.styled.button`
106
115
  border-radius: 2px;
107
116
  background: ${({ theme })=>theme.colors.neutral0};
108
117
  cursor: ${({ $cursor })=>$cursor};
118
+ touch-action: none;
109
119
  `;
110
120
  const FocalPointHandle = styledComponents.styled.button`
111
121
  position: absolute;
@@ -117,6 +127,7 @@ const FocalPointHandle = styledComponents.styled.button`
117
127
  background: transparent;
118
128
  cursor: grab;
119
129
  padding: 0;
130
+ touch-action: none;
120
131
 
121
132
  &::before {
122
133
  content: '';
@@ -145,16 +156,24 @@ const FocalPointHandle = styledComponents.styled.button`
145
156
  cursor: grabbing;
146
157
  }
147
158
  `;
159
+ // Hidden on mobile — the panel (title/hint + numeric crop & focal inputs) is
160
+ // too large for a phone; touch users set the crop by dragging the rectangle and
161
+ // focal handle directly on the image. Shown from tablet up.
148
162
  const InfoBox = styledComponents.styled(designSystem.Box)`
149
- position: absolute;
150
- right: ${({ theme })=>theme.spaces[1]};
151
- bottom: ${({ theme })=>theme.spaces[1]};
152
- width: 100%;
153
- max-width: 32rem;
154
- padding: ${({ theme })=>theme.spaces[3]};
155
- border-radius: ${({ theme })=>theme.borderRadius};
156
- background: ${({ theme })=>theme.colorScheme === 'dark' ? theme.colors.neutral150 : theme.colors.neutral900};
157
- z-index: 20;
163
+ display: none;
164
+
165
+ ${({ theme })=>theme.breakpoints.medium} {
166
+ display: block;
167
+ position: absolute;
168
+ right: ${({ theme })=>theme.spaces[1]};
169
+ bottom: ${({ theme })=>theme.spaces[1]};
170
+ width: 100%;
171
+ max-width: 32rem;
172
+ padding: ${({ theme })=>theme.spaces[3]};
173
+ border-radius: ${({ theme })=>theme.borderRadius};
174
+ background: ${({ theme })=>theme.colorScheme === 'dark' ? theme.colors.neutral150 : theme.colors.neutral900};
175
+ z-index: 20;
176
+ }
158
177
  `;
159
178
  const FooterBar = styledComponents.styled(designSystem.Flex)`
160
179
  width: 100%;
@@ -201,7 +220,7 @@ const BackgroundPreserveRatio = ()=>/*#__PURE__*/ jsxRuntime.jsx(BackgroundPrese
201
220
  })
202
221
  })
203
222
  });
204
- const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy })=>{
223
+ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy, canSaveAsCopy })=>{
205
224
  const { formatMessage } = reactIntl.useIntl();
206
225
  const { toggleNotification } = strapiAdmin.useNotification();
207
226
  // The InfoBox is a fixed dark surface in both themes, so its text can't use a
@@ -213,6 +232,14 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
213
232
  const infoMutedColor = isDark ? 'neutral600' : 'neutral200';
214
233
  const imgRef = React__namespace.useRef(null);
215
234
  const cropAreaRef = React__namespace.useRef(null);
235
+ const overlayRef = React__namespace.useRef(null);
236
+ // FocusTrap's auto-focus lands on the first focusable element — the crop
237
+ // width NumberInput — which pops the keyboard on mobile the moment the
238
+ // editor opens. Focus the (tabIndex -1) overlay instead: keyboard users are
239
+ // one Tab away from the first control, Escape still reaches the trap.
240
+ React__namespace.useEffect(()=>{
241
+ overlayRef.current?.focus();
242
+ }, []);
216
243
  const { init, crop, naturalSize, aspectRatio, setCropSize, setCropPosition, setAspectRatio, produceFile, width, height } = useCropImg.useCropImg();
217
244
  const [aspectLocked, setAspectLocked] = React__namespace.useState(false);
218
245
  // Focal point as a percentage of the crop area (matches the {x,y} contract).
@@ -220,12 +247,21 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
220
247
  x: 50,
221
248
  y: 50
222
249
  });
223
- // Append `updatedAt` as a cache-buster: a replaced asset is served at the same
224
- // URL, so without this, reopening the editor shows the browser-cached old image
225
- // (mirrors AssetPreview).
250
+ // The crop editor reads pixels from a canvas (useCropImg -> toBlob), so its
251
+ // <img> must be CORS-clean and always sets crossOrigin="anonymous" (see the
252
+ // img below) — even for unsigned URLs, which AssetPreview leaves unset because
253
+ // it only displays. That difference is why the crop URL is kept DISTINCT from
254
+ // the thumbnail's: identical URL + different crossOrigin collide in the HTTP
255
+ // cache (#26581), and the crop's anonymous request could otherwise reuse the
256
+ // thumbnail's non-CORS cached response and taint the canvas. So the buster
257
+ // uses `updatedAt` where AssetPreview uses `v`, giving each its own entry
258
+ // (mirrors the legacy PreviewBox fix).
259
+ // Signed URLs get no param at all — a presigned S3 URL breaks if you add one,
260
+ // and on the signed side AssetPreview also loads anonymous, so the identical
261
+ // URL there shares one CORS-consistent entry, which is fine.
226
262
  const rawImageUrl = files.prefixFileUrlWithBackendUrl(asset.url);
227
- const cacheKey = asset.updatedAt ? new Date(asset.updatedAt).getTime() : undefined;
228
- const imageUrl = cacheKey !== undefined ? `${rawImageUrl}${rawImageUrl.includes('?') ? '&' : '?'}v=${cacheKey}` : rawImageUrl;
263
+ const cacheKey = asset.updatedAt && !asset.isUrlSigned ? new Date(asset.updatedAt).getTime() : undefined;
264
+ const imageUrl = cacheKey !== undefined ? `${rawImageUrl}${rawImageUrl.includes('?') ? '&' : '?'}updatedAt=${cacheKey}` : rawImageUrl;
229
265
  const handleImageLoad = ()=>{
230
266
  if (imgRef.current) {
231
267
  init(imgRef.current);
@@ -242,40 +278,75 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
242
278
  y: (event.clientY - rect.top) * ratioY
243
279
  };
244
280
  };
245
- // Drag the entire crop rectangle.
246
- const handleMovePointerDown = (event)=>{
281
+ // Teardown for the drag currently in flight, so it can be run both on pointer
282
+ // release AND on unmount. Without the unmount path, closing the editor mid-drag
283
+ // (Escape, drawer close, a re-render dropping the overlay) would never fire a
284
+ // pointer event, leaking the window listeners and letting a stale `onMove`
285
+ // call `setCropPosition` on an unmounted component.
286
+ const activeDragCleanupRef = React__namespace.useRef(null);
287
+ React__namespace.useEffect(()=>{
288
+ return ()=>{
289
+ activeDragCleanupRef.current?.();
290
+ };
291
+ }, []);
292
+ // Track a pointer drag until the pointer is released or the browser cancels
293
+ // it. The pointer is captured so the drag follows the finger even once it
294
+ // leaves the (12px) handle it started on, and pointercancel is treated as
295
+ // release so an interrupted touch never leaves stale window listeners.
296
+ const trackPointerDrag = (event, onMove)=>{
247
297
  event.preventDefault();
248
298
  event.stopPropagation();
299
+ const { pointerId } = event;
300
+ try {
301
+ event.currentTarget.setPointerCapture(pointerId);
302
+ } catch {
303
+ // Unsupported environment (jsdom) — window listeners still track the drag.
304
+ }
305
+ const move = (e)=>{
306
+ if (e.pointerId !== pointerId) return;
307
+ onMove(e);
308
+ };
309
+ const cleanup = ()=>{
310
+ window.removeEventListener('pointermove', move);
311
+ window.removeEventListener('pointerup', end);
312
+ window.removeEventListener('pointercancel', end);
313
+ activeDragCleanupRef.current = null;
314
+ };
315
+ const end = (e)=>{
316
+ if (e.pointerId !== pointerId) return;
317
+ cleanup();
318
+ };
319
+ // Only one drag is ever live at a time; tear down any previous one first.
320
+ activeDragCleanupRef.current?.();
321
+ activeDragCleanupRef.current = cleanup;
322
+ window.addEventListener('pointermove', move);
323
+ window.addEventListener('pointerup', end);
324
+ window.addEventListener('pointercancel', end);
325
+ };
326
+ // Drag the entire crop rectangle.
327
+ const handleMovePointerDown = (event)=>{
249
328
  const start = pointerToNatural(event);
250
329
  if (!start) return;
251
330
  const startCrop = {
252
331
  ...crop
253
332
  };
254
- const move = (e)=>{
333
+ trackPointerDrag(event, (e)=>{
255
334
  const next = pointerToNatural(e);
256
335
  if (!next) return;
257
336
  setCropPosition({
258
337
  x: startCrop.x + (next.x - start.x),
259
338
  y: startCrop.y + (next.y - start.y)
260
339
  });
261
- };
262
- const up = ()=>{
263
- window.removeEventListener('pointermove', move);
264
- window.removeEventListener('pointerup', up);
265
- };
266
- window.addEventListener('pointermove', move);
267
- window.addEventListener('pointerup', up);
340
+ });
268
341
  };
269
342
  // Resize from a corner; the opposite corner stays anchored.
270
343
  const handleResizePointerDown = (corner)=>(event)=>{
271
- event.preventDefault();
272
- event.stopPropagation();
273
344
  const startCrop = {
274
345
  ...crop
275
346
  };
276
347
  const anchorX = corner === 'tl' || corner === 'bl' ? startCrop.x + startCrop.width : startCrop.x;
277
348
  const anchorY = corner === 'tl' || corner === 'tr' ? startCrop.y + startCrop.height : startCrop.y;
278
- const move = (e)=>{
349
+ trackPointerDrag(event, (e)=>{
279
350
  const point = pointerToNatural(e);
280
351
  if (!point) return;
281
352
  const { x, y, width: w, height: h } = useCropImg.resolveCornerResize({
@@ -292,13 +363,7 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
292
363
  width: w,
293
364
  height: h
294
365
  });
295
- };
296
- const up = ()=>{
297
- window.removeEventListener('pointermove', move);
298
- window.removeEventListener('pointerup', up);
299
- };
300
- window.addEventListener('pointermove', move);
301
- window.addEventListener('pointerup', up);
366
+ });
302
367
  };
303
368
  const toggleAspectLock = ()=>{
304
369
  setAspectLocked((locked)=>{
@@ -309,9 +374,7 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
309
374
  };
310
375
  // Drag the focal handle within the crop rectangle, clamped 0–100.
311
376
  const handleFocalPointerDown = (event)=>{
312
- event.preventDefault();
313
- event.stopPropagation();
314
- const move = (e)=>{
377
+ trackPointerDrag(event, (e)=>{
315
378
  const point = pointerToNatural(e);
316
379
  if (!point) return;
317
380
  // Convert pointer to a percentage of the current crop area.
@@ -321,13 +384,7 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
321
384
  x: Math.round(Math.min(100, Math.max(0, px))),
322
385
  y: Math.round(Math.min(100, Math.max(0, py)))
323
386
  });
324
- };
325
- const up = ()=>{
326
- window.removeEventListener('pointermove', move);
327
- window.removeEventListener('pointerup', up);
328
- };
329
- window.addEventListener('pointermove', move);
330
- window.addEventListener('pointerup', up);
387
+ });
331
388
  };
332
389
  const focalPxX = Math.round(focal.x / 100 * width);
333
390
  const focalPxY = Math.round(focal.y / 100 * height);
@@ -377,7 +434,10 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
377
434
  return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Portal, {
378
435
  children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.FocusTrap, {
379
436
  onEscape: onClose,
437
+ skipAutoFocus: true,
380
438
  children: /*#__PURE__*/ jsxRuntime.jsxs(Overlay, {
439
+ ref: overlayRef,
440
+ tabIndex: -1,
381
441
  children: [
382
442
  /*#__PURE__*/ jsxRuntime.jsxs(HeaderBar, {
383
443
  alignItems: "center",
@@ -405,6 +465,10 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
405
465
  ref: imgRef,
406
466
  src: imageUrl,
407
467
  alt: asset.name,
468
+ // Always anonymous, unlike AssetPreview/AssetsGrid which gate it:
469
+ // the editor reads pixels via canvas (useCropImg -> toBlob), which
470
+ // taints on a cross-origin image loaded without CORS, so every
471
+ // remote image must be fetched CORS-clean.
408
472
  crossOrigin: "anonymous",
409
473
  onLoad: handleImageLoad,
410
474
  draggable: false
@@ -666,7 +730,7 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
666
730
  /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
667
731
  gap: 2,
668
732
  children: [
669
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
733
+ canSaveAsCopy && /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
670
734
  variant: "secondary",
671
735
  onClick: ()=>handleAction('copy'),
672
736
  loading: isBusy,
@@ -1 +1 @@
1
- {"version":3,"file":"AssetCropEditor.js","sources":["../../../../../../../admin/src/future/pages/Assets/components/AssetDetails/AssetCropEditor.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useNotification } from '@strapi/admin/strapi-admin';\nimport {\n Box,\n Button,\n Field,\n Flex,\n FocusTrap,\n IconButton,\n NumberInput,\n Portal,\n Typography,\n} from '@strapi/design-system';\nimport { ArrowsHorizontal, ArrowsVertical, Crop, Link } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled, useTheme } from 'styled-components';\n\nimport { prefixFileUrlWithBackendUrl } from '../../../../utils/files';\nimport { getTranslationKey } from '../../../../utils/translations';\n\nimport { resolveCornerResize, useCropImg } from './useCropImg';\n\nimport type {\n AssetWithPopulatedCreatedBy,\n FocalPoint,\n} from '../../../../../../../shared/contracts/files';\n\nconst FOCAL_DIAMETER_REM = 5.6;\nconst HANDLE_PX = 12;\n\n/* -------------------------------------------------------------------------------------------------\n * Styled\n * -----------------------------------------------------------------------------------------------*/\n\n// Full-viewport takeover with a small inset so the editor reads as a card.\nconst Overlay = styled(Flex)`\n position: fixed;\n z-index: 1200;\n flex-direction: column;\n top: ${({ theme }) => theme.spaces[1]};\n left: ${({ theme }) => theme.spaces[1]};\n right: ${({ theme }) => theme.spaces[1]};\n bottom: ${({ theme }) => theme.spaces[1]};\n border-radius: ${({ theme }) => theme.borderRadius};\n border: 1px solid ${({ theme }) => theme.colors.neutral150};\n background: ${({ theme }) => theme.colors.neutral0};\n`;\n\nconst HeaderBar = styled(Flex)`\n width: 100%;\n gap: ${({ theme }) => theme.spaces[2]};\n padding: ${({ theme }) => `${theme.spaces[3]} ${theme.spaces[5]}`};\n border-bottom: 1px solid ${({ theme }) => theme.colors.neutral150};\n background: ${({ theme }) => theme.colors.neutral0};\n`;\n\n// Fills the remaining space between header/footer; checkerboard pattern.\nconst Body = styled(Box)`\n width: 100%;\n position: relative;\n flex: 1;\n min-height: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n background: repeating-conic-gradient(\n ${({ theme }) => theme.colors.neutral100} 0% 25%,\n ${({ theme }) => theme.colors.neutral0} 0% 50%\n )\n 50% / 20px 20px;\n`;\n\n// Wrapper sized to the image's natural aspect ratio so the <img> inside fills\n// it without letterboxing. Percentage-based positioning of the crop overlay\n// then maps directly to natural-px coordinates.\nconst CropArea = styled.div<{ $aspect?: number }>`\n position: relative;\n max-width: 100%;\n max-height: 100%;\n ${({ $aspect }) => ($aspect ? `aspect-ratio: ${$aspect};` : '')}\n\n img {\n display: block;\n width: 100%;\n height: 100%;\n user-select: none;\n -webkit-user-drag: none;\n }\n`;\n\n// Crop selection rectangle, positioned by % of CropArea. Inverts the dim\n// outside via box-shadow so the focused area shows full color.\nconst CropOverlay = styled.div`\n position: absolute;\n border: 1px dashed ${({ theme }) => theme.colors.primary600};\n box-shadow: 0 0 0 9999px rgba(33, 33, 52, 0.5);\n cursor: move;\n`;\n\nconst ResizeHandle = styled.button<{ $cursor: string }>`\n position: absolute;\n width: ${HANDLE_PX}px;\n height: ${HANDLE_PX}px;\n margin: -${HANDLE_PX / 2}px;\n padding: 0;\n border: 1px solid ${({ theme }) => theme.colors.primary600};\n border-radius: 2px;\n background: ${({ theme }) => theme.colors.neutral0};\n cursor: ${({ $cursor }) => $cursor};\n`;\n\nconst FocalPointHandle = styled.button`\n position: absolute;\n width: ${FOCAL_DIAMETER_REM}rem;\n height: ${FOCAL_DIAMETER_REM}rem;\n margin: ${-FOCAL_DIAMETER_REM / 2}rem 0 0 ${-FOCAL_DIAMETER_REM / 2}rem;\n border-radius: 50%;\n border: 1px solid ${({ theme }) => theme.colors.neutral800};\n background: transparent;\n cursor: grab;\n padding: 0;\n\n &::before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: rgba(0, 0, 0, 0.16);\n transform: translate(-50%, -50%);\n }\n &::after {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: ${({ theme }) => theme.colors.neutral800};\n transform: translate(-50%, -50%);\n }\n\n &:active {\n cursor: grabbing;\n }\n`;\n\nconst InfoBox = styled(Box)`\n position: absolute;\n right: ${({ theme }) => theme.spaces[1]};\n bottom: ${({ theme }) => theme.spaces[1]};\n width: 100%;\n max-width: 32rem;\n padding: ${({ theme }) => theme.spaces[3]};\n border-radius: ${({ theme }) => theme.borderRadius};\n background: ${({ theme }) =>\n theme.colorScheme === 'dark' ? theme.colors.neutral150 : theme.colors.neutral900};\n z-index: 20;\n`;\n\nconst FooterBar = styled(Flex)`\n width: 100%;\n justify-content: space-between;\n padding: ${({ theme }) => `${theme.spaces[3]} ${theme.spaces[5]}`};\n border-top: 1px solid ${({ theme }) => theme.colors.neutral150};\n background: ${({ theme }) => theme.colors.neutral0};\n`;\n\nconst FieldRow = styled(Field.Root)`\n flex-direction: row;\n align-items: center;\n`;\n\nconst FieldNumberInput = styled(NumberInput)`\n width: 8.4rem;\n`;\n\nconst LabelIcon = styled(Field.Label)`\n display: flex;\n align-items: center;\n justify-content: center;\n width: 1.6rem;\n height: 1.6rem;\n`;\n\nconst BackgroundPreserveRatioContainer = styled(Box)`\n position: absolute;\n top: 50%;\n left: 0;\n transform: translateY(-50%);\n\n svg {\n display: block;\n }\n`;\n\nconst BackgroundPreserveRatio = () => (\n <BackgroundPreserveRatioContainer>\n <svg width=\"17\" height=\"49\" viewBox=\"0 0 17 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M0.5 0.5H8.5C12.9183 0.5 16.5 4.08172 16.5 8.5M0.5 48.5H8.5C12.9183 48.5 16.5 44.9183 16.5 40.5\"\n stroke=\"#666687\"\n strokeLinecap=\"round\"\n />\n </svg>\n </BackgroundPreserveRatioContainer>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * AssetCropEditor\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetCropEditorProps {\n asset: AssetWithPopulatedCreatedBy;\n isBusy?: boolean;\n onClose: () => void;\n onApply: (file: globalThis.File, focalPoint: FocalPoint) => void;\n onSaveAsCopy: (file: globalThis.File, focalPoint: FocalPoint) => void;\n}\n\ntype Corner = 'tl' | 'tr' | 'bl' | 'br';\n\nexport const AssetCropEditor = ({\n asset,\n isBusy = false,\n onClose,\n onApply,\n onSaveAsCopy,\n}: AssetCropEditorProps) => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n // The InfoBox is a fixed dark surface in both themes, so its text can't use a\n // single neutral token (those invert with the scheme). Pick the scheme's white\n // and a muted grey explicitly.\n const theme = useTheme();\n const isDark = theme.colorScheme === 'dark';\n const infoTextColor = isDark ? 'neutral1000' : 'neutral0';\n const infoMutedColor = isDark ? 'neutral600' : 'neutral200';\n const imgRef = React.useRef<HTMLImageElement>(null);\n const cropAreaRef = React.useRef<HTMLDivElement>(null);\n\n const {\n init,\n crop,\n naturalSize,\n aspectRatio,\n setCropSize,\n setCropPosition,\n setAspectRatio,\n produceFile,\n width,\n height,\n } = useCropImg();\n\n const [aspectLocked, setAspectLocked] = React.useState(false);\n // Focal point as a percentage of the crop area (matches the {x,y} contract).\n const [focal, setFocal] = React.useState<FocalPoint>(asset.focalPoint ?? { x: 50, y: 50 });\n\n // Append `updatedAt` as a cache-buster: a replaced asset is served at the same\n // URL, so without this, reopening the editor shows the browser-cached old image\n // (mirrors AssetPreview).\n const rawImageUrl = prefixFileUrlWithBackendUrl(asset.url) as string;\n const cacheKey = asset.updatedAt ? new Date(asset.updatedAt).getTime() : undefined;\n const imageUrl =\n cacheKey !== undefined\n ? `${rawImageUrl}${rawImageUrl.includes('?') ? '&' : '?'}v=${cacheKey}`\n : rawImageUrl;\n\n const handleImageLoad = () => {\n if (imgRef.current) {\n init(imgRef.current);\n }\n };\n\n // Map a pointer event to natural-px coordinates inside the image.\n const pointerToNatural = (event: PointerEvent | React.PointerEvent) => {\n const rect = cropAreaRef.current?.getBoundingClientRect();\n if (!rect || !naturalSize.width || !naturalSize.height) return null;\n const ratioX = naturalSize.width / rect.width;\n const ratioY = naturalSize.height / rect.height;\n return {\n x: (event.clientX - rect.left) * ratioX,\n y: (event.clientY - rect.top) * ratioY,\n };\n };\n\n // Drag the entire crop rectangle.\n const handleMovePointerDown = (event: React.PointerEvent) => {\n event.preventDefault();\n event.stopPropagation();\n const start = pointerToNatural(event);\n if (!start) return;\n const startCrop = { ...crop };\n const move = (e: PointerEvent) => {\n const next = pointerToNatural(e);\n if (!next) return;\n setCropPosition({\n x: startCrop.x + (next.x - start.x),\n y: startCrop.y + (next.y - start.y),\n });\n };\n const up = () => {\n window.removeEventListener('pointermove', move);\n window.removeEventListener('pointerup', up);\n };\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', up);\n };\n\n // Resize from a corner; the opposite corner stays anchored.\n const handleResizePointerDown = (corner: Corner) => (event: React.PointerEvent) => {\n event.preventDefault();\n event.stopPropagation();\n const startCrop = { ...crop };\n const anchorX =\n corner === 'tl' || corner === 'bl' ? startCrop.x + startCrop.width : startCrop.x;\n const anchorY =\n corner === 'tl' || corner === 'tr' ? startCrop.y + startCrop.height : startCrop.y;\n const move = (e: PointerEvent) => {\n const point = pointerToNatural(e);\n if (!point) return;\n const {\n x,\n y,\n width: w,\n height: h,\n } = resolveCornerResize({\n anchorX,\n anchorY,\n point,\n aspectRatio: aspectLocked ? aspectRatio : null,\n });\n setCropPosition({ x, y });\n setCropSize({ width: w, height: h });\n };\n const up = () => {\n window.removeEventListener('pointermove', move);\n window.removeEventListener('pointerup', up);\n };\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', up);\n };\n\n const toggleAspectLock = () => {\n setAspectLocked((locked) => {\n const next = !locked;\n setAspectRatio(next && height ? width / height : null);\n return next;\n });\n };\n\n // Drag the focal handle within the crop rectangle, clamped 0–100.\n const handleFocalPointerDown = (event: React.PointerEvent) => {\n event.preventDefault();\n event.stopPropagation();\n const move = (e: PointerEvent) => {\n const point = pointerToNatural(e);\n if (!point) return;\n // Convert pointer to a percentage of the current crop area.\n const px = ((point.x - crop.x) / crop.width) * 100;\n const py = ((point.y - crop.y) / crop.height) * 100;\n setFocal({\n x: Math.round(Math.min(100, Math.max(0, px))),\n y: Math.round(Math.min(100, Math.max(0, py))),\n });\n };\n const up = () => {\n window.removeEventListener('pointermove', move);\n window.removeEventListener('pointerup', up);\n };\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', up);\n };\n\n const focalPxX = Math.round((focal.x / 100) * width);\n const focalPxY = Math.round((focal.y / 100) * height);\n\n const setFocalPx = (axis: 'x' | 'y', value: number) => {\n const dim = axis === 'x' ? width : height;\n if (!dim) return;\n const pct = Math.min(100, Math.max(0, (value / dim) * 100));\n setFocal((prev) => ({ ...prev, [axis]: Math.round(pct) }));\n };\n\n const cropPercents =\n naturalSize.width && naturalSize.height\n ? {\n left: (crop.x / naturalSize.width) * 100,\n top: (crop.y / naturalSize.height) * 100,\n width: (crop.width / naturalSize.width) * 100,\n height: (crop.height / naturalSize.height) * 100,\n }\n : null;\n\n // The crop is only usable once the image has loaded and `init()` has seeded\n // the natural size. Until then the produce/export path would reject.\n const isReady = cropPercents !== null;\n\n const handleAction = async (action: 'apply' | 'copy') => {\n if (!isReady) return;\n\n let file: globalThis.File;\n try {\n file = await produceFile(asset.name, asset.mime ?? 'image/png', asset.updatedAt);\n } catch {\n toggleNotification({\n type: 'danger',\n message: formatMessage({\n id: getTranslationKey('asset-details.crop.export-error'),\n defaultMessage: 'Could not process the cropped image.',\n }),\n });\n return;\n }\n\n const roundedFocal = { x: Math.round(focal.x), y: Math.round(focal.y) };\n if (action === 'apply') {\n onApply(file, roundedFocal);\n } else {\n onSaveAsCopy(file, roundedFocal);\n }\n };\n\n return (\n <Portal>\n <FocusTrap onEscape={onClose}>\n <Overlay>\n <HeaderBar alignItems=\"center\">\n <Crop aria-hidden />\n <Typography variant=\"omega\" fontWeight=\"bold\">\n {formatMessage({\n id: getTranslationKey('asset-details.crop.title'),\n defaultMessage: 'Crop & Focus area',\n })}\n </Typography>\n </HeaderBar>\n\n <Body>\n <CropArea\n ref={cropAreaRef}\n $aspect={\n naturalSize.width && naturalSize.height\n ? naturalSize.width / naturalSize.height\n : undefined\n }\n >\n <img\n ref={imgRef}\n src={imageUrl}\n alt={asset.name}\n crossOrigin=\"anonymous\"\n onLoad={handleImageLoad}\n draggable={false}\n />\n\n {cropPercents ? (\n <CropOverlay\n style={{\n left: `${cropPercents.left}%`,\n top: `${cropPercents.top}%`,\n width: `${cropPercents.width}%`,\n height: `${cropPercents.height}%`,\n }}\n onPointerDown={handleMovePointerDown}\n >\n <ResizeHandle\n type=\"button\"\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.resize.top-left'),\n defaultMessage: 'Resize top-left',\n })}\n $cursor=\"nwse-resize\"\n style={{ left: 0, top: 0 }}\n onPointerDown={handleResizePointerDown('tl')}\n />\n <ResizeHandle\n type=\"button\"\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.resize.top-right'),\n defaultMessage: 'Resize top-right',\n })}\n $cursor=\"nesw-resize\"\n style={{ right: 0, top: 0 }}\n onPointerDown={handleResizePointerDown('tr')}\n />\n <ResizeHandle\n type=\"button\"\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.resize.bottom-left'),\n defaultMessage: 'Resize bottom-left',\n })}\n $cursor=\"nesw-resize\"\n style={{ left: 0, bottom: 0 }}\n onPointerDown={handleResizePointerDown('bl')}\n />\n <ResizeHandle\n type=\"button\"\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.resize.bottom-right'),\n defaultMessage: 'Resize bottom-right',\n })}\n $cursor=\"nwse-resize\"\n style={{ right: 0, bottom: 0 }}\n onPointerDown={handleResizePointerDown('br')}\n />\n\n <FocalPointHandle\n type=\"button\"\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.focal-point'),\n defaultMessage: 'Focal point',\n })}\n style={{ left: `${focal.x}%`, top: `${focal.y}%` }}\n onPointerDown={handleFocalPointerDown}\n />\n </CropOverlay>\n ) : null}\n </CropArea>\n\n <InfoBox>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={1} paddingBottom={3}>\n <Typography variant=\"omega\" fontWeight=\"bold\" textColor={infoTextColor}>\n {formatMessage({\n id: getTranslationKey('asset-details.crop.title'),\n defaultMessage: 'Crop & Focus area',\n })}\n </Typography>\n <Typography variant=\"pi\" textColor={infoMutedColor}>\n {formatMessage({\n id: getTranslationKey('asset-details.crop.hint'),\n defaultMessage:\n 'Set the crop area with the rectangle. Pin the always-visible area with the circle.',\n })}\n </Typography>\n </Flex>\n\n <Flex gap={6} alignItems=\"center\">\n <Flex alignItems=\"center\" gap={2}>\n <Flex direction=\"column\" gap={2}>\n <FieldRow name=\"crop-width\" gap={2}>\n <LabelIcon textColor={infoTextColor}>\n <ArrowsHorizontal />\n </LabelIcon>\n <FieldNumberInput\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.width'),\n defaultMessage: 'Width (px)',\n })}\n value={width}\n min={1}\n max={naturalSize.width || undefined}\n onValueChange={(next) => {\n if (next !== undefined) setCropSize({ width: next });\n }}\n />\n </FieldRow>\n <FieldRow name=\"crop-height\" gap={2}>\n <LabelIcon textColor={infoTextColor}>\n <ArrowsVertical />\n </LabelIcon>\n <FieldNumberInput\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.height'),\n defaultMessage: 'Height (px)',\n })}\n value={height}\n min={1}\n max={naturalSize.height || undefined}\n onValueChange={(next) => {\n if (next !== undefined) setCropSize({ height: next });\n }}\n />\n </FieldRow>\n </Flex>\n\n <Flex position=\"relative\">\n <IconButton\n label={formatMessage({\n id: getTranslationKey('asset-details.crop.aspect-lock'),\n defaultMessage: 'Lock aspect ratio',\n })}\n variant={aspectLocked ? 'secondary' : 'ghost'}\n onClick={toggleAspectLock}\n >\n <Link />\n </IconButton>\n <BackgroundPreserveRatio />\n </Flex>\n </Flex>\n\n <Flex direction=\"column\" gap={2} marginLeft={'auto'}>\n <FieldRow name=\"focal-x\" gap={2}>\n <Field.Label textColor={infoTextColor}>\n {formatMessage({\n id: getTranslationKey('asset-details.crop.focal-x-axis'),\n defaultMessage: 'X',\n })}\n </Field.Label>\n <FieldNumberInput\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.focal-x'),\n defaultMessage: 'Focal point X (px)',\n })}\n value={focalPxX}\n onValueChange={(next) => {\n if (next !== undefined) setFocalPx('x', next);\n }}\n />\n </FieldRow>\n <FieldRow name=\"focal-y\" gap={2}>\n <Field.Label textColor={infoTextColor}>\n {formatMessage({\n id: getTranslationKey('asset-details.crop.focal-y-axis'),\n defaultMessage: 'Y',\n })}\n </Field.Label>\n <FieldNumberInput\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.focal-y'),\n defaultMessage: 'Focal point Y (px)',\n })}\n value={focalPxY}\n onValueChange={(next) => {\n if (next !== undefined) setFocalPx('y', next);\n }}\n />\n </FieldRow>\n </Flex>\n </Flex>\n </InfoBox>\n </Body>\n\n <FooterBar alignItems=\"center\">\n <Button variant=\"tertiary\" onClick={onClose} disabled={isBusy}>\n {formatMessage({ id: 'app.components.Button.cancel', defaultMessage: 'Cancel' })}\n </Button>\n <Flex gap={2}>\n <Button\n variant=\"secondary\"\n onClick={() => handleAction('copy')}\n loading={isBusy}\n disabled={!isReady}\n >\n {formatMessage({\n id: getTranslationKey('asset-details.crop.save-as-copy'),\n defaultMessage: 'Save as copy',\n })}\n </Button>\n <Button\n variant=\"default\"\n onClick={() => handleAction('apply')}\n loading={isBusy}\n disabled={!isReady}\n >\n {formatMessage({\n id: getTranslationKey('asset-details.crop.apply'),\n defaultMessage: 'Apply',\n })}\n </Button>\n </Flex>\n </FooterBar>\n </Overlay>\n </FocusTrap>\n </Portal>\n );\n};\n"],"names":["FOCAL_DIAMETER_REM","HANDLE_PX","Overlay","styled","Flex","theme","spaces","borderRadius","colors","neutral150","neutral0","HeaderBar","Body","Box","neutral100","CropArea","div","$aspect","CropOverlay","primary600","ResizeHandle","button","$cursor","FocalPointHandle","neutral800","InfoBox","colorScheme","neutral900","FooterBar","FieldRow","Field","Root","FieldNumberInput","NumberInput","LabelIcon","Label","BackgroundPreserveRatioContainer","BackgroundPreserveRatio","_jsx","svg","width","height","viewBox","fill","xmlns","path","d","stroke","strokeLinecap","AssetCropEditor","asset","isBusy","onClose","onApply","onSaveAsCopy","formatMessage","useIntl","toggleNotification","useNotification","useTheme","isDark","infoTextColor","infoMutedColor","imgRef","React","useRef","cropAreaRef","init","crop","naturalSize","aspectRatio","setCropSize","setCropPosition","setAspectRatio","produceFile","useCropImg","aspectLocked","setAspectLocked","useState","focal","setFocal","focalPoint","x","y","rawImageUrl","prefixFileUrlWithBackendUrl","url","cacheKey","updatedAt","Date","getTime","undefined","imageUrl","includes","handleImageLoad","current","pointerToNatural","event","rect","getBoundingClientRect","ratioX","ratioY","clientX","left","clientY","top","handleMovePointerDown","preventDefault","stopPropagation","start","startCrop","move","e","next","up","window","removeEventListener","addEventListener","handleResizePointerDown","corner","anchorX","anchorY","point","w","h","resolveCornerResize","toggleAspectLock","locked","handleFocalPointerDown","px","py","Math","round","min","max","focalPxX","focalPxY","setFocalPx","axis","value","dim","pct","prev","cropPercents","isReady","handleAction","action","file","name","mime","type","message","id","getTranslationKey","defaultMessage","roundedFocal","Portal","FocusTrap","onEscape","_jsxs","alignItems","Crop","aria-hidden","Typography","variant","fontWeight","ref","img","src","alt","crossOrigin","onLoad","draggable","style","onPointerDown","aria-label","right","bottom","direction","gap","paddingBottom","textColor","ArrowsHorizontal","onValueChange","ArrowsVertical","position","IconButton","label","onClick","Link","marginLeft","Button","disabled","loading"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,MAAMA,kBAAAA,GAAqB,GAAA;AAC3B,MAAMC,SAAAA,GAAY,EAAA;AAElB;;AAEkG;AAGlG,MAAMC,OAAAA,GAAUC,uBAAAA,CAAOC,iBAAAA,CAAK;;;;OAIrB,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;QAChC,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;SAChC,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;UAChC,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;AAC1B,iBAAA,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAME,YAAY,CAAC;oBACjC,EAAE,CAAC,EAAEF,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACC,UAAU,CAAC;cAC/C,EAAE,CAAC,EAAEJ,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACE,QAAQ,CAAC;AACrD,CAAC;AAED,MAAMC,SAAAA,GAAYR,uBAAAA,CAAOC,iBAAAA,CAAK;;OAEvB,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;AAC7B,WAAA,EAAE,CAAC,EAAED,KAAK,EAAE,GAAK,CAAA,EAAGA,MAAMC,MAAM,CAAC,CAAA,CAAE,CAAC,CAAC,EAAED,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,EAAE,CAAC;2BACzC,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACC,UAAU,CAAC;cACtD,EAAE,CAAC,EAAEJ,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACE,QAAQ,CAAC;AACrD,CAAC;AAED;AACA,MAAME,IAAAA,GAAOT,uBAAAA,CAAOU,gBAAAA,CAAI;;;;;;;;;;MAUlB,EAAE,CAAC,EAAER,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACM,UAAU,CAAC;MACzC,EAAE,CAAC,EAAET,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACE,QAAQ,CAAC;;;AAG7C,CAAC;AAED;AACA;AACA;AACA,MAAMK,QAAAA,GAAWZ,uBAAAA,CAAOa,GAAyB;;;;AAI/C,EAAA,EAAE,CAAC,EAAEC,OAAO,EAAE,GAAMA,OAAAA,GAAU,CAAC,cAAc,EAAEA,OAAAA,CAAQ,CAAC,CAAC,GAAG,EAAA;;;;;;;;;AAS9D,CAAC;AAED;AACA;AACA,MAAMC,WAAAA,GAAcf,uBAAAA,CAAOa,GAAG;;qBAET,EAAE,CAAC,EAAEX,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACW,UAAU,CAAC;;;AAG9D,CAAC;AAED,MAAMC,YAAAA,GAAejB,uBAAAA,CAAOkB,MAA2B;;AAE9C,SAAA,EAAEpB,SAAAA,CAAU;AACX,UAAA,EAAEA,SAAAA,CAAU;AACX,WAAA,EAAEA,YAAY,CAAA,CAAE;;oBAEP,EAAE,CAAC,EAAEI,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACW,UAAU,CAAC;;cAE/C,EAAE,CAAC,EAAEd,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACE,QAAQ,CAAC;AAC3C,UAAA,EAAE,CAAC,EAAEY,OAAO,EAAE,GAAKA,OAAAA,CAAQ;AACrC,CAAC;AAED,MAAMC,gBAAAA,GAAmBpB,uBAAAA,CAAOkB,MAAM;;AAE7B,SAAA,EAAErB,kBAAAA,CAAmB;AACpB,UAAA,EAAEA,kBAAAA,CAAmB;AACrB,UAAA,EAAE,CAACA,kBAAAA,GAAqB,CAAA,CAAE,QAAQ,EAAE,CAACA,qBAAqB,CAAA,CAAE;;oBAElD,EAAE,CAAC,EAAEK,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACgB,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;gBAwB7C,EAAE,CAAC,EAAEnB,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACgB,UAAU,CAAC;;;;;;;AAOzD,CAAC;AAED,MAAMC,OAAAA,GAAUtB,uBAAAA,CAAOU,gBAAAA,CAAI;;SAElB,EAAE,CAAC,EAAER,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;UAChC,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;;;WAGhC,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,CAAC;AAC3B,iBAAA,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAME,YAAY,CAAC;AACvC,cAAA,EAAE,CAAC,EAAEF,KAAK,EAAE,GACtBA,KAAAA,CAAMqB,WAAW,KAAK,MAAA,GAASrB,KAAAA,CAAMG,MAAM,CAACC,UAAU,GAAGJ,MAAMG,MAAM,CAACmB,UAAU,CAAC;;AAErF,CAAC;AAED,MAAMC,SAAAA,GAAYzB,uBAAAA,CAAOC,iBAAAA,CAAK;;;AAGnB,WAAA,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAK,CAAA,EAAGA,MAAMC,MAAM,CAAC,CAAA,CAAE,CAAC,CAAC,EAAED,KAAAA,CAAMC,MAAM,CAAC,CAAA,CAAE,EAAE,CAAC;wBAC5C,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACC,UAAU,CAAC;cACnD,EAAE,CAAC,EAAEJ,KAAK,EAAE,GAAKA,KAAAA,CAAMG,MAAM,CAACE,QAAQ,CAAC;AACrD,CAAC;AAED,MAAMmB,QAAAA,GAAW1B,uBAAAA,CAAO2B,kBAAAA,CAAMC,IAAI,CAAC;;;AAGnC,CAAC;AAED,MAAMC,gBAAAA,GAAmB7B,uBAAAA,CAAO8B,wBAAAA,CAAY;;AAE5C,CAAC;AAED,MAAMC,SAAAA,GAAY/B,uBAAAA,CAAO2B,kBAAAA,CAAMK,KAAK,CAAC;;;;;;AAMrC,CAAC;AAED,MAAMC,gCAAAA,GAAmCjC,uBAAAA,CAAOU,gBAAAA,CAAI;;;;;;;;;AASpD,CAAC;AAED,MAAMwB,uBAAAA,GAA0B,kBAC9BC,cAAA,CAACF,gCAAAA,EAAAA;AACC,QAAA,QAAA,gBAAAE,cAAA,CAACC,KAAAA,EAAAA;YAAIC,KAAAA,EAAM,IAAA;YAAKC,MAAAA,EAAO,IAAA;YAAKC,OAAAA,EAAQ,WAAA;YAAYC,IAAAA,EAAK,MAAA;YAAOC,KAAAA,EAAM,4BAAA;AAChE,YAAA,QAAA,gBAAAN,cAAA,CAACO,MAAAA,EAAAA;gBACCC,CAAAA,EAAE,iGAAA;gBACFC,MAAAA,EAAO,SAAA;gBACPC,aAAAA,EAAc;;;;AAoBf,MAAMC,eAAAA,GAAkB,CAAC,EAC9BC,KAAK,EACLC,MAAAA,GAAS,KAAK,EACdC,OAAO,EACPC,OAAO,EACPC,YAAY,EACS,GAAA;IACrB,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;IAC1B,MAAM,EAAEC,kBAAkB,EAAE,GAAGC,2BAAAA,EAAAA;;;;AAI/B,IAAA,MAAMrD,KAAAA,GAAQsD,yBAAAA,EAAAA;IACd,MAAMC,MAAAA,GAASvD,KAAAA,CAAMqB,WAAW,KAAK,MAAA;IACrC,MAAMmC,aAAAA,GAAgBD,SAAS,aAAA,GAAgB,UAAA;IAC/C,MAAME,cAAAA,GAAiBF,SAAS,YAAA,GAAe,YAAA;IAC/C,MAAMG,MAAAA,GAASC,gBAAAA,CAAMC,MAAM,CAAmB,IAAA,CAAA;IAC9C,MAAMC,WAAAA,GAAcF,gBAAAA,CAAMC,MAAM,CAAiB,IAAA,CAAA;IAEjD,MAAM,EACJE,IAAI,EACJC,IAAI,EACJC,WAAW,EACXC,WAAW,EACXC,WAAW,EACXC,eAAe,EACfC,cAAc,EACdC,WAAW,EACXlC,KAAK,EACLC,MAAM,EACP,GAAGkC,qBAAAA,EAAAA;AAEJ,IAAA,MAAM,CAACC,YAAAA,EAAcC,eAAAA,CAAgB,GAAGb,gBAAAA,CAAMc,QAAQ,CAAC,KAAA,CAAA;;IAEvD,MAAM,CAACC,OAAOC,QAAAA,CAAS,GAAGhB,iBAAMc,QAAQ,CAAa5B,KAAAA,CAAM+B,UAAU,IAAI;QAAEC,CAAAA,EAAG,EAAA;QAAIC,CAAAA,EAAG;AAAG,KAAA,CAAA;;;;IAKxF,MAAMC,WAAAA,GAAcC,iCAAAA,CAA4BnC,KAAAA,CAAMoC,GAAG,CAAA;IACzD,MAAMC,QAAAA,GAAWrC,KAAAA,CAAMsC,SAAS,GAAG,IAAIC,KAAKvC,KAAAA,CAAMsC,SAAS,CAAA,CAAEE,OAAO,EAAA,GAAKC,SAAAA;AACzE,IAAA,MAAMC,QAAAA,GACJL,QAAAA,KAAaI,SAAAA,GACT,CAAA,EAAGP,cAAcA,WAAAA,CAAYS,QAAQ,CAAC,GAAA,CAAA,GAAO,GAAA,GAAM,GAAA,CAAI,EAAE,EAAEN,UAAU,GACrEH,WAAAA;AAEN,IAAA,MAAMU,eAAAA,GAAkB,IAAA;QACtB,IAAI/B,MAAAA,CAAOgC,OAAO,EAAE;AAClB5B,YAAAA,IAAAA,CAAKJ,OAAOgC,OAAO,CAAA;AACrB,QAAA;AACF,IAAA,CAAA;;AAGA,IAAA,MAAMC,mBAAmB,CAACC,KAAAA,GAAAA;QACxB,MAAMC,IAAAA,GAAOhC,WAAAA,CAAY6B,OAAO,EAAEI,qBAAAA,EAAAA;QAClC,IAAI,CAACD,IAAAA,IAAQ,CAAC7B,WAAAA,CAAY7B,KAAK,IAAI,CAAC6B,WAAAA,CAAY5B,MAAM,EAAE,OAAO,IAAA;AAC/D,QAAA,MAAM2D,MAAAA,GAAS/B,WAAAA,CAAY7B,KAAK,GAAG0D,KAAK1D,KAAK;AAC7C,QAAA,MAAM6D,MAAAA,GAAShC,WAAAA,CAAY5B,MAAM,GAAGyD,KAAKzD,MAAM;QAC/C,OAAO;YACLyC,CAAAA,EAAIe,CAAAA,KAAAA,CAAMK,OAAO,GAAGJ,IAAAA,CAAKK,IAAI,IAAIH,MAAAA;YACjCjB,CAAAA,EAAIc,CAAAA,KAAAA,CAAMO,OAAO,GAAGN,IAAAA,CAAKO,GAAG,IAAIJ;AAClC,SAAA;AACF,IAAA,CAAA;;AAGA,IAAA,MAAMK,wBAAwB,CAACT,KAAAA,GAAAA;AAC7BA,QAAAA,KAAAA,CAAMU,cAAc,EAAA;AACpBV,QAAAA,KAAAA,CAAMW,eAAe,EAAA;AACrB,QAAA,MAAMC,QAAQb,gBAAAA,CAAiBC,KAAAA,CAAAA;AAC/B,QAAA,IAAI,CAACY,KAAAA,EAAO;AACZ,QAAA,MAAMC,SAAAA,GAAY;AAAE,YAAA,GAAG1C;AAAK,SAAA;AAC5B,QAAA,MAAM2C,OAAO,CAACC,CAAAA,GAAAA;AACZ,YAAA,MAAMC,OAAOjB,gBAAAA,CAAiBgB,CAAAA,CAAAA;AAC9B,YAAA,IAAI,CAACC,IAAAA,EAAM;YACXzC,eAAAA,CAAgB;gBACdU,CAAAA,EAAG4B,SAAAA,CAAU5B,CAAC,IAAI+B,KAAK/B,CAAC,GAAG2B,KAAAA,CAAM3B,CAAC,CAADA;gBACjCC,CAAAA,EAAG2B,SAAAA,CAAU3B,CAAC,IAAI8B,KAAK9B,CAAC,GAAG0B,KAAAA,CAAM1B,CAAC;AACpC,aAAA,CAAA;AACF,QAAA,CAAA;AACA,QAAA,MAAM+B,EAAAA,GAAK,IAAA;YACTC,MAAAA,CAAOC,mBAAmB,CAAC,aAAA,EAAeL,IAAAA,CAAAA;YAC1CI,MAAAA,CAAOC,mBAAmB,CAAC,WAAA,EAAaF,EAAAA,CAAAA;AAC1C,QAAA,CAAA;QACAC,MAAAA,CAAOE,gBAAgB,CAAC,aAAA,EAAeN,IAAAA,CAAAA;QACvCI,MAAAA,CAAOE,gBAAgB,CAAC,WAAA,EAAaH,EAAAA,CAAAA;AACvC,IAAA,CAAA;;IAGA,MAAMI,uBAAAA,GAA0B,CAACC,MAAAA,GAAmB,CAACtB,KAAAA,GAAAA;AACnDA,YAAAA,KAAAA,CAAMU,cAAc,EAAA;AACpBV,YAAAA,KAAAA,CAAMW,eAAe,EAAA;AACrB,YAAA,MAAME,SAAAA,GAAY;AAAE,gBAAA,GAAG1C;AAAK,aAAA;AAC5B,YAAA,MAAMoD,OAAAA,GACJD,MAAAA,KAAW,IAAA,IAAQA,MAAAA,KAAW,IAAA,GAAOT,SAAAA,CAAU5B,CAAC,GAAG4B,SAAAA,CAAUtE,KAAK,GAAGsE,SAAAA,CAAU5B,CAAC;AAClF,YAAA,MAAMuC,OAAAA,GACJF,MAAAA,KAAW,IAAA,IAAQA,MAAAA,KAAW,IAAA,GAAOT,SAAAA,CAAU3B,CAAC,GAAG2B,SAAAA,CAAUrE,MAAM,GAAGqE,SAAAA,CAAU3B,CAAC;AACnF,YAAA,MAAM4B,OAAO,CAACC,CAAAA,GAAAA;AACZ,gBAAA,MAAMU,QAAQ1B,gBAAAA,CAAiBgB,CAAAA,CAAAA;AAC/B,gBAAA,IAAI,CAACU,KAAAA,EAAO;AACZ,gBAAA,MAAM,EACJxC,CAAC,EACDC,CAAC,EACD3C,KAAAA,EAAOmF,CAAC,EACRlF,MAAAA,EAAQmF,CAAC,EACV,GAAGC,8BAAAA,CAAoB;AACtBL,oBAAAA,OAAAA;AACAC,oBAAAA,OAAAA;AACAC,oBAAAA,KAAAA;AACApD,oBAAAA,WAAAA,EAAaM,eAAeN,WAAAA,GAAc;AAC5C,iBAAA,CAAA;gBACAE,eAAAA,CAAgB;AAAEU,oBAAAA,CAAAA;AAAGC,oBAAAA;AAAE,iBAAA,CAAA;gBACvBZ,WAAAA,CAAY;oBAAE/B,KAAAA,EAAOmF,CAAAA;oBAAGlF,MAAAA,EAAQmF;AAAE,iBAAA,CAAA;AACpC,YAAA,CAAA;AACA,YAAA,MAAMV,EAAAA,GAAK,IAAA;gBACTC,MAAAA,CAAOC,mBAAmB,CAAC,aAAA,EAAeL,IAAAA,CAAAA;gBAC1CI,MAAAA,CAAOC,mBAAmB,CAAC,WAAA,EAAaF,EAAAA,CAAAA;AAC1C,YAAA,CAAA;YACAC,MAAAA,CAAOE,gBAAgB,CAAC,aAAA,EAAeN,IAAAA,CAAAA;YACvCI,MAAAA,CAAOE,gBAAgB,CAAC,WAAA,EAAaH,EAAAA,CAAAA;AACvC,QAAA,CAAA;AAEA,IAAA,MAAMY,gBAAAA,GAAmB,IAAA;AACvBjD,QAAAA,eAAAA,CAAgB,CAACkD,MAAAA,GAAAA;AACf,YAAA,MAAMd,OAAO,CAACc,MAAAA;YACdtD,cAAAA,CAAewC,IAAAA,IAAQxE,MAAAA,GAASD,KAAAA,GAAQC,MAAAA,GAAS,IAAA,CAAA;YACjD,OAAOwE,IAAAA;AACT,QAAA,CAAA,CAAA;AACF,IAAA,CAAA;;AAGA,IAAA,MAAMe,yBAAyB,CAAC/B,KAAAA,GAAAA;AAC9BA,QAAAA,KAAAA,CAAMU,cAAc,EAAA;AACpBV,QAAAA,KAAAA,CAAMW,eAAe,EAAA;AACrB,QAAA,MAAMG,OAAO,CAACC,CAAAA,GAAAA;AACZ,YAAA,MAAMU,QAAQ1B,gBAAAA,CAAiBgB,CAAAA,CAAAA;AAC/B,YAAA,IAAI,CAACU,KAAAA,EAAO;;AAEZ,YAAA,MAAMO,EAAAA,GAAOP,CAAAA,KAAAA,CAAMxC,CAAC,GAAGd,IAAAA,CAAKc,CAAC,IAAId,IAAAA,CAAK5B,KAAK,GAAI,GAAA;AAC/C,YAAA,MAAM0F,EAAAA,GAAOR,CAAAA,KAAAA,CAAMvC,CAAC,GAAGf,IAAAA,CAAKe,CAAC,IAAIf,IAAAA,CAAK3B,MAAM,GAAI,GAAA;YAChDuC,QAAAA,CAAS;gBACPE,CAAAA,EAAGiD,IAAAA,CAAKC,KAAK,CAACD,IAAAA,CAAKE,GAAG,CAAC,GAAA,EAAKF,IAAAA,CAAKG,GAAG,CAAC,CAAA,EAAGL,EAAAA,CAAAA,CAAAA,CAAAA;gBACxC9C,CAAAA,EAAGgD,IAAAA,CAAKC,KAAK,CAACD,IAAAA,CAAKE,GAAG,CAAC,GAAA,EAAKF,IAAAA,CAAKG,GAAG,CAAC,CAAA,EAAGJ,EAAAA,CAAAA,CAAAA;AAC1C,aAAA,CAAA;AACF,QAAA,CAAA;AACA,QAAA,MAAMhB,EAAAA,GAAK,IAAA;YACTC,MAAAA,CAAOC,mBAAmB,CAAC,aAAA,EAAeL,IAAAA,CAAAA;YAC1CI,MAAAA,CAAOC,mBAAmB,CAAC,WAAA,EAAaF,EAAAA,CAAAA;AAC1C,QAAA,CAAA;QACAC,MAAAA,CAAOE,gBAAgB,CAAC,aAAA,EAAeN,IAAAA,CAAAA;QACvCI,MAAAA,CAAOE,gBAAgB,CAAC,WAAA,EAAaH,EAAAA,CAAAA;AACvC,IAAA,CAAA;IAEA,MAAMqB,QAAAA,GAAWJ,KAAKC,KAAK,CAAC,KAACrD,CAAMG,CAAC,GAAG,GAAA,GAAO1C,KAAAA,CAAAA;IAC9C,MAAMgG,QAAAA,GAAWL,KAAKC,KAAK,CAAC,KAACrD,CAAMI,CAAC,GAAG,GAAA,GAAO1C,MAAAA,CAAAA;IAE9C,MAAMgG,UAAAA,GAAa,CAACC,IAAAA,EAAiBC,KAAAA,GAAAA;QACnC,MAAMC,GAAAA,GAAMF,IAAAA,KAAS,GAAA,GAAMlG,KAAAA,GAAQC,MAAAA;AACnC,QAAA,IAAI,CAACmG,GAAAA,EAAK;QACV,MAAMC,GAAAA,GAAMV,IAAAA,CAAKE,GAAG,CAAC,GAAA,EAAKF,IAAAA,CAAKG,GAAG,CAAC,CAAA,EAAG,KAACK,GAAQC,GAAAA,GAAO,GAAA,CAAA,CAAA;QACtD5D,QAAAA,CAAS,CAAC8D,QAAU;AAAE,gBAAA,GAAGA,IAAI;AAAE,gBAAA,CAACJ,IAAAA,GAAOP,IAAAA,CAAKC,KAAK,CAACS,GAAAA;aAAK,CAAA,CAAA;AACzD,IAAA,CAAA;AAEA,IAAA,MAAME,eACJ1E,WAAAA,CAAY7B,KAAK,IAAI6B,WAAAA,CAAY5B,MAAM,GACnC;AACE8D,QAAAA,IAAAA,EAAM,IAACnC,CAAKc,CAAC,GAAGb,WAAAA,CAAY7B,KAAK,GAAI,GAAA;AACrCiE,QAAAA,GAAAA,EAAK,IAACrC,CAAKe,CAAC,GAAGd,WAAAA,CAAY5B,MAAM,GAAI,GAAA;AACrCD,QAAAA,KAAAA,EAAO,IAAC4B,CAAK5B,KAAK,GAAG6B,WAAAA,CAAY7B,KAAK,GAAI,GAAA;AAC1CC,QAAAA,MAAAA,EAAQ,IAAC2B,CAAK3B,MAAM,GAAG4B,WAAAA,CAAY5B,MAAM,GAAI;KAC/C,GACA,IAAA;;;AAIN,IAAA,MAAMuG,UAAUD,YAAAA,KAAiB,IAAA;AAEjC,IAAA,MAAME,eAAe,OAAOC,MAAAA,GAAAA;AAC1B,QAAA,IAAI,CAACF,OAAAA,EAAS;QAEd,IAAIG,IAAAA;QACJ,IAAI;YACFA,IAAAA,GAAO,MAAMzE,WAAAA,CAAYxB,KAAAA,CAAMkG,IAAI,EAAElG,MAAMmG,IAAI,IAAI,WAAA,EAAanG,KAAAA,CAAMsC,SAAS,CAAA;AACjF,QAAA,CAAA,CAAE,OAAM;YACN/B,kBAAAA,CAAmB;gBACjB6F,IAAAA,EAAM,QAAA;AACNC,gBAAAA,OAAAA,EAAShG,aAAAA,CAAc;AACrBiG,oBAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,iCAAA,CAAA;oBACtBC,cAAAA,EAAgB;AAClB,iBAAA;AACF,aAAA,CAAA;AACA,YAAA;AACF,QAAA;AAEA,QAAA,MAAMC,YAAAA,GAAe;AAAEzE,YAAAA,CAAAA,EAAGiD,IAAAA,CAAKC,KAAK,CAACrD,KAAAA,CAAMG,CAAC,CAAA;AAAGC,YAAAA,CAAAA,EAAGgD,IAAAA,CAAKC,KAAK,CAACrD,KAAAA,CAAMI,CAAC;AAAE,SAAA;AACtE,QAAA,IAAI+D,WAAW,OAAA,EAAS;AACtB7F,YAAAA,OAAAA,CAAQ8F,IAAAA,EAAMQ,YAAAA,CAAAA;QAChB,CAAA,MAAO;AACLrG,YAAAA,YAAAA,CAAa6F,IAAAA,EAAMQ,YAAAA,CAAAA;AACrB,QAAA;AACF,IAAA,CAAA;AAEA,IAAA,qBACErH,cAAA,CAACsH,mBAAAA,EAAAA;AACC,QAAA,QAAA,gBAAAtH,cAAA,CAACuH,sBAAAA,EAAAA;YAAUC,QAAAA,EAAU1G,OAAAA;AACnB,YAAA,QAAA,gBAAA2G,eAAA,CAAC7J,OAAAA,EAAAA;;kCACC6J,eAAA,CAACpJ,SAAAA,EAAAA;wBAAUqJ,UAAAA,EAAW,QAAA;;0CACpB1H,cAAA,CAAC2H,UAAAA,EAAAA;gCAAKC,aAAW,EAAA;;0CACjB5H,cAAA,CAAC6H,uBAAAA,EAAAA;gCAAWC,OAAAA,EAAQ,OAAA;gCAAQC,UAAAA,EAAW,MAAA;0CACpC9G,aAAAA,CAAc;AACbiG,oCAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,0BAAA,CAAA;oCACtBC,cAAAA,EAAgB;AAClB,iCAAA;;;;kCAIJK,eAAA,CAACnJ,IAAAA,EAAAA;;0CACCmJ,eAAA,CAAChJ,QAAAA,EAAAA;gCACCuJ,GAAAA,EAAKpG,WAAAA;gCACLjD,OAAAA,EACEoD,WAAAA,CAAY7B,KAAK,IAAI6B,WAAAA,CAAY5B,MAAM,GACnC4B,WAAAA,CAAY7B,KAAK,GAAG6B,WAAAA,CAAY5B,MAAM,GACtCkD,SAAAA;;kDAGNrD,cAAA,CAACiI,KAAAA,EAAAA;wCACCD,GAAAA,EAAKvG,MAAAA;wCACLyG,GAAAA,EAAK5E,QAAAA;AACL6E,wCAAAA,GAAAA,EAAKvH,MAAMkG,IAAI;wCACfsB,WAAAA,EAAY,WAAA;wCACZC,MAAAA,EAAQ7E,eAAAA;wCACR8E,SAAAA,EAAW;;AAGZ7B,oCAAAA,YAAAA,iBACCgB,eAAA,CAAC7I,WAAAA,EAAAA;wCACC2J,KAAAA,EAAO;AACLtE,4CAAAA,IAAAA,EAAM,CAAA,EAAGwC,YAAAA,CAAaxC,IAAI,CAAC,CAAC,CAAC;AAC7BE,4CAAAA,GAAAA,EAAK,CAAA,EAAGsC,YAAAA,CAAatC,GAAG,CAAC,CAAC,CAAC;AAC3BjE,4CAAAA,KAAAA,EAAO,CAAA,EAAGuG,YAAAA,CAAavG,KAAK,CAAC,CAAC,CAAC;AAC/BC,4CAAAA,MAAAA,EAAQ,CAAA,EAAGsG,YAAAA,CAAatG,MAAM,CAAC,CAAC;AAClC,yCAAA;wCACAqI,aAAAA,EAAepE,qBAAAA;;0DAEfpE,cAAA,CAAClB,YAAAA,EAAAA;gDACCkI,IAAAA,EAAK,QAAA;AACLyB,gDAAAA,YAAAA,EAAYxH,aAAAA,CAAc;AACxBiG,oDAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,oCAAA,CAAA;oDACtBC,cAAAA,EAAgB;AAClB,iDAAA,CAAA;gDACApI,OAAAA,EAAQ,aAAA;gDACRuJ,KAAAA,EAAO;oDAAEtE,IAAAA,EAAM,CAAA;oDAAGE,GAAAA,EAAK;AAAE,iDAAA;AACzBqE,gDAAAA,aAAAA,EAAexD,uBAAAA,CAAwB,IAAA;;0DAEzChF,cAAA,CAAClB,YAAAA,EAAAA;gDACCkI,IAAAA,EAAK,QAAA;AACLyB,gDAAAA,YAAAA,EAAYxH,aAAAA,CAAc;AACxBiG,oDAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,qCAAA,CAAA;oDACtBC,cAAAA,EAAgB;AAClB,iDAAA,CAAA;gDACApI,OAAAA,EAAQ,aAAA;gDACRuJ,KAAAA,EAAO;oDAAEG,KAAAA,EAAO,CAAA;oDAAGvE,GAAAA,EAAK;AAAE,iDAAA;AAC1BqE,gDAAAA,aAAAA,EAAexD,uBAAAA,CAAwB,IAAA;;0DAEzChF,cAAA,CAAClB,YAAAA,EAAAA;gDACCkI,IAAAA,EAAK,QAAA;AACLyB,gDAAAA,YAAAA,EAAYxH,aAAAA,CAAc;AACxBiG,oDAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,uCAAA,CAAA;oDACtBC,cAAAA,EAAgB;AAClB,iDAAA,CAAA;gDACApI,OAAAA,EAAQ,aAAA;gDACRuJ,KAAAA,EAAO;oDAAEtE,IAAAA,EAAM,CAAA;oDAAG0E,MAAAA,EAAQ;AAAE,iDAAA;AAC5BH,gDAAAA,aAAAA,EAAexD,uBAAAA,CAAwB,IAAA;;0DAEzChF,cAAA,CAAClB,YAAAA,EAAAA;gDACCkI,IAAAA,EAAK,QAAA;AACLyB,gDAAAA,YAAAA,EAAYxH,aAAAA,CAAc;AACxBiG,oDAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,wCAAA,CAAA;oDACtBC,cAAAA,EAAgB;AAClB,iDAAA,CAAA;gDACApI,OAAAA,EAAQ,aAAA;gDACRuJ,KAAAA,EAAO;oDAAEG,KAAAA,EAAO,CAAA;oDAAGC,MAAAA,EAAQ;AAAE,iDAAA;AAC7BH,gDAAAA,aAAAA,EAAexD,uBAAAA,CAAwB,IAAA;;0DAGzChF,cAAA,CAACf,gBAAAA,EAAAA;gDACC+H,IAAAA,EAAK,QAAA;AACLyB,gDAAAA,YAAAA,EAAYxH,aAAAA,CAAc;AACxBiG,oDAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,gCAAA,CAAA;oDACtBC,cAAAA,EAAgB;AAClB,iDAAA,CAAA;gDACAmB,KAAAA,EAAO;AAAEtE,oDAAAA,IAAAA,EAAM,CAAA,EAAGxB,KAAAA,CAAMG,CAAC,CAAC,CAAC,CAAC;AAAEuB,oDAAAA,GAAAA,EAAK,CAAA,EAAG1B,KAAAA,CAAMI,CAAC,CAAC,CAAC;AAAE,iDAAA;gDACjD2F,aAAAA,EAAe9C;;;AAGjB,qCAAA,CAAA,GAAA;;;0CAGN+B,eAAA,CAACtI,OAAAA,EAAAA;;kDACCsI,eAAA,CAAC3J,iBAAAA,EAAAA;wCAAK8K,SAAAA,EAAU,QAAA;wCAASlB,UAAAA,EAAW,SAAA;wCAAUmB,GAAAA,EAAK,CAAA;wCAAGC,aAAAA,EAAe,CAAA;;0DACnE9I,cAAA,CAAC6H,uBAAAA,EAAAA;gDAAWC,OAAAA,EAAQ,OAAA;gDAAQC,UAAAA,EAAW,MAAA;gDAAOgB,SAAAA,EAAWxH,aAAAA;0DACtDN,aAAAA,CAAc;AACbiG,oDAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,0BAAA,CAAA;oDACtBC,cAAAA,EAAgB;AAClB,iDAAA;;0DAEFpH,cAAA,CAAC6H,uBAAAA,EAAAA;gDAAWC,OAAAA,EAAQ,IAAA;gDAAKiB,SAAAA,EAAWvH,cAAAA;0DACjCP,aAAAA,CAAc;AACbiG,oDAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,yBAAA,CAAA;oDACtBC,cAAAA,EACE;AACJ,iDAAA;;;;kDAIJK,eAAA,CAAC3J,iBAAAA,EAAAA;wCAAK+K,GAAAA,EAAK,CAAA;wCAAGnB,UAAAA,EAAW,QAAA;;0DACvBD,eAAA,CAAC3J,iBAAAA,EAAAA;gDAAK4J,UAAAA,EAAW,QAAA;gDAASmB,GAAAA,EAAK,CAAA;;kEAC7BpB,eAAA,CAAC3J,iBAAAA,EAAAA;wDAAK8K,SAAAA,EAAU,QAAA;wDAASC,GAAAA,EAAK,CAAA;;0EAC5BpB,eAAA,CAAClI,QAAAA,EAAAA;gEAASuH,IAAAA,EAAK,YAAA;gEAAa+B,GAAAA,EAAK,CAAA;;kFAC/B7I,cAAA,CAACJ,SAAAA,EAAAA;wEAAUmJ,SAAAA,EAAWxH,aAAAA;AACpB,wEAAA,QAAA,gBAAAvB,cAAA,CAACgJ,sBAAAA,EAAAA,EAAAA;;kFAEHhJ,cAAA,CAACN,gBAAAA,EAAAA;AACC+I,wEAAAA,YAAAA,EAAYxH,aAAAA,CAAc;AACxBiG,4EAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,0BAAA,CAAA;4EACtBC,cAAAA,EAAgB;AAClB,yEAAA,CAAA;wEACAf,KAAAA,EAAOnG,KAAAA;wEACP6F,GAAAA,EAAK,CAAA;wEACLC,GAAAA,EAAKjE,WAAAA,CAAY7B,KAAK,IAAImD,SAAAA;AAC1B4F,wEAAAA,aAAAA,EAAe,CAACtE,IAAAA,GAAAA;4EACd,IAAIA,IAAAA,KAAStB,WAAWpB,WAAAA,CAAY;gFAAE/B,KAAAA,EAAOyE;AAAK,6EAAA,CAAA;AACpD,wEAAA;;;;0EAGJ8C,eAAA,CAAClI,QAAAA,EAAAA;gEAASuH,IAAAA,EAAK,aAAA;gEAAc+B,GAAAA,EAAK,CAAA;;kFAChC7I,cAAA,CAACJ,SAAAA,EAAAA;wEAAUmJ,SAAAA,EAAWxH,aAAAA;AACpB,wEAAA,QAAA,gBAAAvB,cAAA,CAACkJ,oBAAAA,EAAAA,EAAAA;;kFAEHlJ,cAAA,CAACN,gBAAAA,EAAAA;AACC+I,wEAAAA,YAAAA,EAAYxH,aAAAA,CAAc;AACxBiG,4EAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,2BAAA,CAAA;4EACtBC,cAAAA,EAAgB;AAClB,yEAAA,CAAA;wEACAf,KAAAA,EAAOlG,MAAAA;wEACP4F,GAAAA,EAAK,CAAA;wEACLC,GAAAA,EAAKjE,WAAAA,CAAY5B,MAAM,IAAIkD,SAAAA;AAC3B4F,wEAAAA,aAAAA,EAAe,CAACtE,IAAAA,GAAAA;4EACd,IAAIA,IAAAA,KAAStB,WAAWpB,WAAAA,CAAY;gFAAE9B,MAAAA,EAAQwE;AAAK,6EAAA,CAAA;AACrD,wEAAA;;;;;;kEAKN8C,eAAA,CAAC3J,iBAAAA,EAAAA;wDAAKqL,QAAAA,EAAS,UAAA;;0EACbnJ,cAAA,CAACoJ,uBAAAA,EAAAA;AACCC,gEAAAA,KAAAA,EAAOpI,aAAAA,CAAc;AACnBiG,oEAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,gCAAA,CAAA;oEACtBC,cAAAA,EAAgB;AAClB,iEAAA,CAAA;AACAU,gEAAAA,OAAAA,EAASxF,eAAe,WAAA,GAAc,OAAA;gEACtCgH,OAAAA,EAAS9D,gBAAAA;AAET,gEAAA,QAAA,gBAAAxF,cAAA,CAACuJ,UAAAA,EAAAA,EAAAA;;0EAEHvJ,cAAA,CAACD,uBAAAA,EAAAA,EAAAA;;;;;0DAIL0H,eAAA,CAAC3J,iBAAAA,EAAAA;gDAAK8K,SAAAA,EAAU,QAAA;gDAASC,GAAAA,EAAK,CAAA;gDAAGW,UAAAA,EAAY,MAAA;;kEAC3C/B,eAAA,CAAClI,QAAAA,EAAAA;wDAASuH,IAAAA,EAAK,SAAA;wDAAU+B,GAAAA,EAAK,CAAA;;AAC5B,0EAAA7I,cAAA,CAACR,mBAAMK,KAAK,EAAA;gEAACkJ,SAAAA,EAAWxH,aAAAA;0EACrBN,aAAAA,CAAc;AACbiG,oEAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,iCAAA,CAAA;oEACtBC,cAAAA,EAAgB;AAClB,iEAAA;;0EAEFpH,cAAA,CAACN,gBAAAA,EAAAA;AACC+I,gEAAAA,YAAAA,EAAYxH,aAAAA,CAAc;AACxBiG,oEAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,4BAAA,CAAA;oEACtBC,cAAAA,EAAgB;AAClB,iEAAA,CAAA;gEACAf,KAAAA,EAAOJ,QAAAA;AACPgD,gEAAAA,aAAAA,EAAe,CAACtE,IAAAA,GAAAA;oEACd,IAAIA,IAAAA,KAAStB,SAAAA,EAAW8C,UAAAA,CAAW,GAAA,EAAKxB,IAAAA,CAAAA;AAC1C,gEAAA;;;;kEAGJ8C,eAAA,CAAClI,QAAAA,EAAAA;wDAASuH,IAAAA,EAAK,SAAA;wDAAU+B,GAAAA,EAAK,CAAA;;AAC5B,0EAAA7I,cAAA,CAACR,mBAAMK,KAAK,EAAA;gEAACkJ,SAAAA,EAAWxH,aAAAA;0EACrBN,aAAAA,CAAc;AACbiG,oEAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,iCAAA,CAAA;oEACtBC,cAAAA,EAAgB;AAClB,iEAAA;;0EAEFpH,cAAA,CAACN,gBAAAA,EAAAA;AACC+I,gEAAAA,YAAAA,EAAYxH,aAAAA,CAAc;AACxBiG,oEAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,4BAAA,CAAA;oEACtBC,cAAAA,EAAgB;AAClB,iEAAA,CAAA;gEACAf,KAAAA,EAAOH,QAAAA;AACP+C,gEAAAA,aAAAA,EAAe,CAACtE,IAAAA,GAAAA;oEACd,IAAIA,IAAAA,KAAStB,SAAAA,EAAW8C,UAAAA,CAAW,GAAA,EAAKxB,IAAAA,CAAAA;AAC1C,gEAAA;;;;;;;;;;;;kCAQZ8C,eAAA,CAACnI,SAAAA,EAAAA;wBAAUoI,UAAAA,EAAW,QAAA;;0CACpB1H,cAAA,CAACyJ,mBAAAA,EAAAA;gCAAO3B,OAAAA,EAAQ,UAAA;gCAAWwB,OAAAA,EAASxI,OAAAA;gCAAS4I,QAAAA,EAAU7I,MAAAA;0CACpDI,aAAAA,CAAc;oCAAEiG,EAAAA,EAAI,8BAAA;oCAAgCE,cAAAA,EAAgB;AAAS,iCAAA;;0CAEhFK,eAAA,CAAC3J,iBAAAA,EAAAA;gCAAK+K,GAAAA,EAAK,CAAA;;kDACT7I,cAAA,CAACyJ,mBAAAA,EAAAA;wCACC3B,OAAAA,EAAQ,WAAA;AACRwB,wCAAAA,OAAAA,EAAS,IAAM3C,YAAAA,CAAa,MAAA,CAAA;wCAC5BgD,OAAAA,EAAS9I,MAAAA;AACT6I,wCAAAA,QAAAA,EAAU,CAAChD,OAAAA;kDAEVzF,aAAAA,CAAc;AACbiG,4CAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,iCAAA,CAAA;4CACtBC,cAAAA,EAAgB;AAClB,yCAAA;;kDAEFpH,cAAA,CAACyJ,mBAAAA,EAAAA;wCACC3B,OAAAA,EAAQ,SAAA;AACRwB,wCAAAA,OAAAA,EAAS,IAAM3C,YAAAA,CAAa,OAAA,CAAA;wCAC5BgD,OAAAA,EAAS9I,MAAAA;AACT6I,wCAAAA,QAAAA,EAAU,CAAChD,OAAAA;kDAEVzF,aAAAA,CAAc;AACbiG,4CAAAA,EAAAA,EAAIC,8BAAAA,CAAkB,0BAAA,CAAA;4CACtBC,cAAAA,EAAgB;AAClB,yCAAA;;;;;;;;;;AAQhB;;;;"}
1
+ {"version":3,"file":"AssetCropEditor.js","sources":["../../../../../../../admin/src/future/pages/Assets/components/AssetDetails/AssetCropEditor.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useNotification } from '@strapi/admin/strapi-admin';\nimport {\n Box,\n Button,\n Field,\n Flex,\n FocusTrap,\n IconButton,\n NumberInput,\n Portal,\n Typography,\n} from '@strapi/design-system';\nimport { ArrowsHorizontal, ArrowsVertical, Crop, Link } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { styled, useTheme } from 'styled-components';\n\nimport { prefixFileUrlWithBackendUrl } from '../../../../utils/files';\nimport { getTranslationKey } from '../../../../utils/translations';\n\nimport { resolveCornerResize, useCropImg } from './useCropImg';\n\nimport type {\n AssetWithPopulatedCreatedBy,\n FocalPoint,\n} from '../../../../../../../shared/contracts/files';\n\nconst FOCAL_DIAMETER_REM = 5.6;\nconst HANDLE_PX = 12;\n\n/* -------------------------------------------------------------------------------------------------\n * Styled\n * -----------------------------------------------------------------------------------------------*/\n\n// Full-viewport takeover with a small inset so the editor reads as a card.\nconst Overlay = styled(Flex)`\n position: fixed;\n z-index: 1200;\n flex-direction: column;\n top: ${({ theme }) => theme.spaces[1]};\n left: ${({ theme }) => theme.spaces[1]};\n right: ${({ theme }) => theme.spaces[1]};\n bottom: ${({ theme }) => theme.spaces[1]};\n border-radius: ${({ theme }) => theme.borderRadius};\n border: 1px solid ${({ theme }) => theme.colors.neutral150};\n background: ${({ theme }) => theme.colors.neutral0};\n /* Focused programmatically on open (tabIndex -1) — no visible ring needed. */\n outline: none;\n`;\n\nconst HeaderBar = styled(Flex)`\n width: 100%;\n gap: ${({ theme }) => theme.spaces[2]};\n padding: ${({ theme }) => `${theme.spaces[3]} ${theme.spaces[5]}`};\n border-bottom: 1px solid ${({ theme }) => theme.colors.neutral150};\n background: ${({ theme }) => theme.colors.neutral0};\n`;\n\n// Fills the remaining space between header/footer; checkerboard pattern.\n// The horizontal padding keeps the image off the viewport edges — the corner\n// handles overhang the image by half their size, and on narrow (mobile)\n// screens an edge-to-edge image leaves nothing to grab.\nconst Body = styled(Box)`\n width: 100%;\n position: relative;\n flex: 1;\n min-height: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n padding: 0 ${({ theme }) => theme.spaces[4]};\n background: repeating-conic-gradient(\n ${({ theme }) => theme.colors.neutral100} 0% 25%,\n ${({ theme }) => theme.colors.neutral0} 0% 50%\n )\n 50% / 20px 20px;\n`;\n\n// Wrapper sized to the image's natural aspect ratio so the <img> inside fills\n// it without letterboxing. Percentage-based positioning of the crop overlay\n// then maps directly to natural-px coordinates.\nconst CropArea = styled.div<{ $aspect?: number }>`\n position: relative;\n max-width: 100%;\n max-height: 100%;\n ${({ $aspect }) => ($aspect ? `aspect-ratio: ${$aspect};` : '')}\n\n img {\n display: block;\n width: 100%;\n height: 100%;\n user-select: none;\n -webkit-user-drag: none;\n }\n`;\n\n// Crop selection rectangle, positioned by % of CropArea. Inverts the dim\n// outside via box-shadow so the focused area shows full color.\nconst CropOverlay = styled.div`\n position: absolute;\n border: 1px dashed ${({ theme }) => theme.colors.primary600};\n box-shadow: 0 0 0 9999px rgba(33, 33, 52, 0.5);\n cursor: move;\n /* Without this, touch browsers claim the gesture for scrolling and fire\n pointercancel mid-drag — the crop drag dies while the finger is down. */\n touch-action: none;\n`;\n\nconst ResizeHandle = styled.button<{ $cursor: string }>`\n position: absolute;\n width: ${HANDLE_PX}px;\n height: ${HANDLE_PX}px;\n margin: -${HANDLE_PX / 2}px;\n padding: 0;\n border: 1px solid ${({ theme }) => theme.colors.primary600};\n border-radius: 2px;\n background: ${({ theme }) => theme.colors.neutral0};\n cursor: ${({ $cursor }) => $cursor};\n touch-action: none;\n`;\n\nconst FocalPointHandle = styled.button`\n position: absolute;\n width: ${FOCAL_DIAMETER_REM}rem;\n height: ${FOCAL_DIAMETER_REM}rem;\n margin: ${-FOCAL_DIAMETER_REM / 2}rem 0 0 ${-FOCAL_DIAMETER_REM / 2}rem;\n border-radius: 50%;\n border: 1px solid ${({ theme }) => theme.colors.neutral800};\n background: transparent;\n cursor: grab;\n padding: 0;\n touch-action: none;\n\n &::before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: rgba(0, 0, 0, 0.16);\n transform: translate(-50%, -50%);\n }\n &::after {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: ${({ theme }) => theme.colors.neutral800};\n transform: translate(-50%, -50%);\n }\n\n &:active {\n cursor: grabbing;\n }\n`;\n\n// Hidden on mobile — the panel (title/hint + numeric crop & focal inputs) is\n// too large for a phone; touch users set the crop by dragging the rectangle and\n// focal handle directly on the image. Shown from tablet up.\nconst InfoBox = styled(Box)`\n display: none;\n\n ${({ theme }) => theme.breakpoints.medium} {\n display: block;\n position: absolute;\n right: ${({ theme }) => theme.spaces[1]};\n bottom: ${({ theme }) => theme.spaces[1]};\n width: 100%;\n max-width: 32rem;\n padding: ${({ theme }) => theme.spaces[3]};\n border-radius: ${({ theme }) => theme.borderRadius};\n background: ${({ theme }) =>\n theme.colorScheme === 'dark' ? theme.colors.neutral150 : theme.colors.neutral900};\n z-index: 20;\n }\n`;\n\nconst FooterBar = styled(Flex)`\n width: 100%;\n justify-content: space-between;\n padding: ${({ theme }) => `${theme.spaces[3]} ${theme.spaces[5]}`};\n border-top: 1px solid ${({ theme }) => theme.colors.neutral150};\n background: ${({ theme }) => theme.colors.neutral0};\n`;\n\nconst FieldRow = styled(Field.Root)`\n flex-direction: row;\n align-items: center;\n`;\n\nconst FieldNumberInput = styled(NumberInput)`\n width: 8.4rem;\n`;\n\nconst LabelIcon = styled(Field.Label)`\n display: flex;\n align-items: center;\n justify-content: center;\n width: 1.6rem;\n height: 1.6rem;\n`;\n\nconst BackgroundPreserveRatioContainer = styled(Box)`\n position: absolute;\n top: 50%;\n left: 0;\n transform: translateY(-50%);\n\n svg {\n display: block;\n }\n`;\n\nconst BackgroundPreserveRatio = () => (\n <BackgroundPreserveRatioContainer>\n <svg width=\"17\" height=\"49\" viewBox=\"0 0 17 49\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M0.5 0.5H8.5C12.9183 0.5 16.5 4.08172 16.5 8.5M0.5 48.5H8.5C12.9183 48.5 16.5 44.9183 16.5 40.5\"\n stroke=\"#666687\"\n strokeLinecap=\"round\"\n />\n </svg>\n </BackgroundPreserveRatioContainer>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * AssetCropEditor\n * -----------------------------------------------------------------------------------------------*/\n\ninterface AssetCropEditorProps {\n asset: AssetWithPopulatedCreatedBy;\n isBusy?: boolean;\n onClose: () => void;\n onApply: (file: globalThis.File, focalPoint: FocalPoint) => void;\n onSaveAsCopy: (file: globalThis.File, focalPoint: FocalPoint) => void;\n /**\n * \"Save as copy\" creates a new asset (`assets.create`), a different permission\n * from cropping in place (`assets.update`). Hidden when the user lacks it, so\n * an update-only role can't trigger a 403.\n */\n canSaveAsCopy: boolean;\n}\n\ntype Corner = 'tl' | 'tr' | 'bl' | 'br';\n\nexport const AssetCropEditor = ({\n asset,\n isBusy = false,\n onClose,\n onApply,\n onSaveAsCopy,\n canSaveAsCopy,\n}: AssetCropEditorProps) => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n // The InfoBox is a fixed dark surface in both themes, so its text can't use a\n // single neutral token (those invert with the scheme). Pick the scheme's white\n // and a muted grey explicitly.\n const theme = useTheme();\n const isDark = theme.colorScheme === 'dark';\n const infoTextColor = isDark ? 'neutral1000' : 'neutral0';\n const infoMutedColor = isDark ? 'neutral600' : 'neutral200';\n const imgRef = React.useRef<HTMLImageElement>(null);\n const cropAreaRef = React.useRef<HTMLDivElement>(null);\n const overlayRef = React.useRef<HTMLDivElement>(null);\n\n // FocusTrap's auto-focus lands on the first focusable element — the crop\n // width NumberInput — which pops the keyboard on mobile the moment the\n // editor opens. Focus the (tabIndex -1) overlay instead: keyboard users are\n // one Tab away from the first control, Escape still reaches the trap.\n React.useEffect(() => {\n overlayRef.current?.focus();\n }, []);\n\n const {\n init,\n crop,\n naturalSize,\n aspectRatio,\n setCropSize,\n setCropPosition,\n setAspectRatio,\n produceFile,\n width,\n height,\n } = useCropImg();\n\n const [aspectLocked, setAspectLocked] = React.useState(false);\n // Focal point as a percentage of the crop area (matches the {x,y} contract).\n const [focal, setFocal] = React.useState<FocalPoint>(asset.focalPoint ?? { x: 50, y: 50 });\n\n // The crop editor reads pixels from a canvas (useCropImg -> toBlob), so its\n // <img> must be CORS-clean and always sets crossOrigin=\"anonymous\" (see the\n // img below) — even for unsigned URLs, which AssetPreview leaves unset because\n // it only displays. That difference is why the crop URL is kept DISTINCT from\n // the thumbnail's: identical URL + different crossOrigin collide in the HTTP\n // cache (#26581), and the crop's anonymous request could otherwise reuse the\n // thumbnail's non-CORS cached response and taint the canvas. So the buster\n // uses `updatedAt` where AssetPreview uses `v`, giving each its own entry\n // (mirrors the legacy PreviewBox fix).\n // Signed URLs get no param at all — a presigned S3 URL breaks if you add one,\n // and on the signed side AssetPreview also loads anonymous, so the identical\n // URL there shares one CORS-consistent entry, which is fine.\n const rawImageUrl = prefixFileUrlWithBackendUrl(asset.url) as string;\n const cacheKey =\n asset.updatedAt && !asset.isUrlSigned ? new Date(asset.updatedAt).getTime() : undefined;\n const imageUrl =\n cacheKey !== undefined\n ? `${rawImageUrl}${rawImageUrl.includes('?') ? '&' : '?'}updatedAt=${cacheKey}`\n : rawImageUrl;\n\n const handleImageLoad = () => {\n if (imgRef.current) {\n init(imgRef.current);\n }\n };\n\n // Map a pointer event to natural-px coordinates inside the image.\n const pointerToNatural = (event: PointerEvent | React.PointerEvent) => {\n const rect = cropAreaRef.current?.getBoundingClientRect();\n if (!rect || !naturalSize.width || !naturalSize.height) return null;\n const ratioX = naturalSize.width / rect.width;\n const ratioY = naturalSize.height / rect.height;\n return {\n x: (event.clientX - rect.left) * ratioX,\n y: (event.clientY - rect.top) * ratioY,\n };\n };\n\n // Teardown for the drag currently in flight, so it can be run both on pointer\n // release AND on unmount. Without the unmount path, closing the editor mid-drag\n // (Escape, drawer close, a re-render dropping the overlay) would never fire a\n // pointer event, leaking the window listeners and letting a stale `onMove`\n // call `setCropPosition` on an unmounted component.\n const activeDragCleanupRef = React.useRef<(() => void) | null>(null);\n\n React.useEffect(() => {\n return () => {\n activeDragCleanupRef.current?.();\n };\n }, []);\n\n // Track a pointer drag until the pointer is released or the browser cancels\n // it. The pointer is captured so the drag follows the finger even once it\n // leaves the (12px) handle it started on, and pointercancel is treated as\n // release so an interrupted touch never leaves stale window listeners.\n const trackPointerDrag = (event: React.PointerEvent, onMove: (e: PointerEvent) => void) => {\n event.preventDefault();\n event.stopPropagation();\n const { pointerId } = event;\n try {\n event.currentTarget.setPointerCapture(pointerId);\n } catch {\n // Unsupported environment (jsdom) — window listeners still track the drag.\n }\n const move = (e: PointerEvent) => {\n if (e.pointerId !== pointerId) return;\n onMove(e);\n };\n const cleanup = () => {\n window.removeEventListener('pointermove', move);\n window.removeEventListener('pointerup', end);\n window.removeEventListener('pointercancel', end);\n activeDragCleanupRef.current = null;\n };\n const end = (e: PointerEvent) => {\n if (e.pointerId !== pointerId) return;\n cleanup();\n };\n // Only one drag is ever live at a time; tear down any previous one first.\n activeDragCleanupRef.current?.();\n activeDragCleanupRef.current = cleanup;\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', end);\n window.addEventListener('pointercancel', end);\n };\n\n // Drag the entire crop rectangle.\n const handleMovePointerDown = (event: React.PointerEvent) => {\n const start = pointerToNatural(event);\n if (!start) return;\n const startCrop = { ...crop };\n trackPointerDrag(event, (e) => {\n const next = pointerToNatural(e);\n if (!next) return;\n setCropPosition({\n x: startCrop.x + (next.x - start.x),\n y: startCrop.y + (next.y - start.y),\n });\n });\n };\n\n // Resize from a corner; the opposite corner stays anchored.\n const handleResizePointerDown = (corner: Corner) => (event: React.PointerEvent) => {\n const startCrop = { ...crop };\n const anchorX =\n corner === 'tl' || corner === 'bl' ? startCrop.x + startCrop.width : startCrop.x;\n const anchorY =\n corner === 'tl' || corner === 'tr' ? startCrop.y + startCrop.height : startCrop.y;\n trackPointerDrag(event, (e) => {\n const point = pointerToNatural(e);\n if (!point) return;\n const {\n x,\n y,\n width: w,\n height: h,\n } = resolveCornerResize({\n anchorX,\n anchorY,\n point,\n aspectRatio: aspectLocked ? aspectRatio : null,\n });\n setCropPosition({ x, y });\n setCropSize({ width: w, height: h });\n });\n };\n\n const toggleAspectLock = () => {\n setAspectLocked((locked) => {\n const next = !locked;\n setAspectRatio(next && height ? width / height : null);\n return next;\n });\n };\n\n // Drag the focal handle within the crop rectangle, clamped 0–100.\n const handleFocalPointerDown = (event: React.PointerEvent) => {\n trackPointerDrag(event, (e) => {\n const point = pointerToNatural(e);\n if (!point) return;\n // Convert pointer to a percentage of the current crop area.\n const px = ((point.x - crop.x) / crop.width) * 100;\n const py = ((point.y - crop.y) / crop.height) * 100;\n setFocal({\n x: Math.round(Math.min(100, Math.max(0, px))),\n y: Math.round(Math.min(100, Math.max(0, py))),\n });\n });\n };\n\n const focalPxX = Math.round((focal.x / 100) * width);\n const focalPxY = Math.round((focal.y / 100) * height);\n\n const setFocalPx = (axis: 'x' | 'y', value: number) => {\n const dim = axis === 'x' ? width : height;\n if (!dim) return;\n const pct = Math.min(100, Math.max(0, (value / dim) * 100));\n setFocal((prev) => ({ ...prev, [axis]: Math.round(pct) }));\n };\n\n const cropPercents =\n naturalSize.width && naturalSize.height\n ? {\n left: (crop.x / naturalSize.width) * 100,\n top: (crop.y / naturalSize.height) * 100,\n width: (crop.width / naturalSize.width) * 100,\n height: (crop.height / naturalSize.height) * 100,\n }\n : null;\n\n // The crop is only usable once the image has loaded and `init()` has seeded\n // the natural size. Until then the produce/export path would reject.\n const isReady = cropPercents !== null;\n\n const handleAction = async (action: 'apply' | 'copy') => {\n if (!isReady) return;\n\n let file: globalThis.File;\n try {\n file = await produceFile(asset.name, asset.mime ?? 'image/png', asset.updatedAt);\n } catch {\n toggleNotification({\n type: 'danger',\n message: formatMessage({\n id: getTranslationKey('asset-details.crop.export-error'),\n defaultMessage: 'Could not process the cropped image.',\n }),\n });\n return;\n }\n\n const roundedFocal = { x: Math.round(focal.x), y: Math.round(focal.y) };\n if (action === 'apply') {\n onApply(file, roundedFocal);\n } else {\n onSaveAsCopy(file, roundedFocal);\n }\n };\n\n return (\n <Portal>\n <FocusTrap onEscape={onClose} skipAutoFocus>\n <Overlay ref={overlayRef} tabIndex={-1}>\n <HeaderBar alignItems=\"center\">\n <Crop aria-hidden />\n <Typography variant=\"omega\" fontWeight=\"bold\">\n {formatMessage({\n id: getTranslationKey('asset-details.crop.title'),\n defaultMessage: 'Crop & Focus area',\n })}\n </Typography>\n </HeaderBar>\n\n <Body>\n <CropArea\n ref={cropAreaRef}\n $aspect={\n naturalSize.width && naturalSize.height\n ? naturalSize.width / naturalSize.height\n : undefined\n }\n >\n <img\n ref={imgRef}\n src={imageUrl}\n alt={asset.name}\n // Always anonymous, unlike AssetPreview/AssetsGrid which gate it:\n // the editor reads pixels via canvas (useCropImg -> toBlob), which\n // taints on a cross-origin image loaded without CORS, so every\n // remote image must be fetched CORS-clean.\n crossOrigin=\"anonymous\"\n onLoad={handleImageLoad}\n draggable={false}\n />\n\n {cropPercents ? (\n <CropOverlay\n style={{\n left: `${cropPercents.left}%`,\n top: `${cropPercents.top}%`,\n width: `${cropPercents.width}%`,\n height: `${cropPercents.height}%`,\n }}\n onPointerDown={handleMovePointerDown}\n >\n <ResizeHandle\n type=\"button\"\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.resize.top-left'),\n defaultMessage: 'Resize top-left',\n })}\n $cursor=\"nwse-resize\"\n style={{ left: 0, top: 0 }}\n onPointerDown={handleResizePointerDown('tl')}\n />\n <ResizeHandle\n type=\"button\"\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.resize.top-right'),\n defaultMessage: 'Resize top-right',\n })}\n $cursor=\"nesw-resize\"\n style={{ right: 0, top: 0 }}\n onPointerDown={handleResizePointerDown('tr')}\n />\n <ResizeHandle\n type=\"button\"\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.resize.bottom-left'),\n defaultMessage: 'Resize bottom-left',\n })}\n $cursor=\"nesw-resize\"\n style={{ left: 0, bottom: 0 }}\n onPointerDown={handleResizePointerDown('bl')}\n />\n <ResizeHandle\n type=\"button\"\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.resize.bottom-right'),\n defaultMessage: 'Resize bottom-right',\n })}\n $cursor=\"nwse-resize\"\n style={{ right: 0, bottom: 0 }}\n onPointerDown={handleResizePointerDown('br')}\n />\n\n <FocalPointHandle\n type=\"button\"\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.focal-point'),\n defaultMessage: 'Focal point',\n })}\n style={{ left: `${focal.x}%`, top: `${focal.y}%` }}\n onPointerDown={handleFocalPointerDown}\n />\n </CropOverlay>\n ) : null}\n </CropArea>\n\n <InfoBox>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={1} paddingBottom={3}>\n <Typography variant=\"omega\" fontWeight=\"bold\" textColor={infoTextColor}>\n {formatMessage({\n id: getTranslationKey('asset-details.crop.title'),\n defaultMessage: 'Crop & Focus area',\n })}\n </Typography>\n <Typography variant=\"pi\" textColor={infoMutedColor}>\n {formatMessage({\n id: getTranslationKey('asset-details.crop.hint'),\n defaultMessage:\n 'Set the crop area with the rectangle. Pin the always-visible area with the circle.',\n })}\n </Typography>\n </Flex>\n\n <Flex gap={6} alignItems=\"center\">\n <Flex alignItems=\"center\" gap={2}>\n <Flex direction=\"column\" gap={2}>\n <FieldRow name=\"crop-width\" gap={2}>\n <LabelIcon textColor={infoTextColor}>\n <ArrowsHorizontal />\n </LabelIcon>\n <FieldNumberInput\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.width'),\n defaultMessage: 'Width (px)',\n })}\n value={width}\n min={1}\n max={naturalSize.width || undefined}\n onValueChange={(next) => {\n if (next !== undefined) setCropSize({ width: next });\n }}\n />\n </FieldRow>\n <FieldRow name=\"crop-height\" gap={2}>\n <LabelIcon textColor={infoTextColor}>\n <ArrowsVertical />\n </LabelIcon>\n <FieldNumberInput\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.height'),\n defaultMessage: 'Height (px)',\n })}\n value={height}\n min={1}\n max={naturalSize.height || undefined}\n onValueChange={(next) => {\n if (next !== undefined) setCropSize({ height: next });\n }}\n />\n </FieldRow>\n </Flex>\n\n <Flex position=\"relative\">\n <IconButton\n label={formatMessage({\n id: getTranslationKey('asset-details.crop.aspect-lock'),\n defaultMessage: 'Lock aspect ratio',\n })}\n variant={aspectLocked ? 'secondary' : 'ghost'}\n onClick={toggleAspectLock}\n >\n <Link />\n </IconButton>\n <BackgroundPreserveRatio />\n </Flex>\n </Flex>\n\n <Flex direction=\"column\" gap={2} marginLeft={'auto'}>\n <FieldRow name=\"focal-x\" gap={2}>\n <Field.Label textColor={infoTextColor}>\n {formatMessage({\n id: getTranslationKey('asset-details.crop.focal-x-axis'),\n defaultMessage: 'X',\n })}\n </Field.Label>\n <FieldNumberInput\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.focal-x'),\n defaultMessage: 'Focal point X (px)',\n })}\n value={focalPxX}\n onValueChange={(next) => {\n if (next !== undefined) setFocalPx('x', next);\n }}\n />\n </FieldRow>\n <FieldRow name=\"focal-y\" gap={2}>\n <Field.Label textColor={infoTextColor}>\n {formatMessage({\n id: getTranslationKey('asset-details.crop.focal-y-axis'),\n defaultMessage: 'Y',\n })}\n </Field.Label>\n <FieldNumberInput\n aria-label={formatMessage({\n id: getTranslationKey('asset-details.crop.focal-y'),\n defaultMessage: 'Focal point Y (px)',\n })}\n value={focalPxY}\n onValueChange={(next) => {\n if (next !== undefined) setFocalPx('y', next);\n }}\n />\n </FieldRow>\n </Flex>\n </Flex>\n </InfoBox>\n </Body>\n\n <FooterBar alignItems=\"center\">\n <Button variant=\"tertiary\" onClick={onClose} disabled={isBusy}>\n {formatMessage({ id: 'app.components.Button.cancel', defaultMessage: 'Cancel' })}\n </Button>\n <Flex gap={2}>\n {canSaveAsCopy && (\n <Button\n variant=\"secondary\"\n onClick={() => handleAction('copy')}\n loading={isBusy}\n disabled={!isReady}\n >\n {formatMessage({\n id: getTranslationKey('asset-details.crop.save-as-copy'),\n defaultMessage: 'Save as copy',\n })}\n </Button>\n )}\n <Button\n variant=\"default\"\n onClick={() => handleAction('apply')}\n loading={isBusy}\n disabled={!isReady}\n >\n {formatMessage({\n id: getTranslationKey('asset-details.crop.apply'),\n defaultMessage: 'Apply',\n })}\n </Button>\n </Flex>\n </FooterBar>\n </Overlay>\n </FocusTrap>\n </Portal>\n );\n};\n"],"names":["FOCAL_DIAMETER_REM","HANDLE_PX","Overlay","styled","Flex","theme","spaces","borderRadius","colors","neutral150","neutral0","HeaderBar","Body","Box","neutral100","CropArea","div","$aspect","CropOverlay","primary600","ResizeHandle","button","$cursor","FocalPointHandle","neutral800","InfoBox","breakpoints","medium","colorScheme","neutral900","FooterBar","FieldRow","Field","Root","FieldNumberInput","NumberInput","LabelIcon","Label","BackgroundPreserveRatioContainer","BackgroundPreserveRatio","_jsx","svg","width","height","viewBox","fill","xmlns","path","d","stroke","strokeLinecap","AssetCropEditor","asset","isBusy","onClose","onApply","onSaveAsCopy","canSaveAsCopy","formatMessage","useIntl","toggleNotification","useNotification","useTheme","isDark","infoTextColor","infoMutedColor","imgRef","React","useRef","cropAreaRef","overlayRef","useEffect","current","focus","init","crop","naturalSize","aspectRatio","setCropSize","setCropPosition","setAspectRatio","produceFile","useCropImg","aspectLocked","setAspectLocked","useState","focal","setFocal","focalPoint","x","y","rawImageUrl","prefixFileUrlWithBackendUrl","url","cacheKey","updatedAt","isUrlSigned","Date","getTime","undefined","imageUrl","includes","handleImageLoad","pointerToNatural","event","rect","getBoundingClientRect","ratioX","ratioY","clientX","left","clientY","top","activeDragCleanupRef","trackPointerDrag","onMove","preventDefault","stopPropagation","pointerId","currentTarget","setPointerCapture","move","e","cleanup","window","removeEventListener","end","addEventListener","handleMovePointerDown","start","startCrop","next","handleResizePointerDown","corner","anchorX","anchorY","point","w","h","resolveCornerResize","toggleAspectLock","locked","handleFocalPointerDown","px","py","Math","round","min","max","focalPxX","focalPxY","setFocalPx","axis","value","dim","pct","prev","cropPercents","isReady","handleAction","action","file","name","mime","type","message","id","getTranslationKey","defaultMessage","roundedFocal","Portal","FocusTrap","onEscape","skipAutoFocus","_jsxs","ref","tabIndex","alignItems","Crop","aria-hidden","Typography","variant","fontWeight","img","src","alt","crossOrigin","onLoad","draggable","style","onPointerDown","aria-label","right","bottom","direction","gap","paddingBottom","textColor","ArrowsHorizontal","onValueChange","ArrowsVertical","position","IconButton","label","onClick","Link","marginLeft","Button","disabled","loading"],"mappings":"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"}