zimme-zoom 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Kulcsár Rudolf
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # zimme-zoom
2
+
3
+ A lightweight React photo viewer with zoom, navigation, blurred background, and SVG overlay support.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ yarn add zimme-zoom
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ #TBD
14
+
15
+ ## Development
16
+
17
+ ```bash
18
+ # Install dependencies
19
+ yarn install
20
+
21
+ # Start development mode
22
+ yarn dev
23
+
24
+ # Build the package
25
+ yarn build
26
+
27
+ # Run tests
28
+ yarn test
29
+
30
+ # Lint code
31
+ yarn lint
32
+
33
+ # Format code
34
+ yarn format
35
+ ```
36
+
37
+ ## Requirements
38
+
39
+ - Node.js >= 14.0.0
40
+ - Yarn >= 1.22.0
41
+
42
+ ## License
43
+
44
+ MIT
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { ZZImage } from '../types/image.type';
3
+ type GalleryProps = {
4
+ images: ZZImage[];
5
+ };
6
+ export declare const Gallery: ({ images }: GalleryProps) => React.JSX.Element;
7
+ export {};
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { ZZImage } from '../types/image.type';
3
+ type ImageProps = {
4
+ image: ZZImage;
5
+ onClick?: () => void;
6
+ };
7
+ export declare const Image: ({ image, onClick }: ImageProps) => React.JSX.Element;
8
+ export {};
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ interface NavigationProps {
3
+ title: string;
4
+ onClose?: (e?: React.MouseEvent) => void;
5
+ onZoomIn?: () => void;
6
+ onZoomOut?: () => void;
7
+ onRotate?: (direction: 'left' | 'right') => void;
8
+ onReset?: () => void;
9
+ onNext?: () => void;
10
+ onPrevious?: () => void;
11
+ showControls?: boolean;
12
+ }
13
+ export declare const Navigation: React.FC<NavigationProps>;
14
+ export default Navigation;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ interface NavigationActionButtonProps {
3
+ icon: string;
4
+ onClick?: (e?: React.MouseEvent) => void;
5
+ transform?: string;
6
+ }
7
+ export declare const NavigationActionButton: React.FC<NavigationActionButtonProps>;
8
+ export default NavigationActionButton;
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import { ZZImage } from '../types/image.type';
3
+ type PhotoViewerSettings = {
4
+ allowZoom: boolean;
5
+ allowRotate: boolean;
6
+ allowReset: boolean;
7
+ doubleClickZoom: number;
8
+ clickOutsideToExit: boolean;
9
+ keyboardInteraction: boolean;
10
+ maxZoom: number;
11
+ minZoom: number;
12
+ zoomStep: number;
13
+ };
14
+ export type PhotoViewerProps = {
15
+ selectedImage: ZZImage | null;
16
+ images: ZZImage[];
17
+ onClose: () => void;
18
+ onImageChange?: (image: ZZImage) => void;
19
+ settings?: Partial<PhotoViewerSettings>;
20
+ };
21
+ export declare const PhotoViewer: React.FC<PhotoViewerProps>;
22
+ export {};
@@ -0,0 +1,6 @@
1
+ export declare const IconClose = "url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgaGVpZ2h0PSIxMDAwIiB3aWR0aD0iMTAwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgo8bWV0YWRhdGE+SWNvRm9udCBJY29uczwvbWV0YWRhdGE+Cjx0aXRsZT5jbG9zZS1saW5lPC90aXRsZT4KPGdseXBoIGdseXBoLW5hbWU9ImNsb3NlLWxpbmUiIHVuaWNvZGU9IiYjeGVlZTE7IiBob3Jpei1hZHYteD0iMTAwMCIgLz4KPHBhdGggIGZpbGw9IiNmZmZmZmYiIGQ9Ik03NjIuNSAyMDBsMzcuNSAzNy41LTI2Mi41IDI2Mi41IDI2Mi41IDI2Mi41LTM3LjUgMzcuNS0yNjIuNS0yNjIuNS0yNjIuNSAyNjIuNS0zNy41LTM3LjUgMjYyLjUtMjYyLjUtMjYyLjUtMjYyLjUgMzcuNS0zNy41IDI2Mi41IDI2Mi41eiIvPgo8L3N2Zz4=\")";
2
+ export declare const IconArrow = "url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgaGVpZ2h0PSIxMDAwIiB3aWR0aD0iMTAwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgo8bWV0YWRhdGE+SWNvRm9udCBJY29uczwvbWV0YWRhdGE+Cjx0aXRsZT5hcnJvdy1sZWZ0PC90aXRsZT4KPGdseXBoIGdseXBoLW5hbWU9ImFycm93LWxlZnQiIHVuaWNvZGU9IiYjeGVhNWM7IiBob3Jpei1hZHYteD0iMTAwMCIgLz4KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTc3Ny40IDQyNy42aC0zNDMuMjk5OTk5OTk5OTk5OTVsMTI3LjUtMTI3LjVjOC43OTk5OTk5OTk5OTk5NTUtOC44MDAwMDAwMDAwMDAwMTEgOC43OTk5OTk5OTk5OTk5NTUtMjMuMTAwMDAwMDAwMDAwMDIzIDAtMzEuOTAwMDAwMDAwMDAwMDM0bC01My42MDAwMDAwMDAwMDAwMi01My41OTk5OTk5OTk5OTk5OTRjLTguODAwMDAwMDAwMDAwMDExLTguNzk5OTk5OTk5OTk5OTgzLTIzLjEwMDAwMDAwMDAwMDAyMy04Ljc5OTk5OTk5OTk5OTk4My0zMS44OTk5OTk5OTk5OTk5NzcgMGwtMjY5LjUgMjY5LjRjLTguODAwMDAwMDAwMDAwMDExIDguODAwMDAwMDAwMDAwMDExLTguODAwMDAwMDAwMDAwMDExIDIzLjEwMDAwMDAwMDAwMDAyMy0yLjg0MjE3MDk0MzA0MDQwMWUtMTQgMzEuODk5OTk5OTk5OTk5OTc3bDI2OS41IDI2OS41YzguNzk5OTk5OTk5OTk5OTU1IDguODAwMDAwMDAwMDAwMDY4IDIzLjA5OTk5OTk5OTk5OTk2NiA4LjgwMDAwMDAwMDAwMDA2OCAzMS44OTk5OTk5OTk5OTk5NzcgMGw1My42MDAwMDAwMDAwMDAwMi01My42MDAwMDAwMDAwMDAwMmM4Ljc5OTk5OTk5OTk5OTk1NS04Ljc5OTk5OTk5OTk5OTk1NSA4Ljc5OTk5OTk5OTk5OTk1NS0yMy4wOTk5OTk5OTk5OTk5MSAwLTMxLjg5OTk5OTk5OTk5OTk3N2wtMTM2LjkwMDAwMDAwMDAwMDAzLTEzNi43OTk5OTk5OTk5OTk5NWgzNTIuN2MxMi41IDAgMjIuNjAwMDAwMDAwMDAwMDIzLTEwLjEwMDAwMDAwMDAwMDAyMyAyMi42MDAwMDAwMDAwMDAwMjMtMjIuNjAwMDAwMDAwMDAwMDIzdi05MC4zMDAwMDAwMDAwMDAwMWMwLTEyLjUtMTAuMTAwMDAwMDAwMDAwMDIzLTIyLjU5OTk5OTk5OTk5OTk2Ni0yMi42MDAwMDAwMDAwMDAwMjMtMjIuNTk5OTk5OTk5OTk5OTY2eiIvPgo8L3N2Zz4=\")";
3
+ export declare const IconZoomIn = "url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgaGVpZ2h0PSIxMDAwIiB3aWR0aD0iMTAwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgo8bWV0YWRhdGE+SWNvRm9udCBJY29uczwvbWV0YWRhdGE+Cjx0aXRsZT51aS16b29tLWluPC90aXRsZT4KPGdseXBoIGdseXBoLW5hbWU9InVpLXpvb20taW4iIHVuaWNvZGU9IiYjeGVjOTc7IiBob3Jpei1hZHYteD0iMTAwMCIgLz4KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTk4Mi4yIDc4OC42bC0yMzQuOTAwMDAwMDAwMDAwMS0yMTZjMjcuMTAwMDAwMDAwMDAwMDIzLTUzLjM5OTk5OTk5OTk5OTk4IDQyLjYwMDAwMDAwMDAwMDAyLTExMy42MDAwMDAwMDAwMDAwMiA0Mi42MDAwMDAwMDAwMDAwMi0xNzcuNzAwMDAwMDAwMDAwMDUgMC0yMTguMDk5OTk5OTk5OTk5OTctMTc2Ljc5OTk5OTk5OTk5OTk1LTM5NC45LTM5NS0zOTQuOS0yMTcuOTk5OTk5OTk5OTk5OTcgMC0zOTQuOSAxNzYuOC0zOTQuOSAzOTQuOSAwIDIxOC4yMDAwMDAwMDAwMDAwNSAxNzYuOSAzOTUgMzk0LjkgMzk1IDY0IDAgMTI0LjIwMDAwMDAwMDAwMDA1LTE1LjUgMTc3LjYwMDAwMDAwMDAwMDAyLTQyLjVsMjE2IDIzNWMyMSAyMi44MDAwMDAwMDAwMDAwNjggNTYuMTAwMDAwMDAwMDAwMDIgMjMuNSA3OC4xMDAwMDAwMDAwMDAwMiAxLjYwMDAwMDAwMDAwMDAyMjdsMTE3LjE5OTk5OTk5OTk5OTkzLTExNy4yOTk5OTk5OTk5OTk5NWMyMi0yMiAyMS4yMDAwMDAwMDAwMDAwNDUtNTcuMTAwMDAwMDAwMDAwMDItMS41OTk5OTk5OTk5OTk5MDktNzh6IG0tNTg3LjMwMDAwMDAwMDAwMDEtMTUyLjcwMDAwMDAwMDAwMDA1Yy0xMzIuODk5OTk5OTk5OTk5OTggMC0yNDAuNzk5OTk5OTk5OTk5OTgtMTA3Ljg5OTk5OTk5OTk5OTk4LTI0MC43OTk5OTk5OTk5OTk5OC0yNDFzMTA3LjktMjQwLjg5OTk5OTk5OTk5OTk4IDI0MC43OTk5OTk5OTk5OTk5OC0yNDAuODk5OTk5OTk5OTk5OThjMTMzLjEwMDAwMDAwMDAwMDAyIDAgMjQxIDEwNy44OTk5OTk5OTk5OTk5OCAyNDEgMjQwLjg5OTk5OTk5OTk5OTk4cy0xMDcuODk5OTk5OTk5OTk5OTggMjQxLTI0MSAyNDF6IG0xMjUuMzAwMDAwMDAwMDAwMDctMjgyLjVoLTg5LjQwMDAwMDAwMDAwMDAzdi04OS4zOTk5OTk5OTk5OTk5OGMwLTEyLjQwMDAwMDAwMDAwMDAwNi0xMC4xOTk5OTk5OTk5OTk5ODktMjIuNTk5OTk5OTk5OTk5OTk0LTIyLjYwMDAwMDAwMDAwMDAyMy0yMi41OTk5OTk5OTk5OTk5OTRoLTI5LjM5OTk5OTk5OTk5OTk3N2MtMTIuNSAwLTIyLjY5OTk5OTk5OTk5OTk5IDEwLjE5OTk5OTk5OTk5OTk4OS0yMi42OTk5OTk5OTk5OTk5OSAyMi41OTk5OTk5OTk5OTk5OTR2ODkuMzk5OTk5OTk5OTk5OThoLTg5LjQwMDAwMDAwMDAwMDAzYy0xMi4zOTk5OTk5OTk5OTk5NzcgMC0yMi41OTk5OTk5OTk5OTk5OTQgMTAuMjAwMDAwMDAwMDAwMDQ1LTIyLjU5OTk5OTk5OTk5OTk5NCAyMi42MDAwMDAwMDAwMDAwMjN2MjkuNWMwIDEyLjM5OTk5OTk5OTk5OTk3NyAxMC4yMDAwMDAwMDAwMDAwMTcgMjIuNjAwMDAwMDAwMDAwMDIzIDIyLjU5OTk5OTk5OTk5OTk5NCAyMi42MDAwMDAwMDAwMDAwMjNoODkuNDAwMDAwMDAwMDAwMDN2ODkuMzk5OTk5OTk5OTk5OThjMCAxMi41IDEwLjE5OTk5OTk5OTk5OTk4OSAyMi42MDAwMDAwMDAwMDAwMjMgMjIuNjk5OTk5OTk5OTk5OTkgMjIuNjAwMDAwMDAwMDAwMDIzaDI5LjM5OTk5OTk5OTk5OTk3N2MxMi40MDAwMDAwMDAwMDAwMzQgMCAyMi42MDAwMDAwMDAwMDAwMjMtMTAuMTAwMDAwMDAwMDAwMDIzIDIyLjYwMDAwMDAwMDAwMDAyMy0yMi42MDAwMDAwMDAwMDAwMjN2LTg5LjM5OTk5OTk5OTk5OTk4aDg5LjQwMDAwMDAwMDAwMDAzYzEyLjUgMCAyMi41OTk5OTk5OTk5OTk5MS0xMC4yMDAwMDAwMDAwMDAwNDUgMjIuNTk5OTk5OTk5OTk5OTEtMjIuNjAwMDAwMDAwMDAwMDIzdi0yOS41YzAtMTIuMzk5OTk5OTk5OTk5OTc3LTEwLjA5OTk5OTk5OTk5OTkwOS0yMi42MDAwMDAwMDAwMDAwMjMtMjIuNTk5OTk5OTk5OTk5OTEtMjIuNjAwMDAwMDAwMDAwMDIzeiIvPgo8L3N2Zz4=\")";
4
+ export declare const IconZoomOut = "url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgaGVpZ2h0PSIxMDAwIiB3aWR0aD0iMTAwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgo8bWV0YWRhdGE+SWNvRm9udCBJY29uczwvbWV0YWRhdGE+Cjx0aXRsZT51aS16b29tLW91dDwvdGl0bGU+CjxnbHlwaCBnbHlwaC1uYW1lPSJ1aS16b29tLW91dCIgdW5pY29kZT0iJiN4ZWM5ODsiIGhvcml6LWFkdi14PSIxMDAwIiAvPgo8cGF0aCBmaWxsPSIjZmZmZmZmIiBkPSJNOTgyLjIgNzg4LjZsLTIzNC45MDAwMDAwMDAwMDAxLTIxNmMyNy01My41IDQyLjYwMDAwMDAwMDAwMDAyLTExMy43MDAwMDAwMDAwMDAwNSA0Mi42MDAwMDAwMDAwMDAwMi0xNzcuNzAwMDAwMDAwMDAwMDUgMC0yMTguMDk5OTk5OTk5OTk5OTctMTc2Ljg5OTk5OTk5OTk5OTk4LTM5NC45LTM5NC45LTM5NC45LTIxOC4yIDAtMzk1IDE3Ni44LTM5NSAzOTQuOSAwIDIxOC4xMDAwMDAwMDAwMDAwMiAxNzYuOCAzOTUgMzk1IDM5NSA2My44OTk5OTk5OTk5OTk5OCAwIDEyNC4xMDAwMDAwMDAwMDAwMi0xNS41IDE3Ny42MDAwMDAwMDAwMDAwMi00Mi41bDIxNS44OTk5OTk5OTk5OTk5OCAyMzQuODk5OTk5OTk5OTk5OThjMjEgMjIuOTAwMDAwMDAwMDAwMDkgNTYuMjAwMDAwMDAwMDAwMDQ1IDIzLjYwMDAwMDAwMDAwMDAyMyA3OC4yMDAwMDAwMDAwMDAwNSAxLjYwMDAwMDAwMDAwMDAyMjdsMTE3LjI5OTk5OTk5OTk5OTk1LTExNy4yOTk5OTk5OTk5OTk5NWMyMS43OTk5OTk5OTk5OTk5NTUtMjEuODAwMDAwMDAwMDAwMDY4IDIxLjEwMDAwMDAwMDAwMDAyMy01Ny0xLjc5OTk5OTk5OTk5OTk1NDUtNzh6IG0tNTg3LjItMTUyLjcwMDAwMDAwMDAwMDA1Yy0xMzMgMC0yNDAuOS0xMDcuODk5OTk5OTk5OTk5OTgtMjQwLjktMjQwLjg5OTk5OTk5OTk5OTk4czEwNy45LTI0MSAyNDAuOS0yNDFjMTMzLjEwMDAwMDAwMDAwMDAyIDAgMjQwLjg5OTk5OTk5OTk5OTk4IDEwNy44OTk5OTk5OTk5OTk5OCAyNDAuODk5OTk5OTk5OTk5OTggMjQwLjg5OTk5OTk5OTk5OTk4cy0xMDcuODk5OTk5OTk5OTk5OTggMjQxLTI0MC44OTk5OTk5OTk5OTk5OCAyNDF6IG0xMjUuMjk5OTk5OTk5OTk5OTUtMjgyLjVoLTI1My41OTk5OTk5OTk5OTk5N2MtMTIuMzk5OTk5OTk5OTk5OTc3IDAtMjIuNSAxMC4xMDAwMDAwMDAwMDAwMjMtMjIuNSAyMi42MDAwMDAwMDAwMDAwMjN2MjkuNWMwIDEyLjM5OTk5OTk5OTk5OTk3NyAxMC4xMDAwMDAwMDAwMDAwMjMgMjIuNjAwMDAwMDAwMDAwMDIzIDIyLjUgMjIuNjAwMDAwMDAwMDAwMDIzaDI1My41OTk5OTk5OTk5OTk5N2MxMi40MDAwMDAwMDAwMDAwOTEgMCAyMi41LTEwLjEwMDAwMDAwMDAwMDAyMyAyMi41LTIyLjYwMDAwMDAwMDAwMDAyM3YtMjkuNWMwLTEyLjM5OTk5OTk5OTk5OTk3Ny0xMC4wOTk5OTk5OTk5OTk5MDktMjIuNjAwMDAwMDAwMDAwMDIzLTIyLjUtMjIuNjAwMDAwMDAwMDAwMDIzeiIvPgo8L3N2Zz4=\")";
5
+ export declare const IconRotate = "url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgaGVpZ2h0PSIxMDAwIiB3aWR0aD0iMTAwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgo8bWV0YWRhdGE+SWNvRm9udCBJY29uczwvbWV0YWRhdGE+Cjx0aXRsZT51bmRvPC90aXRsZT4KPGdseXBoIGdseXBoLW5hbWU9InVuZG8iIHVuaWNvZGU9IiYjeGVlMGI7IiBob3Jpei1hZHYteD0iMTAwMCIgLz4KPHBhdGggIGZpbGw9IiNmZmZmZmYiIGQ9Ik04OTguMSA2NTVjLTcuMjAwMDAwMDAwMDAwMDQ1NSAyOS41LTExLjM5OTk5OTk5OTk5OTk3NyA1OS43MDAwMDAwMDAwMDAwNDUtMjEuNzAwMDAwMDAwMDAwMDQ1IDg4LjUtNTMuMzk5OTk5OTk5OTk5OTggMTUwLjcwMDAwMDAwMDAwMDA1LTIwMCAyNTUuODk5OTk5OTk5OTk5OTgtMzU4LjI5OTk5OTk5OTk5OTk1IDI1Ni41LTQxLjcwMDAwMDAwMDAwMDA0NSAwLjEwMDAwMDAwMDAwMDAyMjc0LTc2LjMwMDAwMDAwMDAwMDAxLTI4Ljg5OTk5OTk5OTk5OTk3Ny04MC40MDAwMDAwMDAwMDAwMy02Ny4zOTk5OTk5OTk5OTk5OC00LjM5OTk5OTk5OTk5OTk3Ny00MC44OTk5OTk5OTk5OTk5OCAyMC45MDAwMDAwMDAwMDAwMzQtNzcuODk5OTk5OTk5OTk5OTggNjAuNjAwMDAwMDAwMDAwMDItODUuMTAwMDAwMDAwMDAwMDIgMjIuODAwMDAwMDAwMDAwMDEtNC4xMDAwMDAwMDAwMDAwMjMgNDYuNjk5OTk5OTk5OTk5OTktMi4yOTk5OTk5OTk5OTk5NTQ1IDY5LjQwMDAwMDAwMDAwMDAzLTguNSA5Mi4wOTk5OTk5OTk5OTk5MS0yNS4yMDAwMDAwMDAwMDAwNDUgMTUzLTg0IDE3MC43OTk5OTk5OTk5OTk5NS0xNzcuMjk5OTk5OTk5OTk5OTUgMTguODk5OTk5OTk5OTk5OTc3LTk4LjMwMDAwMDAwMDAwMDA3LTkuNS0xODQuMDAwMDAwMDAwMDAwMDYtOTIuMjAwMDAwMDAwMDAwMDUtMjQ2LjQwMDAwMDAwMDAwMDAzLTIzLjM5OTk5OTk5OTk5OTk3Ny0xNy42MDAwMDAwMDAwMDAwMjMtNTAuODk5OTk5OTk5OTk5OTgtMjguMTk5OTk5OTk5OTk5OTktODAtMjktNTYuMTk5OTk5OTk5OTk5OTMtMS41LTExMi4zOTk5OTk5OTk5OTk5OC0wLjQwMDAwMDAwMDAwMDAzNDEtMTY5LjA5OTk5OTk5OTk5OTk3LTAuNDAwMDAwMDAwMDAwMDM0MSAwLjQwMDAwMDAwMDAwMDAzNDEgNy41IDYuNSAxMC4yMDAwMDAwMDAwMDAwNDUgMTAuNDAwMDAwMDAwMDAwMDM0IDE0LjEwMDAwMDAwMDAwMDAyMyAyNy43OTk5OTk5OTk5OTk5NTUgMjguMTAwMDAwMDAwMDAwMDIzIDU2LjM5OTk5OTk5OTk5OTk4IDU1LjYwMDAwMDAwMDAwMDAyIDgzLjc5OTk5OTk5OTk5OTk1IDg0LjEwMDAwMDAwMDAwMDAyIDMxIDMyLjEwMDAwMDAwMDAwMDAyIDMwLjUgNzkuMjk5OTk5OTk5OTk5OTUtMC4wOTk5OTk5OTk5OTk5NjU5IDEwOS42OTk5OTk5OTk5OTk5My0yOS44MDAwMDAwMDAwMDAwMSAyOS42MDAwMDAwMDAwMDAwMjMtNzcuMTAwMDAwMDAwMDAwMDIgMzAuMjAwMDAwMDAwMDAwMDQ1LTEwOC4zMDAwMDAwMDAwMDAwMS0wLjY5OTk5OTk5OTk5OTkzMTgtOTIuNS05MS43MDAwMDAwMDAwMDAwNS0xODQuMi0xODQuMTAwMDAwMDAwMDAwMDItMjc2LjQtMjc1LjkwMDAwMDAwMDAwMDAzLTcuNTAwMDAwMDAwMDAwMDI4LTcuNS02LjIwMDAwMDAwMDAwMDAxNy0xMS4zOTk5OTk5OTk5OTk5NzcgMC42OTk5OTk5OTk5OTk5NzQ0LTE4LjMwMDAwMDAwMDAwMDAxIDkxLjgtOTEuMjk5OTk5OTk5OTk5OTggMTgzLjM5OTk5OTk5OTk5OTk4LTE4Mi44OTk5OTk5OTk5OTk5OCAyNzQuNy0yNzQuNyAxMS44MDAwMDAwMDAwMDAwMTEtMTEuODk5OTk5OTk5OTk5OTg4IDI3LTE2LjY5OTk5OTk5OTk5OTk5IDQxLTI0LjE5OTk5OTk5OTk5OTk5aDI4LjgwMDAwMDAwMDAwMDAxYzEuMzk5OTk5OTk5OTk5OTc3MyAzLjQgNC41OTk5OTk5OTk5OTk5NjYgMy4xIDcuMzk5OTk5OTk5OTk5OTc3IDQuMSA1OC4xOTk5OTk5OTk5OTk5OSAyMC41IDczLjY5OTk5OTk5OTk5OTk5IDg1LjUgMzAuOTAwMDAwMDAwMDAwMDM0IDEzMC05LjUgOS45MDAwMDAwMDAwMDAwMDYtMTkuNSAxOS41LTI5LjMwMDAwMDAwMDAwMDAxIDI5LjIwMDAwMDAwMDAwMDAxNy0yMS41IDIxLjE5OTk5OTk5OTk5OTk5LTQzIDQyLjUtNjguMzAwMDAwMDAwMDAwMDEgNjcuMzk5OTk5OTk5OTk5OThoMjMuMTAwMDAwMDAwMDAwMDIzYzQ3LjM5OTk5OTk5OTk5OTk4IDAgOTQuNjk5OTk5OTk5OTk5OTktMC4zOTk5OTk5OTk5OTk5NzcyNiAxNDIuMTAwMDAwMDAwMDAwMDIgMC4zMDAwMDAwMDAwMDAwMTEzNyAzNC44OTk5OTk5OTk5OTk5OCAwLjU5OTk5OTk5OTk5OTk5NDMgNjkuMTk5OTk5OTk5OTk5OTMgNi41IDEwMS43OTk5OTk5OTk5OTk5NSAxOS4wOTk5OTk5OTk5OTk5OTQgMTEzLjEwMDAwMDAwMDAwMDAyIDQzLjU5OTk5OTk5OTk5OTk5NCAxODIuMzk5OTk5OTk5OTk5OTggMTI3LjUwMDAwMDAwMDAwMDAzIDIyMC4xMDAwMDAwMDAwMDAwMiAyNDAuMjk5OTk5OTk5OTk5OTggOC44OTk5OTk5OTk5OTk5NzcgMjYuNzAwMDAwMDAwMDAwMDQ1IDExLjM5OTk5OTk5OTk5OTk3NyA1NC44MDAwMDAwMDAwMDAwNyAxOC4zOTk5OTk5OTk5OTk5NzcgODEuODAwMDAwMDAwMDAwMDcgMC4xMDAwMDAwMDAwMDAwMjI3NCAyNy41OTk5OTk5OTk5OTk5MSAwLjEwMDAwMDAwMDAwMDAyMjc0IDU1LjE5OTk5OTk5OTk5OTkzIDAuMTAwMDAwMDAwMDAwMDIyNzQgODIuNzk5OTk5OTk5OTk5OTV6Ii8+Cjwvc3ZnPg==\")";
6
+ export declare const IconReset = "url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgaGVpZ2h0PSIxMDAwIiB3aWR0aD0iMTAwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgo8bWV0YWRhdGE+SWNvRm9udCBJY29uczwvbWV0YWRhdGE+Cjx0aXRsZT5yZWZyZXNoPC90aXRsZT4KPGdseXBoIGdseXBoLW5hbWU9InJlZnJlc2giIHVuaWNvZGU9IiYjeGVmZDE7IiBob3Jpei1hZHYteD0iMTAwMCIgLz4KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTg5OS44IDU1NC42aC00Mi4xOTk5OTk5OTk5OTk5M2MtMTguODk5OTk5OTk5OTk5OTc3IDAtMzYuNSAxNS4xOTk5OTk5OTk5OTk5MzItNDEuNjAwMDAwMDAwMDAwMDIgMzMuMzk5OTk5OTk5OTk5OTgtMzguMjk5OTk5OTk5OTk5OTU1IDEzOC4zOTk5OTk5OTk5OTk5OC0xNjUuMzk5OTk5OTk5OTk5OTggMjQwLTMxNi4yIDI0MC0xMDIuODAwMDAwMDAwMDAwMDEgMC0xOTQuOC00Ny4yOTk5OTk5OTk5OTk5NTUtMjU0LjktMTIxLjYwMDAwMDAwMDAwMDAyLTExLjkwMDAwMDAwMDAwMDAwNi0xNC42OTk5OTk5OTk5OTk5MzItOC44MDAwMDAwMDAwMDAwMTEtMzggNS4wOTk5OTk5OTk5OTk5OTQtNTAuNzk5OTk5OTk5OTk5OTU1bDg0LjgwMDAwMDAwMDAwMDAxLTc3Ljg5OTk5OTk5OTk5OTk4YzEzLjg5OTk5OTk5OTk5OTk3Ny0xMi44MDAwMDAwMDAwMDAwNjggOS44OTk5OTk5OTk5OTk5NzctMjMuMTAwMDAwMDAwMDAwMDIzLTktMjMuMTAwMDAwMDAwMDAwMDIzaC0yMjkuMTAwMDAwMDAwMDAwMDJjLTE4Ljg5OTk5OTk5OTk5OTk5IDAtMzQuMTk5OTk5OTk5OTk5OTkgMTUuMjk5OTk5OTk5OTk5OTU1LTM0LjE5OTk5OTk5OTk5OTk5IDM0LjE5OTk5OTk5OTk5OTkzdjIwNS4xMDAwMDAwMDAwMDAwMmMwIDE4Ljg5OTk5OTk5OTk5OTk3NyAxMS4yOTk5OTk5OTk5OTk5OTcgMjMuODAwMDAwMDAwMDAwMDY4IDI1LjA5OTk5OTk5OTk5OTk5NCAxMWwzMC42MDAwMDAwMDAwMDAwMS0yOC4xOTk5OTk5OTk5OTk5MzJjMTMuODk5OTk5OTk5OTk5OTkxLTEyLjgwMDAwMDAwMDAwMDA2OCAzMy44OTk5OTk5OTk5OTk5OS0xMC42MDAwMDAwMDAwMDAwMjMgNDYuMTAwMDAwMDAwMDAwMDEgMy44OTk5OTk5OTk5OTk5NzczIDgwLjI5OTk5OTk5OTk5OTk4IDk1Ljg5OTk5OTk5OTk5OTk4IDIwMC44OTk5OTk5OTk5OTk5OCAxNTYuODk5OTk5OTk5OTk5OTggMzM1LjUgMTU2Ljg5OTk5OTk5OTk5OTk4IDIxMS40OTk5OTk5OTk5OTk5NCAwIDM4Ny43LTE1MCA0MjguNTk5OTk5OTk5OTk5OTctMzQ5LjIwMDAwMDAwMDAwMDA1IDMuODk5OTk5OTk5OTk5OTc3My0xOC41LTkuNjk5OTk5OTk5OTk5OTMyLTMzLjY5OTk5OTk5OTk5OTkzLTI4LjYwMDAwMDAwMDAwMDAyMy0zMy42OTk5OTk5OTk5OTk5M3ogbTEzLjUtMzU4LjQwMDAwMDAwMDAwMDAzbC0yOS44OTk5OTk5OTk5OTk5NzcgMjkuODAwMDAwMDAwMDAwMDFjLTEzLjM5OTk5OTk5OTk5OTk3NyAxMy4zMDAwMDAwMDAwMDAwMTEtMzIuNzk5OTk5OTk5OTk5OTU1IDExLjUtNDQuNzk5OTk5OTk5OTk5OTU1LTMuMDk5OTk5OTk5OTk5OTk0My04MC4yMDAwMDAwMDAwMDAwNS05Ny45LTIwMi4zMDAwMDAwMDAwMDAwNy0xNjAuNC0zMzguOC0xNjAuNC0yMTEuMTAwMDAwMDAwMDAwMDIgMC0zODcuNiAxNDkuNy00MjguMyAzNDkuMi0zLjc5OTk5OTk5OTk5OTk5NyAxOC41IDkuNzk5OTk5OTk5OTk5OTk3IDMzLjgwMDAwMDAwMDAwMDAxIDI4LjcwMDAwMDAwMDAwMDAwMyAzMy44MDAwMDAwMDAwMDAwMWg0Mi4yYzE4LjkwMDAwMDAwMDAwMDAwNiAwIDM2LjUtMTUuMTAwMDAwMDAwMDAwMDIzIDQxLjUtMzMuMzAwMDAwMDAwMDAwMDEgMzguMjk5OTk5OTk5OTk5OTgtMTM4LjggMTY1LjQtMjQwLjIgMzE1LjktMjQwLjIgMTA2LjYwMDAwMDAwMDAwMDAyIDAgMjAxLjIwMDAwMDAwMDAwMDA1IDUwLjUgMjYxLjIwMDAwMDAwMDAwMDA1IDEyOS4xMDAwMDAwMDAwMDAwMiAxMS41IDE1IDguMzk5OTk5OTk5OTk5OTc3IDM5LTQuODk5OTk5OTk5OTk5OTc3IDUyLjI5OTk5OTk5OTk5OTk1NWwtNjcuODAwMDAwMDAwMDAwMDcgNjcuOTAwMDAwMDAwMDAwMDNjLTEzLjI5OTk5OTk5OTk5OTk1NSAxMy4zOTk5OTk5OTk5OTk5NzctOC44OTk5OTk5OTk5OTk5NzcgMjQuMTk5OTk5OTk5OTk5OTkgMTAgMjQuMTk5OTk5OTk5OTk5OTloMjA1LjEwMDAwMDAwMDAwMDAyYzE4Ljg5OTk5OTk5OTk5OTk3NyAwIDM0LjIwMDAwMDAwMDAwMDA0NS0xNS4zMDAwMDAwMDAwMDAwMTEgMzQuMjAwMDAwMDAwMDAwMDQ1LTM0LjE5OTk5OTk5OTk5OTk5di0yMDUuMTAwMDAwMDAwMDAwMDJjLTAuMTAwMDAwMDAwMDAwMDIyNzQtMTguODk5OTk5OTk5OTk5OTc3LTEwLjg5OTk5OTk5OTk5OTk3Ny0yMy4zOTk5OTk5OTk5OTk5NzctMjQuMzAwMDAwMDAwMDAwMDY4LTEweiIvPgo8L3N2Zz4=\")";
@@ -0,0 +1,5 @@
1
+ export { PhotoViewer } from './components/PhotoViewer';
2
+ export type { PhotoViewerProps } from './components/PhotoViewer';
3
+ export { Gallery } from './components/Gallery';
4
+ export type { ZZImage } from './types/image.type';
5
+ export { Image } from './components/Image';
@@ -0,0 +1,308 @@
1
+ import React, { useState, useRef, useEffect, useCallback } from 'react';
2
+
3
+ /******************************************************************************
4
+ Copyright (c) Microsoft Corporation.
5
+
6
+ Permission to use, copy, modify, and/or distribute this software for any
7
+ purpose with or without fee is hereby granted.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15
+ PERFORMANCE OF THIS SOFTWARE.
16
+ ***************************************************************************** */
17
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
18
+
19
+
20
+ var __assign = function() {
21
+ __assign = Object.assign || function __assign(t) {
22
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
23
+ s = arguments[i];
24
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
25
+ }
26
+ return t;
27
+ };
28
+ return __assign.apply(this, arguments);
29
+ };
30
+
31
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
32
+ var e = new Error(message);
33
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
34
+ };
35
+
36
+ var IconClose = "url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgaGVpZ2h0PSIxMDAwIiB3aWR0aD0iMTAwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgo8bWV0YWRhdGE+SWNvRm9udCBJY29uczwvbWV0YWRhdGE+Cjx0aXRsZT5jbG9zZS1saW5lPC90aXRsZT4KPGdseXBoIGdseXBoLW5hbWU9ImNsb3NlLWxpbmUiIHVuaWNvZGU9IiYjeGVlZTE7IiBob3Jpei1hZHYteD0iMTAwMCIgLz4KPHBhdGggIGZpbGw9IiNmZmZmZmYiIGQ9Ik03NjIuNSAyMDBsMzcuNSAzNy41LTI2Mi41IDI2Mi41IDI2Mi41IDI2Mi41LTM3LjUgMzcuNS0yNjIuNS0yNjIuNS0yNjIuNSAyNjIuNS0zNy41LTM3LjUgMjYyLjUtMjYyLjUtMjYyLjUtMjYyLjUgMzcuNS0zNy41IDI2Mi41IDI2Mi41eiIvPgo8L3N2Zz4=\")";
37
+ var IconArrow = "url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgaGVpZ2h0PSIxMDAwIiB3aWR0aD0iMTAwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgo8bWV0YWRhdGE+SWNvRm9udCBJY29uczwvbWV0YWRhdGE+Cjx0aXRsZT5hcnJvdy1sZWZ0PC90aXRsZT4KPGdseXBoIGdseXBoLW5hbWU9ImFycm93LWxlZnQiIHVuaWNvZGU9IiYjeGVhNWM7IiBob3Jpei1hZHYteD0iMTAwMCIgLz4KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTc3Ny40IDQyNy42aC0zNDMuMjk5OTk5OTk5OTk5OTVsMTI3LjUtMTI3LjVjOC43OTk5OTk5OTk5OTk5NTUtOC44MDAwMDAwMDAwMDAwMTEgOC43OTk5OTk5OTk5OTk5NTUtMjMuMTAwMDAwMDAwMDAwMDIzIDAtMzEuOTAwMDAwMDAwMDAwMDM0bC01My42MDAwMDAwMDAwMDAwMi01My41OTk5OTk5OTk5OTk5OTRjLTguODAwMDAwMDAwMDAwMDExLTguNzk5OTk5OTk5OTk5OTgzLTIzLjEwMDAwMDAwMDAwMDAyMy04Ljc5OTk5OTk5OTk5OTk4My0zMS44OTk5OTk5OTk5OTk5NzcgMGwtMjY5LjUgMjY5LjRjLTguODAwMDAwMDAwMDAwMDExIDguODAwMDAwMDAwMDAwMDExLTguODAwMDAwMDAwMDAwMDExIDIzLjEwMDAwMDAwMDAwMDAyMy0yLjg0MjE3MDk0MzA0MDQwMWUtMTQgMzEuODk5OTk5OTk5OTk5OTc3bDI2OS41IDI2OS41YzguNzk5OTk5OTk5OTk5OTU1IDguODAwMDAwMDAwMDAwMDY4IDIzLjA5OTk5OTk5OTk5OTk2NiA4LjgwMDAwMDAwMDAwMDA2OCAzMS44OTk5OTk5OTk5OTk5NzcgMGw1My42MDAwMDAwMDAwMDAwMi01My42MDAwMDAwMDAwMDAwMmM4Ljc5OTk5OTk5OTk5OTk1NS04Ljc5OTk5OTk5OTk5OTk1NSA4Ljc5OTk5OTk5OTk5OTk1NS0yMy4wOTk5OTk5OTk5OTk5MSAwLTMxLjg5OTk5OTk5OTk5OTk3N2wtMTM2LjkwMDAwMDAwMDAwMDAzLTEzNi43OTk5OTk5OTk5OTk5NWgzNTIuN2MxMi41IDAgMjIuNjAwMDAwMDAwMDAwMDIzLTEwLjEwMDAwMDAwMDAwMDAyMyAyMi42MDAwMDAwMDAwMDAwMjMtMjIuNjAwMDAwMDAwMDAwMDIzdi05MC4zMDAwMDAwMDAwMDAwMWMwLTEyLjUtMTAuMTAwMDAwMDAwMDAwMDIzLTIyLjU5OTk5OTk5OTk5OTk2Ni0yMi42MDAwMDAwMDAwMDAwMjMtMjIuNTk5OTk5OTk5OTk5OTY2eiIvPgo8L3N2Zz4=\")";
38
+ var IconZoomIn = "url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgaGVpZ2h0PSIxMDAwIiB3aWR0aD0iMTAwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgo8bWV0YWRhdGE+SWNvRm9udCBJY29uczwvbWV0YWRhdGE+Cjx0aXRsZT51aS16b29tLWluPC90aXRsZT4KPGdseXBoIGdseXBoLW5hbWU9InVpLXpvb20taW4iIHVuaWNvZGU9IiYjeGVjOTc7IiBob3Jpei1hZHYteD0iMTAwMCIgLz4KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTk4Mi4yIDc4OC42bC0yMzQuOTAwMDAwMDAwMDAwMS0yMTZjMjcuMTAwMDAwMDAwMDAwMDIzLTUzLjM5OTk5OTk5OTk5OTk4IDQyLjYwMDAwMDAwMDAwMDAyLTExMy42MDAwMDAwMDAwMDAwMiA0Mi42MDAwMDAwMDAwMDAwMi0xNzcuNzAwMDAwMDAwMDAwMDUgMC0yMTguMDk5OTk5OTk5OTk5OTctMTc2Ljc5OTk5OTk5OTk5OTk1LTM5NC45LTM5NS0zOTQuOS0yMTcuOTk5OTk5OTk5OTk5OTcgMC0zOTQuOSAxNzYuOC0zOTQuOSAzOTQuOSAwIDIxOC4yMDAwMDAwMDAwMDAwNSAxNzYuOSAzOTUgMzk0LjkgMzk1IDY0IDAgMTI0LjIwMDAwMDAwMDAwMDA1LTE1LjUgMTc3LjYwMDAwMDAwMDAwMDAyLTQyLjVsMjE2IDIzNWMyMSAyMi44MDAwMDAwMDAwMDAwNjggNTYuMTAwMDAwMDAwMDAwMDIgMjMuNSA3OC4xMDAwMDAwMDAwMDAwMiAxLjYwMDAwMDAwMDAwMDAyMjdsMTE3LjE5OTk5OTk5OTk5OTkzLTExNy4yOTk5OTk5OTk5OTk5NWMyMi0yMiAyMS4yMDAwMDAwMDAwMDAwNDUtNTcuMTAwMDAwMDAwMDAwMDItMS41OTk5OTk5OTk5OTk5MDktNzh6IG0tNTg3LjMwMDAwMDAwMDAwMDEtMTUyLjcwMDAwMDAwMDAwMDA1Yy0xMzIuODk5OTk5OTk5OTk5OTggMC0yNDAuNzk5OTk5OTk5OTk5OTgtMTA3Ljg5OTk5OTk5OTk5OTk4LTI0MC43OTk5OTk5OTk5OTk5OC0yNDFzMTA3LjktMjQwLjg5OTk5OTk5OTk5OTk4IDI0MC43OTk5OTk5OTk5OTk5OC0yNDAuODk5OTk5OTk5OTk5OThjMTMzLjEwMDAwMDAwMDAwMDAyIDAgMjQxIDEwNy44OTk5OTk5OTk5OTk5OCAyNDEgMjQwLjg5OTk5OTk5OTk5OTk4cy0xMDcuODk5OTk5OTk5OTk5OTggMjQxLTI0MSAyNDF6IG0xMjUuMzAwMDAwMDAwMDAwMDctMjgyLjVoLTg5LjQwMDAwMDAwMDAwMDAzdi04OS4zOTk5OTk5OTk5OTk5OGMwLTEyLjQwMDAwMDAwMDAwMDAwNi0xMC4xOTk5OTk5OTk5OTk5ODktMjIuNTk5OTk5OTk5OTk5OTk0LTIyLjYwMDAwMDAwMDAwMDAyMy0yMi41OTk5OTk5OTk5OTk5OTRoLTI5LjM5OTk5OTk5OTk5OTk3N2MtMTIuNSAwLTIyLjY5OTk5OTk5OTk5OTk5IDEwLjE5OTk5OTk5OTk5OTk4OS0yMi42OTk5OTk5OTk5OTk5OSAyMi41OTk5OTk5OTk5OTk5OTR2ODkuMzk5OTk5OTk5OTk5OThoLTg5LjQwMDAwMDAwMDAwMDAzYy0xMi4zOTk5OTk5OTk5OTk5NzcgMC0yMi41OTk5OTk5OTk5OTk5OTQgMTAuMjAwMDAwMDAwMDAwMDQ1LTIyLjU5OTk5OTk5OTk5OTk5NCAyMi42MDAwMDAwMDAwMDAwMjN2MjkuNWMwIDEyLjM5OTk5OTk5OTk5OTk3NyAxMC4yMDAwMDAwMDAwMDAwMTcgMjIuNjAwMDAwMDAwMDAwMDIzIDIyLjU5OTk5OTk5OTk5OTk5NCAyMi42MDAwMDAwMDAwMDAwMjNoODkuNDAwMDAwMDAwMDAwMDN2ODkuMzk5OTk5OTk5OTk5OThjMCAxMi41IDEwLjE5OTk5OTk5OTk5OTk4OSAyMi42MDAwMDAwMDAwMDAwMjMgMjIuNjk5OTk5OTk5OTk5OTkgMjIuNjAwMDAwMDAwMDAwMDIzaDI5LjM5OTk5OTk5OTk5OTk3N2MxMi40MDAwMDAwMDAwMDAwMzQgMCAyMi42MDAwMDAwMDAwMDAwMjMtMTAuMTAwMDAwMDAwMDAwMDIzIDIyLjYwMDAwMDAwMDAwMDAyMy0yMi42MDAwMDAwMDAwMDAwMjN2LTg5LjM5OTk5OTk5OTk5OTk4aDg5LjQwMDAwMDAwMDAwMDAzYzEyLjUgMCAyMi41OTk5OTk5OTk5OTk5MS0xMC4yMDAwMDAwMDAwMDAwNDUgMjIuNTk5OTk5OTk5OTk5OTEtMjIuNjAwMDAwMDAwMDAwMDIzdi0yOS41YzAtMTIuMzk5OTk5OTk5OTk5OTc3LTEwLjA5OTk5OTk5OTk5OTkwOS0yMi42MDAwMDAwMDAwMDAwMjMtMjIuNTk5OTk5OTk5OTk5OTEtMjIuNjAwMDAwMDAwMDAwMDIzeiIvPgo8L3N2Zz4=\")";
39
+ var IconZoomOut = "url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgaGVpZ2h0PSIxMDAwIiB3aWR0aD0iMTAwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgo8bWV0YWRhdGE+SWNvRm9udCBJY29uczwvbWV0YWRhdGE+Cjx0aXRsZT51aS16b29tLW91dDwvdGl0bGU+CjxnbHlwaCBnbHlwaC1uYW1lPSJ1aS16b29tLW91dCIgdW5pY29kZT0iJiN4ZWM5ODsiIGhvcml6LWFkdi14PSIxMDAwIiAvPgo8cGF0aCBmaWxsPSIjZmZmZmZmIiBkPSJNOTgyLjIgNzg4LjZsLTIzNC45MDAwMDAwMDAwMDAxLTIxNmMyNy01My41IDQyLjYwMDAwMDAwMDAwMDAyLTExMy43MDAwMDAwMDAwMDAwNSA0Mi42MDAwMDAwMDAwMDAwMi0xNzcuNzAwMDAwMDAwMDAwMDUgMC0yMTguMDk5OTk5OTk5OTk5OTctMTc2Ljg5OTk5OTk5OTk5OTk4LTM5NC45LTM5NC45LTM5NC45LTIxOC4yIDAtMzk1IDE3Ni44LTM5NSAzOTQuOSAwIDIxOC4xMDAwMDAwMDAwMDAwMiAxNzYuOCAzOTUgMzk1IDM5NSA2My44OTk5OTk5OTk5OTk5OCAwIDEyNC4xMDAwMDAwMDAwMDAwMi0xNS41IDE3Ny42MDAwMDAwMDAwMDAwMi00Mi41bDIxNS44OTk5OTk5OTk5OTk5OCAyMzQuODk5OTk5OTk5OTk5OThjMjEgMjIuOTAwMDAwMDAwMDAwMDkgNTYuMjAwMDAwMDAwMDAwMDQ1IDIzLjYwMDAwMDAwMDAwMDAyMyA3OC4yMDAwMDAwMDAwMDAwNSAxLjYwMDAwMDAwMDAwMDAyMjdsMTE3LjI5OTk5OTk5OTk5OTk1LTExNy4yOTk5OTk5OTk5OTk5NWMyMS43OTk5OTk5OTk5OTk5NTUtMjEuODAwMDAwMDAwMDAwMDY4IDIxLjEwMDAwMDAwMDAwMDAyMy01Ny0xLjc5OTk5OTk5OTk5OTk1NDUtNzh6IG0tNTg3LjItMTUyLjcwMDAwMDAwMDAwMDA1Yy0xMzMgMC0yNDAuOS0xMDcuODk5OTk5OTk5OTk5OTgtMjQwLjktMjQwLjg5OTk5OTk5OTk5OTk4czEwNy45LTI0MSAyNDAuOS0yNDFjMTMzLjEwMDAwMDAwMDAwMDAyIDAgMjQwLjg5OTk5OTk5OTk5OTk4IDEwNy44OTk5OTk5OTk5OTk5OCAyNDAuODk5OTk5OTk5OTk5OTggMjQwLjg5OTk5OTk5OTk5OTk4cy0xMDcuODk5OTk5OTk5OTk5OTggMjQxLTI0MC44OTk5OTk5OTk5OTk5OCAyNDF6IG0xMjUuMjk5OTk5OTk5OTk5OTUtMjgyLjVoLTI1My41OTk5OTk5OTk5OTk5N2MtMTIuMzk5OTk5OTk5OTk5OTc3IDAtMjIuNSAxMC4xMDAwMDAwMDAwMDAwMjMtMjIuNSAyMi42MDAwMDAwMDAwMDAwMjN2MjkuNWMwIDEyLjM5OTk5OTk5OTk5OTk3NyAxMC4xMDAwMDAwMDAwMDAwMjMgMjIuNjAwMDAwMDAwMDAwMDIzIDIyLjUgMjIuNjAwMDAwMDAwMDAwMDIzaDI1My41OTk5OTk5OTk5OTk5N2MxMi40MDAwMDAwMDAwMDAwOTEgMCAyMi41LTEwLjEwMDAwMDAwMDAwMDAyMyAyMi41LTIyLjYwMDAwMDAwMDAwMDAyM3YtMjkuNWMwLTEyLjM5OTk5OTk5OTk5OTk3Ny0xMC4wOTk5OTk5OTk5OTk5MDktMjIuNjAwMDAwMDAwMDAwMDIzLTIyLjUtMjIuNjAwMDAwMDAwMDAwMDIzeiIvPgo8L3N2Zz4=\")";
40
+ var IconRotate = "url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgaGVpZ2h0PSIxMDAwIiB3aWR0aD0iMTAwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgo8bWV0YWRhdGE+SWNvRm9udCBJY29uczwvbWV0YWRhdGE+Cjx0aXRsZT51bmRvPC90aXRsZT4KPGdseXBoIGdseXBoLW5hbWU9InVuZG8iIHVuaWNvZGU9IiYjeGVlMGI7IiBob3Jpei1hZHYteD0iMTAwMCIgLz4KPHBhdGggIGZpbGw9IiNmZmZmZmYiIGQ9Ik04OTguMSA2NTVjLTcuMjAwMDAwMDAwMDAwMDQ1NSAyOS41LTExLjM5OTk5OTk5OTk5OTk3NyA1OS43MDAwMDAwMDAwMDAwNDUtMjEuNzAwMDAwMDAwMDAwMDQ1IDg4LjUtNTMuMzk5OTk5OTk5OTk5OTggMTUwLjcwMDAwMDAwMDAwMDA1LTIwMCAyNTUuODk5OTk5OTk5OTk5OTgtMzU4LjI5OTk5OTk5OTk5OTk1IDI1Ni41LTQxLjcwMDAwMDAwMDAwMDA0NSAwLjEwMDAwMDAwMDAwMDAyMjc0LTc2LjMwMDAwMDAwMDAwMDAxLTI4Ljg5OTk5OTk5OTk5OTk3Ny04MC40MDAwMDAwMDAwMDAwMy02Ny4zOTk5OTk5OTk5OTk5OC00LjM5OTk5OTk5OTk5OTk3Ny00MC44OTk5OTk5OTk5OTk5OCAyMC45MDAwMDAwMDAwMDAwMzQtNzcuODk5OTk5OTk5OTk5OTggNjAuNjAwMDAwMDAwMDAwMDItODUuMTAwMDAwMDAwMDAwMDIgMjIuODAwMDAwMDAwMDAwMDEtNC4xMDAwMDAwMDAwMDAwMjMgNDYuNjk5OTk5OTk5OTk5OTktMi4yOTk5OTk5OTk5OTk5NTQ1IDY5LjQwMDAwMDAwMDAwMDAzLTguNSA5Mi4wOTk5OTk5OTk5OTk5MS0yNS4yMDAwMDAwMDAwMDAwNDUgMTUzLTg0IDE3MC43OTk5OTk5OTk5OTk5NS0xNzcuMjk5OTk5OTk5OTk5OTUgMTguODk5OTk5OTk5OTk5OTc3LTk4LjMwMDAwMDAwMDAwMDA3LTkuNS0xODQuMDAwMDAwMDAwMDAwMDYtOTIuMjAwMDAwMDAwMDAwMDUtMjQ2LjQwMDAwMDAwMDAwMDAzLTIzLjM5OTk5OTk5OTk5OTk3Ny0xNy42MDAwMDAwMDAwMDAwMjMtNTAuODk5OTk5OTk5OTk5OTgtMjguMTk5OTk5OTk5OTk5OTktODAtMjktNTYuMTk5OTk5OTk5OTk5OTMtMS41LTExMi4zOTk5OTk5OTk5OTk5OC0wLjQwMDAwMDAwMDAwMDAzNDEtMTY5LjA5OTk5OTk5OTk5OTk3LTAuNDAwMDAwMDAwMDAwMDM0MSAwLjQwMDAwMDAwMDAwMDAzNDEgNy41IDYuNSAxMC4yMDAwMDAwMDAwMDAwNDUgMTAuNDAwMDAwMDAwMDAwMDM0IDE0LjEwMDAwMDAwMDAwMDAyMyAyNy43OTk5OTk5OTk5OTk5NTUgMjguMTAwMDAwMDAwMDAwMDIzIDU2LjM5OTk5OTk5OTk5OTk4IDU1LjYwMDAwMDAwMDAwMDAyIDgzLjc5OTk5OTk5OTk5OTk1IDg0LjEwMDAwMDAwMDAwMDAyIDMxIDMyLjEwMDAwMDAwMDAwMDAyIDMwLjUgNzkuMjk5OTk5OTk5OTk5OTUtMC4wOTk5OTk5OTk5OTk5NjU5IDEwOS42OTk5OTk5OTk5OTk5My0yOS44MDAwMDAwMDAwMDAwMSAyOS42MDAwMDAwMDAwMDAwMjMtNzcuMTAwMDAwMDAwMDAwMDIgMzAuMjAwMDAwMDAwMDAwMDQ1LTEwOC4zMDAwMDAwMDAwMDAwMS0wLjY5OTk5OTk5OTk5OTkzMTgtOTIuNS05MS43MDAwMDAwMDAwMDAwNS0xODQuMi0xODQuMTAwMDAwMDAwMDAwMDItMjc2LjQtMjc1LjkwMDAwMDAwMDAwMDAzLTcuNTAwMDAwMDAwMDAwMDI4LTcuNS02LjIwMDAwMDAwMDAwMDAxNy0xMS4zOTk5OTk5OTk5OTk5NzcgMC42OTk5OTk5OTk5OTk5NzQ0LTE4LjMwMDAwMDAwMDAwMDAxIDkxLjgtOTEuMjk5OTk5OTk5OTk5OTggMTgzLjM5OTk5OTk5OTk5OTk4LTE4Mi44OTk5OTk5OTk5OTk5OCAyNzQuNy0yNzQuNyAxMS44MDAwMDAwMDAwMDAwMTEtMTEuODk5OTk5OTk5OTk5OTg4IDI3LTE2LjY5OTk5OTk5OTk5OTk5IDQxLTI0LjE5OTk5OTk5OTk5OTk5aDI4LjgwMDAwMDAwMDAwMDAxYzEuMzk5OTk5OTk5OTk5OTc3MyAzLjQgNC41OTk5OTk5OTk5OTk5NjYgMy4xIDcuMzk5OTk5OTk5OTk5OTc3IDQuMSA1OC4xOTk5OTk5OTk5OTk5OSAyMC41IDczLjY5OTk5OTk5OTk5OTk5IDg1LjUgMzAuOTAwMDAwMDAwMDAwMDM0IDEzMC05LjUgOS45MDAwMDAwMDAwMDAwMDYtMTkuNSAxOS41LTI5LjMwMDAwMDAwMDAwMDAxIDI5LjIwMDAwMDAwMDAwMDAxNy0yMS41IDIxLjE5OTk5OTk5OTk5OTk5LTQzIDQyLjUtNjguMzAwMDAwMDAwMDAwMDEgNjcuMzk5OTk5OTk5OTk5OThoMjMuMTAwMDAwMDAwMDAwMDIzYzQ3LjM5OTk5OTk5OTk5OTk4IDAgOTQuNjk5OTk5OTk5OTk5OTktMC4zOTk5OTk5OTk5OTk5NzcyNiAxNDIuMTAwMDAwMDAwMDAwMDIgMC4zMDAwMDAwMDAwMDAwMTEzNyAzNC44OTk5OTk5OTk5OTk5OCAwLjU5OTk5OTk5OTk5OTk5NDMgNjkuMTk5OTk5OTk5OTk5OTMgNi41IDEwMS43OTk5OTk5OTk5OTk5NSAxOS4wOTk5OTk5OTk5OTk5OTQgMTEzLjEwMDAwMDAwMDAwMDAyIDQzLjU5OTk5OTk5OTk5OTk5NCAxODIuMzk5OTk5OTk5OTk5OTggMTI3LjUwMDAwMDAwMDAwMDAzIDIyMC4xMDAwMDAwMDAwMDAwMiAyNDAuMjk5OTk5OTk5OTk5OTggOC44OTk5OTk5OTk5OTk5NzcgMjYuNzAwMDAwMDAwMDAwMDQ1IDExLjM5OTk5OTk5OTk5OTk3NyA1NC44MDAwMDAwMDAwMDAwNyAxOC4zOTk5OTk5OTk5OTk5NzcgODEuODAwMDAwMDAwMDAwMDcgMC4xMDAwMDAwMDAwMDAwMjI3NCAyNy41OTk5OTk5OTk5OTk5MSAwLjEwMDAwMDAwMDAwMDAyMjc0IDU1LjE5OTk5OTk5OTk5OTkzIDAuMTAwMDAwMDAwMDAwMDIyNzQgODIuNzk5OTk5OTk5OTk5OTV6Ii8+Cjwvc3ZnPg==\")";
41
+ var IconReset = "url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgaGVpZ2h0PSIxMDAwIiB3aWR0aD0iMTAwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgo8bWV0YWRhdGE+SWNvRm9udCBJY29uczwvbWV0YWRhdGE+Cjx0aXRsZT5yZWZyZXNoPC90aXRsZT4KPGdseXBoIGdseXBoLW5hbWU9InJlZnJlc2giIHVuaWNvZGU9IiYjeGVmZDE7IiBob3Jpei1hZHYteD0iMTAwMCIgLz4KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTg5OS44IDU1NC42aC00Mi4xOTk5OTk5OTk5OTk5M2MtMTguODk5OTk5OTk5OTk5OTc3IDAtMzYuNSAxNS4xOTk5OTk5OTk5OTk5MzItNDEuNjAwMDAwMDAwMDAwMDIgMzMuMzk5OTk5OTk5OTk5OTgtMzguMjk5OTk5OTk5OTk5OTU1IDEzOC4zOTk5OTk5OTk5OTk5OC0xNjUuMzk5OTk5OTk5OTk5OTggMjQwLTMxNi4yIDI0MC0xMDIuODAwMDAwMDAwMDAwMDEgMC0xOTQuOC00Ny4yOTk5OTk5OTk5OTk5NTUtMjU0LjktMTIxLjYwMDAwMDAwMDAwMDAyLTExLjkwMDAwMDAwMDAwMDAwNi0xNC42OTk5OTk5OTk5OTk5MzItOC44MDAwMDAwMDAwMDAwMTEtMzggNS4wOTk5OTk5OTk5OTk5OTQtNTAuNzk5OTk5OTk5OTk5OTU1bDg0LjgwMDAwMDAwMDAwMDAxLTc3Ljg5OTk5OTk5OTk5OTk4YzEzLjg5OTk5OTk5OTk5OTk3Ny0xMi44MDAwMDAwMDAwMDAwNjggOS44OTk5OTk5OTk5OTk5NzctMjMuMTAwMDAwMDAwMDAwMDIzLTktMjMuMTAwMDAwMDAwMDAwMDIzaC0yMjkuMTAwMDAwMDAwMDAwMDJjLTE4Ljg5OTk5OTk5OTk5OTk5IDAtMzQuMTk5OTk5OTk5OTk5OTkgMTUuMjk5OTk5OTk5OTk5OTU1LTM0LjE5OTk5OTk5OTk5OTk5IDM0LjE5OTk5OTk5OTk5OTkzdjIwNS4xMDAwMDAwMDAwMDAwMmMwIDE4Ljg5OTk5OTk5OTk5OTk3NyAxMS4yOTk5OTk5OTk5OTk5OTcgMjMuODAwMDAwMDAwMDAwMDY4IDI1LjA5OTk5OTk5OTk5OTk5NCAxMWwzMC42MDAwMDAwMDAwMDAwMS0yOC4xOTk5OTk5OTk5OTk5MzJjMTMuODk5OTk5OTk5OTk5OTkxLTEyLjgwMDAwMDAwMDAwMDA2OCAzMy44OTk5OTk5OTk5OTk5OS0xMC42MDAwMDAwMDAwMDAwMjMgNDYuMTAwMDAwMDAwMDAwMDEgMy44OTk5OTk5OTk5OTk5NzczIDgwLjI5OTk5OTk5OTk5OTk4IDk1Ljg5OTk5OTk5OTk5OTk4IDIwMC44OTk5OTk5OTk5OTk5OCAxNTYuODk5OTk5OTk5OTk5OTggMzM1LjUgMTU2Ljg5OTk5OTk5OTk5OTk4IDIxMS40OTk5OTk5OTk5OTk5NCAwIDM4Ny43LTE1MCA0MjguNTk5OTk5OTk5OTk5OTctMzQ5LjIwMDAwMDAwMDAwMDA1IDMuODk5OTk5OTk5OTk5OTc3My0xOC41LTkuNjk5OTk5OTk5OTk5OTMyLTMzLjY5OTk5OTk5OTk5OTkzLTI4LjYwMDAwMDAwMDAwMDAyMy0zMy42OTk5OTk5OTk5OTk5M3ogbTEzLjUtMzU4LjQwMDAwMDAwMDAwMDAzbC0yOS44OTk5OTk5OTk5OTk5NzcgMjkuODAwMDAwMDAwMDAwMDFjLTEzLjM5OTk5OTk5OTk5OTk3NyAxMy4zMDAwMDAwMDAwMDAwMTEtMzIuNzk5OTk5OTk5OTk5OTU1IDExLjUtNDQuNzk5OTk5OTk5OTk5OTU1LTMuMDk5OTk5OTk5OTk5OTk0My04MC4yMDAwMDAwMDAwMDAwNS05Ny45LTIwMi4zMDAwMDAwMDAwMDAwNy0xNjAuNC0zMzguOC0xNjAuNC0yMTEuMTAwMDAwMDAwMDAwMDIgMC0zODcuNiAxNDkuNy00MjguMyAzNDkuMi0zLjc5OTk5OTk5OTk5OTk5NyAxOC41IDkuNzk5OTk5OTk5OTk5OTk3IDMzLjgwMDAwMDAwMDAwMDAxIDI4LjcwMDAwMDAwMDAwMDAwMyAzMy44MDAwMDAwMDAwMDAwMWg0Mi4yYzE4LjkwMDAwMDAwMDAwMDAwNiAwIDM2LjUtMTUuMTAwMDAwMDAwMDAwMDIzIDQxLjUtMzMuMzAwMDAwMDAwMDAwMDEgMzguMjk5OTk5OTk5OTk5OTgtMTM4LjggMTY1LjQtMjQwLjIgMzE1LjktMjQwLjIgMTA2LjYwMDAwMDAwMDAwMDAyIDAgMjAxLjIwMDAwMDAwMDAwMDA1IDUwLjUgMjYxLjIwMDAwMDAwMDAwMDA1IDEyOS4xMDAwMDAwMDAwMDAwMiAxMS41IDE1IDguMzk5OTk5OTk5OTk5OTc3IDM5LTQuODk5OTk5OTk5OTk5OTc3IDUyLjI5OTk5OTk5OTk5OTk1NWwtNjcuODAwMDAwMDAwMDAwMDcgNjcuOTAwMDAwMDAwMDAwMDNjLTEzLjI5OTk5OTk5OTk5OTk1NSAxMy4zOTk5OTk5OTk5OTk5NzctOC44OTk5OTk5OTk5OTk5NzcgMjQuMTk5OTk5OTk5OTk5OTkgMTAgMjQuMTk5OTk5OTk5OTk5OTloMjA1LjEwMDAwMDAwMDAwMDAyYzE4Ljg5OTk5OTk5OTk5OTk3NyAwIDM0LjIwMDAwMDAwMDAwMDA0NS0xNS4zMDAwMDAwMDAwMDAwMTEgMzQuMjAwMDAwMDAwMDAwMDQ1LTM0LjE5OTk5OTk5OTk5OTk5di0yMDUuMTAwMDAwMDAwMDAwMDJjLTAuMTAwMDAwMDAwMDAwMDIyNzQtMTguODk5OTk5OTk5OTk5OTc3LTEwLjg5OTk5OTk5OTk5OTk3Ny0yMy4zOTk5OTk5OTk5OTk5NzctMjQuMzAwMDAwMDAwMDAwMDY4LTEweiIvPgo8L3N2Zz4=\")";
42
+
43
+ var NavigationActionButton = function (_a) {
44
+ var icon = _a.icon, onClick = _a.onClick, transform = _a.transform;
45
+ return (React.createElement("div", { className: "nav-action-button", style: {
46
+ width: '12px',
47
+ height: '12px',
48
+ backgroundImage: icon,
49
+ backgroundSize: 'contain',
50
+ backgroundRepeat: 'no-repeat',
51
+ cursor: 'pointer',
52
+ transform: transform,
53
+ transition: 'all 0.2s ease-in-out',
54
+ borderRadius: '4px',
55
+ padding: '4px',
56
+ }, onClick: onClick }));
57
+ };
58
+ var style = document.createElement('style');
59
+ style.textContent = "\n .nav-action-button:hover {\n transform: scale(1.2);\n background-color: rgba(0, 0, 0, 0.05);\n }\n";
60
+ document.head.appendChild(style);
61
+
62
+ var Navigation = function (_a) {
63
+ var title = _a.title, onClose = _a.onClose, onZoomIn = _a.onZoomIn, onZoomOut = _a.onZoomOut, onRotate = _a.onRotate, onReset = _a.onReset, onNext = _a.onNext, onPrevious = _a.onPrevious, _b = _a.showControls, showControls = _b === void 0 ? true : _b;
64
+ return (React.createElement("div", { className: "photo-viewer-navigation", style: {
65
+ position: 'fixed',
66
+ bottom: 30,
67
+ left: '50%',
68
+ transform: 'translateX(-50%)',
69
+ width: '60%',
70
+ height: '3rem',
71
+ backgroundColor: showControls ? 'rgba(0, 0, 0, 0.8)' : 'rgba(0, 0, 0, 0.5)',
72
+ display: 'flex',
73
+ justifyContent: 'space-between',
74
+ alignItems: 'center',
75
+ borderRadius: '1.5rem',
76
+ transition: 'background-color 0.2s ease',
77
+ padding: '0 1.5rem',
78
+ zIndex: 9999,
79
+ } },
80
+ React.createElement("div", { style: { color: 'white', fontSize: '0.9rem' } }, title),
81
+ React.createElement("div", { style: { display: 'flex', gap: '1rem' } },
82
+ onReset && React.createElement(NavigationActionButton, { icon: IconReset, onClick: onReset }),
83
+ onPrevious && React.createElement(NavigationActionButton, { icon: IconArrow, onClick: onPrevious }),
84
+ onNext && React.createElement(NavigationActionButton, { icon: IconArrow, onClick: onNext, transform: "rotateY(180deg)" }),
85
+ onZoomOut && React.createElement(NavigationActionButton, { icon: IconZoomOut, onClick: onZoomOut }),
86
+ onZoomIn && React.createElement(NavigationActionButton, { icon: IconZoomIn, onClick: onZoomIn }),
87
+ onRotate && React.createElement(NavigationActionButton, { icon: IconRotate, onClick: function () { return onRotate('left'); } }),
88
+ onRotate && (React.createElement(NavigationActionButton, { icon: IconRotate, onClick: function () { return onRotate('right'); }, transform: "rotateY(180deg)" })),
89
+ onClose && React.createElement(NavigationActionButton, { icon: IconClose, onClick: onClose }))));
90
+ };
91
+
92
+ var DEFAULT_ZOOM_STEP = 0.3;
93
+ var DEFAULT_LARGE_ZOOM = 4;
94
+ var defaultSettings = {
95
+ allowZoom: true,
96
+ allowRotate: true,
97
+ allowReset: true,
98
+ doubleClickZoom: DEFAULT_LARGE_ZOOM,
99
+ clickOutsideToExit: true,
100
+ keyboardInteraction: true,
101
+ maxZoom: 4,
102
+ minZoom: 0.5,
103
+ zoomStep: DEFAULT_ZOOM_STEP,
104
+ };
105
+ var PhotoViewer = function (_a) {
106
+ var selectedImage = _a.selectedImage, images = _a.images, onClose = _a.onClose, onImageChange = _a.onImageChange, _b = _a.settings, settings = _b === void 0 ? {} : _b;
107
+ var mergedSettings = __assign(__assign({}, defaultSettings), settings);
108
+ var allowZoom = mergedSettings.allowZoom, allowRotate = mergedSettings.allowRotate, allowReset = mergedSettings.allowReset, doubleClickZoom = mergedSettings.doubleClickZoom, clickOutsideToExit = mergedSettings.clickOutsideToExit, keyboardInteraction = mergedSettings.keyboardInteraction, maxZoom = mergedSettings.maxZoom, minZoom = mergedSettings.minZoom, zoomStep = mergedSettings.zoomStep;
109
+ var _c = useState(1), zoom = _c[0], setZoom = _c[1];
110
+ var _d = useState(0), rotationCount = _d[0], setRotationCount = _d[1];
111
+ var _e = useState(false), isHovered = _e[0], setIsHovered = _e[1];
112
+ var containerRef = useRef(null);
113
+ var imageRef = useRef(null);
114
+ var _f = useState(selectedImage), currentSelectedImage = _f[0], setCurrentSelectedImage = _f[1];
115
+ useEffect(function () {
116
+ setCurrentSelectedImage(selectedImage);
117
+ setZoom(1);
118
+ setRotationCount(0);
119
+ }, [selectedImage]);
120
+ var handleNext = useCallback(function () {
121
+ var currentImageIndex = images.findIndex(function (img) { return img.id === (currentSelectedImage === null || currentSelectedImage === void 0 ? void 0 : currentSelectedImage.id); });
122
+ if (images.length > 0) {
123
+ var nextIndex = (currentImageIndex + 1) % images.length;
124
+ var nextImage = images[nextIndex];
125
+ setCurrentSelectedImage(nextImage);
126
+ setZoom(1);
127
+ setRotationCount(0);
128
+ onImageChange === null || onImageChange === void 0 ? void 0 : onImageChange(nextImage);
129
+ }
130
+ }, [images, currentSelectedImage, onImageChange]);
131
+ var handlePrevious = useCallback(function () {
132
+ var currentImageIndex = images.findIndex(function (img) { return img.id === (currentSelectedImage === null || currentSelectedImage === void 0 ? void 0 : currentSelectedImage.id); });
133
+ if (images.length > 0) {
134
+ var prevIndex = (currentImageIndex - 1 + images.length) % images.length;
135
+ var prevImage = images[prevIndex];
136
+ setCurrentSelectedImage(prevImage);
137
+ setZoom(1);
138
+ setRotationCount(0);
139
+ onImageChange === null || onImageChange === void 0 ? void 0 : onImageChange(prevImage);
140
+ }
141
+ }, [images, currentSelectedImage, onImageChange]);
142
+ var handleZoom = useCallback(function (newZoom) {
143
+ var clampedZoom = Math.min(Math.max(newZoom, minZoom), maxZoom);
144
+ setZoom(clampedZoom);
145
+ }, [maxZoom, minZoom]);
146
+ var handleRotate = useCallback(function (direction) {
147
+ if (direction === void 0) { direction = 'right'; }
148
+ if (allowRotate) {
149
+ setRotationCount(function (prev) { return prev + (direction === 'left' ? -1 : 1); });
150
+ }
151
+ }, [allowRotate]);
152
+ var handleReset = useCallback(function () {
153
+ if (allowReset) {
154
+ setZoom(1);
155
+ setRotationCount(0);
156
+ }
157
+ }, [allowReset]);
158
+ var handleDoubleClick = useCallback(function () {
159
+ if (allowZoom) {
160
+ handleZoom(zoom === doubleClickZoom ? 1 : doubleClickZoom);
161
+ }
162
+ }, [allowZoom, doubleClickZoom, handleZoom, zoom]);
163
+ var handleWheel = useCallback(function (e) {
164
+ if (!allowZoom)
165
+ return;
166
+ e.preventDefault();
167
+ var delta = e.deltaY > 0 ? -zoomStep : zoomStep;
168
+ handleZoom(zoom + delta);
169
+ }, [allowZoom, handleZoom, zoom, zoomStep]);
170
+ var handleKeyDown = useCallback(function (e) {
171
+ if (!keyboardInteraction)
172
+ return;
173
+ switch (e.key) {
174
+ case 'Escape':
175
+ onClose();
176
+ break;
177
+ case '+':
178
+ case '=':
179
+ handleZoom(zoom + zoomStep);
180
+ break;
181
+ case '-':
182
+ handleZoom(zoom - zoomStep);
183
+ break;
184
+ case 'r':
185
+ handleRotate();
186
+ break;
187
+ case '0':
188
+ handleReset();
189
+ break;
190
+ case 'ArrowRight':
191
+ handleNext();
192
+ break;
193
+ case 'ArrowLeft':
194
+ handlePrevious();
195
+ break;
196
+ }
197
+ }, [handleZoom, handleRotate, handleReset, handleNext, handlePrevious, keyboardInteraction, onClose, zoom, zoomStep]);
198
+ var handleClickOutside = useCallback(function (e) {
199
+ if (clickOutsideToExit &&
200
+ containerRef.current &&
201
+ !e.target.closest('.photo-viewer img') &&
202
+ !e.target.closest('.photo-viewer-navigation') &&
203
+ !e.target.closest('.nav-action-button')) {
204
+ onClose();
205
+ }
206
+ }, [clickOutsideToExit, onClose]);
207
+ useEffect(function () {
208
+ var container = containerRef.current;
209
+ if (!container)
210
+ return;
211
+ container.addEventListener('wheel', handleWheel, { passive: false });
212
+ window.addEventListener('keydown', handleKeyDown);
213
+ window.addEventListener('mousedown', handleClickOutside);
214
+ return function () {
215
+ container.removeEventListener('wheel', handleWheel);
216
+ window.removeEventListener('keydown', handleKeyDown);
217
+ window.removeEventListener('mousedown', handleClickOutside);
218
+ };
219
+ }, [handleWheel, handleKeyDown, handleClickOutside]);
220
+ if (!selectedImage) {
221
+ return null;
222
+ }
223
+ return (React.createElement("div", { ref: containerRef, className: "photo-viewer", style: {
224
+ position: 'fixed',
225
+ top: 0,
226
+ left: 0,
227
+ right: 0,
228
+ bottom: 0,
229
+ backgroundColor: 'rgba(0, 0, 0, 0.9)',
230
+ display: 'flex',
231
+ flexDirection: 'column',
232
+ alignItems: 'center',
233
+ justifyContent: 'center',
234
+ zIndex: 1000,
235
+ }, onMouseEnter: function () { return setIsHovered(true); }, onMouseLeave: function () { return setIsHovered(false); } },
236
+ React.createElement(Navigation, { title: (currentSelectedImage === null || currentSelectedImage === void 0 ? void 0 : currentSelectedImage.title) || 'Photo Viewer', onClose: onClose, onNext: images.length > 1 ? handleNext : undefined, onPrevious: images.length > 1 ? handlePrevious : undefined, onZoomIn: allowZoom ? function () { return handleZoom(zoom + zoomStep); } : undefined, onZoomOut: allowZoom ? function () { return handleZoom(zoom - zoomStep); } : undefined, onRotate: allowRotate ? handleRotate : undefined, onReset: zoom !== 1 || rotationCount !== 0 ? handleReset : undefined, showControls: isHovered }),
237
+ React.createElement("div", { style: {
238
+ position: 'relative',
239
+ width: '100%',
240
+ height: '100%',
241
+ display: 'flex',
242
+ alignItems: 'center',
243
+ justifyContent: 'center',
244
+ } },
245
+ React.createElement("img", { ref: imageRef, src: currentSelectedImage === null || currentSelectedImage === void 0 ? void 0 : currentSelectedImage.src, alt: (currentSelectedImage === null || currentSelectedImage === void 0 ? void 0 : currentSelectedImage.alt) || '', onDoubleClick: handleDoubleClick, style: {
246
+ maxWidth: '80%',
247
+ maxHeight: '80%',
248
+ minHeight: '80%',
249
+ objectFit: 'contain',
250
+ transform: "scale(".concat(zoom, ") rotateZ(").concat(rotationCount * 90, "deg)"),
251
+ transformOrigin: 'center',
252
+ transition: 'transform 0.2s ease',
253
+ } }))));
254
+ };
255
+
256
+ var Image = function (_a) {
257
+ var image = _a.image, onClick = _a.onClick;
258
+ var _b = useState(true), isLoading = _b[0], setIsLoading = _b[1];
259
+ return (React.createElement("div", { key: image.id, style: {
260
+ aspectRatio: '4/4',
261
+ overflow: 'hidden',
262
+ borderRadius: '8px',
263
+ cursor: 'pointer',
264
+ boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
265
+ transition: 'transform 0.2s ease',
266
+ position: 'relative',
267
+ }, onClick: onClick },
268
+ isLoading && (React.createElement("div", { style: {
269
+ position: 'absolute',
270
+ top: 0,
271
+ left: 0,
272
+ width: '100%',
273
+ height: '100%',
274
+ backgroundColor: '#f0f0f0',
275
+ animation: 'pulse 1.5s infinite',
276
+ } })),
277
+ React.createElement("img", { src: image.src, alt: image.alt, style: {
278
+ width: '100%',
279
+ height: '100%',
280
+ objectFit: 'cover',
281
+ opacity: isLoading ? 0 : 1,
282
+ transition: 'opacity 0.3s ease',
283
+ }, onLoad: function () { return setIsLoading(false); } }),
284
+ React.createElement("style", null, "\n @keyframes pulse {\n 0% { opacity: 0.6; }\n 50% { opacity: 0.8; }\n 100% { opacity: 0.6; }\n }\n ")));
285
+ };
286
+
287
+ var GalleryGrid = function (_a) {
288
+ var children = _a.children;
289
+ return (React.createElement("div", { style: {
290
+ display: 'grid',
291
+ gridTemplateColumns: 'repeat(auto-fill, minmax(300px, 1fr))',
292
+ gap: '1rem',
293
+ maxWidth: '1200px',
294
+ margin: '0 auto',
295
+ } }, children));
296
+ };
297
+ var Gallery = function (_a) {
298
+ var images = _a.images;
299
+ var _b = useState(null), selectedImage = _b[0], setSelectedImage = _b[1];
300
+ return (React.createElement(React.Fragment, null,
301
+ React.createElement(GalleryGrid, null, images.map(function (image) { return (React.createElement(Image, { key: image.id, image: image, onClick: function () {
302
+ setSelectedImage(image);
303
+ } })); })),
304
+ React.createElement(PhotoViewer, { selectedImage: selectedImage, images: images, onClose: function () { return setSelectedImage(null); } })));
305
+ };
306
+
307
+ export { Gallery, Image, PhotoViewer };
308
+ //# sourceMappingURL=index.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/index.js ADDED
@@ -0,0 +1,312 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+
5
+ /******************************************************************************
6
+ Copyright (c) Microsoft Corporation.
7
+
8
+ Permission to use, copy, modify, and/or distribute this software for any
9
+ purpose with or without fee is hereby granted.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17
+ PERFORMANCE OF THIS SOFTWARE.
18
+ ***************************************************************************** */
19
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
20
+
21
+
22
+ var __assign = function() {
23
+ __assign = Object.assign || function __assign(t) {
24
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
25
+ s = arguments[i];
26
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
27
+ }
28
+ return t;
29
+ };
30
+ return __assign.apply(this, arguments);
31
+ };
32
+
33
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
34
+ var e = new Error(message);
35
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
36
+ };
37
+
38
+ var IconClose = "url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgaGVpZ2h0PSIxMDAwIiB3aWR0aD0iMTAwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgo8bWV0YWRhdGE+SWNvRm9udCBJY29uczwvbWV0YWRhdGE+Cjx0aXRsZT5jbG9zZS1saW5lPC90aXRsZT4KPGdseXBoIGdseXBoLW5hbWU9ImNsb3NlLWxpbmUiIHVuaWNvZGU9IiYjeGVlZTE7IiBob3Jpei1hZHYteD0iMTAwMCIgLz4KPHBhdGggIGZpbGw9IiNmZmZmZmYiIGQ9Ik03NjIuNSAyMDBsMzcuNSAzNy41LTI2Mi41IDI2Mi41IDI2Mi41IDI2Mi41LTM3LjUgMzcuNS0yNjIuNS0yNjIuNS0yNjIuNSAyNjIuNS0zNy41LTM3LjUgMjYyLjUtMjYyLjUtMjYyLjUtMjYyLjUgMzcuNS0zNy41IDI2Mi41IDI2Mi41eiIvPgo8L3N2Zz4=\")";
39
+ var IconArrow = "url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgaGVpZ2h0PSIxMDAwIiB3aWR0aD0iMTAwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgo8bWV0YWRhdGE+SWNvRm9udCBJY29uczwvbWV0YWRhdGE+Cjx0aXRsZT5hcnJvdy1sZWZ0PC90aXRsZT4KPGdseXBoIGdseXBoLW5hbWU9ImFycm93LWxlZnQiIHVuaWNvZGU9IiYjeGVhNWM7IiBob3Jpei1hZHYteD0iMTAwMCIgLz4KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTc3Ny40IDQyNy42aC0zNDMuMjk5OTk5OTk5OTk5OTVsMTI3LjUtMTI3LjVjOC43OTk5OTk5OTk5OTk5NTUtOC44MDAwMDAwMDAwMDAwMTEgOC43OTk5OTk5OTk5OTk5NTUtMjMuMTAwMDAwMDAwMDAwMDIzIDAtMzEuOTAwMDAwMDAwMDAwMDM0bC01My42MDAwMDAwMDAwMDAwMi01My41OTk5OTk5OTk5OTk5OTRjLTguODAwMDAwMDAwMDAwMDExLTguNzk5OTk5OTk5OTk5OTgzLTIzLjEwMDAwMDAwMDAwMDAyMy04Ljc5OTk5OTk5OTk5OTk4My0zMS44OTk5OTk5OTk5OTk5NzcgMGwtMjY5LjUgMjY5LjRjLTguODAwMDAwMDAwMDAwMDExIDguODAwMDAwMDAwMDAwMDExLTguODAwMDAwMDAwMDAwMDExIDIzLjEwMDAwMDAwMDAwMDAyMy0yLjg0MjE3MDk0MzA0MDQwMWUtMTQgMzEuODk5OTk5OTk5OTk5OTc3bDI2OS41IDI2OS41YzguNzk5OTk5OTk5OTk5OTU1IDguODAwMDAwMDAwMDAwMDY4IDIzLjA5OTk5OTk5OTk5OTk2NiA4LjgwMDAwMDAwMDAwMDA2OCAzMS44OTk5OTk5OTk5OTk5NzcgMGw1My42MDAwMDAwMDAwMDAwMi01My42MDAwMDAwMDAwMDAwMmM4Ljc5OTk5OTk5OTk5OTk1NS04Ljc5OTk5OTk5OTk5OTk1NSA4Ljc5OTk5OTk5OTk5OTk1NS0yMy4wOTk5OTk5OTk5OTk5MSAwLTMxLjg5OTk5OTk5OTk5OTk3N2wtMTM2LjkwMDAwMDAwMDAwMDAzLTEzNi43OTk5OTk5OTk5OTk5NWgzNTIuN2MxMi41IDAgMjIuNjAwMDAwMDAwMDAwMDIzLTEwLjEwMDAwMDAwMDAwMDAyMyAyMi42MDAwMDAwMDAwMDAwMjMtMjIuNjAwMDAwMDAwMDAwMDIzdi05MC4zMDAwMDAwMDAwMDAwMWMwLTEyLjUtMTAuMTAwMDAwMDAwMDAwMDIzLTIyLjU5OTk5OTk5OTk5OTk2Ni0yMi42MDAwMDAwMDAwMDAwMjMtMjIuNTk5OTk5OTk5OTk5OTY2eiIvPgo8L3N2Zz4=\")";
40
+ var IconZoomIn = "url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgaGVpZ2h0PSIxMDAwIiB3aWR0aD0iMTAwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgo8bWV0YWRhdGE+SWNvRm9udCBJY29uczwvbWV0YWRhdGE+Cjx0aXRsZT51aS16b29tLWluPC90aXRsZT4KPGdseXBoIGdseXBoLW5hbWU9InVpLXpvb20taW4iIHVuaWNvZGU9IiYjeGVjOTc7IiBob3Jpei1hZHYteD0iMTAwMCIgLz4KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTk4Mi4yIDc4OC42bC0yMzQuOTAwMDAwMDAwMDAwMS0yMTZjMjcuMTAwMDAwMDAwMDAwMDIzLTUzLjM5OTk5OTk5OTk5OTk4IDQyLjYwMDAwMDAwMDAwMDAyLTExMy42MDAwMDAwMDAwMDAwMiA0Mi42MDAwMDAwMDAwMDAwMi0xNzcuNzAwMDAwMDAwMDAwMDUgMC0yMTguMDk5OTk5OTk5OTk5OTctMTc2Ljc5OTk5OTk5OTk5OTk1LTM5NC45LTM5NS0zOTQuOS0yMTcuOTk5OTk5OTk5OTk5OTcgMC0zOTQuOSAxNzYuOC0zOTQuOSAzOTQuOSAwIDIxOC4yMDAwMDAwMDAwMDAwNSAxNzYuOSAzOTUgMzk0LjkgMzk1IDY0IDAgMTI0LjIwMDAwMDAwMDAwMDA1LTE1LjUgMTc3LjYwMDAwMDAwMDAwMDAyLTQyLjVsMjE2IDIzNWMyMSAyMi44MDAwMDAwMDAwMDAwNjggNTYuMTAwMDAwMDAwMDAwMDIgMjMuNSA3OC4xMDAwMDAwMDAwMDAwMiAxLjYwMDAwMDAwMDAwMDAyMjdsMTE3LjE5OTk5OTk5OTk5OTkzLTExNy4yOTk5OTk5OTk5OTk5NWMyMi0yMiAyMS4yMDAwMDAwMDAwMDAwNDUtNTcuMTAwMDAwMDAwMDAwMDItMS41OTk5OTk5OTk5OTk5MDktNzh6IG0tNTg3LjMwMDAwMDAwMDAwMDEtMTUyLjcwMDAwMDAwMDAwMDA1Yy0xMzIuODk5OTk5OTk5OTk5OTggMC0yNDAuNzk5OTk5OTk5OTk5OTgtMTA3Ljg5OTk5OTk5OTk5OTk4LTI0MC43OTk5OTk5OTk5OTk5OC0yNDFzMTA3LjktMjQwLjg5OTk5OTk5OTk5OTk4IDI0MC43OTk5OTk5OTk5OTk5OC0yNDAuODk5OTk5OTk5OTk5OThjMTMzLjEwMDAwMDAwMDAwMDAyIDAgMjQxIDEwNy44OTk5OTk5OTk5OTk5OCAyNDEgMjQwLjg5OTk5OTk5OTk5OTk4cy0xMDcuODk5OTk5OTk5OTk5OTggMjQxLTI0MSAyNDF6IG0xMjUuMzAwMDAwMDAwMDAwMDctMjgyLjVoLTg5LjQwMDAwMDAwMDAwMDAzdi04OS4zOTk5OTk5OTk5OTk5OGMwLTEyLjQwMDAwMDAwMDAwMDAwNi0xMC4xOTk5OTk5OTk5OTk5ODktMjIuNTk5OTk5OTk5OTk5OTk0LTIyLjYwMDAwMDAwMDAwMDAyMy0yMi41OTk5OTk5OTk5OTk5OTRoLTI5LjM5OTk5OTk5OTk5OTk3N2MtMTIuNSAwLTIyLjY5OTk5OTk5OTk5OTk5IDEwLjE5OTk5OTk5OTk5OTk4OS0yMi42OTk5OTk5OTk5OTk5OSAyMi41OTk5OTk5OTk5OTk5OTR2ODkuMzk5OTk5OTk5OTk5OThoLTg5LjQwMDAwMDAwMDAwMDAzYy0xMi4zOTk5OTk5OTk5OTk5NzcgMC0yMi41OTk5OTk5OTk5OTk5OTQgMTAuMjAwMDAwMDAwMDAwMDQ1LTIyLjU5OTk5OTk5OTk5OTk5NCAyMi42MDAwMDAwMDAwMDAwMjN2MjkuNWMwIDEyLjM5OTk5OTk5OTk5OTk3NyAxMC4yMDAwMDAwMDAwMDAwMTcgMjIuNjAwMDAwMDAwMDAwMDIzIDIyLjU5OTk5OTk5OTk5OTk5NCAyMi42MDAwMDAwMDAwMDAwMjNoODkuNDAwMDAwMDAwMDAwMDN2ODkuMzk5OTk5OTk5OTk5OThjMCAxMi41IDEwLjE5OTk5OTk5OTk5OTk4OSAyMi42MDAwMDAwMDAwMDAwMjMgMjIuNjk5OTk5OTk5OTk5OTkgMjIuNjAwMDAwMDAwMDAwMDIzaDI5LjM5OTk5OTk5OTk5OTk3N2MxMi40MDAwMDAwMDAwMDAwMzQgMCAyMi42MDAwMDAwMDAwMDAwMjMtMTAuMTAwMDAwMDAwMDAwMDIzIDIyLjYwMDAwMDAwMDAwMDAyMy0yMi42MDAwMDAwMDAwMDAwMjN2LTg5LjM5OTk5OTk5OTk5OTk4aDg5LjQwMDAwMDAwMDAwMDAzYzEyLjUgMCAyMi41OTk5OTk5OTk5OTk5MS0xMC4yMDAwMDAwMDAwMDAwNDUgMjIuNTk5OTk5OTk5OTk5OTEtMjIuNjAwMDAwMDAwMDAwMDIzdi0yOS41YzAtMTIuMzk5OTk5OTk5OTk5OTc3LTEwLjA5OTk5OTk5OTk5OTkwOS0yMi42MDAwMDAwMDAwMDAwMjMtMjIuNTk5OTk5OTk5OTk5OTEtMjIuNjAwMDAwMDAwMDAwMDIzeiIvPgo8L3N2Zz4=\")";
41
+ var IconZoomOut = "url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgaGVpZ2h0PSIxMDAwIiB3aWR0aD0iMTAwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgo8bWV0YWRhdGE+SWNvRm9udCBJY29uczwvbWV0YWRhdGE+Cjx0aXRsZT51aS16b29tLW91dDwvdGl0bGU+CjxnbHlwaCBnbHlwaC1uYW1lPSJ1aS16b29tLW91dCIgdW5pY29kZT0iJiN4ZWM5ODsiIGhvcml6LWFkdi14PSIxMDAwIiAvPgo8cGF0aCBmaWxsPSIjZmZmZmZmIiBkPSJNOTgyLjIgNzg4LjZsLTIzNC45MDAwMDAwMDAwMDAxLTIxNmMyNy01My41IDQyLjYwMDAwMDAwMDAwMDAyLTExMy43MDAwMDAwMDAwMDAwNSA0Mi42MDAwMDAwMDAwMDAwMi0xNzcuNzAwMDAwMDAwMDAwMDUgMC0yMTguMDk5OTk5OTk5OTk5OTctMTc2Ljg5OTk5OTk5OTk5OTk4LTM5NC45LTM5NC45LTM5NC45LTIxOC4yIDAtMzk1IDE3Ni44LTM5NSAzOTQuOSAwIDIxOC4xMDAwMDAwMDAwMDAwMiAxNzYuOCAzOTUgMzk1IDM5NSA2My44OTk5OTk5OTk5OTk5OCAwIDEyNC4xMDAwMDAwMDAwMDAwMi0xNS41IDE3Ny42MDAwMDAwMDAwMDAwMi00Mi41bDIxNS44OTk5OTk5OTk5OTk5OCAyMzQuODk5OTk5OTk5OTk5OThjMjEgMjIuOTAwMDAwMDAwMDAwMDkgNTYuMjAwMDAwMDAwMDAwMDQ1IDIzLjYwMDAwMDAwMDAwMDAyMyA3OC4yMDAwMDAwMDAwMDAwNSAxLjYwMDAwMDAwMDAwMDAyMjdsMTE3LjI5OTk5OTk5OTk5OTk1LTExNy4yOTk5OTk5OTk5OTk5NWMyMS43OTk5OTk5OTk5OTk5NTUtMjEuODAwMDAwMDAwMDAwMDY4IDIxLjEwMDAwMDAwMDAwMDAyMy01Ny0xLjc5OTk5OTk5OTk5OTk1NDUtNzh6IG0tNTg3LjItMTUyLjcwMDAwMDAwMDAwMDA1Yy0xMzMgMC0yNDAuOS0xMDcuODk5OTk5OTk5OTk5OTgtMjQwLjktMjQwLjg5OTk5OTk5OTk5OTk4czEwNy45LTI0MSAyNDAuOS0yNDFjMTMzLjEwMDAwMDAwMDAwMDAyIDAgMjQwLjg5OTk5OTk5OTk5OTk4IDEwNy44OTk5OTk5OTk5OTk5OCAyNDAuODk5OTk5OTk5OTk5OTggMjQwLjg5OTk5OTk5OTk5OTk4cy0xMDcuODk5OTk5OTk5OTk5OTggMjQxLTI0MC44OTk5OTk5OTk5OTk5OCAyNDF6IG0xMjUuMjk5OTk5OTk5OTk5OTUtMjgyLjVoLTI1My41OTk5OTk5OTk5OTk5N2MtMTIuMzk5OTk5OTk5OTk5OTc3IDAtMjIuNSAxMC4xMDAwMDAwMDAwMDAwMjMtMjIuNSAyMi42MDAwMDAwMDAwMDAwMjN2MjkuNWMwIDEyLjM5OTk5OTk5OTk5OTk3NyAxMC4xMDAwMDAwMDAwMDAwMjMgMjIuNjAwMDAwMDAwMDAwMDIzIDIyLjUgMjIuNjAwMDAwMDAwMDAwMDIzaDI1My41OTk5OTk5OTk5OTk5N2MxMi40MDAwMDAwMDAwMDAwOTEgMCAyMi41LTEwLjEwMDAwMDAwMDAwMDAyMyAyMi41LTIyLjYwMDAwMDAwMDAwMDAyM3YtMjkuNWMwLTEyLjM5OTk5OTk5OTk5OTk3Ny0xMC4wOTk5OTk5OTk5OTk5MDktMjIuNjAwMDAwMDAwMDAwMDIzLTIyLjUtMjIuNjAwMDAwMDAwMDAwMDIzeiIvPgo8L3N2Zz4=\")";
42
+ var IconRotate = "url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgaGVpZ2h0PSIxMDAwIiB3aWR0aD0iMTAwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgo8bWV0YWRhdGE+SWNvRm9udCBJY29uczwvbWV0YWRhdGE+Cjx0aXRsZT51bmRvPC90aXRsZT4KPGdseXBoIGdseXBoLW5hbWU9InVuZG8iIHVuaWNvZGU9IiYjeGVlMGI7IiBob3Jpei1hZHYteD0iMTAwMCIgLz4KPHBhdGggIGZpbGw9IiNmZmZmZmYiIGQ9Ik04OTguMSA2NTVjLTcuMjAwMDAwMDAwMDAwMDQ1NSAyOS41LTExLjM5OTk5OTk5OTk5OTk3NyA1OS43MDAwMDAwMDAwMDAwNDUtMjEuNzAwMDAwMDAwMDAwMDQ1IDg4LjUtNTMuMzk5OTk5OTk5OTk5OTggMTUwLjcwMDAwMDAwMDAwMDA1LTIwMCAyNTUuODk5OTk5OTk5OTk5OTgtMzU4LjI5OTk5OTk5OTk5OTk1IDI1Ni41LTQxLjcwMDAwMDAwMDAwMDA0NSAwLjEwMDAwMDAwMDAwMDAyMjc0LTc2LjMwMDAwMDAwMDAwMDAxLTI4Ljg5OTk5OTk5OTk5OTk3Ny04MC40MDAwMDAwMDAwMDAwMy02Ny4zOTk5OTk5OTk5OTk5OC00LjM5OTk5OTk5OTk5OTk3Ny00MC44OTk5OTk5OTk5OTk5OCAyMC45MDAwMDAwMDAwMDAwMzQtNzcuODk5OTk5OTk5OTk5OTggNjAuNjAwMDAwMDAwMDAwMDItODUuMTAwMDAwMDAwMDAwMDIgMjIuODAwMDAwMDAwMDAwMDEtNC4xMDAwMDAwMDAwMDAwMjMgNDYuNjk5OTk5OTk5OTk5OTktMi4yOTk5OTk5OTk5OTk5NTQ1IDY5LjQwMDAwMDAwMDAwMDAzLTguNSA5Mi4wOTk5OTk5OTk5OTk5MS0yNS4yMDAwMDAwMDAwMDAwNDUgMTUzLTg0IDE3MC43OTk5OTk5OTk5OTk5NS0xNzcuMjk5OTk5OTk5OTk5OTUgMTguODk5OTk5OTk5OTk5OTc3LTk4LjMwMDAwMDAwMDAwMDA3LTkuNS0xODQuMDAwMDAwMDAwMDAwMDYtOTIuMjAwMDAwMDAwMDAwMDUtMjQ2LjQwMDAwMDAwMDAwMDAzLTIzLjM5OTk5OTk5OTk5OTk3Ny0xNy42MDAwMDAwMDAwMDAwMjMtNTAuODk5OTk5OTk5OTk5OTgtMjguMTk5OTk5OTk5OTk5OTktODAtMjktNTYuMTk5OTk5OTk5OTk5OTMtMS41LTExMi4zOTk5OTk5OTk5OTk5OC0wLjQwMDAwMDAwMDAwMDAzNDEtMTY5LjA5OTk5OTk5OTk5OTk3LTAuNDAwMDAwMDAwMDAwMDM0MSAwLjQwMDAwMDAwMDAwMDAzNDEgNy41IDYuNSAxMC4yMDAwMDAwMDAwMDAwNDUgMTAuNDAwMDAwMDAwMDAwMDM0IDE0LjEwMDAwMDAwMDAwMDAyMyAyNy43OTk5OTk5OTk5OTk5NTUgMjguMTAwMDAwMDAwMDAwMDIzIDU2LjM5OTk5OTk5OTk5OTk4IDU1LjYwMDAwMDAwMDAwMDAyIDgzLjc5OTk5OTk5OTk5OTk1IDg0LjEwMDAwMDAwMDAwMDAyIDMxIDMyLjEwMDAwMDAwMDAwMDAyIDMwLjUgNzkuMjk5OTk5OTk5OTk5OTUtMC4wOTk5OTk5OTk5OTk5NjU5IDEwOS42OTk5OTk5OTk5OTk5My0yOS44MDAwMDAwMDAwMDAwMSAyOS42MDAwMDAwMDAwMDAwMjMtNzcuMTAwMDAwMDAwMDAwMDIgMzAuMjAwMDAwMDAwMDAwMDQ1LTEwOC4zMDAwMDAwMDAwMDAwMS0wLjY5OTk5OTk5OTk5OTkzMTgtOTIuNS05MS43MDAwMDAwMDAwMDAwNS0xODQuMi0xODQuMTAwMDAwMDAwMDAwMDItMjc2LjQtMjc1LjkwMDAwMDAwMDAwMDAzLTcuNTAwMDAwMDAwMDAwMDI4LTcuNS02LjIwMDAwMDAwMDAwMDAxNy0xMS4zOTk5OTk5OTk5OTk5NzcgMC42OTk5OTk5OTk5OTk5NzQ0LTE4LjMwMDAwMDAwMDAwMDAxIDkxLjgtOTEuMjk5OTk5OTk5OTk5OTggMTgzLjM5OTk5OTk5OTk5OTk4LTE4Mi44OTk5OTk5OTk5OTk5OCAyNzQuNy0yNzQuNyAxMS44MDAwMDAwMDAwMDAwMTEtMTEuODk5OTk5OTk5OTk5OTg4IDI3LTE2LjY5OTk5OTk5OTk5OTk5IDQxLTI0LjE5OTk5OTk5OTk5OTk5aDI4LjgwMDAwMDAwMDAwMDAxYzEuMzk5OTk5OTk5OTk5OTc3MyAzLjQgNC41OTk5OTk5OTk5OTk5NjYgMy4xIDcuMzk5OTk5OTk5OTk5OTc3IDQuMSA1OC4xOTk5OTk5OTk5OTk5OSAyMC41IDczLjY5OTk5OTk5OTk5OTk5IDg1LjUgMzAuOTAwMDAwMDAwMDAwMDM0IDEzMC05LjUgOS45MDAwMDAwMDAwMDAwMDYtMTkuNSAxOS41LTI5LjMwMDAwMDAwMDAwMDAxIDI5LjIwMDAwMDAwMDAwMDAxNy0yMS41IDIxLjE5OTk5OTk5OTk5OTk5LTQzIDQyLjUtNjguMzAwMDAwMDAwMDAwMDEgNjcuMzk5OTk5OTk5OTk5OThoMjMuMTAwMDAwMDAwMDAwMDIzYzQ3LjM5OTk5OTk5OTk5OTk4IDAgOTQuNjk5OTk5OTk5OTk5OTktMC4zOTk5OTk5OTk5OTk5NzcyNiAxNDIuMTAwMDAwMDAwMDAwMDIgMC4zMDAwMDAwMDAwMDAwMTEzNyAzNC44OTk5OTk5OTk5OTk5OCAwLjU5OTk5OTk5OTk5OTk5NDMgNjkuMTk5OTk5OTk5OTk5OTMgNi41IDEwMS43OTk5OTk5OTk5OTk5NSAxOS4wOTk5OTk5OTk5OTk5OTQgMTEzLjEwMDAwMDAwMDAwMDAyIDQzLjU5OTk5OTk5OTk5OTk5NCAxODIuMzk5OTk5OTk5OTk5OTggMTI3LjUwMDAwMDAwMDAwMDAzIDIyMC4xMDAwMDAwMDAwMDAwMiAyNDAuMjk5OTk5OTk5OTk5OTggOC44OTk5OTk5OTk5OTk5NzcgMjYuNzAwMDAwMDAwMDAwMDQ1IDExLjM5OTk5OTk5OTk5OTk3NyA1NC44MDAwMDAwMDAwMDAwNyAxOC4zOTk5OTk5OTk5OTk5NzcgODEuODAwMDAwMDAwMDAwMDcgMC4xMDAwMDAwMDAwMDAwMjI3NCAyNy41OTk5OTk5OTk5OTk5MSAwLjEwMDAwMDAwMDAwMDAyMjc0IDU1LjE5OTk5OTk5OTk5OTkzIDAuMTAwMDAwMDAwMDAwMDIyNzQgODIuNzk5OTk5OTk5OTk5OTV6Ii8+Cjwvc3ZnPg==\")";
43
+ var IconReset = "url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgaGVpZ2h0PSIxMDAwIiB3aWR0aD0iMTAwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgo8bWV0YWRhdGE+SWNvRm9udCBJY29uczwvbWV0YWRhdGE+Cjx0aXRsZT5yZWZyZXNoPC90aXRsZT4KPGdseXBoIGdseXBoLW5hbWU9InJlZnJlc2giIHVuaWNvZGU9IiYjeGVmZDE7IiBob3Jpei1hZHYteD0iMTAwMCIgLz4KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTg5OS44IDU1NC42aC00Mi4xOTk5OTk5OTk5OTk5M2MtMTguODk5OTk5OTk5OTk5OTc3IDAtMzYuNSAxNS4xOTk5OTk5OTk5OTk5MzItNDEuNjAwMDAwMDAwMDAwMDIgMzMuMzk5OTk5OTk5OTk5OTgtMzguMjk5OTk5OTk5OTk5OTU1IDEzOC4zOTk5OTk5OTk5OTk5OC0xNjUuMzk5OTk5OTk5OTk5OTggMjQwLTMxNi4yIDI0MC0xMDIuODAwMDAwMDAwMDAwMDEgMC0xOTQuOC00Ny4yOTk5OTk5OTk5OTk5NTUtMjU0LjktMTIxLjYwMDAwMDAwMDAwMDAyLTExLjkwMDAwMDAwMDAwMDAwNi0xNC42OTk5OTk5OTk5OTk5MzItOC44MDAwMDAwMDAwMDAwMTEtMzggNS4wOTk5OTk5OTk5OTk5OTQtNTAuNzk5OTk5OTk5OTk5OTU1bDg0LjgwMDAwMDAwMDAwMDAxLTc3Ljg5OTk5OTk5OTk5OTk4YzEzLjg5OTk5OTk5OTk5OTk3Ny0xMi44MDAwMDAwMDAwMDAwNjggOS44OTk5OTk5OTk5OTk5NzctMjMuMTAwMDAwMDAwMDAwMDIzLTktMjMuMTAwMDAwMDAwMDAwMDIzaC0yMjkuMTAwMDAwMDAwMDAwMDJjLTE4Ljg5OTk5OTk5OTk5OTk5IDAtMzQuMTk5OTk5OTk5OTk5OTkgMTUuMjk5OTk5OTk5OTk5OTU1LTM0LjE5OTk5OTk5OTk5OTk5IDM0LjE5OTk5OTk5OTk5OTkzdjIwNS4xMDAwMDAwMDAwMDAwMmMwIDE4Ljg5OTk5OTk5OTk5OTk3NyAxMS4yOTk5OTk5OTk5OTk5OTcgMjMuODAwMDAwMDAwMDAwMDY4IDI1LjA5OTk5OTk5OTk5OTk5NCAxMWwzMC42MDAwMDAwMDAwMDAwMS0yOC4xOTk5OTk5OTk5OTk5MzJjMTMuODk5OTk5OTk5OTk5OTkxLTEyLjgwMDAwMDAwMDAwMDA2OCAzMy44OTk5OTk5OTk5OTk5OS0xMC42MDAwMDAwMDAwMDAwMjMgNDYuMTAwMDAwMDAwMDAwMDEgMy44OTk5OTk5OTk5OTk5NzczIDgwLjI5OTk5OTk5OTk5OTk4IDk1Ljg5OTk5OTk5OTk5OTk4IDIwMC44OTk5OTk5OTk5OTk5OCAxNTYuODk5OTk5OTk5OTk5OTggMzM1LjUgMTU2Ljg5OTk5OTk5OTk5OTk4IDIxMS40OTk5OTk5OTk5OTk5NCAwIDM4Ny43LTE1MCA0MjguNTk5OTk5OTk5OTk5OTctMzQ5LjIwMDAwMDAwMDAwMDA1IDMuODk5OTk5OTk5OTk5OTc3My0xOC41LTkuNjk5OTk5OTk5OTk5OTMyLTMzLjY5OTk5OTk5OTk5OTkzLTI4LjYwMDAwMDAwMDAwMDAyMy0zMy42OTk5OTk5OTk5OTk5M3ogbTEzLjUtMzU4LjQwMDAwMDAwMDAwMDAzbC0yOS44OTk5OTk5OTk5OTk5NzcgMjkuODAwMDAwMDAwMDAwMDFjLTEzLjM5OTk5OTk5OTk5OTk3NyAxMy4zMDAwMDAwMDAwMDAwMTEtMzIuNzk5OTk5OTk5OTk5OTU1IDExLjUtNDQuNzk5OTk5OTk5OTk5OTU1LTMuMDk5OTk5OTk5OTk5OTk0My04MC4yMDAwMDAwMDAwMDAwNS05Ny45LTIwMi4zMDAwMDAwMDAwMDAwNy0xNjAuNC0zMzguOC0xNjAuNC0yMTEuMTAwMDAwMDAwMDAwMDIgMC0zODcuNiAxNDkuNy00MjguMyAzNDkuMi0zLjc5OTk5OTk5OTk5OTk5NyAxOC41IDkuNzk5OTk5OTk5OTk5OTk3IDMzLjgwMDAwMDAwMDAwMDAxIDI4LjcwMDAwMDAwMDAwMDAwMyAzMy44MDAwMDAwMDAwMDAwMWg0Mi4yYzE4LjkwMDAwMDAwMDAwMDAwNiAwIDM2LjUtMTUuMTAwMDAwMDAwMDAwMDIzIDQxLjUtMzMuMzAwMDAwMDAwMDAwMDEgMzguMjk5OTk5OTk5OTk5OTgtMTM4LjggMTY1LjQtMjQwLjIgMzE1LjktMjQwLjIgMTA2LjYwMDAwMDAwMDAwMDAyIDAgMjAxLjIwMDAwMDAwMDAwMDA1IDUwLjUgMjYxLjIwMDAwMDAwMDAwMDA1IDEyOS4xMDAwMDAwMDAwMDAwMiAxMS41IDE1IDguMzk5OTk5OTk5OTk5OTc3IDM5LTQuODk5OTk5OTk5OTk5OTc3IDUyLjI5OTk5OTk5OTk5OTk1NWwtNjcuODAwMDAwMDAwMDAwMDcgNjcuOTAwMDAwMDAwMDAwMDNjLTEzLjI5OTk5OTk5OTk5OTk1NSAxMy4zOTk5OTk5OTk5OTk5NzctOC44OTk5OTk5OTk5OTk5NzcgMjQuMTk5OTk5OTk5OTk5OTkgMTAgMjQuMTk5OTk5OTk5OTk5OTloMjA1LjEwMDAwMDAwMDAwMDAyYzE4Ljg5OTk5OTk5OTk5OTk3NyAwIDM0LjIwMDAwMDAwMDAwMDA0NS0xNS4zMDAwMDAwMDAwMDAwMTEgMzQuMjAwMDAwMDAwMDAwMDQ1LTM0LjE5OTk5OTk5OTk5OTk5di0yMDUuMTAwMDAwMDAwMDAwMDJjLTAuMTAwMDAwMDAwMDAwMDIyNzQtMTguODk5OTk5OTk5OTk5OTc3LTEwLjg5OTk5OTk5OTk5OTk3Ny0yMy4zOTk5OTk5OTk5OTk5NzctMjQuMzAwMDAwMDAwMDAwMDY4LTEweiIvPgo8L3N2Zz4=\")";
44
+
45
+ var NavigationActionButton = function (_a) {
46
+ var icon = _a.icon, onClick = _a.onClick, transform = _a.transform;
47
+ return (React.createElement("div", { className: "nav-action-button", style: {
48
+ width: '12px',
49
+ height: '12px',
50
+ backgroundImage: icon,
51
+ backgroundSize: 'contain',
52
+ backgroundRepeat: 'no-repeat',
53
+ cursor: 'pointer',
54
+ transform: transform,
55
+ transition: 'all 0.2s ease-in-out',
56
+ borderRadius: '4px',
57
+ padding: '4px',
58
+ }, onClick: onClick }));
59
+ };
60
+ var style = document.createElement('style');
61
+ style.textContent = "\n .nav-action-button:hover {\n transform: scale(1.2);\n background-color: rgba(0, 0, 0, 0.05);\n }\n";
62
+ document.head.appendChild(style);
63
+
64
+ var Navigation = function (_a) {
65
+ var title = _a.title, onClose = _a.onClose, onZoomIn = _a.onZoomIn, onZoomOut = _a.onZoomOut, onRotate = _a.onRotate, onReset = _a.onReset, onNext = _a.onNext, onPrevious = _a.onPrevious, _b = _a.showControls, showControls = _b === void 0 ? true : _b;
66
+ return (React.createElement("div", { className: "photo-viewer-navigation", style: {
67
+ position: 'fixed',
68
+ bottom: 30,
69
+ left: '50%',
70
+ transform: 'translateX(-50%)',
71
+ width: '60%',
72
+ height: '3rem',
73
+ backgroundColor: showControls ? 'rgba(0, 0, 0, 0.8)' : 'rgba(0, 0, 0, 0.5)',
74
+ display: 'flex',
75
+ justifyContent: 'space-between',
76
+ alignItems: 'center',
77
+ borderRadius: '1.5rem',
78
+ transition: 'background-color 0.2s ease',
79
+ padding: '0 1.5rem',
80
+ zIndex: 9999,
81
+ } },
82
+ React.createElement("div", { style: { color: 'white', fontSize: '0.9rem' } }, title),
83
+ React.createElement("div", { style: { display: 'flex', gap: '1rem' } },
84
+ onReset && React.createElement(NavigationActionButton, { icon: IconReset, onClick: onReset }),
85
+ onPrevious && React.createElement(NavigationActionButton, { icon: IconArrow, onClick: onPrevious }),
86
+ onNext && React.createElement(NavigationActionButton, { icon: IconArrow, onClick: onNext, transform: "rotateY(180deg)" }),
87
+ onZoomOut && React.createElement(NavigationActionButton, { icon: IconZoomOut, onClick: onZoomOut }),
88
+ onZoomIn && React.createElement(NavigationActionButton, { icon: IconZoomIn, onClick: onZoomIn }),
89
+ onRotate && React.createElement(NavigationActionButton, { icon: IconRotate, onClick: function () { return onRotate('left'); } }),
90
+ onRotate && (React.createElement(NavigationActionButton, { icon: IconRotate, onClick: function () { return onRotate('right'); }, transform: "rotateY(180deg)" })),
91
+ onClose && React.createElement(NavigationActionButton, { icon: IconClose, onClick: onClose }))));
92
+ };
93
+
94
+ var DEFAULT_ZOOM_STEP = 0.3;
95
+ var DEFAULT_LARGE_ZOOM = 4;
96
+ var defaultSettings = {
97
+ allowZoom: true,
98
+ allowRotate: true,
99
+ allowReset: true,
100
+ doubleClickZoom: DEFAULT_LARGE_ZOOM,
101
+ clickOutsideToExit: true,
102
+ keyboardInteraction: true,
103
+ maxZoom: 4,
104
+ minZoom: 0.5,
105
+ zoomStep: DEFAULT_ZOOM_STEP,
106
+ };
107
+ var PhotoViewer = function (_a) {
108
+ var selectedImage = _a.selectedImage, images = _a.images, onClose = _a.onClose, onImageChange = _a.onImageChange, _b = _a.settings, settings = _b === void 0 ? {} : _b;
109
+ var mergedSettings = __assign(__assign({}, defaultSettings), settings);
110
+ var allowZoom = mergedSettings.allowZoom, allowRotate = mergedSettings.allowRotate, allowReset = mergedSettings.allowReset, doubleClickZoom = mergedSettings.doubleClickZoom, clickOutsideToExit = mergedSettings.clickOutsideToExit, keyboardInteraction = mergedSettings.keyboardInteraction, maxZoom = mergedSettings.maxZoom, minZoom = mergedSettings.minZoom, zoomStep = mergedSettings.zoomStep;
111
+ var _c = React.useState(1), zoom = _c[0], setZoom = _c[1];
112
+ var _d = React.useState(0), rotationCount = _d[0], setRotationCount = _d[1];
113
+ var _e = React.useState(false), isHovered = _e[0], setIsHovered = _e[1];
114
+ var containerRef = React.useRef(null);
115
+ var imageRef = React.useRef(null);
116
+ var _f = React.useState(selectedImage), currentSelectedImage = _f[0], setCurrentSelectedImage = _f[1];
117
+ React.useEffect(function () {
118
+ setCurrentSelectedImage(selectedImage);
119
+ setZoom(1);
120
+ setRotationCount(0);
121
+ }, [selectedImage]);
122
+ var handleNext = React.useCallback(function () {
123
+ var currentImageIndex = images.findIndex(function (img) { return img.id === (currentSelectedImage === null || currentSelectedImage === void 0 ? void 0 : currentSelectedImage.id); });
124
+ if (images.length > 0) {
125
+ var nextIndex = (currentImageIndex + 1) % images.length;
126
+ var nextImage = images[nextIndex];
127
+ setCurrentSelectedImage(nextImage);
128
+ setZoom(1);
129
+ setRotationCount(0);
130
+ onImageChange === null || onImageChange === void 0 ? void 0 : onImageChange(nextImage);
131
+ }
132
+ }, [images, currentSelectedImage, onImageChange]);
133
+ var handlePrevious = React.useCallback(function () {
134
+ var currentImageIndex = images.findIndex(function (img) { return img.id === (currentSelectedImage === null || currentSelectedImage === void 0 ? void 0 : currentSelectedImage.id); });
135
+ if (images.length > 0) {
136
+ var prevIndex = (currentImageIndex - 1 + images.length) % images.length;
137
+ var prevImage = images[prevIndex];
138
+ setCurrentSelectedImage(prevImage);
139
+ setZoom(1);
140
+ setRotationCount(0);
141
+ onImageChange === null || onImageChange === void 0 ? void 0 : onImageChange(prevImage);
142
+ }
143
+ }, [images, currentSelectedImage, onImageChange]);
144
+ var handleZoom = React.useCallback(function (newZoom) {
145
+ var clampedZoom = Math.min(Math.max(newZoom, minZoom), maxZoom);
146
+ setZoom(clampedZoom);
147
+ }, [maxZoom, minZoom]);
148
+ var handleRotate = React.useCallback(function (direction) {
149
+ if (direction === void 0) { direction = 'right'; }
150
+ if (allowRotate) {
151
+ setRotationCount(function (prev) { return prev + (direction === 'left' ? -1 : 1); });
152
+ }
153
+ }, [allowRotate]);
154
+ var handleReset = React.useCallback(function () {
155
+ if (allowReset) {
156
+ setZoom(1);
157
+ setRotationCount(0);
158
+ }
159
+ }, [allowReset]);
160
+ var handleDoubleClick = React.useCallback(function () {
161
+ if (allowZoom) {
162
+ handleZoom(zoom === doubleClickZoom ? 1 : doubleClickZoom);
163
+ }
164
+ }, [allowZoom, doubleClickZoom, handleZoom, zoom]);
165
+ var handleWheel = React.useCallback(function (e) {
166
+ if (!allowZoom)
167
+ return;
168
+ e.preventDefault();
169
+ var delta = e.deltaY > 0 ? -zoomStep : zoomStep;
170
+ handleZoom(zoom + delta);
171
+ }, [allowZoom, handleZoom, zoom, zoomStep]);
172
+ var handleKeyDown = React.useCallback(function (e) {
173
+ if (!keyboardInteraction)
174
+ return;
175
+ switch (e.key) {
176
+ case 'Escape':
177
+ onClose();
178
+ break;
179
+ case '+':
180
+ case '=':
181
+ handleZoom(zoom + zoomStep);
182
+ break;
183
+ case '-':
184
+ handleZoom(zoom - zoomStep);
185
+ break;
186
+ case 'r':
187
+ handleRotate();
188
+ break;
189
+ case '0':
190
+ handleReset();
191
+ break;
192
+ case 'ArrowRight':
193
+ handleNext();
194
+ break;
195
+ case 'ArrowLeft':
196
+ handlePrevious();
197
+ break;
198
+ }
199
+ }, [handleZoom, handleRotate, handleReset, handleNext, handlePrevious, keyboardInteraction, onClose, zoom, zoomStep]);
200
+ var handleClickOutside = React.useCallback(function (e) {
201
+ if (clickOutsideToExit &&
202
+ containerRef.current &&
203
+ !e.target.closest('.photo-viewer img') &&
204
+ !e.target.closest('.photo-viewer-navigation') &&
205
+ !e.target.closest('.nav-action-button')) {
206
+ onClose();
207
+ }
208
+ }, [clickOutsideToExit, onClose]);
209
+ React.useEffect(function () {
210
+ var container = containerRef.current;
211
+ if (!container)
212
+ return;
213
+ container.addEventListener('wheel', handleWheel, { passive: false });
214
+ window.addEventListener('keydown', handleKeyDown);
215
+ window.addEventListener('mousedown', handleClickOutside);
216
+ return function () {
217
+ container.removeEventListener('wheel', handleWheel);
218
+ window.removeEventListener('keydown', handleKeyDown);
219
+ window.removeEventListener('mousedown', handleClickOutside);
220
+ };
221
+ }, [handleWheel, handleKeyDown, handleClickOutside]);
222
+ if (!selectedImage) {
223
+ return null;
224
+ }
225
+ return (React.createElement("div", { ref: containerRef, className: "photo-viewer", style: {
226
+ position: 'fixed',
227
+ top: 0,
228
+ left: 0,
229
+ right: 0,
230
+ bottom: 0,
231
+ backgroundColor: 'rgba(0, 0, 0, 0.9)',
232
+ display: 'flex',
233
+ flexDirection: 'column',
234
+ alignItems: 'center',
235
+ justifyContent: 'center',
236
+ zIndex: 1000,
237
+ }, onMouseEnter: function () { return setIsHovered(true); }, onMouseLeave: function () { return setIsHovered(false); } },
238
+ React.createElement(Navigation, { title: (currentSelectedImage === null || currentSelectedImage === void 0 ? void 0 : currentSelectedImage.title) || 'Photo Viewer', onClose: onClose, onNext: images.length > 1 ? handleNext : undefined, onPrevious: images.length > 1 ? handlePrevious : undefined, onZoomIn: allowZoom ? function () { return handleZoom(zoom + zoomStep); } : undefined, onZoomOut: allowZoom ? function () { return handleZoom(zoom - zoomStep); } : undefined, onRotate: allowRotate ? handleRotate : undefined, onReset: zoom !== 1 || rotationCount !== 0 ? handleReset : undefined, showControls: isHovered }),
239
+ React.createElement("div", { style: {
240
+ position: 'relative',
241
+ width: '100%',
242
+ height: '100%',
243
+ display: 'flex',
244
+ alignItems: 'center',
245
+ justifyContent: 'center',
246
+ } },
247
+ React.createElement("img", { ref: imageRef, src: currentSelectedImage === null || currentSelectedImage === void 0 ? void 0 : currentSelectedImage.src, alt: (currentSelectedImage === null || currentSelectedImage === void 0 ? void 0 : currentSelectedImage.alt) || '', onDoubleClick: handleDoubleClick, style: {
248
+ maxWidth: '80%',
249
+ maxHeight: '80%',
250
+ minHeight: '80%',
251
+ objectFit: 'contain',
252
+ transform: "scale(".concat(zoom, ") rotateZ(").concat(rotationCount * 90, "deg)"),
253
+ transformOrigin: 'center',
254
+ transition: 'transform 0.2s ease',
255
+ } }))));
256
+ };
257
+
258
+ var Image = function (_a) {
259
+ var image = _a.image, onClick = _a.onClick;
260
+ var _b = React.useState(true), isLoading = _b[0], setIsLoading = _b[1];
261
+ return (React.createElement("div", { key: image.id, style: {
262
+ aspectRatio: '4/4',
263
+ overflow: 'hidden',
264
+ borderRadius: '8px',
265
+ cursor: 'pointer',
266
+ boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
267
+ transition: 'transform 0.2s ease',
268
+ position: 'relative',
269
+ }, onClick: onClick },
270
+ isLoading && (React.createElement("div", { style: {
271
+ position: 'absolute',
272
+ top: 0,
273
+ left: 0,
274
+ width: '100%',
275
+ height: '100%',
276
+ backgroundColor: '#f0f0f0',
277
+ animation: 'pulse 1.5s infinite',
278
+ } })),
279
+ React.createElement("img", { src: image.src, alt: image.alt, style: {
280
+ width: '100%',
281
+ height: '100%',
282
+ objectFit: 'cover',
283
+ opacity: isLoading ? 0 : 1,
284
+ transition: 'opacity 0.3s ease',
285
+ }, onLoad: function () { return setIsLoading(false); } }),
286
+ React.createElement("style", null, "\n @keyframes pulse {\n 0% { opacity: 0.6; }\n 50% { opacity: 0.8; }\n 100% { opacity: 0.6; }\n }\n ")));
287
+ };
288
+
289
+ var GalleryGrid = function (_a) {
290
+ var children = _a.children;
291
+ return (React.createElement("div", { style: {
292
+ display: 'grid',
293
+ gridTemplateColumns: 'repeat(auto-fill, minmax(300px, 1fr))',
294
+ gap: '1rem',
295
+ maxWidth: '1200px',
296
+ margin: '0 auto',
297
+ } }, children));
298
+ };
299
+ var Gallery = function (_a) {
300
+ var images = _a.images;
301
+ var _b = React.useState(null), selectedImage = _b[0], setSelectedImage = _b[1];
302
+ return (React.createElement(React.Fragment, null,
303
+ React.createElement(GalleryGrid, null, images.map(function (image) { return (React.createElement(Image, { key: image.id, image: image, onClick: function () {
304
+ setSelectedImage(image);
305
+ } })); })),
306
+ React.createElement(PhotoViewer, { selectedImage: selectedImage, images: images, onClose: function () { return setSelectedImage(null); } })));
307
+ };
308
+
309
+ exports.Gallery = Gallery;
310
+ exports.Image = Image;
311
+ exports.PhotoViewer = PhotoViewer;
312
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,7 @@
1
+ export type ZZImage = {
2
+ id: string;
3
+ src: string;
4
+ alt?: string;
5
+ title?: string;
6
+ svgOverlay?: React.ReactNode;
7
+ };
package/package.json ADDED
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "zimme-zoom",
3
+ "version": "0.1.0",
4
+ "description": "A lightweight React photo viewer with zoom, navigation, blurred background, and SVG overlay support",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.esm.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "scripts": {
12
+ "build": "yarn clean && rollup -c",
13
+ "build:storybook": "storybook build",
14
+ "build:vercel": "storybook build",
15
+ "dev": "rollup -c -w",
16
+ "clean": "rimraf dist",
17
+ "test": "jest",
18
+ "lint": "eslint src --ext .ts,.tsx",
19
+ "format": "prettier --write \"src/**/*.{ts,tsx}\"",
20
+ "prepare": "yarn build",
21
+ "storybook": "storybook dev -p 6006",
22
+ "build-storybook": "storybook build"
23
+ },
24
+ "peerDependencies": {
25
+ "react": ">=16.8.0",
26
+ "react-dom": ">=16.8.0"
27
+ },
28
+ "devDependencies": {
29
+ "@storybook/addon-essentials": "^8.6.14",
30
+ "@storybook/addon-interactions": "^8.6.14",
31
+ "@storybook/addon-links": "^8.6.14",
32
+ "@storybook/blocks": "^8.6.14",
33
+ "@storybook/react": "^8.6.14",
34
+ "@storybook/react-vite": "^8.6.14",
35
+ "@storybook/test": "^8.6.14",
36
+ "@storybook/testing-library": "^0.2.2",
37
+ "@types/react": "^18.2.0",
38
+ "@types/react-dom": "^18.2.0",
39
+ "@typescript-eslint/eslint-plugin": "^7.0.0",
40
+ "@typescript-eslint/parser": "^7.0.0",
41
+ "eslint": "^8.56.0",
42
+ "eslint-config-prettier": "^9.1.0",
43
+ "eslint-plugin-react": "^7.33.2",
44
+ "eslint-plugin-react-hooks": "^4.6.0",
45
+ "prettier": "^3.2.5",
46
+ "react": "^19.2.0",
47
+ "react-dom": "^19.2.0",
48
+ "rimraf": "^5.0.5",
49
+ "rollup": "^4.9.6",
50
+ "rollup-plugin-typescript2": "^0.36.0",
51
+ "storybook": "^8.6.14",
52
+ "typescript": "^5.8.3",
53
+ "vite": "^7.2.6"
54
+ },
55
+ "keywords": [
56
+ "react",
57
+ "photo-viewer",
58
+ "zoom",
59
+ "image-viewer",
60
+ "lightbox",
61
+ "svg-overlay"
62
+ ],
63
+ "author": "Kulcsar Rudolf <kulcsarrudolf@gmail.com>",
64
+ "license": "MIT",
65
+ "repository": {
66
+ "type": "git",
67
+ "url": "https://github.com/kulcsarrudolf/zimme-zoom"
68
+ },
69
+ "bugs": {
70
+ "url": "https://github.com/kulcsarrudolf/zimme-zoom/issues"
71
+ },
72
+ "homepage": "https://github.com/kulcsarrudolf/zimme-zoom#readme",
73
+ "engines": {
74
+ "node": ">=14.0.0",
75
+ "yarn": ">=1.22.0"
76
+ }
77
+ }