lightgallery 3.0.0-beta.2 → 3.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/dist/lightgallery.es5.js +5 -56
  2. package/dist/lightgallery.es5.js.map +1 -1
  3. package/dist/lightgallery.min.js +1 -1
  4. package/dist/lightgallery.umd.js +5 -56
  5. package/dist/lightgallery.umd.js.map +1 -1
  6. package/dist/package.json +1 -1
  7. package/dist/plugins/autoplay/lg-autoplay.es5.js +1 -1
  8. package/dist/plugins/autoplay/lg-autoplay.umd.js +1 -1
  9. package/dist/plugins/comment/lg-comment.es5.js +1 -1
  10. package/dist/plugins/comment/lg-comment.umd.js +1 -1
  11. package/dist/plugins/fullscreen/lg-fullscreen.es5.js +1 -1
  12. package/dist/plugins/fullscreen/lg-fullscreen.umd.js +1 -1
  13. package/dist/plugins/hash/lg-hash.es5.js +1 -1
  14. package/dist/plugins/hash/lg-hash.umd.js +1 -1
  15. package/dist/plugins/justified/lg-justified.es5.js +1 -1
  16. package/dist/plugins/justified/lg-justified.umd.js +1 -1
  17. package/dist/plugins/mediumZoom/lg-medium-zoom.es5.js +1 -1
  18. package/dist/plugins/mediumZoom/lg-medium-zoom.umd.js +1 -1
  19. package/dist/plugins/originCrop/lg-origin-crop.es5.js +1 -1
  20. package/dist/plugins/originCrop/lg-origin-crop.umd.js +1 -1
  21. package/dist/plugins/pager/lg-pager.es5.js +1 -1
  22. package/dist/plugins/pager/lg-pager.umd.js +1 -1
  23. package/dist/plugins/relativeCaption/lg-relative-caption.es5.js +1 -1
  24. package/dist/plugins/relativeCaption/lg-relative-caption.umd.js +1 -1
  25. package/dist/plugins/rotate/lg-rotate.es5.js +1 -1
  26. package/dist/plugins/rotate/lg-rotate.umd.js +1 -1
  27. package/dist/plugins/share/lg-share.es5.js +1 -1
  28. package/dist/plugins/share/lg-share.umd.js +1 -1
  29. package/dist/plugins/thumbnail/lg-thumbnail.es5.js +1 -1
  30. package/dist/plugins/thumbnail/lg-thumbnail.umd.js +1 -1
  31. package/dist/plugins/video/lg-video.es5.js +1 -1
  32. package/dist/plugins/video/lg-video.umd.js +1 -1
  33. package/dist/plugins/vimeoThumbnail/lg-vimeo-thumbnail.es5.js +1 -1
  34. package/dist/plugins/vimeoThumbnail/lg-vimeo-thumbnail.umd.js +1 -1
  35. package/dist/plugins/zoom/lg-zoom.es5.js +1 -1
  36. package/dist/plugins/zoom/lg-zoom.umd.js +1 -1
  37. package/dist/types/headless/announce.d.ts +22 -0
  38. package/dist/types/headless/emitter.d.ts +14 -0
  39. package/dist/types/headless/gestures.d.ts +128 -0
  40. package/dist/types/headless/hash-driver.d.ts +77 -0
  41. package/dist/types/headless/icons.d.ts +56 -0
  42. package/dist/types/headless/index.d.ts +34 -0
  43. package/dist/types/headless/items.d.ts +92 -0
  44. package/dist/types/headless/justified-layout.d.ts +71 -0
  45. package/dist/types/headless/license.d.ts +35 -0
  46. package/dist/types/headless/origin-crop.d.ts +135 -0
  47. package/dist/types/headless/origin.d.ts +65 -0
  48. package/dist/types/headless/plugin-slices.d.ts +64 -0
  49. package/dist/types/headless/preload.d.ts +36 -0
  50. package/dist/types/headless/responsive.d.ts +90 -0
  51. package/dist/types/headless/settings.d.ts +268 -0
  52. package/dist/types/headless/share-urls.d.ts +60 -0
  53. package/dist/types/headless/spring.d.ts +42 -0
  54. package/dist/types/headless/state.d.ts +63 -0
  55. package/dist/types/headless/thumb-math.d.ts +85 -0
  56. package/dist/types/headless/toolbar-overflow.d.ts +61 -0
  57. package/dist/types/headless/transition.d.ts +33 -0
  58. package/dist/types/headless/velocity.d.ts +31 -0
  59. package/dist/types/headless/video-urls.d.ts +64 -0
  60. package/dist/types/headless/zoom-math.d.ts +89 -0
  61. package/dist/types/index.d.ts +2 -1
  62. package/dist/types/lg-icons.d.ts +1 -1
  63. package/dist/types/lg-settings.d.ts +1 -7
  64. package/dist/types/lg-spring-runner.d.ts +1 -1
  65. package/dist/types/lightgallery.d.ts +0 -1
  66. package/dist/types/plugins/hash/lg-hash-settings.d.ts +1 -1
  67. package/dist/types/plugins/video/lg-video-settings.d.ts +1 -1
  68. package/dist/types/plugins/zoom/lg-zoom.d.ts +1 -1
  69. package/package.json +56 -71
@@ -1 +1 @@
1
- {"version":3,"file":"lightgallery.es5.js","sources":["../packages/headless/src/video-urls.ts","../packages/headless/src/license.ts","../packages/headless/src/announce.ts","../packages/headless/src/spring.ts","../packages/headless/src/gestures.ts","../packages/headless/src/origin.ts","../packages/headless/src/icons.ts","../packages/headless/src/toolbar-overflow.ts","../packages/headless/src/transition.ts","../packages/headless/src/responsive.ts","../packages/headless/src/velocity.ts","../src/lg-events.ts","../src/lg-settings.ts","../src/lg-toolbar-overflow.ts","../src/lg-icons.ts","../src/lg-spring-runner.ts","../src/lgQuery.ts","../src/lg-utils.ts","../src/lightgallery.ts","../src/index.ts"],"sourcesContent":["/**\n * Video URL detection and embed-URL builders, ported from 2.x\n * `utils.isVideo` (`src/lg-utils.ts`) and `lg-video-utils.ts` as pure\n * functions. The video plugin renders the returned URLs; nothing here\n * touches the DOM.\n */\n\nexport interface VideoInfo {\n /** RegExp match parts: `[match, videoId, urlParams?]`. */\n youtube?: string[];\n vimeo?: string[];\n /** RegExp match parts; index 4 is the media id. */\n wistia?: string[];\n html5?: boolean;\n}\n\n// `true` is accepted for 2.x-contract compatibility and means the same\n// as an empty params object.\nexport type PlayerParams = Record<string, string | number | boolean> | boolean;\n\nfunction toParamsObject(\n params: PlayerParams,\n): Record<string, string | number | boolean> {\n return typeof params === 'object' && params ? params : {};\n}\n\n/** Detect the video provider for a src URL (2.x `utils.isVideo`). */\nexport function getVideoInfo(\n src: string | undefined,\n hasHtml5Video: boolean,\n): VideoInfo | undefined {\n if (!src) {\n return hasHtml5Video ? { html5: true } : undefined;\n }\n const youtube = src.match(\n /\\/\\/(?:www\\.)?youtu(?:\\.be|be\\.com|be-nocookie\\.com)\\/(?:watch\\?v=|embed\\/)?([a-z0-9\\-_%]+)([&|?][\\S]*)*/i,\n );\n if (youtube) {\n return { youtube: [...youtube] };\n }\n const vimeo = src.match(\n /\\/\\/(?:www\\.)?(?:player\\.)?vimeo.com\\/(?:video\\/)?([0-9a-z\\-_]+)(.*)?/i,\n );\n if (vimeo) {\n return { vimeo: [...vimeo] };\n }\n const wistia = src.match(\n /https?:\\/\\/(.+)?(wistia\\.com|wi\\.st)\\/(medias|embed)\\/([0-9a-z\\-_]+)(.*)/,\n );\n if (wistia) {\n return { wistia: [...wistia] };\n }\n return hasHtml5Video ? { html5: true } : undefined;\n}\n\n/** Serialize params as a query string (2.x `param`). */\nexport function param(obj: Record<string, string | number | boolean>): string {\n return Object.keys(obj)\n .map(\n (key) =>\n `${encodeURIComponent(key)}=${encodeURIComponent(obj[key]!)}`,\n )\n .join('&');\n}\n\n/** Parse `?a=b&c=d` into an object (2.x `paramsToObject`). */\nexport function paramsToObject(url: string): Record<string, string> {\n return url\n .slice(1)\n .split('&')\n .map((pair) => pair.split('='))\n .reduce<Record<string, string>>((obj, pair) => {\n const [key, value] = pair.map(decodeURIComponent);\n if (key) {\n obj[key] = value ?? '';\n }\n return obj;\n }, {});\n}\n\nexport function isYouTubeNoCookie(url: string): boolean {\n return url.includes('youtube-nocookie.com');\n}\n\n/**\n * YouTube embed URL. Precedence (2.x parity): defaults < settings < params\n * already present on the slide URL. The privacy-enhanced\n * `youtube-nocookie.com` host is the default; pass `preferNoCookie: false`\n * (the `youTubeNoCookie` setting) to revert to `youtube.com`. A slide URL\n * that already names the nocookie host always keeps it.\n */\nexport function getYouTubeEmbedUrl(\n videoInfo: VideoInfo,\n playerParamsSettings: PlayerParams,\n srcUrl: string,\n preferNoCookie = true,\n): string | undefined {\n if (!videoInfo.youtube) {\n return undefined;\n }\n const slideUrlParams = videoInfo.youtube[2]\n ? paramsToObject(videoInfo.youtube[2])\n : {};\n const params = {\n wmode: 'opaque',\n autoplay: 0,\n mute: 1,\n enablejsapi: 1,\n ...toParamsObject(playerParamsSettings),\n ...slideUrlParams,\n };\n const base =\n preferNoCookie || isYouTubeNoCookie(srcUrl)\n ? '//www.youtube-nocookie.com/'\n : '//www.youtube.com/';\n return `${base}embed/${videoInfo.youtube[1]}?${param(params)}`;\n}\n\n/**\n * YouTube's public thumbnail endpoint for a detected video — the one\n * provider poster that needs no API call. (Vimeo/Wistia poster endpoints\n * require a fetch/auth, so their facades rely on the item's own\n * poster/thumb — see getFacadePoster.)\n */\nexport function getYouTubePosterUrl(\n videoInfo: VideoInfo | undefined,\n): string | undefined {\n if (!videoInfo?.youtube) {\n return undefined;\n }\n return `//img.youtube.com/vi/${videoInfo.youtube[1]}/maxresdefault.jpg`;\n}\n\n/**\n * Poster for a provider-video facade (lite embed): the explicit item\n * poster wins, then the YouTube thumbnail endpoint (when enabled), then\n * the item's grid thumb — for Vimeo galleries the vimeoThumbnail plugin\n * rewrites `thumb` to the oEmbed thumbnail, which feeds this chain.\n * HTML5 slides never get a synthesized poster (unchanged 2.x behavior);\n * a provider slide with no resolvable poster returns undefined and keeps\n * the eager-iframe path.\n */\nexport function getFacadePoster(\n item: { poster?: string; thumb?: string },\n videoInfo: VideoInfo | undefined,\n loadYouTubePoster: boolean,\n): string | undefined {\n if (!videoInfo || videoInfo.html5) {\n return item.poster || undefined;\n }\n return (\n item.poster ||\n (loadYouTubePoster ? getYouTubePosterUrl(videoInfo) : undefined) ||\n item.thumb ||\n undefined\n );\n}\n\n/**\n * Provider player-API script URLs, loaded on demand at first play (the\n * vanilla runtime's control paths need them; the framework bindings drive\n * players via postMessage and load nothing).\n */\nexport const VIMEO_PLAYER_SCRIPT_URL = 'https://player.vimeo.com/api/player.js';\nexport const WISTIA_PLAYER_SCRIPT_URL =\n 'https://fast.wistia.com/assets/external/E-v1.js';\n\n/**\n * Vimeo embed URL, including the private-video hash handling (2.x\n * `getVimeoURLParams`).\n */\nexport function getVimeoEmbedUrl(\n videoInfo: VideoInfo,\n playerParamsSettings: PlayerParams,\n): string | undefined {\n if (!videoInfo.vimeo) {\n return undefined;\n }\n let urlParams = videoInfo.vimeo[2] || '';\n const defaultPlayerParams = {\n autoplay: 0,\n muted: 1,\n ...toParamsObject(playerParamsSettings),\n };\n let defaultParams = param(defaultPlayerParams);\n\n // Private videos carry a hash as the last path segment.\n const urlWithHash = videoInfo.vimeo[0]!.split('/').pop() || '';\n const urlWithHashWithoutParams = urlWithHash.split('?')[0] || '';\n const hash = urlWithHashWithoutParams.split('#')[0]!;\n const isPrivate = videoInfo.vimeo[1] !== hash;\n if (isPrivate) {\n urlParams = urlParams.replace(`/${hash}`, '');\n }\n urlParams =\n urlParams[0] === '?' ? `&${urlParams.slice(1)}` : urlParams || '';\n const privateUrlParams = isPrivate ? `h=${hash}` : '';\n defaultParams = privateUrlParams ? `&${defaultParams}` : defaultParams;\n\n return `//player.vimeo.com/video/${videoInfo.vimeo[1]}?${privateUrlParams}${defaultParams}${urlParams}`;\n}\n\n/** Wistia embed URL. */\nexport function getWistiaEmbedUrl(\n videoInfo: VideoInfo,\n playerParamsSettings: PlayerParams,\n): string | undefined {\n if (!videoInfo.wistia) {\n return undefined;\n }\n const paramsObject = toParamsObject(playerParamsSettings);\n const params = Object.keys(paramsObject).length ? param(paramsObject) : '';\n return `//fast.wistia.net/embed/iframe/${videoInfo.wistia[4]}${\n params ? `?${params}` : ''\n }`;\n}\n","/**\n * License key check shared by every package. The key never limits a\n * feature; it only decides which console message, if any, the gallery\n * logs. `checkLicenseKey` is pure; the page-wide key and the once-per-page\n * bookkeeping are module state, and the runtime does the logging.\n */\n\n/** The temporary key; also the default `licenseKey`. */\nexport const TESTING_LICENSE_KEY = '0000-0000-000-0000';\n\n/** Every lightGallery 3 key starts with this; v1 and v2 keys don't. */\nexport const LICENSE_KEY_PREFIX = 'LIG';\n\nconst LICENSE_DOCS = 'https://www.lightgalleryjs.com/docs/license/';\n\nexport interface LicenseNotice {\n level: 'error' | 'warn';\n message: string;\n}\n\n/**\n * The console notice for a license key, or `null` for a lightGallery 3\n * key. An empty key is an error; the testing key and keys from v1 or v2\n * (no `LIG` prefix) are warnings.\n */\nexport function checkLicenseKey(\n licenseKey: string | undefined,\n): LicenseNotice | null {\n const key = (licenseKey ?? '').trim();\n if (!key) {\n return {\n level: 'error',\n message: `lightGallery: please provide a valid license key. See ${LICENSE_DOCS}`,\n };\n }\n if (key === TESTING_LICENSE_KEY) {\n return {\n level: 'warn',\n message: `lightGallery: ${key} license key is not valid for production use. See ${LICENSE_DOCS}`,\n };\n }\n if (!key.startsWith(LICENSE_KEY_PREFIX)) {\n return {\n level: 'warn',\n message: `lightGallery: this license key is for v1 or v2 and is not valid for v3. Please upgrade to a v3 license. See ${LICENSE_DOCS}`,\n };\n }\n return null;\n}\n\nlet pageLicenseKey: string | undefined;\nconst loggedNotices = new Set<string>();\n\n/**\n * Set the license key once for every gallery on the page. Call it before\n * creating galleries; a gallery's own `licenseKey` still wins.\n */\nexport function setLicenseKey(licenseKey: string): void {\n pageLicenseKey = licenseKey;\n}\n\n/**\n * The key a gallery runs with: its own `licenseKey`, or the page-wide key\n * when it has none (or only the testing default).\n */\nexport function resolveLicenseKey(instanceKey: string | undefined): string {\n const own = (instanceKey ?? '').trim();\n if (pageLicenseKey !== undefined && (!own || own === TESTING_LICENSE_KEY)) {\n return pageLicenseKey;\n }\n return instanceKey ?? TESTING_LICENSE_KEY;\n}\n\n/**\n * The notice a new gallery should log, or `null`. Each message is logged\n * once per page, however many galleries share the key.\n */\nexport function takeLicenseNotice(\n instanceKey: string | undefined,\n): LicenseNotice | null {\n const notice = checkLicenseKey(resolveLicenseKey(instanceKey));\n if (!notice || loggedNotices.has(notice.message)) return null;\n loggedNotices.add(notice.message);\n return notice;\n}\n","/**\n * Slide-change announcement formatting for the shared `aria-live` region.\n * All four runtimes build their announcer text through this helper so the\n * wording (and its localization surface, `strings.slideAnnouncement`) stays\n * identical everywhere.\n */\n\nexport interface SlideAnnouncementOptions {\n /** `strings.slideAnnouncement` template with `{index}`/`{total}` slots. */\n template: string;\n /** 1-based position of the shown slide. */\n index: number;\n /** Total slide count. */\n total: number;\n /** Plain-text caption of the shown slide, if any. */\n caption?: string;\n}\n\n/**\n * Build the text announced on a slide change: the filled template, then the\n * caption (comma-separated) when one exists. Whitespace in the caption is\n * collapsed so multi-line/rich captions read as one sentence.\n */\nexport function formatSlideAnnouncement(\n options: SlideAnnouncementOptions,\n): string {\n const base = options.template\n .replace('{index}', String(options.index))\n .replace('{total}', String(options.total));\n const caption = (options.caption || '').replace(/\\s+/g, ' ').trim();\n return caption ? `${base}, ${caption}` : base;\n}\n","/**\n * Gesture-release physics: momentum projection and a damped-spring\n * stepper. Releases compute where momentum would land (`project`),\n * clamp that into bounds, and animate there with a spring seeded by the\n * live release velocity — velocity stays continuous across the\n * finger-lift boundary, which is most of what native feel is.\n *\n * The stepper advances the standard damped harmonic oscillator by its\n * closed-form solution over each frame, so step size never affects the\n * trajectory and the state (position + velocity) can re-seed a new\n * spring at any interruption point.\n */\n\nexport interface SpringState {\n position: number;\n /** px per ms (same unit as the windowed gesture velocity). */\n velocity: number;\n}\n\nexport interface SpringConfig {\n /** 1 = never overshoot; < 1 overshoots and returns. */\n dampingRatio?: number;\n /** Rad/s — higher settles faster. */\n naturalFrequency?: number;\n}\n\n/** Settling toward an in-bounds target: no overshoot. */\nexport const SPRING_SETTLE_DAMPING = 1;\n\n/** Settling against a clamped bound: one soft bounce. */\nexport const SPRING_BOUNCE_DAMPING = 0.82;\n\nexport const SPRING_NATURAL_FREQUENCY = 12;\n\n/**\n * Momentum projection: how far a release keeps traveling when it loses\n * `1 - decelerationRate` of its velocity every millisecond (the classic\n * scroll-view constant; 0.995 ≈ half a percent per ms).\n */\nexport const DECELERATION_RATE = 0.995;\n\nexport function project(\n velocity: number,\n decelerationRate: number = DECELERATION_RATE,\n): number {\n return (velocity * decelerationRate) / (1 - decelerationRate);\n}\n\n/**\n * Advance a spring toward `target` by `dtMs`, exactly (closed form with\n * the current state as initial conditions).\n */\nexport function stepSpring(\n state: SpringState,\n target: number,\n dtMs: number,\n {\n dampingRatio = SPRING_SETTLE_DAMPING,\n naturalFrequency = SPRING_NATURAL_FREQUENCY,\n }: SpringConfig = {},\n): SpringState {\n const t = dtMs / 1000;\n const w0 = naturalFrequency;\n const zeta = Math.min(dampingRatio, 1);\n const x0 = state.position - target;\n const v0 = state.velocity * 1000; // px/s for the oscillator\n const decay = Math.exp(-zeta * w0 * t);\n\n let x: number;\n let v: number;\n if (zeta < 1) {\n const wd = w0 * Math.sqrt(1 - zeta * zeta);\n const a = x0;\n const b = (v0 + zeta * w0 * x0) / wd;\n const cos = Math.cos(wd * t);\n const sin = Math.sin(wd * t);\n x = decay * (a * cos + b * sin);\n v =\n decay *\n ((b * wd - zeta * w0 * a) * cos - (a * wd + zeta * w0 * b) * sin);\n } else {\n const b = v0 + w0 * x0;\n x = decay * (x0 + b * t);\n v = decay * (b - w0 * (x0 + b * t));\n }\n return { position: target + x, velocity: v / 1000 };\n}\n\n/** Whether a spring is close enough to stop animating. */\nexport function isSpringSettled(\n state: SpringState,\n target: number,\n restDelta = 0.3,\n restVelocity = 0.012,\n): boolean {\n return (\n Math.abs(state.position - target) < restDelta &&\n Math.abs(state.velocity) < restVelocity\n );\n}\n","/**\n * Gesture math, ported from the 2.x touch/drag implementation\n * (`touchMove`/`touchEnd` in `src/lightgallery.ts`) as pure functions. The\n * framework layer owns pointer events and writes the returned transforms\n * straight to the DOM (never through framework state — one render per\n * gesture, not per move); every *decision* lives here so swipe feel is\n * identical across frameworks.\n */\n\nimport { project } from './spring';\nimport type { ResolvedGalleryDirection } from './settings';\n\nexport type SwipeAxis = 'horizontal' | 'vertical';\n\n/**\n * Minimum travel (px) before a drag commits to an axis. Tuned from the\n * 2.x 15px to ~10 (UIPanGestureRecognizer territory): drags answer a\n * touch sooner without axis flip-flop — the commit is still sticky.\n */\nexport const SWIPE_AXIS_THRESHOLD = 10;\n\n/**\n * Flick support: a release faster than this (px/ms, windowed — see\n * `velocity.ts`) navigates even below `swipeThreshold`. Default per the\n * gesture-physics teardown: windowed readings run higher than the old\n * whole-gesture averages, so this gate and windowed measurement ship as\n * one change. Public setting: `flickVelocity`.\n */\nexport const FLICK_VELOCITY = 0.5;\n\n/** Minimum travel (px) for a flick, so taps never navigate. */\nexport const FLICK_MIN_DISTANCE = 20;\n\n/** Vertical travel (px) beyond which the drag hides the UI chrome — 2.x. */\nexport const VERTICAL_CLOSE_THRESHOLD = 100;\n\n/**\n * Drag-to-close verdict: the momentum-projected travel must pass this\n * fraction of the viewport height — a small fast downward flick closes,\n * a large slow drag released while returning does not.\n */\nexport const VERTICAL_CLOSE_RATIO = 0.4;\n\n/**\n * Minimum actual travel (px) before the projected close arms. Momentum\n * may extend a real drag, never replace one: a grazed tap releases with\n * a fast final instant, and projection alone would read it as a close\n * flick.\n */\nexport const VERTICAL_CLOSE_MIN_DRAG = 40;\n\n/**\n * Rubber-band friction past the first/last slide (no loop): the drag\n * keeps moving at this fraction of the finger instead of the 2.x\n * un-resisted 1:1 travel — you feel that there is nothing further.\n */\nexport const SLIDE_EDGE_FRICTION = 0.35;\n\n/**\n * Horizontal drag delta with rubber-banding past the gallery ends.\n * `hasPrev`/`hasNext` reflect whether a slide exists in that direction\n * (loop counts); the release spring returns the frictioned distance.\n */\nexport function getEdgeFrictionedDelta(\n deltaX: number,\n hasPrev: boolean,\n hasNext: boolean,\n direction: ResolvedGalleryDirection = 'ltr',\n): number {\n // In RTL the finger drags toward the mirrored neighbor.\n const [towardPrev, towardNext] =\n direction === 'rtl' ? [hasNext, hasPrev] : [hasPrev, hasNext];\n if ((deltaX > 0 && !towardPrev) || (deltaX < 0 && !towardNext)) {\n return deltaX * SLIDE_EDGE_FRICTION;\n }\n return deltaX;\n}\n\n/** Decide (once) which axis a drag follows; sticky after the first commit. */\nexport function getSwipeAxis(\n deltaX: number,\n deltaY: number,\n current: SwipeAxis | undefined,\n): SwipeAxis | undefined {\n if (current) {\n return current;\n }\n if (Math.abs(deltaX) > SWIPE_AXIS_THRESHOLD) {\n return 'horizontal';\n }\n if (Math.abs(deltaY) > SWIPE_AXIS_THRESHOLD) {\n return 'vertical';\n }\n return undefined;\n}\n\nexport interface HorizontalDragTransforms {\n current: string;\n prev: string;\n next: string;\n}\n\n/**\n * Follow-the-finger transforms for the current slide and its neighbors\n * (2.x `touchMove` horizontal branch, including the shrinking gutter).\n */\nexport function getHorizontalDragTransforms(\n deltaX: number,\n slideWidth: number,\n direction: ResolvedGalleryDirection = 'ltr',\n): HorizontalDragTransforms {\n const slideWidthAmount = (slideWidth * 15) / 100;\n const gutter = slideWidthAmount - Math.abs((deltaX * 10) / 100);\n const before = `translate3d(${-slideWidth + deltaX - gutter}px, 0px, 0px)`;\n const after = `translate3d(${slideWidth + deltaX + gutter}px, 0px, 0px)`;\n return {\n current: `translate3d(${deltaX}px, 0px, 0px)`,\n // In RTL the prev slide rests to the physical right (lg-rtl.css\n // flips the resting positions the same way).\n prev: direction === 'rtl' ? after : before,\n next: direction === 'rtl' ? before : after,\n };\n}\n\nexport interface VerticalDragEffects {\n /** Backdrop opacity fading out with the drag. */\n backdropOpacity: number;\n /** Transform for the current slide (translate + shrink). */\n transform: string;\n /** True once the UI chrome should hide (past the close threshold). */\n hideUi: boolean;\n}\n\n/** Drag-to-close visuals (2.x `touchMove` vertical branch). */\nexport function getVerticalDragEffects(\n deltaY: number,\n viewportWidth: number,\n viewportHeight: number,\n): VerticalDragEffects {\n const distance = Math.abs(deltaY);\n const scale = 1 - distance / (viewportWidth * 2);\n return {\n backdropOpacity: 1 - distance / viewportHeight,\n transform: `translate3d(0px, ${deltaY}px, 0px) scale3d(${scale}, ${scale}, 1)`,\n hideUi: distance > VERTICAL_CLOSE_THRESHOLD,\n };\n}\n\nexport type SwipeReleaseVerdict = 'next' | 'prev' | 'stay';\n\nexport interface SwipeReleaseInput {\n deltaX: number;\n /** Release velocity, px/ms signed (windowed — see `velocity.ts`). */\n velocityX: number;\n /** `swipeThreshold` setting (px). */\n threshold: number;\n /** `flickVelocity` setting (px/ms). */\n flickVelocity?: number;\n /**\n * Slide width (px). When given, a release whose momentum-projected\n * travel crosses the midpoint also navigates — a firm half-hearted\n * swipe keeps going where a hesitant one snaps back.\n */\n viewportWidth?: number;\n /** Resolved gallery direction; in `'rtl'` the verdict mirrors. */\n direction?: ResolvedGalleryDirection;\n}\n\n/**\n * Horizontal release decision: past `swipeThreshold`, or a quick flick →\n * navigate (negative delta = next, 2.x parity); otherwise snap back.\n * The flick counts only when the release velocity points the same way\n * as the drag — reversing direction just before lifting is a cancel,\n * not a flick.\n */\nexport function getSwipeReleaseVerdict({\n deltaX,\n velocityX,\n threshold,\n flickVelocity = FLICK_VELOCITY,\n viewportWidth,\n direction = 'ltr',\n}: SwipeReleaseInput): SwipeReleaseVerdict {\n const distance = Math.abs(deltaX);\n const directionMatches =\n deltaX !== 0 && Math.sign(velocityX) === Math.sign(deltaX);\n const projected = deltaX + project(velocityX);\n const passes =\n distance > threshold ||\n (distance > FLICK_MIN_DISTANCE &&\n directionMatches &&\n Math.abs(velocityX) > flickVelocity) ||\n (viewportWidth !== undefined &&\n distance > FLICK_MIN_DISTANCE &&\n directionMatches &&\n Math.abs(projected) > viewportWidth / 2);\n if (!passes) {\n return 'stay';\n }\n const towardNext = direction === 'rtl' ? deltaX > 0 : deltaX < 0;\n return towardNext ? 'next' : 'prev';\n}\n\n/**\n * Vertical release decision: close when the momentum-projected travel\n * passes {@link VERTICAL_CLOSE_RATIO} of the viewport in the drag's own\n * direction (a release moving back toward rest never closes), and the\n * finger actually travelled {@link VERTICAL_CLOSE_MIN_DRAG}.\n */\nexport function shouldCloseOnVerticalDrag(\n deltaY: number,\n velocityY: number,\n viewportHeight: number,\n options: { closable: boolean; swipeToClose: boolean },\n): boolean {\n if (!options.closable || !options.swipeToClose || deltaY === 0) {\n return false;\n }\n if (Math.abs(deltaY) < VERTICAL_CLOSE_MIN_DRAG) {\n return false;\n }\n const projected = deltaY + project(velocityY);\n return (\n Math.sign(projected) === Math.sign(deltaY) &&\n Math.abs(projected) > VERTICAL_CLOSE_RATIO * viewportHeight\n );\n}\n\n/**\n * Which slide navigation a release verdict maps to, honoring the 2.x touch\n * loop rule: galleries with fewer than 3 slides never wrap from touch.\n */\nexport function resolveSwipeTarget(\n verdict: SwipeReleaseVerdict,\n currentIndex: number,\n slidesCount: number,\n loop: boolean,\n): number | null {\n if (verdict === 'stay') {\n return null;\n }\n const touchLoop = loop && slidesCount >= 3;\n if (verdict === 'next') {\n if (currentIndex + 1 < slidesCount) {\n return currentIndex + 1;\n }\n return touchLoop ? 0 : null;\n }\n if (currentIndex > 0) {\n return currentIndex - 1;\n }\n return touchLoop ? slidesCount - 1 : null;\n}\n\n/** One live pointer, for multi-pointer consumers (zoom plugin). */\nexport interface PointerRecord {\n id: number;\n startX: number;\n startY: number;\n x: number;\n y: number;\n}\n\n/** Add or update a pointer record, returning a new array. */\nexport function upsertPointer(\n pointers: readonly PointerRecord[],\n record: PointerRecord,\n): PointerRecord[] {\n const existing = pointers.findIndex((p) => p.id === record.id);\n if (existing === -1) {\n return [...pointers, record];\n }\n const copy = [...pointers];\n copy[existing] = record;\n return copy;\n}\n\n/** Remove a pointer record by id, returning a new array. */\nexport function removePointer(\n pointers: readonly PointerRecord[],\n id: number,\n): PointerRecord[] {\n return pointers.filter((p) => p.id !== id);\n}\n","/**\n * Zoom-from-origin math, ported from 2.x `utils.getSize`/`utils.getTransform`\n * (`src/lg-utils.ts`) as pure rect arithmetic. The framework layer measures\n * the DOM (trigger/container bounding rects) and passes plain numbers in.\n *\n * Note: this module is an addition to the ADR 0001 §1 table — it\n * follows the standing rule that pure functions needed by React live in\n * headless. It is distinct from `zoom-math.ts` (zoom plugin).\n */\n\nexport interface ImageSize {\n width: number;\n height: number;\n}\n\nexport interface RectLike {\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\n/**\n * Parse an item's `lgSize` value (`\"1920-1280\"`, or a responsive list like\n * `\"240-160-375, 1600-1067\"` where the third number is the max viewport\n * width the entry applies to).\n */\nexport function parseImageSize(\n lgSize: string | undefined,\n viewportWidth: number,\n): ImageSize | undefined {\n if (!lgSize) {\n return undefined;\n }\n let size = lgSize;\n const responsiveSizes = lgSize.split(',');\n if (responsiveSizes[1]) {\n for (let i = 0; i < responsiveSizes.length; i++) {\n const candidate = responsiveSizes[i]!.trim();\n const responsiveWidth = parseInt(candidate.split('-')[2]!, 10);\n if (responsiveWidth > viewportWidth) {\n size = candidate;\n break;\n }\n if (i === responsiveSizes.length - 1) {\n size = candidate;\n }\n }\n }\n const parts = size.trim().split('-');\n const width = parseInt(parts[0]!, 10);\n const height = parseInt(parts[1]!, 10);\n if (!Number.isFinite(width) || !Number.isFinite(height)) {\n return undefined;\n }\n return { width, height };\n}\n\n/**\n * Fit a natural image size into the available container box, preserving\n * aspect ratio and never scaling up (2.x `utils.getSize` math).\n */\nexport function fitImageSize(\n size: ImageSize,\n containerWidth: number,\n containerHeight: number,\n): ImageSize {\n const maxWidth = Math.min(containerWidth, size.width);\n const maxHeight = Math.min(containerHeight, size.height);\n const ratio = Math.min(maxWidth / size.width, maxHeight / size.height);\n return { width: size.width * ratio, height: size.height * ratio };\n}\n\n/**\n * Whether a measured trigger rect can anchor the zoom-from-origin flight.\n * A trigger that is hidden (`display: none`, the `hidden` attribute),\n * detached or collapsed measures 0×0 at the viewport origin; a flight\n * aimed at it would shrink the slide into the top-left corner.\n */\nexport function isUsableOriginRect(\n rect: RectLike | null | undefined,\n): rect is RectLike {\n return (\n !!rect &&\n Number.isFinite(rect.left) &&\n Number.isFinite(rect.top) &&\n rect.width > 0 &&\n rect.height > 0\n );\n}\n\n/** Scale the closing slide shrinks to when it has no trigger to return to. */\nexport const CENTER_CLOSE_SCALE = 0.5;\n\n/**\n * Close transform for a slide without a usable origin (hidden or\n * collapsed trigger, no `lgSize`): shrink in place about the stage centre,\n * the mirror of the `lg-start-zoom` open. The runtime pairs it with the\n * `lg-close-to-center` class, which fades the slide out over the same\n * duration.\n */\nexport function getCenterCloseTransform(scale = CENTER_CLOSE_SCALE): string {\n return `translate3d(0, 0, 0) scale3d(${scale}, ${scale}, 1)`;\n}\n\nexport interface OriginTransformInput {\n /** Bounding rect of the trigger thumbnail image, viewport coordinates. */\n triggerRect: RectLike;\n\n /** Bounding rect of the gallery outer element, viewport coordinates. */\n containerRect: RectLike;\n\n /** Media container top offset (toolbar height), px. */\n top: number;\n\n /** Media container bottom offset (caption + thumb strip height), px. */\n bottom: number;\n\n /** Final displayed image size (see {@link fitImageSize}). */\n imageSize: ImageSize;\n}\n\n/**\n * CSS transform that places the (centered, final-size) slide image exactly\n * over the trigger thumbnail — the starting point of the zoom-from-origin\n * open animation and the end point of the close animation.\n */\nexport function getOriginTransform(input: OriginTransformInput): string {\n const { triggerRect, containerRect, top, bottom, imageSize } = input;\n\n const availableWidth = containerRect.width;\n const availableHeight = containerRect.height - (top + bottom);\n\n const x =\n (availableWidth - triggerRect.width) / 2 -\n triggerRect.left +\n containerRect.left;\n const y =\n (availableHeight - triggerRect.height) / 2 - triggerRect.top + top;\n\n const scaleX = triggerRect.width / imageSize.width;\n const scaleY = triggerRect.height / imageSize.height;\n\n return `translate3d(${-x}px, ${-y}px, 0) scale3d(${scaleX}, ${scaleY}, 1)`;\n}\n","/**\n * Built-in UI icon set: inline SVG strings, one per icon name, grouped\n * by the feature that renders them so bundlers ship only the groups a\n * consumer's plugins import. Pure string data — safe in this DOM-free\n * package. Runtimes render these when the consumer supplies no custom\n * icon for a name.\n *\n * The artwork is lightGallery's own icon set, carried over from the\n * 2.x icon font: each glyph's vector outline extracted from the font\n * and re-baselined onto a square viewBox (font ascent 960 on a 1024\n * em). Same shapes the library has always shipped — now crisp inline\n * SVGs that follow `currentColor`.\n */\n\n/** The icon-name contract shared by every runtime and plugin. */\nexport type LgIconName =\n | 'close'\n | 'prev'\n | 'next'\n | 'download'\n | 'maximize'\n | 'minimize'\n | 'more'\n | 'zoomIn'\n | 'zoomOut'\n | 'actualSize'\n | 'rotateLeft'\n | 'rotateRight'\n | 'flipHorizontal'\n | 'flipVertical'\n | 'share'\n | 'shareFacebook'\n | 'shareX'\n | 'sharePinterest'\n | 'autoplayPlay'\n | 'autoplayPause'\n | 'fullscreen'\n | 'fullscreenExit'\n | 'comment'\n | 'commentClose'\n | 'toggleThumbnails';\n\nexport const coreDefaultIcons = {\n close: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M810 664.667l-238-238 238-238-60-60-238 238-238-238-60 60 238 238-238 238 60 60 238-238 238 238z\"/></svg>',\n // Three dots for the toolbar's More options menu button.\n more: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><circle cx=\"232\" cy=\"512\" r=\"80\"/><circle cx=\"512\" cy=\"512\" r=\"80\"/><circle cx=\"792\" cy=\"512\" r=\"80\"/></svg>',\n prev: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M426.667 768q17.667 0 30.167-12.5t12.5-30.167q0-18-12.667-30.333l-225.667-225.667h665q17.667 0 30.167-12.5t12.5-30.167-12.5-30.167-30.167-12.5h-665l225.667-225.667q12.667-12.333 12.667-30.333 0-17.667-12.5-30.167t-30.167-12.5q-18 0-30.333 12.333l-298.667 298.667q-12.333 13-12.333 30.333t12.333 30.333l298.667 298.667q12.667 12.333 30.333 12.333z\"/></svg>',\n next: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M597.333 768q18 0 30.333-12.333l298.667-298.667q12.333-12.333 12.333-30.333t-12.333-30.333l-298.667-298.667q-12.333-12.333-30.333-12.333-18.333 0-30.5 12.167t-12.167 30.5q0 18 12.333 30.333l226 225.667h-665q-17.667 0-30.167 12.5t-12.5 30.167 12.5 30.167 30.167 12.5h665l-226 225.667q-12.333 12.333-12.333 30.333 0 18.333 12.167 30.5t30.5 12.167z\"/></svg>',\n download:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M170 128.667h684v-86h-684v86zM682 384.667l-170-172-170 172h128v426h84v-426h128z\"/></svg>',\n maximize:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M793.003 768l-225.835-225.835c-16.683-16.683-16.683-43.691 0-60.331s43.691-16.683 60.331 0l225.835 225.835v-153.003c0-23.552 19.115-42.667 42.667-42.667s42.667 19.115 42.667 42.667v256c0 5.803-1.152 11.307-3.243 16.341s-5.163 9.728-9.216 13.781c-0.043 0.043-0.043 0.043-0.085 0.085-3.925 3.925-8.619 7.083-13.781 9.216-5.035 2.091-10.539 3.243-16.341 3.243h-256c-23.552 0-42.667-19.115-42.667-42.667s19.115-42.667 42.667-42.667zM230.997 85.334l225.835 225.835c16.683 16.683 16.683 43.691 0 60.331s-43.691 16.683-60.331 0l-225.835-225.835v153.003c0 23.552-19.115 42.667-42.667 42.667s-42.667-19.115-42.667-42.667v-256c0-23.552 19.115-42.667 42.667-42.667h256c23.552 0 42.667 19.115 42.667 42.667s-19.115 42.667-42.667 42.667z\"/></svg>',\n minimize:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M700.331 554.667l225.835 225.835c16.683 16.683 16.683 43.691 0 60.331s-43.691 16.683-60.331 0l-225.835-225.835v153.003c0 23.552-19.115 42.667-42.667 42.667s-42.667-19.115-42.667-42.667v-256c0-5.803 1.152-11.307 3.243-16.341s5.163-9.728 9.216-13.781c0.043-0.043 0.043-0.043 0.085-0.085 3.925-3.925 8.619-7.083 13.781-9.216 5.035-2.091 10.539-3.243 16.341-3.243h256c23.552 0 42.667 19.115 42.667 42.667s-19.115 42.667-42.667 42.667zM158.165 12.502l225.835 225.835v-153.003c0-23.552 19.115-42.667 42.667-42.667s42.667 19.115 42.667 42.667v256c0 5.803-1.152 11.307-3.243 16.341s-5.163 9.728-9.216 13.781c-0.043 0.043-0.043 0.043-0.085 0.085-4.096 4.053-8.789 7.125-13.781 9.216-5.035 2.091-10.539 3.243-16.341 3.243h-256c-23.552 0-42.667-19.115-42.667-42.667s19.115-42.667 42.667-42.667h153.003l-225.835-225.835c-16.683-16.683-16.683-43.691 0-60.331s43.691-16.683 60.331 0z\"/></svg>',\n} as const;\n\nexport const zoomDefaultIcons = {\n zoomIn: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M512 512.667h-86v-86h-42v86h-86v42h86v86h42v-86h86v-42zM406 340.667q80 0 136 56t56 136-56 136-136 56-136-56-56-136 56-136 136-56zM662 340.667l212-212-64-64-212 212v34l-12 12q-76-66-180-66-116 0-197 80t-81 196 81 197 197 81 196-81 80-197q0-104-66-180l12-12h34z\"/></svg>',\n zoomOut:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M298 554.667h214v-42h-214v42zM406 340.667q80 0 136 56t56 136-56 136-136 56-136-56-56-136 56-136 136-56zM662 340.667l212-212-64-64-212 212v34l-12 12q-76-66-180-66-116 0-197 80t-81 196 81 197 197 81 196-81 80-197q0-104-66-180l12-12h34z\"/></svg>',\n actualSize:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M384 853.334h426.667q53 0 90.5-37.5t37.5-90.5v-426.667q0-53-37.5-90.5t-90.5-37.5h-426.667q-53 0-90.5 37.5t-37.5 90.5v426.667q0 53 37.5 90.5t90.5 37.5zM170.667 675.334v-547.333q0-17.667 12.5-30.167t30.167-12.5h547.333q-13.333-37.667-46.333-61.5t-74.333-23.833h-426.667q-53 0-90.5 37.5t-37.5 90.5v426.667q0 41.333 23.833 74.333t61.5 46.333zM810.667 768h-426.667q-17.667 0-30.167-12.5t-12.5-30.167v-426.667q0-17.667 12.5-30.167t30.167-12.5h426.667q17.667 0 30.167 12.5t12.5 30.167v426.667q0 17.667-12.5 30.167t-30.167 12.5z\"/></svg>',\n} as const;\n\nexport const rotateDefaultIcons = {\n rotateLeft:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M554 764.667q126-16 213-112t87-226-87-226-213-112v86q92 16 153 87t61 165-61 165-153 87v-166l-194 190 194 194v-132zM302 156.667l62 62q46-34 106-44v-86q-96 12-168 68zM260 384.667q10-58 42-106l-60-60q-56 74-68 166h86zM304 574.667q-36-52-44-106h-86q12 90 70 166z\"/></svg>',\n rotateRight:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M720 278.667q34 46 44 106h86q-12-92-68-166zM554 174.667q60 10 106 44l62-62q-72-56-168-68v86zM850 468.667h-86q-10 60-44 106l62 60q58-72 68-166zM664 702.667l-194-190v166q-92-16-153-87t-61-165 61-165 153-87v-86q-126 16-213 112t-87 226 87 226 213 112v132z\"/></svg>',\n flipHorizontal:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M896 554.667l-170-170v128h-300v84h300v128zM298 468.667v-128h300v-84h-300v-128l-170 170z\"/></svg>',\n flipVertical:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M384 810.667l170-170h-128v-300h-84v300h-128zM682 212.667h128l-170-170-170 170h128v300h84v-300z\"/></svg>',\n} as const;\n\nexport const shareDefaultIcons = {\n share: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M768 252.667c68 0 124-56 124-124s-56-126-124-126-124 58-124 126c0 10 0 20 2 28l-302 176c-24-22-54-34-88-34-70 0-128 58-128 128s58 128 128 128c34 0 64-12 88-34l300 174c-2 10-4 20-4 30 0 70 58 128 128 128s128-58 128-128-58-128-128-128c-34 0-64 14-88 36l-300-176c2-10 4-20 4-30s-2-20-4-30l304-176c22 20 52 32 84 32z\"/></svg>',\n shareFacebook:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M512 952.32c-271.462 0-491.52-220.058-491.52-491.52s220.058-491.52 491.52-491.52 491.52 220.058 491.52 491.52-220.058 491.52-491.52 491.52zM628.429 612.659h-73.882c-8.755 0-18.483-11.52-18.483-26.829v-53.35h92.416l-13.978-76.083h-78.438v-228.403h-87.194v228.403h-79.104v76.083h79.104v44.749c0 64.205 44.544 116.378 105.677 116.378h73.882v-80.947z\"/></svg>',\n shareX: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><circle cx=\"512\" cy=\"512\" r=\"491.52\"/><path fill=\"#fff\" transform=\"translate(227 224) scale(24)\" d=\"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z\"/></svg>',\n sharePinterest:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M512 952.32c-271.462 0-491.52-220.058-491.52-491.52s220.058-491.52 491.52-491.52 491.52 220.058 491.52 491.52-220.058 491.52-491.52 491.52zM545.638 344.32c-31.539 2.406-44.749 18.022-69.427 32.973-13.568-71.219-30.157-139.52-79.309-175.206-15.206 107.725 22.221 188.518 39.629 274.381-29.645 49.92 3.533 150.323 66.099 125.645 76.954-30.515-66.662-185.6 29.747-205.005 100.659-20.173 141.773 174.694 79.36 237.978-90.214 91.494-262.502 2.099-241.306-128.87 5.12-32 38.246-41.728 13.21-85.914-57.702 12.8-74.957 58.317-72.704 118.989 3.533 99.328 89.242 168.909 175.155 178.483 108.698 12.083 210.688-39.885 224.819-142.182 15.821-115.405-49.101-240.282-165.274-231.27z\"/></svg>',\n} as const;\n\nexport const autoplayDefaultIcons = {\n autoplayPlay:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M512 84.667q140 0 241 101t101 241-101 241-241 101-241-101-101-241 101-241 241-101zM512 852.667q176 0 301-125t125-301-125-301-301-125-301 125-125 301 125 301 301 125zM426 234.667v384l256-192z\"/></svg>',\n autoplayPause:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M554 256.667v340h86v-340h-86zM512 84.667q140 0 241 101t101 241-101 241-241 101-241-101-101-241 101-241 241-101zM512 852.667q176 0 301-125t125-301-125-301-301-125-301 125-125 301 125 301 301 125zM384 256.667v340h86v-340h-86z\"/></svg>',\n} as const;\n\nexport const fullscreenDefaultIcons = {\n fullscreen:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M598 724.667h212v-212h-84v128h-128v84zM726 212.667v128h84v-212h-212v84h128zM214 512.667v212h212v-84h-128v-128h-84zM298 340.667v-128h128v-84h-212v212h84z\"/></svg>',\n fullscreenExit:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M682 596.667h128v-84h-212v212h84v-128zM598 128.667v212h212v-84h-128v-128h-84zM342 596.667v128h84v-212h-212v84h128zM214 256.667v84h212v-212h-84v128h-128z\"/></svg>',\n} as const;\n\nexport const commentDefaultIcons = {\n comment:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M938.667 448.128v21.205c0 0.725-0.043 1.621-0.085 2.475-5.803 99.755-47.488 190.336-112.725 258.176-68.352 71.125-162.731 117.419-268.843 123.264-0.683 0.043-1.536 0.085-2.347 0.085h-20.864c-59.947 0.683-122.965-13.227-181.931-43.008-52.181-26.496-97.749-63.488-133.931-108.16-56.405-69.717-89.899-158.080-89.941-253.696-0.597-54.4 10.795-111.36 35.157-165.419l-75.605-226.859c-2.816-8.363-3.072-17.835 0-26.965 7.467-22.357 31.616-34.432 53.973-26.965l226.731 75.563c49.493-22.485 105.984-35.243 165.376-35.115 58.539 0.384 115.797 13.141 168.149 36.949 81.579 37.163 151.040 101.248 193.749 186.667 27.477 53.291 43.307 115.84 43.136 181.803zM853.333 447.872c0.128-52.267-12.459-101.333-33.664-142.464-34.176-68.352-88.832-118.827-153.259-148.139-41.387-18.859-86.827-28.971-133.376-29.269-52.096-0.128-101.163 12.459-142.293 33.664-10.624 5.504-22.528 6.059-33.067 2.56l-162.261-54.101 54.101 162.261c3.755 11.221 2.56 22.912-2.389 32.725-23.552 46.677-34.304 96.171-33.792 142.421 0.043 76.331 26.411 145.92 70.955 200.917 28.629 35.371 64.768 64.725 106.24 85.76 46.592 23.552 96.085 34.304 142.336 33.792h19.456c83.712-4.565 158.037-41.003 212.011-97.152 51.285-53.376 84.139-124.416 89.003-202.795z\"/></svg>',\n commentClose:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M810 664.667l-238-238 238-238-60-60-238 238-238-238-60 60 238 238-238 238 60 60 238-238 238 238z\"/></svg>',\n} as const;\n\nexport const thumbnailDefaultIcons = {\n toggleThumbnails:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M682 84.667v172h172v-172h-172zM682 340.667v172h172v-172h-172zM426 596.667v172h172v-172h-172zM682 768.667h172v-172h-172v172zM426 340.667v172h172v-172h-172zM170 340.667v172h172v-172h-172zM170 84.667v172h172v-172h-172zM426 84.667v172h172v-172h-172zM170 596.667v172h172v-172h-172z\"/></svg>',\n} as const;\n","/**\n * Toolbar overflow: when the toolbar's icon buttons do not fit on one row\n * beside the counter, the lowest-priority buttons move into a \"More\n * options\" menu. Pure layout arithmetic over measured widths; each runtime\n * measures its own DOM, applies the result and renders the menu.\n */\n\n/** Priority of a button that never moves into the menu (close). */\nexport const TOOLBAR_PINNED = Number.POSITIVE_INFINITY;\n\n/** Priority of a button the table does not know (custom plugin buttons). */\nexport const TOOLBAR_DEFAULT_PRIORITY = 20;\n\n/**\n * Higher stays in the row longer. Keyed by the class each button carries\n * in every runtime; the first matching class wins.\n */\nconst PRIORITY_BY_CLASS: ReadonlyArray<readonly [string, number]> = [\n ['lg-close', TOOLBAR_PINNED],\n ['lg-share', 30],\n ['lg-autoplay-button', 30],\n ['lg-download', 30],\n ['lg-fullscreen', 20],\n ['lg-toggle-thumb', 20],\n ['lg-comment-toggle', 20],\n ['lg-maximize', 10],\n ['lg-rotate-left', 10],\n ['lg-rotate-right', 10],\n ['lg-flip-hor', 10],\n ['lg-flip-ver', 10],\n // Gesture duplicates go first: pinch and double-tap do the same.\n ['lg-zoom-in', 0],\n ['lg-zoom-out', 0],\n ['lg-actual-size', 0],\n];\n\n/** Overflow priority of a toolbar button from its class names. */\nexport function getToolbarItemPriority(classList: Iterable<string>): number {\n const classes = new Set(classList);\n for (const [className, priority] of PRIORITY_BY_CLASS) {\n if (classes.has(className)) {\n return priority;\n }\n }\n return TOOLBAR_DEFAULT_PRIORITY;\n}\n\nexport interface ToolbarOverflowItem {\n /** Measured width, px. */\n width: number;\n /** From {@link getToolbarItemPriority}; higher stays longer. */\n priority: number;\n}\n\nexport interface ToolbarOverflowInput {\n /** Width of the toolbar row, px. */\n available: number;\n /** Width taken by content that never moves (the counter), px. */\n reserved: number;\n /** Width of the More button, px. */\n moreWidth: number;\n /** The toolbar's icon buttons, in DOM order. */\n items: readonly ToolbarOverflowItem[];\n}\n\n/**\n * Indices (in DOM order) of the buttons that move into the menu; empty\n * when everything fits, or when the toolbar has no width yet (not laid\n * out). Lowest priority moves first; among equals, the button later in\n * DOM order goes first, which is the one furthest from the close button.\n * The More button's own width is paid as soon as anything moves.\n */\nexport function getToolbarOverflow({\n available,\n reserved,\n moreWidth,\n items,\n}: ToolbarOverflowInput): number[] {\n if (available <= 0) {\n return [];\n }\n const total = items.reduce((sum, item) => sum + item.width, 0);\n if (reserved + total <= available) {\n return [];\n }\n const candidates = items\n .map((item, index) => ({ ...item, index }))\n .filter((item) => item.priority !== TOOLBAR_PINNED)\n .sort((a, b) => a.priority - b.priority || b.index - a.index);\n let used = reserved + moreWidth + total;\n const moved: number[] = [];\n for (const item of candidates) {\n if (used <= available) {\n break;\n }\n moved.push(item.index);\n used -= item.width;\n }\n return moved.sort((a, b) => a - b);\n}\n\n/**\n * Whether a click's event path runs through the toolbar. Clicks there are\n * controls, not a tap on the backdrop: Medium zoom closes on the latter\n * only. The path (`event.composedPath()`) still lists a More menu item the\n * click already removed from the document.\n */\nexport function isToolbarEventPath(path: readonly unknown[]): boolean {\n return path.some(\n (node) =>\n !!(\n node as { classList?: { contains(name: string): boolean } }\n ).classList?.contains('lg-toolbar'),\n );\n}\n\n/**\n * Class names of the backdrop around the slide, where a tap closes the\n * gallery (`closeOnTap`) and a drag starts a swipe.\n */\nconst BACKDROP_CLASS_NAMES = [\n 'lg-outer',\n 'lg-item',\n 'lg-img-wrap',\n 'lg-img-rotate',\n];\n\n/** What the dismissal of a toolbar menu reads from the dismissing press. */\nexport interface MenuDismissEvent {\n target: unknown;\n preventDefault(): void;\n stopPropagation(): void;\n}\n\n/**\n * A press outside an open toolbar menu (the More options menu, the share\n * dropdown) dismisses it. A press on a control passes through, so one\n * click on another toolbar button both dismisses the menu and runs the\n * button. A press on the backdrop around the slide is consumed instead:\n * there the gallery's own tap-to-close and drag would fire, and\n * dismissing a menu must not also close the gallery. Cancelling the\n * pointerdown suppresses the compatibility mouse events the vanilla\n * runtime listens to; stopping it keeps the pointer-driven runtimes'\n * handlers from arming. Returns whether the press was consumed.\n */\nexport function consumeBackdropPress(event: MenuDismissEvent): boolean {\n const classList = (\n event.target as {\n classList?: { contains(name: string): boolean };\n } | null\n )?.classList;\n if (\n !classList ||\n !BACKDROP_CLASS_NAMES.some((name) => classList.contains(name))\n ) {\n return false;\n }\n event.preventDefault();\n event.stopPropagation();\n return true;\n}\n","/**\n * Settle gate for a CSS transition: call back once the transition of\n * `property` on `element` has actually ended.\n *\n * A fixed timer measured from the moment the target value is applied\n * lands at the same wall-clock offset whether or not the transition has\n * started, but the transition only starts at the first style recalc\n * after the value lands — on a busy main thread (a gallery's first\n * layout, a big thumbnail decode) that can be well past the offset.\n * Anything gated on the fixed timer then fires mid-flight.\n *\n * Contract:\n * - No `transitionstart` within `fallbackMs` → the element is not\n * transitioning (reduced motion, identity transform, no CSS) and the\n * gate settles on the timer, exactly like the fixed timer did.\n * - `transitionstart` re-bases the timer on the real start; `transitionend`\n * settles immediately. Interrupted transitions (`transitioncancel`)\n * leave the timer running so a restart still settles in time.\n * - Events bubbling from descendants, or for other properties, are\n * ignored. The callback runs at most once.\n *\n * Returns a disposer; disposing after settle is a no-op.\n */\nexport interface TransitionSettleEvent {\n target: unknown;\n propertyName?: string;\n}\n\n/** Structural slice of a DOM element: headless carries no DOM lib. */\nexport interface TransitionSettleTarget {\n addEventListener(\n type: string,\n listener: (event: TransitionSettleEvent) => void,\n ): void;\n removeEventListener(\n type: string,\n listener: (event: TransitionSettleEvent) => void,\n ): void;\n}\n\nexport function onTransitionSettle(\n element: TransitionSettleTarget,\n property: string,\n fallbackMs: number,\n callback: () => void,\n): () => void {\n let settled = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const isOwn = (event: TransitionSettleEvent) =>\n event.target === element && event.propertyName === property;\n const dispose = () => {\n clearTimeout(timer);\n element.removeEventListener('transitionstart', onStart);\n element.removeEventListener('transitionend', onEnd);\n };\n const settle = () => {\n if (settled) {\n return;\n }\n settled = true;\n dispose();\n callback();\n };\n const onStart = (event: TransitionSettleEvent) => {\n if (isOwn(event)) {\n clearTimeout(timer);\n timer = setTimeout(settle, fallbackMs);\n }\n };\n const onEnd = (event: TransitionSettleEvent) => {\n if (isOwn(event)) {\n settle();\n }\n };\n element.addEventListener('transitionstart', onStart);\n element.addEventListener('transitionend', onEnd);\n timer = setTimeout(settle, fallbackMs);\n return () => {\n settled = true;\n dispose();\n };\n}\n","/**\n * Responsive image selection + decode gating (plan: responsive loading).\n *\n * The browser already picks a candidate natively when the runtimes render\n * `<picture>`/`srcset` — these helpers exist for the places that need the\n * DECISION as data: preload warming at the right resolution, tooling, and\n * the framework image-component recipes. The algorithm mirrors the HTML\n * spec's srcset selection closely enough to be deterministic and\n * unit-testable: parse candidates, derive the slot width from `sizes`,\n * scale by DPR, pick the smallest candidate that covers the target\n * (falling back to the largest available).\n */\n\nimport type { GalleryItem, ImageSources } from './items';\nimport { parseImageSize } from './origin';\n\nexport interface SrcsetCandidate {\n url: string;\n /** Width descriptor (`640w`) in px, if given. */\n width?: number;\n /** Density descriptor (`2x`), if given; bare candidates read as 1x. */\n density?: number;\n}\n\nexport interface Viewport {\n width: number;\n height: number;\n /** devicePixelRatio; defaults to 1. */\n dpr?: number;\n}\n\n/** Parse a `srcset` attribute string into candidates. Malformed entries\n * are skipped rather than thrown — item data is author-provided. */\nexport function parseSrcset(srcset: string | undefined): SrcsetCandidate[] {\n const candidates: SrcsetCandidate[] = [];\n if (typeof srcset !== 'string') {\n return candidates;\n }\n for (const entry of srcset.split(',')) {\n const parts = entry.trim().split(/\\s+/);\n const url = parts[0];\n if (!url) {\n continue;\n }\n const descriptor = parts[1];\n if (!descriptor) {\n candidates.push({ url, density: 1 });\n continue;\n }\n const value = parseFloat(descriptor);\n if (Number.isNaN(value) || value <= 0) {\n continue;\n }\n if (descriptor.endsWith('w')) {\n candidates.push({ url, width: value });\n } else if (descriptor.endsWith('x')) {\n candidates.push({ url, density: value });\n }\n }\n return candidates;\n}\n\n/**\n * Effective slot width (px) from a `sizes` attribute for a viewport.\n * Supports the common authored forms deterministically: comma-separated\n * `(min-width: Npx) <len>` / `(max-width: Npx) <len>` clauses with a\n * bare `<len>` default, where `<len>` is `px` or `vw`. The first\n * matching clause wins (spec order). Unsupported conditions are skipped;\n * no match falls back to the full viewport width (`100vw`, the spec\n * default).\n */\nexport function resolveSizes(\n sizes: string | undefined,\n viewportWidth: number,\n): number {\n if (!sizes) {\n return viewportWidth;\n }\n const toLength = (raw: string): number | null => {\n const value = parseFloat(raw);\n if (Number.isNaN(value)) {\n return null;\n }\n if (raw.endsWith('vw')) {\n return (value / 100) * viewportWidth;\n }\n if (raw.endsWith('px')) {\n return value;\n }\n return null;\n };\n for (const clause of sizes.split(',')) {\n const trimmed = clause.trim();\n if (!trimmed) {\n continue;\n }\n const condition = /^\\((min|max)-width:\\s*([\\d.]+)px\\)\\s+(\\S+)$/.exec(\n trimmed,\n );\n if (condition) {\n const bound = parseFloat(condition[2]!);\n const matches =\n condition[1] === 'min'\n ? viewportWidth >= bound\n : viewportWidth <= bound;\n if (!matches) {\n continue;\n }\n const length = toLength(condition[3]!);\n if (length !== null) {\n return length;\n }\n continue;\n }\n // Bare default clause (no condition).\n if (!trimmed.startsWith('(')) {\n const length = toLength(trimmed);\n if (length !== null) {\n return length;\n }\n }\n }\n return viewportWidth;\n}\n\n/** Whether a `<source media>` condition matches the viewport. Same\n * deterministic subset as {@link resolveSizes}: min/max-width in px;\n * unsupported conditions read as NOT matching. Absent media matches. */\nexport function matchesMedia(\n media: string | undefined,\n viewport: Viewport,\n): boolean {\n if (!media) {\n return true;\n }\n const condition = /^\\(\\s*(min|max)-width:\\s*([\\d.]+)px\\s*\\)$/.exec(\n media.trim(),\n );\n if (!condition) {\n return false;\n }\n const bound = parseFloat(condition[2]!);\n return condition[1] === 'min'\n ? viewport.width >= bound\n : viewport.width <= bound;\n}\n\nfunction pickFromCandidates(\n candidates: SrcsetCandidate[],\n slotWidth: number,\n dpr: number,\n): SrcsetCandidate | null {\n if (!candidates.length) {\n return null;\n }\n const widthCandidates = candidates\n .filter((c) => c.width !== undefined)\n .sort((a, b) => a.width! - b.width!);\n if (widthCandidates.length) {\n const target = slotWidth * dpr;\n return (\n widthCandidates.find((c) => c.width! >= target) ??\n widthCandidates[widthCandidates.length - 1]!\n );\n }\n const densityCandidates = [...candidates].sort(\n (a, b) => (a.density ?? 1) - (b.density ?? 1),\n );\n return (\n densityCandidates.find((c) => (c.density ?? 1) >= dpr) ??\n densityCandidates[densityCandidates.length - 1]!\n );\n}\n\nexport interface ResolvedImageSource {\n src: string;\n /** Intrinsic width (px) when the winning candidate declared one. */\n width?: number;\n /** The `<source>` entry that won, when selection went through\n * `sources` (picture semantics) rather than the item srcset. */\n source?: ImageSources;\n}\n\n/**\n * Deterministically resolve which image URL a viewport displays for an\n * item, mirroring picture/srcset semantics: the first matching\n * `sources[]` entry wins (spec order), then the item-level\n * `srcset`/`sizes`, then plain `src`. Returns null for items with no\n * image source at all.\n */\nexport function resolveImageSource(\n item: Pick<GalleryItem, 'src' | 'srcset' | 'sizes' | 'sources'>,\n viewport: Viewport,\n): ResolvedImageSource | null {\n const dpr = viewport.dpr && viewport.dpr > 0 ? viewport.dpr : 1;\n for (const source of item.sources ?? []) {\n if (!matchesMedia(source.media, viewport)) {\n continue;\n }\n const picked = pickFromCandidates(\n parseSrcset(source.srcset),\n resolveSizes(source.sizes, viewport.width),\n dpr,\n );\n if (picked) {\n return { src: picked.url, width: picked.width, source };\n }\n }\n if (item.srcset) {\n const picked = pickFromCandidates(\n parseSrcset(item.srcset),\n resolveSizes(item.sizes, viewport.width),\n dpr,\n );\n if (picked) {\n return { src: picked.url, width: picked.width };\n }\n }\n return item.src ? { src: item.src } : null;\n}\n\n/**\n * The width \"actual size\" zoom refers to. `img.naturalWidth` LIES under\n * `srcset`/`sizes`: w-descriptor selection density-corrects the\n * intrinsic size to roughly the layout slot — on phones that collapses\n * the actual-size scale to ~1 and kills double-tap/pinch zoom. The\n * resolution order mirrors what the item DECLARES before trusting the\n * element: explicit `width` (2.x `data-width`), the largest candidate\n * the srcset ladder can serve (first matching `sources[]` entry per\n * picture semantics, else the item srcset), the `lgSize` natural dims,\n * and only then the reported natural width. The declared tiers are what\n * make optimizer components (next/image, NuxtImg, NgOptimizedImage) —\n * which manage their own srcset — zoomable to full resolution.\n */\nexport function getActualSizeWidth(\n item: Pick<GalleryItem, 'width' | 'srcset' | 'sources' | 'lgSize'>,\n viewport: Viewport,\n naturalWidth: number,\n): number {\n if (item.width) {\n const declared = parseFloat(item.width);\n if (!Number.isNaN(declared) && declared > 0) {\n return declared;\n }\n }\n let candidates: SrcsetCandidate[] = [];\n // Author data: a runtime may hand over `sources` before it has been\n // normalised (a raw `data-sources` JSON string) — never iterate that.\n const sources = Array.isArray(item.sources) ? item.sources : [];\n for (const source of sources) {\n if (matchesMedia(source.media, viewport)) {\n candidates = parseSrcset(source.srcset);\n break;\n }\n }\n if (!candidates.length && item.srcset) {\n candidates = parseSrcset(item.srcset);\n }\n const widths = candidates\n .map((candidate) => candidate.width)\n .filter((width): width is number => width !== undefined);\n if (widths.length) {\n return Math.max(...widths);\n }\n const natural = parseImageSize(item.lgSize, viewport.width);\n if (natural && natural.width > 0) {\n return natural.width;\n }\n return naturalWidth;\n}\n\n/**\n * How long a slide waits on `img.decode()` before completing anyway —\n * the gate must never strand a slide on a browser that rejects or\n * stalls decode (huge images evict decoded data; some UAs reject on\n * detached nodes).\n */\nexport const DECODE_TIMEOUT_MS = 500;\n\n/**\n * Decode gate: resolve when the image is safe to paint — after\n * `decode()` settles (success OR rejection; rejection still means the\n * data arrived) or after the timeout, whichever is first. Browsers\n * without `decode()` resolve immediately (the load event already\n * fired). Never rejects.\n */\nexport function awaitDecode(\n img: { decode?: () => Promise<void> },\n timeoutMs: number = DECODE_TIMEOUT_MS,\n): Promise<void> {\n if (typeof img.decode !== 'function') {\n return Promise.resolve();\n }\n return new Promise((resolve) => {\n let done = false;\n const finish = () => {\n if (!done) {\n done = true;\n clearTimeout(timer);\n resolve();\n }\n };\n const timer = setTimeout(finish, timeoutMs);\n img.decode!().then(finish, finish);\n });\n}\n","/**\n * Rolling-window velocity tracking. Release decisions must read the\n * velocity of the gesture's final instant, not its whole-gesture\n * average: a drag that pauses and then flicks reads fast, and a drag\n * that ends resting reads zero. Sessions push a sample per move; the\n * release reads the window ending at the release timestamp.\n */\n\nexport interface VelocitySample {\n x: number;\n y: number;\n /** Timestamp in ms (same clock as the release read). */\n t: number;\n}\n\nexport interface Velocity {\n /** px/ms, signed. */\n x: number;\n y: number;\n}\n\n/** How far back a release looks when reading the gesture velocity. */\nexport const VELOCITY_WINDOW_MS = 100;\n\n/** Below this displacement (px) an axis reads as at rest. */\nconst MIN_DISPLACEMENT = 1;\n\n/** Below this span (ms) the window cannot measure reliably. */\nconst MIN_WINDOW_SPAN_MS = 5;\n\n/**\n * Append a sample, pruning everything older than the window — the\n * buffer stays a handful of entries regardless of gesture length.\n */\nexport function pushVelocitySample(\n samples: readonly VelocitySample[],\n sample: VelocitySample,\n windowMs: number = VELOCITY_WINDOW_MS,\n): VelocitySample[] {\n return [...samples.filter((s) => sample.t - s.t <= windowMs), sample];\n}\n\n/**\n * Velocity (px/ms per axis) over the samples inside the window ending\n * at `releaseTime`. Fewer than two recent samples — the finger rested\n * before lifting — reads as zero, as does sub-pixel drift.\n */\nexport function getWindowedVelocity(\n samples: readonly VelocitySample[],\n releaseTime: number,\n windowMs: number = VELOCITY_WINDOW_MS,\n): Velocity {\n const recent = samples.filter((s) => releaseTime - s.t <= windowMs);\n if (recent.length < 2) {\n return { x: 0, y: 0 };\n }\n const first = recent[0]!;\n const last = recent[recent.length - 1]!;\n const dt = last.t - first.t;\n if (dt < MIN_WINDOW_SPAN_MS) {\n return { x: 0, y: 0 };\n }\n const dx = last.x - first.x;\n const dy = last.y - first.y;\n return {\n x: Math.abs(dx) > MIN_DISPLACEMENT ? dx / dt : 0,\n y: Math.abs(dy) > MIN_DISPLACEMENT ? dy / dt : 0,\n };\n}\n","import { LightGallery } from './lightgallery';\nimport { VideoSource } from './plugins/video/types';\n\n/**\n * List of lightGallery events\n * All events should be documented here\n * Below interfaces are used to build the website documentations\n * */\nexport const lGEvents: {\n [key: string]: string;\n} = {\n afterAppendSlide: 'lgAfterAppendSlide',\n init: 'lgInit',\n hasVideo: 'lgHasVideo',\n containerResize: 'lgContainerResize',\n updateSlides: 'lgUpdateSlides',\n afterAppendSubHtml: 'lgAfterAppendSubHtml',\n beforeOpen: 'lgBeforeOpen',\n afterOpen: 'lgAfterOpen',\n slideItemLoad: 'lgSlideItemLoad',\n beforeSlide: 'lgBeforeSlide',\n afterSlide: 'lgAfterSlide',\n posterClick: 'lgPosterClick',\n dragStart: 'lgDragStart',\n dragMove: 'lgDragMove',\n dragEnd: 'lgDragEnd',\n beforeNextSlide: 'lgBeforeNextSlide',\n beforePrevSlide: 'lgBeforePrevSlide',\n beforeClose: 'lgBeforeClose',\n afterClose: 'lgAfterClose',\n rotateLeft: 'lgRotateLeft',\n rotateRight: 'lgRotateRight',\n flipHorizontal: 'lgFlipHorizontal',\n flipVertical: 'lgFlipVertical',\n autoplay: 'lgAutoplay',\n autoplayStart: 'lgAutoplayStart',\n autoplayStop: 'lgAutoplayStop',\n};\n\n// Follow the below format for the event documentation\n// @method is the method name when event is used with Angular/React components\n\n/**\n * Fired only once when lightGallery is initialized\n * @name lgInit\n * @method onInit\n * @example\n * const lg = document.getElementById('custom-events-demo');\n * // Perform any action on lightGallery initialization.\n * // Init event returns the plugin instance that can be used to call any lightGalley public method\n * let pluginInstance = null;\n * lg.addEventListener('lgInit', (event) => {\n * pluginInstance = event.detail.instance;\n * });\n * lightGallery(lg);\n * @see <a href=\"/docs/methods/\">Methods</a>\n */\nexport interface InitDetail {\n /**\n * lightGallery plugin instance\n */\n instance: LightGallery;\n}\n\n/**\n * Fired when the slide content has been inserted into it's slide container.\n * @name lgAfterAppendSlide\n * @method onAfterAppendSlide\n */\nexport interface AfterAppendSlideEventDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired immediately before opening the gallery\n * @name lgBeforeOpen\n * @method onBeforeOpen\n */\nexport interface BeforeOpenDetail {}\n\n/**\n * Fired immediately after opening the gallery\n * @name lgAfterOpen\n * @method onAfterOpen\n */\nexport interface AfterOpenDetail {}\n\n/**\n * Fired once the media inside the slide has been completely loaded .\n * @name lgSlideItemLoad\n * @method onSlideItemLoad\n */\nexport interface SlideItemLoadDetail {\n /**\n * Index of the slide\n */\n index: number;\n /**\n * For the first slide, lightGallery adds some delay for displaying the loaded slide item.\n * This delay is required for the transition effect when the slide item is displayed\n * Respect the delay when you use this event\n */\n delay: number;\n\n // Will be true for the first slide\n isFirstSlide: boolean;\n}\n\n/**\n * Fired immediately before each slide transition.\n * @name lgBeforeSlide\n * @method onBeforeSlide\n * @example\n * const lg = document.getElementById('custom-events-demo');\n * // Perform any action before each slide transition\n * lg.addEventListener('lgBeforeSlide', (event) => {\n * const { index, prevIndex } = event.detail;\n * alert(index, prevIndex);\n * });\n * lightGallery(lg);\n */\nexport interface BeforeSlideDetail {\n /**\n * Index of the previous slide\n */\n prevIndex: number;\n /**\n * Index of the slide\n */\n index: number;\n /**\n * true if slide function called via touch event or mouse drag\n */\n fromTouch: boolean;\n /**\n * true if slide function called via thumbnail click\n */\n fromThumb: boolean;\n}\n\n/**\n * Fired immediately after each slide transition.\n * @name lgAfterSlide\n * @method onAfterSlide\n */\nexport interface AfterSlideDetail {\n /**\n * Index of the previous slide\n */\n prevIndex: number;\n /**\n * Index of the slide\n */\n index: number;\n /**\n * true if slide function called via touch event or mouse drag\n */\n fromTouch: boolean;\n /**\n * true if slide function called via thumbnail click\n */\n fromThumb: boolean;\n}\n\n/**\n * Fired when the video poster is clicked.\n * @name lgPosterClick\n * @method onPosterClick\n */\nexport interface PosterClickDetail {}\n\n/**\n * Fired when the drag event to move to different slide starts.\n * @name lgDragStart\n * @method onDragStart\n */\nexport interface DragStartDetail {}\n\n/**\n * Fired periodically during the drag operation.\n * @name lgDragMove\n * @method onDragMove\n */\nexport interface DragMoveDetail {}\n\n/**\n * Fired when the user has finished the drag operation\n * @name lgDragEnd\n * @method onDragEnd\n */\nexport interface DragEndDetail {}\n\n/**\n * Fired immediately before the start of the close process.\n * @name lgBeforeClose\n * @method onBeforeClose\n */\nexport interface BeforeCloseDetail {}\n\n/**\n * Fired immediately once lightGallery is closed.\n * @name lgAfterClose\n * @method onAfterClose\n */\nexport interface AfterCloseDetail {\n /**\n * lightGallery plugin instance\n */\n instance: LightGallery;\n}\n\n/**\n * Fired immediately before each \"next\" slide transition\n * @name lgBeforeNextSlide\n * @method onBeforeNextSlide\n */\nexport interface BeforeNextSlideDetail {\n /**\n * Index of the slide\n */\n index: number;\n /**\n * true if slide function called via touch event or mouse drag\n */\n fromTouch: boolean;\n}\n\n/**\n * Fired immediately before each \"prev\" slide transition\n * @name lgBeforePrevSlide\n * @method onBeforePrevSlide\n */\nexport interface BeforePrevSlideDetail {\n /**\n * Index of the slide\n */\n index: number;\n /**\n * true if slide function called via touch event or mouse drag\n */\n fromTouch: boolean;\n}\n\n/**\n * Fired when the sub-html content (ex : title/ description) has been appended into the slide.\n * @name lgAfterAppendSubHtml\n * @method onAfterAppendSubHtml\n */\nexport interface AfterAppendSubHtmlDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired when the lightGallery container has been resized.\n * @name lgContainerResize\n * @method onContainerResize\n */\nexport interface ContainerResizeDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired when lightGallery detects video slide\n * @name lgHasVideo\n * @method onHasVideo\n */\nexport interface HasVideoDetail {\n /**\n * Index of the slide,\n */\n index: number;\n /**\n * Video source\n */\n src: string;\n /**\n * HTML5 video source if available\n * <p>\n HTML5 video source = source: {\n src: string;\n type: string;\n }[];\n attributes: HTMLVideoElement;\n * </p>\n */\n html5Video: VideoSource;\n /**\n * True if video has poster\n */\n hasPoster: boolean;\n}\n\n/**\n * Fired when the image is rotated in anticlockwise direction\n * @name lgRotateLeft\n * @method onRotateLeft\n */\nexport interface RotateLeftDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired when the image is rotated in clockwise direction\n * @name lgRotateRight\n * @method onRotateRight\n */\nexport interface RotateRightDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired when the image is flipped horizontally\n * @name lgFlipHorizontal\n * @method onFlipHorizontal\n */\nexport interface FlipHorizontalDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired when the image is flipped vertically\n * @name lgFlipVertical\n * @method onFlipVertical\n */\nexport interface FlipVerticalDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n","import { VirtualizationSettings } from '@lightgallery/headless';\n\nimport { LgIcons } from './lg-icons';\nimport { GalleryItem } from './lg-utils';\nimport { LgQuery } from './lgQuery';\nimport { LightGallery } from './lightgallery';\nimport { AutoplaySettings } from './plugins/autoplay/lg-autoplay-settings';\nimport { CommentSettings } from './plugins/comment/lg-comment-settings';\nimport { FullscreenSettings } from './plugins/fullscreen/lg-fullscreen-settings';\nimport { HashSettings } from './plugins/hash/lg-hash-settings';\nimport { JustifiedSettings } from './plugins/justified/lg-justified-settings';\nimport { MediumZoomSettings } from './plugins/mediumZoom/lg-medium-zoom-settings';\nimport { PagerSettings } from './plugins/pager/lg-pager-settings';\nimport { RotateSettings } from './plugins/rotate/lg-rotate-settings';\nimport { ShareSettings } from './plugins/share/lg-share-settings';\nimport { ThumbnailsSettings } from './plugins/thumbnail/lg-thumbnail-settings';\nimport { VideoSettings } from './plugins/video/lg-video-settings';\nimport { ZoomSettings } from './plugins/zoom/lg-zoom-settings';\n\ntype LightGalleryCoreMobileSettings = Exclude<\n LightGalleryCoreSettings,\n 'mobileSettings'\n>;\n\n// @todo use separate mobile settings for plugins\nexport interface MobileSettings\n extends LightGalleryCoreMobileSettings,\n Partial<ZoomSettings>,\n Partial<ThumbnailsSettings>,\n Partial<VideoSettings>,\n Partial<AutoplaySettings>,\n Partial<CommentSettings>,\n Partial<FullscreenSettings>,\n Partial<HashSettings>,\n Partial<PagerSettings>,\n Partial<RotateSettings>,\n Partial<ShareSettings> {}\n\nexport interface LightGalleryCoreStrings {\n closeGallery: string;\n toggleMaximize: string;\n previousSlide: string;\n nextSlide: string;\n download: string;\n playVideo: string;\n mediaLoadingFailed: string;\n /** Accessible name of the gallery dialog when `ariaLabelledby` is not set. */\n galleryLabel: string;\n /**\n * Template announced to assistive technology on every slide change.\n * `{index}` and `{total}` are replaced with the 1-based slide position\n * and the slide count; the slide caption, when present, is appended.\n */\n slideAnnouncement: string;\n /** Label of the toolbar's More options menu button. */\n moreOptions: string;\n\n // Plugin labels: every user-facing string lives in this one contract.\n // The legacy per-plugin *PluginStrings objects remain as deprecated\n // aliases, an explicitly set legacy key wins.\n /** Share plugin: share button label. */\n share: string;\n /** Thumbnail plugin: strip toggle button label. */\n toggleThumbnails: string;\n /** Autoplay plugin: slideshow toggle button label. */\n toggleAutoplay: string;\n /** Fullscreen plugin: fullscreen toggle button label. */\n toggleFullscreen: string;\n /** Zoom plugin: zoom-in button label. */\n zoomIn: string;\n /** Zoom plugin: zoom-out button label. */\n zoomOut: string;\n /** Zoom plugin: actual-size button label. */\n viewActualSize: string;\n /** Rotate plugin: rotate-left button label. */\n rotateLeft: string;\n /** Rotate plugin: rotate-right button label. */\n rotateRight: string;\n /** Rotate plugin: horizontal flip button label. */\n flipHorizontal: string;\n /** Rotate plugin: vertical flip button label. */\n flipVertical: string;\n /** Comment plugin: comments toggle button label. */\n toggleComments: string;\n}\n\nexport type LightGalleryAllSettings = LightGalleryCoreSettings &\n ZoomSettings &\n ThumbnailsSettings &\n VideoSettings &\n AutoplaySettings &\n CommentSettings &\n FullscreenSettings &\n HashSettings &\n JustifiedSettings &\n PagerSettings &\n RotateSettings &\n ShareSettings &\n MediumZoomSettings;\n\n// User-facing input: everything optional, strings mergeable per-key\n// (headless UserSettings parity, a partial strings object merges over\n// the defaults instead of replacing the whole contract).\nexport type LightGallerySettings = Partial<\n Omit<LightGalleryAllSettings, 'strings'>\n> & { strings?: Partial<LightGalleryCoreStrings> };\n\nexport interface LightGalleryCoreSettings {\n /**\n * Type of transition between images.\n */\n mode:\n | 'lg-slide'\n | 'lg-fade'\n | 'lg-zoom-in'\n | 'lg-zoom-in-big'\n | 'lg-zoom-out'\n | 'lg-zoom-out-big'\n | 'lg-zoom-out-in'\n | 'lg-zoom-in-out'\n | 'lg-soft-zoom'\n | 'lg-scale-up'\n | 'lg-slide-circular'\n | 'lg-slide-circular-vertical'\n | 'lg-slide-vertical'\n | 'lg-slide-vertical-growth'\n | 'lg-slide-skew-only'\n | 'lg-slide-skew-only-rev'\n | 'lg-slide-skew-only-y'\n | 'lg-slide-skew-only-y-rev'\n | 'lg-slide-skew'\n | 'lg-slide-skew-rev'\n | 'lg-slide-skew-cross'\n | 'lg-slide-skew-cross-rev'\n | 'lg-slide-skew-ver'\n | 'lg-slide-skew-ver-rev'\n | 'lg-slide-skew-ver-cross'\n | 'lg-slide-skew-ver-cross-rev'\n | 'lg-lollipop'\n | 'lg-lollipop-rev'\n | 'lg-rotate'\n | 'lg-rotate-rev'\n | 'lg-tube';\n\n /**\n * Slide animation CSS easing property\n */\n easing: string;\n\n /**\n *Transition duration (in ms).\n */\n speed: number;\n\n /**\n * If you are using lightGallery for commercial projects, you need to purchase a commercial license\n * to get the license key. For projects that are compatible with GPLv3 license,\n * please contact us for getting a license key at <a href=\"mailto:contact@lightgalleryjs.com\">contact@lightgalleryjs.com</a>.\n * If you want to test lightGallery before purchasing a commercial license, you can\n * use `0000-0000-000-0000` as a temporary license key. It does not limit any\n * feature; it only logs a console warning. lightGallery 3 keys start with `LIG`;\n * a key from v1 or v2 logs a warning asking you to upgrade.\n * See <a href=\"/docs/license/\">License</a>.\n */\n\n licenseKey: string;\n\n /**\n * Height of the gallery.\n * example '100%' , '300px'\n */\n height: string;\n\n /**\n * Width of the gallery.\n * example '100%' , '300px'\n */\n width: string;\n\n /**\n * Add custom class for gallery container\n * This can be used to set different style for different galleries\n */\n addClass: string;\n\n /**\n * Start animation class for the gallery.\n * @description\n * <ul>\n * <li>startClass will be empty zoomFromOrigin is true.</li>\n * <li>This can be used to change the starting effect when the image is loaded</li>\n * <li>This is also applied when navigating to new slides</li>\n * </ul>\n */\n startClass: string;\n\n /**\n * Enable zoom from origin effect.\n * @description You need to know the original image size upfront and provide it via data-lg-size attribute as <code> data-lg-size=\"1920-1280</code>\"\n *\n * If you don't know, the size of a few images in the list, you can skip the data-lg-size attribute for the particular slides,\n * lightGallery will show the default animation if data-lg-size is not available\n *\n * If you are using responsive images,\n * you can pass a comma separated list of sizes combined with a max-width (up to what size the particular image should be used)\n *\n * example -\n * <code> data-lg-size=\"240-160-375, 400-267-480, 1600-1067\"\n * data-responsive=\"img-240.jpg 375, img-400.jpg 480\"\n * data-src=\"img-1600.jpg\" </code>\n *\n * In the above example, upto 375 width img.240.jpg and lg-size 240-160 will be used.\n * Similarly, upto 480 pixel width size 400-267 and img-400.jpg will be used\n * And above 480, lg-size 1600-1067 and img-1600.jpg will be used\n *\n * When the gallery closes on a slide that has no thumbnail to return to\n * (the trigger is hidden or collapsed, as with the overflow items behind a\n * \"+9 photos\" tile, it has no data-lg-size, or the gallery is dynamic), the\n * slide shrinks to the centre of the stage and fades out instead of flying\n * to the thumbnail.\n *\n * <ul>\n * <li>At the moment, zoomFromOrigin options is supported only for image slides.</li>\n * <li>The opening flight is skipped if dynamic option is enabled or galleryID found in the URL.</li>\n * <li>startClass will be empty if zoomFromOrigin is true to avoid css conflicts.</li>\n * </ul>\n */\n zoomFromOrigin: boolean;\n\n /**\n * Zoom from image animation duration\n */\n startAnimationDuration: number;\n\n /**\n * Backdrop transition duration.\n * Note - Do not change the value of backdrop via css.\n */\n backdropDuration: number;\n\n /**\n * Configure where the gallery should be appended.\n * Useful to create inline galleries and more\n * It is an empty string in the default settings and later assigned to document.body to avoid accessing document for SSR\n */\n container: HTMLElement | (() => HTMLElement | null) | (string | null);\n\n /**\n * Delay for hiding gallery controls in ms.\n * Pass <code>0</code> if you don't want to hide the controls\n */\n hideBarsDelay: number;\n\n /**\n * Delay in hiding controls for the first time when gallery is opened\n */\n showBarsAfter: number;\n\n /**\n * Delay slide transitions.\n * @description This is useful if you want to do any action in the current slide before moving to next slide.\n * <section>\n * For example, fading out the captions before going to next slide.\n * <code>.lg-slide-progress</code> class name is added to the current slide immediately after calling the slide method.\n * But transition begins only after the delay\n * </section>\n */\n slideDelay: number;\n\n /**\n * Support legacy browsers\n * @description Currently this is used only for adding support to srcset attribute via picturefill library\n * If true lightGallery will show warning message to include picturefill library\n */\n supportLegacyBrowser: boolean;\n\n /**\n * If true, toolbar, captions and thumbnails will not overlap with media element\n * This will not effect thumbnails if animateThumb is false\n * Also, toggle thumbnails button is not displayed if allowMediaOverlap is false\n * <section>\n * Note - Changing the position of the media on every slide transition creates a flickering effect.\n * Therefore, the height of the caption is calculated dynamically, only once based on the first slide caption.\n * </section>\n * <section>\n * if you have dynamic captions for each media,\n * you can provide an appropriate height for the captions via allowMediaOverlap option\n * </section>\n */\n allowMediaOverlap: boolean;\n\n /**\n * Video max size.\n * @description This can be over-written by passing specific size via data-lg-size attribute\n * Recommended video resolution and & aspect ratios <a href=\"https://support.google.com/youtube/answer/6375112\">https://support.google.com/youtube/answer/6375112</a>\n */\n videoMaxSize: string;\n\n /**\n * Automatically load poster image for YouTube videos\n */\n loadYouTubePoster: boolean;\n\n /**\n * Height of the caption for calculating allowMediaOverlap positions\n * Note - this is only used to find the position of media item if allowMediaOverlap is true.\n * Not for setting height of the captions\n * Set 0 if you want to calculate the height of captions dynamically\n */\n defaultCaptionHeight: number;\n\n /**\n * aria-labelledby attribute fot gallery\n */\n ariaLabelledby: string;\n\n /**\n * aria-describedby attribute for gallery\n */\n ariaDescribedby: string;\n\n /**\n * Large-gallery virtualization. Off when undefined, the classic\n * behavior: every thumbnail renders and the mounted-slide window is\n * numberOfSlideItemsInDom.\n * @description slides overrides the mounted-slide pool size; thumbs\n * turns on thumbnail-strip windowing (only the visible thumbs plus an\n * overscan render, with spacers preserving the strip geometry), a\n * number is the overscan thumb count per side, 'auto' derives one\n * extra viewport per side. The window advances at commit points\n * (release, slide change, resize), never per pointer move.\n * See <a href=\"/docs/virtualization/\">Virtualization</a>.\n * @version V3.0.0\n */\n virtualization?: VirtualizationSettings;\n\n /**\n * Announce slide changes to assistive technology through a dedicated\n * polite live region (strings.slideAnnouncement + the slide caption).\n * @description While enabled, the counter and caption bar are not\n * separate live regions, the announcer is the single source of\n * slide-change announcements. Set to false to restore the previous\n * behavior (live counter and caption, no announcer).\n * See <a href=\"/docs/accessibility/\">Accessibility</a>.\n * @version V3.0.0\n */\n ariaAnnouncements: boolean;\n\n /**\n * Hide scrollbar when gallery is opened\n * @version V2.5.0\n */\n hideScrollbar: boolean;\n\n /**\n * Reset to previous scrollPosition when lightGallery is closed\n * @description By default, lightGallery doesn't hide the scrollbar for a smooth opening transition.\n * If a user changes the scroll position, lightGallery resets it to the previous value\n * @version V2.5.0\n */\n resetScrollPosition: boolean;\n\n /**\n * If false user won't be able to close the gallery at all\n * This is useful for creating inline galleries.\n */\n closable: boolean;\n\n /**\n * allows vertical drag/swipe to close gallery\n * <code>false</code> if option <code>closable</code> is <code>false</code>\n */\n swipeToClose: boolean;\n /**\n * allows clicks on black area to close gallery.\n */\n closeOnTap: boolean;\n\n /**\n * If false, close button won't be displayed.\n * Useful for creating inline galleries.\n */\n showCloseIcon: boolean;\n\n /**\n * Show maximize icon.\n * Useful for creating inline galleries.\n */\n showMaximizeIcon: boolean;\n\n /**\n * Keep the toolbar on one row.\n * @description When the toolbar buttons do not fit beside the counter,\n * the lowest-priority ones move into a \"More options\" menu. Set to\n * false to let the buttons wrap onto a second row instead.\n * See <a href=\"/docs/settings/#toolbarOverflow\">toolbarOverflow</a>.\n * @version V3.0.0\n */\n toolbarOverflow: boolean;\n\n /**\n * Show the toolbar buttons that repeat a touch gesture.\n * @description Zoom in, zoom out and actual size do what pinch and\n * double-tap already do. On by default, and turned off on touch\n * devices through mobileSettings.\n * See <a href=\"/docs/settings/#showGestureButtons\">showGestureButtons</a>.\n * @version V3.0.0\n */\n showGestureButtons: boolean;\n\n /**\n * If false, will disable the ability to loop back to the beginning of the gallery from the last slide.\n */\n loop: boolean;\n\n /**\n * Whether the LightGallery could be closed by pressing the \"Esc\" key.\n */\n escKey: boolean;\n\n /**\n * Enable keyboard navigation\n */\n keyPress: boolean;\n\n /**\n * Trap focus within the lightGallery\n * @version V2.5.0\n */\n trapFocus: boolean;\n\n /**\n * If false, prev/next buttons will not be displayed.\n */\n controls: boolean;\n\n /**\n * Enable slideEnd animation\n */\n slideEndAnimation: boolean;\n\n /**\n * If true, prev/next button will be hidden on first/last image.\n * @description Note - this option will be ignored if <code>loop</code> or <code>slideEndAnimation</code> is set to true\n */\n hideControlOnEnd: boolean;\n\n /**\n * ability to navigate to next/prev slides on mousewheel\n */\n mousewheel: boolean;\n\n /**\n * Gallery reading direction: keyboard arrows, swipe advance and the\n * slide/thumbnail transforms follow it. Visual mirroring is the\n * opt-in lg-rtl.css layer - load it whenever this resolves to 'rtl'.\n * 'auto' inherits the computed direction of the gallery element;\n * the default stays 'ltr' so upgrades never change behavior on\n * existing pages.\n * See <a href=\"/docs/localization-rtl/\">Localization &amp; RTL</a>.\n * @version V3.0.0\n */\n direction: 'ltr' | 'rtl' | 'auto';\n\n /**\n * Option to get captions from alt or title tags.\n */\n getCaptionFromTitleOrAlt: boolean;\n\n /**\n * control where the sub-html should be appended.\n * If you choose '.lg-outer', you are responsible for placing the div at the right position.\n * '.lg-outer' is useful if you want show custom HTML outside the normal gallery\n */\n appendSubHtmlTo: '.lg-sub-html' | '.lg-item' | '.lg-outer';\n\n /**\n * Set to true if the selector in \"data-sub-html\" should use the current item as its origin.\n */\n subHtmlSelectorRelative: boolean;\n\n /**\n * number of preload slides\n * @description will exicute only after the current slide is fully loaded.\n * for example, if you click on 4th image and if preload = 1 then 3rd slide and 5th\n * slide will be loaded in the background after the 4th slide is fully loaded..\n * if preload is 2 then 2nd 3rd 5th 6th slides will be preloaded.\n */\n preload: number;\n\n /**\n * Control how many slide items should be kept in dom at a time\n * @description To improve performance by reducing number of gallery items in the dom,\n * lightGallery keeps only the lowest possible number of slides in the dom at a time.\n * This has a minimum value of 3\n */\n numberOfSlideItemsInDom: number;\n\n /**\n * Custom selector property instead of direct children.\n * @description Based on your markup structure, you can specify custom selectors to fetch media data for the gallery\n * Pass \"this\" to select same element\n * You can also pass HTMLCollection directly\n * Example - '.my-selector' | '#my-selector' | this | document.querySelectorAll('.my-selector')\n */\n selector: string | HTMLCollection[];\n\n /**\n * By default selector element relative to the current gallery.\n * Instead of that you can tell lightGallery to select element relative to another element.\n * Example - '.my-selector-container' | '#my-selector-container'\n * In the code this become selector = document.querySelector(this.s.selectWithin ).querySelectorAll(this.s.selector);\n */\n selectWithin: string;\n\n /**\n * Custom html for next control\n */\n nextHtml: string;\n\n /**\n * Custom html for prev control\n */\n prevHtml: string;\n\n /**\n * specify which slide should load initially\n */\n index: number;\n\n /**\n * Set width for iframe.\n */\n iframeWidth: string;\n\n /**\n * Set height for iframe.\n */\n iframeHeight: string;\n\n /**\n * Set max width for iframe.\n */\n iframeMaxWidth: string;\n\n /**\n * Set max height for iframe.\n */\n iframeMaxHeight: string;\n\n /**\n * Enable download button.\n * @description By default download url will be taken from data-src/href attribute but it supports only for modern browsers.\n * If you want you can provide another url for download via data-download-url.\n * pass false in data-download-url if you want to hide download button for the particular slide.\n */\n download: boolean;\n\n /**\n * Whether to show total number of images and index number of currently displayed image.\n */\n counter: boolean;\n\n /**\n * Where the counter should be appended\n */\n appendCounterTo: string;\n\n /**\n * By setting the swipeThreshold (in px) you can set how far the user must swipe for the next/prev image.\n */\n swipeThreshold: number;\n\n /**\n * Release velocity (px/ms, measured over the gesture's final ~100ms)\n * at which a short swipe still changes slides, a flick.\n * @version V3.0.0\n */\n flickVelocity: number;\n\n /**\n * Pinching down on an un-zoomed image and releasing closes the\n * gallery (iOS Photos). Guarded: a pinch that went past fit zoom at\n * any point is a zoom correction and never closes. Requires\n * `closable` and the zoom plugin.\n * @version V3.0.0\n */\n pinchToClose: boolean;\n\n /**\n * Enables swipe support for touch devices\n */\n enableSwipe: boolean;\n\n /**\n * Enables desktop mouse drag support\n */\n enableDrag: boolean;\n\n /**\n * LightGallery can be instantiated and launched programmatically by setting this option to true and populating dynamicEl option (see below) with the definitions of images.\n */\n dynamic: boolean;\n\n /**\n * An array of objects (src, iframe, subHtml, thumb, poster, responsive, srcset sizes) representing gallery elements.\n */\n dynamicEl: GalleryItem[];\n\n /**\n * Fetch custom properties from the selector\n * @description this is useful for plugin development\n * By default lightGallery fetches and store all the props selectors to\n * reduce frequent dom interaction for fetching props every time.\n *\n * If you need any addition data to be fetched and stored in the galleryItems variable,\n * you can do this just by passing the prop names via extraProps\n * @example\n * HTML:\n * <div id=\"lightGallery\">\n * <a href=\"a.jpg\" data-custom-prop=\"abc\"><img src=\"thumb.jpg\" /></a>\n * <a href=\"a.jpg\" data-custom-prop=\"xyz\"><img src=\"thumb.jpg\" /></a>\n * </div>\n * JS:\n * lightGallery(document.getElementById('lightGallery'), {\n * extraProps: ['customProp']\n * })\n * // Note - If you are using dynamic mode, you can pass any custom prop in the galleryItem\n * lightGallery(document.getElementById('lightGallery'), {\n * dynamic: true,\n * dynamicEl: [{\n * src: 'img/img1.jpg',\n * customProp:'abc',\n * }]\n * })\n *\n */\n extraProps: string[];\n\n /**\n * Option to fetch different thumbnail image other than first image\n * @description If you want to use external image for thumbnail,\n * add the path of that image inside \"data-\" attribute\n * and set value of this option to the name of your custom attribute.\n *\n * @example\n * <div id=\"lightGallery\">\n * <a href=\"a.jpg\" data-external-thumb-image=\"images/externalThumb.jpg\" ><img src=\"thumb.jpg\" /></a>\n * </div>\n *\n * lightGallery(document.getElementById('lightGallery'), {\n * exThumbImage: 'data-external-thumb-image'\n * })\n */\n exThumbImage: string;\n\n /**\n * Function to detect mobile devices\n */\n isMobile?: () => boolean;\n\n /**\n * Separate settings for mobile devices\n * @description Note - this is applied only at the time of loading\n * by default controls and close buttons are disabled on mobile devices.\n * use this options if you want to enable them or change any other settings for mobile devices\n * Note - mobileSettings does not merge default values, You need to provide all mobileSettings including default values\n */\n mobileSettings: Partial<MobileSettings>;\n\n /**\n * Customize string.\n * @description This can be useful if you want to localize the lightGallery strings to other languages.\n * Use your own service to translate the strings and pass it via settings.strings\n * Every core and plugin label lives here; the per-plugin `*PluginStrings` objects are deprecated.\n * Strings merge per-key over the defaults, override only the keys\n * you need (the old provide-everything requirement is gone).\n * See <a href=\"/docs/localization-rtl/\">Localization &amp; RTL</a>.\n */\n strings: LightGalleryCoreStrings;\n\n /**\n * Custom icons: SVG markup per icon name, rendered instead of the\n * built-in SVG icon set, bring your own icons without touching CSS.\n * @description Omitted names keep the built-in icon. State-pair\n * buttons (`maximize`/`minimize`, `autoplayPlay`/`autoplayPause`,\n * `fullscreen`/`fullscreenExit`) need both names provided; a\n * half-provided pair keeps the built-in pair. Size and color follow\n * the button (`1em`/`currentColor`-friendly SVGs recommended).\n * See <a href=\"/docs/custom-icons/\">Custom icons</a>.\n * @version V3.0.0\n */\n icons: LgIcons;\n\n plugins: (new (instance: LightGallery, $LG: LgQuery) => any)[];\n}\n\nexport const lightGalleryCoreSettings: LightGalleryCoreSettings = {\n mode: 'lg-slide',\n easing: 'ease',\n speed: 400,\n licenseKey: '0000-0000-000-0000',\n height: '100%',\n width: '100%',\n addClass: '',\n startClass: 'lg-start-zoom',\n backdropDuration: 300,\n container: '',\n startAnimationDuration: 400,\n zoomFromOrigin: true,\n hideBarsDelay: 0,\n showBarsAfter: 10000,\n slideDelay: 0,\n supportLegacyBrowser: true,\n allowMediaOverlap: false,\n videoMaxSize: '1280-720',\n loadYouTubePoster: true,\n defaultCaptionHeight: 0,\n ariaLabelledby: '',\n ariaDescribedby: '',\n ariaAnnouncements: true,\n resetScrollPosition: true,\n hideScrollbar: false,\n closable: true,\n swipeToClose: true,\n closeOnTap: true,\n showCloseIcon: true,\n showMaximizeIcon: false,\n loop: true,\n escKey: true,\n keyPress: true,\n trapFocus: true,\n controls: true,\n slideEndAnimation: true,\n hideControlOnEnd: false,\n mousewheel: false,\n direction: 'ltr',\n getCaptionFromTitleOrAlt: true,\n appendSubHtmlTo: '.lg-sub-html',\n subHtmlSelectorRelative: false,\n preload: 2,\n numberOfSlideItemsInDom: 10,\n selector: '',\n selectWithin: '',\n nextHtml: '',\n prevHtml: '',\n index: 0,\n iframeWidth: '100%',\n iframeHeight: '100%',\n iframeMaxWidth: '100%',\n iframeMaxHeight: '100%',\n download: true,\n counter: true,\n appendCounterTo: '.lg-toolbar',\n swipeThreshold: 50,\n flickVelocity: 0.5,\n pinchToClose: true,\n enableSwipe: true,\n enableDrag: true,\n dynamic: false,\n dynamicEl: [],\n extraProps: [],\n exThumbImage: '',\n toolbarOverflow: true,\n showGestureButtons: true,\n isMobile: undefined,\n mobileSettings: {\n controls: false,\n showCloseIcon: false,\n download: false,\n showGestureButtons: false,\n } as MobileSettings,\n plugins: [],\n strings: {\n closeGallery: 'Close gallery',\n toggleMaximize: 'Toggle maximize',\n previousSlide: 'Previous slide',\n nextSlide: 'Next slide',\n download: 'Download',\n playVideo: 'Play video',\n mediaLoadingFailed: 'Oops... Failed to load content...',\n galleryLabel: 'Gallery',\n slideAnnouncement: 'Image {index} of {total}',\n moreOptions: 'More options',\n share: 'Share',\n toggleThumbnails: 'Toggle thumbnails',\n toggleAutoplay: 'Toggle Autoplay',\n toggleFullscreen: 'Toggle Fullscreen',\n zoomIn: 'Zoom in',\n zoomOut: 'Zoom out',\n viewActualSize: 'View actual size',\n rotateLeft: 'Rotate left',\n rotateRight: 'Rotate right',\n flipHorizontal: 'Flip horizontal',\n flipVertical: 'Flip vertical',\n toggleComments: 'Toggle Comments',\n } as LightGalleryCoreStrings,\n icons: {},\n};\n","import {\n consumeBackdropPress,\n getToolbarItemPriority,\n getToolbarOverflow,\n} from '@lightgallery/headless';\n\nexport interface ToolbarOverflowOptions {\n /** Id of the More options button; the menu id derives from it. */\n id: string;\n /** Accessible name of the More options button and its menu. */\n label: string;\n}\n\nconst schedule: (callback: () => void) => number =\n typeof requestAnimationFrame === 'function'\n ? (callback) => requestAnimationFrame(callback)\n : (callback) => window.setTimeout(callback, 16);\nconst cancel: (handle: number) => void =\n typeof cancelAnimationFrame === 'function'\n ? (handle) => cancelAnimationFrame(handle)\n : (handle) => window.clearTimeout(handle);\n\n/**\n * The toolbar's own icon buttons in DOM order: not the More button, not\n * the menu's items or the share dropdown's links, and not icons nested\n * inside another button.\n */\nfunction toolbarButtons(toolbar: Element, more: Element): HTMLElement[] {\n return Array.from(toolbar.querySelectorAll<HTMLElement>('.lg-icon')).filter(\n (button) =>\n button !== more &&\n !button.closest('.lg-toolbar-menu, .lg-dropdown') &&\n !button.parentElement?.closest('.lg-icon'),\n );\n}\n\n/** The icon a button currently shows (state pairs render both). */\nfunction visibleIconMarkup(button: HTMLElement): string {\n const icons = Array.from(button.querySelectorAll<HTMLElement>('.lg-ci'));\n if (!icons.length) {\n return button.querySelector('svg')?.outerHTML ?? '';\n }\n const shown =\n icons.find(\n (icon) => window.getComputedStyle(icon).display !== 'none',\n ) ?? icons[0];\n return shown.outerHTML;\n}\n\n/**\n * Keeps the toolbar on one row: measures it, hides the buttons that do\n * not fit (`data-lg-overflow`) and lists them in a \"More options\" menu\n * whose items trigger the hidden buttons, so every plugin's handlers keep\n * working unchanged.\n */\nexport class ToolbarOverflow {\n private readonly more: HTMLButtonElement;\n private menu: HTMLElement | null = null;\n private frame = 0;\n private movedSignature = '';\n private readonly widths = new WeakMap<HTMLElement, number>();\n private readonly resizeObserver?: ResizeObserver;\n private readonly mutationObserver?: MutationObserver;\n\n constructor(\n private readonly toolbar: HTMLElement,\n private readonly options: ToolbarOverflowOptions,\n ) {\n const more = document.createElement('button');\n more.type = 'button';\n more.id = options.id;\n more.className = 'lg-more lg-icon';\n more.hidden = true;\n more.setAttribute('aria-label', options.label);\n more.setAttribute('aria-haspopup', 'menu');\n more.setAttribute('aria-expanded', 'false');\n more.addEventListener('click', this.onMoreClick);\n // Right after the close button, so it sits beside it in the row.\n const close = toolbar.querySelector('.lg-close');\n if (close) {\n close.insertAdjacentElement('afterend', more);\n } else {\n toolbar.insertBefore(more, toolbar.firstChild);\n }\n this.more = more;\n\n if (typeof ResizeObserver === 'function') {\n this.resizeObserver = new ResizeObserver(this.requestUpdate);\n this.resizeObserver.observe(toolbar);\n }\n if (typeof MutationObserver === 'function') {\n this.mutationObserver = new MutationObserver((records) => {\n // The menu's own re-renders do not change the row.\n if (\n records.some(\n (record) =>\n !(record.target as Element).closest?.(\n '.lg-toolbar-menu',\n ),\n )\n ) {\n this.requestUpdate();\n }\n });\n this.mutationObserver.observe(toolbar, {\n childList: true,\n subtree: true,\n });\n }\n }\n\n /** Re-measure the row and move buttons in or out of the menu. */\n update(): void {\n const buttons = toolbarButtons(this.toolbar, this.more);\n buttons.forEach((button) => {\n if (!button.hasAttribute('data-lg-overflow')) {\n const width = button.offsetWidth;\n if (width) {\n this.widths.set(button, width);\n }\n }\n });\n const fallback =\n buttons\n .map((button) => this.widths.get(button))\n .find((width) => !!width) ?? 0;\n const counter = this.toolbar.querySelector<HTMLElement>('.lg-counter');\n\n const moved = getToolbarOverflow({\n available: this.toolbar.clientWidth,\n reserved: counter ? counter.offsetWidth : 0,\n moreWidth: this.widths.get(this.more) ?? fallback,\n items: buttons.map((button) => ({\n width: this.widths.get(button) ?? fallback,\n priority: getToolbarItemPriority(Array.from(button.classList)),\n })),\n });\n const overflow = new Set(moved);\n buttons.forEach((button, index) => {\n if (overflow.has(index)) {\n button.setAttribute('data-lg-overflow', '');\n } else {\n button.removeAttribute('data-lg-overflow');\n }\n });\n this.more.hidden = overflow.size === 0;\n if (!this.more.hidden && this.more.offsetWidth) {\n this.widths.set(this.more, this.more.offsetWidth);\n }\n const signature = `${buttons.length}:${moved.join(',')}`;\n const changed = signature !== this.movedSignature;\n this.movedSignature = signature;\n if (!overflow.size) {\n this.close(false);\n } else if (this.menu && changed) {\n this.renderMenu();\n }\n }\n\n /** Close the menu; optionally hand focus back to the More button. */\n close(returnFocus: boolean): void {\n if (!this.menu) {\n return;\n }\n this.menu.removeEventListener('keydown', this.onMenuKeydown);\n this.menu.remove();\n this.menu = null;\n document.removeEventListener(\n 'pointerdown',\n this.onDocumentPointerDown,\n true,\n );\n this.more.setAttribute('aria-expanded', 'false');\n this.more.removeAttribute('aria-controls');\n if (returnFocus) {\n this.more.focus();\n }\n }\n\n destroy(): void {\n this.close(false);\n cancel(this.frame);\n this.resizeObserver?.disconnect();\n this.mutationObserver?.disconnect();\n toolbarButtons(this.toolbar, this.more).forEach((button) =>\n button.removeAttribute('data-lg-overflow'),\n );\n this.more.remove();\n }\n\n private readonly requestUpdate = (): void => {\n if (this.frame) {\n return;\n }\n this.frame = schedule(() => {\n this.frame = 0;\n this.update();\n });\n };\n\n private readonly onMoreClick = (): void => {\n if (this.menu) {\n this.close(true);\n } else {\n this.open();\n }\n };\n\n private open(): void {\n const menu = document.createElement('div');\n menu.id = `${this.options.id}-menu`;\n menu.className = 'lg-toolbar-menu';\n menu.setAttribute('role', 'menu');\n menu.setAttribute('aria-label', this.options.label);\n menu.addEventListener('keydown', this.onMenuKeydown);\n this.menu = menu;\n this.renderMenu();\n this.toolbar.appendChild(menu);\n this.more.setAttribute('aria-expanded', 'true');\n this.more.setAttribute('aria-controls', menu.id);\n document.addEventListener(\n 'pointerdown',\n this.onDocumentPointerDown,\n true,\n );\n this.items()[0]?.focus();\n }\n\n private renderMenu(): void {\n const menu = this.menu;\n if (!menu) {\n return;\n }\n menu.textContent = '';\n toolbarButtons(this.toolbar, this.more)\n .filter((button) => button.hasAttribute('data-lg-overflow'))\n .forEach((button) => {\n const item = document.createElement('button');\n item.type = 'button';\n item.className = 'lg-toolbar-menu-item';\n item.setAttribute('role', 'menuitem');\n const icon = document.createElement('span');\n icon.className = 'lg-toolbar-menu-icon';\n icon.setAttribute('aria-hidden', 'true');\n icon.innerHTML = visibleIconMarkup(button);\n const label = document.createElement('span');\n label.textContent = button.getAttribute('aria-label') ?? '';\n item.append(icon, label);\n item.addEventListener('click', () => {\n this.close(true);\n button.click();\n });\n menu.appendChild(item);\n });\n }\n\n private items(): HTMLElement[] {\n return this.menu\n ? Array.from(\n this.menu.querySelectorAll<HTMLElement>('[role=\"menuitem\"]'),\n )\n : [];\n }\n\n private readonly onMenuKeydown = (event: KeyboardEvent): void => {\n const items = this.items();\n const index = items.indexOf(document.activeElement as HTMLElement);\n switch (event.key) {\n case 'Escape':\n this.close(true);\n break;\n case 'ArrowDown':\n items[(index + 1) % items.length]?.focus();\n break;\n case 'ArrowUp':\n items[(index - 1 + items.length) % items.length]?.focus();\n break;\n case 'Home':\n items[0]?.focus();\n break;\n case 'End':\n items[items.length - 1]?.focus();\n break;\n case 'ArrowLeft':\n case 'ArrowRight':\n // Keep the gallery from changing slides behind the menu.\n break;\n case 'Tab':\n this.close(false);\n return;\n default:\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n };\n\n private readonly onDocumentPointerDown = (event: Event): void => {\n const target = event.target as Node | null;\n if (\n target &&\n (this.menu?.contains(target) || this.more.contains(target))\n ) {\n return;\n }\n consumeBackdropPress(event);\n this.close(false);\n };\n}\n","/**\n * Icon injection: the gallery's icons are inline SVG strings, built-in\n * defaults (registered by the core and by each plugin, so a plugin's\n * icons ship in its own bundle) merged under the consumer's\n * `settings.icons` overrides. One generic pass over the built structure,\n * every icon button (core and plugins alike) is an empty classed element\n * by the end of `buildStructure`, so a name→selector table covers them\n * all without touching the individual templates.\n *\n * State-pair buttons (maximize/minimize, autoplay play/pause, fullscreen\n * enter/exit) render BOTH icons of the pair; state classes (`lg-inline`,\n * `lg-show-autoplay`, `lg-fullscreen-on`) toggle their visibility in\n * CSS. A consumer override applies only when it answers every name of a\n * pair, a half-provided pair keeps the defaults so no state ends up\n * iconless.\n */\n\nimport type { LgIconName } from '@lightgallery/headless';\n\nexport type { LgIconName };\n\n/** SVG markup per icon; omitted names keep the built-in glyph. */\nexport type LgIcons = Partial<Record<LgIconName, string>>;\n\ninterface IconTarget {\n /** Selector within the gallery container. */\n selector: string;\n /** One name, or a state pair in [default-state, active-state] order. */\n names: LgIconName[];\n}\n\n// The dropdown lives INSIDE the share button, and future markup may nest\n// too, injection always PREPENDS, never replaces the element's HTML.\nconst ICON_TARGETS: IconTarget[] = [\n { selector: '.lg-close', names: ['close'] },\n { selector: '.lg-prev', names: ['prev'] },\n { selector: '.lg-next', names: ['next'] },\n { selector: '.lg-download', names: ['download'] },\n { selector: '.lg-more', names: ['more'] },\n // Shown while `.lg-inline` (prompting maximize) / after maximizing.\n { selector: '.lg-maximize', names: ['maximize', 'minimize'] },\n // The actual-size button's CLASS toggles between the two zoom\n // classes as the zoom state changes (2.x swapped the glyph that\n // way), it carries BOTH zoom icons and the class picks one in\n // CSS. Listed before the class-based zoom targets so the id match\n // claims it first (the pass skips already-processed elements).\n { selector: '[id^=\"lg-actual-size-\"]', names: ['zoomIn', 'zoomOut'] },\n { selector: '.lg-zoom-in', names: ['zoomIn'] },\n { selector: '.lg-zoom-out', names: ['zoomOut'] },\n // No '.lg-actual-size' target: vanilla's actual-size BUTTON never\n // carries that class (it rides the zoom classes above; the outer\n // gets `lg-actual-size` as a zoom-state class after build). The\n // `actualSize` name serves the framework ports' static button.\n { selector: '.lg-rotate-left', names: ['rotateLeft'] },\n { selector: '.lg-rotate-right', names: ['rotateRight'] },\n { selector: '.lg-flip-hor', names: ['flipHorizontal'] },\n { selector: '.lg-flip-ver', names: ['flipVertical'] },\n { selector: '.lg-share', names: ['share'] },\n { selector: '.lg-share-facebook .lg-icon', names: ['shareFacebook'] },\n { selector: '.lg-share-twitter .lg-icon', names: ['shareX'] },\n { selector: '.lg-share-pinterest .lg-icon', names: ['sharePinterest'] },\n // Shown while idle (prompting play) / while `.lg-show-autoplay`.\n {\n selector: '.lg-autoplay-button',\n names: ['autoplayPlay', 'autoplayPause'],\n },\n // Shown while windowed / while `.lg-fullscreen-on`.\n { selector: '.lg-fullscreen', names: ['fullscreen', 'fullscreenExit'] },\n { selector: '.lg-comment-toggle', names: ['comment'] },\n { selector: '.lg-comment-close', names: ['commentClose'] },\n { selector: '.lg-toggle-thumb', names: ['toggleThumbnails'] },\n];\n\nconst toKebab = (name: string): string =>\n name.replace(/[A-Z]/g, (char) => `-${char.toLowerCase()}`);\n\n/** `<span class=\"lg-ci lg-ci-<kebab-name>\">svg</span>` wrapper markup. */\nfunction getCustomIconMarkup(icons: LgIcons, names: LgIconName[]): string {\n if (!names.every((name) => icons[name])) {\n return '';\n }\n return names\n .map(\n (name) =>\n `<span class=\"lg-ci lg-ci-${toKebab(\n name,\n )}\" aria-hidden=\"true\">${icons[name]}</span>`,\n )\n .join('');\n}\n\n/**\n * Inject the gallery's icons into the built structure: per target, the\n * consumer's overrides apply when they answer every name (pairs must be\n * complete), else the registered defaults render. Elements keep their\n * classes and listeners, the icons are prepended children.\n */\nexport function applyCustomIcons(\n container: HTMLElement,\n defaults: LgIcons,\n overrides: LgIcons | undefined,\n): void {\n ICON_TARGETS.forEach(({ selector, names }) => {\n const source =\n overrides && names.every((name) => overrides[name])\n ? overrides\n : defaults;\n const markup = getCustomIconMarkup(source, names);\n if (!markup) {\n return;\n }\n container.querySelectorAll(selector).forEach((element) => {\n if (element.classList.contains('lg-icon-custom')) {\n return;\n }\n element.classList.add('lg-icon-custom');\n element.insertAdjacentHTML('afterbegin', markup);\n });\n });\n}\n","import {\n isSpringSettled,\n stepSpring,\n type SpringConfig,\n type SpringState,\n} from '@lightgallery/headless';\n\n/**\n * rAF driver for the shared spring math: advances one spring per track\n * each frame and hands the values to the caller's DOM writer. The math\n * (and therefore the feel) lives in @lightgallery/headless; this file\n * only owns scheduling.\n */\n\nexport interface SpringTrack extends SpringConfig {\n from: number;\n /** Seed velocity, px/ms, the gesture's windowed release velocity. */\n velocity: number;\n target: number;\n}\n\n/** Frame gap clamp so a background-tab pause cannot teleport a spring. */\nconst MAX_FRAME_MS = 64;\n\nexport function runSprings(\n tracks: SpringTrack[],\n onFrame: (values: number[]) => void,\n onDone?: () => void,\n): () => void {\n let raf = 0;\n let last = Date.now();\n const states: SpringState[] = tracks.map((t) => ({\n position: t.from,\n velocity: t.velocity,\n }));\n const frame = () => {\n // Date.now over the rAF timestamp: one clock for seeding and\n // stepping (and the one fake timers drive in tests). Clamp into\n // [0, MAX]: a paused tab cannot teleport the spring and a\n // non-monotonic reading cannot blow it up (negative dt turns\n // the decay exponential).\n const now = Date.now();\n const dt = Math.min(Math.max(now - last, 0), MAX_FRAME_MS);\n last = now;\n let settled = true;\n tracks.forEach((t, i) => {\n states[i] = stepSpring(states[i], t.target, dt, t);\n if (!isSpringSettled(states[i], t.target)) {\n settled = false;\n }\n });\n if (settled) {\n onFrame(tracks.map((t) => t.target));\n onDone?.();\n return;\n }\n onFrame(states.map((s) => s.position));\n raf = requestAnimationFrame(frame);\n };\n raf = requestAnimationFrame(frame);\n return () => cancelAnimationFrame(raf);\n}\n","interface Offset {\n left: number;\n top: number;\n}\n\nfunction initLgPolyfills() {\n (function () {\n if (typeof window.CustomEvent === 'function') return false;\n\n function CustomEvent(event: string, params: any) {\n params = params || {\n bubbles: false,\n cancelable: false,\n detail: null,\n };\n const evt = document.createEvent('CustomEvent');\n evt.initCustomEvent(\n event,\n params.bubbles,\n params.cancelable,\n params.detail,\n );\n return evt;\n }\n\n window.CustomEvent = CustomEvent as any;\n })();\n (function () {\n if (!Element.prototype.matches) {\n Element.prototype.matches =\n (Element.prototype as any).msMatchesSelector ||\n Element.prototype.webkitMatchesSelector;\n }\n })();\n}\n\nexport type LgQuery = (selector: any) => lgQuery;\nexport class lgQuery {\n static eventListeners: { [key: string]: any[] } = {};\n static generateUUID(): string {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(\n /[xy]/g,\n function (c) {\n const r = (Math.random() * 16) | 0,\n v = c == 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n },\n );\n }\n\n private selector: any;\n private firstElement: any;\n private cssVenderPrefixes: string[] = [\n 'TransitionDuration',\n 'TransitionTimingFunction',\n 'Transform',\n 'Transition',\n ];\n constructor(selector: string | Element) {\n this.selector = this._getSelector(selector);\n this.firstElement = this._getFirstEl();\n return this;\n }\n\n private _getSelector(\n selector: string | Element,\n context: Element | Document = document,\n ): Element | null | NodeListOf<Element> {\n if (typeof selector !== 'string') {\n return selector;\n }\n context = context || document;\n const fl = selector.substring(0, 1);\n if (fl === '#') {\n return context.querySelector(selector);\n } else {\n return context.querySelectorAll(selector);\n }\n }\n\n private _each(\n func: (\n elements: Element | NodeListOf<Element> | null,\n index: number,\n ) => void,\n ): this {\n if (!this.selector) {\n return this;\n }\n if (this.selector.length !== undefined) {\n [].forEach.call(this.selector, func);\n } else {\n func(this.selector, 0);\n }\n return this;\n }\n\n private _setCssVendorPrefix(\n el: any,\n cssProperty: string,\n value?: string | number,\n ): void {\n // Custom properties are case sensitive and never vendor prefixed,\n // and `style[name]` silently drops them.\n if (cssProperty.startsWith('--')) {\n el.style.setProperty(cssProperty, String(value));\n return;\n }\n // prettier-ignore\n const property = cssProperty.replace(/-([a-z])/gi, function (\n s,\n group1,\n ) {\n return group1.toUpperCase();\n });\n if (this.cssVenderPrefixes.indexOf(property) !== -1) {\n el.style[property.charAt(0).toLowerCase() + property.slice(1)] =\n value;\n el.style['webkit' + property] = value;\n el.style['moz' + property] = value;\n el.style['ms' + property] = value;\n el.style['o' + property] = value;\n } else {\n el.style[property] = value;\n }\n }\n\n private _getFirstEl() {\n if (this.selector && this.selector.length !== undefined) {\n return this.selector[0];\n } else {\n return this.selector;\n }\n }\n\n private isEventMatched(event: string, eventName: string): boolean {\n const eventNamespace = eventName.split('.');\n return event\n .split('.')\n .filter((e) => e)\n .every((e) => {\n return eventNamespace.indexOf(e) !== -1;\n });\n }\n\n attr(attr: string): string;\n attr(attr: string, value: string | number | boolean): this;\n attr(attr: string, value?: string | number | boolean): string | this {\n if (value === undefined) {\n if (!this.firstElement) {\n return '';\n }\n return this.firstElement.getAttribute(attr);\n }\n this._each((el: any) => {\n el.setAttribute(attr, value);\n });\n return this;\n }\n\n find(selector: any): lgQuery {\n return $LG(this._getSelector(selector, this.selector));\n }\n\n first(): lgQuery {\n if (this.selector && this.selector.length !== undefined) {\n return $LG(this.selector[0]);\n } else {\n return $LG(this.selector);\n }\n }\n\n eq(index: number): lgQuery {\n return $LG(this.selector[index]);\n }\n\n parent(): lgQuery {\n return $LG(this.selector.parentElement);\n }\n\n get(): HTMLElement {\n return this._getFirstEl();\n }\n\n removeAttr(attributes: string): this {\n const attrs = attributes.split(' ');\n this._each((el: any) => {\n attrs.forEach((attr: string) => el.removeAttribute(attr));\n });\n return this;\n }\n\n wrap(className: string): this {\n if (!this.firstElement) {\n return this;\n }\n const wrapper = document.createElement('div');\n wrapper.className = className;\n this.firstElement.parentNode.insertBefore(wrapper, this.firstElement);\n this.firstElement.parentNode.removeChild(this.firstElement);\n wrapper.appendChild(this.firstElement);\n return this;\n }\n\n addClass(classNames = ''): this {\n this._each((el: any) => {\n // IE doesn't support multiple arguments\n classNames.split(' ').forEach((className) => {\n if (className) {\n el.classList.add(className);\n }\n });\n });\n return this;\n }\n\n removeClass(classNames: string): this {\n this._each((el: any) => {\n // IE doesn't support multiple arguments\n classNames.split(' ').forEach((className) => {\n if (className) {\n el.classList.remove(className);\n }\n });\n });\n return this;\n }\n\n hasClass(className: string): boolean {\n if (!this.firstElement) {\n return false;\n }\n return this.firstElement.classList.contains(className);\n }\n hasAttribute(attribute: string): boolean {\n if (!this.firstElement) {\n return false;\n }\n return this.firstElement.hasAttribute(attribute);\n }\n toggleClass(className: string): this {\n if (!this.firstElement) {\n return this;\n }\n if (this.hasClass(className)) {\n this.removeClass(className);\n } else {\n this.addClass(className);\n }\n return this;\n }\n\n css(property: string, value?: string | number): this {\n this._each((el: any) => {\n this._setCssVendorPrefix(el, property, value);\n });\n return this;\n }\n // Need to pass separate namespaces for separate elements\n on(events: string, listener: (e: any) => void): this {\n if (!this.selector) {\n return this;\n }\n events.split(' ').forEach((event: string) => {\n if (!Array.isArray(lgQuery.eventListeners[event])) {\n lgQuery.eventListeners[event] = [];\n }\n lgQuery.eventListeners[event].push(listener);\n this.selector.addEventListener(event.split('.')[0], listener);\n });\n\n return this;\n }\n // @todo - test this\n once(event: string, listener: (e: any) => void): this {\n this.on(event, () => {\n this.off(event);\n listener(event);\n });\n return this;\n }\n off(event: string): this {\n if (!this.selector) {\n return this;\n }\n Object.keys(lgQuery.eventListeners).forEach((eventName) => {\n if (this.isEventMatched(event, eventName)) {\n lgQuery.eventListeners[eventName].forEach((listener) => {\n this.selector.removeEventListener(\n eventName.split('.')[0],\n listener,\n );\n });\n lgQuery.eventListeners[eventName] = [];\n }\n });\n\n return this;\n }\n trigger<Detail>(event: string, detail?: Detail): this {\n if (!this.firstElement) {\n return this;\n }\n\n const customEvent = new CustomEvent(event.split('.')[0], {\n detail: detail || null,\n });\n this.firstElement.dispatchEvent(customEvent);\n return this;\n }\n\n // Does not support IE\n load(url: string): this {\n fetch(url)\n .then((res) => res.text())\n .then((html) => {\n this.selector.innerHTML = html;\n });\n return this;\n }\n\n html(): string;\n html(html: string): this;\n html(html?: string): string | this {\n if (html === undefined) {\n if (!this.firstElement) {\n return '';\n }\n return this.firstElement.innerHTML;\n }\n this._each((el: any) => {\n el.innerHTML = html;\n });\n return this;\n }\n append(html: string | HTMLElement): this {\n this._each((el: any) => {\n if (typeof html === 'string') {\n el.insertAdjacentHTML('beforeend', html);\n } else {\n el.appendChild(html);\n }\n });\n return this;\n }\n prepend(html: string | HTMLElement): this {\n this._each((el: any) => {\n if (typeof html === 'string') {\n el.insertAdjacentHTML('afterbegin', html);\n } else if (html instanceof HTMLElement) {\n el.insertBefore(html.cloneNode(true), el.firstChild);\n }\n });\n return this;\n }\n remove(): this {\n this._each((el: any) => {\n el.parentNode.removeChild(el);\n });\n return this;\n }\n empty(): this {\n this._each((el: any) => {\n el.innerHTML = '';\n });\n return this;\n }\n // Supports only window\n scrollTop(): number;\n scrollTop(scrollTop: number): this;\n scrollTop(scrollTop?: number): number | this {\n if (scrollTop !== undefined) {\n document.body.scrollTop = scrollTop;\n document.documentElement.scrollTop = scrollTop;\n return this;\n } else {\n return (\n window.pageYOffset ||\n document.documentElement.scrollTop ||\n document.body.scrollTop ||\n 0\n );\n }\n }\n // Supports only window\n scrollLeft(): number;\n scrollLeft(scrollLeft?: number): this;\n scrollLeft(scrollLeft?: number): number | this {\n if (scrollLeft !== undefined) {\n document.body.scrollLeft = scrollLeft;\n document.documentElement.scrollLeft = scrollLeft;\n return this;\n } else {\n return (\n window.pageXOffset ||\n document.documentElement.scrollLeft ||\n document.body.scrollLeft ||\n 0\n );\n }\n }\n offset(): Offset {\n if (!this.firstElement) {\n return {\n left: 0,\n top: 0,\n };\n }\n const rect = this.firstElement.getBoundingClientRect();\n const bodyMarginLeft = $LG('body').style().marginLeft;\n\n // Minus body margin - https://stackoverflow.com/questions/30711548/is-getboundingclientrect-left-returning-a-wrong-value\n return {\n left: rect.left - parseFloat(bodyMarginLeft) + this.scrollLeft(),\n top: rect.top + this.scrollTop(),\n };\n }\n style(): CSSStyleDeclaration {\n if (!this.firstElement) {\n return {} as CSSStyleDeclaration;\n }\n return (\n this.firstElement.currentStyle ||\n window.getComputedStyle(this.firstElement)\n );\n }\n // Width without padding and border even if box-sizing is used.\n width(): number {\n const style = this.style();\n return (\n this.firstElement.clientWidth -\n parseFloat(style.paddingLeft) -\n parseFloat(style.paddingRight)\n );\n }\n // Height without padding and border even if box-sizing is used.\n height(): number {\n const style = this.style();\n return (\n this.firstElement.clientHeight -\n parseFloat(style.paddingTop) -\n parseFloat(style.paddingBottom)\n );\n }\n}\n\nexport function $LG(selector: any): lgQuery {\n initLgPolyfills();\n return new lgQuery(selector);\n}\n","import {\n fitImageSize,\n getOriginTransform,\n isUsableOriginRect,\n getVideoInfo,\n parseImageSize,\n} from '@lightgallery/headless';\n\nimport { $LG, lgQuery } from './lgQuery';\nimport { VideoSource } from './plugins/video/types';\nimport { VideoInfo } from './types';\n\nexport interface ImageSize {\n width: number;\n height: number;\n}\n\nexport interface ImageSources {\n media?: string;\n srcset: string;\n sizes?: string;\n type?: string;\n}\n\nexport interface GalleryItem {\n /**\n * url of the media\n * @data-attr data-src\n */\n src?: string;\n\n /**\n * Source attributes for the <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/source#attributes\">picture</a> element\n * @data-attr data-sources\n */\n sources?: ImageSources[];\n\n /**\n * Thumbnail url\n * @description By default lightGallery uses the image inside gallery selector as thumbnail.\n * But, If you want to use external image for thumbnail,\n * pass the thumbnail url via any data attribute and\n * pass the attribute name via exThumbImage option\n * @example\n * <div id=\"lightGallery\">\n * <a href=\"a.jpg\" data-external-thumb-image=\"images/externalThumb.jpg\" ><img src=\"thumb.jpg\" /></a>\n * </div>\n *\n * lightGallery(document.getElementById('lightGallery'), {\n * exThumbImage: 'data-external-thumb-image'\n * })\n * @data-attr data-*\n */\n thumb?: string;\n\n /**\n * alt attribute for the image\n * @data-attr alt\n */\n alt?: string;\n\n /**\n * Title attribute for the video\n * @data-attr title\n */\n title?: string;\n\n /**\n * Title for iframe\n * @data-attr data-iframe-title\n */\n iframeTitle?: string;\n\n /**\n * Caption for the slide\n * @description You can either pass the HTML markup or the ID or class name of the element which contains the captions\n * @data-attr data-sub-html\n */\n subHtml?: string;\n\n /**\n * url of the file which contain the sub html.\n * @description Note - Does not support Internet Explorer browser\n * @data-attr data-sub-html-url\n */\n subHtmlUrl?: string;\n\n /**\n * Video source\n * @data-attr data-video\n */\n video?: VideoSource;\n\n /**\n * Poster url\n * @data-attr data-poster\n */\n poster?: string;\n\n /**\n * Custom slide name to use in the url when hash plugin is enabled\n * @data-attr data-slide-name\n */\n slideName?: string;\n\n /**\n * List of images and viewport's max width separated by comma.\n * @description Ex?: img/1-375.jpg 375, img/1-480.jpg 480, img/1-757.jpg 757.\n * @data-attr data-responsive\n */\n responsive?: string;\n\n /**\n * srcset attribute values for the main image\n * @data-attr data-srcset\n */\n srcset?: string;\n\n /**\n * srcset sizes attribute for the main image\n * @data-attr data-sizes\n */\n sizes?: string;\n\n /**\n * Set true is you want to open your url in an iframe\n * @data-attr data-iframe\n */\n iframe?: boolean;\n\n /**\n * Download url for your image/video.\n * @description Pass false if you want to disable the download button.\n * @data-attr data-download-url\n */\n downloadUrl?: string | boolean;\n\n /**\n * Name of the file after it is downloaded.\n * @description The HTML value of the download attribute.\n * There are no restrictions on allowed values, and the browser will automatically\n * detect the correct file extension and add it to the file (.img, .pdf, .txt, .html, etc.).\n * <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-download\">More info</a>\n * @data-attr data-download\n */\n download?: string | boolean;\n\n /**\n * Actual size of the image in px.\n * @description This is used in zoom plugin to see the actual size of the image when double taped on the image.\n * @data-attr data-width\n */\n width?: string;\n\n /**\n * Canonical share URL for the native share sheet (Web Share API).\n * @description Specify only if you want a separate URL for the specific\n * slide. Falls back to the network-specific share URLs, then the current\n * browser URL.\n * @data-attr data-share-url\n */\n shareUrl?: string;\n\n /**\n * Facebook share URL.\n * @description Specify only if you want to provide separate share URL for the specific slide. By default, current browser URL is taken.\n * @data-attr data-facebook-share-url\n */\n facebookShareUrl?: string;\n\n /**\n * Tweet text\n * @data-attr data-tweet-text\n */\n tweetText?: string;\n\n /**\n * Twitter share URL.\n * @description Specify only if you want to provide separate share URL for the specific slide. By default, current browser URL will be taken.\n * @data-attr data-twitter-share-url\n */\n twitterShareUrl?: string;\n\n /**\n * Pinterest share URL.\n * @description Specify only if you want to provide separate share URL for the specific slide. By default, current browser URL will be taken.\n * Note?: Pinterest requires absolute URL\n * @data-attr data-pinterest-share-url\n */\n pinterestShareUrl?: string;\n\n /**\n * Description for Pinterest post.\n * @data-attr data-pinterest-text\n */\n pinterestText?: string;\n\n /**\n * Facebook comments body html\n * @description Please refer <a href=\"https://developers.facebook.com/docs/plugins/comments/#comments-plugin\">facebook official documentation</a> for generating the HTML markup\n * @example\n * <div\n * class=\"fb-comments\"\n * data-href=\"https://www.example.com/your-page/#lg=1&slide=0\"\n * data-width=\"400\"\n * data-numposts=\"5\">\n * </div>\n * @data-attr data-fb-html\n */\n fbHtml?: string;\n\n /**\n * Disqus page identifier\n * @description Please refer official <a href=\"https://help.disqus.com/en/articles/1717084-javascript-configuration-variables\">disqus documentation</a> for more info\n * @data-attr data-disqus-identifier\n */\n disqusIdentifier?: string;\n\n /**\n * Disqus page url\n * @description Please refer official <a href=\"https://help.disqus.com/en/articles/1717084-javascript-configuration-variables\">disqus documentation</a> for more info\n * @data-attr data-disqus-url\n */\n disqusUrl?: string;\n\n __slideVideoInfo?: VideoInfo;\n [key: string]: any;\n}\n\nconst defaultDynamicOptions = [\n 'src',\n 'sources',\n 'subHtml',\n 'subHtmlUrl',\n 'html',\n 'video',\n 'poster',\n 'slideName',\n 'responsive',\n 'srcset',\n 'sizes',\n 'iframe',\n 'downloadUrl',\n 'download',\n 'width',\n 'shareUrl',\n 'facebookShareUrl',\n 'tweetText',\n 'iframeTitle',\n 'twitterShareUrl',\n 'pinterestShareUrl',\n 'pinterestText',\n 'fbHtml',\n 'disqusIdentifier',\n 'disqusUrl',\n];\n\n// Convert html data-attribute to camalcase\nexport function convertToData(attr: string): string {\n // FInd a way for lgsize\n if (attr === 'href') {\n return 'src';\n }\n attr = attr.replace('data-', '');\n attr = attr.charAt(0).toLowerCase() + attr.slice(1);\n attr = attr.replace(/-([a-z])/g, (g) => g[1].toUpperCase());\n\n return attr;\n}\n\nconst utils = {\n /**\n * Fetches HTML content from a given URL and inserts it into a specified element.\n *\n * @param url - The URL to fetch the HTML content from.\n * @param element - The DOM element (jQuery object) to insert the HTML content into.\n * @param insertMethod - The method to insert the HTML ('append' or 'replace').\n */\n fetchCaptionFromUrl(\n url: string,\n element: lgQuery,\n insertMethod: 'append' | 'replace',\n ): void {\n // Fetch content from the URL\n fetch(url)\n .then((response) => response.text())\n .then((htmlContent) => {\n if (insertMethod === 'append') {\n const contentDiv = `<div class=\"lg-sub-html\">${htmlContent}</div>`;\n element.append(contentDiv);\n } else {\n element.html(htmlContent);\n }\n });\n },\n /**\n * get possible width and height from the lgSize attribute. Used for ZoomFromOrigin option\n */\n getSize(\n el: HTMLElement,\n container: lgQuery,\n spacing = 0,\n defaultLgSize?: string,\n ): ImageSize | undefined {\n const LGel = $LG(el);\n const lgSize = LGel.attr('data-lg-size') || defaultLgSize;\n\n const parsed = parseImageSize(lgSize, window.innerWidth);\n if (!parsed) {\n return;\n }\n\n return fitImageSize(\n parsed,\n container.width(),\n container.height() - spacing,\n );\n },\n\n /**\n * @desc Get transform value based on the imageSize. Used for ZoomFromOrigin option\n * @param {jQuery Element}\n * @returns {String} Transform CSS string\n */\n getTransform(\n el: HTMLElement,\n container: lgQuery,\n top: number,\n bottom: number,\n imageSize?: ImageSize,\n ): string | undefined {\n // Degenerate measurement (zero-sized/hidden viewport, offsets\n // taller than the stage): the shared math would emit a mirrored\n // flight, fall back to the startClass fade instead (the sibling\n // bindings guard the same way).\n if (!imageSize || imageSize.width <= 0 || imageSize.height <= 0) {\n return;\n }\n const LGel = $LG(el).find('img').first();\n if (!LGel.get()) {\n return;\n }\n\n const containerRect = container.get().getBoundingClientRect();\n\n // Viewport coords straight from the rect. `offset()` folds in a\n // body-margin correction that shifts the origin on any centered\n // body (`margin: auto`), the long-standing \"flight starts beside\n // the thumbnail\" bug, and the old padding/border terms adjusted\n // in the wrong direction on styled thumbnails.\n const rect = LGel.get().getBoundingClientRect();\n const triggerRect = {\n left: rect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height,\n };\n // A hidden or collapsed trigger (a collage's overflow items behind\n // a \"+N photos\" tile) measures 0×0 at the viewport origin: no\n // flight, the caller falls back to the centred animation.\n if (!isUsableOriginRect(triggerRect)) {\n return;\n }\n\n return getOriginTransform({\n triggerRect,\n containerRect: {\n left: containerRect.left,\n top: containerRect.top,\n width: containerRect.width,\n // Element height, not rect height, includes the mobile\n // safari bottom bar handling this always had.\n height: container.height(),\n },\n top,\n bottom,\n imageSize,\n });\n },\n\n getIframeMarkup(\n iframeWidth: string,\n iframeHeight: string,\n iframeMaxWidth: string,\n iframeMaxHeight: string,\n src?: string,\n iframeTitle?: string,\n ): string {\n const title = iframeTitle ? 'title=\"' + iframeTitle + '\"' : '';\n return `<div class=\"lg-media-cont lg-has-iframe\" style=\"width:${iframeWidth}; max-width:${iframeMaxWidth}; height: ${iframeHeight}; max-height:${iframeMaxHeight}\">\n <iframe class=\"lg-object\" frameborder=\"0\" ${title} src=\"${src}\" allowfullscreen=\"true\"></iframe>\n </div>`;\n },\n\n getImgMarkup(\n index: number,\n src: string,\n altAttr: string,\n srcset?: string,\n sizes?: string,\n sources?: ImageSources[],\n ): string {\n const srcsetAttr = srcset ? `srcset=\"${srcset}\"` : '';\n const sizesAttr = sizes ? `sizes=\"${sizes}\"` : '';\n const imgMarkup = `<img ${altAttr} ${srcsetAttr} ${sizesAttr} class=\"lg-object lg-image\" data-index=\"${index}\" src=\"${src}\" />`;\n let sourceTag = '';\n if (sources) {\n const sourceObj =\n typeof sources === 'string' ? JSON.parse(sources) : sources;\n\n sourceTag = sourceObj.map((source: any) => {\n let attrs = '';\n Object.keys(source).forEach((key) => {\n // Do not remove the first space as it is required to separate the attributes\n attrs += ` ${key}=\"${source[key]}\"`;\n });\n return `<source ${attrs}></source>`;\n });\n }\n return `${sourceTag}${imgMarkup}`;\n },\n\n // Get src from responsive src\n getResponsiveSrc(srcItms: string[]): string {\n const rsWidth = [];\n const rsSrc = [];\n let src = '';\n for (let i = 0; i < srcItms.length; i++) {\n const _src = srcItms[i].split(' ');\n\n // Manage empty space\n if (_src[0] === '') {\n _src.splice(0, 1);\n }\n\n rsSrc.push(_src[0]);\n rsWidth.push(_src[1]);\n }\n\n const wWidth = window.innerWidth;\n for (let j = 0; j < rsWidth.length; j++) {\n if (parseInt(rsWidth[j], 10) > wWidth) {\n src = rsSrc[j];\n break;\n }\n }\n return src;\n },\n\n isImageLoaded(img: HTMLImageElement): boolean {\n if (!img) return false;\n // During the onload event, IE correctly identifies any images that\n // weren’t downloaded as not complete. Others should too. Gecko-based\n // browsers act like NS4 in that they report this incorrectly.\n if (!img.complete) {\n return false;\n }\n\n // However, they do have two very useful properties: naturalWidth and\n // naturalHeight. These give the true size of the image. If it failed\n // to load, either of these should be zero.\n if (img.naturalWidth === 0) {\n return false;\n }\n\n // No other way of checking: assume it’s ok.\n return true;\n },\n\n getVideoPosterMarkup(\n _poster: string,\n dummyImg: string | HTMLElement,\n videoContStyle: string,\n playVideoString: string,\n _isVideo?: VideoInfo,\n ): string {\n let videoClass = '';\n if (_isVideo && _isVideo.youtube) {\n videoClass = 'lg-has-youtube';\n } else if (_isVideo && _isVideo.vimeo) {\n videoClass = 'lg-has-vimeo';\n } else if (_isVideo && _isVideo.wistia) {\n // Wistia fell into lg-has-html5 in 2.x; the facades made the\n // gap visible (binding providerClass had it right all along).\n videoClass = 'lg-has-wistia';\n } else {\n videoClass = 'lg-has-html5';\n }\n let _dummy = dummyImg;\n if (typeof dummyImg !== 'string') {\n _dummy = dummyImg.outerHTML;\n }\n return `<div class=\"lg-video-cont ${videoClass}\" style=\"${videoContStyle}\">\n <div class=\"lg-video-play-button\">\n <svg\n viewBox=\"0 0 20 20\"\n preserveAspectRatio=\"xMidYMid\"\n focusable=\"false\"\n aria-labelledby=\"${playVideoString}\"\n role=\"img\"\n class=\"lg-video-play-icon\"\n >\n <title>${playVideoString}</title>\n <polygon class=\"lg-video-play-icon-inner\" points=\"1,0 20,10 1,20\"></polygon>\n </svg>\n <svg class=\"lg-video-play-icon-bg\" viewBox=\"0 0 50 50\" focusable=\"false\">\n <circle cx=\"50%\" cy=\"50%\" r=\"20\"></circle></svg>\n <svg class=\"lg-video-play-icon-circle\" viewBox=\"0 0 50 50\" focusable=\"false\">\n <circle cx=\"50%\" cy=\"50%\" r=\"20\"></circle>\n </svg>\n </div>\n ${_dummy}\n <img class=\"lg-object lg-video-poster\" src=\"${_poster}\" />\n </div>`;\n },\n\n getFocusableElements(container: HTMLElement): NodeListOf<Element> {\n const elements = container.querySelectorAll(\n 'a[href]:not([disabled]), button:not([disabled]), textarea:not([disabled]), input[type=\"text\"]:not([disabled]), input[type=\"radio\"]:not([disabled]), input[type=\"checkbox\"]:not([disabled]), select:not([disabled])',\n );\n const visibleElements = [].filter.call(\n elements,\n (element: HTMLElement) => {\n const style = window.getComputedStyle(element);\n return (\n style.display !== 'none' &&\n style.visibility !== 'hidden' &&\n // Hidden or moved into the toolbar's More menu, whatever\n // the stylesheet says about their display.\n !element.closest('[hidden], [data-lg-overflow]')\n );\n },\n );\n return visibleElements as unknown as NodeListOf<Element>;\n },\n\n /**\n * @desc Create dynamic elements array from gallery items when dynamic option is false\n * It helps to avoid frequent DOM interaction\n * and avoid multiple checks for dynamic elments\n *\n * @returns {Array} dynamicEl\n */\n getDynamicOptions(\n items: any,\n extraProps: string[],\n getCaptionFromTitleOrAlt: boolean,\n exThumbImage: string,\n ): GalleryItem[] {\n const dynamicElements: GalleryItem[] = [];\n const availableDynamicOptions = [\n ...defaultDynamicOptions,\n ...extraProps,\n ];\n [].forEach.call(items, (item: HTMLElement) => {\n const dynamicEl: GalleryItem = {} as GalleryItem;\n for (let i = 0; i < item.attributes.length; i++) {\n const attr = item.attributes[i];\n if (attr.specified) {\n const dynamicAttr = convertToData(attr.name);\n let label = '';\n if (availableDynamicOptions.indexOf(dynamicAttr) > -1) {\n label = dynamicAttr;\n }\n if (label) {\n (dynamicEl as any)[label] = attr.value;\n }\n }\n }\n // `data-sources` is JSON on the element; the item carries the\n // parsed array so every consumer (slide markup, the zoom\n // plugin's actual-size lookup) sees the headless shape.\n if (typeof dynamicEl.sources === 'string') {\n try {\n dynamicEl.sources = JSON.parse(dynamicEl.sources);\n } catch (e) {\n console.warn(\n 'lightGallery :- data-sources must be a JSON array of picture source objects. See https://www.lightgalleryjs.com/docs/responsive-loading/',\n );\n delete dynamicEl.sources;\n }\n }\n const currentItem = $LG(item);\n const alt = currentItem.find('img').first().attr('alt');\n const title = currentItem.attr('title');\n\n const thumb = exThumbImage\n ? currentItem.attr(exThumbImage)\n : currentItem.find('img').first().attr('src');\n dynamicEl.thumb = thumb;\n\n if (getCaptionFromTitleOrAlt && !dynamicEl.subHtml) {\n dynamicEl.subHtml = title || alt || '';\n }\n dynamicEl.alt = alt || title || '';\n dynamicElements.push(dynamicEl);\n });\n return dynamicElements;\n },\n isMobile(): boolean {\n return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);\n },\n /**\n * @desc Check the given src is video\n * @param {String} src\n * @return {Object} video type\n * Ex:{ youtube : [\"//www.youtube.com/watch?v=c0asJgSyxcY\", \"c0asJgSyxcY\"] }\n *\n * @todo - this information can be moved to dynamicEl to avoid frequent calls\n */\n\n isVideo(\n src: string,\n isHTML5VIdeo: boolean,\n index: number,\n ): VideoInfo | undefined {\n if (!src) {\n if (isHTML5VIdeo) {\n return {\n html5: true,\n };\n } else {\n console.error(\n 'lightGallery :- data-src is not provided on slide item ' +\n (index + 1) +\n '. Please make sure the selector property is properly configured. More info - https://www.lightgalleryjs.com/demos/html-markup/',\n );\n return;\n }\n }\n\n // Documented deviation from the shared helper: 2.x ignores the\n // html5 flag once a src is present, a URL matching no provider\n // is not a video, video payload or not.\n return getVideoInfo(src, false);\n },\n};\n\nexport default utils;\n","import {\n takeLicenseNotice,\n awaitDecode,\n formatSlideAnnouncement,\n getCenterCloseTransform,\n getEdgeFrictionedDelta,\n getFacadePoster,\n getYouTubePosterUrl,\n getHorizontalDragTransforms,\n getSwipeAxis,\n getSwipeReleaseVerdict,\n getVerticalDragEffects,\n getWindowedVelocity,\n onTransitionSettle,\n pushVelocitySample,\n resolveSwipeTarget,\n shouldCloseOnVerticalDrag,\n type VelocitySample,\n coreDefaultIcons,\n} from '@lightgallery/headless';\n\nimport {\n AfterAppendSlideEventDetail,\n AfterAppendSubHtmlDetail,\n BeforeSlideDetail,\n lGEvents,\n SlideItemLoadDetail,\n} from './lg-events';\nimport {\n LightGalleryAllSettings,\n lightGalleryCoreSettings,\n LightGallerySettings,\n} from './lg-settings';\nimport { ToolbarOverflow } from './lg-toolbar-overflow';\nimport { applyCustomIcons, LgIcons } from './lg-icons';\nimport { runSprings } from './lg-spring-runner';\nimport utils, { GalleryItem, ImageSize } from './lg-utils';\nimport { $LG, lgQuery } from './lgQuery';\nimport {\n Coords,\n MediaContainerPosition,\n SlideDirection,\n VideoInfo,\n} from './types';\n\ndeclare let picturefill: any;\n\n// @ref - https://stackoverflow.com/questions/3971841/how-to-resize-images-proportionally-keeping-the-aspect-ratio\n// @ref - https://2ality.com/2017/04/setting-up-multi-platform-packages.html\n\n// Unique id for each gallery\nlet lgId = 0;\n\nexport class LightGallery {\n public settings!: LightGalleryAllSettings;\n public galleryItems!: GalleryItem[];\n\n // Current gallery item\n public lgId!: number;\n\n public el!: HTMLElement;\n public LGel!: lgQuery;\n public lgOpened = false;\n\n public index = 0;\n\n // lightGallery modules\n public plugins: any[] = [];\n\n // false when lightGallery load first slide content;\n public lGalleryOn = false;\n\n // True when a slide animation is in progress\n public lgBusy = false;\n // Built-in icon SVGs: core defaults + whatever the instantiated\n // plugins register; `settings.icons` overrides per name at apply.\n private defaultIcons: LgIcons = { ...coreDefaultIcons };\n private toolbarOverflow?: ToolbarOverflow;\n\n // Type of touch action - {swipe, zoomSwipe, pinch}\n public touchAction?: 'swipe' | 'zoomSwipe' | 'pinch';\n\n // Direction of swipe/drag - {horizontal, vertical}\n public swipeDirection?: 'horizontal' | 'vertical';\n\n // Rolling gesture samples, for the windowed release velocity\n private swipeSamples: VelocitySample[] = [];\n\n // Cancels a running release spring (slide snap-back / drag restore)\n private cancelSlideSpring?: () => void;\n\n // Timeout function for hiding controls;\n public hideBarTimeout: any;\n\n public currentItemsInDom: string[] = [];\n\n public outer!: lgQuery;\n\n public items: any;\n\n public $backdrop!: lgQuery;\n public $lgComponents!: lgQuery;\n\n public $container!: lgQuery;\n\n public $inner!: lgQuery;\n public $content!: lgQuery;\n public $toolbar!: lgQuery;\n\n // Scroll top value before lightGallery is opened\n public prevScrollTop = 0;\n\n // Element that held focus before the gallery opened; focus is returned\n // to it after close (dialog pattern; captured only when trapFocus runs).\n private prevActiveElement?: HTMLElement;\n\n public bodyPaddingRight = 0;\n\n private zoomFromOrigin!: boolean;\n\n // Read by the zoom plugin (upstream 2.x exposes it the same way).\n public currentImageSize?: ImageSize;\n\n private isDummyImageRemoved = false;\n\n private dragOrSwipeEnabled = false;\n\n public mediaContainerPosition = {\n top: 0,\n bottom: 0,\n };\n\n constructor(element: HTMLElement, options?: LightGallerySettings) {\n if (!element) {\n return this;\n }\n lgId++;\n this.lgId = lgId;\n\n this.el = element;\n this.LGel = $LG(element);\n\n this.generateSettings(options);\n\n this.buildModules();\n\n // When using dynamic mode, ensure dynamicEl is an array\n if (\n this.settings.dynamic &&\n this.settings.dynamicEl !== undefined &&\n !Array.isArray(this.settings.dynamicEl)\n ) {\n throw 'When using dynamic mode, you must also define dynamicEl as an Array.';\n }\n\n this.galleryItems = this.getItems();\n this.normalizeSettings();\n\n // Gallery items\n\n this.init();\n\n this.validateLicense();\n\n return this;\n }\n\n private generateSettings(options?: LightGallerySettings) {\n // lightGallery settings\n this.settings = {\n ...lightGalleryCoreSettings,\n ...options,\n // Strings merge per-key (headless resolveSettings parity), // a partial override keeps every other default.\n strings: {\n ...lightGalleryCoreSettings.strings,\n ...(options?.strings ?? {}),\n },\n } as LightGalleryAllSettings;\n if (\n this.settings.isMobile &&\n typeof this.settings.isMobile === 'function'\n ? this.settings.isMobile()\n : utils.isMobile()\n ) {\n const mobileSettings = {\n ...this.settings.mobileSettings,\n };\n this.settings = { ...this.settings, ...mobileSettings };\n }\n\n // prefers-reduced-motion collapses every animation to 0ms and\n // disables the zoom-from-origin/bounce effects (a11y; checked once\n // per instance, matching the React/Vue/Angular bindings).\n if (\n typeof window !== 'undefined' &&\n typeof window.matchMedia === 'function' &&\n window.matchMedia('(prefers-reduced-motion: reduce)').matches\n ) {\n this.settings = {\n ...this.settings,\n speed: 0,\n backdropDuration: 0,\n startAnimationDuration: 0,\n zoomFromOrigin: false,\n slideEndAnimation: false,\n };\n }\n }\n\n private normalizeSettings() {\n // Resolve direction 'auto' against the gallery element once, // every direction-aware call site reads the resolved value.\n if (this.settings.direction === 'auto') {\n this.settings.direction =\n typeof window !== 'undefined' &&\n typeof window.getComputedStyle === 'function' &&\n window.getComputedStyle(this.el).direction === 'rtl'\n ? 'rtl'\n : 'ltr';\n }\n if (this.settings.slideEndAnimation) {\n this.settings.hideControlOnEnd = false;\n }\n if (!this.settings.closable) {\n this.settings.swipeToClose = false;\n }\n\n // And reset it on close to get the correct value next time\n this.zoomFromOrigin = this.settings.zoomFromOrigin;\n\n // At the moment, Zoom from image doesn't support dynamic options\n // @todo add zoomFromOrigin support for dynamic images\n if (this.settings.dynamic) {\n this.zoomFromOrigin = false;\n }\n\n if (this.settings.container) {\n const { container } = this.settings;\n if (typeof container === 'function') {\n this.settings.container = container();\n } else if (typeof container === 'string') {\n const el = document.querySelector<HTMLElement>(container);\n this.settings.container = el ?? document.body;\n }\n } else {\n this.settings.container = document.body;\n }\n\n // settings.preload should not be grater than $item.length\n this.settings.preload = Math.min(\n this.settings.preload,\n this.galleryItems.length,\n );\n }\n\n init(): void {\n this.addSlideVideoInfo(this.galleryItems);\n\n this.buildStructure();\n\n this.LGel.trigger(lGEvents.init, {\n instance: this,\n });\n\n if (this.settings.keyPress) {\n this.keyPress();\n }\n\n setTimeout(() => {\n this.enableDrag();\n this.enableSwipe();\n this.triggerPosterClick();\n }, 50);\n\n this.arrow();\n if (this.settings.mousewheel) {\n this.mousewheel();\n }\n\n if (!this.settings.dynamic) {\n this.openGalleryOnItemClick();\n }\n }\n\n openGalleryOnItemClick(): void {\n // Using for loop instead of using bubbling as the items can be any html element.\n for (let index = 0; index < this.items.length; index++) {\n const element = this.items[index];\n const $element = $LG(element);\n // Using different namespace for click because click event should not unbind if selector is same object('this')\n // @todo manage all event listners - should have namespace that represent element\n const uuid = lgQuery.generateUUID();\n $element\n .attr('data-lg-id', uuid)\n .on(`click.lgcustom-item-${uuid}`, (e) => {\n e.preventDefault();\n const currentItemIndex = this.settings.index || index;\n this.openGallery(currentItemIndex, element);\n });\n }\n }\n\n /**\n * Module constructor\n * Modules are build incrementally.\n * Gallery should be opened only once all the modules are initialized.\n * use moduleBuildTimeout to make sure this\n */\n buildModules(): void {\n this.settings.plugins.forEach((plugin) => {\n this.plugins.push(new plugin(this, $LG));\n });\n }\n\n validateLicense(): void {\n const notice = takeLicenseNotice(this.settings.licenseKey);\n if (notice) console[notice.level](notice.message);\n }\n\n getSlideItem(index: number): lgQuery {\n return $LG(this.getSlideItemId(index));\n }\n\n getSlideItemId(index: number): string {\n return `#lg-item-${this.lgId}-${index}`;\n }\n\n getIdName(id: string): string {\n return `${id}-${this.lgId}`;\n }\n getElementById(id: string): lgQuery {\n return $LG(`#${this.getIdName(id)}`);\n }\n\n manageSingleSlideClassName(): void {\n if (this.galleryItems.length < 2) {\n this.outer.addClass('lg-single-item');\n } else {\n this.outer.removeClass('lg-single-item');\n }\n }\n\n buildStructure(): void {\n const container = this.$container && this.$container.get();\n if (container) {\n return;\n }\n let controls = '';\n let subHtmlCont = '';\n\n // Create controls\n if (this.settings.controls) {\n controls = `<button type=\"button\" id=\"${this.getIdName(\n 'lg-prev',\n )}\" aria-label=\"${\n this.settings.strings['previousSlide']\n }\" class=\"lg-prev lg-icon\"> ${this.settings.prevHtml} </button>\n <button type=\"button\" id=\"${this.getIdName(\n 'lg-next',\n )}\" aria-label=\"${\n this.settings.strings['nextSlide']\n }\" class=\"lg-next lg-icon\"> ${this.settings.nextHtml} </button>`;\n }\n\n if (this.settings.appendSubHtmlTo !== '.lg-item') {\n // When the announcer owns slide-change announcements the caption\n // bar must not be a second live region (double announcements).\n subHtmlCont = this.settings.ariaAnnouncements\n ? '<div class=\"lg-sub-html\"></div>'\n : '<div class=\"lg-sub-html\" role=\"status\" aria-live=\"polite\"></div>';\n }\n\n let addClasses = '';\n\n if (this.settings.allowMediaOverlap) {\n // Do not remove space before last single quote\n addClasses += 'lg-media-overlap ';\n }\n\n // Dialogs need an accessible name; fall back to a localizable\n // aria-label when the consumer doesn't provide ariaLabelledby.\n const ariaLabelledby = this.settings.ariaLabelledby\n ? 'aria-labelledby=\"' + this.settings.ariaLabelledby + '\"'\n : `aria-label=\"${this.settings.strings['galleryLabel']}\"`;\n const ariaDescribedby = this.settings.ariaDescribedby\n ? 'aria-describedby=\"' + this.settings.ariaDescribedby + '\"'\n : '';\n\n const containerClassName = `lg-container ${this.settings.addClass} ${\n document.body !== this.settings.container ? 'lg-inline' : ''\n }`;\n const closeIcon =\n this.settings.closable && this.settings.showCloseIcon\n ? `<button type=\"button\" aria-label=\"${\n this.settings.strings['closeGallery']\n }\" id=\"${this.getIdName(\n 'lg-close',\n )}\" class=\"lg-close lg-icon\"></button>`\n : '';\n const maximizeIcon = this.settings.showMaximizeIcon\n ? `<button type=\"button\" aria-label=\"${\n this.settings.strings['toggleMaximize']\n }\" id=\"${this.getIdName(\n 'lg-maximize',\n )}\" class=\"lg-maximize lg-icon\"></button>`\n : '';\n const template = `\n <div class=\"${containerClassName}\" id=\"${this.getIdName(\n 'lg-container',\n )}\" tabindex=\"-1\" aria-modal=\"true\" ${ariaLabelledby} ${ariaDescribedby} role=\"dialog\" dir=\"${this.getDirection()}\"\n >\n <div id=\"${this.getIdName(\n 'lg-backdrop',\n )}\" class=\"lg-backdrop\"></div>\n ${\n this.settings.ariaAnnouncements\n ? `<div id=\"${this.getIdName(\n 'lg-announcer',\n )}\" class=\"lg-announcer\" role=\"status\" aria-live=\"polite\"></div>`\n : ''\n }\n\n <div id=\"${this.getIdName(\n 'lg-outer',\n )}\" class=\"lg-outer lg-use-css3 lg-css3 lg-hide-items ${addClasses} \">\n\n <div id=\"${this.getIdName('lg-content')}\" class=\"lg-content\">\n <div id=\"${this.getIdName('lg-inner')}\" class=\"lg-inner\">\n </div>\n ${controls}\n </div>\n <div id=\"${this.getIdName(\n 'lg-toolbar',\n )}\" class=\"lg-toolbar lg-group\">\n ${maximizeIcon}\n ${closeIcon}\n </div>\n ${\n this.settings.appendSubHtmlTo === '.lg-outer'\n ? subHtmlCont\n : ''\n }\n <div id=\"${this.getIdName(\n 'lg-components',\n )}\" class=\"lg-components\">\n ${\n this.settings.appendSubHtmlTo === '.lg-sub-html'\n ? subHtmlCont\n : ''\n }\n </div>\n </div>\n </div>\n `;\n\n $LG(this.settings.container).append(template);\n\n if (document.body !== this.settings.container) {\n $LG(this.settings.container).css('position', 'relative');\n }\n\n this.outer = this.getElementById('lg-outer');\n this.$lgComponents = this.getElementById('lg-components');\n this.$backdrop = this.getElementById('lg-backdrop');\n this.$container = this.getElementById('lg-container');\n this.$inner = this.getElementById('lg-inner');\n this.$content = this.getElementById('lg-content');\n this.$toolbar = this.getElementById('lg-toolbar');\n\n this.$backdrop.css(\n 'transition-duration',\n this.settings.backdropDuration + 'ms',\n );\n\n let outerClassNames = `${this.settings.mode} `;\n\n this.manageSingleSlideClassName();\n\n if (this.settings.enableDrag) {\n outerClassNames += 'lg-grab ';\n }\n\n this.outer.addClass(outerClassNames);\n\n this.$inner.css('transition-timing-function', this.settings.easing);\n this.$inner.css('transition-duration', this.settings.speed + 'ms');\n // Slides read the speed per property: the transform runs for the\n // full duration while the crossfade stays short (see the mode\n // transitions in the stylesheet).\n this.$inner.css('--lg-speed', this.settings.speed + 'ms');\n\n if (this.settings.download) {\n this.$toolbar.append(\n `<a id=\"${this.getIdName(\n 'lg-download',\n )}\" target=\"_blank\" rel=\"noopener\" aria-label=\"${\n this.settings.strings['download']\n }\" download class=\"lg-download lg-icon\"></a>`,\n );\n }\n\n this.counter();\n\n $LG(window).on(\n `resize.lg.global${this.lgId} orientationchange.lg.global${this.lgId}`,\n () => {\n this.refreshOnResize();\n },\n );\n\n this.hideBars();\n\n this.manageCloseGallery();\n this.toggleMaximize();\n\n this.initModules();\n\n // After the plugins have appended their buttons, and before the\n // icon pass, so the More options button gets its icon too.\n if (this.settings.toolbarOverflow) {\n this.toolbarOverflow = new ToolbarOverflow(this.$toolbar.get(), {\n id: this.getIdName('lg-more'),\n label: this.settings.strings.moreOptions,\n });\n const update = () => this.toolbarOverflow?.update();\n this.LGel.on(`${lGEvents.afterOpen}.lg`, update);\n this.LGel.on(`${lGEvents.afterSlide}.lg`, update);\n this.LGel.on(`${lGEvents.containerResize}.lg`, update);\n this.LGel.on(`${lGEvents.beforeClose}.lg`, () =>\n this.toolbarOverflow?.close(false),\n );\n }\n\n // Icons: one pass after the plugins have appended their buttons\n // and registered their default sets, every icon element exists\n // by now. `settings.icons` overrides per name; pairs fall back\n // whole (see lg-icons.ts).\n applyCustomIcons(\n this.$container.get(),\n this.defaultIcons,\n this.settings.icons,\n );\n }\n\n /**\n * Merge a plugin's built-in icon SVGs into the default set (called\n * from plugin `init()`, before the icon pass runs). Consumer\n * `settings.icons` still win over anything registered here.\n */\n registerDefaultIcons(icons: LgIcons): void {\n this.defaultIcons = { ...this.defaultIcons, ...icons };\n }\n\n /**\n * Cache the fitted (contain) size of a slide's media. Every consumer\n * of `currentImageSize` measures against the CURRENT slide: the\n * actual-size zoom divides the natural width by it, and the\n * zoom-from-origin close flight positions against it. Recomputed on\n * every slide change, not just at open — one cached landscape size\n * makes a portrait slide zoom to the wrong scale and then snap to\n * its real size when the natural-px swap lands.\n */\n private updateCurrentImageSize(index: number): void {\n const { __slideVideoInfo } = this.galleryItems[index];\n const { top, bottom } = this.mediaContainerPosition;\n this.currentImageSize = utils.getSize(\n this.items[index],\n this.outer,\n top + bottom,\n __slideVideoInfo && this.settings.videoMaxSize,\n );\n }\n\n refreshOnResize(): void {\n if (this.lgOpened) {\n const currentGalleryItem = this.galleryItems[this.index];\n const { __slideVideoInfo } = currentGalleryItem;\n\n this.mediaContainerPosition = this.getMediaContainerPosition();\n this.updateCurrentImageSize(this.index);\n if (__slideVideoInfo) {\n this.resizeVideoSlide(this.index, this.currentImageSize);\n }\n if (this.zoomFromOrigin && !this.isDummyImageRemoved) {\n const imgStyle = this.getDummyImgStyles(this.currentImageSize);\n this.outer\n .find('.lg-current .lg-dummy-img')\n .first()\n .attr('style', imgStyle);\n }\n this.LGel.trigger(lGEvents.containerResize);\n }\n }\n\n resizeVideoSlide(index: number, imageSize?: ImageSize): void {\n const lgVideoStyle = this.getVideoContStyle(imageSize);\n const currentSlide = this.getSlideItem(index);\n currentSlide.find('.lg-video-cont').attr('style', lgVideoStyle);\n }\n\n /**\n * Update slides dynamically.\n * Add, edit or delete slides dynamically when lightGallery is opened.\n * Modify the current gallery items and pass it via updateSlides method\n * @note\n * - Do not mutate existing lightGallery items directly.\n * - Always pass new list of gallery items\n * - You need to take care of thumbnails outside the gallery if any\n * - user this method only if you want to update slides when the gallery is opened. Otherwise, use `refresh()` method.\n * @param items Gallery items\n * @param index After the update operation, which slide gallery should navigate to\n * @category lGPublicMethods\n * @example\n * const plugin = lightGallery();\n *\n * // Adding slides dynamically\n * let galleryItems = [\n * // Access existing lightGallery items\n * // galleryItems are automatically generated internally from the gallery HTML markup\n * // or directly from galleryItems when dynamic gallery is used\n * ...plugin.galleryItems,\n * ...[\n * {\n * src: 'img/img-1.png',\n * thumb: 'img/thumb1.png',\n * },\n * ],\n * ];\n * plugin.updateSlides(\n * galleryItems,\n * plugin.index,\n * );\n *\n *\n * // Remove slides dynamically\n * galleryItems = JSON.parse(\n * JSON.stringify(updateSlideInstance.galleryItems),\n * );\n * galleryItems.shift();\n * updateSlideInstance.updateSlides(galleryItems, 1);\n * @see <a href=\"/demos/update-slides/\">Demo</a>\n */\n updateSlides(items: GalleryItem[], index: number): void {\n if (this.index > items.length - 1) {\n this.index = items.length - 1;\n }\n if (items.length === 1) {\n this.index = 0;\n }\n if (!items.length) {\n this.closeGallery();\n return;\n }\n const currentSrc = this.galleryItems[index].src;\n this.galleryItems = items;\n this.updateControls();\n this.$inner.empty();\n this.currentItemsInDom = [];\n\n let _index = 0;\n // Find the current index based on source value of the slide\n this.galleryItems.some((galleryItem, itemIndex) => {\n if (galleryItem.src === currentSrc) {\n _index = itemIndex;\n return true;\n }\n return false;\n });\n\n this.currentItemsInDom = this.organizeSlideItems(_index, -1);\n this.loadContent(_index, true);\n this.getSlideItem(_index).addClass('lg-current');\n\n this.index = _index;\n this.updateCurrentCounter(_index);\n this.LGel.trigger(lGEvents.updateSlides);\n }\n\n // Get gallery items based on multiple conditions\n getItems(): GalleryItem[] {\n // Gallery items\n this.items = [];\n if (!this.settings.dynamic) {\n if (this.settings.selector === 'this') {\n this.items.push(this.el);\n } else if (this.settings.selector) {\n if (typeof this.settings.selector === 'string') {\n if (this.settings.selectWithin) {\n const selectWithin = $LG(this.settings.selectWithin);\n this.items = selectWithin\n .find(this.settings.selector)\n .get();\n } else {\n this.items = this.el.querySelectorAll(\n this.settings.selector,\n );\n }\n } else {\n this.items = this.settings.selector;\n }\n } else {\n this.items = this.el.children;\n }\n return utils.getDynamicOptions(\n this.items,\n this.settings.extraProps,\n this.settings.getCaptionFromTitleOrAlt,\n this.settings.exThumbImage,\n );\n } else {\n return this.settings.dynamicEl || [];\n }\n }\n\n shouldHideScrollbar(): boolean {\n return (\n this.settings.hideScrollbar &&\n document.body === this.settings.container\n );\n }\n\n hideScrollbar(): void {\n if (!this.shouldHideScrollbar()) {\n return;\n }\n this.bodyPaddingRight = parseFloat($LG('body').style().paddingRight);\n const bodyRect = document.documentElement.getBoundingClientRect();\n const scrollbarWidth = window.innerWidth - bodyRect.width;\n\n $LG(document.body).css(\n 'padding-right',\n scrollbarWidth + this.bodyPaddingRight + 'px',\n );\n $LG(document.body).addClass('lg-overlay-open');\n }\n\n resetScrollBar(): void {\n if (!this.shouldHideScrollbar()) {\n return;\n }\n $LG(document.body).css('padding-right', this.bodyPaddingRight + 'px');\n $LG(document.body).removeClass('lg-overlay-open');\n }\n\n /**\n * Open lightGallery.\n * Open gallery with specific slide by passing index of the slide as parameter.\n * @category lGPublicMethods\n * @param {Number} index - index of the slide\n * @param {HTMLElement} element - Which image lightGallery should zoom from\n *\n * @example\n * const $dynamicGallery = document.getElementById('dynamic-gallery-demo');\n * const dynamicGallery = lightGallery($dynamicGallery, {\n * dynamic: true,\n * dynamicEl: [\n * {\n * src: 'img/1.jpg',\n * thumb: 'img/thumb-1.jpg',\n * subHtml: '<h4>Image 1 title</h4><p>Image 1 descriptions.</p>',\n * },\n * ...\n * ],\n * });\n * $dynamicGallery.addEventListener('click', function () {\n * // Starts with third item.(Optional).\n * // This is useful if you want use dynamic mode with\n * // custom thumbnails (thumbnails outside gallery),\n * dynamicGallery.openGallery(2);\n * });\n *\n */\n openGallery(index = this.settings.index, element?: HTMLElement): void {\n // prevent accidental double execution\n if (this.lgOpened) return;\n this.lgOpened = true;\n this.outer.removeClass('lg-hide-items');\n\n this.hideScrollbar();\n\n // Add display block, but still has opacity 0\n this.$container.addClass('lg-show');\n\n const itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(\n index,\n index,\n );\n this.currentItemsInDom = itemsToBeInsertedToDom;\n\n let items = '';\n itemsToBeInsertedToDom.forEach((item) => {\n items = items + `<div id=\"${item}\" class=\"lg-item\"></div>`;\n });\n\n this.$inner.append(items);\n this.addHtml(index);\n let transform: string | undefined = '';\n this.mediaContainerPosition = this.getMediaContainerPosition();\n const { top, bottom } = this.mediaContainerPosition;\n if (!this.settings.allowMediaOverlap) {\n this.setMediaContainerPosition(top, bottom);\n }\n const { __slideVideoInfo } = this.galleryItems[index];\n if (this.zoomFromOrigin && element) {\n this.currentImageSize = utils.getSize(\n element,\n this.outer,\n top + bottom,\n __slideVideoInfo && this.settings.videoMaxSize,\n );\n transform = this.getOriginTransform(element, this.currentImageSize);\n }\n if (!this.zoomFromOrigin || !transform) {\n this.outer.addClass(this.settings.startClass);\n this.getSlideItem(index).removeClass('lg-complete');\n }\n const timeout = this.settings.zoomFromOrigin\n ? 100\n : this.settings.backdropDuration;\n setTimeout(() => {\n this.outer.addClass('lg-components-open');\n }, timeout);\n this.index = index;\n this.LGel.trigger(lGEvents.beforeOpen);\n\n // add class lg-current to remove initial transition\n this.getSlideItem(index).addClass('lg-current');\n\n this.lGalleryOn = false;\n // Store the current scroll top value to scroll back after closing the gallery..\n this.prevScrollTop = $LG(window).scrollTop();\n\n // Remember where focus came from so it can be returned on close\n // (dialog pattern). Captured under the same condition that moves\n // focus into the gallery, never touched otherwise.\n if (\n this.settings.trapFocus &&\n document.body === this.settings.container\n ) {\n this.prevActiveElement =\n document.activeElement instanceof HTMLElement\n ? document.activeElement\n : undefined;\n }\n\n setTimeout(() => {\n // Need to check both zoomFromOrigin and transform values as we need to set set the\n // default opening animation if user missed to add the lg-size attribute\n\n if (this.zoomFromOrigin && transform) {\n const currentSlide = this.getSlideItem(index);\n currentSlide.css('transform', transform);\n setTimeout(() => {\n currentSlide\n .addClass('lg-start-progress lg-start-end-progress')\n .css(\n 'transition-duration',\n this.settings.startAnimationDuration + 'ms',\n );\n this.outer.addClass('lg-zoom-from-image');\n });\n setTimeout(() => {\n currentSlide.css('transform', 'translate3d(0, 0, 0)');\n }, 100);\n }\n\n setTimeout(() => {\n this.$backdrop.addClass('in');\n this.$container.addClass('lg-show-in');\n }, 10);\n\n setTimeout(() => {\n if (\n this.settings.trapFocus &&\n document.body === this.settings.container\n ) {\n this.trapFocus();\n }\n }, this.settings.backdropDuration + 50);\n\n // lg-visible class resets gallery opacity to 1\n if (!this.zoomFromOrigin || !transform) {\n setTimeout(() => {\n this.outer.addClass('lg-visible');\n }, this.settings.backdropDuration);\n }\n\n // initiate slide function\n this.slide(index, false, false, false);\n\n this.LGel.trigger(lGEvents.afterOpen);\n });\n\n if (document.body === this.settings.container) {\n $LG('html').addClass('lg-on');\n }\n }\n\n /**\n * The zoom-from-origin transform for a trigger: it lands the slide on\n * the trigger's thumbnail, the start of the opening flight and the end\n * of the closing one. Undefined when the trigger cannot anchor a flight,\n * and the gallery opens or closes about the stage centre instead.\n * Plugins may replace it on the instance to fly differently.\n */\n public getOriginTransform(\n element: HTMLElement,\n imageSize?: ImageSize,\n ): string | undefined {\n const { top, bottom } = this.mediaContainerPosition;\n return utils.getTransform(element, this.outer, top, bottom, imageSize);\n }\n\n /**\n * Note - Changing the position of the media on every slide transition creates a flickering effect.\n * Therefore, The height of the caption is calculated dynamically, only once based on the first slide caption.\n * if you have dynamic captions for each media,\n * you can provide an appropriate height for the captions via allowMediaOverlap option\n */\n public getMediaContainerPosition(): MediaContainerPosition {\n if (this.settings.allowMediaOverlap) {\n return {\n top: 0,\n bottom: 0,\n };\n }\n const top = this.$toolbar.get().clientHeight || 0;\n const subHtml = this.outer.find('.lg-components .lg-sub-html').get();\n const captionHeight =\n this.settings.defaultCaptionHeight ||\n (subHtml && subHtml.clientHeight) ||\n 0;\n const thumbContainer = this.outer.find('.lg-thumb-outer').get();\n const thumbHeight = thumbContainer ? thumbContainer.clientHeight : 0;\n const bottom = thumbHeight + captionHeight;\n return {\n top,\n bottom,\n };\n }\n\n private setMediaContainerPosition(top = 0, bottom = 0): void {\n this.$content.css('top', top + 'px').css('bottom', bottom + 'px');\n }\n\n hideBars(): void {\n // Hide controllers if mouse doesn't move for some period\n setTimeout(() => {\n this.outer.removeClass('lg-hide-items');\n if (this.settings.hideBarsDelay > 0) {\n this.outer.on('mousemove.lg click.lg touchstart.lg', () => {\n this.outer.removeClass('lg-hide-items');\n\n clearTimeout(this.hideBarTimeout);\n\n // Timeout will be cleared on each slide movement also\n this.hideBarTimeout = setTimeout(() => {\n this.outer.addClass('lg-hide-items');\n }, this.settings.hideBarsDelay);\n });\n this.outer.trigger('mousemove.lg');\n }\n }, this.settings.showBarsAfter);\n }\n\n initPictureFill($img: lgQuery): void {\n if (this.settings.supportLegacyBrowser) {\n try {\n picturefill({\n elements: [$img.get()],\n });\n } catch (e) {\n console.warn(\n 'lightGallery :- If you want srcset or picture tag to be supported for older browser please include picturefil javascript library in your document. See https://www.lightgalleryjs.com/docs/responsive-loading/',\n );\n }\n }\n }\n\n /**\n * @desc Create image counter\n * Ex: 1/10\n */\n counter(): void {\n if (this.settings.counter) {\n // With the announcer active the counter is decorative, the\n // announcer already conveys the position in a friendlier form.\n const counterA11yAttrs = this.settings.ariaAnnouncements\n ? 'aria-hidden=\"true\"'\n : 'role=\"status\" aria-live=\"polite\"';\n const counterHtml = `<div class=\"lg-counter\" ${counterA11yAttrs}>\n <span id=\"${this.getIdName(\n 'lg-counter-current',\n )}\" class=\"lg-counter-current\">${this.index + 1} </span> /\n <span id=\"${this.getIdName(\n 'lg-counter-all',\n )}\" class=\"lg-counter-all\">${\n this.galleryItems.length\n } </span></div>`;\n this.outer.find(this.settings.appendCounterTo).append(counterHtml);\n }\n }\n\n /**\n * @desc add sub-html into the slide\n * @param {Number} index - index of the slide\n */\n addHtml(index: number): void {\n let subHtml;\n let subHtmlUrl;\n if (this.galleryItems[index].subHtmlUrl) {\n subHtmlUrl = this.galleryItems[index].subHtmlUrl;\n } else {\n subHtml = this.galleryItems[index].subHtml;\n }\n\n if (!subHtmlUrl) {\n if (subHtml) {\n // get first letter of sub-html\n // if first letter starts with . or # get the html form the jQuery object\n const fL = subHtml.substring(0, 1);\n if (fL === '.' || fL === '#') {\n try {\n if (\n this.settings.subHtmlSelectorRelative &&\n !this.settings.dynamic\n ) {\n subHtml = $LG(this.items)\n .eq(index)\n .find(subHtml)\n .first()\n .html();\n } else {\n subHtml = $LG(subHtml).first().html();\n }\n } catch (error) {\n console.warn(\n `lightGallery: error processing subHtml selector \"${subHtml}\". See https://www.lightgalleryjs.com/demos/captions/`,\n );\n subHtml = '';\n }\n }\n } else {\n subHtml = '';\n }\n }\n\n if (this.settings.appendSubHtmlTo !== '.lg-item') {\n if (subHtmlUrl) {\n utils.fetchCaptionFromUrl(\n subHtmlUrl,\n this.outer.find('.lg-sub-html'),\n 'replace',\n );\n } else {\n this.outer.find('.lg-sub-html').html(subHtml as string);\n }\n } else {\n const currentSlide = $LG(this.getSlideItemId(index));\n if (subHtmlUrl) {\n utils.fetchCaptionFromUrl(subHtmlUrl, currentSlide, 'append');\n } else {\n currentSlide.append(\n `<div class=\"lg-sub-html\">${subHtml}</div>`,\n );\n }\n }\n\n // Add lg-empty-html class if title doesn't exist\n if (typeof subHtml !== 'undefined' && subHtml !== null) {\n if (subHtml === '') {\n this.outer\n .find(this.settings.appendSubHtmlTo)\n .addClass('lg-empty-html');\n } else {\n this.outer\n .find(this.settings.appendSubHtmlTo)\n .removeClass('lg-empty-html');\n }\n }\n\n this.LGel.trigger<AfterAppendSubHtmlDetail>(\n lGEvents.afterAppendSubHtml,\n {\n index,\n },\n );\n }\n\n /**\n * @desc Preload slides\n * @param {Number} index - index of the slide\n * @todo preload not working for the first slide, Also, should work for the first and last slide as well\n */\n preload(index: number): void {\n for (let i = 1; i <= this.settings.preload; i++) {\n if (i >= this.galleryItems.length - index) {\n break;\n }\n\n this.loadContent(index + i, false);\n }\n\n for (let j = 1; j <= this.settings.preload; j++) {\n if (index - j < 0) {\n break;\n }\n\n this.loadContent(index - j, false);\n }\n }\n\n getDummyImgStyles(imageSize?: ImageSize): string {\n if (!imageSize) return '';\n return `width:${imageSize.width}px;\n margin-left: -${imageSize.width / 2}px;\n margin-top: -${imageSize.height / 2}px;\n height:${imageSize.height}px`;\n }\n getVideoContStyle(imageSize?: ImageSize): string {\n if (!imageSize) return '';\n return `width:${imageSize.width}px;\n height:${imageSize.height}px`;\n }\n\n getDummyImageContent(\n $currentSlide: lgQuery,\n index: number,\n alt: string,\n ): HTMLImageElement | string {\n let $currentItem;\n if (!this.settings.dynamic) {\n $currentItem = $LG(this.items).eq(index);\n }\n if ($currentItem) {\n let _dummyImgSrc;\n if (!this.settings.exThumbImage) {\n _dummyImgSrc = $currentItem.find('img').first().attr('src');\n } else {\n _dummyImgSrc = $currentItem.attr(this.settings.exThumbImage);\n }\n if (!_dummyImgSrc) return '';\n const imgStyle = this.getDummyImgStyles(this.currentImageSize);\n const dummyImgContentImg = document.createElement('img');\n dummyImgContentImg.alt = alt || '';\n dummyImgContentImg.src = _dummyImgSrc;\n dummyImgContentImg.className = `lg-dummy-img`;\n dummyImgContentImg.style.cssText = imgStyle;\n\n $currentSlide.addClass('lg-first-slide');\n this.outer.addClass('lg-first-slide-loading');\n\n return dummyImgContentImg;\n }\n return '';\n }\n\n setImgMarkup(src: string, $currentSlide: lgQuery, index: number): void {\n const currentGalleryItem = this.galleryItems[index];\n const { alt, srcset, sizes, sources } = currentGalleryItem;\n\n // Use the thumbnail as dummy image which will be resized to actual image size and\n // displayed on top of actual image\n let imgContent: string | HTMLImageElement = '';\n const altAttr = alt ? 'alt=\"' + alt + '\"' : '';\n\n if (this.isFirstSlideWithZoomAnimation()) {\n imgContent = this.getDummyImageContent(\n $currentSlide,\n index,\n altAttr,\n );\n } else {\n imgContent = utils.getImgMarkup(\n index,\n src,\n altAttr,\n srcset,\n sizes,\n sources,\n );\n }\n const picture = document.createElement('picture');\n picture.className = 'lg-img-wrap';\n $LG(picture).append(imgContent);\n $currentSlide.prepend(picture);\n }\n\n onSlideObjectLoad(\n $slide: lgQuery,\n isHTML5VideoWithoutPoster: boolean,\n onLoad: () => void,\n onError: () => void,\n ): void {\n const mediaObject = $slide.find('.lg-object').first();\n const media = mediaObject.get() as HTMLImageElement;\n // Decode gate (shared contract with the bindings): completion\n // flips only once the browser can paint the FULL image, a\n // loaded-but-undecoded flip paints partially on slow devices.\n // Synchronous when `decode()` is unavailable; the timeout\n // fallback keeps a stalling decode from stranding the spinner.\n const gated = (handler: () => void) => {\n if (\n media instanceof HTMLImageElement &&\n typeof media.decode === 'function'\n ) {\n void awaitDecode(media).then(handler);\n } else {\n handler();\n }\n };\n if (utils.isImageLoaded(media) || isHTML5VideoWithoutPoster) {\n gated(onLoad);\n } else {\n mediaObject.on('load.lg error.lg', () => {\n gated(() => onLoad && onLoad());\n });\n mediaObject.on('error.lg', () => {\n onError && onError();\n });\n }\n }\n\n /**\n *\n * @param $el Current slide item\n * @param index\n * @param delay Delay is 0 except first time\n * @param speed Speed is same as delay, except it is 0 if gallery is opened via hash plugin\n * @param isFirstSlide\n */\n onLgObjectLoad(\n currentSlide: lgQuery,\n index: number,\n delay: number,\n speed: number,\n isFirstSlide: boolean,\n isHTML5VideoWithoutPoster: boolean,\n ): void {\n this.onSlideObjectLoad(\n currentSlide,\n isHTML5VideoWithoutPoster,\n () => {\n this.triggerSlideItemLoad(\n currentSlide,\n index,\n delay,\n speed,\n isFirstSlide,\n );\n },\n () => {\n currentSlide.addClass('lg-complete lg-complete_');\n currentSlide.html(\n '<span class=\"lg-error-msg\">' +\n this.settings.strings['mediaLoadingFailed'] +\n '</span>',\n );\n },\n );\n }\n\n triggerSlideItemLoad(\n $currentSlide: lgQuery,\n index: number,\n delay: number,\n speed: number,\n isFirstSlide: boolean,\n ): void {\n const currentGalleryItem = this.galleryItems[index];\n\n // Adding delay for video slides without poster for better performance and user experience\n // Videos should start playing once once the gallery is completely loaded\n const _speed =\n isFirstSlide &&\n this.getSlideType(currentGalleryItem) === 'video' &&\n !currentGalleryItem.poster\n ? speed\n : 0;\n setTimeout(() => {\n $currentSlide.addClass('lg-complete lg-complete_');\n this.LGel.trigger<SlideItemLoadDetail>(lGEvents.slideItemLoad, {\n index,\n delay: delay || 0,\n isFirstSlide,\n });\n }, _speed);\n }\n\n isFirstSlideWithZoomAnimation(): boolean {\n return !!(\n !this.lGalleryOn &&\n this.zoomFromOrigin &&\n this.currentImageSize\n );\n }\n\n // Add video slideInfo\n addSlideVideoInfo(items: GalleryItem[]): void {\n items.forEach((element, index) => {\n element.__slideVideoInfo = utils.isVideo(\n element.src as string,\n !!element.video,\n index,\n );\n const videoInfo = element.__slideVideoInfo;\n if (!videoInfo) {\n return;\n }\n if (this.settings.videoFacade !== false) {\n // Lite-embed facade: provider slides get a poster (item\n // poster → YouTube thumbnail endpoint → item thumb) so the\n // iframe is created only on play. The headless chain never\n // synthesizes a poster for html5 slides.\n element.poster = getFacadePoster(\n element,\n videoInfo,\n this.settings.loadYouTubePoster,\n );\n } else if (\n this.settings.loadYouTubePoster &&\n !element.poster &&\n videoInfo.youtube\n ) {\n // videoFacade:false, 2.x behavior: only the YouTube\n // poster is synthesized.\n element.poster = getYouTubePosterUrl(videoInfo);\n }\n });\n }\n\n /**\n * Load slide content into slide.\n * This is used to load content into slides that is not visible too\n * @param {Number} index - index of the slide.\n * @param {Boolean} rec - if true call loadcontent() function again.\n */\n loadContent(index: number, rec: boolean): void {\n const currentGalleryItem = this.galleryItems[index];\n const $currentSlide = $LG(this.getSlideItemId(index));\n\n const { poster, srcset, sizes, sources } = currentGalleryItem;\n let { src } = currentGalleryItem;\n\n const video = currentGalleryItem.video;\n\n const _html5Video =\n video && typeof video === 'string' ? JSON.parse(video) : video;\n\n if (currentGalleryItem.responsive) {\n const srcDyItms = currentGalleryItem.responsive.split(',');\n src = utils.getResponsiveSrc(srcDyItms) || src;\n }\n\n const videoInfo = currentGalleryItem.__slideVideoInfo;\n let lgVideoStyle = '';\n\n const iframe = !!currentGalleryItem.iframe;\n\n const isFirstSlide = !this.lGalleryOn;\n\n // delay for adding complete class. it is 0 except first time.\n let delay = 0;\n if (isFirstSlide) {\n if (this.zoomFromOrigin && this.currentImageSize) {\n delay = this.settings.startAnimationDuration + 10;\n } else {\n delay = this.settings.backdropDuration + 10;\n }\n }\n\n if (!$currentSlide.hasClass('lg-loaded')) {\n if (videoInfo) {\n const { top, bottom } = this.mediaContainerPosition;\n const videoSize = utils.getSize(\n this.items[index],\n this.outer,\n top + bottom,\n videoInfo && this.settings.videoMaxSize,\n );\n lgVideoStyle = this.getVideoContStyle(videoSize);\n }\n if (iframe) {\n const markup = utils.getIframeMarkup(\n this.settings.iframeWidth,\n this.settings.iframeHeight,\n this.settings.iframeMaxWidth,\n this.settings.iframeMaxHeight,\n src,\n currentGalleryItem.iframeTitle,\n );\n $currentSlide.prepend(markup);\n } else if (poster) {\n let dummyImg: string | HTMLImageElement = '';\n const hasStartAnimation =\n isFirstSlide &&\n this.zoomFromOrigin &&\n this.currentImageSize;\n if (hasStartAnimation) {\n dummyImg = this.getDummyImageContent(\n $currentSlide,\n index,\n '',\n );\n }\n\n const markup = utils.getVideoPosterMarkup(\n poster,\n dummyImg || '',\n lgVideoStyle,\n this.settings.strings['playVideo'],\n videoInfo,\n );\n $currentSlide.prepend(markup);\n } else if (videoInfo) {\n const markup = `<div class=\"lg-video-cont \" style=\"${lgVideoStyle}\"></div>`;\n $currentSlide.prepend(markup);\n } else {\n this.setImgMarkup(src as string, $currentSlide, index);\n if (srcset || sources) {\n const $img = $currentSlide.find('.lg-object');\n this.initPictureFill($img);\n }\n }\n if (poster || videoInfo) {\n this.LGel.trigger(lGEvents.hasVideo, {\n index,\n src: src,\n html5Video: _html5Video,\n hasPoster: !!poster,\n });\n }\n\n this.LGel.trigger<AfterAppendSlideEventDetail>(\n lGEvents.afterAppendSlide,\n { index },\n );\n\n if (\n this.lGalleryOn &&\n this.settings.appendSubHtmlTo === '.lg-item'\n ) {\n this.addHtml(index);\n }\n }\n\n // For first time add some delay for displaying the start animation.\n let _speed = 0;\n\n // Do not change the delay value because it is required for zoom plugin.\n // If gallery opened from direct url (hash) speed value should be 0\n if (delay && !$LG(document.body).hasClass('lg-from-hash')) {\n _speed = delay;\n }\n\n // Only for first slide and zoomFromOrigin is enabled\n if (this.isFirstSlideWithZoomAnimation()) {\n // The real image lands only once the zoom-from-origin flight\n // has actually ended. The flight's transition starts at the\n // first style recalc after the transform reset, which the\n // gallery's own first layout can push well past the fixed\n // offset, and a fast (cached) image appended on that offset then\n // swaps in over the still-scaling thumbnail.\n const settleFlight = (onLanded: () => void) =>\n onTransitionSettle(\n $currentSlide.get(),\n 'transform',\n this.settings.startAnimationDuration + 100,\n onLanded,\n );\n settleFlight(() => {\n $currentSlide\n .removeClass('lg-start-end-progress lg-start-progress')\n .removeAttr('style');\n });\n if (!$currentSlide.hasClass('lg-loaded')) {\n settleFlight(() => {\n if (this.getSlideType(currentGalleryItem) === 'image') {\n const { alt } = currentGalleryItem;\n const altAttr = alt ? 'alt=\"' + alt + '\"' : '';\n\n $currentSlide\n .find('.lg-img-wrap')\n .append(\n utils.getImgMarkup(\n index,\n src as string,\n altAttr,\n srcset,\n sizes,\n currentGalleryItem.sources,\n ),\n );\n if (srcset || sources) {\n const $img = $currentSlide.find('.lg-object');\n this.initPictureFill($img);\n }\n }\n if (\n this.getSlideType(currentGalleryItem) === 'image' ||\n (this.getSlideType(currentGalleryItem) === 'video' &&\n poster)\n ) {\n this.onLgObjectLoad(\n $currentSlide,\n index,\n delay,\n _speed,\n true,\n false,\n );\n\n // load remaining slides once the slide is completely loaded\n this.onSlideObjectLoad(\n $currentSlide,\n !!(videoInfo && videoInfo.html5 && !poster),\n () => {\n this.loadContentOnFirstSlideLoad(\n index,\n $currentSlide,\n _speed,\n );\n },\n () => {\n this.loadContentOnFirstSlideLoad(\n index,\n $currentSlide,\n _speed,\n );\n },\n );\n }\n });\n }\n }\n\n // SLide content has been added to dom\n $currentSlide.addClass('lg-loaded');\n\n if (\n !this.isFirstSlideWithZoomAnimation() ||\n (this.getSlideType(currentGalleryItem) === 'video' && !poster)\n ) {\n this.onLgObjectLoad(\n $currentSlide,\n index,\n delay,\n _speed,\n isFirstSlide,\n !!(videoInfo && videoInfo.html5 && !poster),\n );\n }\n\n // When gallery is opened once content is loaded (second time) need to add lg-complete class for css styling\n if (\n (!this.zoomFromOrigin || !this.currentImageSize) &&\n $currentSlide.hasClass('lg-complete_') &&\n !this.lGalleryOn\n ) {\n setTimeout(() => {\n $currentSlide.addClass('lg-complete');\n }, this.settings.backdropDuration);\n }\n\n // Content loaded\n // Need to set lGalleryOn before calling preload function\n this.lGalleryOn = true;\n\n if (rec === true) {\n if (!$currentSlide.hasClass('lg-complete_')) {\n $currentSlide\n .find('.lg-object')\n .first()\n .on('load.lg error.lg', () => {\n this.preload(index);\n });\n } else {\n this.preload(index);\n }\n }\n }\n\n /**\n * @desc Remove dummy image content and load next slides\n * Called only for the first time if zoomFromOrigin animation is enabled\n * @param index\n * @param $currentSlide\n * @param speed\n */\n loadContentOnFirstSlideLoad(\n index: number,\n $currentSlide: lgQuery,\n speed: number,\n ): void {\n setTimeout(() => {\n $currentSlide.find('.lg-dummy-img').remove();\n $currentSlide.removeClass('lg-first-slide');\n this.outer.removeClass('lg-first-slide-loading');\n this.isDummyImageRemoved = true;\n this.preload(index);\n }, speed + 300);\n }\n\n getItemsToBeInsertedToDom(\n index: number,\n prevIndex: number,\n numberOfItems = 0,\n ): string[] {\n const itemsToBeInsertedToDom: string[] = [];\n // Minimum 2 items should be there\n let possibleNumberOfItems = Math.max(numberOfItems, 3);\n possibleNumberOfItems = Math.min(\n possibleNumberOfItems,\n this.galleryItems.length,\n );\n const prevIndexItem = `lg-item-${this.lgId}-${prevIndex}`;\n if (this.galleryItems.length <= 3) {\n this.galleryItems.forEach((_element, index) => {\n itemsToBeInsertedToDom.push(`lg-item-${this.lgId}-${index}`);\n });\n return itemsToBeInsertedToDom;\n }\n\n if (index < (this.galleryItems.length - 1) / 2) {\n for (\n let idx = index;\n idx > index - possibleNumberOfItems / 2 && idx >= 0;\n idx--\n ) {\n itemsToBeInsertedToDom.push(`lg-item-${this.lgId}-${idx}`);\n }\n const numberOfExistingItems = itemsToBeInsertedToDom.length;\n for (\n let idx = 0;\n idx < possibleNumberOfItems - numberOfExistingItems;\n idx++\n ) {\n itemsToBeInsertedToDom.push(\n `lg-item-${this.lgId}-${index + idx + 1}`,\n );\n }\n } else {\n for (\n let idx = index;\n idx <= this.galleryItems.length - 1 &&\n idx < index + possibleNumberOfItems / 2;\n idx++\n ) {\n itemsToBeInsertedToDom.push(`lg-item-${this.lgId}-${idx}`);\n }\n const numberOfExistingItems = itemsToBeInsertedToDom.length;\n for (\n let idx = 0;\n idx < possibleNumberOfItems - numberOfExistingItems;\n idx++\n ) {\n itemsToBeInsertedToDom.push(\n `lg-item-${this.lgId}-${index - idx - 1}`,\n );\n }\n }\n if (this.settings.loop) {\n if (index === this.galleryItems.length - 1) {\n itemsToBeInsertedToDom.push(`lg-item-${this.lgId}-${0}`);\n } else if (index === 0) {\n itemsToBeInsertedToDom.push(\n `lg-item-${this.lgId}-${this.galleryItems.length - 1}`,\n );\n }\n }\n if (itemsToBeInsertedToDom.indexOf(prevIndexItem) === -1) {\n itemsToBeInsertedToDom.push(`lg-item-${this.lgId}-${prevIndex}`);\n }\n\n return itemsToBeInsertedToDom;\n }\n\n organizeSlideItems(index: number, prevIndex: number): string[] {\n // Pool size: virtualization.slides (large-gallery setting)\n // overrides the classic numberOfSlideItemsInDom. The current\n // slide is always in the window, and the zoom plugin resets zoom\n // on slide change, so removal never touches live zoom state.\n const itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(\n index,\n prevIndex,\n this.settings.virtualization?.slides ??\n this.settings.numberOfSlideItemsInDom,\n );\n\n itemsToBeInsertedToDom.forEach((item) => {\n if (this.currentItemsInDom.indexOf(item) === -1) {\n this.$inner.append(`<div id=\"${item}\" class=\"lg-item\"></div>`);\n }\n });\n\n this.currentItemsInDom.forEach((item) => {\n if (itemsToBeInsertedToDom.indexOf(item) === -1) {\n $LG(`#${item}`).remove();\n }\n });\n return itemsToBeInsertedToDom;\n }\n\n /**\n * Get previous index of the slide\n */\n getPreviousSlideIndex(): number {\n let prevIndex = 0;\n try {\n const currentItemId = this.outer\n .find('.lg-current')\n .first()\n .attr('id');\n prevIndex = parseInt(currentItemId.split('-')[3]) || 0;\n } catch (error) {\n prevIndex = 0;\n }\n return prevIndex;\n }\n\n setDownloadValue(index: number): void {\n if (this.settings.download) {\n const currentGalleryItem = this.galleryItems[index];\n const hideDownloadBtn =\n currentGalleryItem.downloadUrl === false ||\n currentGalleryItem.downloadUrl === 'false';\n if (hideDownloadBtn) {\n this.outer.addClass('lg-hide-download');\n } else {\n const $download = this.getElementById('lg-download');\n this.outer.removeClass('lg-hide-download');\n $download.attr(\n 'href',\n currentGalleryItem.downloadUrl ||\n (currentGalleryItem.src as string),\n );\n if (currentGalleryItem.download) {\n $download.attr('download', currentGalleryItem.download);\n }\n }\n }\n }\n\n makeSlideAnimation(\n direction: 'next' | 'prev',\n currentSlideItem: lgQuery,\n previousSlideItem: lgQuery,\n ): void {\n if (this.lGalleryOn) {\n previousSlideItem.addClass('lg-slide-progress');\n }\n setTimeout(\n () => {\n // remove all transitions\n this.outer.addClass('lg-no-trans');\n\n this.outer\n .find('.lg-item')\n .removeClass('lg-prev-slide lg-next-slide');\n\n if (direction === 'prev') {\n //prevslide\n currentSlideItem.addClass('lg-prev-slide');\n previousSlideItem.addClass('lg-next-slide');\n } else {\n // next slide\n currentSlideItem.addClass('lg-next-slide');\n previousSlideItem.addClass('lg-prev-slide');\n }\n\n // give 50 ms for browser to add/remove class\n setTimeout(() => {\n this.outer.find('.lg-item').removeClass('lg-current');\n\n currentSlideItem.addClass('lg-current');\n\n // reset all transitions\n this.outer.removeClass('lg-no-trans');\n }, 50);\n },\n this.lGalleryOn ? this.settings.slideDelay : 0,\n );\n }\n\n /**\n * Goto a specific slide.\n * @param {Number} index - index of the slide\n * @param {Boolean} fromTouch - true if slide function called via touch event or mouse drag\n * @param {Boolean} fromThumb - true if slide function called via thumbnail click\n * @param {String} direction - Direction of the slide(next/prev)\n * @category lGPublicMethods\n * @example\n * const plugin = lightGallery();\n * // to go to 3rd slide\n * plugin.slide(2);\n *\n */\n slide(\n index: number,\n fromTouch?: boolean,\n fromThumb?: boolean,\n direction?: SlideDirection | false,\n ): void {\n const prevIndex = this.getPreviousSlideIndex();\n this.currentItemsInDom = this.organizeSlideItems(index, prevIndex);\n\n // Prevent multiple call, Required for hsh plugin\n if (this.lGalleryOn && prevIndex === index) {\n return;\n }\n\n const numberOfGalleryItems = this.galleryItems.length;\n\n if (!this.lgBusy) {\n if (this.settings.counter) {\n this.updateCurrentCounter(index);\n }\n this.announceSlide(index);\n\n const currentSlideItem = this.getSlideItem(index);\n const previousSlideItem = this.getSlideItem(prevIndex);\n\n const currentGalleryItem = this.galleryItems[index];\n const videoInfo = currentGalleryItem.__slideVideoInfo;\n\n this.outer.attr(\n 'data-lg-slide-type',\n this.getSlideType(currentGalleryItem),\n );\n this.setDownloadValue(index);\n\n // The fitted size belongs to the slide on screen; consumers\n // (actual-size zoom, the close flight) measure against it.\n this.updateCurrentImageSize(index);\n\n if (videoInfo) {\n const { top, bottom } = this.mediaContainerPosition;\n const videoSize = utils.getSize(\n this.items[index],\n this.outer,\n top + bottom,\n videoInfo && this.settings.videoMaxSize,\n );\n this.resizeVideoSlide(index, videoSize);\n }\n\n this.LGel.trigger<BeforeSlideDetail>(lGEvents.beforeSlide, {\n prevIndex,\n index,\n fromTouch: !!fromTouch,\n fromThumb: !!fromThumb,\n });\n\n this.lgBusy = true;\n\n clearTimeout(this.hideBarTimeout);\n\n this.arrowDisable(index);\n\n if (!direction) {\n if (index < prevIndex) {\n direction = 'prev';\n } else if (index > prevIndex) {\n direction = 'next';\n }\n }\n\n if (!fromTouch) {\n this.makeSlideAnimation(\n direction as SlideDirection,\n currentSlideItem,\n previousSlideItem,\n );\n } else {\n this.outer\n .find('.lg-item')\n .removeClass('lg-prev-slide lg-current lg-next-slide');\n let touchPrev;\n let touchNext;\n if (numberOfGalleryItems > 2) {\n touchPrev = index - 1;\n touchNext = index + 1;\n\n if (index === 0 && prevIndex === numberOfGalleryItems - 1) {\n // next slide\n touchNext = 0;\n touchPrev = numberOfGalleryItems - 1;\n } else if (\n index === numberOfGalleryItems - 1 &&\n prevIndex === 0\n ) {\n // prev slide\n touchNext = 0;\n touchPrev = numberOfGalleryItems - 1;\n }\n } else {\n touchPrev = 0;\n touchNext = 1;\n }\n\n if (direction === 'prev') {\n this.getSlideItem(touchNext).addClass('lg-next-slide');\n } else {\n this.getSlideItem(touchPrev).addClass('lg-prev-slide');\n }\n\n currentSlideItem.addClass('lg-current');\n }\n\n // Do not put load content in set timeout as it needs to load immediately when the gallery is opened\n if (!this.lGalleryOn) {\n this.loadContent(index, true);\n } else {\n setTimeout(() => {\n this.loadContent(index, true);\n // Add title if this.settings.appendSubHtmlTo === lg-sub-html\n if (this.settings.appendSubHtmlTo !== '.lg-item') {\n this.addHtml(index);\n }\n }, this.settings.speed + 50 + (fromTouch ? 0 : this.settings.slideDelay));\n }\n\n setTimeout(() => {\n this.lgBusy = false;\n previousSlideItem.removeClass('lg-slide-progress');\n this.LGel.trigger(lGEvents.afterSlide, {\n prevIndex: prevIndex,\n index,\n fromTouch,\n fromThumb,\n });\n }, (this.lGalleryOn ? this.settings.speed + 100 : 100) + (fromTouch ? 0 : this.settings.slideDelay));\n }\n\n this.index = index;\n }\n\n updateCurrentCounter(index: number): void {\n this.getElementById('lg-counter-current').html(index + 1 + '');\n }\n\n /**\n * Plain-text caption of a slide for the aria-live announcer. Resolves\n * the same sources addHtml uses (inline subHtml markup or a selector)\n * and strips the markup down to readable text. Remote captions\n * (subHtmlUrl) are skipped, announcing can't wait on a fetch.\n */\n private getSlideCaptionText(index: number): string {\n const currentGalleryItem = this.galleryItems[index];\n if (!currentGalleryItem || currentGalleryItem.subHtmlUrl) {\n return '';\n }\n let subHtml = currentGalleryItem.subHtml || '';\n const firstLetter = subHtml.substring(0, 1);\n if (firstLetter === '.' || firstLetter === '#') {\n try {\n if (\n this.settings.subHtmlSelectorRelative &&\n !this.settings.dynamic\n ) {\n subHtml = $LG(this.items)\n .eq(index)\n .find(subHtml)\n .first()\n .html();\n } else {\n subHtml = $LG(subHtml).first().html();\n }\n } catch (error) {\n subHtml = '';\n }\n }\n if (!subHtml) {\n return '';\n }\n const container = document.createElement('div');\n container.innerHTML = subHtml;\n return container.textContent || '';\n }\n\n /**\n * Update the polite live region with the shown slide's position and\n * caption (\"Image X of Y, caption\"). The single announcement source,\n * counter and caption bar are not live regions while this is enabled.\n */\n private announceSlide(index: number): void {\n if (!this.settings.ariaAnnouncements) {\n return;\n }\n const announcer = this.getElementById('lg-announcer').get();\n if (!announcer) {\n return;\n }\n announcer.textContent = formatSlideAnnouncement({\n template: this.settings.strings['slideAnnouncement'],\n index: index + 1,\n total: this.galleryItems.length,\n caption: this.getSlideCaptionText(index),\n });\n }\n\n updateCounterTotal(): void {\n this.getElementById('lg-counter-all').html(\n this.galleryItems.length + '',\n );\n }\n\n getSlideType(item: GalleryItem): 'video' | 'iframe' | 'image' {\n if (item.__slideVideoInfo) {\n return 'video';\n } else if (item.iframe) {\n return 'iframe';\n } else {\n return 'image';\n }\n }\n\n /** Stop a running release spring; visuals stay at the live frame. */\n stopSlideSpring(): void {\n if (this.cancelSlideSpring) {\n this.cancelSlideSpring();\n this.cancelSlideSpring = undefined;\n }\n }\n\n touchMove(startCoords: Coords, endCoords: Coords, e?: TouchEvent): void {\n const distanceX = endCoords.pageX - startCoords.pageX;\n const distanceY = endCoords.pageY - startCoords.pageY;\n\n this.swipeSamples = pushVelocitySample(this.swipeSamples, {\n x: endCoords.pageX,\n y: endCoords.pageY,\n t: Date.now(),\n });\n\n this.swipeDirection = getSwipeAxis(\n distanceX,\n distanceY,\n this.swipeDirection,\n );\n if (!this.swipeDirection) {\n return;\n }\n\n const $currentSlide = this.getSlideItem(this.index);\n\n if (this.swipeDirection === 'horizontal') {\n e?.preventDefault();\n // reset opacity and transition duration\n this.outer.addClass('lg-dragging');\n\n // move current slide and its neighbors, keeping the gutter;\n // past the gallery ends the drag rubber-bands instead of\n // tracking 1:1\n const transforms = getHorizontalDragTransforms(\n this.getEdgeDragDelta(distanceX),\n $currentSlide.get().offsetWidth,\n this.getDirection(),\n );\n $currentSlide.css('transform', transforms.current);\n this.outer\n .find('.lg-prev-slide')\n .first()\n .css('transform', transforms.prev);\n this.outer\n .find('.lg-next-slide')\n .first()\n .css('transform', transforms.next);\n } else if (this.swipeDirection === 'vertical') {\n if (this.settings.swipeToClose) {\n e?.preventDefault();\n this.$container.addClass('lg-dragging-vertical');\n\n const effects = getVerticalDragEffects(\n distanceY,\n window.innerWidth,\n window.innerHeight,\n );\n this.$backdrop.css('opacity', effects.backdropOpacity);\n $currentSlide.css('transform', effects.transform);\n if (effects.hideUi) {\n this.outer\n .addClass('lg-hide-items')\n .removeClass('lg-components-open');\n }\n }\n }\n }\n\n /**\n * The horizontal delta as rendered: rubber-banded when the drag\n * points past the first/last slide with nothing there (loop counts).\n */\n private getEdgeDragDelta(distanceX: number): number {\n const count = this.galleryItems.length;\n return getEdgeFrictionedDelta(\n distanceX,\n resolveSwipeTarget(\n 'prev',\n this.index,\n count,\n this.settings.loop,\n ) !== null,\n resolveSwipeTarget(\n 'next',\n this.index,\n count,\n this.settings.loop,\n ) !== null,\n this.getDirection(),\n );\n }\n\n /** Resolved reading direction ('auto' is resolved at init). */\n private getDirection(): 'ltr' | 'rtl' {\n return this.settings.direction === 'rtl' ? 'rtl' : 'ltr';\n }\n\n /**\n * Spring the dragged slides back to rest, seeded with the release\n * velocity. Returns false (no spring) for sub-pixel drags.\n */\n private springSlidesBack(deltaX: number, velocityX: number): boolean {\n if (Math.abs(deltaX) < 1) {\n return false;\n }\n const $currentSlide = this.getSlideItem(this.index);\n const $prev = this.outer.find('.lg-prev-slide').first();\n const $next = this.outer.find('.lg-next-slide').first();\n const width = $currentSlide.get().offsetWidth;\n this.stopSlideSpring();\n this.cancelSlideSpring = runSprings(\n [{ from: deltaX, velocity: velocityX, target: 0 }],\n ([x]) => {\n const transforms = getHorizontalDragTransforms(\n x!,\n width,\n this.getDirection(),\n );\n $currentSlide.css('transform', transforms.current);\n $prev.css('transform', transforms.prev);\n $next.css('transform', transforms.next);\n },\n () => {\n this.cancelSlideSpring = undefined;\n this.endDragVisuals();\n },\n );\n return true;\n }\n\n /**\n * Carry the release velocity into a gesture navigation: navigate\n * immediately (events, counter and busy-lock on time; fromTouch\n * classes flip underneath, inline transforms keep the visuals),\n * then spring the same drag geometry until the arriving slide lands\n * at rest. Falls back to a snap-back when navigation declines\n * (busy, or an edge without loop, the 2.x end animation plays).\n */\n private springSlideNavigation(\n verdict: 'next' | 'prev',\n deltaX: number,\n velocityX: number,\n ): boolean {\n const $current = this.getSlideItem(this.index);\n const $prev = this.outer.find('.lg-prev-slide').first();\n const $next = this.outer.find('.lg-next-slide').first();\n const width = $current.get().offsetWidth;\n if (!width) {\n return false;\n }\n\n const prevIndex = this.index;\n if (verdict === 'next') {\n this.goToNextSlide(true);\n } else {\n this.goToPrevSlide(true);\n }\n if (this.index === prevIndex) {\n return this.springSlidesBack(deltaX, velocityX);\n }\n\n // The x at which the arriving neighbor sits exactly at 0 in the\n // drag geometry (gutter included): width + x + (0.15w - 0.1|x|).\n const target =\n (verdict === 'next' ? -1 : 1) *\n (this.getDirection() === 'rtl' ? -1 : 1) *\n ((width * 115) / 110);\n this.stopSlideSpring();\n this.cancelSlideSpring = runSprings(\n [{ from: deltaX, velocity: velocityX, target }],\n ([x]) => {\n const transforms = getHorizontalDragTransforms(\n x!,\n width,\n this.getDirection(),\n );\n $current.css('transform', transforms.current);\n $prev.css('transform', transforms.prev);\n $next.css('transform', transforms.next);\n },\n () => {\n this.cancelSlideSpring = undefined;\n // Hands the slides back AND drops the forced lg-slide\n // geometry (the timer-based restore skips while\n // lg-dragging is on).\n this.endDragVisuals();\n },\n );\n return true;\n }\n\n /**\n * Hand the slides back to CSS after a gesture. The inline transforms\n * go first, while lg-dragging still pins transition-duration to 0s,\n * so the snap from the released position to the slide's resting\n * place lands in a single frame. Dropping the class first animates\n * that snap instead, and the outgoing slide is seen travelling back\n * toward the centre while its fade is still running.\n */\n private endDragVisuals(): void {\n this.outer.find('.lg-item').removeAttr('style');\n // The gesture forced lg-slide geometry onto whatever mode is\n // configured; drop it inside the same suppressed frame. Restoring\n // the mode after the hand-back animates every slide from the\n // slide-mode resting place to the configured one, which is the\n // outgoing slide gliding back to the centre as it fades.\n if (this.settings.mode !== 'lg-slide') {\n this.outer.removeClass('lg-slide');\n }\n // Flush the snap before transitions come back.\n void this.outer.get().offsetHeight;\n this.outer.removeClass('lg-dragging');\n }\n\n /**\n * Spring a non-closing vertical drag back to rest, slide transform\n * and backdrop opacity together, seeded with the release velocity.\n */\n private springVerticalRestore(deltaY: number, velocityY: number): boolean {\n if (Math.abs(deltaY) < 1) {\n return false;\n }\n const $currentSlide = this.getSlideItem(this.index);\n this.stopSlideSpring();\n this.$container.addClass('lg-dragging-vertical');\n this.cancelSlideSpring = runSprings(\n [{ from: deltaY, velocity: velocityY, target: 0 }],\n ([y]) => {\n const effects = getVerticalDragEffects(\n y!,\n window.innerWidth,\n window.innerHeight,\n );\n this.$backdrop.css('opacity', effects.backdropOpacity);\n $currentSlide.css('transform', effects.transform);\n },\n () => {\n this.cancelSlideSpring = undefined;\n this.$container.removeClass('lg-dragging-vertical');\n this.endDragVisuals();\n this.$backdrop.css('opacity', 1);\n },\n );\n return true;\n }\n\n touchEnd(endCoords: Coords, startCoords: Coords, event: TouchEvent): void {\n // Read the release velocity NOW, the work below is deferred a\n // tick, and velocity is defined at the moment the finger lifts.\n const releaseVelocity = getWindowedVelocity(\n this.swipeSamples,\n Date.now(),\n );\n\n // keep slide animation for any mode while dragg/swipe\n if (this.settings.mode !== 'lg-slide') {\n this.outer.addClass('lg-slide');\n }\n\n // set transition duration\n setTimeout(() => {\n this.$container.removeClass('lg-dragging-vertical');\n this.outer\n .removeClass('lg-hide-items')\n .addClass('lg-components-open');\n\n let triggerClick = true;\n let springing = false;\n\n if (this.swipeDirection === 'horizontal') {\n // Navigate past swipeThreshold, a quick flick, or a\n // momentum projection past the midpoint, shared release\n // verdict, all runtimes.\n const verdict = getSwipeReleaseVerdict({\n deltaX: endCoords.pageX - startCoords.pageX,\n velocityX: releaseVelocity.x,\n threshold: this.settings.swipeThreshold,\n flickVelocity: this.settings.flickVelocity,\n viewportWidth: this.outer.get().offsetWidth,\n direction: this.getDirection(),\n });\n // Springs start from the RENDERED delta, rubber-banded\n // at the gallery ends, identical to raw elsewhere.\n const renderedDeltaX = this.getEdgeDragDelta(\n endCoords.pageX - startCoords.pageX,\n );\n if (verdict === 'next' || verdict === 'prev') {\n triggerClick = false;\n springing = this.springSlideNavigation(\n verdict,\n renderedDeltaX,\n releaseVelocity.x,\n );\n } else {\n // Snap back on a spring seeded with the release\n // velocity; lg-dragging stays on (transitions down)\n // until it settles.\n springing = this.springSlidesBack(\n renderedDeltaX,\n releaseVelocity.x,\n );\n }\n } else if (this.swipeDirection === 'vertical') {\n if (\n shouldCloseOnVerticalDrag(\n endCoords.pageY - startCoords.pageY,\n releaseVelocity.y,\n window.innerHeight,\n {\n closable: this.settings.closable,\n swipeToClose: this.settings.swipeToClose,\n },\n )\n ) {\n this.closeGallery();\n return;\n }\n // Only spring back what actually moved. With\n // swipeToClose off (a non-closable gallery, inline being\n // the common case) the drag applied nothing, so springing\n // here would jump the slide to the drag offset and\n // animate it back.\n if (this.settings.swipeToClose) {\n springing = this.springVerticalRestore(\n endCoords.pageY - startCoords.pageY,\n releaseVelocity.y,\n );\n }\n }\n if (!springing) {\n this.endDragVisuals();\n this.$backdrop.css('opacity', 1);\n }\n\n if (\n triggerClick &&\n Math.abs(endCoords.pageX - startCoords.pageX) < 5\n ) {\n // Trigger click if distance is less than 5 pix\n const target = $LG(event.target);\n if (this.isPosterElement(target)) {\n this.LGel.trigger(lGEvents.posterClick);\n }\n }\n\n this.swipeDirection = undefined;\n });\n\n // remove slide class once drag/swipe is completed if mode is not slide\n setTimeout(() => {\n if (\n !this.outer.hasClass('lg-dragging') &&\n this.settings.mode !== 'lg-slide'\n ) {\n this.outer.removeClass('lg-slide');\n }\n }, this.settings.speed + 100);\n }\n\n enableSwipe(): void {\n let startCoords: Coords = {} as Coords;\n let endCoords: Coords = {} as Coords;\n let isMoved = false;\n let isSwiping = false;\n\n if (this.settings.enableSwipe) {\n this.$inner.on('touchstart.lg', (e) => {\n this.dragOrSwipeEnabled = true;\n const $item = this.getSlideItem(this.index);\n if (\n ($LG(e.target).hasClass('lg-item') ||\n $item.get().contains(e.target)) &&\n !this.outer.hasClass('lg-zoomed') &&\n !this.lgBusy &&\n e.touches.length === 1\n ) {\n isSwiping = true;\n this.touchAction = 'swipe';\n // A swipe hijacked by a pinch never reaches its\n // touchend, stale isMoved/endCoords would make the\n // NEXT tap run touchEnd on garbage deltas (same\n // pattern zoomSwipe had).\n isMoved = false;\n endCoords = {} as Coords;\n this.stopSlideSpring();\n this.manageSwipeClass();\n this.swipeSamples = [\n {\n x: e.touches[0].pageX,\n y: e.touches[0].pageY,\n t: Date.now(),\n },\n ];\n startCoords = {\n pageX: e.touches[0].pageX,\n pageY: e.touches[0].pageY,\n };\n }\n });\n\n this.$inner.on('touchmove.lg', (e) => {\n if (\n isSwiping &&\n this.touchAction === 'swipe' &&\n e.touches.length === 1\n ) {\n endCoords = {\n pageX: e.touches[0].pageX,\n pageY: e.touches[0].pageY,\n };\n this.touchMove(startCoords, endCoords, e);\n isMoved = true;\n }\n });\n\n this.$inner.on('touchend.lg', (event: TouchEvent) => {\n if (this.touchAction === 'swipe') {\n if (isMoved) {\n isMoved = false;\n this.touchEnd(endCoords, startCoords, event);\n } else if (isSwiping) {\n const target = $LG(event.target);\n if (this.isPosterElement(target)) {\n this.LGel.trigger(lGEvents.posterClick);\n }\n }\n this.touchAction = undefined;\n isSwiping = false;\n }\n });\n }\n }\n\n enableDrag(): void {\n let startCoords: Coords = {} as Coords;\n let endCoords: Coords = {} as Coords;\n let isDraging = false;\n let isMoved = false;\n if (this.settings.enableDrag) {\n this.outer.on('mousedown.lg', (e) => {\n this.dragOrSwipeEnabled = true;\n const $item = this.getSlideItem(this.index);\n if (\n $LG(e.target).hasClass('lg-item') ||\n $item.get().contains(e.target)\n ) {\n if (!this.outer.hasClass('lg-zoomed') && !this.lgBusy) {\n e.preventDefault();\n this.stopSlideSpring();\n this.manageSwipeClass();\n this.swipeSamples = [\n { x: e.pageX, y: e.pageY, t: Date.now() },\n ];\n startCoords = {\n pageX: e.pageX,\n pageY: e.pageY,\n };\n isDraging = true;\n\n // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723\n this.outer.get().scrollLeft += 1;\n this.outer.get().scrollLeft -= 1;\n\n // *\n\n this.outer\n .removeClass('lg-grab')\n .addClass('lg-grabbing');\n\n this.LGel.trigger(lGEvents.dragStart);\n }\n }\n });\n\n $LG(window).on(`mousemove.lg.global${this.lgId}`, (e) => {\n if (isDraging && this.lgOpened) {\n isMoved = true;\n endCoords = {\n pageX: e.pageX,\n pageY: e.pageY,\n };\n this.touchMove(startCoords, endCoords);\n this.LGel.trigger(lGEvents.dragMove);\n }\n });\n\n $LG(window).on(`mouseup.lg.global${this.lgId}`, (event) => {\n if (!this.lgOpened) {\n return;\n }\n const target = $LG(event.target);\n if (isMoved) {\n isMoved = false;\n this.touchEnd(endCoords, startCoords, event);\n this.LGel.trigger(lGEvents.dragEnd);\n } else if (this.isPosterElement(target)) {\n this.LGel.trigger(lGEvents.posterClick);\n }\n\n // Prevent execution on click\n if (isDraging) {\n isDraging = false;\n this.outer.removeClass('lg-grabbing').addClass('lg-grab');\n }\n });\n }\n }\n\n triggerPosterClick(): void {\n this.$inner.on('click.lg', (event) => {\n if (\n !this.dragOrSwipeEnabled &&\n this.isPosterElement($LG(event.target))\n ) {\n this.LGel.trigger(lGEvents.posterClick);\n }\n });\n }\n\n manageSwipeClass(): void {\n let _touchNext = this.index + 1;\n let _touchPrev = this.index - 1;\n if (this.settings.loop && this.galleryItems.length > 2) {\n if (this.index === 0) {\n _touchPrev = this.galleryItems.length - 1;\n } else if (this.index === this.galleryItems.length - 1) {\n _touchNext = 0;\n }\n }\n\n this.outer.find('.lg-item').removeClass('lg-next-slide lg-prev-slide');\n if (_touchPrev > -1) {\n this.getSlideItem(_touchPrev).addClass('lg-prev-slide');\n }\n\n this.getSlideItem(_touchNext).addClass('lg-next-slide');\n }\n\n /**\n * Go to next slide\n * @param {Boolean} fromTouch - true if slide function called via touch event\n * @category lGPublicMethods\n * @example\n * const plugin = lightGallery();\n * plugin.goToNextSlide();\n * @see <a href=\"/demos/methods/\">Demo</a>\n */\n goToNextSlide(fromTouch?: boolean): void {\n let _loop = this.settings.loop;\n if (fromTouch && this.galleryItems.length < 3) {\n _loop = false;\n }\n\n if (!this.lgBusy) {\n if (this.index + 1 < this.galleryItems.length) {\n this.index++;\n this.LGel.trigger(lGEvents.beforeNextSlide, {\n index: this.index,\n });\n this.slide(this.index, !!fromTouch, false, 'next');\n } else {\n if (_loop) {\n this.index = 0;\n this.LGel.trigger(lGEvents.beforeNextSlide, {\n index: this.index,\n });\n this.slide(this.index, !!fromTouch, false, 'next');\n } else if (this.settings.slideEndAnimation && !fromTouch) {\n this.outer.addClass('lg-right-end');\n setTimeout(() => {\n this.outer.removeClass('lg-right-end');\n }, 400);\n }\n }\n }\n }\n\n /**\n * Go to previous slides\n * @param {Boolean} fromTouch - true if slide function called via touch event\n * @category lGPublicMethods\n * @example\n * const plugin = lightGallery({});\n * plugin.goToPrevSlide();\n * @see <a href=\"/demos/methods/\">Demo</a>\n *\n */\n goToPrevSlide(fromTouch?: boolean): void {\n let _loop = this.settings.loop;\n if (fromTouch && this.galleryItems.length < 3) {\n _loop = false;\n }\n\n if (!this.lgBusy) {\n if (this.index > 0) {\n this.index--;\n this.LGel.trigger(lGEvents.beforePrevSlide, {\n index: this.index,\n fromTouch,\n });\n this.slide(this.index, !!fromTouch, false, 'prev');\n } else {\n if (_loop) {\n this.index = this.galleryItems.length - 1;\n this.LGel.trigger(lGEvents.beforePrevSlide, {\n index: this.index,\n fromTouch,\n });\n this.slide(this.index, !!fromTouch, false, 'prev');\n } else if (this.settings.slideEndAnimation && !fromTouch) {\n this.outer.addClass('lg-left-end');\n setTimeout(() => {\n this.outer.removeClass('lg-left-end');\n }, 400);\n }\n }\n }\n }\n\n keyPress(): void {\n $LG(window).on(`keydown.lg.global${this.lgId}`, (e) => {\n if (\n this.lgOpened &&\n this.settings.escKey === true &&\n e.keyCode === 27\n ) {\n e.preventDefault();\n if (\n this.settings.allowMediaOverlap &&\n this.outer.hasClass('lg-can-toggle') &&\n this.outer.hasClass('lg-components-open')\n ) {\n this.outer.removeClass('lg-components-open');\n } else {\n this.closeGallery();\n }\n }\n if (this.lgOpened && this.galleryItems.length > 1) {\n // Physical arrows follow the reading direction.\n const rtl = this.getDirection() === 'rtl';\n if (e.keyCode === 37) {\n e.preventDefault();\n if (rtl) {\n this.goToNextSlide();\n } else {\n this.goToPrevSlide();\n }\n }\n\n if (e.keyCode === 39) {\n e.preventDefault();\n if (rtl) {\n this.goToPrevSlide();\n } else {\n this.goToNextSlide();\n }\n }\n }\n });\n }\n\n arrow(): void {\n this.getElementById('lg-prev').on('click.lg', () => {\n this.goToPrevSlide();\n });\n this.getElementById('lg-next').on('click.lg', () => {\n this.goToNextSlide();\n });\n }\n\n arrowDisable(index: number): void {\n // Disable arrows if settings.hideControlOnEnd is true\n if (!this.settings.loop && this.settings.hideControlOnEnd) {\n const $prev = this.getElementById('lg-prev');\n const $next = this.getElementById('lg-next');\n if (index + 1 === this.galleryItems.length) {\n $next.attr('disabled', 'disabled').addClass('disabled');\n } else {\n $next.removeAttr('disabled').removeClass('disabled');\n }\n\n if (index === 0) {\n $prev.attr('disabled', 'disabled').addClass('disabled');\n } else {\n $prev.removeAttr('disabled').removeClass('disabled');\n }\n }\n }\n\n setTranslate(\n $el: lgQuery,\n xValue: number,\n yValue: number,\n scaleX = 1,\n scaleY = 1,\n ): void {\n $el.css(\n 'transform',\n 'translate3d(' +\n xValue +\n 'px, ' +\n yValue +\n 'px, 0px) scale3d(' +\n scaleX +\n ', ' +\n scaleY +\n ', 1)',\n );\n }\n\n mousewheel(): void {\n let lastCall = 0;\n this.outer.on('wheel.lg', (e) => {\n if (!e.deltaY || this.galleryItems.length < 2) {\n return;\n }\n e.preventDefault();\n const now = new Date().getTime();\n if (now - lastCall < 1000) {\n return;\n }\n lastCall = now;\n if (e.deltaY > 0) {\n this.goToNextSlide();\n } else if (e.deltaY < 0) {\n this.goToPrevSlide();\n }\n });\n }\n\n isSlideElement(target: lgQuery): boolean {\n return (\n target.hasClass('lg-outer') ||\n target.hasClass('lg-item') ||\n target.hasClass('lg-img-wrap') ||\n target.hasClass('lg-img-rotate')\n );\n }\n\n isPosterElement(target: lgQuery): boolean {\n const playButton = this.getSlideItem(this.index)\n .find('.lg-video-play-button')\n .get();\n return (\n target.hasClass('lg-video-poster') ||\n target.hasClass('lg-video-play-button') ||\n (playButton && playButton.contains(target.get()))\n );\n }\n\n /**\n * Maximize minimize inline gallery.\n * @category lGPublicMethods\n */\n toggleMaximize(): void {\n this.getElementById('lg-maximize').on('click.lg', () => {\n this.$container.toggleClass('lg-inline');\n this.refreshOnResize();\n });\n }\n\n invalidateItems(): void {\n for (let index = 0; index < this.items.length; index++) {\n const element = this.items[index];\n const $element = $LG(element);\n $element.off(`click.lgcustom-item-${$element.attr('data-lg-id')}`);\n }\n }\n\n trapFocus(): void {\n this.$container.get().focus({\n preventScroll: true,\n });\n $LG(window).on(`keydown.lg.global${this.lgId}`, (e) => {\n if (!this.lgOpened) {\n return;\n }\n\n const isTabPressed = e.key === 'Tab' || e.keyCode === 9;\n if (!isTabPressed) {\n return;\n }\n const focusableEls = utils.getFocusableElements(\n this.$container.get(),\n );\n const firstFocusableEl = focusableEls[0];\n const lastFocusableEl = focusableEls[focusableEls.length - 1];\n\n if (e.shiftKey) {\n if (document.activeElement === firstFocusableEl) {\n (lastFocusableEl as HTMLElement).focus();\n e.preventDefault();\n }\n } else {\n if (document.activeElement === lastFocusableEl) {\n (firstFocusableEl as HTMLElement).focus();\n e.preventDefault();\n }\n }\n });\n }\n\n manageCloseGallery(): void {\n if (!this.settings.closable) return;\n let mousedown = false;\n this.getElementById('lg-close').on('click.lg', () => {\n this.closeGallery();\n });\n\n if (this.settings.closeOnTap) {\n // If you drag the slide and release outside gallery gets close on chrome\n // for preventing this check mousedown and mouseup happened on .lg-item or lg-outer\n this.outer.on('mousedown.lg', (e) => {\n const target = $LG(e.target);\n if (this.isSlideElement(target)) {\n mousedown = true;\n } else {\n mousedown = false;\n }\n });\n\n this.outer.on('mousemove.lg', () => {\n mousedown = false;\n });\n\n this.outer.on('mouseup.lg', (e) => {\n const target = $LG(e.target);\n if (this.isSlideElement(target) && mousedown) {\n if (!this.outer.hasClass('lg-dragging')) {\n this.closeGallery();\n }\n }\n });\n }\n }\n\n /**\n * Close lightGallery if it is opened.\n *\n * @description If closable is false in the settings, you need to pass true via closeGallery method to force close gallery\n * @return returns the estimated time to close gallery completely including the close animation duration\n * @category lGPublicMethods\n * @example\n * const plugin = lightGallery();\n * plugin.closeGallery();\n *\n */\n closeGallery(force?: boolean): number {\n if (!this.lgOpened || (!this.settings.closable && !force)) {\n return 0;\n }\n this.LGel.trigger(lGEvents.beforeClose);\n\n if (this.settings.resetScrollPosition && !this.settings.hideScrollbar) {\n $LG(window).scrollTop(this.prevScrollTop);\n }\n\n const currentItem = this.items[this.index];\n let transform: string | undefined;\n if (this.zoomFromOrigin && currentItem) {\n const { top, bottom } = this.mediaContainerPosition;\n const { __slideVideoInfo, poster } = this.galleryItems[this.index];\n const imageSize = utils.getSize(\n currentItem,\n this.outer,\n top + bottom,\n __slideVideoInfo && poster && this.settings.videoMaxSize,\n );\n transform = this.getOriginTransform(currentItem, imageSize);\n }\n // No thumbnail to fly back to (hidden or collapsed trigger, no\n // lg-size, zoomFromOrigin off, a dynamic gallery): shrink about the\n // stage centre and fade, the mirror of the startClass open.\n if (!transform) {\n transform = getCenterCloseTransform();\n this.outer.addClass('lg-close-to-center');\n }\n if (transform) {\n this.outer.addClass('lg-closing lg-zoom-from-image');\n this.getSlideItem(this.index)\n .addClass('lg-start-end-progress')\n .css(\n 'transition-duration',\n this.settings.startAnimationDuration + 'ms',\n )\n .css('transform', transform);\n } else {\n this.outer.addClass('lg-hide-items');\n // lg-zoom-from-image is used for setting the opacity to 1 if zoomFromOrigin is true\n // If the closing item doesn't have the lg-size attribute, remove this class to avoid the closing css conflicts\n this.outer.removeClass('lg-zoom-from-image');\n }\n\n // Unbind all events added by lightGallery\n // @todo\n //this.$el.off('.lg.tm');\n\n this.destroyModules();\n\n this.lGalleryOn = false;\n this.isDummyImageRemoved = false;\n this.zoomFromOrigin = this.settings.zoomFromOrigin;\n\n clearTimeout(this.hideBarTimeout);\n this.hideBarTimeout = false;\n $LG('html').removeClass('lg-on');\n\n this.outer.removeClass('lg-visible lg-components-open');\n\n // Resetting opacity to 0 isd required as vertical swipe to close function adds inline opacity.\n this.$backdrop.removeClass('in').css('opacity', 0);\n\n const removeTimeout = transform\n ? Math.max(\n this.settings.startAnimationDuration,\n this.settings.backdropDuration,\n )\n : this.settings.backdropDuration;\n this.$container.removeClass('lg-show-in');\n\n // Once the closign animation is completed and gallery is invisible\n setTimeout(() => {\n if (transform) {\n this.outer.removeClass('lg-zoom-from-image');\n }\n this.$container.removeClass('lg-show');\n\n // Reset scrollbar\n this.resetScrollBar();\n\n // Need to remove inline opacity as it is used in the stylesheet as well\n this.$backdrop\n .removeAttr('style')\n .css(\n 'transition-duration',\n this.settings.backdropDuration + 'ms',\n );\n\n this.outer.removeClass(\n `lg-closing lg-close-to-center ${this.settings.startClass}`,\n );\n\n this.getSlideItem(this.index).removeClass('lg-start-end-progress');\n this.$inner.empty();\n\n // Clear the announcer so reopening at the same slide is a fresh\n // live-region mutation (otherwise identical text = silence).\n const announcer = this.getElementById('lg-announcer').get();\n if (announcer) {\n announcer.textContent = '';\n }\n\n if (this.lgOpened) {\n this.LGel.trigger(lGEvents.afterClose, {\n instance: this,\n });\n }\n if (this.$container.get()) {\n this.$container.get().blur();\n }\n\n // Return focus to where it was before the gallery opened\n // (dialog pattern; captured only when trapFocus moved it).\n if (this.prevActiveElement && this.prevActiveElement.isConnected) {\n this.prevActiveElement.focus({ preventScroll: true });\n }\n this.prevActiveElement = undefined;\n\n this.lgOpened = false;\n }, removeTimeout + 100);\n return removeTimeout + 100;\n }\n\n initModules(): void {\n this.plugins.forEach((module) => {\n try {\n module.init();\n } catch (err) {\n console.warn(\n `lightGallery:- make sure lightGallery module is properly initiated. See https://www.lightgalleryjs.com/docs/methods/`,\n );\n }\n });\n }\n\n destroyModules(destroy?: true): void {\n this.plugins.forEach((module) => {\n try {\n if (destroy) {\n module.destroy();\n } else {\n module.closeGallery && module.closeGallery();\n }\n } catch (err) {\n console.warn(\n `lightGallery:- make sure lightGallery module is properly destroyed. See https://www.lightgalleryjs.com/docs/methods/`,\n );\n }\n });\n }\n\n /**\n * Refresh lightGallery with new set of children.\n *\n * @description This is useful to update the gallery when the child elements are changed without calling destroy method.\n *\n * If you are using dynamic mode, you can pass the modified array of dynamicEl as the first parameter to refresh the dynamic gallery\n * @see <a href=\"/demos/dynamic-mode/\">Demo</a>\n * @category lGPublicMethods\n * @example\n * const plugin = lightGallery();\n * // Delete or add children, then call\n * plugin.refresh();\n *\n */\n refresh(galleryItems?: GalleryItem[]): void {\n if (!this.settings.dynamic) {\n this.invalidateItems();\n }\n if (galleryItems) {\n this.galleryItems = galleryItems;\n } else {\n this.galleryItems = this.getItems();\n }\n this.updateControls();\n this.openGalleryOnItemClick();\n this.LGel.trigger(lGEvents.updateSlides);\n }\n\n updateControls(): void {\n this.addSlideVideoInfo(this.galleryItems);\n this.updateCounterTotal();\n this.manageSingleSlideClassName();\n }\n\n private destroyGallery(): void {\n this.destroyModules(true);\n if (!this.settings.dynamic) {\n this.invalidateItems();\n }\n $LG(window).off(`.lg.global${this.lgId}`);\n this.LGel.off('.lg');\n this.toolbarOverflow?.destroy();\n this.toolbarOverflow = undefined;\n this.$container.remove();\n }\n\n /**\n * Destroy lightGallery.\n * Destroy lightGallery and its plugin instances completely\n *\n * @description This method also calls CloseGallery function internally. Returns the time takes to completely close and destroy the instance.\n * In case if you want to re-initialize lightGallery right after destroying it, initialize it only once the destroy process is completed.\n * You can use refresh method most of the times.\n * @category lGPublicMethods\n * @example\n * const plugin = lightGallery();\n * plugin.destroy();\n *\n */\n destroy(): number {\n const closeTimeout = this.closeGallery(true);\n if (closeTimeout) {\n setTimeout(this.destroyGallery.bind(this), closeTimeout);\n } else {\n this.destroyGallery();\n }\n return closeTimeout;\n }\n}\n","import { setLicenseKey } from '@lightgallery/headless';\n\nimport { LightGallerySettings } from './lg-settings';\nimport { LightGallery } from './lightgallery';\n\nfunction lightGallery(\n el: HTMLElement,\n options?: LightGallerySettings,\n): LightGallery {\n return new LightGallery(el, options);\n}\n/**\n * Set the license key once for every gallery on the page, before creating\n * them. A gallery's own `licenseKey` still wins.\n * See <a href=\"/docs/license/\">License</a>.\n */\nlightGallery.setLicenseKey = setLicenseKey;\nexport default lightGallery;\nexport type { LgIconName, LgIcons } from './lg-icons';\n"],"names":["__spreadProps","__spreadValues","_a","CustomEvent","_lgQuery","index"],"mappings":"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"}
1
+ {"version":3,"file":"lightgallery.es5.js","sources":["../packages/headless/src/video-urls.ts","../packages/headless/src/license.ts","../packages/headless/src/announce.ts","../packages/headless/src/spring.ts","../packages/headless/src/gestures.ts","../packages/headless/src/origin.ts","../packages/headless/src/icons.ts","../packages/headless/src/toolbar-overflow.ts","../packages/headless/src/transition.ts","../packages/headless/src/responsive.ts","../packages/headless/src/velocity.ts","../src/lg-events.ts","../src/lg-settings.ts","../src/lg-toolbar-overflow.ts","../src/lg-icons.ts","../src/lg-spring-runner.ts","../src/lgQuery.ts","../src/lg-utils.ts","../src/lightgallery.ts","../src/index.ts"],"sourcesContent":["/**\n * Video URL detection and embed-URL builders, ported from 2.x\n * `utils.isVideo` (`src/lg-utils.ts`) and `lg-video-utils.ts` as pure\n * functions. The video plugin renders the returned URLs; nothing here\n * touches the DOM.\n */\n\nexport interface VideoInfo {\n /** RegExp match parts: `[match, videoId, urlParams?]`. */\n youtube?: string[];\n vimeo?: string[];\n /** RegExp match parts; index 4 is the media id. */\n wistia?: string[];\n html5?: boolean;\n}\n\n// `true` is accepted for 2.x-contract compatibility and means the same\n// as an empty params object.\nexport type PlayerParams = Record<string, string | number | boolean> | boolean;\n\nfunction toParamsObject(\n params: PlayerParams,\n): Record<string, string | number | boolean> {\n return typeof params === 'object' && params ? params : {};\n}\n\n/** Detect the video provider for a src URL (2.x `utils.isVideo`). */\nexport function getVideoInfo(\n src: string | undefined,\n hasHtml5Video: boolean,\n): VideoInfo | undefined {\n if (!src) {\n return hasHtml5Video ? { html5: true } : undefined;\n }\n const youtube = src.match(\n /\\/\\/(?:www\\.)?youtu(?:\\.be|be\\.com|be-nocookie\\.com)\\/(?:watch\\?v=|embed\\/)?([a-z0-9\\-_%]+)([&|?][\\S]*)*/i,\n );\n if (youtube) {\n return { youtube: [...youtube] };\n }\n const vimeo = src.match(\n /\\/\\/(?:www\\.)?(?:player\\.)?vimeo.com\\/(?:video\\/)?([0-9a-z\\-_]+)(.*)?/i,\n );\n if (vimeo) {\n return { vimeo: [...vimeo] };\n }\n const wistia = src.match(\n /https?:\\/\\/(.+)?(wistia\\.com|wi\\.st)\\/(medias|embed)\\/([0-9a-z\\-_]+)(.*)/,\n );\n if (wistia) {\n return { wistia: [...wistia] };\n }\n return hasHtml5Video ? { html5: true } : undefined;\n}\n\n/** Serialize params as a query string (2.x `param`). */\nexport function param(obj: Record<string, string | number | boolean>): string {\n return Object.keys(obj)\n .map(\n (key) =>\n `${encodeURIComponent(key)}=${encodeURIComponent(obj[key]!)}`,\n )\n .join('&');\n}\n\n/** Parse `?a=b&c=d` into an object (2.x `paramsToObject`). */\nexport function paramsToObject(url: string): Record<string, string> {\n return url\n .slice(1)\n .split('&')\n .map((pair) => pair.split('='))\n .reduce<Record<string, string>>((obj, pair) => {\n const [key, value] = pair.map(decodeURIComponent);\n if (key) {\n obj[key] = value ?? '';\n }\n return obj;\n }, {});\n}\n\nexport function isYouTubeNoCookie(url: string): boolean {\n return url.includes('youtube-nocookie.com');\n}\n\n/**\n * YouTube embed URL. Precedence (2.x parity): defaults < settings < params\n * already present on the slide URL. The privacy-enhanced\n * `youtube-nocookie.com` host is the default; pass `preferNoCookie: false`\n * (the `youTubeNoCookie` setting) to revert to `youtube.com`. A slide URL\n * that already names the nocookie host always keeps it.\n */\nexport function getYouTubeEmbedUrl(\n videoInfo: VideoInfo,\n playerParamsSettings: PlayerParams,\n srcUrl: string,\n preferNoCookie = true,\n): string | undefined {\n if (!videoInfo.youtube) {\n return undefined;\n }\n const slideUrlParams = videoInfo.youtube[2]\n ? paramsToObject(videoInfo.youtube[2])\n : {};\n const params = {\n wmode: 'opaque',\n autoplay: 0,\n mute: 1,\n enablejsapi: 1,\n ...toParamsObject(playerParamsSettings),\n ...slideUrlParams,\n };\n const base =\n preferNoCookie || isYouTubeNoCookie(srcUrl)\n ? '//www.youtube-nocookie.com/'\n : '//www.youtube.com/';\n return `${base}embed/${videoInfo.youtube[1]}?${param(params)}`;\n}\n\n/**\n * YouTube's public thumbnail endpoint for a detected video — the one\n * provider poster that needs no API call. (Vimeo/Wistia poster endpoints\n * require a fetch/auth, so their facades rely on the item's own\n * poster/thumb — see getFacadePoster.)\n */\nexport function getYouTubePosterUrl(\n videoInfo: VideoInfo | undefined,\n): string | undefined {\n if (!videoInfo?.youtube) {\n return undefined;\n }\n return `//img.youtube.com/vi/${videoInfo.youtube[1]}/maxresdefault.jpg`;\n}\n\n/**\n * Poster for a provider-video facade (lite embed): the explicit item\n * poster wins, then the YouTube thumbnail endpoint (when enabled), then\n * the item's grid thumb — for Vimeo galleries the vimeoThumbnail plugin\n * rewrites `thumb` to the oEmbed thumbnail, which feeds this chain.\n * HTML5 slides never get a synthesized poster (unchanged 2.x behavior);\n * a provider slide with no resolvable poster returns undefined and keeps\n * the eager-iframe path.\n */\nexport function getFacadePoster(\n item: { poster?: string; thumb?: string },\n videoInfo: VideoInfo | undefined,\n loadYouTubePoster: boolean,\n): string | undefined {\n if (!videoInfo || videoInfo.html5) {\n return item.poster || undefined;\n }\n return (\n item.poster ||\n (loadYouTubePoster ? getYouTubePosterUrl(videoInfo) : undefined) ||\n item.thumb ||\n undefined\n );\n}\n\n/**\n * Provider player-API script URLs, loaded on demand at first play (the\n * vanilla runtime's control paths need them; the framework bindings drive\n * players via postMessage and load nothing).\n */\nexport const VIMEO_PLAYER_SCRIPT_URL = 'https://player.vimeo.com/api/player.js';\nexport const WISTIA_PLAYER_SCRIPT_URL =\n 'https://fast.wistia.com/assets/external/E-v1.js';\n\n/**\n * Vimeo embed URL, including the private-video hash handling (2.x\n * `getVimeoURLParams`).\n */\nexport function getVimeoEmbedUrl(\n videoInfo: VideoInfo,\n playerParamsSettings: PlayerParams,\n): string | undefined {\n if (!videoInfo.vimeo) {\n return undefined;\n }\n let urlParams = videoInfo.vimeo[2] || '';\n const defaultPlayerParams = {\n autoplay: 0,\n muted: 1,\n ...toParamsObject(playerParamsSettings),\n };\n let defaultParams = param(defaultPlayerParams);\n\n // Private videos carry a hash as the last path segment.\n const urlWithHash = videoInfo.vimeo[0]!.split('/').pop() || '';\n const urlWithHashWithoutParams = urlWithHash.split('?')[0] || '';\n const hash = urlWithHashWithoutParams.split('#')[0]!;\n const isPrivate = videoInfo.vimeo[1] !== hash;\n if (isPrivate) {\n urlParams = urlParams.replace(`/${hash}`, '');\n }\n urlParams =\n urlParams[0] === '?' ? `&${urlParams.slice(1)}` : urlParams || '';\n const privateUrlParams = isPrivate ? `h=${hash}` : '';\n defaultParams = privateUrlParams ? `&${defaultParams}` : defaultParams;\n\n return `//player.vimeo.com/video/${videoInfo.vimeo[1]}?${privateUrlParams}${defaultParams}${urlParams}`;\n}\n\n/** Wistia embed URL. */\nexport function getWistiaEmbedUrl(\n videoInfo: VideoInfo,\n playerParamsSettings: PlayerParams,\n): string | undefined {\n if (!videoInfo.wistia) {\n return undefined;\n }\n const paramsObject = toParamsObject(playerParamsSettings);\n const params = Object.keys(paramsObject).length ? param(paramsObject) : '';\n return `//fast.wistia.net/embed/iframe/${videoInfo.wistia[4]}${\n params ? `?${params}` : ''\n }`;\n}\n","/**\n * License key check shared by every package. The key never limits a\n * feature; it only decides which console message, if any, the gallery\n * logs. `checkLicenseKey` is pure; the page-wide key and the once-per-page\n * bookkeeping are module state, and the runtime does the logging.\n */\n\n/** The temporary key; also the default `licenseKey`. */\nexport const TESTING_LICENSE_KEY = '0000-0000-000-0000';\n\n/** Every lightGallery 3 key starts with this; v1 and v2 keys don't. */\nexport const LICENSE_KEY_PREFIX = 'LIG';\n\nconst LICENSE_DOCS = 'https://www.lightgalleryjs.com/docs/license/';\n\nexport interface LicenseNotice {\n level: 'error' | 'warn';\n message: string;\n}\n\n/**\n * The console notice for a license key, or `null` for a lightGallery 3\n * key. An empty key is an error; the testing key and keys from v1 or v2\n * (no `LIG` prefix) are warnings.\n */\nexport function checkLicenseKey(\n licenseKey: string | undefined,\n): LicenseNotice | null {\n const key = (licenseKey ?? '').trim();\n if (!key) {\n return {\n level: 'error',\n message: `lightGallery: please provide a valid license key. See ${LICENSE_DOCS}`,\n };\n }\n if (key === TESTING_LICENSE_KEY) {\n return {\n level: 'warn',\n message: `lightGallery: ${key} license key is not valid for production use. See ${LICENSE_DOCS}`,\n };\n }\n if (!key.startsWith(LICENSE_KEY_PREFIX)) {\n return {\n level: 'warn',\n message: `lightGallery: this license key is for v1 or v2 and is not valid for v3. Please upgrade to a v3 license. See ${LICENSE_DOCS}`,\n };\n }\n return null;\n}\n\nlet pageLicenseKey: string | undefined;\nconst loggedNotices = new Set<string>();\n\n/**\n * Set the license key once for every gallery on the page. Call it before\n * creating galleries; a gallery's own `licenseKey` still wins.\n */\nexport function setLicenseKey(licenseKey: string): void {\n pageLicenseKey = licenseKey;\n}\n\n/**\n * The key a gallery runs with: its own `licenseKey`, or the page-wide key\n * when it has none (or only the testing default).\n */\nexport function resolveLicenseKey(instanceKey: string | undefined): string {\n const own = (instanceKey ?? '').trim();\n if (pageLicenseKey !== undefined && (!own || own === TESTING_LICENSE_KEY)) {\n return pageLicenseKey;\n }\n return instanceKey ?? TESTING_LICENSE_KEY;\n}\n\n/**\n * The notice a new gallery should log, or `null`. Each message is logged\n * once per page, however many galleries share the key.\n */\nexport function takeLicenseNotice(\n instanceKey: string | undefined,\n): LicenseNotice | null {\n const notice = checkLicenseKey(resolveLicenseKey(instanceKey));\n if (!notice || loggedNotices.has(notice.message)) return null;\n loggedNotices.add(notice.message);\n return notice;\n}\n","/**\n * Slide-change announcement formatting for the shared `aria-live` region.\n * All four runtimes build their announcer text through this helper so the\n * wording (and its localization surface, `strings.slideAnnouncement`) stays\n * identical everywhere.\n */\n\nexport interface SlideAnnouncementOptions {\n /** `strings.slideAnnouncement` template with `{index}`/`{total}` slots. */\n template: string;\n /** 1-based position of the shown slide. */\n index: number;\n /** Total slide count. */\n total: number;\n /** Plain-text caption of the shown slide, if any. */\n caption?: string;\n}\n\n/**\n * Build the text announced on a slide change: the filled template, then the\n * caption (comma-separated) when one exists. Whitespace in the caption is\n * collapsed so multi-line/rich captions read as one sentence.\n */\nexport function formatSlideAnnouncement(\n options: SlideAnnouncementOptions,\n): string {\n const base = options.template\n .replace('{index}', String(options.index))\n .replace('{total}', String(options.total));\n const caption = (options.caption || '').replace(/\\s+/g, ' ').trim();\n return caption ? `${base}, ${caption}` : base;\n}\n","/**\n * Gesture-release physics: momentum projection and a damped-spring\n * stepper. Releases compute where momentum would land (`project`),\n * clamp that into bounds, and animate there with a spring seeded by the\n * live release velocity — velocity stays continuous across the\n * finger-lift boundary, which is most of what native feel is.\n *\n * The stepper advances the standard damped harmonic oscillator by its\n * closed-form solution over each frame, so step size never affects the\n * trajectory and the state (position + velocity) can re-seed a new\n * spring at any interruption point.\n */\n\nexport interface SpringState {\n position: number;\n /** px per ms (same unit as the windowed gesture velocity). */\n velocity: number;\n}\n\nexport interface SpringConfig {\n /** 1 = never overshoot; < 1 overshoots and returns. */\n dampingRatio?: number;\n /** Rad/s — higher settles faster. */\n naturalFrequency?: number;\n}\n\n/** Settling toward an in-bounds target: no overshoot. */\nexport const SPRING_SETTLE_DAMPING = 1;\n\n/** Settling against a clamped bound: one soft bounce. */\nexport const SPRING_BOUNCE_DAMPING = 0.82;\n\nexport const SPRING_NATURAL_FREQUENCY = 12;\n\n/**\n * Momentum projection: how far a release keeps traveling when it loses\n * `1 - decelerationRate` of its velocity every millisecond (the classic\n * scroll-view constant; 0.995 ≈ half a percent per ms).\n */\nexport const DECELERATION_RATE = 0.995;\n\nexport function project(\n velocity: number,\n decelerationRate: number = DECELERATION_RATE,\n): number {\n return (velocity * decelerationRate) / (1 - decelerationRate);\n}\n\n/**\n * Advance a spring toward `target` by `dtMs`, exactly (closed form with\n * the current state as initial conditions).\n */\nexport function stepSpring(\n state: SpringState,\n target: number,\n dtMs: number,\n {\n dampingRatio = SPRING_SETTLE_DAMPING,\n naturalFrequency = SPRING_NATURAL_FREQUENCY,\n }: SpringConfig = {},\n): SpringState {\n const t = dtMs / 1000;\n const w0 = naturalFrequency;\n const zeta = Math.min(dampingRatio, 1);\n const x0 = state.position - target;\n const v0 = state.velocity * 1000; // px/s for the oscillator\n const decay = Math.exp(-zeta * w0 * t);\n\n let x: number;\n let v: number;\n if (zeta < 1) {\n const wd = w0 * Math.sqrt(1 - zeta * zeta);\n const a = x0;\n const b = (v0 + zeta * w0 * x0) / wd;\n const cos = Math.cos(wd * t);\n const sin = Math.sin(wd * t);\n x = decay * (a * cos + b * sin);\n v =\n decay *\n ((b * wd - zeta * w0 * a) * cos - (a * wd + zeta * w0 * b) * sin);\n } else {\n const b = v0 + w0 * x0;\n x = decay * (x0 + b * t);\n v = decay * (b - w0 * (x0 + b * t));\n }\n return { position: target + x, velocity: v / 1000 };\n}\n\n/** Whether a spring is close enough to stop animating. */\nexport function isSpringSettled(\n state: SpringState,\n target: number,\n restDelta = 0.3,\n restVelocity = 0.012,\n): boolean {\n return (\n Math.abs(state.position - target) < restDelta &&\n Math.abs(state.velocity) < restVelocity\n );\n}\n","/**\n * Gesture math, ported from the 2.x touch/drag implementation\n * (`touchMove`/`touchEnd` in `src/lightgallery.ts`) as pure functions. The\n * framework layer owns pointer events and writes the returned transforms\n * straight to the DOM (never through framework state — one render per\n * gesture, not per move); every *decision* lives here so swipe feel is\n * identical across frameworks.\n */\n\nimport { project } from './spring';\nimport type { ResolvedGalleryDirection } from './settings';\n\nexport type SwipeAxis = 'horizontal' | 'vertical';\n\n/**\n * Minimum travel (px) before a drag commits to an axis. Tuned from the\n * 2.x 15px to ~10 (UIPanGestureRecognizer territory): drags answer a\n * touch sooner without axis flip-flop — the commit is still sticky.\n */\nexport const SWIPE_AXIS_THRESHOLD = 10;\n\n/**\n * Flick support: a release faster than this (px/ms, windowed — see\n * `velocity.ts`) navigates even below `swipeThreshold`. Default per the\n * gesture-physics teardown: windowed readings run higher than the old\n * whole-gesture averages, so this gate and windowed measurement ship as\n * one change. Public setting: `flickVelocity`.\n */\nexport const FLICK_VELOCITY = 0.5;\n\n/** Minimum travel (px) for a flick, so taps never navigate. */\nexport const FLICK_MIN_DISTANCE = 20;\n\n/** Vertical travel (px) beyond which the drag hides the UI chrome — 2.x. */\nexport const VERTICAL_CLOSE_THRESHOLD = 100;\n\n/**\n * Drag-to-close verdict: the momentum-projected travel must pass this\n * fraction of the viewport height — a small fast downward flick closes,\n * a large slow drag released while returning does not.\n */\nexport const VERTICAL_CLOSE_RATIO = 0.4;\n\n/**\n * Minimum actual travel (px) before the projected close arms. Momentum\n * may extend a real drag, never replace one: a grazed tap releases with\n * a fast final instant, and projection alone would read it as a close\n * flick.\n */\nexport const VERTICAL_CLOSE_MIN_DRAG = 40;\n\n/**\n * Rubber-band friction past the first/last slide (no loop): the drag\n * keeps moving at this fraction of the finger instead of the 2.x\n * un-resisted 1:1 travel — you feel that there is nothing further.\n */\nexport const SLIDE_EDGE_FRICTION = 0.35;\n\n/**\n * Horizontal drag delta with rubber-banding past the gallery ends.\n * `hasPrev`/`hasNext` reflect whether a slide exists in that direction\n * (loop counts); the release spring returns the frictioned distance.\n */\nexport function getEdgeFrictionedDelta(\n deltaX: number,\n hasPrev: boolean,\n hasNext: boolean,\n direction: ResolvedGalleryDirection = 'ltr',\n): number {\n // In RTL the finger drags toward the mirrored neighbor.\n const [towardPrev, towardNext] =\n direction === 'rtl' ? [hasNext, hasPrev] : [hasPrev, hasNext];\n if ((deltaX > 0 && !towardPrev) || (deltaX < 0 && !towardNext)) {\n return deltaX * SLIDE_EDGE_FRICTION;\n }\n return deltaX;\n}\n\n/** Decide (once) which axis a drag follows; sticky after the first commit. */\nexport function getSwipeAxis(\n deltaX: number,\n deltaY: number,\n current: SwipeAxis | undefined,\n): SwipeAxis | undefined {\n if (current) {\n return current;\n }\n if (Math.abs(deltaX) > SWIPE_AXIS_THRESHOLD) {\n return 'horizontal';\n }\n if (Math.abs(deltaY) > SWIPE_AXIS_THRESHOLD) {\n return 'vertical';\n }\n return undefined;\n}\n\nexport interface HorizontalDragTransforms {\n current: string;\n prev: string;\n next: string;\n}\n\n/**\n * Follow-the-finger transforms for the current slide and its neighbors\n * (2.x `touchMove` horizontal branch, including the shrinking gutter).\n */\nexport function getHorizontalDragTransforms(\n deltaX: number,\n slideWidth: number,\n direction: ResolvedGalleryDirection = 'ltr',\n): HorizontalDragTransforms {\n const slideWidthAmount = (slideWidth * 15) / 100;\n const gutter = slideWidthAmount - Math.abs((deltaX * 10) / 100);\n const before = `translate3d(${-slideWidth + deltaX - gutter}px, 0px, 0px)`;\n const after = `translate3d(${slideWidth + deltaX + gutter}px, 0px, 0px)`;\n return {\n current: `translate3d(${deltaX}px, 0px, 0px)`,\n // In RTL the prev slide rests to the physical right (lg-rtl.css\n // flips the resting positions the same way).\n prev: direction === 'rtl' ? after : before,\n next: direction === 'rtl' ? before : after,\n };\n}\n\nexport interface VerticalDragEffects {\n /** Backdrop opacity fading out with the drag. */\n backdropOpacity: number;\n /** Transform for the current slide (translate + shrink). */\n transform: string;\n /** True once the UI chrome should hide (past the close threshold). */\n hideUi: boolean;\n}\n\n/** Drag-to-close visuals (2.x `touchMove` vertical branch). */\nexport function getVerticalDragEffects(\n deltaY: number,\n viewportWidth: number,\n viewportHeight: number,\n): VerticalDragEffects {\n const distance = Math.abs(deltaY);\n const scale = 1 - distance / (viewportWidth * 2);\n return {\n backdropOpacity: 1 - distance / viewportHeight,\n transform: `translate3d(0px, ${deltaY}px, 0px) scale3d(${scale}, ${scale}, 1)`,\n hideUi: distance > VERTICAL_CLOSE_THRESHOLD,\n };\n}\n\nexport type SwipeReleaseVerdict = 'next' | 'prev' | 'stay';\n\nexport interface SwipeReleaseInput {\n deltaX: number;\n /** Release velocity, px/ms signed (windowed — see `velocity.ts`). */\n velocityX: number;\n /** `swipeThreshold` setting (px). */\n threshold: number;\n /** `flickVelocity` setting (px/ms). */\n flickVelocity?: number;\n /**\n * Slide width (px). When given, a release whose momentum-projected\n * travel crosses the midpoint also navigates — a firm half-hearted\n * swipe keeps going where a hesitant one snaps back.\n */\n viewportWidth?: number;\n /** Resolved gallery direction; in `'rtl'` the verdict mirrors. */\n direction?: ResolvedGalleryDirection;\n}\n\n/**\n * Horizontal release decision: past `swipeThreshold`, or a quick flick →\n * navigate (negative delta = next, 2.x parity); otherwise snap back.\n * The flick counts only when the release velocity points the same way\n * as the drag — reversing direction just before lifting is a cancel,\n * not a flick.\n */\nexport function getSwipeReleaseVerdict({\n deltaX,\n velocityX,\n threshold,\n flickVelocity = FLICK_VELOCITY,\n viewportWidth,\n direction = 'ltr',\n}: SwipeReleaseInput): SwipeReleaseVerdict {\n const distance = Math.abs(deltaX);\n const directionMatches =\n deltaX !== 0 && Math.sign(velocityX) === Math.sign(deltaX);\n const projected = deltaX + project(velocityX);\n const passes =\n distance > threshold ||\n (distance > FLICK_MIN_DISTANCE &&\n directionMatches &&\n Math.abs(velocityX) > flickVelocity) ||\n (viewportWidth !== undefined &&\n distance > FLICK_MIN_DISTANCE &&\n directionMatches &&\n Math.abs(projected) > viewportWidth / 2);\n if (!passes) {\n return 'stay';\n }\n const towardNext = direction === 'rtl' ? deltaX > 0 : deltaX < 0;\n return towardNext ? 'next' : 'prev';\n}\n\n/**\n * Vertical release decision: close when the momentum-projected travel\n * passes {@link VERTICAL_CLOSE_RATIO} of the viewport in the drag's own\n * direction (a release moving back toward rest never closes), and the\n * finger actually travelled {@link VERTICAL_CLOSE_MIN_DRAG}.\n */\nexport function shouldCloseOnVerticalDrag(\n deltaY: number,\n velocityY: number,\n viewportHeight: number,\n options: { closable: boolean; swipeToClose: boolean },\n): boolean {\n if (!options.closable || !options.swipeToClose || deltaY === 0) {\n return false;\n }\n if (Math.abs(deltaY) < VERTICAL_CLOSE_MIN_DRAG) {\n return false;\n }\n const projected = deltaY + project(velocityY);\n return (\n Math.sign(projected) === Math.sign(deltaY) &&\n Math.abs(projected) > VERTICAL_CLOSE_RATIO * viewportHeight\n );\n}\n\n/**\n * Which slide navigation a release verdict maps to, honoring the 2.x touch\n * loop rule: galleries with fewer than 3 slides never wrap from touch.\n */\nexport function resolveSwipeTarget(\n verdict: SwipeReleaseVerdict,\n currentIndex: number,\n slidesCount: number,\n loop: boolean,\n): number | null {\n if (verdict === 'stay') {\n return null;\n }\n const touchLoop = loop && slidesCount >= 3;\n if (verdict === 'next') {\n if (currentIndex + 1 < slidesCount) {\n return currentIndex + 1;\n }\n return touchLoop ? 0 : null;\n }\n if (currentIndex > 0) {\n return currentIndex - 1;\n }\n return touchLoop ? slidesCount - 1 : null;\n}\n\n/** One live pointer, for multi-pointer consumers (zoom plugin). */\nexport interface PointerRecord {\n id: number;\n startX: number;\n startY: number;\n x: number;\n y: number;\n}\n\n/** Add or update a pointer record, returning a new array. */\nexport function upsertPointer(\n pointers: readonly PointerRecord[],\n record: PointerRecord,\n): PointerRecord[] {\n const existing = pointers.findIndex((p) => p.id === record.id);\n if (existing === -1) {\n return [...pointers, record];\n }\n const copy = [...pointers];\n copy[existing] = record;\n return copy;\n}\n\n/** Remove a pointer record by id, returning a new array. */\nexport function removePointer(\n pointers: readonly PointerRecord[],\n id: number,\n): PointerRecord[] {\n return pointers.filter((p) => p.id !== id);\n}\n","/**\n * Zoom-from-origin math, ported from 2.x `utils.getSize`/`utils.getTransform`\n * (`src/lg-utils.ts`) as pure rect arithmetic. The framework layer measures\n * the DOM (trigger/container bounding rects) and passes plain numbers in.\n *\n * Note: this module is an addition to the ADR 0001 §1 table — it\n * follows the standing rule that pure functions needed by React live in\n * headless. It is distinct from `zoom-math.ts` (zoom plugin).\n */\n\nexport interface ImageSize {\n width: number;\n height: number;\n}\n\nexport interface RectLike {\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\n/**\n * Parse an item's `lgSize` value (`\"1920-1280\"`, or a responsive list like\n * `\"240-160-375, 1600-1067\"` where the third number is the max viewport\n * width the entry applies to).\n */\nexport function parseImageSize(\n lgSize: string | undefined,\n viewportWidth: number,\n): ImageSize | undefined {\n if (!lgSize) {\n return undefined;\n }\n let size = lgSize;\n const responsiveSizes = lgSize.split(',');\n if (responsiveSizes[1]) {\n for (let i = 0; i < responsiveSizes.length; i++) {\n const candidate = responsiveSizes[i]!.trim();\n const responsiveWidth = parseInt(candidate.split('-')[2]!, 10);\n if (responsiveWidth > viewportWidth) {\n size = candidate;\n break;\n }\n if (i === responsiveSizes.length - 1) {\n size = candidate;\n }\n }\n }\n const parts = size.trim().split('-');\n const width = parseInt(parts[0]!, 10);\n const height = parseInt(parts[1]!, 10);\n if (!Number.isFinite(width) || !Number.isFinite(height)) {\n return undefined;\n }\n return { width, height };\n}\n\n/**\n * Fit a natural image size into the available container box, preserving\n * aspect ratio and never scaling up (2.x `utils.getSize` math).\n */\nexport function fitImageSize(\n size: ImageSize,\n containerWidth: number,\n containerHeight: number,\n): ImageSize {\n const maxWidth = Math.min(containerWidth, size.width);\n const maxHeight = Math.min(containerHeight, size.height);\n const ratio = Math.min(maxWidth / size.width, maxHeight / size.height);\n return { width: size.width * ratio, height: size.height * ratio };\n}\n\n/**\n * Whether a measured trigger rect can anchor the zoom-from-origin flight.\n * A trigger that is hidden (`display: none`, the `hidden` attribute),\n * detached or collapsed measures 0×0 at the viewport origin; a flight\n * aimed at it would shrink the slide into the top-left corner.\n */\nexport function isUsableOriginRect(\n rect: RectLike | null | undefined,\n): rect is RectLike {\n return (\n !!rect &&\n Number.isFinite(rect.left) &&\n Number.isFinite(rect.top) &&\n rect.width > 0 &&\n rect.height > 0\n );\n}\n\n/** Scale the closing slide shrinks to when it has no trigger to return to. */\nexport const CENTER_CLOSE_SCALE = 0.5;\n\n/**\n * Close transform for a slide without a usable origin (hidden or\n * collapsed trigger, no `lgSize`): shrink in place about the stage centre,\n * the mirror of the `lg-start-zoom` open. The runtime pairs it with the\n * `lg-close-to-center` class, which fades the slide out over the same\n * duration.\n */\nexport function getCenterCloseTransform(scale = CENTER_CLOSE_SCALE): string {\n return `translate3d(0, 0, 0) scale3d(${scale}, ${scale}, 1)`;\n}\n\nexport interface OriginTransformInput {\n /** Bounding rect of the trigger thumbnail image, viewport coordinates. */\n triggerRect: RectLike;\n\n /** Bounding rect of the gallery outer element, viewport coordinates. */\n containerRect: RectLike;\n\n /** Media container top offset (toolbar height), px. */\n top: number;\n\n /** Media container bottom offset (caption + thumb strip height), px. */\n bottom: number;\n\n /** Final displayed image size (see {@link fitImageSize}). */\n imageSize: ImageSize;\n}\n\n/**\n * CSS transform that places the (centered, final-size) slide image exactly\n * over the trigger thumbnail — the starting point of the zoom-from-origin\n * open animation and the end point of the close animation.\n */\nexport function getOriginTransform(input: OriginTransformInput): string {\n const { triggerRect, containerRect, top, bottom, imageSize } = input;\n\n const availableWidth = containerRect.width;\n const availableHeight = containerRect.height - (top + bottom);\n\n const x =\n (availableWidth - triggerRect.width) / 2 -\n triggerRect.left +\n containerRect.left;\n const y =\n (availableHeight - triggerRect.height) / 2 - triggerRect.top + top;\n\n const scaleX = triggerRect.width / imageSize.width;\n const scaleY = triggerRect.height / imageSize.height;\n\n return `translate3d(${-x}px, ${-y}px, 0) scale3d(${scaleX}, ${scaleY}, 1)`;\n}\n","/**\n * Built-in UI icon set: inline SVG strings, one per icon name, grouped\n * by the feature that renders them so bundlers ship only the groups a\n * consumer's plugins import. Pure string data — safe in this DOM-free\n * package. Runtimes render these when the consumer supplies no custom\n * icon for a name.\n *\n * The artwork is lightGallery's own icon set, carried over from the\n * 2.x icon font: each glyph's vector outline extracted from the font\n * and re-baselined onto a square viewBox (font ascent 960 on a 1024\n * em). Same shapes the library has always shipped — now crisp inline\n * SVGs that follow `currentColor`.\n */\n\n/** The icon-name contract shared by every runtime and plugin. */\nexport type LgIconName =\n | 'close'\n | 'prev'\n | 'next'\n | 'download'\n | 'maximize'\n | 'minimize'\n | 'more'\n | 'zoomIn'\n | 'zoomOut'\n | 'actualSize'\n | 'rotateLeft'\n | 'rotateRight'\n | 'flipHorizontal'\n | 'flipVertical'\n | 'share'\n | 'shareFacebook'\n | 'shareX'\n | 'sharePinterest'\n | 'autoplayPlay'\n | 'autoplayPause'\n | 'fullscreen'\n | 'fullscreenExit'\n | 'comment'\n | 'commentClose'\n | 'toggleThumbnails';\n\nexport const coreDefaultIcons = {\n close: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M810 664.667l-238-238 238-238-60-60-238 238-238-238-60 60 238 238-238 238 60 60 238-238 238 238z\"/></svg>',\n // Three dots for the toolbar's More options menu button.\n more: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><circle cx=\"232\" cy=\"512\" r=\"80\"/><circle cx=\"512\" cy=\"512\" r=\"80\"/><circle cx=\"792\" cy=\"512\" r=\"80\"/></svg>',\n prev: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M426.667 768q17.667 0 30.167-12.5t12.5-30.167q0-18-12.667-30.333l-225.667-225.667h665q17.667 0 30.167-12.5t12.5-30.167-12.5-30.167-30.167-12.5h-665l225.667-225.667q12.667-12.333 12.667-30.333 0-17.667-12.5-30.167t-30.167-12.5q-18 0-30.333 12.333l-298.667 298.667q-12.333 13-12.333 30.333t12.333 30.333l298.667 298.667q12.667 12.333 30.333 12.333z\"/></svg>',\n next: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M597.333 768q18 0 30.333-12.333l298.667-298.667q12.333-12.333 12.333-30.333t-12.333-30.333l-298.667-298.667q-12.333-12.333-30.333-12.333-18.333 0-30.5 12.167t-12.167 30.5q0 18 12.333 30.333l226 225.667h-665q-17.667 0-30.167 12.5t-12.5 30.167 12.5 30.167 30.167 12.5h665l-226 225.667q-12.333 12.333-12.333 30.333 0 18.333 12.167 30.5t30.5 12.167z\"/></svg>',\n download:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M170 128.667h684v-86h-684v86zM682 384.667l-170-172-170 172h128v426h84v-426h128z\"/></svg>',\n maximize:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M793.003 768l-225.835-225.835c-16.683-16.683-16.683-43.691 0-60.331s43.691-16.683 60.331 0l225.835 225.835v-153.003c0-23.552 19.115-42.667 42.667-42.667s42.667 19.115 42.667 42.667v256c0 5.803-1.152 11.307-3.243 16.341s-5.163 9.728-9.216 13.781c-0.043 0.043-0.043 0.043-0.085 0.085-3.925 3.925-8.619 7.083-13.781 9.216-5.035 2.091-10.539 3.243-16.341 3.243h-256c-23.552 0-42.667-19.115-42.667-42.667s19.115-42.667 42.667-42.667zM230.997 85.334l225.835 225.835c16.683 16.683 16.683 43.691 0 60.331s-43.691 16.683-60.331 0l-225.835-225.835v153.003c0 23.552-19.115 42.667-42.667 42.667s-42.667-19.115-42.667-42.667v-256c0-23.552 19.115-42.667 42.667-42.667h256c23.552 0 42.667 19.115 42.667 42.667s-19.115 42.667-42.667 42.667z\"/></svg>',\n minimize:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M700.331 554.667l225.835 225.835c16.683 16.683 16.683 43.691 0 60.331s-43.691 16.683-60.331 0l-225.835-225.835v153.003c0 23.552-19.115 42.667-42.667 42.667s-42.667-19.115-42.667-42.667v-256c0-5.803 1.152-11.307 3.243-16.341s5.163-9.728 9.216-13.781c0.043-0.043 0.043-0.043 0.085-0.085 3.925-3.925 8.619-7.083 13.781-9.216 5.035-2.091 10.539-3.243 16.341-3.243h256c23.552 0 42.667 19.115 42.667 42.667s-19.115 42.667-42.667 42.667zM158.165 12.502l225.835 225.835v-153.003c0-23.552 19.115-42.667 42.667-42.667s42.667 19.115 42.667 42.667v256c0 5.803-1.152 11.307-3.243 16.341s-5.163 9.728-9.216 13.781c-0.043 0.043-0.043 0.043-0.085 0.085-4.096 4.053-8.789 7.125-13.781 9.216-5.035 2.091-10.539 3.243-16.341 3.243h-256c-23.552 0-42.667-19.115-42.667-42.667s19.115-42.667 42.667-42.667h153.003l-225.835-225.835c-16.683-16.683-16.683-43.691 0-60.331s43.691-16.683 60.331 0z\"/></svg>',\n} as const;\n\nexport const zoomDefaultIcons = {\n zoomIn: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M512 512.667h-86v-86h-42v86h-86v42h86v86h42v-86h86v-42zM406 340.667q80 0 136 56t56 136-56 136-136 56-136-56-56-136 56-136 136-56zM662 340.667l212-212-64-64-212 212v34l-12 12q-76-66-180-66-116 0-197 80t-81 196 81 197 197 81 196-81 80-197q0-104-66-180l12-12h34z\"/></svg>',\n zoomOut:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M298 554.667h214v-42h-214v42zM406 340.667q80 0 136 56t56 136-56 136-136 56-136-56-56-136 56-136 136-56zM662 340.667l212-212-64-64-212 212v34l-12 12q-76-66-180-66-116 0-197 80t-81 196 81 197 197 81 196-81 80-197q0-104-66-180l12-12h34z\"/></svg>',\n actualSize:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M384 853.334h426.667q53 0 90.5-37.5t37.5-90.5v-426.667q0-53-37.5-90.5t-90.5-37.5h-426.667q-53 0-90.5 37.5t-37.5 90.5v426.667q0 53 37.5 90.5t90.5 37.5zM170.667 675.334v-547.333q0-17.667 12.5-30.167t30.167-12.5h547.333q-13.333-37.667-46.333-61.5t-74.333-23.833h-426.667q-53 0-90.5 37.5t-37.5 90.5v426.667q0 41.333 23.833 74.333t61.5 46.333zM810.667 768h-426.667q-17.667 0-30.167-12.5t-12.5-30.167v-426.667q0-17.667 12.5-30.167t30.167-12.5h426.667q17.667 0 30.167 12.5t12.5 30.167v426.667q0 17.667-12.5 30.167t-30.167 12.5z\"/></svg>',\n} as const;\n\nexport const rotateDefaultIcons = {\n rotateLeft:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M554 764.667q126-16 213-112t87-226-87-226-213-112v86q92 16 153 87t61 165-61 165-153 87v-166l-194 190 194 194v-132zM302 156.667l62 62q46-34 106-44v-86q-96 12-168 68zM260 384.667q10-58 42-106l-60-60q-56 74-68 166h86zM304 574.667q-36-52-44-106h-86q12 90 70 166z\"/></svg>',\n rotateRight:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M720 278.667q34 46 44 106h86q-12-92-68-166zM554 174.667q60 10 106 44l62-62q-72-56-168-68v86zM850 468.667h-86q-10 60-44 106l62 60q58-72 68-166zM664 702.667l-194-190v166q-92-16-153-87t-61-165 61-165 153-87v-86q-126 16-213 112t-87 226 87 226 213 112v132z\"/></svg>',\n flipHorizontal:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M896 554.667l-170-170v128h-300v84h300v128zM298 468.667v-128h300v-84h-300v-128l-170 170z\"/></svg>',\n flipVertical:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M384 810.667l170-170h-128v-300h-84v300h-128zM682 212.667h128l-170-170-170 170h128v300h84v-300z\"/></svg>',\n} as const;\n\nexport const shareDefaultIcons = {\n share: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M768 252.667c68 0 124-56 124-124s-56-126-124-126-124 58-124 126c0 10 0 20 2 28l-302 176c-24-22-54-34-88-34-70 0-128 58-128 128s58 128 128 128c34 0 64-12 88-34l300 174c-2 10-4 20-4 30 0 70 58 128 128 128s128-58 128-128-58-128-128-128c-34 0-64 14-88 36l-300-176c2-10 4-20 4-30s-2-20-4-30l304-176c22 20 52 32 84 32z\"/></svg>',\n shareFacebook:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M512 952.32c-271.462 0-491.52-220.058-491.52-491.52s220.058-491.52 491.52-491.52 491.52 220.058 491.52 491.52-220.058 491.52-491.52 491.52zM628.429 612.659h-73.882c-8.755 0-18.483-11.52-18.483-26.829v-53.35h92.416l-13.978-76.083h-78.438v-228.403h-87.194v228.403h-79.104v76.083h79.104v44.749c0 64.205 44.544 116.378 105.677 116.378h73.882v-80.947z\"/></svg>',\n shareX: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><circle cx=\"512\" cy=\"512\" r=\"491.52\"/><path fill=\"#fff\" transform=\"translate(227 224) scale(24)\" d=\"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z\"/></svg>',\n sharePinterest:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M512 952.32c-271.462 0-491.52-220.058-491.52-491.52s220.058-491.52 491.52-491.52 491.52 220.058 491.52 491.52-220.058 491.52-491.52 491.52zM545.638 344.32c-31.539 2.406-44.749 18.022-69.427 32.973-13.568-71.219-30.157-139.52-79.309-175.206-15.206 107.725 22.221 188.518 39.629 274.381-29.645 49.92 3.533 150.323 66.099 125.645 76.954-30.515-66.662-185.6 29.747-205.005 100.659-20.173 141.773 174.694 79.36 237.978-90.214 91.494-262.502 2.099-241.306-128.87 5.12-32 38.246-41.728 13.21-85.914-57.702 12.8-74.957 58.317-72.704 118.989 3.533 99.328 89.242 168.909 175.155 178.483 108.698 12.083 210.688-39.885 224.819-142.182 15.821-115.405-49.101-240.282-165.274-231.27z\"/></svg>',\n} as const;\n\nexport const autoplayDefaultIcons = {\n autoplayPlay:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M512 84.667q140 0 241 101t101 241-101 241-241 101-241-101-101-241 101-241 241-101zM512 852.667q176 0 301-125t125-301-125-301-301-125-301 125-125 301 125 301 301 125zM426 234.667v384l256-192z\"/></svg>',\n autoplayPause:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M554 256.667v340h86v-340h-86zM512 84.667q140 0 241 101t101 241-101 241-241 101-241-101-101-241 101-241 241-101zM512 852.667q176 0 301-125t125-301-125-301-301-125-301 125-125 301 125 301 301 125zM384 256.667v340h86v-340h-86z\"/></svg>',\n} as const;\n\nexport const fullscreenDefaultIcons = {\n fullscreen:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M598 724.667h212v-212h-84v128h-128v84zM726 212.667v128h84v-212h-212v84h128zM214 512.667v212h212v-84h-128v-128h-84zM298 340.667v-128h128v-84h-212v212h84z\"/></svg>',\n fullscreenExit:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M682 596.667h128v-84h-212v212h84v-128zM598 128.667v212h212v-84h-128v-128h-84zM342 596.667v128h84v-212h-212v84h128zM214 256.667v84h212v-212h-84v128h-128z\"/></svg>',\n} as const;\n\nexport const commentDefaultIcons = {\n comment:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M938.667 448.128v21.205c0 0.725-0.043 1.621-0.085 2.475-5.803 99.755-47.488 190.336-112.725 258.176-68.352 71.125-162.731 117.419-268.843 123.264-0.683 0.043-1.536 0.085-2.347 0.085h-20.864c-59.947 0.683-122.965-13.227-181.931-43.008-52.181-26.496-97.749-63.488-133.931-108.16-56.405-69.717-89.899-158.080-89.941-253.696-0.597-54.4 10.795-111.36 35.157-165.419l-75.605-226.859c-2.816-8.363-3.072-17.835 0-26.965 7.467-22.357 31.616-34.432 53.973-26.965l226.731 75.563c49.493-22.485 105.984-35.243 165.376-35.115 58.539 0.384 115.797 13.141 168.149 36.949 81.579 37.163 151.040 101.248 193.749 186.667 27.477 53.291 43.307 115.84 43.136 181.803zM853.333 447.872c0.128-52.267-12.459-101.333-33.664-142.464-34.176-68.352-88.832-118.827-153.259-148.139-41.387-18.859-86.827-28.971-133.376-29.269-52.096-0.128-101.163 12.459-142.293 33.664-10.624 5.504-22.528 6.059-33.067 2.56l-162.261-54.101 54.101 162.261c3.755 11.221 2.56 22.912-2.389 32.725-23.552 46.677-34.304 96.171-33.792 142.421 0.043 76.331 26.411 145.92 70.955 200.917 28.629 35.371 64.768 64.725 106.24 85.76 46.592 23.552 96.085 34.304 142.336 33.792h19.456c83.712-4.565 158.037-41.003 212.011-97.152 51.285-53.376 84.139-124.416 89.003-202.795z\"/></svg>',\n commentClose:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M810 664.667l-238-238 238-238-60-60-238 238-238-238-60 60 238 238-238 238 60 60 238-238 238 238z\"/></svg>',\n} as const;\n\nexport const thumbnailDefaultIcons = {\n toggleThumbnails:\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1024 1024\" fill=\"currentColor\"><path transform=\"translate(0, 960) scale(1, -1)\" d=\"M682 84.667v172h172v-172h-172zM682 340.667v172h172v-172h-172zM426 596.667v172h172v-172h-172zM682 768.667h172v-172h-172v172zM426 340.667v172h172v-172h-172zM170 340.667v172h172v-172h-172zM170 84.667v172h172v-172h-172zM426 84.667v172h172v-172h-172zM170 596.667v172h172v-172h-172z\"/></svg>',\n} as const;\n","/**\n * Toolbar overflow: when the toolbar's icon buttons do not fit on one row\n * beside the counter, the lowest-priority buttons move into a \"More\n * options\" menu. Pure layout arithmetic over measured widths; each runtime\n * measures its own DOM, applies the result and renders the menu.\n */\n\n/** Priority of a button that never moves into the menu (close). */\nexport const TOOLBAR_PINNED = Number.POSITIVE_INFINITY;\n\n/** Priority of a button the table does not know (custom plugin buttons). */\nexport const TOOLBAR_DEFAULT_PRIORITY = 20;\n\n/**\n * Higher stays in the row longer. Keyed by the class each button carries\n * in every runtime; the first matching class wins.\n */\nconst PRIORITY_BY_CLASS: ReadonlyArray<readonly [string, number]> = [\n ['lg-close', TOOLBAR_PINNED],\n ['lg-share', 30],\n ['lg-autoplay-button', 30],\n ['lg-download', 30],\n ['lg-fullscreen', 20],\n ['lg-toggle-thumb', 20],\n ['lg-comment-toggle', 20],\n ['lg-maximize', 10],\n ['lg-rotate-left', 10],\n ['lg-rotate-right', 10],\n ['lg-flip-hor', 10],\n ['lg-flip-ver', 10],\n // Gesture duplicates go first: pinch and double-tap do the same.\n ['lg-zoom-in', 0],\n ['lg-zoom-out', 0],\n ['lg-actual-size', 0],\n];\n\n/** Overflow priority of a toolbar button from its class names. */\nexport function getToolbarItemPriority(classList: Iterable<string>): number {\n const classes = new Set(classList);\n for (const [className, priority] of PRIORITY_BY_CLASS) {\n if (classes.has(className)) {\n return priority;\n }\n }\n return TOOLBAR_DEFAULT_PRIORITY;\n}\n\nexport interface ToolbarOverflowItem {\n /** Measured width, px. */\n width: number;\n /** From {@link getToolbarItemPriority}; higher stays longer. */\n priority: number;\n}\n\nexport interface ToolbarOverflowInput {\n /** Width of the toolbar row, px. */\n available: number;\n /** Width taken by content that never moves (the counter), px. */\n reserved: number;\n /** Width of the More button, px. */\n moreWidth: number;\n /** The toolbar's icon buttons, in DOM order. */\n items: readonly ToolbarOverflowItem[];\n}\n\n/**\n * Indices (in DOM order) of the buttons that move into the menu; empty\n * when everything fits, or when the toolbar has no width yet (not laid\n * out). Lowest priority moves first; among equals, the button later in\n * DOM order goes first, which is the one furthest from the close button.\n * The More button's own width is paid as soon as anything moves.\n */\nexport function getToolbarOverflow({\n available,\n reserved,\n moreWidth,\n items,\n}: ToolbarOverflowInput): number[] {\n if (available <= 0) {\n return [];\n }\n const total = items.reduce((sum, item) => sum + item.width, 0);\n if (reserved + total <= available) {\n return [];\n }\n const candidates = items\n .map((item, index) => ({ ...item, index }))\n .filter((item) => item.priority !== TOOLBAR_PINNED)\n .sort((a, b) => a.priority - b.priority || b.index - a.index);\n let used = reserved + moreWidth + total;\n const moved: number[] = [];\n for (const item of candidates) {\n if (used <= available) {\n break;\n }\n moved.push(item.index);\n used -= item.width;\n }\n return moved.sort((a, b) => a - b);\n}\n\n/**\n * Whether a click's event path runs through the toolbar. Clicks there are\n * controls, not a tap on the backdrop: Medium zoom closes on the latter\n * only. The path (`event.composedPath()`) still lists a More menu item the\n * click already removed from the document.\n */\nexport function isToolbarEventPath(path: readonly unknown[]): boolean {\n return path.some(\n (node) =>\n !!(\n node as { classList?: { contains(name: string): boolean } }\n ).classList?.contains('lg-toolbar'),\n );\n}\n\n/**\n * Class names of the backdrop around the slide, where a tap closes the\n * gallery (`closeOnTap`) and a drag starts a swipe.\n */\nconst BACKDROP_CLASS_NAMES = [\n 'lg-outer',\n 'lg-item',\n 'lg-img-wrap',\n 'lg-img-rotate',\n];\n\n/** What the dismissal of a toolbar menu reads from the dismissing press. */\nexport interface MenuDismissEvent {\n target: unknown;\n preventDefault(): void;\n stopPropagation(): void;\n}\n\n/**\n * A press outside an open toolbar menu (the More options menu, the share\n * dropdown) dismisses it. A press on a control passes through, so one\n * click on another toolbar button both dismisses the menu and runs the\n * button. A press on the backdrop around the slide is consumed instead:\n * there the gallery's own tap-to-close and drag would fire, and\n * dismissing a menu must not also close the gallery. Cancelling the\n * pointerdown suppresses the compatibility mouse events the vanilla\n * runtime listens to; stopping it keeps the pointer-driven runtimes'\n * handlers from arming. Returns whether the press was consumed.\n */\nexport function consumeBackdropPress(event: MenuDismissEvent): boolean {\n const classList = (\n event.target as {\n classList?: { contains(name: string): boolean };\n } | null\n )?.classList;\n if (\n !classList ||\n !BACKDROP_CLASS_NAMES.some((name) => classList.contains(name))\n ) {\n return false;\n }\n event.preventDefault();\n event.stopPropagation();\n return true;\n}\n","/**\n * Settle gate for a CSS transition: call back once the transition of\n * `property` on `element` has actually ended.\n *\n * A fixed timer measured from the moment the target value is applied\n * lands at the same wall-clock offset whether or not the transition has\n * started, but the transition only starts at the first style recalc\n * after the value lands — on a busy main thread (a gallery's first\n * layout, a big thumbnail decode) that can be well past the offset.\n * Anything gated on the fixed timer then fires mid-flight.\n *\n * Contract:\n * - No `transitionstart` within `fallbackMs` → the element is not\n * transitioning (reduced motion, identity transform, no CSS) and the\n * gate settles on the timer, exactly like the fixed timer did.\n * - `transitionstart` re-bases the timer on the real start; `transitionend`\n * settles immediately. Interrupted transitions (`transitioncancel`)\n * leave the timer running so a restart still settles in time.\n * - Events bubbling from descendants, or for other properties, are\n * ignored. The callback runs at most once.\n *\n * Returns a disposer; disposing after settle is a no-op.\n */\nexport interface TransitionSettleEvent {\n target: unknown;\n propertyName?: string;\n}\n\n/** Structural slice of a DOM element: headless carries no DOM lib. */\nexport interface TransitionSettleTarget {\n addEventListener(\n type: string,\n listener: (event: TransitionSettleEvent) => void,\n ): void;\n removeEventListener(\n type: string,\n listener: (event: TransitionSettleEvent) => void,\n ): void;\n}\n\nexport function onTransitionSettle(\n element: TransitionSettleTarget,\n property: string,\n fallbackMs: number,\n callback: () => void,\n): () => void {\n let settled = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const isOwn = (event: TransitionSettleEvent) =>\n event.target === element && event.propertyName === property;\n const dispose = () => {\n clearTimeout(timer);\n element.removeEventListener('transitionstart', onStart);\n element.removeEventListener('transitionend', onEnd);\n };\n const settle = () => {\n if (settled) {\n return;\n }\n settled = true;\n dispose();\n callback();\n };\n const onStart = (event: TransitionSettleEvent) => {\n if (isOwn(event)) {\n clearTimeout(timer);\n timer = setTimeout(settle, fallbackMs);\n }\n };\n const onEnd = (event: TransitionSettleEvent) => {\n if (isOwn(event)) {\n settle();\n }\n };\n element.addEventListener('transitionstart', onStart);\n element.addEventListener('transitionend', onEnd);\n timer = setTimeout(settle, fallbackMs);\n return () => {\n settled = true;\n dispose();\n };\n}\n","/**\n * Responsive image selection + decode gating (plan: responsive loading).\n *\n * The browser already picks a candidate natively when the runtimes render\n * `<picture>`/`srcset` — these helpers exist for the places that need the\n * DECISION as data: preload warming at the right resolution, tooling, and\n * the framework image-component recipes. The algorithm mirrors the HTML\n * spec's srcset selection closely enough to be deterministic and\n * unit-testable: parse candidates, derive the slot width from `sizes`,\n * scale by DPR, pick the smallest candidate that covers the target\n * (falling back to the largest available).\n */\n\nimport type { GalleryItem, ImageSources } from './items';\nimport { parseImageSize } from './origin';\n\nexport interface SrcsetCandidate {\n url: string;\n /** Width descriptor (`640w`) in px, if given. */\n width?: number;\n /** Density descriptor (`2x`), if given; bare candidates read as 1x. */\n density?: number;\n}\n\nexport interface Viewport {\n width: number;\n height: number;\n /** devicePixelRatio; defaults to 1. */\n dpr?: number;\n}\n\n/** Parse a `srcset` attribute string into candidates. Malformed entries\n * are skipped rather than thrown — item data is author-provided. */\nexport function parseSrcset(srcset: string | undefined): SrcsetCandidate[] {\n const candidates: SrcsetCandidate[] = [];\n if (typeof srcset !== 'string') {\n return candidates;\n }\n for (const entry of srcset.split(',')) {\n const parts = entry.trim().split(/\\s+/);\n const url = parts[0];\n if (!url) {\n continue;\n }\n const descriptor = parts[1];\n if (!descriptor) {\n candidates.push({ url, density: 1 });\n continue;\n }\n const value = parseFloat(descriptor);\n if (Number.isNaN(value) || value <= 0) {\n continue;\n }\n if (descriptor.endsWith('w')) {\n candidates.push({ url, width: value });\n } else if (descriptor.endsWith('x')) {\n candidates.push({ url, density: value });\n }\n }\n return candidates;\n}\n\n/**\n * Effective slot width (px) from a `sizes` attribute for a viewport.\n * Supports the common authored forms deterministically: comma-separated\n * `(min-width: Npx) <len>` / `(max-width: Npx) <len>` clauses with a\n * bare `<len>` default, where `<len>` is `px` or `vw`. The first\n * matching clause wins (spec order). Unsupported conditions are skipped;\n * no match falls back to the full viewport width (`100vw`, the spec\n * default).\n */\nexport function resolveSizes(\n sizes: string | undefined,\n viewportWidth: number,\n): number {\n if (!sizes) {\n return viewportWidth;\n }\n const toLength = (raw: string): number | null => {\n const value = parseFloat(raw);\n if (Number.isNaN(value)) {\n return null;\n }\n if (raw.endsWith('vw')) {\n return (value / 100) * viewportWidth;\n }\n if (raw.endsWith('px')) {\n return value;\n }\n return null;\n };\n for (const clause of sizes.split(',')) {\n const trimmed = clause.trim();\n if (!trimmed) {\n continue;\n }\n const condition = /^\\((min|max)-width:\\s*([\\d.]+)px\\)\\s+(\\S+)$/.exec(\n trimmed,\n );\n if (condition) {\n const bound = parseFloat(condition[2]!);\n const matches =\n condition[1] === 'min'\n ? viewportWidth >= bound\n : viewportWidth <= bound;\n if (!matches) {\n continue;\n }\n const length = toLength(condition[3]!);\n if (length !== null) {\n return length;\n }\n continue;\n }\n // Bare default clause (no condition).\n if (!trimmed.startsWith('(')) {\n const length = toLength(trimmed);\n if (length !== null) {\n return length;\n }\n }\n }\n return viewportWidth;\n}\n\n/** Whether a `<source media>` condition matches the viewport. Same\n * deterministic subset as {@link resolveSizes}: min/max-width in px;\n * unsupported conditions read as NOT matching. Absent media matches. */\nexport function matchesMedia(\n media: string | undefined,\n viewport: Viewport,\n): boolean {\n if (!media) {\n return true;\n }\n const condition = /^\\(\\s*(min|max)-width:\\s*([\\d.]+)px\\s*\\)$/.exec(\n media.trim(),\n );\n if (!condition) {\n return false;\n }\n const bound = parseFloat(condition[2]!);\n return condition[1] === 'min'\n ? viewport.width >= bound\n : viewport.width <= bound;\n}\n\nfunction pickFromCandidates(\n candidates: SrcsetCandidate[],\n slotWidth: number,\n dpr: number,\n): SrcsetCandidate | null {\n if (!candidates.length) {\n return null;\n }\n const widthCandidates = candidates\n .filter((c) => c.width !== undefined)\n .sort((a, b) => a.width! - b.width!);\n if (widthCandidates.length) {\n const target = slotWidth * dpr;\n return (\n widthCandidates.find((c) => c.width! >= target) ??\n widthCandidates[widthCandidates.length - 1]!\n );\n }\n const densityCandidates = [...candidates].sort(\n (a, b) => (a.density ?? 1) - (b.density ?? 1),\n );\n return (\n densityCandidates.find((c) => (c.density ?? 1) >= dpr) ??\n densityCandidates[densityCandidates.length - 1]!\n );\n}\n\nexport interface ResolvedImageSource {\n src: string;\n /** Intrinsic width (px) when the winning candidate declared one. */\n width?: number;\n /** The `<source>` entry that won, when selection went through\n * `sources` (picture semantics) rather than the item srcset. */\n source?: ImageSources;\n}\n\n/**\n * Deterministically resolve which image URL a viewport displays for an\n * item, mirroring picture/srcset semantics: the first matching\n * `sources[]` entry wins (spec order), then the item-level\n * `srcset`/`sizes`, then plain `src`. Returns null for items with no\n * image source at all.\n */\nexport function resolveImageSource(\n item: Pick<GalleryItem, 'src' | 'srcset' | 'sizes' | 'sources'>,\n viewport: Viewport,\n): ResolvedImageSource | null {\n const dpr = viewport.dpr && viewport.dpr > 0 ? viewport.dpr : 1;\n for (const source of item.sources ?? []) {\n if (!matchesMedia(source.media, viewport)) {\n continue;\n }\n const picked = pickFromCandidates(\n parseSrcset(source.srcset),\n resolveSizes(source.sizes, viewport.width),\n dpr,\n );\n if (picked) {\n return { src: picked.url, width: picked.width, source };\n }\n }\n if (item.srcset) {\n const picked = pickFromCandidates(\n parseSrcset(item.srcset),\n resolveSizes(item.sizes, viewport.width),\n dpr,\n );\n if (picked) {\n return { src: picked.url, width: picked.width };\n }\n }\n return item.src ? { src: item.src } : null;\n}\n\n/**\n * The width \"actual size\" zoom refers to. `img.naturalWidth` LIES under\n * `srcset`/`sizes`: w-descriptor selection density-corrects the\n * intrinsic size to roughly the layout slot — on phones that collapses\n * the actual-size scale to ~1 and kills double-tap/pinch zoom. The\n * resolution order mirrors what the item DECLARES before trusting the\n * element: explicit `width` (2.x `data-width`), the largest candidate\n * the srcset ladder can serve (first matching `sources[]` entry per\n * picture semantics, else the item srcset), the `lgSize` natural dims,\n * and only then the reported natural width. The declared tiers are what\n * make optimizer components (next/image, NuxtImg, NgOptimizedImage) —\n * which manage their own srcset — zoomable to full resolution.\n */\nexport function getActualSizeWidth(\n item: Pick<GalleryItem, 'width' | 'srcset' | 'sources' | 'lgSize'>,\n viewport: Viewport,\n naturalWidth: number,\n): number {\n if (item.width) {\n const declared = parseFloat(item.width);\n if (!Number.isNaN(declared) && declared > 0) {\n return declared;\n }\n }\n let candidates: SrcsetCandidate[] = [];\n // Author data: a runtime may hand over `sources` before it has been\n // normalised (a raw `data-sources` JSON string) — never iterate that.\n const sources = Array.isArray(item.sources) ? item.sources : [];\n for (const source of sources) {\n if (matchesMedia(source.media, viewport)) {\n candidates = parseSrcset(source.srcset);\n break;\n }\n }\n if (!candidates.length && item.srcset) {\n candidates = parseSrcset(item.srcset);\n }\n const widths = candidates\n .map((candidate) => candidate.width)\n .filter((width): width is number => width !== undefined);\n if (widths.length) {\n return Math.max(...widths);\n }\n const natural = parseImageSize(item.lgSize, viewport.width);\n if (natural && natural.width > 0) {\n return natural.width;\n }\n return naturalWidth;\n}\n\n/**\n * How long a slide waits on `img.decode()` before completing anyway —\n * the gate must never strand a slide on a browser that rejects or\n * stalls decode (huge images evict decoded data; some UAs reject on\n * detached nodes).\n */\nexport const DECODE_TIMEOUT_MS = 500;\n\n/**\n * Decode gate: resolve when the image is safe to paint — after\n * `decode()` settles (success OR rejection; rejection still means the\n * data arrived) or after the timeout, whichever is first. Browsers\n * without `decode()` resolve immediately (the load event already\n * fired). Never rejects.\n */\nexport function awaitDecode(\n img: { decode?: () => Promise<void> },\n timeoutMs: number = DECODE_TIMEOUT_MS,\n): Promise<void> {\n if (typeof img.decode !== 'function') {\n return Promise.resolve();\n }\n return new Promise((resolve) => {\n let done = false;\n const finish = () => {\n if (!done) {\n done = true;\n clearTimeout(timer);\n resolve();\n }\n };\n const timer = setTimeout(finish, timeoutMs);\n img.decode!().then(finish, finish);\n });\n}\n","/**\n * Rolling-window velocity tracking. Release decisions must read the\n * velocity of the gesture's final instant, not its whole-gesture\n * average: a drag that pauses and then flicks reads fast, and a drag\n * that ends resting reads zero. Sessions push a sample per move; the\n * release reads the window ending at the release timestamp.\n */\n\nexport interface VelocitySample {\n x: number;\n y: number;\n /** Timestamp in ms (same clock as the release read). */\n t: number;\n}\n\nexport interface Velocity {\n /** px/ms, signed. */\n x: number;\n y: number;\n}\n\n/** How far back a release looks when reading the gesture velocity. */\nexport const VELOCITY_WINDOW_MS = 100;\n\n/** Below this displacement (px) an axis reads as at rest. */\nconst MIN_DISPLACEMENT = 1;\n\n/** Below this span (ms) the window cannot measure reliably. */\nconst MIN_WINDOW_SPAN_MS = 5;\n\n/**\n * Append a sample, pruning everything older than the window — the\n * buffer stays a handful of entries regardless of gesture length.\n */\nexport function pushVelocitySample(\n samples: readonly VelocitySample[],\n sample: VelocitySample,\n windowMs: number = VELOCITY_WINDOW_MS,\n): VelocitySample[] {\n return [...samples.filter((s) => sample.t - s.t <= windowMs), sample];\n}\n\n/**\n * Velocity (px/ms per axis) over the samples inside the window ending\n * at `releaseTime`. Fewer than two recent samples — the finger rested\n * before lifting — reads as zero, as does sub-pixel drift.\n */\nexport function getWindowedVelocity(\n samples: readonly VelocitySample[],\n releaseTime: number,\n windowMs: number = VELOCITY_WINDOW_MS,\n): Velocity {\n const recent = samples.filter((s) => releaseTime - s.t <= windowMs);\n if (recent.length < 2) {\n return { x: 0, y: 0 };\n }\n const first = recent[0]!;\n const last = recent[recent.length - 1]!;\n const dt = last.t - first.t;\n if (dt < MIN_WINDOW_SPAN_MS) {\n return { x: 0, y: 0 };\n }\n const dx = last.x - first.x;\n const dy = last.y - first.y;\n return {\n x: Math.abs(dx) > MIN_DISPLACEMENT ? dx / dt : 0,\n y: Math.abs(dy) > MIN_DISPLACEMENT ? dy / dt : 0,\n };\n}\n","import { LightGallery } from './lightgallery';\nimport { VideoSource } from './plugins/video/types';\n\n/**\n * List of lightGallery events\n * All events should be documented here\n * Below interfaces are used to build the website documentations\n * */\nexport const lGEvents: {\n [key: string]: string;\n} = {\n afterAppendSlide: 'lgAfterAppendSlide',\n init: 'lgInit',\n hasVideo: 'lgHasVideo',\n containerResize: 'lgContainerResize',\n updateSlides: 'lgUpdateSlides',\n afterAppendSubHtml: 'lgAfterAppendSubHtml',\n beforeOpen: 'lgBeforeOpen',\n afterOpen: 'lgAfterOpen',\n slideItemLoad: 'lgSlideItemLoad',\n beforeSlide: 'lgBeforeSlide',\n afterSlide: 'lgAfterSlide',\n posterClick: 'lgPosterClick',\n dragStart: 'lgDragStart',\n dragMove: 'lgDragMove',\n dragEnd: 'lgDragEnd',\n beforeNextSlide: 'lgBeforeNextSlide',\n beforePrevSlide: 'lgBeforePrevSlide',\n beforeClose: 'lgBeforeClose',\n afterClose: 'lgAfterClose',\n rotateLeft: 'lgRotateLeft',\n rotateRight: 'lgRotateRight',\n flipHorizontal: 'lgFlipHorizontal',\n flipVertical: 'lgFlipVertical',\n autoplay: 'lgAutoplay',\n autoplayStart: 'lgAutoplayStart',\n autoplayStop: 'lgAutoplayStop',\n};\n\n// Follow the below format for the event documentation\n// @method is the method name when event is used with Angular/React components\n\n/**\n * Fired only once when lightGallery is initialized\n * @name lgInit\n * @method onInit\n * @example\n * const lg = document.getElementById('custom-events-demo');\n * // Perform any action on lightGallery initialization.\n * // Init event returns the plugin instance that can be used to call any lightGalley public method\n * let pluginInstance = null;\n * lg.addEventListener('lgInit', (event) => {\n * pluginInstance = event.detail.instance;\n * });\n * lightGallery(lg);\n * @see <a href=\"/docs/methods/\">Methods</a>\n */\nexport interface InitDetail {\n /**\n * lightGallery plugin instance\n */\n instance: LightGallery;\n}\n\n/**\n * Fired when the slide content has been inserted into it's slide container.\n * @name lgAfterAppendSlide\n * @method onAfterAppendSlide\n */\nexport interface AfterAppendSlideEventDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired immediately before opening the gallery\n * @name lgBeforeOpen\n * @method onBeforeOpen\n */\nexport interface BeforeOpenDetail {}\n\n/**\n * Fired immediately after opening the gallery\n * @name lgAfterOpen\n * @method onAfterOpen\n */\nexport interface AfterOpenDetail {}\n\n/**\n * Fired once the media inside the slide has been completely loaded .\n * @name lgSlideItemLoad\n * @method onSlideItemLoad\n */\nexport interface SlideItemLoadDetail {\n /**\n * Index of the slide\n */\n index: number;\n /**\n * For the first slide, lightGallery adds some delay for displaying the loaded slide item.\n * This delay is required for the transition effect when the slide item is displayed\n * Respect the delay when you use this event\n */\n delay: number;\n\n // Will be true for the first slide\n isFirstSlide: boolean;\n}\n\n/**\n * Fired immediately before each slide transition.\n * @name lgBeforeSlide\n * @method onBeforeSlide\n * @example\n * const lg = document.getElementById('custom-events-demo');\n * // Perform any action before each slide transition\n * lg.addEventListener('lgBeforeSlide', (event) => {\n * const { index, prevIndex } = event.detail;\n * alert(index, prevIndex);\n * });\n * lightGallery(lg);\n */\nexport interface BeforeSlideDetail {\n /**\n * Index of the previous slide\n */\n prevIndex: number;\n /**\n * Index of the slide\n */\n index: number;\n /**\n * true if slide function called via touch event or mouse drag\n */\n fromTouch: boolean;\n /**\n * true if slide function called via thumbnail click\n */\n fromThumb: boolean;\n}\n\n/**\n * Fired immediately after each slide transition.\n * @name lgAfterSlide\n * @method onAfterSlide\n */\nexport interface AfterSlideDetail {\n /**\n * Index of the previous slide\n */\n prevIndex: number;\n /**\n * Index of the slide\n */\n index: number;\n /**\n * true if slide function called via touch event or mouse drag\n */\n fromTouch: boolean;\n /**\n * true if slide function called via thumbnail click\n */\n fromThumb: boolean;\n}\n\n/**\n * Fired when the video poster is clicked.\n * @name lgPosterClick\n * @method onPosterClick\n */\nexport interface PosterClickDetail {}\n\n/**\n * Fired when the drag event to move to different slide starts.\n * @name lgDragStart\n * @method onDragStart\n */\nexport interface DragStartDetail {}\n\n/**\n * Fired periodically during the drag operation.\n * @name lgDragMove\n * @method onDragMove\n */\nexport interface DragMoveDetail {}\n\n/**\n * Fired when the user has finished the drag operation\n * @name lgDragEnd\n * @method onDragEnd\n */\nexport interface DragEndDetail {}\n\n/**\n * Fired immediately before the start of the close process.\n * @name lgBeforeClose\n * @method onBeforeClose\n */\nexport interface BeforeCloseDetail {}\n\n/**\n * Fired immediately once lightGallery is closed.\n * @name lgAfterClose\n * @method onAfterClose\n */\nexport interface AfterCloseDetail {\n /**\n * lightGallery plugin instance\n */\n instance: LightGallery;\n}\n\n/**\n * Fired immediately before each \"next\" slide transition\n * @name lgBeforeNextSlide\n * @method onBeforeNextSlide\n */\nexport interface BeforeNextSlideDetail {\n /**\n * Index of the slide\n */\n index: number;\n /**\n * true if slide function called via touch event or mouse drag\n */\n fromTouch: boolean;\n}\n\n/**\n * Fired immediately before each \"prev\" slide transition\n * @name lgBeforePrevSlide\n * @method onBeforePrevSlide\n */\nexport interface BeforePrevSlideDetail {\n /**\n * Index of the slide\n */\n index: number;\n /**\n * true if slide function called via touch event or mouse drag\n */\n fromTouch: boolean;\n}\n\n/**\n * Fired when the sub-html content (ex : title/ description) has been appended into the slide.\n * @name lgAfterAppendSubHtml\n * @method onAfterAppendSubHtml\n */\nexport interface AfterAppendSubHtmlDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired when the lightGallery container has been resized.\n * @name lgContainerResize\n * @method onContainerResize\n */\nexport interface ContainerResizeDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired when lightGallery detects video slide\n * @name lgHasVideo\n * @method onHasVideo\n */\nexport interface HasVideoDetail {\n /**\n * Index of the slide,\n */\n index: number;\n /**\n * Video source\n */\n src: string;\n /**\n * HTML5 video source if available\n * <p>\n HTML5 video source = source: {\n src: string;\n type: string;\n }[];\n attributes: HTMLVideoElement;\n * </p>\n */\n html5Video: VideoSource;\n /**\n * True if video has poster\n */\n hasPoster: boolean;\n}\n\n/**\n * Fired when the image is rotated in anticlockwise direction\n * @name lgRotateLeft\n * @method onRotateLeft\n */\nexport interface RotateLeftDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired when the image is rotated in clockwise direction\n * @name lgRotateRight\n * @method onRotateRight\n */\nexport interface RotateRightDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired when the image is flipped horizontally\n * @name lgFlipHorizontal\n * @method onFlipHorizontal\n */\nexport interface FlipHorizontalDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired when the image is flipped vertically\n * @name lgFlipVertical\n * @method onFlipVertical\n */\nexport interface FlipVerticalDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n","import { VirtualizationSettings } from '@lightgallery/headless';\n\nimport { LgIcons } from './lg-icons';\nimport { GalleryItem } from './lg-utils';\nimport { LgQuery } from './lgQuery';\nimport { LightGallery } from './lightgallery';\nimport { AutoplaySettings } from './plugins/autoplay/lg-autoplay-settings';\nimport { CommentSettings } from './plugins/comment/lg-comment-settings';\nimport { FullscreenSettings } from './plugins/fullscreen/lg-fullscreen-settings';\nimport { HashSettings } from './plugins/hash/lg-hash-settings';\nimport { JustifiedSettings } from './plugins/justified/lg-justified-settings';\nimport { MediumZoomSettings } from './plugins/mediumZoom/lg-medium-zoom-settings';\nimport { PagerSettings } from './plugins/pager/lg-pager-settings';\nimport { RotateSettings } from './plugins/rotate/lg-rotate-settings';\nimport { ShareSettings } from './plugins/share/lg-share-settings';\nimport { ThumbnailsSettings } from './plugins/thumbnail/lg-thumbnail-settings';\nimport { VideoSettings } from './plugins/video/lg-video-settings';\nimport { ZoomSettings } from './plugins/zoom/lg-zoom-settings';\n\ntype LightGalleryCoreMobileSettings = Exclude<\n LightGalleryCoreSettings,\n 'mobileSettings'\n>;\n\n// @todo use separate mobile settings for plugins\nexport interface MobileSettings\n extends LightGalleryCoreMobileSettings,\n Partial<ZoomSettings>,\n Partial<ThumbnailsSettings>,\n Partial<VideoSettings>,\n Partial<AutoplaySettings>,\n Partial<CommentSettings>,\n Partial<FullscreenSettings>,\n Partial<HashSettings>,\n Partial<PagerSettings>,\n Partial<RotateSettings>,\n Partial<ShareSettings> {}\n\nexport interface LightGalleryCoreStrings {\n closeGallery: string;\n toggleMaximize: string;\n previousSlide: string;\n nextSlide: string;\n download: string;\n playVideo: string;\n mediaLoadingFailed: string;\n /** Accessible name of the gallery dialog when `ariaLabelledby` is not set. */\n galleryLabel: string;\n /**\n * Template announced to assistive technology on every slide change.\n * `{index}` and `{total}` are replaced with the 1-based slide position\n * and the slide count; the slide caption, when present, is appended.\n */\n slideAnnouncement: string;\n /** Label of the toolbar's More options menu button. */\n moreOptions: string;\n\n // Plugin labels: every user-facing string lives in this one contract.\n // The legacy per-plugin *PluginStrings objects remain as deprecated\n // aliases, an explicitly set legacy key wins.\n /** Share plugin: share button label. */\n share: string;\n /** Thumbnail plugin: strip toggle button label. */\n toggleThumbnails: string;\n /** Autoplay plugin: slideshow toggle button label. */\n toggleAutoplay: string;\n /** Fullscreen plugin: fullscreen toggle button label. */\n toggleFullscreen: string;\n /** Zoom plugin: zoom-in button label. */\n zoomIn: string;\n /** Zoom plugin: zoom-out button label. */\n zoomOut: string;\n /** Zoom plugin: actual-size button label. */\n viewActualSize: string;\n /** Rotate plugin: rotate-left button label. */\n rotateLeft: string;\n /** Rotate plugin: rotate-right button label. */\n rotateRight: string;\n /** Rotate plugin: horizontal flip button label. */\n flipHorizontal: string;\n /** Rotate plugin: vertical flip button label. */\n flipVertical: string;\n /** Comment plugin: comments toggle button label. */\n toggleComments: string;\n}\n\nexport type LightGalleryAllSettings = LightGalleryCoreSettings &\n ZoomSettings &\n ThumbnailsSettings &\n VideoSettings &\n AutoplaySettings &\n CommentSettings &\n FullscreenSettings &\n HashSettings &\n JustifiedSettings &\n PagerSettings &\n RotateSettings &\n ShareSettings &\n MediumZoomSettings;\n\n// User-facing input: everything optional, strings mergeable per-key\n// (headless UserSettings parity, a partial strings object merges over\n// the defaults instead of replacing the whole contract).\nexport type LightGallerySettings = Partial<\n Omit<LightGalleryAllSettings, 'strings'>\n> & { strings?: Partial<LightGalleryCoreStrings> };\n\nexport interface LightGalleryCoreSettings {\n /**\n * Type of transition between images.\n */\n mode:\n | 'lg-slide'\n | 'lg-fade'\n | 'lg-zoom-in'\n | 'lg-zoom-in-big'\n | 'lg-zoom-out'\n | 'lg-zoom-out-big'\n | 'lg-zoom-out-in'\n | 'lg-zoom-in-out'\n | 'lg-soft-zoom'\n | 'lg-scale-up'\n | 'lg-slide-circular'\n | 'lg-slide-circular-vertical'\n | 'lg-slide-vertical'\n | 'lg-slide-vertical-growth'\n | 'lg-slide-skew-only'\n | 'lg-slide-skew-only-rev'\n | 'lg-slide-skew-only-y'\n | 'lg-slide-skew-only-y-rev'\n | 'lg-slide-skew'\n | 'lg-slide-skew-rev'\n | 'lg-slide-skew-cross'\n | 'lg-slide-skew-cross-rev'\n | 'lg-slide-skew-ver'\n | 'lg-slide-skew-ver-rev'\n | 'lg-slide-skew-ver-cross'\n | 'lg-slide-skew-ver-cross-rev'\n | 'lg-lollipop'\n | 'lg-lollipop-rev'\n | 'lg-rotate'\n | 'lg-rotate-rev'\n | 'lg-tube';\n\n /**\n * Slide animation CSS easing property\n */\n easing: string;\n\n /**\n *Transition duration (in ms).\n */\n speed: number;\n\n /**\n * If you are using lightGallery for commercial projects, you need to purchase a commercial license\n * to get the license key. For projects that are compatible with GPLv3 license,\n * please contact us for getting a license key at <a href=\"mailto:contact@lightgalleryjs.com\">contact@lightgalleryjs.com</a>.\n * If you want to test lightGallery before purchasing a commercial license, you can\n * use `0000-0000-000-0000` as a temporary license key. It does not limit any\n * feature; it only logs a console warning. lightGallery 3 keys start with `LIG`;\n * a key from v1 or v2 logs a warning asking you to upgrade.\n * See <a href=\"/docs/license/\">License</a>.\n */\n\n licenseKey: string;\n\n /**\n * Height of the gallery.\n * example '100%' , '300px'\n */\n height: string;\n\n /**\n * Width of the gallery.\n * example '100%' , '300px'\n */\n width: string;\n\n /**\n * Add custom class for gallery container\n * This can be used to set different style for different galleries\n */\n addClass: string;\n\n /**\n * Start animation class for the gallery.\n * @description\n * <ul>\n * <li>startClass will be empty zoomFromOrigin is true.</li>\n * <li>This can be used to change the starting effect when the image is loaded</li>\n * <li>This is also applied when navigating to new slides</li>\n * </ul>\n */\n startClass: string;\n\n /**\n * Enable zoom from origin effect.\n * @description You need to know the original image size upfront and provide it via data-lg-size attribute as <code> data-lg-size=\"1920-1280</code>\"\n *\n * If you don't know, the size of a few images in the list, you can skip the data-lg-size attribute for the particular slides,\n * lightGallery will show the default animation if data-lg-size is not available\n *\n * If you are using responsive images,\n * you can pass a comma separated list of sizes combined with a max-width (up to what size the particular image should be used)\n *\n * example -\n * <code> data-lg-size=\"240-160-375, 400-267-480, 1600-1067\"\n * data-responsive=\"img-240.jpg 375, img-400.jpg 480\"\n * data-src=\"img-1600.jpg\" </code>\n *\n * In the above example, upto 375 width img.240.jpg and lg-size 240-160 will be used.\n * Similarly, upto 480 pixel width size 400-267 and img-400.jpg will be used\n * And above 480, lg-size 1600-1067 and img-1600.jpg will be used\n *\n * When the gallery closes on a slide that has no thumbnail to return to\n * (the trigger is hidden or collapsed, as with the overflow items behind a\n * \"+9 photos\" tile, it has no data-lg-size, or the gallery is dynamic), the\n * slide shrinks to the centre of the stage and fades out instead of flying\n * to the thumbnail.\n *\n * <ul>\n * <li>At the moment, zoomFromOrigin options is supported only for image slides.</li>\n * <li>The opening flight is skipped if dynamic option is enabled or galleryID found in the URL.</li>\n * <li>startClass will be empty if zoomFromOrigin is true to avoid css conflicts.</li>\n * </ul>\n */\n zoomFromOrigin: boolean;\n\n /**\n * Zoom from image animation duration\n */\n startAnimationDuration: number;\n\n /**\n * Backdrop transition duration.\n * Note - Do not change the value of backdrop via css.\n */\n backdropDuration: number;\n\n /**\n * Configure where the gallery should be appended.\n * Useful to create inline galleries and more\n * It is an empty string in the default settings and later assigned to document.body to avoid accessing document for SSR\n */\n container: HTMLElement | (() => HTMLElement | null) | (string | null);\n\n /**\n * Delay for hiding gallery controls in ms.\n * Pass <code>0</code> if you don't want to hide the controls\n */\n hideBarsDelay: number;\n\n /**\n * Delay in hiding controls for the first time when gallery is opened\n */\n showBarsAfter: number;\n\n /**\n * Delay slide transitions.\n * @description This is useful if you want to do any action in the current slide before moving to next slide.\n * <section>\n * For example, fading out the captions before going to next slide.\n * <code>.lg-slide-progress</code> class name is added to the current slide immediately after calling the slide method.\n * But transition begins only after the delay\n * </section>\n */\n slideDelay: number;\n\n /**\n * If true, toolbar, captions and thumbnails will not overlap with media element\n * This will not effect thumbnails if animateThumb is false\n * Also, toggle thumbnails button is not displayed if allowMediaOverlap is false\n * <section>\n * Note - Changing the position of the media on every slide transition creates a flickering effect.\n * Therefore, the height of the caption is calculated dynamically, only once based on the first slide caption.\n * </section>\n * <section>\n * if you have dynamic captions for each media,\n * you can provide an appropriate height for the captions via allowMediaOverlap option\n * </section>\n */\n allowMediaOverlap: boolean;\n\n /**\n * Video max size.\n * @description This can be over-written by passing specific size via data-lg-size attribute\n * Recommended video resolution and & aspect ratios <a href=\"https://support.google.com/youtube/answer/6375112\">https://support.google.com/youtube/answer/6375112</a>\n */\n videoMaxSize: string;\n\n /**\n * Automatically load poster image for YouTube videos\n */\n loadYouTubePoster: boolean;\n\n /**\n * Height of the caption for calculating allowMediaOverlap positions\n * Note - this is only used to find the position of media item if allowMediaOverlap is true.\n * Not for setting height of the captions\n * Set 0 if you want to calculate the height of captions dynamically\n */\n defaultCaptionHeight: number;\n\n /**\n * aria-labelledby attribute fot gallery\n */\n ariaLabelledby: string;\n\n /**\n * aria-describedby attribute for gallery\n */\n ariaDescribedby: string;\n\n /**\n * Large-gallery virtualization. Off when undefined, the classic\n * behavior: every thumbnail renders and the mounted-slide window is\n * numberOfSlideItemsInDom.\n * @description slides overrides the mounted-slide pool size; thumbs\n * turns on thumbnail-strip windowing (only the visible thumbs plus an\n * overscan render, with spacers preserving the strip geometry), a\n * number is the overscan thumb count per side, 'auto' derives one\n * extra viewport per side. The window advances at commit points\n * (release, slide change, resize), never per pointer move.\n * See <a href=\"/docs/virtualization/\">Virtualization</a>.\n * @version V3.0.0\n */\n virtualization?: VirtualizationSettings;\n\n /**\n * Announce slide changes to assistive technology through a dedicated\n * polite live region (strings.slideAnnouncement + the slide caption).\n * @description While enabled, the counter and caption bar are not\n * separate live regions, the announcer is the single source of\n * slide-change announcements. Set to false to restore the previous\n * behavior (live counter and caption, no announcer).\n * See <a href=\"/docs/accessibility/\">Accessibility</a>.\n * @version V3.0.0\n */\n ariaAnnouncements: boolean;\n\n /**\n * Hide scrollbar when gallery is opened\n * @version V2.5.0\n */\n hideScrollbar: boolean;\n\n /**\n * Reset to previous scrollPosition when lightGallery is closed\n * @description By default, lightGallery doesn't hide the scrollbar for a smooth opening transition.\n * If a user changes the scroll position, lightGallery resets it to the previous value\n * @version V2.5.0\n */\n resetScrollPosition: boolean;\n\n /**\n * If false user won't be able to close the gallery at all\n * This is useful for creating inline galleries.\n */\n closable: boolean;\n\n /**\n * allows vertical drag/swipe to close gallery\n * <code>false</code> if option <code>closable</code> is <code>false</code>\n */\n swipeToClose: boolean;\n /**\n * allows clicks on black area to close gallery.\n */\n closeOnTap: boolean;\n\n /**\n * If false, close button won't be displayed.\n * Useful for creating inline galleries.\n */\n showCloseIcon: boolean;\n\n /**\n * Show maximize icon.\n * Useful for creating inline galleries.\n */\n showMaximizeIcon: boolean;\n\n /**\n * Keep the toolbar on one row.\n * @description When the toolbar buttons do not fit beside the counter,\n * the lowest-priority ones move into a \"More options\" menu. Set to\n * false to let the buttons wrap onto a second row instead.\n * See <a href=\"/docs/settings/#toolbarOverflow\">toolbarOverflow</a>.\n * @version V3.0.0\n */\n toolbarOverflow: boolean;\n\n /**\n * Show the toolbar buttons that repeat a touch gesture.\n * @description Zoom in, zoom out and actual size do what pinch and\n * double-tap already do. On by default, and turned off on touch\n * devices through mobileSettings.\n * See <a href=\"/docs/settings/#showGestureButtons\">showGestureButtons</a>.\n * @version V3.0.0\n */\n showGestureButtons: boolean;\n\n /**\n * If false, will disable the ability to loop back to the beginning of the gallery from the last slide.\n */\n loop: boolean;\n\n /**\n * Whether the LightGallery could be closed by pressing the \"Esc\" key.\n */\n escKey: boolean;\n\n /**\n * Enable keyboard navigation\n */\n keyPress: boolean;\n\n /**\n * Trap focus within the lightGallery\n * @version V2.5.0\n */\n trapFocus: boolean;\n\n /**\n * If false, prev/next buttons will not be displayed.\n */\n controls: boolean;\n\n /**\n * Enable slideEnd animation\n */\n slideEndAnimation: boolean;\n\n /**\n * If true, prev/next button will be hidden on first/last image.\n * @description Note - this option will be ignored if <code>loop</code> or <code>slideEndAnimation</code> is set to true\n */\n hideControlOnEnd: boolean;\n\n /**\n * ability to navigate to next/prev slides on mousewheel\n */\n mousewheel: boolean;\n\n /**\n * Gallery reading direction: keyboard arrows, swipe advance and the\n * slide/thumbnail transforms follow it. Visual mirroring is the\n * opt-in lg-rtl.css layer - load it whenever this resolves to 'rtl'.\n * 'auto' inherits the computed direction of the gallery element;\n * the default stays 'ltr' so upgrades never change behavior on\n * existing pages.\n * See <a href=\"/docs/localization-rtl/\">Localization &amp; RTL</a>.\n * @version V3.0.0\n */\n direction: 'ltr' | 'rtl' | 'auto';\n\n /**\n * Option to get captions from alt or title tags.\n */\n getCaptionFromTitleOrAlt: boolean;\n\n /**\n * control where the sub-html should be appended.\n * If you choose '.lg-outer', you are responsible for placing the div at the right position.\n * '.lg-outer' is useful if you want show custom HTML outside the normal gallery\n */\n appendSubHtmlTo: '.lg-sub-html' | '.lg-item' | '.lg-outer';\n\n /**\n * Set to true if the selector in \"data-sub-html\" should use the current item as its origin.\n */\n subHtmlSelectorRelative: boolean;\n\n /**\n * number of preload slides\n * @description will exicute only after the current slide is fully loaded.\n * for example, if you click on 4th image and if preload = 1 then 3rd slide and 5th\n * slide will be loaded in the background after the 4th slide is fully loaded..\n * if preload is 2 then 2nd 3rd 5th 6th slides will be preloaded.\n */\n preload: number;\n\n /**\n * Control how many slide items should be kept in dom at a time\n * @description To improve performance by reducing number of gallery items in the dom,\n * lightGallery keeps only the lowest possible number of slides in the dom at a time.\n * This has a minimum value of 3\n */\n numberOfSlideItemsInDom: number;\n\n /**\n * Custom selector property instead of direct children.\n * @description Based on your markup structure, you can specify custom selectors to fetch media data for the gallery\n * Pass \"this\" to select same element\n * You can also pass HTMLCollection directly\n * Example - '.my-selector' | '#my-selector' | this | document.querySelectorAll('.my-selector')\n */\n selector: string | HTMLCollection[];\n\n /**\n * By default selector element relative to the current gallery.\n * Instead of that you can tell lightGallery to select element relative to another element.\n * Example - '.my-selector-container' | '#my-selector-container'\n * In the code this become selector = document.querySelector(this.s.selectWithin ).querySelectorAll(this.s.selector);\n */\n selectWithin: string;\n\n /**\n * Custom html for next control\n */\n nextHtml: string;\n\n /**\n * Custom html for prev control\n */\n prevHtml: string;\n\n /**\n * specify which slide should load initially\n */\n index: number;\n\n /**\n * Set width for iframe.\n */\n iframeWidth: string;\n\n /**\n * Set height for iframe.\n */\n iframeHeight: string;\n\n /**\n * Set max width for iframe.\n */\n iframeMaxWidth: string;\n\n /**\n * Set max height for iframe.\n */\n iframeMaxHeight: string;\n\n /**\n * Enable download button.\n * @description By default download url will be taken from data-src/href attribute but it supports only for modern browsers.\n * If you want you can provide another url for download via data-download-url.\n * pass false in data-download-url if you want to hide download button for the particular slide.\n */\n download: boolean;\n\n /**\n * Whether to show total number of images and index number of currently displayed image.\n */\n counter: boolean;\n\n /**\n * Where the counter should be appended\n */\n appendCounterTo: string;\n\n /**\n * By setting the swipeThreshold (in px) you can set how far the user must swipe for the next/prev image.\n */\n swipeThreshold: number;\n\n /**\n * Release velocity (px/ms, measured over the gesture's final ~100ms)\n * at which a short swipe still changes slides, a flick.\n * @version V3.0.0\n */\n flickVelocity: number;\n\n /**\n * Pinching down on an un-zoomed image and releasing closes the\n * gallery (iOS Photos). Guarded: a pinch that went past fit zoom at\n * any point is a zoom correction and never closes. Requires\n * `closable` and the zoom plugin.\n * @version V3.0.0\n */\n pinchToClose: boolean;\n\n /**\n * Enables swipe support for touch devices\n */\n enableSwipe: boolean;\n\n /**\n * Enables desktop mouse drag support\n */\n enableDrag: boolean;\n\n /**\n * LightGallery can be instantiated and launched programmatically by setting this option to true and populating dynamicEl option (see below) with the definitions of images.\n */\n dynamic: boolean;\n\n /**\n * An array of objects (src, iframe, subHtml, thumb, poster, responsive, srcset sizes) representing gallery elements.\n */\n dynamicEl: GalleryItem[];\n\n /**\n * Fetch custom properties from the selector\n * @description this is useful for plugin development\n * By default lightGallery fetches and store all the props selectors to\n * reduce frequent dom interaction for fetching props every time.\n *\n * If you need any addition data to be fetched and stored in the galleryItems variable,\n * you can do this just by passing the prop names via extraProps\n * @example\n * HTML:\n * <div id=\"lightGallery\">\n * <a href=\"a.jpg\" data-custom-prop=\"abc\"><img src=\"thumb.jpg\" /></a>\n * <a href=\"a.jpg\" data-custom-prop=\"xyz\"><img src=\"thumb.jpg\" /></a>\n * </div>\n * JS:\n * lightGallery(document.getElementById('lightGallery'), {\n * extraProps: ['customProp']\n * })\n * // Note - If you are using dynamic mode, you can pass any custom prop in the galleryItem\n * lightGallery(document.getElementById('lightGallery'), {\n * dynamic: true,\n * dynamicEl: [{\n * src: 'img/img1.jpg',\n * customProp:'abc',\n * }]\n * })\n *\n */\n extraProps: string[];\n\n /**\n * Option to fetch different thumbnail image other than first image\n * @description If you want to use external image for thumbnail,\n * add the path of that image inside \"data-\" attribute\n * and set value of this option to the name of your custom attribute.\n *\n * @example\n * <div id=\"lightGallery\">\n * <a href=\"a.jpg\" data-external-thumb-image=\"images/externalThumb.jpg\" ><img src=\"thumb.jpg\" /></a>\n * </div>\n *\n * lightGallery(document.getElementById('lightGallery'), {\n * exThumbImage: 'data-external-thumb-image'\n * })\n */\n exThumbImage: string;\n\n /**\n * Function to detect mobile devices\n */\n isMobile?: () => boolean;\n\n /**\n * Separate settings for mobile devices\n * @description Note - this is applied only at the time of loading\n * by default controls and close buttons are disabled on mobile devices.\n * use this options if you want to enable them or change any other settings for mobile devices\n * Note - mobileSettings does not merge default values, You need to provide all mobileSettings including default values\n */\n mobileSettings: Partial<MobileSettings>;\n\n /**\n * Customize string.\n * @description This can be useful if you want to localize the lightGallery strings to other languages.\n * Use your own service to translate the strings and pass it via settings.strings\n * Every core and plugin label lives here; the per-plugin `*PluginStrings` objects are deprecated.\n * Strings merge per-key over the defaults, override only the keys\n * you need (the old provide-everything requirement is gone).\n * See <a href=\"/docs/localization-rtl/\">Localization &amp; RTL</a>.\n */\n strings: LightGalleryCoreStrings;\n\n /**\n * Custom icons: SVG markup per icon name, rendered instead of the\n * built-in SVG icon set, bring your own icons without touching CSS.\n * @description Omitted names keep the built-in icon. State-pair\n * buttons (`maximize`/`minimize`, `autoplayPlay`/`autoplayPause`,\n * `fullscreen`/`fullscreenExit`) need both names provided; a\n * half-provided pair keeps the built-in pair. Size and color follow\n * the button (`1em`/`currentColor`-friendly SVGs recommended).\n * See <a href=\"/docs/custom-icons/\">Custom icons</a>.\n * @version V3.0.0\n */\n icons: LgIcons;\n\n plugins: (new (instance: LightGallery, $LG: LgQuery) => any)[];\n}\n\nexport const lightGalleryCoreSettings: LightGalleryCoreSettings = {\n mode: 'lg-slide',\n easing: 'ease',\n speed: 400,\n licenseKey: '0000-0000-000-0000',\n height: '100%',\n width: '100%',\n addClass: '',\n startClass: 'lg-start-zoom',\n backdropDuration: 300,\n container: '',\n startAnimationDuration: 400,\n zoomFromOrigin: true,\n hideBarsDelay: 0,\n showBarsAfter: 10000,\n slideDelay: 0,\n allowMediaOverlap: false,\n videoMaxSize: '1280-720',\n loadYouTubePoster: true,\n defaultCaptionHeight: 0,\n ariaLabelledby: '',\n ariaDescribedby: '',\n ariaAnnouncements: true,\n resetScrollPosition: true,\n hideScrollbar: false,\n closable: true,\n swipeToClose: true,\n closeOnTap: true,\n showCloseIcon: true,\n showMaximizeIcon: false,\n loop: true,\n escKey: true,\n keyPress: true,\n trapFocus: true,\n controls: true,\n slideEndAnimation: true,\n hideControlOnEnd: false,\n mousewheel: false,\n direction: 'ltr',\n getCaptionFromTitleOrAlt: true,\n appendSubHtmlTo: '.lg-sub-html',\n subHtmlSelectorRelative: false,\n preload: 2,\n numberOfSlideItemsInDom: 10,\n selector: '',\n selectWithin: '',\n nextHtml: '',\n prevHtml: '',\n index: 0,\n iframeWidth: '100%',\n iframeHeight: '100%',\n iframeMaxWidth: '100%',\n iframeMaxHeight: '100%',\n download: true,\n counter: true,\n appendCounterTo: '.lg-toolbar',\n swipeThreshold: 50,\n flickVelocity: 0.5,\n pinchToClose: true,\n enableSwipe: true,\n enableDrag: true,\n dynamic: false,\n dynamicEl: [],\n extraProps: [],\n exThumbImage: '',\n toolbarOverflow: true,\n showGestureButtons: true,\n isMobile: undefined,\n mobileSettings: {\n controls: false,\n showCloseIcon: false,\n download: false,\n showGestureButtons: false,\n } as MobileSettings,\n plugins: [],\n strings: {\n closeGallery: 'Close gallery',\n toggleMaximize: 'Toggle maximize',\n previousSlide: 'Previous slide',\n nextSlide: 'Next slide',\n download: 'Download',\n playVideo: 'Play video',\n mediaLoadingFailed: 'Oops... Failed to load content...',\n galleryLabel: 'Gallery',\n slideAnnouncement: 'Image {index} of {total}',\n moreOptions: 'More options',\n share: 'Share',\n toggleThumbnails: 'Toggle thumbnails',\n toggleAutoplay: 'Toggle Autoplay',\n toggleFullscreen: 'Toggle Fullscreen',\n zoomIn: 'Zoom in',\n zoomOut: 'Zoom out',\n viewActualSize: 'View actual size',\n rotateLeft: 'Rotate left',\n rotateRight: 'Rotate right',\n flipHorizontal: 'Flip horizontal',\n flipVertical: 'Flip vertical',\n toggleComments: 'Toggle Comments',\n } as LightGalleryCoreStrings,\n icons: {},\n};\n","import {\n consumeBackdropPress,\n getToolbarItemPriority,\n getToolbarOverflow,\n} from '@lightgallery/headless';\n\nexport interface ToolbarOverflowOptions {\n /** Id of the More options button; the menu id derives from it. */\n id: string;\n /** Accessible name of the More options button and its menu. */\n label: string;\n}\n\nconst schedule: (callback: () => void) => number =\n typeof requestAnimationFrame === 'function'\n ? (callback) => requestAnimationFrame(callback)\n : (callback) => window.setTimeout(callback, 16);\nconst cancel: (handle: number) => void =\n typeof cancelAnimationFrame === 'function'\n ? (handle) => cancelAnimationFrame(handle)\n : (handle) => window.clearTimeout(handle);\n\n/**\n * The toolbar's own icon buttons in DOM order: not the More button, not\n * the menu's items or the share dropdown's links, and not icons nested\n * inside another button.\n */\nfunction toolbarButtons(toolbar: Element, more: Element): HTMLElement[] {\n return Array.from(toolbar.querySelectorAll<HTMLElement>('.lg-icon')).filter(\n (button) =>\n button !== more &&\n !button.closest('.lg-toolbar-menu, .lg-dropdown') &&\n !button.parentElement?.closest('.lg-icon'),\n );\n}\n\n/** The icon a button currently shows (state pairs render both). */\nfunction visibleIconMarkup(button: HTMLElement): string {\n const icons = Array.from(button.querySelectorAll<HTMLElement>('.lg-ci'));\n if (!icons.length) {\n return button.querySelector('svg')?.outerHTML ?? '';\n }\n const shown =\n icons.find(\n (icon) => window.getComputedStyle(icon).display !== 'none',\n ) ?? icons[0];\n return shown.outerHTML;\n}\n\n/**\n * Keeps the toolbar on one row: measures it, hides the buttons that do\n * not fit (`data-lg-overflow`) and lists them in a \"More options\" menu\n * whose items trigger the hidden buttons, so every plugin's handlers keep\n * working unchanged.\n */\nexport class ToolbarOverflow {\n private readonly more: HTMLButtonElement;\n private menu: HTMLElement | null = null;\n private frame = 0;\n private movedSignature = '';\n private readonly widths = new WeakMap<HTMLElement, number>();\n private readonly resizeObserver?: ResizeObserver;\n private readonly mutationObserver?: MutationObserver;\n\n constructor(\n private readonly toolbar: HTMLElement,\n private readonly options: ToolbarOverflowOptions,\n ) {\n const more = document.createElement('button');\n more.type = 'button';\n more.id = options.id;\n more.className = 'lg-more lg-icon';\n more.hidden = true;\n more.setAttribute('aria-label', options.label);\n more.setAttribute('aria-haspopup', 'menu');\n more.setAttribute('aria-expanded', 'false');\n more.addEventListener('click', this.onMoreClick);\n // Right after the close button, so it sits beside it in the row.\n const close = toolbar.querySelector('.lg-close');\n if (close) {\n close.insertAdjacentElement('afterend', more);\n } else {\n toolbar.insertBefore(more, toolbar.firstChild);\n }\n this.more = more;\n\n if (typeof ResizeObserver === 'function') {\n this.resizeObserver = new ResizeObserver(this.requestUpdate);\n this.resizeObserver.observe(toolbar);\n }\n if (typeof MutationObserver === 'function') {\n this.mutationObserver = new MutationObserver((records) => {\n // The menu's own re-renders do not change the row.\n if (\n records.some(\n (record) =>\n !(record.target as Element).closest?.(\n '.lg-toolbar-menu',\n ),\n )\n ) {\n this.requestUpdate();\n }\n });\n this.mutationObserver.observe(toolbar, {\n childList: true,\n subtree: true,\n });\n }\n }\n\n /** Re-measure the row and move buttons in or out of the menu. */\n update(): void {\n const buttons = toolbarButtons(this.toolbar, this.more);\n buttons.forEach((button) => {\n if (!button.hasAttribute('data-lg-overflow')) {\n const width = button.offsetWidth;\n if (width) {\n this.widths.set(button, width);\n }\n }\n });\n const fallback =\n buttons\n .map((button) => this.widths.get(button))\n .find((width) => !!width) ?? 0;\n const counter = this.toolbar.querySelector<HTMLElement>('.lg-counter');\n\n const moved = getToolbarOverflow({\n available: this.toolbar.clientWidth,\n reserved: counter ? counter.offsetWidth : 0,\n moreWidth: this.widths.get(this.more) ?? fallback,\n items: buttons.map((button) => ({\n width: this.widths.get(button) ?? fallback,\n priority: getToolbarItemPriority(Array.from(button.classList)),\n })),\n });\n const overflow = new Set(moved);\n buttons.forEach((button, index) => {\n if (overflow.has(index)) {\n button.setAttribute('data-lg-overflow', '');\n } else {\n button.removeAttribute('data-lg-overflow');\n }\n });\n this.more.hidden = overflow.size === 0;\n if (!this.more.hidden && this.more.offsetWidth) {\n this.widths.set(this.more, this.more.offsetWidth);\n }\n const signature = `${buttons.length}:${moved.join(',')}`;\n const changed = signature !== this.movedSignature;\n this.movedSignature = signature;\n if (!overflow.size) {\n this.close(false);\n } else if (this.menu && changed) {\n this.renderMenu();\n }\n }\n\n /** Close the menu; optionally hand focus back to the More button. */\n close(returnFocus: boolean): void {\n if (!this.menu) {\n return;\n }\n this.menu.removeEventListener('keydown', this.onMenuKeydown);\n this.menu.remove();\n this.menu = null;\n document.removeEventListener(\n 'pointerdown',\n this.onDocumentPointerDown,\n true,\n );\n this.more.setAttribute('aria-expanded', 'false');\n this.more.removeAttribute('aria-controls');\n if (returnFocus) {\n this.more.focus();\n }\n }\n\n destroy(): void {\n this.close(false);\n cancel(this.frame);\n this.resizeObserver?.disconnect();\n this.mutationObserver?.disconnect();\n toolbarButtons(this.toolbar, this.more).forEach((button) =>\n button.removeAttribute('data-lg-overflow'),\n );\n this.more.remove();\n }\n\n private readonly requestUpdate = (): void => {\n if (this.frame) {\n return;\n }\n this.frame = schedule(() => {\n this.frame = 0;\n this.update();\n });\n };\n\n private readonly onMoreClick = (): void => {\n if (this.menu) {\n this.close(true);\n } else {\n this.open();\n }\n };\n\n private open(): void {\n const menu = document.createElement('div');\n menu.id = `${this.options.id}-menu`;\n menu.className = 'lg-toolbar-menu';\n menu.setAttribute('role', 'menu');\n menu.setAttribute('aria-label', this.options.label);\n menu.addEventListener('keydown', this.onMenuKeydown);\n this.menu = menu;\n this.renderMenu();\n this.toolbar.appendChild(menu);\n this.more.setAttribute('aria-expanded', 'true');\n this.more.setAttribute('aria-controls', menu.id);\n document.addEventListener(\n 'pointerdown',\n this.onDocumentPointerDown,\n true,\n );\n this.items()[0]?.focus();\n }\n\n private renderMenu(): void {\n const menu = this.menu;\n if (!menu) {\n return;\n }\n menu.textContent = '';\n toolbarButtons(this.toolbar, this.more)\n .filter((button) => button.hasAttribute('data-lg-overflow'))\n .forEach((button) => {\n const item = document.createElement('button');\n item.type = 'button';\n item.className = 'lg-toolbar-menu-item';\n item.setAttribute('role', 'menuitem');\n const icon = document.createElement('span');\n icon.className = 'lg-toolbar-menu-icon';\n icon.setAttribute('aria-hidden', 'true');\n icon.innerHTML = visibleIconMarkup(button);\n const label = document.createElement('span');\n label.textContent = button.getAttribute('aria-label') ?? '';\n item.append(icon, label);\n item.addEventListener('click', () => {\n this.close(true);\n button.click();\n });\n menu.appendChild(item);\n });\n }\n\n private items(): HTMLElement[] {\n return this.menu\n ? Array.from(\n this.menu.querySelectorAll<HTMLElement>('[role=\"menuitem\"]'),\n )\n : [];\n }\n\n private readonly onMenuKeydown = (event: KeyboardEvent): void => {\n const items = this.items();\n const index = items.indexOf(document.activeElement as HTMLElement);\n switch (event.key) {\n case 'Escape':\n this.close(true);\n break;\n case 'ArrowDown':\n items[(index + 1) % items.length]?.focus();\n break;\n case 'ArrowUp':\n items[(index - 1 + items.length) % items.length]?.focus();\n break;\n case 'Home':\n items[0]?.focus();\n break;\n case 'End':\n items[items.length - 1]?.focus();\n break;\n case 'ArrowLeft':\n case 'ArrowRight':\n // Keep the gallery from changing slides behind the menu.\n break;\n case 'Tab':\n this.close(false);\n return;\n default:\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n };\n\n private readonly onDocumentPointerDown = (event: Event): void => {\n const target = event.target as Node | null;\n if (\n target &&\n (this.menu?.contains(target) || this.more.contains(target))\n ) {\n return;\n }\n consumeBackdropPress(event);\n this.close(false);\n };\n}\n","/**\n * Icon injection: the gallery's icons are inline SVG strings, built-in\n * defaults (registered by the core and by each plugin, so a plugin's\n * icons ship in its own bundle) merged under the consumer's\n * `settings.icons` overrides. One generic pass over the built structure,\n * every icon button (core and plugins alike) is an empty classed element\n * by the end of `buildStructure`, so a name→selector table covers them\n * all without touching the individual templates.\n *\n * State-pair buttons (maximize/minimize, autoplay play/pause, fullscreen\n * enter/exit) render BOTH icons of the pair; state classes (`lg-inline`,\n * `lg-show-autoplay`, `lg-fullscreen-on`) toggle their visibility in\n * CSS. A consumer override applies only when it answers every name of a\n * pair, a half-provided pair keeps the defaults so no state ends up\n * iconless.\n */\n\nimport type { LgIconName } from '@lightgallery/headless';\n\nexport type { LgIconName };\n\n/** SVG markup per icon; omitted names keep the built-in glyph. */\nexport type LgIcons = Partial<Record<LgIconName, string>>;\n\ninterface IconTarget {\n /** Selector within the gallery container. */\n selector: string;\n /** One name, or a state pair in [default-state, active-state] order. */\n names: LgIconName[];\n}\n\n// The dropdown lives INSIDE the share button, and future markup may nest\n// too, injection always PREPENDS, never replaces the element's HTML.\nconst ICON_TARGETS: IconTarget[] = [\n { selector: '.lg-close', names: ['close'] },\n { selector: '.lg-prev', names: ['prev'] },\n { selector: '.lg-next', names: ['next'] },\n { selector: '.lg-download', names: ['download'] },\n { selector: '.lg-more', names: ['more'] },\n // Shown while `.lg-inline` (prompting maximize) / after maximizing.\n { selector: '.lg-maximize', names: ['maximize', 'minimize'] },\n // The actual-size button's CLASS toggles between the two zoom\n // classes as the zoom state changes (2.x swapped the glyph that\n // way), it carries BOTH zoom icons and the class picks one in\n // CSS. Listed before the class-based zoom targets so the id match\n // claims it first (the pass skips already-processed elements).\n { selector: '[id^=\"lg-actual-size-\"]', names: ['zoomIn', 'zoomOut'] },\n { selector: '.lg-zoom-in', names: ['zoomIn'] },\n { selector: '.lg-zoom-out', names: ['zoomOut'] },\n // No '.lg-actual-size' target: vanilla's actual-size BUTTON never\n // carries that class (it rides the zoom classes above; the outer\n // gets `lg-actual-size` as a zoom-state class after build). The\n // `actualSize` name serves the framework ports' static button.\n { selector: '.lg-rotate-left', names: ['rotateLeft'] },\n { selector: '.lg-rotate-right', names: ['rotateRight'] },\n { selector: '.lg-flip-hor', names: ['flipHorizontal'] },\n { selector: '.lg-flip-ver', names: ['flipVertical'] },\n { selector: '.lg-share', names: ['share'] },\n { selector: '.lg-share-facebook .lg-icon', names: ['shareFacebook'] },\n { selector: '.lg-share-twitter .lg-icon', names: ['shareX'] },\n { selector: '.lg-share-pinterest .lg-icon', names: ['sharePinterest'] },\n // Shown while idle (prompting play) / while `.lg-show-autoplay`.\n {\n selector: '.lg-autoplay-button',\n names: ['autoplayPlay', 'autoplayPause'],\n },\n // Shown while windowed / while `.lg-fullscreen-on`.\n { selector: '.lg-fullscreen', names: ['fullscreen', 'fullscreenExit'] },\n { selector: '.lg-comment-toggle', names: ['comment'] },\n { selector: '.lg-comment-close', names: ['commentClose'] },\n { selector: '.lg-toggle-thumb', names: ['toggleThumbnails'] },\n];\n\nconst toKebab = (name: string): string =>\n name.replace(/[A-Z]/g, (char) => `-${char.toLowerCase()}`);\n\n/** `<span class=\"lg-ci lg-ci-<kebab-name>\">svg</span>` wrapper markup. */\nfunction getCustomIconMarkup(icons: LgIcons, names: LgIconName[]): string {\n if (!names.every((name) => icons[name])) {\n return '';\n }\n return names\n .map(\n (name) =>\n `<span class=\"lg-ci lg-ci-${toKebab(\n name,\n )}\" aria-hidden=\"true\">${icons[name]}</span>`,\n )\n .join('');\n}\n\n/**\n * Inject the gallery's icons into the built structure: per target, the\n * consumer's overrides apply when they answer every name (pairs must be\n * complete), else the registered defaults render. Elements keep their\n * classes and listeners, the icons are prepended children.\n */\nexport function applyCustomIcons(\n container: HTMLElement,\n defaults: LgIcons,\n overrides: LgIcons | undefined,\n): void {\n ICON_TARGETS.forEach(({ selector, names }) => {\n const source =\n overrides && names.every((name) => overrides[name])\n ? overrides\n : defaults;\n const markup = getCustomIconMarkup(source, names);\n if (!markup) {\n return;\n }\n container.querySelectorAll(selector).forEach((element) => {\n if (element.classList.contains('lg-icon-custom')) {\n return;\n }\n element.classList.add('lg-icon-custom');\n element.insertAdjacentHTML('afterbegin', markup);\n });\n });\n}\n","import {\n isSpringSettled,\n stepSpring,\n type SpringConfig,\n type SpringState,\n} from '@lightgallery/headless';\n\n/**\n * rAF driver for the shared spring math: advances one spring per track\n * each frame and hands the values to the caller's DOM writer. The math\n * (and therefore the feel) lives in @lightgallery/headless; this file\n * only owns scheduling.\n */\n\nexport interface SpringTrack extends SpringConfig {\n from: number;\n /** Seed velocity, px/ms, the gesture's windowed release velocity. */\n velocity: number;\n target: number;\n}\n\n/** Frame gap clamp so a background-tab pause cannot teleport a spring. */\nconst MAX_FRAME_MS = 64;\n\nexport function runSprings(\n tracks: SpringTrack[],\n onFrame: (values: number[]) => void,\n onDone?: () => void,\n): () => void {\n let raf = 0;\n let last = Date.now();\n const states: SpringState[] = tracks.map((t) => ({\n position: t.from,\n velocity: t.velocity,\n }));\n const frame = () => {\n // Date.now over the rAF timestamp: one clock for seeding and\n // stepping (and the one fake timers drive in tests). Clamp into\n // [0, MAX]: a paused tab cannot teleport the spring and a\n // non-monotonic reading cannot blow it up (negative dt turns\n // the decay exponential).\n const now = Date.now();\n const dt = Math.min(Math.max(now - last, 0), MAX_FRAME_MS);\n last = now;\n let settled = true;\n tracks.forEach((t, i) => {\n states[i] = stepSpring(states[i], t.target, dt, t);\n if (!isSpringSettled(states[i], t.target)) {\n settled = false;\n }\n });\n if (settled) {\n onFrame(tracks.map((t) => t.target));\n onDone?.();\n return;\n }\n onFrame(states.map((s) => s.position));\n raf = requestAnimationFrame(frame);\n };\n raf = requestAnimationFrame(frame);\n return () => cancelAnimationFrame(raf);\n}\n","interface Offset {\n left: number;\n top: number;\n}\n\nexport type LgQuery = (selector: any) => lgQuery;\nexport class lgQuery {\n static eventListeners: { [key: string]: any[] } = {};\n static generateUUID(): string {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(\n /[xy]/g,\n function (c) {\n const r = (Math.random() * 16) | 0,\n v = c == 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n },\n );\n }\n\n private selector: any;\n private firstElement: any;\n private cssVenderPrefixes: string[] = [\n 'TransitionDuration',\n 'TransitionTimingFunction',\n 'Transform',\n 'Transition',\n ];\n constructor(selector: string | Element) {\n this.selector = this._getSelector(selector);\n this.firstElement = this._getFirstEl();\n return this;\n }\n\n private _getSelector(\n selector: string | Element,\n context: Element | Document = document,\n ): Element | null | NodeListOf<Element> {\n if (typeof selector !== 'string') {\n return selector;\n }\n context = context || document;\n const fl = selector.substring(0, 1);\n if (fl === '#') {\n return context.querySelector(selector);\n } else {\n return context.querySelectorAll(selector);\n }\n }\n\n private _each(\n func: (\n elements: Element | NodeListOf<Element> | null,\n index: number,\n ) => void,\n ): this {\n if (!this.selector) {\n return this;\n }\n if (this.selector.length !== undefined) {\n [].forEach.call(this.selector, func);\n } else {\n func(this.selector, 0);\n }\n return this;\n }\n\n private _setCssVendorPrefix(\n el: any,\n cssProperty: string,\n value?: string | number,\n ): void {\n // Custom properties are case sensitive and never vendor prefixed,\n // and `style[name]` silently drops them.\n if (cssProperty.startsWith('--')) {\n el.style.setProperty(cssProperty, String(value));\n return;\n }\n // prettier-ignore\n const property = cssProperty.replace(/-([a-z])/gi, function (\n s,\n group1,\n ) {\n return group1.toUpperCase();\n });\n if (this.cssVenderPrefixes.indexOf(property) !== -1) {\n el.style[property.charAt(0).toLowerCase() + property.slice(1)] =\n value;\n el.style['webkit' + property] = value;\n el.style['moz' + property] = value;\n el.style['ms' + property] = value;\n el.style['o' + property] = value;\n } else {\n el.style[property] = value;\n }\n }\n\n private _getFirstEl() {\n if (this.selector && this.selector.length !== undefined) {\n return this.selector[0];\n } else {\n return this.selector;\n }\n }\n\n private isEventMatched(event: string, eventName: string): boolean {\n const eventNamespace = eventName.split('.');\n return event\n .split('.')\n .filter((e) => e)\n .every((e) => {\n return eventNamespace.indexOf(e) !== -1;\n });\n }\n\n attr(attr: string): string;\n attr(attr: string, value: string | number | boolean): this;\n attr(attr: string, value?: string | number | boolean): string | this {\n if (value === undefined) {\n if (!this.firstElement) {\n return '';\n }\n return this.firstElement.getAttribute(attr);\n }\n this._each((el: any) => {\n el.setAttribute(attr, value);\n });\n return this;\n }\n\n find(selector: any): lgQuery {\n return $LG(this._getSelector(selector, this.selector));\n }\n\n first(): lgQuery {\n if (this.selector && this.selector.length !== undefined) {\n return $LG(this.selector[0]);\n } else {\n return $LG(this.selector);\n }\n }\n\n eq(index: number): lgQuery {\n return $LG(this.selector[index]);\n }\n\n parent(): lgQuery {\n return $LG(this.selector.parentElement);\n }\n\n get(): HTMLElement {\n return this._getFirstEl();\n }\n\n removeAttr(attributes: string): this {\n const attrs = attributes.split(' ');\n this._each((el: any) => {\n attrs.forEach((attr: string) => el.removeAttribute(attr));\n });\n return this;\n }\n\n wrap(className: string): this {\n if (!this.firstElement) {\n return this;\n }\n const wrapper = document.createElement('div');\n wrapper.className = className;\n this.firstElement.parentNode.insertBefore(wrapper, this.firstElement);\n this.firstElement.parentNode.removeChild(this.firstElement);\n wrapper.appendChild(this.firstElement);\n return this;\n }\n\n addClass(classNames = ''): this {\n this._each((el: any) => {\n // IE doesn't support multiple arguments\n classNames.split(' ').forEach((className) => {\n if (className) {\n el.classList.add(className);\n }\n });\n });\n return this;\n }\n\n removeClass(classNames: string): this {\n this._each((el: any) => {\n // IE doesn't support multiple arguments\n classNames.split(' ').forEach((className) => {\n if (className) {\n el.classList.remove(className);\n }\n });\n });\n return this;\n }\n\n hasClass(className: string): boolean {\n if (!this.firstElement) {\n return false;\n }\n return this.firstElement.classList.contains(className);\n }\n hasAttribute(attribute: string): boolean {\n if (!this.firstElement) {\n return false;\n }\n return this.firstElement.hasAttribute(attribute);\n }\n toggleClass(className: string): this {\n if (!this.firstElement) {\n return this;\n }\n if (this.hasClass(className)) {\n this.removeClass(className);\n } else {\n this.addClass(className);\n }\n return this;\n }\n\n css(property: string, value?: string | number): this {\n this._each((el: any) => {\n this._setCssVendorPrefix(el, property, value);\n });\n return this;\n }\n // Need to pass separate namespaces for separate elements\n on(events: string, listener: (e: any) => void): this {\n if (!this.selector) {\n return this;\n }\n events.split(' ').forEach((event: string) => {\n if (!Array.isArray(lgQuery.eventListeners[event])) {\n lgQuery.eventListeners[event] = [];\n }\n lgQuery.eventListeners[event].push(listener);\n this.selector.addEventListener(event.split('.')[0], listener);\n });\n\n return this;\n }\n // @todo - test this\n once(event: string, listener: (e: any) => void): this {\n this.on(event, () => {\n this.off(event);\n listener(event);\n });\n return this;\n }\n off(event: string): this {\n if (!this.selector) {\n return this;\n }\n Object.keys(lgQuery.eventListeners).forEach((eventName) => {\n if (this.isEventMatched(event, eventName)) {\n lgQuery.eventListeners[eventName].forEach((listener) => {\n this.selector.removeEventListener(\n eventName.split('.')[0],\n listener,\n );\n });\n lgQuery.eventListeners[eventName] = [];\n }\n });\n\n return this;\n }\n trigger<Detail>(event: string, detail?: Detail): this {\n if (!this.firstElement) {\n return this;\n }\n\n const customEvent = new CustomEvent(event.split('.')[0], {\n detail: detail || null,\n });\n this.firstElement.dispatchEvent(customEvent);\n return this;\n }\n\n // Does not support IE\n load(url: string): this {\n fetch(url)\n .then((res) => res.text())\n .then((html) => {\n this.selector.innerHTML = html;\n });\n return this;\n }\n\n html(): string;\n html(html: string): this;\n html(html?: string): string | this {\n if (html === undefined) {\n if (!this.firstElement) {\n return '';\n }\n return this.firstElement.innerHTML;\n }\n this._each((el: any) => {\n el.innerHTML = html;\n });\n return this;\n }\n append(html: string | HTMLElement): this {\n this._each((el: any) => {\n if (typeof html === 'string') {\n el.insertAdjacentHTML('beforeend', html);\n } else {\n el.appendChild(html);\n }\n });\n return this;\n }\n prepend(html: string | HTMLElement): this {\n this._each((el: any) => {\n if (typeof html === 'string') {\n el.insertAdjacentHTML('afterbegin', html);\n } else if (html instanceof HTMLElement) {\n el.insertBefore(html.cloneNode(true), el.firstChild);\n }\n });\n return this;\n }\n remove(): this {\n this._each((el: any) => {\n el.parentNode.removeChild(el);\n });\n return this;\n }\n empty(): this {\n this._each((el: any) => {\n el.innerHTML = '';\n });\n return this;\n }\n // Supports only window\n scrollTop(): number;\n scrollTop(scrollTop: number): this;\n scrollTop(scrollTop?: number): number | this {\n if (scrollTop !== undefined) {\n window.scrollTo(window.scrollX, scrollTop);\n return this;\n } else {\n return window.scrollY;\n }\n }\n // Supports only window\n scrollLeft(): number;\n scrollLeft(scrollLeft?: number): this;\n scrollLeft(scrollLeft?: number): number | this {\n if (scrollLeft !== undefined) {\n window.scrollTo(scrollLeft, window.scrollY);\n return this;\n } else {\n return window.scrollX;\n }\n }\n offset(): Offset {\n if (!this.firstElement) {\n return {\n left: 0,\n top: 0,\n };\n }\n const rect = this.firstElement.getBoundingClientRect();\n const bodyMarginLeft = $LG('body').style().marginLeft;\n\n // Minus body margin - https://stackoverflow.com/questions/30711548/is-getboundingclientrect-left-returning-a-wrong-value\n return {\n left: rect.left - parseFloat(bodyMarginLeft) + this.scrollLeft(),\n top: rect.top + this.scrollTop(),\n };\n }\n style(): CSSStyleDeclaration {\n if (!this.firstElement) {\n return {} as CSSStyleDeclaration;\n }\n return (\n this.firstElement.currentStyle ||\n window.getComputedStyle(this.firstElement)\n );\n }\n // Width without padding and border even if box-sizing is used.\n width(): number {\n const style = this.style();\n return (\n this.firstElement.clientWidth -\n parseFloat(style.paddingLeft) -\n parseFloat(style.paddingRight)\n );\n }\n // Height without padding and border even if box-sizing is used.\n height(): number {\n const style = this.style();\n return (\n this.firstElement.clientHeight -\n parseFloat(style.paddingTop) -\n parseFloat(style.paddingBottom)\n );\n }\n}\n\nexport function $LG(selector: any): lgQuery {\n return new lgQuery(selector);\n}\n","import {\n fitImageSize,\n getOriginTransform,\n isUsableOriginRect,\n getVideoInfo,\n parseImageSize,\n} from '@lightgallery/headless';\n\nimport { $LG, lgQuery } from './lgQuery';\nimport { VideoSource } from './plugins/video/types';\nimport { VideoInfo } from './types';\n\nexport interface ImageSize {\n width: number;\n height: number;\n}\n\nexport interface ImageSources {\n media?: string;\n srcset: string;\n sizes?: string;\n type?: string;\n}\n\nexport interface GalleryItem {\n /**\n * url of the media\n * @data-attr data-src\n */\n src?: string;\n\n /**\n * Source attributes for the <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/source#attributes\">picture</a> element\n * @data-attr data-sources\n */\n sources?: ImageSources[];\n\n /**\n * Thumbnail url\n * @description By default lightGallery uses the image inside gallery selector as thumbnail.\n * But, If you want to use external image for thumbnail,\n * pass the thumbnail url via any data attribute and\n * pass the attribute name via exThumbImage option\n * @example\n * <div id=\"lightGallery\">\n * <a href=\"a.jpg\" data-external-thumb-image=\"images/externalThumb.jpg\" ><img src=\"thumb.jpg\" /></a>\n * </div>\n *\n * lightGallery(document.getElementById('lightGallery'), {\n * exThumbImage: 'data-external-thumb-image'\n * })\n * @data-attr data-*\n */\n thumb?: string;\n\n /**\n * alt attribute for the image\n * @data-attr alt\n */\n alt?: string;\n\n /**\n * Title attribute for the video\n * @data-attr title\n */\n title?: string;\n\n /**\n * Title for iframe\n * @data-attr data-iframe-title\n */\n iframeTitle?: string;\n\n /**\n * Caption for the slide\n * @description You can either pass the HTML markup or the ID or class name of the element which contains the captions\n * @data-attr data-sub-html\n */\n subHtml?: string;\n\n /**\n * url of the file which contain the sub html.\n * @description Note - Does not support Internet Explorer browser\n * @data-attr data-sub-html-url\n */\n subHtmlUrl?: string;\n\n /**\n * Video source\n * @data-attr data-video\n */\n video?: VideoSource;\n\n /**\n * Poster url\n * @data-attr data-poster\n */\n poster?: string;\n\n /**\n * Custom slide name to use in the url when hash plugin is enabled\n * @data-attr data-slide-name\n */\n slideName?: string;\n\n /**\n * List of images and viewport's max width separated by comma.\n * @description Ex?: img/1-375.jpg 375, img/1-480.jpg 480, img/1-757.jpg 757.\n * @data-attr data-responsive\n */\n responsive?: string;\n\n /**\n * srcset attribute values for the main image\n * @data-attr data-srcset\n */\n srcset?: string;\n\n /**\n * srcset sizes attribute for the main image\n * @data-attr data-sizes\n */\n sizes?: string;\n\n /**\n * Set true is you want to open your url in an iframe\n * @data-attr data-iframe\n */\n iframe?: boolean;\n\n /**\n * Download url for your image/video.\n * @description Pass false if you want to disable the download button.\n * @data-attr data-download-url\n */\n downloadUrl?: string | boolean;\n\n /**\n * Name of the file after it is downloaded.\n * @description The HTML value of the download attribute.\n * There are no restrictions on allowed values, and the browser will automatically\n * detect the correct file extension and add it to the file (.img, .pdf, .txt, .html, etc.).\n * <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-download\">More info</a>\n * @data-attr data-download\n */\n download?: string | boolean;\n\n /**\n * Actual size of the image in px.\n * @description This is used in zoom plugin to see the actual size of the image when double taped on the image.\n * @data-attr data-width\n */\n width?: string;\n\n /**\n * Canonical share URL for the native share sheet (Web Share API).\n * @description Specify only if you want a separate URL for the specific\n * slide. Falls back to the network-specific share URLs, then the current\n * browser URL.\n * @data-attr data-share-url\n */\n shareUrl?: string;\n\n /**\n * Facebook share URL.\n * @description Specify only if you want to provide separate share URL for the specific slide. By default, current browser URL is taken.\n * @data-attr data-facebook-share-url\n */\n facebookShareUrl?: string;\n\n /**\n * Tweet text\n * @data-attr data-tweet-text\n */\n tweetText?: string;\n\n /**\n * Twitter share URL.\n * @description Specify only if you want to provide separate share URL for the specific slide. By default, current browser URL will be taken.\n * @data-attr data-twitter-share-url\n */\n twitterShareUrl?: string;\n\n /**\n * Pinterest share URL.\n * @description Specify only if you want to provide separate share URL for the specific slide. By default, current browser URL will be taken.\n * Note?: Pinterest requires absolute URL\n * @data-attr data-pinterest-share-url\n */\n pinterestShareUrl?: string;\n\n /**\n * Description for Pinterest post.\n * @data-attr data-pinterest-text\n */\n pinterestText?: string;\n\n /**\n * Facebook comments body html\n * @description Please refer <a href=\"https://developers.facebook.com/docs/plugins/comments/#comments-plugin\">facebook official documentation</a> for generating the HTML markup\n * @example\n * <div\n * class=\"fb-comments\"\n * data-href=\"https://www.example.com/your-page/#lg=1&slide=0\"\n * data-width=\"400\"\n * data-numposts=\"5\">\n * </div>\n * @data-attr data-fb-html\n */\n fbHtml?: string;\n\n /**\n * Disqus page identifier\n * @description Please refer official <a href=\"https://help.disqus.com/en/articles/1717084-javascript-configuration-variables\">disqus documentation</a> for more info\n * @data-attr data-disqus-identifier\n */\n disqusIdentifier?: string;\n\n /**\n * Disqus page url\n * @description Please refer official <a href=\"https://help.disqus.com/en/articles/1717084-javascript-configuration-variables\">disqus documentation</a> for more info\n * @data-attr data-disqus-url\n */\n disqusUrl?: string;\n\n __slideVideoInfo?: VideoInfo;\n [key: string]: any;\n}\n\nconst defaultDynamicOptions = [\n 'src',\n 'sources',\n 'subHtml',\n 'subHtmlUrl',\n 'html',\n 'video',\n 'poster',\n 'slideName',\n 'responsive',\n 'srcset',\n 'sizes',\n 'iframe',\n 'downloadUrl',\n 'download',\n 'width',\n 'shareUrl',\n 'facebookShareUrl',\n 'tweetText',\n 'iframeTitle',\n 'twitterShareUrl',\n 'pinterestShareUrl',\n 'pinterestText',\n 'fbHtml',\n 'disqusIdentifier',\n 'disqusUrl',\n];\n\n// Convert html data-attribute to camalcase\nexport function convertToData(attr: string): string {\n // FInd a way for lgsize\n if (attr === 'href') {\n return 'src';\n }\n attr = attr.replace('data-', '');\n attr = attr.charAt(0).toLowerCase() + attr.slice(1);\n attr = attr.replace(/-([a-z])/g, (g) => g[1].toUpperCase());\n\n return attr;\n}\n\nconst utils = {\n /**\n * Fetches HTML content from a given URL and inserts it into a specified element.\n *\n * @param url - The URL to fetch the HTML content from.\n * @param element - The DOM element (jQuery object) to insert the HTML content into.\n * @param insertMethod - The method to insert the HTML ('append' or 'replace').\n */\n fetchCaptionFromUrl(\n url: string,\n element: lgQuery,\n insertMethod: 'append' | 'replace',\n ): void {\n // Fetch content from the URL\n fetch(url)\n .then((response) => response.text())\n .then((htmlContent) => {\n if (insertMethod === 'append') {\n const contentDiv = `<div class=\"lg-sub-html\">${htmlContent}</div>`;\n element.append(contentDiv);\n } else {\n element.html(htmlContent);\n }\n });\n },\n /**\n * get possible width and height from the lgSize attribute. Used for ZoomFromOrigin option\n */\n getSize(\n el: HTMLElement,\n container: lgQuery,\n spacing = 0,\n defaultLgSize?: string,\n ): ImageSize | undefined {\n const LGel = $LG(el);\n const lgSize = LGel.attr('data-lg-size') || defaultLgSize;\n\n const parsed = parseImageSize(lgSize, window.innerWidth);\n if (!parsed) {\n return;\n }\n\n return fitImageSize(\n parsed,\n container.width(),\n container.height() - spacing,\n );\n },\n\n /**\n * @desc Get transform value based on the imageSize. Used for ZoomFromOrigin option\n * @param {jQuery Element}\n * @returns {String} Transform CSS string\n */\n getTransform(\n el: HTMLElement,\n container: lgQuery,\n top: number,\n bottom: number,\n imageSize?: ImageSize,\n ): string | undefined {\n // Degenerate measurement (zero-sized/hidden viewport, offsets\n // taller than the stage): the shared math would emit a mirrored\n // flight, fall back to the startClass fade instead (the sibling\n // bindings guard the same way).\n if (!imageSize || imageSize.width <= 0 || imageSize.height <= 0) {\n return;\n }\n const LGel = $LG(el).find('img').first();\n if (!LGel.get()) {\n return;\n }\n\n const containerRect = container.get().getBoundingClientRect();\n\n // Viewport coords straight from the rect. `offset()` folds in a\n // body-margin correction that shifts the origin on any centered\n // body (`margin: auto`), the long-standing \"flight starts beside\n // the thumbnail\" bug, and the old padding/border terms adjusted\n // in the wrong direction on styled thumbnails.\n const rect = LGel.get().getBoundingClientRect();\n const triggerRect = {\n left: rect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height,\n };\n // A hidden or collapsed trigger (a collage's overflow items behind\n // a \"+N photos\" tile) measures 0×0 at the viewport origin: no\n // flight, the caller falls back to the centred animation.\n if (!isUsableOriginRect(triggerRect)) {\n return;\n }\n\n return getOriginTransform({\n triggerRect,\n containerRect: {\n left: containerRect.left,\n top: containerRect.top,\n width: containerRect.width,\n // Element height, not rect height, includes the mobile\n // safari bottom bar handling this always had.\n height: container.height(),\n },\n top,\n bottom,\n imageSize,\n });\n },\n\n getIframeMarkup(\n iframeWidth: string,\n iframeHeight: string,\n iframeMaxWidth: string,\n iframeMaxHeight: string,\n src?: string,\n iframeTitle?: string,\n ): string {\n const title = iframeTitle ? 'title=\"' + iframeTitle + '\"' : '';\n return `<div class=\"lg-media-cont lg-has-iframe\" style=\"width:${iframeWidth}; max-width:${iframeMaxWidth}; height: ${iframeHeight}; max-height:${iframeMaxHeight}\">\n <iframe class=\"lg-object\" frameborder=\"0\" ${title} src=\"${src}\" allowfullscreen=\"true\"></iframe>\n </div>`;\n },\n\n getImgMarkup(\n index: number,\n src: string,\n altAttr: string,\n srcset?: string,\n sizes?: string,\n sources?: ImageSources[],\n ): string {\n const srcsetAttr = srcset ? `srcset=\"${srcset}\"` : '';\n const sizesAttr = sizes ? `sizes=\"${sizes}\"` : '';\n const imgMarkup = `<img ${altAttr} ${srcsetAttr} ${sizesAttr} class=\"lg-object lg-image\" data-index=\"${index}\" src=\"${src}\" />`;\n let sourceTag = '';\n if (sources) {\n const sourceObj =\n typeof sources === 'string' ? JSON.parse(sources) : sources;\n\n sourceTag = sourceObj.map((source: any) => {\n let attrs = '';\n Object.keys(source).forEach((key) => {\n // Do not remove the first space as it is required to separate the attributes\n attrs += ` ${key}=\"${source[key]}\"`;\n });\n return `<source ${attrs}></source>`;\n });\n }\n return `${sourceTag}${imgMarkup}`;\n },\n\n // Get src from responsive src\n getResponsiveSrc(srcItms: string[]): string {\n const rsWidth = [];\n const rsSrc = [];\n let src = '';\n for (let i = 0; i < srcItms.length; i++) {\n const _src = srcItms[i].split(' ');\n\n // Manage empty space\n if (_src[0] === '') {\n _src.splice(0, 1);\n }\n\n rsSrc.push(_src[0]);\n rsWidth.push(_src[1]);\n }\n\n const wWidth = window.innerWidth;\n for (let j = 0; j < rsWidth.length; j++) {\n if (parseInt(rsWidth[j], 10) > wWidth) {\n src = rsSrc[j];\n break;\n }\n }\n return src;\n },\n\n isImageLoaded(img: HTMLImageElement): boolean {\n if (!img) return false;\n // During the onload event, IE correctly identifies any images that\n // weren’t downloaded as not complete. Others should too. Gecko-based\n // browsers act like NS4 in that they report this incorrectly.\n if (!img.complete) {\n return false;\n }\n\n // However, they do have two very useful properties: naturalWidth and\n // naturalHeight. These give the true size of the image. If it failed\n // to load, either of these should be zero.\n if (img.naturalWidth === 0) {\n return false;\n }\n\n // No other way of checking: assume it’s ok.\n return true;\n },\n\n getVideoPosterMarkup(\n _poster: string,\n dummyImg: string | HTMLElement,\n videoContStyle: string,\n playVideoString: string,\n _isVideo?: VideoInfo,\n ): string {\n let videoClass = '';\n if (_isVideo && _isVideo.youtube) {\n videoClass = 'lg-has-youtube';\n } else if (_isVideo && _isVideo.vimeo) {\n videoClass = 'lg-has-vimeo';\n } else if (_isVideo && _isVideo.wistia) {\n // Wistia fell into lg-has-html5 in 2.x; the facades made the\n // gap visible (binding providerClass had it right all along).\n videoClass = 'lg-has-wistia';\n } else {\n videoClass = 'lg-has-html5';\n }\n let _dummy = dummyImg;\n if (typeof dummyImg !== 'string') {\n _dummy = dummyImg.outerHTML;\n }\n return `<div class=\"lg-video-cont ${videoClass}\" style=\"${videoContStyle}\">\n <div class=\"lg-video-play-button\">\n <svg\n viewBox=\"0 0 20 20\"\n preserveAspectRatio=\"xMidYMid\"\n focusable=\"false\"\n aria-labelledby=\"${playVideoString}\"\n role=\"img\"\n class=\"lg-video-play-icon\"\n >\n <title>${playVideoString}</title>\n <polygon class=\"lg-video-play-icon-inner\" points=\"1,0 20,10 1,20\"></polygon>\n </svg>\n <svg class=\"lg-video-play-icon-bg\" viewBox=\"0 0 50 50\" focusable=\"false\">\n <circle cx=\"50%\" cy=\"50%\" r=\"20\"></circle></svg>\n <svg class=\"lg-video-play-icon-circle\" viewBox=\"0 0 50 50\" focusable=\"false\">\n <circle cx=\"50%\" cy=\"50%\" r=\"20\"></circle>\n </svg>\n </div>\n ${_dummy}\n <img class=\"lg-object lg-video-poster\" src=\"${_poster}\" />\n </div>`;\n },\n\n getFocusableElements(container: HTMLElement): NodeListOf<Element> {\n const elements = container.querySelectorAll(\n 'a[href]:not([disabled]), button:not([disabled]), textarea:not([disabled]), input[type=\"text\"]:not([disabled]), input[type=\"radio\"]:not([disabled]), input[type=\"checkbox\"]:not([disabled]), select:not([disabled])',\n );\n const visibleElements = [].filter.call(\n elements,\n (element: HTMLElement) => {\n const style = window.getComputedStyle(element);\n return (\n style.display !== 'none' &&\n style.visibility !== 'hidden' &&\n // Hidden or moved into the toolbar's More menu, whatever\n // the stylesheet says about their display.\n !element.closest('[hidden], [data-lg-overflow]')\n );\n },\n );\n return visibleElements as unknown as NodeListOf<Element>;\n },\n\n /**\n * @desc Create dynamic elements array from gallery items when dynamic option is false\n * It helps to avoid frequent DOM interaction\n * and avoid multiple checks for dynamic elments\n *\n * @returns {Array} dynamicEl\n */\n getDynamicOptions(\n items: any,\n extraProps: string[],\n getCaptionFromTitleOrAlt: boolean,\n exThumbImage: string,\n ): GalleryItem[] {\n const dynamicElements: GalleryItem[] = [];\n const availableDynamicOptions = [\n ...defaultDynamicOptions,\n ...extraProps,\n ];\n [].forEach.call(items, (item: HTMLElement) => {\n const dynamicEl: GalleryItem = {} as GalleryItem;\n for (let i = 0; i < item.attributes.length; i++) {\n const attr = item.attributes[i];\n if (attr.specified) {\n const dynamicAttr = convertToData(attr.name);\n let label = '';\n if (availableDynamicOptions.indexOf(dynamicAttr) > -1) {\n label = dynamicAttr;\n }\n if (label) {\n (dynamicEl as any)[label] = attr.value;\n }\n }\n }\n // `data-sources` is JSON on the element; the item carries the\n // parsed array so every consumer (slide markup, the zoom\n // plugin's actual-size lookup) sees the headless shape.\n if (typeof dynamicEl.sources === 'string') {\n try {\n dynamicEl.sources = JSON.parse(dynamicEl.sources);\n } catch (e) {\n console.warn(\n 'lightGallery :- data-sources must be a JSON array of picture source objects. See https://www.lightgalleryjs.com/docs/responsive-loading/',\n );\n delete dynamicEl.sources;\n }\n }\n const currentItem = $LG(item);\n const alt = currentItem.find('img').first().attr('alt');\n const title = currentItem.attr('title');\n\n const thumb = exThumbImage\n ? currentItem.attr(exThumbImage)\n : currentItem.find('img').first().attr('src');\n dynamicEl.thumb = thumb;\n\n if (getCaptionFromTitleOrAlt && !dynamicEl.subHtml) {\n dynamicEl.subHtml = title || alt || '';\n }\n dynamicEl.alt = alt || title || '';\n dynamicElements.push(dynamicEl);\n });\n return dynamicElements;\n },\n isMobile(): boolean {\n return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);\n },\n /**\n * @desc Check the given src is video\n * @param {String} src\n * @return {Object} video type\n * Ex:{ youtube : [\"//www.youtube.com/watch?v=c0asJgSyxcY\", \"c0asJgSyxcY\"] }\n *\n * @todo - this information can be moved to dynamicEl to avoid frequent calls\n */\n\n isVideo(\n src: string,\n isHTML5VIdeo: boolean,\n index: number,\n ): VideoInfo | undefined {\n if (!src) {\n if (isHTML5VIdeo) {\n return {\n html5: true,\n };\n } else {\n console.error(\n 'lightGallery :- data-src is not provided on slide item ' +\n (index + 1) +\n '. Please make sure the selector property is properly configured. More info - https://www.lightgalleryjs.com/demos/html-markup/',\n );\n return;\n }\n }\n\n // Documented deviation from the shared helper: 2.x ignores the\n // html5 flag once a src is present, a URL matching no provider\n // is not a video, video payload or not.\n return getVideoInfo(src, false);\n },\n};\n\nexport default utils;\n","import {\n takeLicenseNotice,\n awaitDecode,\n formatSlideAnnouncement,\n getCenterCloseTransform,\n getEdgeFrictionedDelta,\n getFacadePoster,\n getYouTubePosterUrl,\n getHorizontalDragTransforms,\n getSwipeAxis,\n getSwipeReleaseVerdict,\n getVerticalDragEffects,\n getWindowedVelocity,\n onTransitionSettle,\n pushVelocitySample,\n resolveSwipeTarget,\n shouldCloseOnVerticalDrag,\n type VelocitySample,\n coreDefaultIcons,\n} from '@lightgallery/headless';\n\nimport {\n AfterAppendSlideEventDetail,\n AfterAppendSubHtmlDetail,\n BeforeSlideDetail,\n lGEvents,\n SlideItemLoadDetail,\n} from './lg-events';\nimport {\n LightGalleryAllSettings,\n lightGalleryCoreSettings,\n LightGallerySettings,\n} from './lg-settings';\nimport { ToolbarOverflow } from './lg-toolbar-overflow';\nimport { applyCustomIcons, LgIcons } from './lg-icons';\nimport { runSprings } from './lg-spring-runner';\nimport utils, { GalleryItem, ImageSize } from './lg-utils';\nimport { $LG, lgQuery } from './lgQuery';\nimport {\n Coords,\n MediaContainerPosition,\n SlideDirection,\n VideoInfo,\n} from './types';\n\n// @ref - https://stackoverflow.com/questions/3971841/how-to-resize-images-proportionally-keeping-the-aspect-ratio\n// @ref - https://2ality.com/2017/04/setting-up-multi-platform-packages.html\n\n// Unique id for each gallery\nlet lgId = 0;\n\nexport class LightGallery {\n public settings!: LightGalleryAllSettings;\n public galleryItems!: GalleryItem[];\n\n // Current gallery item\n public lgId!: number;\n\n public el!: HTMLElement;\n public LGel!: lgQuery;\n public lgOpened = false;\n\n public index = 0;\n\n // lightGallery modules\n public plugins: any[] = [];\n\n // false when lightGallery load first slide content;\n public lGalleryOn = false;\n\n // True when a slide animation is in progress\n public lgBusy = false;\n // Built-in icon SVGs: core defaults + whatever the instantiated\n // plugins register; `settings.icons` overrides per name at apply.\n private defaultIcons: LgIcons = { ...coreDefaultIcons };\n private toolbarOverflow?: ToolbarOverflow;\n\n // Type of touch action - {swipe, zoomSwipe, pinch}\n public touchAction?: 'swipe' | 'zoomSwipe' | 'pinch';\n\n // Direction of swipe/drag - {horizontal, vertical}\n public swipeDirection?: 'horizontal' | 'vertical';\n\n // Rolling gesture samples, for the windowed release velocity\n private swipeSamples: VelocitySample[] = [];\n\n // Cancels a running release spring (slide snap-back / drag restore)\n private cancelSlideSpring?: () => void;\n\n // Timeout function for hiding controls;\n public hideBarTimeout: any;\n\n public currentItemsInDom: string[] = [];\n\n public outer!: lgQuery;\n\n public items: any;\n\n public $backdrop!: lgQuery;\n public $lgComponents!: lgQuery;\n\n public $container!: lgQuery;\n\n public $inner!: lgQuery;\n public $content!: lgQuery;\n public $toolbar!: lgQuery;\n\n // Scroll top value before lightGallery is opened\n public prevScrollTop = 0;\n\n // Element that held focus before the gallery opened; focus is returned\n // to it after close (dialog pattern; captured only when trapFocus runs).\n private prevActiveElement?: HTMLElement;\n\n public bodyPaddingRight = 0;\n\n private zoomFromOrigin!: boolean;\n\n // Read by the zoom plugin (upstream 2.x exposes it the same way).\n public currentImageSize?: ImageSize;\n\n private isDummyImageRemoved = false;\n\n private dragOrSwipeEnabled = false;\n\n public mediaContainerPosition = {\n top: 0,\n bottom: 0,\n };\n\n constructor(element: HTMLElement, options?: LightGallerySettings) {\n if (!element) {\n return this;\n }\n lgId++;\n this.lgId = lgId;\n\n this.el = element;\n this.LGel = $LG(element);\n\n this.generateSettings(options);\n\n this.buildModules();\n\n // When using dynamic mode, ensure dynamicEl is an array\n if (\n this.settings.dynamic &&\n this.settings.dynamicEl !== undefined &&\n !Array.isArray(this.settings.dynamicEl)\n ) {\n throw 'When using dynamic mode, you must also define dynamicEl as an Array.';\n }\n\n this.galleryItems = this.getItems();\n this.normalizeSettings();\n\n // Gallery items\n\n this.init();\n\n this.validateLicense();\n\n return this;\n }\n\n private generateSettings(options?: LightGallerySettings) {\n // lightGallery settings\n this.settings = {\n ...lightGalleryCoreSettings,\n ...options,\n // Strings merge per-key (headless resolveSettings parity), // a partial override keeps every other default.\n strings: {\n ...lightGalleryCoreSettings.strings,\n ...(options?.strings ?? {}),\n },\n } as LightGalleryAllSettings;\n if (\n this.settings.isMobile &&\n typeof this.settings.isMobile === 'function'\n ? this.settings.isMobile()\n : utils.isMobile()\n ) {\n const mobileSettings = {\n ...this.settings.mobileSettings,\n };\n this.settings = { ...this.settings, ...mobileSettings };\n }\n\n // prefers-reduced-motion collapses every animation to 0ms and\n // disables the zoom-from-origin/bounce effects (a11y; checked once\n // per instance, matching the React/Vue/Angular bindings).\n if (\n typeof window !== 'undefined' &&\n typeof window.matchMedia === 'function' &&\n window.matchMedia('(prefers-reduced-motion: reduce)').matches\n ) {\n this.settings = {\n ...this.settings,\n speed: 0,\n backdropDuration: 0,\n startAnimationDuration: 0,\n zoomFromOrigin: false,\n slideEndAnimation: false,\n };\n }\n }\n\n private normalizeSettings() {\n // Resolve direction 'auto' against the gallery element once, // every direction-aware call site reads the resolved value.\n if (this.settings.direction === 'auto') {\n this.settings.direction =\n typeof window !== 'undefined' &&\n typeof window.getComputedStyle === 'function' &&\n window.getComputedStyle(this.el).direction === 'rtl'\n ? 'rtl'\n : 'ltr';\n }\n if (this.settings.slideEndAnimation) {\n this.settings.hideControlOnEnd = false;\n }\n if (!this.settings.closable) {\n this.settings.swipeToClose = false;\n }\n\n // And reset it on close to get the correct value next time\n this.zoomFromOrigin = this.settings.zoomFromOrigin;\n\n // At the moment, Zoom from image doesn't support dynamic options\n // @todo add zoomFromOrigin support for dynamic images\n if (this.settings.dynamic) {\n this.zoomFromOrigin = false;\n }\n\n if (this.settings.container) {\n const { container } = this.settings;\n if (typeof container === 'function') {\n this.settings.container = container();\n } else if (typeof container === 'string') {\n const el = document.querySelector<HTMLElement>(container);\n this.settings.container = el ?? document.body;\n }\n } else {\n this.settings.container = document.body;\n }\n\n // settings.preload should not be grater than $item.length\n this.settings.preload = Math.min(\n this.settings.preload,\n this.galleryItems.length,\n );\n }\n\n init(): void {\n this.addSlideVideoInfo(this.galleryItems);\n\n this.buildStructure();\n\n this.LGel.trigger(lGEvents.init, {\n instance: this,\n });\n\n if (this.settings.keyPress) {\n this.keyPress();\n }\n\n setTimeout(() => {\n this.enableDrag();\n this.enableSwipe();\n this.triggerPosterClick();\n }, 50);\n\n this.arrow();\n if (this.settings.mousewheel) {\n this.mousewheel();\n }\n\n if (!this.settings.dynamic) {\n this.openGalleryOnItemClick();\n }\n }\n\n openGalleryOnItemClick(): void {\n // Using for loop instead of using bubbling as the items can be any html element.\n for (let index = 0; index < this.items.length; index++) {\n const element = this.items[index];\n const $element = $LG(element);\n // Using different namespace for click because click event should not unbind if selector is same object('this')\n // @todo manage all event listners - should have namespace that represent element\n const uuid = lgQuery.generateUUID();\n $element\n .attr('data-lg-id', uuid)\n .on(`click.lgcustom-item-${uuid}`, (e) => {\n e.preventDefault();\n const currentItemIndex = this.settings.index || index;\n this.openGallery(currentItemIndex, element);\n });\n }\n }\n\n /**\n * Module constructor\n * Modules are build incrementally.\n * Gallery should be opened only once all the modules are initialized.\n * use moduleBuildTimeout to make sure this\n */\n buildModules(): void {\n this.settings.plugins.forEach((plugin) => {\n this.plugins.push(new plugin(this, $LG));\n });\n }\n\n validateLicense(): void {\n const notice = takeLicenseNotice(this.settings.licenseKey);\n if (notice) console[notice.level](notice.message);\n }\n\n getSlideItem(index: number): lgQuery {\n return $LG(this.getSlideItemId(index));\n }\n\n getSlideItemId(index: number): string {\n return `#lg-item-${this.lgId}-${index}`;\n }\n\n getIdName(id: string): string {\n return `${id}-${this.lgId}`;\n }\n getElementById(id: string): lgQuery {\n return $LG(`#${this.getIdName(id)}`);\n }\n\n manageSingleSlideClassName(): void {\n if (this.galleryItems.length < 2) {\n this.outer.addClass('lg-single-item');\n } else {\n this.outer.removeClass('lg-single-item');\n }\n }\n\n buildStructure(): void {\n const container = this.$container && this.$container.get();\n if (container) {\n return;\n }\n let controls = '';\n let subHtmlCont = '';\n\n // Create controls\n if (this.settings.controls) {\n controls = `<button type=\"button\" id=\"${this.getIdName(\n 'lg-prev',\n )}\" aria-label=\"${\n this.settings.strings['previousSlide']\n }\" class=\"lg-prev lg-icon\"> ${this.settings.prevHtml} </button>\n <button type=\"button\" id=\"${this.getIdName(\n 'lg-next',\n )}\" aria-label=\"${\n this.settings.strings['nextSlide']\n }\" class=\"lg-next lg-icon\"> ${this.settings.nextHtml} </button>`;\n }\n\n if (this.settings.appendSubHtmlTo !== '.lg-item') {\n // When the announcer owns slide-change announcements the caption\n // bar must not be a second live region (double announcements).\n subHtmlCont = this.settings.ariaAnnouncements\n ? '<div class=\"lg-sub-html\"></div>'\n : '<div class=\"lg-sub-html\" role=\"status\" aria-live=\"polite\"></div>';\n }\n\n let addClasses = '';\n\n if (this.settings.allowMediaOverlap) {\n // Do not remove space before last single quote\n addClasses += 'lg-media-overlap ';\n }\n\n // Dialogs need an accessible name; fall back to a localizable\n // aria-label when the consumer doesn't provide ariaLabelledby.\n const ariaLabelledby = this.settings.ariaLabelledby\n ? 'aria-labelledby=\"' + this.settings.ariaLabelledby + '\"'\n : `aria-label=\"${this.settings.strings['galleryLabel']}\"`;\n const ariaDescribedby = this.settings.ariaDescribedby\n ? 'aria-describedby=\"' + this.settings.ariaDescribedby + '\"'\n : '';\n\n const containerClassName = `lg-container ${this.settings.addClass} ${\n document.body !== this.settings.container ? 'lg-inline' : ''\n }`;\n const closeIcon =\n this.settings.closable && this.settings.showCloseIcon\n ? `<button type=\"button\" aria-label=\"${\n this.settings.strings['closeGallery']\n }\" id=\"${this.getIdName(\n 'lg-close',\n )}\" class=\"lg-close lg-icon\"></button>`\n : '';\n const maximizeIcon = this.settings.showMaximizeIcon\n ? `<button type=\"button\" aria-label=\"${\n this.settings.strings['toggleMaximize']\n }\" id=\"${this.getIdName(\n 'lg-maximize',\n )}\" class=\"lg-maximize lg-icon\"></button>`\n : '';\n const template = `\n <div class=\"${containerClassName}\" id=\"${this.getIdName(\n 'lg-container',\n )}\" tabindex=\"-1\" aria-modal=\"true\" ${ariaLabelledby} ${ariaDescribedby} role=\"dialog\" dir=\"${this.getDirection()}\"\n >\n <div id=\"${this.getIdName(\n 'lg-backdrop',\n )}\" class=\"lg-backdrop\"></div>\n ${\n this.settings.ariaAnnouncements\n ? `<div id=\"${this.getIdName(\n 'lg-announcer',\n )}\" class=\"lg-announcer\" role=\"status\" aria-live=\"polite\"></div>`\n : ''\n }\n\n <div id=\"${this.getIdName(\n 'lg-outer',\n )}\" class=\"lg-outer lg-use-css3 lg-css3 lg-hide-items ${addClasses} \">\n\n <div id=\"${this.getIdName('lg-content')}\" class=\"lg-content\">\n <div id=\"${this.getIdName('lg-inner')}\" class=\"lg-inner\">\n </div>\n ${controls}\n </div>\n <div id=\"${this.getIdName(\n 'lg-toolbar',\n )}\" class=\"lg-toolbar lg-group\">\n ${maximizeIcon}\n ${closeIcon}\n </div>\n ${\n this.settings.appendSubHtmlTo === '.lg-outer'\n ? subHtmlCont\n : ''\n }\n <div id=\"${this.getIdName(\n 'lg-components',\n )}\" class=\"lg-components\">\n ${\n this.settings.appendSubHtmlTo === '.lg-sub-html'\n ? subHtmlCont\n : ''\n }\n </div>\n </div>\n </div>\n `;\n\n $LG(this.settings.container).append(template);\n\n if (document.body !== this.settings.container) {\n $LG(this.settings.container).css('position', 'relative');\n }\n\n this.outer = this.getElementById('lg-outer');\n this.$lgComponents = this.getElementById('lg-components');\n this.$backdrop = this.getElementById('lg-backdrop');\n this.$container = this.getElementById('lg-container');\n this.$inner = this.getElementById('lg-inner');\n this.$content = this.getElementById('lg-content');\n this.$toolbar = this.getElementById('lg-toolbar');\n\n this.$backdrop.css(\n 'transition-duration',\n this.settings.backdropDuration + 'ms',\n );\n\n let outerClassNames = `${this.settings.mode} `;\n\n this.manageSingleSlideClassName();\n\n if (this.settings.enableDrag) {\n outerClassNames += 'lg-grab ';\n }\n\n this.outer.addClass(outerClassNames);\n\n this.$inner.css('transition-timing-function', this.settings.easing);\n this.$inner.css('transition-duration', this.settings.speed + 'ms');\n // Slides read the speed per property: the transform runs for the\n // full duration while the crossfade stays short (see the mode\n // transitions in the stylesheet).\n this.$inner.css('--lg-speed', this.settings.speed + 'ms');\n\n if (this.settings.download) {\n this.$toolbar.append(\n `<a id=\"${this.getIdName(\n 'lg-download',\n )}\" target=\"_blank\" rel=\"noopener\" aria-label=\"${\n this.settings.strings['download']\n }\" download class=\"lg-download lg-icon\"></a>`,\n );\n }\n\n this.counter();\n\n $LG(window).on(\n `resize.lg.global${this.lgId} orientationchange.lg.global${this.lgId}`,\n () => {\n this.refreshOnResize();\n },\n );\n\n this.hideBars();\n\n this.manageCloseGallery();\n this.toggleMaximize();\n\n this.initModules();\n\n // After the plugins have appended their buttons, and before the\n // icon pass, so the More options button gets its icon too.\n if (this.settings.toolbarOverflow) {\n this.toolbarOverflow = new ToolbarOverflow(this.$toolbar.get(), {\n id: this.getIdName('lg-more'),\n label: this.settings.strings.moreOptions,\n });\n const update = () => this.toolbarOverflow?.update();\n this.LGel.on(`${lGEvents.afterOpen}.lg`, update);\n this.LGel.on(`${lGEvents.afterSlide}.lg`, update);\n this.LGel.on(`${lGEvents.containerResize}.lg`, update);\n this.LGel.on(`${lGEvents.beforeClose}.lg`, () =>\n this.toolbarOverflow?.close(false),\n );\n }\n\n // Icons: one pass after the plugins have appended their buttons\n // and registered their default sets, every icon element exists\n // by now. `settings.icons` overrides per name; pairs fall back\n // whole (see lg-icons.ts).\n applyCustomIcons(\n this.$container.get(),\n this.defaultIcons,\n this.settings.icons,\n );\n }\n\n /**\n * Merge a plugin's built-in icon SVGs into the default set (called\n * from plugin `init()`, before the icon pass runs). Consumer\n * `settings.icons` still win over anything registered here.\n */\n registerDefaultIcons(icons: LgIcons): void {\n this.defaultIcons = { ...this.defaultIcons, ...icons };\n }\n\n /**\n * Cache the fitted (contain) size of a slide's media. Every consumer\n * of `currentImageSize` measures against the CURRENT slide: the\n * actual-size zoom divides the natural width by it, and the\n * zoom-from-origin close flight positions against it. Recomputed on\n * every slide change, not just at open — one cached landscape size\n * makes a portrait slide zoom to the wrong scale and then snap to\n * its real size when the natural-px swap lands.\n */\n private updateCurrentImageSize(index: number): void {\n const { __slideVideoInfo } = this.galleryItems[index];\n const { top, bottom } = this.mediaContainerPosition;\n this.currentImageSize = utils.getSize(\n this.items[index],\n this.outer,\n top + bottom,\n __slideVideoInfo && this.settings.videoMaxSize,\n );\n }\n\n refreshOnResize(): void {\n if (this.lgOpened) {\n const currentGalleryItem = this.galleryItems[this.index];\n const { __slideVideoInfo } = currentGalleryItem;\n\n this.mediaContainerPosition = this.getMediaContainerPosition();\n this.updateCurrentImageSize(this.index);\n if (__slideVideoInfo) {\n this.resizeVideoSlide(this.index, this.currentImageSize);\n }\n if (this.zoomFromOrigin && !this.isDummyImageRemoved) {\n const imgStyle = this.getDummyImgStyles(this.currentImageSize);\n this.outer\n .find('.lg-current .lg-dummy-img')\n .first()\n .attr('style', imgStyle);\n }\n this.LGel.trigger(lGEvents.containerResize);\n }\n }\n\n resizeVideoSlide(index: number, imageSize?: ImageSize): void {\n const lgVideoStyle = this.getVideoContStyle(imageSize);\n const currentSlide = this.getSlideItem(index);\n currentSlide.find('.lg-video-cont').attr('style', lgVideoStyle);\n }\n\n /**\n * Update slides dynamically.\n * Add, edit or delete slides dynamically when lightGallery is opened.\n * Modify the current gallery items and pass it via updateSlides method\n * @note\n * - Do not mutate existing lightGallery items directly.\n * - Always pass new list of gallery items\n * - You need to take care of thumbnails outside the gallery if any\n * - user this method only if you want to update slides when the gallery is opened. Otherwise, use `refresh()` method.\n * @param items Gallery items\n * @param index After the update operation, which slide gallery should navigate to\n * @category lGPublicMethods\n * @example\n * const plugin = lightGallery();\n *\n * // Adding slides dynamically\n * let galleryItems = [\n * // Access existing lightGallery items\n * // galleryItems are automatically generated internally from the gallery HTML markup\n * // or directly from galleryItems when dynamic gallery is used\n * ...plugin.galleryItems,\n * ...[\n * {\n * src: 'img/img-1.png',\n * thumb: 'img/thumb1.png',\n * },\n * ],\n * ];\n * plugin.updateSlides(\n * galleryItems,\n * plugin.index,\n * );\n *\n *\n * // Remove slides dynamically\n * galleryItems = JSON.parse(\n * JSON.stringify(updateSlideInstance.galleryItems),\n * );\n * galleryItems.shift();\n * updateSlideInstance.updateSlides(galleryItems, 1);\n * @see <a href=\"/demos/update-slides/\">Demo</a>\n */\n updateSlides(items: GalleryItem[], index: number): void {\n if (this.index > items.length - 1) {\n this.index = items.length - 1;\n }\n if (items.length === 1) {\n this.index = 0;\n }\n if (!items.length) {\n this.closeGallery();\n return;\n }\n const currentSrc = this.galleryItems[index].src;\n this.galleryItems = items;\n this.updateControls();\n this.$inner.empty();\n this.currentItemsInDom = [];\n\n let _index = 0;\n // Find the current index based on source value of the slide\n this.galleryItems.some((galleryItem, itemIndex) => {\n if (galleryItem.src === currentSrc) {\n _index = itemIndex;\n return true;\n }\n return false;\n });\n\n this.currentItemsInDom = this.organizeSlideItems(_index, -1);\n this.loadContent(_index, true);\n this.getSlideItem(_index).addClass('lg-current');\n\n this.index = _index;\n this.updateCurrentCounter(_index);\n this.LGel.trigger(lGEvents.updateSlides);\n }\n\n // Get gallery items based on multiple conditions\n getItems(): GalleryItem[] {\n // Gallery items\n this.items = [];\n if (!this.settings.dynamic) {\n if (this.settings.selector === 'this') {\n this.items.push(this.el);\n } else if (this.settings.selector) {\n if (typeof this.settings.selector === 'string') {\n if (this.settings.selectWithin) {\n const selectWithin = $LG(this.settings.selectWithin);\n this.items = selectWithin\n .find(this.settings.selector)\n .get();\n } else {\n this.items = this.el.querySelectorAll(\n this.settings.selector,\n );\n }\n } else {\n this.items = this.settings.selector;\n }\n } else {\n this.items = this.el.children;\n }\n return utils.getDynamicOptions(\n this.items,\n this.settings.extraProps,\n this.settings.getCaptionFromTitleOrAlt,\n this.settings.exThumbImage,\n );\n } else {\n return this.settings.dynamicEl || [];\n }\n }\n\n shouldHideScrollbar(): boolean {\n return (\n this.settings.hideScrollbar &&\n document.body === this.settings.container\n );\n }\n\n hideScrollbar(): void {\n if (!this.shouldHideScrollbar()) {\n return;\n }\n this.bodyPaddingRight = parseFloat($LG('body').style().paddingRight);\n const bodyRect = document.documentElement.getBoundingClientRect();\n const scrollbarWidth = window.innerWidth - bodyRect.width;\n\n $LG(document.body).css(\n 'padding-right',\n scrollbarWidth + this.bodyPaddingRight + 'px',\n );\n $LG(document.body).addClass('lg-overlay-open');\n }\n\n resetScrollBar(): void {\n if (!this.shouldHideScrollbar()) {\n return;\n }\n $LG(document.body).css('padding-right', this.bodyPaddingRight + 'px');\n $LG(document.body).removeClass('lg-overlay-open');\n }\n\n /**\n * Open lightGallery.\n * Open gallery with specific slide by passing index of the slide as parameter.\n * @category lGPublicMethods\n * @param {Number} index - index of the slide\n * @param {HTMLElement} element - Which image lightGallery should zoom from\n *\n * @example\n * const $dynamicGallery = document.getElementById('dynamic-gallery-demo');\n * const dynamicGallery = lightGallery($dynamicGallery, {\n * dynamic: true,\n * dynamicEl: [\n * {\n * src: 'img/1.jpg',\n * thumb: 'img/thumb-1.jpg',\n * subHtml: '<h4>Image 1 title</h4><p>Image 1 descriptions.</p>',\n * },\n * ...\n * ],\n * });\n * $dynamicGallery.addEventListener('click', function () {\n * // Starts with third item.(Optional).\n * // This is useful if you want use dynamic mode with\n * // custom thumbnails (thumbnails outside gallery),\n * dynamicGallery.openGallery(2);\n * });\n *\n */\n openGallery(index = this.settings.index, element?: HTMLElement): void {\n // prevent accidental double execution\n if (this.lgOpened) return;\n this.lgOpened = true;\n this.outer.removeClass('lg-hide-items');\n\n this.hideScrollbar();\n\n // Add display block, but still has opacity 0\n this.$container.addClass('lg-show');\n\n const itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(\n index,\n index,\n );\n this.currentItemsInDom = itemsToBeInsertedToDom;\n\n let items = '';\n itemsToBeInsertedToDom.forEach((item) => {\n items = items + `<div id=\"${item}\" class=\"lg-item\"></div>`;\n });\n\n this.$inner.append(items);\n this.addHtml(index);\n let transform: string | undefined = '';\n this.mediaContainerPosition = this.getMediaContainerPosition();\n const { top, bottom } = this.mediaContainerPosition;\n if (!this.settings.allowMediaOverlap) {\n this.setMediaContainerPosition(top, bottom);\n }\n const { __slideVideoInfo } = this.galleryItems[index];\n if (this.zoomFromOrigin && element) {\n this.currentImageSize = utils.getSize(\n element,\n this.outer,\n top + bottom,\n __slideVideoInfo && this.settings.videoMaxSize,\n );\n transform = this.getOriginTransform(element, this.currentImageSize);\n }\n if (!this.zoomFromOrigin || !transform) {\n this.outer.addClass(this.settings.startClass);\n this.getSlideItem(index).removeClass('lg-complete');\n }\n const timeout = this.settings.zoomFromOrigin\n ? 100\n : this.settings.backdropDuration;\n setTimeout(() => {\n this.outer.addClass('lg-components-open');\n }, timeout);\n this.index = index;\n this.LGel.trigger(lGEvents.beforeOpen);\n\n // add class lg-current to remove initial transition\n this.getSlideItem(index).addClass('lg-current');\n\n this.lGalleryOn = false;\n // Store the current scroll top value to scroll back after closing the gallery..\n this.prevScrollTop = $LG(window).scrollTop();\n\n // Remember where focus came from so it can be returned on close\n // (dialog pattern). Captured under the same condition that moves\n // focus into the gallery, never touched otherwise.\n if (\n this.settings.trapFocus &&\n document.body === this.settings.container\n ) {\n this.prevActiveElement =\n document.activeElement instanceof HTMLElement\n ? document.activeElement\n : undefined;\n }\n\n setTimeout(() => {\n // Need to check both zoomFromOrigin and transform values as we need to set set the\n // default opening animation if user missed to add the lg-size attribute\n\n if (this.zoomFromOrigin && transform) {\n const currentSlide = this.getSlideItem(index);\n currentSlide.css('transform', transform);\n setTimeout(() => {\n currentSlide\n .addClass('lg-start-progress lg-start-end-progress')\n .css(\n 'transition-duration',\n this.settings.startAnimationDuration + 'ms',\n );\n this.outer.addClass('lg-zoom-from-image');\n });\n setTimeout(() => {\n currentSlide.css('transform', 'translate3d(0, 0, 0)');\n }, 100);\n }\n\n setTimeout(() => {\n this.$backdrop.addClass('in');\n this.$container.addClass('lg-show-in');\n }, 10);\n\n setTimeout(() => {\n if (\n this.settings.trapFocus &&\n document.body === this.settings.container\n ) {\n this.trapFocus();\n }\n }, this.settings.backdropDuration + 50);\n\n // lg-visible class resets gallery opacity to 1\n if (!this.zoomFromOrigin || !transform) {\n setTimeout(() => {\n this.outer.addClass('lg-visible');\n }, this.settings.backdropDuration);\n }\n\n // initiate slide function\n this.slide(index, false, false, false);\n\n this.LGel.trigger(lGEvents.afterOpen);\n });\n\n if (document.body === this.settings.container) {\n $LG('html').addClass('lg-on');\n }\n }\n\n /**\n * The zoom-from-origin transform for a trigger: it lands the slide on\n * the trigger's thumbnail, the start of the opening flight and the end\n * of the closing one. Undefined when the trigger cannot anchor a flight,\n * and the gallery opens or closes about the stage centre instead.\n * Plugins may replace it on the instance to fly differently.\n */\n public getOriginTransform(\n element: HTMLElement,\n imageSize?: ImageSize,\n ): string | undefined {\n const { top, bottom } = this.mediaContainerPosition;\n return utils.getTransform(element, this.outer, top, bottom, imageSize);\n }\n\n /**\n * Note - Changing the position of the media on every slide transition creates a flickering effect.\n * Therefore, The height of the caption is calculated dynamically, only once based on the first slide caption.\n * if you have dynamic captions for each media,\n * you can provide an appropriate height for the captions via allowMediaOverlap option\n */\n public getMediaContainerPosition(): MediaContainerPosition {\n if (this.settings.allowMediaOverlap) {\n return {\n top: 0,\n bottom: 0,\n };\n }\n const top = this.$toolbar.get().clientHeight || 0;\n const subHtml = this.outer.find('.lg-components .lg-sub-html').get();\n const captionHeight =\n this.settings.defaultCaptionHeight ||\n (subHtml && subHtml.clientHeight) ||\n 0;\n const thumbContainer = this.outer.find('.lg-thumb-outer').get();\n const thumbHeight = thumbContainer ? thumbContainer.clientHeight : 0;\n const bottom = thumbHeight + captionHeight;\n return {\n top,\n bottom,\n };\n }\n\n private setMediaContainerPosition(top = 0, bottom = 0): void {\n this.$content.css('top', top + 'px').css('bottom', bottom + 'px');\n }\n\n hideBars(): void {\n // Hide controllers if mouse doesn't move for some period\n setTimeout(() => {\n this.outer.removeClass('lg-hide-items');\n if (this.settings.hideBarsDelay > 0) {\n this.outer.on('mousemove.lg click.lg touchstart.lg', () => {\n this.outer.removeClass('lg-hide-items');\n\n clearTimeout(this.hideBarTimeout);\n\n // Timeout will be cleared on each slide movement also\n this.hideBarTimeout = setTimeout(() => {\n this.outer.addClass('lg-hide-items');\n }, this.settings.hideBarsDelay);\n });\n this.outer.trigger('mousemove.lg');\n }\n }, this.settings.showBarsAfter);\n }\n\n /**\n * @desc Create image counter\n * Ex: 1/10\n */\n counter(): void {\n if (this.settings.counter) {\n // With the announcer active the counter is decorative, the\n // announcer already conveys the position in a friendlier form.\n const counterA11yAttrs = this.settings.ariaAnnouncements\n ? 'aria-hidden=\"true\"'\n : 'role=\"status\" aria-live=\"polite\"';\n const counterHtml = `<div class=\"lg-counter\" ${counterA11yAttrs}>\n <span id=\"${this.getIdName(\n 'lg-counter-current',\n )}\" class=\"lg-counter-current\">${this.index + 1} </span> /\n <span id=\"${this.getIdName(\n 'lg-counter-all',\n )}\" class=\"lg-counter-all\">${\n this.galleryItems.length\n } </span></div>`;\n this.outer.find(this.settings.appendCounterTo).append(counterHtml);\n }\n }\n\n /**\n * @desc add sub-html into the slide\n * @param {Number} index - index of the slide\n */\n addHtml(index: number): void {\n let subHtml;\n let subHtmlUrl;\n if (this.galleryItems[index].subHtmlUrl) {\n subHtmlUrl = this.galleryItems[index].subHtmlUrl;\n } else {\n subHtml = this.galleryItems[index].subHtml;\n }\n\n if (!subHtmlUrl) {\n if (subHtml) {\n // get first letter of sub-html\n // if first letter starts with . or # get the html form the jQuery object\n const fL = subHtml.substring(0, 1);\n if (fL === '.' || fL === '#') {\n try {\n if (\n this.settings.subHtmlSelectorRelative &&\n !this.settings.dynamic\n ) {\n subHtml = $LG(this.items)\n .eq(index)\n .find(subHtml)\n .first()\n .html();\n } else {\n subHtml = $LG(subHtml).first().html();\n }\n } catch (error) {\n console.warn(\n `lightGallery: error processing subHtml selector \"${subHtml}\". See https://www.lightgalleryjs.com/demos/captions/`,\n );\n subHtml = '';\n }\n }\n } else {\n subHtml = '';\n }\n }\n\n if (this.settings.appendSubHtmlTo !== '.lg-item') {\n if (subHtmlUrl) {\n utils.fetchCaptionFromUrl(\n subHtmlUrl,\n this.outer.find('.lg-sub-html'),\n 'replace',\n );\n } else {\n this.outer.find('.lg-sub-html').html(subHtml as string);\n }\n } else {\n const currentSlide = $LG(this.getSlideItemId(index));\n if (subHtmlUrl) {\n utils.fetchCaptionFromUrl(subHtmlUrl, currentSlide, 'append');\n } else {\n currentSlide.append(\n `<div class=\"lg-sub-html\">${subHtml}</div>`,\n );\n }\n }\n\n // Add lg-empty-html class if title doesn't exist\n if (typeof subHtml !== 'undefined' && subHtml !== null) {\n if (subHtml === '') {\n this.outer\n .find(this.settings.appendSubHtmlTo)\n .addClass('lg-empty-html');\n } else {\n this.outer\n .find(this.settings.appendSubHtmlTo)\n .removeClass('lg-empty-html');\n }\n }\n\n this.LGel.trigger<AfterAppendSubHtmlDetail>(\n lGEvents.afterAppendSubHtml,\n {\n index,\n },\n );\n }\n\n /**\n * @desc Preload slides\n * @param {Number} index - index of the slide\n * @todo preload not working for the first slide, Also, should work for the first and last slide as well\n */\n preload(index: number): void {\n for (let i = 1; i <= this.settings.preload; i++) {\n if (i >= this.galleryItems.length - index) {\n break;\n }\n\n this.loadContent(index + i, false);\n }\n\n for (let j = 1; j <= this.settings.preload; j++) {\n if (index - j < 0) {\n break;\n }\n\n this.loadContent(index - j, false);\n }\n }\n\n getDummyImgStyles(imageSize?: ImageSize): string {\n if (!imageSize) return '';\n return `width:${imageSize.width}px;\n margin-left: -${imageSize.width / 2}px;\n margin-top: -${imageSize.height / 2}px;\n height:${imageSize.height}px`;\n }\n getVideoContStyle(imageSize?: ImageSize): string {\n if (!imageSize) return '';\n return `width:${imageSize.width}px;\n height:${imageSize.height}px`;\n }\n\n getDummyImageContent(\n $currentSlide: lgQuery,\n index: number,\n alt: string,\n ): HTMLImageElement | string {\n let $currentItem;\n if (!this.settings.dynamic) {\n $currentItem = $LG(this.items).eq(index);\n }\n if ($currentItem) {\n let _dummyImgSrc;\n if (!this.settings.exThumbImage) {\n _dummyImgSrc = $currentItem.find('img').first().attr('src');\n } else {\n _dummyImgSrc = $currentItem.attr(this.settings.exThumbImage);\n }\n if (!_dummyImgSrc) return '';\n const imgStyle = this.getDummyImgStyles(this.currentImageSize);\n const dummyImgContentImg = document.createElement('img');\n dummyImgContentImg.alt = alt || '';\n dummyImgContentImg.src = _dummyImgSrc;\n dummyImgContentImg.className = `lg-dummy-img`;\n dummyImgContentImg.style.cssText = imgStyle;\n\n $currentSlide.addClass('lg-first-slide');\n this.outer.addClass('lg-first-slide-loading');\n\n return dummyImgContentImg;\n }\n return '';\n }\n\n setImgMarkup(src: string, $currentSlide: lgQuery, index: number): void {\n const currentGalleryItem = this.galleryItems[index];\n const { alt, srcset, sizes, sources } = currentGalleryItem;\n\n // Use the thumbnail as dummy image which will be resized to actual image size and\n // displayed on top of actual image\n let imgContent: string | HTMLImageElement = '';\n const altAttr = alt ? 'alt=\"' + alt + '\"' : '';\n\n if (this.isFirstSlideWithZoomAnimation()) {\n imgContent = this.getDummyImageContent(\n $currentSlide,\n index,\n altAttr,\n );\n } else {\n imgContent = utils.getImgMarkup(\n index,\n src,\n altAttr,\n srcset,\n sizes,\n sources,\n );\n }\n const picture = document.createElement('picture');\n picture.className = 'lg-img-wrap';\n $LG(picture).append(imgContent);\n $currentSlide.prepend(picture);\n }\n\n onSlideObjectLoad(\n $slide: lgQuery,\n isHTML5VideoWithoutPoster: boolean,\n onLoad: () => void,\n onError: () => void,\n ): void {\n const mediaObject = $slide.find('.lg-object').first();\n const media = mediaObject.get() as HTMLImageElement;\n // Decode gate (shared contract with the bindings): completion\n // flips only once the browser can paint the FULL image, a\n // loaded-but-undecoded flip paints partially on slow devices.\n // Synchronous when `decode()` is unavailable; the timeout\n // fallback keeps a stalling decode from stranding the spinner.\n const gated = (handler: () => void) => {\n if (\n media instanceof HTMLImageElement &&\n typeof media.decode === 'function'\n ) {\n void awaitDecode(media).then(handler);\n } else {\n handler();\n }\n };\n if (utils.isImageLoaded(media) || isHTML5VideoWithoutPoster) {\n gated(onLoad);\n } else {\n mediaObject.on('load.lg error.lg', () => {\n gated(() => onLoad && onLoad());\n });\n mediaObject.on('error.lg', () => {\n onError && onError();\n });\n }\n }\n\n /**\n *\n * @param $el Current slide item\n * @param index\n * @param delay Delay is 0 except first time\n * @param speed Speed is same as delay, except it is 0 if gallery is opened via hash plugin\n * @param isFirstSlide\n */\n onLgObjectLoad(\n currentSlide: lgQuery,\n index: number,\n delay: number,\n speed: number,\n isFirstSlide: boolean,\n isHTML5VideoWithoutPoster: boolean,\n ): void {\n this.onSlideObjectLoad(\n currentSlide,\n isHTML5VideoWithoutPoster,\n () => {\n this.triggerSlideItemLoad(\n currentSlide,\n index,\n delay,\n speed,\n isFirstSlide,\n );\n },\n () => {\n currentSlide.addClass('lg-complete lg-complete_');\n currentSlide.html(\n '<span class=\"lg-error-msg\">' +\n this.settings.strings['mediaLoadingFailed'] +\n '</span>',\n );\n },\n );\n }\n\n triggerSlideItemLoad(\n $currentSlide: lgQuery,\n index: number,\n delay: number,\n speed: number,\n isFirstSlide: boolean,\n ): void {\n const currentGalleryItem = this.galleryItems[index];\n\n // Adding delay for video slides without poster for better performance and user experience\n // Videos should start playing once once the gallery is completely loaded\n const _speed =\n isFirstSlide &&\n this.getSlideType(currentGalleryItem) === 'video' &&\n !currentGalleryItem.poster\n ? speed\n : 0;\n setTimeout(() => {\n $currentSlide.addClass('lg-complete lg-complete_');\n this.LGel.trigger<SlideItemLoadDetail>(lGEvents.slideItemLoad, {\n index,\n delay: delay || 0,\n isFirstSlide,\n });\n }, _speed);\n }\n\n isFirstSlideWithZoomAnimation(): boolean {\n return !!(\n !this.lGalleryOn &&\n this.zoomFromOrigin &&\n this.currentImageSize\n );\n }\n\n // Add video slideInfo\n addSlideVideoInfo(items: GalleryItem[]): void {\n items.forEach((element, index) => {\n element.__slideVideoInfo = utils.isVideo(\n element.src as string,\n !!element.video,\n index,\n );\n const videoInfo = element.__slideVideoInfo;\n if (!videoInfo) {\n return;\n }\n if (this.settings.videoFacade !== false) {\n // Lite-embed facade: provider slides get a poster (item\n // poster → YouTube thumbnail endpoint → item thumb) so the\n // iframe is created only on play. The headless chain never\n // synthesizes a poster for html5 slides.\n element.poster = getFacadePoster(\n element,\n videoInfo,\n this.settings.loadYouTubePoster,\n );\n } else if (\n this.settings.loadYouTubePoster &&\n !element.poster &&\n videoInfo.youtube\n ) {\n // videoFacade:false, 2.x behavior: only the YouTube\n // poster is synthesized.\n element.poster = getYouTubePosterUrl(videoInfo);\n }\n });\n }\n\n /**\n * Load slide content into slide.\n * This is used to load content into slides that is not visible too\n * @param {Number} index - index of the slide.\n * @param {Boolean} rec - if true call loadcontent() function again.\n */\n loadContent(index: number, rec: boolean): void {\n const currentGalleryItem = this.galleryItems[index];\n const $currentSlide = $LG(this.getSlideItemId(index));\n\n const { poster, srcset, sizes, sources } = currentGalleryItem;\n let { src } = currentGalleryItem;\n\n const video = currentGalleryItem.video;\n\n const _html5Video =\n video && typeof video === 'string' ? JSON.parse(video) : video;\n\n if (currentGalleryItem.responsive) {\n const srcDyItms = currentGalleryItem.responsive.split(',');\n src = utils.getResponsiveSrc(srcDyItms) || src;\n }\n\n const videoInfo = currentGalleryItem.__slideVideoInfo;\n let lgVideoStyle = '';\n\n const iframe = !!currentGalleryItem.iframe;\n\n const isFirstSlide = !this.lGalleryOn;\n\n // delay for adding complete class. it is 0 except first time.\n let delay = 0;\n if (isFirstSlide) {\n if (this.zoomFromOrigin && this.currentImageSize) {\n delay = this.settings.startAnimationDuration + 10;\n } else {\n delay = this.settings.backdropDuration + 10;\n }\n }\n\n if (!$currentSlide.hasClass('lg-loaded')) {\n if (videoInfo) {\n const { top, bottom } = this.mediaContainerPosition;\n const videoSize = utils.getSize(\n this.items[index],\n this.outer,\n top + bottom,\n videoInfo && this.settings.videoMaxSize,\n );\n lgVideoStyle = this.getVideoContStyle(videoSize);\n }\n if (iframe) {\n const markup = utils.getIframeMarkup(\n this.settings.iframeWidth,\n this.settings.iframeHeight,\n this.settings.iframeMaxWidth,\n this.settings.iframeMaxHeight,\n src,\n currentGalleryItem.iframeTitle,\n );\n $currentSlide.prepend(markup);\n } else if (poster) {\n let dummyImg: string | HTMLImageElement = '';\n const hasStartAnimation =\n isFirstSlide &&\n this.zoomFromOrigin &&\n this.currentImageSize;\n if (hasStartAnimation) {\n dummyImg = this.getDummyImageContent(\n $currentSlide,\n index,\n '',\n );\n }\n\n const markup = utils.getVideoPosterMarkup(\n poster,\n dummyImg || '',\n lgVideoStyle,\n this.settings.strings['playVideo'],\n videoInfo,\n );\n $currentSlide.prepend(markup);\n } else if (videoInfo) {\n const markup = `<div class=\"lg-video-cont \" style=\"${lgVideoStyle}\"></div>`;\n $currentSlide.prepend(markup);\n } else {\n this.setImgMarkup(src as string, $currentSlide, index);\n }\n if (poster || videoInfo) {\n this.LGel.trigger(lGEvents.hasVideo, {\n index,\n src: src,\n html5Video: _html5Video,\n hasPoster: !!poster,\n });\n }\n\n this.LGel.trigger<AfterAppendSlideEventDetail>(\n lGEvents.afterAppendSlide,\n { index },\n );\n\n if (\n this.lGalleryOn &&\n this.settings.appendSubHtmlTo === '.lg-item'\n ) {\n this.addHtml(index);\n }\n }\n\n // For first time add some delay for displaying the start animation.\n let _speed = 0;\n\n // Do not change the delay value because it is required for zoom plugin.\n // If gallery opened from direct url (hash) speed value should be 0\n if (delay && !$LG(document.body).hasClass('lg-from-hash')) {\n _speed = delay;\n }\n\n // Only for first slide and zoomFromOrigin is enabled\n if (this.isFirstSlideWithZoomAnimation()) {\n // The real image lands only once the zoom-from-origin flight\n // has actually ended. The flight's transition starts at the\n // first style recalc after the transform reset, which the\n // gallery's own first layout can push well past the fixed\n // offset, and a fast (cached) image appended on that offset then\n // swaps in over the still-scaling thumbnail.\n const settleFlight = (onLanded: () => void) =>\n onTransitionSettle(\n $currentSlide.get(),\n 'transform',\n this.settings.startAnimationDuration + 100,\n onLanded,\n );\n settleFlight(() => {\n $currentSlide\n .removeClass('lg-start-end-progress lg-start-progress')\n .removeAttr('style');\n });\n if (!$currentSlide.hasClass('lg-loaded')) {\n settleFlight(() => {\n if (this.getSlideType(currentGalleryItem) === 'image') {\n const { alt } = currentGalleryItem;\n const altAttr = alt ? 'alt=\"' + alt + '\"' : '';\n\n $currentSlide\n .find('.lg-img-wrap')\n .append(\n utils.getImgMarkup(\n index,\n src as string,\n altAttr,\n srcset,\n sizes,\n currentGalleryItem.sources,\n ),\n );\n }\n if (\n this.getSlideType(currentGalleryItem) === 'image' ||\n (this.getSlideType(currentGalleryItem) === 'video' &&\n poster)\n ) {\n this.onLgObjectLoad(\n $currentSlide,\n index,\n delay,\n _speed,\n true,\n false,\n );\n\n // load remaining slides once the slide is completely loaded\n this.onSlideObjectLoad(\n $currentSlide,\n !!(videoInfo && videoInfo.html5 && !poster),\n () => {\n this.loadContentOnFirstSlideLoad(\n index,\n $currentSlide,\n _speed,\n );\n },\n () => {\n this.loadContentOnFirstSlideLoad(\n index,\n $currentSlide,\n _speed,\n );\n },\n );\n }\n });\n }\n }\n\n // SLide content has been added to dom\n $currentSlide.addClass('lg-loaded');\n\n if (\n !this.isFirstSlideWithZoomAnimation() ||\n (this.getSlideType(currentGalleryItem) === 'video' && !poster)\n ) {\n this.onLgObjectLoad(\n $currentSlide,\n index,\n delay,\n _speed,\n isFirstSlide,\n !!(videoInfo && videoInfo.html5 && !poster),\n );\n }\n\n // When gallery is opened once content is loaded (second time) need to add lg-complete class for css styling\n if (\n (!this.zoomFromOrigin || !this.currentImageSize) &&\n $currentSlide.hasClass('lg-complete_') &&\n !this.lGalleryOn\n ) {\n setTimeout(() => {\n $currentSlide.addClass('lg-complete');\n }, this.settings.backdropDuration);\n }\n\n // Content loaded\n // Need to set lGalleryOn before calling preload function\n this.lGalleryOn = true;\n\n if (rec === true) {\n if (!$currentSlide.hasClass('lg-complete_')) {\n $currentSlide\n .find('.lg-object')\n .first()\n .on('load.lg error.lg', () => {\n this.preload(index);\n });\n } else {\n this.preload(index);\n }\n }\n }\n\n /**\n * @desc Remove dummy image content and load next slides\n * Called only for the first time if zoomFromOrigin animation is enabled\n * @param index\n * @param $currentSlide\n * @param speed\n */\n loadContentOnFirstSlideLoad(\n index: number,\n $currentSlide: lgQuery,\n speed: number,\n ): void {\n setTimeout(() => {\n $currentSlide.find('.lg-dummy-img').remove();\n $currentSlide.removeClass('lg-first-slide');\n this.outer.removeClass('lg-first-slide-loading');\n this.isDummyImageRemoved = true;\n this.preload(index);\n }, speed + 300);\n }\n\n getItemsToBeInsertedToDom(\n index: number,\n prevIndex: number,\n numberOfItems = 0,\n ): string[] {\n const itemsToBeInsertedToDom: string[] = [];\n // Minimum 2 items should be there\n let possibleNumberOfItems = Math.max(numberOfItems, 3);\n possibleNumberOfItems = Math.min(\n possibleNumberOfItems,\n this.galleryItems.length,\n );\n const prevIndexItem = `lg-item-${this.lgId}-${prevIndex}`;\n if (this.galleryItems.length <= 3) {\n this.galleryItems.forEach((_element, index) => {\n itemsToBeInsertedToDom.push(`lg-item-${this.lgId}-${index}`);\n });\n return itemsToBeInsertedToDom;\n }\n\n if (index < (this.galleryItems.length - 1) / 2) {\n for (\n let idx = index;\n idx > index - possibleNumberOfItems / 2 && idx >= 0;\n idx--\n ) {\n itemsToBeInsertedToDom.push(`lg-item-${this.lgId}-${idx}`);\n }\n const numberOfExistingItems = itemsToBeInsertedToDom.length;\n for (\n let idx = 0;\n idx < possibleNumberOfItems - numberOfExistingItems;\n idx++\n ) {\n itemsToBeInsertedToDom.push(\n `lg-item-${this.lgId}-${index + idx + 1}`,\n );\n }\n } else {\n for (\n let idx = index;\n idx <= this.galleryItems.length - 1 &&\n idx < index + possibleNumberOfItems / 2;\n idx++\n ) {\n itemsToBeInsertedToDom.push(`lg-item-${this.lgId}-${idx}`);\n }\n const numberOfExistingItems = itemsToBeInsertedToDom.length;\n for (\n let idx = 0;\n idx < possibleNumberOfItems - numberOfExistingItems;\n idx++\n ) {\n itemsToBeInsertedToDom.push(\n `lg-item-${this.lgId}-${index - idx - 1}`,\n );\n }\n }\n if (this.settings.loop) {\n if (index === this.galleryItems.length - 1) {\n itemsToBeInsertedToDom.push(`lg-item-${this.lgId}-${0}`);\n } else if (index === 0) {\n itemsToBeInsertedToDom.push(\n `lg-item-${this.lgId}-${this.galleryItems.length - 1}`,\n );\n }\n }\n if (itemsToBeInsertedToDom.indexOf(prevIndexItem) === -1) {\n itemsToBeInsertedToDom.push(`lg-item-${this.lgId}-${prevIndex}`);\n }\n\n return itemsToBeInsertedToDom;\n }\n\n organizeSlideItems(index: number, prevIndex: number): string[] {\n // Pool size: virtualization.slides (large-gallery setting)\n // overrides the classic numberOfSlideItemsInDom. The current\n // slide is always in the window, and the zoom plugin resets zoom\n // on slide change, so removal never touches live zoom state.\n const itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(\n index,\n prevIndex,\n this.settings.virtualization?.slides ??\n this.settings.numberOfSlideItemsInDom,\n );\n\n itemsToBeInsertedToDom.forEach((item) => {\n if (this.currentItemsInDom.indexOf(item) === -1) {\n this.$inner.append(`<div id=\"${item}\" class=\"lg-item\"></div>`);\n }\n });\n\n this.currentItemsInDom.forEach((item) => {\n if (itemsToBeInsertedToDom.indexOf(item) === -1) {\n $LG(`#${item}`).remove();\n }\n });\n return itemsToBeInsertedToDom;\n }\n\n /**\n * Get previous index of the slide\n */\n getPreviousSlideIndex(): number {\n let prevIndex = 0;\n try {\n const currentItemId = this.outer\n .find('.lg-current')\n .first()\n .attr('id');\n prevIndex = parseInt(currentItemId.split('-')[3]) || 0;\n } catch (error) {\n prevIndex = 0;\n }\n return prevIndex;\n }\n\n setDownloadValue(index: number): void {\n if (this.settings.download) {\n const currentGalleryItem = this.galleryItems[index];\n const hideDownloadBtn =\n currentGalleryItem.downloadUrl === false ||\n currentGalleryItem.downloadUrl === 'false';\n if (hideDownloadBtn) {\n this.outer.addClass('lg-hide-download');\n } else {\n const $download = this.getElementById('lg-download');\n this.outer.removeClass('lg-hide-download');\n $download.attr(\n 'href',\n currentGalleryItem.downloadUrl ||\n (currentGalleryItem.src as string),\n );\n if (currentGalleryItem.download) {\n $download.attr('download', currentGalleryItem.download);\n }\n }\n }\n }\n\n makeSlideAnimation(\n direction: 'next' | 'prev',\n currentSlideItem: lgQuery,\n previousSlideItem: lgQuery,\n ): void {\n if (this.lGalleryOn) {\n previousSlideItem.addClass('lg-slide-progress');\n }\n setTimeout(\n () => {\n // remove all transitions\n this.outer.addClass('lg-no-trans');\n\n this.outer\n .find('.lg-item')\n .removeClass('lg-prev-slide lg-next-slide');\n\n if (direction === 'prev') {\n //prevslide\n currentSlideItem.addClass('lg-prev-slide');\n previousSlideItem.addClass('lg-next-slide');\n } else {\n // next slide\n currentSlideItem.addClass('lg-next-slide');\n previousSlideItem.addClass('lg-prev-slide');\n }\n\n // give 50 ms for browser to add/remove class\n setTimeout(() => {\n this.outer.find('.lg-item').removeClass('lg-current');\n\n currentSlideItem.addClass('lg-current');\n\n // reset all transitions\n this.outer.removeClass('lg-no-trans');\n }, 50);\n },\n this.lGalleryOn ? this.settings.slideDelay : 0,\n );\n }\n\n /**\n * Goto a specific slide.\n * @param {Number} index - index of the slide\n * @param {Boolean} fromTouch - true if slide function called via touch event or mouse drag\n * @param {Boolean} fromThumb - true if slide function called via thumbnail click\n * @param {String} direction - Direction of the slide(next/prev)\n * @category lGPublicMethods\n * @example\n * const plugin = lightGallery();\n * // to go to 3rd slide\n * plugin.slide(2);\n *\n */\n slide(\n index: number,\n fromTouch?: boolean,\n fromThumb?: boolean,\n direction?: SlideDirection | false,\n ): void {\n const prevIndex = this.getPreviousSlideIndex();\n this.currentItemsInDom = this.organizeSlideItems(index, prevIndex);\n\n // Prevent multiple call, Required for hsh plugin\n if (this.lGalleryOn && prevIndex === index) {\n return;\n }\n\n const numberOfGalleryItems = this.galleryItems.length;\n\n if (!this.lgBusy) {\n if (this.settings.counter) {\n this.updateCurrentCounter(index);\n }\n this.announceSlide(index);\n\n const currentSlideItem = this.getSlideItem(index);\n const previousSlideItem = this.getSlideItem(prevIndex);\n\n const currentGalleryItem = this.galleryItems[index];\n const videoInfo = currentGalleryItem.__slideVideoInfo;\n\n this.outer.attr(\n 'data-lg-slide-type',\n this.getSlideType(currentGalleryItem),\n );\n this.setDownloadValue(index);\n\n // The fitted size belongs to the slide on screen; consumers\n // (actual-size zoom, the close flight) measure against it.\n this.updateCurrentImageSize(index);\n\n if (videoInfo) {\n const { top, bottom } = this.mediaContainerPosition;\n const videoSize = utils.getSize(\n this.items[index],\n this.outer,\n top + bottom,\n videoInfo && this.settings.videoMaxSize,\n );\n this.resizeVideoSlide(index, videoSize);\n }\n\n this.LGel.trigger<BeforeSlideDetail>(lGEvents.beforeSlide, {\n prevIndex,\n index,\n fromTouch: !!fromTouch,\n fromThumb: !!fromThumb,\n });\n\n this.lgBusy = true;\n\n clearTimeout(this.hideBarTimeout);\n\n this.arrowDisable(index);\n\n if (!direction) {\n if (index < prevIndex) {\n direction = 'prev';\n } else if (index > prevIndex) {\n direction = 'next';\n }\n }\n\n if (!fromTouch) {\n this.makeSlideAnimation(\n direction as SlideDirection,\n currentSlideItem,\n previousSlideItem,\n );\n } else {\n this.outer\n .find('.lg-item')\n .removeClass('lg-prev-slide lg-current lg-next-slide');\n let touchPrev;\n let touchNext;\n if (numberOfGalleryItems > 2) {\n touchPrev = index - 1;\n touchNext = index + 1;\n\n if (index === 0 && prevIndex === numberOfGalleryItems - 1) {\n // next slide\n touchNext = 0;\n touchPrev = numberOfGalleryItems - 1;\n } else if (\n index === numberOfGalleryItems - 1 &&\n prevIndex === 0\n ) {\n // prev slide\n touchNext = 0;\n touchPrev = numberOfGalleryItems - 1;\n }\n } else {\n touchPrev = 0;\n touchNext = 1;\n }\n\n if (direction === 'prev') {\n this.getSlideItem(touchNext).addClass('lg-next-slide');\n } else {\n this.getSlideItem(touchPrev).addClass('lg-prev-slide');\n }\n\n currentSlideItem.addClass('lg-current');\n }\n\n // Do not put load content in set timeout as it needs to load immediately when the gallery is opened\n if (!this.lGalleryOn) {\n this.loadContent(index, true);\n } else {\n setTimeout(() => {\n this.loadContent(index, true);\n // Add title if this.settings.appendSubHtmlTo === lg-sub-html\n if (this.settings.appendSubHtmlTo !== '.lg-item') {\n this.addHtml(index);\n }\n }, this.settings.speed + 50 + (fromTouch ? 0 : this.settings.slideDelay));\n }\n\n setTimeout(() => {\n this.lgBusy = false;\n previousSlideItem.removeClass('lg-slide-progress');\n this.LGel.trigger(lGEvents.afterSlide, {\n prevIndex: prevIndex,\n index,\n fromTouch,\n fromThumb,\n });\n }, (this.lGalleryOn ? this.settings.speed + 100 : 100) + (fromTouch ? 0 : this.settings.slideDelay));\n }\n\n this.index = index;\n }\n\n updateCurrentCounter(index: number): void {\n this.getElementById('lg-counter-current').html(index + 1 + '');\n }\n\n /**\n * Plain-text caption of a slide for the aria-live announcer. Resolves\n * the same sources addHtml uses (inline subHtml markup or a selector)\n * and strips the markup down to readable text. Remote captions\n * (subHtmlUrl) are skipped, announcing can't wait on a fetch.\n */\n private getSlideCaptionText(index: number): string {\n const currentGalleryItem = this.galleryItems[index];\n if (!currentGalleryItem || currentGalleryItem.subHtmlUrl) {\n return '';\n }\n let subHtml = currentGalleryItem.subHtml || '';\n const firstLetter = subHtml.substring(0, 1);\n if (firstLetter === '.' || firstLetter === '#') {\n try {\n if (\n this.settings.subHtmlSelectorRelative &&\n !this.settings.dynamic\n ) {\n subHtml = $LG(this.items)\n .eq(index)\n .find(subHtml)\n .first()\n .html();\n } else {\n subHtml = $LG(subHtml).first().html();\n }\n } catch (error) {\n subHtml = '';\n }\n }\n if (!subHtml) {\n return '';\n }\n const container = document.createElement('div');\n container.innerHTML = subHtml;\n return container.textContent || '';\n }\n\n /**\n * Update the polite live region with the shown slide's position and\n * caption (\"Image X of Y, caption\"). The single announcement source,\n * counter and caption bar are not live regions while this is enabled.\n */\n private announceSlide(index: number): void {\n if (!this.settings.ariaAnnouncements) {\n return;\n }\n const announcer = this.getElementById('lg-announcer').get();\n if (!announcer) {\n return;\n }\n announcer.textContent = formatSlideAnnouncement({\n template: this.settings.strings['slideAnnouncement'],\n index: index + 1,\n total: this.galleryItems.length,\n caption: this.getSlideCaptionText(index),\n });\n }\n\n updateCounterTotal(): void {\n this.getElementById('lg-counter-all').html(\n this.galleryItems.length + '',\n );\n }\n\n getSlideType(item: GalleryItem): 'video' | 'iframe' | 'image' {\n if (item.__slideVideoInfo) {\n return 'video';\n } else if (item.iframe) {\n return 'iframe';\n } else {\n return 'image';\n }\n }\n\n /** Stop a running release spring; visuals stay at the live frame. */\n stopSlideSpring(): void {\n if (this.cancelSlideSpring) {\n this.cancelSlideSpring();\n this.cancelSlideSpring = undefined;\n }\n }\n\n touchMove(startCoords: Coords, endCoords: Coords, e?: TouchEvent): void {\n const distanceX = endCoords.pageX - startCoords.pageX;\n const distanceY = endCoords.pageY - startCoords.pageY;\n\n this.swipeSamples = pushVelocitySample(this.swipeSamples, {\n x: endCoords.pageX,\n y: endCoords.pageY,\n t: Date.now(),\n });\n\n this.swipeDirection = getSwipeAxis(\n distanceX,\n distanceY,\n this.swipeDirection,\n );\n if (!this.swipeDirection) {\n return;\n }\n\n const $currentSlide = this.getSlideItem(this.index);\n\n if (this.swipeDirection === 'horizontal') {\n e?.preventDefault();\n // reset opacity and transition duration\n this.outer.addClass('lg-dragging');\n\n // move current slide and its neighbors, keeping the gutter;\n // past the gallery ends the drag rubber-bands instead of\n // tracking 1:1\n const transforms = getHorizontalDragTransforms(\n this.getEdgeDragDelta(distanceX),\n $currentSlide.get().offsetWidth,\n this.getDirection(),\n );\n $currentSlide.css('transform', transforms.current);\n this.outer\n .find('.lg-prev-slide')\n .first()\n .css('transform', transforms.prev);\n this.outer\n .find('.lg-next-slide')\n .first()\n .css('transform', transforms.next);\n } else if (this.swipeDirection === 'vertical') {\n if (this.settings.swipeToClose) {\n e?.preventDefault();\n this.$container.addClass('lg-dragging-vertical');\n\n const effects = getVerticalDragEffects(\n distanceY,\n window.innerWidth,\n window.innerHeight,\n );\n this.$backdrop.css('opacity', effects.backdropOpacity);\n $currentSlide.css('transform', effects.transform);\n if (effects.hideUi) {\n this.outer\n .addClass('lg-hide-items')\n .removeClass('lg-components-open');\n }\n }\n }\n }\n\n /**\n * The horizontal delta as rendered: rubber-banded when the drag\n * points past the first/last slide with nothing there (loop counts).\n */\n private getEdgeDragDelta(distanceX: number): number {\n const count = this.galleryItems.length;\n return getEdgeFrictionedDelta(\n distanceX,\n resolveSwipeTarget(\n 'prev',\n this.index,\n count,\n this.settings.loop,\n ) !== null,\n resolveSwipeTarget(\n 'next',\n this.index,\n count,\n this.settings.loop,\n ) !== null,\n this.getDirection(),\n );\n }\n\n /** Resolved reading direction ('auto' is resolved at init). */\n private getDirection(): 'ltr' | 'rtl' {\n return this.settings.direction === 'rtl' ? 'rtl' : 'ltr';\n }\n\n /**\n * Spring the dragged slides back to rest, seeded with the release\n * velocity. Returns false (no spring) for sub-pixel drags.\n */\n private springSlidesBack(deltaX: number, velocityX: number): boolean {\n if (Math.abs(deltaX) < 1) {\n return false;\n }\n const $currentSlide = this.getSlideItem(this.index);\n const $prev = this.outer.find('.lg-prev-slide').first();\n const $next = this.outer.find('.lg-next-slide').first();\n const width = $currentSlide.get().offsetWidth;\n this.stopSlideSpring();\n this.cancelSlideSpring = runSprings(\n [{ from: deltaX, velocity: velocityX, target: 0 }],\n ([x]) => {\n const transforms = getHorizontalDragTransforms(\n x!,\n width,\n this.getDirection(),\n );\n $currentSlide.css('transform', transforms.current);\n $prev.css('transform', transforms.prev);\n $next.css('transform', transforms.next);\n },\n () => {\n this.cancelSlideSpring = undefined;\n this.endDragVisuals();\n },\n );\n return true;\n }\n\n /**\n * Carry the release velocity into a gesture navigation: navigate\n * immediately (events, counter and busy-lock on time; fromTouch\n * classes flip underneath, inline transforms keep the visuals),\n * then spring the same drag geometry until the arriving slide lands\n * at rest. Falls back to a snap-back when navigation declines\n * (busy, or an edge without loop, the 2.x end animation plays).\n */\n private springSlideNavigation(\n verdict: 'next' | 'prev',\n deltaX: number,\n velocityX: number,\n ): boolean {\n const $current = this.getSlideItem(this.index);\n const $prev = this.outer.find('.lg-prev-slide').first();\n const $next = this.outer.find('.lg-next-slide').first();\n const width = $current.get().offsetWidth;\n if (!width) {\n return false;\n }\n\n const prevIndex = this.index;\n if (verdict === 'next') {\n this.goToNextSlide(true);\n } else {\n this.goToPrevSlide(true);\n }\n if (this.index === prevIndex) {\n return this.springSlidesBack(deltaX, velocityX);\n }\n\n // The x at which the arriving neighbor sits exactly at 0 in the\n // drag geometry (gutter included): width + x + (0.15w - 0.1|x|).\n const target =\n (verdict === 'next' ? -1 : 1) *\n (this.getDirection() === 'rtl' ? -1 : 1) *\n ((width * 115) / 110);\n this.stopSlideSpring();\n this.cancelSlideSpring = runSprings(\n [{ from: deltaX, velocity: velocityX, target }],\n ([x]) => {\n const transforms = getHorizontalDragTransforms(\n x!,\n width,\n this.getDirection(),\n );\n $current.css('transform', transforms.current);\n $prev.css('transform', transforms.prev);\n $next.css('transform', transforms.next);\n },\n () => {\n this.cancelSlideSpring = undefined;\n // Hands the slides back AND drops the forced lg-slide\n // geometry (the timer-based restore skips while\n // lg-dragging is on).\n this.endDragVisuals();\n },\n );\n return true;\n }\n\n /**\n * Hand the slides back to CSS after a gesture. The inline transforms\n * go first, while lg-dragging still pins transition-duration to 0s,\n * so the snap from the released position to the slide's resting\n * place lands in a single frame. Dropping the class first animates\n * that snap instead, and the outgoing slide is seen travelling back\n * toward the centre while its fade is still running.\n */\n private endDragVisuals(): void {\n this.outer.find('.lg-item').removeAttr('style');\n // The gesture forced lg-slide geometry onto whatever mode is\n // configured; drop it inside the same suppressed frame. Restoring\n // the mode after the hand-back animates every slide from the\n // slide-mode resting place to the configured one, which is the\n // outgoing slide gliding back to the centre as it fades.\n if (this.settings.mode !== 'lg-slide') {\n this.outer.removeClass('lg-slide');\n }\n // Flush the snap before transitions come back.\n void this.outer.get().offsetHeight;\n this.outer.removeClass('lg-dragging');\n }\n\n /**\n * Spring a non-closing vertical drag back to rest, slide transform\n * and backdrop opacity together, seeded with the release velocity.\n */\n private springVerticalRestore(deltaY: number, velocityY: number): boolean {\n if (Math.abs(deltaY) < 1) {\n return false;\n }\n const $currentSlide = this.getSlideItem(this.index);\n this.stopSlideSpring();\n this.$container.addClass('lg-dragging-vertical');\n this.cancelSlideSpring = runSprings(\n [{ from: deltaY, velocity: velocityY, target: 0 }],\n ([y]) => {\n const effects = getVerticalDragEffects(\n y!,\n window.innerWidth,\n window.innerHeight,\n );\n this.$backdrop.css('opacity', effects.backdropOpacity);\n $currentSlide.css('transform', effects.transform);\n },\n () => {\n this.cancelSlideSpring = undefined;\n this.$container.removeClass('lg-dragging-vertical');\n this.endDragVisuals();\n this.$backdrop.css('opacity', 1);\n },\n );\n return true;\n }\n\n touchEnd(endCoords: Coords, startCoords: Coords, event: TouchEvent): void {\n // Read the release velocity NOW, the work below is deferred a\n // tick, and velocity is defined at the moment the finger lifts.\n const releaseVelocity = getWindowedVelocity(\n this.swipeSamples,\n Date.now(),\n );\n\n // keep slide animation for any mode while dragg/swipe\n if (this.settings.mode !== 'lg-slide') {\n this.outer.addClass('lg-slide');\n }\n\n // set transition duration\n setTimeout(() => {\n this.$container.removeClass('lg-dragging-vertical');\n this.outer\n .removeClass('lg-hide-items')\n .addClass('lg-components-open');\n\n let triggerClick = true;\n let springing = false;\n\n if (this.swipeDirection === 'horizontal') {\n // Navigate past swipeThreshold, a quick flick, or a\n // momentum projection past the midpoint, shared release\n // verdict, all runtimes.\n const verdict = getSwipeReleaseVerdict({\n deltaX: endCoords.pageX - startCoords.pageX,\n velocityX: releaseVelocity.x,\n threshold: this.settings.swipeThreshold,\n flickVelocity: this.settings.flickVelocity,\n viewportWidth: this.outer.get().offsetWidth,\n direction: this.getDirection(),\n });\n // Springs start from the RENDERED delta, rubber-banded\n // at the gallery ends, identical to raw elsewhere.\n const renderedDeltaX = this.getEdgeDragDelta(\n endCoords.pageX - startCoords.pageX,\n );\n if (verdict === 'next' || verdict === 'prev') {\n triggerClick = false;\n springing = this.springSlideNavigation(\n verdict,\n renderedDeltaX,\n releaseVelocity.x,\n );\n } else {\n // Snap back on a spring seeded with the release\n // velocity; lg-dragging stays on (transitions down)\n // until it settles.\n springing = this.springSlidesBack(\n renderedDeltaX,\n releaseVelocity.x,\n );\n }\n } else if (this.swipeDirection === 'vertical') {\n if (\n shouldCloseOnVerticalDrag(\n endCoords.pageY - startCoords.pageY,\n releaseVelocity.y,\n window.innerHeight,\n {\n closable: this.settings.closable,\n swipeToClose: this.settings.swipeToClose,\n },\n )\n ) {\n this.closeGallery();\n return;\n }\n // Only spring back what actually moved. With\n // swipeToClose off (a non-closable gallery, inline being\n // the common case) the drag applied nothing, so springing\n // here would jump the slide to the drag offset and\n // animate it back.\n if (this.settings.swipeToClose) {\n springing = this.springVerticalRestore(\n endCoords.pageY - startCoords.pageY,\n releaseVelocity.y,\n );\n }\n }\n if (!springing) {\n this.endDragVisuals();\n this.$backdrop.css('opacity', 1);\n }\n\n if (\n triggerClick &&\n Math.abs(endCoords.pageX - startCoords.pageX) < 5\n ) {\n // Trigger click if distance is less than 5 pix\n const target = $LG(event.target);\n if (this.isPosterElement(target)) {\n this.LGel.trigger(lGEvents.posterClick);\n }\n }\n\n this.swipeDirection = undefined;\n });\n\n // remove slide class once drag/swipe is completed if mode is not slide\n setTimeout(() => {\n if (\n !this.outer.hasClass('lg-dragging') &&\n this.settings.mode !== 'lg-slide'\n ) {\n this.outer.removeClass('lg-slide');\n }\n }, this.settings.speed + 100);\n }\n\n enableSwipe(): void {\n let startCoords: Coords = {} as Coords;\n let endCoords: Coords = {} as Coords;\n let isMoved = false;\n let isSwiping = false;\n\n if (this.settings.enableSwipe) {\n this.$inner.on('touchstart.lg', (e) => {\n this.dragOrSwipeEnabled = true;\n const $item = this.getSlideItem(this.index);\n if (\n ($LG(e.target).hasClass('lg-item') ||\n $item.get().contains(e.target)) &&\n !this.outer.hasClass('lg-zoomed') &&\n !this.lgBusy &&\n e.touches.length === 1\n ) {\n isSwiping = true;\n this.touchAction = 'swipe';\n // A swipe hijacked by a pinch never reaches its\n // touchend, stale isMoved/endCoords would make the\n // NEXT tap run touchEnd on garbage deltas (same\n // pattern zoomSwipe had).\n isMoved = false;\n endCoords = {} as Coords;\n this.stopSlideSpring();\n this.manageSwipeClass();\n this.swipeSamples = [\n {\n x: e.touches[0].pageX,\n y: e.touches[0].pageY,\n t: Date.now(),\n },\n ];\n startCoords = {\n pageX: e.touches[0].pageX,\n pageY: e.touches[0].pageY,\n };\n }\n });\n\n this.$inner.on('touchmove.lg', (e) => {\n if (\n isSwiping &&\n this.touchAction === 'swipe' &&\n e.touches.length === 1\n ) {\n endCoords = {\n pageX: e.touches[0].pageX,\n pageY: e.touches[0].pageY,\n };\n this.touchMove(startCoords, endCoords, e);\n isMoved = true;\n }\n });\n\n this.$inner.on('touchend.lg', (event: TouchEvent) => {\n if (this.touchAction === 'swipe') {\n if (isMoved) {\n isMoved = false;\n this.touchEnd(endCoords, startCoords, event);\n } else if (isSwiping) {\n const target = $LG(event.target);\n if (this.isPosterElement(target)) {\n this.LGel.trigger(lGEvents.posterClick);\n }\n }\n this.touchAction = undefined;\n isSwiping = false;\n }\n });\n }\n }\n\n enableDrag(): void {\n let startCoords: Coords = {} as Coords;\n let endCoords: Coords = {} as Coords;\n let isDraging = false;\n let isMoved = false;\n if (this.settings.enableDrag) {\n this.outer.on('mousedown.lg', (e) => {\n this.dragOrSwipeEnabled = true;\n const $item = this.getSlideItem(this.index);\n if (\n $LG(e.target).hasClass('lg-item') ||\n $item.get().contains(e.target)\n ) {\n if (!this.outer.hasClass('lg-zoomed') && !this.lgBusy) {\n e.preventDefault();\n this.stopSlideSpring();\n this.manageSwipeClass();\n this.swipeSamples = [\n { x: e.pageX, y: e.pageY, t: Date.now() },\n ];\n startCoords = {\n pageX: e.pageX,\n pageY: e.pageY,\n };\n isDraging = true;\n\n // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723\n this.outer.get().scrollLeft += 1;\n this.outer.get().scrollLeft -= 1;\n\n // *\n\n this.outer\n .removeClass('lg-grab')\n .addClass('lg-grabbing');\n\n this.LGel.trigger(lGEvents.dragStart);\n }\n }\n });\n\n $LG(window).on(`mousemove.lg.global${this.lgId}`, (e) => {\n if (isDraging && this.lgOpened) {\n isMoved = true;\n endCoords = {\n pageX: e.pageX,\n pageY: e.pageY,\n };\n this.touchMove(startCoords, endCoords);\n this.LGel.trigger(lGEvents.dragMove);\n }\n });\n\n $LG(window).on(`mouseup.lg.global${this.lgId}`, (event) => {\n if (!this.lgOpened) {\n return;\n }\n const target = $LG(event.target);\n if (isMoved) {\n isMoved = false;\n this.touchEnd(endCoords, startCoords, event);\n this.LGel.trigger(lGEvents.dragEnd);\n } else if (this.isPosterElement(target)) {\n this.LGel.trigger(lGEvents.posterClick);\n }\n\n // Prevent execution on click\n if (isDraging) {\n isDraging = false;\n this.outer.removeClass('lg-grabbing').addClass('lg-grab');\n }\n });\n }\n }\n\n triggerPosterClick(): void {\n this.$inner.on('click.lg', (event) => {\n if (\n !this.dragOrSwipeEnabled &&\n this.isPosterElement($LG(event.target))\n ) {\n this.LGel.trigger(lGEvents.posterClick);\n }\n });\n }\n\n manageSwipeClass(): void {\n let _touchNext = this.index + 1;\n let _touchPrev = this.index - 1;\n if (this.settings.loop && this.galleryItems.length > 2) {\n if (this.index === 0) {\n _touchPrev = this.galleryItems.length - 1;\n } else if (this.index === this.galleryItems.length - 1) {\n _touchNext = 0;\n }\n }\n\n this.outer.find('.lg-item').removeClass('lg-next-slide lg-prev-slide');\n if (_touchPrev > -1) {\n this.getSlideItem(_touchPrev).addClass('lg-prev-slide');\n }\n\n this.getSlideItem(_touchNext).addClass('lg-next-slide');\n }\n\n /**\n * Go to next slide\n * @param {Boolean} fromTouch - true if slide function called via touch event\n * @category lGPublicMethods\n * @example\n * const plugin = lightGallery();\n * plugin.goToNextSlide();\n * @see <a href=\"/demos/methods/\">Demo</a>\n */\n goToNextSlide(fromTouch?: boolean): void {\n let _loop = this.settings.loop;\n if (fromTouch && this.galleryItems.length < 3) {\n _loop = false;\n }\n\n if (!this.lgBusy) {\n if (this.index + 1 < this.galleryItems.length) {\n this.index++;\n this.LGel.trigger(lGEvents.beforeNextSlide, {\n index: this.index,\n });\n this.slide(this.index, !!fromTouch, false, 'next');\n } else {\n if (_loop) {\n this.index = 0;\n this.LGel.trigger(lGEvents.beforeNextSlide, {\n index: this.index,\n });\n this.slide(this.index, !!fromTouch, false, 'next');\n } else if (this.settings.slideEndAnimation && !fromTouch) {\n this.outer.addClass('lg-right-end');\n setTimeout(() => {\n this.outer.removeClass('lg-right-end');\n }, 400);\n }\n }\n }\n }\n\n /**\n * Go to previous slides\n * @param {Boolean} fromTouch - true if slide function called via touch event\n * @category lGPublicMethods\n * @example\n * const plugin = lightGallery({});\n * plugin.goToPrevSlide();\n * @see <a href=\"/demos/methods/\">Demo</a>\n *\n */\n goToPrevSlide(fromTouch?: boolean): void {\n let _loop = this.settings.loop;\n if (fromTouch && this.galleryItems.length < 3) {\n _loop = false;\n }\n\n if (!this.lgBusy) {\n if (this.index > 0) {\n this.index--;\n this.LGel.trigger(lGEvents.beforePrevSlide, {\n index: this.index,\n fromTouch,\n });\n this.slide(this.index, !!fromTouch, false, 'prev');\n } else {\n if (_loop) {\n this.index = this.galleryItems.length - 1;\n this.LGel.trigger(lGEvents.beforePrevSlide, {\n index: this.index,\n fromTouch,\n });\n this.slide(this.index, !!fromTouch, false, 'prev');\n } else if (this.settings.slideEndAnimation && !fromTouch) {\n this.outer.addClass('lg-left-end');\n setTimeout(() => {\n this.outer.removeClass('lg-left-end');\n }, 400);\n }\n }\n }\n }\n\n keyPress(): void {\n $LG(window).on(`keydown.lg.global${this.lgId}`, (e) => {\n if (\n this.lgOpened &&\n this.settings.escKey === true &&\n e.keyCode === 27\n ) {\n e.preventDefault();\n if (\n this.settings.allowMediaOverlap &&\n this.outer.hasClass('lg-can-toggle') &&\n this.outer.hasClass('lg-components-open')\n ) {\n this.outer.removeClass('lg-components-open');\n } else {\n this.closeGallery();\n }\n }\n if (this.lgOpened && this.galleryItems.length > 1) {\n // Physical arrows follow the reading direction.\n const rtl = this.getDirection() === 'rtl';\n if (e.keyCode === 37) {\n e.preventDefault();\n if (rtl) {\n this.goToNextSlide();\n } else {\n this.goToPrevSlide();\n }\n }\n\n if (e.keyCode === 39) {\n e.preventDefault();\n if (rtl) {\n this.goToPrevSlide();\n } else {\n this.goToNextSlide();\n }\n }\n }\n });\n }\n\n arrow(): void {\n this.getElementById('lg-prev').on('click.lg', () => {\n this.goToPrevSlide();\n });\n this.getElementById('lg-next').on('click.lg', () => {\n this.goToNextSlide();\n });\n }\n\n arrowDisable(index: number): void {\n // Disable arrows if settings.hideControlOnEnd is true\n if (!this.settings.loop && this.settings.hideControlOnEnd) {\n const $prev = this.getElementById('lg-prev');\n const $next = this.getElementById('lg-next');\n if (index + 1 === this.galleryItems.length) {\n $next.attr('disabled', 'disabled').addClass('disabled');\n } else {\n $next.removeAttr('disabled').removeClass('disabled');\n }\n\n if (index === 0) {\n $prev.attr('disabled', 'disabled').addClass('disabled');\n } else {\n $prev.removeAttr('disabled').removeClass('disabled');\n }\n }\n }\n\n setTranslate(\n $el: lgQuery,\n xValue: number,\n yValue: number,\n scaleX = 1,\n scaleY = 1,\n ): void {\n $el.css(\n 'transform',\n 'translate3d(' +\n xValue +\n 'px, ' +\n yValue +\n 'px, 0px) scale3d(' +\n scaleX +\n ', ' +\n scaleY +\n ', 1)',\n );\n }\n\n mousewheel(): void {\n let lastCall = 0;\n this.outer.on('wheel.lg', (e) => {\n if (!e.deltaY || this.galleryItems.length < 2) {\n return;\n }\n e.preventDefault();\n const now = new Date().getTime();\n if (now - lastCall < 1000) {\n return;\n }\n lastCall = now;\n if (e.deltaY > 0) {\n this.goToNextSlide();\n } else if (e.deltaY < 0) {\n this.goToPrevSlide();\n }\n });\n }\n\n isSlideElement(target: lgQuery): boolean {\n return (\n target.hasClass('lg-outer') ||\n target.hasClass('lg-item') ||\n target.hasClass('lg-img-wrap') ||\n target.hasClass('lg-img-rotate')\n );\n }\n\n isPosterElement(target: lgQuery): boolean {\n const playButton = this.getSlideItem(this.index)\n .find('.lg-video-play-button')\n .get();\n return (\n target.hasClass('lg-video-poster') ||\n target.hasClass('lg-video-play-button') ||\n (playButton && playButton.contains(target.get()))\n );\n }\n\n /**\n * Maximize minimize inline gallery.\n * @category lGPublicMethods\n */\n toggleMaximize(): void {\n this.getElementById('lg-maximize').on('click.lg', () => {\n this.$container.toggleClass('lg-inline');\n this.refreshOnResize();\n });\n }\n\n invalidateItems(): void {\n for (let index = 0; index < this.items.length; index++) {\n const element = this.items[index];\n const $element = $LG(element);\n $element.off(`click.lgcustom-item-${$element.attr('data-lg-id')}`);\n }\n }\n\n trapFocus(): void {\n this.$container.get().focus({\n preventScroll: true,\n });\n $LG(window).on(`keydown.lg.global${this.lgId}`, (e) => {\n if (!this.lgOpened) {\n return;\n }\n\n const isTabPressed = e.key === 'Tab' || e.keyCode === 9;\n if (!isTabPressed) {\n return;\n }\n const focusableEls = utils.getFocusableElements(\n this.$container.get(),\n );\n const firstFocusableEl = focusableEls[0];\n const lastFocusableEl = focusableEls[focusableEls.length - 1];\n\n if (e.shiftKey) {\n if (document.activeElement === firstFocusableEl) {\n (lastFocusableEl as HTMLElement).focus();\n e.preventDefault();\n }\n } else {\n if (document.activeElement === lastFocusableEl) {\n (firstFocusableEl as HTMLElement).focus();\n e.preventDefault();\n }\n }\n });\n }\n\n manageCloseGallery(): void {\n if (!this.settings.closable) return;\n let mousedown = false;\n this.getElementById('lg-close').on('click.lg', () => {\n this.closeGallery();\n });\n\n if (this.settings.closeOnTap) {\n // If you drag the slide and release outside gallery gets close on chrome\n // for preventing this check mousedown and mouseup happened on .lg-item or lg-outer\n this.outer.on('mousedown.lg', (e) => {\n const target = $LG(e.target);\n if (this.isSlideElement(target)) {\n mousedown = true;\n } else {\n mousedown = false;\n }\n });\n\n this.outer.on('mousemove.lg', () => {\n mousedown = false;\n });\n\n this.outer.on('mouseup.lg', (e) => {\n const target = $LG(e.target);\n if (this.isSlideElement(target) && mousedown) {\n if (!this.outer.hasClass('lg-dragging')) {\n this.closeGallery();\n }\n }\n });\n }\n }\n\n /**\n * Close lightGallery if it is opened.\n *\n * @description If closable is false in the settings, you need to pass true via closeGallery method to force close gallery\n * @return returns the estimated time to close gallery completely including the close animation duration\n * @category lGPublicMethods\n * @example\n * const plugin = lightGallery();\n * plugin.closeGallery();\n *\n */\n closeGallery(force?: boolean): number {\n if (!this.lgOpened || (!this.settings.closable && !force)) {\n return 0;\n }\n this.LGel.trigger(lGEvents.beforeClose);\n\n if (this.settings.resetScrollPosition && !this.settings.hideScrollbar) {\n $LG(window).scrollTop(this.prevScrollTop);\n }\n\n const currentItem = this.items[this.index];\n let transform: string | undefined;\n if (this.zoomFromOrigin && currentItem) {\n const { top, bottom } = this.mediaContainerPosition;\n const { __slideVideoInfo, poster } = this.galleryItems[this.index];\n const imageSize = utils.getSize(\n currentItem,\n this.outer,\n top + bottom,\n __slideVideoInfo && poster && this.settings.videoMaxSize,\n );\n transform = this.getOriginTransform(currentItem, imageSize);\n }\n // No thumbnail to fly back to (hidden or collapsed trigger, no\n // lg-size, zoomFromOrigin off, a dynamic gallery): shrink about the\n // stage centre and fade, the mirror of the startClass open.\n if (!transform) {\n transform = getCenterCloseTransform();\n this.outer.addClass('lg-close-to-center');\n }\n if (transform) {\n this.outer.addClass('lg-closing lg-zoom-from-image');\n this.getSlideItem(this.index)\n .addClass('lg-start-end-progress')\n .css(\n 'transition-duration',\n this.settings.startAnimationDuration + 'ms',\n )\n .css('transform', transform);\n } else {\n this.outer.addClass('lg-hide-items');\n // lg-zoom-from-image is used for setting the opacity to 1 if zoomFromOrigin is true\n // If the closing item doesn't have the lg-size attribute, remove this class to avoid the closing css conflicts\n this.outer.removeClass('lg-zoom-from-image');\n }\n\n // Unbind all events added by lightGallery\n // @todo\n //this.$el.off('.lg.tm');\n\n this.destroyModules();\n\n this.lGalleryOn = false;\n this.isDummyImageRemoved = false;\n this.zoomFromOrigin = this.settings.zoomFromOrigin;\n\n clearTimeout(this.hideBarTimeout);\n this.hideBarTimeout = false;\n $LG('html').removeClass('lg-on');\n\n this.outer.removeClass('lg-visible lg-components-open');\n\n // Resetting opacity to 0 isd required as vertical swipe to close function adds inline opacity.\n this.$backdrop.removeClass('in').css('opacity', 0);\n\n const removeTimeout = transform\n ? Math.max(\n this.settings.startAnimationDuration,\n this.settings.backdropDuration,\n )\n : this.settings.backdropDuration;\n this.$container.removeClass('lg-show-in');\n\n // Once the closign animation is completed and gallery is invisible\n setTimeout(() => {\n if (transform) {\n this.outer.removeClass('lg-zoom-from-image');\n }\n this.$container.removeClass('lg-show');\n\n // Reset scrollbar\n this.resetScrollBar();\n\n // Need to remove inline opacity as it is used in the stylesheet as well\n this.$backdrop\n .removeAttr('style')\n .css(\n 'transition-duration',\n this.settings.backdropDuration + 'ms',\n );\n\n this.outer.removeClass(\n `lg-closing lg-close-to-center ${this.settings.startClass}`,\n );\n\n this.getSlideItem(this.index).removeClass('lg-start-end-progress');\n this.$inner.empty();\n\n // Clear the announcer so reopening at the same slide is a fresh\n // live-region mutation (otherwise identical text = silence).\n const announcer = this.getElementById('lg-announcer').get();\n if (announcer) {\n announcer.textContent = '';\n }\n\n if (this.lgOpened) {\n this.LGel.trigger(lGEvents.afterClose, {\n instance: this,\n });\n }\n if (this.$container.get()) {\n this.$container.get().blur();\n }\n\n // Return focus to where it was before the gallery opened\n // (dialog pattern; captured only when trapFocus moved it).\n if (this.prevActiveElement && this.prevActiveElement.isConnected) {\n this.prevActiveElement.focus({ preventScroll: true });\n }\n this.prevActiveElement = undefined;\n\n this.lgOpened = false;\n }, removeTimeout + 100);\n return removeTimeout + 100;\n }\n\n initModules(): void {\n this.plugins.forEach((module) => {\n try {\n module.init();\n } catch (err) {\n console.warn(\n `lightGallery:- make sure lightGallery module is properly initiated. See https://www.lightgalleryjs.com/docs/methods/`,\n );\n }\n });\n }\n\n destroyModules(destroy?: true): void {\n this.plugins.forEach((module) => {\n try {\n if (destroy) {\n module.destroy();\n } else {\n module.closeGallery && module.closeGallery();\n }\n } catch (err) {\n console.warn(\n `lightGallery:- make sure lightGallery module is properly destroyed. See https://www.lightgalleryjs.com/docs/methods/`,\n );\n }\n });\n }\n\n /**\n * Refresh lightGallery with new set of children.\n *\n * @description This is useful to update the gallery when the child elements are changed without calling destroy method.\n *\n * If you are using dynamic mode, you can pass the modified array of dynamicEl as the first parameter to refresh the dynamic gallery\n * @see <a href=\"/demos/dynamic-mode/\">Demo</a>\n * @category lGPublicMethods\n * @example\n * const plugin = lightGallery();\n * // Delete or add children, then call\n * plugin.refresh();\n *\n */\n refresh(galleryItems?: GalleryItem[]): void {\n if (!this.settings.dynamic) {\n this.invalidateItems();\n }\n if (galleryItems) {\n this.galleryItems = galleryItems;\n } else {\n this.galleryItems = this.getItems();\n }\n this.updateControls();\n this.openGalleryOnItemClick();\n this.LGel.trigger(lGEvents.updateSlides);\n }\n\n updateControls(): void {\n this.addSlideVideoInfo(this.galleryItems);\n this.updateCounterTotal();\n this.manageSingleSlideClassName();\n }\n\n private destroyGallery(): void {\n this.destroyModules(true);\n if (!this.settings.dynamic) {\n this.invalidateItems();\n }\n $LG(window).off(`.lg.global${this.lgId}`);\n this.LGel.off('.lg');\n this.toolbarOverflow?.destroy();\n this.toolbarOverflow = undefined;\n this.$container.remove();\n }\n\n /**\n * Destroy lightGallery.\n * Destroy lightGallery and its plugin instances completely\n *\n * @description This method also calls CloseGallery function internally. Returns the time takes to completely close and destroy the instance.\n * In case if you want to re-initialize lightGallery right after destroying it, initialize it only once the destroy process is completed.\n * You can use refresh method most of the times.\n * @category lGPublicMethods\n * @example\n * const plugin = lightGallery();\n * plugin.destroy();\n *\n */\n destroy(): number {\n const closeTimeout = this.closeGallery(true);\n if (closeTimeout) {\n setTimeout(this.destroyGallery.bind(this), closeTimeout);\n } else {\n this.destroyGallery();\n }\n return closeTimeout;\n }\n}\n","import { setLicenseKey } from '@lightgallery/headless';\n\nimport { LightGallerySettings } from './lg-settings';\nimport { LightGallery } from './lightgallery';\n\nfunction lightGallery(\n el: HTMLElement,\n options?: LightGallerySettings,\n): LightGallery {\n return new LightGallery(el, options);\n}\n/**\n * Set the license key once for every gallery on the page, before creating\n * them. A gallery's own `licenseKey` still wins.\n * See <a href=\"/docs/license/\">License</a>.\n */\nlightGallery.setLicenseKey = setLicenseKey;\nexport default lightGallery;\nexport type { LightGallery };\nexport type { LgIconName, LgIcons } from './lg-icons';\n"],"names":["__spreadProps","__spreadValues","_a","_lgQuery","index"],"mappings":"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"}