senangwebs-photobooth 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/swp.css ADDED
@@ -0,0 +1,448 @@
1
+ @import url(https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css);
2
+ /**
3
+ * SenangWebs Photobooth (SWP) - Styles
4
+ * @version 1.0.0
5
+ */
6
+
7
+ /* Font Awesome */
8
+
9
+ /* Container */
10
+ .swp-container {
11
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
12
+ max-width: 1200px;
13
+ box-sizing: border-box;
14
+ }
15
+
16
+ .swp-wrapper {
17
+ background: #ffffff;
18
+ overflow: hidden;
19
+ height: 100%;
20
+ display: flex;
21
+ flex-direction: column;
22
+ }
23
+
24
+ /* Toolbar */
25
+ .swp-toolbar {
26
+ display: flex;
27
+ gap: 8px;
28
+ padding: 8px;
29
+ background: #f8f9fa;
30
+ flex-wrap: wrap;
31
+ justify-content: space-between;
32
+ }
33
+
34
+ .swp-toolbar-group {
35
+ display: flex;
36
+ gap: 0px;
37
+ align-items: center;
38
+ border: 1px solid #dee2e6;
39
+ border-radius: 8px;
40
+ overflow: hidden;
41
+ }
42
+
43
+ .swp-toolbar-group .swp-btn {
44
+ display: flex;
45
+ flex-direction: column;
46
+ gap: 0px;
47
+ height: 48px;
48
+ width: 80px;
49
+ min-width: 48px;
50
+ align-items: center;
51
+ justify-content: center;
52
+ border-radius: 0px;
53
+ border: none;
54
+ padding: 0px;
55
+ }
56
+
57
+ .swp-toolbar-group .swp-btn span {
58
+ font-size: 12px;
59
+ }
60
+
61
+ .swp-btn {
62
+ display: flex;
63
+ align-items: center;
64
+ justify-content: center;
65
+ gap: 8px;
66
+ padding: 0px 12px;
67
+ border: 1px solid #dee2e6;
68
+ background: #ffffff;
69
+ border-radius: 6px;
70
+ cursor: pointer;
71
+ font-size: 14px;
72
+ color: #495057;
73
+ transition: all 0.2s ease;
74
+ font-family: inherit;
75
+ height: 40px;
76
+ }
77
+
78
+ .swp-btn:hover {
79
+ background: #e9ecef;
80
+ border-color: #adb5bd;
81
+ }
82
+
83
+ .swp-btn:active {
84
+ transform: scale(0.98);
85
+ }
86
+
87
+ .swp-btn-primary {
88
+ background: #007bff;
89
+ color: white;
90
+ border-color: #007bff;
91
+ }
92
+
93
+ .swp-btn-primary:hover {
94
+ background: #0056b3;
95
+ border-color: #0056b3;
96
+ }
97
+
98
+ .swp-btn-icon-only {
99
+ padding: 0px 12px;
100
+ justify-content: center;
101
+ align-items: center;
102
+ aspect-ratio: 1 / 1;
103
+ max-width: 40px;
104
+ }
105
+
106
+ .swp-icon {
107
+ font-size: 18px;
108
+ }
109
+
110
+ .swp-layout-container {
111
+ display: flex;
112
+ flex-grow: 1;
113
+ }
114
+
115
+ .swp-control-container {
116
+ min-width: 348px;
117
+ background: #f8f9fa;
118
+ padding: 8px 16px;
119
+ }
120
+
121
+ .swp-control-container.hidden {
122
+ display: block;
123
+ }
124
+
125
+ /* Canvas Container */
126
+ .swp-canvas-container {
127
+ position: relative;
128
+ display: flex;
129
+ align-items: center;
130
+ justify-content: center;
131
+ min-height: 400px;
132
+ padding: 8px;
133
+ border-top: 1px solid #dee2e6;
134
+ border-right: 1px solid #dee2e6;
135
+ border-top-right-radius: 8px;
136
+ flex-grow: 1;
137
+ min-width: 452px;;
138
+ }
139
+
140
+ .swp-canvas {
141
+ max-width: 100%;
142
+ height: auto;
143
+ background: white;
144
+ }
145
+
146
+ /* Adjustments Panel */
147
+ .swp-adjustments-panel,
148
+ .swp-filters-panel,
149
+ .swp-resize-panel {
150
+ display: none;
151
+ }
152
+
153
+ .swp-adjustments-panel.active,
154
+ .swp-filters-panel.active,
155
+ .swp-resize-panel.active {
156
+ display: block;
157
+ }
158
+
159
+ .swp-adjustments-panel h3,
160
+ .swp-filters-panel h3,
161
+ .swp-resize-panel h3 {
162
+ margin: 0 0 15px 0;
163
+ font-size: 16px;
164
+ font-weight: 600;
165
+ color: #212529;
166
+ }
167
+
168
+ .swp-adjustment {
169
+ display: flex;
170
+ align-items: center;
171
+ gap: 12px;
172
+ margin-bottom: 15px;
173
+ width: 100%;
174
+ }
175
+
176
+ .swp-adjustment label {
177
+ min-width: 100px;
178
+ font-size: 14px;
179
+ color: #495057;
180
+ font-weight: 500;
181
+ }
182
+
183
+ .swp-adjustment input[type="range"] {
184
+ flex: 1;
185
+ flex-shrink: 1;
186
+ height: 6px;
187
+ border-radius: 3px;
188
+ background: #e9ecef;
189
+ outline: none;
190
+ -webkit-appearance: none;
191
+ }
192
+
193
+ .swp-adjustment input[type="range"]::-webkit-slider-thumb {
194
+ -webkit-appearance: none;
195
+ appearance: none;
196
+ width: 18px;
197
+ height: 18px;
198
+ border-radius: 50%;
199
+ background: #007bff;
200
+ cursor: pointer;
201
+ transition: all 0.2s ease;
202
+ }
203
+
204
+ .swp-adjustment input[type="range"]::-webkit-slider-thumb:hover {
205
+ background: #0056b3;
206
+ transform: scale(1.1);
207
+ }
208
+
209
+ .swp-adjustment input[type="range"]::-moz-range-thumb {
210
+ width: 18px;
211
+ height: 18px;
212
+ border-radius: 50%;
213
+ background: #007bff;
214
+ cursor: pointer;
215
+ border: none;
216
+ transition: all 0.2s ease;
217
+ }
218
+
219
+ .swp-adjustment input[type="range"]::-moz-range-thumb:hover {
220
+ background: #0056b3;
221
+ transform: scale(1.1);
222
+ }
223
+
224
+ .swp-value {
225
+ text-align: right;
226
+ font-size: 14px;
227
+ color: #6c757d;
228
+ font-weight: 500;
229
+ }
230
+
231
+ /* Resize Panel */
232
+ .swp-resize-controls {
233
+ display: flex;
234
+ flex-direction: column;
235
+ gap: 15px;
236
+ }
237
+
238
+ .swp-resize-controls .swp-adjustment {
239
+ display: flex;
240
+ align-items: center;
241
+ gap: 10px;
242
+ }
243
+
244
+ .swp-resize-controls input[type="number"] {
245
+ flex: 1;
246
+ padding: 8px 12px;
247
+ border: 1px solid #dee2e6;
248
+ border-radius: 6px;
249
+ font-size: 14px;
250
+ color: #495057;
251
+ }
252
+
253
+ .swp-resize-controls input[type="number"]:focus {
254
+ outline: none;
255
+ border-color: #007bff;
256
+ }
257
+
258
+ .swp-resize-controls input[type="checkbox"] {
259
+ width: 18px;
260
+ height: 18px;
261
+ cursor: pointer;
262
+ }
263
+
264
+ .swp-resize-controls label {
265
+ display: flex;
266
+ align-items: center;
267
+ gap: 8px;
268
+ cursor: pointer;
269
+ font-size: 14px;
270
+ color: #495057;
271
+ }
272
+
273
+ .swp-resize-controls button {
274
+ margin-top: 10px;
275
+ }
276
+
277
+
278
+ /* Filters Panel */
279
+ .swp-filters-grid {
280
+ display: grid;
281
+ grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
282
+ gap: 15px;
283
+ }
284
+
285
+ .swp-filter-btn {
286
+ display: flex;
287
+ flex-direction: column;
288
+ align-items: center;
289
+ gap: 8px;
290
+ padding: 12px;
291
+ border: 2px solid #dee2e6;
292
+ background: #ffffff;
293
+ border-radius: 8px;
294
+ cursor: pointer;
295
+ font-size: 13px;
296
+ color: #495057;
297
+ transition: all 0.2s ease;
298
+ font-family: inherit;
299
+ }
300
+
301
+ .swp-filter-btn:hover {
302
+ border-color: #007bff;
303
+ background: #f8f9fa;
304
+ }
305
+
306
+ .swp-filter-btn.active {
307
+ border-color: #007bff;
308
+ background: #e7f3ff;
309
+ color: #007bff;
310
+ font-weight: 600;
311
+ }
312
+
313
+ .swp-filter-preview {
314
+ width: 60px;
315
+ height: 60px;
316
+ border-radius: 6px;
317
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
318
+ display: block;
319
+ }
320
+
321
+ .swp-filter-preview[data-filter="grayscale"] {
322
+ filter: grayscale(100%);
323
+ }
324
+
325
+ .swp-filter-preview[data-filter="sepia"] {
326
+ filter: sepia(100%);
327
+ }
328
+
329
+ .swp-filter-preview[data-filter="invert"] {
330
+ filter: invert(100%);
331
+ }
332
+
333
+ .swp-filter-preview[data-filter="blur"] {
334
+ filter: blur(3px);
335
+ }
336
+
337
+ .swp-filter-preview[data-filter="none"] {
338
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
339
+ }
340
+
341
+ /* Responsive Design */
342
+ @media (max-width: 768px) {
343
+ .swp-toolbar {
344
+ padding: 10px;
345
+ gap: 5px;
346
+ }
347
+
348
+ .swp-toolbar-group {
349
+ gap: 5px;
350
+ }
351
+
352
+ .swp-btn {
353
+ padding: 6px 12px;
354
+ font-size: 12px;
355
+ }
356
+
357
+ .swp-btn span:not(.swp-icon) {
358
+ display: none;
359
+ }
360
+
361
+ .swp-canvas-container {
362
+ min-height: 300px;
363
+ padding: 10px;
364
+ }
365
+
366
+ .swp-adjustments-panel,
367
+ .swp-filters-panel {
368
+ padding: 15px;
369
+ }
370
+
371
+ .swp-adjustment {
372
+ flex-wrap: wrap;
373
+ }
374
+
375
+ .swp-adjustment label {
376
+ min-width: 100%;
377
+ }
378
+
379
+ .swp-filters-grid {
380
+ grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
381
+ gap: 10px;
382
+ }
383
+
384
+ .swp-filter-preview {
385
+ width: 50px;
386
+ height: 50px;
387
+ }
388
+ }
389
+
390
+ /* Loading State */
391
+ .swp-loading {
392
+ position: absolute;
393
+ top: 50%;
394
+ left: 50%;
395
+ transform: translate(-50%, -50%);
396
+ font-size: 14px;
397
+ color: #6c757d;
398
+ }
399
+
400
+ /* Empty State */
401
+ .swp-empty-state {
402
+ text-align: center;
403
+ padding: 60px 20px;
404
+ color: #6c757d;
405
+ }
406
+
407
+ .swp-empty-state-icon {
408
+ font-size: 48px;
409
+ margin-bottom: 15px;
410
+ opacity: 0.5;
411
+ }
412
+
413
+ .swp-empty-state-text {
414
+ font-size: 16px;
415
+ margin-bottom: 20px;
416
+ }
417
+
418
+ /* Animations */
419
+ @keyframes fadeIn {
420
+ from {
421
+ opacity: 0;
422
+ transform: translateY(-10px);
423
+ }
424
+ to {
425
+ opacity: 1;
426
+ transform: translateY(0);
427
+ }
428
+ }
429
+
430
+ .swp-adjustments-panel.active,
431
+ .swp-filters-panel.active {
432
+ animation: fadeIn 0.3s ease;
433
+ }
434
+
435
+ /* Print Styles */
436
+ @media print {
437
+ .swp-toolbar,
438
+ .swp-adjustments-panel,
439
+ .swp-filters-panel {
440
+ display: none;
441
+ }
442
+
443
+ .swp-canvas-container {
444
+ padding: 0;
445
+ background: transparent;
446
+ }
447
+ }
448
+
package/dist/swp.js ADDED
@@ -0,0 +1 @@
1
+ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.SWP=t():e.SWP=t()}(this,()=>(()=>{"use strict";var e={d:(t,a)=>{for(var s in a)e.o(a,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:a[s]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{default:()=>s});class a{constructor(e,t={}){this.container=e,this.options={imageUrl:t.imageUrl||null,width:t.width||800,height:t.height||600,showIcons:void 0===t.showIcons||t.showIcons,showLabels:void 0===t.showLabels||t.showLabels,labels:{upload:void 0!==t.labels?.upload?t.labels.upload:"Upload",rotateLeft:void 0!==t.labels?.rotateLeft?t.labels.rotateLeft:null,rotateRight:void 0!==t.labels?.rotateRight?t.labels.rotateRight:null,flipH:void 0!==t.labels?.flipH?t.labels.flipH:null,flipV:void 0!==t.labels?.flipV?t.labels.flipV:null,resize:void 0!==t.labels?.resize?t.labels.resize:"Resize",adjust:void 0!==t.labels?.adjust?t.labels.adjust:"Adjust",filters:void 0!==t.labels?.filters?t.labels.filters:"Filters",reset:void 0!==t.labels?.reset?t.labels.reset:"Reset",save:void 0!==t.labels?.save?t.labels.save:"Save"}},this.canvas=null,this.ctx=null,this.originalImage=null,this.currentImage=null,this.history=[],this.currentState={brightness:100,contrast:100,saturation:100,rotation:0,flipH:!1,flipV:!1,filter:"none"},this.eventListeners={},this.init()}init(){this.createUI(),this.options.imageUrl&&this.loadImage(this.options.imageUrl)}createUI(){this.container.innerHTML="",this.container.classList.add("swp-container");const e=document.createElement("div");e.className="swp-wrapper";const t=document.createElement("div");t.className="swp-toolbar",t.innerHTML=this.createToolbarHTML();const a=document.createElement("div");a.className="swp-layout-container";const s=document.createElement("div");s.className="swp-control-container";const n=document.createElement("div");n.className="swp-canvas-container",this.canvas=document.createElement("canvas"),this.canvas.width=this.options.width,this.canvas.height=this.options.height,this.canvas.className="swp-canvas",this.ctx=this.canvas.getContext("2d"),n.appendChild(this.canvas);const i=document.createElement("div");i.className="swp-adjustments-panel",i.innerHTML=this.createAdjustmentsPanelHTML();const r=document.createElement("div");r.className="swp-filters-panel",r.innerHTML=this.createFiltersPanelHTML();const l=document.createElement("div");l.className="swp-resize-panel",l.innerHTML=this.createResizePanelHTML(),e.appendChild(t),e.appendChild(a),a.appendChild(n),a.appendChild(s),s.appendChild(i),s.appendChild(r),s.appendChild(l),this.container.appendChild(e),this.bindEvents()}createToolbarHTML(){const{showIcons:e,showLabels:t,labels:a}=this.options,s=(a,s,n,i)=>{const r=t&&null!==n?`<span>${n}</span>`:"";return`<button class="swp-btn${r?"":" swp-btn-icon-only"}" data-action="${a}" title="${i}">${e?`<span class="swp-icon"><i class="${s}"></i></span>`:""}${r}</button>`};return`\n <div class="swp-toolbar-group">\n ${s("upload","fas fa-folder",a.upload,"Upload Image")}\n <input type="file" id="swp-file-input" accept="image/*" style="display: none;">\n </div>\n \n <div class="swp-toolbar-group" style="margin: 0px auto;">\n ${s("rotate-left","fas fa-undo",a.rotateLeft,"Rotate Left")}\n ${s("rotate-right","fas fa-redo",a.rotateRight,"Rotate Right")}\n ${s("flip-h","fas fa-arrows-alt-h",a.flipH,"Flip Horizontal")}\n ${s("flip-v","fas fa-arrows-alt-v",a.flipV,"Flip Vertical")}\n </div>\n\n <div class="swp-toolbar-group">\n ${s("reset","fas fa-history",a.reset,"Reset")}\n </div>\n\n <div class="swp-toolbar-group">\n ${s("toggle-resize","fas fa-expand-arrows-alt",a.resize,"Resize")}\n ${s("toggle-adjustments","fas fa-sliders-h",a.adjust,"Adjustments")}\n ${s("toggle-filters","fas fa-magic",a.filters,"Filters")}\n </div>\n <div class="swp-toolbar-group">\n <button class="swp-btn swp-btn-primary${t&&null!==a.save?"":" swp-btn-icon-only"}" data-action="download" title="Download">\n ${e?'<span class="swp-icon"><i class="fas fa-save"></i></span>':""}\n ${t&&null!==a.save?`<span>${a.save}</span>`:""}\n </button>\n </div>\n `}createAdjustmentsPanelHTML(){return'\n <h3>Adjustments</h3>\n <div class="swp-adjustment">\n <label>Brightness</label>\n <input type="range" id="swp-brightness" min="0" max="200" value="100">\n <span class="swp-value">100%</span>\n </div>\n <div class="swp-adjustment">\n <label>Contrast</label>\n <input type="range" id="swp-contrast" min="0" max="200" value="100">\n <span class="swp-value">100%</span>\n </div>\n <div class="swp-adjustment">\n <label>Saturation</label>\n <input type="range" id="swp-saturation" min="0" max="200" value="100">\n <span class="swp-value">100%</span>\n </div>\n '}createResizePanelHTML(){return'\n <h3>Resize Image</h3>\n <div class="swp-resize-controls">\n <div class="swp-adjustment">\n <label>Width (px)</label>\n <input type="number" id="swp-resize-width" min="1" max="5000" value="800">\n </div>\n <div class="swp-adjustment">\n <label>Height (px)</label>\n <input type="number" id="swp-resize-height" min="1" max="5000" value="600">\n </div>\n <div class="swp-adjustment">\n <label>\n <input type="checkbox" id="swp-maintain-ratio" checked>\n Maintain aspect ratio\n </label>\n </div>\n <button class="swp-btn swp-btn-primary" data-action="apply-resize">Apply Resize</button>\n </div>\n '}createFiltersPanelHTML(){return`\n <h3>Filters</h3>\n <div class="swp-filters-grid">\n ${[{name:"none",label:"None"},{name:"grayscale",label:"Grayscale"},{name:"sepia",label:"Sepia"},{name:"invert",label:"Invert"},{name:"blur",label:"Blur"}].map(e=>`\n <button class="swp-filter-btn ${"none"===e.name?"active":""}" \n data-filter="${e.name}">\n <span class="swp-filter-preview" data-filter="${e.name}"></span>\n <span>${e.label}</span>\n </button>\n `).join("")}\n </div>\n `}bindEvents(){this.container.querySelectorAll("[data-action]").forEach(e=>{e.addEventListener("click",e=>{const t=e.currentTarget.getAttribute("data-action");this.handleAction(t)})});const e=this.container.querySelector("#swp-file-input");e&&e.addEventListener("change",e=>{const t=e.target.files[0];if(t){const e=new FileReader;e.onload=e=>{this.loadImage(e.target.result)},e.readAsDataURL(t)}}),["brightness","contrast","saturation"].forEach(e=>{const t=this.container.querySelector(`#swp-${e}`);t&&t.addEventListener("input",t=>{const a=parseInt(t.target.value);t.target.nextElementSibling.textContent=a+"%",this.setAdjustment(e,a)})}),this.container.querySelectorAll("[data-filter]").forEach(e=>{e.classList.contains("swp-filter-btn")&&e.addEventListener("click",e=>{const t=e.currentTarget.getAttribute("data-filter");this.applyFilter(t),this.container.querySelectorAll(".swp-filter-btn").forEach(e=>{e.classList.remove("active")}),e.currentTarget.classList.add("active")})})}bindResizeInputs(){const e=this.container.querySelector("#swp-resize-width"),t=this.container.querySelector("#swp-resize-height"),a=this.container.querySelector("#swp-maintain-ratio");if(!e||!t||!this.currentImage)return;const s=e.cloneNode(!0),n=t.cloneNode(!0);e.parentNode.replaceChild(s,e),t.parentNode.replaceChild(n,t);const i=this.currentImage.width/this.currentImage.height;s.addEventListener("input",e=>{const t=parseInt(e.target.value);if(a.checked){const e=Math.round(t/i);n.value=e}this.updateCanvasSize(parseInt(s.value),parseInt(n.value))}),n.addEventListener("input",e=>{const t=parseInt(e.target.value);if(a.checked){const e=Math.round(t*i);s.value=e}this.updateCanvasSize(parseInt(s.value),parseInt(n.value))})}updateCanvasSize(e,t){!this.currentImage||!e||!t||e<1||t<1||(this.canvas.width=e,this.canvas.height=t,this.drawImage())}handleAction(e){switch(e){case"upload":this.container.querySelector("#swp-file-input").click();break;case"rotate-left":this.rotate(-90);break;case"rotate-right":this.rotate(90);break;case"flip-h":this.flip("horizontal");break;case"flip-v":this.flip("vertical");break;case"toggle-adjustments":this.togglePanel(".swp-adjustments-panel");break;case"toggle-filters":this.togglePanel(".swp-filters-panel");break;case"toggle-resize":this.togglePanel(".swp-resize-panel");break;case"apply-resize":this.applyResize();break;case"reset":this.reset();break;case"download":this.download()}}togglePanel(e){const t=this.container.querySelector(e);t&&(t.classList.toggle("active"),[".swp-adjustments-panel",".swp-filters-panel",".swp-resize-panel"].forEach(t=>{t!==e&&this.container.querySelector(t)?.classList.remove("active")}))}loadImage(e){const t=new Image;t.crossOrigin="anonymous",t.onload=()=>{this.originalImage=t,this.currentImage=t,this.canvas.width=t.width,this.canvas.height=t.height;const e=this.container.querySelector("#swp-resize-width"),a=this.container.querySelector("#swp-resize-height");e&&(e.value=t.width),a&&(a.value=t.height),this.bindResizeInputs(),this.drawImage(),this.emit("load")},t.onerror=()=>{console.error("Failed to load image")},t.src=e}drawImage(){if(!this.currentImage)return;const e=this.canvas,t=this.ctx;t.clearRect(0,0,e.width,e.height),t.save(),t.translate(e.width/2,e.height/2),t.rotate(this.currentState.rotation*Math.PI/180),t.scale(this.currentState.flipH?-1:1,this.currentState.flipV?-1:1),t.filter=this.getFilterString(),t.drawImage(this.currentImage,-e.width/2,-e.height/2,e.width,e.height),t.restore(),this.emit("change")}getFilterString(){let e=[];switch(100!==this.currentState.brightness&&e.push(`brightness(${this.currentState.brightness}%)`),100!==this.currentState.contrast&&e.push(`contrast(${this.currentState.contrast}%)`),100!==this.currentState.saturation&&e.push(`saturate(${this.currentState.saturation}%)`),this.currentState.filter){case"grayscale":e.push("grayscale(100%)");break;case"sepia":e.push("sepia(100%)");break;case"invert":e.push("invert(100%)");break;case"blur":e.push("blur(5px)")}return e.length>0?e.join(" "):"none"}rotate(e){this.currentImage&&(this.currentState.rotation=(this.currentState.rotation+e)%360,this.drawImage())}flip(e){this.currentImage&&("horizontal"===e?this.currentState.flipH=!this.currentState.flipH:"vertical"===e&&(this.currentState.flipV=!this.currentState.flipV),this.drawImage())}setAdjustment(e,t){this.currentImage&&(this.currentState[e]=t,this.drawImage())}applyFilter(e){this.currentImage&&(this.currentState.filter=e,this.drawImage())}applyResize(){if(!this.currentImage)return;const e=this.container.querySelector("#swp-resize-width"),t=this.container.querySelector("#swp-resize-height"),a=parseInt(e.value),s=parseInt(t.value);if(!a||!s||a<1||s<1)return void alert("Please enter valid dimensions");const n=document.createElement("canvas");n.width=this.canvas.width,n.height=this.canvas.height,n.getContext("2d").drawImage(this.canvas,0,0);const i=new Image;i.onload=()=>{this.currentImage=i,this.originalImage=i,this.bindResizeInputs(),this.drawImage()},i.src=n.toDataURL()}crop(e,t,a,s){if(!this.currentImage)return;const n=document.createElement("canvas");n.width=a,n.height=s,n.getContext("2d").drawImage(this.canvas,e,t,a,s,0,0,a,s);const i=new Image;i.onload=()=>{this.currentImage=i,this.drawImage()},i.src=n.toDataURL()}reset(){this.currentState={brightness:100,contrast:100,saturation:100,rotation:0,flipH:!1,flipV:!1,filter:"none"},["brightness","contrast","saturation"].forEach(e=>{const t=this.container.querySelector(`#swp-${e}`);t&&(t.value=100,t.nextElementSibling.textContent="100%")}),this.container.querySelectorAll(".swp-filter-btn").forEach(e=>{e.classList.remove("active"),"none"===e.getAttribute("data-filter")&&e.classList.add("active")}),this.originalImage&&(this.currentImage=this.originalImage,this.drawImage())}getImageData(e="jpeg",t=.9){if(!this.canvas)return null;const a="png"===e?"image/png":"image/jpeg";return this.canvas.toDataURL(a,t)}download(){const e=this.getImageData("png");if(!e)return;const t=document.createElement("a");t.download=`swp-edited-${Date.now()}.png`,t.href=e,t.click(),this.emit("save")}on(e,t){this.eventListeners[e]||(this.eventListeners[e]=[]),this.eventListeners[e].push(t)}emit(e,t){this.eventListeners[e]&&this.eventListeners[e].forEach(e=>{e(t)})}}"undefined"!=typeof document&&document.addEventListener("DOMContentLoaded",()=>{document.querySelectorAll("[data-swp]").forEach(e=>{const t={};if(e.dataset.swpImageUrl&&(t.imageUrl=e.dataset.swpImageUrl),e.dataset.swpWidth&&(t.width=parseInt(e.dataset.swpWidth)),e.dataset.swpHeight&&(t.height=parseInt(e.dataset.swpHeight)),void 0!==e.dataset.swpShowIcons&&(t.showIcons="false"!==e.dataset.swpShowIcons),void 0!==e.dataset.swpShowLabels&&(t.showLabels="false"!==e.dataset.swpShowLabels),e.dataset.swpLabels)try{let a=e.dataset.swpLabels.trim();a.startsWith("{")?t.labels=JSON.parse(a):(t.labels={},a.split(";").forEach(e=>{const[a,s]=e.split(":").map(e=>e.trim());if(a&&s){const e=s.replace(/^['"]|['"]$/g,"");t.labels[a]="null"===e?null:e}}))}catch(e){console.error("Failed to parse data-swp-labels:",e)}new a(e,t)})});const s=a;return"undefined"!=typeof window&&(window.SWP=a),t.default})());