pixedi 1.0.0 → 1.0.2

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 (113) hide show
  1. package/README.md +65 -60
  2. package/README.npm.md +80 -0
  3. package/dist/lib/index.js +1602 -0
  4. package/dist/lib/index.umd.js +28 -0
  5. package/package.json +9 -4
  6. package/.github/workflows/deploy.yml +0 -54
  7. package/.prettierr +0 -9
  8. package/.storybook/main.ts +0 -16
  9. package/.storybook/preview.ts +0 -53
  10. package/.vscode/extensions.json +0 -6
  11. package/eslint.config.js +0 -22
  12. package/index.html +0 -13
  13. package/pnpm-workspace.yaml +0 -2
  14. package/public/favicon.svg +0 -1
  15. package/src/app/App.tsx +0 -10
  16. package/src/app/entries/index.ts +0 -145
  17. package/src/app/providers/RouterProvider.tsx +0 -6
  18. package/src/app/providers/index.ts +0 -1
  19. package/src/app/router/AppRouter.tsx +0 -12
  20. package/src/app/router/index.ts +0 -0
  21. package/src/app/styles/index.css +0 -4
  22. package/src/features/gallery/GalleryPage.tsx +0 -33
  23. package/src/features/gallery/ImageEditPage.tsx +0 -37
  24. package/src/features/gallery/index.ts +0 -2
  25. package/src/main.tsx +0 -10
  26. package/src/shared/components/ImageCard/ImageCard.tsx +0 -54
  27. package/src/shared/components/ImageCard/index.ts +0 -1
  28. package/src/shared/components/ImageEditor/ImageEditor.tsx +0 -48
  29. package/src/shared/components/ImageEditor/assets/icons.tsx +0 -114
  30. package/src/shared/components/ImageEditor/constants.ts +0 -118
  31. package/src/shared/components/ImageEditor/crop/Crop.tsx +0 -60
  32. package/src/shared/components/ImageEditor/crop/CropBorders.tsx +0 -28
  33. package/src/shared/components/ImageEditor/crop/CropLines.tsx +0 -8
  34. package/src/shared/components/ImageEditor/crop/CropPointer.tsx +0 -21
  35. package/src/shared/components/ImageEditor/crop/CropPointers.tsx +0 -44
  36. package/src/shared/components/ImageEditor/crop/CropTools.tsx +0 -138
  37. package/src/shared/components/ImageEditor/crop/crop.css +0 -180
  38. package/src/shared/components/ImageEditor/crop/index.ts +0 -8
  39. package/src/shared/components/ImageEditor/crop/useCropInteraction.ts +0 -230
  40. package/src/shared/components/ImageEditor/eventBus.ts +0 -8
  41. package/src/shared/components/ImageEditor/frame/Frame.tsx +0 -48
  42. package/src/shared/components/ImageEditor/frame/frame.css +0 -40
  43. package/src/shared/components/ImageEditor/frame/index.ts +0 -1
  44. package/src/shared/components/ImageEditor/header/Header.tsx +0 -81
  45. package/src/shared/components/ImageEditor/header/header.css +0 -27
  46. package/src/shared/components/ImageEditor/header/index.ts +0 -1
  47. package/src/shared/components/ImageEditor/hooks/index.ts +0 -5
  48. package/src/shared/components/ImageEditor/hooks/useAbove.tsx +0 -18
  49. package/src/shared/components/ImageEditor/hooks/useBellow.tsx +0 -18
  50. package/src/shared/components/ImageEditor/hooks/useImageLoader.tsx +0 -110
  51. package/src/shared/components/ImageEditor/hooks/useImageProcessor.test.tsx +0 -147
  52. package/src/shared/components/ImageEditor/hooks/useImageProcessor.ts +0 -225
  53. package/src/shared/components/ImageEditor/hooks/useMobile.tsx +0 -33
  54. package/src/shared/components/ImageEditor/index.css +0 -145
  55. package/src/shared/components/ImageEditor/index.ts +0 -1
  56. package/src/shared/components/ImageEditor/provider/ImageEditorProvider.test.tsx +0 -126
  57. package/src/shared/components/ImageEditor/provider/ImageEditorProvider.tsx +0 -107
  58. package/src/shared/components/ImageEditor/provider/StoreContext.tsx +0 -20
  59. package/src/shared/components/ImageEditor/provider/initialState.ts +0 -30
  60. package/src/shared/components/ImageEditor/provider/useImageEditorContext.tsx +0 -12
  61. package/src/shared/components/ImageEditor/resize/ResizeTools.tsx +0 -183
  62. package/src/shared/components/ImageEditor/resize/index.ts +0 -1
  63. package/src/shared/components/ImageEditor/resize/resize.css +0 -56
  64. package/src/shared/components/ImageEditor/sidebar/Sidebar.tsx +0 -54
  65. package/src/shared/components/ImageEditor/sidebar/SidebarCrop.tsx +0 -57
  66. package/src/shared/components/ImageEditor/sidebar/SidebarPresets.tsx +0 -54
  67. package/src/shared/components/ImageEditor/sidebar/SidebarResize.tsx +0 -26
  68. package/src/shared/components/ImageEditor/sidebar/index.ts +0 -1
  69. package/src/shared/components/ImageEditor/sidebar/sidebar.css +0 -101
  70. package/src/shared/components/ImageEditor/types.ts +0 -59
  71. package/src/shared/components/ImageEditor/ui/button/Button.stories.tsx +0 -42
  72. package/src/shared/components/ImageEditor/ui/button/Button.tsx +0 -21
  73. package/src/shared/components/ImageEditor/ui/button/button.css +0 -69
  74. package/src/shared/components/ImageEditor/ui/button-crop/ButtonCrop.stories.tsx +0 -26
  75. package/src/shared/components/ImageEditor/ui/button-crop/ButtonCrop.tsx +0 -29
  76. package/src/shared/components/ImageEditor/ui/button-crop/button-crop.css +0 -38
  77. package/src/shared/components/ImageEditor/ui/index.ts +0 -6
  78. package/src/shared/components/ImageEditor/ui/input/Input.stories.tsx +0 -45
  79. package/src/shared/components/ImageEditor/ui/input/Input.tsx +0 -20
  80. package/src/shared/components/ImageEditor/ui/input/input.css +0 -48
  81. package/src/shared/components/ImageEditor/ui/input-pixel/InputPixel.stories.tsx +0 -33
  82. package/src/shared/components/ImageEditor/ui/input-pixel/InputPixel.tsx +0 -23
  83. package/src/shared/components/ImageEditor/ui/input-pixel/input-pixel.css +0 -24
  84. package/src/shared/components/ImageEditor/ui/select/Select.stories.tsx +0 -67
  85. package/src/shared/components/ImageEditor/ui/select/Select.tsx +0 -161
  86. package/src/shared/components/ImageEditor/ui/select/select.css +0 -147
  87. package/src/shared/components/ImageEditor/ui/separator/Separator.stories.tsx +0 -37
  88. package/src/shared/components/ImageEditor/ui/separator/Separator.tsx +0 -27
  89. package/src/shared/components/ImageEditor/ui/separator/separator.css +0 -19
  90. package/src/shared/components/ImageEditor/utils.test.ts +0 -136
  91. package/src/shared/components/ImageEditor/utils.ts +0 -497
  92. package/src/shared/components/ui/index.ts +0 -1
  93. package/src/shared/components/ui/preloader.tsx +0 -78
  94. package/src/shared/config/index.ts +0 -3
  95. package/src/shared/config/routes.ts +0 -4
  96. package/src/shared/features/gallery/GalleryPage.tsx +0 -33
  97. package/src/shared/features/gallery/ImageEditPage.tsx +0 -37
  98. package/src/shared/features/gallery/index.ts +0 -2
  99. package/src/shared/hooks/index.ts +0 -1
  100. package/src/shared/hooks/useImagePreload.tsx +0 -49
  101. package/src/shared/types/index.ts +0 -11
  102. package/src/test/setup.ts +0 -14
  103. package/src/virtual-css-injected-by-js.d.ts +0 -8
  104. package/src/widget.tsx +0 -119
  105. package/tsconfig.app.json +0 -29
  106. package/tsconfig.json +0 -12
  107. package/tsconfig.lib.json +0 -18
  108. package/tsconfig.node.json +0 -23
  109. package/vite-env.d.ts +0 -1
  110. package/vite.config.ts +0 -24
  111. package/vite.lib.config.ts +0 -33
  112. package/vite.widget.config.ts +0 -39
  113. package/wrangler.json +0 -5
@@ -0,0 +1,28 @@
1
+ (function(){try{if(typeof document<`u`){var e=document.createElement(`style`);e.appendChild(document.createTextNode(`.btn{cursor:pointer;white-space:nowrap;-webkit-user-select:none;user-select:none;box-sizing:border-box;background-color:#0000;border:1px solid #0000;border-radius:4px;justify-content:center;align-items:center;gap:8px;height:32px;padding-left:8px;padding-right:8px;font-family:inherit;font-size:14px;font-weight:500;transition:background-color .2s,border-color .2s,opacity .2s;display:inline-flex}.btn:disabled{pointer-events:none;opacity:.5}.btn:active{transform:translateY(1px)}.btn svg{flex-shrink:0;width:16px;height:16px}.btn-default{background-color:var(--primary);color:var(--primary-foreground)}.btn-default:hover{opacity:.9}.btn-outline{border-color:var(--border);background-color:var(--background);color:var(--foreground)}.btn-outline:hover{background-color:var(--secondary)}.btn-ghost{color:var(--foreground);padding-left:8px;padding-right:8px}.btn-ghost:hover{background-color:var(--secondary)}.btn-rect{width:32px;height:32px}.btn-crop{border:1px solid var(--border);background-color:var(--background);color:var(--foreground);cursor:pointer;-webkit-user-select:none;user-select:none;box-sizing:border-box;border-radius:4px;flex-direction:column;justify-content:center;align-items:center;gap:8px;padding:12px;font-family:inherit;font-size:12px;transition:all .2s;display:inline-flex}.btn-crop:hover:not([aria-pressed=true]){background-color:var(--secondary)}.btn-crop[aria-pressed=true]{border-color:var(--accent-blue);background-color:var(--accent-blue-light);color:var(--foreground)}.btn-crop svg{flex-shrink:0;width:20px;height:20px}.btn-crop span{white-space:nowrap}.separator{background-color:var(--border);box-sizing:border-box;border:none;flex-shrink:0;display:block}.separator[data-orientation=horizontal]{width:100%;height:1px}.separator[data-orientation=vertical]{align-self:stretch;width:1px;height:100%;margin:0}.select-wrapper{box-sizing:border-box;width:100%;position:relative}.select-trigger{width:100%;height:32px;color:var(--foreground);background-color:var(--background);border:1px solid var(--border);cursor:pointer;box-sizing:border-box;-webkit-user-select:none;user-select:none;border-radius:4px;outline:none;justify-content:space-between;align-items:center;padding-left:10px;padding-right:8px;font-family:inherit;font-size:14px;transition:border-color .2s;display:flex}.select-trigger:hover,.select-trigger:focus{border-color:var(--muted-foreground)}.select-trigger-arrow{width:16px;height:16px;color:var(--muted-foreground);transition:transform .2s}.select-wrapper[data-state=open] .select-trigger-arrow{transform:rotate(180deg)}.select-content{background-color:var(--background);border:1px solid var(--border);z-index:50;box-sizing:border-box;border-radius:4px;width:100%;max-height:282px;padding:4px;position:absolute;top:calc(100% + 4px);left:0;overflow-y:auto;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -2px #0000000d}.select-content::-webkit-scrollbar{width:4px}.select-content::-webkit-scrollbar-track{background:0 0}.select-content::-webkit-scrollbar-thumb{background-color:var(--border);border-radius:10px}.select-wrapper[data-state=closed] .select-content{display:none}.select-group-label{color:var(--muted-foreground);-webkit-user-select:none;user-select:none;padding:8px 10px;font-size:12px;font-weight:500}.select-item{width:100%;color:var(--foreground);cursor:pointer;-webkit-user-select:none;user-select:none;box-sizing:border-box;background:0 0;border-radius:4px;justify-content:space-between;align-items:center;padding:4px 10px;display:flex}.select-item:hover{background-color:var(--secondary)}.select-item-left{font-size:14px;font-weight:400}.select-item-addon{align-items:center;gap:8px;display:flex}.select-item-addon>span{color:var(--muted-foreground);font-size:12px}.select-item-addon>svg{font-size:14px}.select-item-addon>b{flex-shrink:0;width:16px;height:16px}.select-item-right-container{align-items:center;gap:8px;display:flex}.select-item-right{color:var(--muted-foreground);font-size:14px}.select-item-check{width:16px;height:16px;color:var(--foreground);flex-shrink:0}.input{width:100%;height:32px;color:var(--foreground);background-color:var(--background);border:1px solid var(--input);box-sizing:border-box;border-radius:4px;outline:none;padding-left:8px;padding-right:8px;font-family:inherit;font-size:14px;line-height:normal;transition:border-color .2s,box-shadow .2s;display:block}.input:hover:not(:disabled):not(:focus){border-color:var(--muted-foreground)}.input:focus{box-shadow:0 0 0 1px var(--ring)}.input:disabled{cursor:not-allowed;opacity:.5;background-color:var(--secondary)}.input::placeholder{color:var(--muted-foreground);opacity:1}.input-number-clean::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.input-number-clean::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.input-number-clean[type=number]{-moz-appearance:textfield}.input-pixel-container{position:relative}.input-pixel-legend{color:var(--muted-foreground);background:var(--background);margin-left:8px;padding-left:4px;padding-right:4px;font-size:12px;position:absolute;top:-9px}.input-pixel-suffix{color:var(--muted-foreground);pointer-events:none;-webkit-user-select:none;user-select:none;font-size:14px;position:absolute;bottom:2px;right:8px}.header{box-sizing:border-box;background-color:var(--background);border-bottom:1px solid var(--border);justify-content:space-between;align-items:center;height:48px;padding-left:8px;padding-right:8px;display:flex}.header-tools{gap:8px;display:flex}.header-history{align-items:center;gap:8px;display:flex}.header-history-text{color:var(--muted-foreground);font-size:14px}.crop-image{width:100%;height:100%;position:absolute;inset:0}.crop-box{cursor:move;position:absolute}.crop-tools{background-color:var(--background);box-sizing:border-box;border:1px solid var(--border);border-radius:4px;align-items:center;height:36px;padding-left:12px;display:flex;position:absolute;bottom:24px;left:50%;transform:translate(-50%);box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -1px #0000000f}.crop-tools-info{min-width:54px;margin-top:-2px;display:inline-block}.crop-tools-info-label{color:var(--muted-foreground);font-size:12px;line-height:12px}.crop-tools-info-value{font-size:14px;line-height:14px}.crop-b{background-color:var(--accent-blue);position:absolute}.crop-b-t{cursor:ns-resize;width:100%;height:2px;top:0;left:0}.crop-b-r{cursor:ew-resize;width:2px;height:100%;top:0;right:0}.crop-b-b{cursor:ns-resize;width:100%;height:2px;bottom:0;left:0;transform:translateY(1px)}.crop-b-l{cursor:ew-resize;width:2px;height:100%;top:0;left:-1px;transform:translate(1px)}.crop-l-box{pointer-events:none;position:absolute;inset:2px}.crop-l{border:1px dashed var(--color-white);opacity:.5;position:absolute}.crop-l-v{border-top:0;border-bottom:0;width:33%;height:100%;top:0;left:33%}.crop-l-h{border-left:0;border-right:0;width:100%;height:33%;top:33%;left:0}.crop-ps{box-sizing:border-box;border:1px solid var(--accent-blue);background-color:var(--overlay-bg-white);border-radius:50%;width:12px;height:12px;position:absolute}.crop-ps-tl{cursor:nwse-resize;top:-5px;left:-5px}.crop-ps-t{cursor:ns-resize;top:-5px;left:50%;transform:translate(-50%)}.crop-ps-tr{cursor:nesw-resize;top:-5px;right:-5px}.crop-ps-r{cursor:ew-resize;top:50%;right:-5px;transform:translateY(-50%)}.crop-ps-br{cursor:nwse-resize;bottom:-5px;right:-5px}.crop-ps-b{cursor:ns-resize;bottom:-5px;left:50%;transform:translate(-50%)}.crop-ps-bl{cursor:nesw-resize;bottom:-5px;left:-5px}.crop-ps-l{cursor:ew-resize;top:50%;left:-5px;transform:translateY(-50%)}.crop-p-b{box-sizing:border-box;border:2px solid var(--accent-blue);position:absolute;inset:0}.crop-p-p{background-color:var(--overlay-bg-white);border:3px solid var(--accent-blue);box-sizing:border-box;border-radius:50%;width:32px;height:32px;position:absolute;bottom:-16px;right:-16px}.frame{box-sizing:border-box;justify-content:center;align-items:center;width:100%;height:100%;min-height:0;padding:16px;display:flex;position:relative;overflow:hidden}.frame--faded{background-color:#00000080}.frame-preview{-webkit-user-select:none;user-select:none;flex-shrink:1;width:auto;min-width:0;max-width:100%;height:auto;min-height:0;max-height:100%;transition:transform .2s;display:block;position:relative}.frame-image{object-fit:contain;width:100%;height:100%}.frame-image--faded{opacity:.4}.resize{background-color:var(--background);border-radius:4px;flex-direction:column;padding:16px;display:flex;position:absolute;bottom:24px;left:50%;transform:translate(-50%);box-shadow:0 2px 8px #0000001a}.resize-text{text-align:center;color:var(--muted-foreground);font-size:14px}.resize-border{border-bottom:1px solid var(--border);width:60px;margin:12px auto 4px;display:inline-block}.resize-tools{align-items:center;gap:6px;margin-top:16px;display:flex}.resize-tools-lock{width:12px;height:12px;color:var(--muted-foreground)}.resize-tools-buttons{margin-left:4px;display:flex}.resize-tools-save{border-top-right-radius:0;border-bottom-right-radius:0;width:36px}.resize-tools-close{border-top-left-radius:0;border-bottom-left-radius:0;width:36px;margin-left:-1px}.sidebar{z-index:10;width:0;transition:transform .15s ease-out;position:relative}@media (width>=768px){.sidebar{width:320px;transition:none}}.sidebar-settings{border-radius:50%;width:40px;height:40px;position:absolute;top:8px;right:8px;box-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a}@media (width>=768px){.sidebar-settings{display:none}}.sidebar-container{box-sizing:border-box;border-left:1px solid var(--border);position:absolute;inset:0}.sidebar-content{background-color:var(--background);box-sizing:border-box;flex-direction:column;width:320px;height:100%;padding:16px;display:flex;position:absolute;top:0;left:0;overflow-y:auto}@media (width<=767px){.sidebar-content{padding-top:48px}}.sidebar-close-btn{position:absolute;top:8px;right:8px}.sidebar-separator{margin-top:20px;margin-bottom:12px}.sidebar-resize{justify-content:space-between;align-items:center;display:flex}.sidebar-resize-icon{align-items:center;gap:8px;display:flex}.sidebar-resize-size{color:var(--muted-foreground);font-size:14px}.sidebar-crop{flex-direction:column;gap:8px;display:flex}.sidebar-crop-ratios{grid-template-columns:repeat(3,1fr);gap:8px;display:grid}.sidebar-preset{flex-direction:column;gap:8px;display:flex}.picedi{font-size:16px;font-family:var(--font-sans);--font-sans:system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Tahoma, Helvetica, Arial, sans-serif;--color-white:#fff;--color-black:#000;--color-transparent:transparent;--color-red:oklch(63.7% .237 25.331);--color-green:oklch(76.8% .188 151.716);--background:oklch(100% 0 0);--foreground:oklch(14.5% 0 0);--card:oklch(100% 0 0);--card-foreground:oklch(14.5% 0 0);--popover:oklch(100% 0 0);--popover-foreground:oklch(14.5% 0 0);--primary:oklch(20.5% 0 0);--primary-foreground:oklch(98.5% 0 0);--secondary:oklch(97% 0 0);--secondary-foreground:oklch(20.5% 0 0);--muted:oklch(97% 0 0);--muted-foreground:oklch(55.6% 0 0);--accent:oklch(97% 0 0);--accent-foreground:oklch(20.5% 0 0);--accent-blue:oklch(60.9% .221 251.687);--accent-blue-light:oklch(96% .02 250);--destructive:oklch(57.7% .245 27.325);--success:oklch(76.8% .188 151.716);--border:oklch(92.2% 0 0);--input:oklch(92.2% 0 0);--ring:oklch(70.8% 0 0);--radius:4px;--sidebar:oklch(98.5% 0 0);--sidebar-foreground:oklch(14.5% 0 0);--sidebar-primary:oklch(20.5% 0 0);--sidebar-primary-foreground:oklch(98.5% 0 0);--sidebar-accent:oklch(97% 0 0);--sidebar-accent-foreground:oklch(20.5% 0 0);--sidebar-border:oklch(92.2% 0 0);--sidebar-ring:oklch(70.8% 0 0);--overlay-bg:color-mix(in srgb, var(--color-black) 50%, transparent);--overlay-bg-white:color-mix(in srgb, var(--color-white) 80%, transparent)}:host([data-theme=dark]) .picedi,[data-theme=dark] .picedi,[data-theme=dark].picedi{--background:oklch(14.5% 0 0);--foreground:oklch(98.5% 0 0);--card:oklch(20.5% 0 0);--card-foreground:oklch(98.5% 0 0);--popover:oklch(20.5% 0 0);--popover-foreground:oklch(98.5% 0 0);--primary:oklch(92.2% 0 0);--primary-foreground:oklch(20.5% 0 0);--secondary:oklch(26.9% 0 0);--secondary-foreground:oklch(98.5% 0 0);--muted:oklch(26.9% 0 0);--muted-foreground:oklch(70.8% 0 0);--accent:oklch(26.9% 0 0);--accent-foreground:oklch(98.5% 0 0);--accent-blue-light:oklch(25% .06 250);--destructive:oklch(70.4% .191 22.216);--border:oklch(100% 0 0/.1);--input:oklch(100% 0 0/.15);--ring:oklch(55.6% 0 0);--sidebar-foreground:oklch(98.5% 0 0);--sidebar-primary:oklch(48.8% .243 264.376);--sidebar-primary-foreground:oklch(98.5% 0 0);--sidebar-accent:oklch(26.9% 0 0);--sidebar-accent-foreground:oklch(98.5% 0 0);--sidebar-border:oklch(100% 0 0/.1);--sidebar-ring:oklch(55.6% 0 0);--overlay-bg:color-mix(in srgb, var(--color-black) 75%, transparent)}.picedi h1,.picedi h2,.picedi h3,.picedi h4,.picedi h5,.picedi h6{margin:0;font-weight:600}.text-red{color:var(--color-red)}.bg-red{background-color:var(--color-red)}.bg-green{background-color:var(--color-green)}.text-green{color:var(--color-green)}.mask{background-color:var(--overlay-bg)}.semibold{letter-spacing:.4px;font-weight:600}.bold{letter-spacing:.4px;font-weight:700}.sys{width:100%;height:100%;color:var(--muted-foreground);justify-content:center;align-items:center;display:flex;position:relative}.main{background-color:var(--background);grid-template-rows:auto 1fr;height:100%;display:grid;overflow:hidden}.grid{grid-template-columns:1fr auto;min-height:0;display:grid;position:relative;overflow:hidden}/*$vite$:1*/`)),document.head.appendChild(e)}}catch(e){console.error(`vite-plugin-css-injected-by-js`,e)}})();
2
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("react")):typeof define==`function`&&define.amd?define([`exports`,`react`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.Pixedi={},e.React))})(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var n=Object.create,r=Object.defineProperty,i=Object.getOwnPropertyDescriptor,a=Object.getOwnPropertyNames,o=Object.getPrototypeOf,s=Object.prototype.hasOwnProperty,c=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),l=(e,t,n,o)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var c=a(t),l=0,u=c.length,d;l<u;l++)d=c[l],!s.call(e,d)&&d!==n&&r(e,d,{get:(e=>t[e]).bind(null,d),enumerable:!(o=i(t,d))||o.enumerable});return e};t=((e,t,i)=>(i=e==null?{}:n(o(e)),l(t||!e||!e.__esModule?r(i,`default`,{value:e,enumerable:!0}):i,e)))(t,1);var u=c((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),d=c((e=>{process.env.NODE_ENV!==`production`&&(function(){function t(e){if(e==null)return null;if(typeof e==`function`)return e.$$typeof===O?null:e.displayName||e.name||null;if(typeof e==`string`)return e;switch(e){case _:return`Fragment`;case y:return`Profiler`;case v:return`StrictMode`;case C:return`Suspense`;case w:return`SuspenseList`;case D:return`Activity`}if(typeof e==`object`)switch(typeof e.tag==`number`&&console.error(`Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.`),e.$$typeof){case g:return`Portal`;case x:return e.displayName||`Context`;case b:return(e._context.displayName||`Context`)+`.Consumer`;case S:var n=e.render;return e=e.displayName,e||=(e=n.displayName||n.name||``,e===``?`ForwardRef`:`ForwardRef(`+e+`)`),e;case T:return n=e.displayName||null,n===null?t(e.type)||`Memo`:n;case E:n=e._payload,e=e._init;try{return t(e(n))}catch{}}return null}function n(e){return``+e}function r(e){try{n(e);var t=!1}catch{t=!0}if(t){t=console;var r=t.error,i=typeof Symbol==`function`&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||`Object`;return r.call(t,`The provided key is an unsupported type %s. This value must be coerced to a string before using it here.`,i),n(e)}}function i(e){if(e===_)return`<>`;if(typeof e==`object`&&e&&e.$$typeof===E)return`<...>`;try{var n=t(e);return n?`<`+n+`>`:`<...>`}catch{return`<...>`}}function a(){var e=k.A;return e===null?null:e.getOwner()}function o(){return Error(`react-stack-top-frame`)}function s(e){if(A.call(e,`key`)){var t=Object.getOwnPropertyDescriptor(e,`key`).get;if(t&&t.isReactWarning)return!1}return e.key!==void 0}function c(e,t){function n(){M||(M=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",t))}n.isReactWarning=!0,Object.defineProperty(e,"key",{get:n,configurable:!0})}function l(){var e=t(this.type);return N[e]||(N[e]=!0,console.error(`Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.`)),e=this.props.ref,e===void 0?null:e}function u(e,t,n,r,i,a){var o=n.ref;return e={$$typeof:h,type:e,key:t,props:n,_owner:r},(o===void 0?null:o)===null?Object.defineProperty(e,"ref",{enumerable:!1,value:null}):Object.defineProperty(e,"ref",{enumerable:!1,get:l}),e._store={},Object.defineProperty(e._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(e,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(e,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:i}),Object.defineProperty(e,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:a}),Object.freeze&&(Object.freeze(e.props),Object.freeze(e)),e}function d(e,n,i,o,l,d){var p=n.children;if(p!==void 0)if(o)if(ee(p)){for(o=0;o<p.length;o++)f(p[o]);Object.freeze&&Object.freeze(p)}else console.error(`React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.`);else f(p);if(A.call(n,`key`)){p=t(e);var m=Object.keys(n).filter(function(e){return e!==`key`});o=0<m.length?`{key: someKey, `+m.join(`: ..., `)+`: ...}`:`{key: someKey}`,I[p+o]||(m=0<m.length?`{`+m.join(`: ..., `)+`: ...}`:`{}`,console.error(`A props object containing a "key" prop is being spread into JSX:
3
+ let props = %s;
4
+ <%s {...props} />
5
+ React keys must be passed directly to JSX without using spread:
6
+ let props = %s;
7
+ <%s key={someKey} {...props} />`,o,p,m,p),I[p+o]=!0)}if(p=null,i!==void 0&&(r(i),p=``+i),s(n)&&(r(n.key),p=``+n.key),`key`in n)for(var h in i={},n)h!==`key`&&(i[h]=n[h]);else i=n;return p&&c(i,typeof e==`function`?e.displayName||e.name||`Unknown`:e),u(e,p,i,a(),l,d)}function f(e){p(e)?e._store&&(e._store.validated=1):typeof e==`object`&&e&&e.$$typeof===E&&(e._payload.status===`fulfilled`?p(e._payload.value)&&e._payload.value._store&&(e._payload.value._store.validated=1):e._store&&(e._store.validated=1))}function p(e){return typeof e==`object`&&!!e&&e.$$typeof===h}var m=require("react"),h=Symbol.for(`react.transitional.element`),g=Symbol.for(`react.portal`),_=Symbol.for(`react.fragment`),v=Symbol.for(`react.strict_mode`),y=Symbol.for(`react.profiler`),b=Symbol.for(`react.consumer`),x=Symbol.for(`react.context`),S=Symbol.for(`react.forward_ref`),C=Symbol.for(`react.suspense`),w=Symbol.for(`react.suspense_list`),T=Symbol.for(`react.memo`),E=Symbol.for(`react.lazy`),D=Symbol.for(`react.activity`),O=Symbol.for(`react.client.reference`),k=m.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,A=Object.prototype.hasOwnProperty,ee=Array.isArray,j=console.createTask?console.createTask:function(){return null};m={react_stack_bottom_frame:function(e){return e()}};var M,N={},P=m.react_stack_bottom_frame.bind(m,o)(),F=j(i(o)),I={};e.Fragment=_,e.jsx=function(e,t,n){var r=1e4>k.recentlyCreatedOwnerStacks++;return d(e,t,n,!1,r?Error(`react-stack-top-frame`):P,r?j(i(e)):F)},e.jsxs=function(e,t,n){var r=1e4>k.recentlyCreatedOwnerStacks++;return d(e,t,n,!0,r?Error(`react-stack-top-frame`):P,r?j(i(e)):F)}})()})),f=c(((e,t)=>{process.env.NODE_ENV===`production`?t.exports=u():t.exports=d()}))();function p({size:e=36,className:t,style:n,color:r=`currentColor`}){return(0,f.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,x:`0px`,y:`0px`,viewBox:`0 0 80 80`,width:e,height:e,fill:r,className:t,style:n,children:[(0,f.jsx)(`path`,{d:`M10,40c0,0,0-0.4,0-1.1c0-0.3,0-0.8,0-1.3c0-0.3,0-0.5,0-0.8c0-0.3,0.1-0.6,0.1-0.9c0.1-0.6,0.1-1.4,0.2-2.1
8
+ c0.2-0.8,0.3-1.6,0.5-2.5c0.2-0.9,0.6-1.8,0.8-2.8c0.3-1,0.8-1.9,1.2-3c0.5-1,1.1-2,1.7-3.1c0.7-1,1.4-2.1,2.2-3.1
9
+ c1.6-2.1,3.7-3.9,6-5.6c2.3-1.7,5-3,7.9-4.1c0.7-0.2,1.5-0.4,2.2-0.7c0.7-0.3,1.5-0.3,2.3-0.5c0.8-0.2,1.5-0.3,2.3-0.4l1.2-0.1
10
+ l0.6-0.1l0.3,0l0.1,0l0.1,0l0,0c0.1,0-0.1,0,0.1,0c1.5,0,2.9-0.1,4.5,0.2c0.8,0.1,1.6,0.1,2.4,0.3c0.8,0.2,1.5,0.3,2.3,0.5
11
+ c3,0.8,5.9,2,8.5,3.6c2.6,1.6,4.9,3.4,6.8,5.4c1,1,1.8,2.1,2.7,3.1c0.8,1.1,1.5,2.1,2.1,3.2c0.6,1.1,1.2,2.1,1.6,3.1
12
+ c0.4,1,0.9,2,1.2,3c0.3,1,0.6,1.9,0.8,2.7c0.2,0.9,0.3,1.6,0.5,2.4c0.1,0.4,0.1,0.7,0.2,1c0,0.3,0.1,0.6,0.1,0.9
13
+ c0.1,0.6,0.1,1,0.1,1.4C74,39.6,74,40,74,40c0.2,2.2-1.5,4.1-3.7,4.3s-4.1-1.5-4.3-3.7c0-0.1,0-0.2,0-0.3l0-0.4c0,0,0-0.3,0-0.9
14
+ c0-0.3,0-0.7,0-1.1c0-0.2,0-0.5,0-0.7c0-0.2-0.1-0.5-0.1-0.8c-0.1-0.6-0.1-1.2-0.2-1.9c-0.1-0.7-0.3-1.4-0.4-2.2
15
+ c-0.2-0.8-0.5-1.6-0.7-2.4c-0.3-0.8-0.7-1.7-1.1-2.6c-0.5-0.9-0.9-1.8-1.5-2.7c-0.6-0.9-1.2-1.8-1.9-2.7c-1.4-1.8-3.2-3.4-5.2-4.9
16
+ c-2-1.5-4.4-2.7-6.9-3.6c-0.6-0.2-1.3-0.4-1.9-0.6c-0.7-0.2-1.3-0.3-1.9-0.4c-1.2-0.3-2.8-0.4-4.2-0.5l-2,0c-0.7,0-1.4,0.1-2.1,0.1
17
+ c-0.7,0.1-1.4,0.1-2,0.3c-0.7,0.1-1.3,0.3-2,0.4c-2.6,0.7-5.2,1.7-7.5,3.1c-2.2,1.4-4.3,2.9-6,4.7c-0.9,0.8-1.6,1.8-2.4,2.7
18
+ c-0.7,0.9-1.3,1.9-1.9,2.8c-0.5,1-1,1.9-1.4,2.8c-0.4,0.9-0.8,1.8-1,2.6c-0.3,0.9-0.5,1.6-0.7,2.4c-0.2,0.7-0.3,1.4-0.4,2.1
19
+ c-0.1,0.3-0.1,0.6-0.2,0.9c0,0.3-0.1,0.6-0.1,0.8c0,0.5-0.1,0.9-0.1,1.3C10,39.6,10,40,10,40z`,children:(0,f.jsx)(`animateTransform`,{attributeType:`xml`,attributeName:`transform`,type:`rotate`,from:`0 40 40`,to:`360 40 40`,dur:`0.8s`,repeatCount:`indefinite`})}),(0,f.jsx)(`path`,{fill:`currentColor`,d:`M62,40.1c0,0,0,0.2-0.1,0.7c0,0.2,0,0.5-0.1,0.8c0,0.2,0,0.3,0,0.5c0,0.2-0.1,0.4-0.1,0.7
20
+ c-0.1,0.5-0.2,1-0.3,1.6c-0.2,0.5-0.3,1.1-0.5,1.8c-0.2,0.6-0.5,1.3-0.7,1.9c-0.3,0.7-0.7,1.3-1,2.1c-0.4,0.7-0.9,1.4-1.4,2.1
21
+ c-0.5,0.7-1.1,1.4-1.7,2c-1.2,1.3-2.7,2.5-4.4,3.6c-1.7,1-3.6,1.8-5.5,2.4c-2,0.5-4,0.7-6.2,0.7c-1.9-0.1-4.1-0.4-6-1.1
22
+ c-1.9-0.7-3.7-1.5-5.2-2.6c-1.5-1.1-2.9-2.3-4-3.7c-0.6-0.6-1-1.4-1.5-2c-0.4-0.7-0.8-1.4-1.2-2c-0.3-0.7-0.6-1.3-0.8-2
23
+ c-0.2-0.6-0.4-1.2-0.6-1.8c-0.1-0.6-0.3-1.1-0.4-1.6c-0.1-0.5-0.1-1-0.2-1.4c-0.1-0.9-0.1-1.5-0.1-2c0-0.5,0-0.7,0-0.7
24
+ s0,0.2,0.1,0.7c0.1,0.5,0,1.1,0.2,2c0.1,0.4,0.2,0.9,0.3,1.4c0.1,0.5,0.3,1,0.5,1.6c0.2,0.6,0.4,1.1,0.7,1.8
25
+ c0.3,0.6,0.6,1.2,0.9,1.9c0.4,0.6,0.8,1.3,1.2,1.9c0.5,0.6,1,1.3,1.6,1.8c1.1,1.2,2.5,2.3,4,3.2c1.5,0.9,3.2,1.6,5,2.1
26
+ c1.8,0.5,3.6,0.6,5.6,0.6c1.8-0.1,3.7-0.4,5.4-1c1.7-0.6,3.3-1.4,4.7-2.4c1.4-1,2.6-2.1,3.6-3.3c0.5-0.6,0.9-1.2,1.3-1.8
27
+ c0.4-0.6,0.7-1.2,1-1.8c0.3-0.6,0.6-1.2,0.8-1.8c0.2-0.6,0.4-1.1,0.5-1.7c0.1-0.5,0.2-1,0.3-1.5c0.1-0.4,0.1-0.8,0.1-1.2
28
+ c0-0.2,0-0.4,0.1-0.5c0-0.2,0-0.4,0-0.5c0-0.3,0-0.6,0-0.8c0-0.5,0-0.7,0-0.7c0-1.1,0.9-2,2-2s2,0.9,2,2C62,40,62,40.1,62,40.1z`,children:(0,f.jsx)(`animateTransform`,{attributeType:`xml`,attributeName:`transform`,type:`rotate`,from:`0 40 40`,to:`-360 40 40`,dur:`0.6s`,repeatCount:`indefinite`})})]})}var m=(e,t,n,r)=>({history:{pointer:0,items:[{name:`Initial`,base64:r,width:t,height:n}]},currentAction:null,extension:e,sidebar:!1}),h=(0,t.createContext)(void 0),g=({children:e,base64:n,width:r,height:i,ext:a})=>{let[o,s]=(0,t.useState)(m(a,r,i,n)),c=()=>o.currentAction,l=e=>s(t=>({...t,currentAction:e})),u=e=>s(t=>{let n=t.history.pointer+1,r=[...t.history.items.slice(0,n),e];return{...t,currentAction:null,history:{items:r,pointer:n}}}),d=()=>o.history.items.at(o.history.pointer),p=()=>s(e=>({...e,history:m(a,r,i,n).history})),g=()=>s(e=>{let t=e.history.items.at(e.history.pointer);return{...e,history:{items:[t],pointer:0}}}),_=()=>s(e=>e.history.pointer<=0?e:{...e,history:{...e.history,pointer:e.history.pointer-1}}),v=()=>s(e=>e.history.pointer>=e.history.items.length-1?e:{...e,history:{...e.history,pointer:e.history.pointer+1}}),y=()=>o.sidebar,b=e=>s(t=>({...t,sidebar:e}));return(0,f.jsx)(h,{value:{...o,getCurrentAction:c,setCurrentAction:l,addToHistory:u,resetHistory:p,resetHistoryAfterSave:g,undo:_,redo:v,getLastHistoryItem:d,getSidebar:y,setSidebar:b},children:e})},_={"image/jpeg":`jpg`,"image/jpg":`jpg`,"image/png":`png`,"image/gif":`gif`,"image/webp":`webp`},v=e=>{let[n,r]=(0,t.useState)({loading:!0,error:null,width:0,height:0,extension:null,base64:null});return(0,t.useEffect)(()=>{let t=!0;return(async()=>{try{let n=await fetch(e);if(!n.ok)throw Error(`HTTP error! Status: ${n.status}`);let i=(n.headers.get(`content-type`)||``).split(`;`)[0].toLowerCase().trim(),a=i.startsWith(`image/`),o=_[i]||`unknown`;if(!a){t&&r(e=>({...e,loading:!1,error:`The requested resource is not a valid image.`,extension:o}));return}let s=await n.blob(),c=await new Promise((e,t)=>{let n=new FileReader;n.onloadend=()=>e(n.result),n.onerror=()=>t(Error(`Failed to read image data stream`)),n.readAsDataURL(s)}),l=await new Promise((e,t)=>{let n=new Image;n.src=c,n.onload=()=>e({width:n.naturalWidth,height:n.naturalHeight}),n.onerror=()=>t(Error(`Failed to parse image dimensions`))});t&&r({loading:!1,error:null,width:l.width,height:l.height,extension:o,base64:c})}catch(e){t&&r(t=>({...t,loading:!1,error:e instanceof Error?e.message:`An error occurred during extraction.`}))}})(),()=>{t=!1}},[e]),n},y=()=>{let e=(0,t.useRef)(null),n=(0,t.useCallback)(e=>{let t=e.match(/^data:(image\/[a-zA-Z+.-]+);base64,(.+)$/);if(!t)throw Error(`Invalid Base64 image format`);let n=t[1],r=t[2];return n===`image/gif`&&(n=`image/png`),{mimeType:n,rawData:r}},[]),r=(0,t.useCallback)(async e=>{let{mimeType:t,rawData:r}=n(e),i=atob(r),a=new Uint8Array(i.length);for(let e=0;e<i.length;e++)a[e]=i.charCodeAt(e);let o=new Blob([a],{type:t});return{bitmap:await createImageBitmap(o),mimeType:t}},[n]),i=(0,t.useCallback)(t=>{e.current||=document.createElement(`canvas`);let n=e.current,r=t===`image/png`||t===`image/webp`;return{canvas:n,ctx:n.getContext(`2d`,{alpha:r})}},[]),a=(0,t.useCallback)((e,t)=>t===`image/jpeg`||t===`image/webp`?e.toDataURL(t,.85):e.toDataURL(t),[]);return{resize:(0,t.useCallback)(async(e,t,n)=>{let{bitmap:o,mimeType:s}=await r(e),{canvas:c,ctx:l}=i(s);return c.width=t,c.height=n,l&&(l.clearRect(0,0,t,n),l.drawImage(o,0,0,t,n)),o.close(),a(c,s)},[r,i,a]),crop:(0,t.useCallback)(async(e,t,n,o,s)=>{let{bitmap:c,mimeType:l}=await r(e),{canvas:u,ctx:d}=i(l);return u.width=o,u.height=s,d&&(d.clearRect(0,0,o,s),d.drawImage(c,t,n,o,s,0,0,o,s)),c.close(),a(u,l)},[r,i,a]),flip:(0,t.useCallback)(async(e,t,n)=>{let{bitmap:o,mimeType:s}=await r(e),{canvas:c,ctx:l}=i(s);return c.width=o.width,c.height=o.height,l&&(l.clearRect(0,0,c.width,c.height),l.save(),l.translate(t?o.width:0,n?o.height:0),l.scale(t?-1:1,n?-1:1),l.drawImage(o,0,0),l.restore()),o.close(),a(c,s)},[r,i,a]),rotate:(0,t.useCallback)(async(e,t)=>{let{bitmap:n,mimeType:o}=await r(e),{canvas:s,ctx:c}=i(o);return s.width=n.width,s.height=n.height,c&&(c.clearRect(0,0,s.width,s.height),c.save(),c.translate(n.width/2,n.height/2),c.rotate(t*Math.PI/180),c.drawImage(n,-n.width/2,-n.height/2),c.restore()),n.close(),a(s,o)},[r,i,a]),filter:(0,t.useCallback)(async(e,t)=>{let{bitmap:n,mimeType:o}=await r(e),{canvas:s,ctx:c}=i(o);return s.width=n.width,s.height=n.height,c&&(c.filter=Object.entries(t).map(([e,t])=>`${e}(${t}%)`).join(` `),c.drawImage(n,0,0)),n.close(),a(s,o)},[r,i,a])}},b=()=>{if(typeof window>`u`||!window.navigator)return null;let e=window.navigator.userAgent.toLowerCase();return/android/.test(e)?`android`:/iphone|ipad|ipod/.test(e)?`ios`:/windows phone/.test(e)?`windows-phone`:/blackberry|bb10/.test(e)?`blackberry`:/opera mini/.test(e)?`opera-mini`:/mobile/.test(e)?`mobile`:null},x=()=>{let[e]=(0,t.useState)(()=>b());return e},S={sm:640,md:768,lg:1024,xl:1280};function C(e){let[n,r]=(0,t.useState)(()=>window.innerWidth<S[e]);return(0,t.useEffect)(()=>{function t(){r(window.innerWidth<S[e])}return window.addEventListener(`resize`,t),()=>window.removeEventListener(`resize`,t)},[e]),n}var w={xmlns:`http://w3.org`,width:`24`,height:`24`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`},T=e=>(0,f.jsx)(`svg`,{...w,...e,children:(0,f.jsx)(`path`,{d:`M20 6 9 17l-5-5`})}),E=e=>(0,f.jsxs)(`svg`,{...w,...e,children:[(0,f.jsx)(`path`,{d:`M18 6 6 18`}),(0,f.jsx)(`path`,{d:`m6 6 12 12`})]}),D=e=>(0,f.jsxs)(`svg`,{...w,...e,children:[(0,f.jsx)(`rect`,{width:`18`,height:`11`,x:`3`,y:`11`,rx:`2`,ry:`2`}),(0,f.jsx)(`path`,{d:`M7 11V7a5 5 0 0 1 10 0v4`})]}),O=e=>(0,f.jsxs)(`svg`,{...w,...e,children:[(0,f.jsx)(`path`,{d:`m12 19-7-7 7-7`}),(0,f.jsx)(`path`,{d:`M19 12H5`})]}),k=e=>(0,f.jsx)(`svg`,{...w,...e,children:(0,f.jsx)(`path`,{d:`m6 9 6 6 6-6`})}),A=e=>(0,f.jsxs)(`svg`,{...w,...e,children:[(0,f.jsx)(`path`,{d:`M3 7v6h6`}),(0,f.jsx)(`path`,{d:`M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13`})]}),ee=e=>(0,f.jsxs)(`svg`,{...w,...e,children:[(0,f.jsx)(`path`,{d:`M21 7v6h-6`}),(0,f.jsx)(`path`,{d:`M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3l3 2.7`})]}),j=e=>(0,f.jsxs)(`svg`,{...w,...e,children:[(0,f.jsx)(`path`,{d:`M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915`}),(0,f.jsx)(`circle`,{cx:`12`,cy:`12`,r:`3`})]}),M=e=>(0,f.jsxs)(`svg`,{...w,...e,children:[(0,f.jsx)(`path`,{d:`M6 2v14a2 2 0 0 0 2 2h14`}),(0,f.jsx)(`path`,{d:`M18 22V8a2 2 0 0 0-2-2H2`})]}),N=e=>(0,f.jsxs)(`svg`,{...w,...e,children:[(0,f.jsx)(`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,ry:`2`}),(0,f.jsx)(`circle`,{cx:`9`,cy:`9`,r:`2`}),(0,f.jsx)(`path`,{d:`m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21`})]}),P=e=>(0,f.jsx)(`svg`,{...w,...e,children:(0,f.jsx)(`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`})}),F=e=>(0,f.jsxs)(`svg`,{...w,...e,children:[(0,f.jsx)(`path`,{d:`M3 7V5a2 2 0 0 1 2-2h2`}),(0,f.jsx)(`path`,{d:`M17 3h2a2 2 0 0 1 2 2v2`}),(0,f.jsx)(`path`,{d:`M21 17v2a2 2 0 0 1-2 2h-2`}),(0,f.jsx)(`path`,{d:`M7 21H5a2 2 0 0 1-2-2v-2`}),(0,f.jsx)(`rect`,{width:`10`,height:`8`,x:`7`,y:`8`,rx:`1`})]}),I=e=>(0,f.jsx)(`svg`,{...w,...e,children:(0,f.jsx)(`path`,{d:`M21 12a9 9 0 1 1-6.219-8.56`,children:(0,f.jsx)(`animateTransform`,{attributeType:`xml`,attributeName:`transform`,type:`rotate`,from:`0 12 12`,to:`360 12 12`,dur:`0.8s`,repeatCount:`indefinite`})})}),L=()=>{let e=(0,t.useContext)(h);if(!e)throw Error(`useImageEditorContext must be used within an ImageEditorProvider`);return e},R=(0,t.forwardRef)(({className:e=``,variant:t=`default`,children:n,...r},i)=>(0,f.jsx)(`button`,{ref:i,className:`btn ${`btn-${t}`} ${e}`.trim(),...r,children:n})),z=(0,t.forwardRef)(({className:e=``,active:t=!1,icon:n,label:r,...i},a)=>(0,f.jsxs)(`button`,{ref:a,type:`button`,"aria-pressed":t,className:`btn-crop ${e}`.trim(),...i,children:[n,(0,f.jsx)(`span`,{className:`semibold`,children:r})]}));z.displayName=`ButtonCrop`;var B=(0,t.forwardRef)(({className:e=``,orientation:t=`horizontal`,...n},r)=>(0,f.jsx)(`hr`,{ref:r,role:`separator`,"aria-orientation":t,"data-orientation":t,className:`separator ${e}`.trim(),...n}));B.displayName=`Separator`;var te=({items:e,value:n,onChange:r,placeholder:i=`Select an option`,className:a=``,renderOption:o})=>{let[s,c]=(0,t.useState)(!1),l=(0,t.useRef)(null),u=(0,t.useRef)(null),d=(0,t.useRef)(null),p=(0,t.useMemo)(()=>{let t=e=>e.reduce((e,n)=>n.options?[...e,...t(n.options.map(e=>({...e,fullName:`${n.label} ${e.label}`})))]:[...e,n],[]);return t(e)},[e]).find(e=>e.value===n);(0,t.useEffect)(()=>{let e=e=>{l.current&&!l.current.contains(e.target)&&c(!1)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[]),(0,t.useLayoutEffect)(()=>{if(!s||!u.current||!d.current)return;let e=l.current?.closest(`.picedi.main`)?.getBoundingClientRect(),t=u.current.getBoundingClientRect(),n=d.current.getBoundingClientRect(),r=(e?.bottom??window.innerHeight)-16,i=t.bottom+n.height+4,a=`calc(100% + 4px)`;i>r&&(a=`calc(100% + 4px - ${i-r}px)`),d.current.style.top=a},[s,e]);let m=e=>{r(e),c(!1)};return(0,f.jsxs)(`div`,{ref:l,className:`select-wrapper ${a}`.trim(),"data-state":s?`open`:`closed`,children:[(0,f.jsxs)(`button`,{ref:u,type:`button`,className:`select-trigger`,onClick:()=>c(!s),children:[(0,f.jsx)(`span`,{children:p?p.fullName:i}),(0,f.jsx)(k,{className:`select-trigger-arrow`})]}),(0,f.jsx)(`div`,{ref:d,className:`select-content`,children:e.map((e,t)=>e.options?(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`div`,{className:`select-group-label semibold`,children:e.label}),e.options.map(e=>(0,f.jsxs)(`div`,{className:`select-item`,onClick:()=>m(e.value),children:[o?o(e):(0,f.jsx)(`span`,{className:`select-item-left`,children:e.label}),(0,f.jsxs)(`div`,{className:`select-item-addon`,children:[e.rightLabel&&(0,f.jsx)(`span`,{children:e.rightLabel}),n===e.value&&(0,f.jsx)(T,{className:`select-item-check`}),n!==e.value&&(0,f.jsx)(`b`,{})]})]},e.value))]},`group-${t}`):(0,f.jsxs)(`div`,{className:`select-item`,onClick:()=>m(e.value),children:[o?o(e):(0,f.jsxs)(`span`,{className:`select-item-left`,children:[e.label,`1`]}),n===e.value&&(0,f.jsx)(T,{className:`select-item-check`})]},e.value))})]})},V=(0,t.forwardRef)(({className:e=``,type:t=`text`,hideArrows:n=!0,...r},i)=>(0,f.jsx)(`input`,{ref:i,type:t,className:`input ${t===`number`&&n?`input-number-clean`:``} ${e}`.trim(),...r}));V.displayName=`Input`;var H=(0,t.forwardRef)(({label:e,className:t=``,style:n,...r},i)=>(0,f.jsxs)(`div`,{className:`input-pixel-container ${t}`.trim(),style:n,children:[(0,f.jsx)(`span`,{className:`input-pixel-legend`,children:e}),(0,f.jsx)(V,{ref:i,type:`number`,...r}),(0,f.jsx)(`span`,{className:`input-pixel-suffix`,children:`px`})]})),ne=({onBack:e,onSave:n})=>{let[r,i]=(0,t.useState)(!1),{history:a,undo:o,redo:s,resetHistory:c,resetHistoryAfterSave:l,getLastHistoryItem:u}=L(),{base64:d}=u(),p=a.items.length>1&&!r,m=a.pointer===0,h=a.pointer===a.items.length-1,g=a.items.length<2||r;return(0,f.jsxs)(`div`,{className:`header`,children:[(0,f.jsx)(R,{variant:`ghost`,className:`btn-rect`,onClick:e,children:(0,f.jsx)(O,{})}),(0,f.jsxs)(`div`,{className:`header-tools`,children:[p&&(0,f.jsxs)(`div`,{className:`header-history`,children:[(0,f.jsx)(R,{variant:`outline`,disabled:m,className:`btn-rect`,onClick:o,children:(0,f.jsx)(A,{})}),(0,f.jsxs)(`div`,{className:`header-history-text`,children:[a.pointer+1,`/`,a.items.length]}),(0,f.jsx)(R,{variant:`outline`,disabled:h,className:`btn-rect`,onClick:s,children:(0,f.jsx)(ee,{})})]}),(0,f.jsx)(R,{variant:`outline`,disabled:r,onClick:c,children:`Reset`}),(0,f.jsxs)(R,{disabled:g,onClick:async()=>{if(d){i(!0);try{await n(d),l()}finally{i(!1)}}},children:[r?(0,f.jsx)(I,{}):(0,f.jsx)(T,{}),`Save`]})]})]})},U=32,W=e=>({x:e.offsetLeft,y:e.offsetTop,w:e.offsetWidth,h:e.offsetHeight}),re=(e,t,n,r,i,a,o,s)=>{let{x:c}=o,{y:l,w:u,h:d}=o;if(e)u+=r-n,u+c>i&&(u=i-c),u<U&&(u=U);else{let e=r-n,o=Math.round(e/t);if(u+=e,d+=o,l-=o/2,l<0||d+l>a||u+c>i||u<U||d<U)return W(s)}return{x:c,y:l,w:u,h:d}},ie=(e,t,n,r,i,a,o,s)=>{let{x:c,y:l,w:u,h:d}=o;if(e){let e=i-o.w-o.x;c+=r-n,c<0&&(c=0),u=i-c-e,u<U&&(u=U,c=i-e-U)}else{let e=r-n,i=Math.round(e/t);if(u-=e,d-=i,c+=e,l+=i/2,l<0||c<0||d+l>a||u<U||d<U)return W(s)}return{x:c,y:l,w:u,h:d}},ae=(e,t,n,r,i,a,o,s)=>{let{x:c,y:l,w:u,h:d}=o,f=a-d-l;if(e)l+=r-n,l<0&&(l=0),d=a-l-f,d<U&&(d=U,l=a-f-U);else{let e=r-n,a=Math.round(e*t);if(d-=e,u-=a,c+=a/2,l+=e,l<0||c<0||u+c>i||u<U||d<U)return W(s)}return{x:c,y:l,w:u,h:d}},oe=(e,t,n,r,i,a,o,s)=>{let{y:c}=o,{x:l,w:u,h:d}=o;if(e)d+=r-n,d+c>a&&(d=a-c),d<U&&(d=U);else{let e=r-n,o=Math.round(e*t);if(d+=e,u+=o,l-=o/2,d+c>a||l<0||u+l>i||u<U||d<U)return W(s)}return{x:l,y:c,w:u,h:d}},se=(e,t,n,r,i,a,o,s,c,l)=>{let{x:u,y:d,w:f,h:p}=c;if(e){let e=o-c.w-c.x;u+=i-n,u<0&&(u=0),f=o-u-e,f<U&&(f=U,u=o-e-U);let t=s-p-d;d+=a-r,d<0&&(d=0),p=s-d-t,p<U&&(p=U,d=s-t-U)}else{if(t>=1){let e=i-n,r=Math.round(e/t);f-=e,p-=r,u+=e,d+=r}else{let e=a-r,n=Math.round(e*t);f-=n,p-=e,u+=n,d+=e}if(u<0||d<0||f<U||p<U)return W(l)}return{x:u,y:d,w:f,h:p}},ce=(e,t,n,r,i,a,o,s,c,l)=>{let{x:u}=c,{y:d,w:f,h:p}=c;if(e){f+=i-n,f+u>o&&(f=o-u),f<U&&(f=U);let e=s-p-d;d+=a-r,d<0&&(d=0),p=s-d-e,p<U&&(p=U,d=s-e-U)}else{if(t>1){let e=i-n,r=Math.round(e/t);f+=e,p+=r,d-=r}else{let e=a-r,n=Math.round(e*t);f-=n,p-=e,d+=e}if(f+u>o||d<0||f<U||p<U)return W(l)}return{x:u,y:d,w:f,h:p}},le=(e,t,n,r,i,a,o,s,c,l)=>{let{y:u}=c,{x:d,w:f,h:p}=c;if(e){p+=a-r,p+u>s&&(p=s-u),p<U&&(p=U);let e=o-c.w-c.x;d+=i-n,d<0&&(d=0),f=o-d-e,f<U&&(f=U,d=o-e-U)}else{if(t>=1){let e=i-n,r=Math.round(e/t);f-=e,p-=r,d+=e}else{let e=a-r,n=Math.round(e*t);f+=n,p+=e,d-=n}if(p+u>s||d<0||f<U||p<U)return W(l)}return{x:d,y:u,w:f,h:p}},ue=(e,t,n,r,i,a,o,s,c,l)=>{let{x:u,y:d}=c,{w:f,h:p}=c;if(e)f+=i-n,f+u>o&&(f=o-u),f<U&&(f=U),p+=a-r,p+d>s&&(p=s-d),p<U&&(p=U);else{if(t>=1){let e=i-n,r=Math.round(e/t);f+=e,p+=r}else{let e=a-r,n=Math.round(e*t);f+=n,p+=e}if(p+d>s||f+u>o||f<U||p<U)return W(l)}return{x:u,y:d,w:f,h:p}},de=(e,t,n,r,i,a,o,s,c,l,u)=>e===`r`?re(t,n,r,a,s,c,l,u):e===`l`?ie(t,n,r,a,s,c,l,u):e===`t`?ae(t,n,i,o,s,c,l,u):e===`b`?oe(t,n,i,o,s,c,l,u):e===`tl`?se(t,n,r,i,a,o,s,c,l,u):e===`tr`?ce(t,n,r,i,a,o,s,c,l,u):e===`bl`?le(t,n,r,i,a,o,s,c,l,u):e===`br`?ue(t,n,r,i,a,o,s,c,l,u):{x:0,y:0,w:0,h:0},G=(e,t,n)=>{let r=.1,i=t/n,a=0,o=0;e===1&&(a=(i>1?n:t)*(1-r*2),o=a),e>1&&(i>e?(o=n*(1-r*2),a=o*e):(a=t*(1-r*2),o=a/e)),e<1&&(i>e?(o=n*(1-r*2),a=o*e):(a=t*(1-r*2),o=a/e));let s=a/t*100,c=o/n*100;return{x:(t-a)/2/t*100,y:(n-o)/2/n*100,w:s,h:c,xPx:Math.round((t-a)/2),yPx:Math.round((n-o)/2),wPx:a,hPx:o}},fe=()=>{let{getCurrentAction:e,getLastHistoryItem:n}=L(),r=e(),i=x(),a=(0,t.useRef)(null),o=(0,t.useRef)(null),{handleCropStart:s}=ye({imgRef:a,cropRef:o});if(!r||r.name!==`crop`)return null;let{width:c,height:l,base64:u}=n(),{x:d,y:p,w:m,h}=G(r.args.ratio,c,l);return(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(`img`,{ref:a,src:u,alt:`Image`,className:`crop-image`,style:{clipPath:`xywh(${d}% ${p}% ${m}% ${h}%)`}}),(0,f.jsxs)(`div`,{ref:o,className:`crop-box`,style:{width:`${m}%`,height:`${h}%`,top:`${p}%`,left:`${d}%`},children:[(0,f.jsx)(he,{}),i?(0,f.jsx)(be,{onMouseDown:s}):(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(me,{onMouseDown:s}),(0,f.jsx)(ge,{onMouseDown:s})]})]})]})},K=new EventTarget,q=e=>{let t=new CustomEvent(`crop-update`,{detail:e});K.dispatchEvent(t)},pe=()=>{let{setCurrentAction:e,getCurrentAction:n,getLastHistoryItem:r,addToHistory:i,setSidebar:a}=L(),{crop:o,resize:s}=y(),[c,l]=(0,t.useState)(!1),u=n(),{base64:d,width:p,height:m}=r(),h=(0,t.useRef)(null),g=(0,t.useRef)(null),_=(0,t.useRef)(null),v=(0,t.useRef)(null),b=(0,t.useRef)(null);return(0,t.useEffect)(()=>{if(u?.name!==`crop`)return;let{x:e,y:t,w:n,h:r}=G(u.args.ratio,p,m),i=Math.round(e/100*p),a=Math.round(t/100*m),o=Math.round(n/100*p),s=Math.round(r/100*m);h.current&&(h.current.textContent=i.toString()),g.current&&(g.current.textContent=a.toString()),_.current&&(_.current.textContent=o.toString()),v.current&&(v.current.textContent=s.toString()),b.current={x:i,y:a,w:o,h:s};let c=e=>{let t=e,{x:n,y:r,w:i,h:a}=t.detail;b.current=t.detail,h.current&&(h.current.textContent=n.toString()),g.current&&(g.current.textContent=r.toString()),_.current&&(_.current.textContent=i.toString()),v.current&&(v.current.textContent=a.toString())};return K.addEventListener(`crop-update`,c),()=>{K.removeEventListener(`crop-update`,c)}},[u,p,m]),(0,f.jsxs)(`div`,{className:`crop-tools`,children:[(0,f.jsxs)(`div`,{className:`crop-tools-info`,children:[(0,f.jsx)(`div`,{className:`crop-tools-info-label`,children:`left`}),(0,f.jsx)(`div`,{className:`crop-tools-info-value semibold`,ref:h})]}),(0,f.jsxs)(`div`,{className:`crop-tools-info`,children:[(0,f.jsx)(`div`,{className:`crop-tools-info-label`,children:`top`}),(0,f.jsx)(`div`,{className:`crop-tools-info-value semibold`,ref:g})]}),(0,f.jsxs)(`div`,{className:`crop-tools-info`,children:[(0,f.jsx)(`div`,{className:`crop-tools-info-label`,children:`width`}),(0,f.jsx)(`div`,{className:`crop-tools-info-value semibold`,ref:_})]}),(0,f.jsxs)(`div`,{className:`crop-tools-info`,children:[(0,f.jsx)(`div`,{className:`crop-tools-info-label`,children:`height`}),(0,f.jsx)(`div`,{className:`crop-tools-info-value semibold`,ref:v})]}),(0,f.jsx)(B,{orientation:`vertical`}),(0,f.jsx)(R,{variant:`ghost`,className:`text-green`,style:{height:`36px`,width:`36px`},disabled:c,onClick:async()=>{if(!(!u||u.name!==`crop`))try{if(l(!0),!b.current)return;let{x:e,y:t,w:n,h:r}=b.current,{preset:c}=u.args,f=await o(d,e,t,n,r);if(c){let{w:e,h:t}=c;f=await s(f,e,t)}i({name:`Crop`,base64:f,width:c?c.w:b.current.w,height:c?c.h:b.current.h}),a(!0)}catch(e){console.error(`Failed to process image:`,e)}finally{l(!1)}},children:c?(0,f.jsx)(I,{}):(0,f.jsx)(T,{})}),(0,f.jsx)(B,{orientation:`vertical`}),(0,f.jsx)(R,{variant:`ghost`,style:{height:`36px`,width:`36px`},disabled:c,onClick:()=>{e(null),a(!0)},children:(0,f.jsx)(E,{className:`text-red`})})]})},me=({onMouseDown:e})=>(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(`span`,{className:`crop-b crop-b-t`,onMouseDown:t=>e(t,`t`,`ns`)}),(0,f.jsx)(`span`,{className:`crop-b crop-b-r`,onMouseDown:t=>e(t,`r`,`ew`)}),(0,f.jsx)(`span`,{className:`crop-b crop-b-b`,onMouseDown:t=>e(t,`b`,`ns`)}),(0,f.jsx)(`span`,{className:`crop-b crop-b-l`,onMouseDown:t=>e(t,`l`,`ew`)})]}),he=()=>(0,f.jsxs)(`div`,{className:`crop-l-box`,children:[(0,f.jsx)(`span`,{className:`crop-l crop-l-v`}),(0,f.jsx)(`span`,{className:`crop-l crop-l-h`})]}),ge=({onMouseDown:e})=>(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(`span`,{className:`crop-ps crop-ps-tl`,onMouseDown:t=>e(t,`tl`,`nwse`)}),(0,f.jsx)(`span`,{className:`crop-ps crop-ps-t`,onMouseDown:t=>e(t,`t`,`ns`)}),(0,f.jsx)(`span`,{className:`crop-ps crop-ps-tr`,onMouseDown:t=>e(t,`tr`,`nesw`)}),(0,f.jsx)(`span`,{className:`crop-ps crop-ps-r`,onMouseDown:t=>e(t,`r`,`ew`)}),(0,f.jsx)(`span`,{className:`crop-ps crop-ps-br`,onMouseDown:t=>e(t,`br`,`nwse`)}),(0,f.jsx)(`span`,{className:`crop-ps crop-ps-b`,onMouseDown:t=>e(t,`b`,`ns`)}),(0,f.jsx)(`span`,{className:`crop-ps crop-ps-bl`,onMouseDown:t=>e(t,`bl`,`nesw`)}),(0,f.jsx)(`span`,{className:`crop-ps crop-ps-l`,onMouseDown:t=>e(t,`l`,`ew`)})]});function J(e,t,n){return Math.min(Math.max(e,t),n)}function Y(e,t){return e/t*100}function _e(e,t,n,r,i){e.style.left=`${t}%`,e.style.top=`${n}%`,e.style.width=`${r}%`,e.style.height=`${i}%`}function ve(e,t,n,r,i){e.style.clipPath=`xywh(${t}% ${n}% ${r}% ${i}%)`}var ye=({imgRef:e,cropRef:n})=>{let{getCurrentAction:r,getLastHistoryItem:i}=L(),a=x(),o=(0,t.useRef)(null),s=(0,t.useRef)(``),c=(0,t.useRef)({xPct:0,yPct:0}),l=(0,t.useRef)({x:0,y:0,w:0,h:0});return(0,t.useEffect)(()=>{let t=e=>{if(n.current){let e=n.current.parentElement;e&&(c.current={xPct:Y(n.current.offsetLeft,e.offsetWidth),yPct:Y(n.current.offsetTop,e.offsetHeight)})}let t=`clientX`in e?e.clientX:e.touches[0].clientX,r=`clientY`in e?e.clientY:e.touches[0].clientY;o.current={x:t,y:r},document.body.style.cursor=`move`},a=t=>{if(!e.current||!n.current||!o.current)return;let r=n.current,i=e.current,a=r.parentElement;if(!a)return;let c=a.offsetWidth,l=a.offsetHeight;if(s.current){u(t,r,i,c,l);return}d(t,r,i,c,l)},u=(e,t,n,a,c)=>{let u=r();if(!u||u.name!==`crop`||!o.current)return;let{isFree:d,ratio:f}=u.args,p=`clientX`in e?e.clientX:e.touches[0].clientX,m=`clientY`in e?e.clientY:e.touches[0].clientY,{x:h,y:g,w:_,h:v}=de(s.current,d,f,o.current.x,o.current.y,p,m,a,c,l.current,t),y=Y(h,a),b=Y(g,c),x=Y(_,a),S=Y(v,c);_e(t,y,b,x,S),ve(n,y,b,x,S);let C=i();if(!C)return;let{width:w,height:T}=C;q({x:Math.round(y/100*w),y:Math.round(b/100*T),w:Math.round(x/100*w),h:Math.round(S/100*T)})},d=(e,t,n,r,a)=>{if(!o.current)return;console.log(`HandleDrag`);let s=t.offsetWidth,l=t.offsetHeight,u=`clientX`in e?e.clientX:e.touches[0].clientX,d=`clientY`in e?e.clientY:e.touches[0].clientY,f=Y(u-o.current.x,r),p=Y(d-o.current.y,a);o.current={x:u,y:d};let m=Y(r-s,r),h=Y(a-l,a),g=J(c.current.xPct+f,0,m),_=J(c.current.yPct+p,0,h),v=Y(s,r),y=Y(l,a);c.current={xPct:g,yPct:_},_e(t,g,_,v,y),ve(n,g,_,v,y);let{width:b,height:x}=i();q({x:Math.round(g/100*b),y:Math.round(_/100*x),w:Math.round(v/100*b),h:Math.round(y/100*x)})},f=()=>{n.current&&(o.current=null,s.current=``,n.current.style.cursor=`move`,document.body.style.cursor=`auto`)};if(!n.current)return;let p=new AbortController,{signal:m}=p;return n.current.addEventListener(`mousedown`,t,{signal:m}),n.current.addEventListener(`touchstart`,t,{signal:m}),document.addEventListener(`mousemove`,a,{signal:m}),document.addEventListener(`touchmove`,a,{signal:m}),document.addEventListener(`mouseup`,f,{signal:m}),document.addEventListener(`touchend`,f,{signal:m}),()=>p.abort()},[r,i,e,n]),{handleCropStart:(e,t,r)=>{if(!n.current)return;e.stopPropagation(),l.current={x:n.current.offsetLeft,y:n.current.offsetTop,w:n.current.offsetWidth,h:n.current.offsetHeight};let i=`clientX`in e?e.clientX:e.touches[0].clientX,c=`clientY`in e?e.clientY:e.touches[0].clientY;o.current={x:i,y:c},s.current=t,a||(n.current.style.cursor=`${r}-resize`,document.body.style.cursor=`${r}-resize`)}}},be=({onMouseDown:e})=>(0,f.jsx)(`div`,{className:`crop-p-b`,children:(0,f.jsx)(`div`,{className:`crop-p-p`,onTouchStart:t=>e(t,`br`,`nwse`)})}),X=10,Z=200,Q=(e,t,n)=>(e<X&&(e=X),e>Z&&(e=Z),{updatedScale:e,updatedWidth:Math.round(e/100*t),updatedHeight:Math.round(e/100*n)}),xe=({onResizing:e})=>{let{getLastHistoryItem:n,setCurrentAction:r,addToHistory:i,setSidebar:a}=L(),{width:o,height:s,base64:c}=n(),[l,u]=(0,t.useState)(!1),[d,p]=(0,t.useState)(o),[m,h]=(0,t.useState)(s),g=(0,t.useRef)(0),{resize:_}=y(),v=x(),b=t=>{let{updatedScale:n,updatedWidth:r,updatedHeight:i}=Q(parseInt(t.target.value)/o*100,o,s);p(r),h(i),e(n)},S=t=>{let{updatedScale:n,updatedWidth:r,updatedHeight:i}=Q(parseInt(t.target.value)/s*100,o,s);h(i),p(r),e(n)},C=()=>{e(100),r(null),a(!0)},w=async()=>{try{u(!0);let t=await _(c,d,m);i({name:`Resize`,base64:t,width:d,height:m}),e(100),a(!0)}catch(e){console.error(`Failed to process image:`,e)}finally{u(!1)}};return(0,t.useEffect)(()=>{let t=Math.round(d/o*100),n=t=>{let{updatedHeight:n,updatedWidth:r}=Q(t,o,s);h(n),p(r),e(t)},r=e=>{if(l)return;let r=Math.sign(e.deltaY);t-=r*2,t<=X&&(t=X),t>=Z&&(t=Z),n(t)},i=e=>{g.current=e.touches[0].clientY},a=e=>{if(l)return;let r=e.touches[0].clientY,i=g.current-r;Math.abs(i)<10||(t+=Math.sign(i)*2,t<=X&&(t=X),t>=Z&&(t=Z),n(t),g.current=r)},c=new AbortController,{signal:u}=c;return window.addEventListener(`wheel`,r,{signal:u}),window.addEventListener(`touchstart`,i,{signal:u}),window.addEventListener(`touchmove`,a,{signal:u}),()=>c.abort()},[s,o,l,v,e,d]),(0,f.jsxs)(`div`,{className:`resize`,children:[(0,f.jsx)(`div`,{className:`resize-text`,children:v?`Slide UP/Down to Resize`:`Scroll UP/Down to Resize`}),(0,f.jsx)(`div`,{className:`resize-border`}),(0,f.jsxs)(`div`,{className:`resize-tools`,children:[(0,f.jsx)(H,{value:d,name:`width`,label:`Width`,disabled:l,style:{width:`88px`},onChange:b}),(0,f.jsx)(D,{className:`resize-tools-lock`}),(0,f.jsx)(H,{value:m,name:`height`,label:`Height`,disabled:l,style:{width:`88px`},onChange:S}),(0,f.jsxs)(`div`,{className:`resize-tools-buttons`,children:[(0,f.jsx)(R,{variant:`outline`,className:`resize-tools-save text-green`,disabled:d===o||l,onClick:()=>w(),children:l?(0,f.jsx)(I,{}):(0,f.jsx)(T,{})}),(0,f.jsx)(R,{variant:`outline`,className:`resize-tools-close text-red`,disabled:l,onClick:C,children:(0,f.jsx)(E,{})})]})]})]})},Se=()=>{let{getLastHistoryItem:e,currentAction:n}=L(),r=(0,t.useRef)(null),i=(0,t.useRef)(null),{width:a,height:o,base64:s}=e(),c=n?.name===`crop`,l=n?.name===`resize`,u=c||l,d=e=>{r.current&&(r.current.style.transform=`scale(${e/100})`)},p=`frame ${u?`mask`:``}`,m=`frame-image ${u?`frame-image--faded`:``}`;return(0,f.jsxs)(`div`,{className:p,children:[(0,f.jsxs)(`div`,{ref:r,style:{aspectRatio:`${a} / ${o}`},className:`frame-preview`,children:[(0,f.jsx)(`img`,{ref:i,src:s,alt:`Image`,className:m}),c&&(0,f.jsx)(fe,{},n?.args?.id)]}),l&&(0,f.jsx)(xe,{onResizing:d}),c&&(0,f.jsx)(pe,{})]})},Ce=()=>{let{getLastHistoryItem:e,setCurrentAction:t,setSidebar:n}=L(),{width:r,height:i}=e()??{width:0,height:0};return(0,f.jsxs)(R,{variant:`outline`,className:`sidebar-resize`,onClick:()=>{t({name:`resize`,args:{width:r,height:i}}),n(!1)},children:[(0,f.jsxs)(`div`,{className:`sidebar-resize-icon`,children:[(0,f.jsx)(F,{}),`Resize`]}),(0,f.jsxs)(`div`,{className:`sidebar-resize-size`,children:[r,` x `,i]})]})},we=()=>{let{currentAction:e,setCurrentAction:t,getLastHistoryItem:n,setSidebar:r}=L(),{name:i,args:a}=e||{},o=i===`crop`?a?.id:``,{width:s,height:c}=n(),l=s/c,u=e=>{e!==o&&(t({name:`crop`,args:{id:e,ratio:e===`1:1`?1:l,isFree:e===`freeform`,preset:null}}),r(!1))};return(0,f.jsxs)(`div`,{className:`sidebar-crop`,children:[(0,f.jsx)(`h4`,{children:`Crop`}),(0,f.jsxs)(`div`,{className:`sidebar-crop-ratios`,children:[(0,f.jsx)(z,{label:`Freeform`,icon:(0,f.jsx)(M,{}),active:o===`freeform`,onClick:()=>u(`freeform`)}),(0,f.jsx)(z,{label:`Original`,icon:(0,f.jsx)(N,{}),active:o===`original`,onClick:()=>u(`original`)}),(0,f.jsx)(z,{label:`1:1`,icon:(0,f.jsx)(P,{}),active:o===`1:1`,onClick:()=>u(`1:1`)})]})]})},$=[{label:`Facebook`,value:`facebook`,options:[{value:`facebook-post`,label:`Post`,w:1200,h:630,rightLabel:`1200 x 630`},{value:`facebook-cover`,label:`Cover`,w:851,h:315,rightLabel:`851 x 315`},{value:`facebook-profile`,label:`Profile`,w:170,h:170,rightLabel:`170 x 170`},{value:`facebook-story`,label:`Story`,w:1080,h:1920,rightLabel:`1080 x 1920`}]},{label:`Instagram`,value:`instagram`,options:[{value:`instagram-landscape`,label:`Landscape`,w:1080,h:566,rightLabel:`1080 x 566`},{value:`instagram-portait`,label:`Portait`,w:1080,h:1350,rightLabel:`1080 x 1350`},{value:`instagram-square`,label:`Square`,w:1080,h:1080,rightLabel:`1080 x 1080`},{value:`instagram-story`,label:`Story`,w:1080,h:1920,rightLabel:`1080 x 1920`},{value:`instagram-thumbnail`,label:`Thumbnail`,w:161,h:161,rightLabel:`161 x 161`}]},{label:`LinkedIn`,value:`linkedin`,options:[{value:`linkedin-blog-post`,label:`Blog Post`,w:1200,h:627,rightLabel:`1200 x 627`},{value:`linkedin-cover`,label:`Cover`,w:1128,h:191,rightLabel:`1128 x 191`},{value:`linkedin-profile`,label:`Profile`,w:400,h:400,rightLabel:`400 x 400`}]}],Te=$.map(e=>e.options).flat(),Ee=()=>{let{setCurrentAction:e,currentAction:t,setSidebar:n}=L(),r=t?.name===`crop`&&Te.some(e=>e.value===t.args.id)?t.args.id:``;return(0,f.jsxs)(`div`,{className:`sidebar-preset`,children:[(0,f.jsx)(`h4`,{children:`Presets`}),(0,f.jsx)(`div`,{className:`relative`,children:(0,f.jsx)(te,{value:r,placeholder:`Select a preset`,onChange:t=>{if(!t)return;let r=$.map(e=>e.options).flat().find(e=>e.value===t);if(!r)return;let i={id:t,ratio:r.w/r.h,isFree:!1,preset:{w:r.w,h:r.h}};e({name:`crop`,args:i}),n(!1)},items:$})})]})},De=()=>{let{getSidebar:e,setSidebar:t}=L(),n=e(),r=C(`md`);return(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(R,{variant:`outline`,className:`sidebar-settings`,onClick:()=>t(!0),children:(0,f.jsx)(j,{})}),(0,f.jsx)(`div`,{className:`sidebar`,style:{transform:r&&n?`translateX(-320px)`:`translateX(0%)`},children:(0,f.jsx)(`div`,{className:`sidebar-container`,children:(0,f.jsxs)(`div`,{className:`sidebar-content`,children:[r&&(0,f.jsx)(R,{variant:`ghost`,className:`sidebar-close-btn btn-rect`,onClick:()=>t(!1),children:(0,f.jsx)(E,{})}),(0,f.jsx)(Ce,{}),(0,f.jsx)(B,{className:`sidebar-separator`}),(0,f.jsx)(we,{}),(0,f.jsx)(B,{className:`sidebar-separator`}),(0,f.jsx)(Ee,{})]})})})]})};e.ImageEditor=({image:e,onSave:t,onBack:n})=>{let{loading:r,error:i,width:a,height:o,base64:s,extension:c}=v(e);return r||i||!s||!c?(0,f.jsxs)(`div`,{className:`picedi sys`,children:[r&&(0,f.jsx)(p,{size:48}),i&&(0,f.jsx)(`div`,{className:`text-red`,children:i}),!r&&!i&&(!s||!c)&&(0,f.jsx)(`div`,{className:`text-red`,children:`Failed to load image.`})]}):(0,f.jsx)(g,{base64:s,width:a,height:o,ext:c,children:(0,f.jsxs)(`div`,{className:`picedi main`,children:[(0,f.jsx)(ne,{onSave:t,onBack:n}),(0,f.jsxs)(`div`,{className:`grid`,children:[(0,f.jsx)(Se,{}),(0,f.jsx)(De,{})]})]})})}});
package/package.json CHANGED
@@ -1,10 +1,15 @@
1
1
  {
2
2
  "name": "pixedi",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
+ "description": "A lightweight, embeddable React image editor component.",
4
5
  "type": "module",
5
6
  "main": "./dist/lib/index.umd.js",
6
7
  "module": "./dist/lib/index.js",
7
8
  "types": "./dist/lib/index.d.ts",
9
+ "files": [
10
+ "dist/lib",
11
+ "README.md"
12
+ ],
8
13
  "dependencies": {
9
14
  "react-router": "^8.0.1"
10
15
  },
@@ -21,6 +26,8 @@
21
26
  "@storybook/react": "^8.6.0",
22
27
  "@storybook/react-vite": "^8.6.0",
23
28
  "@storybook/test": "^8.6.0",
29
+ "@testing-library/jest-dom": "^6.9.1",
30
+ "@testing-library/react": "^16.3.2",
24
31
  "@types/node": "^24.13.2",
25
32
  "@types/react": "^19.2.17",
26
33
  "@types/react-dom": "^19.2.3",
@@ -29,15 +36,13 @@
29
36
  "eslint-plugin-react-hooks": "^7.1.1",
30
37
  "eslint-plugin-react-refresh": "^0.5.3",
31
38
  "globals": "^17.7.0",
39
+ "jsdom": "^27.4.0",
32
40
  "prettier": "^3.8.5",
33
41
  "storybook": "^8.6.0",
34
42
  "typescript": "~6.0.2",
35
43
  "typescript-eslint": "^8.62.0",
36
44
  "vite": "^8.1.1",
37
45
  "vite-plugin-css-injected-by-js": "^5.0.1",
38
- "@testing-library/jest-dom": "^6.9.1",
39
- "@testing-library/react": "^16.3.2",
40
- "jsdom": "^27.4.0",
41
46
  "vitest": "^4.0.18"
42
47
  },
43
48
  "scripts": {
@@ -1,54 +0,0 @@
1
- name: CI/CD Pipeline
2
-
3
- on:
4
- push:
5
- branches: [ main ]
6
-
7
- jobs:
8
- build-and-deploy:
9
- runs-on: ubuntu-latest
10
- steps:
11
- - name: Checkout Repository
12
- uses: actions/checkout@v4
13
-
14
- - name: Setup Node.js
15
- uses: actions/setup-node@v4
16
- with:
17
- node-version: '22'
18
- registry-url: 'https://registry.npmjs.org'
19
-
20
- - name: Install pnpm globally
21
- run: npm install -g pnpm@9
22
-
23
- # Install regular project dependencies
24
- - name: Install Dependencies
25
- run: pnpm install --frozen-lockfile
26
-
27
- - name: Run Vitest Tests
28
- run: pnpm test
29
-
30
- - name: Run TypeScript Type Check
31
- run: pnpm type-check
32
-
33
- - name: Run Unified Build Configuration
34
- run: pnpm build
35
-
36
- # --- 1. Deploy to Cloudflare Pages ---
37
- # This uploads the dist folder containing both the SPA app and the widget CDN
38
- # Make sure you have CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID in GitHub Secrets
39
- - name: Deploy SPA & Widget CDN to Cloudflare Pages
40
- uses: cloudflare/pages-action@v1
41
- with:
42
- apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
43
- accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
44
- projectName: 'pixedi' # The project name inside your Cloudflare Pages account
45
- directory: 'dist' # Uploads everything generated in the previous step
46
-
47
- # --- 2. EXISTING WORKING STEP: PUBLISH TO NPM ---
48
- - name: Publish React Component to NPM
49
- run: |
50
- pnpm config set registry https://registry.npmjs.org
51
- pnpm config set //registry.npmjs.org/:_authToken "$NODE_AUTH_TOKEN"
52
- pnpm publish --no-git-checks
53
- env:
54
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/.prettierr DELETED
@@ -1,9 +0,0 @@
1
- {
2
- "semi": true,
3
- "trailingComma": "all",
4
- "singleQuote": true,
5
- "printWidth": 100,
6
- "tabWidth": 2,
7
- "useTabs": false,
8
- "endOfLine": "lf"
9
- }
@@ -1,16 +0,0 @@
1
- import type { StorybookConfig } from "@storybook/react-vite";
2
-
3
- const config: StorybookConfig = {
4
- stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
5
- addons: [
6
- "@storybook/addon-essentials",
7
- "@storybook/addon-actions",
8
- "@storybook/addon-onboarding",
9
- ],
10
- framework: {
11
- name: "@storybook/react-vite",
12
- options: {},
13
- },
14
- };
15
-
16
- export default config;
@@ -1,53 +0,0 @@
1
- import React from "react";
2
- import type { Preview } from "@storybook/react";
3
- import "@/app/styles/index.css";
4
- import "@/shared/components/ImageEditor/index.css";
5
-
6
- const preview: Preview = {
7
- parameters: {
8
- controls: {
9
- matchers: {
10
- color: /(background|color)$/i,
11
- date: /Date$/i,
12
- },
13
- },
14
- },
15
- globalTypes: {
16
- theme: {
17
- description: "Global theme for components",
18
- defaultValue: "light",
19
- toolbar: {
20
- title: "Theme",
21
- icon: "circlehollow",
22
- items: [
23
- { value: "light", icon: "sun", title: "Light Mode" },
24
- { value: "dark", icon: "moon", title: "Dark Mode" },
25
- ],
26
- dynamicTitle: true,
27
- },
28
- },
29
- },
30
- decorators: [
31
- (Story, context) => {
32
- const selectedTheme = context.globals.theme || "light";
33
-
34
- return React.createElement(
35
- "div",
36
- {
37
- "data-theme": selectedTheme,
38
- className: "root",
39
- style: {
40
- padding: 24,
41
- minHeight: "100vh",
42
- backgroundColor:
43
- selectedTheme === "dark" ? "#22252a" : "oklch(1 0 0)",
44
- transition: "background-color 0.2s ease",
45
- },
46
- },
47
- React.createElement(Story),
48
- );
49
- },
50
- ],
51
- };
52
-
53
- export default preview;
@@ -1,6 +0,0 @@
1
- {
2
- "recommendations": [
3
- "esbenp.prettier-vscode",
4
- "dbaeumer.vscode-eslint"
5
- ]
6
- }
package/eslint.config.js DELETED
@@ -1,22 +0,0 @@
1
- import js from '@eslint/js'
2
- import globals from 'globals'
3
- import reactHooks from 'eslint-plugin-react-hooks'
4
- import reactRefresh from 'eslint-plugin-react-refresh'
5
- import tseslint from 'typescript-eslint'
6
- import { defineConfig, globalIgnores } from 'eslint/config'
7
-
8
- export default defineConfig([
9
- globalIgnores(['dist']),
10
- {
11
- files: ['**/*.{ts,tsx}'],
12
- extends: [
13
- js.configs.recommended,
14
- tseslint.configs.recommended,
15
- reactHooks.configs.flat.recommended,
16
- reactRefresh.configs.vite,
17
- ],
18
- languageOptions: {
19
- globals: globals.browser,
20
- },
21
- },
22
- ])
package/index.html DELETED
@@ -1,13 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>picedi</title>
8
- </head>
9
- <body>
10
- <div id="root"></div>
11
- <script type="module" src="/src/main.tsx"></script>
12
- </body>
13
- </html>
@@ -1,2 +0,0 @@
1
- packages:
2
- - '.'
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="46" fill="none" viewBox="0 0 48 46"><path fill="#863bff" d="M25.946 44.938c-.664.845-2.021.375-2.021-.698V33.937a2.26 2.26 0 0 0-2.262-2.262H10.287c-.92 0-1.456-1.04-.92-1.788l7.48-10.471c1.07-1.497 0-3.578-1.842-3.578H1.237c-.92 0-1.456-1.04-.92-1.788L10.013.474c.214-.297.556-.474.92-.474h28.894c.92 0 1.456 1.04.92 1.788l-7.48 10.471c-1.07 1.498 0 3.579 1.842 3.579h11.377c.943 0 1.473 1.088.89 1.83L25.947 44.94z" style="fill:#863bff;fill:color(display-p3 .5252 .23 1);fill-opacity:1"/><mask id="a" width="48" height="46" x="0" y="0" maskUnits="userSpaceOnUse" style="mask-type:alpha"><path fill="#000" d="M25.842 44.938c-.664.844-2.021.375-2.021-.698V33.937a2.26 2.26 0 0 0-2.262-2.262H10.183c-.92 0-1.456-1.04-.92-1.788l7.48-10.471c1.07-1.498 0-3.579-1.842-3.579H1.133c-.92 0-1.456-1.04-.92-1.787L9.91.473c.214-.297.556-.474.92-.474h28.894c.92 0 1.456 1.04.92 1.788l-7.48 10.471c-1.07 1.498 0 3.578 1.842 3.578h11.377c.943 0 1.473 1.088.89 1.832L25.843 44.94z" style="fill:#000;fill-opacity:1"/></mask><g mask="url(#a)"><g filter="url(#b)"><ellipse cx="5.508" cy="14.704" fill="#ede6ff" rx="5.508" ry="14.704" style="fill:#ede6ff;fill:color(display-p3 .9275 .9033 1);fill-opacity:1" transform="matrix(.00324 1 1 -.00324 -4.47 31.516)"/></g><g filter="url(#c)"><ellipse cx="10.399" cy="29.851" fill="#ede6ff" rx="10.399" ry="29.851" style="fill:#ede6ff;fill:color(display-p3 .9275 .9033 1);fill-opacity:1" transform="matrix(.00324 1 1 -.00324 -39.328 7.883)"/></g><g filter="url(#d)"><ellipse cx="5.508" cy="30.487" fill="#7e14ff" rx="5.508" ry="30.487" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.814 -25.913 -14.639)scale(1 -1)"/></g><g filter="url(#e)"><ellipse cx="5.508" cy="30.599" fill="#7e14ff" rx="5.508" ry="30.599" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.814 -32.644 -3.334)scale(1 -1)"/></g><g filter="url(#f)"><ellipse cx="5.508" cy="30.599" fill="#7e14ff" rx="5.508" ry="30.599" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="matrix(.00324 1 1 -.00324 -34.34 30.47)"/></g><g filter="url(#g)"><ellipse cx="14.072" cy="22.078" fill="#ede6ff" rx="14.072" ry="22.078" style="fill:#ede6ff;fill:color(display-p3 .9275 .9033 1);fill-opacity:1" transform="rotate(93.35 24.506 48.493)scale(-1 1)"/></g><g filter="url(#h)"><ellipse cx="3.47" cy="21.501" fill="#7e14ff" rx="3.47" ry="21.501" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.009 28.708 47.59)scale(-1 1)"/></g><g filter="url(#i)"><ellipse cx="3.47" cy="21.501" fill="#7e14ff" rx="3.47" ry="21.501" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.009 28.708 47.59)scale(-1 1)"/></g><g filter="url(#j)"><ellipse cx=".387" cy="8.972" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(39.51 .387 8.972)"/></g><g filter="url(#k)"><ellipse cx="47.523" cy="-6.092" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 47.523 -6.092)"/></g><g filter="url(#l)"><ellipse cx="41.412" cy="6.333" fill="#47bfff" rx="5.971" ry="9.665" style="fill:#47bfff;fill:color(display-p3 .2799 .748 1);fill-opacity:1" transform="rotate(37.892 41.412 6.333)"/></g><g filter="url(#m)"><ellipse cx="-1.879" cy="38.332" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 -1.88 38.332)"/></g><g filter="url(#n)"><ellipse cx="-1.879" cy="38.332" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 -1.88 38.332)"/></g><g filter="url(#o)"><ellipse cx="35.651" cy="29.907" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 35.651 29.907)"/></g><g filter="url(#p)"><ellipse cx="38.418" cy="32.4" fill="#47bfff" rx="5.971" ry="15.297" style="fill:#47bfff;fill:color(display-p3 .2799 .748 1);fill-opacity:1" transform="rotate(37.892 38.418 32.4)"/></g></g><defs><filter id="b" width="60.045" height="41.654" x="-19.77" y="16.149" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="7.659"/></filter><filter id="c" width="90.34" height="51.437" x="-54.613" y="-7.533" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="7.659"/></filter><filter id="d" width="79.355" height="29.4" x="-49.64" y="2.03" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="e" width="79.579" height="29.4" x="-45.045" y="20.029" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="f" width="79.579" height="29.4" x="-43.513" y="21.178" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="g" width="74.749" height="58.852" x="15.756" y="-17.901" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="7.659"/></filter><filter id="h" width="61.377" height="25.362" x="23.548" y="2.284" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="i" width="61.377" height="25.362" x="23.548" y="2.284" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="j" width="56.045" height="63.649" x="-27.636" y="-22.853" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="k" width="54.814" height="64.646" x="20.116" y="-38.415" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="l" width="33.541" height="35.313" x="24.641" y="-11.323" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="m" width="54.814" height="64.646" x="-29.286" y="6.009" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="n" width="54.814" height="64.646" x="-29.286" y="6.009" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="o" width="54.814" height="64.646" x="8.244" y="-2.416" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="p" width="39.409" height="43.623" x="18.713" y="10.588" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter></defs></svg>
package/src/app/App.tsx DELETED
@@ -1,10 +0,0 @@
1
- import { RouterProvider } from "@/app/providers";
2
- import { AppRouter } from "@/app/router/AppRouter";
3
-
4
- export default function App() {
5
- return (
6
- <RouterProvider>
7
- <AppRouter />
8
- </RouterProvider>
9
- );
10
- }
@@ -1,145 +0,0 @@
1
- import type { Image } from "@/shared/types";
2
-
3
- export const imagesData: Image[] = [
4
- {
5
- id: "20",
6
- author: "Aleks Dorohovich",
7
- title: "Creative desktop with laptop and smartphone",
8
- width: 918,
9
- height: 616,
10
- ext: "jpg",
11
- fileName: "sunset_over_lake.jpg",
12
- },
13
- {
14
- id: "35",
15
- author: "Shane Colella",
16
- title: "Mountain Peaks in Spring Surrounded",
17
- width: 2758,
18
- height: 3622,
19
- ext: "jpg",
20
- fileName: "mountain_peaks.jpg",
21
- },
22
- {
23
- id: "42",
24
- author: "Luke Chesser",
25
- width: 3456,
26
- height: 2304,
27
- title: "Morning in a cozy cafe",
28
- ext: "jpg",
29
- fileName: "calm_forest_morning.jpg",
30
- },
31
- {
32
- id: "43",
33
- author: "Oleg Chursin",
34
- title: "Old Town Alleyway Bathed in Warm Golden Sunlight",
35
- width: 1280,
36
- height: 831,
37
- ext: "jpg",
38
- fileName: "old_town_alleyway_sunlight.jpg",
39
- },
40
- {
41
- id: "57",
42
- author: "Nicholas Swanson",
43
- title: "Golden Wheat Fields",
44
- width: 2448,
45
- height: 3264,
46
- ext: "jpg",
47
- fileName: "golden_wheat_fields.jpg",
48
- },
49
- {
50
- id: "75",
51
- author: "Jessy Onyae",
52
- title: "Ocean Waves Crashing Against Rocky Shores at Sunset",
53
- width: 1999,
54
- height: 2998,
55
- ext: "jpg",
56
- fileName: "ocean_waves_rocky.jpg",
57
- },
58
- {
59
- id: "78",
60
- author: "Paul Evens",
61
- title: "Quiet Countryside Road",
62
- width: 1584,
63
- height: 2376,
64
- ext: "jpg",
65
- fileName: "quiet_countryside_road.jpg",
66
- },
67
- {
68
- id: "90",
69
- author: "Rula Sibai",
70
- title: "Blooming Spring Garden",
71
- width: 3000,
72
- height: 1992,
73
- ext: "jpg",
74
- fileName: "blooming_spring_garden.jpg",
75
- },
76
- {
77
- id: "106",
78
- author: "Arvee Marie",
79
- title: "Snowy Mountain Trail",
80
- width: 2592,
81
- height: 1728,
82
- ext: "jpg",
83
- fileName: "snowy_mountain_trail.jpg",
84
- },
85
- {
86
- id: "110",
87
- author: "Kenneth Thewissen",
88
- title: "Starry Night Sky Illuminated by the Milky Way",
89
- width: 5000,
90
- height: 3333,
91
- ext: "jpg",
92
- fileName: "starry_night_milky_way.jpg",
93
- },
94
- {
95
- id: "163",
96
- author: "Lyhn Nguyen",
97
- title: "Peaceful Riverside View",
98
- width: 2000,
99
- height: 1333,
100
- ext: "jpg",
101
- fileName: "peaceful_riverside_view.jpg",
102
- },
103
- {
104
- id: "21",
105
- author: "Alejandro Escamilla",
106
- title: "White shoes on the woody floor",
107
- width: 3008,
108
- height: 2008,
109
- ext: "jpg",
110
- fileName: "white_shoes_wooden_floor.jpg",
111
- },
112
- {
113
- id: "26",
114
- author: "Vadim Sherbakov",
115
- title: "Accessories",
116
- width: 4209,
117
- height: 2769,
118
- ext: "jpg",
119
- fileName: "accessories.jpg",
120
- },
121
- {
122
- id: "88",
123
- author: "Barcelona",
124
- title: "Car traffic",
125
- width: 1280,
126
- height: 1707,
127
- ext: "jpg",
128
- fileName: "car_traffic.jpg",
129
- },
130
- {
131
- id: "116",
132
- author: "Anton Sulsky",
133
- title: "Tuscany Hills",
134
- width: 3504,
135
- height: 2336,
136
- ext: "jpg",
137
- fileName: "tuscany_hills.jpg",
138
- },
139
- ].map((image) => ({
140
- ...image,
141
- thumbnail: `https://picsum.photos/id/${image.id}/400/300`,
142
- original: `https://picsum.photos/id/${image.id}/${image.width}/${image.height}`,
143
- }));
144
-
145
- //https://picsum.photos/id/26/4209/2769
@@ -1,6 +0,0 @@
1
- import type { ReactNode } from "react";
2
- import { BrowserRouter } from "react-router";
3
-
4
- export const RouterProvider = ({ children }: { children: ReactNode }) => {
5
- return <BrowserRouter>{children}</BrowserRouter>;
6
- };
@@ -1 +0,0 @@
1
- export { RouterProvider } from "./RouterProvider";
@@ -1,12 +0,0 @@
1
- import { Route, Routes } from "react-router";
2
- import { ROUTES } from "@/shared/config";
3
- import { GalleryPage, ImageEditPage } from "@/features/gallery";
4
-
5
- export const AppRouter = () => {
6
- return (
7
- <Routes>
8
- <Route path={ROUTES.HOME} element={<GalleryPage />} />
9
- <Route path={ROUTES.IMAGE_EDIT} element={<ImageEditPage />} />
10
- </Routes>
11
- );
12
- };
File without changes
@@ -1,4 +0,0 @@
1
- body {
2
- margin: 0;
3
- padding: 0;
4
- }
@@ -1,33 +0,0 @@
1
- import { imagesData } from "@/app/entries";
2
- import { ImageCard } from "@/shared/components/ImageCard";
3
- import { Preloader } from "@/shared/components/ui";
4
- import { useImagePreload } from "@/shared/hooks";
5
-
6
- export const GalleryPage = () => {
7
- const isLoaded = useImagePreload(imagesData.map((image) => image.original));
8
-
9
- if (!isLoaded) {
10
- return (
11
- <div className="w-full min-h-screen flex items-center justify-center">
12
- <Preloader size={64} />
13
- </div>
14
- );
15
- }
16
-
17
- return (
18
- <div
19
- className={`
20
- max-w-4xl mx-6
21
- my-6
22
- grid content-start gap-6
23
- grid-cols-1
24
- sm:grid-cols-2
25
- md:grid-cols-3 md:mx-auto
26
- `}
27
- >
28
- {imagesData.map((image) => (
29
- <ImageCard key={image.id} image={image} />
30
- ))}
31
- </div>
32
- );
33
- };