zumly 0.9.11 → 0.18.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/zumly.mjs CHANGED
@@ -1,771 +1,7 @@
1
- /**
2
- * zumly v0.9.11
3
- * Author Juan Martín Muda, @license MIT
4
- * https://zumly.org
1
+ /*
2
+ * zumly
3
+ * v.0.18.1
4
+ * Author Juan Martin Muda - Zumerlab
5
+ * License MIT
5
6
  */
6
- function checkArray (array) {
7
- // remove duplicates and map
8
- if (array !== undefined && array[0].toLowerCase() === 'none') {
9
- return true
10
- }
11
- if (array !== undefined && array.length > 0) {
12
- const unique = array => [...new Set(array)];
13
- const lowerArray = array.map(e => e.toLowerCase());
14
- return unique(lowerArray).every(value => ['blur', 'sepia', 'saturate'].indexOf(value) !== -1)
15
- }
16
- }
17
-
18
- function setFx (values) {
19
- var start = '';
20
- var end = '';
21
- if (values !== undefined) {
22
- values.map(effect => {
23
- start += `${effect.toLowerCase() === 'blur' ? 'blur(0px) ' : effect.toLowerCase() === 'sepia' ? 'sepia(0) ' : effect.toLowerCase() === 'saturate' ? 'saturate(0) ' : 'none'}`;
24
- end += `${effect.toLowerCase() === 'blur' ? 'blur(0.8px) ' : effect.toLowerCase() === 'sepia' ? 'sepia(5) ' : effect.toLowerCase() === 'saturate' ? 'saturate(8) ' : 'none'}`;
25
- });
26
- return [start, end]
27
- }
28
- }
29
- function assignProperty (instance, propertiesToAdd, value) {
30
- instance[propertiesToAdd] = value;
31
- }
32
-
33
- function validate (instance, name, value, type, options = { isRequired: false, defaultValue: 0, allowedValues: 0, hasValidation: 0, hasAssignFunction: 0 }) {
34
- var msg = `'${name}' property is required when instance is defined`;
35
- var msg1 = `'${name}' property has problems`;
36
- var checkValue = value !== undefined;
37
- var checkDefault = options.defaultValue !== undefined;
38
- var checkCustomValidation = options.hasValidation !== undefined;
39
- var checkCustomAssign = options.hasAssignFunction !== undefined;
40
- if (type === 'string' || type === 'object' || type === 'boolean') {
41
- var checkTypeof = typeof value === type; // eslint-disable-line
42
- // value = checkTypeof && type === 'string' ? value.toLowerCase() : value
43
- } else if (type === 'array') {
44
- checkTypeof = Array.isArray(value);
45
- }
46
- if (options.isRequired) {
47
- checkValue && checkTypeof ? assignProperty(instance, name, value) : notification(false, msg, 'error');
48
- }
49
- if (checkDefault && !checkCustomValidation && !checkCustomAssign) {
50
- checkValue && checkTypeof ? assignProperty(instance, name, value) : value === undefined ? assignProperty(instance, name, options.defaultValue) : notification(false, msg1, 'error');
51
- }
52
- if (checkCustomValidation && checkDefault && !checkCustomAssign) {
53
- checkValue && checkTypeof && options.hasValidation ? assignProperty(instance, name, value) : value === undefined ? assignProperty(instance, name, options.defaultValue) : notification(false, msg1, 'error');
54
- }
55
- // console.log(name, checkCustomValidation, checkDefault, checkCustomAssign)
56
- if (checkCustomValidation && checkDefault && checkCustomAssign) {
57
- checkValue && checkTypeof && options.hasValidation ? assignProperty(instance, name, options.hasAssignFunction) : value === undefined ? assignProperty(instance, name, options.defaultValue) : notification(false, msg1, 'error');
58
- }
59
- }
60
-
61
- function shimIdleCallBack (cb) {
62
- var start = Date.now();
63
- return setTimeout(() => {
64
- cb({ didTimeout: false, timeRemaining () { return Math.max(0, 50 - (Date.now() - start)) } }); // eslint-disable-line
65
- }, 1)
66
- }
67
-
68
- function prepareCSS (instance) {
69
- var instanceStyle = document.createElement('style');
70
- const views = ['current-view', 'previous-view', 'last-view'];
71
- let result = '';
72
- views.map(view => {
73
- result += `
74
- .zoom-${view}-${instance} {
75
- animation-name: zoom-${view}-${instance};
76
- animation-duration: var(--zoom-duration-${instance});
77
- animation-timing-function: var(--zoom-ease-${instance});
78
- }
79
- @keyframes zoom-${view}-${instance} {
80
- 0% {
81
- transform-origin: var(--${view}-transformOrigin-start-${instance});
82
- transform: var(--${view}-transform-start-${instance});
83
- opacity: var(--${view}-opacity-start-${instance});
84
- filter: var(--${view}-filter-start-${instance})
85
- }
86
- 100% {
87
- transform-origin: var(--${view}-transformOrigin-end-${instance});
88
- transform: var(--${view}-transform-end-${instance});
89
- opacity: var(--${view}-opacity-end-${instance});
90
- filter: var(--${view}-filter-end-${instance})
91
- }
92
- }
93
- `;
94
- });
95
- instanceStyle.innerHTML = result;
96
- document.head.appendChild(instanceStyle);
97
- }
98
-
99
- function setCSSVariables (transition, currentStage, instance) {
100
- const viewStage = currentStage;
101
- const current = viewStage.views[0];
102
- const previous = viewStage.views[1];
103
- const last = viewStage.views[2];
104
- const views = [{ name: 'current-view', stage: current }, { name: 'previous-view', stage: previous }, { name: 'last-view', stage: last }];
105
- views.map(view => {
106
- if (transition === 'zoomOut' && view.stage !== undefined) {
107
- document.documentElement.style.setProperty(`--${view.name}-transform-start-${instance}`, view.stage.forwardState.transform);
108
- document.documentElement.style.setProperty(`--${view.name}-transform-end-${instance}`, view.stage.backwardState.transform);
109
- document.documentElement.style.setProperty(`--${view.name}-transformOrigin-start-${instance}`, view.stage.forwardState.origin);
110
- document.documentElement.style.setProperty(`--${view.name}-transformOrigin-end-${instance}`, view.stage.backwardState.origin);
111
- document.documentElement.style.setProperty(`--${view.name}-opacity-start-${instance}`, 1);
112
- document.documentElement.style.setProperty(`--${view.name}-filter-start-${instance}`, view.stage.forwardState.filter);
113
- document.documentElement.style.setProperty(`--${view.name}-filter-end-${instance}`, view.stage.backwardState.filter);
114
- if (view.name === 'current-view') {
115
- document.documentElement.style.setProperty(`--zoom-duration-${instance}`, view.stage.backwardState.duration);
116
- document.documentElement.style.setProperty(`--zoom-ease-${instance}`, view.stage.backwardState.ease);
117
- document.documentElement.style.setProperty(`--${view.name}-opacity-end-${instance}`, 0);
118
- document.documentElement.style.setProperty(`--${view.name}-filter-start-${instance}`, 'none');
119
- document.documentElement.style.setProperty(`--${view.name}-filter-end-${instance}`, 'none');
120
- } else {
121
- document.documentElement.style.setProperty(`--${view.name}-opacity-end-${instance}`, 1);
122
- }
123
- }
124
- if (transition === 'zoomIn' && view.stage !== undefined) {
125
- document.documentElement.style.setProperty(`--${view.name}-transform-start-${instance}`, view.stage.backwardState.transform);
126
- document.documentElement.style.setProperty(`--${view.name}-transform-end-${instance}`, view.stage.forwardState.transform);
127
- document.documentElement.style.setProperty(`--${view.name}-transformOrigin-start-${instance}`, view.stage.backwardState.origin);
128
- document.documentElement.style.setProperty(`--${view.name}-transformOrigin-end-${instance}`, view.stage.forwardState.origin);
129
- document.documentElement.style.setProperty(`--${view.name}-filter-start-${instance}`, view.stage.backwardState.filter);
130
- document.documentElement.style.setProperty(`--${view.name}-filter-end-${instance}`, view.stage.forwardState.filter);
131
- if (view.name === 'current-view') {
132
- document.documentElement.style.setProperty(`--zoom-duration-${instance}`, view.stage.forwardState.duration);
133
- document.documentElement.style.setProperty(`--zoom-ease-${instance}`, view.stage.forwardState.ease);
134
- document.documentElement.style.setProperty(`--${view.name}-opacity-start-${instance}`, 0);
135
- document.documentElement.style.setProperty(`--${view.name}-filter-start-${instance}`, 'none');
136
- document.documentElement.style.setProperty(`--${view.name}-filter-end-${instance}`, 'none');
137
- } else {
138
- document.documentElement.style.setProperty(`--${view.name}-opacity-start-${instance}`, 1);
139
- }
140
- document.documentElement.style.setProperty(`--${view.name}-opacity-end-${instance}`, 1);
141
- }
142
- });
143
- }
144
-
145
- async function renderView (el, canvas, views, init, componentContext) {
146
- var viewName = null;
147
- init ? viewName = el : viewName = el.dataset.to;
148
- var newView = document.createElement('template');
149
-
150
- if(typeof views[viewName] === 'object' && views[viewName].render !== undefined) {
151
- // makes optional de 'render' function
152
- newView.innerHTML = await views[viewName].render();
153
- } else if(typeof views[viewName] === 'function') {
154
- // view is a component constructor
155
- var newViewInner = document.createElement('div');
156
- let comp = new views[viewName]({
157
- target: newViewInner,
158
- context: componentContext,
159
- props: el.dataset
160
- });
161
- newViewInner.classList.add('z-view');
162
- newView.content.appendChild(newViewInner);
163
- } else {
164
- // view is plain HTML
165
- newView.innerHTML = views[viewName];
166
- }
167
-
168
- let vv = newView.content.querySelector('.z-view');
169
-
170
- if (!init) {
171
- vv.classList.add('is-new-current-view');
172
- vv.classList.add('has-no-events');
173
- vv.classList.add('hide');
174
- vv.classList.add('performance');
175
- } else {
176
- vv.classList.add('is-current-view');
177
- }
178
- vv.style.transformOrigin = '0 0';
179
- vv.dataset.viewName = viewName;
180
-
181
- var appendedView = await canvas.append(newView.content);
182
- // makes optional de 'mounted' hook
183
- if (typeof views[viewName] === 'object' && views[viewName].mounted !== undefined && typeof views[viewName].mounted() === 'function') await views[viewName].mounted();
184
- }
185
-
186
- function notification (debug, msg, type) {
187
- if (msg && type === 'welcome') {
188
- console.info(`%c Zumly %c ${msg}`, 'background: #424085; color: white; border-radius: 3px;', 'color: #424085'); // eslint-disable-line no-console
189
- }
190
- if (msg && debug && (type === 'info' || type === undefined)) {
191
- console.info(`%c Zumly %c ${msg}`, 'background: #6679A3; color: #304157; border-radius: 3px;', 'color: #6679A3'); // eslint-disable-line no-console
192
- }
193
- if (msg && type === 'warn') {
194
- console.warn(`%c Zumly %c ${msg}`, 'background: #DCBF53; color: #424085; border-radius: 3px;', 'color: #424085'); // eslint-disable-line no-console
195
- }
196
- if (msg && type === 'error') {
197
- console.error(`%c Zumly %c ${msg}`, 'background: #BE4747; color: white; border-radius: 3px;', 'color: #424085'); // eslint-disable-line no-console
198
- }
199
- }
200
-
201
- function checkParameters (parameters, instance) {
202
- // First check if options are provided
203
- if (parameters && typeof parameters === 'object') {
204
- assignProperty(instance, 'options', true);
205
- // Then check its properties
206
- // mount property. String DOM element. Required
207
- validate(instance, 'mount', parameters.mount, 'string', { isRequired: true });
208
- // initialView property. Strng view name. Required
209
- validate(instance, 'initialView', parameters.initialView, 'string', { isRequired: true });
210
- // views property. Object with views. Required
211
- validate(instance, 'views', parameters.views, 'object', { isRequired: true });
212
- // debug property. Boolean. Optional. Default false
213
- validate(instance, 'debug', parameters.debug, 'boolean', { defaultValue: false });
214
- // Svelte component context
215
- validate(instance, 'componentContext', parameters.componentContext, 'object', { isRequired: false, defaultValue: new Map() });
216
- // Check transtions
217
- if (parameters.transitions && typeof parameters.transitions === 'object') {
218
- // value exist; type, allowed, deafult
219
- validate(instance, 'cover', parameters.transitions.cover, 'string', { defaultValue: 'width', hasValidation: () => { ['height', 'width'].indexOf(parameters.transitions.cover.toLowerCase()) !== -1; } }); // eslint-disable-line
220
- // value, type, , default
221
- validate(instance, 'duration', parameters.transitions.duration, 'string', { defaultValue: '1s' });
222
- // value, type, ,default
223
- validate(instance, 'ease', parameters.transitions.ease, 'string', { defaultValue: 'ease-in-out' });
224
- // value, type, custom validation, custom asignament, default
225
- validate(instance, 'effects', parameters.transitions.effects, 'array', { defaultValue: ['none', 'none'], hasValidation: checkArray(parameters.transitions.effects), hasAssignFunction: setFx(parameters.transitions.effects) });
226
- } else {
227
- // assign deafult values
228
- assignProperty(instance, 'cover', 'width');
229
- assignProperty(instance, 'duration', '1s');
230
- assignProperty(instance, 'ease', 'ease-in-out');
231
- assignProperty(instance, 'effects', ['none', 'none']);
232
- }
233
- } else {
234
- notification(false, '\'options\' object has to be provided when instance is defined', 'error');
235
- }
236
- }
237
-
238
- window.requestIdleCallback = window.requestIdleCallback || shimIdleCallBack;
239
-
240
- /**
241
- * Zumly
242
- * Powers your apps with a zoomable user interface (ZUI) taste.
243
- * @class
244
- */
245
- class Zumly {
246
- /**
247
- * Creates a Zumly instance
248
- * @constructor
249
- * @params {Objet} options
250
- * @example
251
- * new Zumly({
252
- * mount: '.mount',
253
- * initialView: 'home',
254
- * views: {
255
- * home,
256
- * contact,
257
- * ...
258
- * }
259
- *
260
- */
261
- constructor (options) {
262
- // Internal state:
263
- // Register global instances of Zumly
264
- this.instance = Zumly.counter;
265
- // Store snapshots of each zoom transition
266
- this.storedViews = [];
267
- // Show current zoom level properties
268
- this.currentStage = null;
269
- // Store the scale of previous zoom transition
270
- this.storedPreviousScale = [1];
271
- // Array of events useful for debugging
272
- this.trace = [];
273
- // Deactive events during transtions
274
- this.blockEvents = false;
275
- // Initial values for gesture events
276
- this.touchstartX = 0;
277
- this.touchstartY = 0;
278
- this.touchendX = 0;
279
- this.touchendY = 0;
280
- this.touching = false;
281
- // Check if user options exist
282
- checkParameters(options, this);
283
- if (this.options) {
284
- // Event bindings:
285
- this._onZoom = this.onZoom.bind(this);
286
- this._onZoomInHandlerStart = this.onZoomInHandlerStart.bind(this);
287
- this._onZoomInHandlerEnd = this.onZoomInHandlerEnd.bind(this);
288
- this._onZoomOutHandlerStart = this.onZoomOutHandlerStart.bind(this);
289
- this._onZoomOutHandlerEnd = this.onZoomOutHandlerEnd.bind(this);
290
- this._onTouchStart = this.onTouchStart.bind(this);
291
- this._onTouchEnd = this.onTouchEnd.bind(this);
292
- this._onKeyUp = this.onKeyUp.bind(this);
293
- this._onWeel = this.onWeel.bind(this);
294
- // Prepare the instance:
295
- this.canvas = document.querySelector(this.mount);
296
- this.canvas.setAttribute('tabindex', 0);
297
- this.canvas.addEventListener('mouseup', this._onZoom, false);
298
- this.canvas.addEventListener('touchend', this._onZoom, false);
299
- this.canvas.addEventListener('touchstart', this._onTouchStart, { passive: true });
300
- this.canvas.addEventListener('touchend', this._onTouchEnd, false);
301
- this.canvas.addEventListener('keyup', this._onKeyUp, false);
302
- this.canvas.addEventListener('wheel', this._onWeel, { passive: true });
303
- } else {
304
- this.notify('is unable to start: no {options} have been passed to the Zumly\'s instance.', 'error');
305
- }
306
- }
307
-
308
- /**
309
- * Helpers
310
- */
311
- storeViews (data) {
312
- this.tracing('storedViews()');
313
- this.storedViews.push(data);
314
- }
315
-
316
- setPreviousScale (scale) {
317
- this.tracing('setPreviousScale()');
318
- this.storedPreviousScale.push(scale);
319
- }
320
-
321
- tracing (data) {
322
- if (data === 'ended') {
323
- const parse = this.trace.map((task, index) => `${index === 0 ? `Instance ${this.instance}: ${task}` : `${task}`}`).join(' > ');
324
- this.notify(parse);
325
- this.trace = [];
326
- } else {
327
- this.trace.push(data);
328
- }
329
- }
330
-
331
- /**
332
- * Private methods
333
- */
334
- static get counter () {
335
- Zumly._counter = (Zumly._counter || 0) + 1;
336
- return Zumly._counter
337
- }
338
-
339
- notify (msg, type) {
340
- return notification(this.debug, msg, type)
341
- }
342
-
343
- /**
344
- * Public methods
345
- */
346
- zoomLevel () {
347
- return this.storedViews.length
348
- }
349
-
350
- async init () {
351
- if (this.options) {
352
- // add instance style
353
- this.tracing('init()');
354
- prepareCSS(this.instance);
355
- await renderView(this.initialView, this.canvas, this.views, 'init', this.componentContext);
356
- // add to storage. OPTIMIZAR
357
- this.storeViews({
358
- zoomLevel: this.storedViews.length,
359
- views: [{
360
- viewName: this.initialView,
361
- backwardState: {
362
- origin: '0 0',
363
- transform: ''
364
- }
365
- }]
366
- });
367
- //
368
- this.notify(`${this.instance > 1
369
- ? `instance nº ${this.instance} is active.`
370
- : `is running! Instance nº ${this.instance} is active. ${this.debug
371
- ? 'Debug is active, can be deactivate by setting \'debug: false\' when you define the instance.' : ''}
372
- More tips & docs at https://zumly.org`}`, 'welcome');
373
- }
374
- }
375
-
376
- /**
377
- * Main methods
378
- */
379
- async zoomIn (el) {
380
- this.tracing('zoomIn()');
381
- var instance = this.instance;
382
- const canvas = this.canvas;
383
- const coordenadasCanvas = canvas.getBoundingClientRect();
384
- var offsetX = coordenadasCanvas.left;
385
- var offsetY = coordenadasCanvas.top;
386
- const preScale = this.storedPreviousScale[this.storedPreviousScale.length - 1];
387
- // generated new view from activated .zoom-me element
388
- // generateNewView(el)
389
- this.tracing('renderView()');
390
- await renderView(el, canvas, this.views, false, this.componentContext);
391
- el.classList.add('zoomed');
392
- const coordenadasEl = el.getBoundingClientRect();
393
- // create new view in a template tag
394
- // select VIEWS from DOM
395
- var currentView = canvas.querySelector('.is-new-current-view');
396
- var previousView = canvas.querySelector('.is-current-view');
397
- var lastView = canvas.querySelector('.is-previous-view');
398
- var removeView = canvas.querySelector('.is-last-view');
399
- if (removeView !== null) canvas.removeChild(removeView);
400
- // do changes
401
- const cc = currentView.getBoundingClientRect();
402
- const scale = cc.width / coordenadasEl.width;
403
- const scaleInv = 1 / scale;
404
- const scaleh = cc.height / coordenadasEl.height;
405
- const scaleInvh = 1 / scaleh;
406
- // muy interesante featura... usar el zoom de acuardo a la h o w mayor y agra
407
- var duration = el.dataset.withDuration || this.duration;
408
- var ease = el.dataset.withEease || this.ease;
409
- var filterIn = this.effects[0];
410
- var filterOut = this.effects[1];
411
- var cover = this.cover;
412
-
413
- if (cover === 'width') {
414
- var laScala = scale;
415
- var laScalaInv = scaleInv;
416
- } else if (cover === 'height') {
417
- laScala = scaleh;
418
- laScalaInv = scaleInvh;
419
- }
420
-
421
- this.setPreviousScale(laScala);
422
- var transformCurrentView0 = `translate(${coordenadasEl.x - offsetX + (coordenadasEl.width - cc.width * laScalaInv) / 2}px, ${coordenadasEl.y - offsetY + (coordenadasEl.height - cc.height * laScalaInv) / 2}px) scale(${laScalaInv})`;
423
- currentView.style.transform = transformCurrentView0;
424
- //
425
- previousView.classList.add('is-previous-view');
426
- previousView.classList.remove('is-current-view');
427
- const coordenadasPreviousView = previousView.getBoundingClientRect();
428
- // PREVIOUS VIEW EXACTAMENTE ONDE ESTANA ANTES COMO CURRENT
429
- var transformPreviousView0 = previousView.style.transform;
430
- previousView.style.transformOrigin = `${coordenadasEl.x + coordenadasEl.width / 2 - coordenadasPreviousView.x}px ${coordenadasEl.y + coordenadasEl.height / 2 - coordenadasPreviousView.y}px`;
431
-
432
- const x = coordenadasCanvas.width / 2 - coordenadasEl.width / 2 - coordenadasEl.x + coordenadasPreviousView.x;
433
- const y = coordenadasCanvas.height / 2 - coordenadasEl.height / 2 - coordenadasEl.y + coordenadasPreviousView.y;
434
-
435
- const transformPreviousView1 = `translate(${x}px, ${y}px) scale(${laScala})`;
436
- // PREVIOUS VIEW FINAL STAGE
437
- previousView.style.transform = transformPreviousView1;
438
- // ACA CAMBIA LA COSA, LEVANTO LAS COORDENADAS DEL ELEMENTO CLICLEADO QUE ESTBA DNRO DE PREVIOUS VIEW
439
- var newcoordenadasEl = el.getBoundingClientRect();
440
- // LO QUE DETERMINA LA POSICINES FONAL DEL CURRENT VIEW
441
- var transformCurrentView1 = `translate(${newcoordenadasEl.x - offsetX + (newcoordenadasEl.width - cc.width) / 2}px, ${newcoordenadasEl.y - offsetY + (newcoordenadasEl.height - cc.height) / 2}px)`;
442
-
443
- if (lastView !== null) {
444
- lastView.classList.remove('is-previous-view');
445
- lastView.classList.add('is-last-view');
446
- var transformLastView0 = lastView.style.transform;
447
- var newcoordenadasPV = previousView.getBoundingClientRect();
448
- lastView.style.transform = `translate(${x - offsetX}px, ${y - offsetY}px) scale(${laScala * preScale})`;
449
- const last = lastView.querySelector('.zoomed');
450
- var coorLast = last.getBoundingClientRect();
451
- lastView.style.transform = transformLastView0;
452
- previousView.style.transform = transformPreviousView0;
453
- var coorPrev = previousView.getBoundingClientRect();
454
- var transformLastView1 = `translate(${coordenadasCanvas.width / 2 - coordenadasEl.width / 2 - coordenadasEl.x + (coorPrev.x - coorLast.x) + newcoordenadasPV.x - offsetX + (newcoordenadasPV.width - coorLast.width) / 2}px, ${coordenadasCanvas.height / 2 - coordenadasEl.height / 2 - coordenadasEl.y + (coorPrev.y - coorLast.y) + newcoordenadasPV.y - offsetY +
455
- (newcoordenadasPV.height - coorLast.height) / 2}px) scale(${laScala * preScale})`;
456
- } else {
457
- previousView.style.transform = transformPreviousView0;
458
- }
459
- // arrays
460
- var snapShoot = {
461
- zoomLevel: this.storedViews.length,
462
- views: []
463
- };
464
- const currentv = currentView ? {
465
- viewName: currentView.dataset.viewName,
466
- backwardState: {
467
- origin: currentView.style.transformOrigin,
468
- duration: duration,
469
- ease: ease,
470
- transform: transformCurrentView0,
471
- filter: filterIn
472
- },
473
- forwardState: {
474
- origin: currentView.style.transformOrigin,
475
- duration: duration,
476
- ease: ease,
477
- transform: transformCurrentView1,
478
- filter: filterOut
479
- }
480
- } : null;
481
- const previousv = previousView ? {
482
- viewName: previousView.dataset.viewName,
483
- backwardState: {
484
- origin: previousView.style.transformOrigin,
485
- duration: duration,
486
- ease: ease,
487
- transform: transformPreviousView0,
488
- filter: window.getComputedStyle(document.documentElement).getPropertyValue(`--previous-view-filter-end-${instance}`)
489
- },
490
- forwardState: {
491
- origin: previousView.style.transformOrigin,
492
- duration: duration,
493
- ease: ease,
494
- transform: transformPreviousView1,
495
- filter: filterOut
496
- }
497
- } : null;
498
- const lastv = lastView ? {
499
- viewName: lastView.dataset.viewName,
500
- backwardState: {
501
- origin: lastView.style.transformOrigin,
502
- duration: duration,
503
- ease: ease,
504
- transform: transformLastView0,
505
- filter: window.getComputedStyle(document.documentElement).getPropertyValue(`--previous-view-filter-end-${instance}`)
506
- },
507
- forwardState: {
508
- origin: lastView.style.transformOrigin,
509
- duration: duration,
510
- ease: ease,
511
- transform: transformLastView1,
512
- filter: filterOut
513
- }
514
- } : null;
515
- const gonev = removeView ? { // ACA VA LA VISTA ENTERA FALTA REALIZAR UN ZOOM IGUAL ANTES DE SACARLA DE JUEGO
516
- viewName: removeView
517
- } : null;
518
- if (currentv !== null) snapShoot.views.push(currentv);
519
- if (previousv !== null) snapShoot.views.push(previousv);
520
- if (lastv !== null) snapShoot.views.push(lastv);
521
- if (gonev !== null) snapShoot.views.push(gonev);
522
- this.storeViews(snapShoot);
523
- this.currentStage = this.storedViews[this.storedViews.length - 1];
524
- // animation
525
- this.tracing('setCSSVariables()');
526
- setCSSVariables('zoomIn', this.currentStage, this.instance);
527
- previousView.classList.add('performance');
528
- if (lastView !== null) lastView.classList.add('performance');
529
- //
530
- currentView.classList.remove('hide');
531
- currentView.addEventListener('animationstart', this._onZoomInHandlerStart);
532
- currentView.addEventListener('animationend', this._onZoomInHandlerEnd);
533
- previousView.addEventListener('animationend', this._onZoomInHandlerEnd);
534
- if (lastView !== null) lastView.addEventListener('animationend', this._onZoomInHandlerEnd);
535
- //
536
- currentView.classList.add(`zoom-current-view-${instance}`);
537
- previousView.classList.add(`zoom-previous-view-${instance}`);
538
- if (lastView !== null) lastView.classList.add(`zoom-last-view-${instance}`);
539
- }
540
-
541
- zoomOut () {
542
- this.tracing('zoomOut()');
543
- this.blockEvents = true;
544
- this.storedPreviousScale.pop();
545
- var instance = this.instance;
546
- const canvas = this.canvas;
547
- this.currentStage = this.storedViews[this.storedViews.length - 1];
548
- const reAttachView = this.currentStage.views[3];
549
- var currentView = canvas.querySelector('.is-current-view');
550
- var previousView = canvas.querySelector('.is-previous-view');
551
- var lastView = canvas.querySelector('.is-last-view');
552
- //
553
- this.tracing('setCSSVariables()');
554
- setCSSVariables('zoomOut', this.currentStage, this.instance);
555
- //
556
- //
557
- currentView.classList.remove('performance');
558
- //
559
- previousView.querySelector('.zoomed').classList.remove('zoomed');
560
- previousView.classList.remove('is-previous-view');
561
- previousView.classList.add('is-current-view');
562
- previousView.classList.remove('performance');
563
- //
564
- if (lastView !== null) {
565
- lastView.classList.add('performance');
566
- lastView.classList.add('is-previous-view');
567
- lastView.classList.remove('is-last-view');
568
- lastView.classList.remove('hide');
569
- }
570
- //
571
- if (reAttachView !== undefined) {
572
- canvas.prepend(reAttachView.viewName);
573
- var newlastView = canvas.querySelector('.z-view:first-child');
574
- newlastView.classList.add('hide');
575
- }
576
- //
577
- currentView.addEventListener('animationstart', this._onZoomOutHandlerStart);
578
- currentView.addEventListener('animationend', this._onZoomOutHandlerEnd);
579
- previousView.addEventListener('animationend', this._onZoomOutHandlerEnd);
580
- if (lastView !== null) lastView.addEventListener('animationend', this._onZoomOutHandlerEnd);
581
- //
582
- currentView.classList.add(`zoom-current-view-${instance}`);
583
- previousView.classList.add(`zoom-previous-view-${instance}`);
584
- if (lastView !== null) lastView.classList.add(`zoom-last-view-${instance}`);
585
- this.storedViews.pop();
586
- }
587
-
588
- /**
589
- * Event hangling
590
- */
591
- onZoom (event) {
592
- if (this.storedViews.length > 1 && !this.blockEvents && !event.target.classList.contains('zoom-me') && event.target.closest('.is-current-view') === null && !this.touching) {
593
- this.tracing('onZoom()');
594
- event.stopPropagation();
595
- this.zoomOut();
596
- }
597
- if (!this.blockEvents && event.target.classList.contains('zoom-me') && !this.touching) {
598
- this.tracing('onZoom()');
599
- event.stopPropagation();
600
- this.zoomIn(event.target);
601
- }
602
- }
603
-
604
- onKeyUp (event) {
605
- this.tracing('onKeyUp()');
606
- // Possible conflict with usar inputs
607
- if (event.key === 'ArrowLeft' || event.key === 'ArrowDown') {
608
- event.preventDefault();
609
- if (this.storedViews.length > 1 && !this.blockEvents) {
610
- this.zoomOut();
611
- } else {
612
- this.notify(`is on level zero. Can't zoom out. Trigger: ${event.key}`, 'warn');
613
- }
614
- }
615
- if (event.key === 'ArrowRight' || event.key === 'ArrowUp') {
616
- event.preventDefault();
617
- this.notify(event.key + 'has not actions defined');
618
- }
619
- }
620
-
621
- onWeel (event) {
622
- // inertia need to be fixed
623
- if (!this.blockEvents) {
624
- this.tracing('onWeel()');
625
- if (event.deltaY < 0) ;
626
- if (event.deltaY > 0) {
627
- if (this.storedViews.length > 1 && !this.blockEvents) {
628
- this.zoomOut();
629
- }
630
- }
631
- }
632
- }
633
-
634
- onTouchStart (event) {
635
- this.tracing('onTouchStart()');
636
- this.touching = true;
637
- this.touchstartX = event.changedTouches[0].screenX;
638
- this.touchstartY = event.changedTouches[0].screenY;
639
- }
640
-
641
- onTouchEnd (event) {
642
- if (!this.blockEvents) {
643
- this.tracing('onTouchEnd()');
644
- this.touchendX = event.changedTouches[0].screenX;
645
- this.touchendY = event.changedTouches[0].screenY;
646
- this.handleGesture(event);
647
- // event.preventDefault()
648
- }
649
- }
650
-
651
- handleGesture (event) {
652
- event.stopPropagation();
653
- this.tracing('handleGesture()');
654
- if (this.touchendX < this.touchstartX - 30) {
655
- if (this.storedViews.length > 1 && !this.blockEvents) {
656
- this.tracing('swipe left');
657
- this.zoomOut();
658
- } else {
659
- this.notify("is on level zero. Can't zoom out. Trigger: Swipe left", 'warn');
660
- }
661
- }
662
- if (this.touchendY < this.touchstartY - 10) {
663
- if (this.storedViews.length > 1 && !this.blockEvents) {
664
- this.tracing('swipe up');
665
- // Disabled. In near future enable if Zumly is full screen
666
- // this.zoomOut()
667
- } else {
668
- this.notify("is on level zero. Can't zoom out. Trigger: Swipe up", 'warn');
669
- }
670
- }
671
- if (this.touchendY === this.touchstartY && !this.blockEvents && event.target.classList.contains('zoom-me') && this.touching) {
672
- this.touching = false;
673
- this.tracing('tap');
674
- event.preventDefault();
675
- this.zoomIn(event.target);
676
- }
677
- if (this.touchendY === this.touchstartY && this.storedViews.length > 1 && !this.blockEvents && !event.target.classList.contains('zoom-me') && event.target.closest('.is-current-view') === null && this.touching) {
678
- this.touching = false;
679
- this.tracing('tap');
680
- this.zoomOut();
681
- }
682
- }
683
-
684
- onZoomOutHandlerStart (event) {
685
- this.tracing('onZoomOutHandlerStart()');
686
- this.blockEvents = true;
687
- event.target.removeEventListener('animationstart', this._onZoomOutHandlerStart);
688
- }
689
-
690
- onZoomOutHandlerEnd (event) {
691
- this.tracing('onZoomOutHandlerEnd()');
692
- const element = event.target;
693
- var currentZoomLevel = this.currentStage;
694
- element.removeEventListener('animationend', this._onZoomOutHandlerEnd);
695
- // current
696
- if (element.classList.contains(`zoom-current-view-${this.instance}`)) {
697
- try {
698
- this.canvas.removeChild(element);
699
- } catch(e) {
700
- console.debug("Error when trying to remove element after zoom out. Trying to remove its parent instead...");
701
- try {
702
- this.canvas.removeChild(element.parentElement);
703
- } catch(e) {
704
- console.debug("Error when trying to remove elemont after zoom out:", e);
705
- console.debug("Element to remove was:", element);
706
- }
707
-
708
- }
709
-
710
- this.blockEvents = false;
711
- }
712
- if (element.classList.contains(`zoom-previous-view-${this.instance}`)) {
713
- var origin = currentZoomLevel.views[1].backwardState.origin;
714
- var transform = currentZoomLevel.views[1].backwardState.transform;
715
- element.classList.remove('performance');
716
- element.classList.remove(`zoom-previous-view-${this.instance}`);
717
- element.style.transformOrigin = origin;
718
- element.style.transform = transform;
719
- element.style.filter = 'none';
720
- if (currentZoomLevel.views.length === 2) this.tracing('ended');
721
- }
722
- if (element.classList.contains(`zoom-last-view-${this.instance}`)) {
723
- origin = currentZoomLevel.views[2].backwardState.origin;
724
- transform = currentZoomLevel.views[2].backwardState.transform;
725
- element.classList.remove('performance');
726
- element.classList.remove(`zoom-last-view-${this.instance}`);
727
- element.style.transformOrigin = origin;
728
- element.style.transform = transform;
729
- if (currentZoomLevel.views.length > 2) this.tracing('ended');
730
- }
731
- }
732
-
733
- onZoomInHandlerStart (event) {
734
- this.tracing('onZoomInHandlerStart()');
735
- this.blockEvents = true;
736
- event.target.removeEventListener('animationstart', this._onZoomInHandlerStart);
737
- }
738
-
739
- onZoomInHandlerEnd (event) {
740
- this.tracing('onZoomInHandlerEnd()');
741
- const element = event.target;
742
- var currentZoomLevel = this.currentStage;
743
- if (event.target.classList.contains('is-new-current-view')) {
744
- this.blockEvents = false;
745
- var viewName = 'current-view';
746
- var transform = currentZoomLevel.views[0].forwardState.transform;
747
- var origin = currentZoomLevel.views[0].forwardState.origin;
748
- element.classList.remove('is-new-current-view');
749
- element.classList.add('is-current-view');
750
- } else if (event.target.classList.contains('is-previous-view')) {
751
- viewName = 'previous-view';
752
- transform = currentZoomLevel.views[1].forwardState.transform;
753
- origin = currentZoomLevel.views[1].forwardState.origin;
754
- if (currentZoomLevel.views.length === 2) this.tracing('ended');
755
- } else {
756
- viewName = 'last-view';
757
- transform = currentZoomLevel.views[2].forwardState.transform;
758
- origin = currentZoomLevel.views[2].forwardState.origin;
759
- if (currentZoomLevel.views.length > 2) this.tracing('ended');
760
- }
761
- element.classList.remove('performance');
762
- element.classList.remove(`zoom-${viewName}-${this.instance}`);
763
- element.classList.remove('has-no-events');
764
- element.style.transformOrigin = origin;
765
- element.style.transform = transform;
766
- element.style.filter = window.getComputedStyle(document.documentElement).getPropertyValue(`--${viewName}-filter-end-${this.instance}`);
767
- element.removeEventListener('animationend', this._onZoomInHandlerEnd);
768
- }
769
- }
770
-
771
- export default Zumly;
7
+ function Et(s){var t="",r="";if(s!==void 0)return s.map(n=>{t+=`${n.toLowerCase()==="blur"?"blur(0px) ":n.toLowerCase()==="sepia"?"sepia(0) ":n.toLowerCase()==="saturate"?"saturate(0) ":"none"}`,r+=`${n.toLowerCase()==="blur"?"blur(0.8px) ":n.toLowerCase()==="sepia"?"sepia(5) ":n.toLowerCase()==="saturate"?"saturate(8) ":"none"}`}),[t,r]}async function _(s,t,r,n,o,e){if(!s||!s.classList){let f=document.createElement("div");f.classList.add("z-view"),s&&f.appendChild(s),s=f}else s.classList.contains("z-view")||s.classList.add("z-view");return s.dataset.viewName=t,s.style.transformOrigin="0 0",n?s.classList.add("is-current-view"):s.classList.add("is-new-current-view","has-no-events","hide"),r.append(s),typeof o[t]=="object"&&typeof o[t].mounted=="function"&&await o[t].mounted(),s}function O(s,t,r){t&&r==="welcome"&&console.info(`%c Zumly %c ${t}`,"background: #424085; color: white; border-radius: 3px;","color: #424085"),t&&s&&(r==="info"||r===void 0)&&console.info(`%c Zumly %c ${t}`,"background: #6679A3; color: #304157; border-radius: 3px;","color: #6679A3"),t&&r==="warn"&&console.warn(`%c Zumly %c ${t}`,"background: #DCBF53; color: #424085; border-radius: 3px;","color: #424085"),t&&r==="error"&&console.error(`%c Zumly %c ${t}`,"background: #BE4747; color: white; border-radius: 3px;","color: #424085")}function mt(s,t){if(!s||typeof s!="object"){O(!1,"'options' object has to be provided when instance is defined","error");return}t.options=!0,typeof s.mount=="string"?t.mount=s.mount:O(!1,"'mount' must be a string selector","error"),typeof s.initialView=="string"?t.initialView=s.initialView:O(!1,"'initialView' must be a string","error"),s.views&&typeof s.views=="object"?t.views=s.views:O(!1,"'views' must be an object","error"),t.preload=Array.isArray(s.preload)?s.preload:[],t.debug=typeof s.debug=="boolean"?s.debug:!1,t.componentContext=s.componentContext&&typeof s.componentContext=="object"?s.componentContext:new Map;let r=s.transitions&&typeof s.transitions=="object"?s.transitions:null,n=r&&r.cover,o=typeof n=="string"?n.toLowerCase():null,e=o==="width"||o==="height";if(t.cover=e?o:"width",!e&&r&&n!==void 0&&O(!1,`'transitions.cover' must be either "width" or "height". Falling back to "width".`,"warn"),t.duration=r&&typeof r.duration=="string"?r.duration:"1s",t.ease=r&&typeof r.ease=="string"?r.ease:"ease-in-out",!r||r.effects===void 0)t.effects=["none","none"];else{let c=r.effects;if(!Array.isArray(c)||c.length===0||!c.every(i=>typeof i=="string"))O(!1,`'transitions.effects' must be an array of strings: blur|sepia|saturate (or ["none",...]). Falling back to ["none","none"].`,"warn"),t.effects=["none","none"];else{let i=c.map(h=>h.toLowerCase()),a=i[0]==="none",u=["blur","sepia","saturate"];a||[...new Set(i)].every(h=>u.indexOf(h)!==-1)?(t.effects=Et(i),t.effects||(t.effects=["none","none"])):(O(!1,`'transitions.effects' contains invalid values. Falling back to ["none","none"].`,"warn"),t.effects=["none","none"])}}let f=r&&r.driver,l=typeof f=="string"?f.toLowerCase():null,d=typeof f=="function"?f:null;if(l!==null){let c=["css","waapi","none","anime","gsap","motion"];t.transitionDriver=c.includes(l)?l:"css",c.includes(l)||O(!1,`'transitions.driver' must be "css", "waapi", "none", "anime", "gsap", "motion", or a function. Got "${f}". Falling back to "css".`,"warn")}else d!==null?t.transitionDriver=d:t.transitionDriver="css"}var q=class{#t={};constructor(t={}){this.#t=t}#s(t){return typeof t=="function"?"function":t instanceof HTMLElement?"element":typeof t=="object"&&t!==null&&typeof t.render=="function"?"object":typeof t!="string"?"unknown":/^https?:\/\/|^\/|\.html$|\.php$/i.test(t)?"url":t.includes("<")?"html":t.includes("-")?"webcomponent":"unknown"}async resolve(t,r=null){if(typeof t=="string"&&Object.prototype.hasOwnProperty.call(this.#t,t)){let o=this.#t[t];return this.resolve(o,r)}switch(this.#s(t)){case"html":{let o=document.createElement("div");o.innerHTML=t.trim();let e=o.firstElementChild;if(!e)throw new Error("Zumly: view produced no element (html)");return e}case"url":{let o=await fetch(t);if(!o.ok)throw new Error(`Zumly: fetch failed for "${t}" (${o.status})`);let e=await o.text(),f=document.createElement("div");f.innerHTML=e.trim();let l=f.firstElementChild;if(!l)throw new Error("Zumly: view produced no element (url)");return l}case"function":{let o=r&&r.target||document.createElement("div"),e=await t({...r,target:o});if(typeof e=="string")return this.resolve(e,r);if(e instanceof HTMLElement)return e;let f=o.firstElementChild||o;return f.classList.contains("z-view")||f.classList.add("z-view"),f}case"object":{let o=await t.render(r);if(typeof o!="string")throw new Error("Zumly: view render() must return string");return this.resolve(o,r)}case"element":return t.cloneNode(!0);case"webcomponent":return await customElements.whenDefined(t),document.createElement(t);default:throw new Error("Zumly: unknown view type for source")}}};var R=class{#t=new Map;set(t,r,n=null){this.#t.set(t,{node:r.cloneNode(!0),expires:n?Date.now()+n:null})}get(t){let r=this.#t.get(t);return r?r.expires!==null&&Date.now()>r.expires?(this.#t.delete(t),null):r.node.cloneNode(!0):null}has(t){return this.get(t)!==null}invalidate(t){this.#t.delete(t)}clear(){this.#t.clear()}};var xt=300*1e3,N=class{#t;#s;#n;#r=new Map;constructor(t={}){this.#n=t,this.#t=new q(t),this.#s=new R}async get(t,r=null){let n=this.#s.get(t);if(n)return n;if(this.#r.has(t))return this.#r.get(t);let o=(async()=>{let e=await this.#t.resolve(t,r),f=this.#n[t];if(typeof f=="string"){let l=/^https?:\/\/|^\/|\.html$|\.php$/i.test(f)?xt:null;this.#s.set(t,e,l)}return this.#r.delete(t),e})();return this.#r.set(t,o),o}async preloadEager(t,r=null){!Array.isArray(t)||t.length===0||await Promise.all(t.map(n=>this.get(n,r)))}prefetchOnHover(t,r=null){this.get(t,r).catch(()=>{})}scanAndPrefetch(t,r=null){if(!t||!t.querySelectorAll)return;t.querySelectorAll(".zoom-me[data-to]").forEach(o=>{let e=o.dataset.to;e&&this.prefetchOnHover(e,r)})}};function B(s,t){let{type:r,currentView:n,previousView:o,lastView:e,currentStage:f,duration:l,ease:d,canvas:c}=s;if(!n||!o||!f){t();return}r==="zoomIn"?zt(n,o,e,f,l,d,t):r==="zoomOut"?Ot(n,o,e,f,l,d,c,t):t()}function zt(s,t,r,n,o,e,f){s.classList.remove("hide"),s.style.setProperty("--zoom-duration",o),s.style.setProperty("--zoom-ease",e),s.style.setProperty("--current-view-transform-start",n.views[0].backwardState.transform),s.style.setProperty("--current-view-transform-end",n.views[0].forwardState.transform),t.style.setProperty("--zoom-duration",o),t.style.setProperty("--zoom-ease",e),t.style.setProperty("--previous-view-transform-start",n.views[1].backwardState.transform),t.style.setProperty("--previous-view-transform-end",n.views[1].forwardState.transform),r&&(r.style.setProperty("--zoom-duration",o),r.style.setProperty("--zoom-ease",e),r.style.setProperty("--last-view-transform-start",n.views[2].backwardState.transform),r.style.setProperty("--last-view-transform-end",n.views[2].forwardState.transform)),s.style.contentVisibility="auto",t.style.contentVisibility="auto",r&&(r.style.contentVisibility="auto"),s.classList.add("zoom-current-view"),t.classList.add("zoom-previous-view"),r&&r.classList.add("zoom-last-view");let l=r?[s,t,r]:[s,t],d=l.length;function c(i){let a=i.target;a.removeEventListener("animationend",c),kt(a,n),d--,d===0&&f()}l.forEach(i=>i.addEventListener("animationend",c))}function kt(s,t){if(s.classList.contains("is-new-current-view")){let r=t.views[0].forwardState;s.classList.replace("is-new-current-view","is-current-view"),s.classList.remove("zoom-current-view","has-no-events"),s.style.transformOrigin=r.origin,s.style.transform=r.transform;return}if(s.classList.contains("is-previous-view")){let r=t.views[1].forwardState;s.classList.remove("zoom-previous-view"),s.style.transformOrigin=r.origin,s.style.transform=r.transform;return}if(s.classList.contains("is-last-view")){let r=t.views[2].forwardState;s.classList.remove("zoom-last-view"),s.style.transformOrigin=r.origin,s.style.transform=r.transform}}function Ot(s,t,r,n,o,e,f,l){s.classList.add("zoom-current-view-reverse"),t.classList.add("zoom-previous-view-reverse"),r&&r.classList.add("zoom-last-view-reverse"),s.style.setProperty("--zoom-duration",o),s.style.setProperty("--zoom-ease",e),t.style.setProperty("--zoom-duration",o),t.style.setProperty("--zoom-ease",e),r&&r.style.setProperty("--zoom-duration",o);let d=r?[s,t,r]:[s,t],c=d.length;function i(a){let u=a.target;u.removeEventListener("animationend",i),Tt(u,n,f),c--,c===0&&l()}d.forEach(a=>a.addEventListener("animationend",i))}function Tt(s,t,r){if(s.classList.contains("zoom-current-view-reverse")){try{r&&r.removeChild(s)}catch{try{s.parentElement&&r.removeChild(s.parentElement)}catch{}}return}if(s.classList.contains("zoom-previous-view-reverse")){let n=t.views[1].backwardState;s.classList.remove("zoom-previous-view-reverse"),s.style.transformOrigin="0 0",s.style.transform=n.transform;return}if(s.classList.contains("zoom-last-view-reverse")){let n=t.views[2].backwardState;s.classList.remove("zoom-last-view-reverse"),s.style.transformOrigin=n.origin,s.style.transform=n.transform}}function X(s,t){let{type:r,currentView:n,previousView:o,lastView:e,currentStage:f,canvas:l}=s;if(!n||!o||!f){t();return}r==="zoomIn"?(n.classList.remove("hide"),n.style.contentVisibility="auto",o.style.contentVisibility="auto",e&&(e.style.contentVisibility="auto"),H(n,f),H(o,f),e&&H(e,f)):r==="zoomOut"&&(Ft(n,l),o.style.contentVisibility="auto",e&&(e.style.contentVisibility="auto"),Ct(o,f.views[1].backwardState),e&&$t(e,f.views[2].backwardState)),t()}function H(s,t){if(s.classList.contains("is-new-current-view")){let r=t.views[0].forwardState;s.classList.replace("is-new-current-view","is-current-view"),s.classList.remove("zoom-current-view","has-no-events"),s.style.transformOrigin=r.origin,s.style.transform=r.transform;return}if(s.classList.contains("is-previous-view")){let r=t.views[1].forwardState;s.classList.remove("zoom-previous-view","has-no-events"),s.style.transformOrigin=r.origin,s.style.transform=r.transform;return}if(s.classList.contains("is-last-view")){let r=t.views[2].forwardState;s.classList.remove("zoom-last-view","has-no-events"),s.style.transformOrigin=r.origin,s.style.transform=r.transform}}function Ft(s,t){try{t&&t.removeChild(s)}catch{try{s.parentElement&&t.removeChild(s.parentElement)}catch{}}}function Ct(s,t){s.classList.remove("zoom-previous-view-reverse","has-no-events"),s.style.transformOrigin="0 0",s.style.transform=t.transform}function $t(s,t){s.classList.remove("zoom-last-view-reverse","has-no-events"),s.style.transformOrigin=t.origin,s.style.transform=t.transform}function U(s,t){let{type:r,currentView:n,previousView:o,lastView:e,currentStage:f,duration:l,ease:d,canvas:c}=s;if(!n||!o||!f){t();return}let i=Pt(l);r==="zoomIn"?Zt(n,o,e,f,i,d,t):r==="zoomOut"?At(n,o,e,f,i,d,c,t):t()}function Pt(s){if(typeof s=="number")return s;let t=String(s),r=parseFloat(t);return t.includes("ms")?r:t.includes("s")?r*1e3:1e3}function Zt(s,t,r,n,o,e,f){s.classList.remove("hide"),s.style.contentVisibility="auto",t.style.contentVisibility="auto",r&&(r.style.contentVisibility="auto");let l=n.views[0],d=n.views[1],c=r&&n.views[2]?n.views[2]:null;s.style.transformOrigin=l.backwardState.origin,s.style.transform=l.backwardState.transform,t.style.transformOrigin=d.backwardState.origin,t.style.transform=d.backwardState.transform,c&&(r.style.transformOrigin=c.backwardState.origin,r.style.transform=c.backwardState.transform);let i=[];i.push(s.animate([{transform:l.backwardState.transform},{transform:l.forwardState.transform}],{duration:o,easing:e,fill:"forwards"})),i.push(t.animate([{transform:d.backwardState.transform},{transform:d.forwardState.transform}],{duration:o,easing:e,fill:"forwards"})),c&&i.push(r.animate([{transform:c.backwardState.transform},{transform:c.forwardState.transform}],{duration:o,easing:e,fill:"forwards"})),Promise.all(i.map(a=>a.finished)).then(()=>{i.forEach(a=>a.cancel()),G(s,n),G(t,n),r&&G(r,n),f()}).catch(()=>{i.forEach(a=>a.cancel()),f()})}function G(s,t){if(s.classList.contains("is-new-current-view")){let r=t.views[0].forwardState;s.classList.replace("is-new-current-view","is-current-view"),s.classList.remove("has-no-events"),s.style.transformOrigin=r.origin,s.style.transform=r.transform;return}if(s.classList.contains("is-previous-view")){let r=t.views[1].forwardState;s.classList.remove("has-no-events"),s.style.transformOrigin=r.origin,s.style.transform=r.transform;return}if(s.classList.contains("is-last-view")){let r=t.views[2].forwardState;s.classList.remove("has-no-events"),s.style.transformOrigin=r.origin,s.style.transform=r.transform}}function At(s,t,r,n,o,e,f,l){let d=n.views[0],c=n.views[1],i=r&&n.views[2]?n.views[2]:null,a=c.backwardState,u=i?i.backwardState:null;s.style.transformOrigin=d.forwardState.origin,s.style.transform=d.forwardState.transform;let m;function h(){t.style.transformOrigin=c.forwardState.origin,r&&i&&(r.style.transformOrigin=i.forwardState.origin);let v=t.style.transform||getComputedStyle(t).transform||c.forwardState.transform,b=r&&i?r.style.transform||getComputedStyle(r).transform||i.forwardState.transform:null;m=[s.animate([{transform:d.forwardState.transform},{transform:d.backwardState.transform}],{duration:o,easing:e,fill:"forwards"})],m.push(t.animate([{transform:v},{transform:a.transform}],{duration:o,easing:e,fill:"forwards"})),r&&u&&m.push(r.animate([{transform:b},{transform:u.transform}],{duration:o,easing:e,fill:"forwards"})),t.style.removeProperty("transform"),r&&r.style.removeProperty("transform"),Promise.all(m.map(g=>g.finished)).then(w).catch(()=>{m.forEach(g=>g.cancel()),l()})}function w(){m.forEach(v=>v.cancel());try{f&&f.removeChild(s)}catch{try{s.parentElement&&f.removeChild(s.parentElement)}catch{}}t.classList.remove("has-no-events"),t.style.transformOrigin="0 0",t.style.transform=a.transform,r&&u&&(r.style.transformOrigin=u.origin,r.style.transform=u.transform),l()}requestAnimationFrame(()=>{requestAnimationFrame(h)})}function K(s,t){let r=typeof globalThis<"u"&&globalThis.anime;if(!r||typeof r!="function"){typeof console<"u"&&console.warn&&console.warn('Zumly anime driver: Anime.js not loaded. Add <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.2/anime.min.js"><\/script>'),t();return}let{type:n,currentView:o,previousView:e,lastView:f,currentStage:l,duration:d,ease:c,canvas:i}=s;if(!o||!e||!l){t();return}let a=Mt(d);n==="zoomIn"?jt(r,o,e,f,l,a,c,t):n==="zoomOut"?Dt(r,o,e,f,l,a,c,i,t):t()}function Mt(s){if(typeof s=="number")return s;let t=String(s),r=parseFloat(t);return t.includes("ms")?r:t.includes("s")?r*1e3:1e3}function ut(){return{a:1,b:0,c:0,d:1,e:0,f:0}}function It(s){if(!s||s==="none")return ut();let t=String(s).match(/matrix\(([-\d.eE]+),\s*([-\d.eE]+),\s*([-\d.eE]+),\s*([-\d.eE]+),\s*([-\d.eE]+),\s*([-\d.eE]+)\)/);return t?{a:parseFloat(t[1])||1,b:parseFloat(t[2])||0,c:parseFloat(t[3])||0,d:parseFloat(t[4])||1,e:parseFloat(t[5])||0,f:parseFloat(t[6])||0}:ut()}function S(s){return`matrix(${s.a}, ${s.b}, ${s.c}, ${s.d}, ${s.e}, ${s.f})`}function C(s,t,r){return s+(t-s)*r}function $(s,t,r){let n=Math.max(0,Math.min(1,r));return{a:C(s.a,t.a,n),b:C(s.b,t.b,n),c:C(s.c,t.c,n),d:C(s.d,t.d,n),e:C(s.e,t.e,n),f:C(s.f,t.f,n)}}function L(s,t,r){s.style.transformOrigin=t,s.style.transform=r;try{s.getBoundingClientRect()}catch{}return It(getComputedStyle(s).transform)}function W(s,t){if(s.classList.contains("is-new-current-view")){let r=t.views[0].forwardState;s.classList.replace("is-new-current-view","is-current-view"),s.classList.remove("has-no-events"),s.style.transformOrigin=r.origin,s.style.transform=r.transform;return}if(s.classList.contains("is-previous-view")){let r=t.views[1].forwardState;s.classList.remove("has-no-events"),s.style.transformOrigin=r.origin,s.style.transform=r.transform;return}if(s.classList.contains("is-last-view")){let r=t.views[2].forwardState;s.classList.remove("has-no-events"),s.style.transformOrigin=r.origin,s.style.transform=r.transform}}function jt(s,t,r,n,o,e,f,l){t.classList.remove("hide"),t.style.contentVisibility="auto",r.style.contentVisibility="auto",n&&(n.style.contentVisibility="auto");let d=o.views[0],c=o.views[1],i=n&&o.views[2]?o.views[2]:null,a=L(t,d.backwardState.origin,d.backwardState.transform),u=L(t,d.backwardState.origin,d.forwardState.transform),m=L(r,c.backwardState.origin,c.backwardState.transform),h=L(r,c.backwardState.origin,c.forwardState.transform),w=i?L(n,i.backwardState.origin,i.backwardState.transform):null,v=i?L(n,i.backwardState.origin,i.forwardState.transform):null;t.style.transform=S(a),r.style.transform=S(m),i&&(n.style.transform=S(w));let b={value:0};s({targets:b,value:1,duration:e,easing:ht(f),update:()=>{let y=b.value;t.style.transform=S($(a,u,y)),r.style.transform=S($(m,h,y)),i&&(n.style.transform=S($(w,v,y)))},complete:()=>{W(t,o),W(r,o),n&&W(n,o),l()}})}function Dt(s,t,r,n,o,e,f,l,d){let c=o.views[0],i=o.views[1],a=n&&o.views[2]?o.views[2]:null,u=i.backwardState,m=a?a.backwardState:null,h=L(t,c.forwardState.origin,c.forwardState.transform),w=L(t,c.forwardState.origin,c.backwardState.transform),v=L(r,i.forwardState.origin,i.forwardState.transform),b=L(r,i.forwardState.origin,i.backwardState.transform),y=a?L(n,a.forwardState.origin,a.forwardState.transform):null,g=a?L(n,a.forwardState.origin,a.backwardState.transform):null;t.style.transform=S(h),r.style.transform=S(v),a&&(n.style.transform=S(y));let T={value:0};s({targets:T,value:1,duration:e,easing:ht(f),update:()=>{let z=T.value;t.style.transform=S($(h,w,z)),r.style.transform=S($(v,b,z)),a&&(n.style.transform=S($(y,g,z)))},complete:()=>{try{l&&l.removeChild(t)}catch{try{t.parentElement&&l.removeChild(t.parentElement)}catch{}}r.classList.remove("zoom-previous-view-reverse"),r.classList.remove("has-no-events"),r.style.transformOrigin="0 0",r.style.transform=u.transform,n&&m&&(n.classList.remove("zoom-last-view-reverse"),n.style.transformOrigin=m.origin,n.style.transform=m.transform),d()}})}function ht(s){if(typeof s!="string")return"easeInOutQuad";let t=s.toLowerCase();return t==="linear"?"linear":t.includes("ease-in-out")?"easeInOutQuad":t.includes("ease-in")?"easeInQuad":t.includes("ease-out")?"easeOutQuad":t}function J(s,t){let r=typeof globalThis<"u"&&globalThis.gsap;if(!r||typeof r.to!="function"){typeof console<"u"&&console.warn&&console.warn('Zumly GSAP driver: GSAP not loaded. Add <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"><\/script>'),t();return}let{type:n,currentView:o,previousView:e,lastView:f,currentStage:l,duration:d,ease:c,canvas:i}=s;if(!o||!e||!l){t();return}let a=qt(d);n==="zoomIn"?Rt(r,o,e,f,l,a,c,t):n==="zoomOut"?Nt(r,o,e,f,l,a,c,i,t):t()}function qt(s){if(typeof s=="number")return s/1e3;let t=String(s),r=parseFloat(t);return t.includes("ms")?r/1e3:t.includes("s")?r:1}function Q(s,t){if(s.classList.contains("is-new-current-view")){let r=t.views[0].forwardState;s.classList.replace("is-new-current-view","is-current-view"),s.classList.remove("has-no-events"),s.style.transformOrigin=r.origin,s.style.transform=r.transform;return}if(s.classList.contains("is-previous-view")){let r=t.views[1].forwardState;s.classList.remove("has-no-events"),s.style.transformOrigin=r.origin,s.style.transform=r.transform;return}if(s.classList.contains("is-last-view")){let r=t.views[2].forwardState;s.classList.remove("has-no-events"),s.style.transformOrigin=r.origin,s.style.transform=r.transform}}function Rt(s,t,r,n,o,e,f,l){t.classList.remove("hide"),t.style.contentVisibility="auto",r.style.contentVisibility="auto",n&&(n.style.contentVisibility="auto");let d=o.views[0],c=o.views[1],i=n&&o.views[2]?o.views[2]:null;t.style.transformOrigin=d.backwardState.origin,t.style.transform=d.backwardState.transform,r.style.transformOrigin=c.backwardState.origin,r.style.transform=c.backwardState.transform,i&&(n.style.transformOrigin=i.backwardState.origin,n.style.transform=i.backwardState.transform);let a=s.timeline({onComplete:()=>{Q(t,o),Q(r,o),n&&Q(n,o),l()}});a.to(t,{transform:d.forwardState.transform,duration:e,ease:P(f)},0),a.to(r,{transform:c.forwardState.transform,duration:e,ease:P(f)},0),i&&a.to(n,{transform:i.forwardState.transform,duration:e,ease:P(f)},0)}function Nt(s,t,r,n,o,e,f,l,d){let c=o.views[0],i=o.views[1],a=n&&o.views[2]?o.views[2]:null,u=i.backwardState,m=a?a.backwardState:null;t.style.transformOrigin=c.forwardState.origin,t.style.transform=c.forwardState.transform;let h=r.style.transform||getComputedStyle(r).transform||i.forwardState.transform,w=n&&a?n.style.transform||getComputedStyle(n).transform||a.forwardState.transform:null;r.style.transformOrigin=i.forwardState.origin,n&&a&&(n.style.transformOrigin=a.forwardState.origin);let v=s.timeline({onComplete:()=>{try{l&&l.removeChild(t)}catch{try{t.parentElement&&l.removeChild(t.parentElement)}catch{}}r.classList.remove("has-no-events"),r.style.transformOrigin="0 0",r.style.transform=u.transform,n&&m&&(n.style.transformOrigin=m.origin,n.style.transform=m.transform),d()}});v.fromTo(t,{transform:c.forwardState.transform},{transform:c.backwardState.transform,duration:e,ease:P(f)},0),v.fromTo(r,{transform:h},{transform:u.transform,duration:e,ease:P(f)},0),r.style.removeProperty("transform"),n&&m&&(v.fromTo(n,{transform:w},{transform:m.transform,duration:e,ease:P(f)},0),n.style.removeProperty("transform"))}function P(s){if(typeof s!="string")return"power2.inOut";let t=s.toLowerCase();return t==="linear"?"none":t.includes("ease-in-out")?"power2.inOut":t.includes("ease-in")?"power2.in":t.includes("ease-out")?"power2.out":t}function tt(s,t){let r=Yt();if(!r||typeof r!="function"){typeof console<"u"&&console.warn&&console.warn('Zumly Motion driver: Motion not loaded. Add <script src="https://cdn.jsdelivr.net/npm/motion@11/dist/motion.min.js"><\/script>'),t();return}let{type:n,currentView:o,previousView:e,lastView:f,currentStage:l,duration:d,ease:c,canvas:i}=s;if(!o||!e||!l){t();return}let a=_t(d);n==="zoomIn"?Ht(r,o,e,f,l,a,c,t):n==="zoomOut"?Xt(r,o,e,f,l,a,c,i,t):t()}function Yt(){let s=typeof globalThis<"u"?globalThis:typeof window<"u"?window:{};return s.motion?.animate||s.Motion?.animate||s.animate}function _t(s){if(typeof s=="number")return s/1e3;let t=String(s),r=parseFloat(t);return t.includes("ms")?r/1e3:t.includes("s")?r:1}function yt(){return{a:1,b:0,c:0,d:1,e:0,f:0}}function Bt(s){if(!s||s==="none")return yt();let t=String(s).match(/matrix\(([-\d.eE]+),\s*([-\d.eE]+),\s*([-\d.eE]+),\s*([-\d.eE]+),\s*([-\d.eE]+),\s*([-\d.eE]+)\)/);return t?{a:parseFloat(t[1])||1,b:parseFloat(t[2])||0,c:parseFloat(t[3])||0,d:parseFloat(t[4])||1,e:parseFloat(t[5])||0,f:parseFloat(t[6])||0}:yt()}function E(s){return`matrix(${s.a}, ${s.b}, ${s.c}, ${s.d}, ${s.e}, ${s.f})`}function Z(s,t,r){return s+(t-s)*r}function A(s,t,r){let n=Math.max(0,Math.min(1,r));return{a:Z(s.a,t.a,n),b:Z(s.b,t.b,n),c:Z(s.c,t.c,n),d:Z(s.d,t.d,n),e:Z(s.e,t.e,n),f:Z(s.f,t.f,n)}}function x(s,t,r){s.style.transformOrigin=t,s.style.transform=r;try{s.getBoundingClientRect()}catch{}return Bt(getComputedStyle(s).transform)}function V(s,t){if(s.classList.contains("is-new-current-view")){let r=t.views[0].forwardState;s.classList.replace("is-new-current-view","is-current-view"),s.classList.remove("has-no-events"),s.style.transformOrigin=r.origin,s.style.transform=r.transform;return}if(s.classList.contains("is-previous-view")){let r=t.views[1].forwardState;s.classList.remove("has-no-events"),s.style.transformOrigin=r.origin,s.style.transform=r.transform;return}if(s.classList.contains("is-last-view")){let r=t.views[2].forwardState;s.classList.remove("has-no-events"),s.style.transformOrigin=r.origin,s.style.transform=r.transform}}function Ht(s,t,r,n,o,e,f,l){t.classList.remove("hide"),t.style.contentVisibility="auto",r.style.contentVisibility="auto",n&&(n.style.contentVisibility="auto");let d=o.views[0],c=o.views[1],i=n&&o.views[2]?o.views[2]:null,a=x(t,d.backwardState.origin,d.backwardState.transform),u=x(t,d.backwardState.origin,d.forwardState.transform),m=x(r,c.backwardState.origin,c.backwardState.transform),h=x(r,c.backwardState.origin,c.forwardState.transform),w=i?x(n,i.backwardState.origin,i.backwardState.transform):null,v=i?x(n,i.backwardState.origin,i.forwardState.transform):null;t.style.transform=E(a),r.style.transform=E(m),i&&(n.style.transform=E(w)),s(0,1,{duration:e,ease:vt(f),onUpdate:y=>{let g=y;t.style.transform=E(A(a,u,g)),r.style.transform=E(A(m,h,g)),i&&(n.style.transform=E(A(w,v,g)))}}).then(()=>{V(t,o),V(r,o),n&&V(n,o),l()}).catch(()=>l())}function Xt(s,t,r,n,o,e,f,l,d){let c=o.views[0],i=o.views[1],a=n&&o.views[2]?o.views[2]:null,u=i.backwardState,m=a?a.backwardState:null,h=x(t,c.forwardState.origin,c.forwardState.transform),w=x(t,c.forwardState.origin,c.backwardState.transform),v=x(r,i.forwardState.origin,i.forwardState.transform),b=x(r,i.forwardState.origin,i.backwardState.transform),y=a?x(n,a.forwardState.origin,a.forwardState.transform):null,g=a?x(n,a.forwardState.origin,a.backwardState.transform):null;t.style.transform=E(h),r.style.transform=E(v),a&&(n.style.transform=E(y)),s(0,1,{duration:e,ease:vt(f),onUpdate:z=>{let k=z;t.style.transform=E(A(h,w,k)),r.style.transform=E(A(v,b,k)),a&&(n.style.transform=E(A(y,g,k)))}}).then(()=>{try{l&&l.removeChild(t)}catch{try{t.parentElement&&l.removeChild(t.parentElement)}catch{}}r.classList.remove("zoom-previous-view-reverse"),r.classList.remove("has-no-events"),r.style.transformOrigin="0 0",r.style.transform=u.transform,n&&m&&(n.classList.remove("zoom-last-view-reverse"),n.style.transformOrigin=m.origin,n.style.transform=m.transform),d()}).catch(()=>d())}function vt(s){if(typeof s!="string")return"easeInOut";let t=s.toLowerCase();return t==="linear"?"linear":t.includes("ease-in-out")?"easeInOut":t.includes("ease-in")?"easeIn":t.includes("ease-out")?"easeOut":s}function pt(s){if(typeof s=="function")return{runTransition(r,n){s(r,n)}};switch(typeof s=="string"?s.toLowerCase():"css"){case"waapi":return{runTransition:U};case"none":return{runTransition:X};case"anime":return{runTransition:K};case"gsap":return{runTransition:J};case"motion":return{runTransition:tt};default:return{runTransition:B}}}var Y=class{constructor(t){this.storedViews=[],this.currentStage=null,this.storedPreviousScale=[1],this.debug=!1,this.trace=[],this.blockEvents=!1,this.touchstartX=0,this.touchstartY=0,this.touchendX=0,this.touchendY=0,this.touching=!1,mt(t,this),this.options?(this.transitionDriver=pt(this.transitionDriver),this._onZoom=this.onZoom.bind(this),this._onTouchStart=this.onTouchStart.bind(this),this._onTouchEnd=this.onTouchEnd.bind(this),this._onKeyUp=this.onKeyUp.bind(this),this._onWeel=this.onWeel.bind(this),this.prefetcher=new N(this.views),this.canvas=document.querySelector(this.mount),this.canvas.setAttribute("tabindex",0),this.canvas.addEventListener("mouseup",this._onZoom,!1),this.canvas.addEventListener("touchend",this._onZoom,!1),this.canvas.addEventListener("touchstart",this._onTouchStart,{passive:!0}),this.canvas.addEventListener("touchend",this._onTouchEnd,!1),this.canvas.addEventListener("keyup",this._onKeyUp,!1),this.canvas.addEventListener("wheel",this._onWeel,{passive:!0}),this.canvas.addEventListener("mouseover",this._onPrefetchHover=r=>{r.target.classList.contains("zoom-me")&&r.target.dataset.to&&this.prefetcher.prefetchOnHover(r.target.dataset.to,{trigger:r.target,...r.target.dataset})},{passive:!0})):this.notify("is unable to start: no {options} have been passed to the Zumly's instance.","error")}storeViews(t){this.tracing("storedViews()"),this.storedViews.push(t),this.debug&&console.debug("Zumly storedViews",t)}setPreviousScale(t){this.tracing("setPreviousScale()"),this.storedPreviousScale.push(t)}tracing(t){if(this.debug)if(t==="ended"){let r=this.trace.map((n,o)=>`${o===0?`Instance ${this.instance}: ${n}`:`${n}`}`).join(" > ");this.notify(r),this.trace=[]}else this.trace.push(t)}notify(t,r){return O(this.debug,t,r)}zoomLevel(){return this.storedViews.length}async init(){if(this.options){this.tracing("init()"),this.preload&&this.preload.length&&await this.prefetcher.preloadEager(this.preload,null);let t=await this.prefetcher.get(this.initialView,null),r=await _(t,this.initialView,this.canvas,!0,this.views,this.componentContext);this.prefetcher.scanAndPrefetch(r,null),this.storeViews({zoomLevel:this.storedViews.length,views:[{viewName:this.initialView,backwardState:{origin:"0 0",transform:""}}]})}}async zoomIn(t){this.tracing("zoomIn()");let r=this.canvas,n=r.getBoundingClientRect();var o=n.left,e=n.top;let f=this.storedPreviousScale[this.storedPreviousScale.length-1];this.tracing("getView()");let l={trigger:t,target:document.createElement("div"),context:this.componentContext,props:Object.assign({},t.dataset)},d=await this.prefetcher.get(t.dataset.to,l);this.prefetcher.scanAndPrefetch(d,l);var c=await _(d,t.dataset.to,r,!1,this.views,this.componentContext);if(c){t.classList.add("zoomed");let p=t.getBoundingClientRect();var i=r.querySelector(".is-current-view"),a=r.querySelector(".is-previous-view"),u=r.querySelector(".is-last-view");c.style.contentVisibility="hidden",i.style.contentVisibility="hidden",a!==null&&(a.style.contentVisibility="hidden"),u!==null&&(u.style.contentVisibility="hidden"),u!==null&&r.removeChild(u);let F=c.getBoundingClientRect(),nt=F.width/p.width,bt=1/nt,ot=F.height/p.height,St=1/ot;var m=t.dataset.withDuration||this.duration,h=t.dataset.withEase||this.ease,w=this.effects[0],v=this.effects[1],b=this.cover,y,g;b==="width"?(y=nt,g=bt):b==="height"&&(y=ot,g=St),this.setPreviousScale(y);var T=`translate(${p.x-o+(p.width-F.width*g)/2}px, ${p.y-e+(p.height-F.height*g)/2}px) scale(${g})`;c.style.transform=T,i.classList.replace("is-current-view","is-previous-view");let D=i.getBoundingClientRect();var z=i.style.transform;i.style.transformOrigin=`${p.x+p.width/2-D.x}px ${p.y+p.height/2-D.y}px`;let it=n.width/2-p.width/2-p.x+D.x,et=n.height/2-p.height/2-p.y+D.y,at=`translate(${it}px, ${et}px) scale(${y})`;i.style.transform=at;var k=t.getBoundingClientRect(),gt=`translate(${k.x-o+(k.width-F.width)/2}px, ${k.y-e+(k.height-F.height)/2}px)`;if(a!==null){a.classList.replace("is-previous-view","is-last-view");var st=a.style.transform,I=i.getBoundingClientRect();a.style.transform=`translate(${it-o}px, ${et-e}px) scale(${y*f})`;var j=a.querySelector(".zoomed").getBoundingClientRect();a.style.transform=st,i.style.transform=z;var rt=i.getBoundingClientRect(),wt=`translate(${n.width/2-p.width/2-p.x+(rt.x-j.x)+I.x-o+(I.width-j.width)/2}px, ${n.height/2-p.height/2-p.y+(rt.y-j.y)+I.y-e+(I.height-j.height)/2}px) scale(${y*f})`}else i.style.transform=z;var M={zoomLevel:this.storedViews.length,views:[]};let ct=c?{viewName:c.dataset.viewName,backwardState:{origin:c.style.transformOrigin,duration:m,ease:h,transform:T},forwardState:{origin:c.style.transformOrigin,duration:m,ease:h,transform:gt}}:null,ft=i?{viewName:i.dataset.viewName,backwardState:{origin:i.style.transformOrigin,duration:m,ease:h,transform:z},forwardState:{origin:i.style.transformOrigin,duration:m,ease:h,transform:at}}:null,lt=a?{viewName:a.dataset.viewName,backwardState:{origin:a.style.transformOrigin,duration:m,ease:h,transform:st},forwardState:{origin:a.style.transformOrigin,duration:m,ease:h,transform:wt}}:null,dt=u?{viewName:u}:null;ct!==null&&M.views.push(ct),ft!==null&&M.views.push(ft),lt!==null&&M.views.push(lt),dt!==null&&M.views.push(dt),this.storeViews(M),this.currentStage=this.storedViews[this.storedViews.length-1],this.tracing("setCSSVariables()"),this.blockEvents=!0;let Lt={type:"zoomIn",currentView:c,previousView:i,lastView:a,currentStage:this.currentStage,duration:m,ease:h};this.transitionDriver.runTransition(Lt,()=>{this.blockEvents=!1,this.tracing("ended")})}}zoomOut(){this.tracing("zoomOut()");let t=this.canvas;var r=t.querySelector(".is-current-view"),n=t.querySelector(".is-previous-view");if(!r||!n){this.notify("zoomOut: current or previous view not found (animation may still be running)","warn");return}this.blockEvents=!0,this.storedPreviousScale.pop(),this.currentStage=this.storedViews[this.storedViews.length-1];let o=this.currentStage.views[3];var e=t.querySelector(".is-last-view");this.tracing("setCSSVariables()");let f=n.querySelector(".zoomed");if(f&&f.classList.remove("zoomed"),n.classList.replace("is-previous-view","is-current-view"),e!==null&&(e.classList.replace("is-last-view","is-previous-view"),e.classList.remove("hide")),o!==void 0&&o.viewName instanceof Node){t.prepend(o.viewName);var l=t.querySelector(".z-view:first-child");l&&(l.style.contentVisibility="auto",l.classList.add("hide"))}let d=this.currentStage.views[0]?.forwardState?.duration??this.duration,c=this.currentStage.views[0]?.forwardState?.ease??this.ease,i={type:"zoomOut",currentView:r,previousView:n,lastView:e,currentStage:this.currentStage,duration:d,ease:c,canvas:t};this.transitionDriver.runTransition(i,()=>{this.blockEvents=!1,this.tracing("ended")}),this.storedViews.pop()}onZoom(t){this.storedViews.length>1&&!this.blockEvents&&!t.target.classList.contains("zoom-me")&&t.target.closest(".is-current-view")===null&&!this.touching&&(this.tracing("onZoom()"),t.stopPropagation(),this.zoomOut()),!this.blockEvents&&t.target.classList.contains("zoom-me")&&!this.touching&&(this.tracing("onZoom()"),t.stopPropagation(),this.zoomIn(t.target))}onKeyUp(t){this.tracing("onKeyUp()"),(t.key==="ArrowLeft"||t.key==="ArrowDown")&&(t.preventDefault(),this.storedViews.length>1&&!this.blockEvents?this.zoomOut():this.notify(`is on level zero. Can't zoom out. Trigger: ${t.key}`,"warn")),(t.key==="ArrowRight"||t.key==="ArrowUp")&&(t.preventDefault(),this.notify(t.key+"has not actions defined"))}onWeel(t){this.blockEvents||(this.tracing("onWeel()"),t.deltaY<0,t.deltaY>0&&this.storedViews.length>1&&!this.blockEvents&&this.zoomOut())}onTouchStart(t){this.tracing("onTouchStart()"),this.touching=!0,this.touchstartX=t.changedTouches[0].screenX,this.touchstartY=t.changedTouches[0].screenY}onTouchEnd(t){this.blockEvents||(this.tracing("onTouchEnd()"),this.touchendX=t.changedTouches[0].screenX,this.touchendY=t.changedTouches[0].screenY,this.handleGesture(t))}handleGesture(t){t.stopPropagation(),this.tracing("handleGesture()"),this.touchendX<this.touchstartX-30&&(this.storedViews.length>1&&!this.blockEvents?(this.tracing("swipe left"),this.zoomOut()):this.notify("is on level zero. Can't zoom out. Trigger: Swipe left","warn")),this.touchendY<this.touchstartY-10&&(this.storedViews.length>1&&!this.blockEvents?this.tracing("swipe up"):this.notify("is on level zero. Can't zoom out. Trigger: Swipe up","warn")),this.touchendY===this.touchstartY&&!this.blockEvents&&t.target.classList.contains("zoom-me")&&this.touching&&(this.touching=!1,this.tracing("tap"),t.preventDefault(),this.zoomIn(t.target)),this.touchendY===this.touchstartY&&this.storedViews.length>1&&!this.blockEvents&&!t.target.classList.contains("zoom-me")&&t.target.closest(".is-current-view")===null&&this.touching&&(this.touching=!1,this.tracing("tap"),this.zoomOut())}};window.Zumly=Y;