@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
@@ -25,6 +25,8 @@ const Overlay = styled(Flex)`
25
25
  border-radius: ${({ theme })=>theme.borderRadius};
26
26
  border: 1px solid ${({ theme })=>theme.colors.neutral150};
27
27
  background: ${({ theme })=>theme.colors.neutral0};
28
+ /* Focused programmatically on open (tabIndex -1) — no visible ring needed. */
29
+ outline: none;
28
30
  `;
29
31
  const HeaderBar = styled(Flex)`
30
32
  width: 100%;
@@ -34,6 +36,9 @@ const HeaderBar = styled(Flex)`
34
36
  background: ${({ theme })=>theme.colors.neutral0};
35
37
  `;
36
38
  // Fills the remaining space between header/footer; checkerboard pattern.
39
+ // The horizontal padding keeps the image off the viewport edges — the corner
40
+ // handles overhang the image by half their size, and on narrow (mobile)
41
+ // screens an edge-to-edge image leaves nothing to grab.
37
42
  const Body = styled(Box)`
38
43
  width: 100%;
39
44
  position: relative;
@@ -43,6 +48,7 @@ const Body = styled(Box)`
43
48
  align-items: center;
44
49
  justify-content: center;
45
50
  overflow: hidden;
51
+ padding: 0 ${({ theme })=>theme.spaces[4]};
46
52
  background: repeating-conic-gradient(
47
53
  ${({ theme })=>theme.colors.neutral100} 0% 25%,
48
54
  ${({ theme })=>theme.colors.neutral0} 0% 50%
@@ -73,6 +79,9 @@ const CropOverlay = styled.div`
73
79
  border: 1px dashed ${({ theme })=>theme.colors.primary600};
74
80
  box-shadow: 0 0 0 9999px rgba(33, 33, 52, 0.5);
75
81
  cursor: move;
82
+ /* Without this, touch browsers claim the gesture for scrolling and fire
83
+ pointercancel mid-drag — the crop drag dies while the finger is down. */
84
+ touch-action: none;
76
85
  `;
77
86
  const ResizeHandle = styled.button`
78
87
  position: absolute;
@@ -84,6 +93,7 @@ const ResizeHandle = styled.button`
84
93
  border-radius: 2px;
85
94
  background: ${({ theme })=>theme.colors.neutral0};
86
95
  cursor: ${({ $cursor })=>$cursor};
96
+ touch-action: none;
87
97
  `;
88
98
  const FocalPointHandle = styled.button`
89
99
  position: absolute;
@@ -95,6 +105,7 @@ const FocalPointHandle = styled.button`
95
105
  background: transparent;
96
106
  cursor: grab;
97
107
  padding: 0;
108
+ touch-action: none;
98
109
 
99
110
  &::before {
100
111
  content: '';
@@ -123,16 +134,24 @@ const FocalPointHandle = styled.button`
123
134
  cursor: grabbing;
124
135
  }
125
136
  `;
137
+ // Hidden on mobile — the panel (title/hint + numeric crop & focal inputs) is
138
+ // too large for a phone; touch users set the crop by dragging the rectangle and
139
+ // focal handle directly on the image. Shown from tablet up.
126
140
  const InfoBox = styled(Box)`
127
- position: absolute;
128
- right: ${({ theme })=>theme.spaces[1]};
129
- bottom: ${({ theme })=>theme.spaces[1]};
130
- width: 100%;
131
- max-width: 32rem;
132
- padding: ${({ theme })=>theme.spaces[3]};
133
- border-radius: ${({ theme })=>theme.borderRadius};
134
- background: ${({ theme })=>theme.colorScheme === 'dark' ? theme.colors.neutral150 : theme.colors.neutral900};
135
- z-index: 20;
141
+ display: none;
142
+
143
+ ${({ theme })=>theme.breakpoints.medium} {
144
+ display: block;
145
+ position: absolute;
146
+ right: ${({ theme })=>theme.spaces[1]};
147
+ bottom: ${({ theme })=>theme.spaces[1]};
148
+ width: 100%;
149
+ max-width: 32rem;
150
+ padding: ${({ theme })=>theme.spaces[3]};
151
+ border-radius: ${({ theme })=>theme.borderRadius};
152
+ background: ${({ theme })=>theme.colorScheme === 'dark' ? theme.colors.neutral150 : theme.colors.neutral900};
153
+ z-index: 20;
154
+ }
136
155
  `;
137
156
  const FooterBar = styled(Flex)`
138
157
  width: 100%;
@@ -179,7 +198,7 @@ const BackgroundPreserveRatio = ()=>/*#__PURE__*/ jsx(BackgroundPreserveRatioCon
179
198
  })
180
199
  })
181
200
  });
182
- const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy })=>{
201
+ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy, canSaveAsCopy })=>{
183
202
  const { formatMessage } = useIntl();
184
203
  const { toggleNotification } = useNotification();
185
204
  // The InfoBox is a fixed dark surface in both themes, so its text can't use a
@@ -191,6 +210,14 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
191
210
  const infoMutedColor = isDark ? 'neutral600' : 'neutral200';
192
211
  const imgRef = React.useRef(null);
193
212
  const cropAreaRef = React.useRef(null);
213
+ const overlayRef = React.useRef(null);
214
+ // FocusTrap's auto-focus lands on the first focusable element — the crop
215
+ // width NumberInput — which pops the keyboard on mobile the moment the
216
+ // editor opens. Focus the (tabIndex -1) overlay instead: keyboard users are
217
+ // one Tab away from the first control, Escape still reaches the trap.
218
+ React.useEffect(()=>{
219
+ overlayRef.current?.focus();
220
+ }, []);
194
221
  const { init, crop, naturalSize, aspectRatio, setCropSize, setCropPosition, setAspectRatio, produceFile, width, height } = useCropImg();
195
222
  const [aspectLocked, setAspectLocked] = React.useState(false);
196
223
  // Focal point as a percentage of the crop area (matches the {x,y} contract).
@@ -198,12 +225,21 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
198
225
  x: 50,
199
226
  y: 50
200
227
  });
201
- // Append `updatedAt` as a cache-buster: a replaced asset is served at the same
202
- // URL, so without this, reopening the editor shows the browser-cached old image
203
- // (mirrors AssetPreview).
228
+ // The crop editor reads pixels from a canvas (useCropImg -> toBlob), so its
229
+ // <img> must be CORS-clean and always sets crossOrigin="anonymous" (see the
230
+ // img below) — even for unsigned URLs, which AssetPreview leaves unset because
231
+ // it only displays. That difference is why the crop URL is kept DISTINCT from
232
+ // the thumbnail's: identical URL + different crossOrigin collide in the HTTP
233
+ // cache (#26581), and the crop's anonymous request could otherwise reuse the
234
+ // thumbnail's non-CORS cached response and taint the canvas. So the buster
235
+ // uses `updatedAt` where AssetPreview uses `v`, giving each its own entry
236
+ // (mirrors the legacy PreviewBox fix).
237
+ // Signed URLs get no param at all — a presigned S3 URL breaks if you add one,
238
+ // and on the signed side AssetPreview also loads anonymous, so the identical
239
+ // URL there shares one CORS-consistent entry, which is fine.
204
240
  const rawImageUrl = prefixFileUrlWithBackendUrl(asset.url);
205
- const cacheKey = asset.updatedAt ? new Date(asset.updatedAt).getTime() : undefined;
206
- const imageUrl = cacheKey !== undefined ? `${rawImageUrl}${rawImageUrl.includes('?') ? '&' : '?'}v=${cacheKey}` : rawImageUrl;
241
+ const cacheKey = asset.updatedAt && !asset.isUrlSigned ? new Date(asset.updatedAt).getTime() : undefined;
242
+ const imageUrl = cacheKey !== undefined ? `${rawImageUrl}${rawImageUrl.includes('?') ? '&' : '?'}updatedAt=${cacheKey}` : rawImageUrl;
207
243
  const handleImageLoad = ()=>{
208
244
  if (imgRef.current) {
209
245
  init(imgRef.current);
@@ -220,40 +256,75 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
220
256
  y: (event.clientY - rect.top) * ratioY
221
257
  };
222
258
  };
223
- // Drag the entire crop rectangle.
224
- const handleMovePointerDown = (event)=>{
259
+ // Teardown for the drag currently in flight, so it can be run both on pointer
260
+ // release AND on unmount. Without the unmount path, closing the editor mid-drag
261
+ // (Escape, drawer close, a re-render dropping the overlay) would never fire a
262
+ // pointer event, leaking the window listeners and letting a stale `onMove`
263
+ // call `setCropPosition` on an unmounted component.
264
+ const activeDragCleanupRef = React.useRef(null);
265
+ React.useEffect(()=>{
266
+ return ()=>{
267
+ activeDragCleanupRef.current?.();
268
+ };
269
+ }, []);
270
+ // Track a pointer drag until the pointer is released or the browser cancels
271
+ // it. The pointer is captured so the drag follows the finger even once it
272
+ // leaves the (12px) handle it started on, and pointercancel is treated as
273
+ // release so an interrupted touch never leaves stale window listeners.
274
+ const trackPointerDrag = (event, onMove)=>{
225
275
  event.preventDefault();
226
276
  event.stopPropagation();
277
+ const { pointerId } = event;
278
+ try {
279
+ event.currentTarget.setPointerCapture(pointerId);
280
+ } catch {
281
+ // Unsupported environment (jsdom) — window listeners still track the drag.
282
+ }
283
+ const move = (e)=>{
284
+ if (e.pointerId !== pointerId) return;
285
+ onMove(e);
286
+ };
287
+ const cleanup = ()=>{
288
+ window.removeEventListener('pointermove', move);
289
+ window.removeEventListener('pointerup', end);
290
+ window.removeEventListener('pointercancel', end);
291
+ activeDragCleanupRef.current = null;
292
+ };
293
+ const end = (e)=>{
294
+ if (e.pointerId !== pointerId) return;
295
+ cleanup();
296
+ };
297
+ // Only one drag is ever live at a time; tear down any previous one first.
298
+ activeDragCleanupRef.current?.();
299
+ activeDragCleanupRef.current = cleanup;
300
+ window.addEventListener('pointermove', move);
301
+ window.addEventListener('pointerup', end);
302
+ window.addEventListener('pointercancel', end);
303
+ };
304
+ // Drag the entire crop rectangle.
305
+ const handleMovePointerDown = (event)=>{
227
306
  const start = pointerToNatural(event);
228
307
  if (!start) return;
229
308
  const startCrop = {
230
309
  ...crop
231
310
  };
232
- const move = (e)=>{
311
+ trackPointerDrag(event, (e)=>{
233
312
  const next = pointerToNatural(e);
234
313
  if (!next) return;
235
314
  setCropPosition({
236
315
  x: startCrop.x + (next.x - start.x),
237
316
  y: startCrop.y + (next.y - start.y)
238
317
  });
239
- };
240
- const up = ()=>{
241
- window.removeEventListener('pointermove', move);
242
- window.removeEventListener('pointerup', up);
243
- };
244
- window.addEventListener('pointermove', move);
245
- window.addEventListener('pointerup', up);
318
+ });
246
319
  };
247
320
  // Resize from a corner; the opposite corner stays anchored.
248
321
  const handleResizePointerDown = (corner)=>(event)=>{
249
- event.preventDefault();
250
- event.stopPropagation();
251
322
  const startCrop = {
252
323
  ...crop
253
324
  };
254
325
  const anchorX = corner === 'tl' || corner === 'bl' ? startCrop.x + startCrop.width : startCrop.x;
255
326
  const anchorY = corner === 'tl' || corner === 'tr' ? startCrop.y + startCrop.height : startCrop.y;
256
- const move = (e)=>{
327
+ trackPointerDrag(event, (e)=>{
257
328
  const point = pointerToNatural(e);
258
329
  if (!point) return;
259
330
  const { x, y, width: w, height: h } = resolveCornerResize({
@@ -270,13 +341,7 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
270
341
  width: w,
271
342
  height: h
272
343
  });
273
- };
274
- const up = ()=>{
275
- window.removeEventListener('pointermove', move);
276
- window.removeEventListener('pointerup', up);
277
- };
278
- window.addEventListener('pointermove', move);
279
- window.addEventListener('pointerup', up);
344
+ });
280
345
  };
281
346
  const toggleAspectLock = ()=>{
282
347
  setAspectLocked((locked)=>{
@@ -287,9 +352,7 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
287
352
  };
288
353
  // Drag the focal handle within the crop rectangle, clamped 0–100.
289
354
  const handleFocalPointerDown = (event)=>{
290
- event.preventDefault();
291
- event.stopPropagation();
292
- const move = (e)=>{
355
+ trackPointerDrag(event, (e)=>{
293
356
  const point = pointerToNatural(e);
294
357
  if (!point) return;
295
358
  // Convert pointer to a percentage of the current crop area.
@@ -299,13 +362,7 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
299
362
  x: Math.round(Math.min(100, Math.max(0, px))),
300
363
  y: Math.round(Math.min(100, Math.max(0, py)))
301
364
  });
302
- };
303
- const up = ()=>{
304
- window.removeEventListener('pointermove', move);
305
- window.removeEventListener('pointerup', up);
306
- };
307
- window.addEventListener('pointermove', move);
308
- window.addEventListener('pointerup', up);
365
+ });
309
366
  };
310
367
  const focalPxX = Math.round(focal.x / 100 * width);
311
368
  const focalPxY = Math.round(focal.y / 100 * height);
@@ -355,7 +412,10 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
355
412
  return /*#__PURE__*/ jsx(Portal, {
356
413
  children: /*#__PURE__*/ jsx(FocusTrap, {
357
414
  onEscape: onClose,
415
+ skipAutoFocus: true,
358
416
  children: /*#__PURE__*/ jsxs(Overlay, {
417
+ ref: overlayRef,
418
+ tabIndex: -1,
359
419
  children: [
360
420
  /*#__PURE__*/ jsxs(HeaderBar, {
361
421
  alignItems: "center",
@@ -383,6 +443,10 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
383
443
  ref: imgRef,
384
444
  src: imageUrl,
385
445
  alt: asset.name,
446
+ // Always anonymous, unlike AssetPreview/AssetsGrid which gate it:
447
+ // the editor reads pixels via canvas (useCropImg -> toBlob), which
448
+ // taints on a cross-origin image loaded without CORS, so every
449
+ // remote image must be fetched CORS-clean.
386
450
  crossOrigin: "anonymous",
387
451
  onLoad: handleImageLoad,
388
452
  draggable: false
@@ -644,7 +708,7 @@ const AssetCropEditor = ({ asset, isBusy = false, onClose, onApply, onSaveAsCopy
644
708
  /*#__PURE__*/ jsxs(Flex, {
645
709
  gap: 2,
646
710
  children: [
647
- /*#__PURE__*/ jsx(Button, {
711
+ canSaveAsCopy && /*#__PURE__*/ jsx(Button, {
648
712
  variant: "secondary",
649
713
  onClick: ()=>handleAction('copy'),
650
714
  loading: isBusy,
@@ -1 +1 @@
1
- {"version":3,"file":"AssetCropEditor.mjs","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":"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"}
1
+ {"version":3,"file":"AssetCropEditor.mjs","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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"}