@acorex/components 22.1.0-next.31 → 22.1.0-next.32

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 (262) hide show
  1. package/emoji/README.md +3 -0
  2. package/emojipicker/README.md +3 -0
  3. package/fesm2022/acorex-components-accordion.mjs +13 -13
  4. package/fesm2022/acorex-components-accordion.mjs.map +1 -1
  5. package/fesm2022/acorex-components-action-sheet.mjs +13 -13
  6. package/fesm2022/acorex-components-alert.mjs +7 -7
  7. package/fesm2022/acorex-components-aspect-ratio.mjs +3 -3
  8. package/fesm2022/acorex-components-audio-wave.mjs +295 -271
  9. package/fesm2022/acorex-components-audio-wave.mjs.map +1 -1
  10. package/fesm2022/acorex-components-autocomplete.mjs +7 -7
  11. package/fesm2022/acorex-components-avatar.mjs +10 -10
  12. package/fesm2022/acorex-components-badge.mjs +7 -7
  13. package/fesm2022/acorex-components-bottom-navigation.mjs +10 -10
  14. package/fesm2022/acorex-components-breadcrumbs.mjs +10 -10
  15. package/fesm2022/acorex-components-bubble.mjs +71 -0
  16. package/fesm2022/acorex-components-bubble.mjs.map +1 -0
  17. package/fesm2022/acorex-components-button-group.mjs +22 -15
  18. package/fesm2022/acorex-components-button-group.mjs.map +1 -1
  19. package/fesm2022/acorex-components-button.mjs +14 -14
  20. package/fesm2022/acorex-components-button.mjs.map +1 -1
  21. package/fesm2022/acorex-components-calendar.mjs +332 -130
  22. package/fesm2022/acorex-components-calendar.mjs.map +1 -1
  23. package/fesm2022/acorex-components-check-box.mjs +7 -7
  24. package/fesm2022/acorex-components-chips.mjs +7 -7
  25. package/fesm2022/acorex-components-circular-progress.mjs +7 -7
  26. package/fesm2022/acorex-components-code-editor.mjs +44 -19
  27. package/fesm2022/acorex-components-code-editor.mjs.map +1 -1
  28. package/fesm2022/acorex-components-color-box.mjs +7 -7
  29. package/fesm2022/acorex-components-color-palette.mjs +28 -28
  30. package/fesm2022/acorex-components-combo-box.mjs +244 -54
  31. package/fesm2022/acorex-components-combo-box.mjs.map +1 -1
  32. package/fesm2022/acorex-components-command.mjs +7 -7
  33. package/fesm2022/acorex-components-comment.mjs +28 -28
  34. package/fesm2022/acorex-components-conversation-acorex-components-conversation-BBWe3tfe.mjs +19099 -0
  35. package/fesm2022/acorex-components-conversation-acorex-components-conversation-BBWe3tfe.mjs.map +1 -0
  36. package/fesm2022/acorex-components-conversation-composer-action-choice-dialog.component-F5fLD_SK.mjs +50 -0
  37. package/fesm2022/acorex-components-conversation-composer-action-choice-dialog.component-F5fLD_SK.mjs.map +1 -0
  38. package/fesm2022/acorex-components-conversation-image-picker-editor-dialog.component-Bk3ixvt2.mjs +87 -0
  39. package/fesm2022/acorex-components-conversation-image-picker-editor-dialog.component-Bk3ixvt2.mjs.map +1 -0
  40. package/fesm2022/acorex-components-conversation-picker-rename-file-dialog.component-OAHRGH_G.mjs +65 -0
  41. package/fesm2022/acorex-components-conversation-picker-rename-file-dialog.component-OAHRGH_G.mjs.map +1 -0
  42. package/fesm2022/acorex-components-conversation.mjs +1 -15470
  43. package/fesm2022/acorex-components-conversation.mjs.map +1 -1
  44. package/fesm2022/acorex-components-cron-job.mjs +47 -47
  45. package/fesm2022/acorex-components-cron-job.mjs.map +1 -1
  46. package/fesm2022/acorex-components-data-list.mjs +3 -3
  47. package/fesm2022/acorex-components-data-pager.mjs +35 -35
  48. package/fesm2022/acorex-components-data-pager.mjs.map +1 -1
  49. package/fesm2022/acorex-components-data-table.mjs +734 -165
  50. package/fesm2022/acorex-components-data-table.mjs.map +1 -1
  51. package/fesm2022/acorex-components-datetime-box.mjs +7 -7
  52. package/fesm2022/acorex-components-datetime-input.mjs +7 -7
  53. package/fesm2022/acorex-components-datetime-picker.mjs +8 -8
  54. package/fesm2022/acorex-components-datetime-picker.mjs.map +1 -1
  55. package/fesm2022/acorex-components-decorators.mjs +60 -30
  56. package/fesm2022/acorex-components-decorators.mjs.map +1 -1
  57. package/fesm2022/acorex-components-dialog.mjs +11 -11
  58. package/fesm2022/acorex-components-dialog.mjs.map +1 -1
  59. package/fesm2022/acorex-components-drawer.mjs +10 -10
  60. package/fesm2022/acorex-components-dropdown-button.mjs +8 -8
  61. package/fesm2022/acorex-components-dropdown-button.mjs.map +1 -1
  62. package/fesm2022/acorex-components-dropdown.mjs +14 -14
  63. package/fesm2022/acorex-components-dropdown.mjs.map +1 -1
  64. package/fesm2022/acorex-components-editor.mjs +15 -14
  65. package/fesm2022/acorex-components-editor.mjs.map +1 -1
  66. package/fesm2022/acorex-components-emoji.mjs +74 -0
  67. package/fesm2022/acorex-components-emoji.mjs.map +1 -0
  68. package/fesm2022/acorex-components-emojipicker.mjs +425 -0
  69. package/fesm2022/acorex-components-emojipicker.mjs.map +1 -0
  70. package/fesm2022/acorex-components-fab.mjs +6 -6
  71. package/fesm2022/acorex-components-fab.mjs.map +1 -1
  72. package/fesm2022/acorex-components-file-viewer.mjs +372 -122
  73. package/fesm2022/acorex-components-file-viewer.mjs.map +1 -1
  74. package/fesm2022/acorex-components-form.mjs +17 -17
  75. package/fesm2022/acorex-components-form.mjs.map +1 -1
  76. package/fesm2022/acorex-components-grid-layout-builder.mjs +10 -10
  77. package/fesm2022/acorex-components-highlight.mjs +80 -0
  78. package/fesm2022/acorex-components-highlight.mjs.map +1 -0
  79. package/fesm2022/acorex-components-image-editor.mjs +780 -451
  80. package/fesm2022/acorex-components-image-editor.mjs.map +1 -1
  81. package/fesm2022/acorex-components-image.mjs +7 -7
  82. package/fesm2022/acorex-components-inline-reaction.mjs +111 -0
  83. package/fesm2022/acorex-components-inline-reaction.mjs.map +1 -0
  84. package/fesm2022/acorex-components-json-viewer.mjs +7 -7
  85. package/fesm2022/acorex-components-kanban.mjs +3 -3
  86. package/fesm2022/acorex-components-kanban.mjs.map +1 -1
  87. package/fesm2022/acorex-components-kbd.mjs +6 -6
  88. package/fesm2022/acorex-components-label.mjs +7 -7
  89. package/fesm2022/acorex-components-list.mjs +28 -9
  90. package/fesm2022/acorex-components-list.mjs.map +1 -1
  91. package/fesm2022/acorex-components-loading-dialog.mjs +10 -10
  92. package/fesm2022/acorex-components-loading-dialog.mjs.map +1 -1
  93. package/fesm2022/acorex-components-loading.mjs +16 -16
  94. package/fesm2022/acorex-components-lookup.mjs +764 -156
  95. package/fesm2022/acorex-components-lookup.mjs.map +1 -1
  96. package/fesm2022/acorex-components-map.mjs +20 -13
  97. package/fesm2022/acorex-components-map.mjs.map +1 -1
  98. package/fesm2022/acorex-components-media-viewer.mjs +215 -218
  99. package/fesm2022/acorex-components-media-viewer.mjs.map +1 -1
  100. package/fesm2022/acorex-components-menu.mjs +146 -45
  101. package/fesm2022/acorex-components-menu.mjs.map +1 -1
  102. package/fesm2022/acorex-components-message-status.mjs +71 -0
  103. package/fesm2022/acorex-components-message-status.mjs.map +1 -0
  104. package/fesm2022/acorex-components-message-time.mjs +36 -0
  105. package/fesm2022/acorex-components-message-time.mjs.map +1 -0
  106. package/fesm2022/acorex-components-message.mjs +120 -0
  107. package/fesm2022/acorex-components-message.mjs.map +1 -0
  108. package/fesm2022/acorex-components-navbar.mjs +7 -7
  109. package/fesm2022/acorex-components-notification.mjs +11 -11
  110. package/fesm2022/acorex-components-notification.mjs.map +1 -1
  111. package/fesm2022/acorex-components-number-box.mjs +7 -7
  112. package/fesm2022/acorex-components-otp.mjs +7 -7
  113. package/fesm2022/acorex-components-page.mjs +10 -10
  114. package/fesm2022/acorex-components-paint.mjs +25 -25
  115. package/fesm2022/acorex-components-paint.mjs.map +1 -1
  116. package/fesm2022/acorex-components-password-box.mjs +10 -10
  117. package/fesm2022/acorex-components-password-box.mjs.map +1 -1
  118. package/fesm2022/acorex-components-pdf-reader.mjs +7 -7
  119. package/fesm2022/acorex-components-phone-box.mjs +7 -7
  120. package/fesm2022/acorex-components-picker.mjs +13 -13
  121. package/fesm2022/acorex-components-popover.mjs +33 -15
  122. package/fesm2022/acorex-components-popover.mjs.map +1 -1
  123. package/fesm2022/acorex-components-popup.mjs +67 -56
  124. package/fesm2022/acorex-components-popup.mjs.map +1 -1
  125. package/fesm2022/acorex-components-progress-bar.mjs +7 -7
  126. package/fesm2022/acorex-components-qrcode.mjs +7 -7
  127. package/fesm2022/acorex-components-radio.mjs +7 -7
  128. package/fesm2022/acorex-components-rail-navigation.mjs +14 -14
  129. package/fesm2022/acorex-components-rail-navigation.mjs.map +1 -1
  130. package/fesm2022/acorex-components-range-slider.mjs +9 -9
  131. package/fesm2022/acorex-components-range-slider.mjs.map +1 -1
  132. package/fesm2022/acorex-components-rate-picker.mjs +7 -7
  133. package/fesm2022/acorex-components-reaction.mjs +144 -0
  134. package/fesm2022/acorex-components-reaction.mjs.map +1 -0
  135. package/fesm2022/acorex-components-rest-api-generator.mjs +22 -22
  136. package/fesm2022/acorex-components-rest-api-generator.mjs.map +1 -1
  137. package/fesm2022/acorex-components-result.mjs +7 -7
  138. package/fesm2022/acorex-components-routing-progress.mjs +7 -7
  139. package/fesm2022/acorex-components-rrule.mjs +9 -9
  140. package/fesm2022/acorex-components-rrule.mjs.map +1 -1
  141. package/fesm2022/acorex-components-scheduler-picker.mjs +56 -56
  142. package/fesm2022/acorex-components-scheduler-picker.mjs.map +1 -1
  143. package/fesm2022/acorex-components-scheduler.mjs +34 -34
  144. package/fesm2022/acorex-components-scheduler.mjs.map +1 -1
  145. package/fesm2022/acorex-components-search-box.mjs +7 -7
  146. package/fesm2022/acorex-components-select-box.mjs +7 -7
  147. package/fesm2022/acorex-components-selection-list.mjs +7 -8
  148. package/fesm2022/acorex-components-selection-list.mjs.map +1 -1
  149. package/fesm2022/acorex-components-side-menu.mjs +55 -42
  150. package/fesm2022/acorex-components-side-menu.mjs.map +1 -1
  151. package/fesm2022/acorex-components-sidebar.mjs +28 -28
  152. package/fesm2022/acorex-components-skeleton.mjs +7 -7
  153. package/fesm2022/acorex-components-slider.mjs +7 -7
  154. package/fesm2022/acorex-components-sliding-item.mjs +13 -13
  155. package/fesm2022/acorex-components-step-wizard.mjs +16 -18
  156. package/fesm2022/acorex-components-step-wizard.mjs.map +1 -1
  157. package/fesm2022/acorex-components-switch.mjs +10 -10
  158. package/fesm2022/acorex-components-tabs.mjs +529 -78
  159. package/fesm2022/acorex-components-tabs.mjs.map +1 -1
  160. package/fesm2022/acorex-components-tag-box.mjs +7 -7
  161. package/fesm2022/acorex-components-tag.mjs +7 -7
  162. package/fesm2022/acorex-components-text-area.mjs +7 -7
  163. package/fesm2022/acorex-components-text-box.mjs +7 -7
  164. package/fesm2022/acorex-components-time-duration.mjs +7 -7
  165. package/fesm2022/acorex-components-time-line.mjs +10 -10
  166. package/fesm2022/acorex-components-toast.mjs +10 -10
  167. package/fesm2022/acorex-components-toolbar.mjs +7 -7
  168. package/fesm2022/acorex-components-tooltip.mjs +10 -10
  169. package/fesm2022/acorex-components-tree-view.mjs +58 -15
  170. package/fesm2022/acorex-components-tree-view.mjs.map +1 -1
  171. package/fesm2022/acorex-components-uploader.mjs +13 -13
  172. package/fesm2022/acorex-components-video-player.mjs +7 -7
  173. package/fesm2022/acorex-components-wysiwyg.mjs +109 -39
  174. package/fesm2022/acorex-components-wysiwyg.mjs.map +1 -1
  175. package/highlight/README.md +13 -0
  176. package/inline-reaction/README.md +3 -0
  177. package/lookup/README.md +1 -1
  178. package/message/README.md +3 -0
  179. package/message-status/README.md +3 -0
  180. package/message-time/README.md +3 -0
  181. package/package.json +42 -12
  182. package/reaction/README.md +3 -0
  183. package/types/acorex-components-action-sheet.d.ts +1 -1
  184. package/types/acorex-components-audio-wave.d.ts +132 -73
  185. package/types/acorex-components-bubble.d.ts +31 -0
  186. package/types/acorex-components-button-group.d.ts +4 -0
  187. package/types/acorex-components-button.d.ts +1 -1
  188. package/types/acorex-components-calendar.d.ts +43 -12
  189. package/types/acorex-components-check-box.d.ts +1 -1
  190. package/types/acorex-components-code-editor.d.ts +4 -1
  191. package/types/acorex-components-color-box.d.ts +1 -1
  192. package/types/acorex-components-color-palette.d.ts +2 -2
  193. package/types/acorex-components-combo-box.d.ts +34 -4
  194. package/types/acorex-components-command.d.ts +1 -1
  195. package/types/acorex-components-conversation.d.ts +1771 -1342
  196. package/types/acorex-components-cron-job.d.ts +6 -6
  197. package/types/acorex-components-data-pager.d.ts +2 -2
  198. package/types/acorex-components-data-table.d.ts +194 -21
  199. package/types/acorex-components-datetime-box.d.ts +1 -1
  200. package/types/acorex-components-datetime-picker.d.ts +1 -1
  201. package/types/acorex-components-decorators.d.ts +13 -1
  202. package/types/acorex-components-dialog.d.ts +1 -1
  203. package/types/acorex-components-dropdown.d.ts +1 -1
  204. package/types/acorex-components-editor.d.ts +1 -1
  205. package/types/acorex-components-emoji.d.ts +42 -0
  206. package/types/acorex-components-emojipicker.d.ts +146 -0
  207. package/types/acorex-components-file-viewer.d.ts +50 -6
  208. package/types/acorex-components-highlight.d.ts +31 -0
  209. package/types/acorex-components-image-editor.d.ts +72 -50
  210. package/types/acorex-components-inline-reaction.d.ts +52 -0
  211. package/types/acorex-components-list.d.ts +12 -0
  212. package/types/acorex-components-loading-dialog.d.ts +1 -1
  213. package/types/acorex-components-loading.d.ts +1 -1
  214. package/types/acorex-components-lookup.d.ts +213 -82
  215. package/types/acorex-components-map.d.ts +7 -2
  216. package/types/acorex-components-media-viewer.d.ts +4 -3
  217. package/types/acorex-components-menu.d.ts +17 -5
  218. package/types/acorex-components-message-status.d.ts +23 -0
  219. package/types/acorex-components-message-time.d.ts +19 -0
  220. package/types/acorex-components-message.d.ts +59 -0
  221. package/types/acorex-components-notification.d.ts +1 -1
  222. package/types/acorex-components-number-box.d.ts +1 -1
  223. package/types/acorex-components-otp.d.ts +1 -1
  224. package/types/acorex-components-page.d.ts +2 -2
  225. package/types/acorex-components-paint.d.ts +2 -2
  226. package/types/acorex-components-password-box.d.ts +1 -1
  227. package/types/acorex-components-phone-box.d.ts +1 -1
  228. package/types/acorex-components-popover.d.ts +10 -4
  229. package/types/acorex-components-popup.d.ts +20 -10
  230. package/types/acorex-components-rail-navigation.d.ts +1 -1
  231. package/types/acorex-components-range-slider.d.ts +1 -1
  232. package/types/acorex-components-reaction.d.ts +85 -0
  233. package/types/acorex-components-rest-api-generator.d.ts +1 -1
  234. package/types/acorex-components-rrule.d.ts +1 -1
  235. package/types/acorex-components-scheduler-picker.d.ts +1 -1
  236. package/types/acorex-components-scheduler.d.ts +1 -1
  237. package/types/acorex-components-search-box.d.ts +1 -1
  238. package/types/acorex-components-selection-list.d.ts +1 -1
  239. package/types/acorex-components-side-menu.d.ts +6 -8
  240. package/types/acorex-components-slider.d.ts +1 -1
  241. package/types/acorex-components-step-wizard.d.ts +4 -4
  242. package/types/acorex-components-switch.d.ts +1 -1
  243. package/types/acorex-components-tabs.d.ts +150 -19
  244. package/types/acorex-components-tag-box.d.ts +2 -2
  245. package/types/acorex-components-text-area.d.ts +1 -1
  246. package/types/acorex-components-text-box.d.ts +1 -1
  247. package/types/acorex-components-time-duration.d.ts +1 -1
  248. package/types/acorex-components-toast.d.ts +1 -1
  249. package/types/acorex-components-tree-view.d.ts +32 -3
  250. package/types/acorex-components-wysiwyg.d.ts +15 -2
  251. package/fesm2022/acorex-components-conversation-composer-action-choice-dialog.component-DCcRJYfF.mjs +0 -50
  252. package/fesm2022/acorex-components-conversation-composer-action-choice-dialog.component-DCcRJYfF.mjs.map +0 -1
  253. package/fesm2022/acorex-components-conversation-open-composer-picker-for-files-DnSW908R.mjs +0 -210
  254. package/fesm2022/acorex-components-conversation-open-composer-picker-for-files-DnSW908R.mjs.map +0 -1
  255. package/fesm2022/acorex-components-flow-chart.mjs +0 -735
  256. package/fesm2022/acorex-components-flow-chart.mjs.map +0 -1
  257. package/fesm2022/acorex-components-query-builder.mjs +0 -267
  258. package/fesm2022/acorex-components-query-builder.mjs.map +0 -1
  259. package/flow-chart/README.md +0 -3
  260. package/query-builder/README.md +0 -3
  261. package/types/acorex-components-flow-chart.d.ts +0 -187
  262. package/types/acorex-components-query-builder.d.ts +0 -52
@@ -1,24 +1,21 @@
1
1
  import { AXComponent, MXBaseComponent, MXInputBaseValueComponent, MXLookComponent, AXFocusableComponent, AXValuableComponent } from '@acorex/cdk/common';
2
2
  import * as i1 from '@acorex/components/decorators';
3
3
  import { AXDecoratorModule, AXDecoratorIconComponent } from '@acorex/components/decorators';
4
- import { AXLoadingSpinnerComponent, AXLoadingModule } from '@acorex/components/loading';
4
+ import { AXLoadingSpinnerComponent } from '@acorex/components/loading';
5
+ import { AXTranslatorPipe } from '@acorex/core/translation';
6
+ import { isPlatformBrowser, AsyncPipe } from '@angular/common';
5
7
  import * as i0 from '@angular/core';
6
- import { signal, Injectable, input, inject, NgZone, ElementRef, viewChild, Renderer2, PLATFORM_ID, effect, afterNextRender, ViewEncapsulation, Component, linkedSignal, contentChild, forwardRef, HostBinding, output, computed, NgModule } from '@angular/core';
8
+ import { signal, Injectable, input, inject, NgZone, ElementRef, viewChild, Renderer2, PLATFORM_ID, effect, untracked, afterNextRender, ChangeDetectionStrategy, ViewEncapsulation, Component, DestroyRef, contentChild, forwardRef, output, computed, NgModule } from '@angular/core';
7
9
  import * as i1$1 from '@angular/forms';
8
10
  import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
9
11
  import { classes } from 'polytype';
10
- import { isPlatformBrowser, AsyncPipe } from '@angular/common';
11
- import { AXButtonComponent, AXButtonModule } from '@acorex/components/button';
12
+ import { AXButtonComponent } from '@acorex/components/button';
12
13
  import * as i2 from '@acorex/components/tooltip';
13
14
  import { AXTooltipModule, AXTooltipDirective } from '@acorex/components/tooltip';
14
- import { AXTranslatorPipe } from '@acorex/core/translation';
15
15
  import * as i2$1 from '@acorex/components/toolbar';
16
16
  import { AXToolBarModule } from '@acorex/components/toolbar';
17
- import { AXColorBoxComponent, AXColorBoxModule } from '@acorex/components/color-box';
18
- import { AXRangeSliderComponent, AXRangeSliderModule } from '@acorex/components/range-slider';
19
- import { AXDialogModule } from '@acorex/components/dialog';
20
- import { AXPopoverModule } from '@acorex/components/popover';
21
- import { AXSelectBoxModule } from '@acorex/components/select-box';
17
+ import { AXColorBoxComponent } from '@acorex/components/color-box';
18
+ import { AXRangeSliderComponent } from '@acorex/components/range-slider';
22
19
 
23
20
  class AXImageEditorService {
24
21
  constructor() {
@@ -38,6 +35,8 @@ class AXImageEditorService {
38
35
  ...(ngDevMode ? [{ debugName: "rotate" }] : /* istanbul ignore next */ []));
39
36
  this.isImageLoad = signal(false, /* @ts-ignore */
40
37
  ...(ngDevMode ? [{ debugName: "isImageLoad" }] : /* istanbul ignore next */ []));
38
+ this.loadError = signal(false, /* @ts-ignore */
39
+ ...(ngDevMode ? [{ debugName: "loadError" }] : /* istanbul ignore next */ []));
41
40
  this.newImage = null;
42
41
  this.initialImage = null;
43
42
  this.imageBlob = signal([], /* @ts-ignore */
@@ -46,6 +45,10 @@ class AXImageEditorService {
46
45
  ...(ngDevMode ? [{ debugName: "undoPressed" }] : /* istanbul ignore next */ []));
47
46
  this.redoPressed = signal(false, /* @ts-ignore */
48
47
  ...(ngDevMode ? [{ debugName: "redoPressed" }] : /* istanbul ignore next */ []));
48
+ this.canUndo = signal(false, /* @ts-ignore */
49
+ ...(ngDevMode ? [{ debugName: "canUndo" }] : /* istanbul ignore next */ []));
50
+ this.canRedo = signal(false, /* @ts-ignore */
51
+ ...(ngDevMode ? [{ debugName: "canRedo" }] : /* istanbul ignore next */ []));
49
52
  this.cropperRatio = signal(null, /* @ts-ignore */
50
53
  ...(ngDevMode ? [{ debugName: "cropperRatio" }] : /* istanbul ignore next */ []));
51
54
  this.cropperSize = signal(150, /* @ts-ignore */
@@ -54,6 +57,7 @@ class AXImageEditorService {
54
57
  toggleTool(tool) {
55
58
  if (this.activeToolState() === tool) {
56
59
  this.activeToolState.set(null);
60
+ this.penType.set(null);
57
61
  return;
58
62
  }
59
63
  this.activateTool(tool);
@@ -62,12 +66,54 @@ class AXImageEditorService {
62
66
  this.activeToolState.set(tool);
63
67
  if (tool === 'pen' || tool === 'highlight') {
64
68
  this.penType.set(tool);
69
+ return;
70
+ }
71
+ this.penType.set(null);
72
+ }
73
+ undo() {
74
+ if (!this.canUndo()) {
75
+ return;
76
+ }
77
+ this.undoPressed.set(true);
78
+ }
79
+ redo() {
80
+ if (!this.canRedo()) {
81
+ return;
65
82
  }
83
+ this.redoPressed.set(true);
66
84
  }
67
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
68
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorService }); }
85
+ /** Handles Ctrl/Cmd+Z and Ctrl/Cmd+Y history shortcuts. Returns true when handled. */
86
+ handleHistoryShortcut(event) {
87
+ const modifier = event.ctrlKey || event.metaKey;
88
+ if (!modifier) {
89
+ return false;
90
+ }
91
+ const isUndo = event.code === 'KeyZ' && !event.shiftKey;
92
+ const isRedo = event.code === 'KeyY' || (event.code === 'KeyZ' && event.shiftKey);
93
+ if (isUndo) {
94
+ if (!this.canUndo()) {
95
+ return false;
96
+ }
97
+ event.preventDefault();
98
+ event.stopPropagation();
99
+ this.undo();
100
+ return true;
101
+ }
102
+ if (isRedo) {
103
+ if (!this.canRedo()) {
104
+ return false;
105
+ }
106
+ event.preventDefault();
107
+ event.stopPropagation();
108
+ this.redo();
109
+ return true;
110
+ }
111
+ return false;
112
+ }
113
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
114
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorService }); }
69
115
  }
70
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorService, decorators: [{
116
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorService, decorators: [{
71
117
  type: Injectable
72
118
  }] });
73
119
 
@@ -91,63 +137,46 @@ class AXImageEditorCropperWindowComponent {
91
137
  this.elementRef = inject(ElementRef);
92
138
  this.cropperWindow = viewChild('r', /* @ts-ignore */
93
139
  ...(ngDevMode ? [{ debugName: "cropperWindow" }] : /* istanbul ignore next */ []));
94
- this.currentX = signal(-45, /* @ts-ignore */
140
+ this.currentX = signal(0, /* @ts-ignore */
95
141
  ...(ngDevMode ? [{ debugName: "currentX" }] : /* istanbul ignore next */ []));
96
- this.currentY = signal(-45, /* @ts-ignore */
142
+ this.currentY = signal(0, /* @ts-ignore */
97
143
  ...(ngDevMode ? [{ debugName: "currentY" }] : /* istanbul ignore next */ []));
98
- this.prevX = signal(0, /* @ts-ignore */
99
- ...(ngDevMode ? [{ debugName: "prevX" }] : /* istanbul ignore next */ []));
100
- this.prevY = signal(0, /* @ts-ignore */
101
- ...(ngDevMode ? [{ debugName: "prevY" }] : /* istanbul ignore next */ []));
102
- this.aspectWidth = signal(0, /* @ts-ignore */
144
+ this.aspectWidth = signal(1, /* @ts-ignore */
103
145
  ...(ngDevMode ? [{ debugName: "aspectWidth" }] : /* istanbul ignore next */ []));
104
- this.aspectHeight = signal(0, /* @ts-ignore */
146
+ this.aspectHeight = signal(1, /* @ts-ignore */
105
147
  ...(ngDevMode ? [{ debugName: "aspectHeight" }] : /* istanbul ignore next */ []));
106
148
  this.isMousePressed = signal(false, /* @ts-ignore */
107
149
  ...(ngDevMode ? [{ debugName: "isMousePressed" }] : /* istanbul ignore next */ []));
108
150
  this.renderer = inject(Renderer2);
109
151
  this.platformID = inject(PLATFORM_ID);
110
- this.#eff = effect(() => {
152
+ this.positioned = false;
153
+ this.#sizeEffect = effect(() => {
111
154
  const host = this.elementRef.nativeElement;
112
- let width;
113
- let height;
114
155
  const scale = this.size() ?? this.service.cropperSize();
115
- switch (this.service.cropperRatio()) {
116
- case '1:1':
117
- width = 1;
118
- height = 1;
119
- break;
120
- case '16:9':
121
- width = 1.777777777777778;
122
- height = 1;
123
- break;
124
- case null:
125
- width = 1;
126
- height = 1;
127
- break;
128
- default:
129
- [width, height] = this.service.cropperRatio().split(':').map(Number);
156
+ const ratio = this.service.cropperRatio();
157
+ const { width, height } = this.normalizeRatio(ratio);
158
+ this.aspectWidth.set(width);
159
+ this.aspectHeight.set(height);
160
+ const { width: maxW, height: maxH } = this.getImageBounds();
161
+ const boundsW = maxW || scale * width;
162
+ const boundsH = maxH || scale * height;
163
+ let nextWidth = Math.min(width * scale, boundsW * 0.9);
164
+ let nextHeight = (nextWidth * height) / width;
165
+ if (nextHeight > boundsH * 0.9) {
166
+ nextHeight = boundsH * 0.9;
167
+ nextWidth = (nextHeight * width) / height;
130
168
  }
131
- if (width >= height) {
132
- const aspect = width / height;
133
- width = aspect;
134
- height = 1;
135
- this.aspectWidth.set(aspect);
136
- this.aspectHeight.set(1);
169
+ host.style.width = `${Math.max(20, nextWidth)}px`;
170
+ host.style.height = `${Math.max(20, nextHeight)}px`;
171
+ if (this.positioned) {
172
+ untracked(() => this.clampToParent());
137
173
  }
138
- else {
139
- const aspect = height / width;
140
- width = 1;
141
- height = aspect;
142
- this.aspectWidth.set(1);
143
- this.aspectHeight.set(aspect);
144
- }
145
- host.style.width = `${width * scale}px`;
146
- host.style.height = `${height * scale}px`;
147
174
  }, /* @ts-ignore */
148
- ...(ngDevMode ? [{ debugName: "#eff" }] : /* istanbul ignore next */ []));
175
+ ...(ngDevMode ? [{ debugName: "#sizeEffect" }] : /* istanbul ignore next */ []));
149
176
  this.#init = afterNextRender(() => {
150
177
  const host = this.elementRef.nativeElement;
178
+ this.centerOnParent();
179
+ this.positioned = true;
151
180
  this.ngZone.runOutsideAngular(() => {
152
181
  this.mouseMoveEvent = this.renderer.listen(document, 'pointermove', this.changeSizeHandler.bind(this));
153
182
  this.mouseUpEvent = this.renderer.listen(document, 'pointerup', this.clearSelector.bind(this));
@@ -156,34 +185,26 @@ class AXImageEditorCropperWindowComponent {
156
185
  this.mouseUpEvent2 = this.renderer.listen(host, 'pointerup', this.panUp.bind(this));
157
186
  });
158
187
  });
159
- this.#positionChange = effect(() => {
160
- this.setPosition(this.currentX(), this.currentY());
161
- }, /* @ts-ignore */
162
- ...(ngDevMode ? [{ debugName: "#positionChange" }] : /* istanbul ignore next */ []));
188
+ this.startX = 0;
189
+ this.startY = 0;
190
+ this.startWidth = 0;
191
+ this.startHeight = 0;
192
+ this.startLeft = 0;
193
+ this.startTop = 0;
163
194
  }
164
- #eff;
195
+ #sizeEffect;
165
196
  #init;
166
197
  ngOnDestroy() {
167
- if (isPlatformBrowser(this.platformID) && this.mouseMoveEvent) {
168
- this.mouseMoveEvent();
169
- }
170
- if (isPlatformBrowser(this.platformID) && this.mouseUpEvent) {
171
- this.mouseUpEvent();
172
- }
173
- if (isPlatformBrowser(this.platformID) && this.mouseDownEvent) {
174
- this.mouseDownEvent();
175
- }
176
- if (isPlatformBrowser(this.platformID) && this.mouseMoveEvent2) {
177
- this.mouseMoveEvent2();
178
- }
179
- if (isPlatformBrowser(this.platformID) && this.mouseUpEvent2) {
180
- this.mouseUpEvent2();
181
- }
182
- if (isPlatformBrowser(this.platformID) && this.mouseLeaveEvent) {
183
- this.mouseLeaveEvent();
198
+ if (!isPlatformBrowser(this.platformID)) {
199
+ return;
184
200
  }
201
+ this.mouseMoveEvent?.();
202
+ this.mouseUpEvent?.();
203
+ this.mouseDownEvent?.();
204
+ this.mouseMoveEvent2?.();
205
+ this.mouseUpEvent2?.();
206
+ this.mouseLeaveEvent?.();
185
207
  }
186
- #positionChange;
187
208
  panMove(e) {
188
209
  if (!this.isMousePressed())
189
210
  return;
@@ -191,39 +212,27 @@ class AXImageEditorCropperWindowComponent {
191
212
  return;
192
213
  if (!this.panState())
193
214
  return;
194
- const currentX = e.clientX;
195
- const currentY = e.clientY;
196
- const deltaX = currentX - this.prevX();
197
- const deltaY = currentY - this.prevY();
198
- this.currentX.update((prev) => prev + deltaX);
199
- this.currentY.update((prev) => prev + deltaY);
200
- this.prevX.set(currentX);
201
- this.prevY.set(currentY);
215
+ this.currentX.update((prev) => prev + e.movementX);
216
+ this.currentY.update((prev) => prev + e.movementY);
217
+ this.clampToParent();
202
218
  }
203
219
  panDown(e) {
204
- this.isMousePressed.set(true);
205
220
  if (this.selectedHandle())
206
221
  return;
222
+ this.isMousePressed.set(true);
207
223
  this.panState.set(true);
208
- this.prevX.set(e.clientX);
209
- this.prevY.set(e.clientY);
224
+ e.currentTarget?.setPointerCapture?.(e.pointerId);
210
225
  }
211
226
  panUp() {
212
227
  this.isMousePressed.set(false);
213
- if (this.selectedHandle())
214
- return;
215
228
  this.panState.set(false);
216
229
  }
217
230
  getCropperArea() {
218
231
  return this.elementRef.nativeElement.getBoundingClientRect();
219
232
  }
220
- setPosition(posX, posY) {
221
- const el = this.elementRef.nativeElement;
222
- el.style.transform = `translate(${posX}px, ${posY}px)`;
223
- }
224
233
  handleSelector(e, value) {
225
- if (this.panState())
226
- return;
234
+ e.stopPropagation();
235
+ e.preventDefault();
227
236
  const host = this.elementRef.nativeElement;
228
237
  this.startX = e.clientX;
229
238
  this.startY = e.clientY;
@@ -232,6 +241,8 @@ class AXImageEditorCropperWindowComponent {
232
241
  this.startLeft = host.offsetLeft;
233
242
  this.startTop = host.offsetTop;
234
243
  this.selectedHandle.set(value);
244
+ this.isMousePressed.set(true);
245
+ e.currentTarget?.setPointerCapture?.(e.pointerId);
235
246
  }
236
247
  changeSizeHandler(e) {
237
248
  if (!this.isMousePressed())
@@ -243,164 +254,231 @@ class AXImageEditorCropperWindowComponent {
243
254
  const host = this.elementRef.nativeElement;
244
255
  const dy = e.clientY - this.startY;
245
256
  const dx = e.clientX - this.startX;
246
- let newWidth;
247
- let newHeight;
248
257
  const minSize = 20;
258
+ const locked = !!this.service.cropperRatio();
259
+ const aspect = this.aspectWidth() / this.aspectHeight();
260
+ let width = this.startWidth;
261
+ let height = this.startHeight;
262
+ let left = this.startLeft;
263
+ let top = this.startTop;
249
264
  switch (this.selectedHandle()) {
250
265
  case 'right':
251
- newWidth = Math.max(minSize, this.startWidth + dx);
252
- host.style.width = `${newWidth}px`;
266
+ width = Math.max(minSize, this.startWidth + dx);
253
267
  break;
254
268
  case 'top':
255
- newHeight = Math.max(minSize, this.startHeight - dy);
256
- host.style.height = `${newHeight}px`;
257
- host.style.top = `${this.startTop + (this.startHeight - newHeight)}px`;
269
+ height = Math.max(minSize, this.startHeight - dy);
270
+ top = this.startTop + (this.startHeight - height);
258
271
  break;
259
272
  case 'left':
260
- newWidth = Math.max(minSize, this.startWidth - dx);
261
- host.style.width = `${newWidth}px`;
262
- host.style.left = `${this.startLeft + (this.startWidth - newWidth)}px`;
273
+ width = Math.max(minSize, this.startWidth - dx);
274
+ left = this.startLeft + (this.startWidth - width);
263
275
  break;
264
276
  case 'bottom':
265
- newHeight = Math.max(minSize, this.startHeight + dy);
266
- host.style.height = `${newHeight}px`;
277
+ height = Math.max(minSize, this.startHeight + dy);
267
278
  break;
268
279
  case 'right-top':
269
- if (this.service.cropperRatio()) {
270
- newWidth = Math.max(minSize, this.startWidth + dx);
271
- newHeight = (newWidth * this.aspectHeight()) / this.aspectWidth();
272
- if (newHeight < minSize) {
273
- newHeight = minSize;
274
- newWidth = (newHeight * this.aspectWidth()) / this.aspectHeight();
275
- }
276
- host.style.width = `${newWidth}px`;
277
- host.style.height = `${newHeight}px`;
278
- host.style.top = `${this.startTop + (this.startHeight - newHeight)}px`;
279
- }
280
- else {
281
- newWidth = Math.max(minSize, this.startWidth + dx);
282
- newHeight = Math.max(minSize, this.startHeight - dy);
283
- host.style.width = `${newWidth}px`;
284
- host.style.height = `${newHeight}px`;
285
- host.style.top = `${this.startTop + (this.startHeight - newHeight)}px`;
280
+ width = Math.max(minSize, this.startWidth + dx);
281
+ height = locked ? width / aspect : Math.max(minSize, this.startHeight - dy);
282
+ if (locked && height < minSize) {
283
+ height = minSize;
284
+ width = height * aspect;
286
285
  }
286
+ top = this.startTop + (this.startHeight - height);
287
287
  break;
288
288
  case 'bottom-right':
289
- if (this.service.cropperRatio()) {
290
- newWidth = Math.max(minSize, this.startWidth + dx);
291
- newHeight = (newWidth * this.aspectHeight()) / this.aspectWidth();
292
- if (newHeight < minSize) {
293
- newHeight = minSize;
294
- newWidth = (newHeight * this.aspectWidth()) / this.aspectHeight();
295
- }
296
- host.style.width = `${newWidth}px`;
297
- host.style.height = `${newHeight}px`;
298
- }
299
- else {
300
- newWidth = Math.max(minSize, this.startWidth + dx);
301
- newHeight = Math.max(minSize, this.startHeight + dy);
302
- host.style.width = `${newWidth}px`;
303
- host.style.height = `${newHeight}px`;
289
+ width = Math.max(minSize, this.startWidth + dx);
290
+ height = locked ? width / aspect : Math.max(minSize, this.startHeight + dy);
291
+ if (locked && height < minSize) {
292
+ height = minSize;
293
+ width = height * aspect;
304
294
  }
305
295
  break;
306
296
  case 'bottom-left':
307
- if (this.service.cropperRatio()) {
308
- newWidth = Math.max(minSize, this.startWidth - dx);
309
- newHeight = (newWidth * this.aspectHeight()) / this.aspectWidth();
310
- if (newHeight < minSize) {
311
- newHeight = minSize;
312
- newWidth = (newHeight * this.aspectWidth()) / this.aspectHeight();
313
- }
314
- host.style.width = `${newWidth}px`;
315
- host.style.height = `${newHeight}px`;
316
- host.style.left = `${this.startLeft + (this.startWidth - newWidth)}px`;
317
- }
318
- else {
319
- newWidth = Math.max(minSize, this.startWidth - dx);
320
- newHeight = Math.max(minSize, this.startHeight + dy);
321
- host.style.width = `${newWidth}px`;
322
- host.style.height = `${newHeight}px`;
323
- host.style.left = `${this.startLeft + (this.startWidth - newWidth)}px`;
297
+ width = Math.max(minSize, this.startWidth - dx);
298
+ height = locked ? width / aspect : Math.max(minSize, this.startHeight + dy);
299
+ if (locked && height < minSize) {
300
+ height = minSize;
301
+ width = height * aspect;
324
302
  }
303
+ left = this.startLeft + (this.startWidth - width);
325
304
  break;
326
305
  case 'left-top':
327
- if (this.service.cropperRatio()) {
328
- newWidth = Math.max(minSize, this.startWidth - dx);
329
- newHeight = (newWidth * this.aspectHeight()) / this.aspectWidth();
330
- if (newHeight < minSize) {
331
- newHeight = minSize;
332
- newWidth = (newHeight * this.aspectWidth()) / this.aspectHeight();
333
- }
334
- host.style.width = `${newWidth}px`;
335
- host.style.height = `${newHeight}px`;
336
- host.style.left = `${this.startLeft + (this.startWidth - newWidth)}px`;
337
- host.style.top = `${this.startTop + (this.startHeight - newHeight)}px`;
338
- }
339
- else {
340
- newWidth = Math.max(minSize, this.startWidth - dx);
341
- newHeight = Math.max(minSize, this.startHeight - dy);
342
- host.style.width = `${newWidth}px`;
343
- host.style.height = `${newHeight}px`;
344
- host.style.left = `${this.startLeft + (this.startWidth - newWidth)}px`;
345
- host.style.top = `${this.startTop + (this.startHeight - newHeight)}px`;
306
+ width = Math.max(minSize, this.startWidth - dx);
307
+ height = locked ? width / aspect : Math.max(minSize, this.startHeight - dy);
308
+ if (locked && height < minSize) {
309
+ height = minSize;
310
+ width = height * aspect;
346
311
  }
312
+ left = this.startLeft + (this.startWidth - width);
313
+ top = this.startTop + (this.startHeight - height);
347
314
  break;
348
315
  }
316
+ const constrained = this.constrainCropBox(left, top, width, height);
317
+ host.style.width = `${constrained.width}px`;
318
+ host.style.height = `${constrained.height}px`;
319
+ this.currentX.set(constrained.left);
320
+ this.currentY.set(constrained.top);
321
+ this.applyPosition();
349
322
  }
350
323
  clearSelector() {
351
- if (this.panState())
352
- return;
353
324
  this.selectedHandle.set(null);
325
+ this.isMousePressed.set(false);
326
+ this.panState.set(false);
354
327
  }
355
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorCropperWindowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
356
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXImageEditorCropperWindowComponent, isStandalone: true, selector: "ax-image-editor-cropper-window", inputs: { showGrid: { classPropertyName: "showGrid", publicName: "showGrid", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, providers: [{ provide: AXComponent, useExisting: AXImageEditorCropperWindowComponent }], viewQueries: [{ propertyName: "cropperWindow", first: true, predicate: ["r"], descendants: true, isSignal: true }], ngImport: i0, template: "<div [style.border]=\"!showGrid() ? '1px dashed white' : null\" #r class=\"ax-image-cropper-window-container\">\n @if (!service.cropperRatio()) {\n <div (pointerdown)=\"handleSelector($event, 'right')\" class=\"ax-image-right-handle ax-handle-shape\"></div>\n <div (pointerdown)=\"handleSelector($event, 'top')\" class=\"ax-image-top-handle ax-handle-shape\"></div>\n <div (pointerdown)=\"handleSelector($event, 'left')\" class=\"ax-image-left-handle ax-handle-shape\"></div>\n <div (pointerdown)=\"handleSelector($event, 'bottom')\" class=\"ax-image-bottom-handle ax-handle-shape\"></div>\n }\n\n <div (pointerdown)=\"handleSelector($event, 'right-top')\" class=\"ax-image-right-top-handle ax-handle-shape\"></div>\n <div\n (pointerdown)=\"handleSelector($event, 'bottom-right')\"\n class=\"ax-image-bottom-right-handle ax-handle-shape\"\n ></div>\n <div (pointerdown)=\"handleSelector($event, 'bottom-left')\" class=\"ax-image-bottom-left-handle ax-handle-shape\"></div>\n <div (pointerdown)=\"handleSelector($event, 'left-top')\" class=\"ax-image-left-top-handle ax-handle-shape\"></div>\n\n @if (showGrid()) {\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n }\n</div>\n", styles: ["@layer properties;@layer components{ax-image-editor-cropper-window{position:absolute;top:45%;left:45%;touch-action:none;-webkit-user-select:none;user-select:none}ax-image-editor-cropper-window .ax-image-cropper-window-container{position:relative;display:grid;height:100%;cursor:move;grid-template-columns:repeat(3,minmax(0,1fr));outline-style:var(--tw-outline-style);outline-width:100vmax;outline-color:color-mix(in srgb,#000 70%,transparent);--tw-outline-style: solid;outline-style:solid}@supports (color: color-mix(in lab,red,red)){ax-image-editor-cropper-window .ax-image-cropper-window-container{outline-color:color-mix(in oklab,var(--color-black, #000) 70%,transparent)}}ax-image-editor-cropper-window .ax-image-cropper-window-container .ax-grid-item{border-style:var(--tw-border-style);border-width:1px;--tw-border-style: dashed;border-style:dashed;border-color:color-mix(in srgb,#fff 50%,transparent)}@supports (color: color-mix(in lab,red,red)){ax-image-editor-cropper-window .ax-image-cropper-window-container .ax-grid-item{border-color:color-mix(in oklab,var(--color-white, #fff) 50%,transparent)}}ax-image-editor-cropper-window .ax-handle-shape{position:absolute;height:calc(var(--spacing, .25rem) * 4);width:calc(var(--spacing, .25rem) * 4);border-style:var(--tw-border-style);border-width:1px;--tw-border-style: dashed;border-style:dashed;border-color:var(--color-white, #fff);background-color:var(--color-gray-500, oklch(55.1% .027 264.364));-webkit-user-select:none;user-select:none}ax-image-editor-cropper-window .ax-image-right-top-handle{top:calc(var(--spacing, .25rem) * -2);right:calc(var(--spacing, .25rem) * -2);cursor:ne-resize}ax-image-editor-cropper-window .ax-image-bottom-right-handle{right:calc(var(--spacing, .25rem) * -2);bottom:calc(var(--spacing, .25rem) * -2);cursor:se-resize}ax-image-editor-cropper-window .ax-image-right-handle{top:calc(50% - .5rem);right:calc(var(--spacing, .25rem) * -2);cursor:e-resize}ax-image-editor-cropper-window .ax-image-bottom-left-handle{bottom:calc(var(--spacing, .25rem) * -2);left:calc(var(--spacing, .25rem) * -2);cursor:sw-resize}ax-image-editor-cropper-window .ax-image-left-top-handle{top:calc(var(--spacing, .25rem) * -2);left:calc(var(--spacing, .25rem) * -2);cursor:nw-resize}ax-image-editor-cropper-window .ax-image-bottom-handle{right:calc(50% - .5rem);bottom:calc(var(--spacing, .25rem) * -2);cursor:s-resize}ax-image-editor-cropper-window .ax-image-left-handle{top:calc(50% - .5rem);left:calc(var(--spacing, .25rem) * -2);cursor:w-resize}ax-image-editor-cropper-window .ax-image-top-handle{top:calc(var(--spacing, .25rem) * -2);right:calc(50% - .5rem);cursor:n-resize}}@property --tw-outline-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-outline-style: solid;--tw-border-style: solid}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], encapsulation: i0.ViewEncapsulation.None }); }
357
- }
358
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorCropperWindowComponent, decorators: [{
359
- type: Component,
360
- args: [{ selector: 'ax-image-editor-cropper-window', encapsulation: ViewEncapsulation.None, providers: [{ provide: AXComponent, useExisting: AXImageEditorCropperWindowComponent }], template: "<div [style.border]=\"!showGrid() ? '1px dashed white' : null\" #r class=\"ax-image-cropper-window-container\">\n @if (!service.cropperRatio()) {\n <div (pointerdown)=\"handleSelector($event, 'right')\" class=\"ax-image-right-handle ax-handle-shape\"></div>\n <div (pointerdown)=\"handleSelector($event, 'top')\" class=\"ax-image-top-handle ax-handle-shape\"></div>\n <div (pointerdown)=\"handleSelector($event, 'left')\" class=\"ax-image-left-handle ax-handle-shape\"></div>\n <div (pointerdown)=\"handleSelector($event, 'bottom')\" class=\"ax-image-bottom-handle ax-handle-shape\"></div>\n }\n\n <div (pointerdown)=\"handleSelector($event, 'right-top')\" class=\"ax-image-right-top-handle ax-handle-shape\"></div>\n <div\n (pointerdown)=\"handleSelector($event, 'bottom-right')\"\n class=\"ax-image-bottom-right-handle ax-handle-shape\"\n ></div>\n <div (pointerdown)=\"handleSelector($event, 'bottom-left')\" class=\"ax-image-bottom-left-handle ax-handle-shape\"></div>\n <div (pointerdown)=\"handleSelector($event, 'left-top')\" class=\"ax-image-left-top-handle ax-handle-shape\"></div>\n\n @if (showGrid()) {\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n }\n</div>\n", styles: ["@layer properties;@layer components{ax-image-editor-cropper-window{position:absolute;top:45%;left:45%;touch-action:none;-webkit-user-select:none;user-select:none}ax-image-editor-cropper-window .ax-image-cropper-window-container{position:relative;display:grid;height:100%;cursor:move;grid-template-columns:repeat(3,minmax(0,1fr));outline-style:var(--tw-outline-style);outline-width:100vmax;outline-color:color-mix(in srgb,#000 70%,transparent);--tw-outline-style: solid;outline-style:solid}@supports (color: color-mix(in lab,red,red)){ax-image-editor-cropper-window .ax-image-cropper-window-container{outline-color:color-mix(in oklab,var(--color-black, #000) 70%,transparent)}}ax-image-editor-cropper-window .ax-image-cropper-window-container .ax-grid-item{border-style:var(--tw-border-style);border-width:1px;--tw-border-style: dashed;border-style:dashed;border-color:color-mix(in srgb,#fff 50%,transparent)}@supports (color: color-mix(in lab,red,red)){ax-image-editor-cropper-window .ax-image-cropper-window-container .ax-grid-item{border-color:color-mix(in oklab,var(--color-white, #fff) 50%,transparent)}}ax-image-editor-cropper-window .ax-handle-shape{position:absolute;height:calc(var(--spacing, .25rem) * 4);width:calc(var(--spacing, .25rem) * 4);border-style:var(--tw-border-style);border-width:1px;--tw-border-style: dashed;border-style:dashed;border-color:var(--color-white, #fff);background-color:var(--color-gray-500, oklch(55.1% .027 264.364));-webkit-user-select:none;user-select:none}ax-image-editor-cropper-window .ax-image-right-top-handle{top:calc(var(--spacing, .25rem) * -2);right:calc(var(--spacing, .25rem) * -2);cursor:ne-resize}ax-image-editor-cropper-window .ax-image-bottom-right-handle{right:calc(var(--spacing, .25rem) * -2);bottom:calc(var(--spacing, .25rem) * -2);cursor:se-resize}ax-image-editor-cropper-window .ax-image-right-handle{top:calc(50% - .5rem);right:calc(var(--spacing, .25rem) * -2);cursor:e-resize}ax-image-editor-cropper-window .ax-image-bottom-left-handle{bottom:calc(var(--spacing, .25rem) * -2);left:calc(var(--spacing, .25rem) * -2);cursor:sw-resize}ax-image-editor-cropper-window .ax-image-left-top-handle{top:calc(var(--spacing, .25rem) * -2);left:calc(var(--spacing, .25rem) * -2);cursor:nw-resize}ax-image-editor-cropper-window .ax-image-bottom-handle{right:calc(50% - .5rem);bottom:calc(var(--spacing, .25rem) * -2);cursor:s-resize}ax-image-editor-cropper-window .ax-image-left-handle{top:calc(50% - .5rem);left:calc(var(--spacing, .25rem) * -2);cursor:w-resize}ax-image-editor-cropper-window .ax-image-top-handle{top:calc(var(--spacing, .25rem) * -2);right:calc(50% - .5rem);cursor:n-resize}}@property --tw-outline-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-outline-style: solid;--tw-border-style: solid}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"] }]
361
- }], propDecorators: { showGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGrid", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], cropperWindow: [{ type: i0.ViewChild, args: ['r', { isSignal: true }] }] } });
362
-
363
- class AXImageEditorViewComponent extends MXBaseComponent {
364
- /** @ignore */
365
- resizeWindow() {
366
- this.canvasResponsive(this.service.newImage);
328
+ normalizeRatio(ratio) {
329
+ let width = 1;
330
+ let height = 1;
331
+ if (ratio && ratio.includes(':')) {
332
+ const [rawW, rawH] = ratio.split(':').map(Number);
333
+ if (rawW > 0 && rawH > 0) {
334
+ width = rawW;
335
+ height = rawH;
336
+ }
337
+ }
338
+ if (width >= height) {
339
+ return { width: width / height, height: 1 };
340
+ }
341
+ return { width: 1, height: height / width };
367
342
  }
368
- /** @ignore */
369
- canvasResponsive(image) {
370
- const imageWidth = image.width;
371
- const imageHeight = image.height;
372
- this.originalWidth.set(imageWidth);
373
- this.originalHeight.set(imageHeight);
374
- if (imageWidth > imageHeight) {
375
- this.canvasElem().nativeElement.width = imageWidth;
376
- this.canvasElem().nativeElement.height = imageWidth;
343
+ centerOnParent() {
344
+ const host = this.elementRef.nativeElement;
345
+ const { width: maxW, height: maxH } = this.getImageBounds();
346
+ if (!maxW || !maxH) {
347
+ return;
377
348
  }
378
- else {
379
- this.canvasElem().nativeElement.width = imageHeight;
380
- this.canvasElem().nativeElement.height = imageHeight;
349
+ const left = Math.max(0, (maxW - host.offsetWidth) / 2);
350
+ const top = Math.max(0, (maxH - host.offsetHeight) / 2);
351
+ this.currentX.set(left);
352
+ this.currentY.set(top);
353
+ this.clampToParent();
354
+ }
355
+ getImageBounds() {
356
+ const stage = this.elementRef.nativeElement.parentElement;
357
+ const canvas = stage?.querySelector('canvas.ax-canvas-element');
358
+ if (canvas instanceof HTMLCanvasElement) {
359
+ return {
360
+ width: canvas.clientWidth,
361
+ height: canvas.clientHeight,
362
+ };
363
+ }
364
+ return {
365
+ width: stage?.clientWidth ?? 0,
366
+ height: stage?.clientHeight ?? 0,
367
+ };
368
+ }
369
+ constrainCropBox(left, top, width, height) {
370
+ const { width: maxW, height: maxH } = this.getImageBounds();
371
+ if (!maxW || !maxH) {
372
+ return { left, top, width, height };
381
373
  }
382
- requestAnimationFrame(() => {
383
- //recalculate width after canvas size change
384
- const recalculateWidth = this.canvasElem().nativeElement.getClientRects()[0]?.width;
385
- let scale;
386
- if (imageWidth > imageHeight) {
387
- scale = this.originalWidth() / recalculateWidth;
374
+ const minSize = 20;
375
+ const locked = !!this.service.cropperRatio();
376
+ const aspect = this.aspectWidth() / this.aspectHeight();
377
+ width = Math.max(minSize, width);
378
+ height = Math.max(minSize, height);
379
+ if (locked) {
380
+ height = width / aspect;
381
+ if (height < minSize) {
382
+ height = minSize;
383
+ width = height * aspect;
388
384
  }
389
- else {
390
- scale = this.originalHeight() / recalculateWidth;
385
+ }
386
+ const fitScale = Math.min(1, maxW / width, maxH / height);
387
+ width *= fitScale;
388
+ height *= fitScale;
389
+ if (locked) {
390
+ height = width / aspect;
391
+ if (height > maxH) {
392
+ height = maxH;
393
+ width = height * aspect;
391
394
  }
392
- this.scale.set(scale);
393
- this.canvasElem().nativeElement.width = recalculateWidth;
394
- this.canvasElem().nativeElement.height = recalculateWidth;
395
- if (imageWidth > imageHeight) {
396
- this.ctx().drawImage(image, 0, recalculateWidth / 2 - this.originalHeight() / scale / 2, recalculateWidth, this.originalHeight() / scale);
395
+ if (width > maxW) {
396
+ width = maxW;
397
+ height = width / aspect;
397
398
  }
398
- else {
399
- this.ctx().drawImage(image, recalculateWidth / 2 - this.originalWidth() / scale / 2, 0, this.originalWidth() / scale, recalculateWidth);
399
+ }
400
+ width = Math.max(minSize, Math.min(width, maxW));
401
+ height = Math.max(minSize, Math.min(height, maxH));
402
+ left = Math.max(0, Math.min(left, maxW - width));
403
+ top = Math.max(0, Math.min(top, maxH - height));
404
+ width = Math.min(width, maxW - left);
405
+ height = Math.min(height, maxH - top);
406
+ if (locked) {
407
+ const scale = Math.min(1, (maxW - left) / width, (maxH - top) / height);
408
+ width = Math.max(minSize, width * scale);
409
+ height = width / aspect;
410
+ }
411
+ return { left, top, width, height };
412
+ }
413
+ clampToParent() {
414
+ const host = this.elementRef.nativeElement;
415
+ const constrained = this.constrainCropBox(this.currentX(), this.currentY(), host.offsetWidth, host.offsetHeight);
416
+ host.style.width = `${constrained.width}px`;
417
+ host.style.height = `${constrained.height}px`;
418
+ this.currentX.set(constrained.left);
419
+ this.currentY.set(constrained.top);
420
+ this.applyPosition();
421
+ }
422
+ applyPosition() {
423
+ const host = this.elementRef.nativeElement;
424
+ host.style.left = `${this.currentX()}px`;
425
+ host.style.top = `${this.currentY()}px`;
426
+ }
427
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorCropperWindowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
428
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: AXImageEditorCropperWindowComponent, isStandalone: true, selector: "ax-image-editor-cropper-window", inputs: { showGrid: { classPropertyName: "showGrid", publicName: "showGrid", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, providers: [{ provide: AXComponent, useExisting: AXImageEditorCropperWindowComponent }], viewQueries: [{ propertyName: "cropperWindow", first: true, predicate: ["r"], descendants: true, isSignal: true }], ngImport: i0, template: "<div [style.border]=\"!showGrid() ? '1px dashed white' : null\" #r class=\"ax-image-cropper-window-container\">\n @if (!service.cropperRatio()) {\n <div (pointerdown)=\"handleSelector($event, 'right')\" class=\"ax-image-right-handle ax-handle-shape\"></div>\n <div (pointerdown)=\"handleSelector($event, 'top')\" class=\"ax-image-top-handle ax-handle-shape\"></div>\n <div (pointerdown)=\"handleSelector($event, 'left')\" class=\"ax-image-left-handle ax-handle-shape\"></div>\n <div (pointerdown)=\"handleSelector($event, 'bottom')\" class=\"ax-image-bottom-handle ax-handle-shape\"></div>\n }\n\n <div (pointerdown)=\"handleSelector($event, 'right-top')\" class=\"ax-image-right-top-handle ax-handle-shape\"></div>\n <div\n (pointerdown)=\"handleSelector($event, 'bottom-right')\"\n class=\"ax-image-bottom-right-handle ax-handle-shape\"\n ></div>\n <div (pointerdown)=\"handleSelector($event, 'bottom-left')\" class=\"ax-image-bottom-left-handle ax-handle-shape\"></div>\n <div (pointerdown)=\"handleSelector($event, 'left-top')\" class=\"ax-image-left-top-handle ax-handle-shape\"></div>\n\n @if (showGrid()) {\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n }\n</div>\n", styles: ["@layer properties;@layer components{ax-image-editor-cropper-window{position:absolute;top:calc(var(--spacing, .25rem) * 0);left:calc(var(--spacing, .25rem) * 0);touch-action:none;-webkit-user-select:none;user-select:none}ax-image-editor-cropper-window .ax-image-cropper-window-container{position:relative;display:grid;height:100%;cursor:move;grid-template-columns:repeat(3,minmax(0,1fr));outline-style:var(--tw-outline-style);outline-width:100vmax;outline-color:color-mix(in srgb,#000 70%,transparent);--tw-outline-style: solid;outline-style:solid}@supports (color: color-mix(in lab,red,red)){ax-image-editor-cropper-window .ax-image-cropper-window-container{outline-color:color-mix(in oklab,var(--color-black, #000) 70%,transparent)}}ax-image-editor-cropper-window .ax-image-cropper-window-container .ax-grid-item{border-style:var(--tw-border-style);border-width:1px;--tw-border-style: dashed;border-style:dashed;border-color:color-mix(in srgb,#fff 50%,transparent)}@supports (color: color-mix(in lab,red,red)){ax-image-editor-cropper-window .ax-image-cropper-window-container .ax-grid-item{border-color:color-mix(in oklab,var(--color-white, #fff) 50%,transparent)}}ax-image-editor-cropper-window .ax-handle-shape{position:absolute;height:calc(var(--spacing, .25rem) * 4);width:calc(var(--spacing, .25rem) * 4);border-style:var(--tw-border-style);border-width:1px;--tw-border-style: dashed;border-style:dashed;border-color:var(--color-white, #fff);background-color:var(--color-gray-500, oklch(55.1% .027 264.364));-webkit-user-select:none;user-select:none}ax-image-editor-cropper-window .ax-image-right-top-handle{top:calc(var(--spacing, .25rem) * -2);right:calc(var(--spacing, .25rem) * -2);cursor:ne-resize}ax-image-editor-cropper-window .ax-image-bottom-right-handle{right:calc(var(--spacing, .25rem) * -2);bottom:calc(var(--spacing, .25rem) * -2);cursor:se-resize}ax-image-editor-cropper-window .ax-image-right-handle{top:calc(50% - .5rem);right:calc(var(--spacing, .25rem) * -2);cursor:e-resize}ax-image-editor-cropper-window .ax-image-bottom-left-handle{bottom:calc(var(--spacing, .25rem) * -2);left:calc(var(--spacing, .25rem) * -2);cursor:sw-resize}ax-image-editor-cropper-window .ax-image-left-top-handle{top:calc(var(--spacing, .25rem) * -2);left:calc(var(--spacing, .25rem) * -2);cursor:nw-resize}ax-image-editor-cropper-window .ax-image-bottom-handle{right:calc(50% - .5rem);bottom:calc(var(--spacing, .25rem) * -2);cursor:s-resize}ax-image-editor-cropper-window .ax-image-left-handle{top:calc(50% - .5rem);left:calc(var(--spacing, .25rem) * -2);cursor:w-resize}ax-image-editor-cropper-window .ax-image-top-handle{top:calc(var(--spacing, .25rem) * -2);right:calc(50% - .5rem);cursor:n-resize}}@property --tw-outline-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-outline-style: solid;--tw-border-style: solid}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
429
+ }
430
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorCropperWindowComponent, decorators: [{
431
+ type: Component,
432
+ args: [{ selector: 'ax-image-editor-cropper-window', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: AXComponent, useExisting: AXImageEditorCropperWindowComponent }], template: "<div [style.border]=\"!showGrid() ? '1px dashed white' : null\" #r class=\"ax-image-cropper-window-container\">\n @if (!service.cropperRatio()) {\n <div (pointerdown)=\"handleSelector($event, 'right')\" class=\"ax-image-right-handle ax-handle-shape\"></div>\n <div (pointerdown)=\"handleSelector($event, 'top')\" class=\"ax-image-top-handle ax-handle-shape\"></div>\n <div (pointerdown)=\"handleSelector($event, 'left')\" class=\"ax-image-left-handle ax-handle-shape\"></div>\n <div (pointerdown)=\"handleSelector($event, 'bottom')\" class=\"ax-image-bottom-handle ax-handle-shape\"></div>\n }\n\n <div (pointerdown)=\"handleSelector($event, 'right-top')\" class=\"ax-image-right-top-handle ax-handle-shape\"></div>\n <div\n (pointerdown)=\"handleSelector($event, 'bottom-right')\"\n class=\"ax-image-bottom-right-handle ax-handle-shape\"\n ></div>\n <div (pointerdown)=\"handleSelector($event, 'bottom-left')\" class=\"ax-image-bottom-left-handle ax-handle-shape\"></div>\n <div (pointerdown)=\"handleSelector($event, 'left-top')\" class=\"ax-image-left-top-handle ax-handle-shape\"></div>\n\n @if (showGrid()) {\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n <div class=\"ax-grid-item\"></div>\n }\n</div>\n", styles: ["@layer properties;@layer components{ax-image-editor-cropper-window{position:absolute;top:calc(var(--spacing, .25rem) * 0);left:calc(var(--spacing, .25rem) * 0);touch-action:none;-webkit-user-select:none;user-select:none}ax-image-editor-cropper-window .ax-image-cropper-window-container{position:relative;display:grid;height:100%;cursor:move;grid-template-columns:repeat(3,minmax(0,1fr));outline-style:var(--tw-outline-style);outline-width:100vmax;outline-color:color-mix(in srgb,#000 70%,transparent);--tw-outline-style: solid;outline-style:solid}@supports (color: color-mix(in lab,red,red)){ax-image-editor-cropper-window .ax-image-cropper-window-container{outline-color:color-mix(in oklab,var(--color-black, #000) 70%,transparent)}}ax-image-editor-cropper-window .ax-image-cropper-window-container .ax-grid-item{border-style:var(--tw-border-style);border-width:1px;--tw-border-style: dashed;border-style:dashed;border-color:color-mix(in srgb,#fff 50%,transparent)}@supports (color: color-mix(in lab,red,red)){ax-image-editor-cropper-window .ax-image-cropper-window-container .ax-grid-item{border-color:color-mix(in oklab,var(--color-white, #fff) 50%,transparent)}}ax-image-editor-cropper-window .ax-handle-shape{position:absolute;height:calc(var(--spacing, .25rem) * 4);width:calc(var(--spacing, .25rem) * 4);border-style:var(--tw-border-style);border-width:1px;--tw-border-style: dashed;border-style:dashed;border-color:var(--color-white, #fff);background-color:var(--color-gray-500, oklch(55.1% .027 264.364));-webkit-user-select:none;user-select:none}ax-image-editor-cropper-window .ax-image-right-top-handle{top:calc(var(--spacing, .25rem) * -2);right:calc(var(--spacing, .25rem) * -2);cursor:ne-resize}ax-image-editor-cropper-window .ax-image-bottom-right-handle{right:calc(var(--spacing, .25rem) * -2);bottom:calc(var(--spacing, .25rem) * -2);cursor:se-resize}ax-image-editor-cropper-window .ax-image-right-handle{top:calc(50% - .5rem);right:calc(var(--spacing, .25rem) * -2);cursor:e-resize}ax-image-editor-cropper-window .ax-image-bottom-left-handle{bottom:calc(var(--spacing, .25rem) * -2);left:calc(var(--spacing, .25rem) * -2);cursor:sw-resize}ax-image-editor-cropper-window .ax-image-left-top-handle{top:calc(var(--spacing, .25rem) * -2);left:calc(var(--spacing, .25rem) * -2);cursor:nw-resize}ax-image-editor-cropper-window .ax-image-bottom-handle{right:calc(50% - .5rem);bottom:calc(var(--spacing, .25rem) * -2);cursor:s-resize}ax-image-editor-cropper-window .ax-image-left-handle{top:calc(50% - .5rem);left:calc(var(--spacing, .25rem) * -2);cursor:w-resize}ax-image-editor-cropper-window .ax-image-top-handle{top:calc(var(--spacing, .25rem) * -2);right:calc(50% - .5rem);cursor:n-resize}}@property --tw-outline-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-outline-style: solid;--tw-border-style: solid}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"] }]
433
+ }], propDecorators: { showGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGrid", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], cropperWindow: [{ type: i0.ViewChild, args: ['r', { isSignal: true }] }] } });
434
+
435
+ const IMAGE_EDITOR_MAX_BUFFER = 4096;
436
+ const IMAGE_EDITOR_EXPORT_QUALITY = 1;
437
+ function loadHtmlImage(src) {
438
+ return new Promise((resolve, reject) => {
439
+ const image = new Image();
440
+ if (!src.startsWith('data:') && !src.startsWith('blob:')) {
441
+ image.crossOrigin = 'anonymous';
442
+ }
443
+ image.onload = () => resolve(image);
444
+ image.onerror = () => reject(new Error('Failed to load image'));
445
+ image.src = src;
446
+ });
447
+ }
448
+ function canvasToBlob(canvas, type, quality) {
449
+ return new Promise((resolve, reject) => {
450
+ canvas.toBlob((blob) => {
451
+ if (blob) {
452
+ resolve(blob);
453
+ return;
400
454
  }
401
- });
455
+ reject(new Error(`toBlob returned null for type ${type}`));
456
+ }, type, quality);
457
+ });
458
+ }
459
+ async function canvasToEditorBlobs(canvas) {
460
+ const jpeg = await canvasToBlob(canvas, 'image/jpeg', IMAGE_EDITOR_EXPORT_QUALITY);
461
+ const extra = await Promise.allSettled([
462
+ canvasToBlob(canvas, 'image/png'),
463
+ canvasToBlob(canvas, 'image/webp', IMAGE_EDITOR_EXPORT_QUALITY),
464
+ ]);
465
+ const blobs = [jpeg];
466
+ for (const result of extra) {
467
+ if (result.status === 'fulfilled') {
468
+ blobs.push(result.value);
469
+ }
402
470
  }
403
- /** @ignore */
471
+ return blobs;
472
+ }
473
+ function bufferSizeForImage(width, height, max = IMAGE_EDITOR_MAX_BUFFER) {
474
+ const scale = Math.min(1, max / Math.max(width, height, 1));
475
+ return {
476
+ width: Math.max(1, Math.round(width * scale)),
477
+ height: Math.max(1, Math.round(height * scale)),
478
+ };
479
+ }
480
+
481
+ class AXImageEditorViewComponent extends MXBaseComponent {
404
482
  constructor() {
405
483
  super();
406
484
  /**
@@ -442,44 +520,80 @@ class AXImageEditorViewComponent extends MXBaseComponent {
442
520
  ...(ngDevMode ? [{ debugName: "isDrawRectangleCreated" }] : /* istanbul ignore next */ []));
443
521
  /** @ignore */
444
522
  this.parent = inject(AXImageEditorContainerComponent);
445
- /** @ignore */
446
- this.renderer = inject(Renderer2);
523
+ this.destroyRef = inject(DestroyRef);
524
+ this.host = inject((ElementRef));
447
525
  /** @ignore */
448
526
  this.imageEditorHistory = signal([], /* @ts-ignore */
449
527
  ...(ngDevMode ? [{ debugName: "imageEditorHistory" }] : /* istanbul ignore next */ []));
450
528
  /** @ignore */
451
- this.imageEditorHistoryPointer = linkedSignal(() => this.imageEditorHistory().length - 1, /* @ts-ignore */
529
+ this.imageEditorHistoryPointer = signal(-1, /* @ts-ignore */
452
530
  ...(ngDevMode ? [{ debugName: "imageEditorHistoryPointer" }] : /* istanbul ignore next */ []));
453
- this.originalWidth = signal(0, /* @ts-ignore */
454
- ...(ngDevMode ? [{ debugName: "originalWidth" }] : /* istanbul ignore next */ []));
455
- this.originalHeight = signal(0, /* @ts-ignore */
456
- ...(ngDevMode ? [{ debugName: "originalHeight" }] : /* istanbul ignore next */ []));
457
- this.scale = signal(0, /* @ts-ignore */
458
- ...(ngDevMode ? [{ debugName: "scale" }] : /* istanbul ignore next */ []));
531
+ this.canvasReady = signal(false, /* @ts-ignore */
532
+ ...(ngDevMode ? [{ debugName: "canvasReady" }] : /* istanbul ignore next */ []));
533
+ this.drawing = false;
534
+ this.didDraw = false;
535
+ this.highlightSnapshot = null;
536
+ this.highlightPoints = [];
537
+ this.persistGeneration = 0;
538
+ this.sourceToken = 0;
459
539
  afterNextRender(() => {
460
- this.resizeEventListener = this.renderer.listen(window, 'resize', this.resizeWindow.bind(this));
461
- //set canvas options
462
- this.ctx.set(this.canvasElem().nativeElement.getContext('2d', { willReadFrequently: true }));
463
- this.ctx().lineJoin = 'round';
464
- this.ctx().lineCap = 'round';
540
+ const canvas = this.canvasElem()?.nativeElement;
541
+ if (!canvas) {
542
+ return;
543
+ }
544
+ const ctx = canvas.getContext('2d', { willReadFrequently: true });
545
+ if (!ctx) {
546
+ return;
547
+ }
548
+ ctx.lineJoin = 'round';
549
+ ctx.lineCap = 'round';
550
+ this.ctx.set(ctx);
551
+ this.canvasReady.set(true);
552
+ const onResize = () => this.fitCanvasDisplay();
553
+ window.addEventListener('resize', onResize);
554
+ this.destroyRef.onDestroy(() => window.removeEventListener('resize', onResize));
465
555
  });
466
556
  effect(() => {
467
- this.setInitialImage(this.src());
557
+ const src = this.src();
558
+ const ready = this.canvasReady();
559
+ if (!ready) {
560
+ return;
561
+ }
562
+ untracked(() => void this.loadSource(src));
468
563
  });
469
564
  effect(() => {
470
565
  if (!this.service.undoPressed()) {
471
- this.imageChanged();
566
+ return;
472
567
  }
568
+ untracked(() => {
569
+ this.applyUndo();
570
+ this.service.undoPressed.set(false);
571
+ });
473
572
  });
474
573
  effect(() => {
475
574
  if (!this.service.redoPressed()) {
476
- this.imageChanged();
575
+ return;
477
576
  }
577
+ untracked(() => {
578
+ this.applyRedo();
579
+ this.service.redoPressed.set(false);
580
+ });
478
581
  });
479
582
  effect(() => {
480
- if (!this.service.rotate().userInteract || !this.ctx())
583
+ const rotate = this.service.rotate();
584
+ const ctx = this.ctx();
585
+ if (!rotate.userInteract || !ctx) {
481
586
  return;
482
- this.rotateImage();
587
+ }
588
+ untracked(() => void this.rotateImage());
589
+ });
590
+ effect(() => {
591
+ if (!this.service.isImageLoad()) {
592
+ return;
593
+ }
594
+ untracked(() => {
595
+ requestAnimationFrame(() => this.fitCanvasDisplay());
596
+ });
483
597
  });
484
598
  effect(() => {
485
599
  const size = this.cropperSize();
@@ -489,167 +603,363 @@ class AXImageEditorViewComponent extends MXBaseComponent {
489
603
  });
490
604
  }
491
605
  /** @ignore */
492
- ngOnDestroy() {
493
- if (this.resizeEventListener) {
494
- this.resizeEventListener();
495
- }
496
- if (this.imageLoadEventListener) {
497
- this.imageLoadEventListener();
498
- }
606
+ resizeWindow() {
607
+ this.fitCanvasDisplay();
499
608
  }
500
- setInitialImage(src, replaceHistory = true) {
501
- this.service.initialImage = new Image();
502
- this.service.initialImage.src = src;
503
- this.service.initialImage.crossOrigin = 'anonymous';
504
- this.imageLoadEventListener = this.renderer.listen(this.service.initialImage, 'load', () => {
505
- this.service.newImage = this.service.initialImage;
506
- this.service.isImageLoad.set(true);
507
- this.canvasResponsive(this.service.initialImage);
508
- if (replaceHistory) {
509
- this.imageEditorHistory.set([this.service.initialImage]);
609
+ /** @ignore */
610
+ canvasResponsive(image) {
611
+ this.paintImage(image);
612
+ }
613
+ async loadSource(src) {
614
+ const token = ++this.sourceToken;
615
+ this.service.loadError.set(false);
616
+ this.service.isImageLoad.set(false);
617
+ this.service.imageBlob.set([]);
618
+ this.service.newImage = null;
619
+ this.service.initialImage = null;
620
+ if (!src) {
621
+ return;
622
+ }
623
+ try {
624
+ const image = await loadHtmlImage(src);
625
+ if (token !== this.sourceToken) {
626
+ return;
510
627
  }
511
- else {
512
- this.imageEditorHistory.update((prev) => [...prev, this.service.initialImage]);
628
+ this.service.initialImage = image;
629
+ this.service.newImage = image;
630
+ this.replaceHistory(image);
631
+ this.paintImage(image);
632
+ this.service.isImageLoad.set(true);
633
+ }
634
+ catch {
635
+ if (token !== this.sourceToken) {
636
+ return;
513
637
  }
514
- });
638
+ this.service.loadError.set(true);
639
+ this.service.isImageLoad.set(false);
640
+ }
515
641
  }
516
- /** @ignore */
517
- imageChanged() {
518
- if (this.service.undoPressed() && this.imageEditorHistoryPointer() >= 1) {
519
- this.imageEditorHistoryPointer.update((prev) => prev - 1);
520
- this.service.newImage = this.imageEditorHistory()[this.imageEditorHistoryPointer()];
521
- this.canvasResponsive(this.imageEditorHistory()[this.imageEditorHistoryPointer()]);
642
+ paintImage(image) {
643
+ const canvas = this.canvasElem()?.nativeElement;
644
+ const ctx = this.ctx();
645
+ if (!canvas || !ctx || !image) {
646
+ return;
522
647
  }
523
- if (this.service.redoPressed() && this.imageEditorHistoryPointer() < this.imageEditorHistory().length - 1) {
524
- this.imageEditorHistoryPointer.update((prev) => prev + 1);
525
- this.service.newImage = this.imageEditorHistory()[this.imageEditorHistoryPointer()];
526
- this.canvasResponsive(this.imageEditorHistory()[this.imageEditorHistoryPointer()]);
648
+ const buffer = bufferSizeForImage(image.naturalWidth || image.width, image.naturalHeight || image.height);
649
+ canvas.width = buffer.width;
650
+ canvas.height = buffer.height;
651
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
652
+ ctx.globalAlpha = 1;
653
+ ctx.globalCompositeOperation = 'source-over';
654
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
655
+ ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
656
+ this.fitCanvasDisplay();
657
+ }
658
+ fitCanvasDisplay() {
659
+ const canvas = this.canvasElem()?.nativeElement;
660
+ if (!canvas?.width || !canvas.height) {
661
+ return;
662
+ }
663
+ const parent = this.host.nativeElement;
664
+ const maxW = Math.max(parent?.clientWidth || 0, 240);
665
+ const maxH = Math.min(window.innerHeight * 0.55, 560);
666
+ const scale = Math.min(maxW / canvas.width, maxH / canvas.height, 1);
667
+ canvas.style.width = `${Math.max(1, Math.round(canvas.width * scale))}px`;
668
+ canvas.style.height = `${Math.max(1, Math.round(canvas.height * scale))}px`;
669
+ }
670
+ replaceHistory(image) {
671
+ this.imageEditorHistory.set([image]);
672
+ this.imageEditorHistoryPointer.set(0);
673
+ this.syncHistoryFlags();
674
+ }
675
+ pushHistory(image) {
676
+ const pointer = this.imageEditorHistoryPointer();
677
+ const next = this.imageEditorHistory().slice(0, pointer + 1);
678
+ next.push(image);
679
+ this.imageEditorHistory.set(next);
680
+ this.imageEditorHistoryPointer.set(next.length - 1);
681
+ this.syncHistoryFlags();
682
+ }
683
+ syncHistoryFlags() {
684
+ const pointer = this.imageEditorHistoryPointer();
685
+ const length = this.imageEditorHistory().length;
686
+ this.service.canUndo.set(pointer > 0);
687
+ this.service.canRedo.set(pointer >= 0 && pointer < length - 1);
688
+ }
689
+ applyUndo() {
690
+ const pointer = this.imageEditorHistoryPointer();
691
+ if (pointer < 1) {
692
+ this.syncHistoryFlags();
693
+ return;
694
+ }
695
+ const nextPointer = pointer - 1;
696
+ const image = this.imageEditorHistory()[nextPointer];
697
+ this.imageEditorHistoryPointer.set(nextPointer);
698
+ this.service.newImage = image;
699
+ this.paintImage(image);
700
+ this.syncHistoryFlags();
701
+ void this.persistCanvas({ skipHistory: true });
702
+ }
703
+ applyRedo() {
704
+ const history = this.imageEditorHistory();
705
+ const pointer = this.imageEditorHistoryPointer();
706
+ if (pointer >= history.length - 1) {
707
+ this.syncHistoryFlags();
708
+ return;
527
709
  }
528
- this.service.undoPressed.set(false);
529
- this.service.redoPressed.set(false);
710
+ const nextPointer = pointer + 1;
711
+ const image = history[nextPointer];
712
+ this.imageEditorHistoryPointer.set(nextPointer);
713
+ this.service.newImage = image;
714
+ this.paintImage(image);
715
+ this.syncHistoryFlags();
716
+ void this.persistCanvas({ skipHistory: true });
717
+ }
718
+ canvasPoint(event) {
719
+ const canvas = this.canvasElem().nativeElement;
720
+ const rect = canvas.getBoundingClientRect();
721
+ const width = rect.width || 1;
722
+ const height = rect.height || 1;
723
+ return {
724
+ x: ((event.clientX - rect.left) / width) * canvas.width,
725
+ y: ((event.clientY - rect.top) / height) * canvas.height,
726
+ };
727
+ }
728
+ isDrawTool() {
729
+ const tool = this.service.penType();
730
+ return tool === 'pen' || tool === 'highlight';
530
731
  }
531
732
  /** @ignore */
532
733
  penConfigHandler(penType) {
734
+ const ctx = this.ctx();
735
+ if (!ctx) {
736
+ return;
737
+ }
738
+ ctx.lineJoin = 'round';
739
+ ctx.lineCap = 'round';
533
740
  switch (penType) {
534
741
  case 'pen':
535
- this.ctx().globalAlpha = 1;
536
- this.ctx().strokeStyle = this.service.penColor();
537
- this.ctx().lineWidth = this.service.penWidth();
742
+ ctx.globalAlpha = 1;
743
+ ctx.globalCompositeOperation = 'source-over';
744
+ ctx.strokeStyle = this.service.penColor();
745
+ ctx.lineWidth = this.service.penWidth();
538
746
  break;
539
747
  case 'highlight':
540
- this.ctx().globalAlpha = 0.008;
541
- this.ctx().strokeStyle = this.service.highlightColor();
542
- this.ctx().lineWidth = this.service.highlightWidth();
748
+ ctx.globalAlpha = 0.4;
749
+ ctx.globalCompositeOperation = 'multiply';
750
+ ctx.strokeStyle = this.service.highlightColor();
751
+ ctx.lineWidth = this.service.highlightWidth();
543
752
  break;
544
753
  }
545
754
  }
755
+ strokeHighlight(points) {
756
+ const ctx = this.ctx();
757
+ if (!ctx || points.length === 0) {
758
+ return;
759
+ }
760
+ this.penConfigHandler('highlight');
761
+ ctx.beginPath();
762
+ ctx.moveTo(points[0].x, points[0].y);
763
+ for (let i = 1; i < points.length; i++) {
764
+ ctx.lineTo(points[i].x, points[i].y);
765
+ }
766
+ if (points.length === 1) {
767
+ ctx.lineTo(points[0].x, points[0].y);
768
+ }
769
+ ctx.stroke();
770
+ }
546
771
  /** @ignore */
547
- mouseDownHandler(e) {
548
- this.isMouseDown.set(true);
549
- if (!this.service.penType())
772
+ historyKeyDown(event) {
773
+ if (this.parent.disabled) {
550
774
  return;
551
- this.penConfigHandler(this.service.penType());
552
- this.ctx().beginPath();
553
- this.ctx().moveTo(e.offsetX, e.offsetY);
554
- this.ctx().lineTo(e.offsetX, e.offsetY);
555
- this.ctx().stroke();
775
+ }
776
+ this.service.handleHistoryShortcut(event);
777
+ }
778
+ /** @ignore */
779
+ focusCanvas() {
780
+ this.canvasElem()?.nativeElement.focus({ preventScroll: true });
556
781
  }
557
782
  /** @ignore */
558
- mouseMoveHandler(e) {
559
- if (!this.isMouseDown())
783
+ mouseDownHandler(event) {
784
+ this.focusCanvas();
785
+ if (!this.isDrawTool() || this.parent.disabled) {
560
786
  return;
561
- if (!this.service.penType())
787
+ }
788
+ const ctx = this.ctx();
789
+ const canvas = this.canvasElem()?.nativeElement;
790
+ const penType = this.service.penType();
791
+ if (!ctx || !canvas || !penType) {
562
792
  return;
563
- this.ctx().lineTo(e.offsetX, e.offsetY);
564
- this.ctx().stroke();
793
+ }
794
+ event.preventDefault();
795
+ canvas.setPointerCapture(event.pointerId);
796
+ this.isMouseDown.set(true);
797
+ this.drawing = true;
798
+ this.didDraw = false;
799
+ const point = this.canvasPoint(event);
800
+ this.penConfigHandler(penType);
801
+ if (penType === 'highlight') {
802
+ this.highlightSnapshot = ctx.getImageData(0, 0, canvas.width, canvas.height);
803
+ this.highlightPoints = [point];
804
+ this.strokeHighlight(this.highlightPoints);
805
+ }
806
+ else {
807
+ ctx.beginPath();
808
+ ctx.moveTo(point.x, point.y);
809
+ ctx.lineTo(point.x, point.y);
810
+ ctx.stroke();
811
+ }
812
+ this.didDraw = true;
565
813
  }
566
814
  /** @ignore */
567
- mouseUpHandler() {
568
- this.isMouseDown.set(false);
569
- this.ctx().closePath();
570
- this.saveImageChange();
815
+ mouseMoveHandler(event) {
816
+ if (!this.drawing || !this.isDrawTool()) {
817
+ return;
818
+ }
819
+ const ctx = this.ctx();
820
+ const canvas = this.canvasElem()?.nativeElement;
821
+ const penType = this.service.penType();
822
+ if (!ctx || !canvas || !penType) {
823
+ return;
824
+ }
825
+ const point = this.canvasPoint(event);
826
+ if (penType === 'highlight' && this.highlightSnapshot) {
827
+ ctx.putImageData(this.highlightSnapshot, 0, 0);
828
+ this.highlightPoints.push(point);
829
+ this.strokeHighlight(this.highlightPoints);
830
+ }
831
+ else {
832
+ ctx.lineTo(point.x, point.y);
833
+ ctx.stroke();
834
+ }
835
+ this.didDraw = true;
571
836
  }
572
837
  /** @ignore */
838
+ mouseUpHandler(event) {
839
+ const canvas = this.canvasElem()?.nativeElement;
840
+ if (event && canvas?.hasPointerCapture(event.pointerId)) {
841
+ canvas.releasePointerCapture(event.pointerId);
842
+ }
843
+ const wasDrawing = this.drawing && this.didDraw;
844
+ this.drawing = false;
845
+ this.didDraw = false;
846
+ this.isMouseDown.set(false);
847
+ this.highlightSnapshot = null;
848
+ this.highlightPoints = [];
849
+ const ctx = this.ctx();
850
+ if (ctx) {
851
+ ctx.closePath();
852
+ ctx.globalAlpha = 1;
853
+ ctx.globalCompositeOperation = 'source-over';
854
+ }
855
+ if (wasDrawing) {
856
+ void this.persistCanvas();
857
+ }
858
+ }
859
+ /** Applies the current cropper selection. */
573
860
  async crop() {
574
861
  const cropper = this.cropperWindow();
575
- if (this.service.activeToolState() !== 'crop' || !cropper) {
862
+ const ctx = this.ctx();
863
+ const canvas = this.canvasElem()?.nativeElement;
864
+ if (this.service.activeToolState() !== 'crop' || !cropper || !ctx || !canvas) {
576
865
  return;
577
866
  }
578
867
  const cropRect = cropper.getCropperArea();
579
- const canvas = this.canvasElem().nativeElement;
580
868
  const canvasRect = canvas.getBoundingClientRect();
581
- const scaleX = canvas.width / canvasRect.width;
582
- const scaleY = canvas.height / canvasRect.height;
583
- const dx = (cropRect.x - canvasRect.x) * scaleX;
584
- const dy = (cropRect.y - canvasRect.y) * scaleY;
585
- const cropWidth = cropRect.width * scaleX;
586
- const cropHeight = cropRect.height * scaleY;
587
- const imageData = this.ctx().getImageData(Math.round(dx), Math.round(dy), Math.round(cropWidth), Math.round(cropHeight));
588
- canvas.width = Math.round(cropWidth);
589
- canvas.height = Math.round(cropHeight);
590
- this.ctx().putImageData(imageData, 0, 0);
591
- const cropImage = this.canvasElem().nativeElement.toDataURL('image/jpeg', 1);
592
- await this.saveImageChange();
593
- this.setInitialImage(cropImage, false);
869
+ const scaleX = canvas.width / (canvasRect.width || 1);
870
+ const scaleY = canvas.height / (canvasRect.height || 1);
871
+ const dx = Math.max(0, Math.round((cropRect.x - canvasRect.x) * scaleX));
872
+ const dy = Math.max(0, Math.round((cropRect.y - canvasRect.y) * scaleY));
873
+ const cropWidth = Math.max(1, Math.round(cropRect.width * scaleX));
874
+ const cropHeight = Math.max(1, Math.round(cropRect.height * scaleY));
875
+ const width = Math.min(cropWidth, canvas.width - dx);
876
+ const height = Math.min(cropHeight, canvas.height - dy);
877
+ const imageData = ctx.getImageData(dx, dy, width, height);
878
+ canvas.width = width;
879
+ canvas.height = height;
880
+ ctx.putImageData(imageData, 0, 0);
881
+ this.fitCanvasDisplay();
594
882
  this.service.activeToolState.set(null);
883
+ this.service.penType.set(null);
884
+ await this.persistCanvas();
595
885
  }
596
- /** @ignore */
597
- rotateImage() {
598
- this.ctx().globalAlpha = 1;
599
- this.ctx().save();
600
- this.ctx().clearRect(0, 0, this.canvasElem().nativeElement.width, this.canvasElem().nativeElement.height);
601
- // Calculate scale factor to fit rotated image within canvas
602
- const rotationAngle = (this.service.rotate().state * Math.PI) / 180;
603
- const cos = Math.abs(Math.cos(rotationAngle));
604
- const sin = Math.abs(Math.sin(rotationAngle));
605
- const rotatedWidth = this.service.newImage.width * cos + this.service.newImage.height * sin;
606
- const rotatedHeight = this.service.newImage.width * sin + this.service.newImage.height * cos;
607
- const scaleX = this.canvasElem().nativeElement.width / rotatedWidth;
608
- const scaleY = this.canvasElem().nativeElement.height / rotatedHeight;
609
- const scale = Math.min(scaleX, scaleY);
610
- this.ctx().translate(this.canvasElem().nativeElement.width / 2, this.canvasElem().nativeElement.height / 2);
611
- this.ctx().rotate(rotationAngle);
612
- this.ctx().scale(scale, scale);
613
- this.ctx().drawImage(this.service.newImage, -this.service.newImage.width / 2, -this.service.newImage.height / 2);
614
- this.ctx().restore();
615
- this.saveImageChange();
616
- this.service.rotate.update((prev) => {
617
- return { state: prev.state, userInteract: false };
618
- });
886
+ /** Encodes the current canvas into JPEG, PNG, and WebP blobs. */
887
+ async commitChanges() {
888
+ await this.persistCanvas();
889
+ return this.service.imageBlob();
619
890
  }
620
891
  /** @ignore */
621
- async saveImageChange() {
622
- const canvas = this.canvasElem().nativeElement;
623
- const newImage = new Image();
624
- newImage.crossOrigin = 'anonymous';
625
- newImage.src = canvas.toDataURL('image/jpeg', 1);
626
- this.service.newImage = newImage;
627
- this.imageEditorHistory.update((prev) => [...prev, newImage]);
628
- const canvasToBlob = (type, quality) => {
629
- return new Promise((resolve, reject) => {
630
- canvas.toBlob((blob) => {
631
- if (blob) {
632
- resolve(blob);
633
- }
634
- else {
635
- reject(new Error(`toBlob returned null for type ${type}`));
636
- }
637
- }, type, quality);
638
- });
639
- };
640
- const blobs = await Promise.all([
641
- canvasToBlob('image/jpeg', 1),
642
- canvasToBlob('image/png', 1),
643
- canvasToBlob('image/webp', 1),
644
- ]);
645
- this.service.imageBlob.set(blobs);
646
- }
647
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
648
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXImageEditorViewComponent, isStandalone: true, selector: "ax-image-editor-view", inputs: { showGrid: { classPropertyName: "showGrid", publicName: "showGrid", isSignal: true, isRequired: false, transformFunction: null }, cropperSize: { classPropertyName: "cropperSize", publicName: "cropperSize", isSignal: true, isRequired: false, transformFunction: null }, src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: false, transformFunction: null } }, providers: [{ provide: AXComponent, useExisting: AXImageEditorViewComponent }], viewQueries: [{ propertyName: "canvasElem", first: true, predicate: ["canvasElem"], descendants: true, isSignal: true }, { propertyName: "cropperWindow", first: true, predicate: ["f"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<canvas\n tabindex=\"1\"\n (pointerdown)=\"mouseDownHandler($event)\"\n (pointerup)=\"mouseUpHandler()\"\n (pointermove)=\"mouseMoveHandler($event)\"\n class=\"ax-canvas-element\"\n #canvasElem\n></canvas>\n\n@if (this.service.activeToolState() === 'crop') {\n <ax-image-editor-cropper-window [showGrid]=\"showGrid()\" #f></ax-image-editor-cropper-window>\n}\n", styles: ["@layer components{ax-image-editor-view{position:relative;display:flex;width:100%;touch-action:none;align-items:center;justify-content:center;overflow:hidden;background-color:var(--color-white, #fff)}ax-image-editor-view .ax-canvas-element{cursor:crosshair;background-color:var(--color-black, #000)}ax-image-editor-view .ax-crop-save{position:absolute;top:calc(var(--spacing, .25rem) * 0);right:calc(var(--spacing, .25rem) * 0);margin:calc(var(--spacing, .25rem) * 4)}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: AXImageEditorCropperWindowComponent, selector: "ax-image-editor-cropper-window", inputs: ["showGrid", "size"] }], encapsulation: i0.ViewEncapsulation.None }); }
892
+ async rotateImage() {
893
+ const canvas = this.canvasElem()?.nativeElement;
894
+ const ctx = this.ctx();
895
+ if (!canvas || !ctx || !canvas.width || !canvas.height) {
896
+ this.service.rotate.update((prev) => ({ state: prev.state, userInteract: false }));
897
+ return;
898
+ }
899
+ const source = document.createElement('canvas');
900
+ source.width = canvas.width;
901
+ source.height = canvas.height;
902
+ const sourceCtx = source.getContext('2d');
903
+ if (!sourceCtx) {
904
+ this.service.rotate.update((prev) => ({ state: prev.state, userInteract: false }));
905
+ return;
906
+ }
907
+ sourceCtx.drawImage(canvas, 0, 0);
908
+ const degrees = this.service.rotate().state;
909
+ const radians = (degrees * Math.PI) / 180;
910
+ const cos = Math.abs(Math.cos(radians));
911
+ const sin = Math.abs(Math.sin(radians));
912
+ const rotatedWidth = Math.max(1, Math.round(source.width * cos + source.height * sin));
913
+ const rotatedHeight = Math.max(1, Math.round(source.width * sin + source.height * cos));
914
+ canvas.width = rotatedWidth;
915
+ canvas.height = rotatedHeight;
916
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
917
+ ctx.globalAlpha = 1;
918
+ ctx.globalCompositeOperation = 'source-over';
919
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
920
+ ctx.save();
921
+ ctx.translate(canvas.width / 2, canvas.height / 2);
922
+ ctx.rotate(radians);
923
+ ctx.drawImage(source, -source.width / 2, -source.height / 2);
924
+ ctx.restore();
925
+ this.fitCanvasDisplay();
926
+ await this.persistCanvas();
927
+ this.service.rotate.update((prev) => ({ state: prev.state, userInteract: false }));
928
+ }
929
+ async persistCanvas(options) {
930
+ const canvas = this.canvasElem()?.nativeElement;
931
+ if (!canvas?.width || !canvas.height) {
932
+ return;
933
+ }
934
+ const generation = ++this.persistGeneration;
935
+ try {
936
+ const blobs = await canvasToEditorBlobs(canvas);
937
+ if (generation !== this.persistGeneration) {
938
+ return;
939
+ }
940
+ this.service.imageBlob.set(blobs);
941
+ const dataUrl = canvas.toDataURL('image/jpeg', 1);
942
+ const image = await loadHtmlImage(dataUrl);
943
+ if (generation !== this.persistGeneration) {
944
+ return;
945
+ }
946
+ this.service.newImage = image;
947
+ if (!options?.skipHistory) {
948
+ this.pushHistory(image);
949
+ }
950
+ }
951
+ catch {
952
+ if (generation !== this.persistGeneration) {
953
+ return;
954
+ }
955
+ }
956
+ }
957
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
958
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: AXImageEditorViewComponent, isStandalone: true, selector: "ax-image-editor-view", inputs: { showGrid: { classPropertyName: "showGrid", publicName: "showGrid", isSignal: true, isRequired: false, transformFunction: null }, cropperSize: { classPropertyName: "cropperSize", publicName: "cropperSize", isSignal: true, isRequired: false, transformFunction: null }, src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: false, transformFunction: null } }, providers: [{ provide: AXComponent, useExisting: AXImageEditorViewComponent }], viewQueries: [{ propertyName: "canvasElem", first: true, predicate: ["canvasElem"], descendants: true, isSignal: true }, { propertyName: "cropperWindow", first: true, predicate: ["f"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"ax-image-editor-stage\">\n <canvas\n tabindex=\"0\"\n (pointerdown)=\"mouseDownHandler($event)\"\n (pointerup)=\"mouseUpHandler($event)\"\n (pointercancel)=\"mouseUpHandler($event)\"\n (pointermove)=\"mouseMoveHandler($event)\"\n (keydown)=\"historyKeyDown($event)\"\n class=\"ax-canvas-element\"\n #canvasElem\n ></canvas>\n\n @if (service.activeToolState() === 'crop') {\n <ax-image-editor-cropper-window [showGrid]=\"showGrid()\" #f></ax-image-editor-cropper-window>\n }\n</div>\n", styles: ["@layer components{ax-image-editor-view{position:relative;display:flex;width:100%;touch-action:none;align-items:center;justify-content:center;overflow:hidden;background-color:var(--color-white, #fff)}ax-image-editor-view canvas{height:auto!important;width:auto!important}ax-image-editor-view .ax-image-editor-stage{position:relative;display:inline-flex;max-height:100%;max-width:100%;align-items:center;justify-content:center}ax-image-editor-view .ax-canvas-element{max-height:100%;max-width:100%;cursor:crosshair;background-color:var(--color-black, #000);touch-action:none}ax-image-editor-view .ax-crop-save{position:absolute;top:calc(var(--spacing, .25rem) * 0);right:calc(var(--spacing, .25rem) * 0);margin:calc(var(--spacing, .25rem) * 4)}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: AXImageEditorCropperWindowComponent, selector: "ax-image-editor-cropper-window", inputs: ["showGrid", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
649
959
  }
650
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorViewComponent, decorators: [{
960
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorViewComponent, decorators: [{
651
961
  type: Component,
652
- args: [{ selector: 'ax-image-editor-view', encapsulation: ViewEncapsulation.None, imports: [AXImageEditorCropperWindowComponent], providers: [{ provide: AXComponent, useExisting: AXImageEditorViewComponent }], template: "<canvas\n tabindex=\"1\"\n (pointerdown)=\"mouseDownHandler($event)\"\n (pointerup)=\"mouseUpHandler()\"\n (pointermove)=\"mouseMoveHandler($event)\"\n class=\"ax-canvas-element\"\n #canvasElem\n></canvas>\n\n@if (this.service.activeToolState() === 'crop') {\n <ax-image-editor-cropper-window [showGrid]=\"showGrid()\" #f></ax-image-editor-cropper-window>\n}\n", styles: ["@layer components{ax-image-editor-view{position:relative;display:flex;width:100%;touch-action:none;align-items:center;justify-content:center;overflow:hidden;background-color:var(--color-white, #fff)}ax-image-editor-view .ax-canvas-element{cursor:crosshair;background-color:var(--color-black, #000)}ax-image-editor-view .ax-crop-save{position:absolute;top:calc(var(--spacing, .25rem) * 0);right:calc(var(--spacing, .25rem) * 0);margin:calc(var(--spacing, .25rem) * 4)}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"] }]
962
+ args: [{ selector: 'ax-image-editor-view', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [AXImageEditorCropperWindowComponent], providers: [{ provide: AXComponent, useExisting: AXImageEditorViewComponent }], template: "<div class=\"ax-image-editor-stage\">\n <canvas\n tabindex=\"0\"\n (pointerdown)=\"mouseDownHandler($event)\"\n (pointerup)=\"mouseUpHandler($event)\"\n (pointercancel)=\"mouseUpHandler($event)\"\n (pointermove)=\"mouseMoveHandler($event)\"\n (keydown)=\"historyKeyDown($event)\"\n class=\"ax-canvas-element\"\n #canvasElem\n ></canvas>\n\n @if (service.activeToolState() === 'crop') {\n <ax-image-editor-cropper-window [showGrid]=\"showGrid()\" #f></ax-image-editor-cropper-window>\n }\n</div>\n", styles: ["@layer components{ax-image-editor-view{position:relative;display:flex;width:100%;touch-action:none;align-items:center;justify-content:center;overflow:hidden;background-color:var(--color-white, #fff)}ax-image-editor-view canvas{height:auto!important;width:auto!important}ax-image-editor-view .ax-image-editor-stage{position:relative;display:inline-flex;max-height:100%;max-width:100%;align-items:center;justify-content:center}ax-image-editor-view .ax-canvas-element{max-height:100%;max-width:100%;cursor:crosshair;background-color:var(--color-black, #000);touch-action:none}ax-image-editor-view .ax-crop-save{position:absolute;top:calc(var(--spacing, .25rem) * 0);right:calc(var(--spacing, .25rem) * 0);margin:calc(var(--spacing, .25rem) * 4)}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"] }]
653
963
  }], ctorParameters: () => [], propDecorators: { showGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGrid", required: false }] }], cropperSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "cropperSize", required: false }] }], src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: false }] }], canvasElem: [{ type: i0.ViewChild, args: ['canvasElem', { isSignal: true }] }], cropperWindow: [{ type: i0.ViewChild, args: ['f', { isSignal: true }] }] } });
654
964
 
655
965
  /**
@@ -658,25 +968,36 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
658
968
  */
659
969
  class AXImageEditorContainerComponent extends classes((MXInputBaseValueComponent), MXLookComponent) {
660
970
  constructor() {
661
- super(...arguments);
971
+ super();
662
972
  /** @ignore */
663
973
  this.service = inject(AXImageEditorService);
974
+ this.host = inject((ElementRef));
975
+ this.destroyRef = inject(DestroyRef);
664
976
  this.imageEditorContainer = viewChild('f', /* @ts-ignore */
665
977
  ...(ngDevMode ? [{ debugName: "imageEditorContainer" }] : /* istanbul ignore next */ []));
666
978
  this.view = contentChild(AXImageEditorViewComponent, /* @ts-ignore */
667
979
  ...(ngDevMode ? [{ debugName: "view" }] : /* istanbul ignore next */ []));
668
- this.#eff = effect(() => {
669
- void this.service.imageBlob();
670
- if (this.service.imageBlob().length) {
671
- this.commitValue(this.service.imageBlob(), true);
980
+ this.#syncValue = effect(() => {
981
+ const blobs = this.service.imageBlob();
982
+ if (blobs.length) {
983
+ this.commitValue(blobs, true);
672
984
  }
673
985
  else {
674
986
  this.commitValue(null);
675
987
  }
676
988
  }, /* @ts-ignore */
677
- ...(ngDevMode ? [{ debugName: "#eff" }] : /* istanbul ignore next */ []));
989
+ ...(ngDevMode ? [{ debugName: "#syncValue" }] : /* istanbul ignore next */ []));
990
+ afterNextRender(() => {
991
+ const onKeyDown = (event) => this.handleHistoryShortcut(event);
992
+ document.addEventListener('keydown', onKeyDown, true);
993
+ this.destroyRef.onDestroy(() => document.removeEventListener('keydown', onKeyDown, true));
994
+ });
995
+ }
996
+ #syncValue;
997
+ /** @ignore */
998
+ focusEditor() {
999
+ this.host.nativeElement.focus({ preventScroll: true });
678
1000
  }
679
- #eff;
680
1001
  /** Applies the current cropper selection. */
681
1002
  async crop() {
682
1003
  const oldValue = this.value;
@@ -686,16 +1007,45 @@ class AXImageEditorContainerComponent extends classes((MXInputBaseValueComponent
686
1007
  this.commitValue(blobs, true);
687
1008
  }
688
1009
  }
689
- get __hostClass() {
690
- if (this.disabled)
691
- return 'ax-state-disabled';
692
- return '';
1010
+ /** @ignore */
1011
+ onEditorPointerDown(event) {
1012
+ const target = event.target;
1013
+ if (target instanceof Element && target.closest('canvas.ax-canvas-element')) {
1014
+ return;
1015
+ }
1016
+ this.focusEditor();
1017
+ }
1018
+ /** @ignore */
1019
+ handleHistoryShortcut(event) {
1020
+ if (this.disabled) {
1021
+ return;
1022
+ }
1023
+ const root = this.host.nativeElement;
1024
+ const activeElement = document.activeElement;
1025
+ const isInsideEditor = root.contains(activeElement) || event.composedPath().some((node) => node === root);
1026
+ if (!isInsideEditor) {
1027
+ return;
1028
+ }
1029
+ const target = (event.target ?? activeElement);
1030
+ if (target instanceof HTMLElement &&
1031
+ (target.isContentEditable || target.closest('input, textarea, select, [contenteditable="true"]'))) {
1032
+ return;
1033
+ }
1034
+ this.service.handleHistoryShortcut(event);
693
1035
  }
694
- get __hostName() {
695
- return this.name;
1036
+ /** Encodes the current canvas into JPEG, PNG, and WebP blobs. */
1037
+ async commitChanges() {
1038
+ const view = this.view();
1039
+ if (!view) {
1040
+ return this.service.imageBlob();
1041
+ }
1042
+ if (this.service.activeToolState() === 'crop') {
1043
+ await view.crop();
1044
+ }
1045
+ return view.commitChanges();
696
1046
  }
697
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorContainerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
698
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXImageEditorContainerComponent, isStandalone: true, selector: "ax-image-editor-container", inputs: { look: "look", disabled: "disabled" }, outputs: { onValueChanged: "onValueChanged" }, host: { properties: { "class": "this.__hostClass", "attr.name": "this.__hostName" } }, providers: [
1047
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1048
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: AXImageEditorContainerComponent, isStandalone: true, selector: "ax-image-editor-container", inputs: { look: "look", disabled: "disabled" }, outputs: { onValueChanged: "onValueChanged" }, host: { attributes: { "tabindex": "-1" }, listeners: { "keydown": "handleHistoryShortcut($event)" }, properties: { "class.ax-state-disabled": "disabled", "attr.name": "name" } }, providers: [
699
1049
  AXImageEditorService,
700
1050
  { provide: AXComponent, useExisting: AXImageEditorContainerComponent },
701
1051
  { provide: AXFocusableComponent, useExisting: AXImageEditorContainerComponent },
@@ -705,11 +1055,16 @@ class AXImageEditorContainerComponent extends classes((MXInputBaseValueComponent
705
1055
  useExisting: forwardRef(() => AXImageEditorContainerComponent),
706
1056
  multi: true,
707
1057
  },
708
- ], queries: [{ propertyName: "view", first: true, predicate: AXImageEditorViewComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "imageEditorContainer", first: true, predicate: ["f"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (service.isImageLoad()) {\n <div #f class=\"ax-editor-container ax-default {{ look }}\">\n <ng-content select=\"ax-header\"></ng-content>\n\n <ng-content select=\"ax-image-editor-view\"> </ng-content>\n\n <ng-content select=\"ax-footer\"></ng-content>\n </div>\n <div class=\"ax-error-container\"></div>\n} @else {\n <div class=\"ax-loading-spinner-container\">\n <ax-loading-spinner [size]=\"16\" color=\"primary\" text=\"Loading Image ...\"></ax-loading-spinner>\n </div>\n}\n<ng-content select=\"ax-validation-rule\"> </ng-content>\n\n@if (disabled) {\n <div class=\"ax-disable-overlay\"></div>\n}\n", styles: ["@layer components{ax-image-editor-container{position:relative;display:block;width:fit-content}ax-image-editor-container.ax-state-disabled{opacity:50%}ax-image-editor-container .ax-disable-overlay{position:absolute;top:calc(var(--spacing, .25rem) * 0);left:calc(var(--spacing, .25rem) * 0);height:100%;width:100%;cursor:not-allowed}ax-image-editor-container>.ax-editor-container{display:block;height:auto!important;padding:calc(var(--spacing, .25rem) * 0)}ax-image-editor-container .ax-loading-spinner-container{display:flex;align-items:center;justify-content:center}ax-image-editor-container ax-footer{width:100%}ax-image-editor-container ax-header{width:100%}ax-image-editor-container ax-header ax-toolbar{justify-content:space-between}ax-image-editor-container ax-header .ax-start-toolbar-divider{display:none}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: AXLoadingSpinnerComponent, selector: "ax-loading-spinner", inputs: ["text", "color", "size", "stroke"] }], encapsulation: i0.ViewEncapsulation.None }); }
1058
+ ], queries: [{ propertyName: "view", first: true, predicate: AXImageEditorViewComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "imageEditorContainer", first: true, predicate: ["f"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n #f\n class=\"ax-editor-container ax-default {{ look }}\"\n [class.ax-image-editor-pending]=\"!service.isImageLoad()\"\n (pointerdown)=\"onEditorPointerDown($event)\"\n>\n <ng-content select=\"ax-header\"></ng-content>\n\n <ng-content select=\"ax-image-editor-view\"> </ng-content>\n\n <ng-content select=\"ax-footer\"></ng-content>\n</div>\n\n@if (!service.isImageLoad()) {\n @if (service.loadError()) {\n <div class=\"ax-error-container\">{{ '@acorex:image-editor.load-error' | translate | async }}</div>\n } @else {\n <div class=\"ax-loading-spinner-container\">\n <ax-loading-spinner\n [size]=\"16\"\n color=\"primary\"\n [text]=\"('@acorex:image-editor.loading' | translate | async) || ''\"\n ></ax-loading-spinner>\n </div>\n }\n}\n\n<div class=\"ax-error-container\"></div>\n<ng-content select=\"ax-validation-rule\"> </ng-content>\n\n@if (disabled) {\n <div class=\"ax-disable-overlay\"></div>\n}\n", styles: ["@layer components{ax-image-editor-container{position:relative;display:block;width:fit-content}ax-image-editor-container.ax-state-disabled{opacity:50%}ax-image-editor-container .ax-disable-overlay{position:absolute;top:calc(var(--spacing, .25rem) * 0);left:calc(var(--spacing, .25rem) * 0);height:100%;width:100%;cursor:not-allowed}ax-image-editor-container>.ax-editor-container{display:block;height:auto!important;padding:calc(var(--spacing, .25rem) * 0)}ax-image-editor-container>.ax-editor-container.ax-image-editor-pending{position:absolute;height:calc(var(--spacing, .25rem) * 0);width:calc(var(--spacing, .25rem) * 0);overflow:hidden;opacity:0%}ax-image-editor-container .ax-loading-spinner-container,ax-image-editor-container .ax-error-container{display:flex;min-height:calc(var(--spacing, .25rem) * 40);align-items:center;justify-content:center;padding-inline:calc(var(--spacing, .25rem) * 4);text-align:center}ax-image-editor-container ax-footer{width:100%}ax-image-editor-container ax-header{width:100%}ax-image-editor-container ax-header ax-toolbar{justify-content:space-between}ax-image-editor-container ax-header .ax-start-toolbar-divider{display:none}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: AXLoadingSpinnerComponent, selector: "ax-loading-spinner", inputs: ["text", "color", "size", "stroke"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
709
1059
  }
710
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorContainerComponent, decorators: [{
1060
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorContainerComponent, decorators: [{
711
1061
  type: Component,
712
- args: [{ selector: 'ax-image-editor-container', encapsulation: ViewEncapsulation.None, outputs: ['onValueChanged'], inputs: ['look', 'disabled'], providers: [
1062
+ args: [{ selector: 'ax-image-editor-container', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, outputs: ['onValueChanged'], inputs: ['look', 'disabled'], host: {
1063
+ '[class.ax-state-disabled]': 'disabled',
1064
+ '[attr.name]': 'name',
1065
+ tabindex: '-1',
1066
+ '(keydown)': 'handleHistoryShortcut($event)',
1067
+ }, providers: [
713
1068
  AXImageEditorService,
714
1069
  { provide: AXComponent, useExisting: AXImageEditorContainerComponent },
715
1070
  { provide: AXFocusableComponent, useExisting: AXImageEditorContainerComponent },
@@ -719,14 +1074,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
719
1074
  useExisting: forwardRef(() => AXImageEditorContainerComponent),
720
1075
  multi: true,
721
1076
  },
722
- ], imports: [AXDecoratorModule, AXLoadingSpinnerComponent], template: "@if (service.isImageLoad()) {\n <div #f class=\"ax-editor-container ax-default {{ look }}\">\n <ng-content select=\"ax-header\"></ng-content>\n\n <ng-content select=\"ax-image-editor-view\"> </ng-content>\n\n <ng-content select=\"ax-footer\"></ng-content>\n </div>\n <div class=\"ax-error-container\"></div>\n} @else {\n <div class=\"ax-loading-spinner-container\">\n <ax-loading-spinner [size]=\"16\" color=\"primary\" text=\"Loading Image ...\"></ax-loading-spinner>\n </div>\n}\n<ng-content select=\"ax-validation-rule\"> </ng-content>\n\n@if (disabled) {\n <div class=\"ax-disable-overlay\"></div>\n}\n", styles: ["@layer components{ax-image-editor-container{position:relative;display:block;width:fit-content}ax-image-editor-container.ax-state-disabled{opacity:50%}ax-image-editor-container .ax-disable-overlay{position:absolute;top:calc(var(--spacing, .25rem) * 0);left:calc(var(--spacing, .25rem) * 0);height:100%;width:100%;cursor:not-allowed}ax-image-editor-container>.ax-editor-container{display:block;height:auto!important;padding:calc(var(--spacing, .25rem) * 0)}ax-image-editor-container .ax-loading-spinner-container{display:flex;align-items:center;justify-content:center}ax-image-editor-container ax-footer{width:100%}ax-image-editor-container ax-header{width:100%}ax-image-editor-container ax-header ax-toolbar{justify-content:space-between}ax-image-editor-container ax-header .ax-start-toolbar-divider{display:none}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"] }]
723
- }], propDecorators: { imageEditorContainer: [{ type: i0.ViewChild, args: ['f', { isSignal: true }] }], view: [{ type: i0.ContentChild, args: [i0.forwardRef(() => AXImageEditorViewComponent), { isSignal: true }] }], __hostClass: [{
724
- type: HostBinding,
725
- args: ['class']
726
- }], __hostName: [{
727
- type: HostBinding,
728
- args: ['attr.name']
729
- }] } });
1077
+ ], imports: [AXDecoratorModule, AXLoadingSpinnerComponent, AsyncPipe, AXTranslatorPipe], template: "<div\n #f\n class=\"ax-editor-container ax-default {{ look }}\"\n [class.ax-image-editor-pending]=\"!service.isImageLoad()\"\n (pointerdown)=\"onEditorPointerDown($event)\"\n>\n <ng-content select=\"ax-header\"></ng-content>\n\n <ng-content select=\"ax-image-editor-view\"> </ng-content>\n\n <ng-content select=\"ax-footer\"></ng-content>\n</div>\n\n@if (!service.isImageLoad()) {\n @if (service.loadError()) {\n <div class=\"ax-error-container\">{{ '@acorex:image-editor.load-error' | translate | async }}</div>\n } @else {\n <div class=\"ax-loading-spinner-container\">\n <ax-loading-spinner\n [size]=\"16\"\n color=\"primary\"\n [text]=\"('@acorex:image-editor.loading' | translate | async) || ''\"\n ></ax-loading-spinner>\n </div>\n }\n}\n\n<div class=\"ax-error-container\"></div>\n<ng-content select=\"ax-validation-rule\"> </ng-content>\n\n@if (disabled) {\n <div class=\"ax-disable-overlay\"></div>\n}\n", styles: ["@layer components{ax-image-editor-container{position:relative;display:block;width:fit-content}ax-image-editor-container.ax-state-disabled{opacity:50%}ax-image-editor-container .ax-disable-overlay{position:absolute;top:calc(var(--spacing, .25rem) * 0);left:calc(var(--spacing, .25rem) * 0);height:100%;width:100%;cursor:not-allowed}ax-image-editor-container>.ax-editor-container{display:block;height:auto!important;padding:calc(var(--spacing, .25rem) * 0)}ax-image-editor-container>.ax-editor-container.ax-image-editor-pending{position:absolute;height:calc(var(--spacing, .25rem) * 0);width:calc(var(--spacing, .25rem) * 0);overflow:hidden;opacity:0%}ax-image-editor-container .ax-loading-spinner-container,ax-image-editor-container .ax-error-container{display:flex;min-height:calc(var(--spacing, .25rem) * 40);align-items:center;justify-content:center;padding-inline:calc(var(--spacing, .25rem) * 4);text-align:center}ax-image-editor-container ax-footer{width:100%}ax-image-editor-container ax-header{width:100%}ax-image-editor-container ax-header ax-toolbar{justify-content:space-between}ax-image-editor-container ax-header .ax-start-toolbar-divider{display:none}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"] }]
1078
+ }], ctorParameters: () => [], propDecorators: { imageEditorContainer: [{ type: i0.ViewChild, args: ['f', { isSignal: true }] }], view: [{ type: i0.ContentChild, args: [i0.forwardRef(() => AXImageEditorViewComponent), { isSignal: true }] }] } });
730
1079
 
731
1080
  const IMAGE_EDITOR_ASPECT_RATIO_ACTIVE_SUFFIX = ':active';
732
1081
  function parseAspectRatioItem(item) {
@@ -800,10 +1149,10 @@ class AXImageEditorCropComponent extends AXImageEditorToolComponent {
800
1149
  crop() {
801
1150
  this.container.crop();
802
1151
  }
803
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorCropComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
804
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.8", type: AXImageEditorCropComponent, isStandalone: true, selector: "ax-image-editor-crop", inputs: { aspectRatio: { classPropertyName: "aspectRatio", publicName: "aspectRatio", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, providers: [{ provide: AXComponent, useExisting: AXImageEditorCropComponent }], usesInheritance: true, ngImport: i0, template: "<ax-button\n [axTooltip]=\"'@acorex:image-editor.crop' | translate | async\"\n axTooltipPlacement=\"top\"\n (onClick)=\"service.toggleTool('crop')\"\n look=\"blank\"\n [selected]=\"service.activeToolState() === 'crop'\"\n [color]=\"service.activeToolState() === 'crop' ? 'primary' : 'default'\"\n class=\"ax-sm\"\n>\n <ax-icon class=\"ax-icon ax-icon-crop\"></ax-icon>\n</ax-button>\n", dependencies: [{ kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "directive", type: i2.AXTooltipDirective, selector: "[axTooltip]", inputs: ["axTooltipDisabled", "axTooltip", "axTooltipContext", "axTooltipPlacement", "axTooltipOffsetX", "axTooltipOffsetY", "axTooltipOpenAfter", "axTooltipCloseAfter"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
1152
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorCropComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1153
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: AXImageEditorCropComponent, isStandalone: true, selector: "ax-image-editor-crop", inputs: { aspectRatio: { classPropertyName: "aspectRatio", publicName: "aspectRatio", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, providers: [{ provide: AXComponent, useExisting: AXImageEditorCropComponent }], usesInheritance: true, ngImport: i0, template: "<ax-button\n [axTooltip]=\"'@acorex:image-editor.crop' | translate | async\"\n axTooltipPlacement=\"top\"\n (onClick)=\"service.toggleTool('crop')\"\n look=\"blank\"\n [selected]=\"service.activeToolState() === 'crop'\"\n [color]=\"service.activeToolState() === 'crop' ? 'primary' : 'default'\"\n class=\"ax-sm\"\n>\n <ax-icon class=\"ax-icon ax-icon-crop\"></ax-icon>\n</ax-button>\n", dependencies: [{ kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "directive", type: i2.AXTooltipDirective, selector: "[axTooltip]", inputs: ["axTooltipDisabled", "axTooltip", "axTooltipContext", "axTooltipPlacement", "axTooltipOffsetX", "axTooltipOffsetY", "axTooltipOpenAfter", "axTooltipCloseAfter"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
805
1154
  }
806
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorCropComponent, decorators: [{
1155
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorCropComponent, decorators: [{
807
1156
  type: Component,
808
1157
  args: [{ selector: 'ax-image-editor-crop', encapsulation: ViewEncapsulation.None, imports: [AXButtonComponent, AXDecoratorModule, AsyncPipe, AXTranslatorPipe, AXTooltipModule], providers: [{ provide: AXComponent, useExisting: AXImageEditorCropComponent }], template: "<ax-button\n [axTooltip]=\"'@acorex:image-editor.crop' | translate | async\"\n axTooltipPlacement=\"top\"\n (onClick)=\"service.toggleTool('crop')\"\n look=\"blank\"\n [selected]=\"service.activeToolState() === 'crop'\"\n [color]=\"service.activeToolState() === 'crop' ? 'primary' : 'default'\"\n class=\"ax-sm\"\n>\n <ax-icon class=\"ax-icon ax-icon-crop\"></ax-icon>\n</ax-button>\n" }]
809
1158
  }], propDecorators: { aspectRatio: [{ type: i0.Input, args: [{ isSignal: true, alias: "aspectRatio", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
@@ -817,10 +1166,10 @@ class AXImageEditorHighlightComponent extends AXImageEditorToolComponent {
817
1166
  super(...arguments);
818
1167
  this.tool = 'highlight';
819
1168
  }
820
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorHighlightComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
821
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.8", type: AXImageEditorHighlightComponent, isStandalone: true, selector: "ax-image-editor-highlight", providers: [{ provide: AXComponent, useExisting: AXImageEditorHighlightComponent }], usesInheritance: true, ngImport: i0, template: "<ax-button\n [axTooltip]=\"'@acorex:paint.tools.highlight' | translate | async\"\n axTooltipPlacement=\"top\"\n (onClick)=\"service.toggleTool('highlight')\"\n look=\"blank\"\n [selected]=\"service.activeToolState() === 'highlight'\"\n [color]=\"service.activeToolState() === 'highlight' ? 'primary' : 'default'\"\n class=\"ax-sm\"\n>\n <ax-icon class=\"ax-icon ax-icon-highlight\"></ax-icon>\n</ax-button>\n", dependencies: [{ kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "directive", type: i2.AXTooltipDirective, selector: "[axTooltip]", inputs: ["axTooltipDisabled", "axTooltip", "axTooltipContext", "axTooltipPlacement", "axTooltipOffsetX", "axTooltipOffsetY", "axTooltipOpenAfter", "axTooltipCloseAfter"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
1169
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorHighlightComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1170
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: AXImageEditorHighlightComponent, isStandalone: true, selector: "ax-image-editor-highlight", providers: [{ provide: AXComponent, useExisting: AXImageEditorHighlightComponent }], usesInheritance: true, ngImport: i0, template: "<ax-button\n [axTooltip]=\"'@acorex:paint.tools.highlight' | translate | async\"\n axTooltipPlacement=\"top\"\n (onClick)=\"service.toggleTool('highlight')\"\n look=\"blank\"\n [selected]=\"service.activeToolState() === 'highlight'\"\n [color]=\"service.activeToolState() === 'highlight' ? 'primary' : 'default'\"\n class=\"ax-sm\"\n>\n <ax-icon class=\"ax-icon ax-icon-highlight\"></ax-icon>\n</ax-button>\n", dependencies: [{ kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "directive", type: i2.AXTooltipDirective, selector: "[axTooltip]", inputs: ["axTooltipDisabled", "axTooltip", "axTooltipContext", "axTooltipPlacement", "axTooltipOffsetX", "axTooltipOffsetY", "axTooltipOpenAfter", "axTooltipCloseAfter"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
822
1171
  }
823
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorHighlightComponent, decorators: [{
1172
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorHighlightComponent, decorators: [{
824
1173
  type: Component,
825
1174
  args: [{ selector: 'ax-image-editor-highlight', encapsulation: ViewEncapsulation.None, imports: [AXButtonComponent, AXDecoratorModule, AsyncPipe, AXTranslatorPipe, AXTooltipModule], providers: [{ provide: AXComponent, useExisting: AXImageEditorHighlightComponent }], template: "<ax-button\n [axTooltip]=\"'@acorex:paint.tools.highlight' | translate | async\"\n axTooltipPlacement=\"top\"\n (onClick)=\"service.toggleTool('highlight')\"\n look=\"blank\"\n [selected]=\"service.activeToolState() === 'highlight'\"\n [color]=\"service.activeToolState() === 'highlight' ? 'primary' : 'default'\"\n class=\"ax-sm\"\n>\n <ax-icon class=\"ax-icon ax-icon-highlight\"></ax-icon>\n</ax-button>\n" }]
826
1175
  }] });
@@ -834,17 +1183,17 @@ class AXImageEditorHistoryComponent {
834
1183
  this.service = inject(AXImageEditorService);
835
1184
  }
836
1185
  UndoHandler() {
837
- this.service.undoPressed.set(true);
1186
+ this.service.undo();
838
1187
  }
839
1188
  RedoHandler() {
840
- this.service.redoPressed.set(true);
1189
+ this.service.redo();
841
1190
  }
842
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorHistoryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
843
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.8", type: AXImageEditorHistoryComponent, isStandalone: true, selector: "ax-image-editor-history", providers: [{ provide: AXComponent, useExisting: AXImageEditorHistoryComponent }], ngImport: i0, template: "<div class=\"flex\">\n <ax-button\n class=\"ax-sm\"\n [axTooltip]=\"'@acorex:image-editor.undo' | translate | async\"\n axTooltipPlacement=\"top\"\n (onClick)=\"UndoHandler()\"\n look=\"blank\"\n >\n <ax-icon class=\"ax-icon ax-icon-undo\"></ax-icon>\n </ax-button>\n\n <ax-button\n class=\"ax-sm\"\n [axTooltip]=\"'@acorex:image-editor.redo' | translate | async\"\n axTooltipPlacement=\"top\"\n (onClick)=\"RedoHandler()\"\n look=\"blank\"\n >\n <ax-icon class=\"ax-icon ax-icon-redo\"></ax-icon>\n </ax-button>\n</div>\n", dependencies: [{ kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "directive", type: AXTooltipDirective, selector: "[axTooltip]", inputs: ["axTooltipDisabled", "axTooltip", "axTooltipContext", "axTooltipPlacement", "axTooltipOffsetX", "axTooltipOffsetY", "axTooltipOpenAfter", "axTooltipCloseAfter"] }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
1191
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorHistoryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1192
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: AXImageEditorHistoryComponent, isStandalone: true, selector: "ax-image-editor-history", providers: [{ provide: AXComponent, useExisting: AXImageEditorHistoryComponent }], ngImport: i0, template: "<div class=\"flex\">\n <ax-button\n class=\"ax-sm\"\n [axTooltip]=\"'@acorex:image-editor.undo' | translate | async\"\n axTooltipPlacement=\"top\"\n (onClick)=\"UndoHandler()\"\n look=\"blank\"\n [disabled]=\"!service.canUndo()\"\n >\n <ax-icon class=\"ax-icon ax-icon-undo\"></ax-icon>\n </ax-button>\n\n <ax-button\n class=\"ax-sm\"\n [axTooltip]=\"'@acorex:image-editor.redo' | translate | async\"\n axTooltipPlacement=\"top\"\n (onClick)=\"RedoHandler()\"\n look=\"blank\"\n [disabled]=\"!service.canRedo()\"\n >\n <ax-icon class=\"ax-icon ax-icon-redo\"></ax-icon>\n </ax-button>\n</div>\n", dependencies: [{ kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "directive", type: AXTooltipDirective, selector: "[axTooltip]", inputs: ["axTooltipDisabled", "axTooltip", "axTooltipContext", "axTooltipPlacement", "axTooltipOffsetX", "axTooltipOffsetY", "axTooltipOpenAfter", "axTooltipCloseAfter"] }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
844
1193
  }
845
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorHistoryComponent, decorators: [{
1194
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorHistoryComponent, decorators: [{
846
1195
  type: Component,
847
- args: [{ selector: 'ax-image-editor-history', encapsulation: ViewEncapsulation.None, imports: [AXButtonComponent, AXDecoratorModule, AXTooltipDirective, AsyncPipe, AXTranslatorPipe, AXTooltipModule], providers: [{ provide: AXComponent, useExisting: AXImageEditorHistoryComponent }], template: "<div class=\"flex\">\n <ax-button\n class=\"ax-sm\"\n [axTooltip]=\"'@acorex:image-editor.undo' | translate | async\"\n axTooltipPlacement=\"top\"\n (onClick)=\"UndoHandler()\"\n look=\"blank\"\n >\n <ax-icon class=\"ax-icon ax-icon-undo\"></ax-icon>\n </ax-button>\n\n <ax-button\n class=\"ax-sm\"\n [axTooltip]=\"'@acorex:image-editor.redo' | translate | async\"\n axTooltipPlacement=\"top\"\n (onClick)=\"RedoHandler()\"\n look=\"blank\"\n >\n <ax-icon class=\"ax-icon ax-icon-redo\"></ax-icon>\n </ax-button>\n</div>\n" }]
1196
+ args: [{ selector: 'ax-image-editor-history', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [AXButtonComponent, AXDecoratorModule, AXTooltipDirective, AsyncPipe, AXTranslatorPipe, AXTooltipModule], providers: [{ provide: AXComponent, useExisting: AXImageEditorHistoryComponent }], template: "<div class=\"flex\">\n <ax-button\n class=\"ax-sm\"\n [axTooltip]=\"'@acorex:image-editor.undo' | translate | async\"\n axTooltipPlacement=\"top\"\n (onClick)=\"UndoHandler()\"\n look=\"blank\"\n [disabled]=\"!service.canUndo()\"\n >\n <ax-icon class=\"ax-icon ax-icon-undo\"></ax-icon>\n </ax-button>\n\n <ax-button\n class=\"ax-sm\"\n [axTooltip]=\"'@acorex:image-editor.redo' | translate | async\"\n axTooltipPlacement=\"top\"\n (onClick)=\"RedoHandler()\"\n look=\"blank\"\n [disabled]=\"!service.canRedo()\"\n >\n <ax-icon class=\"ax-icon ax-icon-redo\"></ax-icon>\n </ax-button>\n</div>\n" }]
848
1197
  }] });
849
1198
 
850
1199
  /**
@@ -856,10 +1205,10 @@ class AXImageEditorPenComponent extends AXImageEditorToolComponent {
856
1205
  super(...arguments);
857
1206
  this.tool = 'pen';
858
1207
  }
859
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorPenComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
860
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.8", type: AXImageEditorPenComponent, isStandalone: true, selector: "ax-image-editor-pen", providers: [{ provide: AXComponent, useExisting: AXImageEditorPenComponent }], usesInheritance: true, ngImport: i0, template: "<ax-button\n [axTooltip]=\"'@acorex:paint.tools.pen' | translate | async\"\n axTooltipPlacement=\"top\"\n (onClick)=\"service.toggleTool('pen')\"\n look=\"blank\"\n [selected]=\"service.activeToolState() === 'pen'\"\n [color]=\"service.activeToolState() === 'pen' ? 'primary' : 'default'\"\n class=\"ax-sm\"\n>\n <ax-icon class=\"ax-icon ax-icon-pen\"></ax-icon>\n</ax-button>\n", dependencies: [{ kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "directive", type: i2.AXTooltipDirective, selector: "[axTooltip]", inputs: ["axTooltipDisabled", "axTooltip", "axTooltipContext", "axTooltipPlacement", "axTooltipOffsetX", "axTooltipOffsetY", "axTooltipOpenAfter", "axTooltipCloseAfter"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
1208
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorPenComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1209
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: AXImageEditorPenComponent, isStandalone: true, selector: "ax-image-editor-pen", providers: [{ provide: AXComponent, useExisting: AXImageEditorPenComponent }], usesInheritance: true, ngImport: i0, template: "<ax-button\n [axTooltip]=\"'@acorex:paint.tools.pen' | translate | async\"\n axTooltipPlacement=\"top\"\n (onClick)=\"service.toggleTool('pen')\"\n look=\"blank\"\n [selected]=\"service.activeToolState() === 'pen'\"\n [color]=\"service.activeToolState() === 'pen' ? 'primary' : 'default'\"\n class=\"ax-sm\"\n>\n <ax-icon class=\"ax-icon ax-icon-pen\"></ax-icon>\n</ax-button>\n", dependencies: [{ kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "directive", type: i2.AXTooltipDirective, selector: "[axTooltip]", inputs: ["axTooltipDisabled", "axTooltip", "axTooltipContext", "axTooltipPlacement", "axTooltipOffsetX", "axTooltipOffsetY", "axTooltipOpenAfter", "axTooltipCloseAfter"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
861
1210
  }
862
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorPenComponent, decorators: [{
1211
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorPenComponent, decorators: [{
863
1212
  type: Component,
864
1213
  args: [{ selector: 'ax-image-editor-pen', encapsulation: ViewEncapsulation.None, imports: [AXButtonComponent, AXDecoratorModule, AsyncPipe, AXTranslatorPipe, AXTooltipModule], providers: [{ provide: AXComponent, useExisting: AXImageEditorPenComponent }], template: "<ax-button\n [axTooltip]=\"'@acorex:paint.tools.pen' | translate | async\"\n axTooltipPlacement=\"top\"\n (onClick)=\"service.toggleTool('pen')\"\n look=\"blank\"\n [selected]=\"service.activeToolState() === 'pen'\"\n [color]=\"service.activeToolState() === 'pen' ? 'primary' : 'default'\"\n class=\"ax-sm\"\n>\n <ax-icon class=\"ax-icon ax-icon-pen\"></ax-icon>\n</ax-button>\n" }]
865
1214
  }] });
@@ -873,10 +1222,10 @@ class AXImageEditorRotateComponent extends AXImageEditorToolComponent {
873
1222
  super(...arguments);
874
1223
  this.tool = 'rotate';
875
1224
  }
876
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorRotateComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
877
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.8", type: AXImageEditorRotateComponent, isStandalone: true, selector: "ax-image-editor-rotate", providers: [{ provide: AXComponent, useExisting: AXImageEditorRotateComponent }], usesInheritance: true, ngImport: i0, template: "<ax-button\n [axTooltip]=\"'@acorex:image-editor.rotate' | translate | async\"\n axTooltipPlacement=\"top\"\n (onClick)=\"service.toggleTool('rotate')\"\n look=\"blank\"\n [selected]=\"service.activeToolState() === 'rotate'\"\n [color]=\"service.activeToolState() === 'rotate' ? 'primary' : 'default'\"\n class=\"ax-sm\"\n>\n <i class=\"fa-solid fa-rotate\"></i>\n</ax-button>\n", dependencies: [{ kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "directive", type: AXTooltipDirective, selector: "[axTooltip]", inputs: ["axTooltipDisabled", "axTooltip", "axTooltipContext", "axTooltipPlacement", "axTooltipOffsetX", "axTooltipOffsetY", "axTooltipOpenAfter", "axTooltipCloseAfter"] }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
1225
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorRotateComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1226
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: AXImageEditorRotateComponent, isStandalone: true, selector: "ax-image-editor-rotate", providers: [{ provide: AXComponent, useExisting: AXImageEditorRotateComponent }], usesInheritance: true, ngImport: i0, template: "<ax-button\n [axTooltip]=\"'@acorex:image-editor.rotate' | translate | async\"\n axTooltipPlacement=\"top\"\n (onClick)=\"service.toggleTool('rotate')\"\n look=\"blank\"\n [selected]=\"service.activeToolState() === 'rotate'\"\n [color]=\"service.activeToolState() === 'rotate' ? 'primary' : 'default'\"\n class=\"ax-sm\"\n>\n <i class=\"fa-solid fa-rotate\"></i>\n</ax-button>\n", dependencies: [{ kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "directive", type: AXTooltipDirective, selector: "[axTooltip]", inputs: ["axTooltipDisabled", "axTooltip", "axTooltipContext", "axTooltipPlacement", "axTooltipOffsetX", "axTooltipOffsetY", "axTooltipOpenAfter", "axTooltipCloseAfter"] }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
878
1227
  }
879
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorRotateComponent, decorators: [{
1228
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorRotateComponent, decorators: [{
880
1229
  type: Component,
881
1230
  args: [{ selector: 'ax-image-editor-rotate', encapsulation: ViewEncapsulation.None, imports: [AXButtonComponent, AXTooltipDirective, AsyncPipe, AXTranslatorPipe, AXTooltipModule], providers: [{ provide: AXComponent, useExisting: AXImageEditorRotateComponent }], template: "<ax-button\n [axTooltip]=\"'@acorex:image-editor.rotate' | translate | async\"\n axTooltipPlacement=\"top\"\n (onClick)=\"service.toggleTool('rotate')\"\n look=\"blank\"\n [selected]=\"service.activeToolState() === 'rotate'\"\n [color]=\"service.activeToolState() === 'rotate' ? 'primary' : 'default'\"\n class=\"ax-sm\"\n>\n <i class=\"fa-solid fa-rotate\"></i>\n</ax-button>\n" }]
882
1231
  }] });
@@ -904,10 +1253,10 @@ class AXImageEditorCropOptionsComponent {
904
1253
  this.service.cropperRatio.set(r);
905
1254
  }
906
1255
  }
907
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorCropOptionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
908
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXImageEditorCropOptionsComponent, isStandalone: true, selector: "ax-image-editor-crop-options", inputs: { aspectRatio: { classPropertyName: "aspectRatio", publicName: "aspectRatio", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cropPressed: "cropPressed" }, providers: [{ provide: AXComponent, useExisting: AXImageEditorCropOptionsComponent }], ngImport: i0, template: "<div class=\"ax-image-editor-crop-ratios\">\n @for (item of aspectRatios(); track item) {\n <ax-button\n [selected]=\"service.cropperRatio() === item\"\n [color]=\"service.cropperRatio() === item ? 'primary' : 'default'\"\n (click)=\"ratioHandler(item)\"\n class=\"ax-crop-save ax-sm\"\n [text]=\"item\"\n ></ax-button>\n } @empty {\n <ax-button\n [selected]=\"service.cropperRatio() === '1:1'\"\n [color]=\"service.cropperRatio() === '1:1' ? 'primary' : 'default'\"\n (click)=\"ratioHandler('1:1')\"\n class=\"ax-crop-save ax-sm\"\n text=\"1:1\"\n ></ax-button>\n <ax-button\n [selected]=\"service.cropperRatio() === '16:9'\"\n [color]=\"service.cropperRatio() === '16:9' ? 'primary' : 'default'\"\n (click)=\"ratioHandler('16:9')\"\n class=\"ax-crop-save ax-sm\"\n text=\"16:9\"\n ></ax-button>\n }\n</div>\n\n<ax-button\n (click)=\"cropButtonHandler()\"\n class=\"ax-crop-save ax-sm\"\n [text]=\"'@acorex:image-editor.crop' | translate | async\"\n color=\"primary\"\n></ax-button>\n", dependencies: [{ kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
1256
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorCropOptionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1257
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: AXImageEditorCropOptionsComponent, isStandalone: true, selector: "ax-image-editor-crop-options", inputs: { aspectRatio: { classPropertyName: "aspectRatio", publicName: "aspectRatio", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cropPressed: "cropPressed" }, providers: [{ provide: AXComponent, useExisting: AXImageEditorCropOptionsComponent }], ngImport: i0, template: "<div class=\"ax-image-editor-crop-ratios\">\n @for (item of aspectRatios(); track item) {\n <ax-button\n [selected]=\"service.cropperRatio() === item\"\n [color]=\"service.cropperRatio() === item ? 'primary' : 'default'\"\n (click)=\"ratioHandler(item)\"\n class=\"ax-crop-save ax-sm\"\n [text]=\"item\"\n ></ax-button>\n } @empty {\n <ax-button\n [selected]=\"service.cropperRatio() === '1:1'\"\n [color]=\"service.cropperRatio() === '1:1' ? 'primary' : 'default'\"\n (click)=\"ratioHandler('1:1')\"\n class=\"ax-crop-save ax-sm\"\n text=\"1:1\"\n ></ax-button>\n <ax-button\n [selected]=\"service.cropperRatio() === '16:9'\"\n [color]=\"service.cropperRatio() === '16:9' ? 'primary' : 'default'\"\n (click)=\"ratioHandler('16:9')\"\n class=\"ax-crop-save ax-sm\"\n text=\"16:9\"\n ></ax-button>\n }\n</div>\n\n<ax-button\n (click)=\"cropButtonHandler()\"\n class=\"ax-crop-save ax-sm\"\n [text]=\"'@acorex:image-editor.crop' | translate | async\"\n color=\"primary\"\n></ax-button>\n", dependencies: [{ kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
909
1258
  }
910
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorCropOptionsComponent, decorators: [{
1259
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorCropOptionsComponent, decorators: [{
911
1260
  type: Component,
912
1261
  args: [{ selector: 'ax-image-editor-crop-options', encapsulation: ViewEncapsulation.None, imports: [AXButtonComponent, AsyncPipe, AXTranslatorPipe], providers: [{ provide: AXComponent, useExisting: AXImageEditorCropOptionsComponent }], template: "<div class=\"ax-image-editor-crop-ratios\">\n @for (item of aspectRatios(); track item) {\n <ax-button\n [selected]=\"service.cropperRatio() === item\"\n [color]=\"service.cropperRatio() === item ? 'primary' : 'default'\"\n (click)=\"ratioHandler(item)\"\n class=\"ax-crop-save ax-sm\"\n [text]=\"item\"\n ></ax-button>\n } @empty {\n <ax-button\n [selected]=\"service.cropperRatio() === '1:1'\"\n [color]=\"service.cropperRatio() === '1:1' ? 'primary' : 'default'\"\n (click)=\"ratioHandler('1:1')\"\n class=\"ax-crop-save ax-sm\"\n text=\"1:1\"\n ></ax-button>\n <ax-button\n [selected]=\"service.cropperRatio() === '16:9'\"\n [color]=\"service.cropperRatio() === '16:9' ? 'primary' : 'default'\"\n (click)=\"ratioHandler('16:9')\"\n class=\"ax-crop-save ax-sm\"\n text=\"16:9\"\n ></ax-button>\n }\n</div>\n\n<ax-button\n (click)=\"cropButtonHandler()\"\n class=\"ax-crop-save ax-sm\"\n [text]=\"'@acorex:image-editor.crop' | translate | async\"\n color=\"primary\"\n></ax-button>\n" }]
913
1262
  }], propDecorators: { cropPressed: [{ type: i0.Output, args: ["cropPressed"] }], aspectRatio: [{ type: i0.Input, args: [{ isSignal: true, alias: "aspectRatio", required: false }] }] } });
@@ -930,10 +1279,10 @@ class AXImageEditorHighlightOptionsComponent {
930
1279
  valueHandler(e) {
931
1280
  this.service.highlightWidth.set(e);
932
1281
  }
933
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorHighlightOptionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
934
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.8", type: AXImageEditorHighlightOptionsComponent, isStandalone: true, selector: "ax-image-editor-highlight-options", providers: [{ provide: AXComponent, useExisting: AXImageEditorHighlightOptionsComponent }], ngImport: i0, template: "<ax-color-box\n [showValue]=\"false\"\n [showIcon]=\"false\"\n [axTooltip]=\"'@acorex:paint.tools.highlight' | translate | async\"\n axTooltipPlacement=\"top\"\n look=\"none\"\n [ngModel]=\"selectedColor()\"\n (ngModelChange)=\"changeColorHandler($event)\"\n>\n</ax-color-box>\n\n<ax-range-slider [min]=\"2\" [max]=\"20\" [(ngModel)]=\"value\" (ngModelChange)=\"valueHandler($event)\"></ax-range-slider>\n", dependencies: [{ kind: "component", type: AXColorBoxComponent, selector: "ax-color-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "showBadge", "showValue", "showClearButton", "showIcon"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: AXRangeSliderComponent, selector: "ax-range-slider", inputs: ["disabled", "readonly", "orientation", "color", "values", "mode", "min", "max", "step", "snap", "tooltipMode", "snapMode", "hasStep", "hasSnap", "hasLable", "hasTooltip"], outputs: ["valuesChange"] }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "directive", type: i2.AXTooltipDirective, selector: "[axTooltip]", inputs: ["axTooltipDisabled", "axTooltip", "axTooltipContext", "axTooltipPlacement", "axTooltipOffsetX", "axTooltipOffsetY", "axTooltipOpenAfter", "axTooltipCloseAfter"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
1282
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorHighlightOptionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1283
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: AXImageEditorHighlightOptionsComponent, isStandalone: true, selector: "ax-image-editor-highlight-options", providers: [{ provide: AXComponent, useExisting: AXImageEditorHighlightOptionsComponent }], ngImport: i0, template: "<ax-color-box\n [showValue]=\"false\"\n [showIcon]=\"false\"\n [axTooltip]=\"'@acorex:paint.tools.highlight' | translate | async\"\n axTooltipPlacement=\"top\"\n look=\"none\"\n [ngModel]=\"selectedColor()\"\n (ngModelChange)=\"changeColorHandler($event)\"\n>\n</ax-color-box>\n\n<ax-range-slider [min]=\"2\" [max]=\"20\" [(ngModel)]=\"value\" (ngModelChange)=\"valueHandler($event)\"></ax-range-slider>\n", dependencies: [{ kind: "component", type: AXColorBoxComponent, selector: "ax-color-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "showBadge", "showValue", "showClearButton", "showIcon"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: AXRangeSliderComponent, selector: "ax-range-slider", inputs: ["disabled", "readonly", "orientation", "color", "values", "mode", "min", "max", "step", "snap", "tooltipMode", "snapMode", "hasStep", "hasSnap", "hasLable", "hasTooltip"], outputs: ["valuesChange"] }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "directive", type: i2.AXTooltipDirective, selector: "[axTooltip]", inputs: ["axTooltipDisabled", "axTooltip", "axTooltipContext", "axTooltipPlacement", "axTooltipOffsetX", "axTooltipOffsetY", "axTooltipOpenAfter", "axTooltipCloseAfter"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
935
1284
  }
936
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorHighlightOptionsComponent, decorators: [{
1285
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorHighlightOptionsComponent, decorators: [{
937
1286
  type: Component,
938
1287
  args: [{ selector: 'ax-image-editor-highlight-options', encapsulation: ViewEncapsulation.None, imports: [AXColorBoxComponent, FormsModule, AXRangeSliderComponent, AsyncPipe, AXTranslatorPipe, AXTooltipModule], providers: [{ provide: AXComponent, useExisting: AXImageEditorHighlightOptionsComponent }], template: "<ax-color-box\n [showValue]=\"false\"\n [showIcon]=\"false\"\n [axTooltip]=\"'@acorex:paint.tools.highlight' | translate | async\"\n axTooltipPlacement=\"top\"\n look=\"none\"\n [ngModel]=\"selectedColor()\"\n (ngModelChange)=\"changeColorHandler($event)\"\n>\n</ax-color-box>\n\n<ax-range-slider [min]=\"2\" [max]=\"20\" [(ngModel)]=\"value\" (ngModelChange)=\"valueHandler($event)\"></ax-range-slider>\n" }]
939
1288
  }] });
@@ -956,10 +1305,10 @@ class AXImageEditorPenOptionsComponent {
956
1305
  valueHandler(e) {
957
1306
  this.service.penWidth.set(e);
958
1307
  }
959
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorPenOptionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
960
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.8", type: AXImageEditorPenOptionsComponent, isStandalone: true, selector: "ax-image-editor-pen-options", providers: [{ provide: AXComponent, useExisting: AXImageEditorPenOptionsComponent }], ngImport: i0, template: "<ax-color-box\n [showValue]=\"false\"\n [showIcon]=\"false\"\n [axTooltip]=\"'@acorex:paint.tools.pen' | translate | async\"\n axTooltipPlacement=\"top\"\n look=\"none\"\n [ngModel]=\"selectedColor()\"\n (ngModelChange)=\"changeColorHandler($event)\"\n>\n</ax-color-box>\n\n<ax-range-slider [min]=\"2\" [max]=\"20\" [(ngModel)]=\"value\" (ngModelChange)=\"valueHandler($event)\"></ax-range-slider>\n", dependencies: [{ kind: "component", type: AXColorBoxComponent, selector: "ax-color-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "showBadge", "showValue", "showClearButton", "showIcon"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: AXRangeSliderComponent, selector: "ax-range-slider", inputs: ["disabled", "readonly", "orientation", "color", "values", "mode", "min", "max", "step", "snap", "tooltipMode", "snapMode", "hasStep", "hasSnap", "hasLable", "hasTooltip"], outputs: ["valuesChange"] }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "directive", type: i2.AXTooltipDirective, selector: "[axTooltip]", inputs: ["axTooltipDisabled", "axTooltip", "axTooltipContext", "axTooltipPlacement", "axTooltipOffsetX", "axTooltipOffsetY", "axTooltipOpenAfter", "axTooltipCloseAfter"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
1308
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorPenOptionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1309
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: AXImageEditorPenOptionsComponent, isStandalone: true, selector: "ax-image-editor-pen-options", providers: [{ provide: AXComponent, useExisting: AXImageEditorPenOptionsComponent }], ngImport: i0, template: "<ax-color-box\n [showValue]=\"false\"\n [showIcon]=\"false\"\n [axTooltip]=\"'@acorex:paint.tools.pen' | translate | async\"\n axTooltipPlacement=\"top\"\n look=\"none\"\n [ngModel]=\"selectedColor()\"\n (ngModelChange)=\"changeColorHandler($event)\"\n>\n</ax-color-box>\n\n<ax-range-slider [min]=\"2\" [max]=\"20\" [(ngModel)]=\"value\" (ngModelChange)=\"valueHandler($event)\"></ax-range-slider>\n", dependencies: [{ kind: "component", type: AXColorBoxComponent, selector: "ax-color-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "showBadge", "showValue", "showClearButton", "showIcon"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: AXRangeSliderComponent, selector: "ax-range-slider", inputs: ["disabled", "readonly", "orientation", "color", "values", "mode", "min", "max", "step", "snap", "tooltipMode", "snapMode", "hasStep", "hasSnap", "hasLable", "hasTooltip"], outputs: ["valuesChange"] }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "directive", type: i2.AXTooltipDirective, selector: "[axTooltip]", inputs: ["axTooltipDisabled", "axTooltip", "axTooltipContext", "axTooltipPlacement", "axTooltipOffsetX", "axTooltipOffsetY", "axTooltipOpenAfter", "axTooltipCloseAfter"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
961
1310
  }
962
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorPenOptionsComponent, decorators: [{
1311
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorPenOptionsComponent, decorators: [{
963
1312
  type: Component,
964
1313
  args: [{ selector: 'ax-image-editor-pen-options', encapsulation: ViewEncapsulation.None, imports: [AXColorBoxComponent, FormsModule, AXRangeSliderComponent, AsyncPipe, AXTranslatorPipe, AXTooltipModule], providers: [{ provide: AXComponent, useExisting: AXImageEditorPenOptionsComponent }], template: "<ax-color-box\n [showValue]=\"false\"\n [showIcon]=\"false\"\n [axTooltip]=\"'@acorex:paint.tools.pen' | translate | async\"\n axTooltipPlacement=\"top\"\n look=\"none\"\n [ngModel]=\"selectedColor()\"\n (ngModelChange)=\"changeColorHandler($event)\"\n>\n</ax-color-box>\n\n<ax-range-slider [min]=\"2\" [max]=\"20\" [(ngModel)]=\"value\" (ngModelChange)=\"valueHandler($event)\"></ax-range-slider>\n" }]
965
1314
  }] });
@@ -975,10 +1324,10 @@ class AXImageEditorRotateOptionsComponent {
975
1324
  rotateLeftHandler() {
976
1325
  this.service.rotate.set({ state: -90, userInteract: true });
977
1326
  }
978
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorRotateOptionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
979
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.8", type: AXImageEditorRotateOptionsComponent, isStandalone: true, selector: "ax-image-editor-rotate-options", providers: [{ provide: AXComponent, useExisting: AXImageEditorRotateOptionsComponent }], ngImport: i0, template: "<ax-button\n [axTooltip]=\"'@acorex:image-editor.rotate-left' | translate | async\"\n axTooltipPlacement=\"top\"\n (click)=\"rotateLeftHandler()\"\n look=\"blank\"\n>\n <ax-icon class=\"ax-icon ax-icon-arrow-turn-left\"></ax-icon>\n</ax-button>\n\n<ax-button\n [axTooltip]=\"'@acorex:image-editor.rotate-right' | translate | async\"\n axTooltipPlacement=\"top\"\n (click)=\"rotateRightHandler()\"\n look=\"blank\"\n>\n <ax-icon class=\"ax-icon ax-icon-arrow-turn-right\"></ax-icon>\n</ax-button>\n", dependencies: [{ kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "directive", type: AXTooltipDirective, selector: "[axTooltip]", inputs: ["axTooltipDisabled", "axTooltip", "axTooltipContext", "axTooltipPlacement", "axTooltipOffsetX", "axTooltipOffsetY", "axTooltipOpenAfter", "axTooltipCloseAfter"] }, { kind: "component", type: AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
1327
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorRotateOptionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1328
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: AXImageEditorRotateOptionsComponent, isStandalone: true, selector: "ax-image-editor-rotate-options", providers: [{ provide: AXComponent, useExisting: AXImageEditorRotateOptionsComponent }], ngImport: i0, template: "<ax-button\n [axTooltip]=\"'@acorex:image-editor.rotate-left' | translate | async\"\n axTooltipPlacement=\"top\"\n (click)=\"rotateLeftHandler()\"\n look=\"blank\"\n>\n <ax-icon class=\"ax-icon ax-icon-arrow-turn-left\"></ax-icon>\n</ax-button>\n\n<ax-button\n [axTooltip]=\"'@acorex:image-editor.rotate-right' | translate | async\"\n axTooltipPlacement=\"top\"\n (click)=\"rotateRightHandler()\"\n look=\"blank\"\n>\n <ax-icon class=\"ax-icon ax-icon-arrow-turn-right\"></ax-icon>\n</ax-button>\n", dependencies: [{ kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "directive", type: AXTooltipDirective, selector: "[axTooltip]", inputs: ["axTooltipDisabled", "axTooltip", "axTooltipContext", "axTooltipPlacement", "axTooltipOffsetX", "axTooltipOffsetY", "axTooltipOpenAfter", "axTooltipCloseAfter"] }, { kind: "component", type: AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTooltipModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
980
1329
  }
981
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorRotateOptionsComponent, decorators: [{
1330
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorRotateOptionsComponent, decorators: [{
982
1331
  type: Component,
983
1332
  args: [{ selector: 'ax-image-editor-rotate-options', encapsulation: ViewEncapsulation.None, imports: [
984
1333
  AXButtonComponent,
@@ -1021,10 +1370,10 @@ class AXImageEditorToolsBarComponent {
1021
1370
  ...(ngDevMode ? [{ debugName: "#activeEffect" }] : /* istanbul ignore next */ []));
1022
1371
  }
1023
1372
  #activeEffect;
1024
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorToolsBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1025
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXImageEditorToolsBarComponent, isStandalone: true, selector: "ax-image-editor-tools-bar", inputs: { active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, hidden: { classPropertyName: "hidden", publicName: "hidden", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.ax-image-editor-tools-bar-hidden": "hidden()" } }, providers: [{ provide: AXComponent, useExisting: AXImageEditorToolsBarComponent }], queries: [{ propertyName: "penTool", first: true, predicate: AXImageEditorPenComponent, descendants: true, isSignal: true }, { propertyName: "highlightTool", first: true, predicate: AXImageEditorHighlightComponent, descendants: true, isSignal: true }, { propertyName: "cropTool", first: true, predicate: AXImageEditorCropComponent, descendants: true, isSignal: true }, { propertyName: "rotateTool", first: true, predicate: AXImageEditorRotateComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<ax-toolbar class=\"ax-main-toolbar\">\n <ax-prefix class=\"ax-image-editor-tool-triggers\">\n <ng-content\n select=\"ax-image-editor-pen, ax-image-editor-highlight, ax-image-editor-crop, ax-image-editor-rotate\"\n ></ng-content>\n </ax-prefix>\n\n @if (service.activeToolState()) {\n <ax-suffix class=\"ax-image-editor-tool-options\">\n @switch (service.activeToolState()) {\n @case ('pen') {\n @if (penTool()) {\n <ax-image-editor-pen-options></ax-image-editor-pen-options>\n }\n }\n @case ('highlight') {\n @if (highlightTool()) {\n <ax-image-editor-highlight-options></ax-image-editor-highlight-options>\n }\n }\n @case ('crop') {\n @if (cropTool()) {\n <ax-image-editor-crop-options [aspectRatio]=\"cropAspectRatio()\"></ax-image-editor-crop-options>\n }\n }\n @case ('rotate') {\n @if (rotateTool()) {\n <ax-image-editor-rotate-options></ax-image-editor-rotate-options>\n }\n }\n }\n </ax-suffix>\n }\n</ax-toolbar>\n", styles: ["@layer components{ax-image-editor-tools-bar{display:block;width:100%}ax-image-editor-tools-bar.ax-image-editor-tools-bar-hidden{display:none}ax-image-editor-tools-bar .ax-main-toolbar{justify-content:space-between;padding:calc(var(--spacing, .25rem) * 2)}ax-image-editor-tools-bar .ax-main-toolbar ax-divider{display:none}ax-image-editor-tools-bar .ax-main-toolbar>ax-suffix{margin-left:auto;flex:1}ax-image-editor-tools-bar .ax-image-editor-tool-triggers{display:flex;align-items:center;justify-content:flex-start;gap:calc(var(--spacing, .25rem) * 2)}ax-image-editor-tools-bar .ax-image-editor-tool-options{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex:1;align-items:center;justify-content:flex-end;gap:calc(var(--spacing, .25rem) * 2)}ax-image-editor-tools-bar .ax-image-editor-crop-ratios{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:calc(var(--spacing, .25rem) * 1)}ax-image-editor-tools-bar ax-image-editor-pen-options,ax-image-editor-tools-bar ax-image-editor-highlight-options{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}:is(ax-image-editor-tools-bar ax-image-editor-pen-options,ax-image-editor-tools-bar ax-image-editor-highlight-options) ax-color-box{flex-shrink:0}:is(ax-image-editor-tools-bar ax-image-editor-pen-options,ax-image-editor-tools-bar ax-image-editor-highlight-options) ax-range-slider{width:calc(var(--spacing, .25rem) * 40);padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2)}:is(ax-image-editor-tools-bar ax-image-editor-pen-options,ax-image-editor-tools-bar ax-image-editor-highlight-options) ax-range-slider .ax-range-slider .ax-range-slider-handler{height:calc(var(--spacing, .25rem) * 4)!important;width:calc(var(--spacing, .25rem) * 4)!important}ax-image-editor-tools-bar ax-image-editor-crop-options{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:calc(var(--spacing, .25rem) * 2)}ax-image-editor-tools-bar ax-image-editor-rotate-options{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 1)}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXToolBarModule }, { kind: "component", type: i2$1.AXToolBarComponent, selector: "ax-toolbar" }, { kind: "component", type: AXImageEditorPenOptionsComponent, selector: "ax-image-editor-pen-options" }, { kind: "component", type: AXImageEditorHighlightOptionsComponent, selector: "ax-image-editor-highlight-options" }, { kind: "component", type: AXImageEditorCropOptionsComponent, selector: "ax-image-editor-crop-options", inputs: ["aspectRatio"], outputs: ["cropPressed"] }, { kind: "component", type: AXImageEditorRotateOptionsComponent, selector: "ax-image-editor-rotate-options" }], encapsulation: i0.ViewEncapsulation.None }); }
1373
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorToolsBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1374
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: AXImageEditorToolsBarComponent, isStandalone: true, selector: "ax-image-editor-tools-bar", inputs: { active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, hidden: { classPropertyName: "hidden", publicName: "hidden", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.ax-image-editor-tools-bar-hidden": "hidden()" } }, providers: [{ provide: AXComponent, useExisting: AXImageEditorToolsBarComponent }], queries: [{ propertyName: "penTool", first: true, predicate: AXImageEditorPenComponent, descendants: true, isSignal: true }, { propertyName: "highlightTool", first: true, predicate: AXImageEditorHighlightComponent, descendants: true, isSignal: true }, { propertyName: "cropTool", first: true, predicate: AXImageEditorCropComponent, descendants: true, isSignal: true }, { propertyName: "rotateTool", first: true, predicate: AXImageEditorRotateComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<ax-toolbar class=\"ax-main-toolbar\">\n <ax-prefix class=\"ax-image-editor-tool-triggers\">\n <ng-content\n select=\"ax-image-editor-pen, ax-image-editor-highlight, ax-image-editor-crop, ax-image-editor-rotate\"\n ></ng-content>\n </ax-prefix>\n\n @if (service.activeToolState()) {\n <ax-suffix class=\"ax-image-editor-tool-options\">\n @switch (service.activeToolState()) {\n @case ('pen') {\n @if (penTool()) {\n <ax-image-editor-pen-options></ax-image-editor-pen-options>\n }\n }\n @case ('highlight') {\n @if (highlightTool()) {\n <ax-image-editor-highlight-options></ax-image-editor-highlight-options>\n }\n }\n @case ('crop') {\n @if (cropTool()) {\n <ax-image-editor-crop-options [aspectRatio]=\"cropAspectRatio()\"></ax-image-editor-crop-options>\n }\n }\n @case ('rotate') {\n @if (rotateTool()) {\n <ax-image-editor-rotate-options></ax-image-editor-rotate-options>\n }\n }\n }\n </ax-suffix>\n }\n</ax-toolbar>\n", styles: ["@layer components{ax-image-editor-tools-bar{display:block;width:100%}ax-image-editor-tools-bar.ax-image-editor-tools-bar-hidden{display:none}ax-image-editor-tools-bar .ax-main-toolbar{justify-content:space-between;padding:calc(var(--spacing, .25rem) * 2)}ax-image-editor-tools-bar .ax-main-toolbar ax-divider{display:none}ax-image-editor-tools-bar .ax-main-toolbar>ax-suffix{margin-left:auto;flex:1}ax-image-editor-tools-bar .ax-image-editor-tool-triggers{display:flex;align-items:center;justify-content:flex-start;gap:calc(var(--spacing, .25rem) * 2)}ax-image-editor-tools-bar .ax-image-editor-tool-options{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex:1;align-items:center;justify-content:flex-end;gap:calc(var(--spacing, .25rem) * 2)}ax-image-editor-tools-bar .ax-image-editor-crop-ratios{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:calc(var(--spacing, .25rem) * 1)}ax-image-editor-tools-bar ax-image-editor-pen-options,ax-image-editor-tools-bar ax-image-editor-highlight-options{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}:is(ax-image-editor-tools-bar ax-image-editor-pen-options,ax-image-editor-tools-bar ax-image-editor-highlight-options) ax-color-box{flex-shrink:0}:is(ax-image-editor-tools-bar ax-image-editor-pen-options,ax-image-editor-tools-bar ax-image-editor-highlight-options) ax-range-slider{width:calc(var(--spacing, .25rem) * 40);padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2)}:is(ax-image-editor-tools-bar ax-image-editor-pen-options,ax-image-editor-tools-bar ax-image-editor-highlight-options) ax-range-slider .ax-range-slider .ax-range-slider-handler{height:calc(var(--spacing, .25rem) * 4)!important;width:calc(var(--spacing, .25rem) * 4)!important}ax-image-editor-tools-bar ax-image-editor-crop-options{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:calc(var(--spacing, .25rem) * 2)}ax-image-editor-tools-bar ax-image-editor-rotate-options{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 1)}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXToolBarModule }, { kind: "component", type: i2$1.AXToolBarComponent, selector: "ax-toolbar" }, { kind: "component", type: AXImageEditorPenOptionsComponent, selector: "ax-image-editor-pen-options" }, { kind: "component", type: AXImageEditorHighlightOptionsComponent, selector: "ax-image-editor-highlight-options" }, { kind: "component", type: AXImageEditorCropOptionsComponent, selector: "ax-image-editor-crop-options", inputs: ["aspectRatio"], outputs: ["cropPressed"] }, { kind: "component", type: AXImageEditorRotateOptionsComponent, selector: "ax-image-editor-rotate-options" }], encapsulation: i0.ViewEncapsulation.None }); }
1026
1375
  }
1027
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorToolsBarComponent, decorators: [{
1376
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorToolsBarComponent, decorators: [{
1028
1377
  type: Component,
1029
1378
  args: [{ selector: 'ax-image-editor-tools-bar', encapsulation: ViewEncapsulation.None, host: {
1030
1379
  '[class.ax-image-editor-tools-bar-hidden]': 'hidden()',
@@ -1047,10 +1396,10 @@ class AXImageEditorToolSelectorComponent {
1047
1396
  this.aspectRatio = input([], /* @ts-ignore */
1048
1397
  ...(ngDevMode ? [{ debugName: "aspectRatio" }] : /* istanbul ignore next */ []));
1049
1398
  }
1050
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorToolSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1051
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.8", type: AXImageEditorToolSelectorComponent, isStandalone: true, selector: "ax-image-editor-tool-selector", inputs: { aspectRatio: { classPropertyName: "aspectRatio", publicName: "aspectRatio", isSignal: true, isRequired: false, transformFunction: null } }, providers: [{ provide: AXComponent, useExisting: AXImageEditorToolSelectorComponent }], ngImport: i0, template: "<ax-image-editor-tools-bar>\n <ax-image-editor-pen></ax-image-editor-pen>\n <ax-image-editor-highlight></ax-image-editor-highlight>\n <ax-image-editor-crop [aspectRatio]=\"aspectRatio()\"></ax-image-editor-crop>\n <ax-image-editor-rotate></ax-image-editor-rotate>\n</ax-image-editor-tools-bar>\n", dependencies: [{ kind: "component", type: AXImageEditorToolsBarComponent, selector: "ax-image-editor-tools-bar", inputs: ["active", "hidden"] }, { kind: "component", type: AXImageEditorPenComponent, selector: "ax-image-editor-pen" }, { kind: "component", type: AXImageEditorHighlightComponent, selector: "ax-image-editor-highlight" }, { kind: "component", type: AXImageEditorCropComponent, selector: "ax-image-editor-crop", inputs: ["aspectRatio", "size"] }, { kind: "component", type: AXImageEditorRotateComponent, selector: "ax-image-editor-rotate" }], encapsulation: i0.ViewEncapsulation.None }); }
1399
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorToolSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1400
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: AXImageEditorToolSelectorComponent, isStandalone: true, selector: "ax-image-editor-tool-selector", inputs: { aspectRatio: { classPropertyName: "aspectRatio", publicName: "aspectRatio", isSignal: true, isRequired: false, transformFunction: null } }, providers: [{ provide: AXComponent, useExisting: AXImageEditorToolSelectorComponent }], ngImport: i0, template: "<ax-image-editor-tools-bar>\n <ax-image-editor-pen></ax-image-editor-pen>\n <ax-image-editor-highlight></ax-image-editor-highlight>\n <ax-image-editor-crop [aspectRatio]=\"aspectRatio()\"></ax-image-editor-crop>\n <ax-image-editor-rotate></ax-image-editor-rotate>\n</ax-image-editor-tools-bar>\n", dependencies: [{ kind: "component", type: AXImageEditorToolsBarComponent, selector: "ax-image-editor-tools-bar", inputs: ["active", "hidden"] }, { kind: "component", type: AXImageEditorPenComponent, selector: "ax-image-editor-pen" }, { kind: "component", type: AXImageEditorHighlightComponent, selector: "ax-image-editor-highlight" }, { kind: "component", type: AXImageEditorCropComponent, selector: "ax-image-editor-crop", inputs: ["aspectRatio", "size"] }, { kind: "component", type: AXImageEditorRotateComponent, selector: "ax-image-editor-rotate" }], encapsulation: i0.ViewEncapsulation.None }); }
1052
1401
  }
1053
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorToolSelectorComponent, decorators: [{
1402
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorToolSelectorComponent, decorators: [{
1054
1403
  type: Component,
1055
1404
  args: [{ selector: 'ax-image-editor-tool-selector', encapsulation: ViewEncapsulation.None, imports: [
1056
1405
  AXImageEditorToolsBarComponent,
@@ -1061,7 +1410,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
1061
1410
  ], providers: [{ provide: AXComponent, useExisting: AXImageEditorToolSelectorComponent }], template: "<ax-image-editor-tools-bar>\n <ax-image-editor-pen></ax-image-editor-pen>\n <ax-image-editor-highlight></ax-image-editor-highlight>\n <ax-image-editor-crop [aspectRatio]=\"aspectRatio()\"></ax-image-editor-crop>\n <ax-image-editor-rotate></ax-image-editor-rotate>\n</ax-image-editor-tools-bar>\n" }]
1062
1411
  }], propDecorators: { aspectRatio: [{ type: i0.Input, args: [{ isSignal: true, alias: "aspectRatio", required: false }] }] } });
1063
1412
 
1064
- const COMPONENT = [
1413
+ const PUBLIC_COMPONENTS = [
1065
1414
  AXImageEditorViewComponent,
1066
1415
  AXImageEditorContainerComponent,
1067
1416
  AXImageEditorCropComponent,
@@ -1073,28 +1422,9 @@ const COMPONENT = [
1073
1422
  AXImageEditorRotateComponent,
1074
1423
  AXImageEditorCropperWindowComponent,
1075
1424
  ];
1076
- const MODULES = [
1077
- AXButtonModule,
1078
- FormsModule,
1079
- AXRangeSliderModule,
1080
- AXSelectBoxModule,
1081
- AXColorBoxModule,
1082
- AXPopoverModule,
1083
- AXDecoratorModule,
1084
- AXLoadingModule,
1085
- AXDialogModule,
1086
- ];
1087
1425
  class AXImageEditorModule {
1088
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1089
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorModule, imports: [AXButtonModule,
1090
- FormsModule,
1091
- AXRangeSliderModule,
1092
- AXSelectBoxModule,
1093
- AXColorBoxModule,
1094
- AXPopoverModule,
1095
- AXDecoratorModule,
1096
- AXLoadingModule,
1097
- AXDialogModule, AXImageEditorViewComponent,
1426
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1427
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorModule, imports: [AXImageEditorViewComponent,
1098
1428
  AXImageEditorContainerComponent,
1099
1429
  AXImageEditorCropComponent,
1100
1430
  AXImageEditorHistoryComponent,
@@ -1113,7 +1443,7 @@ class AXImageEditorModule {
1113
1443
  AXImageEditorHighlightComponent,
1114
1444
  AXImageEditorRotateComponent,
1115
1445
  AXImageEditorCropperWindowComponent] }); }
1116
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorModule, imports: [MODULES, AXImageEditorContainerComponent,
1446
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorModule, imports: [AXImageEditorContainerComponent,
1117
1447
  AXImageEditorCropComponent,
1118
1448
  AXImageEditorHistoryComponent,
1119
1449
  AXImageEditorToolSelectorComponent,
@@ -1122,12 +1452,11 @@ class AXImageEditorModule {
1122
1452
  AXImageEditorHighlightComponent,
1123
1453
  AXImageEditorRotateComponent] }); }
1124
1454
  }
1125
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXImageEditorModule, decorators: [{
1455
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXImageEditorModule, decorators: [{
1126
1456
  type: NgModule,
1127
1457
  args: [{
1128
- imports: [...MODULES, ...COMPONENT],
1129
- exports: [...COMPONENT],
1130
- providers: [],
1458
+ imports: [...PUBLIC_COMPONENTS],
1459
+ exports: [...PUBLIC_COMPONENTS],
1131
1460
  }]
1132
1461
  }] });
1133
1462