├── .gitignore ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── LICENSE ├── README.md ├── ZoomAnyJs.svg ├── ben.jpg ├── docs ├── assets │ ├── bhc.png │ ├── favicon.ai │ ├── favicon.ico │ ├── favicon.png │ ├── favicon.svg │ ├── img1.png │ └── logo.svg ├── index.html ├── main.css └── robots.txt ├── index.html ├── package-lock.json ├── package.json ├── public └── vite.svg ├── src ├── zoom-any-js.css └── zoom-any-js.ts ├── test ├── img │ ├── 1.png │ ├── 2.png │ └── 3.png ├── test.css └── test.js ├── tsconfig.json └── vite.config.ts /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BenHerbst/zoom-any-js/a2db2522d60281dbda6ea6b44cee2ab3cd15adca/1.png -------------------------------------------------------------------------------- /2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BenHerbst/zoom-any-js/a2db2522d60281dbda6ea6b44cee2ab3cd15adca/2.png -------------------------------------------------------------------------------- /3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BenHerbst/zoom-any-js/a2db2522d60281dbda6ea6b44cee2ab3cd15adca/3.png -------------------------------------------------------------------------------- /4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BenHerbst/zoom-any-js/a2db2522d60281dbda6ea6b44cee2ab3cd15adca/4.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # https://zoomanyjs.benherbst.net/ 2 |
3 |

ZoomAny.js

4 | 5 | 6 | Zoom literally **ANY** HTML Element using pure vanilla JavaScript. 7 | 8 | _\*Supports TypeScript_ 9 |
10 | 11 | ## Features 12 | - TypeScript support 13 | - Uses relative and not absolute position ( keep same place, just make zoomable ) 14 | - Enable zoom for any HTML Element you want, not just images 15 | - Boundings 16 | - Fully controlable via functions and data-* attributes 17 | 18 | ## Install 19 | 20 | Install via NPM: 21 | ``` 22 | npm i zoom-any-js 23 | ``` 24 | 25 | Or via CDN: 26 | ``` 27 | CSS: https://cdn.jsdelivr.net/npm/zoom-any-js@latest/dist/zoom-any-js.css 28 | JS: https://cdn.jsdelivr.net/npm/zoom-any-js@latest/dist/zoom-any-js.js 29 | ``` 30 | 31 | ## Basic Usage 32 | 33 | To get started, add the class "zoomable" to the element you want to enable zoom on: 34 | ``` html 35 | 36 | ``` 37 | 38 | ### NPM + Bundler: 39 | Then create a new instance in JavaScript, and import the CSS: 40 | ``` javascript 41 | import ZoomAnyJs from "zoom-any-js"; 42 | import "zoom-any-js/dist/zoom-any-js.css"; 43 | 44 | const zoom = new ZoomAnyJs() 45 | ``` 46 | 47 | ### CDN: 48 | ``` html 49 | 50 | ``` 51 | 52 | ``` html 53 | 58 | ``` 59 | 60 | Now try to zoom into your image, it should start to zoom! 🎉 61 | 62 | ## Examples 63 | 64 | Go to center on click: 65 | ``` ts 66 | document.getElementById("img").addEventListener("click", () => { 67 | zoom.center() 68 | zoom.apply() 69 | }) 70 | ``` 71 | 72 | Zoom into the screen center: 73 | ``` js 74 | zoom.zoomAt(1.1, { x: window.innerWidth / 2, y: window.innerHeight / 2 }) 75 | zoom.apply() 76 | ``` 77 | 78 | Using the wrapper class: 79 | ``` html 80 |
81 | 82 |
83 | ``` 84 | 85 | ![Wrapper Zoomed Out](3.png) 86 | 87 | ![Wrapper Zoomed In](4.png) 88 | 89 | This keeps it inside the wrapper div and makes you zoom into it without any overflow. 90 | 91 | Whatsapp or Windows Photos like Image Zoom: 92 | ``` html 93 | 94 | ``` 95 | 96 | ![Bounded Zoomed Out](1.png) 97 | 98 | ![Bounded Zoomed In](2.png) 99 | 100 | Multiple images: 101 | Each gets their own instance, and you pass a css selector into the constructor like this: 102 | ``` js 103 | const zoom1 = new ZoomAnyJs() 104 | const zoom2 = new ZoomAnyJs(".zoom2") 105 | const zoom3 = new ZoomAnyJs("#zoom3") 106 | 107 | 108 | 109 | 110 | ``` 111 | 112 | ## Options 113 | 114 | Basic options can be set by using data-* attributes on the element you zoom: 115 | 116 | - data-max-zoom: Set maximimum zoom. Default: 4000 117 | - data-min-zoom: Set minimum zoom. Default: 10 118 | - data-bounds: Enable fit to bounding. Default: false 119 | - data-origin-parent: Use the _offsetParent_ as origin for fitting bounding. Else it uses window. Default: false 120 | 121 | _The default zoom level is 100, which is the original size and represents a scale of 1.0_ 122 | 123 | ## Control via JavaScript 124 | 125 | The instance, so in this case _const zoom_, has many functions which you can use to fully control the libary. 126 | 127 | **You need to call .apply() to update the view to the changes!!!** 128 | 129 | All available functions: 130 | - center(): Moves the image to the center of the window or the offsetParent when using data-origin-parent 131 | - fitToBounds(): Fits into the bounds when using data-bounds, else it just returns void 132 | - zoomAt(amplitude: number, pos: {x: number, y: number}): Move to the position by the amplitude. Amplitude > 1 zooms in and amplitude < 1 zooms out 133 | - addListeners(): Adds the event listeners 134 | - removeListeners(): Removes the event listeners 135 | - apply(): Has to be callen to update the view. Without calling it, you cant see any change 136 | - destroy(): Makes the element "normal" again, as before running the zoom library 137 | - reset(): Resets position and zoom to default values 138 | - getZoom(): Returns the zoom 139 | - setZoom(value: number): Sets the zoom 140 | - getPos(): Returns the position 141 | - setPos(value: {x: number, y: number}): Sets the position 142 | -------------------------------------------------------------------------------- /ZoomAnyJs.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /ben.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BenHerbst/zoom-any-js/a2db2522d60281dbda6ea6b44cee2ab3cd15adca/ben.jpg -------------------------------------------------------------------------------- /docs/assets/bhc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BenHerbst/zoom-any-js/a2db2522d60281dbda6ea6b44cee2ab3cd15adca/docs/assets/bhc.png -------------------------------------------------------------------------------- /docs/assets/favicon.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BenHerbst/zoom-any-js/a2db2522d60281dbda6ea6b44cee2ab3cd15adca/docs/assets/favicon.ai -------------------------------------------------------------------------------- /docs/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BenHerbst/zoom-any-js/a2db2522d60281dbda6ea6b44cee2ab3cd15adca/docs/assets/favicon.ico -------------------------------------------------------------------------------- /docs/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BenHerbst/zoom-any-js/a2db2522d60281dbda6ea6b44cee2ab3cd15adca/docs/assets/favicon.png -------------------------------------------------------------------------------- /docs/assets/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /docs/assets/img1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BenHerbst/zoom-any-js/a2db2522d60281dbda6ea6b44cee2ab3cd15adca/docs/assets/img1.png -------------------------------------------------------------------------------- /docs/assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | ZoomAny.js 4 | 5 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 49 |
50 |
51 | 67 |
68 |
69 | Intro Example 71 |
72 | 73 | 74 |
75 |
76 | 77 |

ZoomAny.js is a JavaScript library for zooming any HTML Element, including Images, UI Elements and 78 | Videos.

79 |
80 | Get Started 81 | Examples 82 | GitHub 83 |
84 |
85 |
86 |

Get Started

87 |
88 |

Install

89 |

Install via NPM:

90 |
npm install zoom-any-js
91 |

Or via CDN:

92 |
CSS: https://cdn.jsdelivr.net/npm/zoom-any-js@latest/dist/zoom-any-js.css
 93 | JS: https://cdn.jsdelivr.net/npm/zoom-any-js@latest/dist/zoom-any-js.js
94 |

Basic Usage

95 |

To get started, add the class "zoomable" to the element you want to enable zoom on:

96 |
<img class="zoomable" src="public/img.png">
97 |

NPM + Bundler:

98 |
import ZoomAnyJs from "zoom-any-js";
 99 | import "zoom-any-js/dist/zoom-any-js.css";
100 | 
101 | const zoom = new ZoomAnyJs()
102 |

CDN:

103 |
<link type="text/css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/zoom-any-js@latest/dist/zoom-any-js.css">
104 |
<script type="module">
105 |     import ZoomAnyJs from "https://cdn.jsdelivr.net/npm/zoom-any-js@latest/dist/zoom-any-js.js"
106 | 
107 |     const zoom = new ZoomAnyJs()
108 | </script>
109 |

Now try to zoom into your image, it should start to zoom!

110 |
111 |
112 |

Docs

113 |
114 |

Methods:

115 |
116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 |
MethodDescriptionParametersReturns
constructorSelects the DOM element to be manipulated using the provided selector. Adds event listeners and 129 | applies zoom. 130 | string (default=".zoomable")void
resetResets the internal values of the zoom element to their default state.Nonevoid
getZoomRetrieves the current zoom level of the element.Nonenumber
setZoomSets the current zoom level of the element.numbervoid
setPosSets the position values (x and y coordinates) for the element.object {x: number, y: number}void
getPosRetrieves the current position values (x and y coordinates) of the element.Noneobject {x: number, y: number}
centerCenters the element within its container, which can be the window or the element's parent.Nonevoid
fitToBoundsAdjusts the position of the element to fit within its bounds based on the data-origin and 173 | data-bounds attributes. 174 | Nonevoid
zoomAtZooms the element based on the given amplitude and position.number, object {x: number, y: number}void
addListenersAdds event listeners to the element for handling user interactions.Nonevoid
removeListenersRemoves event listeners from the element to stop handling user interactions.Nonevoid
applyApplies the current transformation and position values to the element.Nonevoid
destroyRemoves all listeners and CSS changes, reverting the element to its initial state.Nonevoid
210 |
211 |

Data-Options:

212 |
213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 |
AttributeFunctionDefault
data-max-zoomSet maximum zoom4000
data-min-zoomSet minimum zoom10
data-boundsEnable fit to boundfalse
data-origin-parentUse the offsetParent as origin for fitting bounding. Else it uses windowfalse
244 |
245 |
246 |
247 |

Examples

248 |
249 |

Fullscreen

250 |
251 |

254 | See the Pen 255 | ZoomAny.js Fullscreen by Ben Herbst (@BenHerbst) 256 | on CodePen. 257 |

258 | 259 |
260 |

Standalone

261 |
262 |

265 | See the Pen 266 | ZoomAny.js Fullscreen by Ben Herbst (@BenHerbst) 267 | on CodePen. 268 |

269 | 270 |
271 |

Wrapper

272 |
273 |

276 | See the Pen 277 | ZoomAny.js Standalone by Ben Herbst (@BenHerbst) 278 | on CodePen. 279 |

280 | 281 |
282 |
283 |
284 | 287 | 347 | 348 | -------------------------------------------------------------------------------- /docs/main.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --primary-color: black; 3 | --primary-color-rgb: 000, 000, 000; 4 | } 5 | 6 | *, *::before, *::after { 7 | box-sizing: border-box; 8 | } 9 | 10 | html, body { 11 | padding: 0; 12 | margin: 0; 13 | font-family: Roboto, 'sans-serif'; 14 | } 15 | 16 | .intro { 17 | display: flex; 18 | flex-direction: column; 19 | align-items: center; 20 | gap: 2rem; 21 | margin-top: 4rem; 22 | margin-bottom: 4rem; 23 | 24 | p { 25 | margin: 0; 26 | } 27 | 28 | img { 29 | cursor: zoom-in; 30 | } 31 | } 32 | 33 | img { 34 | max-width: 100% 35 | } 36 | 37 | .intro h1 { 38 | font-size: 1.1rem; 39 | font-weight: normal; 40 | text-align: center; 41 | color: #4c4c4c; 42 | max-width: 600px; 43 | 44 | b { 45 | color: #000000; 46 | } 47 | } 48 | 49 | header, #hamburgerMenu { 50 | background-color: rgba(var(--primary-color-rgb), 0.9); 51 | -webkit-backdrop-filter: blur(20px); 52 | backdrop-filter: blur(20px); 53 | } 54 | 55 | header { 56 | padding: 10px; 57 | display: flex; 58 | justify-content: center; 59 | position: fixed; 60 | top: 0; 61 | width: 100%; 62 | z-index: 999; 63 | transition: all 0.5s; 64 | 65 | &.shadow { 66 | box-shadow: rgba(0, 0, 0, 0.61) 0px 8px 24px; 67 | } 68 | } 69 | 70 | main { 71 | padding: 72px 1rem 36px; 72 | } 73 | 74 | footer { 75 | padding-bottom: 72px; 76 | padding-right: 1rem; 77 | padding-left: 1rem; 78 | } 79 | 80 | .container-fluid { 81 | max-width: 1000px; 82 | width: 100%; 83 | margin-left: auto; 84 | margin-right: auto; 85 | } 86 | 87 | #hamburger { 88 | display: block; 89 | position: relative; 90 | outline: none; 91 | border: none; 92 | background-color: transparent; 93 | width: 40px; 94 | height: 28px; 95 | padding: 0; 96 | cursor: pointer; 97 | 98 | &[data-open] span { 99 | &:nth-child(1) { 100 | transform: translateY(12px) rotate(45deg); 101 | } 102 | 103 | &:nth-child(2) { 104 | opacity: 0; 105 | } 106 | 107 | &:nth-child(3) { 108 | transform: translateY(-12px) rotate(-45deg); 109 | } 110 | } 111 | 112 | span { 113 | position: absolute; 114 | height: 4px; 115 | width: 40px; 116 | background: #fff; 117 | border-radius: 999px; 118 | transform-origin: center; 119 | transition: 0.1s; 120 | 121 | &:nth-child(1) { 122 | top: 0; 123 | } 124 | 125 | &:nth-child(2) { 126 | top: 12px; 127 | } 128 | 129 | &:nth-child(3) { 130 | top: 24px; 131 | } 132 | } 133 | } 134 | 135 | /* mobile */ 136 | @media (max-width: 699px) { 137 | header { 138 | nav { 139 | display: none !important; 140 | } 141 | 142 | #hamburgerMenu { 143 | visibility: visible; 144 | } 145 | } 146 | 147 | #introButtons { 148 | flex-direction: column; 149 | width: 100%; 150 | gap: 0.5rem !important; 151 | 152 | a { 153 | width: 100%; 154 | } 155 | } 156 | 157 | .intro { 158 | margin-top: 1rem !important; 159 | } 160 | } 161 | 162 | /* desktop */ 163 | @media (min-width: 700px) { 164 | #hamburger { 165 | display: none; 166 | } 167 | 168 | #hamburgerMenu { 169 | visibility: hidden; 170 | } 171 | } 172 | 173 | #hamburgerMenu { 174 | z-index: 998; 175 | position: fixed; 176 | right: 0; 177 | width: 300px; 178 | max-width: 100%; 179 | top: 65px; 180 | height: calc(100vh - 66px); 181 | transform: translateX(100%); 182 | transition: 0.2s; 183 | padding: 2rem; 184 | 185 | &.visible { 186 | transform: translateX(0); 187 | } 188 | 189 | ul { 190 | list-style-type: none; 191 | padding: 0; 192 | margin: 0; 193 | font-size: 1.2rem; 194 | } 195 | 196 | li { 197 | color: #fff; 198 | margin-bottom: 1rem; 199 | } 200 | } 201 | 202 | .navbar { 203 | display: flex; 204 | justify-content: space-between; 205 | align-items: center; 206 | color: #FFF; 207 | 208 | .title { 209 | font-size: 1.4rem; 210 | } 211 | 212 | & * { 213 | display: flex; 214 | align-items: center; 215 | gap: 1rem; 216 | } 217 | } 218 | 219 | a { 220 | color: inherit; 221 | text-decoration: none; 222 | 223 | &:hover { 224 | text-decoration: underline; 225 | } 226 | } 227 | 228 | #logoLink { 229 | text-decoration: none; 230 | } 231 | 232 | #logo { 233 | transition: all 0.3s; 234 | 235 | &:hover { 236 | transform: scale(1.3) 237 | } 238 | 239 | &:active { 240 | transform: scale(0.9) 241 | } 242 | } 243 | 244 | .wrapperMenu { 245 | position: absolute; 246 | display: flex; 247 | flex-direction: column; 248 | gap: 0; 249 | right: 0; 250 | top: 0; 251 | 252 | button { 253 | font-size: 1.5rem; 254 | width: 3rem; 255 | height: 3rem; 256 | background-color: #2b2b2b; 257 | color: #b3b3b3; 258 | border: none; 259 | cursor: pointer; 260 | 261 | &:last-child { 262 | border-bottom-left-radius: 10px; 263 | } 264 | 265 | &:hover { 266 | background-color: #151515; 267 | } 268 | } 269 | } 270 | 271 | .text { 272 | position: relative; 273 | } 274 | 275 | .btn { 276 | position: relative; 277 | padding: 16px 40px; 278 | text-decoration: none !important; 279 | user-select: none; 280 | cursor: pointer; 281 | transition: all 0.2s; 282 | overflow: hidden; 283 | text-align: center; 284 | 285 | &:active { 286 | transform: scale(0.9) 287 | } 288 | 289 | &:hover::before { 290 | transform: translate(0, 0) 291 | } 292 | } 293 | 294 | .btn::before { 295 | content: ""; 296 | position: absolute; 297 | top: -2px; 298 | left: -2px; 299 | width: 110%; 300 | height: 130%; 301 | transition: all 0.5s; 302 | transform: translate(-110%, 0) skew(30deg); 303 | } 304 | 305 | .btn-primary { 306 | color: #FFF; 307 | background-color: var(--primary-color); 308 | 309 | &::before { 310 | background-color: #2b2b2b 311 | } 312 | } 313 | 314 | .btn-secondary { 315 | border: 2px solid var(--primary-color); 316 | 317 | &:hover { 318 | color: #FFF; 319 | } 320 | 321 | &::before { 322 | background-color: #000000; 323 | } 324 | } 325 | 326 | #introButtons { 327 | display: flex; 328 | gap: 1.5rem; 329 | } 330 | 331 | code { 332 | border-radius: 10px; 333 | } 334 | 335 | h3 { 336 | margin-top: 2.5rem; 337 | } 338 | 339 | hr { 340 | border: none; 341 | border-top: 2px solid #a3a3a3; 342 | } 343 | 344 | .tableWrapper { 345 | overflow-x: auto; 346 | } 347 | 348 | table { 349 | width: 100%; 350 | border-collapse: collapse; 351 | } 352 | 353 | th, td { 354 | padding: 10px; 355 | border: 1px solid #ddd; 356 | } 357 | 358 | th { 359 | background-color: #f4f4f4; 360 | } -------------------------------------------------------------------------------- /docs/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Test Zoom Any Js 10 | 11 | 12 | 13 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zoom-any-js", 3 | "version": "0.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "zoom-any-js", 9 | "version": "0.0.0", 10 | "devDependencies": { 11 | "@types/node": "^20.14.9", 12 | "typescript": "^5.2.2", 13 | "vite": "^5.3.1", 14 | "vite-plugin-dts": "^3.9.1" 15 | } 16 | }, 17 | "node_modules/@babel/parser": { 18 | "version": "7.24.7", 19 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", 20 | "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", 21 | "dev": true, 22 | "bin": { 23 | "parser": "bin/babel-parser.js" 24 | }, 25 | "engines": { 26 | "node": ">=6.0.0" 27 | } 28 | }, 29 | "node_modules/@esbuild/aix-ppc64": { 30 | "version": "0.21.5", 31 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", 32 | "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", 33 | "cpu": [ 34 | "ppc64" 35 | ], 36 | "dev": true, 37 | "optional": true, 38 | "os": [ 39 | "aix" 40 | ], 41 | "engines": { 42 | "node": ">=12" 43 | } 44 | }, 45 | "node_modules/@esbuild/android-arm": { 46 | "version": "0.21.5", 47 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", 48 | "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", 49 | "cpu": [ 50 | "arm" 51 | ], 52 | "dev": true, 53 | "optional": true, 54 | "os": [ 55 | "android" 56 | ], 57 | "engines": { 58 | "node": ">=12" 59 | } 60 | }, 61 | "node_modules/@esbuild/android-arm64": { 62 | "version": "0.21.5", 63 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", 64 | "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", 65 | "cpu": [ 66 | "arm64" 67 | ], 68 | "dev": true, 69 | "optional": true, 70 | "os": [ 71 | "android" 72 | ], 73 | "engines": { 74 | "node": ">=12" 75 | } 76 | }, 77 | "node_modules/@esbuild/android-x64": { 78 | "version": "0.21.5", 79 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", 80 | "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", 81 | "cpu": [ 82 | "x64" 83 | ], 84 | "dev": true, 85 | "optional": true, 86 | "os": [ 87 | "android" 88 | ], 89 | "engines": { 90 | "node": ">=12" 91 | } 92 | }, 93 | "node_modules/@esbuild/darwin-arm64": { 94 | "version": "0.21.5", 95 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", 96 | "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", 97 | "cpu": [ 98 | "arm64" 99 | ], 100 | "dev": true, 101 | "optional": true, 102 | "os": [ 103 | "darwin" 104 | ], 105 | "engines": { 106 | "node": ">=12" 107 | } 108 | }, 109 | "node_modules/@esbuild/darwin-x64": { 110 | "version": "0.21.5", 111 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", 112 | "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", 113 | "cpu": [ 114 | "x64" 115 | ], 116 | "dev": true, 117 | "optional": true, 118 | "os": [ 119 | "darwin" 120 | ], 121 | "engines": { 122 | "node": ">=12" 123 | } 124 | }, 125 | "node_modules/@esbuild/freebsd-arm64": { 126 | "version": "0.21.5", 127 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", 128 | "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", 129 | "cpu": [ 130 | "arm64" 131 | ], 132 | "dev": true, 133 | "optional": true, 134 | "os": [ 135 | "freebsd" 136 | ], 137 | "engines": { 138 | "node": ">=12" 139 | } 140 | }, 141 | "node_modules/@esbuild/freebsd-x64": { 142 | "version": "0.21.5", 143 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", 144 | "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", 145 | "cpu": [ 146 | "x64" 147 | ], 148 | "dev": true, 149 | "optional": true, 150 | "os": [ 151 | "freebsd" 152 | ], 153 | "engines": { 154 | "node": ">=12" 155 | } 156 | }, 157 | "node_modules/@esbuild/linux-arm": { 158 | "version": "0.21.5", 159 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", 160 | "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", 161 | "cpu": [ 162 | "arm" 163 | ], 164 | "dev": true, 165 | "optional": true, 166 | "os": [ 167 | "linux" 168 | ], 169 | "engines": { 170 | "node": ">=12" 171 | } 172 | }, 173 | "node_modules/@esbuild/linux-arm64": { 174 | "version": "0.21.5", 175 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", 176 | "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", 177 | "cpu": [ 178 | "arm64" 179 | ], 180 | "dev": true, 181 | "optional": true, 182 | "os": [ 183 | "linux" 184 | ], 185 | "engines": { 186 | "node": ">=12" 187 | } 188 | }, 189 | "node_modules/@esbuild/linux-ia32": { 190 | "version": "0.21.5", 191 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", 192 | "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", 193 | "cpu": [ 194 | "ia32" 195 | ], 196 | "dev": true, 197 | "optional": true, 198 | "os": [ 199 | "linux" 200 | ], 201 | "engines": { 202 | "node": ">=12" 203 | } 204 | }, 205 | "node_modules/@esbuild/linux-loong64": { 206 | "version": "0.21.5", 207 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", 208 | "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", 209 | "cpu": [ 210 | "loong64" 211 | ], 212 | "dev": true, 213 | "optional": true, 214 | "os": [ 215 | "linux" 216 | ], 217 | "engines": { 218 | "node": ">=12" 219 | } 220 | }, 221 | "node_modules/@esbuild/linux-mips64el": { 222 | "version": "0.21.5", 223 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", 224 | "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", 225 | "cpu": [ 226 | "mips64el" 227 | ], 228 | "dev": true, 229 | "optional": true, 230 | "os": [ 231 | "linux" 232 | ], 233 | "engines": { 234 | "node": ">=12" 235 | } 236 | }, 237 | "node_modules/@esbuild/linux-ppc64": { 238 | "version": "0.21.5", 239 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", 240 | "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", 241 | "cpu": [ 242 | "ppc64" 243 | ], 244 | "dev": true, 245 | "optional": true, 246 | "os": [ 247 | "linux" 248 | ], 249 | "engines": { 250 | "node": ">=12" 251 | } 252 | }, 253 | "node_modules/@esbuild/linux-riscv64": { 254 | "version": "0.21.5", 255 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", 256 | "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", 257 | "cpu": [ 258 | "riscv64" 259 | ], 260 | "dev": true, 261 | "optional": true, 262 | "os": [ 263 | "linux" 264 | ], 265 | "engines": { 266 | "node": ">=12" 267 | } 268 | }, 269 | "node_modules/@esbuild/linux-s390x": { 270 | "version": "0.21.5", 271 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", 272 | "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", 273 | "cpu": [ 274 | "s390x" 275 | ], 276 | "dev": true, 277 | "optional": true, 278 | "os": [ 279 | "linux" 280 | ], 281 | "engines": { 282 | "node": ">=12" 283 | } 284 | }, 285 | "node_modules/@esbuild/linux-x64": { 286 | "version": "0.21.5", 287 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", 288 | "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", 289 | "cpu": [ 290 | "x64" 291 | ], 292 | "dev": true, 293 | "optional": true, 294 | "os": [ 295 | "linux" 296 | ], 297 | "engines": { 298 | "node": ">=12" 299 | } 300 | }, 301 | "node_modules/@esbuild/netbsd-x64": { 302 | "version": "0.21.5", 303 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", 304 | "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", 305 | "cpu": [ 306 | "x64" 307 | ], 308 | "dev": true, 309 | "optional": true, 310 | "os": [ 311 | "netbsd" 312 | ], 313 | "engines": { 314 | "node": ">=12" 315 | } 316 | }, 317 | "node_modules/@esbuild/openbsd-x64": { 318 | "version": "0.21.5", 319 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", 320 | "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", 321 | "cpu": [ 322 | "x64" 323 | ], 324 | "dev": true, 325 | "optional": true, 326 | "os": [ 327 | "openbsd" 328 | ], 329 | "engines": { 330 | "node": ">=12" 331 | } 332 | }, 333 | "node_modules/@esbuild/sunos-x64": { 334 | "version": "0.21.5", 335 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", 336 | "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", 337 | "cpu": [ 338 | "x64" 339 | ], 340 | "dev": true, 341 | "optional": true, 342 | "os": [ 343 | "sunos" 344 | ], 345 | "engines": { 346 | "node": ">=12" 347 | } 348 | }, 349 | "node_modules/@esbuild/win32-arm64": { 350 | "version": "0.21.5", 351 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", 352 | "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", 353 | "cpu": [ 354 | "arm64" 355 | ], 356 | "dev": true, 357 | "optional": true, 358 | "os": [ 359 | "win32" 360 | ], 361 | "engines": { 362 | "node": ">=12" 363 | } 364 | }, 365 | "node_modules/@esbuild/win32-ia32": { 366 | "version": "0.21.5", 367 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", 368 | "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", 369 | "cpu": [ 370 | "ia32" 371 | ], 372 | "dev": true, 373 | "optional": true, 374 | "os": [ 375 | "win32" 376 | ], 377 | "engines": { 378 | "node": ">=12" 379 | } 380 | }, 381 | "node_modules/@esbuild/win32-x64": { 382 | "version": "0.21.5", 383 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", 384 | "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", 385 | "cpu": [ 386 | "x64" 387 | ], 388 | "dev": true, 389 | "optional": true, 390 | "os": [ 391 | "win32" 392 | ], 393 | "engines": { 394 | "node": ">=12" 395 | } 396 | }, 397 | "node_modules/@jridgewell/sourcemap-codec": { 398 | "version": "1.4.15", 399 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", 400 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", 401 | "dev": true 402 | }, 403 | "node_modules/@microsoft/api-extractor": { 404 | "version": "7.43.0", 405 | "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.43.0.tgz", 406 | "integrity": "sha512-GFhTcJpB+MI6FhvXEI9b2K0snulNLWHqC/BbcJtyNYcKUiw7l3Lgis5ApsYncJ0leALX7/of4XfmXk+maT111w==", 407 | "dev": true, 408 | "dependencies": { 409 | "@microsoft/api-extractor-model": "7.28.13", 410 | "@microsoft/tsdoc": "0.14.2", 411 | "@microsoft/tsdoc-config": "~0.16.1", 412 | "@rushstack/node-core-library": "4.0.2", 413 | "@rushstack/rig-package": "0.5.2", 414 | "@rushstack/terminal": "0.10.0", 415 | "@rushstack/ts-command-line": "4.19.1", 416 | "lodash": "~4.17.15", 417 | "minimatch": "~3.0.3", 418 | "resolve": "~1.22.1", 419 | "semver": "~7.5.4", 420 | "source-map": "~0.6.1", 421 | "typescript": "5.4.2" 422 | }, 423 | "bin": { 424 | "api-extractor": "bin/api-extractor" 425 | } 426 | }, 427 | "node_modules/@microsoft/api-extractor-model": { 428 | "version": "7.28.13", 429 | "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.13.tgz", 430 | "integrity": "sha512-39v/JyldX4MS9uzHcdfmjjfS6cYGAoXV+io8B5a338pkHiSt+gy2eXQ0Q7cGFJ7quSa1VqqlMdlPrB6sLR/cAw==", 431 | "dev": true, 432 | "dependencies": { 433 | "@microsoft/tsdoc": "0.14.2", 434 | "@microsoft/tsdoc-config": "~0.16.1", 435 | "@rushstack/node-core-library": "4.0.2" 436 | } 437 | }, 438 | "node_modules/@microsoft/api-extractor/node_modules/typescript": { 439 | "version": "5.4.2", 440 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", 441 | "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", 442 | "dev": true, 443 | "bin": { 444 | "tsc": "bin/tsc", 445 | "tsserver": "bin/tsserver" 446 | }, 447 | "engines": { 448 | "node": ">=14.17" 449 | } 450 | }, 451 | "node_modules/@microsoft/tsdoc": { 452 | "version": "0.14.2", 453 | "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz", 454 | "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==", 455 | "dev": true 456 | }, 457 | "node_modules/@microsoft/tsdoc-config": { 458 | "version": "0.16.2", 459 | "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.16.2.tgz", 460 | "integrity": "sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==", 461 | "dev": true, 462 | "dependencies": { 463 | "@microsoft/tsdoc": "0.14.2", 464 | "ajv": "~6.12.6", 465 | "jju": "~1.4.0", 466 | "resolve": "~1.19.0" 467 | } 468 | }, 469 | "node_modules/@microsoft/tsdoc-config/node_modules/resolve": { 470 | "version": "1.19.0", 471 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", 472 | "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", 473 | "dev": true, 474 | "dependencies": { 475 | "is-core-module": "^2.1.0", 476 | "path-parse": "^1.0.6" 477 | }, 478 | "funding": { 479 | "url": "https://github.com/sponsors/ljharb" 480 | } 481 | }, 482 | "node_modules/@rollup/pluginutils": { 483 | "version": "5.1.0", 484 | "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", 485 | "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", 486 | "dev": true, 487 | "dependencies": { 488 | "@types/estree": "^1.0.0", 489 | "estree-walker": "^2.0.2", 490 | "picomatch": "^2.3.1" 491 | }, 492 | "engines": { 493 | "node": ">=14.0.0" 494 | }, 495 | "peerDependencies": { 496 | "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" 497 | }, 498 | "peerDependenciesMeta": { 499 | "rollup": { 500 | "optional": true 501 | } 502 | } 503 | }, 504 | "node_modules/@rollup/rollup-android-arm-eabi": { 505 | "version": "4.18.0", 506 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", 507 | "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", 508 | "cpu": [ 509 | "arm" 510 | ], 511 | "dev": true, 512 | "optional": true, 513 | "os": [ 514 | "android" 515 | ] 516 | }, 517 | "node_modules/@rollup/rollup-android-arm64": { 518 | "version": "4.18.0", 519 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", 520 | "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", 521 | "cpu": [ 522 | "arm64" 523 | ], 524 | "dev": true, 525 | "optional": true, 526 | "os": [ 527 | "android" 528 | ] 529 | }, 530 | "node_modules/@rollup/rollup-darwin-arm64": { 531 | "version": "4.18.0", 532 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", 533 | "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", 534 | "cpu": [ 535 | "arm64" 536 | ], 537 | "dev": true, 538 | "optional": true, 539 | "os": [ 540 | "darwin" 541 | ] 542 | }, 543 | "node_modules/@rollup/rollup-darwin-x64": { 544 | "version": "4.18.0", 545 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", 546 | "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", 547 | "cpu": [ 548 | "x64" 549 | ], 550 | "dev": true, 551 | "optional": true, 552 | "os": [ 553 | "darwin" 554 | ] 555 | }, 556 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { 557 | "version": "4.18.0", 558 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", 559 | "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", 560 | "cpu": [ 561 | "arm" 562 | ], 563 | "dev": true, 564 | "optional": true, 565 | "os": [ 566 | "linux" 567 | ] 568 | }, 569 | "node_modules/@rollup/rollup-linux-arm-musleabihf": { 570 | "version": "4.18.0", 571 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", 572 | "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", 573 | "cpu": [ 574 | "arm" 575 | ], 576 | "dev": true, 577 | "optional": true, 578 | "os": [ 579 | "linux" 580 | ] 581 | }, 582 | "node_modules/@rollup/rollup-linux-arm64-gnu": { 583 | "version": "4.18.0", 584 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", 585 | "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", 586 | "cpu": [ 587 | "arm64" 588 | ], 589 | "dev": true, 590 | "optional": true, 591 | "os": [ 592 | "linux" 593 | ] 594 | }, 595 | "node_modules/@rollup/rollup-linux-arm64-musl": { 596 | "version": "4.18.0", 597 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", 598 | "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", 599 | "cpu": [ 600 | "arm64" 601 | ], 602 | "dev": true, 603 | "optional": true, 604 | "os": [ 605 | "linux" 606 | ] 607 | }, 608 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { 609 | "version": "4.18.0", 610 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", 611 | "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", 612 | "cpu": [ 613 | "ppc64" 614 | ], 615 | "dev": true, 616 | "optional": true, 617 | "os": [ 618 | "linux" 619 | ] 620 | }, 621 | "node_modules/@rollup/rollup-linux-riscv64-gnu": { 622 | "version": "4.18.0", 623 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", 624 | "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", 625 | "cpu": [ 626 | "riscv64" 627 | ], 628 | "dev": true, 629 | "optional": true, 630 | "os": [ 631 | "linux" 632 | ] 633 | }, 634 | "node_modules/@rollup/rollup-linux-s390x-gnu": { 635 | "version": "4.18.0", 636 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", 637 | "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", 638 | "cpu": [ 639 | "s390x" 640 | ], 641 | "dev": true, 642 | "optional": true, 643 | "os": [ 644 | "linux" 645 | ] 646 | }, 647 | "node_modules/@rollup/rollup-linux-x64-gnu": { 648 | "version": "4.18.0", 649 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", 650 | "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", 651 | "cpu": [ 652 | "x64" 653 | ], 654 | "dev": true, 655 | "optional": true, 656 | "os": [ 657 | "linux" 658 | ] 659 | }, 660 | "node_modules/@rollup/rollup-linux-x64-musl": { 661 | "version": "4.18.0", 662 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", 663 | "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", 664 | "cpu": [ 665 | "x64" 666 | ], 667 | "dev": true, 668 | "optional": true, 669 | "os": [ 670 | "linux" 671 | ] 672 | }, 673 | "node_modules/@rollup/rollup-win32-arm64-msvc": { 674 | "version": "4.18.0", 675 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", 676 | "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", 677 | "cpu": [ 678 | "arm64" 679 | ], 680 | "dev": true, 681 | "optional": true, 682 | "os": [ 683 | "win32" 684 | ] 685 | }, 686 | "node_modules/@rollup/rollup-win32-ia32-msvc": { 687 | "version": "4.18.0", 688 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", 689 | "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", 690 | "cpu": [ 691 | "ia32" 692 | ], 693 | "dev": true, 694 | "optional": true, 695 | "os": [ 696 | "win32" 697 | ] 698 | }, 699 | "node_modules/@rollup/rollup-win32-x64-msvc": { 700 | "version": "4.18.0", 701 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", 702 | "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", 703 | "cpu": [ 704 | "x64" 705 | ], 706 | "dev": true, 707 | "optional": true, 708 | "os": [ 709 | "win32" 710 | ] 711 | }, 712 | "node_modules/@rushstack/node-core-library": { 713 | "version": "4.0.2", 714 | "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.0.2.tgz", 715 | "integrity": "sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==", 716 | "dev": true, 717 | "dependencies": { 718 | "fs-extra": "~7.0.1", 719 | "import-lazy": "~4.0.0", 720 | "jju": "~1.4.0", 721 | "resolve": "~1.22.1", 722 | "semver": "~7.5.4", 723 | "z-schema": "~5.0.2" 724 | }, 725 | "peerDependencies": { 726 | "@types/node": "*" 727 | }, 728 | "peerDependenciesMeta": { 729 | "@types/node": { 730 | "optional": true 731 | } 732 | } 733 | }, 734 | "node_modules/@rushstack/rig-package": { 735 | "version": "0.5.2", 736 | "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.2.tgz", 737 | "integrity": "sha512-mUDecIJeH3yYGZs2a48k+pbhM6JYwWlgjs2Ca5f2n1G2/kgdgP9D/07oglEGf6mRyXEnazhEENeYTSNDRCwdqA==", 738 | "dev": true, 739 | "dependencies": { 740 | "resolve": "~1.22.1", 741 | "strip-json-comments": "~3.1.1" 742 | } 743 | }, 744 | "node_modules/@rushstack/terminal": { 745 | "version": "0.10.0", 746 | "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.10.0.tgz", 747 | "integrity": "sha512-UbELbXnUdc7EKwfH2sb8ChqNgapUOdqcCIdQP4NGxBpTZV2sQyeekuK3zmfQSa/MN+/7b4kBogl2wq0vpkpYGw==", 748 | "dev": true, 749 | "dependencies": { 750 | "@rushstack/node-core-library": "4.0.2", 751 | "supports-color": "~8.1.1" 752 | }, 753 | "peerDependencies": { 754 | "@types/node": "*" 755 | }, 756 | "peerDependenciesMeta": { 757 | "@types/node": { 758 | "optional": true 759 | } 760 | } 761 | }, 762 | "node_modules/@rushstack/ts-command-line": { 763 | "version": "4.19.1", 764 | "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.19.1.tgz", 765 | "integrity": "sha512-J7H768dgcpG60d7skZ5uSSwyCZs/S2HrWP1Ds8d1qYAyaaeJmpmmLr9BVw97RjFzmQPOYnoXcKA4GkqDCkduQg==", 766 | "dev": true, 767 | "dependencies": { 768 | "@rushstack/terminal": "0.10.0", 769 | "@types/argparse": "1.0.38", 770 | "argparse": "~1.0.9", 771 | "string-argv": "~0.3.1" 772 | } 773 | }, 774 | "node_modules/@types/argparse": { 775 | "version": "1.0.38", 776 | "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", 777 | "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", 778 | "dev": true 779 | }, 780 | "node_modules/@types/estree": { 781 | "version": "1.0.5", 782 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", 783 | "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", 784 | "dev": true 785 | }, 786 | "node_modules/@types/node": { 787 | "version": "20.14.9", 788 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", 789 | "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", 790 | "dev": true, 791 | "dependencies": { 792 | "undici-types": "~5.26.4" 793 | } 794 | }, 795 | "node_modules/@volar/language-core": { 796 | "version": "1.11.1", 797 | "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.11.1.tgz", 798 | "integrity": "sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==", 799 | "dev": true, 800 | "dependencies": { 801 | "@volar/source-map": "1.11.1" 802 | } 803 | }, 804 | "node_modules/@volar/source-map": { 805 | "version": "1.11.1", 806 | "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.11.1.tgz", 807 | "integrity": "sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==", 808 | "dev": true, 809 | "dependencies": { 810 | "muggle-string": "^0.3.1" 811 | } 812 | }, 813 | "node_modules/@volar/typescript": { 814 | "version": "1.11.1", 815 | "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.11.1.tgz", 816 | "integrity": "sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==", 817 | "dev": true, 818 | "dependencies": { 819 | "@volar/language-core": "1.11.1", 820 | "path-browserify": "^1.0.1" 821 | } 822 | }, 823 | "node_modules/@vue/compiler-core": { 824 | "version": "3.4.31", 825 | "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.31.tgz", 826 | "integrity": "sha512-skOiodXWTV3DxfDhB4rOf3OGalpITLlgCeOwb+Y9GJpfQ8ErigdBUHomBzvG78JoVE8MJoQsb+qhZiHfKeNeEg==", 827 | "dev": true, 828 | "dependencies": { 829 | "@babel/parser": "^7.24.7", 830 | "@vue/shared": "3.4.31", 831 | "entities": "^4.5.0", 832 | "estree-walker": "^2.0.2", 833 | "source-map-js": "^1.2.0" 834 | } 835 | }, 836 | "node_modules/@vue/compiler-dom": { 837 | "version": "3.4.31", 838 | "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.31.tgz", 839 | "integrity": "sha512-wK424WMXsG1IGMyDGyLqB+TbmEBFM78hIsOJ9QwUVLGrcSk0ak6zYty7Pj8ftm7nEtdU/DGQxAXp0/lM/2cEpQ==", 840 | "dev": true, 841 | "dependencies": { 842 | "@vue/compiler-core": "3.4.31", 843 | "@vue/shared": "3.4.31" 844 | } 845 | }, 846 | "node_modules/@vue/language-core": { 847 | "version": "1.8.27", 848 | "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-1.8.27.tgz", 849 | "integrity": "sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==", 850 | "dev": true, 851 | "dependencies": { 852 | "@volar/language-core": "~1.11.1", 853 | "@volar/source-map": "~1.11.1", 854 | "@vue/compiler-dom": "^3.3.0", 855 | "@vue/shared": "^3.3.0", 856 | "computeds": "^0.0.1", 857 | "minimatch": "^9.0.3", 858 | "muggle-string": "^0.3.1", 859 | "path-browserify": "^1.0.1", 860 | "vue-template-compiler": "^2.7.14" 861 | }, 862 | "peerDependencies": { 863 | "typescript": "*" 864 | }, 865 | "peerDependenciesMeta": { 866 | "typescript": { 867 | "optional": true 868 | } 869 | } 870 | }, 871 | "node_modules/@vue/language-core/node_modules/brace-expansion": { 872 | "version": "2.0.1", 873 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 874 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 875 | "dev": true, 876 | "dependencies": { 877 | "balanced-match": "^1.0.0" 878 | } 879 | }, 880 | "node_modules/@vue/language-core/node_modules/minimatch": { 881 | "version": "9.0.5", 882 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", 883 | "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", 884 | "dev": true, 885 | "dependencies": { 886 | "brace-expansion": "^2.0.1" 887 | }, 888 | "engines": { 889 | "node": ">=16 || 14 >=14.17" 890 | }, 891 | "funding": { 892 | "url": "https://github.com/sponsors/isaacs" 893 | } 894 | }, 895 | "node_modules/@vue/shared": { 896 | "version": "3.4.31", 897 | "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.31.tgz", 898 | "integrity": "sha512-Yp3wtJk//8cO4NItOPpi3QkLExAr/aLBGZMmTtW9WpdwBCJpRM6zj9WgWktXAl8IDIozwNMByT45JP3tO3ACWA==", 899 | "dev": true 900 | }, 901 | "node_modules/ajv": { 902 | "version": "6.12.6", 903 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 904 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 905 | "dev": true, 906 | "dependencies": { 907 | "fast-deep-equal": "^3.1.1", 908 | "fast-json-stable-stringify": "^2.0.0", 909 | "json-schema-traverse": "^0.4.1", 910 | "uri-js": "^4.2.2" 911 | }, 912 | "funding": { 913 | "type": "github", 914 | "url": "https://github.com/sponsors/epoberezkin" 915 | } 916 | }, 917 | "node_modules/argparse": { 918 | "version": "1.0.10", 919 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 920 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 921 | "dev": true, 922 | "dependencies": { 923 | "sprintf-js": "~1.0.2" 924 | } 925 | }, 926 | "node_modules/balanced-match": { 927 | "version": "1.0.2", 928 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 929 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 930 | "dev": true 931 | }, 932 | "node_modules/brace-expansion": { 933 | "version": "1.1.11", 934 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 935 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 936 | "dev": true, 937 | "dependencies": { 938 | "balanced-match": "^1.0.0", 939 | "concat-map": "0.0.1" 940 | } 941 | }, 942 | "node_modules/commander": { 943 | "version": "9.5.0", 944 | "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", 945 | "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", 946 | "dev": true, 947 | "optional": true, 948 | "engines": { 949 | "node": "^12.20.0 || >=14" 950 | } 951 | }, 952 | "node_modules/computeds": { 953 | "version": "0.0.1", 954 | "resolved": "https://registry.npmjs.org/computeds/-/computeds-0.0.1.tgz", 955 | "integrity": "sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==", 956 | "dev": true 957 | }, 958 | "node_modules/concat-map": { 959 | "version": "0.0.1", 960 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 961 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 962 | "dev": true 963 | }, 964 | "node_modules/de-indent": { 965 | "version": "1.0.2", 966 | "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", 967 | "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", 968 | "dev": true 969 | }, 970 | "node_modules/debug": { 971 | "version": "4.3.5", 972 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", 973 | "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", 974 | "dev": true, 975 | "dependencies": { 976 | "ms": "2.1.2" 977 | }, 978 | "engines": { 979 | "node": ">=6.0" 980 | }, 981 | "peerDependenciesMeta": { 982 | "supports-color": { 983 | "optional": true 984 | } 985 | } 986 | }, 987 | "node_modules/entities": { 988 | "version": "4.5.0", 989 | "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", 990 | "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", 991 | "dev": true, 992 | "engines": { 993 | "node": ">=0.12" 994 | }, 995 | "funding": { 996 | "url": "https://github.com/fb55/entities?sponsor=1" 997 | } 998 | }, 999 | "node_modules/esbuild": { 1000 | "version": "0.21.5", 1001 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", 1002 | "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", 1003 | "dev": true, 1004 | "hasInstallScript": true, 1005 | "bin": { 1006 | "esbuild": "bin/esbuild" 1007 | }, 1008 | "engines": { 1009 | "node": ">=12" 1010 | }, 1011 | "optionalDependencies": { 1012 | "@esbuild/aix-ppc64": "0.21.5", 1013 | "@esbuild/android-arm": "0.21.5", 1014 | "@esbuild/android-arm64": "0.21.5", 1015 | "@esbuild/android-x64": "0.21.5", 1016 | "@esbuild/darwin-arm64": "0.21.5", 1017 | "@esbuild/darwin-x64": "0.21.5", 1018 | "@esbuild/freebsd-arm64": "0.21.5", 1019 | "@esbuild/freebsd-x64": "0.21.5", 1020 | "@esbuild/linux-arm": "0.21.5", 1021 | "@esbuild/linux-arm64": "0.21.5", 1022 | "@esbuild/linux-ia32": "0.21.5", 1023 | "@esbuild/linux-loong64": "0.21.5", 1024 | "@esbuild/linux-mips64el": "0.21.5", 1025 | "@esbuild/linux-ppc64": "0.21.5", 1026 | "@esbuild/linux-riscv64": "0.21.5", 1027 | "@esbuild/linux-s390x": "0.21.5", 1028 | "@esbuild/linux-x64": "0.21.5", 1029 | "@esbuild/netbsd-x64": "0.21.5", 1030 | "@esbuild/openbsd-x64": "0.21.5", 1031 | "@esbuild/sunos-x64": "0.21.5", 1032 | "@esbuild/win32-arm64": "0.21.5", 1033 | "@esbuild/win32-ia32": "0.21.5", 1034 | "@esbuild/win32-x64": "0.21.5" 1035 | } 1036 | }, 1037 | "node_modules/estree-walker": { 1038 | "version": "2.0.2", 1039 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", 1040 | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", 1041 | "dev": true 1042 | }, 1043 | "node_modules/fast-deep-equal": { 1044 | "version": "3.1.3", 1045 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 1046 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 1047 | "dev": true 1048 | }, 1049 | "node_modules/fast-json-stable-stringify": { 1050 | "version": "2.1.0", 1051 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 1052 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 1053 | "dev": true 1054 | }, 1055 | "node_modules/fs-extra": { 1056 | "version": "7.0.1", 1057 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", 1058 | "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", 1059 | "dev": true, 1060 | "dependencies": { 1061 | "graceful-fs": "^4.1.2", 1062 | "jsonfile": "^4.0.0", 1063 | "universalify": "^0.1.0" 1064 | }, 1065 | "engines": { 1066 | "node": ">=6 <7 || >=8" 1067 | } 1068 | }, 1069 | "node_modules/fsevents": { 1070 | "version": "2.3.3", 1071 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 1072 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 1073 | "dev": true, 1074 | "hasInstallScript": true, 1075 | "optional": true, 1076 | "os": [ 1077 | "darwin" 1078 | ], 1079 | "engines": { 1080 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 1081 | } 1082 | }, 1083 | "node_modules/function-bind": { 1084 | "version": "1.1.2", 1085 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 1086 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 1087 | "dev": true, 1088 | "funding": { 1089 | "url": "https://github.com/sponsors/ljharb" 1090 | } 1091 | }, 1092 | "node_modules/graceful-fs": { 1093 | "version": "4.2.11", 1094 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", 1095 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", 1096 | "dev": true 1097 | }, 1098 | "node_modules/has-flag": { 1099 | "version": "4.0.0", 1100 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1101 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1102 | "dev": true, 1103 | "engines": { 1104 | "node": ">=8" 1105 | } 1106 | }, 1107 | "node_modules/hasown": { 1108 | "version": "2.0.2", 1109 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 1110 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 1111 | "dev": true, 1112 | "dependencies": { 1113 | "function-bind": "^1.1.2" 1114 | }, 1115 | "engines": { 1116 | "node": ">= 0.4" 1117 | } 1118 | }, 1119 | "node_modules/he": { 1120 | "version": "1.2.0", 1121 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 1122 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 1123 | "dev": true, 1124 | "bin": { 1125 | "he": "bin/he" 1126 | } 1127 | }, 1128 | "node_modules/import-lazy": { 1129 | "version": "4.0.0", 1130 | "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", 1131 | "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", 1132 | "dev": true, 1133 | "engines": { 1134 | "node": ">=8" 1135 | } 1136 | }, 1137 | "node_modules/is-core-module": { 1138 | "version": "2.14.0", 1139 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", 1140 | "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", 1141 | "dev": true, 1142 | "dependencies": { 1143 | "hasown": "^2.0.2" 1144 | }, 1145 | "engines": { 1146 | "node": ">= 0.4" 1147 | }, 1148 | "funding": { 1149 | "url": "https://github.com/sponsors/ljharb" 1150 | } 1151 | }, 1152 | "node_modules/jju": { 1153 | "version": "1.4.0", 1154 | "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", 1155 | "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", 1156 | "dev": true 1157 | }, 1158 | "node_modules/json-schema-traverse": { 1159 | "version": "0.4.1", 1160 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 1161 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 1162 | "dev": true 1163 | }, 1164 | "node_modules/jsonfile": { 1165 | "version": "4.0.0", 1166 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", 1167 | "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", 1168 | "dev": true, 1169 | "optionalDependencies": { 1170 | "graceful-fs": "^4.1.6" 1171 | } 1172 | }, 1173 | "node_modules/kolorist": { 1174 | "version": "1.8.0", 1175 | "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", 1176 | "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", 1177 | "dev": true 1178 | }, 1179 | "node_modules/lodash": { 1180 | "version": "4.17.21", 1181 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 1182 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 1183 | "dev": true 1184 | }, 1185 | "node_modules/lodash.get": { 1186 | "version": "4.4.2", 1187 | "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", 1188 | "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", 1189 | "dev": true 1190 | }, 1191 | "node_modules/lodash.isequal": { 1192 | "version": "4.5.0", 1193 | "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", 1194 | "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", 1195 | "dev": true 1196 | }, 1197 | "node_modules/lru-cache": { 1198 | "version": "6.0.0", 1199 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 1200 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 1201 | "dev": true, 1202 | "dependencies": { 1203 | "yallist": "^4.0.0" 1204 | }, 1205 | "engines": { 1206 | "node": ">=10" 1207 | } 1208 | }, 1209 | "node_modules/magic-string": { 1210 | "version": "0.30.10", 1211 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", 1212 | "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", 1213 | "dev": true, 1214 | "dependencies": { 1215 | "@jridgewell/sourcemap-codec": "^1.4.15" 1216 | } 1217 | }, 1218 | "node_modules/minimatch": { 1219 | "version": "3.0.8", 1220 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", 1221 | "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", 1222 | "dev": true, 1223 | "dependencies": { 1224 | "brace-expansion": "^1.1.7" 1225 | }, 1226 | "engines": { 1227 | "node": "*" 1228 | } 1229 | }, 1230 | "node_modules/ms": { 1231 | "version": "2.1.2", 1232 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1233 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1234 | "dev": true 1235 | }, 1236 | "node_modules/muggle-string": { 1237 | "version": "0.3.1", 1238 | "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.3.1.tgz", 1239 | "integrity": "sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==", 1240 | "dev": true 1241 | }, 1242 | "node_modules/nanoid": { 1243 | "version": "3.3.7", 1244 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", 1245 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", 1246 | "dev": true, 1247 | "funding": [ 1248 | { 1249 | "type": "github", 1250 | "url": "https://github.com/sponsors/ai" 1251 | } 1252 | ], 1253 | "bin": { 1254 | "nanoid": "bin/nanoid.cjs" 1255 | }, 1256 | "engines": { 1257 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 1258 | } 1259 | }, 1260 | "node_modules/path-browserify": { 1261 | "version": "1.0.1", 1262 | "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", 1263 | "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", 1264 | "dev": true 1265 | }, 1266 | "node_modules/path-parse": { 1267 | "version": "1.0.7", 1268 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 1269 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 1270 | "dev": true 1271 | }, 1272 | "node_modules/picocolors": { 1273 | "version": "1.0.1", 1274 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", 1275 | "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", 1276 | "dev": true 1277 | }, 1278 | "node_modules/picomatch": { 1279 | "version": "2.3.1", 1280 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 1281 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 1282 | "dev": true, 1283 | "engines": { 1284 | "node": ">=8.6" 1285 | }, 1286 | "funding": { 1287 | "url": "https://github.com/sponsors/jonschlinkert" 1288 | } 1289 | }, 1290 | "node_modules/postcss": { 1291 | "version": "8.4.38", 1292 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", 1293 | "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", 1294 | "dev": true, 1295 | "funding": [ 1296 | { 1297 | "type": "opencollective", 1298 | "url": "https://opencollective.com/postcss/" 1299 | }, 1300 | { 1301 | "type": "tidelift", 1302 | "url": "https://tidelift.com/funding/github/npm/postcss" 1303 | }, 1304 | { 1305 | "type": "github", 1306 | "url": "https://github.com/sponsors/ai" 1307 | } 1308 | ], 1309 | "dependencies": { 1310 | "nanoid": "^3.3.7", 1311 | "picocolors": "^1.0.0", 1312 | "source-map-js": "^1.2.0" 1313 | }, 1314 | "engines": { 1315 | "node": "^10 || ^12 || >=14" 1316 | } 1317 | }, 1318 | "node_modules/punycode": { 1319 | "version": "2.3.1", 1320 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 1321 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 1322 | "dev": true, 1323 | "engines": { 1324 | "node": ">=6" 1325 | } 1326 | }, 1327 | "node_modules/resolve": { 1328 | "version": "1.22.8", 1329 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", 1330 | "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", 1331 | "dev": true, 1332 | "dependencies": { 1333 | "is-core-module": "^2.13.0", 1334 | "path-parse": "^1.0.7", 1335 | "supports-preserve-symlinks-flag": "^1.0.0" 1336 | }, 1337 | "bin": { 1338 | "resolve": "bin/resolve" 1339 | }, 1340 | "funding": { 1341 | "url": "https://github.com/sponsors/ljharb" 1342 | } 1343 | }, 1344 | "node_modules/rollup": { 1345 | "version": "4.18.0", 1346 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", 1347 | "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", 1348 | "dev": true, 1349 | "dependencies": { 1350 | "@types/estree": "1.0.5" 1351 | }, 1352 | "bin": { 1353 | "rollup": "dist/bin/rollup" 1354 | }, 1355 | "engines": { 1356 | "node": ">=18.0.0", 1357 | "npm": ">=8.0.0" 1358 | }, 1359 | "optionalDependencies": { 1360 | "@rollup/rollup-android-arm-eabi": "4.18.0", 1361 | "@rollup/rollup-android-arm64": "4.18.0", 1362 | "@rollup/rollup-darwin-arm64": "4.18.0", 1363 | "@rollup/rollup-darwin-x64": "4.18.0", 1364 | "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", 1365 | "@rollup/rollup-linux-arm-musleabihf": "4.18.0", 1366 | "@rollup/rollup-linux-arm64-gnu": "4.18.0", 1367 | "@rollup/rollup-linux-arm64-musl": "4.18.0", 1368 | "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", 1369 | "@rollup/rollup-linux-riscv64-gnu": "4.18.0", 1370 | "@rollup/rollup-linux-s390x-gnu": "4.18.0", 1371 | "@rollup/rollup-linux-x64-gnu": "4.18.0", 1372 | "@rollup/rollup-linux-x64-musl": "4.18.0", 1373 | "@rollup/rollup-win32-arm64-msvc": "4.18.0", 1374 | "@rollup/rollup-win32-ia32-msvc": "4.18.0", 1375 | "@rollup/rollup-win32-x64-msvc": "4.18.0", 1376 | "fsevents": "~2.3.2" 1377 | } 1378 | }, 1379 | "node_modules/semver": { 1380 | "version": "7.5.4", 1381 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", 1382 | "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", 1383 | "dev": true, 1384 | "dependencies": { 1385 | "lru-cache": "^6.0.0" 1386 | }, 1387 | "bin": { 1388 | "semver": "bin/semver.js" 1389 | }, 1390 | "engines": { 1391 | "node": ">=10" 1392 | } 1393 | }, 1394 | "node_modules/source-map": { 1395 | "version": "0.6.1", 1396 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 1397 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 1398 | "dev": true, 1399 | "engines": { 1400 | "node": ">=0.10.0" 1401 | } 1402 | }, 1403 | "node_modules/source-map-js": { 1404 | "version": "1.2.0", 1405 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", 1406 | "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", 1407 | "dev": true, 1408 | "engines": { 1409 | "node": ">=0.10.0" 1410 | } 1411 | }, 1412 | "node_modules/sprintf-js": { 1413 | "version": "1.0.3", 1414 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 1415 | "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", 1416 | "dev": true 1417 | }, 1418 | "node_modules/string-argv": { 1419 | "version": "0.3.2", 1420 | "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", 1421 | "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", 1422 | "dev": true, 1423 | "engines": { 1424 | "node": ">=0.6.19" 1425 | } 1426 | }, 1427 | "node_modules/strip-json-comments": { 1428 | "version": "3.1.1", 1429 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 1430 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 1431 | "dev": true, 1432 | "engines": { 1433 | "node": ">=8" 1434 | }, 1435 | "funding": { 1436 | "url": "https://github.com/sponsors/sindresorhus" 1437 | } 1438 | }, 1439 | "node_modules/supports-color": { 1440 | "version": "8.1.1", 1441 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", 1442 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", 1443 | "dev": true, 1444 | "dependencies": { 1445 | "has-flag": "^4.0.0" 1446 | }, 1447 | "engines": { 1448 | "node": ">=10" 1449 | }, 1450 | "funding": { 1451 | "url": "https://github.com/chalk/supports-color?sponsor=1" 1452 | } 1453 | }, 1454 | "node_modules/supports-preserve-symlinks-flag": { 1455 | "version": "1.0.0", 1456 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 1457 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 1458 | "dev": true, 1459 | "engines": { 1460 | "node": ">= 0.4" 1461 | }, 1462 | "funding": { 1463 | "url": "https://github.com/sponsors/ljharb" 1464 | } 1465 | }, 1466 | "node_modules/typescript": { 1467 | "version": "5.5.2", 1468 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", 1469 | "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", 1470 | "dev": true, 1471 | "bin": { 1472 | "tsc": "bin/tsc", 1473 | "tsserver": "bin/tsserver" 1474 | }, 1475 | "engines": { 1476 | "node": ">=14.17" 1477 | } 1478 | }, 1479 | "node_modules/undici-types": { 1480 | "version": "5.26.5", 1481 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 1482 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", 1483 | "dev": true 1484 | }, 1485 | "node_modules/universalify": { 1486 | "version": "0.1.2", 1487 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", 1488 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", 1489 | "dev": true, 1490 | "engines": { 1491 | "node": ">= 4.0.0" 1492 | } 1493 | }, 1494 | "node_modules/uri-js": { 1495 | "version": "4.4.1", 1496 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 1497 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 1498 | "dev": true, 1499 | "dependencies": { 1500 | "punycode": "^2.1.0" 1501 | } 1502 | }, 1503 | "node_modules/validator": { 1504 | "version": "13.12.0", 1505 | "resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz", 1506 | "integrity": "sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==", 1507 | "dev": true, 1508 | "engines": { 1509 | "node": ">= 0.10" 1510 | } 1511 | }, 1512 | "node_modules/vite": { 1513 | "version": "5.3.2", 1514 | "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz", 1515 | "integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==", 1516 | "dev": true, 1517 | "dependencies": { 1518 | "esbuild": "^0.21.3", 1519 | "postcss": "^8.4.38", 1520 | "rollup": "^4.13.0" 1521 | }, 1522 | "bin": { 1523 | "vite": "bin/vite.js" 1524 | }, 1525 | "engines": { 1526 | "node": "^18.0.0 || >=20.0.0" 1527 | }, 1528 | "funding": { 1529 | "url": "https://github.com/vitejs/vite?sponsor=1" 1530 | }, 1531 | "optionalDependencies": { 1532 | "fsevents": "~2.3.3" 1533 | }, 1534 | "peerDependencies": { 1535 | "@types/node": "^18.0.0 || >=20.0.0", 1536 | "less": "*", 1537 | "lightningcss": "^1.21.0", 1538 | "sass": "*", 1539 | "stylus": "*", 1540 | "sugarss": "*", 1541 | "terser": "^5.4.0" 1542 | }, 1543 | "peerDependenciesMeta": { 1544 | "@types/node": { 1545 | "optional": true 1546 | }, 1547 | "less": { 1548 | "optional": true 1549 | }, 1550 | "lightningcss": { 1551 | "optional": true 1552 | }, 1553 | "sass": { 1554 | "optional": true 1555 | }, 1556 | "stylus": { 1557 | "optional": true 1558 | }, 1559 | "sugarss": { 1560 | "optional": true 1561 | }, 1562 | "terser": { 1563 | "optional": true 1564 | } 1565 | } 1566 | }, 1567 | "node_modules/vite-plugin-dts": { 1568 | "version": "3.9.1", 1569 | "resolved": "https://registry.npmjs.org/vite-plugin-dts/-/vite-plugin-dts-3.9.1.tgz", 1570 | "integrity": "sha512-rVp2KM9Ue22NGWB8dNtWEr+KekN3rIgz1tWD050QnRGlriUCmaDwa7qA5zDEjbXg5lAXhYMSBJtx3q3hQIJZSg==", 1571 | "dev": true, 1572 | "dependencies": { 1573 | "@microsoft/api-extractor": "7.43.0", 1574 | "@rollup/pluginutils": "^5.1.0", 1575 | "@vue/language-core": "^1.8.27", 1576 | "debug": "^4.3.4", 1577 | "kolorist": "^1.8.0", 1578 | "magic-string": "^0.30.8", 1579 | "vue-tsc": "^1.8.27" 1580 | }, 1581 | "engines": { 1582 | "node": "^14.18.0 || >=16.0.0" 1583 | }, 1584 | "peerDependencies": { 1585 | "typescript": "*", 1586 | "vite": "*" 1587 | }, 1588 | "peerDependenciesMeta": { 1589 | "vite": { 1590 | "optional": true 1591 | } 1592 | } 1593 | }, 1594 | "node_modules/vue-template-compiler": { 1595 | "version": "2.7.16", 1596 | "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", 1597 | "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==", 1598 | "dev": true, 1599 | "dependencies": { 1600 | "de-indent": "^1.0.2", 1601 | "he": "^1.2.0" 1602 | } 1603 | }, 1604 | "node_modules/vue-tsc": { 1605 | "version": "1.8.27", 1606 | "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.8.27.tgz", 1607 | "integrity": "sha512-WesKCAZCRAbmmhuGl3+VrdWItEvfoFIPXOvUJkjULi+x+6G/Dy69yO3TBRJDr9eUlmsNAwVmxsNZxvHKzbkKdg==", 1608 | "dev": true, 1609 | "dependencies": { 1610 | "@volar/typescript": "~1.11.1", 1611 | "@vue/language-core": "1.8.27", 1612 | "semver": "^7.5.4" 1613 | }, 1614 | "bin": { 1615 | "vue-tsc": "bin/vue-tsc.js" 1616 | }, 1617 | "peerDependencies": { 1618 | "typescript": "*" 1619 | } 1620 | }, 1621 | "node_modules/yallist": { 1622 | "version": "4.0.0", 1623 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 1624 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", 1625 | "dev": true 1626 | }, 1627 | "node_modules/z-schema": { 1628 | "version": "5.0.5", 1629 | "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz", 1630 | "integrity": "sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==", 1631 | "dev": true, 1632 | "dependencies": { 1633 | "lodash.get": "^4.4.2", 1634 | "lodash.isequal": "^4.5.0", 1635 | "validator": "^13.7.0" 1636 | }, 1637 | "bin": { 1638 | "z-schema": "bin/z-schema" 1639 | }, 1640 | "engines": { 1641 | "node": ">=8.0.0" 1642 | }, 1643 | "optionalDependencies": { 1644 | "commander": "^9.4.1" 1645 | } 1646 | } 1647 | } 1648 | } 1649 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zoom-any-js", 3 | "description": "ZoomAny.js: Zoom ANY HTML Element using vanilla JavaScript. Also optionally supports TypeScript", 4 | "private": false, 5 | "author": "Ben Herbst", 6 | "version": "1.0.5", 7 | "type": "module", 8 | "main": "dist/zoom-any-js.umd.cjs", 9 | "module": "dist/zoom-any-js.js", 10 | "types": "dist/zoom-any-js.d.ts", 11 | "style": "dist/zoom-any-js.css", 12 | "license": "Apache-2.0", 13 | "scripts": { 14 | "dev": "vite", 15 | "build": "tsc && vite build", 16 | "preview": "vite preview" 17 | }, 18 | "publishConfig": { 19 | "access": "public" 20 | }, 21 | "files": [ 22 | "/dist" 23 | ], 24 | "devDependencies": { 25 | "@types/node": "^20.14.9", 26 | "typescript": "^5.2.2", 27 | "vite": "^5.3.1", 28 | "vite-plugin-dts": "^3.9.1" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/zoom-any-js.css: -------------------------------------------------------------------------------- 1 | .zoomAnyJs-zoomElement { 2 | position: relative; 3 | transform-origin: top left; 4 | } 5 | 6 | .wrapper { 7 | position: relative; 8 | display: inline-block; 9 | overflow: hidden; 10 | } -------------------------------------------------------------------------------- /src/zoom-any-js.ts: -------------------------------------------------------------------------------- 1 | interface IPosition { 2 | x: number, 3 | y: number 4 | } 5 | 6 | import "./zoom-any-js.css" 7 | 8 | export default class ZoomAnyJs { 9 | // @ts-ignore 10 | #element: HTMLElement; 11 | #values = { 12 | x: 0, 13 | y: 0, 14 | zoom: 100 15 | } 16 | #onWheelListener; 17 | 18 | /** 19 | * Selects the DOM element to be manipulated using the provided selector. 20 | * If no selector is provided, it defaults to ".zoomable". 21 | * Adds event listeners to the selected element, including the wheel event listener for zooming. 22 | * Adjusts the element's position to fit within its bounds when data-binds enabled. 23 | * 24 | * @param {string} [elementSelector='.zoomable'] - The CSS selector for the element to zoom. Defaults to ".zoomable". 25 | */ 26 | constructor(elementSelector: string = '.zoomable') { 27 | this.#selectElement(elementSelector) 28 | this.#onWheelListener = this.#onWheel.bind(this) 29 | this.addListeners() 30 | 31 | window.onload = (() => { 32 | this.fitToBounds() 33 | this.apply() 34 | }) 35 | 36 | } 37 | 38 | /** 39 | * Selects a DOM element based on the given CSS selector. 40 | * If the element is found, it assigns it to the `#element` property 41 | * and adds a specific class for further manipulations. 42 | * Throws an error if the element is not found. 43 | * 44 | * @param {string} elementSelector - The CSS selector of the element to select. 45 | * @throws {Error} If no element matching the selector is found. 46 | * @private 47 | */ 48 | #selectElement(elementSelector: string) { 49 | const queried = document.querySelector(elementSelector) 50 | if (queried === null) throw new Error("Zoom element not found") 51 | this.#element = queried as HTMLElement 52 | this.#element.classList.add("zoomAnyJs-zoomElement") 53 | } 54 | 55 | /** 56 | * Resets the internal values of the zoom element to their default state. 57 | * This includes setting the x and y coordinates to 0 and the zoom level to 100. 58 | */ 59 | reset() { 60 | this.#values = { 61 | x: 0, 62 | y: 0, 63 | zoom: 100 64 | } 65 | } 66 | 67 | /** 68 | * Retrieves the current zoom level of the element. 69 | * 70 | * @returns {number} The current zoom level. 71 | */ 72 | getZoom(): number { 73 | return this.#values.zoom 74 | } 75 | 76 | /** 77 | * Sets the current zoom level of the element. 78 | * 79 | * @param {number} value - The value the zoom level is set to. 80 | */ 81 | setZoom(value: number) { 82 | this.#values.zoom = value 83 | } 84 | 85 | /** 86 | * Sets the position values (x and y coordinates) for the element. 87 | * 88 | * @param {IPosition} value - An object containing the x and y coordinates to set. 89 | */ 90 | setPos(value: IPosition) { 91 | this.#values.x = value.x 92 | this.#values.y = value.y 93 | } 94 | 95 | /** 96 | * Retrieves the current position values (x and y coordinates) of the element. 97 | * 98 | * @returns {IPosition} An object containing the current x and y coordinates. 99 | */ 100 | getPos(): IPosition { 101 | return { 102 | x: this.#values.x, 103 | y: this.#values.y 104 | } 105 | } 106 | 107 | /** 108 | * Determines if the origin is the parent or the window based on the data-origin-parent attribute 109 | * 110 | * @private 111 | * @returns {string} Returns 'parent' if the element has the attribute 'data-origin-parent', otherwise 'window'. 112 | */ 113 | #getMode() { 114 | return this.#element.hasAttribute("data-origin-parent") ? 'parent' : 'window' 115 | } 116 | 117 | /** 118 | * Centers the element within its container. 119 | * The container can either be the window or the element's parent, depending on data-origin-parent. 120 | */ 121 | center() { 122 | const mode = this.#getMode() 123 | const rect = this.#element.getBoundingClientRect() 124 | 125 | let width, height; 126 | 127 | if (mode === 'window') { 128 | width = window.innerWidth 129 | height = window.innerHeight 130 | } else { 131 | const parentRect = this.#getParentRect() 132 | 133 | width = parentRect.width 134 | height = parentRect.height 135 | } 136 | 137 | this.#values.x = width / 2 - rect.width / 2 138 | this.#values.y = height / 2 - rect.height / 2 139 | } 140 | 141 | /** 142 | * Retrieves the offset parent of the element. 143 | * 144 | * @private 145 | * @returns {Element | null} The offset parent of the element, or null if there is none. 146 | */ 147 | #getParent() { 148 | return this.#element.offsetParent 149 | } 150 | 151 | /** 152 | * Retrieves the bounding rectangle of the element. 153 | * 154 | * @private 155 | * @returns {DOMRect} The bounding rectangle of the element, providing information about its size and position relative to the viewport. 156 | */ 157 | #getElementRect() { 158 | return this.#element.getBoundingClientRect() 159 | } 160 | 161 | /** 162 | * Retrieves the bounding rectangle of the element's offset parent. 163 | * 164 | * @private 165 | * @returns {DOMRect} The bounding rectangle of the offset parent, providing information about its size and position relative to the viewport. 166 | */ 167 | #getParentRect() { 168 | return this.#getParent()!.getBoundingClientRect() 169 | } 170 | 171 | /** 172 | * Adjusts the position of the element to fit within its bounds. 173 | * The bounds are determined based on the element's data-origin and the presence of the `data-bounds` attribute. 174 | * 175 | * If the `data-bounds` attribute is present, the method checks whether the element fits within the 176 | * specified bounds (window or parent). If not, it adjusts the position so that the element is 177 | * visible within the bounds. 178 | * 179 | * The adjustment logic is as follows: 180 | * - If the element is smaller than the available space, it is centered within the bounds. 181 | * - If the element overflows in either dimension (x or y), its position is adjusted to fit within 182 | * the available space, with the option of setting its position to zero if it is already out of bounds. 183 | */ 184 | fitToBounds() { 185 | const mode = this.#getMode() 186 | 187 | if (!this.#element.hasAttribute("data-bounds")) return; 188 | 189 | const rect = this.#element.getBoundingClientRect() 190 | 191 | const checkBounds = (originWidth: number, originHeight: number, cb: (key: 'x' | 'y') => void) => { 192 | const smallerWidth = rect.width >= originWidth 193 | const smallerHeight = rect.height >= originHeight 194 | 195 | if (!smallerWidth && !smallerHeight) this.center() 196 | 197 | if (smallerWidth) { 198 | cb('x') 199 | } 200 | 201 | if (smallerHeight) { 202 | cb('y') 203 | } 204 | } 205 | 206 | if (mode === "window") checkBounds(window.innerWidth, window.innerHeight, (key) => { 207 | if (rect[key === 'x' ? 'left' : 'top'] > 0) this.#values[key] = 0; 208 | 209 | const windowSize = window[key === 'x' ? 'innerWidth' : 'innerHeight'] 210 | const newRectSize = rect[key === 'x' ? 'right' : 'bottom'] 211 | 212 | if (windowSize > newRectSize) this.#values[key] += windowSize - newRectSize 213 | }) 214 | 215 | if (mode === "parent") { 216 | const originRect = this.#getParentRect() 217 | 218 | checkBounds(originRect.width, originRect.height, (key) => { 219 | const difference = (originRect[key] + originRect[key === "x" ? 'width' : 'height']) - (rect[key === 'x' ? 'left' : 'top'] + rect[key === 'x' ? 'width' : 'height']) 220 | if (this.#element[key === 'x' ? 'offsetLeft' : 'offsetTop'] > 0) this.#values[key] = 0; 221 | if (difference > 0) this.#values[key] += difference 222 | }) 223 | } 224 | } 225 | 226 | /** 227 | * Zooms the element based on the given amplitude and position. 228 | * The zoom effect scales the element's size and adjusts its position to zoom in or out 229 | * relative to a specified point (pos). Zoom levels are constrained within the minimum and 230 | * maximum zoom limits defined in the element's dataset (data-min-zoom and data-max-zoom). 231 | * 232 | * @param {number} amplitude - The zoom factor. Values greater than 1 zoom in, while values less than 1 zoom out. 233 | * @param {{ x: number, y: number }} pos - The position (x, y) to zoom towards. 234 | */ 235 | zoomAt(amplitude: number, pos: { 236 | x: number, 237 | y: number 238 | }) { 239 | const maxZoom: number = parseInt(this.#element.dataset.maxZoom || "4000") 240 | const minZoom: number = parseInt(this.#element.dataset.minZoom || "10") 241 | 242 | if (amplitude < 1 && this.#values.zoom * amplitude <= minZoom) return; 243 | if (amplitude > 1 && this.#values.zoom * amplitude >= maxZoom) return; 244 | 245 | const rect = this.#getElementRect() 246 | 247 | this.#values.x = (pos.x - (rect.left - this.#values.x)) - (pos.x - rect.left) * amplitude 248 | this.#values.y = (pos.y - (rect.top - this.#values.y)) - (pos.y - rect.top) * amplitude 249 | this.#values.zoom *= amplitude 250 | } 251 | 252 | /** 253 | * Handles the zoom in response to a wheel event. 254 | * 255 | * When the user scrolls up (i.e., `event.deltaY < 1`), the zoom level increases. 256 | * When the user scrolls down (i.e., `event.deltaY > 1`), the zoom level decreases. 257 | * 258 | * The zoom is applied relative to the mouse pointer position. 259 | * 260 | * @param {WheelEvent} event - The wheel event containing scroll data and the pointer position. 261 | * @private 262 | */ 263 | #onWheel(event: WheelEvent) { 264 | event.preventDefault() 265 | 266 | let amplitude = 0 267 | 268 | if (event.deltaY < 1) { 269 | amplitude = 1.1 270 | } 271 | 272 | if (event.deltaY > 1) { 273 | amplitude = 1 / 1.1 274 | } 275 | 276 | this.zoomAt( 277 | amplitude, { 278 | x: event.pageX, 279 | y: event.pageY 280 | } 281 | ) 282 | this.apply() 283 | this.fitToBounds() 284 | this.apply() 285 | } 286 | 287 | /** 288 | * Adds event listeners to the element for handling user interactions. 289 | * Specifically, it adds a wheel event listener to manage zooming functionality. 290 | */ 291 | addListeners() { 292 | this.#element.addEventListener("wheel", this.#onWheelListener) 293 | } 294 | 295 | /** 296 | * Removes event listeners from the element to stop handling user interactions. 297 | * Specifically, it removes the wheel event listener that manages zooming functionality. 298 | */ 299 | removeListeners() { 300 | this.#element.removeEventListener("wheel", this.#onWheelListener) 301 | } 302 | 303 | /** 304 | * Applies the current transformation and position values to the element. 305 | * Has to be called everytime you want to apply changes to the element, e.g. after zoomAt() 306 | */ 307 | apply() { 308 | this.#element.style.transform = `scale(${this.#values.zoom / 100})`; 309 | this.#element.style.left = `${this.#values.x}px` 310 | this.#element.style.top = `${this.#values.y}px` 311 | } 312 | 313 | /** 314 | * Removes all listeners and css changes, basically reverting the element back to before using the plugin 315 | */ 316 | destroy() { 317 | this.#element.style.transform = ""; 318 | this.#element.style.left = ""; 319 | this.#element.style.right = ""; 320 | this.#element.classList.remove("zoomAnyJs-zoomElement") 321 | this.removeListeners() 322 | } 323 | } -------------------------------------------------------------------------------- /test/img/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BenHerbst/zoom-any-js/a2db2522d60281dbda6ea6b44cee2ab3cd15adca/test/img/1.png -------------------------------------------------------------------------------- /test/img/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BenHerbst/zoom-any-js/a2db2522d60281dbda6ea6b44cee2ab3cd15adca/test/img/2.png -------------------------------------------------------------------------------- /test/img/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BenHerbst/zoom-any-js/a2db2522d60281dbda6ea6b44cee2ab3cd15adca/test/img/3.png -------------------------------------------------------------------------------- /test/test.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | height: 100vh; 3 | width: 100vw; 4 | padding: 0; 5 | margin: 0; 6 | } -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | import ZoomAnyJs from "../src/zoom-any-js.ts"; 2 | 3 | // const zoom = new ZoomAnyJs() 4 | const zoom2 = new ZoomAnyJs() 5 | 6 | document.getElementById("myButton").addEventListener("click", () => { 7 | zoom2.center() 8 | zoom2.apply() 9 | }) -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "moduleDetection": "force", 15 | "noEmit": true, 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true 22 | }, 23 | "include": ["src"] 24 | } 25 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | // vite.config.js 2 | import { resolve } from 'path' 3 | import { defineConfig } from 'vite' 4 | import dts from 'vite-plugin-dts' 5 | 6 | export default defineConfig({ 7 | server: { 8 | host: '0.0.0.0' 9 | }, 10 | build: { 11 | lib: { 12 | // Could also be a dictionary or array of multiple entry points 13 | entry: resolve(__dirname, 'src/zoom-any-js.ts'), 14 | name: 'zoom-any-js', 15 | // the proper extensions will be added 16 | fileName: 'zoom-any-js', 17 | }, 18 | rollupOptions: { 19 | // make sure to externalize deps that shouldn't be bundled 20 | // into your library 21 | external: [], 22 | output: { 23 | // Provide global variables to use in the UMD build 24 | // for externalized deps 25 | globals: {}, 26 | assetFileNames: (assetInfo) => { 27 | if(assetInfo.name == 'style.css') 28 | return 'zoom-any-js.css' 29 | return assetInfo.name 30 | } 31 | }, 32 | }, 33 | }, 34 | plugins: [dts()] 35 | }) --------------------------------------------------------------------------------