{"version":3,"file":"8619.317471bef449a7fd3182.js","mappings":"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","sources":["webpack://National Motor Museum Trust/../../../src/js/util/util.js","webpack://National Motor Museum Trust/../../../src/js/util/dom-events.js","webpack://National Motor Museum Trust/../../../src/js/util/viewport-size.js","webpack://National Motor Museum Trust/../../../src/js/slide/pan-bounds.js","webpack://National Motor Museum Trust/../../../src/js/slide/zoom-level.js","webpack://National Motor Museum Trust/../../../src/js/slide/slide.js","webpack://National Motor Museum Trust/../../../src/js/gestures/drag-handler.js","webpack://National Motor Museum Trust/../../../src/js/gestures/zoom-handler.js","webpack://National Motor Museum Trust/../../../src/js/gestures/tap-handler.js","webpack://National Motor Museum Trust/../../../src/js/gestures/gestures.js","webpack://National Motor Museum Trust/../../../src/js/main-scroll.js","webpack://National Motor Museum Trust/../../../src/js/keyboard.js","webpack://National Motor Museum Trust/../../../src/js/util/css-animation.js","webpack://National Motor Museum Trust/../../../src/js/util/spring-easer.js","webpack://National Motor Museum Trust/../../../src/js/util/spring-animation.js","webpack://National Motor Museum Trust/../../../src/js/util/animations.js","webpack://National Motor Museum Trust/../../../src/js/scroll-wheel.js","webpack://National Motor Museum Trust/../../../src/js/ui/ui-element.js","webpack://National Motor Museum Trust/../../../src/js/ui/button-arrow.js","webpack://National Motor Museum Trust/../../../src/js/ui/button-close.js","webpack://National Motor Museum Trust/../../../src/js/ui/button-zoom.js","webpack://National Motor Museum Trust/../../../src/js/ui/loading-indicator.js","webpack://National Motor Museum Trust/../../../src/js/ui/counter-indicator.js","webpack://National Motor Museum Trust/../../../src/js/ui/ui.js","webpack://National Motor Museum Trust/../../../src/js/core/eventable.js","webpack://National Motor Museum Trust/../../../src/js/slide/placeholder.js","webpack://National Motor Museum Trust/../../../src/js/slide/content.js","webpack://National Motor Museum Trust/../../../src/js/slide/loader.js","webpack://National Motor Museum Trust/../../../src/js/core/base.js","webpack://National Motor Museum Trust/../../../src/js/opener.js","webpack://National Motor Museum Trust/../../../src/js/photoswipe.js","webpack://National Motor Museum Trust/../../../src/js/slide/get-thumb-bounds.js"],"sourcesContent":["/** @typedef {import('../photoswipe.js').Point} Point */\r\n\r\n/**\r\n * @template {keyof HTMLElementTagNameMap} T\r\n * @param {string} className\r\n * @param {T} tagName\r\n * @param {Node} [appendToEl]\r\n * @returns {HTMLElementTagNameMap[T]}\r\n */\r\nexport function createElement(className, tagName, appendToEl) {\r\n const el = document.createElement(tagName);\r\n if (className) {\r\n el.className = className;\r\n }\r\n if (appendToEl) {\r\n appendToEl.appendChild(el);\r\n }\r\n return el;\r\n}\r\n\r\n/**\r\n * @param {Point} p1\r\n * @param {Point} p2\r\n * @returns {Point}\r\n */\r\nexport function equalizePoints(p1, p2) {\r\n p1.x = p2.x;\r\n p1.y = p2.y;\r\n if (p2.id !== undefined) {\r\n p1.id = p2.id;\r\n }\r\n return p1;\r\n}\r\n\r\n/**\r\n * @param {Point} p\r\n */\r\nexport function roundPoint(p) {\r\n p.x = Math.round(p.x);\r\n p.y = Math.round(p.y);\r\n}\r\n\r\n/**\r\n * Returns distance between two points.\r\n *\r\n * @param {Point} p1\r\n * @param {Point} p2\r\n * @returns {number}\r\n */\r\nexport function getDistanceBetween(p1, p2) {\r\n const x = Math.abs(p1.x - p2.x);\r\n const y = Math.abs(p1.y - p2.y);\r\n return Math.sqrt((x * x) + (y * y));\r\n}\r\n\r\n/**\r\n * Whether X and Y positions of points are equal\r\n *\r\n * @param {Point} p1\r\n * @param {Point} p2\r\n * @returns {boolean}\r\n */\r\nexport function pointsEqual(p1, p2) {\r\n return p1.x === p2.x && p1.y === p2.y;\r\n}\r\n\r\n/**\r\n * The float result between the min and max values.\r\n *\r\n * @param {number} val\r\n * @param {number} min\r\n * @param {number} max\r\n * @returns {number}\r\n */\r\nexport function clamp(val, min, max) {\r\n return Math.min(Math.max(val, min), max);\r\n}\r\n\r\n/**\r\n * Get transform string\r\n *\r\n * @param {number} x\r\n * @param {number} [y]\r\n * @param {number} [scale]\r\n * @returns {string}\r\n */\r\nexport function toTransformString(x, y, scale) {\r\n let propValue = `translate3d(${x}px,${y || 0}px,0)`;\r\n\r\n if (scale !== undefined) {\r\n propValue += ` scale3d(${scale},${scale},1)`;\r\n }\r\n\r\n return propValue;\r\n}\r\n\r\n/**\r\n * Apply transform:translate(x, y) scale(scale) to element\r\n *\r\n * @param {HTMLElement} el\r\n * @param {number} x\r\n * @param {number} [y]\r\n * @param {number} [scale]\r\n */\r\nexport function setTransform(el, x, y, scale) {\r\n el.style.transform = toTransformString(x, y, scale);\r\n}\r\n\r\nconst defaultCSSEasing = 'cubic-bezier(.4,0,.22,1)';\r\n\r\n/**\r\n * Apply CSS transition to element\r\n *\r\n * @param {HTMLElement} el\r\n * @param {string} [prop] CSS property to animate\r\n * @param {number} [duration] in ms\r\n * @param {string} [ease] CSS easing function\r\n */\r\nexport function setTransitionStyle(el, prop, duration, ease) {\r\n // inOut: 'cubic-bezier(.4, 0, .22, 1)', // for \"toggle state\" transitions\r\n // out: 'cubic-bezier(0, 0, .22, 1)', // for \"show\" transitions\r\n // in: 'cubic-bezier(.4, 0, 1, 1)'// for \"hide\" transitions\r\n el.style.transition = prop\r\n ? `${prop} ${duration}ms ${ease || defaultCSSEasing}`\r\n : 'none';\r\n}\r\n\r\n/**\r\n * Apply width and height CSS properties to element\r\n *\r\n * @param {HTMLElement} el\r\n * @param {string | number} w\r\n * @param {string | number} h\r\n */\r\nexport function setWidthHeight(el, w, h) {\r\n el.style.width = (typeof w === 'number') ? `${w}px` : w;\r\n el.style.height = (typeof h === 'number') ? `${h}px` : h;\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} el\r\n */\r\nexport function removeTransitionStyle(el) {\r\n setTransitionStyle(el);\r\n}\r\n\r\n/**\r\n * @param {HTMLImageElement} img\r\n * @returns {Promise}\r\n */\r\nexport function decodeImage(img) {\r\n if ('decode' in img) {\r\n return img.decode().catch(() => {});\r\n }\r\n\r\n if (img.complete) {\r\n return Promise.resolve(img);\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n img.onload = () => resolve(img);\r\n img.onerror = reject;\r\n });\r\n}\r\n\r\n/** @typedef {LOAD_STATE[keyof LOAD_STATE]} LoadState */\r\n/** @type {{ IDLE: 'idle'; LOADING: 'loading'; LOADED: 'loaded'; ERROR: 'error' }} */\r\nexport const LOAD_STATE = {\r\n IDLE: 'idle',\r\n LOADING: 'loading',\r\n LOADED: 'loaded',\r\n ERROR: 'error',\r\n};\r\n\r\n\r\n/**\r\n * Check if click or keydown event was dispatched\r\n * with a special key or via mouse wheel.\r\n *\r\n * @param {MouseEvent | KeyboardEvent} e\r\n * @returns {boolean}\r\n */\r\nexport function specialKeyUsed(e) {\r\n return ('button' in e && e.button === 1) || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey;\r\n}\r\n\r\n/**\r\n * Parse `gallery` or `children` options.\r\n *\r\n * @param {import('../photoswipe.js').ElementProvider} [option]\r\n * @param {string} [legacySelector]\r\n * @param {HTMLElement | Document} [parent]\r\n * @returns HTMLElement[]\r\n */\r\nexport function getElementsFromOption(option, legacySelector, parent = document) {\r\n /** @type {HTMLElement[]} */\r\n let elements = [];\r\n\r\n if (option instanceof Element) {\r\n elements = [option];\r\n } else if (option instanceof NodeList || Array.isArray(option)) {\r\n elements = Array.from(option);\r\n } else {\r\n const selector = typeof option === 'string' ? option : legacySelector;\r\n if (selector) {\r\n elements = Array.from(parent.querySelectorAll(selector));\r\n }\r\n }\r\n\r\n return elements;\r\n}\r\n\r\n/**\r\n * Check if variable is PhotoSwipe class\r\n *\r\n * @param {any} fn\r\n * @returns {boolean}\r\n */\r\nexport function isPswpClass(fn) {\r\n return typeof fn === 'function'\r\n && fn.prototype\r\n && fn.prototype.goTo;\r\n}\r\n\r\n/**\r\n * Check if browser is Safari\r\n *\r\n * @returns {boolean}\r\n */\r\nexport function isSafari() {\r\n return !!(navigator.vendor && navigator.vendor.match(/apple/i));\r\n}\r\n\r\n","// Detect passive event listener support\r\nlet supportsPassive = false;\r\n/* eslint-disable */\r\ntry {\r\n /* @ts-ignore */\r\n window.addEventListener('test', null, Object.defineProperty({}, 'passive', {\r\n get: () => {\r\n supportsPassive = true;\r\n }\r\n }));\r\n} catch (e) {}\r\n/* eslint-enable */\r\n\r\n/**\r\n * @typedef {Object} PoolItem\r\n * @prop {HTMLElement | Window | Document | undefined | null} target\r\n * @prop {string} type\r\n * @prop {EventListenerOrEventListenerObject} listener\r\n * @prop {boolean} [passive]\r\n */\r\n\r\nclass DOMEvents {\r\n constructor() {\r\n /**\r\n * @type {PoolItem[]}\r\n * @private\r\n */\r\n this._pool = [];\r\n }\r\n\r\n /**\r\n * Adds event listeners\r\n *\r\n * @param {PoolItem['target']} target\r\n * @param {PoolItem['type']} type Can be multiple, separated by space.\r\n * @param {PoolItem['listener']} listener\r\n * @param {PoolItem['passive']} [passive]\r\n */\r\n add(target, type, listener, passive) {\r\n this._toggleListener(target, type, listener, passive);\r\n }\r\n\r\n /**\r\n * Removes event listeners\r\n *\r\n * @param {PoolItem['target']} target\r\n * @param {PoolItem['type']} type\r\n * @param {PoolItem['listener']} listener\r\n * @param {PoolItem['passive']} [passive]\r\n */\r\n remove(target, type, listener, passive) {\r\n this._toggleListener(target, type, listener, passive, true);\r\n }\r\n\r\n /**\r\n * Removes all bound events\r\n */\r\n removeAll() {\r\n this._pool.forEach((poolItem) => {\r\n this._toggleListener(\r\n poolItem.target,\r\n poolItem.type,\r\n poolItem.listener,\r\n poolItem.passive,\r\n true,\r\n true\r\n );\r\n });\r\n this._pool = [];\r\n }\r\n\r\n /**\r\n * Adds or removes event\r\n *\r\n * @private\r\n * @param {PoolItem['target']} target\r\n * @param {PoolItem['type']} type\r\n * @param {PoolItem['listener']} listener\r\n * @param {PoolItem['passive']} [passive]\r\n * @param {boolean} [unbind] Whether the event should be added or removed\r\n * @param {boolean} [skipPool] Whether events pool should be skipped\r\n */\r\n _toggleListener(target, type, listener, passive, unbind, skipPool) {\r\n if (!target) {\r\n return;\r\n }\r\n\r\n const methodName = unbind ? 'removeEventListener' : 'addEventListener';\r\n const types = type.split(' ');\r\n types.forEach((eType) => {\r\n if (eType) {\r\n // Events pool is used to easily unbind all events when PhotoSwipe is closed,\r\n // so developer doesn't need to do this manually\r\n if (!skipPool) {\r\n if (unbind) {\r\n // Remove from the events pool\r\n this._pool = this._pool.filter((poolItem) => {\r\n return poolItem.type !== eType\r\n || poolItem.listener !== listener\r\n || poolItem.target !== target;\r\n });\r\n } else {\r\n // Add to the events pool\r\n this._pool.push({\r\n target,\r\n type: eType,\r\n listener,\r\n passive\r\n });\r\n }\r\n }\r\n\r\n // most PhotoSwipe events call preventDefault,\r\n // and we do not need browser to scroll the page\r\n const eventOptions = supportsPassive ? { passive: (passive || false) } : false;\r\n\r\n target[methodName](\r\n eType,\r\n listener,\r\n eventOptions\r\n );\r\n }\r\n });\r\n }\r\n}\r\n\r\nexport default DOMEvents;\r\n","/** @typedef {import('../photoswipe.js').PhotoSwipeOptions} PhotoSwipeOptions */\r\n/** @typedef {import('../core/base.js').default} PhotoSwipeBase */\r\n/** @typedef {import('../photoswipe.js').Point} Point */\r\n/** @typedef {import('../slide/slide.js').SlideData} SlideData */\r\n\r\n/**\r\n * @param {PhotoSwipeOptions} options\r\n * @param {PhotoSwipeBase} pswp\r\n * @returns {Point}\r\n */\r\nexport function getViewportSize(options, pswp) {\r\n if (options.getViewportSizeFn) {\r\n const newViewportSize = options.getViewportSizeFn(options, pswp);\r\n if (newViewportSize) {\r\n return newViewportSize;\r\n }\r\n }\r\n\r\n return {\r\n x: document.documentElement.clientWidth,\r\n\r\n // TODO: height on mobile is very incosistent due to toolbar\r\n // find a way to improve this\r\n //\r\n // document.documentElement.clientHeight - doesn't seem to work well\r\n y: window.innerHeight\r\n };\r\n}\r\n\r\n/**\r\n * Parses padding option.\r\n * Supported formats:\r\n *\r\n * // Object\r\n * padding: {\r\n * top: 0,\r\n * bottom: 0,\r\n * left: 0,\r\n * right: 0\r\n * }\r\n *\r\n * // A function that returns the object\r\n * paddingFn: (viewportSize, itemData, index) => {\r\n * return {\r\n * top: 0,\r\n * bottom: 0,\r\n * left: 0,\r\n * right: 0\r\n * };\r\n * }\r\n *\r\n * // Legacy variant\r\n * paddingLeft: 0,\r\n * paddingRight: 0,\r\n * paddingTop: 0,\r\n * paddingBottom: 0,\r\n *\r\n * @param {'left' | 'top' | 'bottom' | 'right'} prop\r\n * @param {PhotoSwipeOptions} options PhotoSwipe options\r\n * @param {Point} viewportSize PhotoSwipe viewport size, for example: { x:800, y:600 }\r\n * @param {SlideData} itemData Data about the slide\r\n * @param {number} index Slide index\r\n * @returns {number}\r\n */\r\nexport function parsePaddingOption(prop, options, viewportSize, itemData, index) {\r\n let paddingValue = 0;\r\n\r\n if (options.paddingFn) {\r\n paddingValue = options.paddingFn(viewportSize, itemData, index)[prop];\r\n } else if (options.padding) {\r\n paddingValue = options.padding[prop];\r\n } else {\r\n const legacyPropName = 'padding' + prop[0].toUpperCase() + prop.slice(1);\r\n // @ts-expect-error\r\n if (options[legacyPropName]) {\r\n // @ts-expect-error\r\n paddingValue = options[legacyPropName];\r\n }\r\n }\r\n\r\n return Number(paddingValue) || 0;\r\n}\r\n\r\n/**\r\n * @param {PhotoSwipeOptions} options\r\n * @param {Point} viewportSize\r\n * @param {SlideData} itemData\r\n * @param {number} index\r\n * @returns {Point}\r\n */\r\nexport function getPanAreaSize(options, viewportSize, itemData, index) {\r\n return {\r\n x: viewportSize.x\r\n - parsePaddingOption('left', options, viewportSize, itemData, index)\r\n - parsePaddingOption('right', options, viewportSize, itemData, index),\r\n y: viewportSize.y\r\n - parsePaddingOption('top', options, viewportSize, itemData, index)\r\n - parsePaddingOption('bottom', options, viewportSize, itemData, index)\r\n };\r\n}\r\n","import { clamp } from '../util/util.js';\r\nimport { parsePaddingOption } from '../util/viewport-size.js';\r\n\r\n/** @typedef {import('./slide.js').default} Slide */\r\n/** @typedef {Record} Point */\r\n/** @typedef {'x' | 'y'} Axis */\r\n\r\n/**\r\n * Calculates minimum, maximum and initial (center) bounds of a slide\r\n */\r\nclass PanBounds {\r\n /**\r\n * @param {Slide} slide\r\n */\r\n constructor(slide) {\r\n this.slide = slide;\r\n this.currZoomLevel = 1;\r\n this.center = /** @type {Point} */ { x: 0, y: 0 };\r\n this.max = /** @type {Point} */ { x: 0, y: 0 };\r\n this.min = /** @type {Point} */ { x: 0, y: 0 };\r\n }\r\n\r\n /**\r\n * _getItemBounds\r\n *\r\n * @param {number} currZoomLevel\r\n */\r\n update(currZoomLevel) {\r\n this.currZoomLevel = currZoomLevel;\r\n\r\n if (!this.slide.width) {\r\n this.reset();\r\n } else {\r\n this._updateAxis('x');\r\n this._updateAxis('y');\r\n this.slide.pswp.dispatch('calcBounds', { slide: this.slide });\r\n }\r\n }\r\n\r\n /**\r\n * _calculateItemBoundsForAxis\r\n *\r\n * @param {Axis} axis\r\n */\r\n _updateAxis(axis) {\r\n const { pswp } = this.slide;\r\n const elSize = this.slide[axis === 'x' ? 'width' : 'height'] * this.currZoomLevel;\r\n const paddingProp = axis === 'x' ? 'left' : 'top';\r\n const padding = parsePaddingOption(\r\n paddingProp,\r\n pswp.options,\r\n pswp.viewportSize,\r\n this.slide.data,\r\n this.slide.index\r\n );\r\n\r\n const panAreaSize = this.slide.panAreaSize[axis];\r\n\r\n // Default position of element.\r\n // By default, it is center of viewport:\r\n this.center[axis] = Math.round((panAreaSize - elSize) / 2) + padding;\r\n\r\n // maximum pan position\r\n this.max[axis] = (elSize > panAreaSize)\r\n ? Math.round(panAreaSize - elSize) + padding\r\n : this.center[axis];\r\n\r\n // minimum pan position\r\n this.min[axis] = (elSize > panAreaSize)\r\n ? padding\r\n : this.center[axis];\r\n }\r\n\r\n // _getZeroBounds\r\n reset() {\r\n this.center.x = 0;\r\n this.center.y = 0;\r\n this.max.x = 0;\r\n this.max.y = 0;\r\n this.min.x = 0;\r\n this.min.y = 0;\r\n }\r\n\r\n /**\r\n * Correct pan position if it's beyond the bounds\r\n *\r\n * @param {Axis} axis x or y\r\n * @param {number} panOffset\r\n * @returns {number}\r\n */\r\n correctPan(axis, panOffset) { // checkPanBounds\r\n return clamp(panOffset, this.max[axis], this.min[axis]);\r\n }\r\n}\r\n\r\nexport default PanBounds;\r\n","const MAX_IMAGE_WIDTH = 4000;\r\n\r\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\r\n/** @typedef {import('../photoswipe.js').PhotoSwipeOptions} PhotoSwipeOptions */\r\n/** @typedef {import('../photoswipe.js').Point} Point */\r\n/** @typedef {import('../slide/slide.js').SlideData} SlideData */\r\n\r\n/** @typedef {'fit' | 'fill' | number | ((zoomLevelObject: ZoomLevel) => number)} ZoomLevelOption */\r\n\r\n/**\r\n * Calculates zoom levels for specific slide.\r\n * Depends on viewport size and image size.\r\n */\r\nclass ZoomLevel {\r\n /**\r\n * @param {PhotoSwipeOptions} options PhotoSwipe options\r\n * @param {SlideData} itemData Slide data\r\n * @param {number} index Slide index\r\n * @param {PhotoSwipe} [pswp] PhotoSwipe instance, can be undefined if not initialized yet\r\n */\r\n constructor(options, itemData, index, pswp) {\r\n this.pswp = pswp;\r\n this.options = options;\r\n this.itemData = itemData;\r\n this.index = index;\r\n /** @type { Point | null } */\r\n this.panAreaSize = null;\r\n /** @type { Point | null } */\r\n this.elementSize = null;\r\n this.fit = 1;\r\n this.fill = 1;\r\n this.vFill = 1;\r\n this.initial = 1;\r\n this.secondary = 1;\r\n this.max = 1;\r\n this.min = 1;\r\n }\r\n\r\n /**\r\n * Calculate initial, secondary and maximum zoom level for the specified slide.\r\n *\r\n * It should be called when either image or viewport size changes.\r\n *\r\n * @param {number} maxWidth\r\n * @param {number} maxHeight\r\n * @param {Point} panAreaSize\r\n */\r\n update(maxWidth, maxHeight, panAreaSize) {\r\n /** @type {Point} */\r\n const elementSize = { x: maxWidth, y: maxHeight };\r\n this.elementSize = elementSize;\r\n this.panAreaSize = panAreaSize;\r\n\r\n const hRatio = panAreaSize.x / elementSize.x;\r\n const vRatio = panAreaSize.y / elementSize.y;\r\n\r\n this.fit = Math.min(1, hRatio < vRatio ? hRatio : vRatio);\r\n this.fill = Math.min(1, hRatio > vRatio ? hRatio : vRatio);\r\n\r\n // zoom.vFill defines zoom level of the image\r\n // when it has 100% of viewport vertical space (height)\r\n this.vFill = Math.min(1, vRatio);\r\n\r\n this.initial = this._getInitial();\r\n this.secondary = this._getSecondary();\r\n this.max = Math.max(\r\n this.initial,\r\n this.secondary,\r\n this._getMax()\r\n );\r\n\r\n this.min = Math.min(\r\n this.fit,\r\n this.initial,\r\n this.secondary\r\n );\r\n\r\n if (this.pswp) {\r\n this.pswp.dispatch('zoomLevelsUpdate', { zoomLevels: this, slideData: this.itemData });\r\n }\r\n }\r\n\r\n /**\r\n * Parses user-defined zoom option.\r\n *\r\n * @private\r\n * @param {'initial' | 'secondary' | 'max'} optionPrefix Zoom level option prefix (initial, secondary, max)\r\n * @returns { number | undefined }\r\n */\r\n _parseZoomLevelOption(optionPrefix) {\r\n const optionName = /** @type {'initialZoomLevel' | 'secondaryZoomLevel' | 'maxZoomLevel'} */ (\r\n optionPrefix + 'ZoomLevel'\r\n );\r\n const optionValue = this.options[optionName];\r\n\r\n if (!optionValue) {\r\n return;\r\n }\r\n\r\n if (typeof optionValue === 'function') {\r\n return optionValue(this);\r\n }\r\n\r\n if (optionValue === 'fill') {\r\n return this.fill;\r\n }\r\n\r\n if (optionValue === 'fit') {\r\n return this.fit;\r\n }\r\n\r\n return Number(optionValue);\r\n }\r\n\r\n /**\r\n * Get zoom level to which image will be zoomed after double-tap gesture,\r\n * or when user clicks on zoom icon,\r\n * or mouse-click on image itself.\r\n * If you return 1 image will be zoomed to its original size.\r\n *\r\n * @private\r\n * @return {number}\r\n */\r\n _getSecondary() {\r\n let currZoomLevel = this._parseZoomLevelOption('secondary');\r\n\r\n if (currZoomLevel) {\r\n return currZoomLevel;\r\n }\r\n\r\n // 3x of \"fit\" state, but not larger than original\r\n currZoomLevel = Math.min(1, this.fit * 3);\r\n\r\n if (this.elementSize && currZoomLevel * this.elementSize.x > MAX_IMAGE_WIDTH) {\r\n currZoomLevel = MAX_IMAGE_WIDTH / this.elementSize.x;\r\n }\r\n\r\n return currZoomLevel;\r\n }\r\n\r\n /**\r\n * Get initial image zoom level.\r\n *\r\n * @private\r\n * @return {number}\r\n */\r\n _getInitial() {\r\n return this._parseZoomLevelOption('initial') || this.fit;\r\n }\r\n\r\n /**\r\n * Maximum zoom level when user zooms\r\n * via zoom/pinch gesture,\r\n * via cmd/ctrl-wheel or via trackpad.\r\n *\r\n * @private\r\n * @return {number}\r\n */\r\n _getMax() {\r\n // max zoom level is x4 from \"fit state\",\r\n // used for zoom gesture and ctrl/trackpad zoom\r\n return this._parseZoomLevelOption('max') || Math.max(1, this.fit * 4);\r\n }\r\n}\r\n\r\nexport default ZoomLevel;\r\n","/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\r\n/** @typedef {import('../photoswipe.js').Point} Point */\r\n\r\n/**\r\n * @typedef {_SlideData & Record} SlideData\r\n * @typedef {Object} _SlideData\r\n * @prop {HTMLElement} [element] thumbnail element\r\n * @prop {string} [src] image URL\r\n * @prop {string} [srcset] image srcset\r\n * @prop {number} [w] image width (deprecated)\r\n * @prop {number} [h] image height (deprecated)\r\n * @prop {number} [width] image width\r\n * @prop {number} [height] image height\r\n * @prop {string} [msrc] placeholder image URL that's displayed before large image is loaded\r\n * @prop {string} [alt] image alt text\r\n * @prop {boolean} [thumbCropped] whether thumbnail is cropped client-side or not\r\n * @prop {string} [html] html content of a slide\r\n * @prop {'image' | 'html' | string} [type] slide type\r\n */\r\n\r\nimport {\r\n createElement,\r\n setTransform,\r\n equalizePoints,\r\n roundPoint,\r\n toTransformString,\r\n clamp,\r\n} from '../util/util.js';\r\n\r\nimport PanBounds from './pan-bounds.js';\r\nimport ZoomLevel from './zoom-level.js';\r\nimport { getPanAreaSize } from '../util/viewport-size.js';\r\n\r\n/**\r\n * Renders and allows to control a single slide\r\n */\r\nclass Slide {\r\n /**\r\n * @param {SlideData} data\r\n * @param {number} index\r\n * @param {PhotoSwipe} pswp\r\n */\r\n constructor(data, index, pswp) {\r\n this.data = data;\r\n this.index = index;\r\n this.pswp = pswp;\r\n this.isActive = (index === pswp.currIndex);\r\n this.currentResolution = 0;\r\n /** @type {Point} */\r\n this.panAreaSize = { x: 0, y: 0 };\r\n /** @type {Point} */\r\n this.pan = { x: 0, y: 0 };\r\n\r\n this.isFirstSlide = (this.isActive && !pswp.opener.isOpen);\r\n\r\n this.zoomLevels = new ZoomLevel(pswp.options, data, index, pswp);\r\n\r\n this.pswp.dispatch('gettingData', {\r\n slide: this,\r\n data: this.data,\r\n index\r\n });\r\n\r\n this.content = this.pswp.contentLoader.getContentBySlide(this);\r\n this.container = createElement('pswp__zoom-wrap', 'div');\r\n /** @type {HTMLElement | null} */\r\n this.holderElement = null;\r\n\r\n this.currZoomLevel = 1;\r\n /** @type {number} */\r\n this.width = this.content.width;\r\n /** @type {number} */\r\n this.height = this.content.height;\r\n this.heavyAppended = false;\r\n this.bounds = new PanBounds(this);\r\n\r\n this.prevDisplayedWidth = -1;\r\n this.prevDisplayedHeight = -1;\r\n\r\n this.pswp.dispatch('slideInit', { slide: this });\r\n }\r\n\r\n /**\r\n * If this slide is active/current/visible\r\n *\r\n * @param {boolean} isActive\r\n */\r\n setIsActive(isActive) {\r\n if (isActive && !this.isActive) {\r\n // slide just became active\r\n this.activate();\r\n } else if (!isActive && this.isActive) {\r\n // slide just became non-active\r\n this.deactivate();\r\n }\r\n }\r\n\r\n /**\r\n * Appends slide content to DOM\r\n *\r\n * @param {HTMLElement} holderElement\r\n */\r\n append(holderElement) {\r\n this.holderElement = holderElement;\r\n\r\n this.container.style.transformOrigin = '0 0';\r\n\r\n // Slide appended to DOM\r\n if (!this.data) {\r\n return;\r\n }\r\n\r\n this.calculateSize();\r\n\r\n this.load();\r\n this.updateContentSize();\r\n this.appendHeavy();\r\n\r\n this.holderElement.appendChild(this.container);\r\n\r\n this.zoomAndPanToInitial();\r\n\r\n this.pswp.dispatch('firstZoomPan', { slide: this });\r\n\r\n this.applyCurrentZoomPan();\r\n\r\n this.pswp.dispatch('afterSetContent', { slide: this });\r\n\r\n if (this.isActive) {\r\n this.activate();\r\n }\r\n }\r\n\r\n load() {\r\n this.content.load(false);\r\n this.pswp.dispatch('slideLoad', { slide: this });\r\n }\r\n\r\n /**\r\n * Append \"heavy\" DOM elements\r\n *\r\n * This may depend on a type of slide,\r\n * but generally these are large images.\r\n */\r\n appendHeavy() {\r\n const { pswp } = this;\r\n const appendHeavyNearby = true; // todo\r\n\r\n // Avoid appending heavy elements during animations\r\n if (this.heavyAppended\r\n || !pswp.opener.isOpen\r\n || pswp.mainScroll.isShifted()\r\n || (!this.isActive && !appendHeavyNearby)) {\r\n return;\r\n }\r\n\r\n if (this.pswp.dispatch('appendHeavy', { slide: this }).defaultPrevented) {\r\n return;\r\n }\r\n\r\n this.heavyAppended = true;\r\n\r\n this.content.append();\r\n\r\n this.pswp.dispatch('appendHeavyContent', { slide: this });\r\n }\r\n\r\n /**\r\n * Triggered when this slide is active (selected).\r\n *\r\n * If it's part of opening/closing transition -\r\n * activate() will trigger after the transition is ended.\r\n */\r\n activate() {\r\n this.isActive = true;\r\n this.appendHeavy();\r\n this.content.activate();\r\n this.pswp.dispatch('slideActivate', { slide: this });\r\n }\r\n\r\n /**\r\n * Triggered when this slide becomes inactive.\r\n *\r\n * Slide can become inactive only after it was active.\r\n */\r\n deactivate() {\r\n this.isActive = false;\r\n this.content.deactivate();\r\n\r\n if (this.currZoomLevel !== this.zoomLevels.initial) {\r\n // allow filtering\r\n this.calculateSize();\r\n }\r\n\r\n // reset zoom level\r\n this.currentResolution = 0;\r\n this.zoomAndPanToInitial();\r\n this.applyCurrentZoomPan();\r\n this.updateContentSize();\r\n\r\n this.pswp.dispatch('slideDeactivate', { slide: this });\r\n }\r\n\r\n /**\r\n * The slide should destroy itself, it will never be used again.\r\n * (unbind all events and destroy internal components)\r\n */\r\n destroy() {\r\n this.content.hasSlide = false;\r\n this.content.remove();\r\n this.container.remove();\r\n this.pswp.dispatch('slideDestroy', { slide: this });\r\n }\r\n\r\n resize() {\r\n if (this.currZoomLevel === this.zoomLevels.initial || !this.isActive) {\r\n // Keep initial zoom level if it was before the resize,\r\n // as well as when this slide is not active\r\n\r\n // Reset position and scale to original state\r\n this.calculateSize();\r\n this.currentResolution = 0;\r\n this.zoomAndPanToInitial();\r\n this.applyCurrentZoomPan();\r\n this.updateContentSize();\r\n } else {\r\n // readjust pan position if it's beyond the bounds\r\n this.calculateSize();\r\n this.bounds.update(this.currZoomLevel);\r\n this.panTo(this.pan.x, this.pan.y);\r\n }\r\n }\r\n\r\n\r\n /**\r\n * Apply size to current slide content,\r\n * based on the current resolution and scale.\r\n *\r\n * @param {boolean} [force] if size should be updated even if dimensions weren't changed\r\n */\r\n updateContentSize(force) {\r\n // Use initial zoom level\r\n // if resolution is not defined (user didn't zoom yet)\r\n const scaleMultiplier = this.currentResolution || this.zoomLevels.initial;\r\n\r\n if (!scaleMultiplier) {\r\n return;\r\n }\r\n\r\n const width = Math.round(this.width * scaleMultiplier) || this.pswp.viewportSize.x;\r\n const height = Math.round(this.height * scaleMultiplier) || this.pswp.viewportSize.y;\r\n\r\n if (!this.sizeChanged(width, height) && !force) {\r\n return;\r\n }\r\n this.content.setDisplayedSize(width, height);\r\n }\r\n\r\n /**\r\n * @param {number} width\r\n * @param {number} height\r\n */\r\n sizeChanged(width, height) {\r\n if (width !== this.prevDisplayedWidth\r\n || height !== this.prevDisplayedHeight) {\r\n this.prevDisplayedWidth = width;\r\n this.prevDisplayedHeight = height;\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /** @returns {HTMLImageElement | HTMLDivElement | null | undefined} */\r\n getPlaceholderElement() {\r\n return this.content.placeholder?.element;\r\n }\r\n\r\n /**\r\n * Zoom current slide image to...\r\n *\r\n * @param {number} destZoomLevel Destination zoom level.\r\n * @param {Point} [centerPoint]\r\n * Transform origin center point, or false if viewport center should be used.\r\n * @param {number | false} [transitionDuration] Transition duration, may be set to 0.\r\n * @param {boolean} [ignoreBounds] Minimum and maximum zoom levels will be ignored.\r\n */\r\n zoomTo(destZoomLevel, centerPoint, transitionDuration, ignoreBounds) {\r\n const { pswp } = this;\r\n if (!this.isZoomable()\r\n || pswp.mainScroll.isShifted()) {\r\n return;\r\n }\r\n\r\n pswp.dispatch('beforeZoomTo', {\r\n destZoomLevel, centerPoint, transitionDuration\r\n });\r\n\r\n // stop all pan and zoom transitions\r\n pswp.animations.stopAllPan();\r\n\r\n // if (!centerPoint) {\r\n // centerPoint = pswp.getViewportCenterPoint();\r\n // }\r\n\r\n const prevZoomLevel = this.currZoomLevel;\r\n\r\n if (!ignoreBounds) {\r\n destZoomLevel = clamp(destZoomLevel, this.zoomLevels.min, this.zoomLevels.max);\r\n }\r\n\r\n // if (transitionDuration === undefined) {\r\n // transitionDuration = this.pswp.options.zoomAnimationDuration;\r\n // }\r\n\r\n this.setZoomLevel(destZoomLevel);\r\n this.pan.x = this.calculateZoomToPanOffset('x', centerPoint, prevZoomLevel);\r\n this.pan.y = this.calculateZoomToPanOffset('y', centerPoint, prevZoomLevel);\r\n roundPoint(this.pan);\r\n\r\n const finishTransition = () => {\r\n this._setResolution(destZoomLevel);\r\n this.applyCurrentZoomPan();\r\n };\r\n\r\n if (!transitionDuration) {\r\n finishTransition();\r\n } else {\r\n pswp.animations.startTransition({\r\n isPan: true,\r\n name: 'zoomTo',\r\n target: this.container,\r\n transform: this.getCurrentTransform(),\r\n onComplete: finishTransition,\r\n duration: transitionDuration,\r\n easing: pswp.options.easing\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * @param {Point} [centerPoint]\r\n */\r\n toggleZoom(centerPoint) {\r\n this.zoomTo(\r\n this.currZoomLevel === this.zoomLevels.initial\r\n ? this.zoomLevels.secondary : this.zoomLevels.initial,\r\n centerPoint,\r\n this.pswp.options.zoomAnimationDuration\r\n );\r\n }\r\n\r\n /**\r\n * Updates zoom level property and recalculates new pan bounds,\r\n * unlike zoomTo it does not apply transform (use applyCurrentZoomPan)\r\n *\r\n * @param {number} currZoomLevel\r\n */\r\n setZoomLevel(currZoomLevel) {\r\n this.currZoomLevel = currZoomLevel;\r\n this.bounds.update(this.currZoomLevel);\r\n }\r\n\r\n /**\r\n * Get pan position after zoom at a given `point`.\r\n *\r\n * Always call setZoomLevel(newZoomLevel) beforehand to recalculate\r\n * pan bounds according to the new zoom level.\r\n *\r\n * @param {'x' | 'y'} axis\r\n * @param {Point} [point]\r\n * point based on which zoom is performed, usually refers to the current mouse position,\r\n * if false - viewport center will be used.\r\n * @param {number} [prevZoomLevel] Zoom level before new zoom was applied.\r\n * @returns {number}\r\n */\r\n calculateZoomToPanOffset(axis, point, prevZoomLevel) {\r\n const totalPanDistance = this.bounds.max[axis] - this.bounds.min[axis];\r\n if (totalPanDistance === 0) {\r\n return this.bounds.center[axis];\r\n }\r\n\r\n if (!point) {\r\n point = this.pswp.getViewportCenterPoint();\r\n }\r\n\r\n if (!prevZoomLevel) {\r\n prevZoomLevel = this.zoomLevels.initial;\r\n }\r\n\r\n const zoomFactor = this.currZoomLevel / prevZoomLevel;\r\n return this.bounds.correctPan(\r\n axis,\r\n (this.pan[axis] - point[axis]) * zoomFactor + point[axis]\r\n );\r\n }\r\n\r\n /**\r\n * Apply pan and keep it within bounds.\r\n *\r\n * @param {number} panX\r\n * @param {number} panY\r\n */\r\n panTo(panX, panY) {\r\n this.pan.x = this.bounds.correctPan('x', panX);\r\n this.pan.y = this.bounds.correctPan('y', panY);\r\n this.applyCurrentZoomPan();\r\n }\r\n\r\n /**\r\n * If the slide in the current state can be panned by the user\r\n * @returns {boolean}\r\n */\r\n isPannable() {\r\n return Boolean(this.width) && (this.currZoomLevel > this.zoomLevels.fit);\r\n }\r\n\r\n /**\r\n * If the slide can be zoomed\r\n * @returns {boolean}\r\n */\r\n isZoomable() {\r\n return Boolean(this.width) && this.content.isZoomable();\r\n }\r\n\r\n /**\r\n * Apply transform and scale based on\r\n * the current pan position (this.pan) and zoom level (this.currZoomLevel)\r\n */\r\n applyCurrentZoomPan() {\r\n this._applyZoomTransform(this.pan.x, this.pan.y, this.currZoomLevel);\r\n if (this === this.pswp.currSlide) {\r\n this.pswp.dispatch('zoomPanUpdate', { slide: this });\r\n }\r\n }\r\n\r\n zoomAndPanToInitial() {\r\n this.currZoomLevel = this.zoomLevels.initial;\r\n\r\n // pan according to the zoom level\r\n this.bounds.update(this.currZoomLevel);\r\n equalizePoints(this.pan, this.bounds.center);\r\n this.pswp.dispatch('initialZoomPan', { slide: this });\r\n }\r\n\r\n /**\r\n * Set translate and scale based on current resolution\r\n *\r\n * @param {number} x\r\n * @param {number} y\r\n * @param {number} zoom\r\n * @private\r\n */\r\n _applyZoomTransform(x, y, zoom) {\r\n zoom /= this.currentResolution || this.zoomLevels.initial;\r\n setTransform(this.container, x, y, zoom);\r\n }\r\n\r\n calculateSize() {\r\n const { pswp } = this;\r\n\r\n equalizePoints(\r\n this.panAreaSize,\r\n getPanAreaSize(pswp.options, pswp.viewportSize, this.data, this.index)\r\n );\r\n\r\n this.zoomLevels.update(this.width, this.height, this.panAreaSize);\r\n\r\n pswp.dispatch('calcSlideSize', {\r\n slide: this\r\n });\r\n }\r\n\r\n /** @returns {string} */\r\n getCurrentTransform() {\r\n const scale = this.currZoomLevel / (this.currentResolution || this.zoomLevels.initial);\r\n return toTransformString(this.pan.x, this.pan.y, scale);\r\n }\r\n\r\n /**\r\n * Set resolution and re-render the image.\r\n *\r\n * For example, if the real image size is 2000x1500,\r\n * and resolution is 0.5 - it will be rendered as 1000x750.\r\n *\r\n * Image with zoom level 2 and resolution 0.5 is\r\n * the same as image with zoom level 1 and resolution 1.\r\n *\r\n * Used to optimize animations and make\r\n * sure that browser renders image in the highest quality.\r\n * Also used by responsive images to load the correct one.\r\n *\r\n * @param {number} newResolution\r\n */\r\n _setResolution(newResolution) {\r\n if (newResolution === this.currentResolution) {\r\n return;\r\n }\r\n\r\n this.currentResolution = newResolution;\r\n this.updateContentSize();\r\n\r\n this.pswp.dispatch('resolutionChanged');\r\n }\r\n}\r\n\r\nexport default Slide;\r\n","import {\r\n equalizePoints, roundPoint, clamp\r\n} from '../util/util.js';\r\n\r\n/** @typedef {import('../photoswipe.js').Point} Point */\r\n/** @typedef {import('./gestures.js').default} Gestures */\r\n\r\nconst PAN_END_FRICTION = 0.35;\r\nconst VERTICAL_DRAG_FRICTION = 0.6;\r\n\r\n// 1 corresponds to the third of viewport height\r\nconst MIN_RATIO_TO_CLOSE = 0.4;\r\n\r\n// Minimum speed required to navigate\r\n// to next or previous slide\r\nconst MIN_NEXT_SLIDE_SPEED = 0.5;\r\n\r\n/**\r\n * @param {number} initialVelocity\r\n * @param {number} decelerationRate\r\n * @returns {number}\r\n */\r\nfunction project(initialVelocity, decelerationRate) {\r\n return initialVelocity * decelerationRate / (1 - decelerationRate);\r\n}\r\n\r\n/**\r\n * Handles single pointer dragging\r\n */\r\nclass DragHandler {\r\n /**\r\n * @param {Gestures} gestures\r\n */\r\n constructor(gestures) {\r\n this.gestures = gestures;\r\n this.pswp = gestures.pswp;\r\n /** @type {Point} */\r\n this.startPan = { x: 0, y: 0 };\r\n }\r\n\r\n start() {\r\n if (this.pswp.currSlide) {\r\n equalizePoints(this.startPan, this.pswp.currSlide.pan);\r\n }\r\n this.pswp.animations.stopAll();\r\n }\r\n\r\n change() {\r\n const { p1, prevP1, dragAxis } = this.gestures;\r\n const { currSlide } = this.pswp;\r\n\r\n if (dragAxis === 'y'\r\n && this.pswp.options.closeOnVerticalDrag\r\n && (currSlide && currSlide.currZoomLevel <= currSlide.zoomLevels.fit)\r\n && !this.gestures.isMultitouch) {\r\n // Handle vertical drag to close\r\n const panY = currSlide.pan.y + (p1.y - prevP1.y);\r\n if (!this.pswp.dispatch('verticalDrag', { panY }).defaultPrevented) {\r\n this._setPanWithFriction('y', panY, VERTICAL_DRAG_FRICTION);\r\n const bgOpacity = 1 - Math.abs(this._getVerticalDragRatio(currSlide.pan.y));\r\n this.pswp.applyBgOpacity(bgOpacity);\r\n currSlide.applyCurrentZoomPan();\r\n }\r\n } else {\r\n const mainScrollChanged = this._panOrMoveMainScroll('x');\r\n if (!mainScrollChanged) {\r\n this._panOrMoveMainScroll('y');\r\n\r\n if (currSlide) {\r\n roundPoint(currSlide.pan);\r\n currSlide.applyCurrentZoomPan();\r\n }\r\n }\r\n }\r\n }\r\n\r\n end() {\r\n const { velocity } = this.gestures;\r\n const { mainScroll, currSlide } = this.pswp;\r\n let indexDiff = 0;\r\n\r\n this.pswp.animations.stopAll();\r\n\r\n // Handle main scroll if it's shifted\r\n if (mainScroll.isShifted()) {\r\n // Position of the main scroll relative to the viewport\r\n const mainScrollShiftDiff = mainScroll.x - mainScroll.getCurrSlideX();\r\n\r\n // Ratio between 0 and 1:\r\n // 0 - slide is not visible at all,\r\n // 0.5 - half of the slide is visible\r\n // 1 - slide is fully visible\r\n const currentSlideVisibilityRatio = (mainScrollShiftDiff / this.pswp.viewportSize.x);\r\n\r\n // Go next slide.\r\n //\r\n // - if velocity and its direction is matched,\r\n // and we see at least tiny part of the next slide\r\n //\r\n // - or if we see less than 50% of the current slide\r\n // and velocity is close to 0\r\n //\r\n if ((velocity.x < -MIN_NEXT_SLIDE_SPEED && currentSlideVisibilityRatio < 0)\r\n || (velocity.x < 0.1 && currentSlideVisibilityRatio < -0.5)) {\r\n // Go to next slide\r\n indexDiff = 1;\r\n velocity.x = Math.min(velocity.x, 0);\r\n } else if ((velocity.x > MIN_NEXT_SLIDE_SPEED && currentSlideVisibilityRatio > 0)\r\n || (velocity.x > -0.1 && currentSlideVisibilityRatio > 0.5)) {\r\n // Go to prev slide\r\n indexDiff = -1;\r\n velocity.x = Math.max(velocity.x, 0);\r\n }\r\n\r\n mainScroll.moveIndexBy(indexDiff, true, velocity.x);\r\n }\r\n\r\n // Restore zoom level\r\n if ((currSlide && currSlide.currZoomLevel > currSlide.zoomLevels.max)\r\n || this.gestures.isMultitouch) {\r\n this.gestures.zoomLevels.correctZoomPan(true);\r\n } else {\r\n // we run two animations instead of one,\r\n // as each axis has own pan boundaries and thus different spring function\r\n // (correctZoomPan does not have this functionality,\r\n // it animates all properties with single timing function)\r\n this._finishPanGestureForAxis('x');\r\n this._finishPanGestureForAxis('y');\r\n }\r\n }\r\n\r\n /**\r\n * @private\r\n * @param {'x' | 'y'} axis\r\n */\r\n _finishPanGestureForAxis(axis) {\r\n const { velocity } = this.gestures;\r\n const { currSlide } = this.pswp;\r\n\r\n if (!currSlide) {\r\n return;\r\n }\r\n\r\n const { pan, bounds } = currSlide;\r\n const panPos = pan[axis];\r\n const restoreBgOpacity = (this.pswp.bgOpacity < 1 && axis === 'y');\r\n\r\n // 0.995 means - scroll view loses 0.5% of its velocity per millisecond\r\n // Increasing this number will reduce travel distance\r\n const decelerationRate = 0.995; // 0.99\r\n\r\n // Pan position if there is no bounds\r\n const projectedPosition = panPos + project(velocity[axis], decelerationRate);\r\n\r\n if (restoreBgOpacity) {\r\n const vDragRatio = this._getVerticalDragRatio(panPos);\r\n const projectedVDragRatio = this._getVerticalDragRatio(projectedPosition);\r\n\r\n // If we are above and moving upwards,\r\n // or if we are below and moving downwards\r\n if ((vDragRatio < 0 && projectedVDragRatio < -MIN_RATIO_TO_CLOSE)\r\n || (vDragRatio > 0 && projectedVDragRatio > MIN_RATIO_TO_CLOSE)) {\r\n this.pswp.close();\r\n return;\r\n }\r\n }\r\n\r\n // Pan position with corrected bounds\r\n const correctedPanPosition = bounds.correctPan(axis, projectedPosition);\r\n\r\n // Exit if pan position should not be changed\r\n // or if speed it too low\r\n if (panPos === correctedPanPosition) {\r\n return;\r\n }\r\n\r\n // Overshoot if the final position is out of pan bounds\r\n const dampingRatio = (correctedPanPosition === projectedPosition) ? 1 : 0.82;\r\n\r\n const initialBgOpacity = this.pswp.bgOpacity;\r\n const totalPanDist = correctedPanPosition - panPos;\r\n\r\n this.pswp.animations.startSpring({\r\n name: 'panGesture' + axis,\r\n isPan: true,\r\n start: panPos,\r\n end: correctedPanPosition,\r\n velocity: velocity[axis],\r\n dampingRatio,\r\n onUpdate: (pos) => {\r\n // Animate opacity of background relative to Y pan position of an image\r\n if (restoreBgOpacity && this.pswp.bgOpacity < 1) {\r\n // 0 - start of animation, 1 - end of animation\r\n const animationProgressRatio = 1 - (correctedPanPosition - pos) / totalPanDist;\r\n\r\n // We clamp opacity to keep it between 0 and 1.\r\n // As progress ratio can be larger than 1 due to overshoot,\r\n // and we do not want to bounce opacity.\r\n this.pswp.applyBgOpacity(clamp(\r\n initialBgOpacity + (1 - initialBgOpacity) * animationProgressRatio,\r\n 0,\r\n 1\r\n ));\r\n }\r\n\r\n pan[axis] = Math.floor(pos);\r\n currSlide.applyCurrentZoomPan();\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Update position of the main scroll,\r\n * or/and update pan position of the current slide.\r\n *\r\n * Should return true if it changes (or can change) main scroll.\r\n *\r\n * @private\r\n * @param {'x' | 'y'} axis\r\n * @returns {boolean}\r\n */\r\n _panOrMoveMainScroll(axis) {\r\n const { p1, dragAxis, prevP1, isMultitouch } = this.gestures;\r\n const { currSlide, mainScroll } = this.pswp;\r\n const delta = (p1[axis] - prevP1[axis]);\r\n const newMainScrollX = mainScroll.x + delta;\r\n\r\n if (!delta || !currSlide) {\r\n return false;\r\n }\r\n\r\n // Always move main scroll if image can not be panned\r\n if (axis === 'x' && !currSlide.isPannable() && !isMultitouch) {\r\n mainScroll.moveTo(newMainScrollX, true);\r\n return true; // changed main scroll\r\n }\r\n\r\n const { bounds } = currSlide;\r\n const newPan = currSlide.pan[axis] + delta;\r\n\r\n if (this.pswp.options.allowPanToNext\r\n && dragAxis === 'x'\r\n && axis === 'x'\r\n && !isMultitouch) {\r\n const currSlideMainScrollX = mainScroll.getCurrSlideX();\r\n\r\n // Position of the main scroll relative to the viewport\r\n const mainScrollShiftDiff = mainScroll.x - currSlideMainScrollX;\r\n\r\n const isLeftToRight = delta > 0;\r\n const isRightToLeft = !isLeftToRight;\r\n\r\n if (newPan > bounds.min[axis] && isLeftToRight) {\r\n // Panning from left to right, beyond the left edge\r\n\r\n // Wether the image was at minimum pan position (or less)\r\n // when this drag gesture started.\r\n // Minimum pan position refers to the left edge of the image.\r\n const wasAtMinPanPosition = (bounds.min[axis] <= this.startPan[axis]);\r\n\r\n if (wasAtMinPanPosition) {\r\n mainScroll.moveTo(newMainScrollX, true);\r\n return true;\r\n } else {\r\n this._setPanWithFriction(axis, newPan);\r\n //currSlide.pan[axis] = newPan;\r\n }\r\n } else if (newPan < bounds.max[axis] && isRightToLeft) {\r\n // Paning from right to left, beyond the right edge\r\n\r\n // Maximum pan position refers to the right edge of the image.\r\n const wasAtMaxPanPosition = (this.startPan[axis] <= bounds.max[axis]);\r\n\r\n if (wasAtMaxPanPosition) {\r\n mainScroll.moveTo(newMainScrollX, true);\r\n return true;\r\n } else {\r\n this._setPanWithFriction(axis, newPan);\r\n //currSlide.pan[axis] = newPan;\r\n }\r\n } else {\r\n // If main scroll is shifted\r\n if (mainScrollShiftDiff !== 0) {\r\n // If main scroll is shifted right\r\n if (mainScrollShiftDiff > 0 /*&& isRightToLeft*/) {\r\n mainScroll.moveTo(Math.max(newMainScrollX, currSlideMainScrollX), true);\r\n return true;\r\n } else if (mainScrollShiftDiff < 0 /*&& isLeftToRight*/) {\r\n // Main scroll is shifted left (Position is less than 0 comparing to the viewport 0)\r\n mainScroll.moveTo(Math.min(newMainScrollX, currSlideMainScrollX), true);\r\n return true;\r\n }\r\n } else {\r\n // We are within pan bounds, so just pan\r\n this._setPanWithFriction(axis, newPan);\r\n }\r\n }\r\n } else {\r\n if (axis === 'y') {\r\n // Do not pan vertically if main scroll is shifted o\r\n if (!mainScroll.isShifted() && bounds.min.y !== bounds.max.y) {\r\n this._setPanWithFriction(axis, newPan);\r\n }\r\n } else {\r\n this._setPanWithFriction(axis, newPan);\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n // If we move above - the ratio is negative\r\n // If we move below the ratio is positive\r\n\r\n /**\r\n * Relation between pan Y position and third of viewport height.\r\n *\r\n * When we are at initial position (center bounds) - the ratio is 0,\r\n * if position is shifted upwards - the ratio is negative,\r\n * if position is shifted downwards - the ratio is positive.\r\n *\r\n * @private\r\n * @param {number} panY The current pan Y position.\r\n * @returns {number}\r\n */\r\n _getVerticalDragRatio(panY) {\r\n return (panY - (this.pswp.currSlide?.bounds.center.y ?? 0)) / (this.pswp.viewportSize.y / 3);\r\n }\r\n\r\n /**\r\n * Set pan position of the current slide.\r\n * Apply friction if the position is beyond the pan bounds,\r\n * or if custom friction is defined.\r\n *\r\n * @private\r\n * @param {'x' | 'y'} axis\r\n * @param {number} potentialPan\r\n * @param {number} [customFriction] (0.1 - 1)\r\n */\r\n _setPanWithFriction(axis, potentialPan, customFriction) {\r\n const { currSlide } = this.pswp;\r\n\r\n if (!currSlide) {\r\n return;\r\n }\r\n\r\n const { pan, bounds } = currSlide;\r\n const correctedPan = bounds.correctPan(axis, potentialPan);\r\n // If we are out of pan bounds\r\n if (correctedPan !== potentialPan || customFriction) {\r\n const delta = Math.round(potentialPan - pan[axis]);\r\n pan[axis] += delta * (customFriction || PAN_END_FRICTION);\r\n } else {\r\n pan[axis] = potentialPan;\r\n }\r\n }\r\n}\r\n\r\nexport default DragHandler;\r\n","import {\r\n equalizePoints, getDistanceBetween, clamp, pointsEqual\r\n} from '../util/util.js';\r\n\r\n/** @typedef {import('../photoswipe.js').Point} Point */\r\n/** @typedef {import('./gestures.js').default} Gestures */\r\n\r\nconst UPPER_ZOOM_FRICTION = 0.05;\r\nconst LOWER_ZOOM_FRICTION = 0.15;\r\n\r\n\r\n/**\r\n * Get center point between two points\r\n *\r\n * @param {Point} p\r\n * @param {Point} p1\r\n * @param {Point} p2\r\n * @returns {Point}\r\n */\r\nfunction getZoomPointsCenter(p, p1, p2) {\r\n p.x = (p1.x + p2.x) / 2;\r\n p.y = (p1.y + p2.y) / 2;\r\n return p;\r\n}\r\n\r\nclass ZoomHandler {\r\n /**\r\n * @param {Gestures} gestures\r\n */\r\n constructor(gestures) {\r\n this.gestures = gestures;\r\n /**\r\n * @private\r\n * @type {Point}\r\n */\r\n this._startPan = { x: 0, y: 0 };\r\n /**\r\n * @private\r\n * @type {Point}\r\n */\r\n this._startZoomPoint = { x: 0, y: 0 };\r\n /**\r\n * @private\r\n * @type {Point}\r\n */\r\n this._zoomPoint = { x: 0, y: 0 };\r\n /** @private */\r\n this._wasOverFitZoomLevel = false;\r\n /** @private */\r\n this._startZoomLevel = 1;\r\n }\r\n\r\n start() {\r\n const { currSlide } = this.gestures.pswp;\r\n if (currSlide) {\r\n this._startZoomLevel = currSlide.currZoomLevel;\r\n equalizePoints(this._startPan, currSlide.pan);\r\n }\r\n\r\n this.gestures.pswp.animations.stopAllPan();\r\n this._wasOverFitZoomLevel = false;\r\n }\r\n\r\n change() {\r\n const { p1, startP1, p2, startP2, pswp } = this.gestures;\r\n const { currSlide } = pswp;\r\n\r\n if (!currSlide) {\r\n return;\r\n }\r\n\r\n const minZoomLevel = currSlide.zoomLevels.min;\r\n const maxZoomLevel = currSlide.zoomLevels.max;\r\n\r\n if (!currSlide.isZoomable() || pswp.mainScroll.isShifted()) {\r\n return;\r\n }\r\n\r\n getZoomPointsCenter(this._startZoomPoint, startP1, startP2);\r\n getZoomPointsCenter(this._zoomPoint, p1, p2);\r\n\r\n let currZoomLevel = (1 / getDistanceBetween(startP1, startP2))\r\n * getDistanceBetween(p1, p2)\r\n * this._startZoomLevel;\r\n\r\n // slightly over the zoom.fit\r\n if (currZoomLevel > currSlide.zoomLevels.initial + (currSlide.zoomLevels.initial / 15)) {\r\n this._wasOverFitZoomLevel = true;\r\n }\r\n\r\n if (currZoomLevel < minZoomLevel) {\r\n if (pswp.options.pinchToClose\r\n && !this._wasOverFitZoomLevel\r\n && this._startZoomLevel <= currSlide.zoomLevels.initial) {\r\n // fade out background if zooming out\r\n const bgOpacity = 1 - ((minZoomLevel - currZoomLevel) / (minZoomLevel / 1.2));\r\n if (!pswp.dispatch('pinchClose', { bgOpacity }).defaultPrevented) {\r\n pswp.applyBgOpacity(bgOpacity);\r\n }\r\n } else {\r\n // Apply the friction if zoom level is below the min\r\n currZoomLevel = minZoomLevel - (minZoomLevel - currZoomLevel) * LOWER_ZOOM_FRICTION;\r\n }\r\n } else if (currZoomLevel > maxZoomLevel) {\r\n // Apply the friction if zoom level is above the max\r\n currZoomLevel = maxZoomLevel + (currZoomLevel - maxZoomLevel) * UPPER_ZOOM_FRICTION;\r\n }\r\n\r\n currSlide.pan.x = this._calculatePanForZoomLevel('x', currZoomLevel);\r\n currSlide.pan.y = this._calculatePanForZoomLevel('y', currZoomLevel);\r\n\r\n currSlide.setZoomLevel(currZoomLevel);\r\n currSlide.applyCurrentZoomPan();\r\n }\r\n\r\n end() {\r\n const { pswp } = this.gestures;\r\n const { currSlide } = pswp;\r\n if ((!currSlide || currSlide.currZoomLevel < currSlide.zoomLevels.initial)\r\n && !this._wasOverFitZoomLevel\r\n && pswp.options.pinchToClose) {\r\n pswp.close();\r\n } else {\r\n this.correctZoomPan();\r\n }\r\n }\r\n\r\n /**\r\n * @private\r\n * @param {'x' | 'y'} axis\r\n * @param {number} currZoomLevel\r\n * @returns {number}\r\n */\r\n _calculatePanForZoomLevel(axis, currZoomLevel) {\r\n const zoomFactor = currZoomLevel / this._startZoomLevel;\r\n return this._zoomPoint[axis]\r\n - ((this._startZoomPoint[axis] - this._startPan[axis]) * zoomFactor);\r\n }\r\n\r\n /**\r\n * Correct currZoomLevel and pan if they are\r\n * beyond minimum or maximum values.\r\n * With animation.\r\n *\r\n * @param {boolean} [ignoreGesture]\r\n * Wether gesture coordinates should be ignored when calculating destination pan position.\r\n */\r\n correctZoomPan(ignoreGesture) {\r\n const { pswp } = this.gestures;\r\n const { currSlide } = pswp;\r\n\r\n if (!currSlide?.isZoomable()) {\r\n return;\r\n }\r\n\r\n if (this._zoomPoint.x === 0) {\r\n ignoreGesture = true;\r\n }\r\n\r\n const prevZoomLevel = currSlide.currZoomLevel;\r\n\r\n /** @type {number} */\r\n let destinationZoomLevel;\r\n let currZoomLevelNeedsChange = true;\r\n\r\n if (prevZoomLevel < currSlide.zoomLevels.initial) {\r\n destinationZoomLevel = currSlide.zoomLevels.initial;\r\n // zoom to min\r\n } else if (prevZoomLevel > currSlide.zoomLevels.max) {\r\n destinationZoomLevel = currSlide.zoomLevels.max;\r\n // zoom to max\r\n } else {\r\n currZoomLevelNeedsChange = false;\r\n destinationZoomLevel = prevZoomLevel;\r\n }\r\n\r\n const initialBgOpacity = pswp.bgOpacity;\r\n const restoreBgOpacity = pswp.bgOpacity < 1;\r\n\r\n const initialPan = equalizePoints({ x: 0, y: 0 }, currSlide.pan);\r\n let destinationPan = equalizePoints({ x: 0, y: 0 }, initialPan);\r\n\r\n if (ignoreGesture) {\r\n this._zoomPoint.x = 0;\r\n this._zoomPoint.y = 0;\r\n this._startZoomPoint.x = 0;\r\n this._startZoomPoint.y = 0;\r\n this._startZoomLevel = prevZoomLevel;\r\n equalizePoints(this._startPan, initialPan);\r\n }\r\n\r\n if (currZoomLevelNeedsChange) {\r\n destinationPan = {\r\n x: this._calculatePanForZoomLevel('x', destinationZoomLevel),\r\n y: this._calculatePanForZoomLevel('y', destinationZoomLevel)\r\n };\r\n }\r\n\r\n // set zoom level, so pan bounds are updated according to it\r\n currSlide.setZoomLevel(destinationZoomLevel);\r\n\r\n destinationPan = {\r\n x: currSlide.bounds.correctPan('x', destinationPan.x),\r\n y: currSlide.bounds.correctPan('y', destinationPan.y)\r\n };\r\n\r\n // return zoom level and its bounds to initial\r\n currSlide.setZoomLevel(prevZoomLevel);\r\n\r\n const panNeedsChange = !pointsEqual(destinationPan, initialPan);\r\n\r\n if (!panNeedsChange && !currZoomLevelNeedsChange && !restoreBgOpacity) {\r\n // update resolution after gesture\r\n currSlide._setResolution(destinationZoomLevel);\r\n currSlide.applyCurrentZoomPan();\r\n\r\n // nothing to animate\r\n return;\r\n }\r\n\r\n pswp.animations.stopAllPan();\r\n\r\n pswp.animations.startSpring({\r\n isPan: true,\r\n start: 0,\r\n end: 1000,\r\n velocity: 0,\r\n dampingRatio: 1,\r\n naturalFrequency: 40,\r\n onUpdate: (now) => {\r\n now /= 1000; // 0 - start, 1 - end\r\n\r\n if (panNeedsChange || currZoomLevelNeedsChange) {\r\n if (panNeedsChange) {\r\n currSlide.pan.x = initialPan.x + (destinationPan.x - initialPan.x) * now;\r\n currSlide.pan.y = initialPan.y + (destinationPan.y - initialPan.y) * now;\r\n }\r\n\r\n if (currZoomLevelNeedsChange) {\r\n const newZoomLevel = prevZoomLevel\r\n + (destinationZoomLevel - prevZoomLevel) * now;\r\n currSlide.setZoomLevel(newZoomLevel);\r\n }\r\n\r\n currSlide.applyCurrentZoomPan();\r\n }\r\n\r\n // Restore background opacity\r\n if (restoreBgOpacity && pswp.bgOpacity < 1) {\r\n // We clamp opacity to keep it between 0 and 1.\r\n // As progress ratio can be larger than 1 due to overshoot,\r\n // and we do not want to bounce opacity.\r\n pswp.applyBgOpacity(clamp(\r\n initialBgOpacity + (1 - initialBgOpacity) * now, 0, 1\r\n ));\r\n }\r\n },\r\n onComplete: () => {\r\n // update resolution after transition ends\r\n currSlide._setResolution(destinationZoomLevel);\r\n currSlide.applyCurrentZoomPan();\r\n }\r\n });\r\n }\r\n}\r\n\r\nexport default ZoomHandler;\r\n","/**\r\n * @template {string} T\r\n * @template {string} P\r\n * @typedef {import('../types.js').AddPostfix} AddPostfix\r\n */\r\n\r\n/** @typedef {import('./gestures.js').default} Gestures */\r\n/** @typedef {import('../photoswipe.js').Point} Point */\r\n\r\n/** @typedef {'imageClick' | 'bgClick' | 'tap' | 'doubleTap'} Actions */\r\n\r\n/**\r\n * Whether the tap was performed on the main slide\r\n * (rather than controls or caption).\r\n *\r\n * @param {PointerEvent} event\r\n * @returns {boolean}\r\n */\r\nfunction didTapOnMainContent(event) {\r\n return !!(/** @type {HTMLElement} */ (event.target).closest('.pswp__container'));\r\n}\r\n\r\n/**\r\n * Tap, double-tap handler.\r\n */\r\nclass TapHandler {\r\n /**\r\n * @param {Gestures} gestures\r\n */\r\n constructor(gestures) {\r\n this.gestures = gestures;\r\n }\r\n\r\n /**\r\n * @param {Point} point\r\n * @param {PointerEvent} originalEvent\r\n */\r\n click(point, originalEvent) {\r\n const targetClassList = /** @type {HTMLElement} */ (originalEvent.target).classList;\r\n const isImageClick = targetClassList.contains('pswp__img');\r\n const isBackgroundClick = targetClassList.contains('pswp__item')\r\n || targetClassList.contains('pswp__zoom-wrap');\r\n\r\n if (isImageClick) {\r\n this._doClickOrTapAction('imageClick', point, originalEvent);\r\n } else if (isBackgroundClick) {\r\n this._doClickOrTapAction('bgClick', point, originalEvent);\r\n }\r\n }\r\n\r\n /**\r\n * @param {Point} point\r\n * @param {PointerEvent} originalEvent\r\n */\r\n tap(point, originalEvent) {\r\n if (didTapOnMainContent(originalEvent)) {\r\n this._doClickOrTapAction('tap', point, originalEvent);\r\n }\r\n }\r\n\r\n /**\r\n * @param {Point} point\r\n * @param {PointerEvent} originalEvent\r\n */\r\n doubleTap(point, originalEvent) {\r\n if (didTapOnMainContent(originalEvent)) {\r\n this._doClickOrTapAction('doubleTap', point, originalEvent);\r\n }\r\n }\r\n\r\n /**\r\n * @private\r\n * @param {Actions} actionName\r\n * @param {Point} point\r\n * @param {PointerEvent} originalEvent\r\n */\r\n _doClickOrTapAction(actionName, point, originalEvent) {\r\n const { pswp } = this.gestures;\r\n const { currSlide } = pswp;\r\n const actionFullName = /** @type {AddPostfix} */ (actionName + 'Action');\r\n const optionValue = pswp.options[actionFullName];\r\n\r\n if (pswp.dispatch(actionFullName, { point, originalEvent }).defaultPrevented) {\r\n return;\r\n }\r\n\r\n if (typeof optionValue === 'function') {\r\n optionValue.call(pswp, point, originalEvent);\r\n return;\r\n }\r\n\r\n switch (optionValue) {\r\n case 'close':\r\n case 'next':\r\n pswp[optionValue]();\r\n break;\r\n case 'zoom':\r\n currSlide?.toggleZoom(point);\r\n break;\r\n case 'zoom-or-close':\r\n // by default click zooms current image,\r\n // if it can not be zoomed - gallery will be closed\r\n if (currSlide?.isZoomable()\r\n && currSlide.zoomLevels.secondary !== currSlide.zoomLevels.initial) {\r\n currSlide.toggleZoom(point);\r\n } else if (pswp.options.clickToCloseNonZoomable) {\r\n pswp.close();\r\n }\r\n break;\r\n case 'toggle-controls':\r\n this.gestures.pswp.element?.classList.toggle('pswp--ui-visible');\r\n // if (_controlsVisible) {\r\n // _ui.hideControls();\r\n // } else {\r\n // _ui.showControls();\r\n // }\r\n break;\r\n }\r\n }\r\n}\r\n\r\nexport default TapHandler;\r\n","import {\r\n equalizePoints, pointsEqual, getDistanceBetween\r\n} from '../util/util.js';\r\n\r\nimport DragHandler from './drag-handler.js';\r\nimport ZoomHandler from './zoom-handler.js';\r\nimport TapHandler from './tap-handler.js';\r\n\r\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\r\n/** @typedef {import('../photoswipe.js').Point} Point */\r\n\r\n// How far should user should drag\r\n// until we can determine that the gesture is swipe and its direction\r\nconst AXIS_SWIPE_HYSTERISIS = 10;\r\n//const PAN_END_FRICTION = 0.35;\r\n\r\nconst DOUBLE_TAP_DELAY = 300; // ms\r\nconst MIN_TAP_DISTANCE = 25; // px\r\n\r\n/**\r\n * Gestures class bind touch, pointer or mouse events\r\n * and emits drag to drag-handler and zoom events zoom-handler.\r\n *\r\n * Drag and zoom events are emited in requestAnimationFrame,\r\n * and only when one of pointers was actually changed.\r\n */\r\nclass Gestures {\r\n /**\r\n * @param {PhotoSwipe} pswp\r\n */\r\n constructor(pswp) {\r\n this.pswp = pswp;\r\n\r\n /** @type {'x' | 'y' | null} */\r\n this.dragAxis = null;\r\n\r\n // point objects are defined once and reused\r\n // PhotoSwipe keeps track only of two pointers, others are ignored\r\n /** @type {Point} */\r\n this.p1 = { x: 0, y: 0 }; // the first pressed pointer\r\n /** @type {Point} */\r\n this.p2 = { x: 0, y: 0 }; // the second pressed pointer\r\n /** @type {Point} */\r\n this.prevP1 = { x: 0, y: 0 };\r\n /** @type {Point} */\r\n this.prevP2 = { x: 0, y: 0 };\r\n /** @type {Point} */\r\n this.startP1 = { x: 0, y: 0 };\r\n /** @type {Point} */\r\n this.startP2 = { x: 0, y: 0 };\r\n /** @type {Point} */\r\n this.velocity = { x: 0, y: 0 };\r\n\r\n /** @type {Point}\r\n * @private\r\n */\r\n this._lastStartP1 = { x: 0, y: 0 };\r\n /** @type {Point}\r\n * @private\r\n */\r\n this._intervalP1 = { x: 0, y: 0 };\r\n /** @private */\r\n this._numActivePoints = 0;\r\n /** @type {Point[]}\r\n * @private\r\n */\r\n this._ongoingPointers = [];\r\n /** @private */\r\n this._touchEventEnabled = 'ontouchstart' in window;\r\n /** @private */\r\n this._pointerEventEnabled = !!(window.PointerEvent);\r\n this.supportsTouch = this._touchEventEnabled\r\n || (this._pointerEventEnabled && navigator.maxTouchPoints > 1);\r\n /** @private */\r\n this._numActivePoints = 0;\r\n /** @private */\r\n this._intervalTime = 0;\r\n /** @private */\r\n this._velocityCalculated = false;\r\n this.isMultitouch = false;\r\n this.isDragging = false;\r\n this.isZooming = false;\r\n /** @type {number | null} */\r\n this.raf = null;\r\n /** @type {NodeJS.Timeout | null}\r\n * @private\r\n */\r\n this._tapTimer = null;\r\n\r\n if (!this.supportsTouch) {\r\n // disable pan to next slide for non-touch devices\r\n pswp.options.allowPanToNext = false;\r\n }\r\n\r\n this.drag = new DragHandler(this);\r\n this.zoomLevels = new ZoomHandler(this);\r\n this.tapHandler = new TapHandler(this);\r\n\r\n pswp.on('bindEvents', () => {\r\n pswp.events.add(\r\n pswp.scrollWrap,\r\n 'click',\r\n /** @type EventListener */(this._onClick.bind(this))\r\n );\r\n\r\n if (this._pointerEventEnabled) {\r\n this._bindEvents('pointer', 'down', 'up', 'cancel');\r\n } else if (this._touchEventEnabled) {\r\n this._bindEvents('touch', 'start', 'end', 'cancel');\r\n\r\n // In previous versions we also bound mouse event here,\r\n // in case device supports both touch and mouse events,\r\n // but newer versions of browsers now support PointerEvent.\r\n\r\n // on iOS10 if you bind touchmove/end after touchstart,\r\n // and you don't preventDefault touchstart (which PhotoSwipe does),\r\n // preventDefault will have no effect on touchmove and touchend.\r\n // Unless you bind it previously.\r\n if (pswp.scrollWrap) {\r\n pswp.scrollWrap.ontouchmove = () => {};\r\n pswp.scrollWrap.ontouchend = () => {};\r\n }\r\n } else {\r\n this._bindEvents('mouse', 'down', 'up');\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * @private\r\n * @param {'mouse' | 'touch' | 'pointer'} pref\r\n * @param {'down' | 'start'} down\r\n * @param {'up' | 'end'} up\r\n * @param {'cancel'} [cancel]\r\n */\r\n _bindEvents(pref, down, up, cancel) {\r\n const { pswp } = this;\r\n const { events } = pswp;\r\n\r\n const cancelEvent = cancel ? pref + cancel : '';\r\n\r\n events.add(\r\n pswp.scrollWrap,\r\n pref + down,\r\n /** @type EventListener */(this.onPointerDown.bind(this))\r\n );\r\n events.add(window, pref + 'move', /** @type EventListener */(this.onPointerMove.bind(this)));\r\n events.add(window, pref + up, /** @type EventListener */(this.onPointerUp.bind(this)));\r\n if (cancelEvent) {\r\n events.add(\r\n pswp.scrollWrap,\r\n cancelEvent,\r\n /** @type EventListener */(this.onPointerUp.bind(this))\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * @param {PointerEvent} e\r\n */\r\n onPointerDown(e) {\r\n // We do not call preventDefault for touch events\r\n // to allow browser to show native dialog on longpress\r\n // (the one that allows to save image or open it in new tab).\r\n //\r\n // Desktop Safari allows to drag images when preventDefault isn't called on mousedown,\r\n // even though preventDefault IS called on mousemove. That's why we preventDefault mousedown.\r\n const isMousePointer = e.type === 'mousedown' || e.pointerType === 'mouse';\r\n\r\n // Allow dragging only via left mouse button.\r\n // http://www.quirksmode.org/js/events_properties.html\r\n // https://developer.mozilla.org/en-US/docs/Web/API/event.button\r\n if (isMousePointer && e.button > 0) {\r\n return;\r\n }\r\n\r\n const { pswp } = this;\r\n\r\n // if PhotoSwipe is opening or closing\r\n if (!pswp.opener.isOpen) {\r\n e.preventDefault();\r\n return;\r\n }\r\n\r\n if (pswp.dispatch('pointerDown', { originalEvent: e }).defaultPrevented) {\r\n return;\r\n }\r\n\r\n if (isMousePointer) {\r\n pswp.mouseDetected();\r\n\r\n // preventDefault mouse event to prevent\r\n // browser image drag feature\r\n this._preventPointerEventBehaviour(e, 'down');\r\n }\r\n\r\n pswp.animations.stopAll();\r\n\r\n this._updatePoints(e, 'down');\r\n\r\n if (this._numActivePoints === 1) {\r\n this.dragAxis = null;\r\n // we need to store initial point to determine the main axis,\r\n // drag is activated only after the axis is determined\r\n equalizePoints(this.startP1, this.p1);\r\n }\r\n\r\n if (this._numActivePoints > 1) {\r\n // Tap or double tap should not trigger if more than one pointer\r\n this._clearTapTimer();\r\n this.isMultitouch = true;\r\n } else {\r\n this.isMultitouch = false;\r\n }\r\n }\r\n\r\n /**\r\n * @param {PointerEvent} e\r\n */\r\n onPointerMove(e) {\r\n this._preventPointerEventBehaviour(e, 'move');\r\n\r\n if (!this._numActivePoints) {\r\n return;\r\n }\r\n\r\n this._updatePoints(e, 'move');\r\n\r\n if (this.pswp.dispatch('pointerMove', { originalEvent: e }).defaultPrevented) {\r\n return;\r\n }\r\n\r\n if (this._numActivePoints === 1 && !this.isDragging) {\r\n if (!this.dragAxis) {\r\n this._calculateDragDirection();\r\n }\r\n\r\n // Drag axis was detected, emit drag.start\r\n if (this.dragAxis && !this.isDragging) {\r\n if (this.isZooming) {\r\n this.isZooming = false;\r\n this.zoomLevels.end();\r\n }\r\n\r\n this.isDragging = true;\r\n this._clearTapTimer(); // Tap can not trigger after drag\r\n\r\n // Adjust starting point\r\n this._updateStartPoints();\r\n this._intervalTime = Date.now();\r\n //this._startTime = this._intervalTime;\r\n this._velocityCalculated = false;\r\n equalizePoints(this._intervalP1, this.p1);\r\n this.velocity.x = 0;\r\n this.velocity.y = 0;\r\n this.drag.start();\r\n\r\n this._rafStopLoop();\r\n this._rafRenderLoop();\r\n }\r\n } else if (this._numActivePoints > 1 && !this.isZooming) {\r\n this._finishDrag();\r\n\r\n this.isZooming = true;\r\n\r\n // Adjust starting points\r\n this._updateStartPoints();\r\n\r\n this.zoomLevels.start();\r\n\r\n this._rafStopLoop();\r\n this._rafRenderLoop();\r\n }\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n _finishDrag() {\r\n if (this.isDragging) {\r\n this.isDragging = false;\r\n\r\n // Try to calculate velocity,\r\n // if it wasn't calculated yet in drag.change\r\n if (!this._velocityCalculated) {\r\n this._updateVelocity(true);\r\n }\r\n\r\n this.drag.end();\r\n this.dragAxis = null;\r\n }\r\n }\r\n\r\n /**\r\n * @param {PointerEvent} e\r\n */\r\n onPointerUp(e) {\r\n if (!this._numActivePoints) {\r\n return;\r\n }\r\n\r\n this._updatePoints(e, 'up');\r\n\r\n if (this.pswp.dispatch('pointerUp', { originalEvent: e }).defaultPrevented) {\r\n return;\r\n }\r\n\r\n if (this._numActivePoints === 0) {\r\n this._rafStopLoop();\r\n\r\n if (this.isDragging) {\r\n this._finishDrag();\r\n } else if (!this.isZooming && !this.isMultitouch) {\r\n //this.zoomLevels.correctZoomPan();\r\n this._finishTap(e);\r\n }\r\n }\r\n\r\n if (this._numActivePoints < 2 && this.isZooming) {\r\n this.isZooming = false;\r\n this.zoomLevels.end();\r\n\r\n if (this._numActivePoints === 1) {\r\n // Since we have 1 point left, we need to reinitiate drag\r\n this.dragAxis = null;\r\n this._updateStartPoints();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n _rafRenderLoop() {\r\n if (this.isDragging || this.isZooming) {\r\n this._updateVelocity();\r\n\r\n if (this.isDragging) {\r\n // make sure that pointer moved since the last update\r\n if (!pointsEqual(this.p1, this.prevP1)) {\r\n this.drag.change();\r\n }\r\n } else /* if (this.isZooming) */ {\r\n if (!pointsEqual(this.p1, this.prevP1)\r\n || !pointsEqual(this.p2, this.prevP2)) {\r\n this.zoomLevels.change();\r\n }\r\n }\r\n\r\n this._updatePrevPoints();\r\n this.raf = requestAnimationFrame(this._rafRenderLoop.bind(this));\r\n }\r\n }\r\n\r\n /**\r\n * Update velocity at 50ms interval\r\n *\r\n * @private\r\n * @param {boolean} [force]\r\n */\r\n _updateVelocity(force) {\r\n const time = Date.now();\r\n const duration = time - this._intervalTime;\r\n\r\n if (duration < 50 && !force) {\r\n return;\r\n }\r\n\r\n\r\n this.velocity.x = this._getVelocity('x', duration);\r\n this.velocity.y = this._getVelocity('y', duration);\r\n\r\n this._intervalTime = time;\r\n equalizePoints(this._intervalP1, this.p1);\r\n this._velocityCalculated = true;\r\n }\r\n\r\n /**\r\n * @private\r\n * @param {PointerEvent} e\r\n */\r\n _finishTap(e) {\r\n const { mainScroll } = this.pswp;\r\n\r\n // Do not trigger tap events if main scroll is shifted\r\n if (mainScroll.isShifted()) {\r\n // restore main scroll position\r\n // (usually happens if stopped in the middle of animation)\r\n mainScroll.moveIndexBy(0, true);\r\n return;\r\n }\r\n\r\n // Do not trigger tap for touchcancel or pointercancel\r\n if (e.type.indexOf('cancel') > 0) {\r\n return;\r\n }\r\n\r\n // Trigger click instead of tap for mouse events\r\n if (e.type === 'mouseup' || e.pointerType === 'mouse') {\r\n this.tapHandler.click(this.startP1, e);\r\n return;\r\n }\r\n\r\n // Disable delay if there is no doubleTapAction\r\n const tapDelay = this.pswp.options.doubleTapAction ? DOUBLE_TAP_DELAY : 0;\r\n\r\n // If tapTimer is defined - we tapped recently,\r\n // check if the current tap is close to the previous one,\r\n // if yes - trigger double tap\r\n if (this._tapTimer) {\r\n this._clearTapTimer();\r\n // Check if two taps were more or less on the same place\r\n if (getDistanceBetween(this._lastStartP1, this.startP1) < MIN_TAP_DISTANCE) {\r\n this.tapHandler.doubleTap(this.startP1, e);\r\n }\r\n } else {\r\n equalizePoints(this._lastStartP1, this.startP1);\r\n this._tapTimer = setTimeout(() => {\r\n this.tapHandler.tap(this.startP1, e);\r\n this._clearTapTimer();\r\n }, tapDelay);\r\n }\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n _clearTapTimer() {\r\n if (this._tapTimer) {\r\n clearTimeout(this._tapTimer);\r\n this._tapTimer = null;\r\n }\r\n }\r\n\r\n /**\r\n * Get velocity for axis\r\n *\r\n * @private\r\n * @param {'x' | 'y'} axis\r\n * @param {number} duration\r\n * @returns {number}\r\n */\r\n _getVelocity(axis, duration) {\r\n // displacement is like distance, but can be negative.\r\n const displacement = this.p1[axis] - this._intervalP1[axis];\r\n\r\n if (Math.abs(displacement) > 1 && duration > 5) {\r\n return displacement / duration;\r\n }\r\n\r\n return 0;\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n _rafStopLoop() {\r\n if (this.raf) {\r\n cancelAnimationFrame(this.raf);\r\n this.raf = null;\r\n }\r\n }\r\n\r\n /**\r\n * @private\r\n * @param {PointerEvent} e\r\n * @param {'up' | 'down' | 'move'} pointerType Normalized pointer type\r\n */\r\n _preventPointerEventBehaviour(e, pointerType) {\r\n const preventPointerEvent = this.pswp.applyFilters('preventPointerEvent', true, e, pointerType);\r\n if (preventPointerEvent) {\r\n e.preventDefault();\r\n }\r\n }\r\n\r\n /**\r\n * Parses and normalizes points from the touch, mouse or pointer event.\r\n * Updates p1 and p2.\r\n *\r\n * @private\r\n * @param {PointerEvent | TouchEvent} e\r\n * @param {'up' | 'down' | 'move'} pointerType Normalized pointer type\r\n */\r\n _updatePoints(e, pointerType) {\r\n if (this._pointerEventEnabled) {\r\n const pointerEvent = /** @type {PointerEvent} */ (e);\r\n // Try to find the current pointer in ongoing pointers by its ID\r\n const pointerIndex = this._ongoingPointers.findIndex((ongoingPointer) => {\r\n return ongoingPointer.id === pointerEvent.pointerId;\r\n });\r\n\r\n if (pointerType === 'up' && pointerIndex > -1) {\r\n // release the pointer - remove it from ongoing\r\n this._ongoingPointers.splice(pointerIndex, 1);\r\n } else if (pointerType === 'down' && pointerIndex === -1) {\r\n // add new pointer\r\n this._ongoingPointers.push(this._convertEventPosToPoint(pointerEvent, { x: 0, y: 0 }));\r\n } else if (pointerIndex > -1) {\r\n // update existing pointer\r\n this._convertEventPosToPoint(pointerEvent, this._ongoingPointers[pointerIndex]);\r\n }\r\n\r\n this._numActivePoints = this._ongoingPointers.length;\r\n\r\n // update points that PhotoSwipe uses\r\n // to calculate position and scale\r\n if (this._numActivePoints > 0) {\r\n equalizePoints(this.p1, this._ongoingPointers[0]);\r\n }\r\n\r\n if (this._numActivePoints > 1) {\r\n equalizePoints(this.p2, this._ongoingPointers[1]);\r\n }\r\n } else {\r\n const touchEvent = /** @type {TouchEvent} */ (e);\r\n\r\n this._numActivePoints = 0;\r\n if (touchEvent.type.indexOf('touch') > -1) {\r\n // Touch Event\r\n // https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent\r\n if (touchEvent.touches && touchEvent.touches.length > 0) {\r\n this._convertEventPosToPoint(touchEvent.touches[0], this.p1);\r\n this._numActivePoints++;\r\n if (touchEvent.touches.length > 1) {\r\n this._convertEventPosToPoint(touchEvent.touches[1], this.p2);\r\n this._numActivePoints++;\r\n }\r\n }\r\n } else {\r\n // Mouse Event\r\n this._convertEventPosToPoint(/** @type {PointerEvent} */ (e), this.p1);\r\n if (pointerType === 'up') {\r\n // clear all points on mouseup\r\n this._numActivePoints = 0;\r\n } else {\r\n this._numActivePoints++;\r\n }\r\n }\r\n }\r\n }\r\n\r\n /** update points that were used during previous rAF tick\r\n * @private\r\n */\r\n _updatePrevPoints() {\r\n equalizePoints(this.prevP1, this.p1);\r\n equalizePoints(this.prevP2, this.p2);\r\n }\r\n\r\n /** update points at the start of gesture\r\n * @private\r\n */\r\n _updateStartPoints() {\r\n equalizePoints(this.startP1, this.p1);\r\n equalizePoints(this.startP2, this.p2);\r\n this._updatePrevPoints();\r\n }\r\n\r\n /** @private */\r\n _calculateDragDirection() {\r\n if (this.pswp.mainScroll.isShifted()) {\r\n // if main scroll position is shifted – direction is always horizontal\r\n this.dragAxis = 'x';\r\n } else {\r\n // calculate delta of the last touchmove tick\r\n const diff = Math.abs(this.p1.x - this.startP1.x) - Math.abs(this.p1.y - this.startP1.y);\r\n\r\n if (diff !== 0) {\r\n // check if pointer was shifted horizontally or vertically\r\n const axisToCheck = diff > 0 ? 'x' : 'y';\r\n\r\n if (Math.abs(this.p1[axisToCheck] - this.startP1[axisToCheck]) >= AXIS_SWIPE_HYSTERISIS) {\r\n this.dragAxis = axisToCheck;\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Converts touch, pointer or mouse event\r\n * to PhotoSwipe point.\r\n *\r\n * @private\r\n * @param {Touch | PointerEvent} e\r\n * @param {Point} p\r\n * @returns {Point}\r\n */\r\n _convertEventPosToPoint(e, p) {\r\n p.x = e.pageX - this.pswp.offset.x;\r\n p.y = e.pageY - this.pswp.offset.y;\r\n\r\n if ('pointerId' in e) {\r\n p.id = e.pointerId;\r\n } else if (e.identifier !== undefined) {\r\n p.id = e.identifier;\r\n }\r\n\r\n return p;\r\n }\r\n\r\n /**\r\n * @private\r\n * @param {PointerEvent} e\r\n */\r\n _onClick(e) {\r\n // Do not allow click event to pass through after drag\r\n if (this.pswp.mainScroll.isShifted()) {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n }\r\n }\r\n}\r\n\r\nexport default Gestures;\r\n","import {\r\n setTransform,\r\n createElement,\r\n} from './util/util.js';\r\n\r\n/** @typedef {import('./photoswipe.js').default} PhotoSwipe */\r\n/** @typedef {import('./slide/slide.js').default} Slide */\r\n\r\n/** @typedef {{ el: HTMLDivElement; slide?: Slide }} ItemHolder */\r\n\r\nconst MAIN_SCROLL_END_FRICTION = 0.35;\r\n\r\n\r\n// const MIN_SWIPE_TRANSITION_DURATION = 250;\r\n// const MAX_SWIPE_TRABSITION_DURATION = 500;\r\n// const DEFAULT_SWIPE_TRANSITION_DURATION = 333;\r\n\r\n/**\r\n * Handles movement of the main scrolling container\r\n * (for example, it repositions when user swipes left or right).\r\n *\r\n * Also stores its state.\r\n */\r\nclass MainScroll {\r\n /**\r\n * @param {PhotoSwipe} pswp\r\n */\r\n constructor(pswp) {\r\n this.pswp = pswp;\r\n this.x = 0;\r\n this.slideWidth = 0;\r\n /** @private */\r\n this._currPositionIndex = 0;\r\n /** @private */\r\n this._prevPositionIndex = 0;\r\n /** @private */\r\n this._containerShiftIndex = -1;\r\n\r\n /** @type {ItemHolder[]} */\r\n this.itemHolders = [];\r\n }\r\n\r\n /**\r\n * Position the scroller and slide containers\r\n * according to viewport size.\r\n *\r\n * @param {boolean} [resizeSlides] Whether slides content should resized\r\n */\r\n resize(resizeSlides) {\r\n const { pswp } = this;\r\n const newSlideWidth = Math.round(\r\n pswp.viewportSize.x + pswp.viewportSize.x * pswp.options.spacing\r\n );\r\n // Mobile browsers might trigger a resize event during a gesture.\r\n // (due to toolbar appearing or hiding).\r\n // Avoid re-adjusting main scroll position if width wasn't changed\r\n const slideWidthChanged = (newSlideWidth !== this.slideWidth);\r\n\r\n if (slideWidthChanged) {\r\n this.slideWidth = newSlideWidth;\r\n this.moveTo(this.getCurrSlideX());\r\n }\r\n\r\n this.itemHolders.forEach((itemHolder, index) => {\r\n if (slideWidthChanged) {\r\n setTransform(itemHolder.el, (index + this._containerShiftIndex)\r\n * this.slideWidth);\r\n }\r\n\r\n if (resizeSlides && itemHolder.slide) {\r\n itemHolder.slide.resize();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Reset X position of the main scroller to zero\r\n */\r\n resetPosition() {\r\n // Position on the main scroller (offset)\r\n // it is independent from slide index\r\n this._currPositionIndex = 0;\r\n this._prevPositionIndex = 0;\r\n\r\n // This will force recalculation of size on next resize()\r\n this.slideWidth = 0;\r\n\r\n // _containerShiftIndex*viewportSize will give you amount of transform of the current slide\r\n this._containerShiftIndex = -1;\r\n }\r\n\r\n /**\r\n * Create and append array of three items\r\n * that hold data about slides in DOM\r\n */\r\n appendHolders() {\r\n this.itemHolders = [];\r\n\r\n // append our three slide holders -\r\n // previous, current, and next\r\n for (let i = 0; i < 3; i++) {\r\n const el = createElement('pswp__item', 'div', this.pswp.container);\r\n el.setAttribute('role', 'group');\r\n el.setAttribute('aria-roledescription', 'slide');\r\n el.setAttribute('aria-hidden', 'true');\r\n\r\n // hide nearby item holders until initial zoom animation finishes (to avoid extra Paints)\r\n el.style.display = (i === 1) ? 'block' : 'none';\r\n\r\n this.itemHolders.push({\r\n el,\r\n //index: -1\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Whether the main scroll can be horizontally swiped to the next or previous slide.\r\n * @returns {boolean}\r\n */\r\n canBeSwiped() {\r\n return this.pswp.getNumItems() > 1;\r\n }\r\n\r\n /**\r\n * Move main scroll by X amount of slides.\r\n * For example:\r\n * `-1` will move to the previous slide,\r\n * `0` will reset the scroll position of the current slide,\r\n * `3` will move three slides forward\r\n *\r\n * If loop option is enabled - index will be automatically looped too,\r\n * (for example `-1` will move to the last slide of the gallery).\r\n *\r\n * @param {number} diff\r\n * @param {boolean} [animate]\r\n * @param {number} [velocityX]\r\n * @returns {boolean} whether index was changed or not\r\n */\r\n moveIndexBy(diff, animate, velocityX) {\r\n const { pswp } = this;\r\n let newIndex = pswp.potentialIndex + diff;\r\n const numSlides = pswp.getNumItems();\r\n\r\n if (pswp.canLoop()) {\r\n newIndex = pswp.getLoopedIndex(newIndex);\r\n const distance = (diff + numSlides) % numSlides;\r\n if (distance <= numSlides / 2) {\r\n // go forward\r\n diff = distance;\r\n } else {\r\n // go backwards\r\n diff = distance - numSlides;\r\n }\r\n } else {\r\n if (newIndex < 0) {\r\n newIndex = 0;\r\n } else if (newIndex >= numSlides) {\r\n newIndex = numSlides - 1;\r\n }\r\n diff = newIndex - pswp.potentialIndex;\r\n }\r\n\r\n pswp.potentialIndex = newIndex;\r\n this._currPositionIndex -= diff;\r\n\r\n pswp.animations.stopMainScroll();\r\n\r\n const destinationX = this.getCurrSlideX();\r\n if (!animate) {\r\n this.moveTo(destinationX);\r\n this.updateCurrItem();\r\n } else {\r\n pswp.animations.startSpring({\r\n isMainScroll: true,\r\n start: this.x,\r\n end: destinationX,\r\n velocity: velocityX || 0,\r\n naturalFrequency: 30,\r\n dampingRatio: 1, //0.7,\r\n onUpdate: (x) => {\r\n this.moveTo(x);\r\n },\r\n onComplete: () => {\r\n this.updateCurrItem();\r\n pswp.appendHeavy();\r\n }\r\n });\r\n\r\n let currDiff = pswp.potentialIndex - pswp.currIndex;\r\n if (pswp.canLoop()) {\r\n const currDistance = (currDiff + numSlides) % numSlides;\r\n if (currDistance <= numSlides / 2) {\r\n // go forward\r\n currDiff = currDistance;\r\n } else {\r\n // go backwards\r\n currDiff = currDistance - numSlides;\r\n }\r\n }\r\n\r\n // Force-append new slides during transition\r\n // if difference between slides is more than 1\r\n if (Math.abs(currDiff) > 1) {\r\n this.updateCurrItem();\r\n }\r\n }\r\n\r\n return Boolean(diff);\r\n }\r\n\r\n /**\r\n * X position of the main scroll for the current slide\r\n * (ignores position during dragging)\r\n * @returns {number}\r\n */\r\n getCurrSlideX() {\r\n return this.slideWidth * this._currPositionIndex;\r\n }\r\n\r\n /**\r\n * Whether scroll position is shifted.\r\n * For example, it will return true if the scroll is being dragged or animated.\r\n * @returns {boolean}\r\n */\r\n isShifted() {\r\n return this.x !== this.getCurrSlideX();\r\n }\r\n\r\n /**\r\n * Update slides X positions and set their content\r\n */\r\n updateCurrItem() {\r\n const { pswp } = this;\r\n const positionDifference = this._prevPositionIndex - this._currPositionIndex;\r\n\r\n if (!positionDifference) {\r\n return;\r\n }\r\n\r\n this._prevPositionIndex = this._currPositionIndex;\r\n\r\n pswp.currIndex = pswp.potentialIndex;\r\n\r\n let diffAbs = Math.abs(positionDifference);\r\n /** @type {ItemHolder | undefined} */\r\n let tempHolder;\r\n\r\n if (diffAbs >= 3) {\r\n this._containerShiftIndex += positionDifference + (positionDifference > 0 ? -3 : 3);\r\n diffAbs = 3;\r\n }\r\n\r\n for (let i = 0; i < diffAbs; i++) {\r\n if (positionDifference > 0) {\r\n tempHolder = this.itemHolders.shift();\r\n if (tempHolder) {\r\n this.itemHolders[2] = tempHolder; // move first to last\r\n\r\n this._containerShiftIndex++;\r\n\r\n setTransform(tempHolder.el, (this._containerShiftIndex + 2) * this.slideWidth);\r\n\r\n pswp.setContent(tempHolder, (pswp.currIndex - diffAbs) + i + 2);\r\n }\r\n } else {\r\n tempHolder = this.itemHolders.pop();\r\n if (tempHolder) {\r\n this.itemHolders.unshift(tempHolder); // move last to first\r\n\r\n this._containerShiftIndex--;\r\n\r\n setTransform(tempHolder.el, this._containerShiftIndex * this.slideWidth);\r\n\r\n pswp.setContent(tempHolder, (pswp.currIndex + diffAbs) - i - 2);\r\n }\r\n }\r\n }\r\n\r\n // Reset transfrom every 50ish navigations in one direction.\r\n //\r\n // Otherwise transform will keep growing indefinitely,\r\n // which might cause issues as browsers have a maximum transform limit.\r\n // I wasn't able to reach it, but just to be safe.\r\n // This should not cause noticable lag.\r\n if (Math.abs(this._containerShiftIndex) > 50 && !this.isShifted()) {\r\n this.resetPosition();\r\n this.resize();\r\n }\r\n\r\n // Pan transition might be running (and consntantly updating pan position)\r\n pswp.animations.stopAllPan();\r\n\r\n this.itemHolders.forEach((itemHolder, i) => {\r\n if (itemHolder.slide) {\r\n // Slide in the 2nd holder is always active\r\n itemHolder.slide.setIsActive(i === 1);\r\n }\r\n });\r\n\r\n pswp.currSlide = this.itemHolders[1]?.slide;\r\n pswp.contentLoader.updateLazy(positionDifference);\r\n\r\n if (pswp.currSlide) {\r\n pswp.currSlide.applyCurrentZoomPan();\r\n }\r\n\r\n pswp.dispatch('change');\r\n }\r\n\r\n /**\r\n * Move the X position of the main scroll container\r\n *\r\n * @param {number} x\r\n * @param {boolean} [dragging]\r\n */\r\n moveTo(x, dragging) {\r\n if (!this.pswp.canLoop() && dragging) {\r\n // Apply friction\r\n let newSlideIndexOffset = ((this.slideWidth * this._currPositionIndex) - x) / this.slideWidth;\r\n newSlideIndexOffset += this.pswp.currIndex;\r\n const delta = Math.round(x - this.x);\r\n\r\n if ((newSlideIndexOffset < 0 && delta > 0)\r\n || (newSlideIndexOffset >= this.pswp.getNumItems() - 1 && delta < 0)) {\r\n x = this.x + (delta * MAIN_SCROLL_END_FRICTION);\r\n }\r\n }\r\n\r\n this.x = x;\r\n\r\n if (this.pswp.container) {\r\n setTransform(this.pswp.container, x);\r\n }\r\n\r\n this.pswp.dispatch('moveMainScroll', { x, dragging: dragging ?? false });\r\n }\r\n}\r\n\r\nexport default MainScroll;\r\n","import { specialKeyUsed } from './util/util.js';\r\n\r\n/** @typedef {import('./photoswipe.js').default} PhotoSwipe */\r\n\r\n/**\r\n * @template T\r\n * @typedef {import('./types.js').Methods} Methods\r\n */\r\n\r\nconst KeyboardKeyCodesMap = {\r\n Escape: 27,\r\n z: 90,\r\n ArrowLeft: 37,\r\n ArrowUp: 38,\r\n ArrowRight: 39,\r\n ArrowDown: 40,\r\n Tab: 9,\r\n};\r\n\r\n/**\r\n * @template {keyof KeyboardKeyCodesMap} T\r\n * @param {T} key\r\n * @param {boolean} isKeySupported\r\n * @returns {T | number | undefined}\r\n */\r\nconst getKeyboardEventKey = (key, isKeySupported) => {\r\n return isKeySupported ? key : KeyboardKeyCodesMap[key];\r\n};\r\n\r\n/**\r\n * - Manages keyboard shortcuts.\r\n * - Helps trap focus within photoswipe.\r\n */\r\nclass Keyboard {\r\n /**\r\n * @param {PhotoSwipe} pswp\r\n */\r\n constructor(pswp) {\r\n this.pswp = pswp;\r\n /** @private */\r\n this._wasFocused = false;\r\n\r\n pswp.on('bindEvents', () => {\r\n if (pswp.options.trapFocus) {\r\n // Dialog was likely opened by keyboard if initial point is not defined\r\n if (!pswp.options.initialPointerPos) {\r\n // focus causes layout,\r\n // which causes lag during the animation,\r\n // that's why we delay it until the opener transition ends\r\n this._focusRoot();\r\n }\r\n\r\n pswp.events.add(\r\n document,\r\n 'focusin',\r\n /** @type EventListener */(this._onFocusIn.bind(this))\r\n );\r\n }\r\n\r\n pswp.events.add(document, 'keydown', /** @type EventListener */(this._onKeyDown.bind(this)));\r\n });\r\n\r\n const lastActiveElement = /** @type {HTMLElement} */ (document.activeElement);\r\n pswp.on('destroy', () => {\r\n if (pswp.options.returnFocus\r\n && lastActiveElement\r\n && this._wasFocused) {\r\n lastActiveElement.focus();\r\n }\r\n });\r\n }\r\n\r\n /** @private */\r\n _focusRoot() {\r\n if (!this._wasFocused && this.pswp.element) {\r\n this.pswp.element.focus();\r\n this._wasFocused = true;\r\n }\r\n }\r\n\r\n /**\r\n * @private\r\n * @param {KeyboardEvent} e\r\n */\r\n _onKeyDown(e) {\r\n const { pswp } = this;\r\n\r\n if (pswp.dispatch('keydown', { originalEvent: e }).defaultPrevented) {\r\n return;\r\n }\r\n\r\n if (specialKeyUsed(e)) {\r\n // don't do anything if special key pressed\r\n // to prevent from overriding default browser actions\r\n // for example, in Chrome on Mac cmd+arrow-left returns to previous page\r\n return;\r\n }\r\n\r\n /** @type {Methods | undefined} */\r\n let keydownAction;\r\n /** @type {'x' | 'y' | undefined} */\r\n let axis;\r\n let isForward = false;\r\n const isKeySupported = 'key' in e;\r\n\r\n switch (isKeySupported ? e.key : e.keyCode) {\r\n case getKeyboardEventKey('Escape', isKeySupported):\r\n if (pswp.options.escKey) {\r\n keydownAction = 'close';\r\n }\r\n break;\r\n case getKeyboardEventKey('z', isKeySupported):\r\n keydownAction = 'toggleZoom';\r\n break;\r\n case getKeyboardEventKey('ArrowLeft', isKeySupported):\r\n axis = 'x';\r\n break;\r\n case getKeyboardEventKey('ArrowUp', isKeySupported):\r\n axis = 'y';\r\n break;\r\n case getKeyboardEventKey('ArrowRight', isKeySupported):\r\n axis = 'x';\r\n isForward = true;\r\n break;\r\n case getKeyboardEventKey('ArrowDown', isKeySupported):\r\n isForward = true;\r\n axis = 'y';\r\n break;\r\n case getKeyboardEventKey('Tab', isKeySupported):\r\n this._focusRoot();\r\n break;\r\n default:\r\n }\r\n\r\n // if left/right/top/bottom key\r\n if (axis) {\r\n // prevent page scroll\r\n e.preventDefault();\r\n\r\n const { currSlide } = pswp;\r\n\r\n if (pswp.options.arrowKeys\r\n && axis === 'x'\r\n && pswp.getNumItems() > 1) {\r\n keydownAction = isForward ? 'next' : 'prev';\r\n } else if (currSlide && currSlide.currZoomLevel > currSlide.zoomLevels.fit) {\r\n // up/down arrow keys pan the image vertically\r\n // left/right arrow keys pan horizontally.\r\n // Unless there is only one image,\r\n // or arrowKeys option is disabled\r\n currSlide.pan[axis] += isForward ? -80 : 80;\r\n currSlide.panTo(currSlide.pan.x, currSlide.pan.y);\r\n }\r\n }\r\n\r\n if (keydownAction) {\r\n e.preventDefault();\r\n // @ts-ignore\r\n pswp[keydownAction]();\r\n }\r\n }\r\n\r\n /**\r\n * Trap focus inside photoswipe\r\n *\r\n * @private\r\n * @param {FocusEvent} e\r\n */\r\n _onFocusIn(e) {\r\n const { template } = this.pswp;\r\n if (template\r\n && document !== e.target\r\n && template !== e.target\r\n && !template.contains(/** @type {Node} */ (e.target))) {\r\n // focus root element\r\n template.focus();\r\n }\r\n }\r\n}\r\n\r\nexport default Keyboard;\r\n","import { setTransitionStyle, removeTransitionStyle } from './util.js';\r\n\r\nconst DEFAULT_EASING = 'cubic-bezier(.4,0,.22,1)';\r\n\r\n/** @typedef {import('./animations.js').SharedAnimationProps} SharedAnimationProps */\r\n\r\n/** @typedef {Object} DefaultCssAnimationProps\r\n *\r\n * @prop {HTMLElement} target\r\n * @prop {number} [duration]\r\n * @prop {string} [easing]\r\n * @prop {string} [transform]\r\n * @prop {string} [opacity]\r\n * */\r\n\r\n/** @typedef {SharedAnimationProps & DefaultCssAnimationProps} CssAnimationProps */\r\n\r\n/**\r\n * Runs CSS transition.\r\n */\r\nclass CSSAnimation {\r\n /**\r\n * onComplete can be unpredictable, be careful about current state\r\n *\r\n * @param {CssAnimationProps} props\r\n */\r\n constructor(props) {\r\n this.props = props;\r\n const {\r\n target,\r\n onComplete,\r\n transform,\r\n onFinish = () => {},\r\n duration = 333,\r\n easing = DEFAULT_EASING,\r\n } = props;\r\n\r\n this.onFinish = onFinish;\r\n\r\n // support only transform and opacity\r\n const prop = transform ? 'transform' : 'opacity';\r\n const propValue = props[prop] ?? '';\r\n\r\n /** @private */\r\n this._target = target;\r\n /** @private */\r\n this._onComplete = onComplete;\r\n /** @private */\r\n this._finished = false;\r\n\r\n /** @private */\r\n this._onTransitionEnd = this._onTransitionEnd.bind(this);\r\n\r\n // Using timeout hack to make sure that animation\r\n // starts even if the animated property was changed recently,\r\n // otherwise transitionend might not fire or transition won't start.\r\n // https://drafts.csswg.org/css-transitions/#starting\r\n //\r\n // ¯\\_(ツ)_/¯\r\n /** @private */\r\n this._helperTimeout = setTimeout(() => {\r\n setTransitionStyle(target, prop, duration, easing);\r\n this._helperTimeout = setTimeout(() => {\r\n target.addEventListener('transitionend', this._onTransitionEnd, false);\r\n target.addEventListener('transitioncancel', this._onTransitionEnd, false);\r\n\r\n // Safari occasionally does not emit transitionend event\r\n // if element property was modified during the transition,\r\n // which may be caused by resize or third party component,\r\n // using timeout as a safety fallback\r\n this._helperTimeout = setTimeout(() => {\r\n this._finalizeAnimation();\r\n }, duration + 500);\r\n target.style[prop] = propValue;\r\n }, 30); // Do not reduce this number\r\n }, 0);\r\n }\r\n\r\n /**\r\n * @private\r\n * @param {TransitionEvent} e\r\n */\r\n _onTransitionEnd(e) {\r\n if (e.target === this._target) {\r\n this._finalizeAnimation();\r\n }\r\n }\r\n\r\n /**\r\n * @private\r\n */\r\n _finalizeAnimation() {\r\n if (!this._finished) {\r\n this._finished = true;\r\n this.onFinish();\r\n if (this._onComplete) {\r\n this._onComplete();\r\n }\r\n }\r\n }\r\n\r\n // Destroy is called automatically onFinish\r\n destroy() {\r\n if (this._helperTimeout) {\r\n clearTimeout(this._helperTimeout);\r\n }\r\n removeTransitionStyle(this._target);\r\n this._target.removeEventListener('transitionend', this._onTransitionEnd, false);\r\n this._target.removeEventListener('transitioncancel', this._onTransitionEnd, false);\r\n if (!this._finished) {\r\n this._finalizeAnimation();\r\n }\r\n }\r\n}\r\n\r\nexport default CSSAnimation;\r\n","const DEFAULT_NATURAL_FREQUENCY = 12;\r\nconst DEFAULT_DAMPING_RATIO = 0.75;\r\n\r\n/**\r\n * Spring easing helper\r\n */\r\nclass SpringEaser {\r\n /**\r\n * @param {number} initialVelocity Initial velocity, px per ms.\r\n *\r\n * @param {number} [dampingRatio]\r\n * Determines how bouncy animation will be.\r\n * From 0 to 1, 0 - always overshoot, 1 - do not overshoot.\r\n * \"overshoot\" refers to part of animation that\r\n * goes beyond the final value.\r\n *\r\n * @param {number} [naturalFrequency]\r\n * Determines how fast animation will slow down.\r\n * The higher value - the stiffer the transition will be,\r\n * and the faster it will slow down.\r\n * Recommended value from 10 to 50\r\n */\r\n constructor(initialVelocity, dampingRatio, naturalFrequency) {\r\n this.velocity = initialVelocity * 1000; // convert to \"pixels per second\"\r\n\r\n // https://en.wikipedia.org/wiki/Damping_ratio\r\n this._dampingRatio = dampingRatio || DEFAULT_DAMPING_RATIO;\r\n\r\n // https://en.wikipedia.org/wiki/Natural_frequency\r\n this._naturalFrequency = naturalFrequency || DEFAULT_NATURAL_FREQUENCY;\r\n\r\n this._dampedFrequency = this._naturalFrequency;\r\n\r\n if (this._dampingRatio < 1) {\r\n this._dampedFrequency *= Math.sqrt(1 - this._dampingRatio * this._dampingRatio);\r\n }\r\n }\r\n\r\n /**\r\n * @param {number} deltaPosition Difference between current and end position of the animation\r\n * @param {number} deltaTime Frame duration in milliseconds\r\n *\r\n * @returns {number} Displacement, relative to the end position.\r\n */\r\n easeFrame(deltaPosition, deltaTime) {\r\n // Inspired by Apple Webkit and Android spring function implementation\r\n // https://en.wikipedia.org/wiki/Oscillation\r\n // https://en.wikipedia.org/wiki/Damping_ratio\r\n // we ignore mass (assume that it's 1kg)\r\n\r\n let displacement = 0;\r\n let coeff;\r\n\r\n deltaTime /= 1000;\r\n\r\n const naturalDumpingPow = Math.E ** (-this._dampingRatio * this._naturalFrequency * deltaTime);\r\n\r\n if (this._dampingRatio === 1) {\r\n coeff = this.velocity + this._naturalFrequency * deltaPosition;\r\n\r\n displacement = (deltaPosition + coeff * deltaTime) * naturalDumpingPow;\r\n\r\n this.velocity = displacement\r\n * (-this._naturalFrequency) + coeff\r\n * naturalDumpingPow;\r\n } else if (this._dampingRatio < 1) {\r\n coeff = (1 / this._dampedFrequency)\r\n * (this._dampingRatio * this._naturalFrequency * deltaPosition + this.velocity);\r\n\r\n const dumpedFCos = Math.cos(this._dampedFrequency * deltaTime);\r\n const dumpedFSin = Math.sin(this._dampedFrequency * deltaTime);\r\n\r\n displacement = naturalDumpingPow\r\n * (deltaPosition * dumpedFCos + coeff * dumpedFSin);\r\n\r\n this.velocity = displacement\r\n * (-this._naturalFrequency)\r\n * this._dampingRatio\r\n + naturalDumpingPow\r\n * (-this._dampedFrequency * deltaPosition * dumpedFSin\r\n + this._dampedFrequency * coeff * dumpedFCos);\r\n }\r\n\r\n // Overdamped (>1) damping ratio is not supported\r\n\r\n return displacement;\r\n }\r\n}\r\n\r\nexport default SpringEaser;\r\n","import SpringEaser from './spring-easer.js';\r\n\r\n/** @typedef {import('./animations.js').SharedAnimationProps} SharedAnimationProps */\r\n\r\n/**\r\n * @typedef {Object} DefaultSpringAnimationProps\r\n *\r\n * @prop {number} start\r\n * @prop {number} end\r\n * @prop {number} velocity\r\n * @prop {number} [dampingRatio]\r\n * @prop {number} [naturalFrequency]\r\n * @prop {(end: number) => void} onUpdate\r\n */\r\n\r\n/** @typedef {SharedAnimationProps & DefaultSpringAnimationProps} SpringAnimationProps */\r\n\r\nclass SpringAnimation {\r\n /**\r\n * @param {SpringAnimationProps} props\r\n */\r\n constructor(props) {\r\n this.props = props;\r\n this._raf = 0;\r\n\r\n const {\r\n start,\r\n end,\r\n velocity,\r\n onUpdate,\r\n onComplete,\r\n onFinish = () => {},\r\n dampingRatio,\r\n naturalFrequency\r\n } = props;\r\n\r\n this.onFinish = onFinish;\r\n\r\n const easer = new SpringEaser(velocity, dampingRatio, naturalFrequency);\r\n let prevTime = Date.now();\r\n let deltaPosition = start - end;\r\n\r\n const animationLoop = () => {\r\n if (this._raf) {\r\n deltaPosition = easer.easeFrame(deltaPosition, Date.now() - prevTime);\r\n\r\n // Stop the animation if velocity is low and position is close to end\r\n if (Math.abs(deltaPosition) < 1 && Math.abs(easer.velocity) < 50) {\r\n // Finalize the animation\r\n onUpdate(end);\r\n if (onComplete) {\r\n onComplete();\r\n }\r\n this.onFinish();\r\n } else {\r\n prevTime = Date.now();\r\n onUpdate(deltaPosition + end);\r\n this._raf = requestAnimationFrame(animationLoop);\r\n }\r\n }\r\n };\r\n\r\n this._raf = requestAnimationFrame(animationLoop);\r\n }\r\n\r\n // Destroy is called automatically onFinish\r\n destroy() {\r\n if (this._raf >= 0) {\r\n cancelAnimationFrame(this._raf);\r\n }\r\n this._raf = 0;\r\n }\r\n}\r\n\r\nexport default SpringAnimation;\r\n","import CSSAnimation from './css-animation.js';\r\nimport SpringAnimation from './spring-animation.js';\r\n\r\n/** @typedef {import('./css-animation.js').CssAnimationProps} CssAnimationProps */\r\n/** @typedef {import('./spring-animation.js').SpringAnimationProps} SpringAnimationProps */\r\n\r\n/** @typedef {Object} SharedAnimationProps\r\n * @prop {string} [name]\r\n * @prop {boolean} [isPan]\r\n * @prop {boolean} [isMainScroll]\r\n * @prop {VoidFunction} [onComplete]\r\n * @prop {VoidFunction} [onFinish]\r\n */\r\n\r\n/** @typedef {SpringAnimation | CSSAnimation} Animation */\r\n/** @typedef {SpringAnimationProps | CssAnimationProps} AnimationProps */\r\n\r\n/**\r\n * Manages animations\r\n */\r\nclass Animations {\r\n constructor() {\r\n /** @type {Animation[]} */\r\n this.activeAnimations = [];\r\n }\r\n\r\n /**\r\n * @param {SpringAnimationProps} props\r\n */\r\n startSpring(props) {\r\n this._start(props, true);\r\n }\r\n\r\n /**\r\n * @param {CssAnimationProps} props\r\n */\r\n startTransition(props) {\r\n this._start(props);\r\n }\r\n\r\n /**\r\n * @private\r\n * @param {AnimationProps} props\r\n * @param {boolean} [isSpring]\r\n * @returns {Animation}\r\n */\r\n _start(props, isSpring) {\r\n const animation = isSpring\r\n ? new SpringAnimation(/** @type SpringAnimationProps */ (props))\r\n : new CSSAnimation(/** @type CssAnimationProps */ (props));\r\n\r\n this.activeAnimations.push(animation);\r\n animation.onFinish = () => this.stop(animation);\r\n\r\n return animation;\r\n }\r\n\r\n /**\r\n * @param {Animation} animation\r\n */\r\n stop(animation) {\r\n animation.destroy();\r\n const index = this.activeAnimations.indexOf(animation);\r\n if (index > -1) {\r\n this.activeAnimations.splice(index, 1);\r\n }\r\n }\r\n\r\n stopAll() { // _stopAllAnimations\r\n this.activeAnimations.forEach((animation) => {\r\n animation.destroy();\r\n });\r\n this.activeAnimations = [];\r\n }\r\n\r\n /**\r\n * Stop all pan or zoom transitions\r\n */\r\n stopAllPan() {\r\n this.activeAnimations = this.activeAnimations.filter((animation) => {\r\n if (animation.props.isPan) {\r\n animation.destroy();\r\n return false;\r\n }\r\n\r\n return true;\r\n });\r\n }\r\n\r\n stopMainScroll() {\r\n this.activeAnimations = this.activeAnimations.filter((animation) => {\r\n if (animation.props.isMainScroll) {\r\n animation.destroy();\r\n return false;\r\n }\r\n\r\n return true;\r\n });\r\n }\r\n\r\n /**\r\n * Returns true if main scroll transition is running\r\n */\r\n // isMainScrollRunning() {\r\n // return this.activeAnimations.some((animation) => {\r\n // return animation.props.isMainScroll;\r\n // });\r\n // }\r\n\r\n /**\r\n * Returns true if any pan or zoom transition is running\r\n */\r\n isPanRunning() {\r\n return this.activeAnimations.some((animation) => {\r\n return animation.props.isPan;\r\n });\r\n }\r\n}\r\n\r\nexport default Animations;\r\n","/** @typedef {import('./photoswipe.js').default} PhotoSwipe */\r\n\r\n/**\r\n * Handles scroll wheel.\r\n * Can pan and zoom current slide image.\r\n */\r\nclass ScrollWheel {\r\n /**\r\n * @param {PhotoSwipe} pswp\r\n */\r\n constructor(pswp) {\r\n this.pswp = pswp;\r\n pswp.events.add(pswp.element, 'wheel', /** @type EventListener */(this._onWheel.bind(this)));\r\n }\r\n\r\n /**\r\n * @private\r\n * @param {WheelEvent} e\r\n */\r\n _onWheel(e) {\r\n e.preventDefault();\r\n const { currSlide } = this.pswp;\r\n let { deltaX, deltaY } = e;\r\n\r\n if (!currSlide) {\r\n return;\r\n }\r\n\r\n if (this.pswp.dispatch('wheel', { originalEvent: e }).defaultPrevented) {\r\n return;\r\n }\r\n\r\n if (e.ctrlKey || this.pswp.options.wheelToZoom) {\r\n // zoom\r\n if (currSlide.isZoomable()) {\r\n let zoomFactor = -deltaY;\r\n if (e.deltaMode === 1 /* DOM_DELTA_LINE */) {\r\n zoomFactor *= 0.05;\r\n } else {\r\n zoomFactor *= e.deltaMode ? 1 : 0.002;\r\n }\r\n zoomFactor = 2 ** zoomFactor;\r\n\r\n const destZoomLevel = currSlide.currZoomLevel * zoomFactor;\r\n currSlide.zoomTo(destZoomLevel, {\r\n x: e.clientX,\r\n y: e.clientY\r\n });\r\n }\r\n } else {\r\n // pan\r\n if (currSlide.isPannable()) {\r\n if (e.deltaMode === 1 /* DOM_DELTA_LINE */) {\r\n // 18 - average line height\r\n deltaX *= 18;\r\n deltaY *= 18;\r\n }\r\n\r\n currSlide.panTo(\r\n currSlide.pan.x - deltaX,\r\n currSlide.pan.y - deltaY\r\n );\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport default ScrollWheel;\r\n","import { createElement } from '../util/util.js';\r\n\r\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\r\n\r\n/**\r\n * @template T\r\n * @typedef {import('../types.js').Methods} Methods\r\n */\r\n\r\n/**\r\n * @typedef {Object} UIElementMarkupProps\r\n * @prop {boolean} [isCustomSVG]\r\n * @prop {string} inner\r\n * @prop {string} [outlineID]\r\n * @prop {number | string} [size]\r\n */\r\n\r\n/**\r\n * @typedef {Object} UIElementData\r\n * @prop {DefaultUIElements | string} [name]\r\n * @prop {string} [className]\r\n * @prop {UIElementMarkup} [html]\r\n * @prop {boolean} [isButton]\r\n * @prop {keyof HTMLElementTagNameMap} [tagName]\r\n * @prop {string} [title]\r\n * @prop {string} [ariaLabel]\r\n * @prop {(element: HTMLElement, pswp: PhotoSwipe) => void} [onInit]\r\n * @prop {Methods | ((e: MouseEvent, element: HTMLElement, pswp: PhotoSwipe) => void)} [onClick]\r\n * @prop {'bar' | 'wrapper' | 'root'} [appendTo]\r\n * @prop {number} [order]\r\n */\r\n\r\n/** @typedef {'arrowPrev' | 'arrowNext' | 'close' | 'zoom' | 'counter'} DefaultUIElements */\r\n\r\n/** @typedef {string | UIElementMarkupProps} UIElementMarkup */\r\n\r\n/**\r\n * @param {UIElementMarkup} [htmlData]\r\n * @returns {string}\r\n */\r\nfunction addElementHTML(htmlData) {\r\n if (typeof htmlData === 'string') {\r\n // Allow developers to provide full svg,\r\n // For example:\r\n // \r\n // \r\n // \r\n // \r\n // Can also be any HTML string.\r\n return htmlData;\r\n }\r\n\r\n if (!htmlData || !htmlData.isCustomSVG) {\r\n return '';\r\n }\r\n\r\n const svgData = htmlData;\r\n let out = '';\r\n // replace all %d with size\r\n out = out.split('%d').join(/** @type {string} */ (svgData.size || 32));\r\n\r\n // Icons may contain outline/shadow,\r\n // to make it we \"clone\" base icon shape and add border to it.\r\n // Icon itself and border are styled via CSS.\r\n //\r\n // Property shadowID defines ID of element that should be cloned.\r\n if (svgData.outlineID) {\r\n out += '';\r\n }\r\n\r\n out += svgData.inner;\r\n\r\n out += '';\r\n\r\n return out;\r\n}\r\n\r\nclass UIElement {\r\n /**\r\n * @param {PhotoSwipe} pswp\r\n * @param {UIElementData} data\r\n */\r\n constructor(pswp, data) {\r\n const name = data.name || data.className;\r\n let elementHTML = data.html;\r\n\r\n // @ts-expect-error lookup only by `data.name` maybe?\r\n if (pswp.options[name] === false) {\r\n // exit if element is disabled from options\r\n return;\r\n }\r\n\r\n // Allow to override SVG icons from options\r\n // @ts-expect-error lookup only by `data.name` maybe?\r\n if (typeof pswp.options[name + 'SVG'] === 'string') {\r\n // arrowPrevSVG\r\n // arrowNextSVG\r\n // closeSVG\r\n // zoomSVG\r\n // @ts-expect-error lookup only by `data.name` maybe?\r\n elementHTML = pswp.options[name + 'SVG'];\r\n }\r\n\r\n pswp.dispatch('uiElementCreate', { data });\r\n\r\n let className = '';\r\n if (data.isButton) {\r\n className += 'pswp__button ';\r\n className += (data.className || `pswp__button--${data.name}`);\r\n } else {\r\n className += (data.className || `pswp__${data.name}`);\r\n }\r\n\r\n let tagName = data.isButton ? (data.tagName || 'button') : (data.tagName || 'div');\r\n tagName = /** @type {keyof HTMLElementTagNameMap} */ (tagName.toLowerCase());\r\n /** @type {HTMLElement} */\r\n const element = createElement(className, tagName);\r\n\r\n if (data.isButton) {\r\n if (tagName === 'button') {\r\n /** @type {HTMLButtonElement} */ (element).type = 'button';\r\n }\r\n\r\n let { title } = data;\r\n const { ariaLabel } = data;\r\n\r\n // @ts-expect-error lookup only by `data.name` maybe?\r\n if (typeof pswp.options[name + 'Title'] === 'string') {\r\n // @ts-expect-error lookup only by `data.name` maybe?\r\n title = pswp.options[name + 'Title'];\r\n }\r\n\r\n if (title) {\r\n element.title = title;\r\n }\r\n\r\n const ariaText = ariaLabel || title;\r\n if (ariaText) {\r\n element.setAttribute('aria-label', ariaText);\r\n }\r\n }\r\n\r\n element.innerHTML = addElementHTML(elementHTML);\r\n\r\n if (data.onInit) {\r\n data.onInit(element, pswp);\r\n }\r\n\r\n if (data.onClick) {\r\n element.onclick = (e) => {\r\n if (typeof data.onClick === 'string') {\r\n // @ts-ignore\r\n pswp[data.onClick]();\r\n } else if (typeof data.onClick === 'function') {\r\n data.onClick(e, element, pswp);\r\n }\r\n };\r\n }\r\n\r\n // Top bar is default position\r\n const appendTo = data.appendTo || 'bar';\r\n /** @type {HTMLElement | undefined} root element by default */\r\n let container = pswp.element;\r\n if (appendTo === 'bar') {\r\n if (!pswp.topBar) {\r\n pswp.topBar = createElement('pswp__top-bar pswp__hide-on-close', 'div', pswp.scrollWrap);\r\n }\r\n container = pswp.topBar;\r\n } else {\r\n // element outside of top bar gets a secondary class\r\n // that makes element fade out on close\r\n element.classList.add('pswp__hide-on-close');\r\n\r\n if (appendTo === 'wrapper') {\r\n container = pswp.scrollWrap;\r\n }\r\n }\r\n\r\n container?.appendChild(pswp.applyFilters('uiElement', element, data));\r\n }\r\n}\r\n\r\nexport default UIElement;\r\n","/*\r\n Backward and forward arrow buttons\r\n */\r\n\r\n/** @typedef {import('./ui-element.js').UIElementData} UIElementData */\r\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\r\n\r\n/**\r\n *\r\n * @param {HTMLElement} element\r\n * @param {PhotoSwipe} pswp\r\n * @param {boolean} [isNextButton]\r\n */\r\nfunction initArrowButton(element, pswp, isNextButton) {\r\n element.classList.add('pswp__button--arrow');\r\n // TODO: this should point to a unique id for this instance\r\n element.setAttribute('aria-controls', 'pswp__items');\r\n pswp.on('change', () => {\r\n if (!pswp.options.loop) {\r\n if (isNextButton) {\r\n /** @type {HTMLButtonElement} */\r\n (element).disabled = !(pswp.currIndex < pswp.getNumItems() - 1);\r\n } else {\r\n /** @type {HTMLButtonElement} */\r\n (element).disabled = !(pswp.currIndex > 0);\r\n }\r\n }\r\n });\r\n}\r\n\r\n/** @type {UIElementData} */\r\nexport const arrowPrev = {\r\n name: 'arrowPrev',\r\n className: 'pswp__button--arrow--prev',\r\n title: 'Previous',\r\n order: 10,\r\n isButton: true,\r\n appendTo: 'wrapper',\r\n html: {\r\n isCustomSVG: true,\r\n size: 60,\r\n inner: '',\r\n outlineID: 'pswp__icn-arrow'\r\n },\r\n onClick: 'prev',\r\n onInit: initArrowButton\r\n};\r\n\r\n/** @type {UIElementData} */\r\nexport const arrowNext = {\r\n name: 'arrowNext',\r\n className: 'pswp__button--arrow--next',\r\n title: 'Next',\r\n order: 11,\r\n isButton: true,\r\n appendTo: 'wrapper',\r\n html: {\r\n isCustomSVG: true,\r\n size: 60,\r\n inner: '',\r\n outlineID: 'pswp__icn-arrow'\r\n },\r\n onClick: 'next',\r\n onInit: (el, pswp) => {\r\n initArrowButton(el, pswp, true);\r\n }\r\n};\r\n","/** @type {import('./ui-element.js').UIElementData} UIElementData */\r\nconst closeButton = {\r\n name: 'close',\r\n title: 'Close',\r\n order: 20,\r\n isButton: true,\r\n html: {\r\n isCustomSVG: true,\r\n inner: '',\r\n outlineID: 'pswp__icn-close'\r\n },\r\n onClick: 'close'\r\n};\r\n\r\nexport default closeButton;\r\n","/** @type {import('./ui-element.js').UIElementData} UIElementData */\r\nconst zoomButton = {\r\n name: 'zoom',\r\n title: 'Zoom',\r\n order: 10,\r\n isButton: true,\r\n html: {\r\n isCustomSVG: true,\r\n // eslint-disable-next-line max-len\r\n inner: ''\r\n + ''\r\n + '',\r\n outlineID: 'pswp__icn-zoom'\r\n },\r\n onClick: 'toggleZoom'\r\n};\r\n\r\nexport default zoomButton;\r\n","/** @type {import('./ui-element.js').UIElementData} UIElementData */\r\nexport const loadingIndicator = {\r\n name: 'preloader',\r\n appendTo: 'bar',\r\n order: 7,\r\n html: {\r\n isCustomSVG: true,\r\n // eslint-disable-next-line max-len\r\n inner: '',\r\n outlineID: 'pswp__icn-loading'\r\n },\r\n onInit: (indicatorElement, pswp) => {\r\n /** @type {boolean | undefined} */\r\n let isVisible;\r\n /** @type {NodeJS.Timeout | null} */\r\n let delayTimeout = null;\r\n\r\n /**\r\n * @param {string} className\r\n * @param {boolean} add\r\n */\r\n const toggleIndicatorClass = (className, add) => {\r\n indicatorElement.classList.toggle('pswp__preloader--' + className, add);\r\n };\r\n\r\n /**\r\n * @param {boolean} visible\r\n */\r\n const setIndicatorVisibility = (visible) => {\r\n if (isVisible !== visible) {\r\n isVisible = visible;\r\n toggleIndicatorClass('active', visible);\r\n }\r\n };\r\n\r\n const updatePreloaderVisibility = () => {\r\n if (!pswp.currSlide?.content.isLoading()) {\r\n setIndicatorVisibility(false);\r\n if (delayTimeout) {\r\n clearTimeout(delayTimeout);\r\n delayTimeout = null;\r\n }\r\n return;\r\n }\r\n\r\n if (!delayTimeout) {\r\n // display loading indicator with delay\r\n delayTimeout = setTimeout(() => {\r\n setIndicatorVisibility(Boolean(pswp.currSlide?.content.isLoading()));\r\n delayTimeout = null;\r\n }, pswp.options.preloaderDelay);\r\n }\r\n };\r\n\r\n pswp.on('change', updatePreloaderVisibility);\r\n\r\n pswp.on('loadComplete', (e) => {\r\n if (pswp.currSlide === e.slide) {\r\n updatePreloaderVisibility();\r\n }\r\n });\r\n\r\n // expose the method\r\n if (pswp.ui) {\r\n pswp.ui.updatePreloaderVisibility = updatePreloaderVisibility;\r\n }\r\n }\r\n};\r\n","/** @type {import('./ui-element.js').UIElementData} UIElementData */\r\nexport const counterIndicator = {\r\n name: 'counter',\r\n order: 5,\r\n onInit: (counterElement, pswp) => {\r\n pswp.on('change', () => {\r\n counterElement.innerText = (pswp.currIndex + 1)\r\n + pswp.options.indexIndicatorSep\r\n + pswp.getNumItems();\r\n });\r\n }\r\n};\r\n","import UIElement from './ui-element.js';\r\nimport { arrowPrev, arrowNext } from './button-arrow.js';\r\nimport closeButton from './button-close.js';\r\nimport zoomButton from './button-zoom.js';\r\nimport { loadingIndicator } from './loading-indicator.js';\r\nimport { counterIndicator } from './counter-indicator.js';\r\n\r\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\r\n/** @typedef {import('./ui-element.js').UIElementData} UIElementData */\r\n\r\n/**\r\n * Set special class on element when image is zoomed.\r\n *\r\n * By default, it is used to adjust\r\n * zoom icon and zoom cursor via CSS.\r\n *\r\n * @param {HTMLElement} el\r\n * @param {boolean} isZoomedIn\r\n */\r\nfunction setZoomedIn(el, isZoomedIn) {\r\n el.classList.toggle('pswp--zoomed-in', isZoomedIn);\r\n}\r\n\r\nclass UI {\r\n /**\r\n * @param {PhotoSwipe} pswp\r\n */\r\n constructor(pswp) {\r\n this.pswp = pswp;\r\n this.isRegistered = false;\r\n /** @type {UIElementData[]} */\r\n this.uiElementsData = [];\r\n /** @type {(UIElement | UIElementData)[]} */\r\n this.items = [];\r\n /** @type {() => void} */\r\n this.updatePreloaderVisibility = () => {};\r\n\r\n /**\r\n * @private\r\n * @type {number | undefined}\r\n */\r\n this._lastUpdatedZoomLevel = undefined;\r\n }\r\n\r\n init() {\r\n const { pswp } = this;\r\n this.isRegistered = false;\r\n this.uiElementsData = [\r\n closeButton,\r\n arrowPrev,\r\n arrowNext,\r\n zoomButton,\r\n loadingIndicator,\r\n counterIndicator\r\n ];\r\n\r\n pswp.dispatch('uiRegister');\r\n\r\n // sort by order\r\n this.uiElementsData.sort((a, b) => {\r\n // default order is 0\r\n return (a.order || 0) - (b.order || 0);\r\n });\r\n\r\n this.items = [];\r\n\r\n this.isRegistered = true;\r\n this.uiElementsData.forEach((uiElementData) => {\r\n this.registerElement(uiElementData);\r\n });\r\n\r\n pswp.on('change', () => {\r\n pswp.element?.classList.toggle('pswp--one-slide', pswp.getNumItems() === 1);\r\n });\r\n\r\n pswp.on('zoomPanUpdate', () => this._onZoomPanUpdate());\r\n }\r\n\r\n /**\r\n * @param {UIElementData} elementData\r\n */\r\n registerElement(elementData) {\r\n if (this.isRegistered) {\r\n this.items.push(\r\n new UIElement(this.pswp, elementData)\r\n );\r\n } else {\r\n this.uiElementsData.push(elementData);\r\n }\r\n }\r\n\r\n /**\r\n * Fired each time zoom or pan position is changed.\r\n * Update classes that control visibility of zoom button and cursor icon.\r\n *\r\n * @private\r\n */\r\n _onZoomPanUpdate() {\r\n const { template, currSlide, options } = this.pswp;\r\n\r\n if (this.pswp.opener.isClosing || !template || !currSlide) {\r\n return;\r\n }\r\n\r\n let { currZoomLevel } = currSlide;\r\n\r\n // if not open yet - check against initial zoom level\r\n if (!this.pswp.opener.isOpen) {\r\n currZoomLevel = currSlide.zoomLevels.initial;\r\n }\r\n\r\n if (currZoomLevel === this._lastUpdatedZoomLevel) {\r\n return;\r\n }\r\n this._lastUpdatedZoomLevel = currZoomLevel;\r\n\r\n const currZoomLevelDiff = currSlide.zoomLevels.initial - currSlide.zoomLevels.secondary;\r\n\r\n // Initial and secondary zoom levels are almost equal\r\n if (Math.abs(currZoomLevelDiff) < 0.01 || !currSlide.isZoomable()) {\r\n // disable zoom\r\n setZoomedIn(template, false);\r\n template.classList.remove('pswp--zoom-allowed');\r\n return;\r\n }\r\n\r\n template.classList.add('pswp--zoom-allowed');\r\n\r\n const potentialZoomLevel = currZoomLevel === currSlide.zoomLevels.initial\r\n ? currSlide.zoomLevels.secondary : currSlide.zoomLevels.initial;\r\n\r\n setZoomedIn(template, potentialZoomLevel <= currZoomLevel);\r\n\r\n if (options.imageClickAction === 'zoom'\r\n || options.imageClickAction === 'zoom-or-close') {\r\n template.classList.add('pswp--click-to-zoom');\r\n }\r\n }\r\n}\r\n\r\nexport default UI;\r\n","/** @typedef {import('../lightbox/lightbox.js').default} PhotoSwipeLightbox */\r\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\r\n/** @typedef {import('../photoswipe.js').PhotoSwipeOptions} PhotoSwipeOptions */\r\n/** @typedef {import('../photoswipe.js').DataSource} DataSource */\r\n/** @typedef {import('../ui/ui-element.js').UIElementData} UIElementData */\r\n/** @typedef {import('../slide/content.js').default} ContentDefault */\r\n/** @typedef {import('../slide/slide.js').default} Slide */\r\n/** @typedef {import('../slide/slide.js').SlideData} SlideData */\r\n/** @typedef {import('../slide/zoom-level.js').default} ZoomLevel */\r\n/** @typedef {import('../slide/get-thumb-bounds.js').Bounds} Bounds */\r\n\r\n/**\r\n * Allow adding an arbitrary props to the Content\r\n * https://photoswipe.com/custom-content/#using-webp-image-format\r\n * @typedef {ContentDefault & Record} Content\r\n */\r\n/** @typedef {{ x?: number; y?: number }} Point */\r\n\r\n/**\r\n * @typedef {Object} PhotoSwipeEventsMap https://photoswipe.com/events/\r\n *\r\n *\r\n * https://photoswipe.com/adding-ui-elements/\r\n *\r\n * @prop {undefined} uiRegister\r\n * @prop {{ data: UIElementData }} uiElementCreate\r\n *\r\n *\r\n * https://photoswipe.com/events/#initialization-events\r\n *\r\n * @prop {undefined} beforeOpen\r\n * @prop {undefined} firstUpdate\r\n * @prop {undefined} initialLayout\r\n * @prop {undefined} change\r\n * @prop {undefined} afterInit\r\n * @prop {undefined} bindEvents\r\n *\r\n *\r\n * https://photoswipe.com/events/#opening-or-closing-transition-events\r\n *\r\n * @prop {undefined} openingAnimationStart\r\n * @prop {undefined} openingAnimationEnd\r\n * @prop {undefined} closingAnimationStart\r\n * @prop {undefined} closingAnimationEnd\r\n *\r\n *\r\n * https://photoswipe.com/events/#closing-events\r\n *\r\n * @prop {undefined} close\r\n * @prop {undefined} destroy\r\n *\r\n *\r\n * https://photoswipe.com/events/#pointer-and-gesture-events\r\n *\r\n * @prop {{ originalEvent: PointerEvent }} pointerDown\r\n * @prop {{ originalEvent: PointerEvent }} pointerMove\r\n * @prop {{ originalEvent: PointerEvent }} pointerUp\r\n * @prop {{ bgOpacity: number }} pinchClose can be default prevented\r\n * @prop {{ panY: number }} verticalDrag can be default prevented\r\n *\r\n *\r\n * https://photoswipe.com/events/#slide-content-events\r\n *\r\n * @prop {{ content: Content }} contentInit\r\n * @prop {{ content: Content; isLazy: boolean }} contentLoad can be default prevented\r\n * @prop {{ content: Content; isLazy: boolean }} contentLoadImage can be default prevented\r\n * @prop {{ content: Content; slide: Slide; isError?: boolean }} loadComplete\r\n * @prop {{ content: Content; slide: Slide }} loadError\r\n * @prop {{ content: Content; width: number; height: number }} contentResize can be default prevented\r\n * @prop {{ content: Content; width: number; height: number; slide: Slide }} imageSizeChange\r\n * @prop {{ content: Content }} contentLazyLoad can be default prevented\r\n * @prop {{ content: Content }} contentAppend can be default prevented\r\n * @prop {{ content: Content }} contentActivate can be default prevented\r\n * @prop {{ content: Content }} contentDeactivate can be default prevented\r\n * @prop {{ content: Content }} contentRemove can be default prevented\r\n * @prop {{ content: Content }} contentDestroy can be default prevented\r\n *\r\n *\r\n * undocumented\r\n *\r\n * @prop {{ point: Point; originalEvent: PointerEvent }} imageClickAction can be default prevented\r\n * @prop {{ point: Point; originalEvent: PointerEvent }} bgClickAction can be default prevented\r\n * @prop {{ point: Point; originalEvent: PointerEvent }} tapAction can be default prevented\r\n * @prop {{ point: Point; originalEvent: PointerEvent }} doubleTapAction can be default prevented\r\n *\r\n * @prop {{ originalEvent: KeyboardEvent }} keydown can be default prevented\r\n * @prop {{ x: number; dragging: boolean }} moveMainScroll\r\n * @prop {{ slide: Slide }} firstZoomPan\r\n * @prop {{ slide: Slide | undefined, data: SlideData, index: number }} gettingData\r\n * @prop {undefined} beforeResize\r\n * @prop {undefined} resize\r\n * @prop {undefined} viewportSize\r\n * @prop {undefined} updateScrollOffset\r\n * @prop {{ slide: Slide }} slideInit\r\n * @prop {{ slide: Slide }} afterSetContent\r\n * @prop {{ slide: Slide }} slideLoad\r\n * @prop {{ slide: Slide }} appendHeavy can be default prevented\r\n * @prop {{ slide: Slide }} appendHeavyContent\r\n * @prop {{ slide: Slide }} slideActivate\r\n * @prop {{ slide: Slide }} slideDeactivate\r\n * @prop {{ slide: Slide }} slideDestroy\r\n * @prop {{ destZoomLevel: number, centerPoint: Point | undefined, transitionDuration: number | false | undefined }} beforeZoomTo\r\n * @prop {{ slide: Slide }} zoomPanUpdate\r\n * @prop {{ slide: Slide }} initialZoomPan\r\n * @prop {{ slide: Slide }} calcSlideSize\r\n * @prop {undefined} resolutionChanged\r\n * @prop {{ originalEvent: WheelEvent }} wheel can be default prevented\r\n * @prop {{ content: Content }} contentAppendImage can be default prevented\r\n * @prop {{ index: number; itemData: SlideData }} lazyLoadSlide can be default prevented\r\n * @prop {undefined} lazyLoad\r\n * @prop {{ slide: Slide }} calcBounds\r\n * @prop {{ zoomLevels: ZoomLevel, slideData: SlideData }} zoomLevelsUpdate\r\n *\r\n *\r\n * legacy\r\n *\r\n * @prop {undefined} init\r\n * @prop {undefined} initialZoomIn\r\n * @prop {undefined} initialZoomOut\r\n * @prop {undefined} initialZoomInEnd\r\n * @prop {undefined} initialZoomOutEnd\r\n * @prop {{ dataSource: DataSource | undefined, numItems: number }} numItems\r\n * @prop {{ itemData: SlideData; index: number }} itemData\r\n * @prop {{ index: number, itemData: SlideData, instance: PhotoSwipe }} thumbBounds\r\n */\r\n\r\n/**\r\n * @typedef {Object} PhotoSwipeFiltersMap https://photoswipe.com/filters/\r\n *\r\n * @prop {(numItems: number, dataSource: DataSource | undefined) => number} numItems\r\n * Modify the total amount of slides. Example on Data sources page.\r\n * https://photoswipe.com/filters/#numitems\r\n *\r\n * @prop {(itemData: SlideData, index: number) => SlideData} itemData\r\n * Modify slide item data. Example on Data sources page.\r\n * https://photoswipe.com/filters/#itemdata\r\n *\r\n * @prop {(itemData: SlideData, element: HTMLElement, linkEl: HTMLAnchorElement) => SlideData} domItemData\r\n * Modify item data when it's parsed from DOM element. Example on Data sources page.\r\n * https://photoswipe.com/filters/#domitemdata\r\n *\r\n * @prop {(clickedIndex: number, e: MouseEvent, instance: PhotoSwipeLightbox) => number} clickedIndex\r\n * Modify clicked gallery item index.\r\n * https://photoswipe.com/filters/#clickedindex\r\n *\r\n * @prop {(placeholderSrc: string | false, content: Content) => string | false} placeholderSrc\r\n * Modify placeholder image source.\r\n * https://photoswipe.com/filters/#placeholdersrc\r\n *\r\n * @prop {(isContentLoading: boolean, content: Content) => boolean} isContentLoading\r\n * Modify if the content is currently loading.\r\n * https://photoswipe.com/filters/#iscontentloading\r\n *\r\n * @prop {(isContentZoomable: boolean, content: Content) => boolean} isContentZoomable\r\n * Modify if the content can be zoomed.\r\n * https://photoswipe.com/filters/#iscontentzoomable\r\n *\r\n * @prop {(useContentPlaceholder: boolean, content: Content) => boolean} useContentPlaceholder\r\n * Modify if the placeholder should be used for the content.\r\n * https://photoswipe.com/filters/#usecontentplaceholder\r\n *\r\n * @prop {(isKeepingPlaceholder: boolean, content: Content) => boolean} isKeepingPlaceholder\r\n * Modify if the placeholder should be kept after the content is loaded.\r\n * https://photoswipe.com/filters/#iskeepingplaceholder\r\n *\r\n *\r\n * @prop {(contentErrorElement: HTMLElement, content: Content) => HTMLElement} contentErrorElement\r\n * Modify an element when the content has error state (for example, if image cannot be loaded).\r\n * https://photoswipe.com/filters/#contenterrorelement\r\n *\r\n * @prop {(element: HTMLElement, data: UIElementData) => HTMLElement} uiElement\r\n * Modify a UI element that's being created.\r\n * https://photoswipe.com/filters/#uielement\r\n *\r\n * @prop {(thumbnail: HTMLElement | null | undefined, itemData: SlideData, index: number) => HTMLElement} thumbEl\r\n * Modify the thumbnail element from which opening zoom animation starts or ends.\r\n * https://photoswipe.com/filters/#thumbel\r\n *\r\n * @prop {(thumbBounds: Bounds | undefined, itemData: SlideData, index: number) => Bounds} thumbBounds\r\n * Modify the thumbnail bounds from which opening zoom animation starts or ends.\r\n * https://photoswipe.com/filters/#thumbbounds\r\n *\r\n * @prop {(srcsetSizesWidth: number, content: Content) => number} srcsetSizesWidth\r\n *\r\n * @prop {(preventPointerEvent: boolean, event: PointerEvent, pointerType: string) => boolean} preventPointerEvent\r\n *\r\n */\r\n\r\n/**\r\n * @template {keyof PhotoSwipeFiltersMap} T\r\n * @typedef {{ fn: PhotoSwipeFiltersMap[T], priority: number }} Filter\r\n */\r\n\r\n/**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @typedef {PhotoSwipeEventsMap[T] extends undefined ? PhotoSwipeEvent : PhotoSwipeEvent & PhotoSwipeEventsMap[T]} AugmentedEvent\r\n */\r\n\r\n/**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @typedef {(event: AugmentedEvent) => void} EventCallback\r\n */\r\n\r\n/**\r\n * Base PhotoSwipe event object\r\n *\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n */\r\nclass PhotoSwipeEvent {\r\n /**\r\n * @param {T} type\r\n * @param {PhotoSwipeEventsMap[T]} [details]\r\n */\r\n constructor(type, details) {\r\n this.type = type;\r\n this.defaultPrevented = false;\r\n if (details) {\r\n Object.assign(this, details);\r\n }\r\n }\r\n\r\n preventDefault() {\r\n this.defaultPrevented = true;\r\n }\r\n}\r\n\r\n/**\r\n * PhotoSwipe base class that can listen and dispatch for events.\r\n * Shared by PhotoSwipe Core and PhotoSwipe Lightbox, extended by base.js\r\n */\r\nclass Eventable {\r\n constructor() {\r\n /**\r\n * @type {{ [T in keyof PhotoSwipeEventsMap]?: ((event: AugmentedEvent) => void)[] }}\r\n */\r\n this._listeners = {};\r\n\r\n /**\r\n * @type {{ [T in keyof PhotoSwipeFiltersMap]?: Filter[] }}\r\n */\r\n this._filters = {};\r\n\r\n /** @type {PhotoSwipe | undefined} */\r\n this.pswp = undefined;\r\n\r\n /** @type {PhotoSwipeOptions | undefined} */\r\n this.options = undefined;\r\n }\r\n\r\n /**\r\n * @template {keyof PhotoSwipeFiltersMap} T\r\n * @param {T} name\r\n * @param {PhotoSwipeFiltersMap[T]} fn\r\n * @param {number} priority\r\n */\r\n addFilter(name, fn, priority = 100) {\r\n if (!this._filters[name]) {\r\n this._filters[name] = [];\r\n }\r\n\r\n this._filters[name]?.push({ fn, priority });\r\n this._filters[name]?.sort((f1, f2) => f1.priority - f2.priority);\r\n\r\n this.pswp?.addFilter(name, fn, priority);\r\n }\r\n\r\n /**\r\n * @template {keyof PhotoSwipeFiltersMap} T\r\n * @param {T} name\r\n * @param {PhotoSwipeFiltersMap[T]} fn\r\n */\r\n removeFilter(name, fn) {\r\n if (this._filters[name]) {\r\n // @ts-expect-error\r\n this._filters[name] = this._filters[name].filter(filter => (filter.fn !== fn));\r\n }\r\n\r\n if (this.pswp) {\r\n this.pswp.removeFilter(name, fn);\r\n }\r\n }\r\n\r\n /**\r\n * @template {keyof PhotoSwipeFiltersMap} T\r\n * @param {T} name\r\n * @param {Parameters} args\r\n * @returns {Parameters[0]}\r\n */\r\n applyFilters(name, ...args) {\r\n this._filters[name]?.forEach((filter) => {\r\n // @ts-expect-error\r\n args[0] = filter.fn.apply(this, args);\r\n });\r\n return args[0];\r\n }\r\n\r\n /**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @param {T} name\r\n * @param {EventCallback} fn\r\n */\r\n on(name, fn) {\r\n if (!this._listeners[name]) {\r\n this._listeners[name] = [];\r\n }\r\n this._listeners[name]?.push(fn);\r\n\r\n // When binding events to lightbox,\r\n // also bind events to PhotoSwipe Core,\r\n // if it's open.\r\n this.pswp?.on(name, fn);\r\n }\r\n\r\n /**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @param {T} name\r\n * @param {EventCallback} fn\r\n */\r\n off(name, fn) {\r\n if (this._listeners[name]) {\r\n // @ts-expect-error\r\n this._listeners[name] = this._listeners[name].filter(listener => (fn !== listener));\r\n }\r\n\r\n this.pswp?.off(name, fn);\r\n }\r\n\r\n /**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @param {T} name\r\n * @param {PhotoSwipeEventsMap[T]} [details]\r\n * @returns {AugmentedEvent}\r\n */\r\n dispatch(name, details) {\r\n if (this.pswp) {\r\n return this.pswp.dispatch(name, details);\r\n }\r\n\r\n const event = /** @type {AugmentedEvent} */ (new PhotoSwipeEvent(name, details));\r\n\r\n this._listeners[name]?.forEach((listener) => {\r\n listener.call(this, event);\r\n });\r\n\r\n return event;\r\n }\r\n}\r\n\r\nexport default Eventable;\r\n","import { createElement, setWidthHeight, toTransformString } from '../util/util.js';\r\n\r\nclass Placeholder {\r\n /**\r\n * @param {string | false} imageSrc\r\n * @param {HTMLElement} container\r\n */\r\n constructor(imageSrc, container) {\r\n // Create placeholder\r\n // (stretched thumbnail or simple div behind the main image)\r\n /** @type {HTMLImageElement | HTMLDivElement | null} */\r\n this.element = createElement(\r\n 'pswp__img pswp__img--placeholder',\r\n imageSrc ? 'img' : 'div',\r\n container\r\n );\r\n\r\n if (imageSrc) {\r\n const imgEl = /** @type {HTMLImageElement} */ (this.element);\r\n imgEl.decoding = 'async';\r\n imgEl.alt = '';\r\n imgEl.src = imageSrc;\r\n imgEl.setAttribute('role', 'presentation');\r\n }\r\n\r\n this.element.setAttribute('aria-hidden', 'true');\r\n }\r\n\r\n /**\r\n * @param {number} width\r\n * @param {number} height\r\n */\r\n setDisplayedSize(width, height) {\r\n if (!this.element) {\r\n return;\r\n }\r\n\r\n if (this.element.tagName === 'IMG') {\r\n // Use transform scale() to modify img placeholder size\r\n // (instead of changing width/height directly).\r\n // This helps with performance, specifically in iOS15 Safari.\r\n setWidthHeight(this.element, 250, 'auto');\r\n this.element.style.transformOrigin = '0 0';\r\n this.element.style.transform = toTransformString(0, 0, width / 250);\r\n } else {\r\n setWidthHeight(this.element, width, height);\r\n }\r\n }\r\n\r\n destroy() {\r\n if (this.element?.parentNode) {\r\n this.element.remove();\r\n }\r\n this.element = null;\r\n }\r\n}\r\n\r\nexport default Placeholder;\r\n","import { createElement, isSafari, LOAD_STATE, setWidthHeight } from '../util/util.js';\r\nimport Placeholder from './placeholder.js';\r\n\r\n/** @typedef {import('./slide.js').default} Slide */\r\n/** @typedef {import('./slide.js').SlideData} SlideData */\r\n/** @typedef {import('../core/base.js').default} PhotoSwipeBase */\r\n/** @typedef {import('../util/util.js').LoadState} LoadState */\r\n\r\nclass Content {\r\n /**\r\n * @param {SlideData} itemData Slide data\r\n * @param {PhotoSwipeBase} instance PhotoSwipe or PhotoSwipeLightbox instance\r\n * @param {number} index\r\n */\r\n constructor(itemData, instance, index) {\r\n this.instance = instance;\r\n this.data = itemData;\r\n this.index = index;\r\n\r\n /** @type {HTMLImageElement | HTMLDivElement | undefined} */\r\n this.element = undefined;\r\n /** @type {Placeholder | undefined} */\r\n this.placeholder = undefined;\r\n /** @type {Slide | undefined} */\r\n this.slide = undefined;\r\n\r\n this.displayedImageWidth = 0;\r\n this.displayedImageHeight = 0;\r\n\r\n this.width = Number(this.data.w) || Number(this.data.width) || 0;\r\n this.height = Number(this.data.h) || Number(this.data.height) || 0;\r\n\r\n this.isAttached = false;\r\n this.hasSlide = false;\r\n this.isDecoding = false;\r\n /** @type {LoadState} */\r\n this.state = LOAD_STATE.IDLE;\r\n\r\n if (this.data.type) {\r\n this.type = this.data.type;\r\n } else if (this.data.src) {\r\n this.type = 'image';\r\n } else {\r\n this.type = 'html';\r\n }\r\n\r\n this.instance.dispatch('contentInit', { content: this });\r\n }\r\n\r\n removePlaceholder() {\r\n if (this.placeholder && !this.keepPlaceholder()) {\r\n // With delay, as image might be loaded, but not rendered\r\n setTimeout(() => {\r\n if (this.placeholder) {\r\n this.placeholder.destroy();\r\n this.placeholder = undefined;\r\n }\r\n }, 1000);\r\n }\r\n }\r\n\r\n /**\r\n * Preload content\r\n *\r\n * @param {boolean} isLazy\r\n * @param {boolean} [reload]\r\n */\r\n load(isLazy, reload) {\r\n if (this.slide && this.usePlaceholder()) {\r\n if (!this.placeholder) {\r\n const placeholderSrc = this.instance.applyFilters(\r\n 'placeholderSrc',\r\n // use image-based placeholder only for the first slide,\r\n // as rendering (even small stretched thumbnail) is an expensive operation\r\n (this.data.msrc && this.slide.isFirstSlide) ? this.data.msrc : false,\r\n this\r\n );\r\n this.placeholder = new Placeholder(\r\n placeholderSrc,\r\n this.slide.container\r\n );\r\n } else {\r\n const placeholderEl = this.placeholder.element;\r\n // Add placeholder to DOM if it was already created\r\n if (placeholderEl && !placeholderEl.parentElement) {\r\n this.slide.container.prepend(placeholderEl);\r\n }\r\n }\r\n }\r\n\r\n if (this.element && !reload) {\r\n return;\r\n }\r\n\r\n if (this.instance.dispatch('contentLoad', { content: this, isLazy }).defaultPrevented) {\r\n return;\r\n }\r\n\r\n if (this.isImageContent()) {\r\n this.element = createElement('pswp__img', 'img');\r\n // Start loading only after width is defined, as sizes might depend on it.\r\n // Due to Safari feature, we must define sizes before srcset.\r\n if (this.displayedImageWidth) {\r\n this.loadImage(isLazy);\r\n }\r\n } else {\r\n this.element = createElement('pswp__content', 'div');\r\n this.element.innerHTML = this.data.html || '';\r\n }\r\n\r\n if (reload && this.slide) {\r\n this.slide.updateContentSize(true);\r\n }\r\n }\r\n\r\n /**\r\n * Preload image\r\n *\r\n * @param {boolean} isLazy\r\n */\r\n loadImage(isLazy) {\r\n if (!this.isImageContent()\r\n || !this.element\r\n || this.instance.dispatch('contentLoadImage', { content: this, isLazy }).defaultPrevented) {\r\n return;\r\n }\r\n\r\n const imageElement = /** @type HTMLImageElement */ (this.element);\r\n\r\n this.updateSrcsetSizes();\r\n\r\n if (this.data.srcset) {\r\n imageElement.srcset = this.data.srcset;\r\n }\r\n\r\n imageElement.src = this.data.src ?? '';\r\n imageElement.alt = this.data.alt ?? '';\r\n\r\n this.state = LOAD_STATE.LOADING;\r\n\r\n if (imageElement.complete) {\r\n this.onLoaded();\r\n } else {\r\n imageElement.onload = () => {\r\n this.onLoaded();\r\n };\r\n\r\n imageElement.onerror = () => {\r\n this.onError();\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Assign slide to content\r\n *\r\n * @param {Slide} slide\r\n */\r\n setSlide(slide) {\r\n this.slide = slide;\r\n this.hasSlide = true;\r\n this.instance = slide.pswp;\r\n\r\n // todo: do we need to unset slide?\r\n }\r\n\r\n /**\r\n * Content load success handler\r\n */\r\n onLoaded() {\r\n this.state = LOAD_STATE.LOADED;\r\n\r\n if (this.slide && this.element) {\r\n this.instance.dispatch('loadComplete', { slide: this.slide, content: this });\r\n\r\n // if content is reloaded\r\n if (this.slide.isActive\r\n && this.slide.heavyAppended\r\n && !this.element.parentNode) {\r\n this.append();\r\n this.slide.updateContentSize(true);\r\n }\r\n\r\n if (this.state === LOAD_STATE.LOADED || this.state === LOAD_STATE.ERROR) {\r\n this.removePlaceholder();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Content load error handler\r\n */\r\n onError() {\r\n this.state = LOAD_STATE.ERROR;\r\n\r\n if (this.slide) {\r\n this.displayError();\r\n this.instance.dispatch('loadComplete', { slide: this.slide, isError: true, content: this });\r\n this.instance.dispatch('loadError', { slide: this.slide, content: this });\r\n }\r\n }\r\n\r\n /**\r\n * @returns {Boolean} If the content is currently loading\r\n */\r\n isLoading() {\r\n return this.instance.applyFilters(\r\n 'isContentLoading',\r\n this.state === LOAD_STATE.LOADING,\r\n this\r\n );\r\n }\r\n\r\n /**\r\n * @returns {Boolean} If the content is in error state\r\n */\r\n isError() {\r\n return this.state === LOAD_STATE.ERROR;\r\n }\r\n\r\n /**\r\n * @returns {boolean} If the content is image\r\n */\r\n isImageContent() {\r\n return this.type === 'image';\r\n }\r\n\r\n /**\r\n * Update content size\r\n *\r\n * @param {Number} width\r\n * @param {Number} height\r\n */\r\n setDisplayedSize(width, height) {\r\n if (!this.element) {\r\n return;\r\n }\r\n\r\n if (this.placeholder) {\r\n this.placeholder.setDisplayedSize(width, height);\r\n }\r\n\r\n if (this.instance.dispatch(\r\n 'contentResize',\r\n { content: this, width, height }).defaultPrevented\r\n ) {\r\n return;\r\n }\r\n\r\n setWidthHeight(this.element, width, height);\r\n\r\n if (this.isImageContent() && !this.isError()) {\r\n const isInitialSizeUpdate = (!this.displayedImageWidth && width);\r\n\r\n this.displayedImageWidth = width;\r\n this.displayedImageHeight = height;\r\n\r\n if (isInitialSizeUpdate) {\r\n this.loadImage(false);\r\n } else {\r\n this.updateSrcsetSizes();\r\n }\r\n\r\n if (this.slide) {\r\n this.instance.dispatch(\r\n 'imageSizeChange',\r\n { slide: this.slide, width, height, content: this }\r\n );\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @returns {boolean} If the content can be zoomed\r\n */\r\n isZoomable() {\r\n return this.instance.applyFilters(\r\n 'isContentZoomable',\r\n this.isImageContent() && (this.state !== LOAD_STATE.ERROR),\r\n this\r\n );\r\n }\r\n\r\n /**\r\n * Update image srcset sizes attribute based on width and height\r\n */\r\n updateSrcsetSizes() {\r\n // Handle srcset sizes attribute.\r\n //\r\n // Never lower quality, if it was increased previously.\r\n // Chrome does this automatically, Firefox and Safari do not,\r\n // so we store largest used size in dataset.\r\n if (!this.isImageContent() || !this.element || !this.data.srcset) {\r\n return;\r\n }\r\n\r\n const image = /** @type HTMLImageElement */ (this.element);\r\n const sizesWidth = this.instance.applyFilters(\r\n 'srcsetSizesWidth',\r\n this.displayedImageWidth,\r\n this\r\n );\r\n\r\n if (\r\n !image.dataset.largestUsedSize\r\n || sizesWidth > parseInt(image.dataset.largestUsedSize, 10)\r\n ) {\r\n image.sizes = sizesWidth + 'px';\r\n image.dataset.largestUsedSize = String(sizesWidth);\r\n }\r\n }\r\n\r\n /**\r\n * @returns {boolean} If content should use a placeholder (from msrc by default)\r\n */\r\n usePlaceholder() {\r\n return this.instance.applyFilters(\r\n 'useContentPlaceholder',\r\n this.isImageContent(),\r\n this\r\n );\r\n }\r\n\r\n /**\r\n * Preload content with lazy-loading param\r\n */\r\n lazyLoad() {\r\n if (this.instance.dispatch('contentLazyLoad', { content: this }).defaultPrevented) {\r\n return;\r\n }\r\n\r\n this.load(true);\r\n }\r\n\r\n /**\r\n * @returns {boolean} If placeholder should be kept after content is loaded\r\n */\r\n keepPlaceholder() {\r\n return this.instance.applyFilters(\r\n 'isKeepingPlaceholder',\r\n this.isLoading(),\r\n this\r\n );\r\n }\r\n\r\n /**\r\n * Destroy the content\r\n */\r\n destroy() {\r\n this.hasSlide = false;\r\n this.slide = undefined;\r\n\r\n if (this.instance.dispatch('contentDestroy', { content: this }).defaultPrevented) {\r\n return;\r\n }\r\n\r\n this.remove();\r\n\r\n if (this.placeholder) {\r\n this.placeholder.destroy();\r\n this.placeholder = undefined;\r\n }\r\n\r\n if (this.isImageContent() && this.element) {\r\n this.element.onload = null;\r\n this.element.onerror = null;\r\n this.element = undefined;\r\n }\r\n }\r\n\r\n /**\r\n * Display error message\r\n */\r\n displayError() {\r\n if (this.slide) {\r\n let errorMsgEl = createElement('pswp__error-msg', 'div');\r\n errorMsgEl.innerText = this.instance.options?.errorMsg ?? '';\r\n errorMsgEl = /** @type {HTMLDivElement} */ (this.instance.applyFilters(\r\n 'contentErrorElement',\r\n errorMsgEl,\r\n this\r\n ));\r\n this.element = createElement('pswp__content pswp__error-msg-container', 'div');\r\n this.element.appendChild(errorMsgEl);\r\n this.slide.container.innerText = '';\r\n this.slide.container.appendChild(this.element);\r\n this.slide.updateContentSize(true);\r\n this.removePlaceholder();\r\n }\r\n }\r\n\r\n /**\r\n * Append the content\r\n */\r\n append() {\r\n if (this.isAttached || !this.element) {\r\n return;\r\n }\r\n\r\n this.isAttached = true;\r\n\r\n if (this.state === LOAD_STATE.ERROR) {\r\n this.displayError();\r\n return;\r\n }\r\n\r\n if (this.instance.dispatch('contentAppend', { content: this }).defaultPrevented) {\r\n return;\r\n }\r\n\r\n const supportsDecode = ('decode' in this.element);\r\n\r\n if (this.isImageContent()) {\r\n // Use decode() on nearby slides\r\n //\r\n // Nearby slide images are in DOM and not hidden via display:none.\r\n // However, they are placed offscreen (to the left and right side).\r\n //\r\n // Some browsers do not composite the image until it's actually visible,\r\n // using decode() helps.\r\n //\r\n // You might ask \"why dont you just decode() and then append all images\",\r\n // that's because I want to show image before it's fully loaded,\r\n // as browser can render parts of image while it is loading.\r\n // We do not do this in Safari due to partial loading bug.\r\n if (supportsDecode && this.slide && (!this.slide.isActive || isSafari())) {\r\n this.isDecoding = true;\r\n // purposefully using finally instead of then,\r\n // as if srcset sizes changes dynamically - it may cause decode error\r\n /** @type {HTMLImageElement} */\r\n (this.element).decode().catch(() => {}).finally(() => {\r\n this.isDecoding = false;\r\n this.appendImage();\r\n });\r\n } else {\r\n this.appendImage();\r\n }\r\n } else if (this.slide && !this.element.parentNode) {\r\n this.slide.container.appendChild(this.element);\r\n }\r\n }\r\n\r\n /**\r\n * Activate the slide,\r\n * active slide is generally the current one,\r\n * meaning the user can see it.\r\n */\r\n activate() {\r\n if (this.instance.dispatch('contentActivate', { content: this }).defaultPrevented\r\n || !this.slide) {\r\n return;\r\n }\r\n\r\n if (this.isImageContent() && this.isDecoding && !isSafari()) {\r\n // add image to slide when it becomes active,\r\n // even if it's not finished decoding\r\n this.appendImage();\r\n } else if (this.isError()) {\r\n this.load(false, true); // try to reload\r\n }\r\n\r\n if (this.slide.holderElement) {\r\n this.slide.holderElement.setAttribute('aria-hidden', 'false');\r\n }\r\n }\r\n\r\n /**\r\n * Deactivate the content\r\n */\r\n deactivate() {\r\n this.instance.dispatch('contentDeactivate', { content: this });\r\n if (this.slide && this.slide.holderElement) {\r\n this.slide.holderElement.setAttribute('aria-hidden', 'true');\r\n }\r\n }\r\n\r\n\r\n /**\r\n * Remove the content from DOM\r\n */\r\n remove() {\r\n this.isAttached = false;\r\n\r\n if (this.instance.dispatch('contentRemove', { content: this }).defaultPrevented) {\r\n return;\r\n }\r\n\r\n if (this.element && this.element.parentNode) {\r\n this.element.remove();\r\n }\r\n\r\n if (this.placeholder && this.placeholder.element) {\r\n this.placeholder.element.remove();\r\n }\r\n }\r\n\r\n /**\r\n * Append the image content to slide container\r\n */\r\n appendImage() {\r\n if (!this.isAttached) {\r\n return;\r\n }\r\n\r\n if (this.instance.dispatch('contentAppendImage', { content: this }).defaultPrevented) {\r\n return;\r\n }\r\n\r\n // ensure that element exists and is not already appended\r\n if (this.slide && this.element && !this.element.parentNode) {\r\n this.slide.container.appendChild(this.element);\r\n }\r\n\r\n if (this.state === LOAD_STATE.LOADED || this.state === LOAD_STATE.ERROR) {\r\n this.removePlaceholder();\r\n }\r\n }\r\n}\r\n\r\nexport default Content;\r\n","import { getViewportSize, getPanAreaSize } from '../util/viewport-size.js';\r\nimport ZoomLevel from './zoom-level.js';\r\n\r\n/** @typedef {import('./content.js').default} Content */\r\n/** @typedef {import('./slide.js').default} Slide */\r\n/** @typedef {import('./slide.js').SlideData} SlideData */\r\n/** @typedef {import('../core/base.js').default} PhotoSwipeBase */\r\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\r\n\r\nconst MIN_SLIDES_TO_CACHE = 5;\r\n\r\n/**\r\n * Lazy-load an image\r\n * This function is used both by Lightbox and PhotoSwipe core,\r\n * thus it can be called before dialog is opened.\r\n *\r\n * @param {SlideData} itemData Data about the slide\r\n * @param {PhotoSwipeBase} instance PhotoSwipe or PhotoSwipeLightbox instance\r\n * @param {number} index\r\n * @returns {Content} Image that is being decoded or false.\r\n */\r\nexport function lazyLoadData(itemData, instance, index) {\r\n const content = instance.createContentFromData(itemData, index);\r\n /** @type {ZoomLevel | undefined} */\r\n let zoomLevel;\r\n\r\n const { options } = instance;\r\n\r\n // We need to know dimensions of the image to preload it,\r\n // as it might use srcset, and we need to define sizes\r\n if (options) {\r\n zoomLevel = new ZoomLevel(options, itemData, -1);\r\n\r\n let viewportSize;\r\n if (instance.pswp) {\r\n viewportSize = instance.pswp.viewportSize;\r\n } else {\r\n viewportSize = getViewportSize(options, instance);\r\n }\r\n\r\n const panAreaSize = getPanAreaSize(options, viewportSize, itemData, index);\r\n zoomLevel.update(content.width, content.height, panAreaSize);\r\n }\r\n\r\n content.lazyLoad();\r\n\r\n if (zoomLevel) {\r\n content.setDisplayedSize(\r\n Math.ceil(content.width * zoomLevel.initial),\r\n Math.ceil(content.height * zoomLevel.initial)\r\n );\r\n }\r\n\r\n return content;\r\n}\r\n\r\n\r\n/**\r\n * Lazy-loads specific slide.\r\n * This function is used both by Lightbox and PhotoSwipe core,\r\n * thus it can be called before dialog is opened.\r\n *\r\n * By default, it loads image based on viewport size and initial zoom level.\r\n *\r\n * @param {number} index Slide index\r\n * @param {PhotoSwipeBase} instance PhotoSwipe or PhotoSwipeLightbox eventable instance\r\n * @returns {Content | undefined}\r\n */\r\nexport function lazyLoadSlide(index, instance) {\r\n const itemData = instance.getItemData(index);\r\n\r\n if (instance.dispatch('lazyLoadSlide', { index, itemData }).defaultPrevented) {\r\n return;\r\n }\r\n\r\n return lazyLoadData(itemData, instance, index);\r\n}\r\n\r\nclass ContentLoader {\r\n /**\r\n * @param {PhotoSwipe} pswp\r\n */\r\n constructor(pswp) {\r\n this.pswp = pswp;\r\n // Total amount of cached images\r\n this.limit = Math.max(\r\n pswp.options.preload[0] + pswp.options.preload[1] + 1,\r\n MIN_SLIDES_TO_CACHE\r\n );\r\n /** @type {Content[]} */\r\n this._cachedItems = [];\r\n }\r\n\r\n /**\r\n * Lazy load nearby slides based on `preload` option.\r\n *\r\n * @param {number} [diff] Difference between slide indexes that was changed recently, or 0.\r\n */\r\n updateLazy(diff) {\r\n const { pswp } = this;\r\n\r\n if (pswp.dispatch('lazyLoad').defaultPrevented) {\r\n return;\r\n }\r\n\r\n const { preload } = pswp.options;\r\n const isForward = diff === undefined ? true : (diff >= 0);\r\n let i;\r\n\r\n // preload[1] - num items to preload in forward direction\r\n for (i = 0; i <= preload[1]; i++) {\r\n this.loadSlideByIndex(pswp.currIndex + (isForward ? i : (-i)));\r\n }\r\n\r\n // preload[0] - num items to preload in backward direction\r\n for (i = 1; i <= preload[0]; i++) {\r\n this.loadSlideByIndex(pswp.currIndex + (isForward ? (-i) : i));\r\n }\r\n }\r\n\r\n /**\r\n * @param {number} initialIndex\r\n */\r\n loadSlideByIndex(initialIndex) {\r\n const index = this.pswp.getLoopedIndex(initialIndex);\r\n // try to get cached content\r\n let content = this.getContentByIndex(index);\r\n if (!content) {\r\n // no cached content, so try to load from scratch:\r\n content = lazyLoadSlide(index, this.pswp);\r\n // if content can be loaded, add it to cache:\r\n if (content) {\r\n this.addToCache(content);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @param {Slide} slide\r\n * @returns {Content}\r\n */\r\n getContentBySlide(slide) {\r\n let content = this.getContentByIndex(slide.index);\r\n if (!content) {\r\n // create content if not found in cache\r\n content = this.pswp.createContentFromData(slide.data, slide.index);\r\n this.addToCache(content);\r\n }\r\n\r\n // assign slide to content\r\n content.setSlide(slide);\r\n\r\n return content;\r\n }\r\n\r\n /**\r\n * @param {Content} content\r\n */\r\n addToCache(content) {\r\n // move to the end of array\r\n this.removeByIndex(content.index);\r\n this._cachedItems.push(content);\r\n\r\n if (this._cachedItems.length > this.limit) {\r\n // Destroy the first content that's not attached\r\n const indexToRemove = this._cachedItems.findIndex((item) => {\r\n return !item.isAttached && !item.hasSlide;\r\n });\r\n if (indexToRemove !== -1) {\r\n const removedItem = this._cachedItems.splice(indexToRemove, 1)[0];\r\n removedItem.destroy();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Removes an image from cache, does not destroy() it, just removes.\r\n *\r\n * @param {number} index\r\n */\r\n removeByIndex(index) {\r\n const indexToRemove = this._cachedItems.findIndex(item => item.index === index);\r\n if (indexToRemove !== -1) {\r\n this._cachedItems.splice(indexToRemove, 1);\r\n }\r\n }\r\n\r\n /**\r\n * @param {number} index\r\n * @returns {Content | undefined}\r\n */\r\n getContentByIndex(index) {\r\n return this._cachedItems.find(content => content.index === index);\r\n }\r\n\r\n destroy() {\r\n this._cachedItems.forEach(content => content.destroy());\r\n this._cachedItems = [];\r\n }\r\n}\r\n\r\nexport default ContentLoader;\r\n","import Eventable from './eventable.js';\r\nimport { getElementsFromOption } from '../util/util.js';\r\nimport Content from '../slide/content.js';\r\nimport { lazyLoadData } from '../slide/loader.js';\r\n\r\n/** @typedef {import(\"../photoswipe.js\").default} PhotoSwipe */\r\n/** @typedef {import(\"../slide/slide.js\").SlideData} SlideData */\r\n\r\n/**\r\n * PhotoSwipe base class that can retrieve data about every slide.\r\n * Shared by PhotoSwipe Core and PhotoSwipe Lightbox\r\n */\r\nclass PhotoSwipeBase extends Eventable {\r\n /**\r\n * Get total number of slides\r\n *\r\n * @returns {number}\r\n */\r\n getNumItems() {\r\n let numItems = 0;\r\n const dataSource = this.options?.dataSource;\r\n\r\n if (dataSource && 'length' in dataSource) {\r\n // may be an array or just object with length property\r\n numItems = dataSource.length;\r\n } else if (dataSource && 'gallery' in dataSource) {\r\n // query DOM elements\r\n if (!dataSource.items) {\r\n dataSource.items = this._getGalleryDOMElements(dataSource.gallery);\r\n }\r\n\r\n if (dataSource.items) {\r\n numItems = dataSource.items.length;\r\n }\r\n }\r\n\r\n // legacy event, before filters were introduced\r\n const event = this.dispatch('numItems', {\r\n dataSource,\r\n numItems\r\n });\r\n return this.applyFilters('numItems', event.numItems, dataSource);\r\n }\r\n\r\n /**\r\n * @param {SlideData} slideData\r\n * @param {number} index\r\n * @returns {Content}\r\n */\r\n createContentFromData(slideData, index) {\r\n return new Content(slideData, this, index);\r\n }\r\n\r\n /**\r\n * Get item data by index.\r\n *\r\n * \"item data\" should contain normalized information that PhotoSwipe needs to generate a slide.\r\n * For example, it may contain properties like\r\n * `src`, `srcset`, `w`, `h`, which will be used to generate a slide with image.\r\n *\r\n * @param {number} index\r\n * @returns {SlideData}\r\n */\r\n getItemData(index) {\r\n const dataSource = this.options?.dataSource;\r\n /** @type {SlideData | HTMLElement} */\r\n let dataSourceItem = {};\r\n if (Array.isArray(dataSource)) {\r\n // Datasource is an array of elements\r\n dataSourceItem = dataSource[index];\r\n } else if (dataSource && 'gallery' in dataSource) {\r\n // dataSource has gallery property,\r\n // thus it was created by Lightbox, based on\r\n // gallery and children options\r\n\r\n // query DOM elements\r\n if (!dataSource.items) {\r\n dataSource.items = this._getGalleryDOMElements(dataSource.gallery);\r\n }\r\n\r\n dataSourceItem = dataSource.items[index];\r\n }\r\n\r\n let itemData = dataSourceItem;\r\n\r\n if (itemData instanceof Element) {\r\n itemData = this._domElementToItemData(itemData);\r\n }\r\n\r\n // Dispatching the itemData event,\r\n // it's a legacy verion before filters were introduced\r\n const event = this.dispatch('itemData', {\r\n itemData: itemData || {},\r\n index\r\n });\r\n\r\n return this.applyFilters('itemData', event.itemData, index);\r\n }\r\n\r\n /**\r\n * Get array of gallery DOM elements,\r\n * based on childSelector and gallery element.\r\n *\r\n * @param {HTMLElement} galleryElement\r\n * @returns {HTMLElement[]}\r\n */\r\n _getGalleryDOMElements(galleryElement) {\r\n if (this.options?.children || this.options?.childSelector) {\r\n return getElementsFromOption(\r\n this.options.children,\r\n this.options.childSelector,\r\n galleryElement\r\n ) || [];\r\n }\r\n\r\n return [galleryElement];\r\n }\r\n\r\n /**\r\n * Converts DOM element to item data object.\r\n *\r\n * @param {HTMLElement} element DOM element\r\n * @returns {SlideData}\r\n */\r\n _domElementToItemData(element) {\r\n /** @type {SlideData} */\r\n const itemData = {\r\n element\r\n };\r\n\r\n const linkEl = /** @type {HTMLAnchorElement} */ (\r\n element.tagName === 'A'\r\n ? element\r\n : element.querySelector('a')\r\n );\r\n\r\n if (linkEl) {\r\n // src comes from data-pswp-src attribute,\r\n // if it's empty link href is used\r\n itemData.src = linkEl.dataset.pswpSrc || linkEl.href;\r\n\r\n if (linkEl.dataset.pswpSrcset) {\r\n itemData.srcset = linkEl.dataset.pswpSrcset;\r\n }\r\n\r\n itemData.width = linkEl.dataset.pswpWidth ? parseInt(linkEl.dataset.pswpWidth, 10) : 0;\r\n itemData.height = linkEl.dataset.pswpHeight ? parseInt(linkEl.dataset.pswpHeight, 10) : 0;\r\n\r\n // support legacy w & h properties\r\n itemData.w = itemData.width;\r\n itemData.h = itemData.height;\r\n\r\n if (linkEl.dataset.pswpType) {\r\n itemData.type = linkEl.dataset.pswpType;\r\n }\r\n\r\n const thumbnailEl = element.querySelector('img');\r\n\r\n if (thumbnailEl) {\r\n // msrc is URL to placeholder image that's displayed before large image is loaded\r\n // by default it's displayed only for the first slide\r\n itemData.msrc = thumbnailEl.currentSrc || thumbnailEl.src;\r\n itemData.alt = thumbnailEl.getAttribute('alt') ?? '';\r\n }\r\n\r\n if (linkEl.dataset.pswpCropped || linkEl.dataset.cropped) {\r\n itemData.thumbCropped = true;\r\n }\r\n }\r\n\r\n return this.applyFilters('domItemData', itemData, element, linkEl);\r\n }\r\n\r\n /**\r\n * Lazy-load by slide data\r\n *\r\n * @param {SlideData} itemData Data about the slide\r\n * @param {number} index\r\n * @returns {Content} Image that is being decoded or false.\r\n */\r\n lazyLoadData(itemData, index) {\r\n return lazyLoadData(itemData, this, index);\r\n }\r\n}\r\n\r\nexport default PhotoSwipeBase;\r\n","import {\r\n setTransform,\r\n equalizePoints,\r\n decodeImage,\r\n toTransformString\r\n} from './util/util.js';\r\n\r\n/** @typedef {import('./photoswipe.js').default} PhotoSwipe */\r\n/** @typedef {import('./slide/get-thumb-bounds.js').Bounds} Bounds */\r\n/** @typedef {import('./util/animations.js').AnimationProps} AnimationProps */\r\n\r\n// some browsers do not paint\r\n// elements which opacity is set to 0,\r\n// since we need to pre-render elements for the animation -\r\n// we set it to the minimum amount\r\nconst MIN_OPACITY = 0.003;\r\n\r\n/**\r\n * Manages opening and closing transitions of the PhotoSwipe.\r\n *\r\n * It can perform zoom, fade or no transition.\r\n */\r\nclass Opener {\r\n /**\r\n * @param {PhotoSwipe} pswp\r\n */\r\n constructor(pswp) {\r\n this.pswp = pswp;\r\n this.isClosed = true;\r\n this.isOpen = false;\r\n this.isClosing = false;\r\n this.isOpening = false;\r\n /**\r\n * @private\r\n * @type {number | false | undefined}\r\n */\r\n this._duration = undefined;\r\n /** @private */\r\n this._useAnimation = false;\r\n /** @private */\r\n this._croppedZoom = false;\r\n /** @private */\r\n this._animateRootOpacity = false;\r\n /** @private */\r\n this._animateBgOpacity = false;\r\n /**\r\n * @private\r\n * @type { HTMLDivElement | HTMLImageElement | null | undefined }\r\n */\r\n this._placeholder = undefined;\r\n /**\r\n * @private\r\n * @type { HTMLDivElement | undefined }\r\n */\r\n this._opacityElement = undefined;\r\n /**\r\n * @private\r\n * @type { HTMLDivElement | undefined }\r\n */\r\n this._cropContainer1 = undefined;\r\n /**\r\n * @private\r\n * @type { HTMLElement | null | undefined }\r\n */\r\n this._cropContainer2 = undefined;\r\n\r\n /**\r\n * @private\r\n * @type {Bounds | undefined}\r\n */\r\n this._thumbBounds = undefined;\r\n\r\n\r\n this._prepareOpen = this._prepareOpen.bind(this);\r\n\r\n // Override initial zoom and pan position\r\n pswp.on('firstZoomPan', this._prepareOpen);\r\n }\r\n\r\n open() {\r\n this._prepareOpen();\r\n this._start();\r\n }\r\n\r\n close() {\r\n if (this.isClosed || this.isClosing || this.isOpening) {\r\n // if we close during opening animation\r\n // for now do nothing,\r\n // browsers aren't good at changing the direction of the CSS transition\r\n return;\r\n }\r\n\r\n const slide = this.pswp.currSlide;\r\n\r\n this.isOpen = false;\r\n this.isOpening = false;\r\n this.isClosing = true;\r\n this._duration = this.pswp.options.hideAnimationDuration;\r\n\r\n if (slide && slide.currZoomLevel * slide.width >= this.pswp.options.maxWidthToAnimate) {\r\n this._duration = 0;\r\n }\r\n\r\n this._applyStartProps();\r\n setTimeout(() => {\r\n this._start();\r\n }, this._croppedZoom ? 30 : 0);\r\n }\r\n\r\n /** @private */\r\n _prepareOpen() {\r\n this.pswp.off('firstZoomPan', this._prepareOpen);\r\n if (!this.isOpening) {\r\n const slide = this.pswp.currSlide;\r\n this.isOpening = true;\r\n this.isClosing = false;\r\n this._duration = this.pswp.options.showAnimationDuration;\r\n if (slide && slide.zoomLevels.initial * slide.width >= this.pswp.options.maxWidthToAnimate) {\r\n this._duration = 0;\r\n }\r\n this._applyStartProps();\r\n }\r\n }\r\n\r\n /** @private */\r\n _applyStartProps() {\r\n const { pswp } = this;\r\n const slide = this.pswp.currSlide;\r\n const { options } = pswp;\r\n\r\n if (options.showHideAnimationType === 'fade') {\r\n options.showHideOpacity = true;\r\n this._thumbBounds = undefined;\r\n } else if (options.showHideAnimationType === 'none') {\r\n options.showHideOpacity = false;\r\n this._duration = 0;\r\n this._thumbBounds = undefined;\r\n } else if (this.isOpening && pswp._initialThumbBounds) {\r\n // Use initial bounds if defined\r\n this._thumbBounds = pswp._initialThumbBounds;\r\n } else {\r\n this._thumbBounds = this.pswp.getThumbBounds();\r\n }\r\n\r\n this._placeholder = slide?.getPlaceholderElement();\r\n\r\n pswp.animations.stopAll();\r\n\r\n // Discard animations when duration is less than 50ms\r\n this._useAnimation = Boolean(this._duration && this._duration > 50);\r\n this._animateZoom = Boolean(this._thumbBounds)\r\n && slide?.content.usePlaceholder()\r\n && (!this.isClosing || !pswp.mainScroll.isShifted());\r\n if (!this._animateZoom) {\r\n this._animateRootOpacity = true;\r\n\r\n if (this.isOpening && slide) {\r\n slide.zoomAndPanToInitial();\r\n slide.applyCurrentZoomPan();\r\n }\r\n } else {\r\n this._animateRootOpacity = options.showHideOpacity ?? false;\r\n }\r\n this._animateBgOpacity = !this._animateRootOpacity && this.pswp.options.bgOpacity > MIN_OPACITY;\r\n this._opacityElement = this._animateRootOpacity ? pswp.element : pswp.bg;\r\n\r\n if (!this._useAnimation) {\r\n this._duration = 0;\r\n this._animateZoom = false;\r\n this._animateBgOpacity = false;\r\n this._animateRootOpacity = true;\r\n if (this.isOpening) {\r\n if (pswp.element) {\r\n pswp.element.style.opacity = String(MIN_OPACITY);\r\n }\r\n pswp.applyBgOpacity(1);\r\n }\r\n return;\r\n }\r\n\r\n if (this._animateZoom && this._thumbBounds && this._thumbBounds.innerRect) {\r\n // Properties are used when animation from cropped thumbnail\r\n this._croppedZoom = true;\r\n this._cropContainer1 = this.pswp.container;\r\n this._cropContainer2 = this.pswp.currSlide?.holderElement;\r\n\r\n if (pswp.container) {\r\n pswp.container.style.overflow = 'hidden';\r\n pswp.container.style.width = pswp.viewportSize.x + 'px';\r\n }\r\n } else {\r\n this._croppedZoom = false;\r\n }\r\n\r\n if (this.isOpening) {\r\n // Apply styles before opening transition\r\n if (this._animateRootOpacity) {\r\n if (pswp.element) {\r\n pswp.element.style.opacity = String(MIN_OPACITY);\r\n }\r\n pswp.applyBgOpacity(1);\r\n } else {\r\n if (this._animateBgOpacity && pswp.bg) {\r\n pswp.bg.style.opacity = String(MIN_OPACITY);\r\n }\r\n if (pswp.element) {\r\n pswp.element.style.opacity = '1';\r\n }\r\n }\r\n\r\n if (this._animateZoom) {\r\n this._setClosedStateZoomPan();\r\n if (this._placeholder) {\r\n // tell browser that we plan to animate the placeholder\r\n this._placeholder.style.willChange = 'transform';\r\n\r\n // hide placeholder to allow hiding of\r\n // elements that overlap it (such as icons over the thumbnail)\r\n this._placeholder.style.opacity = String(MIN_OPACITY);\r\n }\r\n }\r\n } else if (this.isClosing) {\r\n // hide nearby slides to make sure that\r\n // they are not painted during the transition\r\n if (pswp.mainScroll.itemHolders[0]) {\r\n pswp.mainScroll.itemHolders[0].el.style.display = 'none';\r\n }\r\n if (pswp.mainScroll.itemHolders[2]) {\r\n pswp.mainScroll.itemHolders[2].el.style.display = 'none';\r\n }\r\n\r\n if (this._croppedZoom) {\r\n if (pswp.mainScroll.x !== 0) {\r\n // shift the main scroller to zero position\r\n pswp.mainScroll.resetPosition();\r\n pswp.mainScroll.resize();\r\n }\r\n }\r\n }\r\n }\r\n\r\n /** @private */\r\n _start() {\r\n if (this.isOpening\r\n && this._useAnimation\r\n && this._placeholder\r\n && this._placeholder.tagName === 'IMG') {\r\n // To ensure smooth animation\r\n // we wait till the current slide image placeholder is decoded,\r\n // but no longer than 250ms,\r\n // and no shorter than 50ms\r\n // (just using requestanimationframe is not enough in Firefox,\r\n // for some reason)\r\n new Promise((resolve) => {\r\n let decoded = false;\r\n let isDelaying = true;\r\n decodeImage(/** @type {HTMLImageElement} */ (this._placeholder)).finally(() => {\r\n decoded = true;\r\n if (!isDelaying) {\r\n resolve(true);\r\n }\r\n });\r\n setTimeout(() => {\r\n isDelaying = false;\r\n if (decoded) {\r\n resolve(true);\r\n }\r\n }, 50);\r\n setTimeout(resolve, 250);\r\n }).finally(() => this._initiate());\r\n } else {\r\n this._initiate();\r\n }\r\n }\r\n\r\n /** @private */\r\n _initiate() {\r\n this.pswp.element?.style.setProperty('--pswp-transition-duration', this._duration + 'ms');\r\n\r\n this.pswp.dispatch(\r\n this.isOpening ? 'openingAnimationStart' : 'closingAnimationStart'\r\n );\r\n\r\n // legacy event\r\n this.pswp.dispatch(\r\n /** @type {'initialZoomIn' | 'initialZoomOut'} */\r\n ('initialZoom' + (this.isOpening ? 'In' : 'Out'))\r\n );\r\n\r\n this.pswp.element?.classList.toggle('pswp--ui-visible', this.isOpening);\r\n\r\n if (this.isOpening) {\r\n if (this._placeholder) {\r\n // unhide the placeholder\r\n this._placeholder.style.opacity = '1';\r\n }\r\n this._animateToOpenState();\r\n } else if (this.isClosing) {\r\n this._animateToClosedState();\r\n }\r\n\r\n if (!this._useAnimation) {\r\n this._onAnimationComplete();\r\n }\r\n }\r\n\r\n /** @private */\r\n _onAnimationComplete() {\r\n const { pswp } = this;\r\n this.isOpen = this.isOpening;\r\n this.isClosed = this.isClosing;\r\n this.isOpening = false;\r\n this.isClosing = false;\r\n\r\n pswp.dispatch(\r\n this.isOpen ? 'openingAnimationEnd' : 'closingAnimationEnd'\r\n );\r\n\r\n // legacy event\r\n pswp.dispatch(\r\n /** @type {'initialZoomInEnd' | 'initialZoomOutEnd'} */\r\n ('initialZoom' + (this.isOpen ? 'InEnd' : 'OutEnd'))\r\n );\r\n\r\n if (this.isClosed) {\r\n pswp.destroy();\r\n } else if (this.isOpen) {\r\n if (this._animateZoom && pswp.container) {\r\n pswp.container.style.overflow = 'visible';\r\n pswp.container.style.width = '100%';\r\n }\r\n pswp.currSlide?.applyCurrentZoomPan();\r\n }\r\n }\r\n\r\n /** @private */\r\n _animateToOpenState() {\r\n const { pswp } = this;\r\n if (this._animateZoom) {\r\n if (this._croppedZoom && this._cropContainer1 && this._cropContainer2) {\r\n this._animateTo(this._cropContainer1, 'transform', 'translate3d(0,0,0)');\r\n this._animateTo(this._cropContainer2, 'transform', 'none');\r\n }\r\n\r\n if (pswp.currSlide) {\r\n pswp.currSlide.zoomAndPanToInitial();\r\n this._animateTo(\r\n pswp.currSlide.container,\r\n 'transform',\r\n pswp.currSlide.getCurrentTransform()\r\n );\r\n }\r\n }\r\n\r\n if (this._animateBgOpacity && pswp.bg) {\r\n this._animateTo(pswp.bg, 'opacity', String(pswp.options.bgOpacity));\r\n }\r\n\r\n if (this._animateRootOpacity && pswp.element) {\r\n this._animateTo(pswp.element, 'opacity', '1');\r\n }\r\n }\r\n\r\n /** @private */\r\n _animateToClosedState() {\r\n const { pswp } = this;\r\n\r\n if (this._animateZoom) {\r\n this._setClosedStateZoomPan(true);\r\n }\r\n\r\n // do not animate opacity if it's already at 0\r\n if (this._animateBgOpacity && pswp.bgOpacity > 0.01 && pswp.bg) {\r\n this._animateTo(pswp.bg, 'opacity', '0');\r\n }\r\n\r\n if (this._animateRootOpacity && pswp.element) {\r\n this._animateTo(pswp.element, 'opacity', '0');\r\n }\r\n }\r\n\r\n /**\r\n * @private\r\n * @param {boolean} [animate]\r\n */\r\n _setClosedStateZoomPan(animate) {\r\n if (!this._thumbBounds) return;\r\n\r\n const { pswp } = this;\r\n const { innerRect } = this._thumbBounds;\r\n const { currSlide, viewportSize } = pswp;\r\n\r\n if (this._croppedZoom && innerRect && this._cropContainer1 && this._cropContainer2) {\r\n const containerOnePanX = -viewportSize.x + (this._thumbBounds.x - innerRect.x) + innerRect.w;\r\n const containerOnePanY = -viewportSize.y + (this._thumbBounds.y - innerRect.y) + innerRect.h;\r\n const containerTwoPanX = viewportSize.x - innerRect.w;\r\n const containerTwoPanY = viewportSize.y - innerRect.h;\r\n\r\n\r\n if (animate) {\r\n this._animateTo(\r\n this._cropContainer1,\r\n 'transform',\r\n toTransformString(containerOnePanX, containerOnePanY)\r\n );\r\n\r\n this._animateTo(\r\n this._cropContainer2,\r\n 'transform',\r\n toTransformString(containerTwoPanX, containerTwoPanY)\r\n );\r\n } else {\r\n setTransform(this._cropContainer1, containerOnePanX, containerOnePanY);\r\n setTransform(this._cropContainer2, containerTwoPanX, containerTwoPanY);\r\n }\r\n }\r\n\r\n if (currSlide) {\r\n equalizePoints(currSlide.pan, innerRect || this._thumbBounds);\r\n currSlide.currZoomLevel = this._thumbBounds.w / currSlide.width;\r\n if (animate) {\r\n this._animateTo(currSlide.container, 'transform', currSlide.getCurrentTransform());\r\n } else {\r\n currSlide.applyCurrentZoomPan();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @private\r\n * @param {HTMLElement} target\r\n * @param {'transform' | 'opacity'} prop\r\n * @param {string} propValue\r\n */\r\n _animateTo(target, prop, propValue) {\r\n if (!this._duration) {\r\n target.style[prop] = propValue;\r\n return;\r\n }\r\n\r\n const { animations } = this.pswp;\r\n /** @type {AnimationProps} */\r\n const animProps = {\r\n duration: this._duration,\r\n easing: this.pswp.options.easing,\r\n onComplete: () => {\r\n if (!animations.activeAnimations.length) {\r\n this._onAnimationComplete();\r\n }\r\n },\r\n target,\r\n };\r\n animProps[prop] = propValue;\r\n animations.startTransition(animProps);\r\n }\r\n}\r\n\r\nexport default Opener;\r\n","import {\r\n createElement,\r\n equalizePoints,\r\n pointsEqual,\r\n clamp,\r\n} from './util/util.js';\r\n\r\nimport DOMEvents from './util/dom-events.js';\r\nimport Slide from './slide/slide.js';\r\nimport Gestures from './gestures/gestures.js';\r\nimport MainScroll from './main-scroll.js';\r\n\r\nimport Keyboard from './keyboard.js';\r\nimport Animations from './util/animations.js';\r\nimport ScrollWheel from './scroll-wheel.js';\r\nimport UI from './ui/ui.js';\r\nimport { getViewportSize } from './util/viewport-size.js';\r\nimport { getThumbBounds } from './slide/get-thumb-bounds.js';\r\nimport PhotoSwipeBase from './core/base.js';\r\nimport Opener from './opener.js';\r\nimport ContentLoader from './slide/loader.js';\r\n\r\n/**\r\n * @template T\r\n * @typedef {import('./types.js').Type} Type\r\n */\r\n\r\n/** @typedef {import('./slide/slide.js').SlideData} SlideData */\r\n/** @typedef {import('./slide/zoom-level.js').ZoomLevelOption} ZoomLevelOption */\r\n/** @typedef {import('./ui/ui-element.js').UIElementData} UIElementData */\r\n/** @typedef {import('./main-scroll.js').ItemHolder} ItemHolder */\r\n/** @typedef {import('./core/eventable.js').PhotoSwipeEventsMap} PhotoSwipeEventsMap */\r\n/** @typedef {import('./core/eventable.js').PhotoSwipeFiltersMap} PhotoSwipeFiltersMap */\r\n/** @typedef {import('./slide/get-thumb-bounds').Bounds} Bounds */\r\n/**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @typedef {import('./core/eventable.js').EventCallback} EventCallback\r\n */\r\n/**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @typedef {import('./core/eventable.js').AugmentedEvent} AugmentedEvent\r\n */\r\n\r\n/** @typedef {{ x: number; y: number; id?: string | number }} Point */\r\n/** @typedef {{ top: number; bottom: number; left: number; right: number }} Padding */\r\n/** @typedef {SlideData[]} DataSourceArray */\r\n/** @typedef {{ gallery: HTMLElement; items?: HTMLElement[] }} DataSourceObject */\r\n/** @typedef {DataSourceArray | DataSourceObject} DataSource */\r\n/** @typedef {(point: Point, originalEvent: PointerEvent) => void} ActionFn */\r\n/** @typedef {'close' | 'next' | 'zoom' | 'zoom-or-close' | 'toggle-controls'} ActionType */\r\n/** @typedef {Type | { default: Type }} PhotoSwipeModule */\r\n/** @typedef {PhotoSwipeModule | Promise | (() => Promise)} PhotoSwipeModuleOption */\r\n\r\n/**\r\n * @typedef {string | NodeListOf | HTMLElement[] | HTMLElement} ElementProvider\r\n */\r\n\r\n/** @typedef {Partial} PhotoSwipeOptions https://photoswipe.com/options/ */\r\n/**\r\n * @typedef {Object} PreparedPhotoSwipeOptions\r\n *\r\n * @prop {DataSource} [dataSource]\r\n * Pass an array of any items via dataSource option. Its length will determine amount of slides\r\n * (which may be modified further from numItems event).\r\n *\r\n * Each item should contain data that you need to generate slide\r\n * (for image slide it would be src (image URL), width (image width), height, srcset, alt).\r\n *\r\n * If these properties are not present in your initial array, you may \"pre-parse\" each item from itemData filter.\r\n *\r\n * @prop {number} bgOpacity\r\n * Background backdrop opacity, always define it via this option and not via CSS rgba color.\r\n *\r\n * @prop {number} spacing\r\n * Spacing between slides. Defined as ratio relative to the viewport width (0.1 = 10% of viewport).\r\n *\r\n * @prop {boolean} allowPanToNext\r\n * Allow swipe navigation to the next slide when the current slide is zoomed. Does not apply to mouse events.\r\n *\r\n * @prop {boolean} loop\r\n * If set to true you'll be able to swipe from the last to the first image.\r\n * Option is always false when there are less than 3 slides.\r\n *\r\n * @prop {boolean} [wheelToZoom]\r\n * By default PhotoSwipe zooms image with ctrl-wheel, if you enable this option - image will zoom just via wheel.\r\n *\r\n * @prop {boolean} pinchToClose\r\n * Pinch touch gesture to close the gallery.\r\n *\r\n * @prop {boolean} closeOnVerticalDrag\r\n * Vertical drag gesture to close the PhotoSwipe.\r\n *\r\n * @prop {Padding} [padding]\r\n * Slide area padding (in pixels).\r\n *\r\n * @prop {(viewportSize: Point, itemData: SlideData, index: number) => Padding} [paddingFn]\r\n * The option is checked frequently, so make sure it's performant. Overrides padding option if defined. For example:\r\n *\r\n * @prop {number | false} hideAnimationDuration\r\n * Transition duration in milliseconds, can be 0.\r\n *\r\n * @prop {number | false} showAnimationDuration\r\n * Transition duration in milliseconds, can be 0.\r\n *\r\n * @prop {number | false} zoomAnimationDuration\r\n * Transition duration in milliseconds, can be 0.\r\n *\r\n * @prop {string} easing\r\n * String, 'cubic-bezier(.4,0,.22,1)'. CSS easing function for open/close/zoom transitions.\r\n *\r\n * @prop {boolean} escKey\r\n * Esc key to close.\r\n *\r\n * @prop {boolean} arrowKeys\r\n * Left/right arrow keys for navigation.\r\n *\r\n * @prop {boolean} trapFocus\r\n * Trap focus within PhotoSwipe element while it's open.\r\n *\r\n * @prop {boolean} returnFocus\r\n * Restore focus the last active element after PhotoSwipe is closed.\r\n *\r\n * @prop {boolean} clickToCloseNonZoomable\r\n * If image is not zoomable (for example, smaller than viewport) it can be closed by clicking on it.\r\n *\r\n * @prop {ActionType | ActionFn | false} imageClickAction\r\n * Refer to click and tap actions page.\r\n *\r\n * @prop {ActionType | ActionFn | false} bgClickAction\r\n * Refer to click and tap actions page.\r\n *\r\n * @prop {ActionType | ActionFn | false} tapAction\r\n * Refer to click and tap actions page.\r\n *\r\n * @prop {ActionType | ActionFn | false} doubleTapAction\r\n * Refer to click and tap actions page.\r\n *\r\n * @prop {number} preloaderDelay\r\n * Delay before the loading indicator will be displayed,\r\n * if image is loaded during it - the indicator will not be displayed at all. Can be zero.\r\n *\r\n * @prop {string} indexIndicatorSep\r\n * Used for slide count indicator (\"1 of 10 \").\r\n *\r\n * @prop {(options: PhotoSwipeOptions, pswp: PhotoSwipeBase) => Point} [getViewportSizeFn]\r\n * A function that should return slide viewport width and height, in format {x: 100, y: 100}.\r\n *\r\n * @prop {string} errorMsg\r\n * Message to display when the image wasn't able to load. If you need to display HTML - use contentErrorElement filter.\r\n *\r\n * @prop {[number, number]} preload\r\n * Lazy loading of nearby slides based on direction of movement. Should be an array with two integers,\r\n * first one - number of items to preload before the current image, second one - after the current image.\r\n * Two nearby images are always loaded.\r\n *\r\n * @prop {string} [mainClass]\r\n * Class that will be added to the root element of PhotoSwipe, may contain multiple separated by space.\r\n * Example on Styling page.\r\n *\r\n * @prop {HTMLElement} [appendToEl]\r\n * Element to which PhotoSwipe dialog will be appended when it opens.\r\n *\r\n * @prop {number} maxWidthToAnimate\r\n * Maximum width of image to animate, if initial rendered image width\r\n * is larger than this value - the opening/closing transition will be automatically disabled.\r\n *\r\n * @prop {string} [closeTitle]\r\n * Translating\r\n *\r\n * @prop {string} [zoomTitle]\r\n * Translating\r\n *\r\n * @prop {string} [arrowPrevTitle]\r\n * Translating\r\n *\r\n * @prop {string} [arrowNextTitle]\r\n * Translating\r\n *\r\n * @prop {'zoom' | 'fade' | 'none'} [showHideAnimationType]\r\n * To adjust opening or closing transition type use lightbox option `showHideAnimationType` (`String`).\r\n * It supports three values - `zoom` (default), `fade` (default if there is no thumbnail) and `none`.\r\n *\r\n * Animations are automatically disabled if user `(prefers-reduced-motion: reduce)`.\r\n *\r\n * @prop {number} index\r\n * Defines start slide index.\r\n *\r\n * @prop {(e: MouseEvent) => number} [getClickedIndexFn]\r\n *\r\n * @prop {boolean} [arrowPrev]\r\n * @prop {boolean} [arrowNext]\r\n * @prop {boolean} [zoom]\r\n * @prop {boolean} [close]\r\n * @prop {boolean} [counter]\r\n *\r\n * @prop {string} [arrowPrevSVG]\r\n * @prop {string} [arrowNextSVG]\r\n * @prop {string} [zoomSVG]\r\n * @prop {string} [closeSVG]\r\n * @prop {string} [counterSVG]\r\n *\r\n * @prop {string} [arrowPrevTitle]\r\n * @prop {string} [arrowNextTitle]\r\n * @prop {string} [zoomTitle]\r\n * @prop {string} [closeTitle]\r\n * @prop {string} [counterTitle]\r\n *\r\n * @prop {ZoomLevelOption} [initialZoomLevel]\r\n * @prop {ZoomLevelOption} [secondaryZoomLevel]\r\n * @prop {ZoomLevelOption} [maxZoomLevel]\r\n *\r\n * @prop {boolean} [mouseMovePan]\r\n * @prop {Point | null} [initialPointerPos]\r\n * @prop {boolean} [showHideOpacity]\r\n *\r\n * @prop {PhotoSwipeModuleOption} [pswpModule]\r\n * @prop {() => Promise} [openPromise]\r\n * @prop {boolean} [preloadFirstSlide]\r\n * @prop {ElementProvider} [gallery]\r\n * @prop {string} [gallerySelector]\r\n * @prop {ElementProvider} [children]\r\n * @prop {string} [childSelector]\r\n * @prop {string | false} [thumbSelector]\r\n */\r\n\r\n/** @type {PreparedPhotoSwipeOptions} */\r\nconst defaultOptions = {\r\n allowPanToNext: true,\r\n spacing: 0.1,\r\n loop: true,\r\n pinchToClose: true,\r\n closeOnVerticalDrag: true,\r\n hideAnimationDuration: 333,\r\n showAnimationDuration: 333,\r\n zoomAnimationDuration: 333,\r\n escKey: true,\r\n arrowKeys: true,\r\n trapFocus: true,\r\n returnFocus: true,\r\n maxWidthToAnimate: 4000,\r\n clickToCloseNonZoomable: true,\r\n imageClickAction: 'zoom-or-close',\r\n bgClickAction: 'close',\r\n tapAction: 'toggle-controls',\r\n doubleTapAction: 'zoom',\r\n indexIndicatorSep: ' / ',\r\n preloaderDelay: 2000,\r\n bgOpacity: 0.8,\r\n\r\n index: 0,\r\n errorMsg: 'The image cannot be loaded',\r\n preload: [1, 2],\r\n easing: 'cubic-bezier(.4,0,.22,1)'\r\n};\r\n\r\n/**\r\n * PhotoSwipe Core\r\n */\r\nclass PhotoSwipe extends PhotoSwipeBase {\r\n /**\r\n * @param {PhotoSwipeOptions} [options]\r\n */\r\n constructor(options) {\r\n super();\r\n\r\n this.options = this._prepareOptions(options || {});\r\n\r\n /**\r\n * offset of viewport relative to document\r\n *\r\n * @type {Point}\r\n */\r\n this.offset = { x: 0, y: 0 };\r\n\r\n /**\r\n * @type {Point}\r\n * @private\r\n */\r\n this._prevViewportSize = { x: 0, y: 0 };\r\n\r\n /**\r\n * Size of scrollable PhotoSwipe viewport\r\n *\r\n * @type {Point}\r\n */\r\n this.viewportSize = { x: 0, y: 0 };\r\n\r\n /**\r\n * background (backdrop) opacity\r\n */\r\n this.bgOpacity = 1;\r\n this.currIndex = 0;\r\n this.potentialIndex = 0;\r\n this.isOpen = false;\r\n this.isDestroying = false;\r\n this.hasMouse = false;\r\n\r\n /**\r\n * @private\r\n * @type {SlideData}\r\n */\r\n this._initialItemData = {};\r\n /** @type {Bounds | undefined} */\r\n this._initialThumbBounds = undefined;\r\n\r\n /** @type {HTMLDivElement | undefined} */\r\n this.topBar = undefined;\r\n /** @type {HTMLDivElement | undefined} */\r\n this.element = undefined;\r\n /** @type {HTMLDivElement | undefined} */\r\n this.template = undefined;\r\n /** @type {HTMLDivElement | undefined} */\r\n this.container = undefined;\r\n /** @type {HTMLElement | undefined} */\r\n this.scrollWrap = undefined;\r\n /** @type {Slide | undefined} */\r\n this.currSlide = undefined;\r\n\r\n this.events = new DOMEvents();\r\n this.animations = new Animations();\r\n this.mainScroll = new MainScroll(this);\r\n this.gestures = new Gestures(this);\r\n this.opener = new Opener(this);\r\n this.keyboard = new Keyboard(this);\r\n this.contentLoader = new ContentLoader(this);\r\n }\r\n\r\n /** @returns {boolean} */\r\n init() {\r\n if (this.isOpen || this.isDestroying) {\r\n return false;\r\n }\r\n\r\n this.isOpen = true;\r\n this.dispatch('init'); // legacy\r\n this.dispatch('beforeOpen');\r\n\r\n this._createMainStructure();\r\n\r\n // add classes to the root element of PhotoSwipe\r\n let rootClasses = 'pswp--open';\r\n if (this.gestures.supportsTouch) {\r\n rootClasses += ' pswp--touch';\r\n }\r\n if (this.options.mainClass) {\r\n rootClasses += ' ' + this.options.mainClass;\r\n }\r\n if (this.element) {\r\n this.element.className += ' ' + rootClasses;\r\n }\r\n\r\n this.currIndex = this.options.index || 0;\r\n this.potentialIndex = this.currIndex;\r\n this.dispatch('firstUpdate'); // starting index can be modified here\r\n\r\n // initialize scroll wheel handler to block the scroll\r\n this.scrollWheel = new ScrollWheel(this);\r\n\r\n // sanitize index\r\n if (Number.isNaN(this.currIndex)\r\n || this.currIndex < 0\r\n || this.currIndex >= this.getNumItems()) {\r\n this.currIndex = 0;\r\n }\r\n\r\n if (!this.gestures.supportsTouch) {\r\n // enable mouse features if no touch support detected\r\n this.mouseDetected();\r\n }\r\n\r\n // causes forced synchronous layout\r\n this.updateSize();\r\n\r\n this.offset.y = window.pageYOffset;\r\n\r\n this._initialItemData = this.getItemData(this.currIndex);\r\n this.dispatch('gettingData', {\r\n index: this.currIndex,\r\n data: this._initialItemData,\r\n slide: undefined\r\n });\r\n\r\n // *Layout* - calculate size and position of elements here\r\n this._initialThumbBounds = this.getThumbBounds();\r\n this.dispatch('initialLayout');\r\n\r\n this.on('openingAnimationEnd', () => {\r\n const { itemHolders } = this.mainScroll;\r\n\r\n // Add content to the previous and next slide\r\n if (itemHolders[0]) {\r\n itemHolders[0].el.style.display = 'block';\r\n this.setContent(itemHolders[0], this.currIndex - 1);\r\n }\r\n if (itemHolders[2]) {\r\n itemHolders[2].el.style.display = 'block';\r\n this.setContent(itemHolders[2], this.currIndex + 1);\r\n }\r\n\r\n this.appendHeavy();\r\n\r\n this.contentLoader.updateLazy();\r\n\r\n this.events.add(window, 'resize', this._handlePageResize.bind(this));\r\n this.events.add(window, 'scroll', this._updatePageScrollOffset.bind(this));\r\n this.dispatch('bindEvents');\r\n });\r\n\r\n // set content for center slide (first time)\r\n if (this.mainScroll.itemHolders[1]) {\r\n this.setContent(this.mainScroll.itemHolders[1], this.currIndex);\r\n }\r\n this.dispatch('change');\r\n\r\n this.opener.open();\r\n\r\n this.dispatch('afterInit');\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Get looped slide index\r\n * (for example, -1 will return the last slide)\r\n *\r\n * @param {number} index\r\n * @returns {number}\r\n */\r\n getLoopedIndex(index) {\r\n const numSlides = this.getNumItems();\r\n\r\n if (this.options.loop) {\r\n if (index > numSlides - 1) {\r\n index -= numSlides;\r\n }\r\n\r\n if (index < 0) {\r\n index += numSlides;\r\n }\r\n }\r\n\r\n return clamp(index, 0, numSlides - 1);\r\n }\r\n\r\n appendHeavy() {\r\n this.mainScroll.itemHolders.forEach((itemHolder) => {\r\n itemHolder.slide?.appendHeavy();\r\n });\r\n }\r\n\r\n /**\r\n * Change the slide\r\n * @param {number} index New index\r\n */\r\n goTo(index) {\r\n this.mainScroll.moveIndexBy(\r\n this.getLoopedIndex(index) - this.potentialIndex\r\n );\r\n }\r\n\r\n /**\r\n * Go to the next slide.\r\n */\r\n next() {\r\n this.goTo(this.potentialIndex + 1);\r\n }\r\n\r\n /**\r\n * Go to the previous slide.\r\n */\r\n prev() {\r\n this.goTo(this.potentialIndex - 1);\r\n }\r\n\r\n /**\r\n * @see slide/slide.js zoomTo\r\n *\r\n * @param {Parameters} args\r\n */\r\n zoomTo(...args) {\r\n this.currSlide?.zoomTo(...args);\r\n }\r\n\r\n /**\r\n * @see slide/slide.js toggleZoom\r\n */\r\n toggleZoom() {\r\n this.currSlide?.toggleZoom();\r\n }\r\n\r\n /**\r\n * Close the gallery.\r\n * After closing transition ends - destroy it\r\n */\r\n close() {\r\n if (!this.opener.isOpen || this.isDestroying) {\r\n return;\r\n }\r\n\r\n this.isDestroying = true;\r\n\r\n this.dispatch('close');\r\n\r\n this.events.removeAll();\r\n this.opener.close();\r\n }\r\n\r\n /**\r\n * Destroys the gallery:\r\n * - instantly closes the gallery\r\n * - unbinds events,\r\n * - cleans intervals and timeouts\r\n * - removes elements from DOM\r\n */\r\n destroy() {\r\n if (!this.isDestroying) {\r\n this.options.showHideAnimationType = 'none';\r\n this.close();\r\n return;\r\n }\r\n\r\n this.dispatch('destroy');\r\n\r\n this._listeners = {};\r\n\r\n if (this.scrollWrap) {\r\n this.scrollWrap.ontouchmove = null;\r\n this.scrollWrap.ontouchend = null;\r\n }\r\n\r\n this.element?.remove();\r\n\r\n this.mainScroll.itemHolders.forEach((itemHolder) => {\r\n itemHolder.slide?.destroy();\r\n });\r\n\r\n this.contentLoader.destroy();\r\n this.events.removeAll();\r\n }\r\n\r\n /**\r\n * Refresh/reload content of a slide by its index\r\n *\r\n * @param {number} slideIndex\r\n */\r\n refreshSlideContent(slideIndex) {\r\n this.contentLoader.removeByIndex(slideIndex);\r\n this.mainScroll.itemHolders.forEach((itemHolder, i) => {\r\n let potentialHolderIndex = (this.currSlide?.index ?? 0) - 1 + i;\r\n if (this.canLoop()) {\r\n potentialHolderIndex = this.getLoopedIndex(potentialHolderIndex);\r\n }\r\n if (potentialHolderIndex === slideIndex) {\r\n // set the new slide content\r\n this.setContent(itemHolder, slideIndex, true);\r\n\r\n // activate the new slide if it's current\r\n if (i === 1) {\r\n this.currSlide = itemHolder.slide;\r\n itemHolder.slide?.setIsActive(true);\r\n }\r\n }\r\n });\r\n\r\n this.dispatch('change');\r\n }\r\n\r\n\r\n /**\r\n * Set slide content\r\n *\r\n * @param {ItemHolder} holder mainScroll.itemHolders array item\r\n * @param {number} index Slide index\r\n * @param {boolean} [force] If content should be set even if index wasn't changed\r\n */\r\n setContent(holder, index, force) {\r\n if (this.canLoop()) {\r\n index = this.getLoopedIndex(index);\r\n }\r\n\r\n if (holder.slide) {\r\n if (holder.slide.index === index && !force) {\r\n // exit if holder already contains this slide\r\n // this could be common when just three slides are used\r\n return;\r\n }\r\n\r\n // destroy previous slide\r\n holder.slide.destroy();\r\n holder.slide = undefined;\r\n }\r\n\r\n // exit if no loop and index is out of bounds\r\n if (!this.canLoop() && (index < 0 || index >= this.getNumItems())) {\r\n return;\r\n }\r\n\r\n const itemData = this.getItemData(index);\r\n holder.slide = new Slide(itemData, index, this);\r\n\r\n // set current slide\r\n if (index === this.currIndex) {\r\n this.currSlide = holder.slide;\r\n }\r\n\r\n holder.slide.append(holder.el);\r\n }\r\n\r\n /** @returns {Point} */\r\n getViewportCenterPoint() {\r\n return {\r\n x: this.viewportSize.x / 2,\r\n y: this.viewportSize.y / 2\r\n };\r\n }\r\n\r\n /**\r\n * Update size of all elements.\r\n * Executed on init and on page resize.\r\n *\r\n * @param {boolean} [force] Update size even if size of viewport was not changed.\r\n */\r\n updateSize(force) {\r\n // let item;\r\n // let itemIndex;\r\n\r\n if (this.isDestroying) {\r\n // exit if PhotoSwipe is closed or closing\r\n // (to avoid errors, as resize event might be delayed)\r\n return;\r\n }\r\n\r\n //const newWidth = this.scrollWrap.clientWidth;\r\n //const newHeight = this.scrollWrap.clientHeight;\r\n\r\n const newViewportSize = getViewportSize(this.options, this);\r\n\r\n if (!force && pointsEqual(newViewportSize, this._prevViewportSize)) {\r\n // Exit if dimensions were not changed\r\n return;\r\n }\r\n\r\n //this._prevViewportSize.x = newWidth;\r\n //this._prevViewportSize.y = newHeight;\r\n equalizePoints(this._prevViewportSize, newViewportSize);\r\n\r\n this.dispatch('beforeResize');\r\n\r\n equalizePoints(this.viewportSize, this._prevViewportSize);\r\n\r\n this._updatePageScrollOffset();\r\n\r\n this.dispatch('viewportSize');\r\n\r\n // Resize slides only after opener animation is finished\r\n // and don't re-calculate size on inital size update\r\n this.mainScroll.resize(this.opener.isOpen);\r\n\r\n if (!this.hasMouse && window.matchMedia('(any-hover: hover)').matches) {\r\n this.mouseDetected();\r\n }\r\n\r\n this.dispatch('resize');\r\n }\r\n\r\n /**\r\n * @param {number} opacity\r\n */\r\n applyBgOpacity(opacity) {\r\n this.bgOpacity = Math.max(opacity, 0);\r\n if (this.bg) {\r\n this.bg.style.opacity = String(this.bgOpacity * this.options.bgOpacity);\r\n }\r\n }\r\n\r\n /**\r\n * Whether mouse is detected\r\n */\r\n mouseDetected() {\r\n if (!this.hasMouse) {\r\n this.hasMouse = true;\r\n this.element?.classList.add('pswp--has_mouse');\r\n }\r\n }\r\n\r\n /**\r\n * Page resize event handler\r\n *\r\n * @private\r\n */\r\n _handlePageResize() {\r\n this.updateSize();\r\n\r\n // In iOS webview, if element size depends on document size,\r\n // it'll be measured incorrectly in resize event\r\n //\r\n // https://bugs.webkit.org/show_bug.cgi?id=170595\r\n // https://hackernoon.com/onresize-event-broken-in-mobile-safari-d8469027bf4d\r\n if (/iPhone|iPad|iPod/i.test(window.navigator.userAgent)) {\r\n setTimeout(() => {\r\n this.updateSize();\r\n }, 500);\r\n }\r\n }\r\n\r\n /**\r\n * Page scroll offset is used\r\n * to get correct coordinates\r\n * relative to PhotoSwipe viewport.\r\n *\r\n * @private\r\n */\r\n _updatePageScrollOffset() {\r\n this.setScrollOffset(0, window.pageYOffset);\r\n }\r\n\r\n /**\r\n * @param {number} x\r\n * @param {number} y\r\n */\r\n setScrollOffset(x, y) {\r\n this.offset.x = x;\r\n this.offset.y = y;\r\n this.dispatch('updateScrollOffset');\r\n }\r\n\r\n /**\r\n * Create main HTML structure of PhotoSwipe,\r\n * and add it to DOM\r\n *\r\n * @private\r\n */\r\n _createMainStructure() {\r\n // root DOM element of PhotoSwipe (.pswp)\r\n this.element = createElement('pswp', 'div');\r\n this.element.setAttribute('tabindex', '-1');\r\n this.element.setAttribute('role', 'dialog');\r\n\r\n // template is legacy prop\r\n this.template = this.element;\r\n\r\n // Background is added as a separate element,\r\n // as animating opacity is faster than animating rgba()\r\n this.bg = createElement('pswp__bg', 'div', this.element);\r\n this.scrollWrap = createElement('pswp__scroll-wrap', 'section', this.element);\r\n this.container = createElement('pswp__container', 'div', this.scrollWrap);\r\n\r\n // aria pattern: carousel\r\n this.scrollWrap.setAttribute('aria-roledescription', 'carousel');\r\n this.container.setAttribute('aria-live', 'off');\r\n this.container.setAttribute('id', 'pswp__items');\r\n\r\n this.mainScroll.appendHolders();\r\n\r\n this.ui = new UI(this);\r\n this.ui.init();\r\n\r\n // append to DOM\r\n (this.options.appendToEl || document.body).appendChild(this.element);\r\n }\r\n\r\n\r\n /**\r\n * Get position and dimensions of small thumbnail\r\n * {x:,y:,w:}\r\n *\r\n * Height is optional (calculated based on the large image)\r\n *\r\n * @returns {Bounds | undefined}\r\n */\r\n getThumbBounds() {\r\n return getThumbBounds(\r\n this.currIndex,\r\n this.currSlide ? this.currSlide.data : this._initialItemData,\r\n this\r\n );\r\n }\r\n\r\n /**\r\n * If the PhotoSwipe can have continuous loop\r\n * @returns Boolean\r\n */\r\n canLoop() {\r\n return (this.options.loop && this.getNumItems() > 2);\r\n }\r\n\r\n /**\r\n * @private\r\n * @param {PhotoSwipeOptions} options\r\n * @returns {PreparedPhotoSwipeOptions}\r\n */\r\n _prepareOptions(options) {\r\n if (window.matchMedia('(prefers-reduced-motion), (update: slow)').matches) {\r\n options.showHideAnimationType = 'none';\r\n options.zoomAnimationDuration = 0;\r\n }\r\n\r\n /** @type {PreparedPhotoSwipeOptions} */\r\n return {\r\n ...defaultOptions,\r\n ...options\r\n };\r\n }\r\n}\r\n\r\nexport default PhotoSwipe;\r\n","/** @typedef {import('./slide.js').SlideData} SlideData */\r\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\r\n\r\n/** @typedef {{ x: number; y: number; w: number; innerRect?: { w: number; h: number; x: number; y: number } }} Bounds */\r\n\r\n/**\r\n * @param {HTMLElement} el\r\n * @returns Bounds\r\n */\r\nfunction getBoundsByElement(el) {\r\n const thumbAreaRect = el.getBoundingClientRect();\r\n return {\r\n x: thumbAreaRect.left,\r\n y: thumbAreaRect.top,\r\n w: thumbAreaRect.width\r\n };\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} el\r\n * @param {number} imageWidth\r\n * @param {number} imageHeight\r\n * @returns Bounds\r\n */\r\nfunction getCroppedBoundsByElement(el, imageWidth, imageHeight) {\r\n const thumbAreaRect = el.getBoundingClientRect();\r\n\r\n // fill image into the area\r\n // (do they same as object-fit:cover does to retrieve coordinates)\r\n const hRatio = thumbAreaRect.width / imageWidth;\r\n const vRatio = thumbAreaRect.height / imageHeight;\r\n const fillZoomLevel = hRatio > vRatio ? hRatio : vRatio;\r\n\r\n const offsetX = (thumbAreaRect.width - imageWidth * fillZoomLevel) / 2;\r\n const offsetY = (thumbAreaRect.height - imageHeight * fillZoomLevel) / 2;\r\n\r\n /**\r\n * Coordinates of the image,\r\n * as if it was not cropped,\r\n * height is calculated automatically\r\n *\r\n * @type {Bounds}\r\n */\r\n const bounds = {\r\n x: thumbAreaRect.left + offsetX,\r\n y: thumbAreaRect.top + offsetY,\r\n w: imageWidth * fillZoomLevel\r\n };\r\n\r\n // Coordinates of inner crop area\r\n // relative to the image\r\n bounds.innerRect = {\r\n w: thumbAreaRect.width,\r\n h: thumbAreaRect.height,\r\n x: offsetX,\r\n y: offsetY\r\n };\r\n\r\n return bounds;\r\n}\r\n\r\n/**\r\n * Get dimensions of thumbnail image\r\n * (click on which opens photoswipe or closes photoswipe to)\r\n *\r\n * @param {number} index\r\n * @param {SlideData} itemData\r\n * @param {PhotoSwipe} instance PhotoSwipe instance\r\n * @returns {Bounds | undefined}\r\n */\r\nexport function getThumbBounds(index, itemData, instance) {\r\n // legacy event, before filters were introduced\r\n const event = instance.dispatch('thumbBounds', {\r\n index,\r\n itemData,\r\n instance\r\n });\r\n // @ts-expect-error\r\n if (event.thumbBounds) {\r\n // @ts-expect-error\r\n return event.thumbBounds;\r\n }\r\n\r\n const { element } = itemData;\r\n /** @type {Bounds | undefined} */\r\n let thumbBounds;\r\n /** @type {HTMLElement | null | undefined} */\r\n let thumbnail;\r\n\r\n if (element && instance.options.thumbSelector !== false) {\r\n const thumbSelector = instance.options.thumbSelector || 'img';\r\n thumbnail = element.matches(thumbSelector)\r\n ? element : /** @type {HTMLElement | null} */ (element.querySelector(thumbSelector));\r\n }\r\n\r\n thumbnail = instance.applyFilters('thumbEl', thumbnail, itemData, index);\r\n\r\n if (thumbnail) {\r\n if (!itemData.thumbCropped) {\r\n thumbBounds = getBoundsByElement(thumbnail);\r\n } else {\r\n thumbBounds = getCroppedBoundsByElement(\r\n thumbnail,\r\n itemData.width || itemData.w || 0,\r\n itemData.height || itemData.h || 0\r\n );\r\n }\r\n }\r\n\r\n return instance.applyFilters('thumbBounds', thumbBounds, itemData, index);\r\n}\r\n"],"names":["createElement","className","tagName","appendToEl","el","document","appendChild","equalizePoints","p1","p2","x","y","undefined","id","roundPoint","p","Math","round","getDistanceBetween","abs","sqrt","pointsEqual","clamp","val","min","max","toTransformString","scale","propValue","setTransform","style","transform","defaultCSSEasing","setTransitionStyle","prop","duration","ease","transition","setWidthHeight","w","h","width","height","LOAD_STATE","isSafari","navigator","vendor","match","supportsPassive","window","addEventListener","Object","defineProperty","get","e","DOMEvents","constructor","this","_pool","add","target","type","listener","passive","_toggleListener","remove","removeAll","forEach","poolItem","unbind","skipPool","methodName","split","eType","filter","push","eventOptions","getViewportSize","options","pswp","getViewportSizeFn","newViewportSize","documentElement","clientWidth","innerHeight","parsePaddingOption","viewportSize","itemData","index","paddingValue","paddingFn","padding","legacyPropName","toUpperCase","slice","Number","getPanAreaSize","PanBounds","slide","currZoomLevel","center","update","_updateAxis","dispatch","reset","axis","elSize","data","panAreaSize","correctPan","panOffset","ZoomLevel","elementSize","fit","fill","vFill","initial","secondary","maxWidth","maxHeight","hRatio","vRatio","_getInitial","_getSecondary","_getMax","zoomLevels","slideData","_parseZoomLevelOption","optionPrefix","optionName","optionValue","Slide","isActive","currIndex","currentResolution","pan","isFirstSlide","opener","isOpen","content","contentLoader","getContentBySlide","container","holderElement","heavyAppended","bounds","prevDisplayedWidth","prevDisplayedHeight","setIsActive","activate","deactivate","append","transformOrigin","calculateSize","load","updateContentSize","appendHeavy","zoomAndPanToInitial","applyCurrentZoomPan","mainScroll","isShifted","defaultPrevented","destroy","hasSlide","resize","panTo","force","scaleMultiplier","sizeChanged","setDisplayedSize","getPlaceholderElement","_this$content$placeho","placeholder","element","zoomTo","destZoomLevel","centerPoint","transitionDuration","ignoreBounds","isZoomable","animations","stopAllPan","prevZoomLevel","setZoomLevel","calculateZoomToPanOffset","finishTransition","_setResolution","startTransition","isPan","name","getCurrentTransform","onComplete","easing","toggleZoom","zoomAnimationDuration","point","getViewportCenterPoint","zoomFactor","panX","panY","isPannable","Boolean","_applyZoomTransform","currSlide","zoom","newResolution","DragHandler","gestures","startPan","start","stopAll","change","prevP1","dragAxis","closeOnVerticalDrag","isMultitouch","_setPanWithFriction","bgOpacity","_getVerticalDragRatio","applyBgOpacity","_panOrMoveMainScroll","end","velocity","indexDiff","currentSlideVisibilityRatio","getCurrSlideX","moveIndexBy","correctZoomPan","_finishPanGestureForAxis","panPos","restoreBgOpacity","projectedPosition","initialVelocity","decelerationRate","project","vDragRatio","projectedVDragRatio","close","correctedPanPosition","dampingRatio","initialBgOpacity","totalPanDist","startSpring","onUpdate","pos","animationProgressRatio","floor","delta","newMainScrollX","moveTo","newPan","allowPanToNext","currSlideMainScrollX","mainScrollShiftDiff","isLeftToRight","isRightToLeft","_this$pswp$currSlide$","_this$pswp$currSlide","potentialPan","customFriction","getZoomPointsCenter","ZoomHandler","_startPan","_startZoomPoint","_zoomPoint","_wasOverFitZoomLevel","_startZoomLevel","startP1","startP2","minZoomLevel","maxZoomLevel","pinchToClose","_calculatePanForZoomLevel","ignoreGesture","destinationZoomLevel","currZoomLevelNeedsChange","initialPan","destinationPan","panNeedsChange","naturalFrequency","now","newZoomLevel","didTapOnMainContent","event","closest","TapHandler","click","originalEvent","targetClassList","classList","isImageClick","contains","isBackgroundClick","_doClickOrTapAction","tap","doubleTap","actionName","_this$gestures$pswp$e","actionFullName","clickToCloseNonZoomable","toggle","call","Gestures","prevP2","_lastStartP1","_intervalP1","_numActivePoints","_ongoingPointers","_touchEventEnabled","_pointerEventEnabled","PointerEvent","supportsTouch","maxTouchPoints","_intervalTime","_velocityCalculated","isDragging","isZooming","raf","_tapTimer","drag","tapHandler","on","events","scrollWrap","_onClick","bind","_bindEvents","ontouchmove","ontouchend","pref","down","up","cancel","cancelEvent","onPointerDown","onPointerMove","onPointerUp","isMousePointer","pointerType","button","mouseDetected","_preventPointerEventBehaviour","_updatePoints","_clearTapTimer","preventDefault","_finishDrag","_updateStartPoints","_rafStopLoop","_rafRenderLoop","_calculateDragDirection","Date","_updateVelocity","_finishTap","_updatePrevPoints","requestAnimationFrame","time","_getVelocity","indexOf","tapDelay","doubleTapAction","setTimeout","clearTimeout","displacement","cancelAnimationFrame","applyFilters","pointerEvent","pointerIndex","findIndex","ongoingPointer","pointerId","splice","_convertEventPosToPoint","length","touchEvent","touches","diff","axisToCheck","pageX","offset","pageY","identifier","stopPropagation","MainScroll","slideWidth","_currPositionIndex","_prevPositionIndex","_containerShiftIndex","itemHolders","resizeSlides","newSlideWidth","spacing","slideWidthChanged","itemHolder","resetPosition","appendHolders","i","setAttribute","display","canBeSwiped","getNumItems","animate","velocityX","newIndex","potentialIndex","numSlides","canLoop","getLoopedIndex","distance","stopMainScroll","destinationX","isMainScroll","updateCurrItem","currDiff","currDistance","_this$itemHolders$","positionDifference","tempHolder","diffAbs","shift","setContent","pop","unshift","updateLazy","dragging","newSlideIndexOffset","KeyboardKeyCodesMap","Escape","z","ArrowLeft","ArrowUp","ArrowRight","ArrowDown","Tab","getKeyboardEventKey","key","isKeySupported","Keyboard","_wasFocused","trapFocus","initialPointerPos","_focusRoot","_onFocusIn","_onKeyDown","lastActiveElement","activeElement","returnFocus","focus","ctrlKey","metaKey","altKey","shiftKey","specialKeyUsed","keydownAction","isForward","keyCode","escKey","arrowKeys","template","DEFAULT_EASING","CSSAnimation","props","_props$prop","onFinish","_target","_onComplete","_finished","_onTransitionEnd","_helperTimeout","_finalizeAnimation","removeEventListener","SpringEaser","_dampingRatio","_naturalFrequency","_dampedFrequency","easeFrame","deltaPosition","deltaTime","coeff","naturalDumpingPow","E","dumpedFCos","cos","dumpedFSin","sin","SpringAnimation","_raf","easer","prevTime","animationLoop","Animations","activeAnimations","_start","isSpring","animation","stop","isPanRunning","some","ScrollWheel","_onWheel","deltaX","deltaY","wheelToZoom","deltaMode","clientX","clientY","UIElement","_container","elementHTML","html","isButton","toLowerCase","title","ariaLabel","ariaText","innerHTML","htmlData","isCustomSVG","svgData","out","join","size","outlineID","inner","addElementHTML","onInit","onClick","onclick","appendTo","topBar","initArrowButton","isNextButton","loop","disabled","arrowPrev","order","arrowNext","closeButton","zoomButton","loadingIndicator","indicatorElement","isVisible","delayTimeout","setIndicatorVisibility","visible","toggleIndicatorClass","updatePreloaderVisibility","_pswp$currSlide","isLoading","_pswp$currSlide2","preloaderDelay","ui","counterIndicator","counterElement","innerText","indexIndicatorSep","setZoomedIn","isZoomedIn","UI","isRegistered","uiElementsData","items","_lastUpdatedZoomLevel","init","sort","a","b","uiElementData","registerElement","_pswp$element","_onZoomPanUpdate","elementData","isClosing","currZoomLevelDiff","imageClickAction","PhotoSwipeEvent","details","assign","Eventable","_listeners","_filters","addFilter","fn","priority","_this$_filters$name","_this$_filters$name2","_this$pswp","f1","f2","removeFilter","args","_this$_filters$name3","apply","_this$_listeners$name","_this$pswp2","off","_this$pswp3","_this$_listeners$name2","Placeholder","imageSrc","imgEl","decoding","alt","src","_this$element","parentNode","Content","instance","displayedImageWidth","displayedImageHeight","isAttached","isDecoding","state","removePlaceholder","keepPlaceholder","isLazy","reload","usePlaceholder","placeholderEl","parentElement","prepend","placeholderSrc","msrc","isImageContent","loadImage","_this$data$src","_this$data$alt","imageElement","updateSrcsetSizes","srcset","complete","onLoaded","onload","onerror","onError","setSlide","displayError","isError","isInitialSizeUpdate","image","sizesWidth","dataset","largestUsedSize","parseInt","sizes","String","lazyLoad","_this$instance$option","_this$instance$option2","errorMsgEl","errorMsg","supportsDecode","decode","catch","finally","appendImage","lazyLoadData","createContentFromData","zoomLevel","ceil","ContentLoader","limit","preload","_cachedItems","loadSlideByIndex","initialIndex","getContentByIndex","getItemData","lazyLoadSlide","addToCache","removeByIndex","indexToRemove","item","find","PhotoSwipeBase","_this$options","numItems","dataSource","_getGalleryDOMElements","gallery","_this$options2","dataSourceItem","Array","isArray","Element","_domElementToItemData","galleryElement","_this$options3","_this$options4","children","childSelector","option","legacySelector","parent","elements","NodeList","from","selector","querySelectorAll","getElementsFromOption","linkEl","querySelector","pswpSrc","href","pswpSrcset","pswpWidth","pswpHeight","pswpType","thumbnailEl","_thumbnailEl$getAttri","currentSrc","getAttribute","pswpCropped","cropped","thumbCropped","MIN_OPACITY","Opener","isClosed","isOpening","_duration","_useAnimation","_croppedZoom","_animateRootOpacity","_animateBgOpacity","_placeholder","_opacityElement","_cropContainer1","_cropContainer2","_thumbBounds","_prepareOpen","open","hideAnimationDuration","maxWidthToAnimate","_applyStartProps","showAnimationDuration","_options$showHideOpac","showHideAnimationType","showHideOpacity","_initialThumbBounds","getThumbBounds","_animateZoom","bg","opacity","innerRect","overflow","_setClosedStateZoomPan","willChange","Promise","resolve","decoded","isDelaying","img","reject","_initiate","_this$pswp$element","_this$pswp$element2","setProperty","_animateToOpenState","_animateToClosedState","_onAnimationComplete","_animateTo","containerOnePanX","containerOnePanY","containerTwoPanX","containerTwoPanY","animProps","defaultOptions","bgClickAction","tapAction","PhotoSwipe","super","_prepareOptions","_prevViewportSize","isDestroying","hasMouse","_initialItemData","keyboard","_createMainStructure","rootClasses","mainClass","scrollWheel","isNaN","updateSize","pageYOffset","_handlePageResize","_updatePageScrollOffset","_itemHolder$slide","goTo","next","prev","_this$currSlide","_this$currSlide2","_itemHolder$slide2","refreshSlideContent","slideIndex","_this$currSlide$index","_this$currSlide3","potentialHolderIndex","_itemHolder$slide3","holder","matchMedia","matches","_this$element2","test","userAgent","setScrollOffset","body","thumbBounds","thumbnail","thumbSelector","imageWidth","imageHeight","thumbAreaRect","getBoundingClientRect","fillZoomLevel","offsetX","offsetY","left","top","getCroppedBoundsByElement","getBoundsByElement"],"sourceRoot":""}