zumly 0.92.6 → 0.97.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -23,7 +23,7 @@
23
23
 
24
24
  ## Status
25
25
 
26
- Zumly is under active development. The core stack is stable: depth and lateral navigation, pluggable transition drivers (CSS, WAAPI, none, Anime.js, GSAP, Motion, custom), unified nav UI (depth + lateral, eight positions), view resolver and prefetch cache, optional **plugin** API (<code>.use()</code>), and the **hash router** plugin. View sources include HTML strings, URLs, async functions, objects with <code>render()</code>, DOM nodes, and web component tags.
26
+ Zumly is under active development. It supports depth and lateral navigation, pluggable transition drivers (CSS, WAAPI, none, Anime.js, GSAP, Motion, custom), separate depth and lateral navigation controls, a view resolver and prefetch cache, an optional **plugin** API (<code>.use()</code>), and the **hash router** plugin. View sources include HTML strings, URLs, async functions, objects with <code>render()</code>, DOM nodes, and web component tags.
27
27
 
28
28
  Zoom-out geometry uses batched DOM reads plus pure math where possible to cut layout thrash before animations (see [Geometry optimization](docs/geometry-optimization.md)).
29
29
 
@@ -251,12 +251,13 @@ Each entry in `views` is a **view source**. The resolver detects the type and re
251
251
  | **Async function** | `(ctx) => fetch(...).then(r => r.text())` or return `HTMLElement` | No |
252
252
  | **Object with `render()`** | `{ render(ctx) { return '<div>…</div>' }, mounted?() }` | No |
253
253
  | **Web component** | `'my-view'` (string with hyphen, not a key in `views`) | No |
254
+ | **DOM element** | `document.createElement('div')` | No; cloned on resolution |
254
255
 
255
- **View pipeline:** Resolve → normalize `.z-view` → insert into canvas → call `mounted()` (if present). Static/URL views are cloned from cache on each `get()` so consumers cannot mutate the stored node.
256
+ **View pipeline:** Resolve → normalize `.z-view` → insert into canvas → call `mounted()` (if present). Static/URL views are cloned on every retrieval, including simultaneous requests. DOM element sources are also cloned; listeners attached directly to the original element are not copied.
256
257
 
257
258
  ### Framework integration
258
259
 
259
- Zumly is framework-agnostic. Since views resolve to DOM elements, any framework that can mount into a container works out of the box. Use **function views** or **object views** to bridge your framework:
260
+ Use **function views** or **object views** to mount framework components. Register their teardown with `onCleanup()` so the framework releases its resources when the view is discarded:
260
261
 
261
262
  **React**
262
263
 
@@ -269,8 +270,9 @@ const app = new Zumly({
269
270
  initialView: 'home',
270
271
  views: {
271
272
  home: '<div class="z-view"><div class="zoom-me" data-to="dashboard" data-id="42">Open</div></div>',
272
- dashboard: ({ target, props }) => {
273
+ dashboard: ({ target, props, onCleanup }) => {
273
274
  const root = createRoot(target)
275
+ onCleanup(() => root.unmount())
274
276
  root.render(<Dashboard id={props.id} />)
275
277
  }
276
278
  }
@@ -284,8 +286,10 @@ import { createApp } from 'vue'
284
286
  import Dashboard from './Dashboard.vue'
285
287
 
286
288
  views: {
287
- dashboard: ({ target, props }) => {
288
- createApp(Dashboard, { id: props.id }).mount(target)
289
+ dashboard: ({ target, props, onCleanup }) => {
290
+ const component = createApp(Dashboard, { id: props.id })
291
+ onCleanup(() => component.unmount())
292
+ component.mount(target)
289
293
  }
290
294
  }
291
295
  ```
@@ -296,8 +300,9 @@ views: {
296
300
  import Dashboard from './Dashboard.svelte'
297
301
 
298
302
  views: {
299
- dashboard: ({ target, props }) => {
300
- new Dashboard({ target, props: { id: props.id } })
303
+ dashboard: ({ target, props, onCleanup }) => {
304
+ const component = new Dashboard({ target, props: { id: props.id } })
305
+ onCleanup(() => component.$destroy())
301
306
  }
302
307
  }
303
308
  ```
@@ -306,8 +311,9 @@ views: {
306
311
 
307
312
  ```ts
308
313
  views: {
309
- dashboard: ({ target, props }) => {
314
+ dashboard: ({ target, props, onCleanup }) => {
310
315
  const compRef = viewContainerRef.createComponent(DashboardComponent)
316
+ onCleanup(() => compRef.destroy())
311
317
  compRef.instance.id = props.id
312
318
  target.appendChild(compRef.location.nativeElement)
313
319
  }
@@ -316,19 +322,40 @@ views: {
316
322
 
317
323
  **Key points:**
318
324
 
319
- - The `target` parameter is a fresh `<div>` created by Zumly mount your component there.
325
+ - The `target` parameter is a fresh `<div>` created by Zumly. When a function mounts into it and returns nothing, Zumly preserves that container and all its children. It defaults to the canvas width and height; set `target.style.width` and `target.style.height` for a smaller view.
320
326
  - `props` contains data attributes from the trigger element (`data-id="42"` → `props.id`).
321
327
  - `componentContext` (constructor option) is passed as `context` to all function/object views — use it for shared state (router, store, API client).
322
- - Function views are **never cached** — they resolve fresh each time, so framework components get proper lifecycle management.
328
+ - Function/object views are **never cached or prefetched** — they render only when requested by navigation. Initial views receive the same context contract, with empty `props`.
329
+ - Call `onCleanup(fn)` to register unmount, unsubscribe, or timer cleanup. Callbacks run once when the view is permanently removed, rendering fails, an abandoned async result arrives, or the instance is destroyed. Temporarily detached depth views and kept-alive lateral views retain their resources until discarded. Async callbacks are started without waiting for them.
323
330
  - Use `mounted()` (object views) for post-insertion setup — it runs after the node is in the DOM.
324
- - Zumly handles wrapped elements (e.g. Svelte's extra parent div) in its cleanup logic.
331
+ - Returning an `HTMLElement` from a function or `render()` transfers that resolved view instance to Zumly; prefer `onCleanup()` over relying on DOM removal to unmount framework components.
325
332
 
326
333
  ### Preload and prefetch
327
334
 
328
- - **Eager preload:** `preload: ['viewA', 'viewB']` — those views are resolved and cached during `init()`.
335
+ - **Eager preload:** `preload: ['viewA', 'viewB']` — static HTML and URL views are resolved and cached during `init()`; dynamic views and custom elements are skipped.
329
336
  - **Hover prefetch:** `mouseover` on a `.zoom-me[data-to]` trigger prefetches its target in the background.
330
337
  - **Focus prefetch:** `focusin` on a `.zoom-me[data-to]` also prefetches (for keyboard/accessibility).
331
- - **Scan prefetch:** When a view becomes current, all `.zoom-me[data-to]` targets inside it are prefetched in the background. This works on touch devices where hover is unavailable.
338
+ - **Scan prefetch:** When a view becomes current, its unique `.zoom-me[data-to]` targets enter a background queue. This works on touch devices where hover is unavailable. The queue keeps up to 32 pending targets and starts at most two resolutions concurrently, yielding between starts.
339
+
340
+ All prefetch strategies skip functions, objects, and custom elements to avoid rendering components speculatively.
341
+
342
+ Prefetch warms a template without cloning it. Navigation gets an independent clone when it needs the view. New speculative work pauses during navigation and resumes after completion; a requested view can load immediately without waiting for a queue slot. Already-running requests may still finish. Explicit `preload` remains eager.
343
+
344
+ The template cache holds up to 64 entries, evicts the least recently used, and expires URL responses after five minutes. Eviction only affects reusable templates: mounted views, form values, history, and `keepAlive` nodes stay intact. An evicted or unprefetched target resolves normally when visited.
345
+
346
+ ### Navigation completion and accessibility
347
+
348
+ `zoomTo()`, `zoomIn()`, `goTo()`, `zoomOut()`, and `back()` return promises that settle after the transition and its completion hooks. Await each call when navigating through several views:
349
+
350
+ ```js
351
+ await app.zoomTo('detail')
352
+ await app.zoomTo('deep')
353
+ await app.back()
354
+ ```
355
+
356
+ Calls made while another view is loading or animating are ignored. Failed navigation resolves after recovery and reports the error through Zumly's diagnostics. `init()` is idempotent, and `destroy()` releases pending navigation promises and discards late view results.
357
+
358
+ Generic `.zoom-me` triggers receive keyboard focus and support Enter/Space. Native buttons and links retain their semantics; navigation controls also support keyboard activation. Arrow navigation ignores text inputs and editable controls. Background views become `inert` and hidden from assistive technology until active again. Focus moves to the first usable control in the current view, or to the view itself. Zumly uses instant transitions when `prefers-reduced-motion: reduce` is active.
332
359
 
333
360
  ### Plugins
334
361
 
@@ -388,7 +415,7 @@ The UMD/IIFE bundle attaches the same plugin as `Zumly.Router`. There is no sepa
388
415
 
389
416
  ### Requirements
390
417
 
391
- - Node.js >= 18 (or 16+ with ES module support)
418
+ - Use Node.js 22+ for development. The distributed package entry points support Node.js >= 18; constructing a Zumly instance requires a browser DOM.
392
419
 
393
420
  ### Commands
394
421
 
@@ -403,6 +430,12 @@ npm run dev
403
430
  npm run test:install-browsers
404
431
  npm run test
405
432
 
433
+ # Run the suite in Chromium, Firefox, and WebKit
434
+ npm run test:browsers
435
+
436
+ # Compile and verify the installed npm tarball's public exports
437
+ npm run test:pack
438
+
406
439
  # Run tests with coverage
407
440
  npm run test:coverage
408
441
 
@@ -410,7 +443,7 @@ npm run test:coverage
410
443
  npm run build
411
444
  ```
412
445
 
413
- Tests use [Vitest](https://vitest.dev/) with the browser provider ([Playwright](https://playwright.dev/)), same setup as [SnapDOM](https://github.com/zumerlab/snapdom). Run `npm run test:install-browsers` once (or after upgrading Playwright) to install Chromium.
446
+ Tests use [Vitest](https://vitest.dev/) with the browser provider ([Playwright](https://playwright.dev/)). Run `npm run test:install-browsers` once (or after upgrading Playwright) to install Chromium, Firefox, and WebKit. `npm test` defaults to Chromium; `BROWSER=firefox` or `BROWSER=webkit` selects an individual engine. Run `npm run test:browsers` and `npm run test:pack` locally to check all three engines and the package exports.
414
447
 
415
448
  ### Building
416
449
 
@@ -420,6 +453,8 @@ npm run compile
420
453
 
421
454
  Output is in the `dist/` folder.
422
455
 
456
+ `npm run build` compiles via `prepack` and creates a local tarball. It does not commit, push, or publish.
457
+
423
458
  ## Changelog
424
459
 
425
460
  See [CHANGELOG.md](CHANGELOG.md) for version history.
@@ -435,10 +470,12 @@ See [CHANGELOG.md](CHANGELOG.md) for version history.
435
470
  - Resize correction (translate/origin scaling; deferred while transitioning)
436
471
  - Pluggable drivers (CSS, WAAPI, none, Anime.js, GSAP, Motion, custom)
437
472
  - Batched zoom-out reads + math helpers to reduce reflow (see [geometry-optimization.md](docs/geometry-optimization.md))
473
+ - Keyboard trigger activation, focus management, inactive-view isolation, and reduced-motion support
474
+ - Per-view resource cleanup with `ViewContext.onCleanup()`
438
475
 
439
476
  **Planned:**
440
477
  - Router deep-linking (open a multi-level hash cold)
441
- - Accessibility (focus moves, broader ARIA)
478
+ - Further accessibility testing with assistive technologies
442
479
 
443
480
  Details and more topics: [docs/roadMap.md](docs/roadMap.md). Driver contract and helpers: [docs/DRIVER_API.md](docs/DRIVER_API.md).
444
481
 
@@ -448,7 +485,7 @@ Details and more topics: [docs/roadMap.md](docs/roadMap.md). Driver contract and
448
485
 
449
486
  ## Origin
450
487
 
451
- Zumly is a reimagined, framework-agnostic zoom engine inspired by [Zircle UI](https://github.com/zircleUI/zircleUI). Part of the [Zumerlab](https://github.com/zumerlab) ecosystem — use it with [Orbit](https://github.com/zumerlab/orbit) for radial layouts and [SnapDOM](https://github.com/zumerlab/snapdom) for lightweight DOM diffing.
488
+ Zumly is a reimagined, framework-agnostic zoom engine inspired by [Zircle UI](https://github.com/zircleUI/zircleUI). Part of the [Zumerlab](https://github.com/zumerlab) ecosystem — use it with [Orbit](https://github.com/zumerlab/orbit) for radial layouts and [SnapDOM](https://github.com/zumerlab/snapdom) for DOM-to-image capture. Use [SnapDIFF](https://github.com/zumerlab/snapdiff) to compare captures for visual regression testing.
452
489
 
453
490
  ## License
454
491
 
package/dist/zumly.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * zumly
3
- * v.0.92.6
3
+ * v.0.97.0
4
4
  * Author Juan Martin Muda - Zumerlab
5
5
  * License MIT
6
6
  */
7
- var Tt=Object.defineProperty;var Le=Object.getOwnPropertyDescriptor;var ze=Object.getOwnPropertyNames;var ke=Object.prototype.hasOwnProperty;var Ce=(r,t)=>{for(var e in t)Tt(r,e,{get:t[e],enumerable:!0})},Oe=(r,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of ze(t))!ke.call(r,n)&&n!==e&&Tt(r,n,{get:()=>t[n],enumerable:!(s=Le(t,n))||s.enumerable});return r};var Ae=r=>Oe(Tt({},"__esModule",{value:!0}),r);var ts={};Ce(ts,{Zumly:()=>tt,ZumlyRouter:()=>Ot,default:()=>Je});module.exports=Ae(ts);var ft=class{#t={};constructor(t={}){this.#t=t}#e(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,e=null){if(typeof t=="string"&&Object.prototype.hasOwnProperty.call(this.#t,t)){let n=this.#t[t];return this.resolve(n,e)}switch(this.#e(t)){case"html":{let n=document.createElement("div");n.innerHTML=t.trim();let o=n.firstElementChild;if(!o)throw new Error("Zumly: view produced no element (html)");return o}case"url":{let n=new AbortController,o=setTimeout(()=>n.abort(),1e4),i;try{i=await fetch(t,{signal:n.signal})}finally{clearTimeout(o)}if(!i.ok)throw new Error(`Zumly: fetch failed for "${t}" (${i.status})`);let a=await i.text(),l=document.createElement("div");l.innerHTML=a.trim();let c=l.firstElementChild;if(!c)throw new Error("Zumly: view produced no element (url)");return c}case"function":{let n=e&&e.target||document.createElement("div"),o=await t({...e,target:n});if(typeof o=="string")return this.resolve(o,e);if(o instanceof HTMLElement)return o;let i=n.firstElementChild||n;return i.classList.contains("z-view")||i.classList.add("z-view"),i}case"object":{let n=await t.render(e);if(typeof n!="string")throw new Error("Zumly: view render() must return string");return this.resolve(n,e)}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")}}};async function st(r,t,e,s,n,o){if(!r||!r.classList){let i=document.createElement("div");i.classList.add("z-view"),r&&i.appendChild(r),r=i}else r.classList.contains("z-view")||r.classList.add("z-view");return r.dataset.viewName=t,r.getAttribute("aria-label")||r.setAttribute("aria-label",`View: ${t}`),r.style.transformOrigin="0 0",r.style.position="absolute",s?r.classList.add("is-current-view"):r.classList.add("is-new-current-view","has-no-events","hide"),e.append(r),typeof n[t]=="object"&&typeof n[t].mounted=="function"&&await n[t].mounted(),r}function L(r,t,e){t&&e==="welcome"&&console.info(`%c Zumly %c ${t}`,"background: #424085; color: white; border-radius: 3px;","color: #424085"),t&&r&&(e==="info"||e===void 0)&&console.info(`%c Zumly %c ${t}`,"background: #6679A3; color: #304157; border-radius: 3px;","color: #6679A3"),t&&e==="warn"&&console.warn(`%c Zumly %c ${t}`,"background: #DCBF53; color: #424085; border-radius: 3px;","color: #424085"),t&&e==="error"&&console.error(`%c Zumly %c ${t}`,"background: #BE4747; color: white; border-radius: 3px;","color: #424085")}function Ht(r,t){if(t.isValid=!1,!r||typeof r!="object"){L(!1,"'options' object has to be provided when instance is defined","error");return}if(typeof r.mount!="string"){L(!1,"'mount' must be a string selector","error");return}if(t.mount=r.mount,typeof r.initialView!="string"){L(!1,"'initialView' must be a string","error");return}if(t.initialView=r.initialView,!r.views||typeof r.views!="object"){L(!1,"'views' must be an object","error");return}t.views=r.views,t.isValid=!0,t.preload=Array.isArray(r.preload)?r.preload:[],t.debug=typeof r.debug=="boolean"?r.debug:!1,t.componentContext=r.componentContext&&typeof r.componentContext=="object"?r.componentContext:new Map;let e=r.transitions&&typeof r.transitions=="object"?r.transitions:null,s=e&&e.cover,n=typeof s=="string"?s.toLowerCase():null,o=n==="width"||n==="height";t.cover=o?n:"width",!o&&e&&s!==void 0&&L(!1,`'transitions.cover' must be either "width" or "height". Falling back to "width".`,"warn"),t.duration=e&&typeof e.duration=="string"?e.duration:"1s",t.ease=e&&typeof e.ease=="string"?e.ease:"ease-in-out",t.deferred=typeof r.deferred=="boolean"?r.deferred:!1;let i=e&&e.hideTrigger;i===!0||i==="fade"?t.hideTrigger=i:(t.hideTrigger=!1,i!=null&&i!==!1&&L(!1,`'transitions.hideTrigger' must be true or "fade". Falling back to false.`,"warn"));let a=e&&e.effects;Array.isArray(a)&&a.length>=2&&typeof a[0]=="string"&&typeof a[1]=="string"?t.effects=[a[0],a[1]]:Array.isArray(a)&&a.length===1&&typeof a[0]=="string"?t.effects=[a[0],a[0]]:(t.effects=["none","none"],a!=null&&L(!1,`'transitions.effects' must be an array of 1-2 CSS filter strings (e.g. ["blur(3px)", "blur(8px) saturate(0)"]). Falling back to no effects.`,"warn"));let l=e&&e.driver,c=typeof l=="string"?l.toLowerCase():null,f=typeof l=="function"?l:null;if(c!==null){let d=["css","waapi","none","anime","gsap","motion"];t.transitionDriver=d.includes(c)?c:"css",d.includes(c)||L(!1,`'transitions.driver' must be "css", "waapi", "none", "anime", "gsap", "motion", or a function. Got "${l}". Falling back to "css".`,"warn")}else f!==null?t.transitionDriver=f:t.transitionDriver="css";let u=e&&e.stagger;typeof u=="number"&&u>0?t.stagger=u:(t.stagger=0,u!=null&&u!==0&&L(!1,"'transitions.stagger' must be a positive number (ms). Falling back to 0 (disabled).","warn")),t.parallax=0;let h=r.lateralNav;if(h===!1)t.lateralNav=!1;else if(h&&typeof h=="object"){let d=typeof h.mode=="string"?h.mode.toLowerCase():null,g=d==="auto"||d==="always";d&&!g&&L(!1,`'lateralNav.mode' must be "auto" or "always". Falling back to "auto".`,"warn");let v=null;if(Array.isArray(h.siblings))v=h.siblings.filter(w=>typeof w=="string"&&w),v.length<2&&(L(!1,"'lateralNav.siblings' needs at least 2 view names. Ignoring.","warn"),v=null);else if(h.siblings&&typeof h.siblings=="object"){v={};for(let[w,b]of Object.entries(h.siblings))if(Array.isArray(b)){let _=b.filter(S=>typeof S=="string"&&S);_.length>=2&&(v[w]=_)}Object.keys(v).length===0&&(v=null)}else h.siblings!==void 0&&L(!1,"'lateralNav.siblings' must be an array of view names or a { parentView: [...] } map. Ignoring.","warn");t.lateralNav={mode:g?d:"auto",arrows:typeof h.arrows=="boolean"?h.arrows:!0,dots:typeof h.dots=="boolean"?h.dots:!0,keepAlive:h.keepAlive===!0||h.keepAlive==="visible"?h.keepAlive:!1,siblings:v}}else t.lateralNav={mode:"auto",arrows:!0,dots:!0,keepAlive:!1,siblings:null};let m=r.depthNav;if(m===!1)t.depthNav=!1;else if(m&&typeof m=="object"){let d=typeof m.position=="string"?m.position.toLowerCase():null,g=d==="bottom-left"||d==="top-left";d&&!g&&L(!1,`'depthNav.position' must be "bottom-left" or "top-left". Falling back to "bottom-left".`,"warn"),t.depthNav={position:g?d:"bottom-left"}}else t.depthNav={position:"bottom-left"};let y=r.lateralNav&&typeof r.lateralNav=="object"?r.lateralNav.position:void 0;if(t.lateralNav&&typeof t.lateralNav=="object"){let d=y==="bottom-center"||y==="top-center";y&&!d&&L(!1,`'lateralNav.position' must be "bottom-center" or "top-center". Falling back to "bottom-center".`,"warn"),t.lateralNav.position=d?y:"bottom-center"}let p=r.inputs;p&&typeof p=="object"?t.inputs={wheel:typeof p.wheel=="boolean"?p.wheel:!0,keyboard:typeof p.keyboard=="boolean"?p.keyboard:!0,click:typeof p.click=="boolean"?p.click:!0,touch:typeof p.touch=="boolean"?p.touch:!0}:t.inputs={wheel:!0,keyboard:!0,click:!0,touch:!0}}function jt(r,t,e,s,n){let o=e/r,i=s/t;return n==="height"?{scale:i,scaleInv:1/i}:{scale:o,scaleInv:1/o}}function Rt(r,t,e,s){let n=t.left,o=t.top,i=r.x-n+(r.width-e.width*s)/2,a=r.y-o+(r.height-e.height*s)/2;return`translate(${i}px, ${a}px) scale(${s})`}function qt(r,t,e){let s=t.left,n=t.top,o=r.x-s+(r.width-e.width)/2,i=r.y-n+(r.height-e.height)/2;return`translate(${o}px, ${i}px)`}function Bt(r,t){let e=r.x+r.width/2-t.x,s=r.y+r.height/2-t.y;return`${e}px ${s}px`}function Vt(r,t,e,s,n=0){let o=r.width/2-t.width/2-t.x+e.x,i=r.height/2-t.height/2-t.y+e.y,a=1-n,l=o*a,c=i*a;return{x:o,y:i,transform:`translate(${l}px, ${c}px) scale(${s})`}}function Xt({canvasRect:r,canvasOffset:t,triggerRect:e,previousViewRectAtBaseTransform:s,lastViewZoomedElementRect:n,previousViewRectWithPreviousAtEndTransform:o,scale:i,preScale:a,parallax:l=0}){let c=t.left,f=t.top,u=r.width/2-e.width/2-e.x,h=r.height/2-e.height/2-e.y,m=u+(s.x-n.x)+o.x-c+(o.width-n.width)/2,y=h+(s.y-n.y)+o.y-f+(o.height-n.height)/2,p=1-Math.min(l*2,.9);return`translate(${m*p}px, ${y*p}px) scale(${i*a})`}function Yt(r,t,e,s,n){return`translate(${r-e.left}px, ${t-e.top}px) scale(${s*n})`}function ut(r){let t=r.split(/\s+/);return{x:parseFloat(t[0])||0,y:parseFloat(t[1])||0}}function rt(r){let t=typeof r=="string"?r:"",e=t.match(/translate\s*\(\s*([-+\d.eE]+)px\s*,\s*([-+\d.eE]+)px\s*\)/);if(!e)return{tx:0,ty:0,rest:t.trim(),matched:!1};let s=t.replace(/translate\s*\([^)]+\)\s*/,"").trim();return{tx:parseFloat(e[1]),ty:parseFloat(e[2]),rest:s,matched:!0}}function nt(r){let t=rt(r),e=r.match(/scale\s*\(\s*([-+\d.eE]+)\s*\)/);return{tx:t.matched?t.tx:0,ty:t.matched?t.ty:0,scale:e?parseFloat(e[1]):1}}function ht(r,t,e,s,n,o,i,a,l,c){let f=t.x-e.x*(1-o)-s,u=t.y-e.y*(1-o)-n,h=t.width/o,m=t.height/o,y=f+e.x+(r.x-f-e.x-s)/o,p=u+e.y+(r.y-u-e.y-n)/o,d=r.width/o,g=r.height/o,v=f+i.x+a+c*(y-f-i.x),w=u+i.y+l+c*(p-u-i.y),b=d*c,_=g*c;return{x:v,y:w,width:b,height:_,left:v,top:w,right:v+b,bottom:w+_}}function ot(r,t,e){return{viewName:r,backwardState:t,forwardState:e}}function Ut(r){return{detachedNode:r}}function Wt(r,t,e,s,n){let o=[];return t!==null&&o.push(t),e!==null&&o.push(e),s!==null&&o.push(s),n!==null&&o.push(n),{zoomLevel:r,views:o}}function Kt(r){let t=r.views?.[3];if(!(!t||!(t.detachedNode instanceof Node)))return t.detachedNode}var dt=class{#t=new Map;set(t,e,s=null){this.#t.set(t,{node:e,expires:s?Date.now()+s:null})}get(t){let e=this.#t.get(t);return e?e.expires!==null&&Date.now()>e.expires?(this.#t.delete(t),null):e.node.cloneNode(!0):null}has(t){let e=this.#t.get(t);return e?e.expires!==null&&Date.now()>e.expires?(this.#t.delete(t),!1):!0:!1}invalidate(t){this.#t.delete(t)}clear(){this.#t.clear()}};var Pe=300*1e3,Ie=/^https?:\/\/|^\/|\.html$|\.php$/i,mt=class{#t;#e;#r;#s=new Map;constructor(t={}){this.#r=t,this.#t=new ft(t),this.#e=new dt}#n(t){return typeof this.#r[t]=="string"}#o(t){return Ie.test(t)?Pe:null}async get(t,e=null){if(this.#n(t)){let s=this.#e.get(t);if(s)return s;if(this.#s.has(t))return this.#s.get(t);let n=(async()=>{try{let o=await this.#t.resolve(t,e),i=this.#r[t],a=this.#o(i);return this.#e.set(t,o,a),o}finally{this.#s.delete(t)}})();return this.#s.set(t,n),n}return this.#t.resolve(t,e)}async preloadEager(t,e=null){!Array.isArray(t)||t.length===0||await Promise.all(t.map(s=>this.get(s,e)))}prefetch(t,e=null){this.get(t,e).catch(()=>{})}prefetchOnHover(t,e=null){this.prefetch(t,e)}scanAndPrefetch(t,e=null){if(!t||!t.querySelectorAll)return;t.querySelectorAll(".zoom-me[data-to]").forEach(n=>{let o=n.dataset.to;o&&(n.hasAttribute("role")||n.setAttribute("role","button"),n.hasAttribute("aria-label")||n.setAttribute("aria-label",`Zoom to ${o}`),this.prefetch(o,e))})}};function K(r){r&&(r.style.contentVisibility="hidden")}function X(r){r&&(r.style.contentVisibility="visible")}function F(r){if(typeof r=="number"&&!Number.isNaN(r))return Math.max(0,r);let t=String(r).trim(),e=t.match(/^(\d*\.?\d+)\s*(ms|s)?$/i);if(!e)return typeof console<"u"&&console.warn(`[zumly] Could not parse duration "${t}" \u2014 falling back to 500ms.`),500;let s=parseFloat(e[1]);return(e[2]||"s").toLowerCase()==="ms"?Math.max(0,s):Math.max(0,s*1e3)}function pt(r){return F(r)/1e3}function T(r,t){if(r.classList.contains("is-new-current-view")){let e=t.views[0].forwardState;r.classList.replace("is-new-current-view","is-current-view"),r.classList.remove("zoom-current-view","has-no-events"),r.style.transformOrigin=e.origin,r.style.transform=e.transform;return}if(r.classList.contains("is-previous-view")){let e=t.views[1].forwardState;r.classList.remove("zoom-previous-view","has-no-events"),r.style.transformOrigin=e.origin,r.style.transform=e.transform;return}if(r.classList.contains("is-last-view")){let e=t.views[2].forwardState;r.classList.remove("zoom-last-view","has-no-events"),r.style.transformOrigin=e.origin,r.style.transform=e.transform}}function N(r,t){r.classList.remove("zoom-previous-view-reverse","has-no-events","has-effect","has-effect-reverse"),r.style.removeProperty("--z-effect-filter"),r.style.transformOrigin="0 0",r.style.transform=t.transform}function $(r,t){r.classList.remove("zoom-last-view-reverse","has-no-events","has-effect","has-effect-reverse"),r.style.removeProperty("--z-effect-filter"),r.style.transformOrigin=t.origin,r.style.transform=t.transform}function C(r,t){try{t&&t.removeChild(r)}catch{try{r.parentElement&&t.removeChild(r.parentElement)}catch{}}}function z(...r){for(let t of r)t&&(t.classList.remove("hide"),X(t))}function H(r,t){let{currentView:e,previousView:s,backView:n,backViewState:o,lastView:i,lastViewState:a,incomingTransformEnd:l,currentStage:c,canvas:f}=r,u=c.views[0];z(e),e.classList.replace("is-new-current-view","is-current-view"),e.classList.remove("zoom-current-view","has-no-events"),e.style.transformOrigin=u.forwardState.origin,e.style.transform=l||u.forwardState.transform,n&&o&&(n.style.transform=o.transformEnd),i&&a&&(i.style.transform=a.transformEnd),r.keepAlive||C(s,f),t()}var j=150;function R(r,t){let e=!1,s=setTimeout(()=>{e||(e=!0,r())},t);return{finish(){e||(e=!0,clearTimeout(s),r())},extend(n){e||(clearTimeout(s),s=setTimeout(()=>{e||(e=!0,r())},n))},safetyTimer:s}}function Gt(){return{a:1,b:0,c:0,d:1,e:0,f:0}}function Ne(r){if(!r||r==="none")return Gt();let t=String(r).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}:Gt()}function Q(r){return`matrix(${r.a}, ${r.b}, ${r.c}, ${r.d}, ${r.e}, ${r.f})`}function G(r,t,e){return r+(t-r)*e}function J(r,t,e){let s=Math.max(0,Math.min(1,e));return{a:G(r.a,t.a,s),b:G(r.b,t.b,s),c:G(r.c,t.c,s),d:G(r.d,t.d,s),e:G(r.e,t.e,s),f:G(r.f,t.f,s)}}function Z(r,t,e){r.style.transformOrigin=t,r.style.transform=e;try{r.getBoundingClientRect()}catch{}return Ne(getComputedStyle(r).transform)}function Jt(r,t){let{type:e,currentView:s,previousView:n,lastView:o,currentStage:i,duration:a,ease:l,canvas:c}=r;if(!s||!n||!i){t();return}e==="lateral"?$e(r,t):e==="zoomIn"?Ze(s,n,o,i,a,l,t):e==="zoomOut"?Me(s,n,o,i,a,l,c,t):t()}function $e(r,t){let{currentView:e,previousView:s,backView:n,backViewState:o,lastView:i,lastViewState:a,incomingTransformStart:l,incomingTransformEnd:c,outgoingTransform:f,outgoingTransformEnd:u,currentStage:h,duration:m,ease:y,canvas:p}=r,d=F(m),g=h.views[0];z(e),e.classList.replace("is-new-current-view","is-current-view"),e.classList.remove("zoom-current-view","has-no-events"),e.style.transformOrigin=g.forwardState.origin,n&&o&&(M(n,m,y,{"--lateral-from":o.transformStart,"--lateral-to":o.transformEnd}),n.classList.add("zoom-lateral-back")),i&&a&&(M(i,m,y,{"--lateral-from":a.transformStart,"--lateral-to":a.transformEnd}),i.classList.add("zoom-lateral-back")),r.keepAlive!=="visible"&&(M(s,m,y,{"--lateral-out-from":f,"--lateral-out-to":u}),s.classList.add("zoom-lateral-out")),M(e,m,y,{"--lateral-in-from":l,"--lateral-in-to":c}),e.classList.add("zoom-lateral-in");let v=r.keepAlive==="visible"?[e]:[s,e];n&&o&&v.push(n),i&&a&&v.push(i);let w=v.length,b=d+j,_=new Set(["zoom-lateral-in","zoom-lateral-out","zoom-lateral-back"]),{finish:S,extend:O}=R(()=>{Et(v,I,P),r.keepAlive?(s.classList.remove("zoom-lateral-out"),s.style.opacity=""):C(s,p),n&&(n.classList.remove("zoom-lateral-back"),n.style.transform=o?.transformEnd||n.style.transform),i&&(i.classList.remove("zoom-lateral-back"),i.style.transform=a?.transformEnd||i.style.transform),e.classList.remove("zoom-lateral-in"),e.style.transform=c,t()},b);function P(x){x.target!==x.currentTarget||!_.has(x.animationName)||O(b)}function I(x){if(x.target!==x.currentTarget||!_.has(x.animationName))return;let q=x.currentTarget;q.removeEventListener("animationend",I),q.removeEventListener("animationstart",P),w--,w<=0&&S()}v.forEach(x=>{x.addEventListener("animationstart",P),x.addEventListener("animationend",I)})}function Ze(r,t,e,s,n,o,i){z(r,t,e);let a=s.stagger||0;M(r,n,o,{"--current-view-transform-start":s.views[0].backwardState.transform,"--current-view-transform-end":s.views[0].forwardState.transform}),a>0&&r.style.setProperty("animation-delay","0ms"),M(t,n,o,{"--previous-view-transform-start":s.views[1].backwardState.transform,"--previous-view-transform-end":s.views[1].forwardState.transform}),a>0&&t.style.setProperty("animation-delay",`${a}ms`),e&&(M(e,n,o,{"--last-view-transform-start":s.views[2].backwardState.transform,"--last-view-transform-end":s.views[2].forwardState.transform}),a>0&&e.style.setProperty("animation-delay",`${a*2}ms`)),r.classList.add("zoom-current-view"),t.classList.add("zoom-previous-view"),e&&e.classList.add("zoom-last-view");let l=e?[r,t,e]:[r,t],c=l.length,f=F(n),u=e?a*2:a,h=f+u+j,m=new Set(["zoom-current-view","zoom-previous-view","zoom-last-view"]),{finish:y,extend:p}=R(()=>{Et(l,g,d),l.forEach(v=>v.style.removeProperty("animation-delay")),l.forEach(v=>{if(v?.isConnected)try{T(v,s)}catch{}}),i()},h);function d(v){v.target!==v.currentTarget||!m.has(v.animationName)||p(h)}function g(v){if(v.target!==v.currentTarget||!m.has(v.animationName))return;let w=v.currentTarget;if(w.removeEventListener("animationend",g),w.removeEventListener("animationstart",d),w.isConnected)try{T(w,s)}catch{}c--,c<=0&&y()}l.forEach(v=>{v.addEventListener("animationstart",d),v.addEventListener("animationend",g)})}function Me(r,t,e,s,n,o,i,a){let l=s.views[0],c=s.views[1],f=e&&s.views[2]?s.views[2]:null,u=s.stagger||0;M(r,n,o,{"--current-view-transform-start":l.backwardState.transform,"--current-view-transform-end":l.forwardState.transform}),u>0&&r.style.setProperty("animation-delay","0ms"),M(t,n,o,{"--previous-view-transform-start":c.backwardState.transform,"--previous-view-transform-end":c.forwardState.transform}),u>0&&t.style.setProperty("animation-delay",`${u}ms`),e&&f&&(M(e,n,o,{"--last-view-transform-start":f.backwardState.transform,"--last-view-transform-end":f.forwardState.transform}),u>0&&e.style.setProperty("animation-delay",`${u*2}ms`)),r.classList.add("zoom-current-view-reverse"),t.classList.add("zoom-previous-view-reverse"),e&&e.classList.add("zoom-last-view-reverse");let h=e?[r,t,e]:[r,t],m=h.length,y=F(n),p=e?u*2:u,d=y+p+j,g=new Set(["zoom-current-view-reverse","zoom-previous-view-reverse","zoom-last-view-reverse"]),{finish:v,extend:w}=R(()=>{Et(h,_,b),h.forEach(S=>S.style.removeProperty("animation-delay")),h.forEach(S=>{if(S?.isConnected)try{Qt(S,s,i)}catch{}}),a()},d);function b(S){S.target!==S.currentTarget||!g.has(S.animationName)||w(d)}function _(S){if(S.target!==S.currentTarget||!g.has(S.animationName))return;let O=S.currentTarget;if(O.removeEventListener("animationend",_),O.removeEventListener("animationstart",b),O.isConnected)try{Qt(O,s,i)}catch{}m--,m<=0&&v()}h.forEach(S=>{S.addEventListener("animationstart",b),S.addEventListener("animationend",_)})}function Qt(r,t,e){if(r.classList.contains("zoom-current-view-reverse")){C(r,e);return}if(r.classList.contains("zoom-previous-view-reverse")){N(r,t.views[1].backwardState);return}r.classList.contains("zoom-last-view-reverse")&&$(r,t.views[2].backwardState)}function M(r,t,e,s){r.style.setProperty("--zoom-duration",t),r.style.setProperty("--zoom-ease",e);for(let[n,o]of Object.entries(s))r.style.setProperty(n,o)}function Et(r,t,e){for(let s of r)s?.removeEventListener&&(s.removeEventListener("animationend",t),s.removeEventListener("animationstart",e))}function te(r,t){let{type:e,currentView:s,previousView:n,lastView:o,currentStage:i,canvas:a}=r;if(!s||!n||!i){t();return}if(e==="lateral"){H(r,t);return}if(e==="zoomIn"){z(s,n,o),T(s,i),T(n,i),o&&T(o,i),t();return}if(e==="zoomOut"){C(s,a),z(n,o),N(n,i.views[1].backwardState),o&&$(o,i.views[2].backwardState),t();return}t()}function ee(r,t){let{type:e,currentView:s,previousView:n,lastView:o,currentStage:i,duration:a,ease:l,canvas:c}=r;if(!s||!n||!i){t();return}let f=F(a);if(e==="lateral"){He(r,f,l,t);return}if(e==="zoomIn"){De(s,n,o,i,f,l,t);return}if(e==="zoomOut"){Fe(s,n,o,i,f,l,c,t);return}t()}function De(r,t,e,s,n,o,i){z(r,t,e);let a=s.views[0],l=s.views[1],c=e&&s.views[2]?s.views[2]:null;r.style.transformOrigin=a.backwardState.origin,r.style.transform=a.backwardState.transform,t.style.transformOrigin=l.backwardState.origin,t.style.transform=l.backwardState.transform,c&&(e.style.transformOrigin=c.backwardState.origin,e.style.transform=c.backwardState.transform);let f=s.stagger||0,u=[];u.push(r.animate([{transform:a.backwardState.transform},{transform:a.forwardState.transform}],{duration:n,easing:o,fill:"forwards"})),u.push(t.animate([{transform:l.backwardState.transform},{transform:l.forwardState.transform}],{duration:n,delay:f,easing:o,fill:"forwards"})),c&&u.push(e.animate([{transform:c.backwardState.transform},{transform:c.forwardState.transform}],{duration:n,delay:f*2,easing:o,fill:"forwards"}));let h=c?f*2:f,{finish:m}=R(()=>{xt(u);try{T(r,s),T(t,s),e&&T(e,s)}catch{}i()},n+h+j);Promise.all(u.map(y=>y.finished)).then(m).catch(m)}function Fe(r,t,e,s,n,o,i,a){let l=s.views[0],c=s.views[1],f=e&&s.views[2]?s.views[2]:null,u=c.backwardState,h=f?f.backwardState:null;r.style.transformOrigin=l.forwardState.origin,r.style.transform=l.forwardState.transform,requestAnimationFrame(()=>{requestAnimationFrame(()=>{t.style.transformOrigin=c.forwardState.origin,e&&f&&(e.style.transformOrigin=f.forwardState.origin);let m=t.style.transform||getComputedStyle(t).transform||c.forwardState.transform,y=e&&f?e.style.transform||getComputedStyle(e).transform||f.forwardState.transform:null,p=s.stagger||0,d=[];d.push(r.animate([{transform:l.forwardState.transform},{transform:l.backwardState.transform}],{duration:n,easing:o,fill:"forwards"})),d.push(t.animate([{transform:m},{transform:u.transform}],{duration:n,delay:p,easing:o,fill:"both"})),e&&h&&d.push(e.animate([{transform:y},{transform:h.transform}],{duration:n,delay:p*2,easing:o,fill:"both"})),t.style.removeProperty("transform"),e&&e.style.removeProperty("transform");let g=e&&h?p*2:p,{finish:v}=R(()=>{xt(d);try{C(r,i),N(t,u),e&&h&&$(e,h)}catch{}a()},n+g+j);Promise.all(d.map(w=>w.finished)).then(v).catch(v)})})}function He(r,t,e,s){let{currentView:n,previousView:o,backView:i,backViewState:a,lastView:l,lastViewState:c,incomingTransformStart:f,incomingTransformEnd:u,outgoingTransform:h,outgoingTransformEnd:m,currentStage:y,canvas:p}=r,d=y.views[0];z(n),n.classList.replace("is-new-current-view","is-current-view"),n.classList.remove("zoom-current-view","has-no-events"),n.style.transformOrigin=d.forwardState.origin;let g=[];g.push(n.animate([{transform:f,opacity:0},{transform:u,opacity:1}],{duration:t,easing:e,fill:"forwards"})),r.keepAlive!=="visible"&&g.push(o.animate([{transform:h,opacity:1},{transform:m,opacity:0}],{duration:t,easing:e,fill:"forwards"})),i&&a&&g.push(i.animate([{transform:a.transformStart},{transform:a.transformEnd}],{duration:t,easing:e,fill:"forwards"})),l&&c&&g.push(l.animate([{transform:c.transformStart},{transform:c.transformEnd}],{duration:t,easing:e,fill:"forwards"}));let{finish:v}=R(()=>{xt(g),n.style.transform=u||d.forwardState.transform,i&&a&&(i.style.transform=a.transformEnd),l&&c&&(l.style.transform=c.transformEnd),r.keepAlive?(o.style.opacity="",o.style.transform=m):C(o,p),s()},t+j);Promise.all(g.map(w=>w.finished)).then(v).catch(v)}function xt(r){for(let t of r)try{t.cancel()}catch{}}function se(r,t){let e=typeof globalThis<"u"&&globalThis.anime;if(!e||typeof e!="function"){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:s,currentView:n,previousView:o,lastView:i,currentStage:a,duration:l,ease:c,canvas:f}=r;if(!n||!o||!a){t();return}let u=F(l);s==="lateral"?H(r,t):s==="zoomIn"?je(e,n,o,i,a,u,c,t):s==="zoomOut"?Re(e,n,o,i,a,u,c,f,t):t()}function je(r,t,e,s,n,o,i,a){z(t,e,s);let l=n.views[0],c=n.views[1],f=s&&n.views[2]?n.views[2]:null,u=re([{el:t,backward:l.backwardState,forward:l.forwardState},{el:e,backward:c.backwardState,forward:c.forwardState},...f?[{el:s,backward:f.backwardState,forward:f.forwardState}]:[]],"forward");ne(u,0);let h=n.stagger||0,m=o+(f?h*2:h),y={value:0};r({targets:y,value:1,duration:m,easing:ie(i),update:()=>{let p=y.value*m;oe(u,p,o,h)},complete:()=>{T(t,n),T(e,n),s&&T(s,n),a()}})}function Re(r,t,e,s,n,o,i,a,l){let c=n.views[0],f=n.views[1],u=s&&n.views[2]?n.views[2]:null,h=f.backwardState,m=u?u.backwardState:null,y=re([{el:t,backward:c.backwardState,forward:c.forwardState},{el:e,backward:f.backwardState,forward:f.forwardState},...u?[{el:s,backward:u.backwardState,forward:u.forwardState}]:[]],"backward");ne(y,0);let p=n.stagger||0,d=o+(u?p*2:p),g={value:0};r({targets:g,value:1,duration:d,easing:ie(i),update:()=>{let v=g.value*d;oe(y,v,o,p)},complete:()=>{C(t,a),N(e,h),s&&m&&$(s,m),l()}})}function re(r,t){return r.map(({el:e,backward:s,forward:n})=>{if(t==="forward"){let o=Z(e,s.origin,s.transform),i=Z(e,s.origin,n.transform);return{el:e,from:o,to:i}}else{let o=Z(e,n.origin,n.transform),i=Z(e,n.origin,s.transform);return{el:e,from:o,to:i}}})}function ne(r,t){for(let{el:e,from:s,to:n}of r)e.style.transform=Q(J(s,n,t))}function oe(r,t,e,s){for(let n=0;n<r.length;n++){let{el:o,from:i,to:a}=r[n],l=n*s,c=Math.max(0,t-l),f=e>0?Math.min(1,c/e):1;o.style.transform=Q(J(i,a,f))}}function ie(r){if(typeof r!="string")return"easeInOutQuad";let t=r.toLowerCase();return t==="linear"?"linear":t.includes("ease-in-out")?"easeInOutQuad":t.includes("ease-in")?"easeInQuad":t.includes("ease-out")?"easeOutQuad":t}function ae(r,t){let e=typeof globalThis<"u"&&globalThis.gsap;if(!e||typeof e.to!="function"){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:s,currentView:n,previousView:o,lastView:i,currentStage:a,duration:l,ease:c,canvas:f}=r;if(!n||!o||!a){t();return}let u=pt(l);s==="lateral"?H(r,t):s==="zoomIn"?qe(e,n,o,i,a,u,c,t):s==="zoomOut"?Be(e,n,o,i,a,u,c,f,t):t()}function qe(r,t,e,s,n,o,i,a){z(t,e,s);let l=n.views[0],c=n.views[1],f=s&&n.views[2]?n.views[2]:null;vt(t,l.backwardState),vt(e,c.backwardState),f&&vt(s,f.backwardState);let u=r.timeline({onComplete:()=>{T(t,n),T(e,n),s&&T(s,n),a()}}),h=le(i),m=(n.stagger||0)/1e3;u.to(t,{transform:l.forwardState.transform,duration:o,ease:h},0),u.to(e,{transform:c.forwardState.transform,duration:o,ease:h},m),f&&u.to(s,{transform:f.forwardState.transform,duration:o,ease:h},m*2)}function Be(r,t,e,s,n,o,i,a,l){let c=n.views[0],f=n.views[1],u=s&&n.views[2]?n.views[2]:null,h=f.backwardState,m=u?u.backwardState:null;vt(t,c.forwardState);let y=e.style.transform||getComputedStyle(e).transform||f.forwardState.transform,p=s&&u?s.style.transform||getComputedStyle(s).transform||u.forwardState.transform:null;e.style.transformOrigin=f.forwardState.origin,s&&u&&(s.style.transformOrigin=u.forwardState.origin);let d=le(i),g=r.timeline({onComplete:()=>{C(t,a),N(e,h),s&&m&&$(s,m),l()}}),v=(n.stagger||0)/1e3;r.set(e,{transform:y}),s&&p&&r.set(s,{transform:p}),g.fromTo(t,{transform:c.forwardState.transform},{transform:c.backwardState.transform,duration:o,ease:d},0),g.fromTo(e,{transform:y},{transform:h.transform,duration:o,ease:d},v),s&&m&&g.fromTo(s,{transform:p},{transform:m.transform,duration:o,ease:d},v*2)}function vt(r,t){r.style.transformOrigin=t.origin,r.style.transform=t.transform}function le(r){if(typeof r!="string")return"power2.inOut";let t=r.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 ce(r,t){let e=Ye();if(!e||typeof e!="function"){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:s,currentView:n,previousView:o,lastView:i,currentStage:a,duration:l,ease:c,canvas:f}=r;if(!n||!o||!a){t();return}let u=pt(l);s==="lateral"?H(r,t):s==="zoomIn"?Ve(e,n,o,i,a,u,c,t):s==="zoomOut"?Xe(e,n,o,i,a,u,c,f,t):t()}function Ve(r,t,e,s,n,o,i,a){z(t,e,s);let l=fe(t,e,s,n,"forward");ue(l,0);let c=n.stagger||0,f=c/1e3,u=o*1e3,h=o+(l.length>2?f*2:f);r(0,1,{duration:h,ease:de(i),onUpdate:y=>{let p=y*h*1e3;he(l,p,u,c)}}).then(()=>{T(t,n),T(e,n),s&&T(s,n),a()}).catch(()=>a())}function Xe(r,t,e,s,n,o,i,a,l){let c=n.views[1],f=s&&n.views[2]?n.views[2]:null,u=c.backwardState,h=f?f.backwardState:null,m=fe(t,e,s,n,"backward");ue(m,0);let y=n.stagger||0,p=y/1e3,d=o*1e3,g=o+(m.length>2?p*2:p);r(0,1,{duration:g,ease:de(i),onUpdate:w=>{let b=w*g*1e3;he(m,b,d,y)}}).then(()=>{C(t,a),N(e,u),s&&h&&$(s,h),l()}).catch(()=>l())}function fe(r,t,e,s,n){let o=s.views[0],i=s.views[1],a=e&&s.views[2]?s.views[2]:null,l=[{el:r,backward:o.backwardState,forward:o.forwardState},{el:t,backward:i.backwardState,forward:i.forwardState}];return a&&l.push({el:e,backward:a.backwardState,forward:a.forwardState}),l.map(({el:c,backward:f,forward:u})=>n==="forward"?{el:c,from:Z(c,f.origin,f.transform),to:Z(c,f.origin,u.transform)}:{el:c,from:Z(c,u.origin,u.transform),to:Z(c,u.origin,f.transform)})}function ue(r,t){for(let{el:e,from:s,to:n}of r)e.style.transform=Q(J(s,n,t))}function he(r,t,e,s){for(let n=0;n<r.length;n++){let{el:o,from:i,to:a}=r[n],l=n*s,c=Math.max(0,t-l),f=e>0?Math.min(1,c/e):1;o.style.transform=Q(J(i,a,f))}}function Ye(){let r=typeof globalThis<"u"?globalThis:typeof window<"u"?window:{};return r.motion?.animate||r.Motion?.animate||r.animate}function de(r){if(typeof r!="string")return"easeInOut";let t=r.toLowerCase();return t==="linear"?"linear":t.includes("ease-in-out")?"easeInOut":t.includes("ease-in")?"easeIn":t.includes("ease-out")?"easeOut":r}var me={css:Jt,waapi:ee,none:te,anime:se,gsap:ae,motion:ce};function pe(r){if(typeof r=="function")return{runTransition(s,n){r(s,n)}};let t=typeof r=="string"?r.toLowerCase():"css";return{runTransition:me[t]||me.css}}function Ue(r){if(typeof r!="string"||r.trim()==="")return{tx:0,ty:0,rest:""};let t=rt(r);return t.matched?{tx:t.tx,ty:t.ty,rest:t.rest}:null}function Lt(r,t,e){let s=Ue(r);if(s===null)return r;let n=s.tx*t,o=s.ty*e,i=s.rest?` ${s.rest}`:"";return`translate(${n}px, ${o}px)${i}`.trim()}function We(r){if(typeof r!="string"||!r.trim())return null;let t=r.trim().match(/^([-\d.eE]+)px\s+([-\d.eE]+)px$/);return t?{x:parseFloat(t[1]),y:parseFloat(t[2])}:null}function zt(r,t,e){let s=We(r);return s===null?r:`${s.x*t}px ${s.y*e}px`}function kt(r,t,e,s,n){if(!r.storedViews?.length||!r.canvas||t<=0||e<=0)return;let o=s/t,i=n/e;for(let m of r.storedViews){let y=m.views;if(Array.isArray(y))for(let p=0;p<y.length;p++){let d=y[p];!d||d.detachedNode||(d.backwardState&&(d.backwardState.transform=Lt(d.backwardState.transform,o,i),d.backwardState.origin!=null&&(d.backwardState.origin=zt(d.backwardState.origin,o,i))),d.forwardState&&(d.forwardState.transform=Lt(d.forwardState.transform,o,i),d.forwardState.origin!=null&&(d.forwardState.origin=zt(d.forwardState.origin,o,i))))}}let a=r.canvas,l=a.querySelector(".is-current-view"),c=a.querySelector(".is-previous-view"),f=a.querySelector(".is-last-view"),u=a.querySelector(".is-new-current-view"),h=[l,c,f,u].filter(Boolean);for(let m of h){if(!m.style)continue;let y=m.style.transform;y!=null&&y!==""&&(m.style.transform=Lt(y,o,i));let p=m.style.transformOrigin;p!=null&&p!==""&&(m.style.transformOrigin=zt(p,o,i))}}var Ke=8e3,tt=class{constructor(t){if(this.storedViews=[],this.currentStage=null,this.debug=!1,this.trace=[],this.blockEvents=!1,this._blockEventsSafetyTimer=null,this.touchstartX=0,this.touchstartY=0,this.touchendX=0,this.touchendY=0,this.touching=!1,this.lateralHistory=[],this._lastCanvasWidth=0,this._lastCanvasHeight=0,this._pendingResizeCorrection=!1,this._destroyed=!1,this._trackedTimers=new Set,this._pendingTransitionComplete=null,this._hooks={},this._plugins=[],Ht(t,this),!this.isValid){this.notify("is unable to start: invalid or missing required options (mount, initialView, views).","error");return}if(this.canvas=document.querySelector(this.mount),!this.canvas){this.notify(`mount selector "${this.mount}" did not match any element.`,"error"),this.isValid=!1;return}this.transitionDriver=pe(this.transitionDriver),this._onZoom=this.onZoom.bind(this),this._onTouchStart=this.onTouchStart.bind(this),this._onTouchEnd=this.onTouchEnd.bind(this),this._onTouchCancel=()=>{this.touching=!1},this._onKeyUp=this.onKeyUp.bind(this),this._onWheel=this.onWheel.bind(this),this._wheelCooldown=!1,this._onPrefetchTrigger=e=>{e.target.classList.contains("zoom-me")&&e.target.dataset.to&&this.prefetcher.prefetch(e.target.dataset.to,{trigger:e.target,...e.target.dataset})},this._onResize=this._handleResize.bind(this),this._resizeDebounceTimer=null,this._RESIZE_DEBOUNCE_MS=80,this.prefetcher=new mt(this.views),this._bindEvents()}_bindEvents(){let t=this.canvas;t&&(t.setAttribute("tabindex","0"),t.setAttribute("role","application"),t.setAttribute("aria-roledescription","zoomable interface"),t.setAttribute("aria-live","polite"),t.addEventListener("mouseup",this._onZoom,!1),t.addEventListener("touchend",this._onZoom,!1),t.addEventListener("touchstart",this._onTouchStart,{passive:!0}),t.addEventListener("touchend",this._onTouchEnd,!1),t.addEventListener("touchcancel",this._onTouchCancel,{passive:!0}),t.addEventListener("keyup",this._onKeyUp,!1),t.addEventListener("wheel",this._onWheel,{passive:!1}),t.addEventListener("mouseover",this._onPrefetchTrigger,{passive:!0}),t.addEventListener("focusin",this._onPrefetchTrigger,{passive:!0}),window.addEventListener("resize",this._onResize,{passive:!0}),typeof ResizeObserver<"u"&&(this._resizeObserver=new ResizeObserver(()=>this._handleResize()),this._resizeObserver.observe(t)))}_unbindEvents(){let t=this.canvas;t&&(t.removeEventListener("mouseup",this._onZoom,!1),t.removeEventListener("touchend",this._onZoom,!1),t.removeEventListener("touchstart",this._onTouchStart),t.removeEventListener("touchend",this._onTouchEnd,!1),t.removeEventListener("touchcancel",this._onTouchCancel),t.removeEventListener("keyup",this._onKeyUp,!1),t.removeEventListener("wheel",this._onWheel),t.removeEventListener("mouseover",this._onPrefetchTrigger),t.removeEventListener("focusin",this._onPrefetchTrigger)),window.removeEventListener("resize",this._onResize),this._resizeObserver&&(this._resizeObserver.disconnect(),this._resizeObserver=null)}_resetCanvasScroll(t){if(t&&((t.scrollLeft!==0||t.scrollTop!==0)&&(this.notify(`canvas had a residual scroll (${t.scrollLeft}, ${t.scrollTop}) \u2014 resetting. Something scrolled the canvas mid-transition.`,"warn"),t.scrollLeft=0,t.scrollTop=0),!this._warnedScrolledAncestor)){for(let e=t.parentElement;e&&e!==document.body;e=e.parentElement)if(e.scrollLeft!==0||e.scrollTop!==0){let s=e.className?`.${String(e.className).trim().split(/\s+/).join(".")}`:e.tagName.toLowerCase();this.notify(`an ancestor of the canvas (${s}) is scrolled (${e.scrollLeft}, ${e.scrollTop}): all zooms will land displaced. Use 'overflow: clip' (not 'hidden') on containers around the canvas.`,"warn"),this._warnedScrolledAncestor=!0;break}}}_setBlockEvents(){this.blockEvents=!0,this._clearBlockEventsSafety(),this._blockEventsSafetyTimer=setTimeout(()=>{if(this.blockEvents&&!this._destroyed){this.notify("blockEvents safety timeout: driver did not call onComplete. Force-resetting.","warn"),this.blockEvents=!1;let t=this._pendingTransitionComplete;t?t():this._onTransitionComplete()}},Ke)}_clearBlockEventsSafety(){this._blockEventsSafetyTimer!==null&&(clearTimeout(this._blockEventsSafetyTimer),this._blockEventsSafetyTimer=null)}_setTrackedTimeout(t,e){let s=setTimeout(()=>{this._trackedTimers.delete(s),!this._destroyed&&t()},e);return this._trackedTimers.add(s),s}_clearTrackedTimeouts(){for(let t of this._trackedTimers)clearTimeout(t);this._trackedTimers.clear()}storeViews(t){this.tracing("storedViews()"),this.storedViews.push(t),this.debug&&console.debug("Zumly storedViews",t)}tracing(t){if(this.debug)if(t==="ended"){let e=this.trace.map((s,n)=>`${n===0?`Instance ${this.mount}: ${s}`:`${s}`}`).join(" > ");this.notify(e),this.trace=[]}else this.trace.push(t)}notify(t,e){return L(this.debug,t,e)}_recordCanvasSize(){if(!this.canvas)return;let t=this.canvas.getBoundingClientRect();this._lastCanvasWidth=t.width,this._lastCanvasHeight=t.height}_handleResize(){this._destroyed||(this._resizeDebounceTimer&&clearTimeout(this._resizeDebounceTimer),this._resizeDebounceTimer=setTimeout(()=>{if(this._resizeDebounceTimer=null,!this.isValid||!this.canvas||this._lastCanvasWidth===0)return;let t=this.canvas.getBoundingClientRect(),e=t.width,s=t.height;if(!(e===this._lastCanvasWidth&&s===this._lastCanvasHeight)){if(this.blockEvents){this._pendingResizeCorrection=!0;return}kt(this,this._lastCanvasWidth,this._lastCanvasHeight,e,s),this._lastCanvasWidth=e,this._lastCanvasHeight=s}},this._RESIZE_DEBOUNCE_MS))}_onTransitionComplete(){if(this._clearBlockEventsSafety(),this._pendingResizeCorrection&&!this.blockEvents){this._pendingResizeCorrection=!1;let t=this.canvas?.getBoundingClientRect();if(t&&this._lastCanvasWidth>0){let e=t.width,s=t.height;(e!==this._lastCanvasWidth||s!==this._lastCanvasHeight)&&kt(this,this._lastCanvasWidth,this._lastCanvasHeight,e,s),this._lastCanvasWidth=e,this._lastCanvasHeight=s}}else this._recordCanvasSize();this._manageFocus()}_manageFocus(){if(!this.canvas)return;let t=this.canvas.querySelector(".is-current-view");if(!t)return;let e=t.querySelector('a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])');e?e.focus({preventScroll:!0}):(t.setAttribute("tabindex","-1"),t.focus({preventScroll:!0}))}_resolveEffects(t){let e=t?.dataset?.withEffects;if(e&&typeof e=="string"){let s=e.split("|").map(n=>n.trim());return[s[0]||"none",s[1]||s[0]||"none"]}return this.effects}_applyEffects(t,e,s,n,o){!s||s[0]==="none"&&s[1]==="none"||(t&&s[0]!=="none"&&(t.style.setProperty("--z-effect-filter",s[0]),t.style.setProperty("--zoom-duration",n),t.style.setProperty("--zoom-ease",o),t.classList.add("has-effect")),e&&s[1]!=="none"&&(e.style.setProperty("--z-effect-filter",s[1]),e.style.setProperty("--zoom-duration",n),e.style.setProperty("--zoom-ease",o),e.classList.add("has-effect")))}_removeEffect(t){if(!t||!t.classList.contains("has-effect"))return;t.classList.remove("has-effect"),t.classList.add("has-effect-reverse");let e=()=>{t.classList.remove("has-effect-reverse"),t.style.removeProperty("--z-effect-filter"),t.removeEventListener("transitionend",e)};t.addEventListener("transitionend",e,{once:!0});let s=t.style.getPropertyValue("--zoom-duration");this._setTrackedTimeout(e,s?parseFloat(s)*(s.includes("ms")?1:1e3)+100:1100)}_resolveHideTrigger(t){return t?.dataset?.hideTrigger!==void 0?t.dataset.hideTrigger==="fade"?"fade":!0:this.hideTrigger}_applyHideTrigger(t,e,s,n,o){!s||!t||(s==="fade"?(t.style.setProperty("--zoom-duration",n),t.style.setProperty("--zoom-ease",o),t.classList.add("z-trigger-fade"),e.style.setProperty("--zoom-duration",n),e.style.setProperty("--zoom-ease",o),e.classList.add("z-view-fade-in"),e.offsetHeight,e.classList.remove("hide")):t.classList.add("z-trigger-hidden"))}_restoreHideTrigger(t,e,s,n){if(!(!e||!t))if(e==="fade"){t.classList.remove("z-trigger-fade"),t.style.setProperty("--zoom-duration",s),t.style.setProperty("--zoom-ease",n),t.classList.add("z-trigger-fade-reverse");let o=()=>{t.classList.remove("z-trigger-fade-reverse"),t.style.removeProperty("--zoom-duration"),t.style.removeProperty("--zoom-ease"),t.removeEventListener("transitionend",o)};t.addEventListener("transitionend",o,{once:!0}),this._setTrackedTimeout(o,parseFloat(s)*(s.includes("ms")?1:1e3)+100)}else t.classList.remove("z-trigger-hidden")}on(t,e){return typeof e!="function"?this:((this._hooks[t]||=[]).push(e),this)}use(t,e){if(!t)return this;let s={plugin:t,options:e};return this._plugins.push(s),this._initialized&&this._installPlugin(s),this}_installPlugin(t){let{plugin:e,options:s}=t;try{typeof e=="function"?e(this,s):typeof e.install=="function"&&e.install(this,s)}catch(n){this.notify(`plugin install error: ${n.message}`,"error")}}off(t,e){return e?this._hooks[t]&&(this._hooks[t]=this._hooks[t].filter(s=>s!==e)):delete this._hooks[t],this}_emit(t,e={}){let s=this._hooks[t];if(!(!s||s.length===0))for(let n of s)try{n(e)}catch(o){this.debug&&console.error(`Zumly hook "${t}" threw:`,o)}}zoomLevel(){return this.storedViews.length}getZoomLevel(){return this.zoomLevel()}getCurrentViewName(){return!this.storedViews||this.storedViews.length===0?null:this.storedViews[this.storedViews.length-1]?.views?.[0]?.viewName??null}back(){if(!this._destroyed){if(this.blockEvents){this.notify("back ignored: a transition is already running.","warn");return}if(this.lateralHistory&&this.lateralHistory.length>0){let t=this.lateralHistory.pop(),e=t&&typeof t=="object"?t.name:t,s=t&&typeof t=="object"?t.entry:void 0,n=t&&typeof t=="object"?t.node:void 0;return this._doLateral(e,!0,{savedEntry:s,keepAliveNode:n})}this.zoomOut()}}async goTo(t,e={}){return this._destroyed?void 0:(e.mode==="lateral"?"lateral":"depth")==="depth"?this.zoomTo(t,e):this._doLateral(t,!1,e)}async zoomTo(t,e={}){if(this._destroyed)return;if(!this.isValid||!this.canvas){this.notify("zoomTo() cannot run: instance is invalid or canvas not found.","error");return}if(typeof t!="string"||!t){this.notify("zoomTo() requires a non-empty view name.","warn");return}if(!Object.prototype.hasOwnProperty.call(this.views,t)){this.notify(`zoomTo("${t}"): view not found in views. Available: ${Object.keys(this.views).join(", ")}`,"warn");return}if(this.getCurrentViewName()===t)return;let n=this.canvas.getBoundingClientRect(),o=Math.max(40,n.width*.1),i=Math.max(40,n.height*.1),l={rect:{x:n.left+(n.width-o)/2,y:n.top+(n.height-i)/2,width:o,height:i},duration:e.duration??this.duration,ease:e.ease??this.ease,props:e.props??{}};await this._doZoomIn(t,l)}async init(){if(this._destroyed)return;if(!this.isValid||!this.canvas){this.notify("init() cannot run: instance is invalid or canvas element was not found.","error");return}this.tracing("init()"),this.preload&&this.preload.length&&await this.prefetcher.preloadEager(this.preload,null).catch(e=>{this.notify(`preload failed: ${e.message}`,"warn")});let t;try{let e=await this.prefetcher.get(this.initialView,null);t=await st(e,this.initialView,this.canvas,!0,this.views,this.componentContext)}catch(e){this.notify(`init() failed to resolve initial view "${this.initialView}": ${e.message}`,"error");return}this._emit("viewMounted",{viewName:this.initialView,node:t}),this.prefetcher.scanAndPrefetch(t,null),this.storeViews({zoomLevel:this.storedViews.length,scale:1,views:[{viewName:this.initialView,backwardState:{origin:"0 0",transform:""}}]}),this.currentStage=this.storedViews[this.storedViews.length-1],this._recordCanvasSize(),this._initialized=!0;for(let e of this._plugins)this._installPlugin(e)}destroy(){this._destroyed||(this._emit("destroy"),this._destroyed=!0,this._clearBlockEventsSafety(),this._clearTrackedTimeouts(),this._pendingTransitionComplete=null,this._resizeDebounceTimer&&(clearTimeout(this._resizeDebounceTimer),this._resizeDebounceTimer=null),this._unbindEvents(),this._removeNav(),this._cleanupLateralKeepAlive(),this.blockEvents=!1,this.storedViews=[],this.currentStage=null,this.lateralHistory=[],this.trace=[],this._hooks={},this.prefetcher=null,this.transitionDriver=null,this.canvas&&(this.canvas.removeAttribute("tabindex"),this.canvas.removeAttribute("role"),this.canvas.removeAttribute("aria-roledescription"),this.canvas.removeAttribute("aria-live")),this.isValid=!1)}async _doZoomIn(t,e){if(this._destroyed)return;if(this.blockEvents){this.notify("zoomIn ignored: a transition is already running.","warn");return}this._cleanupLateralKeepAlive(),this.lateralHistory=[],this._emit("beforeZoomIn",{viewName:t}),this.tracing("zoomIn()");let s=this.canvas,n=e.el;this._resetCanvasScroll(s);let o=s.getBoundingClientRect(),i=o.left,a=o.top,c=(this.storedViews.length>0?this.storedViews[this.storedViews.length-1]:null)?.scale??1;this.tracing("getView()");let f=n?{trigger:n,target:document.createElement("div"),context:this.componentContext,props:Object.assign({},n.dataset)}:{target:document.createElement("div"),context:this.componentContext,props:e.props??{}},u=n?.dataset?.deferred!==void 0?!0:this.deferred,h,m=null;try{if(u){let E=await this.prefetcher.get(t,f);if(this._destroyed)return;for(m=document.createDocumentFragment();E.firstChild;)m.appendChild(E.firstChild);h=await st(E,t,s,!1,{},this.componentContext)}else{let E=await this.prefetcher.get(t,f);if(this._destroyed)return;this.prefetcher.scanAndPrefetch(E,f),h=await st(E,t,s,!1,this.views,this.componentContext)}}catch(E){this.notify(`zoomIn aborted: failed to resolve view "${t}": ${E.message}`,"error");return}if(!h)return;u||this._emit("viewMounted",{viewName:t,node:h}),n&&n.classList.add("zoomed");let y=n?(()=>{let E=n.getBoundingClientRect();return{x:E.x,y:E.y,width:E.width,height:E.height}})():e.rect,p=n?n.dataset.withDuration||this.duration:e.duration??this.duration,d=n?n.dataset.withEase||this.ease:e.ease??this.ease,g=n?n.dataset.withCover||this.cover:e.cover??this.cover,v=n?parseInt(n.dataset.withStagger,10)||this.stagger:e.stagger??this.stagger,w=s.querySelector(".is-current-view"),b=s.querySelector(".is-previous-view"),_=s.querySelector(".is-last-view");if(!w){this.notify("zoomIn aborted: no current view found in canvas. Call init() before navigating and keep Zumly view classes intact.","error"),n&&n.classList.remove("zoomed");try{s.removeChild(h)}catch{}return}K(h),K(w),K(b),_&&(K(_),s.removeChild(_));let S,O,P,I,x,q,B,et=w.style.transform,k=w.style.transformOrigin,D=b?b.style.transform:null,A=b?b.style.transformOrigin:null;try{w.classList.replace("is-current-view","is-previous-view"),b&&b.classList.replace("is-previous-view","is-last-view");let E=h.getBoundingClientRect(),V=w.getBoundingClientRect(),bt=null,At=null,lt=null;b&&(bt=b.getBoundingClientRect(),lt=b.querySelector(".zoomed"),At=lt&&lt.getBoundingClientRect?lt.getBoundingClientRect():bt);let ct={left:i,top:a},Pt={width:o.width,height:o.height},It={width:E.width,height:E.height},Nt=jt(y.width,y.height,E.width,E.height,g);B=Nt.scale;let Se=Nt.scaleInv;S=Rt(y,ct,It,Se),P=w.style.transform;let $t=Bt(y,V);I=Vt(Pt,y,V,B,this.parallax);let Zt=ut(k||"0 0"),U=nt(P||""),Mt=ut($t),W=nt(I.transform),Dt=y;if(n&&(Dt=ht(y,V,Zt,U.tx,U.ty,U.scale,Mt,W.tx,W.ty,W.scale)),O=qt(Dt,ct,It),b){x=b.style.transform;let Te=ht(V,V,Zt,U.tx,U.ty,U.scale,Mt,W.tx,W.ty,W.scale),Ee=Yt(I.x,I.y,ct,B,c),Ft=ut(A||"0 0"),_t=nt(x||""),St=nt(Ee),xe=ht(At,bt,Ft,_t.tx,_t.ty,_t.scale,Ft,St.tx,St.ty,St.scale);q=Xt({canvasRect:Pt,canvasOffset:ct,triggerRect:y,previousViewRectAtBaseTransform:V,lastViewZoomedElementRect:xe,previousViewRectWithPreviousAtEndTransform:Te,scale:B,preScale:c,parallax:this.parallax})}h.style.transform=S,w.style.transformOrigin=$t}catch(E){this.notify(`zoomIn geometry computation failed: ${E.message}. Aborting zoom.`,"error"),this.debug&&console.error("Zumly _doZoomIn error:",E),w.style.transform=et,w.style.transformOrigin=k,w.classList.contains("is-previous-view")&&w.classList.replace("is-previous-view","is-current-view"),b&&(b.style.transform=D,b.style.transformOrigin=A,b.classList.contains("is-last-view")&&b.classList.replace("is-last-view","is-previous-view"));try{s.removeChild(h)}catch{}n&&n.classList.remove("zoomed"),X(w),X(b);return}let Y=ot(h.dataset.viewName,{origin:h.style.transformOrigin,duration:p,ease:d,transform:S},{origin:h.style.transformOrigin,duration:p,ease:d,transform:O}),ye=ot(w.dataset.viewName,{origin:w.style.transformOrigin,duration:p,ease:d,transform:P},{origin:w.style.transformOrigin,duration:p,ease:d,transform:I.transform}),we=b?ot(b.dataset.viewName,{origin:b.style.transformOrigin,duration:p,ease:d,transform:x},{origin:b.style.transformOrigin,duration:p,ease:d,transform:q}):null,ge=_?Ut(_):null,at=Wt(this.storedViews.length,Y,ye,we,ge);at.scale=B,at.stagger=v||0,this.storeViews(at),this.currentStage=this.storedViews[this.storedViews.length-1],this.tracing("setCSSVariables()");let be=this._resolveEffects(n);this._applyEffects(w,b,be,p,d);let wt=this._resolveHideTrigger(n);this._applyHideTrigger(n,h,wt,p,d),wt&&(at.hideTriggerMode=wt),this._setBlockEvents();let _e={type:"zoomIn",currentView:h,previousView:w,lastView:b,currentStage:this.currentStage,duration:p,ease:d},gt=async()=>{this._pendingTransitionComplete===gt&&(this._pendingTransitionComplete=null,!this._destroyed&&(u&&m&&h&&(h.appendChild(m),this.prefetcher.scanAndPrefetch(h,f),typeof this.views[t]=="object"&&typeof this.views[t].mounted=="function"&&await this.views[t].mounted(),this._emit("viewMounted",{viewName:t,node:h})),this.blockEvents=!1,this._onTransitionComplete(),this._updateNav(),this._emit("afterZoomIn",{viewName:t,zoomLevel:this.zoomLevel()}),this.tracing("ended")))};this._pendingTransitionComplete=gt,this.transitionDriver.runTransition(_e,gt)}async zoomIn(t){this._destroyed||t?.dataset?.to&&await this._doZoomIn(t.dataset.to,{el:t})}async _doLateral(t,e=!1,s={}){if(this._destroyed)return;if(this.blockEvents){this.notify("lateral navigation ignored: a transition is already running.","warn");return}if(!this.isValid||!this.canvas)return;if(!Object.prototype.hasOwnProperty.call(this.views,t)){this.notify(`goTo("${t}", { mode: 'lateral' }): view not found in views. Available: ${Object.keys(this.views).join(", ")}`,"warn");return}let n=this.canvas.querySelector(".is-current-view");if(!n)return;let o=n.dataset?.viewName;if(o===t)return;this._emit("beforeLateral",{viewName:t,from:o,isBack:e});let i=this.lateralNav&&this.lateralNav.keepAlive,a=null;if(!e){this.lateralHistory=this.lateralHistory||[];let k=this.storedViews[this.storedViews.length-1];a={name:o,entry:k.views[0],node:i?n:null}}this.tracing("lateral()");let l=s.duration??this.duration,c=s.ease??this.ease,f=this.canvas.querySelector(".is-previous-view"),u=this.canvas.querySelector(".is-last-view"),h=0,m=0,y=this._declaredSiblings(),p=y?y.indexOf(o):-1,d=y?y.indexOf(t):-1;if(p!==-1&&d!==-1){let k=this.canvas.getBoundingClientRect();h=(p-d)*k.width*.15}else if(f){let k=f.querySelector(`.zoom-me[data-to="${o}"]`),D=f.querySelector(`.zoom-me[data-to="${t}"]`);if(k&&D){let A=k.getBoundingClientRect(),Y=D.getBoundingClientRect();h=A.left+A.width/2-(Y.left+Y.width/2),m=A.top+A.height/2-(Y.top+Y.height/2)}else h=this.canvas.getBoundingClientRect().width*.15}let g=null,v=null;if(i&&(e&&s.keepAliveNode?v=s.keepAliveNode:v=this.canvas.querySelector(`.is-lateral-hidden[data-view-name="${t}"]`)),v){if(v.style.display="",v.style.opacity="",v.classList.remove("is-lateral-hidden","zoom-lateral-out"),v.classList.add("is-new-current-view","has-no-events"),g=v,!e&&this.lateralHistory){let k=this.lateralHistory.findIndex(D=>D.node===v);k!==-1&&this.lateralHistory.splice(k,1)}}else{let k=()=>{e&&this.lateralHistory.push({name:t,entry:s.savedEntry,node:s.keepAliveNode??null})},D={target:document.createElement("div"),context:this.componentContext,props:s.props??{}};try{let A=await this.prefetcher.get(t,D);if(this._destroyed)return;this.prefetcher.scanAndPrefetch(A,D),g=await st(A,t,this.canvas,!1,this.views,this.componentContext)}catch(A){this.notify(`lateral navigation aborted: failed to resolve view "${t}": ${A.message}`,"error"),k();return}if(!g){k();return}this._emit("viewMounted",{viewName:t,node:g})}a&&this.lateralHistory.push(a),K(g);let w=n.style.transform||"",b=n.style.transformOrigin||"0 0";g.style.transform=w,g.style.transformOrigin=b;let _=this.storedViews[this.storedViews.length-1],S=e&&s.savedEntry?{...s.savedEntry,viewName:t}:ot(t,{origin:b,duration:l,ease:c,transform:w},{origin:b,duration:l,ease:c,transform:w});_.views[0]=S,this.currentStage=_;let O=f?{transformStart:f.style.transform||"",transformEnd:this._computeLateralBackTransform(f.style.transform||"",h,m)}:null,P=u&&_.views[2]?{transformStart:u.style.transform||"",transformEnd:this._computeLateralBackTransform(u.style.transform||"",h*.7,m*.7)}:null;O&&_.views[1]&&(_.views[1].forwardState={..._.views[1].forwardState,transform:O.transformEnd}),P&&_.views[2]&&(_.views[2].forwardState={..._.views[2].forwardState,transform:P.transformEnd});let I=w,x=this._computeLateralBackTransform(I,-h,-m),q=this._computeLateralBackTransform(w,h,m);this._setBlockEvents();let B={type:"lateral",currentView:g,previousView:n,lastView:u||null,backView:f||null,backViewState:O,lastViewState:P,incomingTransformStart:x,incomingTransformEnd:I,outgoingTransform:w,outgoingTransformEnd:q,currentStage:this.currentStage,duration:l,ease:c,canvas:this.canvas,slideDeltaX:h,slideDeltaY:m,keepAlive:i&&!e?i:!1},et=()=>{this._pendingTransitionComplete===et&&(this._pendingTransitionComplete=null,!this._destroyed&&(i&&!e&&(n.classList.remove("is-current-view","is-new-current-view","has-no-events"),n.classList.add("is-lateral-hidden"),i!=="visible"?n.style.display="none":(n.style.transform=w,n.style.opacity="")),this.blockEvents=!1,this._onTransitionComplete(),this._updateNav(),this._emit("afterLateral",{viewName:t,from:o,isBack:e}),this.tracing("ended")))};this._pendingTransitionComplete=et,this.transitionDriver.runTransition(B,et)}_computeLateralBackTransform(t,e,s){let n=rt(t);return n.matched?`translate(${n.tx+e}px, ${n.ty+s}px) ${n.rest}`.trim():`translate(${e}px, ${s}px) ${t}`.trim()}zoomOut(){if(this._destroyed)return;if(this.blockEvents){this.notify("zoomOut ignored: a transition is already running.","warn");return}this._cleanupLateralKeepAlive(),this.lateralHistory=[],this._emit("beforeZoomOut",{zoomLevel:this.zoomLevel()}),this.tracing("zoomOut()");let t=this.canvas;this._resetCanvasScroll(t);let e=t.querySelector(".is-current-view"),s=t.querySelector(".is-previous-view");if(!e||!s){this.notify("zoomOut: current or previous view not found (animation may still be running)","warn");return}this._setBlockEvents(),this.currentStage=this.storedViews[this.storedViews.length-1];let n=t.querySelector(".is-last-view");this.tracing("setCSSVariables()");let o=this.currentStage.views[0]?.forwardState?.duration??this.duration,i=this.currentStage.views[0]?.forwardState?.ease??this.ease,a=s.querySelector(".zoomed");a&&a.classList.remove("zoomed");let l=this.currentStage.hideTriggerMode;l&&a&&this._restoreHideTrigger(a,l,o,i),l==="fade"?(e.classList.remove("z-view-fade-in"),e.style.setProperty("--zoom-duration",o),e.style.setProperty("--zoom-ease",i),e.classList.add("z-view-fade-out")):(e.classList.remove("z-view-fade-in"),e.style.removeProperty("opacity")),this._removeEffect(s),s.classList.replace("is-previous-view","is-current-view"),n!==null&&(n.classList.contains("has-effect")&&this.effects[0]!=="none"&&n.style.setProperty("--z-effect-filter",this.effects[0]),n.classList.replace("is-last-view","is-previous-view"),n.classList.remove("hide"),X(n));let c=Kt(this.currentStage);if(c){t.prepend(c);let h=t.querySelector(".z-view:first-child");h&&(X(h),h.classList.add("hide"))}let f={type:"zoomOut",currentView:e,previousView:s,lastView:n,currentStage:this.currentStage,duration:o,ease:i,canvas:t},u=()=>{this._pendingTransitionComplete===u&&(this._pendingTransitionComplete=null,!this._destroyed&&(this.blockEvents=!1,this._onTransitionComplete(),this.storedViews.pop(),this._updateNav(),this._emit("afterZoomOut",{zoomLevel:this.zoomLevel()}),this.tracing("ended")))};this._pendingTransitionComplete=u,this.transitionDriver.runTransition(f,u)}onZoom(t){if(this._destroyed||t.type==="mouseup"&&!this.inputs.click||t.type==="touchend"&&!this.inputs.touch)return;let e=t.target;if(e.closest(".z-depth-nav")||e.closest(".z-lateral-nav"))return;let s=e.classList.contains("zoom-me")||e.closest(".zoom-me");if(!this.blockEvents&&s&&!this.touching){this.tracing("onZoom() \u2192 zoomIn"),t.stopPropagation();let n=e.classList.contains("zoom-me")?e:e.closest(".zoom-me");this.zoomIn(n);return}if(this.storedViews.length>1&&!this.blockEvents&&!s&&!this.touching){let n=this.canvas.querySelector(".is-current-view");if(n&&n.contains(e))return;let o=this._findSiblingTriggerAtPoint(t.clientX,t.clientY);if(o){this.tracing("onZoom() \u2192 lateral"),t.stopPropagation(),this._doLateral(o.dataset.to);return}this.tracing("onZoom() \u2192 zoomOut"),t.stopPropagation(),this.zoomOut()}}_findSiblingTriggerAtPoint(t,e){let s=this.canvas.querySelector(".is-previous-view");if(!s)return null;let o=this.canvas.querySelector(".is-current-view")?.dataset?.viewName;if(!o)return null;let i=s.querySelectorAll(".zoom-me[data-to]");for(let a of i){if(a.dataset.to===o)continue;let l=a.getBoundingClientRect();if(t>=l.left&&t<=l.right&&e>=l.top&&e<=l.bottom)return a}return null}_getSiblings(){let e=this.canvas.querySelector(".is-current-view")?.dataset?.viewName,s=this._declaredSiblings();if(s&&s.indexOf(e)!==-1)return{siblings:s,currentIndex:s.indexOf(e)};let n=this.canvas.querySelector(".is-previous-view");if(!n)return{siblings:[],currentIndex:-1};let o=n.querySelectorAll(".zoom-me[data-to]"),i=[];for(let l of o)l.dataset.to&&i.push(l.dataset.to);let a=i.indexOf(e);return{siblings:i,currentIndex:a}}_declaredSiblings(){let t=this.lateralNav&&typeof this.lateralNav=="object"?this.lateralNav.siblings:null;if(!t)return null;if(Array.isArray(t))return t;let e=this.canvas.querySelector(".is-previous-view")?.dataset?.viewName;return e&&Array.isArray(t[e])?t[e]:null}_updateNav(){this._destroyed||(this._removeNav(),this._updateDepthNav(),this._updateLateralNav())}_updateDepthNav(){if(!this.depthNav||this.storedViews.length-1<1)return;let e=this.canvas.querySelector(".z-view.is-current-view");if(e&&e.querySelector(".z-depth-nav"))return;let s=this.depthNav.position||"bottom-left",n=document.createElement("div");n.className="z-depth-nav z-depth-nav--"+s;let o=document.createElement("button");o.className="z-nav-back",o.setAttribute("aria-label","Zoom out (go back)"),o.innerHTML="&#8249;",o.addEventListener("mouseup",i=>{i.stopPropagation(),!this.blockEvents&&this.storedViews.length>1&&this.zoomOut()}),n.appendChild(o),this.canvas.appendChild(n)}_updateLateralNav(){if(!this.lateralNav)return;let t=this.storedViews.length-1,e=this._getSiblings();if(e.siblings.length<2)return;if(this.lateralNav.mode==="auto"&&t>=1){let a=this.canvas.querySelector(".z-view.is-current-view");if(a&&a.offsetWidth>=this.canvas.offsetWidth&&a.offsetHeight>=this.canvas.offsetHeight)return}let{siblings:s,currentIndex:n}=e,o=this.lateralNav.position||"bottom-center",i=document.createElement("div");if(i.className="z-lateral-nav z-lateral-nav--"+o,this.lateralNav.arrows){let a=document.createElement("button");a.className="z-nav-arrow z-nav-prev",a.setAttribute("aria-label","Previous sibling view"),a.innerHTML="&#8249;",a.disabled=n<=0,a.addEventListener("mouseup",l=>{l.stopPropagation(),n>0&&this._doLateral(s[n-1])}),i.appendChild(a)}if(this.lateralNav.dots){let a=document.createElement("div");a.className="z-nav-lateral-dots";for(let l=0;l<s.length;l++){let c=document.createElement("button");c.className="z-nav-dot z-nav-lat-dot"+(l===n?" is-active":""),c.setAttribute("aria-label",`Go to ${s[l]}`),c.dataset.to=s[l],c.addEventListener("mouseup",(f=>u=>{u.stopPropagation(),f!==n&&this._doLateral(s[f])})(l)),a.appendChild(c)}i.appendChild(a)}if(this.lateralNav.arrows){let a=document.createElement("button");a.className="z-nav-arrow z-nav-next",a.setAttribute("aria-label","Next sibling view"),a.innerHTML="&#8250;",a.disabled=n>=s.length-1,a.addEventListener("mouseup",l=>{l.stopPropagation(),n<s.length-1&&this._doLateral(s[n+1])}),i.appendChild(a)}this.canvas.appendChild(i)}_removeNav(){this.canvas&&this.canvas.querySelectorAll(".z-depth-nav, .z-lateral-nav").forEach(t=>t.remove())}_cleanupLateralKeepAlive(){if(!this.canvas)return;let t=this.canvas.querySelectorAll(".is-lateral-hidden");for(let e of t)e.remove()}onKeyUp(t){this._destroyed||this.inputs.keyboard&&(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 no actions defined")))}onWheel(t){this._destroyed||this.inputs.wheel&&(this._isInsideScrollable(t.target,t.deltaY)||(t.preventDefault(),!(this.blockEvents||this._wheelCooldown)&&t.deltaY>0&&this.storedViews.length>1&&(this.tracing("onWheel() \u2192 zoomOut"),this._wheelCooldown=!0,this._setTrackedTimeout(()=>{this._wheelCooldown=!1},500),this.zoomOut())))}_isInsideScrollable(t,e){let s=t,n=this.canvas.querySelector(".is-current-view");for(;s&&s!==this.canvas;){if(s===n||n&&n.contains(s)){let{overflowY:o}=window.getComputedStyle(s);if((o==="auto"||o==="scroll")&&(e>0?s.scrollTop+s.clientHeight<s.scrollHeight-1:s.scrollTop>0))return!0}s=s.parentElement}return!1}onTouchStart(t){this._destroyed||this.inputs.touch&&(this.tracing("onTouchStart()"),this.touching=!0,this.touchstartX=t.changedTouches[0].screenX,this.touchstartY=t.changedTouches[0].screenY)}onTouchEnd(t){this._destroyed||this.inputs.touch&&(this.blockEvents||(this.tracing("onTouchEnd()"),this.touchendX=t.changedTouches[0].screenX,this.touchendY=t.changedTouches[0].screenY,this.handleGesture(t)),this.touching=!1)}handleGesture(t){t.stopPropagation(),this.tracing("handleGesture()");let e=this.touchendX-this.touchstartX,s=this.touchendY-this.touchstartY,n=Math.abs(e)<10&&Math.abs(s)<10;e<-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"));let o=t.target.classList.contains("zoom-me")?t.target:t.target.closest(".zoom-me");n&&!this.blockEvents&&o&&this.touching&&(this.touching=!1,this.tracing("tap"),t.preventDefault(),this.zoomIn(o)),n&&this.storedViews.length>1&&!this.blockEvents&&!o&&t.target.closest(".is-current-view")===null&&this.touching&&(this.touching=!1,this.tracing("tap"),this.zoomOut())}};var Ge={separator:"/",prefix:"/"};function ve(r,t){let e=[];for(let s of r.storedViews){let n=s.views&&s.views[0];n&&n.viewName&&e.push(n.viewName)}return e.join(t)}function Qe(r,t){let e=window.location.hash.slice(1);return e.startsWith(r)&&(e=e.slice(r.length)),e?e.split(t).filter(Boolean):[]}var Ot={install(r,t){let e=Object.assign({},Ge,t),s=e.separator,n=e.prefix,o=!1;function i(f){if(o)return;let u=ve(r,s),h="#"+n+u;window.location.hash!==h&&(o=!0,window.history[f](null,"",h),o=!1)}function a(){i("pushState")}function l(){i("replaceState")}r.on("afterZoomIn",a),r.on("afterLateral",a),r.on("afterZoomOut",l);function c(){if(o)return;o=!0;let f=Qe(n,s),u=ve(r,s).split(s).filter(Boolean);if(f.join(s)===u.join(s)){o=!1;return}if(f.length<u.length){let h=u.length-f.length;for(let m=0;m<h;m++)r.zoomOut()}else if(f.length===u.length&&f.length>0){let h=f[f.length-1];h!==u[u.length-1]&&r.goTo(h,{mode:"lateral"})}else f.length>u.length&&window.history.back();o=!1}window.addEventListener("popstate",c),l(),r.on("destroy",function(){r.off("afterZoomIn",a),r.off("afterLateral",a),r.off("afterZoomOut",l),window.removeEventListener("popstate",c)})}};tt.Router=Ot;var Je=tt;
7
+ var Dt=Object.defineProperty;var je=Object.getOwnPropertyDescriptor;var Be=Object.getOwnPropertyNames;var Re=Object.prototype.hasOwnProperty;var qe=(r,t)=>{for(var e in t)Dt(r,e,{get:t[e],enumerable:!0})},We=(r,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Be(t))!Re.call(r,i)&&i!==e&&Dt(r,i,{get:()=>t[i],enumerable:!(s=je(t,i))||s.enumerable});return r};var Xe=r=>We(Dt({},"__esModule",{value:!0}),r);var ws={};qe(ws,{Zumly:()=>ft,ZumlyRouter:()=>Xt,default:()=>gs});module.exports=Xe(ws);var it=Symbol.for("zumly.viewLifecycles");function re(r){try{let t=r();t&&typeof t.then=="function"&&t.catch(e=>console.error("Zumly: view cleanup failed:",e))}catch(t){console.error("Zumly: view cleanup failed:",t)}}function ie(){let r=!1,t=[],e={onCleanup(s){if(typeof s!="function")throw new TypeError("Zumly: onCleanup expects a function");r?re(s):t.push(s)},attach(s){let i=s[it];i||(i=new Set,Object.defineProperty(s,it,{value:i,configurable:!0})),i.add(e)},dispose(){if(!r){r=!0;for(let s of t.splice(0).reverse())re(s)}}};return e}function C(r){if(!r)return;let t=[];r[it]&&t.push(r);let s=(r.ownerDocument||r).createTreeWalker(r,1),i;for(;i=s.nextNode();)i[it]&&t.push(i);for(let n=t.length-1;n>=0;n--){let o=t[n],a=o[it];if(a){for(let c of a)c.dispose();delete o[it]}}}var Ye=1e4,xt=class{#t={};constructor(t={}){this.#t=t}#e(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,e=null){let s=new Set;for(;typeof t=="string"&&Object.prototype.hasOwnProperty.call(this.#t,t);){if(s.has(t))throw new Error(`Zumly: circular view alias "${t}"`);s.add(t),t=this.#t[t]}let i=this.#e(t);switch(i){case"html":{let n=document.createElement("div");n.innerHTML=t.trim();let o=n.firstElementChild;if(!o)throw new Error("Zumly: view produced no element (html)");return o}case"url":{let n=new AbortController,o=setTimeout(()=>n.abort(),Ye),a;try{let f=await fetch(t,{signal:n.signal});if(!f.ok)throw new Error(`Zumly: fetch failed for "${t}" (${f.status})`);a=await f.text()}finally{clearTimeout(o)}let c=document.createElement("div");c.innerHTML=a.trim();let l=c.firstElementChild;if(!l)throw new Error("Zumly: view produced no element (url)");return l}case"function":case"object":{let n=ie(),o=e?.target||document.createElement("div");n.attach(o);let a={...e,target:o,props:e?.props||{},context:e?.context||new Map,onCleanup:n.onCleanup};try{let c=await(i==="function"?t(a):t.render(a)),l;if(typeof c=="string")l=await this.resolve(c,a);else if(c instanceof HTMLElement)l=c;else if(i==="function")l=o,o.classList.length||(o.style.width||(o.style.width="100%"),o.style.height||(o.style.height="100%"));else throw new Error("Zumly: view render() must return a string or HTMLElement");return n.attach(l),l}catch(c){throw n.dispose(),c}}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")}}};async function dt(r,t,e,s,i,n){if(!r||!r.classList){let o=document.createElement("div");o.classList.add("z-view"),r&&o.appendChild(r),r=o}else r.classList.contains("z-view")||r.classList.add("z-view");r.dataset.viewName=t,r.getAttribute("aria-label")||r.setAttribute("aria-label",`View: ${t}`),r.style.transformOrigin="0 0",r.style.position="absolute",s?r.classList.add("is-current-view"):r.classList.add("is-new-current-view","has-no-events","hide"),e.append(r);try{i[t]&&typeof i[t]=="object"&&typeof i[t].mounted=="function"&&await i[t].mounted()}catch(o){throw C(r),r.remove(),o}return r}function $(r,t,e){t&&e==="welcome"&&console.info(`%c Zumly %c ${t}`,"background: #424085; color: white; border-radius: 3px;","color: #424085"),t&&r&&(e==="info"||e===void 0)&&console.info(`%c Zumly %c ${t}`,"background: #6679A3; color: #304157; border-radius: 3px;","color: #6679A3"),t&&e==="warn"&&console.warn(`%c Zumly %c ${t}`,"background: #DCBF53; color: #424085; border-radius: 3px;","color: #424085"),t&&e==="error"&&console.error(`%c Zumly %c ${t}`,"background: #BE4747; color: white; border-radius: 3px;","color: #424085")}function ne(r,t){if(t.isValid=!1,!r||typeof r!="object"){$(!1,"'options' object has to be provided when instance is defined","error");return}if(typeof r.mount!="string"){$(!1,"'mount' must be a string selector","error");return}if(t.mount=r.mount,typeof r.initialView!="string"){$(!1,"'initialView' must be a string","error");return}if(t.initialView=r.initialView,!r.views||typeof r.views!="object"){$(!1,"'views' must be an object","error");return}t.views=r.views,t.isValid=!0,t.preload=Array.isArray(r.preload)?r.preload:[],t.debug=typeof r.debug=="boolean"?r.debug:!1,t.componentContext=r.componentContext&&typeof r.componentContext=="object"?r.componentContext:new Map;let e=r.transitions&&typeof r.transitions=="object"?r.transitions:null,s=e&&e.cover,i=typeof s=="string"?s.toLowerCase():null,n=i==="width"||i==="height";t.cover=n?i:"width",!n&&e&&s!==void 0&&$(!1,`'transitions.cover' must be either "width" or "height". Falling back to "width".`,"warn"),t.duration=e&&typeof e.duration=="string"?e.duration:"1s",t.ease=e&&typeof e.ease=="string"?e.ease:"ease-in-out",t.deferred=typeof r.deferred=="boolean"?r.deferred:!1;let o=e&&e.hideTrigger;o===!0||o==="fade"?t.hideTrigger=o:(t.hideTrigger=!1,o!=null&&o!==!1&&$(!1,`'transitions.hideTrigger' must be true or "fade". Falling back to false.`,"warn"));let a=e&&e.effects;Array.isArray(a)&&a.length>=2&&typeof a[0]=="string"&&typeof a[1]=="string"?t.effects=[a[0],a[1]]:Array.isArray(a)&&a.length===1&&typeof a[0]=="string"?t.effects=[a[0],a[0]]:(t.effects=["none","none"],a!=null&&$(!1,`'transitions.effects' must be an array of 1-2 CSS filter strings (e.g. ["blur(3px)", "blur(8px) saturate(0)"]). Falling back to no effects.`,"warn"));let c=e&&e.driver,l=typeof c=="string"?c.toLowerCase():null,f=typeof c=="function"?c:null;if(l!==null){let p=["css","waapi","none","anime","gsap","motion"];t.transitionDriver=p.includes(l)?l:"css",p.includes(l)||$(!1,`'transitions.driver' must be "css", "waapi", "none", "anime", "gsap", "motion", or a function. Got "${c}". Falling back to "css".`,"warn")}else f!==null?t.transitionDriver=f:t.transitionDriver="css";let h=e&&e.stagger;typeof h=="number"&&h>0?t.stagger=h:(t.stagger=0,h!=null&&h!==0&&$(!1,"'transitions.stagger' must be a positive number (ms). Falling back to 0 (disabled).","warn")),t.parallax=0;let u=r.lateralNav;if(u===!1)t.lateralNav=!1;else if(u&&typeof u=="object"){let p=typeof u.mode=="string"?u.mode.toLowerCase():null,y=p==="auto"||p==="always";p&&!y&&$(!1,`'lateralNav.mode' must be "auto" or "always". Falling back to "auto".`,"warn");let g=null;if(Array.isArray(u.siblings))g=u.siblings.filter(x=>typeof x=="string"&&x),g.length<2&&($(!1,"'lateralNav.siblings' needs at least 2 view names. Ignoring.","warn"),g=null);else if(u.siblings&&typeof u.siblings=="object"){g={};for(let[x,b]of Object.entries(u.siblings))if(Array.isArray(b)){let _=b.filter(S=>typeof S=="string"&&S);_.length>=2&&(g[x]=_)}Object.keys(g).length===0&&(g=null)}else u.siblings!==void 0&&$(!1,"'lateralNav.siblings' must be an array of view names or a { parentView: [...] } map. Ignoring.","warn");t.lateralNav={mode:y?p:"auto",arrows:typeof u.arrows=="boolean"?u.arrows:!0,dots:typeof u.dots=="boolean"?u.dots:!0,keepAlive:u.keepAlive===!0||u.keepAlive==="visible"?u.keepAlive:!1,siblings:g}}else t.lateralNav={mode:"auto",arrows:!0,dots:!0,keepAlive:!1,siblings:null};let d=r.depthNav;if(d===!1)t.depthNav=!1;else if(d&&typeof d=="object"){let p=typeof d.position=="string"?d.position.toLowerCase():null,y=p==="bottom-left"||p==="top-left";p&&!y&&$(!1,`'depthNav.position' must be "bottom-left" or "top-left". Falling back to "bottom-left".`,"warn"),t.depthNav={position:y?p:"bottom-left"}}else t.depthNav={position:"bottom-left"};let v=r.lateralNav&&typeof r.lateralNav=="object"?r.lateralNav.position:void 0;if(t.lateralNav&&typeof t.lateralNav=="object"){let p=v==="bottom-center"||v==="top-center";v&&!p&&$(!1,`'lateralNav.position' must be "bottom-center" or "top-center". Falling back to "bottom-center".`,"warn"),t.lateralNav.position=p?v:"bottom-center"}let m=r.inputs;m===!1?t.inputs={wheel:!1,keyboard:!1,click:!1,touch:!1}:m&&typeof m=="object"?t.inputs={wheel:typeof m.wheel=="boolean"?m.wheel:!0,keyboard:typeof m.keyboard=="boolean"?m.keyboard:!0,click:typeof m.click=="boolean"?m.click:!0,touch:typeof m.touch=="boolean"?m.touch:!0}:t.inputs={wheel:!0,keyboard:!0,click:!0,touch:!0}}function St(r,t,e,s,i){let n=e/r,o=s/t;return i==="height"?{scale:o,scaleInv:1/o}:{scale:n,scaleInv:1/n}}function Ft(r,t,e,s){let i=t.left,n=t.top,o=r.x-i+(r.width-e.width*s)/2,a=r.y-n+(r.height-e.height*s)/2;return`translate(${o}px, ${a}px) scale(${s})`}function oe(r,t,e){let s=t.left,i=t.top,n=r.x-s+(r.width-e.width)/2,o=r.y-i+(r.height-e.height)/2;return`translate(${n}px, ${o}px)`}function ae(r,t){let e=r.x+r.width/2-t.x,s=r.y+r.height/2-t.y;return`${e}px ${s}px`}function le(r,t,e,s,i=0){let n=r.width/2-t.width/2-t.x+e.x,o=r.height/2-t.height/2-t.y+e.y,a=1-i,c=n*a,l=o*a;return{x:n,y:o,transform:`translate(${c}px, ${l}px) scale(${s})`}}function ce({canvasRect:r,canvasOffset:t,triggerRect:e,previousViewRectAtBaseTransform:s,lastViewZoomedElementRect:i,previousViewRectWithPreviousAtEndTransform:n,scale:o,preScale:a,parallax:c=0}){let l=t.left,f=t.top,h=r.width/2-e.width/2-e.x,u=r.height/2-e.height/2-e.y,d=h+(s.x-i.x)+n.x-l+(n.width-i.width)/2,v=u+(s.y-i.y)+n.y-f+(n.height-i.height)/2,m=1-Math.min(c*2,.9);return`translate(${d*m}px, ${v*m}px) scale(${o*a})`}function fe(r,t,e,s,i){return`translate(${r-e.left}px, ${t-e.top}px) scale(${s*i})`}function nt(r){let t=r.split(/\s+/);return{x:parseFloat(t[0])||0,y:parseFloat(t[1])||0}}function et(r){let t=typeof r=="string"?r:"",e=t.match(/translate\s*\(\s*([-+\d.eE]+)px\s*,\s*([-+\d.eE]+)px\s*\)/);if(!e)return{tx:0,ty:0,rest:t.trim(),matched:!1};let s=t.replace(/translate\s*\([^)]+\)\s*/,"").trim();return{tx:parseFloat(e[1]),ty:parseFloat(e[2]),rest:s,matched:!0}}function Y(r){let t=et(r),e=r.match(/scale\s*\(\s*([-+\d.eE]+)\s*\)/);return{tx:t.matched?t.tx:0,ty:t.matched?t.ty:0,scale:e?parseFloat(e[1]):1}}function mt(r,t,e,s,i,n,o,a,c,l){let f=t.x-e.x*(1-n)-s,h=t.y-e.y*(1-n)-i,u=t.width/n,d=t.height/n,v=f+e.x+(r.x-f-e.x-s)/n,m=h+e.y+(r.y-h-e.y-i)/n,p=r.width/n,y=r.height/n,g=f+o.x+a+l*(v-f-o.x),x=h+o.y+c+l*(m-h-o.y),b=p*l,_=y*l;return{x:g,y:x,width:b,height:_,left:g,top:x,right:g+b,bottom:x+_}}function pt(r,t,e){return{viewName:r,backwardState:t,forwardState:e}}function he(r){return{detachedNode:r}}function ue(r,t,e,s,i){let n=[];return t!==null&&n.push(t),e!==null&&n.push(e),s!==null&&n.push(s),i!==null&&n.push(i),{zoomLevel:r,views:n}}function Vt(r){let t=r.views?.[3];if(!(!t||!(t.detachedNode instanceof Node)))return t.detachedNode}var Tt=class{#t=new Map;#e;constructor({maxEntries:t=64}={}){this.#e=Number.isInteger(t)&&t>=0?t:64}set(t,e,s=null){this.#e!==0&&this.adopt(t,e.cloneNode(!0),s)}adopt(t,e,s=null){let i=Date.now();for(let[n,o]of this.#t)o.expires!==null&&i>=o.expires&&this.#t.delete(n);if(this.#e!==0)for(this.#t.delete(t),this.#t.set(t,{node:e,expires:s===null?null:i+s});this.#t.size>this.#e;)this.#t.delete(this.#t.keys().next().value)}get(t){let e=this.#t.get(t);return e?e.expires!==null&&Date.now()>=e.expires?(this.#t.delete(t),null):(this.#t.delete(t),this.#t.set(t,e),e.node.cloneNode(!0)):null}has(t){let e=this.#t.get(t);return e?e.expires!==null&&Date.now()>=e.expires?(this.#t.delete(t),!1):!0:!1}invalidate(t){this.#t.delete(t)}clear(){this.#t.clear()}};var Ke="button, input, select, textarea, a[href], summary";function kt(r){return r?.matches?.(Ke)||!1}function jt(r){return!!r?.closest?.('input, textarea, select, [contenteditable]:not([contenteditable="false"]), [role="textbox"], [role="combobox"], [role="slider"], [role="spinbutton"]')}function de(r){let t=r.querySelectorAll(".zoom-me[data-to]");return t.forEach(e=>{kt(e)||(e.hasAttribute("role")||e.setAttribute("role","button"),e.hasAttribute("tabindex")||e.setAttribute("tabindex","0")),!e.hasAttribute("aria-label")&&!e.hasAttribute("aria-labelledby")&&!e.textContent.trim()&&e.setAttribute("aria-label",`Zoom to ${e.dataset.to}`)}),t}var Et=class{constructor(){this.backgrounds=new Map}sync(t){for(let e of t.children)e.classList.contains("z-view")&&(e.classList.contains("is-current-view")?this.restore(e):(this.backgrounds.has(e)||this.backgrounds.set(e,{inert:e.inert,hidden:e.getAttribute("aria-hidden")}),e.inert=!0,e.setAttribute("aria-hidden","true")));for(let e of this.backgrounds.keys())t.contains(e)||this.restore(e)}restore(t){let e=this.backgrounds.get(t);e&&(t.inert=e.inert,e.hidden===null?t.removeAttribute("aria-hidden"):t.setAttribute("aria-hidden",e.hidden),this.backgrounds.delete(t))}destroy(){for(let t of this.backgrounds.keys())this.restore(t)}};var Ue=300*1e3,me=/^https?:\/\/|^\/|\.(?:html|php)(?:[?#].*)?$/i,zt=class{#t;#e;#l;#n=new Map;#s=new Map;#r=null;#c=0;#d;#f;#i=!1;#o=!1;constructor(t={},{maxCacheEntries:e=64,prefetchConcurrency:s=2,maxPendingPrefetch:i=32}={}){this.#l=t,this.#t=new xt(t),this.#e=new Tt({maxEntries:e}),this.#d=Number.isInteger(s)&&s>0?s:2,this.#f=Number.isInteger(i)&&i>=0?i:32}#h(t){let e=new Set;for(;typeof t=="string"&&Object.prototype.hasOwnProperty.call(this.#l,t);){if(e.has(t))return null;e.add(t),t=this.#l[t]}return typeof t=="string"&&(t.includes("<")||me.test(t))?t:null}#v(t){return me.test(t)?Ue:null}async get(t,e=null){if(this.#i)throw new Error("Zumly: view prefetcher has been destroyed");this.#s.delete(t);let s=this.#h(t);if(s!==null){let i=this.#e.get(t);return i||(await this.#m(t,s,e)).cloneNode(!0)}return this.#t.resolve(t,e)}#m(t,e,s){if(this.#n.has(t))return this.#n.get(t);let i=(async()=>{try{let n=await this.#t.resolve(t,s);return this.#i||this.#e.adopt(t,n,this.#v(e)),n}finally{this.#n.delete(t)}})();return this.#n.set(t,i),i}async#u(t,e){if(this.#i)return;this.#s.delete(t);let s=this.#h(t);s===null||this.#e.has(t)||await this.#m(t,s,e)}async preloadEager(t,e=null){!Array.isArray(t)||t.length===0||await Promise.all([...new Set(t)].map(s=>this.#u(s,e)))}prefetch(t,e=null){if(this.#o){this.#p(t,e);return}this.#u(t,e).catch(()=>{})}prefetchOnHover(t,e=null){this.prefetch(t,e)}scanAndPrefetch(t,e=null){if(this.#i||!t||!t.querySelectorAll)return;let s=de(t);this.#s.clear();let i=new Set;for(let n of s){let o=n.dataset.to;if(!(!o||i.has(o))){if(i.add(o),this.#s.size>=this.#f)break;this.#p(o,e)}}this.#a()}#p(t,e){this.#i||this.#s.size>=this.#f||this.#s.has(t)||this.#h(t)===null||this.#e.has(t)||this.#n.has(t)||this.#s.set(t,e)}#a(){this.#i||this.#o||this.#r!==null||this.#s.size===0||this.#c>=this.#d||(this.#r=setTimeout(()=>{if(this.#r=null,this.#i||this.#s.size===0)return;let[t,e]=this.#s.entries().next().value;this.#s.delete(t),this.#c++,this.#u(t,e).catch(()=>{}).finally(()=>{this.#c--,this.#a()}),this.#a()},0))}pause(){this.#o=!0,this.#r!==null&&clearTimeout(this.#r),this.#r=null}resume(){this.#o=!1,this.#a()}destroy(){this.#i=!0,this.#r!==null&&clearTimeout(this.#r),this.#r=null,this.#s.clear(),this.#e.clear()}};var Lt=Symbol.for("zumly.viewVisibility");function pe(r){r[Lt]||Object.defineProperty(r,Lt,{configurable:!0,value:{value:r.style.getPropertyValue("content-visibility"),priority:r.style.getPropertyPriority("content-visibility")}})}function Ct(r){r&&(pe(r),r.style.contentVisibility="hidden")}function vt(r){r&&(pe(r),r.style.contentVisibility="visible")}function yt(r){let t=r?.[Lt];t&&(t.value?r.style.setProperty("content-visibility",t.value,t.priority):r.style.removeProperty("content-visibility"),delete r[Lt])}function K(r){if(typeof r=="number"&&!Number.isNaN(r))return Math.max(0,r);let t=String(r).trim(),e=t.match(/^(\d*\.?\d+)\s*(ms|s)?$/i);if(!e)return typeof console<"u"&&console.warn(`[zumly] Could not parse duration "${t}" \u2014 falling back to 500ms.`),500;let s=parseFloat(e[1]);return(e[2]||"s").toLowerCase()==="ms"?Math.max(0,s):Math.max(0,s*1e3)}function Nt(r){return K(r)/1e3}function k(r,t){if(r.classList.contains("is-new-current-view")){let e=t.views[0].forwardState;r.classList.replace("is-new-current-view","is-current-view"),r.classList.remove("zoom-current-view","has-no-events"),r.style.transformOrigin=e.origin,r.style.transform=e.transform;return}if(r.classList.contains("is-previous-view")){let e=t.views[1].forwardState;r.classList.remove("zoom-previous-view","has-no-events"),r.style.transformOrigin=e.origin,r.style.transform=e.transform;return}if(r.classList.contains("is-last-view")){let e=t.views[2].forwardState;r.classList.remove("zoom-last-view","has-no-events"),r.style.transformOrigin=e.origin,r.style.transform=e.transform}}function V(r,t){r.classList.remove("zoom-previous-view-reverse","has-no-events","has-effect","has-effect-reverse"),r.style.removeProperty("--z-effect-filter"),r.style.transformOrigin="0 0",r.style.transform=t.transform}function j(r,t){r.classList.remove("zoom-last-view-reverse","has-no-events","has-effect","has-effect-reverse"),r.style.removeProperty("--z-effect-filter"),r.style.transformOrigin=t.origin,r.style.transform=t.transform}function H(r,t){C(r);try{t&&t.removeChild(r)}catch{try{r?.parentElement&&t&&(C(r.parentElement),t.removeChild(r.parentElement))}catch{}}}function Z(...r){for(let t of r)t&&(t.classList.remove("hide"),vt(t))}function G(r,t){let{currentView:e,previousView:s,backView:i,backViewState:n,lastView:o,lastViewState:a,incomingTransformEnd:c,currentStage:l,canvas:f}=r,h=l.views[0];Z(e),e.classList.replace("is-new-current-view","is-current-view"),e.classList.remove("zoom-current-view","has-no-events"),e.style.transformOrigin=h.forwardState.origin,e.style.transform=c||h.forwardState.transform,i&&n&&(i.style.transform=n.transformEnd),o&&a&&(o.style.transform=a.transformEnd),r.keepAlive||H(s,f),t()}var Q=150;function J(r,t){let e=!1,s=setTimeout(()=>{e||(e=!0,r())},t);return{finish(){e||(e=!0,clearTimeout(s),r())},extend(i){e||(clearTimeout(s),s=setTimeout(()=>{e||(e=!0,r())},i))},safetyTimer:s}}function Ot(){return{a:1,b:0,c:0,d:1,e:0,f:0}}function Ge(r){if(!r||r==="none")return Ot();let t=String(r).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]),b:parseFloat(t[2])||0,c:parseFloat(t[3])||0,d:parseFloat(t[4]),e:parseFloat(t[5])||0,f:parseFloat(t[6])||0}:Ot()}function at(r){return`matrix(${r.a}, ${r.b}, ${r.c}, ${r.d}, ${r.e}, ${r.f})`}function ot(r,t,e){return r+(t-r)*e}function lt(r,t,e){let s=Math.max(0,Math.min(1,e));return{a:ot(r.a,t.a,s),b:ot(r.b,t.b,s),c:ot(r.c,t.c,s),d:ot(r.d,t.d,s),e:ot(r.e,t.e,s),f:ot(r.f,t.f,s)}}function ve(r,t,e){r.style.transformOrigin=t,r.style.transform=e;try{r.getBoundingClientRect()}catch{}return Ge(getComputedStyle(r).transform)}function ge(r,t){let{type:e,currentView:s,previousView:i,lastView:n,currentStage:o,duration:a,ease:c,canvas:l}=r;if(!s||!i||!o){t();return}e==="lateral"?Qe(r,t):e==="zoomIn"?Je(s,i,n,o,a,c,t):e==="zoomOut"?ts(s,i,n,o,a,c,l,t):t()}function Qe(r,t){let{currentView:e,previousView:s,backView:i,backViewState:n,lastView:o,lastViewState:a,incomingTransformStart:c,incomingTransformEnd:l,outgoingTransform:f,outgoingTransformEnd:h,currentStage:u,duration:d,ease:v,canvas:m}=r,p=K(d),y=u.views[0];Z(e),e.classList.replace("is-new-current-view","is-current-view"),e.classList.remove("zoom-current-view","has-no-events"),e.style.transformOrigin=y.forwardState.origin,i&&n&&(R(i,d,v,{"--lateral-from":n.transformStart,"--lateral-to":n.transformEnd}),i.classList.add("zoom-lateral-back")),o&&a&&(R(o,d,v,{"--lateral-from":a.transformStart,"--lateral-to":a.transformEnd}),o.classList.add("zoom-lateral-back")),r.keepAlive!=="visible"&&(R(s,d,v,{"--lateral-out-from":f,"--lateral-out-to":h}),s.classList.add("zoom-lateral-out")),R(e,d,v,{"--lateral-in-from":c,"--lateral-in-to":l}),e.classList.add("zoom-lateral-in");let g=r.keepAlive==="visible"?[e]:[s,e];i&&n&&g.push(i),o&&a&&g.push(o);let x=g.length,b=p+Q,_=new Set(["zoom-lateral-in","zoom-lateral-out","zoom-lateral-back"]),{finish:S,extend:O}=J(()=>{Bt(g,E,A),r.keepAlive?(s.classList.remove("zoom-lateral-out"),s.style.opacity=""):H(s,m),i&&(i.classList.remove("zoom-lateral-back"),i.style.transform=n?.transformEnd||i.style.transform),o&&(o.classList.remove("zoom-lateral-back"),o.style.transform=a?.transformEnd||o.style.transform),e.classList.remove("zoom-lateral-in"),e.style.transform=l,t()},b);function A(T){T.target!==T.currentTarget||!_.has(T.animationName)||O(b)}function E(T){if(T.target!==T.currentTarget||!_.has(T.animationName))return;let P=T.currentTarget;P.removeEventListener("animationend",E),P.removeEventListener("animationstart",A),x--,x<=0&&S()}g.forEach(T=>{T.addEventListener("animationstart",A),T.addEventListener("animationend",E)})}function Je(r,t,e,s,i,n,o){Z(r,t,e);let a=s.stagger||0;R(r,i,n,{"--current-view-transform-start":s.views[0].backwardState.transform,"--current-view-transform-end":s.views[0].forwardState.transform}),a>0&&r.style.setProperty("animation-delay","0ms"),R(t,i,n,{"--previous-view-transform-start":s.views[1].backwardState.transform,"--previous-view-transform-end":s.views[1].forwardState.transform}),a>0&&t.style.setProperty("animation-delay",`${a}ms`),e&&(R(e,i,n,{"--last-view-transform-start":s.views[2].backwardState.transform,"--last-view-transform-end":s.views[2].forwardState.transform}),a>0&&e.style.setProperty("animation-delay",`${a*2}ms`)),r.classList.add("zoom-current-view"),t.classList.add("zoom-previous-view"),e&&e.classList.add("zoom-last-view");let c=e?[r,t,e]:[r,t],l=c.length,f=K(i),h=e?a*2:a,u=f+h+Q,d=new Set(["zoom-current-view","zoom-previous-view","zoom-last-view"]),{finish:v,extend:m}=J(()=>{Bt(c,y,p),c.forEach(g=>g.style.removeProperty("animation-delay")),c.forEach(g=>{if(g?.isConnected)try{k(g,s)}catch{}}),o()},u);function p(g){g.target!==g.currentTarget||!d.has(g.animationName)||m(u)}function y(g){if(g.target!==g.currentTarget||!d.has(g.animationName))return;let x=g.currentTarget;if(x.removeEventListener("animationend",y),x.removeEventListener("animationstart",p),x.isConnected)try{k(x,s)}catch{}l--,l<=0&&v()}c.forEach(g=>{g.addEventListener("animationstart",p),g.addEventListener("animationend",y)})}function ts(r,t,e,s,i,n,o,a){let c=s.views[0],l=s.views[1],f=e&&s.views[2]?s.views[2]:null,h=s.stagger||0;R(r,i,n,{"--current-view-transform-start":c.backwardState.transform,"--current-view-transform-end":c.forwardState.transform}),h>0&&r.style.setProperty("animation-delay","0ms"),R(t,i,n,{"--previous-view-transform-start":l.backwardState.transform,"--previous-view-transform-end":l.forwardState.transform}),h>0&&t.style.setProperty("animation-delay",`${h}ms`),e&&f&&(R(e,i,n,{"--last-view-transform-start":f.backwardState.transform,"--last-view-transform-end":f.forwardState.transform}),h>0&&e.style.setProperty("animation-delay",`${h*2}ms`)),r.classList.add("zoom-current-view-reverse"),t.classList.add("zoom-previous-view-reverse"),e&&e.classList.add("zoom-last-view-reverse");let u=e?[r,t,e]:[r,t],d=u.length,v=K(i),m=e?h*2:h,p=v+m+Q,y=new Set(["zoom-current-view-reverse","zoom-previous-view-reverse","zoom-last-view-reverse"]),{finish:g,extend:x}=J(()=>{Bt(u,_,b),u.forEach(S=>S.style.removeProperty("animation-delay")),u.forEach(S=>{if(S?.isConnected)try{ye(S,s,o)}catch{}}),a()},p);function b(S){S.target!==S.currentTarget||!y.has(S.animationName)||x(p)}function _(S){if(S.target!==S.currentTarget||!y.has(S.animationName))return;let O=S.currentTarget;if(O.removeEventListener("animationend",_),O.removeEventListener("animationstart",b),O.isConnected)try{ye(O,s,o)}catch{}d--,d<=0&&g()}u.forEach(S=>{S.addEventListener("animationstart",b),S.addEventListener("animationend",_)})}function ye(r,t,e){if(r.classList.contains("zoom-current-view-reverse")){H(r,e);return}if(r.classList.contains("zoom-previous-view-reverse")){V(r,t.views[1].backwardState);return}r.classList.contains("zoom-last-view-reverse")&&j(r,t.views[2].backwardState)}function R(r,t,e,s){r.style.setProperty("--zoom-duration",t),r.style.setProperty("--zoom-ease",e);for(let[i,n]of Object.entries(s))r.style.setProperty(i,n)}function Bt(r,t,e){for(let s of r)s?.removeEventListener&&(s.removeEventListener("animationend",t),s.removeEventListener("animationstart",e))}function we(r,t){let{type:e,currentView:s,previousView:i,lastView:n,currentStage:o,canvas:a}=r;if(!s||!i||!o){t();return}if(e==="lateral"){G(r,t);return}if(e==="zoomIn"){Z(s,i,n),k(s,o),k(i,o),n&&k(n,o),t();return}if(e==="zoomOut"){H(s,a),Z(i,n),V(i,o.views[1].backwardState),n&&j(n,o.views[2].backwardState),t();return}t()}function be(r,t){let{type:e,currentView:s,previousView:i,lastView:n,currentStage:o,duration:a,ease:c,canvas:l}=r;if(!s||!i||!o){t();return}let f=K(a);if(e==="lateral"){rs(r,f,c,t);return}if(e==="zoomIn"){es(s,i,n,o,f,c,t);return}if(e==="zoomOut"){ss(s,i,n,o,f,c,l,t);return}t()}function es(r,t,e,s,i,n,o){Z(r,t,e);let a=s.views[0],c=s.views[1],l=e&&s.views[2]?s.views[2]:null;r.style.transformOrigin=a.backwardState.origin,r.style.transform=a.backwardState.transform,t.style.transformOrigin=c.backwardState.origin,t.style.transform=c.backwardState.transform,l&&(e.style.transformOrigin=l.backwardState.origin,e.style.transform=l.backwardState.transform);let f=s.stagger||0,h=[];h.push(r.animate([{transform:a.backwardState.transform},{transform:a.forwardState.transform}],{duration:i,easing:n,fill:"forwards"})),h.push(t.animate([{transform:c.backwardState.transform},{transform:c.forwardState.transform}],{duration:i,delay:f,easing:n,fill:"forwards"})),l&&h.push(e.animate([{transform:l.backwardState.transform},{transform:l.forwardState.transform}],{duration:i,delay:f*2,easing:n,fill:"forwards"}));let u=l?f*2:f,{finish:d}=J(()=>{Rt(h);try{k(r,s),k(t,s),e&&k(e,s)}catch{}o()},i+u+Q);Promise.all(h.map(v=>v.finished)).then(d).catch(d)}function ss(r,t,e,s,i,n,o,a){let c=s.views[0],l=s.views[1],f=e&&s.views[2]?s.views[2]:null,h=l.backwardState,u=f?f.backwardState:null;r.style.transformOrigin=c.forwardState.origin,r.style.transform=c.forwardState.transform,requestAnimationFrame(()=>{requestAnimationFrame(()=>{t.style.transformOrigin=l.forwardState.origin,e&&f&&(e.style.transformOrigin=f.forwardState.origin);let d=t.style.transform||getComputedStyle(t).transform||l.forwardState.transform,v=e&&f?e.style.transform||getComputedStyle(e).transform||f.forwardState.transform:null,m=s.stagger||0,p=[];p.push(r.animate([{transform:c.forwardState.transform},{transform:c.backwardState.transform}],{duration:i,easing:n,fill:"forwards"})),p.push(t.animate([{transform:d},{transform:h.transform}],{duration:i,delay:m,easing:n,fill:"both"})),e&&u&&p.push(e.animate([{transform:v},{transform:u.transform}],{duration:i,delay:m*2,easing:n,fill:"both"})),t.style.removeProperty("transform"),e&&e.style.removeProperty("transform");let y=e&&u?m*2:m,{finish:g}=J(()=>{Rt(p);try{H(r,o),V(t,h),e&&u&&j(e,u)}catch{}a()},i+y+Q);Promise.all(p.map(x=>x.finished)).then(g).catch(g)})})}function rs(r,t,e,s){let{currentView:i,previousView:n,backView:o,backViewState:a,lastView:c,lastViewState:l,incomingTransformStart:f,incomingTransformEnd:h,outgoingTransform:u,outgoingTransformEnd:d,currentStage:v,canvas:m}=r,p=v.views[0];Z(i),i.classList.replace("is-new-current-view","is-current-view"),i.classList.remove("zoom-current-view","has-no-events"),i.style.transformOrigin=p.forwardState.origin;let y=[];y.push(i.animate([{transform:f,opacity:0},{transform:h,opacity:1}],{duration:t,easing:e,fill:"forwards"})),r.keepAlive!=="visible"&&y.push(n.animate([{transform:u,opacity:1},{transform:d,opacity:0}],{duration:t,easing:e,fill:"forwards"})),o&&a&&y.push(o.animate([{transform:a.transformStart},{transform:a.transformEnd}],{duration:t,easing:e,fill:"forwards"})),c&&l&&y.push(c.animate([{transform:l.transformStart},{transform:l.transformEnd}],{duration:t,easing:e,fill:"forwards"}));let{finish:g}=J(()=>{Rt(y),i.style.transform=h||p.forwardState.transform,o&&a&&(o.style.transform=a.transformEnd),c&&l&&(c.style.transform=l.transformEnd),r.keepAlive?(n.style.opacity="",n.style.transform=d):H(n,m),s()},t+Q);Promise.all(y.map(x=>x.finished)).then(g).catch(g)}function Rt(r){for(let t of r)try{t.cancel()}catch{}}var xe="[-+]?(?:\\d*\\.\\d+|\\d+)(?:[eE][-+]?\\d+)?",_e=`(${xe})(px)?`,is=new RegExp(`^(?:translate\\(\\s*${_e}\\s*,\\s*${_e}\\s*\\)\\s*)?(?:scale\\(\\s*(${xe})\\s*\\))?$`);function ns(r){if(typeof r!="string")return null;let t=r.trim();if(t==="none")return Ot();if(!t)return null;let e=t.match(is);if(!e)return null;let s=Number(e[1]??0),i=Number(e[3]??0),n=Number(e[5]??1);return s!==0&&!e[2]||i!==0&&!e[4]||![s,i,n].every(Number.isFinite)?null:{a:n,b:0,c:0,d:n,e:s,f:i}}function q(r,t,e){let s=ns(e);return s?(r.style.transformOrigin=t,r.style.transform=e,s):ve(r,t,e)}function Se(r,t){let e=typeof globalThis<"u"&&globalThis.anime;if(!e||typeof e!="function"){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:s,currentView:i,previousView:n,lastView:o,currentStage:a,duration:c,ease:l,canvas:f}=r;if(!i||!n||!a){t();return}let h=K(c);s==="lateral"?G(r,t):s==="zoomIn"?os(e,i,n,o,a,h,l,t):s==="zoomOut"?as(e,i,n,o,a,h,l,f,t):t()}function os(r,t,e,s,i,n,o,a){Z(t,e,s);let c=i.views[0],l=i.views[1],f=s&&i.views[2]?i.views[2]:null,h=Te([{el:t,backward:c.backwardState,forward:c.forwardState},{el:e,backward:l.backwardState,forward:l.forwardState},...f?[{el:s,backward:f.backwardState,forward:f.forwardState}]:[]],"forward");Ee(h,0);let u=i.stagger||0,d=n+(f?u*2:u),v={value:0};r({targets:v,value:1,duration:d,easing:ze(o),update:()=>{let m=v.value*d;ke(h,m,n,u)},complete:()=>{k(t,i),k(e,i),s&&k(s,i),a()}})}function as(r,t,e,s,i,n,o,a,c){let l=i.views[0],f=i.views[1],h=s&&i.views[2]?i.views[2]:null,u=f.backwardState,d=h?h.backwardState:null,v=Te([{el:t,backward:l.backwardState,forward:l.forwardState},{el:e,backward:f.backwardState,forward:f.forwardState},...h?[{el:s,backward:h.backwardState,forward:h.forwardState}]:[]],"backward");Ee(v,0);let m=i.stagger||0,p=n+(h?m*2:m),y={value:0};r({targets:y,value:1,duration:p,easing:ze(o),update:()=>{let g=y.value*p;ke(v,g,n,m)},complete:()=>{H(t,a),V(e,u),s&&d&&j(s,d),c()}})}function Te(r,t){return r.map(({el:e,backward:s,forward:i})=>{if(t==="forward"){let n=q(e,s.origin,s.transform),o=q(e,s.origin,i.transform);return{el:e,from:n,to:o}}else{let n=q(e,i.origin,i.transform),o=q(e,i.origin,s.transform);return{el:e,from:n,to:o}}})}function Ee(r,t){for(let{el:e,from:s,to:i}of r)e.style.transform=at(lt(s,i,t))}function ke(r,t,e,s){for(let i=0;i<r.length;i++){let{el:n,from:o,to:a}=r[i],c=i*s,l=Math.max(0,t-c),f=e>0?Math.min(1,l/e):1;n.style.transform=at(lt(o,a,f))}}function ze(r){if(typeof r!="string")return"easeInOutQuad";let t=r.toLowerCase();return t==="linear"?"linear":t.includes("ease-in-out")?"easeInOutQuad":t.includes("ease-in")?"easeInQuad":t.includes("ease-out")?"easeOutQuad":t}function Le(r,t){let e=typeof globalThis<"u"&&globalThis.gsap;if(!e||typeof e.to!="function"){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:s,currentView:i,previousView:n,lastView:o,currentStage:a,duration:c,ease:l,canvas:f}=r;if(!i||!n||!a){t();return}let h=Nt(c);s==="lateral"?G(r,t):s==="zoomIn"?ls(e,i,n,o,a,h,l,t):s==="zoomOut"?cs(e,i,n,o,a,h,l,f,t):t()}function ls(r,t,e,s,i,n,o,a){Z(t,e,s);let c=i.views[0],l=i.views[1],f=s&&i.views[2]?i.views[2]:null;At(t,c.backwardState),At(e,l.backwardState),f&&At(s,f.backwardState);let h=r.timeline({onComplete:()=>{k(t,i),k(e,i),s&&k(s,i),a()}}),u=Ce(o),d=(i.stagger||0)/1e3;h.to(t,{transform:c.forwardState.transform,duration:n,ease:u},0),h.to(e,{transform:l.forwardState.transform,duration:n,ease:u},d),f&&h.to(s,{transform:f.forwardState.transform,duration:n,ease:u},d*2)}function cs(r,t,e,s,i,n,o,a,c){let l=i.views[0],f=i.views[1],h=s&&i.views[2]?i.views[2]:null,u=f.backwardState,d=h?h.backwardState:null;At(t,l.forwardState);let v=e.style.transform||getComputedStyle(e).transform||f.forwardState.transform,m=s&&h?s.style.transform||getComputedStyle(s).transform||h.forwardState.transform:null;e.style.transformOrigin=f.forwardState.origin,s&&h&&(s.style.transformOrigin=h.forwardState.origin);let p=Ce(o),y=r.timeline({onComplete:()=>{H(t,a),V(e,u),s&&d&&j(s,d),c()}}),g=(i.stagger||0)/1e3;r.set(e,{transform:v}),s&&m&&r.set(s,{transform:m}),y.fromTo(t,{transform:l.forwardState.transform},{transform:l.backwardState.transform,duration:n,ease:p},0),y.fromTo(e,{transform:v},{transform:u.transform,duration:n,ease:p},g),s&&d&&y.fromTo(s,{transform:m},{transform:d.transform,duration:n,ease:p},g*2)}function At(r,t){r.style.transformOrigin=t.origin,r.style.transform=t.transform}function Ce(r){if(typeof r!="string")return"power2.inOut";let t=r.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 Oe(r,t){let e=us();if(!e||typeof e!="function"){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:s,currentView:i,previousView:n,lastView:o,currentStage:a,duration:c,ease:l,canvas:f}=r;if(!i||!n||!a){t();return}let h=Nt(c);s==="lateral"?G(r,t):s==="zoomIn"?fs(e,i,n,o,a,h,l,t):s==="zoomOut"?hs(e,i,n,o,a,h,l,f,t):t()}function fs(r,t,e,s,i,n,o,a){Z(t,e,s);let c=Ne(t,e,s,i,"forward");Ae(c,0);let l=i.stagger||0,f=l/1e3,h=n*1e3,u=n+(c.length>2?f*2:f);r(0,1,{duration:u,ease:Ie(o),onUpdate:v=>{let m=v*u*1e3;Pe(c,m,h,l)}}).then(()=>{k(t,i),k(e,i),s&&k(s,i),a()}).catch(()=>a())}function hs(r,t,e,s,i,n,o,a,c){let l=i.views[1],f=s&&i.views[2]?i.views[2]:null,h=l.backwardState,u=f?f.backwardState:null,d=Ne(t,e,s,i,"backward");Ae(d,0);let v=i.stagger||0,m=v/1e3,p=n*1e3,y=n+(d.length>2?m*2:m);r(0,1,{duration:y,ease:Ie(o),onUpdate:x=>{let b=x*y*1e3;Pe(d,b,p,v)}}).then(()=>{H(t,a),V(e,h),s&&u&&j(s,u),c()}).catch(()=>c())}function Ne(r,t,e,s,i){let n=s.views[0],o=s.views[1],a=e&&s.views[2]?s.views[2]:null,c=[{el:r,backward:n.backwardState,forward:n.forwardState},{el:t,backward:o.backwardState,forward:o.forwardState}];return a&&c.push({el:e,backward:a.backwardState,forward:a.forwardState}),c.map(({el:l,backward:f,forward:h})=>i==="forward"?{el:l,from:q(l,f.origin,f.transform),to:q(l,f.origin,h.transform)}:{el:l,from:q(l,h.origin,h.transform),to:q(l,h.origin,f.transform)})}function Ae(r,t){for(let{el:e,from:s,to:i}of r)e.style.transform=at(lt(s,i,t))}function Pe(r,t,e,s){for(let i=0;i<r.length;i++){let{el:n,from:o,to:a}=r[i],c=i*s,l=Math.max(0,t-c),f=e>0?Math.min(1,l/e):1;n.style.transform=at(lt(o,a,f))}}function us(){let r=typeof globalThis<"u"?globalThis:typeof window<"u"?window:{};return r.motion?.animate||r.Motion?.animate||r.animate}function Ie(r){if(typeof r!="string")return"easeInOut";let t=r.toLowerCase();return t==="linear"?"linear":t.includes("ease-in-out")?"easeInOut":t.includes("ease-in")?"easeIn":t.includes("ease-out")?"easeOut":r}var $e={css:ge,waapi:be,none:we,anime:Se,gsap:Le,motion:Oe};function Pt(r){if(typeof r=="function")return{runTransition(s,i){r(s,i)}};let t=typeof r=="string"?r.toLowerCase():"css";return{runTransition:$e[t]||$e.css}}function ds(r){if(typeof r!="string"||r.trim()==="")return{tx:0,ty:0,rest:""};let t=et(r);return t.matched?{tx:t.tx,ty:t.ty,rest:t.rest}:null}function Ze(r,t,e){let s=ds(r);if(s===null)return r;let i=s.tx*t,n=s.ty*e,o=s.rest?` ${s.rest}`:"";return`translate(${i}px, ${n}px)${o}`.trim()}function ms(r){if(typeof r!="string"||!r.trim())return null;let t=r.trim().match(/^([-\d.eE]+)px\s+([-\d.eE]+)px$/);return t?{x:parseFloat(t[1]),y:parseFloat(t[2])}:null}function Me(r,t,e){let s=ms(r);return s===null?r:`${s.x*t}px ${s.y*e}px`}function qt(r,t,e,s,i){if(!r.storedViews?.length||!r.canvas||t<=0||e<=0)return;let n=s/t,o=i/e,a=new Set,c=p=>{if(!(!p||p.detachedNode))for(let y of[p.backwardState,p.forwardState])!y||a.has(y)||(a.add(y),y.transform=Ze(y.transform,n,o),y.origin!=null&&(y.origin=Me(y.origin,n,o)))},l=[...r.storedViews];for(let p of r.lateralHistory||[])p.stage&&l.push(p.stage),c(p.entry);for(let p of l)Array.isArray(p.views)&&p.views.forEach(c);let f=r.canvas,h=f.querySelector(".is-current-view"),u=f.querySelector(".is-previous-view"),d=f.querySelector(".is-last-view"),v=f.querySelector(".is-new-current-view"),m=[h,u,d,v].filter(Boolean);for(let p of m){if(!p.style)continue;let y=p.style.transform;y!=null&&y!==""&&(p.style.transform=Ze(y,n,o));let g=p.style.transformOrigin;g!=null&&g!==""&&(p.style.transformOrigin=Me(g,n,o))}}var ps=8e3,ft=class{constructor(t){if(this.storedViews=[],this.currentStage=null,this.debug=!1,this.trace=[],this.blockEvents=!1,this._blockEventsSafetyTimer=null,this.touchstartX=0,this.touchstartY=0,this.touchendX=0,this.touchendY=0,this.touching=!1,this.lateralHistory=[],this._lastCanvasWidth=0,this._lastCanvasHeight=0,this._pendingResizeCorrection=!1,this._destroyed=!1,this._trackedTimers=new Set,this._pendingTransitionComplete=null,this._navigationTask=null,this._initPromise=null,this._accessibility=new Et,this._hooks={},this._plugins=[],ne(t,this),!this.isValid){this.notify("is unable to start: invalid or missing required options (mount, initialView, views).","error");return}if(this.canvas=document.querySelector(this.mount),!this.canvas){this.notify(`mount selector "${this.mount}" did not match any element.`,"error"),this.isValid=!1;return}this.transitionDriver=Pt(this.transitionDriver),this._onZoom=this.onZoom.bind(this),this._onTouchStart=this.onTouchStart.bind(this),this._onTouchEnd=this.onTouchEnd.bind(this),this._onTouchCancel=()=>{this.touching=!1},this._onKeyUp=this.onKeyUp.bind(this),this._onKeyDown=this.onKeyDown.bind(this),this._onKeyboardClick=e=>{e.target.closest?.(".zoom-me[data-to]")&&((e.detail===0?!this.inputs.keyboard:!this.inputs.click)||(e.preventDefault(),e.detail===0&&this.onZoom(e)))},this._onWheel=this.onWheel.bind(this),this._wheelCooldown=!1,this._onPrefetchTrigger=e=>{let s=e.target.closest?.(".zoom-me[data-to]");!this._destroyed&&s&&this.canvas.contains(s)&&this.prefetcher.prefetch(s.dataset.to,{trigger:s,context:this.componentContext,props:{...s.dataset}})},this._onResize=this._handleResize.bind(this),this._resizeDebounceTimer=null,this._RESIZE_DEBOUNCE_MS=80,this.prefetcher=new zt(this.views),this._bindEvents()}_bindEvents(){let t=this.canvas;t&&(this._canvasAttributes=new Map(["tabindex","role","aria-roledescription","aria-live"].map(e=>[e,t.getAttribute(e)])),t.setAttribute("tabindex","0"),t.setAttribute("role","application"),t.setAttribute("aria-roledescription","zoomable interface"),t.setAttribute("aria-live","polite"),t.addEventListener("mouseup",this._onZoom,!1),t.addEventListener("touchend",this._onZoom,!1),t.addEventListener("touchstart",this._onTouchStart,{passive:!0}),t.addEventListener("touchend",this._onTouchEnd,!1),t.addEventListener("touchcancel",this._onTouchCancel,{passive:!0}),t.addEventListener("keyup",this._onKeyUp,!1),t.addEventListener("keydown",this._onKeyDown,!1),t.addEventListener("click",this._onKeyboardClick,!1),t.addEventListener("wheel",this._onWheel,{passive:!1}),t.addEventListener("mouseover",this._onPrefetchTrigger,{passive:!0}),t.addEventListener("focusin",this._onPrefetchTrigger,{passive:!0}),window.addEventListener("resize",this._onResize,{passive:!0}),typeof ResizeObserver<"u"&&(this._resizeObserver=new ResizeObserver(()=>this._handleResize()),this._resizeObserver.observe(t)))}_unbindEvents(){let t=this.canvas;t&&(t.removeEventListener("mouseup",this._onZoom,!1),t.removeEventListener("touchend",this._onZoom,!1),t.removeEventListener("touchstart",this._onTouchStart),t.removeEventListener("touchend",this._onTouchEnd,!1),t.removeEventListener("touchcancel",this._onTouchCancel),t.removeEventListener("keyup",this._onKeyUp,!1),t.removeEventListener("keydown",this._onKeyDown,!1),t.removeEventListener("click",this._onKeyboardClick,!1),t.removeEventListener("wheel",this._onWheel),t.removeEventListener("mouseover",this._onPrefetchTrigger),t.removeEventListener("focusin",this._onPrefetchTrigger)),window.removeEventListener("resize",this._onResize),this._resizeObserver&&(this._resizeObserver.disconnect(),this._resizeObserver=null)}_resetCanvasScroll(t){if(t&&((t.scrollLeft!==0||t.scrollTop!==0)&&(this.notify(`canvas had a residual scroll (${t.scrollLeft}, ${t.scrollTop}) \u2014 resetting. Something scrolled the canvas mid-transition.`,"warn"),t.scrollLeft=0,t.scrollTop=0),!this._warnedScrolledAncestor)){for(let e=t.parentElement;e&&e!==document.body;e=e.parentElement)if(e.scrollLeft!==0||e.scrollTop!==0){let s=e.className?`.${String(e.className).trim().split(/\s+/).join(".")}`:e.tagName.toLowerCase();this.notify(`an ancestor of the canvas (${s}) is scrolled (${e.scrollLeft}, ${e.scrollTop}): all zooms will land displaced. Use 'overflow: clip' (not 'hidden') on containers around the canvas.`,"warn"),this._warnedScrolledAncestor=!0;break}}}_setBlockEvents(){this.blockEvents=!0,this._clearBlockEventsSafety(),this._blockEventsSafetyTimer=setTimeout(()=>{if(this.blockEvents&&!this._destroyed){this.notify("blockEvents safety timeout: driver did not call onComplete. Force-resetting.","warn"),this.blockEvents=!1;let t=this._pendingTransitionComplete;t?t():this._onTransitionComplete()}},ps)}_clearBlockEventsSafety(){this._blockEventsSafetyTimer!==null&&(clearTimeout(this._blockEventsSafetyTimer),this._blockEventsSafetyTimer=null)}_setTrackedTimeout(t,e){let s=setTimeout(()=>{this._trackedTimers.delete(s),!this._destroyed&&t()},e);return this._trackedTimers.add(s),s}_clearTrackedTimeouts(){for(let t of this._trackedTimers)clearTimeout(t);this._trackedTimers.clear()}storeViews(t){this.tracing("storedViews()"),this.storedViews.push(t),this.debug&&console.debug("Zumly storedViews",t)}tracing(t){if(this.debug)if(t==="ended"){let e=this.trace.map((s,i)=>`${i===0?`Instance ${this.mount}: ${s}`:`${s}`}`).join(" > ");this.notify(e),this.trace=[]}else this.trace.push(t)}notify(t,e){return $(this.debug,t,e)}_recordCanvasSize(){this.canvas&&(this._lastCanvasWidth=this.canvas.offsetWidth,this._lastCanvasHeight=this.canvas.offsetHeight)}_handleResize(){this._destroyed||(this._resizeDebounceTimer&&clearTimeout(this._resizeDebounceTimer),this._resizeDebounceTimer=setTimeout(()=>{if(this._resizeDebounceTimer=null,!this.isValid||!this.canvas||this._lastCanvasWidth===0)return;let t=this.canvas.offsetWidth,e=this.canvas.offsetHeight;if(!(t===this._lastCanvasWidth&&e===this._lastCanvasHeight)){if(this.blockEvents){this._pendingResizeCorrection=!0;return}qt(this,this._lastCanvasWidth,this._lastCanvasHeight,t,e),this._lastCanvasWidth=t,this._lastCanvasHeight=e}},this._RESIZE_DEBOUNCE_MS))}_onTransitionComplete(){if(this._clearBlockEventsSafety(),this._pendingResizeCorrection&&!this.blockEvents){if(this._pendingResizeCorrection=!1,this.canvas&&this._lastCanvasWidth>0){let e=this.canvas.offsetWidth,s=this.canvas.offsetHeight;(e!==this._lastCanvasWidth||s!==this._lastCanvasHeight)&&qt(this,this._lastCanvasWidth,this._lastCanvasHeight,e,s),this._lastCanvasWidth=e,this._lastCanvasHeight=s}}else this._recordCanvasSize();for(let e of this.canvas?.children||[])e.classList.contains("z-view")&&yt(e);let t=this.canvas?.querySelector(".is-current-view");t&&this._accessibility.restore(t),this._manageFocus(),this.canvas&&this._accessibility.sync(this.canvas)}_manageFocus(){if(!this.canvas)return;let t=this.canvas.querySelector(".is-current-view");if(!t)return;let e='a[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])',s=n=>!n||n.closest("[inert], [hidden]")?!1:(n.focus({preventScroll:!0}),document.activeElement===n||n.contains(document.activeElement)),i=t.querySelector(e);if(!s(i)){for(let n of t.querySelectorAll(e))if(n!==i&&s(n))return;t.setAttribute("tabindex","-1"),t.focus({preventScroll:!0})}}_prefersReducedMotion(){return typeof window.matchMedia=="function"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches}_resolveEffects(t){if(this._prefersReducedMotion())return["none","none"];let e=t?.dataset?.withEffects;if(e&&typeof e=="string"){let s=e.split("|").map(i=>i.trim());return[s[0]||"none",s[1]||s[0]||"none"]}return this.effects}_applyEffects(t,e,s,i,n){!s||s[0]==="none"&&s[1]==="none"||(t&&s[0]!=="none"&&(t.style.setProperty("--z-effect-filter",s[0]),t.style.setProperty("--zoom-duration",i),t.style.setProperty("--zoom-ease",n),t.classList.add("has-effect")),e&&s[1]!=="none"&&(e.style.setProperty("--z-effect-filter",s[1]),e.style.setProperty("--zoom-duration",i),e.style.setProperty("--zoom-ease",n),e.classList.add("has-effect")))}_removeEffect(t){if(!t||!t.classList.contains("has-effect"))return;t.classList.remove("has-effect"),t.classList.add("has-effect-reverse");let e=()=>{t.classList.remove("has-effect-reverse"),t.style.removeProperty("--z-effect-filter"),t.removeEventListener("transitionend",e)};t.addEventListener("transitionend",e,{once:!0});let s=t.style.getPropertyValue("--zoom-duration");this._setTrackedTimeout(e,s?parseFloat(s)*(s.includes("ms")?1:1e3)+100:1100)}_resolveHideTrigger(t){return t?.dataset?.hideTrigger!==void 0?t.dataset.hideTrigger==="fade"?"fade":!0:this.hideTrigger}_applyHideTrigger(t,e,s,i,n,o=!0){if(!(!s||!t))if(s==="fade"){if(t.style.setProperty("--zoom-duration",i),t.style.setProperty("--zoom-ease",n),t.classList.add("z-trigger-fade"),!o)return;e.style.setProperty("--zoom-duration",i),e.style.setProperty("--zoom-ease",n),e.classList.add("z-view-fade-in"),e.offsetHeight,e.classList.remove("hide")}else t.classList.add("z-trigger-hidden")}_restoreHideTrigger(t,e,s,i){if(!(!e||!t))if(e==="fade"){t.classList.remove("z-trigger-fade"),t.style.setProperty("--zoom-duration",s),t.style.setProperty("--zoom-ease",i),t.classList.add("z-trigger-fade-reverse");let n=()=>{t.classList.remove("z-trigger-fade-reverse"),t.style.removeProperty("--zoom-duration"),t.style.removeProperty("--zoom-ease"),t.removeEventListener("transitionend",n)};t.addEventListener("transitionend",n,{once:!0}),this._setTrackedTimeout(n,parseFloat(s)*(s.includes("ms")?1:1e3)+100)}else t.classList.remove("z-trigger-hidden")}on(t,e){return typeof e!="function"?this:((this._hooks[t]||=[]).push(e),this)}use(t,e){if(!t)return this;let s={plugin:t,options:e};return this._plugins.push(s),this._initialized&&this._installPlugin(s),this}_installPlugin(t){let{plugin:e,options:s}=t;try{typeof e=="function"?e(this,s):typeof e.install=="function"&&e.install(this,s)}catch(i){this.notify(`plugin install error: ${i.message}`,"error")}}off(t,e){return e?this._hooks[t]&&(this._hooks[t]=this._hooks[t].filter(s=>s!==e)):delete this._hooks[t],this}_emit(t,e={}){let s=this._hooks[t];if(!(!s||s.length===0))for(let i of s)try{i(e)}catch(n){this.debug&&console.error(`Zumly hook "${t}" threw:`,n)}}_runNavigation(t){if(this._destroyed||this.blockEvents)return Promise.resolve();let e={pendingViews:new Set};e.promise=new Promise(i=>{e.resolve=i}),this._navigationTask=e,this.blockEvents=!0,this.prefetcher?.pause();let s=()=>{this._navigationTask===e&&(this._navigationTask=null,this.blockEvents=!1,this._clearBlockEventsSafety(),this.prefetcher?.resume()),e.resolve()};try{Promise.resolve(t()).then(s,i=>{this.notify(`navigation aborted: ${i.message}`,"error"),s()})}catch(i){this.notify(`navigation aborted: ${i.message}`,"error"),s()}return e.promise}_cancelNavigation(){let t=this._navigationTask;if(this._navigationTask=null,this._pendingTransitionComplete=null,this._clearBlockEventsSafety(),this.blockEvents=!1,t){for(let e of t.pendingViews)C(e);t.pendingViews.clear(),t.releaseTransition?.(),t.resolve()}}_createViewContext(t={},e){let s={target:document.createElement("div"),context:this.componentContext,props:t};return e&&(s.trigger=e),this._navigationTask?.pendingViews.add(s.target),s}_runNavigationTransition(t,e){if(this._destroyed)return Promise.resolve();let s=this._navigationTask;return new Promise(i=>{s&&(s.releaseTransition=i);let n=()=>{if(this._pendingTransitionComplete===n){if(this._pendingTransitionComplete=null,this._destroyed){i();return}try{Promise.resolve(e()).then(i,l=>{this.notify(`transition completion failed: ${l.message}`,"error"),i()})}catch(l){this.notify(`transition completion failed: ${l.message}`,"error"),i()}}};this._setBlockEvents(),this._pendingTransitionComplete=n;let o=this._prefersReducedMotion?.(),a=o?Pt("none"):this.transitionDriver,c=o?{...t,duration:"0s",currentStage:{...t.currentStage,stagger:0}}:t;try{a.runTransition(c,n)}catch(l){this.notify(`transition driver failed: ${l.message}. Finishing without animation.`,"error");try{Pt("none").runTransition(c,n)}catch{n()}}})}zoomLevel(){return this.storedViews.length}getZoomLevel(){return this.zoomLevel()}getCurrentViewName(){return!this.storedViews||this.storedViews.length===0?null:this.storedViews[this.storedViews.length-1]?.views?.[0]?.viewName??null}async back(){if(!this._destroyed){if(this.blockEvents){this.notify("back ignored: a transition is already running.","warn");return}if(this.lateralHistory&&this.lateralHistory.length>0){let t=this.lateralHistory.pop(),e=t&&typeof t=="object"?t.name:t,s=t&&typeof t=="object"?t.entry:void 0,i=t&&typeof t=="object"?t.node:void 0;return this._doLateral(e,!0,{savedEntry:s,keepAliveNode:i,savedStage:t?.stage})}return this.zoomOut()}}async goTo(t,e={}){return this._destroyed?void 0:(e.mode==="lateral"?"lateral":"depth")==="depth"?this.zoomTo(t,e):this._doLateral(t,!1,e)}async zoomTo(t,e={}){if(this._destroyed)return;if(!this.isValid||!this.canvas){this.notify("zoomTo() cannot run: instance is invalid or canvas not found.","error");return}if(typeof t!="string"||!t){this.notify("zoomTo() requires a non-empty view name.","warn");return}if(!Object.prototype.hasOwnProperty.call(this.views,t)){this.notify(`zoomTo("${t}"): view not found in views. Available: ${Object.keys(this.views).join(", ")}`,"warn");return}if(this.getCurrentViewName()===t)return;let i=this.canvas.getBoundingClientRect(),n=Math.max(40,i.width*.1),o=Math.max(40,i.height*.1),c={rect:{x:i.left+(i.width-n)/2,y:i.top+(i.height-o)/2,width:n,height:o},duration:e.duration??this.duration,ease:e.ease??this.ease,props:e.props??{}};await this._doZoomIn(t,c)}init(){return this._destroyed||this._initialized?Promise.resolve():this._initPromise?this._initPromise:!this.isValid||!this.canvas?(this.notify("init() cannot run: instance is invalid or canvas element was not found.","error"),Promise.resolve()):(this._initPromise=this._runNavigation(()=>this._initialize()).finally(()=>{this._initPromise=null}),this._initPromise)}async _initialize(){this.tracing("init()");let t=this.prefetcher,e=this._createViewContext();if(this.preload&&this.preload.length&&(await t.preloadEager(this.preload,null).catch(i=>{this.notify(`preload failed: ${i.message}`,"warn")}),this._destroyed))return;let s;try{let i=await t.get(this.initialView,e);if(this._destroyed){C(i);return}if(s=await dt(i,this.initialView,this.canvas,!0,this.views,this.componentContext),this._destroyed){C(s),s.remove();return}}catch(i){this.notify(`init() failed to resolve initial view "${this.initialView}": ${i.message}`,"error");return}if(this._emit("viewMounted",{viewName:this.initialView,node:s}),!this._destroyed){t.scanAndPrefetch(s,e),this.storeViews({zoomLevel:this.storedViews.length,scale:1,views:[{viewName:this.initialView,backwardState:{origin:"0 0",transform:""}}]}),this.currentStage=this.storedViews[this.storedViews.length-1],this._recordCanvasSize(),this._accessibility.sync(this.canvas),this._initialized=!0;for(let i of this._plugins)this._installPlugin(i)}}destroy(){if(!this._destroyed){this._destroyed=!0,this._emit("destroy"),this._cancelNavigation(),this._clearBlockEventsSafety(),this._clearTrackedTimeouts(),this._pendingTransitionComplete=null,this._resizeDebounceTimer&&(clearTimeout(this._resizeDebounceTimer),this._resizeDebounceTimer=null),this._unbindEvents(),this._removeNav(),this._cleanupLateralKeepAlive(),this._accessibility.destroy(),this.canvas&&C(this.canvas);for(let t of this.storedViews){let e=Vt(t);e&&C(e)}if(this.blockEvents=!1,this.storedViews=[],this.currentStage=null,this.lateralHistory=[],this.trace=[],this._hooks={},this.prefetcher?.destroy(),this.prefetcher=null,this.transitionDriver=null,this.canvas)for(let[t,e]of this._canvasAttributes||[])e===null?this.canvas.removeAttribute(t):this.canvas.setAttribute(t,e);this.isValid=!1}}async _doZoomIn(t,e){return this._runNavigation(()=>this._performZoomIn(t,e))}async _performZoomIn(t,e){if(this._emit("beforeZoomIn",{viewName:t}),this._destroyed)return;this.tracing("zoomIn()");let s=this.canvas,i=e.el;this._resetCanvasScroll(s);let o=(this.storedViews.length>0?this.storedViews[this.storedViews.length-1]:null)?.scale??1;this.tracing("getView()");let a=this._createViewContext(i?{...i.dataset}:e.props??{},i),c=i?.dataset?.deferred!==void 0?!0:this.deferred,l,f=null,h=()=>{C(f),C(l),l?.remove()};try{if(c){let w=await this.prefetcher.get(t,a);if(this._destroyed){C(w);return}for(f=document.createDocumentFragment();w.firstChild;)f.appendChild(w.firstChild);l=await dt(w,t,s,!1,{},this.componentContext)}else{let w=await this.prefetcher.get(t,a);if(this._destroyed){C(w);return}this.prefetcher.scanAndPrefetch(w,a),l=await dt(w,t,s,!1,this.views,this.componentContext)}}catch(w){h(),this.notify(`zoomIn aborted: failed to resolve view "${t}": ${w.message}`,"error");return}if(!l){h();return}if(this._destroyed){h();return}if(c||this._emit("viewMounted",{viewName:t,node:l}),this._destroyed)return;i&&i.classList.add("zoomed");let u=s.getBoundingClientRect(),d=u.left,v=u.top,m=i?(()=>{let w=i.getBoundingClientRect();return{x:w.x,y:w.y,width:w.width,height:w.height}})():e.rect,p=i?i.dataset.withDuration||this.duration:e.duration??this.duration,y=i?i.dataset.withEase||this.ease:e.ease??this.ease,g=i?i.dataset.withCover||this.cover:e.cover??this.cover,x=i?parseInt(i.dataset.withStagger,10)||this.stagger:e.stagger??this.stagger,b=s.querySelector(".is-current-view"),_=s.querySelector(".is-previous-view"),S=s.querySelector(".is-last-view");if(!b){this.notify("zoomIn aborted: no current view found in canvas. Call init() before navigating and keep Zumly view classes intact.","error"),i&&i.classList.remove("zoomed"),h();return}this._cleanupLateralKeepAlive(),this.lateralHistory=[],Ct(l),S&&(Ct(S),s.removeChild(S));let O,A,E,T,P,B,z,D=b.style.transform,N=b.style.transformOrigin,I=_?_.style.transform:null,F=_?_.style.transformOrigin:null;try{b.classList.replace("is-current-view","is-previous-view"),_&&_.classList.replace("is-previous-view","is-last-view");let w=l.getBoundingClientRect(),L=b.getBoundingClientRect(),X=null,Yt=null,bt=null;_&&(X=_.getBoundingClientRect(),bt=_.querySelector(".zoomed"),Yt=bt&&bt.getBoundingClientRect?bt.getBoundingClientRect():X);let _t={left:d,top:v},Kt={width:u.width,height:u.height},Ut={width:w.width,height:w.height},Gt=St(m.width,m.height,w.width,w.height,g);z=Gt.scale;let He=Gt.scaleInv;O=Ft(m,_t,Ut,He),E=b.style.transform;let Qt=ae(m,L);T=le(Kt,m,L,z,this.parallax);let Jt=nt(N||"0 0"),st=Y(E||""),te=nt(Qt),rt=Y(T.transform),ee=m;if(i&&(ee=mt(m,L,Jt,st.tx,st.ty,st.scale,te,rt.tx,rt.ty,rt.scale)),A=oe(ee,_t,Ut),_){P=_.style.transform;let De=mt(L,L,Jt,st.tx,st.ty,st.scale,te,rt.tx,rt.ty,rt.scale),Fe=fe(T.x,T.y,_t,z,o),se=nt(F||"0 0"),Mt=Y(P||""),Ht=Y(Fe),Ve=mt(Yt,X,se,Mt.tx,Mt.ty,Mt.scale,se,Ht.tx,Ht.ty,Ht.scale);B=ce({canvasRect:Kt,canvasOffset:_t,triggerRect:m,previousViewRectAtBaseTransform:L,lastViewZoomedElementRect:Ve,previousViewRectWithPreviousAtEndTransform:De,scale:z,preScale:o,parallax:this.parallax})}l.style.transform=O,b.style.transformOrigin=Qt}catch(w){this.notify(`zoomIn geometry computation failed: ${w.message}. Aborting zoom.`,"error"),this.debug&&console.error("Zumly _doZoomIn error:",w),b.style.transform=D,b.style.transformOrigin=N,b.classList.contains("is-previous-view")&&b.classList.replace("is-previous-view","is-current-view"),_&&(_.style.transform=I,_.style.transformOrigin=F,_.classList.contains("is-last-view")&&_.classList.replace("is-last-view","is-previous-view")),h(),S&&s.prepend(S),i&&i.classList.remove("zoomed"),yt(b),yt(_),yt(S);return}let M=pt(l.dataset.viewName,{origin:l.style.transformOrigin,duration:p,ease:y,transform:O},{origin:l.style.transformOrigin,duration:p,ease:y,transform:A}),wt=pt(b.dataset.viewName,{origin:b.style.transformOrigin,duration:p,ease:y,transform:E},{origin:b.style.transformOrigin,duration:p,ease:y,transform:T.transform}),ht=_?pt(_.dataset.viewName,{origin:_.style.transformOrigin,duration:p,ease:y,transform:P},{origin:_.style.transformOrigin,duration:p,ease:y,transform:B}):null,U=S?he(S):null,W=ue(this.storedViews.length,M,wt,ht,U);W.scale=z,W.stagger=x||0,this.storeViews(W),this.currentStage=this.storedViews[this.storedViews.length-1],this.tracing("setCSSVariables()");let It=this._resolveEffects(i);this._applyEffects(b,_,It,p,y);let ut=this._resolveHideTrigger(i);this._applyHideTrigger(i,l,ut,p,y),ut&&(W.hideTriggerMode=ut);let $t={type:"zoomIn",currentView:l,previousView:b,lastView:_,currentStage:this.currentStage,duration:p,ease:y},Zt=async()=>{if(c&&f&&l){if(l.appendChild(f),this.prefetcher.scanAndPrefetch(l,a),typeof this.views[t]=="object"&&typeof this.views[t].mounted=="function")try{await this.views[t].mounted()}catch(w){this.notify(`deferred view mounted() failed: ${w.message}`,"error")}if(this._destroyed)return;this._emit("viewMounted",{viewName:t,node:l})}this._destroyed||(this.blockEvents=!1,this._onTransitionComplete(),this._updateNav(),this._emit("afterZoomIn",{viewName:t,zoomLevel:this.zoomLevel()}),this.tracing("ended"))};await this._runNavigationTransition($t,Zt),this._destroyed&&f&&C(f)}async zoomIn(t){this._destroyed||t?.dataset?.to&&await this._doZoomIn(t.dataset.to,{el:t})}async _doLateral(t,e=!1,s={}){return this._runNavigation(()=>this._performLateral(t,e,s))}async _performLateral(t,e=!1,s={}){if(!this.isValid||!this.canvas)return;if(!Object.prototype.hasOwnProperty.call(this.views,t)){this.notify(`goTo("${t}", { mode: 'lateral' }): view not found in views. Available: ${Object.keys(this.views).join(", ")}`,"warn");return}let i=this.canvas.querySelector(".is-current-view");if(!i)return;let n=i.dataset?.viewName;if(n===t||(this._emit("beforeLateral",{viewName:t,from:n,isBack:e}),this._destroyed))return;let o=this.lateralNav&&this.lateralNav.keepAlive,a=null;if(!e){this.lateralHistory=this.lateralHistory||[];let w=this.storedViews[this.storedViews.length-1];a={name:n,stage:this._copyLateralStage(w),node:o?i:null},a.entry=a.stage.views[0]}this.tracing("lateral()");let c=s.duration??this.duration,l=s.ease??this.ease,f=this.canvas.querySelector(".is-previous-view"),h=this.canvas.querySelector(".is-last-view"),u=null,d=null;if(o&&(e&&s.keepAliveNode?d=s.keepAliveNode:d=this.canvas.querySelector(`.is-lateral-hidden[data-view-name="${t}"]`)),d){if(d.style.display="",d.style.opacity="",d.classList.remove("is-lateral-hidden","zoom-lateral-out"),d.classList.add("is-new-current-view","has-no-events"),u=d,!e&&this.lateralHistory){let w=this.lateralHistory.findIndex(L=>L.node===d);w!==-1&&this.lateralHistory.splice(w,1)}}else{let w=()=>{e&&this.lateralHistory.push({name:t,entry:s.savedEntry,stage:s.savedStage,node:s.keepAliveNode??null})},L=this._createViewContext(s.props??{});try{let X=await this.prefetcher.get(t,L);if(this._destroyed){C(X);return}this.prefetcher.scanAndPrefetch(X,L),u=await dt(X,t,this.canvas,!1,this.views,this.componentContext)}catch(X){this.notify(`lateral navigation aborted: failed to resolve view "${t}": ${X.message}`,"error"),w();return}if(!u){w();return}if(this._destroyed){C(u),u.remove();return}if(this._emit("viewMounted",{viewName:t,node:u}),this._destroyed)return}let v=i.style.transform||"",m=this.storedViews[this.storedViews.length-1];u.style.transform="",u.style.transformOrigin="0 0";let p=new Map,y=w=>(p.has(w)||p.set(w,w.getBoundingClientRect()),p.get(w)),g=y(u),x=y(i),b=y(this.canvas),_=b.width/this.canvas.offsetWidth||1,S=b.height/this.canvas.offsetHeight||1,O=f?f.querySelectorAll(".zoom-me[data-to]"):[],A,E;for(let w of O)if(!A&&w.dataset.to===n&&(A=w),!E&&w.dataset.to===t&&(E=w),A&&E)break;let T=0,P=0,B=this._declaredSiblings(),z=B?B.indexOf(n):-1,D=B?B.indexOf(t):-1;if(z!==-1&&D!==-1)T=(z-D)*b.width*.15;else if(f)if(A&&E){let w=y(A),L=y(E);T=w.left+w.width/2-(L.left+L.width/2),P=w.top+w.height/2-(L.top+L.height/2)}else T=b.width*.15;let N=f?{transformStart:f.style.transform||"",transformEnd:this._computeLateralBackTransform(f.style.transform||"",T,P)}:null,I=h&&m.views[2]?{transformStart:h.style.transform||"",transformEnd:this._computeLateralBackTransform(h.style.transform||"",T*.7,P*.7)}:null,F=m.views[0],M=this._computeLateralBackTransform("",(x.x-g.x+(x.width-g.width)/2)/_,(x.y-g.y+(x.height-g.height)/2)/S),wt=Y(F.backwardState.transform||"").scale,ht=this._computeLateralBackTransform(F.backwardState.transform||"",(x.width-g.width)*wt/(2*_),(x.height-g.height)*wt/(2*S)),U=f?.querySelector(".zoomed");if(E&&N&&!(e&&s.savedStage)){let w=this._lateralTargetGeometry(u,E,f,h,m,{measure:y,outgoingView:i,canvasRect:b,sx:_,sy:S});w&&(M=w.currentEnd,ht=w.currentBack,N.transformEnd=w.previousEnd,I&&w.lastEnd&&(I.transformEnd=w.lastEnd),m.scale=w.scale)}if(e&&s.savedStage){Object.assign(m,this._copyLateralStage(s.savedStage)),M=m.views[0].forwardState?.transform||"",ht=m.views[0].backwardState.transform,N&&(N.transformEnd=m.views[1].forwardState.transform),I&&(I.transformEnd=m.views[2].forwardState.transform);let w=et(N?.transformStart||v),L=et(N?.transformEnd||M);T=L.tx-w.tx,P=L.ty-w.ty}else m.views[0]=pt(t,{origin:"0 0",duration:c,ease:l,transform:ht},{origin:"0 0",duration:c,ease:l,transform:M});this.currentStage=m,a&&this.lateralHistory.push(a),U?.classList.remove("zoomed");let W=E?this._resolveHideTrigger(E):!1;m.hideTriggerMode=W,E&&(E.classList.add("zoomed"),this._applyHideTrigger(E,u,W,c,l,!1),W&&E.classList.add("z-trigger-hidden")),Ct(u),N&&m.views[1]&&(m.views[1].forwardState={...m.views[1].forwardState,transform:N.transformEnd}),I&&m.views[2]&&(m.views[2].forwardState={...m.views[2].forwardState,transform:I.transformEnd});let It=this._computeLateralBackTransform(M,-T,-P),ut=this._computeLateralBackTransform(v,T,P),$t={type:"lateral",currentView:u,previousView:i,lastView:h||null,backView:f||null,backViewState:N,lastViewState:I,incomingTransformStart:It,incomingTransformEnd:M,outgoingTransform:v,outgoingTransformEnd:ut,currentStage:this.currentStage,duration:c,ease:l,canvas:this.canvas,slideDeltaX:T,slideDeltaY:P,keepAlive:o&&!e?o:!1},Zt=()=>{U&&U!==E&&(U.classList.remove("z-trigger-hidden","z-trigger-fade","z-trigger-fade-reverse"),U.style.removeProperty("--zoom-duration"),U.style.removeProperty("--zoom-ease")),W==="fade"&&E.classList.remove("z-trigger-hidden"),o&&!e&&(i.classList.remove("is-current-view","is-new-current-view","has-no-events"),i.classList.add("is-lateral-hidden"),o!=="visible"?i.style.display="none":(i.style.transform=v,i.style.opacity="")),this.blockEvents=!1,this._onTransitionComplete(),this._updateNav(),this._emit("afterLateral",{viewName:t,from:n,isBack:e}),this.tracing("ended")};return this._runNavigationTransition($t,Zt)}_copyLateralStage(t){return{...t,views:t.views.map(e=>({...e,...e.backwardState&&{backwardState:{...e.backwardState}},...(e.forwardState||e.backwardState)&&{forwardState:{...e.forwardState||e.backwardState}}}))}}_lateralTargetGeometry(t,e,s,i,n,o){let{measure:a,outgoingView:c,canvasRect:l,sx:f,sy:h}=o,u=z=>{let D=a(z);return{x:(D.x-l.x)/f,y:(D.y-l.y)/h,width:D.width/f,height:D.height/h}},d=u(t),v=u(c),m=u(s),p=u(e);if(!d.width||!d.height||!p.width||!p.height)return null;let y=Y(s.style.transform||""),g=nt(s.style.transformOrigin||"0 0"),x=e.dataset.withCover||this.cover,b=St(p.width,p.height,d.width,d.height,x).scale,_=y.scale*b,S=(z,D,N,I,F,M)=>mt(z,D,N,I.tx,I.ty,I.scale,F,M.tx,M.ty,M.scale),O=S(p,m,g,y,g,{...y,scale:_}),A={tx:y.tx+v.x+v.width/2-O.x-O.width/2,ty:y.ty+v.y+v.height/2-O.y-O.height/2,scale:_},E=z=>`translate(${z.tx}px, ${z.ty}px) scale(${z.scale})`,T=S(p,m,g,y,{x:0,y:0},Y(n.views[1].backwardState.transform||"")),P=St(T.width,T.height,d.width,d.height,x).scaleInv,B={currentEnd:`translate(${v.x-d.x+(v.width-d.width)/2}px, ${v.y-d.y+(v.height-d.height)/2}px)`,currentBack:Ft(T,{left:d.x,top:d.y},d,P),previousEnd:E(A),scale:_};if(i&&n.views[2]){let z=u(i),D=nt(i.style.transformOrigin||"0 0"),N=Y(i.style.transform||""),I=S(m,m,g,y,g,A),F={...N,scale:N.scale*b},M=S(z,z,D,N,D,F);F.tx+=I.x+b*(z.x-m.x)-M.x,F.ty+=I.y+b*(z.y-m.y)-M.y,B.lastEnd=E(F)}return B}_computeLateralBackTransform(t,e,s){let i=et(t);return i.matched?`translate(${i.tx+e}px, ${i.ty+s}px) ${i.rest}`.trim():`translate(${e}px, ${s}px) ${t}`.trim()}zoomOut(){return this._runNavigation(()=>this._performZoomOut())}_performZoomOut(){if(this._emit("beforeZoomOut",{zoomLevel:this.zoomLevel()}),this._destroyed)return;this.tracing("zoomOut()");let t=this.canvas;this._resetCanvasScroll(t);let e=t.querySelector(".is-current-view"),s=t.querySelector(".is-previous-view");if(!e||!s){this.notify("zoomOut: current or previous view not found (animation may still be running)","warn");return}this._cleanupLateralKeepAlive(),this.lateralHistory=[],this.currentStage=this.storedViews[this.storedViews.length-1];let i=t.querySelector(".is-last-view");this.tracing("setCSSVariables()");let n=this.currentStage.views[0]?.forwardState?.duration??this.duration,o=this.currentStage.views[0]?.forwardState?.ease??this.ease,a=s.querySelector(".zoomed");a&&a.classList.remove("zoomed");let c=this.currentStage.hideTriggerMode;c&&a&&this._restoreHideTrigger(a,c,n,o),c==="fade"?(e.classList.remove("z-view-fade-in"),e.style.setProperty("--zoom-duration",n),e.style.setProperty("--zoom-ease",o),e.classList.add("z-view-fade-out")):(e.classList.remove("z-view-fade-in"),e.style.removeProperty("opacity")),this._removeEffect(s),s.classList.replace("is-previous-view","is-current-view"),i!==null&&(i.classList.contains("has-effect")&&this.effects[0]!=="none"&&i.style.setProperty("--z-effect-filter",this.effects[0]),i.classList.replace("is-last-view","is-previous-view"),i.classList.remove("hide"),vt(i));let l=Vt(this.currentStage);if(l){t.prepend(l);let u=t.querySelector(".z-view:first-child");u&&(vt(u),u.classList.add("hide"))}let f={type:"zoomOut",currentView:e,previousView:s,lastView:i,currentStage:this.currentStage,duration:n,ease:o,canvas:t},h=()=>{this.blockEvents=!1,this._onTransitionComplete(),this.storedViews.pop(),this._updateNav(),this._emit("afterZoomOut",{zoomLevel:this.zoomLevel()}),this.tracing("ended")};return this._runNavigationTransition(f,h)}onZoom(t){if(this._destroyed||t.type==="mouseup"&&t.button!==0||t.type==="click"&&!this.inputs.keyboard||t.type==="mouseup"&&!this.inputs.click||t.type==="touchend"&&!this.inputs.touch)return;let e=t.target;if(e.closest?.("[inert]")||e.closest(".z-depth-nav")||e.closest(".z-lateral-nav"))return;let s=e.classList.contains("zoom-me")||e.closest(".zoom-me");if(!this.blockEvents&&s&&!this.touching){this.tracing("onZoom() \u2192 zoomIn"),t.preventDefault(),t.stopPropagation();let i=e.classList.contains("zoom-me")?e:e.closest(".zoom-me");this.zoomIn(i);return}if(this.storedViews.length>1&&!this.blockEvents&&!s&&!this.touching){let i=this.canvas.querySelector(".is-current-view");if(i&&i.contains(e))return;let n=this._findSiblingTriggerAtPoint(t.clientX,t.clientY);if(n){this.tracing("onZoom() \u2192 lateral"),t.stopPropagation(),this._doLateral(n.dataset.to);return}this.tracing("onZoom() \u2192 zoomOut"),t.stopPropagation(),this.zoomOut()}}_findSiblingTriggerAtPoint(t,e){let s=this.canvas.querySelector(".is-previous-view");if(!s)return null;let n=this.canvas.querySelector(".is-current-view")?.dataset?.viewName;if(!n)return null;let o=s.querySelectorAll(".zoom-me[data-to]");for(let a of o){if(a.dataset.to===n)continue;let c=a.getBoundingClientRect();if(t>=c.left&&t<=c.right&&e>=c.top&&e<=c.bottom)return a}return null}_getSiblings(){let e=this.canvas.querySelector(".is-current-view")?.dataset?.viewName,s=this._declaredSiblings();if(s&&s.indexOf(e)!==-1)return{siblings:s,currentIndex:s.indexOf(e)};let i=this.canvas.querySelector(".is-previous-view");if(!i)return{siblings:[],currentIndex:-1};let n=i.querySelectorAll(".zoom-me[data-to]"),o=[];for(let c of n)c.dataset.to&&o.push(c.dataset.to);let a=o.indexOf(e);return{siblings:o,currentIndex:a}}_declaredSiblings(){let t=this.lateralNav&&typeof this.lateralNav=="object"?this.lateralNav.siblings:null;if(!t)return null;if(Array.isArray(t))return t;let e=this.canvas.querySelector(".is-previous-view")?.dataset?.viewName;return e&&Array.isArray(t[e])?t[e]:null}_updateNav(){if(this._destroyed)return;let t=this.storedViews.length-1,e=this.canvas.querySelector(":scope > .z-view.is-current-view"),s=!!this.depthNav&&t>=1&&!e?.querySelector(".z-depth-nav"),i=this.lateralNav?this._getSiblings():null;i?.siblings.length<2&&(i=null),i&&this.lateralNav.mode==="auto"&&t>=1&&e&&e.offsetWidth>=this.canvas.offsetWidth&&e.offsetHeight>=this.canvas.offsetHeight&&(i=null),this._updateDepthNav(s),this._updateLateralNav(i)}_updateDepthNav(t){if(t===void 0){let n=this.canvas.querySelector(":scope > .z-view.is-current-view");t=!!this.depthNav&&this.storedViews.length>1&&!n?.querySelector(".z-depth-nav")}if(!t){this._depthNavElement?.remove();return}let e=this.depthNav.position||"bottom-left",s=this._depthNavElement;if(!s){s=document.createElement("div");let n=document.createElement("button");n.className="z-nav-back",n.setAttribute("aria-label","Zoom out (go back)"),n.innerHTML="&#8249;",n.type="button",n.addEventListener("click",o=>{o.stopPropagation(),!this._destroyed&&s.parentNode===this.canvas&&!this.blockEvents&&this.storedViews.length>1&&this.zoomOut()}),s.appendChild(n),this._depthNavElement=s}let i="z-depth-nav z-depth-nav--"+e;s.className!==i&&(s.className=i),s.parentNode!==this.canvas&&this.canvas.appendChild(s)}_updateLateralNav(t){if(t===void 0&&(t=this.lateralNav?this._getSiblings():null,t?.siblings.length<2&&(t=null),t&&this.lateralNav.mode==="auto"&&this.storedViews.length>1)){let l=this.canvas.querySelector(":scope > .z-view.is-current-view");l&&l.offsetWidth>=this.canvas.offsetWidth&&l.offsetHeight>=this.canvas.offsetHeight&&(t=null)}if(!t){this._lateralNavState?.element.remove();return}let{siblings:e,currentIndex:s}=t,i=this.lateralNav.position||"bottom-center",n=!!this.lateralNav.arrows,o=!!this.lateralNav.dots,a=this._lateralNavState;if(!a||a.arrows!==n||a.dots!==o||a.siblings.length!==e.length||a.siblings.some((l,f)=>l!==e[f])){a?.element.remove();let l=document.createElement("div");a={element:l,siblings:[...e],currentIndex:-1,arrows:n,dots:o,dotButtons:[]};let f=(h,u,d)=>{let v=document.createElement("button");return v.className="z-nav-arrow z-nav-"+h,v.setAttribute("aria-label",u),v.innerHTML=d,v.type="button",v};if(n&&(a.prevButton=f("prev","Previous sibling view","&#8249;"),l.appendChild(a.prevButton)),o){let h=document.createElement("div");h.className="z-nav-lateral-dots";for(let u of e){let d=document.createElement("button");d.className="z-nav-dot z-nav-lat-dot",d.setAttribute("aria-label",`Go to ${u}`),d.dataset.to=u,d.type="button",a.dotButtons.push(d),h.appendChild(d)}l.appendChild(h)}n&&(a.nextButton=f("next","Next sibling view","&#8250;"),l.appendChild(a.nextButton)),l.addEventListener("click",h=>{let u=h.target.closest?.("button");if(!u||!l.contains(u))return;h.stopPropagation();let d=this._lateralNavState;if(this._destroyed||this.blockEvents||d?.element!==l||l.parentNode!==this.canvas)return;let v=u===d.prevButton?d.currentIndex-1:u===d.nextButton?d.currentIndex+1:d.dotButtons.indexOf(u);v>=0&&v<d.siblings.length&&v!==d.currentIndex&&this._doLateral(d.siblings[v])}),this._lateralNavState=a}if(a.currentIndex!==s){let l=a.dotButtons[a.currentIndex];l?.classList.remove("is-active"),l?.removeAttribute("aria-current");let f=a.dotButtons[s];f?.classList.add("is-active"),f?.setAttribute("aria-current","true"),a.currentIndex=s}a.prevButton&&a.prevButton.disabled!==s<=0&&(a.prevButton.disabled=s<=0),a.nextButton&&a.nextButton.disabled!==s>=e.length-1&&(a.nextButton.disabled=s>=e.length-1);let c="z-lateral-nav z-lateral-nav--"+i;a.element.className!==c&&(a.element.className=c),a.element.parentNode!==this.canvas&&this.canvas.appendChild(a.element)}_removeNav(){this._depthNavElement?.remove(),this._lateralNavState?.element.remove(),this._depthNavElement=null,this._lateralNavState=null}_cleanupLateralKeepAlive(){if(!this.canvas)return;let t=this.canvas.querySelectorAll(".is-lateral-hidden");for(let e of t)this._accessibility.restore(e),C(e),e.remove()}onKeyDown(t){if(this._destroyed||!this.inputs.keyboard||t.defaultPrevented||jt(t.target))return;let e=t.target.closest?.(".zoom-me[data-to]");!e||kt(e)||e.closest("[inert]")||(t.key===" "||t.key==="Enter")&&(t.preventDefault(),t.key==="Enter"&&!t.repeat&&!this.blockEvents&&this.zoomIn(e))}onKeyUp(t){if(this._destroyed||!this.inputs.keyboard||t.defaultPrevented||jt(t.target)||t.target.closest?.("[inert]"))return;let e=t.target.closest?.(".zoom-me[data-to]");if(t.key===" "&&e&&!kt(e)){t.preventDefault(),this.blockEvents||this.zoomIn(e);return}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"))}onWheel(t){this._destroyed||this.inputs.wheel&&(this._isInsideScrollable(t.target,t.deltaY)||(t.preventDefault(),!(this.blockEvents||this._wheelCooldown)&&t.deltaY>0&&this.storedViews.length>1&&(this.tracing("onWheel() \u2192 zoomOut"),this._wheelCooldown=!0,this._setTrackedTimeout(()=>{this._wheelCooldown=!1},500),this.zoomOut())))}_isInsideScrollable(t,e){let s=t,i=this.canvas.querySelector(".is-current-view");for(;s&&s!==this.canvas;){if(s===i||i&&i.contains(s)){let{overflowY:n}=window.getComputedStyle(s);if((n==="auto"||n==="scroll")&&(e>0?s.scrollTop+s.clientHeight<s.scrollHeight-1:s.scrollTop>0))return!0}s=s.parentElement}return!1}onTouchStart(t){this._destroyed||this.inputs.touch&&(this.tracing("onTouchStart()"),this.touching=!0,this.touchstartX=t.changedTouches[0].screenX,this.touchstartY=t.changedTouches[0].screenY)}onTouchEnd(t){this._destroyed||this.inputs.touch&&(this.blockEvents||(this.tracing("onTouchEnd()"),this.touchendX=t.changedTouches[0].screenX,this.touchendY=t.changedTouches[0].screenY,this.handleGesture(t)),this.touching=!1)}handleGesture(t){if(t.target.closest?.(".z-depth-nav, .z-lateral-nav"))return;t.stopPropagation(),this.tracing("handleGesture()");let e=this.touchendX-this.touchstartX,s=this.touchendY-this.touchstartY,i=Math.abs(e)<10&&Math.abs(s)<10;e<-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"));let n=t.target.classList.contains("zoom-me")?t.target:t.target.closest(".zoom-me");i&&!this.blockEvents&&n&&this.touching&&(this.touching=!1,this.tracing("tap"),t.preventDefault(),this.zoomIn(n)),i&&this.storedViews.length>1&&!this.blockEvents&&!n&&t.target.closest(".is-current-view")===null&&this.touching&&(this.touching=!1,this.tracing("tap"),this.zoomOut())}};var vs={separator:"/",prefix:"/"};function Wt(r,t){let e=[];for(let s of r.storedViews){let i=s.views&&s.views[0];i&&i.viewName&&e.push(i.viewName)}return e.join(t)}function ys(r,t){let e=window.location.hash.slice(1);return e.startsWith(r)&&(e=e.slice(r.length)),e?e.split(t).filter(Boolean):[]}var Xt={install(r,t){let e=Object.assign({},vs,t),s=e.separator,i=e.prefix,n=!1,o=!1,a=null,c=!1;function l(v){if(n)return;let m=Wt(r,s),p="#"+i+m;window.location.hash!==p&&(n=!0,window.history[v](null,"",p),n=!1)}function f(){l("pushState")}function h(){l("replaceState")}r.on("afterZoomIn",f),r.on("afterLateral",f),r.on("afterZoomOut",h);async function u(){if(!(o||c)){o=!0,n=!0;try{for(;a&&!c;){let v=a;if(a=null,await r._navigationTask?.promise,c)return;if(a)continue;let m=Wt(r,s).split(s).filter(Boolean);if(v.join(s)!==m.join(s)){if(v.length>m.length){window.history.back();continue}for(;m.length>v.length&&m.length>1;){let p=m.length;if(await r.zoomOut(),c)return;if(m=Wt(r,s).split(s).filter(Boolean),a||m.length>=p)break}if(!a&&v.length===m.length&&v.length>0){let p=v[v.length-1];if(p!==m[m.length-1]){let y=r.lateralHistory||[],g=b=>typeof b=="object"?b?.name:b,x=y.map(g).lastIndexOf(p);if(x!==-1)for(;r.lateralHistory.length>x;){let b=r.lateralHistory.length;if(await r.back(),c||a||r.lateralHistory.length>=b)break}else await r.goTo(p,{mode:"lateral"})}}}}}finally{n=!1,o=!1}}}function d(){c||(a=ys(i,s),u())}window.addEventListener("popstate",d),h(),r.on("destroy",function(){c=!0,a=null,r.off("afterZoomIn",f),r.off("afterLateral",f),r.off("afterZoomOut",h),window.removeEventListener("popstate",d)})}};ft.Router=Xt;var gs=ft;
package/dist/zumly.css CHANGED
@@ -14,6 +14,20 @@
14
14
  .zumly-canvas:focus {
15
15
  outline: none;
16
16
  }
17
+ .zumly-canvas:focus-visible,
18
+ .zumly-canvas .zoom-me:focus-visible {
19
+ outline: 2px solid currentColor;
20
+ outline-offset: 3px;
21
+ }
22
+ @media (prefers-reduced-motion: reduce) {
23
+ .zumly-canvas .z-view,
24
+ .zumly-canvas .zoom-me,
25
+ .zumly-canvas .z-nav-dot {
26
+ transition-duration: 0s !important;
27
+ animation-duration: 0s !important;
28
+ animation-delay: 0s !important;
29
+ }
30
+ }
17
31
  .z-view {
18
32
  position: absolute;
19
33
  contain: strict;
@@ -21,6 +35,7 @@
21
35
  }
22
36
  .z-view.is-current-view {
23
37
  cursor: default;
38
+ content-visibility: visible;
24
39
  }
25
40
  .z-view.is-previous-view,
26
41
  .z-view.is-last-view,