@redot-src/glare 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/README.md +40 -8
  2. package/dist/core/animation.d.ts +7 -0
  3. package/dist/core/bind.d.ts +8 -0
  4. package/dist/core/dom.d.ts +18 -0
  5. package/dist/core/glare.d.ts +65 -0
  6. package/dist/core/idle.d.ts +9 -0
  7. package/dist/core/interactions.d.ts +3 -0
  8. package/dist/core/loaders.d.ts +5 -0
  9. package/dist/core/options.d.ts +5 -0
  10. package/dist/core/registry.d.ts +9 -0
  11. package/dist/core/zoom.d.ts +36 -0
  12. package/dist/defaults.d.ts +5 -5
  13. package/dist/esm.d.ts +3 -0
  14. package/dist/glare.css +1 -1
  15. package/dist/glare.esm.js +1038 -1171
  16. package/dist/glare.esm.js.map +1 -1
  17. package/dist/glare.js +25 -23
  18. package/dist/glare.js.map +1 -1
  19. package/dist/i18n.d.ts +4 -0
  20. package/dist/icons.d.ts +12 -13
  21. package/dist/index.d.ts +5 -7
  22. package/dist/media/detect.d.ts +4 -0
  23. package/dist/media/items.d.ts +6 -0
  24. package/dist/media/providers.d.ts +6 -0
  25. package/dist/modules/fullscreen.d.ts +15 -0
  26. package/dist/modules/gestures.d.ts +45 -0
  27. package/dist/modules/hash.d.ts +22 -0
  28. package/dist/modules/share.d.ts +17 -0
  29. package/dist/modules/slideshow.d.ts +25 -0
  30. package/dist/modules/thumbs.d.ts +22 -0
  31. package/dist/modules/wheel.d.ts +19 -0
  32. package/dist/templates.d.ts +7 -0
  33. package/dist/types.d.ts +117 -131
  34. package/dist/umd.d.ts +3 -0
  35. package/dist/utils/dom.d.ts +20 -0
  36. package/dist/utils/env.d.ts +5 -0
  37. package/dist/utils/object.d.ts +3 -0
  38. package/dist/utils/template.d.ts +5 -0
  39. package/package.json +18 -24
  40. package/dist/defaults.d.ts.map +0 -1
  41. package/dist/fullscreen.d.ts +0 -14
  42. package/dist/fullscreen.d.ts.map +0 -1
  43. package/dist/gestures.d.ts +0 -24
  44. package/dist/gestures.d.ts.map +0 -1
  45. package/dist/hash.d.ts +0 -20
  46. package/dist/hash.d.ts.map +0 -1
  47. package/dist/icons.d.ts.map +0 -1
  48. package/dist/index.d.ts.map +0 -1
  49. package/dist/instance.d.ts +0 -103
  50. package/dist/instance.d.ts.map +0 -1
  51. package/dist/media.d.ts +0 -5
  52. package/dist/media.d.ts.map +0 -1
  53. package/dist/share.d.ts +0 -13
  54. package/dist/share.d.ts.map +0 -1
  55. package/dist/slideshow.d.ts +0 -19
  56. package/dist/slideshow.d.ts.map +0 -1
  57. package/dist/thumbs.d.ts +0 -17
  58. package/dist/thumbs.d.ts.map +0 -1
  59. package/dist/types.d.ts.map +0 -1
  60. package/dist/utils.d.ts +0 -31
  61. package/dist/utils.d.ts.map +0 -1
  62. package/dist/wheel.d.ts +0 -11
  63. package/dist/wheel.d.ts.map +0 -1
package/dist/glare.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"glare.js","sources":["../src/icons.ts","../src/defaults.ts","../src/utils.ts","../src/gestures.ts","../src/fullscreen.ts","../src/hash.ts","../src/media.ts","../src/share.ts","../src/slideshow.ts","../src/thumbs.ts","../src/wheel.ts","../src/instance.ts"],"sourcesContent":["export const icons = {\n close: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M18 6 6 18\"/><path d=\"m6 6 12 12\"/></svg>`,\n next: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"m9 18 6-6-6-6\"/></svg>`,\n prev: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"m15 18-6-6 6-6\"/></svg>`,\n zoomIn: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"11\" cy=\"11\" r=\"8\"/><path d=\"m21 21-4.3-4.3\"/><path d=\"M11 8v6\"/><path d=\"M8 11h6\"/></svg>`,\n zoomOut: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"11\" cy=\"11\" r=\"8\"/><path d=\"m21 21-4.3-4.3\"/><path d=\"M8 11h6\"/></svg>`,\n download: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><polyline points=\"7 10 12 15 17 10\"/><line x1=\"12\" x2=\"12\" y1=\"15\" y2=\"3\"/></svg>`,\n share: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"18\" cy=\"5\" r=\"3\"/><circle cx=\"6\" cy=\"12\" r=\"3\"/><circle cx=\"18\" cy=\"19\" r=\"3\"/><line x1=\"8.59\" x2=\"15.42\" y1=\"13.51\" y2=\"17.49\"/><line x1=\"15.41\" x2=\"8.59\" y1=\"6.51\" y2=\"10.49\"/></svg>`,\n thumbs: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"/><path d=\"M3 9h18\"/><path d=\"M9 21V9\"/></svg>`,\n play: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><polygon points=\"6 3 20 12 6 21 6 3\"/></svg>`,\n pause: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect width=\"4\" height=\"16\" x=\"6\" y=\"4\"/><rect width=\"4\" height=\"16\" x=\"14\" y=\"4\"/></svg>`,\n fullscreen: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M8 3H5a2 2 0 0 0-2 2v3\"/><path d=\"M21 8V5a2 2 0 0 0-2-2h-3\"/><path d=\"M3 16v3a2 2 0 0 0 2 2h3\"/><path d=\"M16 21h3a2 2 0 0 0 2-2v-3\"/></svg>`,\n fullscreenExit: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M8 3v3a2 2 0 0 1-2 2H3\"/><path d=\"M21 8h-3a2 2 0 0 1-2-2V3\"/><path d=\"M3 16h3a2 2 0 0 1 2 2v3\"/><path d=\"M16 21v-3a2 2 0 0 1 2-2h3\"/></svg>`,\n} as const\n","import type { I18nDict, MediaProvider, GlareOptions } from './types'\nimport { icons } from './icons'\n\nexport const i18nEn: I18nDict = {\n CLOSE: 'Close',\n NEXT: 'Next',\n PREV: 'Previous',\n ERROR: 'The requested content cannot be loaded.<br/>Please try again later.',\n PLAY_START: 'Start slideshow',\n PLAY_STOP: 'Pause slideshow',\n FULL_SCREEN: 'Full screen',\n THUMBS: 'Thumbnails',\n DOWNLOAD: 'Download',\n SHARE: 'Share',\n ZOOM: 'Zoom',\n}\n\nexport const defaultMedia: Record<string, MediaProvider> = {\n youtube: {\n matcher:\n /(?:youtube\\.com|youtu\\.be|youtube-nocookie\\.com)\\/(?:watch\\?(?:.*&)?v=|v\\/|u\\/\\w\\/|embed\\/|shorts\\/)?([\\w-]{11})/i,\n type: 'iframe',\n url: (_m, _url) => {\n const id = _m[1]\n return `https://www.youtube-nocookie.com/embed/${id}`\n },\n thumb: (m) => `https://img.youtube.com/vi/${m[1]}/hqdefault.jpg`,\n params: {\n autoplay: 1,\n rel: 0,\n modestbranding: 1,\n playsinline: 1,\n },\n },\n vimeo: {\n matcher: /(?:vimeo\\.com)\\/(?:video\\/)?(\\d+)/i,\n type: 'iframe',\n url: (m) => `https://player.vimeo.com/video/${m[1]}`,\n params: {\n autoplay: 1,\n title: 0,\n byline: 0,\n portrait: 0,\n },\n },\n gmap: {\n matcher:\n /(?:maps\\.)?google\\.([a-z]{2,3}(?:\\.[a-z]{2})?)\\/(?:maps\\/(?:place\\/[^/]+\\/)?@([^/]+)|maps\\?q=([^&]+)|maps\\/search\\/([^/?]+))/i,\n type: 'iframe',\n url: (m) => {\n const tld = m[1]\n if (m[2]) {\n const parts = m[2].split(',')\n const lat = parts[0]\n const lng = parts[1]\n const zoom = parts[2] ? Math.floor(parseFloat(parts[2])) : 14\n return `https://maps.google.${tld}/maps?ll=${lat},${lng}&z=${zoom}&output=embed`\n }\n const query = decodeURIComponent(m[3] || m[4] || '')\n return `https://maps.google.${tld}/maps?q=${encodeURIComponent(query)}&output=embed`\n },\n },\n}\n\nexport const defaults: GlareOptions = {\n closeExisting: false,\n loop: false,\n gutter: 50,\n keyboard: true,\n preventCaptionOverlap: true,\n arrows: true,\n infobar: true,\n smallBtn: 'auto',\n toolbar: 'auto',\n buttons: ['zoom', 'slideshow', 'thumbs', 'share', 'download', 'fullscreen', 'close'],\n idleTime: 3,\n protect: false,\n modal: false,\n image: {\n preload: false,\n },\n ajax: {\n settings: {\n headers: {\n 'X-Requested-With': 'XMLHttpRequest',\n },\n },\n },\n iframe: {\n preload: true,\n css: {},\n attr: {\n allowfullscreen: 'true',\n allow: 'autoplay; fullscreen; picture-in-picture',\n },\n tpl: '<iframe class=\"glare-iframe\" allowfullscreen allow=\"autoplay; fullscreen; picture-in-picture\" src=\"\"></iframe>',\n },\n video: {\n tpl:\n '<video class=\"glare-video\" controls playsinline controlsList=\"nodownload\" poster=\"{{poster}}\">' +\n '<source src=\"{{src}}\" type=\"{{format}}\"/>' +\n 'Your browser does not support HTML5 video.' +\n '</video>',\n format: '',\n autoStart: true,\n },\n defaultType: 'image',\n animationEffect: 'zoom',\n animationDuration: 366,\n zoomOpacity: 'auto',\n transitionEffect: 'fade',\n transitionDuration: 366,\n slideClass: '',\n baseClass: '',\n parentEl: 'body',\n hideScrollbar: true,\n autoFocus: true,\n backFocus: true,\n trapFocus: true,\n fullScreen: {\n autoStart: false,\n },\n touch: {\n vertical: true,\n momentum: true,\n },\n hash: true,\n media: defaultMedia,\n slideShow: {\n autoStart: false,\n speed: 3000,\n },\n thumbs: {\n autoStart: false,\n hideOnClose: true,\n parentEl: '.glare-container',\n axis: 'y',\n },\n share: true,\n wheel: 'auto',\n clickContent: function (current) {\n return current.type === 'image' ? 'zoom' : false\n },\n clickSlide: 'close',\n clickOutside: 'close',\n dblclickContent: false,\n dblclickSlide: false,\n dblclickOutside: false,\n mobile: {\n preventCaptionOverlap: false,\n idleTime: false,\n clickContent: function (current) {\n return current.type === 'image' ? 'toggleControls' : false\n },\n clickSlide: function (current) {\n return current.type === 'image' ? 'toggleControls' : 'close'\n },\n dblclickContent: function (current) {\n return current.type === 'image' ? 'zoom' : false\n },\n dblclickSlide: function (current) {\n return current.type === 'image' ? 'zoom' : false\n },\n },\n lang: 'en',\n i18n: {\n en: i18nEn,\n },\n spinnerTpl: '<div class=\"glare-spinner\" role=\"status\" aria-label=\"Loading\"></div>',\n errorTpl: '<div class=\"glare-error\"><p>{{ERROR}}</p></div>',\n baseTpl: `\n <div class=\"glare-container\" role=\"dialog\" aria-modal=\"true\" tabindex=\"-1\">\n <div class=\"glare-bg\"></div>\n <div class=\"glare-inner\">\n <div class=\"glare-infobar\"><span class=\"glare-infobar-index\"></span></div>\n <div class=\"glare-toolbar\"></div>\n <div class=\"glare-navigation\">\n <button type=\"button\" class=\"glare-button glare-button--prev\" data-glare-prev title=\"{{PREV}}\" aria-label=\"{{PREV}}\">${icons.prev}</button>\n <button type=\"button\" class=\"glare-button glare-button--next\" data-glare-next title=\"{{NEXT}}\" aria-label=\"{{NEXT}}\">${icons.next}</button>\n </div>\n <div class=\"glare-stage\"></div>\n <div class=\"glare-caption\"></div>\n </div>\n </div>\n `,\n btnTpl: {\n download: `<a class=\"glare-button glare-button--download\" data-glare-download download title=\"{{DOWNLOAD}}\" aria-label=\"{{DOWNLOAD}}\" href=\"javascript:;\">${icons.download}</a>`,\n zoom: `<button type=\"button\" class=\"glare-button glare-button--zoom\" data-glare-zoom title=\"{{ZOOM}}\" aria-label=\"{{ZOOM}}\">${icons.zoomIn}</button>`,\n close: `<button type=\"button\" class=\"glare-button glare-button--close\" data-glare-close title=\"{{CLOSE}}\" aria-label=\"{{CLOSE}}\">${icons.close}</button>`,\n share: `<button type=\"button\" class=\"glare-button glare-button--share\" data-glare-share title=\"{{SHARE}}\" aria-label=\"{{SHARE}}\">${icons.share}</button>`,\n thumbs: `<button type=\"button\" class=\"glare-button glare-button--thumbs\" data-glare-thumbs title=\"{{THUMBS}}\" aria-label=\"{{THUMBS}}\">${icons.thumbs}</button>`,\n slideshow: `<button type=\"button\" class=\"glare-button glare-button--slideshow\" data-glare-slideshow title=\"{{PLAY_START}}\" aria-label=\"{{PLAY_START}}\">${icons.play}</button>`,\n fullscreen: `<button type=\"button\" class=\"glare-button glare-button--fullscreen\" data-glare-fullscreen title=\"{{FULL_SCREEN}}\" aria-label=\"{{FULL_SCREEN}}\">${icons.fullscreen}</button>`,\n smallBtn: `<button type=\"button\" class=\"glare-button glare-close-small\" data-glare-close title=\"{{CLOSE}}\" aria-label=\"{{CLOSE}}\">${icons.close}</button>`,\n },\n}\n","export function isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nexport function deepMerge<T extends Record<string, unknown>>(\n target: T,\n ...sources: Array<Partial<T> | Record<string, unknown> | undefined | null | false>\n): T {\n const result: Record<string, unknown> = { ...target }\n\n for (const source of sources) {\n if (!source || typeof source !== 'object') continue\n for (const [key, value] of Object.entries(source)) {\n if (value === undefined) continue\n const existing = result[key]\n if (isObject(existing) && isObject(value) && !Array.isArray(value)) {\n result[key] = deepMerge(\n existing as Record<string, unknown>,\n value as Record<string, unknown>,\n )\n } else {\n result[key] = value\n }\n }\n }\n\n return result as T\n}\n\nexport function $(\n selector: string,\n context: ParentNode = document,\n): HTMLElement | null {\n return context.querySelector(selector)\n}\n\nexport function $$(\n selector: string,\n context: ParentNode = document,\n): HTMLElement[] {\n return Array.from(context.querySelectorAll(selector))\n}\n\nexport function createEl<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n className?: string,\n html?: string,\n): HTMLElementTagNameMap[K] {\n const el = document.createElement(tag)\n if (className) el.className = className\n if (html !== undefined) el.innerHTML = html\n return el\n}\n\nexport function setAttributes(\n el: HTMLElement,\n attrs: Record<string, string | number | boolean | null | undefined>,\n): void {\n for (const [key, value] of Object.entries(attrs)) {\n if (value === null || value === undefined || value === false) {\n el.removeAttribute(key)\n } else if (value === true) {\n el.setAttribute(key, '')\n } else {\n el.setAttribute(key, String(value))\n }\n }\n}\n\nexport function on<K extends keyof HTMLElementEventMap>(\n el: EventTarget,\n type: K,\n handler: (event: HTMLElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n): () => void\nexport function on(\n el: EventTarget,\n type: string,\n handler: EventListener,\n options?: boolean | AddEventListenerOptions,\n): () => void\nexport function on(\n el: EventTarget,\n type: string,\n handler: EventListener,\n options?: boolean | AddEventListenerOptions,\n): () => void {\n el.addEventListener(type, handler, options)\n return () => el.removeEventListener(type, handler, options)\n}\n\nexport function once(\n el: EventTarget,\n type: string,\n handler: EventListener,\n options?: boolean | AddEventListenerOptions,\n): () => void {\n const wrapped: EventListener = (event) => {\n off()\n handler(event)\n }\n const off = on(el, type, wrapped, options)\n return off\n}\n\nexport function css(\n el: HTMLElement,\n styles: Partial<CSSStyleDeclaration> | Record<string, string | number | null>,\n): void {\n for (const [key, value] of Object.entries(styles)) {\n if (value === null || value === undefined) {\n el.style.removeProperty(kebab(key))\n } else {\n ;(el.style as unknown as Record<string, string>)[key] = String(value)\n }\n }\n}\n\nexport function kebab(str: string): string {\n return str.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`)\n}\n\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value))\n}\n\nexport function isMobile(): boolean {\n return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(\n navigator.userAgent,\n ) || (navigator.maxTouchPoints > 1 && window.matchMedia('(pointer: coarse)').matches)\n}\n\nexport function getScrollbarWidth(): number {\n return window.innerWidth - document.documentElement.clientWidth\n}\n\nexport function lockScroll(lock: boolean): void {\n const html = document.documentElement\n if (lock) {\n const width = getScrollbarWidth()\n html.classList.add('glare-lock')\n if (width > 0) html.style.marginRight = `${width}px`\n } else if (!document.querySelector('.glare-container')) {\n html.classList.remove('glare-lock')\n html.style.marginRight = ''\n }\n}\n\nexport function translate(\n template: string,\n dict: Record<string, string>,\n): string {\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key: string) => dict[key] ?? '')\n}\n\nexport function getOffset(el: HTMLElement): DOMRect {\n return el.getBoundingClientRect()\n}\n\nexport function getCenter(el: HTMLElement): { x: number; y: number } {\n const rect = getOffset(el)\n return {\n x: rect.left + rect.width / 2,\n y: rect.top + rect.height / 2,\n }\n}\n\nexport function requestAnimFrame(cb: FrameRequestCallback): number {\n return window.requestAnimationFrame(cb)\n}\n\nexport function nextFrame(cb: () => void): void {\n requestAnimFrame(() => requestAnimFrame(cb))\n}\n\nexport function parseDataOptions(el: HTMLElement): Record<string, unknown> {\n const raw = el.getAttribute('data-options') || el.getAttribute('data-glare-options')\n if (!raw) return {}\n try {\n return JSON.parse(raw) as Record<string, unknown>\n } catch {\n return {}\n }\n}\n\nexport function getAttr(\n el: HTMLElement,\n names: string[],\n): string | null {\n for (const name of names) {\n const value = el.getAttribute(name)\n if (value !== null && value !== '') return value\n }\n return null\n}\n\nexport function toArray<T>(value: T | T[] | null | undefined): T[] {\n if (value == null) return []\n return Array.isArray(value) ? value : [value]\n}\n\nexport function uniqueId(prefix = 'glare'): string {\n return `${prefix}-${Math.random().toString(36).slice(2, 9)}`\n}\n\nexport function prefersReducedMotion(): boolean {\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches\n}\n\nexport function loadImage(src: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image()\n img.onload = () => resolve(img)\n img.onerror = () => reject(new Error(`Failed to load image: ${src}`))\n img.src = src\n })\n}\n\nexport function buildQuery(params: Record<string, string | number | boolean>): string {\n return Object.entries(params)\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)\n .join('&')\n}\n","import type { GlareInstance, SlideItem } from './types'\nimport { clamp, on } from './utils'\n\ninterface Point {\n x: number\n y: number\n}\n\ninterface GestureState {\n isPanning: boolean\n isSwiping: boolean\n isZooming: boolean\n startPoints: Point[]\n lastPoints: Point[]\n startDistance: number\n startScale: number\n startTranslate: Point\n currentTranslate: Point\n scale: number\n startTime: number\n moved: boolean\n}\n\nfunction distance(a: Point, b: Point): number {\n const dx = a.x - b.x\n const dy = a.y - b.y\n return Math.hypot(dx, dy)\n}\n\nfunction midpoint(a: Point, b: Point): Point {\n return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 }\n}\n\nfunction getPoints(event: TouchEvent | MouseEvent): Point[] {\n if ('touches' in event) {\n return Array.from(event.touches).map((t) => ({ x: t.clientX, y: t.clientY }))\n }\n return [{ x: event.clientX, y: event.clientY }]\n}\n\nexport class Gestures {\n private instance: GlareInstance & {\n getContentEl: () => HTMLElement | null\n getImageWrap: () => HTMLElement | null\n applyZoom: (scale: number, x: number, y: number, animate?: boolean) => void\n getZoomState: () => { scale: number; x: number; y: number; min: number; max: number }\n onSwipe: (dx: number, dy: number, done: boolean, velocity?: Point) => void\n opts: { touch?: false | { vertical?: boolean; momentum?: boolean } }\n }\n\n private state: GestureState = {\n isPanning: false,\n isSwiping: false,\n isZooming: false,\n startPoints: [],\n lastPoints: [],\n startDistance: 0,\n startScale: 1,\n startTranslate: { x: 0, y: 0 },\n currentTranslate: { x: 0, y: 0 },\n scale: 1,\n startTime: 0,\n moved: false,\n }\n\n private cleanups: Array<() => void> = []\n private pointerId: number | null = null\n\n constructor(instance: Gestures['instance']) {\n this.instance = instance\n }\n\n attach(stage: HTMLElement): void {\n this.detach()\n\n this.cleanups.push(\n on(stage, 'pointerdown', (e) => this.onPointerDown(e as PointerEvent), { passive: false }),\n on(window, 'pointermove', (e) => this.onPointerMove(e as PointerEvent), { passive: false }),\n on(window, 'pointerup', (e) => this.onPointerUp(e as PointerEvent)),\n on(window, 'pointercancel', (e) => this.onPointerUp(e as PointerEvent)),\n on(stage, 'touchstart', (e) => this.onTouchStart(e as TouchEvent), { passive: false }),\n on(stage, 'touchmove', (e) => this.onTouchMove(e as TouchEvent), { passive: false }),\n on(stage, 'touchend', (e) => this.onTouchEnd(e as TouchEvent)),\n on(stage, 'touchcancel', (e) => this.onTouchEnd(e as TouchEvent)),\n )\n }\n\n detach(): void {\n this.cleanups.forEach((fn) => fn())\n this.cleanups = []\n }\n\n private touchEnabled(): boolean {\n return this.instance.opts.touch !== false\n }\n\n private onPointerDown(event: PointerEvent): void {\n if (!this.touchEnabled()) return\n if (event.pointerType === 'touch') return // handled by touch events for multi-touch\n if (event.button !== 0) return\n\n const target = event.target as HTMLElement\n if (target.closest('a, button, input, textarea, select, .glare-thumbs')) return\n\n this.pointerId = event.pointerId\n const points = [{ x: event.clientX, y: event.clientY }]\n this.begin(points)\n }\n\n private onPointerMove(event: PointerEvent): void {\n if (this.pointerId !== event.pointerId) return\n this.move([{ x: event.clientX, y: event.clientY }], event)\n }\n\n private onPointerUp(event: PointerEvent): void {\n if (this.pointerId !== event.pointerId) return\n this.pointerId = null\n this.end([{ x: event.clientX, y: event.clientY }])\n }\n\n private onTouchStart(event: TouchEvent): void {\n if (!this.touchEnabled()) return\n const target = event.target as HTMLElement\n if (target.closest('a, button, input, textarea, select, .glare-thumbs')) return\n this.begin(getPoints(event))\n }\n\n private onTouchMove(event: TouchEvent): void {\n this.move(getPoints(event), event)\n }\n\n private onTouchEnd(event: TouchEvent): void {\n this.end(getPoints(event))\n }\n\n private begin(points: Point[]): void {\n const zoom = this.instance.getZoomState()\n this.state = {\n isPanning: false,\n isSwiping: false,\n isZooming: points.length >= 2,\n startPoints: points,\n lastPoints: points,\n startDistance: points.length >= 2 ? distance(points[0], points[1]) : 0,\n startScale: zoom.scale,\n startTranslate: { x: zoom.x, y: zoom.y },\n currentTranslate: { x: zoom.x, y: zoom.y },\n scale: zoom.scale,\n startTime: performance.now(),\n moved: false,\n }\n }\n\n private move(points: Point[], event: Event): void {\n if (!this.state.startPoints.length) return\n const current = this.instance.current\n if (!current) return\n\n if (points.length >= 2 && this.state.startPoints.length >= 2) {\n event.preventDefault()\n this.state.isZooming = true\n this.state.moved = true\n const dist = distance(points[0], points[1])\n const scale = clamp(\n (dist / (this.state.startDistance || dist)) * this.state.startScale,\n 1,\n 5,\n )\n const mid = midpoint(points[0], points[1])\n this.state.scale = scale\n this.instance.applyZoom(scale, mid.x, mid.y, false)\n this.state.lastPoints = points\n return\n }\n\n if (!points.length || !this.state.startPoints.length) return\n\n const dx = points[0].x - this.state.startPoints[0].x\n const dy = points[0].y - this.state.startPoints[0].y\n const absX = Math.abs(dx)\n const absY = Math.abs(dy)\n\n if (!this.state.moved && absX < 6 && absY < 6) return\n this.state.moved = true\n\n const zoom = this.instance.getZoomState()\n const canPan = zoom.scale > 1.01 && current.type === 'image'\n\n if (canPan || this.state.isPanning) {\n event.preventDefault()\n this.state.isPanning = true\n const x = this.state.startTranslate.x + dx\n const y = this.state.startTranslate.y + dy\n this.state.currentTranslate = { x, y }\n this.instance.applyZoom(zoom.scale, x, y, false)\n } else {\n const touchOpts = this.instance.opts.touch\n const allowVertical = touchOpts && typeof touchOpts === 'object' ? touchOpts.vertical !== false : true\n if (!allowVertical && absY > absX) return\n event.preventDefault()\n this.state.isSwiping = true\n this.instance.onSwipe(dx, dy, false)\n }\n\n this.state.lastPoints = points\n }\n\n private end(points: Point[]): void {\n if (!this.state.startPoints.length) return\n\n const elapsed = Math.max(performance.now() - this.state.startTime, 1)\n const last = points[0] || this.state.lastPoints[0] || this.state.startPoints[0]\n const start = this.state.startPoints[0]\n const dx = last.x - start.x\n const dy = last.y - start.y\n const velocity = { x: dx / elapsed, y: dy / elapsed }\n\n if (this.state.isSwiping) {\n this.instance.onSwipe(dx, dy, true, velocity)\n } else if (this.state.isPanning) {\n const touchOpts = this.instance.opts.touch\n const momentum = touchOpts && typeof touchOpts === 'object' ? touchOpts.momentum !== false : true\n if (momentum) {\n const zoom = this.instance.getZoomState()\n this.instance.applyZoom(\n zoom.scale,\n this.state.currentTranslate.x + velocity.x * 120,\n this.state.currentTranslate.y + velocity.y * 120,\n true,\n )\n }\n }\n\n this.state.startPoints = []\n this.state.isPanning = false\n this.state.isSwiping = false\n this.state.isZooming = false\n }\n\n wasMoved(): boolean {\n return this.state.moved\n }\n\n resetMoved(): void {\n this.state.moved = false\n }\n}\n\nexport type { SlideItem }\n","import type { GlareInstance } from './types'\nimport { icons } from './icons'\nimport { on } from './utils'\n\ntype FsDoc = Document & {\n webkitFullscreenElement?: Element\n mozFullScreenElement?: Element\n msFullscreenElement?: Element\n webkitExitFullscreen?: () => Promise<void>\n mozCancelFullScreen?: () => Promise<void>\n msExitFullscreen?: () => Promise<void>\n}\n\ntype FsEl = HTMLElement & {\n webkitRequestFullscreen?: () => Promise<void>\n mozRequestFullScreen?: () => Promise<void>\n msRequestFullscreen?: () => Promise<void>\n}\n\nexport class FullScreen {\n private instance: GlareInstance\n private cleanups: Array<() => void> = []\n\n constructor(instance: GlareInstance) {\n this.instance = instance\n }\n\n init(): void {\n this.cleanups.push(\n on(document, 'fullscreenchange', () => this.sync()),\n on(document, 'webkitfullscreenchange', () => this.sync()),\n )\n }\n\n isFullscreen(): boolean {\n const doc = document as FsDoc\n return !!(\n document.fullscreenElement ||\n doc.webkitFullscreenElement ||\n doc.mozFullScreenElement ||\n doc.msFullscreenElement\n )\n }\n\n request(): void {\n const el = (this.instance.$refs.container || document.documentElement) as FsEl\n const req =\n el.requestFullscreen ||\n el.webkitRequestFullscreen ||\n el.mozRequestFullScreen ||\n el.msRequestFullscreen\n void req?.call(el)\n }\n\n exit(): void {\n const doc = document as FsDoc\n const exit =\n document.exitFullscreen ||\n doc.webkitExitFullscreen ||\n doc.mozCancelFullScreen ||\n doc.msExitFullscreen\n if (this.isFullscreen()) void exit?.call(document)\n }\n\n toggle(): void {\n if (this.isFullscreen()) this.exit()\n else this.request()\n }\n\n private sync(): void {\n const active = this.isFullscreen()\n this.instance.$refs.container?.classList.toggle('glare-is-fullscreen', active)\n const btn = this.instance.$refs.container?.querySelector(\n '[data-glare-fullscreen]',\n ) as HTMLElement | null\n if (btn) {\n btn.innerHTML = active ? icons.fullscreenExit : icons.fullscreen\n btn.classList.toggle('is-active', active)\n }\n }\n\n destroy(): void {\n if (this.isFullscreen()) this.exit()\n this.cleanups.forEach((fn) => fn())\n this.cleanups = []\n }\n}\n","import type { GlareInstance } from './types'\nimport { on } from './utils'\n\nfunction parseHash(): { gallery: string; index: number } | null {\n const hash = window.location.hash.replace(/^#/, '')\n if (!hash) return null\n // Formats: gallery-1 | gallery/2 | glare-gallery-1\n const match = hash.match(/^(?:glare-)?(.+?)(?:-|\\/)(\\d+)$/)\n if (!match) return null\n return { gallery: match[1], index: Math.max(0, parseInt(match[2], 10) - 1) }\n}\n\nexport function getGalleryHash(gallery: string, index: number): string {\n return `${gallery}-${index + 1}`\n}\n\nexport class Hash {\n private instance: GlareInstance\n private gallery: string\n private cleanups: Array<() => void> = []\n private skipping = false\n\n constructor(instance: GlareInstance, gallery: string) {\n this.instance = instance\n this.gallery = gallery || 'gallery'\n }\n\n static parse = parseHash\n\n init(): void {\n this.cleanups.push(\n on(window, 'hashchange', () => {\n if (this.skipping) return\n const parsed = parseHash()\n if (!parsed || parsed.gallery !== this.gallery) {\n if (this.instance.isActive) this.instance.close()\n return\n }\n if (parsed.index !== this.instance.currIndex) {\n this.instance.jumpTo(parsed.index)\n }\n }),\n )\n this.update()\n }\n\n update(index = this.instance.currIndex): void {\n if (!this.gallery) return\n const next = getGalleryHash(this.gallery, index)\n if (window.location.hash.replace(/^#/, '') === next) return\n this.skipping = true\n const url = `${window.location.pathname}${window.location.search}#${next}`\n window.history.replaceState(null, '', url)\n queueMicrotask(() => {\n this.skipping = false\n })\n }\n\n clear(): void {\n const parsed = parseHash()\n if (parsed && parsed.gallery === this.gallery) {\n this.skipping = true\n const url = `${window.location.pathname}${window.location.search}`\n window.history.replaceState(null, '', url)\n queueMicrotask(() => {\n this.skipping = false\n })\n }\n }\n\n destroy(): void {\n this.clear()\n this.cleanups.forEach((fn) => fn())\n this.cleanups = []\n }\n}\n","import type { ContentType, MediaProvider, GlareOptions, SlideItem, SlideSource } from './types'\nimport { buildQuery, deepMerge } from './utils'\n\nconst IMAGE_EXT = /\\.(avif|bmp|gif|jpe?g|png|svg|webp|ico)(\\?.*)?$/i\nconst VIDEO_EXT = /\\.(mp4|webm|ogg|ogv|mov|m4v)(\\?.*)?$/i\nconst PDF_EXT = /\\.pdf(\\?.*)?$/i\n\nexport function detectType(src: string, explicit?: ContentType): ContentType {\n if (explicit) return explicit\n if (!src) return 'html'\n if (src.startsWith('#') || src.startsWith('.')) return 'inline'\n if (IMAGE_EXT.test(src)) return 'image'\n if (VIDEO_EXT.test(src)) return 'video'\n if (PDF_EXT.test(src)) return 'iframe'\n if (/^https?:\\/\\//i.test(src) || src.startsWith('//') || src.startsWith('/')) {\n return 'iframe'\n }\n return 'html'\n}\n\nfunction applyMediaProvider(\n src: string,\n media: Record<string, MediaProvider> | undefined,\n): Partial<SlideSource> | null {\n if (!media) return null\n for (const provider of Object.values(media)) {\n const match = src.match(provider.matcher)\n if (!match) continue\n\n let url = src\n if (typeof provider.url === 'function') {\n url = provider.url(match, src)\n } else if (typeof provider.url === 'string') {\n url = provider.url.replace(/\\$(\\d+)/g, (_, n) => match[Number(n)] || '')\n }\n\n if (provider.params) {\n const sep = url.includes('?') ? '&' : '?'\n url += sep + buildQuery(provider.params)\n }\n\n let thumb: string | undefined\n if (typeof provider.thumb === 'function') {\n thumb = provider.thumb(match, src)\n } else if (typeof provider.thumb === 'string') {\n thumb = provider.thumb.replace(/\\$(\\d+)/g, (_, n) => match[Number(n)] || '')\n }\n\n return {\n src: url,\n type: (provider.type as ContentType) || 'iframe',\n thumb,\n }\n }\n return null\n}\n\nexport function normalizeItem(\n source: SlideSource | string,\n index: number,\n opts: GlareOptions,\n): SlideItem {\n const raw: SlideSource =\n typeof source === 'string' ? { src: source } : { ...source }\n\n let src = raw.src || ''\n let type = raw.type\n let thumb = raw.thumb\n\n if (raw.html && !src) {\n type = 'html'\n src = ''\n }\n\n const mediaHit = src ? applyMediaProvider(src, opts.media) : null\n if (mediaHit) {\n src = mediaHit.src || src\n type = (mediaHit.type as ContentType) || type\n thumb = thumb || mediaHit.thumb\n }\n\n if (!type) {\n if (raw.content || raw.html) type = 'html'\n else type = detectType(src, opts.defaultType)\n }\n\n // Treat unknown remote URLs that look like pages as iframe;\n // images/videos already caught by extension.\n if (type === 'iframe' && IMAGE_EXT.test(src)) type = 'image'\n if (type === 'iframe' && VIDEO_EXT.test(src)) type = 'video'\n\n const item: SlideItem = {\n ...raw,\n index,\n src,\n type,\n thumb,\n caption: raw.caption ?? raw.title ?? '',\n isLoaded: false,\n isComplete: false,\n hasError: false,\n canZoomIn: false,\n canZoomOut: false,\n }\n\n if (raw.opts) {\n item.opts = deepMerge({}, opts, raw.opts) as GlareOptions\n }\n\n return item\n}\n\nexport function itemsFromElements(\n elements: HTMLElement[],\n opts: GlareOptions,\n): SlideItem[] {\n return elements.map((el, index) => {\n const href =\n el.getAttribute('data-src') ||\n el.getAttribute('data-glare-src') ||\n el.getAttribute('href') ||\n ''\n\n const typeAttr = (el.getAttribute('data-type') ||\n el.getAttribute('data-glare-type') ||\n undefined) as ContentType | undefined\n\n const caption =\n el.getAttribute('data-caption') ||\n el.getAttribute('data-glare-caption') ||\n el.getAttribute('title') ||\n ''\n\n const thumb =\n el.getAttribute('data-thumb') ||\n el.getAttribute('data-glare-thumb') ||\n el.querySelector('img')?.getAttribute('src') ||\n undefined\n\n const width = el.getAttribute('data-width') || undefined\n const height = el.getAttribute('data-height') || undefined\n const poster = el.getAttribute('data-poster') || undefined\n const downloadSrc =\n el.getAttribute('data-download-src') ||\n el.getAttribute('data-glare-download') ||\n undefined\n\n let html: string | undefined\n const srcHtml = el.getAttribute('data-html') || el.getAttribute('data-glare-html')\n if (srcHtml) html = srcHtml\n\n const item = normalizeItem(\n {\n src: href,\n type: typeAttr,\n caption,\n thumb,\n width,\n height,\n poster,\n downloadSrc,\n html,\n alt: el.querySelector('img')?.getAttribute('alt') || caption || '',\n $trigger: el,\n },\n index,\n opts,\n )\n\n return item\n })\n}\n","import type { GlareInstance, ShareOptions, SlideItem } from './types'\nimport { createEl, on, translate } from './utils'\n\nconst DEFAULT_TPL = `\n<div class=\"glare-share\">\n <h4 class=\"glare-share-title\">{{SHARE}}</h4>\n <p><a class=\"glare-share-link\" href=\"{{url_facebook}}\" target=\"_blank\" rel=\"noopener\">Facebook</a></p>\n <p><a class=\"glare-share-link\" href=\"{{url_twitter}}\" target=\"_blank\" rel=\"noopener\">X / Twitter</a></p>\n <p><a class=\"glare-share-link\" href=\"{{url_pinterest}}\" target=\"_blank\" rel=\"noopener\">Pinterest</a></p>\n <p><input class=\"glare-share-input\" type=\"text\" value=\"{{url_direct}}\" readonly /></p>\n</div>\n`\n\nexport class Share {\n private instance: GlareInstance\n private opts: ShareOptions\n private $overlay: HTMLElement | null = null\n private cleanups: Array<() => void> = []\n\n constructor(instance: GlareInstance, opts: ShareOptions | true) {\n this.instance = instance\n this.opts = opts === true ? {} : opts\n }\n\n open(): void {\n const current = this.instance.current\n if (!current || !this.instance.$refs.container) return\n\n this.close()\n\n const url = this.resolveUrl(current)\n const encoded = encodeURIComponent(url)\n const media = encodeURIComponent(current.thumb || current.src || url)\n const caption = encodeURIComponent(current.caption || '')\n\n const lang = this.instance.opts.lang || 'en'\n const dict = {\n ...(this.instance.opts.i18n?.en || {}),\n ...(this.instance.opts.i18n?.[lang] || {}),\n url_direct: url,\n url_facebook: `https://www.facebook.com/sharer/sharer.php?u=${encoded}`,\n url_twitter: `https://twitter.com/intent/tweet?url=${encoded}&text=${caption}`,\n url_pinterest: `https://pinterest.com/pin/create/button/?url=${encoded}&media=${media}&description=${caption}`,\n } as Record<string, string>\n\n const html = translate(this.opts.tpl || DEFAULT_TPL, dict)\n this.$overlay = createEl('div', 'glare-share-overlay', html)\n this.instance.$refs.container.appendChild(this.$overlay)\n\n const input = this.$overlay.querySelector('.glare-share-input') as HTMLInputElement | null\n input?.select()\n\n this.cleanups.push(\n on(this.$overlay, 'click', (event) => {\n if (event.target === this.$overlay) this.close()\n }),\n )\n }\n\n close(): void {\n this.cleanups.forEach((fn) => fn())\n this.cleanups = []\n this.$overlay?.remove()\n this.$overlay = null\n }\n\n private resolveUrl(item: SlideItem): string {\n if (typeof this.opts.url === 'function') return this.opts.url(item)\n if (typeof this.opts.url === 'string') return this.opts.url\n if (item.src && /^https?:\\/\\//i.test(item.src)) return item.src\n return window.location.href\n }\n\n destroy(): void {\n this.close()\n }\n}\n","import type { GlareInstance, SlideshowOptions } from './types'\nimport { icons } from './icons'\n\nexport class Slideshow {\n private instance: GlareInstance\n private opts: SlideshowOptions\n private timer: ReturnType<typeof setTimeout> | null = null\n private active = false\n\n constructor(instance: GlareInstance, opts: SlideshowOptions) {\n this.instance = instance\n this.opts = opts\n }\n\n init(): void {\n if (this.opts.autoStart) this.start()\n }\n\n isActive(): boolean {\n return this.active\n }\n\n start(): void {\n if (this.instance.group.length < 2) return\n this.active = true\n this.instance.$refs.container?.classList.add('glare-is-slideshow')\n this.updateButton()\n this.queue()\n }\n\n stop(): void {\n this.active = false\n this.clear()\n this.instance.$refs.container?.classList.remove('glare-is-slideshow')\n this.updateButton()\n }\n\n toggle(): void {\n if (this.active) this.stop()\n else this.start()\n }\n\n private queue(): void {\n this.clear()\n if (!this.active) return\n this.timer = setTimeout(() => {\n if (!this.active) return\n this.instance.next()\n this.queue()\n }, this.opts.speed || 3000)\n }\n\n private clear(): void {\n if (this.timer) {\n clearTimeout(this.timer)\n this.timer = null\n }\n }\n\n private updateButton(): void {\n const btn = this.instance.$refs.container?.querySelector(\n '[data-glare-slideshow]',\n ) as HTMLElement | null\n if (!btn) return\n const label = this.active\n ? this.getLabel('PLAY_STOP')\n : this.getLabel('PLAY_START')\n btn.setAttribute('title', label)\n btn.setAttribute('aria-label', label)\n btn.innerHTML = this.active ? icons.pause : icons.play\n btn.classList.toggle('is-active', this.active)\n }\n\n private getLabel(key: string): string {\n const lang = this.instance.opts.lang || 'en'\n const dict = {\n ...(this.instance.opts.i18n?.en || {}),\n ...(this.instance.opts.i18n?.[lang] || {}),\n } as Record<string, string>\n return dict[key] || key\n }\n\n destroy(): void {\n this.stop()\n }\n}\n","import type { GlareInstance, ThumbsOptions } from './types'\nimport { $, $$, createEl, on } from './utils'\n\nexport class Thumbs {\n isActive = false\n private instance: GlareInstance\n private opts: ThumbsOptions\n private $container: HTMLElement | null = null\n private $list: HTMLElement | null = null\n private cleanups: Array<() => void> = []\n\n constructor(instance: GlareInstance, opts: ThumbsOptions) {\n this.instance = instance\n this.opts = opts\n }\n\n init(): void {\n if (this.instance.group.length < 2) return\n\n const parent =\n typeof this.opts.parentEl === 'string'\n ? $(this.opts.parentEl) || this.instance.$refs.container\n : this.opts.parentEl || this.instance.$refs.container\n\n if (!parent) return\n\n this.$container = createEl('div', `glare-thumbs glare-thumbs--${this.opts.axis || 'y'}`)\n this.$list = createEl('div', 'glare-thumbs-list')\n this.$container.appendChild(this.$list)\n\n for (const item of this.instance.group) {\n const btn = createEl('button', 'glare-thumbs-item') as HTMLButtonElement\n btn.type = 'button'\n btn.setAttribute('aria-label', `Go to slide ${item.index + 1}`)\n btn.dataset.index = String(item.index)\n\n if (item.thumb || (item.type === 'image' && item.src)) {\n const img = createEl('img') as HTMLImageElement\n img.src = item.thumb || item.src\n img.alt = item.alt || item.caption || ''\n img.loading = 'lazy'\n btn.appendChild(img)\n } else {\n btn.textContent = String(item.index + 1)\n }\n\n this.$list.appendChild(btn)\n this.cleanups.push(\n on(btn, 'click', () => {\n this.instance.jumpTo(item.index)\n }),\n )\n }\n\n parent.appendChild(this.$container)\n\n if (this.opts.autoStart) this.show()\n this.focus(this.instance.currIndex)\n }\n\n show(): void {\n if (!this.$container) return\n this.isActive = true\n this.$container.classList.add('glare-thumbs--active')\n this.instance.$refs.container?.classList.add('glare-show-thumbs')\n }\n\n hide(): void {\n if (!this.$container) return\n this.isActive = false\n this.$container.classList.remove('glare-thumbs--active')\n this.instance.$refs.container?.classList.remove('glare-show-thumbs')\n }\n\n toggle(): void {\n if (this.isActive) this.hide()\n else this.show()\n }\n\n focus(index = this.instance.currIndex): void {\n if (!this.$list) return\n $$('.glare-thumbs-item', this.$list).forEach((el) => {\n el.classList.toggle('is-active', Number(el.dataset.index) === index)\n })\n const active = this.$list.querySelector('.is-active') as HTMLElement | null\n active?.scrollIntoView({ block: 'nearest', inline: 'nearest', behavior: 'smooth' })\n }\n\n destroy(): void {\n if (this.opts.hideOnClose !== false) this.hide()\n this.cleanups.forEach((fn) => fn())\n this.cleanups = []\n this.$container?.remove()\n this.$container = null\n this.$list = null\n }\n}\n","import type { GlareInstance } from './types'\nimport { on } from './utils'\n\nexport class WheelNav {\n private instance: GlareInstance\n private mode: boolean | 'auto' | 'slide'\n private cleanups: Array<() => void> = []\n private locked = false\n\n constructor(instance: GlareInstance, mode: boolean | 'auto' | 'slide') {\n this.instance = instance\n this.mode = mode\n }\n\n init(stage: HTMLElement): void {\n if (this.mode === false) return\n this.cleanups.push(\n on(\n stage,\n 'wheel',\n (event) => {\n const e = event as WheelEvent\n if (this.locked) return\n\n const current = this.instance.current\n if (!current) return\n\n if (this.mode === 'auto' && current.type !== 'image') return\n if (current.type === 'image') {\n const zoomed = this.instance.$refs.container?.classList.contains('glare-can-zoom-out')\n if (zoomed) return\n }\n\n e.preventDefault()\n this.locked = true\n if (e.deltaY > 0) this.instance.next()\n else this.instance.prev()\n setTimeout(() => {\n this.locked = false\n }, 350)\n },\n { passive: false },\n ),\n )\n }\n\n destroy(): void {\n this.cleanups.forEach((fn) => fn())\n this.cleanups = []\n }\n}\n","import type {\n ClickAction,\n EventHandler,\n EventName,\n I18nDict,\n GlareInstance,\n GlareOptions,\n SlideItem,\n SlideSource,\n} from './types'\nimport { defaults } from './defaults'\nimport { Gestures } from './gestures'\nimport { FullScreen } from './fullscreen'\nimport { Hash } from './hash'\nimport { icons } from './icons'\nimport { itemsFromElements, normalizeItem } from './media'\nimport { Share } from './share'\nimport { Slideshow } from './slideshow'\nimport { Thumbs } from './thumbs'\nimport {\n $,\n $$,\n clamp,\n createEl,\n css,\n deepMerge,\n getOffset,\n isMobile,\n lockScroll,\n nextFrame,\n on,\n prefersReducedMotion,\n translate,\n} from './utils'\nimport { WheelNav } from './wheel'\n\nlet instanceId = 0\nconst activeStack: Glare[] = []\n\nfunction resolveParent(parentEl: string | HTMLElement | undefined): HTMLElement {\n if (!parentEl) return document.body\n if (typeof parentEl === 'string') return $(parentEl) || document.body\n return parentEl\n}\n\nexport class Glare implements GlareInstance {\n id: number\n group: SlideItem[] = []\n opts: GlareOptions\n current: SlideItem | null = null\n currIndex = 0\n prevIndex = 0\n isActive = false\n isClosing = false\n isAnimating = false\n isIdle = false\n\n $refs: GlareInstance['$refs'] = {\n container: null,\n stage: null,\n bg: null,\n inner: null,\n caption: null,\n toolbar: null,\n infobar: null,\n navigation: null,\n }\n\n SlideShow?: Slideshow\n Thumbs?: Thumbs\n FullScreen?: FullScreen\n\n private galleryName = ''\n private cleanups: Array<() => void> = []\n private idleTimer: ReturnType<typeof setTimeout> | null = null\n private gestures: Gestures | null = null\n private hash: Hash | null = null\n private wheel: WheelNav | null = null\n private share: Share | null = null\n private zoom = { scale: 1, x: 0, y: 0, min: 1, max: 5 }\n private previouslyFocused: HTMLElement | null = null\n private openedFrom: HTMLElement | null = null\n\n constructor(\n items: Array<SlideSource | string> | HTMLElement[],\n options: GlareOptions = {},\n index = 0,\n galleryName = '',\n ) {\n this.id = ++instanceId\n this.galleryName = galleryName\n\n const merged = deepMerge(\n {},\n defaults as Record<string, unknown>,\n options as Record<string, unknown>,\n ) as GlareOptions\n\n if (isMobile() && merged.mobile) {\n this.opts = deepMerge(\n {},\n merged as Record<string, unknown>,\n merged.mobile as Record<string, unknown>,\n ) as GlareOptions\n } else {\n this.opts = merged\n }\n\n if (items.length && items[0] instanceof HTMLElement) {\n this.group = itemsFromElements(items as HTMLElement[], this.opts)\n } else {\n this.group = (items as Array<SlideSource | string>).map((item, i) =>\n normalizeItem(item, i, this.opts),\n )\n }\n\n this.currIndex = clamp(index, 0, Math.max(0, this.group.length - 1))\n }\n\n open(index = this.currIndex): void {\n if (this.isActive) {\n this.jumpTo(index)\n return\n }\n\n if (this.opts.closeExisting) {\n Glare.close(true)\n }\n\n this.currIndex = clamp(index, 0, Math.max(0, this.group.length - 1))\n this.current = this.group[this.currIndex] || null\n this.openedFrom = (this.current?.$trigger as HTMLElement) || null\n this.previouslyFocused = document.activeElement as HTMLElement | null\n\n this.trigger('onInit')\n this.build()\n this.isActive = true\n activeStack.push(this)\n\n if (this.opts.hideScrollbar) lockScroll(true)\n\n this.trigger('onActivate')\n this.trigger('beforeShow', this.current || undefined)\n\n nextFrame(() => {\n this.$refs.container?.classList.add('glare-is-open', 'glare-is-animated')\n this.loadSlide(this.currIndex, true)\n this.bindEvents()\n this.initModules()\n if (this.opts.autoFocus) this.focus()\n this.resetIdle()\n })\n }\n\n close(_event?: Event | null, duration?: number): void {\n if (!this.isActive || this.isClosing) return\n if (this.trigger('beforeClose', this.current || undefined) === false) return\n\n this.isClosing = true\n this.SlideShow?.stop()\n this.clearIdle()\n\n const container = this.$refs.container\n const dur =\n duration ??\n (prefersReducedMotion() ? 0 : this.opts.animationDuration || 0)\n\n container?.classList.add('glare-is-closing')\n container?.classList.remove('glare-is-open')\n\n const finish = () => {\n this.teardown()\n }\n\n if (dur > 0 && container) {\n const onEnd = (e: Event) => {\n if (e.target !== container) return\n container.removeEventListener('transitionend', onEnd)\n finish()\n }\n container.addEventListener('transitionend', onEnd)\n setTimeout(finish, dur + 50)\n } else {\n finish()\n }\n }\n\n next(duration?: number): void {\n this.jumpTo(this.currIndex + 1, duration)\n }\n\n previous(duration?: number): void {\n this.jumpTo(this.currIndex - 1, duration)\n }\n\n prev(duration?: number): void {\n this.previous(duration)\n }\n\n jumpTo(index: number, duration?: number): void {\n if (!this.isActive || this.isClosing) return\n\n const len = this.group.length\n if (!len) return\n\n let nextIndex = index\n if (this.opts.loop) {\n nextIndex = ((index % len) + len) % len\n } else {\n nextIndex = clamp(index, 0, len - 1)\n if (nextIndex === this.currIndex && index !== this.currIndex) return\n }\n\n if (nextIndex === this.currIndex) return\n\n this.prevIndex = this.currIndex\n this.currIndex = nextIndex\n this.current = this.group[nextIndex]\n this.resetZoom()\n this.loadSlide(nextIndex, false, duration)\n this.updateChrome()\n this.Thumbs?.focus(nextIndex)\n this.hash?.update(nextIndex)\n this.trigger('onUpdate', this.current)\n }\n\n scaleToFit(duration = 300): void {\n this.animateZoom(1, 0, 0, duration)\n this.$refs.container?.classList.remove('glare-can-zoom-out')\n this.$refs.container?.classList.add('glare-can-zoom-in')\n this.updateZoomButton()\n }\n\n scaleToActual(x?: number, y?: number, duration = 300): void {\n const wrap = this.getImageWrap()\n if (!wrap) return\n const rect = getOffset(wrap)\n const cx = x ?? rect.left + rect.width / 2\n const cy = y ?? rect.top + rect.height / 2\n const scale = Math.min(this.zoom.max, 2.5)\n const dx = (rect.left + rect.width / 2 - cx) * (scale - 1)\n const dy = (rect.top + rect.height / 2 - cy) * (scale - 1)\n this.animateZoom(scale, dx, dy, duration)\n this.$refs.container?.classList.add('glare-can-zoom-out')\n this.$refs.container?.classList.remove('glare-can-zoom-in')\n this.updateZoomButton()\n }\n\n update(): void {\n this.updateChrome()\n this.positionContent()\n }\n\n focus(): void {\n this.$refs.container?.focus({ preventScroll: true })\n }\n\n toggleControls(force?: boolean): void {\n const container = this.$refs.container\n if (!container) return\n const hide = force === undefined ? !container.classList.contains('glare-is-idle') : force\n container.classList.toggle('glare-is-idle', hide)\n this.isIdle = hide\n }\n\n getContentEl(): HTMLElement | null {\n return this.current?.$content || null\n }\n\n getImageWrap(): HTMLElement | null {\n return this.current?.$slide?.querySelector('.glare-content') as HTMLElement | null\n }\n\n getZoomState() {\n return { ...this.zoom }\n }\n\n applyZoom(scale: number, x: number, y: number, animate = false): void {\n this.animateZoom(scale, x, y, animate ? 250 : 0)\n const zoomed = scale > 1.01\n this.$refs.container?.classList.toggle('glare-can-zoom-out', zoomed)\n this.$refs.container?.classList.toggle('glare-can-zoom-in', !zoomed)\n this.updateZoomButton()\n }\n\n onSwipe(dx: number, dy: number, done: boolean, velocity?: { x: number; y: number }): void {\n const stage = this.$refs.stage\n if (!stage) return\n\n if (!done) {\n css(stage, {\n transform: `translate3d(${dx}px, ${dy}px, 0)`,\n transitionDuration: '0ms',\n })\n if (this.$refs.bg) {\n const opacity = clamp(1 - Math.abs(dy) / 400, 0.35, 1)\n css(this.$refs.bg, { opacity: String(opacity) })\n }\n return\n }\n\n const absX = Math.abs(dx)\n const absY = Math.abs(dy)\n const vx = velocity?.x || 0\n const vy = velocity?.y || 0\n\n css(stage, { transitionDuration: '' })\n if (this.$refs.bg) css(this.$refs.bg, { opacity: '' })\n\n if (absY > 100 || Math.abs(vy) > 0.5) {\n if (absY > absX) {\n this.close()\n return\n }\n }\n\n if (absX > 80 || Math.abs(vx) > 0.4) {\n if (dx < 0) this.next()\n else this.prev()\n }\n\n css(stage, { transform: '' })\n }\n\n /* -------------------- private -------------------- */\n\n private build(): void {\n const dict = this.dict()\n const tpl = translate(this.opts.baseTpl || '', dict)\n const wrapper = createEl('div', '', tpl)\n const container = wrapper.firstElementChild as HTMLElement\n container.dataset.glareId = String(this.id)\n if (this.opts.baseClass) container.classList.add(this.opts.baseClass)\n if (this.opts.modal) container.classList.add('glare-is-modal')\n\n this.$refs.container = container\n this.$refs.bg = $('.glare-bg', container)\n this.$refs.inner = $('.glare-inner', container)\n this.$refs.stage = $('.glare-stage', container)\n this.$refs.caption = $('.glare-caption', container)\n this.$refs.toolbar = $('.glare-toolbar', container)\n this.$refs.infobar = $('.glare-infobar', container)\n this.$refs.navigation = $('.glare-navigation', container)\n\n this.buildToolbar()\n this.updateChrome()\n\n if (!this.opts.arrows || this.group.length < 2) {\n this.$refs.navigation?.classList.add('glare-hidden')\n }\n if (!this.opts.infobar || this.group.length < 2) {\n this.$refs.infobar?.classList.add('glare-hidden')\n }\n\n resolveParent(this.opts.parentEl).appendChild(container)\n }\n\n private buildToolbar(): void {\n const toolbar = this.$refs.toolbar\n if (!toolbar) return\n\n const showToolbar = this.opts.toolbar === true || this.opts.toolbar === 'auto'\n if (!showToolbar) {\n toolbar.classList.add('glare-hidden')\n return\n }\n\n const dict = this.dict()\n const buttons = this.opts.buttons || []\n toolbar.innerHTML = ''\n\n for (const name of buttons) {\n if (name === 'thumbs' && this.group.length < 2) continue\n if (name === 'slideshow' && this.group.length < 2) continue\n const tpl = this.opts.btnTpl?.[name]\n if (!tpl) continue\n toolbar.insertAdjacentHTML('beforeend', translate(tpl, dict))\n }\n }\n\n private initModules(): void {\n const thumbsOpts = this.opts.thumbs\n if (thumbsOpts) {\n const opts =\n thumbsOpts === true\n ? { ...(defaults.thumbs as object) }\n : thumbsOpts\n this.Thumbs = new Thumbs(this, opts)\n this.Thumbs.init()\n }\n\n const slideShowOpts = this.opts.slideShow\n if (slideShowOpts) {\n const opts =\n slideShowOpts === true\n ? { ...(defaults.slideShow as object) }\n : slideShowOpts\n this.SlideShow = new Slideshow(this, opts)\n this.SlideShow.init()\n }\n\n if (this.opts.fullScreen !== false) {\n this.FullScreen = new FullScreen(this)\n this.FullScreen.init()\n const fsOpts = this.opts.fullScreen\n if (fsOpts && typeof fsOpts === 'object' && fsOpts.autoStart) {\n this.FullScreen.request()\n }\n }\n\n if (this.opts.share) {\n this.share = new Share(this, this.opts.share)\n }\n\n if (this.opts.hash && this.galleryName) {\n this.hash = new Hash(this, this.galleryName)\n this.hash.init()\n }\n\n if (this.opts.wheel !== false && this.$refs.stage) {\n this.wheel = new WheelNav(this, this.opts.wheel || 'auto')\n this.wheel.init(this.$refs.stage)\n }\n\n if (this.opts.touch !== false && this.$refs.stage) {\n this.gestures = new Gestures(this as unknown as ConstructorParameters<typeof Gestures>[0])\n this.gestures.attach(this.$refs.stage)\n }\n }\n\n private bindEvents(): void {\n const container = this.$refs.container\n if (!container) return\n\n this.cleanups.push(\n on(container, 'click', (event) => this.onClick(event as MouseEvent)),\n on(container, 'dblclick', (event) => this.onDblClick(event as MouseEvent)),\n on(document, 'keydown', (event) => this.onKeydown(event as KeyboardEvent)),\n on(window, 'resize', () => this.positionContent()),\n on(window, 'orientationchange', () => this.positionContent()),\n on(document, 'mousemove', () => this.resetIdle()),\n on(document, 'touchstart', () => this.resetIdle(), { passive: true }),\n )\n\n if (this.opts.trapFocus) {\n this.cleanups.push(\n on(container, 'keydown', (event) => {\n const e = event as KeyboardEvent\n if (e.key !== 'Tab') return\n const focusables = $$('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])', container)\n .filter((el) => !el.hasAttribute('disabled') && el.offsetParent !== null)\n if (!focusables.length) return\n const first = focusables[0]\n const last = focusables[focusables.length - 1]\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault()\n last.focus()\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault()\n first.focus()\n }\n }),\n )\n }\n\n if (this.opts.protect) {\n this.cleanups.push(\n on(container, 'contextmenu', (e) => {\n e.preventDefault()\n }),\n on(container, 'dragstart', (e) => {\n if ((e.target as HTMLElement).tagName === 'IMG') e.preventDefault()\n }),\n )\n }\n }\n\n private onClick(event: MouseEvent): void {\n if (this.gestures?.wasMoved()) {\n this.gestures.resetMoved()\n return\n }\n\n const target = event.target as HTMLElement\n\n if (target.closest('[data-glare-close]')) {\n this.close(event)\n return\n }\n if (target.closest('[data-glare-next]')) {\n this.next()\n return\n }\n if (target.closest('[data-glare-prev]')) {\n this.prev()\n return\n }\n if (target.closest('[data-glare-zoom]')) {\n this.toggleZoom(event)\n return\n }\n if (target.closest('[data-glare-slideshow]')) {\n this.SlideShow?.toggle()\n return\n }\n if (target.closest('[data-glare-thumbs]')) {\n this.Thumbs?.toggle()\n return\n }\n if (target.closest('[data-glare-fullscreen]')) {\n this.FullScreen?.toggle()\n return\n }\n if (target.closest('[data-glare-share]')) {\n this.share?.open()\n return\n }\n if (target.closest('[data-glare-download]')) {\n return\n }\n\n if (target.closest('.glare-content') || target.closest('.glare-space')) {\n this.handleClickAction(this.opts.clickContent, event)\n return\n }\n if (target.closest('.glare-slide')) {\n this.handleClickAction(this.opts.clickSlide, event)\n return\n }\n if (target.classList.contains('glare-bg') || target.classList.contains('glare-stage')) {\n this.handleClickAction(this.opts.clickOutside, event)\n }\n }\n\n private onDblClick(event: MouseEvent): void {\n const target = event.target as HTMLElement\n if (target.closest('.glare-content') || target.closest('.glare-space')) {\n this.handleClickAction(this.opts.dblclickContent, event)\n } else if (target.closest('.glare-slide')) {\n this.handleClickAction(this.opts.dblclickSlide, event)\n } else {\n this.handleClickAction(this.opts.dblclickOutside, event)\n }\n }\n\n private handleClickAction(action: ClickAction | undefined, event: Event): void {\n if (!action || !this.current) return\n let resolved: ClickAction | void = action\n if (typeof action === 'function') {\n resolved = action(this.current, event)\n }\n switch (resolved) {\n case 'close':\n this.close(event)\n break\n case 'next':\n this.next()\n break\n case 'nextOrClose':\n if (this.currIndex === this.group.length - 1 && !this.opts.loop) this.close(event)\n else this.next()\n break\n case 'toggleControls':\n this.toggleControls()\n break\n case 'zoom':\n this.toggleZoom(event as MouseEvent)\n break\n default:\n break\n }\n }\n\n private onKeydown(event: KeyboardEvent): void {\n if (!this.isActive || !this.opts.keyboard || this.opts.modal) return\n if (activeStack[activeStack.length - 1] !== this) return\n\n const tag = (event.target as HTMLElement)?.tagName\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return\n\n switch (event.key) {\n case 'Escape':\n event.preventDefault()\n this.close(event)\n break\n case 'ArrowRight':\n case 'ArrowDown':\n event.preventDefault()\n this.next()\n break\n case 'ArrowLeft':\n case 'ArrowUp':\n event.preventDefault()\n this.prev()\n break\n case ' ':\n case 'Spacebar':\n event.preventDefault()\n this.SlideShow?.toggle()\n break\n case 'f':\n case 'F':\n this.FullScreen?.toggle()\n break\n default:\n break\n }\n }\n\n private loadSlide(index: number, isOpening: boolean, _duration?: number): void {\n const stage = this.$refs.stage\n if (!stage) return\n\n const item = this.group[index]\n if (!item) return\n\n // Remove old slides except keeping adjacent for transition\n $$('.glare-slide', stage).forEach((slide) => {\n const idx = Number(slide.dataset.index)\n if (idx !== index) {\n slide.classList.add('glare-slide--out')\n setTimeout(() => slide.remove(), this.opts.transitionDuration || 366)\n }\n })\n\n let slide = stage.querySelector(`.glare-slide[data-index=\"${index}\"]`) as HTMLElement | null\n if (!slide) {\n slide = createEl('div', `glare-slide${this.opts.slideClass ? ` ${this.opts.slideClass}` : ''}`)\n slide.dataset.index = String(index)\n slide.innerHTML = `\n <div class=\"glare-space\">\n <div class=\"glare-content\"></div>\n </div>\n `\n stage.appendChild(slide)\n }\n\n item.$slide = slide\n item.$content = $('.glare-content', slide)\n item.pos = index\n\n slide.classList.add('glare-slide--current')\n slide.classList.remove('glare-slide--out')\n\n if (this.shouldSmallBtn(item)) {\n const dict = this.dict()\n if (!slide.querySelector('.glare-close-small')) {\n slide.insertAdjacentHTML(\n 'beforeend',\n translate(this.opts.btnTpl?.smallBtn || '', dict),\n )\n }\n }\n\n this.showSpinner(slide)\n this.trigger('beforeLoad', item)\n\n void this.resolveContent(item).then(() => {\n if (!this.isActive || this.currIndex !== index) return\n this.hideSpinner(slide!)\n this.trigger('afterLoad', item)\n this.positionContent()\n this.updateChrome()\n this.updateDownload(item)\n\n if (isOpening) {\n this.playOpenAnimation(item)\n } else {\n this.playTransition()\n }\n\n this.trigger('afterShow', item)\n this.trigger('onReveal', item)\n }).catch(() => {\n if (!this.isActive || this.currIndex !== index) return\n this.hideSpinner(slide!)\n this.showError(item)\n })\n\n // Preload neighbors\n if (this.opts.image?.preload) {\n ;[index - 1, index + 1].forEach((i) => {\n const neighbor = this.group[i]\n if (neighbor?.type === 'image' && neighbor.src) {\n const img = new Image()\n img.src = neighbor.src\n }\n })\n }\n }\n\n private shouldSmallBtn(item: SlideItem): boolean {\n if (this.opts.smallBtn === true) return true\n if (this.opts.smallBtn === false) return false\n return item.type !== 'image'\n }\n\n private async resolveContent(item: SlideItem): Promise<void> {\n const content = item.$content\n if (!content) throw new Error('Missing content node')\n content.innerHTML = ''\n content.className = `glare-content glare-content--${item.type}`\n\n switch (item.type) {\n case 'image':\n await this.loadImage(item, content)\n break\n case 'video':\n this.loadVideo(item, content)\n break\n case 'iframe':\n await this.loadIframe(item, content)\n break\n case 'inline':\n this.loadInline(item, content)\n break\n case 'ajax':\n await this.loadAjax(item, content)\n break\n case 'html':\n default:\n this.loadHtml(item, content)\n break\n }\n\n item.isLoaded = true\n item.isComplete = true\n }\n\n private loadImage(item: SlideItem, content: HTMLElement): Promise<void> {\n return new Promise((resolve, reject) => {\n const img = createEl('img', 'glare-image') as HTMLImageElement\n img.alt = item.alt || item.caption || ''\n img.decoding = 'async'\n img.draggable = false\n if (this.opts.protect) img.style.pointerEvents = 'none'\n\n img.onload = () => {\n item.$image = img\n item.contentWidth = img.naturalWidth\n item.contentHeight = img.naturalHeight\n item.canZoomIn = true\n content.appendChild(img)\n this.$refs.container?.classList.add('glare-can-zoom-in')\n resolve()\n }\n img.onerror = () => {\n item.hasError = true\n reject(new Error('image error'))\n }\n img.src = item.src\n })\n }\n\n private loadVideo(item: SlideItem, content: HTMLElement): void {\n const format =\n item.format ||\n this.opts.video?.format ||\n (item.src.match(/\\.(\\w+)(?:\\?|$)/)?.[1]\n ? `video/${item.src.match(/\\.(\\w+)(?:\\?|$)/)?.[1]?.replace('ogv', 'ogg')}`\n : 'video/mp4')\n\n const tpl = translate(this.opts.video?.tpl || '', {\n src: item.src,\n format,\n poster: item.poster || '',\n })\n content.innerHTML = tpl\n const video = content.querySelector('video') as HTMLVideoElement | null\n item.$content = content\n if (video && (item.autoStart ?? this.opts.video?.autoStart)) {\n void video.play().catch(() => undefined)\n }\n }\n\n private loadIframe(item: SlideItem, content: HTMLElement): Promise<void> {\n return new Promise((resolve) => {\n const wrap = createEl('div', 'glare-iframe-wrap')\n wrap.innerHTML = this.opts.iframe?.tpl || '<iframe class=\"glare-iframe\"></iframe>'\n const iframe = wrap.querySelector('iframe') as HTMLIFrameElement\n const attrs = this.opts.iframe?.attr || {}\n for (const [k, v] of Object.entries(attrs)) iframe.setAttribute(k, v)\n if (this.opts.iframe?.css) css(iframe, this.opts.iframe.css)\n if (item.width) css(wrap, { width: typeof item.width === 'number' ? `${item.width}px` : String(item.width) })\n if (item.height) css(wrap, { height: typeof item.height === 'number' ? `${item.height}px` : String(item.height) })\n\n content.appendChild(wrap)\n\n if (this.opts.iframe?.preload === false) {\n iframe.src = item.src\n resolve()\n return\n }\n\n iframe.onload = () => resolve()\n iframe.src = item.src\n // Fallback if onload never fires (cross-origin quirks)\n setTimeout(() => resolve(), 1200)\n })\n }\n\n private loadInline(item: SlideItem, content: HTMLElement): void {\n const target = item.src ? $(item.src) : null\n if (!target) {\n item.hasError = true\n throw new Error('inline target missing')\n }\n const clone = target.cloneNode(true) as HTMLElement\n clone.id = ''\n clone.classList.remove('glare-hidden')\n clone.hidden = false\n clone.style.display = ''\n content.appendChild(clone)\n }\n\n private async loadAjax(item: SlideItem, content: HTMLElement): Promise<void> {\n const settings = this.opts.ajax?.settings || {}\n const response = await fetch(item.src, settings)\n if (!response.ok) throw new Error('ajax failed')\n const html = await response.text()\n content.innerHTML = html\n }\n\n private loadHtml(item: SlideItem, content: HTMLElement): void {\n if (item.content instanceof HTMLElement) {\n content.appendChild(item.content)\n } else {\n content.innerHTML = item.html || item.content || item.src || ''\n }\n }\n\n private showSpinner(slide: HTMLElement): void {\n if (slide.querySelector('.glare-spinner')) return\n slide.insertAdjacentHTML('beforeend', this.opts.spinnerTpl || '')\n }\n\n private hideSpinner(slide: HTMLElement): void {\n slide.querySelector('.glare-spinner')?.remove()\n }\n\n private showError(item: SlideItem): void {\n item.hasError = true\n const content = item.$content\n if (!content) return\n content.className = 'glare-content glare-content--error'\n content.innerHTML = translate(this.opts.errorTpl || '', this.dict())\n }\n\n private playOpenAnimation(item: SlideItem): void {\n const container = this.$refs.container\n if (!container) return\n const effect = prefersReducedMotion() ? false : this.opts.animationEffect\n container.dataset.animation = effect ? String(effect) : 'none'\n container.style.setProperty('--glare-duration', `${this.opts.animationDuration || 0}ms`)\n\n if (effect === 'zoom' && item.$trigger && item.type === 'image' && item.$image) {\n const from = getOffset(item.$trigger)\n const to = getOffset(item.$image)\n const sx = from.width / Math.max(to.width, 1)\n const sy = from.height / Math.max(to.height, 1)\n const dx = from.left + from.width / 2 - (to.left + to.width / 2)\n const dy = from.top + from.height / 2 - (to.top + to.height / 2)\n css(item.$image, {\n transform: `translate3d(${dx}px, ${dy}px, 0) scale(${Math.max(sx, sy)})`,\n opacity: this.opts.zoomOpacity === false ? '1' : '0.2',\n transitionDuration: '0ms',\n })\n nextFrame(() => {\n if (!item.$image) return\n css(item.$image, {\n transform: '',\n opacity: '',\n transitionDuration: `${this.opts.animationDuration || 366}ms`,\n })\n })\n }\n\n nextFrame(() => container.classList.add('glare-is-ready'))\n }\n\n private playTransition(): void {\n const container = this.$refs.container\n if (!container) return\n const effect = prefersReducedMotion() ? false : this.opts.transitionEffect\n container.dataset.transition = effect ? String(effect) : 'none'\n container.style.setProperty(\n '--glare-transition-duration',\n `${this.opts.transitionDuration || 0}ms`,\n )\n }\n\n private positionContent(): void {\n // Layout is mostly CSS; update caption overlap / zoom affordance\n const item = this.current\n if (!item?.$image || !item.contentWidth || !item.contentHeight) return\n const slide = item.$slide\n if (!slide) return\n const space = $('.glare-space', slide)\n if (!space) return\n const rect = getOffset(space)\n const fit = Math.min(rect.width / item.contentWidth, rect.height / item.contentHeight, 1)\n item.canZoomIn = fit < 0.98 || item.contentWidth > rect.width || item.contentHeight > rect.height\n this.$refs.container?.classList.toggle('glare-can-zoom-in', !!item.canZoomIn && this.zoom.scale <= 1.01)\n }\n\n private updateChrome(): void {\n const item = this.current\n if (!item) return\n\n if (this.$refs.infobar) {\n const el = $('.glare-infobar-index', this.$refs.infobar)\n if (el) el.textContent = `${this.currIndex + 1} / ${this.group.length}`\n }\n\n if (this.$refs.caption) {\n let caption = item.caption || ''\n if (typeof this.opts.caption === 'function') {\n caption = this.opts.caption(this, item)\n } else if (typeof this.opts.caption === 'string') {\n caption = this.opts.caption\n }\n this.$refs.caption.innerHTML = caption\n this.$refs.caption.classList.toggle('glare-hidden', !caption)\n this.$refs.container?.classList.toggle('glare-show-caption', !!caption)\n }\n\n const atStart = this.currIndex === 0 && !this.opts.loop\n const atEnd = this.currIndex === this.group.length - 1 && !this.opts.loop\n this.$refs.container?.querySelector('[data-glare-prev]')?.classList.toggle('glare-disabled', atStart)\n this.$refs.container?.querySelector('[data-glare-next]')?.classList.toggle('glare-disabled', atEnd)\n this.$refs.container?.setAttribute('aria-label', captionLabel(item, this.currIndex, this.group.length))\n }\n\n private updateDownload(item: SlideItem): void {\n const link = this.$refs.container?.querySelector('[data-glare-download]') as HTMLAnchorElement | null\n if (!link) return\n const href = item.downloadSrc || (item.type === 'image' ? item.src : '')\n if (href) {\n link.href = href\n link.classList.remove('glare-hidden')\n } else {\n link.classList.add('glare-hidden')\n }\n }\n\n private toggleZoom(event?: MouseEvent): void {\n if (!this.current || this.current.type !== 'image') return\n if (this.zoom.scale > 1.01) {\n this.scaleToFit()\n } else {\n const point = event ? { x: event.clientX, y: event.clientY } : undefined\n this.scaleToActual(point?.x, point?.y)\n }\n }\n\n private animateZoom(scale: number, x: number, y: number, duration = 0): void {\n const content = this.getImageWrap()\n const img = this.current?.$image\n if (!content || !img) return\n\n this.zoom.scale = clamp(scale, this.zoom.min, this.zoom.max)\n this.zoom.x = x\n this.zoom.y = y\n\n css(img, {\n transform: `translate3d(${x}px, ${y}px, 0) scale(${this.zoom.scale})`,\n transitionDuration: `${duration}ms`,\n })\n }\n\n private resetZoom(): void {\n this.zoom = { scale: 1, x: 0, y: 0, min: 1, max: 5 }\n this.$refs.container?.classList.remove('glare-can-zoom-out')\n }\n\n private updateZoomButton(): void {\n const btn = this.$refs.container?.querySelector('[data-glare-zoom]') as HTMLElement | null\n if (!btn) return\n btn.innerHTML = this.zoom.scale > 1.01 ? icons.zoomOut : icons.zoomIn\n btn.classList.toggle('is-active', this.zoom.scale > 1.01)\n }\n\n private resetIdle(): void {\n this.clearIdle()\n if (this.isIdle) this.toggleControls(false)\n const time = this.opts.idleTime\n if (!time || this.opts.modal) return\n this.idleTimer = setTimeout(() => {\n this.toggleControls(true)\n }, time * 1000)\n }\n\n private clearIdle(): void {\n if (this.idleTimer) {\n clearTimeout(this.idleTimer)\n this.idleTimer = null\n }\n }\n\n private dict(): I18nDict & Record<string, string> {\n const lang = this.opts.lang || 'en'\n return {\n ...i18nFallback,\n ...(this.opts.i18n?.en || {}),\n ...(this.opts.i18n?.[lang] || {}),\n } as I18nDict & Record<string, string>\n }\n\n private trigger(name: EventName, current?: SlideItem, ...args: unknown[]): unknown {\n const handler = this.opts[name] as EventHandler | undefined\n if (typeof handler === 'function') {\n return handler(this, current, ...args)\n }\n return undefined\n }\n\n private teardown(): void {\n this.gestures?.detach()\n this.wheel?.destroy()\n this.hash?.destroy()\n this.share?.destroy()\n this.Thumbs?.destroy()\n this.SlideShow?.destroy()\n this.FullScreen?.destroy()\n\n this.cleanups.forEach((fn) => fn())\n this.cleanups = []\n\n this.$refs.container?.remove()\n this.$refs = {\n container: null,\n stage: null,\n bg: null,\n inner: null,\n caption: null,\n toolbar: null,\n infobar: null,\n navigation: null,\n }\n\n const idx = activeStack.indexOf(this)\n if (idx >= 0) activeStack.splice(idx, 1)\n\n if (this.opts.hideScrollbar) lockScroll(false)\n\n if (this.opts.backFocus) {\n const el = this.openedFrom || this.previouslyFocused\n el?.focus?.({ preventScroll: true })\n }\n\n this.isActive = false\n this.isClosing = false\n this.trigger('afterClose', this.current || undefined)\n this.trigger('onDeactivate')\n this.trigger('onDestroy')\n }\n\n /* -------------------- static API -------------------- */\n\n static defaults = defaults\n\n static getInstance(id?: number): Glare | null {\n if (id != null) return activeStack.find((i) => i.id === id) || null\n return activeStack[activeStack.length - 1] || null\n }\n\n static getInstances(): Glare[] {\n return [...activeStack]\n }\n\n static open(\n items: Array<SlideSource | string> | HTMLElement[],\n options: GlareOptions = {},\n index = 0,\n ): Glare {\n const instance = new Glare(items, options, index)\n instance.open(index)\n return instance\n }\n\n static close(all = false): void {\n if (all) {\n ;[...activeStack].reverse().forEach((i) => i.close())\n return\n }\n activeStack[activeStack.length - 1]?.close()\n }\n\n static destroy(): void {\n Glare.close(true)\n boundGroups.forEach((g) => g.destroy())\n boundGroups.length = 0\n }\n\n static bind(\n selector: string | HTMLElement | HTMLElement[] | NodeListOf<HTMLElement>,\n options: GlareOptions = {},\n ): { destroy: () => void } {\n const elements =\n typeof selector === 'string'\n ? $$(selector)\n : selector instanceof HTMLElement\n ? [selector]\n : Array.from(selector as ArrayLike<HTMLElement>)\n\n const onClick = (event: Event) => {\n const eventTarget = event.target as HTMLElement | null\n if (!eventTarget) return\n\n const target = elements.find((el) => el === eventTarget || el.contains(eventTarget))\n if (!target) return\n event.preventDefault()\n\n const groupName =\n target.getAttribute('data-glare') ||\n target.getAttribute('data-glare') ||\n ''\n\n const groupEls = groupName\n ? elements.filter(\n (el) =>\n (el.getAttribute('data-glare') || el.getAttribute('data-glare') || '') ===\n groupName,\n )\n : [target]\n\n const index = Math.max(0, groupEls.indexOf(target))\n const instance = new Glare(groupEls, options, index, groupName || 'gallery')\n instance.open(index)\n }\n\n const cleanups = elements.map((el) => on(el, 'click', onClick))\n\n const group = {\n selector: typeof selector === 'string' ? selector : '',\n options,\n elements,\n destroy: () => {\n cleanups.forEach((fn) => fn())\n const i = boundGroups.indexOf(group)\n if (i >= 0) boundGroups.splice(i, 1)\n },\n }\n boundGroups.push(group)\n return group\n }\n\n static fromSelector(\n selector: string,\n options: GlareOptions = {},\n ): Glare | null {\n const els = $$(selector)\n if (!els.length) return null\n const instance = new Glare(els, options, 0, 'gallery')\n instance.open(0)\n return instance\n }\n}\n\nconst boundGroups: Array<{\n selector: string\n options: GlareOptions\n elements: HTMLElement[]\n destroy: () => void\n}> = []\n\nconst i18nFallback: I18nDict = {\n CLOSE: 'Close',\n NEXT: 'Next',\n PREV: 'Previous',\n ERROR: 'The requested content cannot be loaded.<br/>Please try again later.',\n PLAY_START: 'Start slideshow',\n PLAY_STOP: 'Pause slideshow',\n FULL_SCREEN: 'Full screen',\n THUMBS: 'Thumbnails',\n DOWNLOAD: 'Download',\n SHARE: 'Share',\n ZOOM: 'Zoom',\n}\n\nfunction captionLabel(item: SlideItem, index: number, total: number): string {\n const base = item.caption || item.alt || 'Media lightbox'\n return total > 1 ? `${base} (${index + 1} of ${total})` : base\n}\n\n// Auto-bind data-glare on DOM ready\nfunction autoBind(): void {\n if (typeof document === 'undefined') return\n const run = () => {\n const els = $$('[data-glare], [data-glare]')\n if (!els.length) return\n // Group by attribute value; bind once via delegation on document\n Glare.bind('[data-glare], [data-glare]')\n }\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', run, { once: true })\n } else {\n run()\n }\n}\n\nexport { autoBind }\n"],"names":["icons","i18nEn","defaultMedia","_m","_url","m","tld","parts","lat","lng","zoom","query","defaults","current","isObject","value","deepMerge","target","sources","result","source","key","existing","$","selector","context","$$","createEl","tag","className","html","el","on","type","handler","options","css","styles","kebab","str","clamp","min","max","isMobile","getScrollbarWidth","lockScroll","lock","width","translate","template","dict","_","getOffset","requestAnimFrame","cb","nextFrame","prefersReducedMotion","buildQuery","params","k","v","distance","a","b","dx","dy","midpoint","getPoints","event","Gestures","instance","stage","fn","points","dist","scale","mid","absX","absY","x","y","touchOpts","elapsed","last","start","velocity","FullScreen","doc","exit","active","btn","parseHash","hash","match","getGalleryHash","gallery","index","_Hash","parsed","next","url","Hash","IMAGE_EXT","VIDEO_EXT","PDF_EXT","detectType","src","explicit","applyMediaProvider","media","provider","n","sep","thumb","normalizeItem","opts","raw","mediaHit","item","itemsFromElements","elements","href","typeAttr","caption","height","poster","downloadSrc","srcHtml","DEFAULT_TPL","Share","encoded","lang","Slideshow","label","Thumbs","parent","img","WheelNav","mode","e","instanceId","activeStack","resolveParent","parentEl","_Glare","items","galleryName","merged","i","_event","duration","container","dur","finish","onEnd","len","nextIndex","wrap","rect","cx","cy","force","hide","animate","zoomed","done","opacity","vx","vy","tpl","toolbar","buttons","name","thumbsOpts","slideShowOpts","fsOpts","focusables","first","action","resolved","isOpening","_duration","slide","neighbor","content","resolve","reject","format","video","iframe","attrs","clone","settings","response","effect","from","to","sx","sy","space","fit","atStart","atEnd","captionLabel","link","point","time","i18nFallback","args","idx","id","all","boundGroups","g","onClick","eventTarget","groupName","groupEls","cleanups","group","els","Glare","total","base","autoBind","run"],"mappings":"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"}
1
+ {"version":3,"file":"glare.js","sources":["../src/i18n.ts","../src/utils/template.ts","../src/media/providers.ts","../src/icons.ts","../src/templates.ts","../src/defaults.ts","../src/media/detect.ts","../src/media/items.ts","../src/utils/dom.ts","../src/utils/env.ts","../src/core/dom.ts","../src/modules/fullscreen.ts","../src/utils/object.ts","../src/core/zoom.ts","../src/modules/gestures.ts","../src/modules/hash.ts","../src/modules/share.ts","../src/modules/slideshow.ts","../src/modules/thumbs.ts","../src/modules/wheel.ts","../src/core/animation.ts","../src/core/options.ts","../src/core/bind.ts","../src/core/idle.ts","../src/core/registry.ts","../src/core/interactions.ts","../src/core/loaders.ts","../src/core/glare.ts"],"sourcesContent":["import type { GlareOptions, I18nDict } from './types'\n\nexport const i18nEn: I18nDict = {\n CLOSE: 'Close',\n NEXT: 'Next',\n PREV: 'Previous',\n ERROR: 'The requested content cannot be loaded.<br/>Please try again later.',\n LOADING: 'Loading',\n LIGHTBOX: 'Media lightbox',\n GO_TO_SLIDE: 'Go to slide {{index}}',\n VIDEO_UNSUPPORTED: 'Your browser does not support HTML5 video.',\n PLAY_START: 'Start slideshow',\n PLAY_STOP: 'Pause slideshow',\n FULL_SCREEN: 'Full screen',\n FULL_SCREEN_EXIT: 'Exit full screen',\n THUMBS: 'Thumbnails',\n DOWNLOAD: 'Download',\n SHARE: 'Share',\n COPY: 'Copy link',\n ZOOM: 'Zoom',\n ZOOM_OUT: 'Zoom out',\n}\n\n/** Resolves the active dictionary: built-in English, then `i18n.en`, then `i18n[lang]`. */\nexport function getDict(opts: GlareOptions): I18nDict {\n const lang = opts.lang ?? 'en'\n return { ...i18nEn, ...opts.i18n?.en, ...opts.i18n?.[lang] }\n}\n","/** Replaces `{{key}}` placeholders with values from `dict`. */\nexport function translate(template: string, dict: Record<string, string>): string {\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key: string) => dict[key] ?? '')\n}\n\nexport function buildQuery(params: Record<string, string | number | boolean>): string {\n return Object.entries(params)\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)\n .join('&')\n}\n\n/** Expands `$1`-style capture references from a RegExp match. */\nexport function expandMatch(template: string, match: RegExpMatchArray): string {\n return template.replace(/\\$(\\d+)/g, (_, n: string) => match[Number(n)] ?? '')\n}\n","import type { ContentType, MediaProvider, SlideSource } from '../types'\nimport { buildQuery, expandMatch } from '../utils/template'\n\nexport const providers: Record<string, MediaProvider> = {\n youtube: {\n matcher:\n /(?:youtube\\.com|youtu\\.be|youtube-nocookie\\.com)\\/(?:watch\\?(?:.*&)?v=|v\\/|u\\/\\w\\/|embed\\/|shorts\\/)?([\\w-]{11})/i,\n type: 'iframe',\n url: 'https://www.youtube-nocookie.com/embed/$1',\n thumb: 'https://img.youtube.com/vi/$1/hqdefault.jpg',\n params: { autoplay: 1, rel: 0, modestbranding: 1, playsinline: 1 },\n },\n vimeo: {\n matcher: /vimeo\\.com\\/(?:video\\/)?(\\d+)/i,\n type: 'iframe',\n url: 'https://player.vimeo.com/video/$1',\n params: { autoplay: 1, title: 0, byline: 0, portrait: 0 },\n },\n gmap: {\n matcher:\n /(?:maps\\.)?google\\.([a-z]{2,3}(?:\\.[a-z]{2})?)\\/(?:maps\\/(?:place\\/[^/]+\\/)?@([^/]+)|maps\\?q=([^&]+)|maps\\/search\\/([^/?]+))/i,\n type: 'iframe',\n url: (match) => {\n const [, tld, coords, query, search] = match\n if (coords) {\n const [lat, lng, zoom] = coords.split(',')\n const z = zoom ? Math.floor(parseFloat(zoom)) : 14\n return `https://maps.google.${tld}/maps?ll=${lat},${lng}&z=${z}&output=embed`\n }\n const q = encodeURIComponent(decodeURIComponent(query || search || ''))\n return `https://maps.google.${tld}/maps?q=${q}&output=embed`\n },\n },\n}\n\nfunction resolve(\n value: MediaProvider['url'],\n match: RegExpMatchArray,\n src: string,\n): string | undefined {\n if (typeof value === 'function') return value(match, src)\n if (typeof value === 'string') return expandMatch(value, match)\n return undefined\n}\n\n/** Rewrites `src` through the first matching provider, or returns null. */\nexport function applyProvider(\n src: string,\n media: Record<string, MediaProvider> | undefined,\n): Pick<SlideSource, 'src' | 'thumb'> & { type: ContentType } | null {\n for (const provider of Object.values(media ?? {})) {\n const match = src.match(provider.matcher)\n if (!match) continue\n\n let url = resolve(provider.url, match, src) ?? src\n if (provider.params) {\n url += (url.includes('?') ? '&' : '?') + buildQuery(provider.params)\n }\n\n return {\n src: url,\n type: provider.type ?? 'iframe',\n thumb: resolve(provider.thumb, match, src),\n }\n }\n return null\n}\n","const svg = (paths: string): string =>\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${paths}</svg>`\n\nexport const icons = {\n close: svg('<path d=\"M18 6 6 18\"/><path d=\"m6 6 12 12\"/>'),\n next: svg('<path d=\"m9 18 6-6-6-6\"/>'),\n prev: svg('<path d=\"m15 18-6-6 6-6\"/>'),\n zoomIn: svg('<circle cx=\"11\" cy=\"11\" r=\"8\"/><path d=\"m21 21-4.3-4.3\"/><path d=\"M11 8v6\"/><path d=\"M8 11h6\"/>'),\n zoomOut: svg('<circle cx=\"11\" cy=\"11\" r=\"8\"/><path d=\"m21 21-4.3-4.3\"/><path d=\"M8 11h6\"/>'),\n download: svg('<path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><polyline points=\"7 10 12 15 17 10\"/><line x1=\"12\" x2=\"12\" y1=\"15\" y2=\"3\"/>'),\n share: svg('<circle cx=\"18\" cy=\"5\" r=\"3\"/><circle cx=\"6\" cy=\"12\" r=\"3\"/><circle cx=\"18\" cy=\"19\" r=\"3\"/><line x1=\"8.59\" x2=\"15.42\" y1=\"13.51\" y2=\"17.49\"/><line x1=\"15.41\" x2=\"8.59\" y1=\"6.51\" y2=\"10.49\"/>'),\n thumbs: svg('<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"/><path d=\"M3 9h18\"/><path d=\"M9 21V9\"/>'),\n play: svg('<polygon points=\"6 3 20 12 6 21 6 3\"/>'),\n pause: svg('<rect width=\"4\" height=\"16\" x=\"6\" y=\"4\"/><rect width=\"4\" height=\"16\" x=\"14\" y=\"4\"/>'),\n fullscreen: svg('<path d=\"M8 3H5a2 2 0 0 0-2 2v3\"/><path d=\"M21 8V5a2 2 0 0 0-2-2h-3\"/><path d=\"M3 16v3a2 2 0 0 0 2 2h3\"/><path d=\"M16 21h3a2 2 0 0 0 2-2v-3\"/>'),\n fullscreenExit: svg('<path d=\"M8 3v3a2 2 0 0 1-2 2H3\"/><path d=\"M21 8h-3a2 2 0 0 1-2-2V3\"/><path d=\"M3 16h3a2 2 0 0 1 2 2v3\"/><path d=\"M16 21v-3a2 2 0 0 1 2-2h3\"/>'),\n} as const\n","import { icons } from './icons'\n\nconst button = (name: string, label: string, icon: string, attrs = ''): string =>\n `<button type=\"button\" class=\"glare-button glare-button--${name}\" data-glare-${name} title=\"{{${label}}}\" aria-label=\"{{${label}}}\"${attrs}>${icon}</button>`\n\nexport const baseTemplate = `\n<div class=\"glare-container\" role=\"dialog\" aria-modal=\"true\" tabindex=\"-1\">\n <div class=\"glare-bg\"></div>\n <div class=\"glare-progress\" hidden></div>\n <div class=\"glare-inner\">\n <div class=\"glare-live glare-sr-only\" aria-live=\"polite\" aria-atomic=\"true\"></div>\n <div class=\"glare-infobar\"><span class=\"glare-infobar-index\"></span></div>\n <div class=\"glare-toolbar\"></div>\n <div class=\"glare-navigation\">\n ${button('prev', 'PREV', icons.prev)}\n ${button('next', 'NEXT', icons.next)}\n </div>\n <div class=\"glare-stage\"></div>\n <div class=\"glare-caption\"></div>\n </div>\n</div>`\n\nexport const buttonTemplates: Record<string, string> = {\n zoom: button('zoom', 'ZOOM', icons.zoomIn),\n slideshow: button('slideshow', 'PLAY_START', icons.play),\n thumbs: button('thumbs', 'THUMBS', icons.thumbs, ' aria-expanded=\"false\"'),\n share: button('share', 'SHARE', icons.share),\n fullscreen: button('fullscreen', 'FULL_SCREEN', icons.fullscreen),\n close: button('close', 'CLOSE', icons.close),\n download: `<a class=\"glare-button glare-button--download\" data-glare-download download target=\"_blank\" rel=\"noopener\" title=\"{{DOWNLOAD}}\" aria-label=\"{{DOWNLOAD}}\">${icons.download}</a>`,\n smallBtn: `<button type=\"button\" class=\"glare-button glare-close-small\" data-glare-close title=\"{{CLOSE}}\" aria-label=\"{{CLOSE}}\">${icons.close}</button>`,\n}\n\nexport const spinnerTemplate = '<div class=\"glare-spinner\" role=\"status\" aria-label=\"{{LOADING}}\"></div>'\n\nexport const errorTemplate = '<div class=\"glare-error\"><p>{{ERROR}}</p></div>'\n\nexport const videoTemplate =\n '<video class=\"glare-video\" controls playsinline controlsList=\"nodownload\" poster=\"{{poster}}\">' +\n '<source src=\"{{src}}\" type=\"{{format}}\"/>' +\n '{{VIDEO_UNSUPPORTED}}' +\n '</video>'\n\nexport const iframeTemplate = '<iframe class=\"glare-iframe\"></iframe>'\n\nexport const shareTemplate = `\n<div class=\"glare-share\" role=\"dialog\" aria-label=\"{{SHARE}}\">\n <div class=\"glare-share-head\">\n <h4 class=\"glare-share-title\">{{SHARE}}</h4>\n <button type=\"button\" class=\"glare-button glare-share-close\" data-glare-share-close title=\"{{CLOSE}}\" aria-label=\"{{CLOSE}}\">${icons.close}</button>\n </div>\n <p><a class=\"glare-share-link\" href=\"{{url_facebook}}\" target=\"_blank\" rel=\"noopener\">Facebook</a></p>\n <p><a class=\"glare-share-link\" href=\"{{url_twitter}}\" target=\"_blank\" rel=\"noopener\">X / Twitter</a></p>\n <p><a class=\"glare-share-link\" href=\"{{url_pinterest}}\" target=\"_blank\" rel=\"noopener\">Pinterest</a></p>\n <div class=\"glare-share-row\">\n <input class=\"glare-share-input\" type=\"text\" value=\"{{url_direct}}\" readonly />\n <button type=\"button\" class=\"glare-share-copy\" data-glare-share-copy>{{COPY}}</button>\n </div>\n</div>`\n","import type {\n FullscreenOptions,\n ResolvedOptions,\n SlideshowOptions,\n ThumbsOptions,\n} from './types'\nimport { i18nEn } from './i18n'\nimport { providers } from './media/providers'\nimport {\n baseTemplate,\n buttonTemplates,\n errorTemplate,\n iframeTemplate,\n spinnerTemplate,\n videoTemplate,\n} from './templates'\n\nexport const thumbsDefaults: Required<Omit<ThumbsOptions, 'parentEl'>> & ThumbsOptions = {\n autoStart: false,\n axis: 'x',\n}\n\nexport const slideshowDefaults: Required<SlideshowOptions> = {\n autoStart: false,\n speed: 3000,\n}\n\nexport const fullscreenDefaults: Required<FullscreenOptions> = {\n autoStart: false,\n}\n\nexport const defaults: ResolvedOptions = {\n closeExisting: false,\n loop: false,\n keyboard: true,\n protect: false,\n modal: false,\n idleTime: 3,\n hideScrollbar: true,\n autoFocus: true,\n backFocus: true,\n trapFocus: true,\n defaultType: 'image',\n parentEl: 'body',\n baseClass: '',\n slideClass: '',\n\n arrows: true,\n infobar: true,\n toolbar: 'auto',\n smallBtn: 'auto',\n buttons: ['zoom', 'slideshow', 'thumbs', 'share', 'download', 'fullscreen', 'close'],\n\n animationEffect: 'zoom',\n animationDuration: 366,\n zoomOpacity: true,\n transitionEffect: 'fade',\n transitionDuration: 366,\n\n clickContent: (current) => (current.type === 'image' ? 'zoom' : false),\n clickSlide: 'close',\n dblclickContent: false,\n dblclickSlide: false,\n wheel: 'auto',\n touch: { vertical: true, momentum: true },\n mobile: {\n idleTime: false,\n clickContent: (current) => (current.type === 'image' ? 'toggleControls' : false),\n clickSlide: (current) => (current.type === 'image' ? 'toggleControls' : 'close'),\n dblclickContent: (current) => (current.type === 'image' ? 'zoom' : false),\n dblclickSlide: (current) => (current.type === 'image' ? 'zoom' : false),\n },\n\n image: { preload: false },\n video: { tpl: videoTemplate, format: '', autoStart: true },\n iframe: {\n preload: true,\n css: {},\n attr: { allowfullscreen: 'true', allow: 'autoplay; fullscreen; picture-in-picture' },\n tpl: iframeTemplate,\n },\n ajax: { settings: { headers: { 'X-Requested-With': 'XMLHttpRequest' } } },\n media: providers,\n\n hash: true,\n slideshow: slideshowDefaults,\n thumbs: thumbsDefaults,\n fullscreen: fullscreenDefaults,\n share: true,\n\n lang: 'en',\n i18n: { en: i18nEn },\n baseTpl: baseTemplate,\n btnTpl: buttonTemplates,\n spinnerTpl: spinnerTemplate,\n errorTpl: errorTemplate,\n}\n","import type { ContentType } from '../types'\n\nconst IMAGE_EXT = /\\.(avif|bmp|gif|jpe?g|png|svg|webp|ico)(\\?.*)?$/i\nconst VIDEO_EXT = /\\.(mp4|webm|ogg|ogv|mov|m4v)(\\?.*)?$/i\nconst PDF_EXT = /\\.pdf(\\?.*)?$/i\nconst SELECTOR = /^(#[\\w-]+|\\.[\\w-]+)$/\n\n/** Guesses the content type from a URL; falls back to `fallback` for unknown URLs. */\nexport function detectType(src: string, fallback: ContentType = 'image'): ContentType {\n if (!src) return 'html'\n if (SELECTOR.test(src)) return 'inline'\n if (IMAGE_EXT.test(src)) return 'image'\n if (VIDEO_EXT.test(src)) return 'video'\n if (PDF_EXT.test(src)) return 'iframe'\n return fallback\n}\n\nexport function videoMime(src: string): string {\n const ext = src.match(/\\.(\\w+)(?:\\?|$)/)?.[1]?.toLowerCase()\n if (!ext) return 'video/mp4'\n return `video/${ext === 'ogv' ? 'ogg' : ext}`\n}\n","import type { ContentType, GlareOptions, SlideItem, SlideSource } from '../types'\nimport { detectType } from './detect'\nimport { applyProvider } from './providers'\n\n/** Turns a user-provided slide into a normalized `SlideItem`. */\nexport function normalizeItem(source: SlideSource | string, index: number, opts: GlareOptions): SlideItem {\n const raw: SlideSource = typeof source === 'string' ? { src: source } : { ...source }\n let src = raw.src ?? ''\n let type = raw.type\n let thumb = raw.thumb\n\n const provided = src ? applyProvider(src, opts.media) : null\n if (provided) {\n src = provided.src ?? src\n type ??= provided.type\n thumb ??= provided.thumb\n }\n\n if (!type) {\n type = raw.html || raw.content ? 'html' : detectType(src, opts.defaultType)\n }\n\n return {\n ...raw,\n index,\n src,\n type,\n thumb,\n caption: raw.caption ?? raw.title ?? '',\n isLoaded: false,\n hasError: false,\n }\n}\n\nconst attr = (el: HTMLElement, name: string): string | undefined => el.getAttribute(name) || undefined\n\n/** Reads slide data from trigger elements (`href`, `data-*` attributes, nested `<img>`). */\nexport function itemsFromElements(elements: HTMLElement[], opts: GlareOptions): SlideItem[] {\n return elements.map((el, index) => {\n const img = el.querySelector('img')\n const caption = attr(el, 'data-caption') ?? attr(el, 'title') ?? ''\n\n return normalizeItem(\n {\n src: attr(el, 'data-src') ?? attr(el, 'href') ?? '',\n type: attr(el, 'data-type') as ContentType | undefined,\n caption,\n alt: img?.getAttribute('alt') || caption,\n thumb: attr(el, 'data-thumb') ?? img?.getAttribute('src') ?? undefined,\n width: attr(el, 'data-width'),\n height: attr(el, 'data-height'),\n poster: attr(el, 'data-poster'),\n downloadSrc: attr(el, 'data-download-src'),\n html: attr(el, 'data-html'),\n $trigger: el,\n },\n index,\n opts,\n )\n })\n}\n\nexport function createItems(\n items: Array<SlideSource | string> | HTMLElement[],\n opts: GlareOptions,\n): SlideItem[] {\n if (items.length && items[0] instanceof HTMLElement) {\n return itemsFromElements(items as HTMLElement[], opts)\n }\n return (items as Array<SlideSource | string>).map((item, i) => normalizeItem(item, i, opts))\n}\n","export function $(selector: string, root: ParentNode = document): HTMLElement | null {\n return root.querySelector<HTMLElement>(selector)\n}\n\nexport function $$(selector: string, root: ParentNode = document): HTMLElement[] {\n return Array.from(root.querySelectorAll<HTMLElement>(selector))\n}\n\nexport function createEl<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n className = '',\n html = '',\n): HTMLElementTagNameMap[K] {\n const el = document.createElement(tag)\n if (className) el.className = className\n if (html) el.innerHTML = html\n return el\n}\n\n/** Parses an HTML string and returns its first element. */\nexport function fromHtml(html: string): HTMLElement {\n const wrapper = createEl('div', '', html.trim())\n return wrapper.firstElementChild as HTMLElement\n}\n\n/** Strips markup from an HTML string, for labels that must be plain text. */\nexport function toText(html: string): string {\n if (!/[<&]/.test(html)) return html.trim()\n return new DOMParser().parseFromString(html, 'text/html').body.textContent?.trim() ?? ''\n}\n\n/** Resolves a selector or element, searching `root` first and then the document. */\nexport function resolveElement(\n target: string | HTMLElement | null | undefined,\n root: ParentNode = document,\n): HTMLElement | null {\n if (!target) return null\n if (typeof target !== 'string') return target\n return $(target, root) ?? $(target)\n}\n\nexport function toCssSize(value: number | string): string {\n return typeof value === 'number' ? `${value}px` : value\n}\n\n/** Adds an event listener and returns a function that removes it. */\nexport function on<K extends keyof GlobalEventHandlersEventMap>(\n target: EventTarget,\n type: K,\n handler: (event: GlobalEventHandlersEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n): () => void\nexport function on(\n target: EventTarget,\n type: string,\n handler: EventListener,\n options?: boolean | AddEventListenerOptions,\n): () => void\nexport function on(\n target: EventTarget,\n type: string,\n handler: EventListener,\n options?: boolean | AddEventListenerOptions,\n): () => void {\n target.addEventListener(type, handler, options)\n return () => target.removeEventListener(type, handler, options)\n}\n\n/** Runs `callback` after the browser has painted the current frame. */\nexport function nextFrame(callback: () => void): void {\n requestAnimationFrame(() => requestAnimationFrame(callback))\n}\n\n/**\n * Runs `done` exactly once when a transition on `el` ends,\n * or after `duration` as a fallback for transitions that never fire.\n */\nexport function afterTransition(el: HTMLElement, duration: number, done: () => void): void {\n let finished = false\n const finish = () => {\n if (finished) return\n finished = true\n clearTimeout(timer)\n el.removeEventListener('transitionend', onEnd)\n done()\n }\n const onEnd = (event: Event) => {\n if (event.target === el) finish()\n }\n el.addEventListener('transitionend', onEnd)\n const timer = setTimeout(finish, duration + 50)\n}\n","export function isMobile(): boolean {\n return navigator.maxTouchPoints > 0 && window.matchMedia('(pointer: coarse)').matches\n}\n\nexport function prefersReducedMotion(): boolean {\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches\n}\n\nexport function supportsFullscreen(): boolean {\n const doc = document as Document & { webkitFullscreenEnabled?: boolean }\n return Boolean(doc.fullscreenEnabled ?? doc.webkitFullscreenEnabled)\n}\n\nconst LOCK_CLASS = 'glare-lock'\n\n/** Locks page scrolling while compensating for the scrollbar width. */\nexport function lockScroll(lock: boolean): void {\n const html = document.documentElement\n if (lock) {\n const scrollbar = window.innerWidth - html.clientWidth\n html.classList.add(LOCK_CLASS)\n if (scrollbar > 0) html.style.marginRight = `${scrollbar}px`\n } else {\n html.classList.remove(LOCK_CLASS)\n html.style.marginRight = ''\n }\n}\n","import type { GlareRefs, I18nDict, ResolvedOptions, SlideItem } from '../types'\nimport { icons } from '../icons'\nimport { $, $$, createEl, fromHtml, toText } from '../utils/dom'\nimport { supportsFullscreen } from '../utils/env'\nimport { translate } from '../utils/template'\n\nconst HIDDEN = 'glare-hidden'\n\nexport function buildContainer(opts: ResolvedOptions, dict: I18nDict, id: number, count: number): GlareRefs {\n const container = fromHtml(translate(opts.baseTpl, dict))\n container.dataset.glareId = String(id)\n if (opts.baseClass) container.classList.add(opts.baseClass)\n if (opts.modal) container.classList.add('glare-is-modal')\n\n const stage = $('.glare-stage', container)\n if (!stage) throw new Error('baseTpl must contain a .glare-stage element')\n\n const refs: GlareRefs = {\n container,\n bg: $('.glare-bg', container),\n inner: $('.glare-inner', container),\n stage,\n caption: $('.glare-caption', container),\n toolbar: $('.glare-toolbar', container),\n infobar: $('.glare-infobar', container),\n navigation: $('.glare-navigation', container),\n }\n\n const single = count < 2\n refs.navigation?.classList.toggle(HIDDEN, !opts.arrows || single)\n refs.infobar?.classList.toggle(HIDDEN, !opts.infobar || single)\n if (refs.toolbar) buildToolbar(refs.toolbar, opts, dict, single)\n\n return refs\n}\n\nfunction buildToolbar(toolbar: HTMLElement, opts: ResolvedOptions, dict: I18nDict, single: boolean): void {\n if (opts.toolbar === false) {\n toolbar.classList.add(HIDDEN)\n return\n }\n\n for (const name of opts.buttons) {\n if (single && (name === 'thumbs' || name === 'slideshow')) continue\n if (name === 'fullscreen' && !supportsFullscreen()) continue\n\n const tpl = opts.btnTpl[name]\n if (tpl) toolbar.insertAdjacentHTML('beforeend', translate(tpl, dict))\n }\n}\n\n/** Creates a hidden slide with an empty content box and appends it to the stage. */\nexport function mountSlide(stage: HTMLElement, item: SlideItem, opts: ResolvedOptions): HTMLElement {\n const slide = createEl('div', `glare-slide glare-slide--${item.type}`)\n if (opts.slideClass) slide.classList.add(opts.slideClass)\n\n const content = createEl('div', 'glare-content')\n slide.appendChild(content)\n stage.appendChild(slide)\n\n item.$slide = slide\n item.$content = content\n return slide\n}\n\n/** Makes a mounted slide the current one, fading it in unless `instant`. */\nexport function revealSlide(slide: HTMLElement, instant: boolean): void {\n if (instant) slide.style.transition = 'none'\n\n // Force a style flush so the opacity change below is transitioned (or not) as intended.\n void slide.offsetWidth\n slide.classList.add('glare-slide--current')\n\n if (instant) {\n void slide.offsetWidth\n slide.style.transition = ''\n }\n}\n\n/** Fades out every slide except `keep` and removes it after `delay`. */\nexport function retireSlides(stage: HTMLElement, keep: HTMLElement, delay: number): void {\n for (const slide of $$('.glare-slide', stage)) {\n if (slide === keep) continue\n slide.classList.remove('glare-slide--current')\n slide.classList.add('glare-slide--out')\n setTimeout(() => slide.remove(), delay)\n }\n}\n\nexport function addSmallButton(slide: HTMLElement, opts: ResolvedOptions, dict: I18nDict): void {\n slide.insertAdjacentHTML('beforeend', translate(opts.btnTpl.smallBtn ?? '', dict))\n}\n\nexport function showSpinner(stage: HTMLElement, opts: ResolvedOptions, dict: I18nDict): void {\n if (!stage.querySelector(':scope > .glare-spinner')) {\n stage.insertAdjacentHTML('beforeend', translate(opts.spinnerTpl, dict))\n }\n}\n\nexport function hideSpinner(stage: HTMLElement): void {\n stage.querySelector(':scope > .glare-spinner')?.remove()\n}\n\nexport function showError(item: SlideItem, error: unknown, opts: ResolvedOptions, dict: I18nDict): void {\n item.hasError = true\n item.error = error\n if (!item.$content) return\n\n item.$content.className = 'glare-content glare-content--error'\n item.$content.innerHTML = translate(opts.errorTpl, dict)\n}\n\nfunction isToolbarVisible(opts: ResolvedOptions, item: SlideItem): boolean {\n if (typeof opts.toolbar === 'boolean') return opts.toolbar\n return item.type === 'image'\n}\n\nexport function usesSmallButton(opts: ResolvedOptions, item: SlideItem): boolean {\n if (typeof opts.smallBtn === 'boolean') return opts.smallBtn\n return !isToolbarVisible(opts, item)\n}\n\n/** Updates every piece of chrome that depends on the current slide. */\nexport function syncChrome(refs: GlareRefs, opts: ResolvedOptions, dict: I18nDict, item: SlideItem, total: number, caption: string): void {\n const { container, toolbar, infobar } = refs\n\n setTypeClass(container, item.type)\n if (toolbar) syncToolbar(toolbar, opts, item)\n syncDownloadLink(container, item)\n if (infobar) syncInfobar(infobar, item.index, total)\n if (refs.caption) syncCaption(refs.caption, caption)\n syncArrows(container, opts, item.index, total)\n syncDialogLabel(container, dict, item, total)\n}\n\n/** Shows the toolbar for images; with `toolbar: true` other types keep everything except zoom. */\nfunction syncToolbar(toolbar: HTMLElement, opts: ResolvedOptions, item: SlideItem): void {\n if (opts.toolbar === false) return\n\n const visible = isToolbarVisible(opts, item)\n toolbar.classList.toggle(HIDDEN, !visible)\n if (!visible) return\n\n const zoomable = item.type === 'image'\n $('[data-glare-zoom]', toolbar)?.classList.toggle(HIDDEN, !zoomable)\n}\n\nfunction syncDownloadLink(container: HTMLElement, item: SlideItem): void {\n const link = container.querySelector<HTMLAnchorElement>('[data-glare-download]')\n if (!link) return\n\n const href = item.downloadSrc || (item.type === 'image' ? item.src : '')\n link.classList.toggle(HIDDEN, !href)\n if (href) link.href = href\n}\n\nfunction syncInfobar(infobar: HTMLElement, index: number, total: number): void {\n const indexEl = $('.glare-infobar-index', infobar)\n if (indexEl) indexEl.textContent = `${index + 1} / ${total}`\n}\n\nfunction syncCaption(caption: HTMLElement, html: string): void {\n caption.innerHTML = html\n caption.classList.toggle(HIDDEN, !html)\n}\n\nfunction syncArrows(container: HTMLElement, opts: ResolvedOptions, index: number, total: number): void {\n const atStart = !opts.loop && index === 0\n const atEnd = !opts.loop && index === total - 1\n setDisabled($('[data-glare-prev]', container), atStart)\n setDisabled($('[data-glare-next]', container), atEnd)\n}\n\nfunction setDisabled(button: HTMLElement | null, disabled: boolean): void {\n if (!button) return\n button.classList.toggle('glare-is-disabled', disabled)\n button.setAttribute('aria-disabled', String(disabled))\n}\n\n/** Labels the dialog and announces the slide change through the live region. */\nfunction syncDialogLabel(container: HTMLElement, dict: I18nDict, item: SlideItem, total: number): void {\n const base = toText(item.caption) || item.alt || dict.LIGHTBOX\n const label = total > 1 ? `${base} (${item.index + 1} of ${total})` : base\n\n container.setAttribute('aria-label', label)\n const live = $('.glare-live', container)\n if (live) live.textContent = label\n}\n\nfunction setTypeClass(el: HTMLElement, type: string): void {\n const previous = el.dataset.type\n if (previous) el.classList.remove(`glare-type-${previous}`)\n el.dataset.type = type\n el.classList.add(`glare-type-${type}`)\n}\n\nexport function syncZoomButton(container: HTMLElement, dict: I18nDict, zoomed: boolean, hasImage: boolean): void {\n container.classList.toggle('glare-can-zoom-out', zoomed)\n container.classList.toggle('glare-can-zoom-in', !zoomed && hasImage)\n\n const button = $('[data-glare-zoom]', container)\n const state = zoomed ? 'out' : 'in'\n if (!button || button.dataset.state === state) return\n\n button.dataset.state = state\n setToggleState(button, zoomed, zoomed ? dict.ZOOM_OUT : dict.ZOOM, zoomed ? icons.zoomOut : icons.zoomIn)\n}\n\n/** Swaps a toolbar toggle's label and icon and marks it active. */\nexport function setToggleState(button: HTMLElement, active: boolean, label: string, icon: string): void {\n button.setAttribute('title', label)\n button.setAttribute('aria-label', label)\n button.innerHTML = icon\n button.classList.toggle('glare-is-active', active)\n}\n","import type { FullscreenOptions } from '../types'\nimport type { Glare } from '../core/glare'\nimport { setToggleState } from '../core/dom'\nimport { icons } from '../icons'\nimport { $, on } from '../utils/dom'\n\ntype FullscreenDocument = Document & {\n webkitFullscreenElement?: Element | null\n webkitExitFullscreen?: () => Promise<void> | void\n}\n\ntype FullscreenElement = HTMLElement & {\n webkitRequestFullscreen?: () => Promise<void> | void\n}\n\n/** Fullscreen API wrapper with the WebKit fallback still needed by Safari. */\nexport class Fullscreen {\n private readonly offs: Array<() => void>\n\n constructor(\n private readonly glare: Glare,\n private readonly container: HTMLElement,\n opts: FullscreenOptions,\n ) {\n this.offs = [\n on(document, 'fullscreenchange', () => this.sync()),\n on(document, 'webkitfullscreenchange', () => this.sync()),\n ]\n if (opts.autoStart) this.request()\n }\n\n isFullscreen(): boolean {\n const doc = document as FullscreenDocument\n return Boolean(doc.fullscreenElement ?? doc.webkitFullscreenElement)\n }\n\n request(): void {\n const el = this.container as FullscreenElement\n const request = el.requestFullscreen ?? el.webkitRequestFullscreen\n void request?.call(el)\n }\n\n exit(): void {\n if (!this.isFullscreen()) return\n const doc = document as FullscreenDocument\n const exit = doc.exitFullscreen ?? doc.webkitExitFullscreen\n void exit?.call(document)\n }\n\n toggle(): void {\n if (this.isFullscreen()) this.exit()\n else this.request()\n }\n\n destroy(): void {\n this.exit()\n this.offs.forEach((off) => off())\n }\n\n private sync(): void {\n const active = this.isFullscreen()\n this.container.classList.toggle('glare-is-fullscreen', active)\n\n const button = $('[data-glare-fullscreen]', this.container)\n if (!button) return\n\n const { dict } = this.glare\n setToggleState(\n button,\n active,\n active ? dict.FULL_SCREEN_EXIT : dict.FULL_SCREEN,\n active ? icons.fullscreenExit : icons.fullscreen,\n )\n }\n}\n","function isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null) return false\n const proto = Object.getPrototypeOf(value)\n return proto === Object.prototype || proto === null\n}\n\n/** Recursively merges plain objects; other values (arrays, elements, RegExps) are replaced. */\nexport function deepMerge<T extends object>(...sources: Array<object | null | undefined | false>): T {\n const result: Record<string, unknown> = {}\n\n for (const source of sources) {\n if (!source) continue\n for (const [key, value] of Object.entries(source)) {\n if (value === undefined) continue\n const existing = result[key]\n result[key] = isPlainObject(value)\n ? deepMerge(isPlainObject(existing) ? existing : {}, value)\n : value\n }\n }\n\n return result as T\n}\n\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value))\n}\n","import { clamp } from '../utils/object'\n\nexport interface Point {\n x: number\n y: number\n}\n\nexport interface ZoomState extends Point {\n scale: number\n}\n\nexport interface ZoomTarget {\n image(): HTMLImageElement | null\n stage(): HTMLElement | null\n onChange(zoomed: boolean): void\n}\n\nexport const ZOOM_MIN = 1\nexport const ZOOM_MAX = 5\nconst ZOOMED_THRESHOLD = 1.01\n\n/**\n * Controls the transform of the current image.\n * The image is scaled around its centre and then translated by (x, y).\n */\nexport class Zoom {\n scale = ZOOM_MIN\n x = 0\n y = 0\n\n constructor(private readonly target: ZoomTarget) {}\n\n get isZoomed(): boolean {\n return this.scale > ZOOMED_THRESHOLD\n }\n\n get state(): ZoomState {\n return { scale: this.scale, x: this.x, y: this.y }\n }\n\n /** Centre of the image in viewport coordinates, ignoring the current translation. */\n center(): Point | null {\n const image = this.target.image()\n if (!image) return null\n const rect = image.getBoundingClientRect()\n return { x: rect.left + rect.width / 2 - this.x, y: rect.top + rect.height / 2 - this.y }\n }\n\n apply(scale: number, x: number, y: number, duration = 0): void {\n const image = this.target.image()\n if (!image) return\n\n this.scale = clamp(scale, ZOOM_MIN, ZOOM_MAX)\n const translate = this.isZoomed ? this.bounded(x, y) : { x: 0, y: 0 }\n this.x = translate.x\n this.y = translate.y\n\n image.style.transitionDuration = `${duration}ms`\n image.style.transform = `translate3d(${this.x}px, ${this.y}px, 0) scale(${this.scale})`\n this.target.onChange(this.isZoomed)\n }\n\n toFit(duration = 300): void {\n this.apply(ZOOM_MIN, 0, 0, duration)\n }\n\n /** Zooms to the image's natural size (at least 1.5x), keeping `focus` under the pointer. */\n toActual(focus?: Partial<Point>, duration = 300): void {\n const image = this.target.image()\n const center = this.center()\n if (!image || !center) return\n\n const natural = image.naturalWidth / Math.max(image.offsetWidth, 1)\n const scale = clamp(Math.max(natural, 1.5), ZOOM_MIN, ZOOM_MAX)\n const fx = focus?.x ?? center.x\n const fy = focus?.y ?? center.y\n this.apply(scale, (center.x - fx) * (scale - 1), (center.y - fy) * (scale - 1), duration)\n }\n\n reset(): void {\n const image = this.target.image()\n if (image) {\n image.style.transform = ''\n image.style.transitionDuration = ''\n }\n this.scale = ZOOM_MIN\n this.x = 0\n this.y = 0\n this.target.onChange(false)\n }\n\n /** Keeps the scaled image from being dragged fully out of the stage. */\n private bounded(x: number, y: number): Point {\n const image = this.target.image()\n const stage = this.target.stage()\n if (!image || !stage) return { x, y }\n const maxX = Math.max(0, (image.offsetWidth * this.scale - stage.clientWidth) / 2)\n const maxY = Math.max(0, (image.offsetHeight * this.scale - stage.clientHeight) / 2)\n return { x: clamp(x, -maxX, maxX), y: clamp(y, -maxY, maxY) }\n }\n}\n","import type { TouchOptions } from '../types'\nimport type { Point, Zoom, ZoomState } from '../core/zoom'\nimport { on } from '../utils/dom'\nimport { clamp } from '../utils/object'\nimport { ZOOM_MAX, ZOOM_MIN } from '../core/zoom'\n\nexport interface GestureHost {\n zoom: Zoom\n touch: TouchOptions\n /** The backdrop, dimmed while the stage is dragged vertically. */\n bg: HTMLElement | null\n /** Whether the current slide can be panned when zoomed. */\n canPan(): boolean\n close(): void\n next(): void\n prev(): void\n}\n\ntype Mode = 'idle' | 'swipe' | 'pan' | 'pinch'\n\nconst MOVE_THRESHOLD = 6\nconst MOMENTUM = 120\nconst SWIPE_CLOSE_DISTANCE = 100\nconst SWIPE_CLOSE_VELOCITY = 0.5\nconst SWIPE_NAV_DISTANCE = 80\nconst SWIPE_NAV_VELOCITY = 0.4\nconst IGNORED_TARGETS = 'a, button, input, textarea, select, video, .glare-thumbs'\n\nconst distance = (a: Point, b: Point): number => Math.hypot(a.x - b.x, a.y - b.y)\nconst midpoint = (a: Point, b: Point): Point => ({ x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 })\nconst pointOf = (event: PointerEvent): Point => ({ x: event.clientX, y: event.clientY })\n\n/** Swipe, pan and pinch handling on top of Pointer Events. */\nexport class Gestures {\n private readonly pointers = new Map<number, Point>()\n private readonly offs: Array<() => void>\n private mode: Mode = 'idle'\n private moved = false\n private start: Point[] = []\n private startTime = 0\n private startZoom: ZoomState = { scale: 1, x: 0, y: 0 }\n private startMid: Point = { x: 0, y: 0 }\n private startDistance = 0\n\n constructor(\n private readonly stage: HTMLElement,\n private readonly host: GestureHost,\n ) {\n this.offs = [\n on(stage, 'pointerdown', (event) => this.onDown(event)),\n on(window, 'pointermove', (event) => this.onMove(event), { passive: false }),\n on(window, 'pointerup', (event) => this.onUp(event)),\n on(window, 'pointercancel', (event) => this.onUp(event)),\n ]\n }\n\n destroy(): void {\n this.offs.forEach((off) => off())\n this.pointers.clear()\n }\n\n /** Returns whether the last gesture moved, then clears the flag. */\n consumeMoved(): boolean {\n const moved = this.moved\n this.moved = false\n return moved\n }\n\n private onDown(event: PointerEvent): void {\n if (event.pointerType === 'mouse' && event.button !== 0) return\n if ((event.target as Element).closest(IGNORED_TARGETS)) return\n\n this.pointers.set(event.pointerId, pointOf(event))\n if (this.pointers.size <= 2) this.begin()\n }\n\n private onMove(event: PointerEvent): void {\n if (!this.pointers.has(event.pointerId)) return\n this.pointers.set(event.pointerId, pointOf(event))\n this.move(event)\n }\n\n private onUp(event: PointerEvent): void {\n if (!this.pointers.has(event.pointerId)) return\n this.pointers.delete(event.pointerId)\n\n if (this.pointers.size === 0) this.end(pointOf(event))\n else this.begin()\n }\n\n /** Anchors a new gesture on the currently pressed pointers. */\n private begin(): void {\n if (this.mode === 'swipe') this.releaseStage()\n\n const points = [...this.pointers.values()]\n this.start = points\n this.startTime = performance.now()\n this.startZoom = this.host.zoom.state\n this.mode = points.length >= 2 ? 'pinch' : 'idle'\n\n if (points.length >= 2) {\n this.startDistance = distance(points[0], points[1])\n this.startMid = midpoint(points[0], points[1])\n }\n }\n\n private move(event: PointerEvent): void {\n const points = [...this.pointers.values()]\n if (!this.start.length || !points.length) return\n\n if (this.mode === 'pinch' && points.length >= 2) {\n event.preventDefault()\n this.moved = true\n this.pinch(points[0], points[1])\n return\n }\n\n const dx = points[0].x - this.start[0].x\n const dy = points[0].y - this.start[0].y\n if (!this.moved && Math.hypot(dx, dy) < MOVE_THRESHOLD) return\n this.moved = true\n\n if (this.mode === 'idle') {\n this.mode = this.host.zoom.isZoomed && this.host.canPan() ? 'pan' : 'swipe'\n }\n\n if (this.mode === 'pan') {\n event.preventDefault()\n this.host.zoom.apply(this.startZoom.scale, this.startZoom.x + dx, this.startZoom.y + dy)\n } else if (this.mode === 'swipe') {\n const vertical = this.host.touch.vertical !== false\n if (!vertical && Math.abs(dy) > Math.abs(dx)) return\n event.preventDefault()\n this.dragStage(dx, vertical ? dy : 0)\n }\n }\n\n /** Scales around the pinch midpoint so the content under the fingers stays put. */\n private pinch(a: Point, b: Point): void {\n const { zoom } = this.host\n const mid = midpoint(a, b)\n const center = zoom.center() ?? mid\n const scale = clamp(\n (this.startZoom.scale * distance(a, b)) / (this.startDistance || 1),\n ZOOM_MIN,\n ZOOM_MAX,\n )\n\n // Image-space offset of the point that was under the starting midpoint.\n const ox = (this.startMid.x - center.x - this.startZoom.x) / this.startZoom.scale\n const oy = (this.startMid.y - center.y - this.startZoom.y) / this.startZoom.scale\n zoom.apply(scale, mid.x - center.x - scale * ox, mid.y - center.y - scale * oy)\n }\n\n private end(last: Point): void {\n if (!this.start.length) return\n\n const elapsed = Math.max(performance.now() - this.startTime, 1)\n const dx = last.x - this.start[0].x\n const dy = last.y - this.start[0].y\n const velocity = { x: dx / elapsed, y: dy / elapsed }\n\n if (this.mode === 'swipe') {\n this.releaseStage()\n this.finishSwipe(dx, dy, velocity)\n } else if (this.mode === 'pan' && this.host.touch.momentum !== false) {\n const { zoom } = this.host\n zoom.apply(zoom.scale, zoom.x + velocity.x * MOMENTUM, zoom.y + velocity.y * MOMENTUM, 250)\n }\n\n this.mode = 'idle'\n this.start = []\n // Let the click that follows this gesture see `moved`, then forget it.\n if (this.moved) setTimeout(() => (this.moved = false), 0)\n }\n\n /** Moves the whole stage with the finger and dims the backdrop on vertical drags. */\n private dragStage(dx: number, dy: number): void {\n this.stage.style.transitionDuration = '0ms'\n this.stage.style.transform = `translate3d(${dx}px, ${dy}px, 0)`\n\n const { bg } = this.host\n if (bg) {\n bg.style.transitionDuration = '0ms'\n bg.style.opacity = String(clamp(1 - Math.abs(dy) / 400, 0.35, 1))\n }\n }\n\n private releaseStage(): void {\n this.stage.style.transitionDuration = ''\n this.stage.style.transform = ''\n\n const { bg } = this.host\n if (bg) {\n bg.style.transitionDuration = ''\n bg.style.opacity = ''\n }\n }\n\n /** A long or fast vertical swipe closes; a horizontal one navigates. */\n private finishSwipe(dx: number, dy: number, velocity: Point): void {\n const vertical = Math.abs(dy) > Math.abs(dx)\n\n if (vertical) {\n if (Math.abs(dy) > SWIPE_CLOSE_DISTANCE || Math.abs(velocity.y) > SWIPE_CLOSE_VELOCITY) this.host.close()\n return\n }\n\n if (Math.abs(dx) > SWIPE_NAV_DISTANCE || Math.abs(velocity.x) > SWIPE_NAV_VELOCITY) {\n if (dx < 0) this.host.next()\n else this.host.prev()\n }\n }\n}\n","import type { Glare } from '../core/glare'\nimport { on } from '../utils/dom'\n\nconst HASH_PATTERN = /^(.+)-(\\d+)$/\n\n/** Parses `#gallery-3` into `{ gallery: 'gallery', index: 2 }`. */\nexport function parseHash(hash = window.location.hash): { gallery: string; index: number } | null {\n const match = hash.replace(/^#/, '').match(HASH_PATTERN)\n if (!match) return null\n return { gallery: match[1], index: Math.max(0, parseInt(match[2], 10) - 1) }\n}\n\nfunction formatHash(gallery: string, index: number): string {\n return `${gallery}-${index + 1}`\n}\n\n/**\n * Keeps the URL hash in sync with the current slide of a named gallery.\n * Opening pushes one history entry so the browser's Back button closes the lightbox;\n * slide changes replace it so Back never walks through every slide.\n */\nexport class Hash {\n private readonly off: () => void\n private pushed = false\n\n constructor(\n private readonly glare: Glare,\n private readonly gallery: string,\n ) {\n this.off = on(window, 'hashchange', () => this.onHashChange())\n\n const next = formatHash(gallery, glare.currIndex)\n if (currentHash() !== next) {\n window.history.pushState(null, '', `#${next}`)\n this.pushed = true\n }\n }\n\n update(index = this.glare.currIndex): void {\n const next = formatHash(this.gallery, index)\n if (currentHash() !== next) this.replace(`#${next}`)\n }\n\n destroy(): void {\n this.off()\n if (parseHash()?.gallery !== this.gallery) return\n\n if (this.pushed) window.history.back()\n else this.replace('')\n }\n\n private onHashChange(): void {\n const parsed = parseHash()\n if (!parsed || parsed.gallery !== this.gallery) {\n this.pushed = false\n this.glare.close()\n } else if (parsed.index !== this.glare.currIndex) {\n this.glare.jumpTo(parsed.index)\n }\n }\n\n private replace(hash: string): void {\n const { pathname, search } = window.location\n window.history.replaceState(null, '', `${pathname}${search}${hash}`)\n }\n}\n\nconst currentHash = (): string => window.location.hash.replace(/^#/, '')\n","import type { ShareOptions, SlideItem } from '../types'\nimport type { Glare } from '../core/glare'\nimport { shareTemplate } from '../templates'\nimport { $, createEl, on, toText } from '../utils/dom'\nimport { translate } from '../utils/template'\n\n/** Overlay with social share links and a copyable URL. */\nexport class Share {\n private overlay: HTMLElement | null = null\n private off: (() => void) | null = null\n\n constructor(\n private readonly glare: Glare,\n private readonly container: HTMLElement,\n private readonly opts: ShareOptions,\n ) {}\n\n get isOpen(): boolean {\n return this.overlay !== null\n }\n\n open(): void {\n const { current, dict } = this.glare\n if (!current) return\n this.close()\n\n const url = this.resolveUrl(current)\n const encoded = encodeURIComponent(url)\n const media = encodeURIComponent(current.thumb || current.src || url)\n const caption = encodeURIComponent(toText(current.caption))\n\n const html = translate(this.opts.tpl ?? shareTemplate, {\n ...dict,\n url_direct: url,\n url_facebook: `https://www.facebook.com/sharer/sharer.php?u=${encoded}`,\n url_twitter: `https://twitter.com/intent/tweet?url=${encoded}&text=${caption}`,\n url_pinterest: `https://pinterest.com/pin/create/button/?url=${encoded}&media=${media}&description=${caption}`,\n })\n\n this.overlay = createEl('div', 'glare-share-overlay', html)\n this.container.appendChild(this.overlay)\n\n const input = $('.glare-share-input', this.overlay) as HTMLInputElement | null\n input?.select()\n\n this.off = on(this.overlay, 'click', (event) => {\n const target = event.target as HTMLElement\n if (target === this.overlay || target.closest('[data-glare-share-close]')) this.close()\n else if (target.closest('[data-glare-share-copy]')) void this.copy(url, input)\n })\n }\n\n close(): void {\n if (!this.overlay) return\n\n const hadFocus = this.overlay.contains(document.activeElement)\n this.off?.()\n this.off = null\n this.overlay.remove()\n this.overlay = null\n\n // Return focus into the dialog so the focus trap keeps working.\n if (!hadFocus) return\n const button = $('[data-glare-share]', this.container)\n if (button) button.focus()\n else this.glare.focus()\n }\n\n destroy(): void {\n this.close()\n }\n\n private async copy(url: string, input: HTMLInputElement | null): Promise<void> {\n try {\n await navigator.clipboard.writeText(url)\n } catch {\n input?.select()\n document.execCommand('copy')\n }\n input?.select()\n }\n\n private resolveUrl(item: SlideItem): string {\n const { url } = this.opts\n if (typeof url === 'function') return url(item)\n if (url) return url\n return /^https?:\\/\\//i.test(item.src) ? item.src : window.location.href\n }\n}\n","import type { SlideshowOptions } from '../types'\nimport type { Glare } from '../core/glare'\nimport { setToggleState } from '../core/dom'\nimport { slideshowDefaults } from '../defaults'\nimport { icons } from '../icons'\nimport { $ } from '../utils/dom'\nimport { prefersReducedMotion } from '../utils/env'\n\n/** Advances slides on a timer and animates the top progress bar. */\nexport class Slideshow {\n private readonly bar: HTMLElement | null\n private readonly button: HTMLElement | null\n private timer: ReturnType<typeof setTimeout> | null = null\n private active = false\n\n constructor(\n private readonly glare: Glare,\n private readonly container: HTMLElement,\n private readonly opts: SlideshowOptions,\n ) {\n this.bar = $('.glare-progress', container)\n this.button = $('[data-glare-slideshow]', container)\n if (opts.autoStart) this.start()\n }\n\n isActive(): boolean {\n return this.active\n }\n\n start(): void {\n if (this.glare.group.length < 2) return\n\n this.active = true\n this.container.classList.add('glare-is-slideshow')\n this.syncButton()\n this.schedule()\n }\n\n stop(): void {\n this.active = false\n this.clearTimer()\n this.setProgress(0, true)\n this.container.classList.remove('glare-is-slideshow')\n this.syncButton()\n }\n\n toggle(): void {\n if (this.active) this.stop()\n else this.start()\n }\n\n onIndexChange(): void {\n if (this.active) this.schedule()\n }\n\n destroy(): void {\n this.stop()\n }\n\n private get speed(): number {\n return this.opts.speed ?? slideshowDefaults.speed\n }\n\n private get atEnd(): boolean {\n return !this.glare.opts.loop && this.glare.currIndex === this.glare.group.length - 1\n }\n\n private schedule(): void {\n this.clearTimer()\n this.setProgress(0)\n\n if (!prefersReducedMotion()) {\n // Force a reflow so the bar restarts from zero before animating.\n void this.bar?.offsetWidth\n this.setProgress(1)\n }\n\n this.timer = setTimeout(() => (this.atEnd ? this.stop() : this.glare.next()), this.speed)\n }\n\n private clearTimer(): void {\n if (this.timer) clearTimeout(this.timer)\n this.timer = null\n }\n\n private setProgress(value: 0 | 1, hide = false): void {\n if (!this.bar) return\n\n this.bar.hidden = hide\n this.bar.style.transitionDuration = value ? `${this.speed}ms` : '0ms'\n this.bar.style.transform = `scaleX(${value})`\n }\n\n private syncButton(): void {\n if (!this.button) return\n\n const { dict } = this.glare\n setToggleState(\n this.button,\n this.active,\n this.active ? dict.PLAY_STOP : dict.PLAY_START,\n this.active ? icons.pause : icons.play,\n )\n }\n}\n","import type { ThumbsOptions } from '../types'\nimport type { Glare } from '../core/glare'\nimport { $, $$, createEl, on, resolveElement, toText } from '../utils/dom'\nimport { translate } from '../utils/template'\n\n/** Clickable thumbnail strip, horizontal (`x`) or vertical (`y`). */\nexport class Thumbs {\n isActive = false\n private readonly axis: 'x' | 'y'\n private readonly strip: HTMLElement\n private readonly list: HTMLElement\n private offs: Array<() => void> = []\n\n constructor(\n private readonly glare: Glare,\n private readonly container: HTMLElement,\n private readonly opts: ThumbsOptions,\n ) {\n this.axis = opts.axis === 'y' ? 'y' : 'x'\n this.list = createEl('div', 'glare-thumbs-list')\n this.strip = createEl('div', `glare-thumbs glare-thumbs--${this.axis}`)\n this.strip.appendChild(this.list)\n this.build()\n }\n\n show(): void {\n this.setActive(true)\n }\n\n hide(): void {\n this.setActive(false)\n }\n\n toggle(): void {\n this.setActive(!this.isActive)\n }\n\n /** Highlights the thumbnail for `index` and scrolls it into view. */\n focus(index = this.glare.currIndex): void {\n for (const el of $$('.glare-thumbs-item', this.list)) {\n el.classList.toggle('glare-is-active', Number(el.dataset.index) === index)\n }\n this.list\n .querySelector('.glare-is-active')\n ?.scrollIntoView({ block: 'nearest', inline: 'nearest', behavior: 'smooth' })\n }\n\n destroy(): void {\n this.offs.forEach((off) => off())\n this.offs = []\n this.container.classList.remove(`glare-thumbs-axis-${this.axis}`)\n this.strip.remove()\n }\n\n private setActive(active: boolean): void {\n this.isActive = active\n this.strip.classList.toggle('glare-thumbs--active', active)\n this.container.classList.toggle('glare-show-thumbs', active)\n\n const button = $('[data-glare-thumbs]', this.container)\n button?.classList.toggle('glare-is-active', active)\n button?.setAttribute('aria-expanded', String(active))\n }\n\n private build(): void {\n const { group, dict } = this.glare\n if (group.length < 2) return\n\n this.container.classList.add(`glare-thumbs-axis-${this.axis}`)\n\n for (const item of group) {\n const button = createEl('button', 'glare-thumbs-item')\n button.type = 'button'\n button.dataset.index = String(item.index)\n button.setAttribute('aria-label', translate(dict.GO_TO_SLIDE, { index: String(item.index + 1) }))\n\n const src = item.thumb || (item.type === 'image' ? item.src : '')\n if (src) {\n const img = createEl('img')\n img.src = src\n img.alt = item.alt || toText(item.caption)\n img.loading = 'lazy'\n button.appendChild(img)\n } else {\n button.textContent = String(item.index + 1)\n }\n\n this.list.appendChild(button)\n this.offs.push(on(button, 'click', () => this.glare.jumpTo(item.index)))\n }\n\n const parent = resolveElement(this.opts.parentEl, this.container) ?? this.container\n parent.appendChild(this.strip)\n if (this.opts.autoStart) this.show()\n this.focus()\n }\n}\n","import type { SlideItem } from '../types'\nimport { on } from '../utils/dom'\n\nexport interface WheelHost {\n /** `'auto'` only navigates on image slides; `true` on every slide. */\n mode: boolean | 'auto'\n current(): SlideItem | null\n isZoomed(): boolean\n next(): void\n prev(): void\n}\n\n/** Accumulated distance that counts as one deliberate scroll. */\nconst STEP = 40\n/** Gap between events that marks the end of a gesture, including trackpad inertia. */\nconst SETTLE = 150\nconst LINE_HEIGHT = 16\n\n/** Mouse-wheel navigation between slides: one gesture moves one slide. */\nexport class WheelNav {\n private readonly off: () => void\n private distance = 0\n private fired = false\n private settle: ReturnType<typeof setTimeout> | null = null\n\n constructor(stage: HTMLElement, host: WheelHost) {\n this.off = on(\n stage,\n 'wheel',\n (event) => {\n const current = host.current()\n if (!current || event.deltaY === 0) return\n if (host.mode === 'auto' && current.type !== 'image') return\n if (current.type === 'image' && host.isZoomed()) return\n\n event.preventDefault()\n this.restartSettle()\n if (this.fired) return\n\n this.distance += normalize(event, stage)\n if (Math.abs(this.distance) < STEP) return\n\n this.fired = true\n if (this.distance > 0) host.next()\n else host.prev()\n },\n { passive: false },\n )\n }\n\n destroy(): void {\n if (this.settle) clearTimeout(this.settle)\n this.off()\n }\n\n private restartSettle(): void {\n if (this.settle) clearTimeout(this.settle)\n this.settle = setTimeout(() => {\n this.distance = 0\n this.fired = false\n }, SETTLE)\n }\n}\n\n/** Converts line- and page-based deltas to pixels so every input reaches `STEP`. */\nfunction normalize(event: WheelEvent, stage: HTMLElement): number {\n if (event.deltaMode === WheelEvent.DOM_DELTA_LINE) return event.deltaY * LINE_HEIGHT\n if (event.deltaMode === WheelEvent.DOM_DELTA_PAGE) return event.deltaY * stage.clientHeight\n return event.deltaY\n}\n","import type { ResolvedOptions, SlideItem } from '../types'\nimport { nextFrame } from '../utils/dom'\nimport { prefersReducedMotion } from '../utils/env'\n\n/** Writes the effect and duration settings onto the container for the stylesheet to use. */\nexport function applyMotionSettings(container: HTMLElement, opts: ResolvedOptions): void {\n const reduced = prefersReducedMotion()\n const effect = reduced ? false : opts.animationEffect\n const transition = reduced ? false : opts.transitionEffect\n\n container.dataset.animation = effect || 'none'\n container.style.setProperty('--glare-duration', `${effect ? opts.animationDuration : 0}ms`)\n container.style.setProperty('--glare-transition-duration', `${transition ? opts.transitionDuration : 0}ms`)\n}\n\n/** Marks the container so slide-change keyframes apply from now on. */\nexport function enableTransitions(container: HTMLElement, opts: ResolvedOptions): void {\n const transition = prefersReducedMotion() ? false : opts.transitionEffect\n container.dataset.transition = transition || 'none'\n}\n\n/** Flies the opened image in from its trigger element. */\nexport function animateOpen(container: HTMLElement, item: SlideItem, opts: ResolvedOptions): void {\n const image = item.$image\n const trigger = item.$trigger\n if (container.dataset.animation !== 'zoom' || !image || !trigger) return\n\n const from = trigger.getBoundingClientRect()\n const to = image.getBoundingClientRect()\n const scale = Math.max(from.width / Math.max(to.width, 1), from.height / Math.max(to.height, 1))\n const dx = from.left + from.width / 2 - (to.left + to.width / 2)\n const dy = from.top + from.height / 2 - (to.top + to.height / 2)\n\n Object.assign(image.style, {\n transform: `translate3d(${dx}px, ${dy}px, 0) scale(${scale})`,\n opacity: opts.zoomOpacity ? '0.2' : '1',\n transitionDuration: '0ms',\n })\n nextFrame(() => {\n Object.assign(image.style, { transform: '', opacity: '', transitionDuration: '' })\n })\n}\n","import type { GlareOptions, ResolvedOptions } from '../types'\nimport { defaults } from '../defaults'\nimport { isMobile } from '../utils/env'\nimport { deepMerge } from '../utils/object'\n\n/** Merges user options over the defaults, then applies `mobile` overrides on touch devices. */\nexport function resolveOptions(options: GlareOptions): ResolvedOptions {\n const merged = deepMerge<ResolvedOptions>(defaults, options)\n return isMobile() && merged.mobile ? deepMerge<ResolvedOptions>(merged, merged.mobile) : merged\n}\n\n/** Normalizes a `T | boolean` module option: `true` yields the defaults, falsy disables it. */\nexport function moduleOptions<T extends object>(value: Partial<T> | boolean | undefined, fallback: T): T | null {\n if (!value) return null\n return value === true ? { ...fallback } : { ...fallback, ...value }\n}\n","import type { BoundGroup, GlareOptions } from '../types'\nimport { parseHash } from '../modules/hash'\nimport { $$, on } from '../utils/dom'\nimport { resolveOptions } from './options'\n\nexport type BindTarget = string | HTMLElement | HTMLElement[] | NodeListOf<HTMLElement>\n\n/** Opens `elements` as a gallery named `gallery`, starting at `index`. */\ntype Opener = (elements: HTMLElement[], index: number, gallery: string) => void\n\nconst groups: BoundGroup[] = []\n\nconst galleryOf = (el: HTMLElement): string => el.getAttribute('data-glare') ?? ''\n\nfunction toElements(target: BindTarget): HTMLElement[] {\n if (typeof target === 'string') return $$(target)\n if (target instanceof HTMLElement) return [target]\n return Array.from(target)\n}\n\n/** Attaches click handlers that open a lightbox for the clicked element's gallery. */\nexport function bind(target: BindTarget, options: GlareOptions, open: Opener): BoundGroup {\n const elements = toElements(target)\n\n const openFrom = (el: HTMLElement) => {\n const gallery = galleryOf(el)\n const members = gallery ? elements.filter((item) => galleryOf(item) === gallery) : [el]\n open(members, members.indexOf(el), gallery)\n }\n\n const offs = elements.map((el) =>\n on(el, 'click', (event) => {\n event.preventDefault()\n openFrom(el)\n }),\n )\n\n const group: BoundGroup = {\n elements,\n destroy() {\n offs.forEach((off) => off())\n const index = groups.indexOf(group)\n if (index >= 0) groups.splice(index, 1)\n },\n }\n groups.push(group)\n\n if (resolveOptions(options).hash) restoreFromHash(elements, openFrom)\n return group\n}\n\nexport function unbindAll(): void {\n for (const group of [...groups]) group.destroy()\n}\n\n/** Opens the slide referenced by the current URL hash, if it belongs to a bound gallery. */\nfunction restoreFromHash(elements: HTMLElement[], openFrom: (el: HTMLElement) => void): void {\n const parsed = parseHash()\n if (!parsed) return\n\n const members = elements.filter((el) => galleryOf(el) === parsed.gallery)\n const el = members[parsed.index]\n if (el) openFrom(el)\n}\n","/** Calls `onIdle` after `seconds` of no activity; `false` disables it. */\nexport class IdleTimer {\n private timer: ReturnType<typeof setTimeout> | null = null\n\n constructor(\n private readonly seconds: number | false,\n private readonly onIdle: () => void,\n ) {}\n\n reset(): void {\n this.stop()\n if (this.seconds) this.timer = setTimeout(this.onIdle, this.seconds * 1000)\n }\n\n stop(): void {\n if (this.timer) clearTimeout(this.timer)\n this.timer = null\n }\n}\n","import type { Glare } from './glare'\n\n/** Stack of open instances, topmost last. */\nconst stack: Glare[] = []\n\nexport const registry = {\n add(instance: Glare): void {\n stack.push(instance)\n },\n remove(instance: Glare): void {\n const index = stack.indexOf(instance)\n if (index >= 0) stack.splice(index, 1)\n },\n top(): Glare | null {\n return stack[stack.length - 1] ?? null\n },\n get(id: number): Glare | null {\n return stack.find((instance) => instance.id === id) ?? null\n },\n all(): Glare[] {\n return [...stack]\n },\n get size(): number {\n return stack.length\n },\n}\n","import type { ClickAction, ClickActionName } from '../types'\nimport type { Glare } from './glare'\nimport { $$, on } from '../utils/dom'\nimport { registry } from './registry'\n\ntype ButtonHandler = (glare: Glare) => void\n\n/** Toolbar / navigation buttons, matched against `event.target` in order. */\nconst BUTTONS: Array<[selector: string, handler: ButtonHandler]> = [\n ['[data-glare-close]', (g) => g.close()],\n ['[data-glare-next]', (g) => g.next()],\n ['[data-glare-prev]', (g) => g.prev()],\n ['[data-glare-zoom]', (g) => g.toggleZoom()],\n ['[data-glare-slideshow]', (g) => g.slideshow?.toggle()],\n ['[data-glare-thumbs]', (g) => g.thumbs?.toggle()],\n ['[data-glare-fullscreen]', (g) => g.fullscreen?.toggle()],\n ['[data-glare-share]', (g) => g.share?.open()],\n]\n\nconst CONTENT = '.glare-content'\nconst SLIDE_AREA = '.glare-slide, .glare-stage'\nconst FOCUSABLE = 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\nconst FORM_TAGS = new Set(['INPUT', 'TEXTAREA', 'SELECT'])\n\n/** How long a single click waits for a possible second click when a double-click action exists. */\nconst DBLCLICK_WINDOW = 300\n\n/** Wires clicks, keyboard, focus trapping and idle tracking. Returns a cleanup function. */\nexport function bindInteractions(glare: Glare, container: HTMLElement, onActivity: () => void): () => void {\n let pendingClick: ReturnType<typeof setTimeout> | null = null\n const cancelPending = () => {\n if (pendingClick) clearTimeout(pendingClick)\n pendingClick = null\n }\n\n const offs = [\n on(container, 'click', (event) => {\n if (glare.consumeGesture()) return\n\n const target = event.target as HTMLElement\n const button = BUTTONS.find(([selector]) => target.closest(selector))\n if (button) return button[1](glare)\n if (target.closest('.glare-button')) return\n\n const single = slideAction(glare, target, 'click')\n if (!single) return\n\n // When a double-click action exists, hold the single click so a double-tap does not fire both.\n if (!resolveAction(glare, slideAction(glare, target, 'dblclick'), event)) {\n return runAction(glare, single, event)\n }\n cancelPending()\n pendingClick = setTimeout(() => runAction(glare, single, event), DBLCLICK_WINDOW)\n }),\n on(container, 'dblclick', (event) => {\n cancelPending()\n const target = event.target as HTMLElement\n if (target.closest('.glare-button')) return\n runAction(glare, slideAction(glare, target, 'dblclick'), event)\n }),\n on(document, 'keydown', (event) => onKeydown(glare, event)),\n on(document, 'keydown', onActivity),\n on(document, 'mousemove', onActivity),\n on(document, 'touchstart', onActivity, { passive: true }),\n ]\n\n if (glare.opts.trapFocus) {\n offs.push(on(container, 'keydown', (event) => trapFocus(container, event)))\n }\n\n if (glare.opts.protect) {\n offs.push(\n on(container, 'contextmenu', (event) => event.preventDefault()),\n on(container, 'dragstart', (event) => {\n if ((event.target as HTMLElement).tagName === 'IMG') event.preventDefault()\n }),\n )\n }\n\n return () => {\n cancelPending()\n offs.forEach((off) => off())\n }\n}\n\n/** Picks the content action or the slide action for `target`; modal mode ignores the slide area. */\nfunction slideAction(glare: Glare, target: HTMLElement, kind: 'click' | 'dblclick'): ClickAction | undefined {\n const { opts } = glare\n if (target.closest(CONTENT)) return kind === 'click' ? opts.clickContent : opts.dblclickContent\n if (opts.modal || !target.closest(SLIDE_AREA)) return undefined\n return kind === 'click' ? opts.clickSlide : opts.dblclickSlide\n}\n\nfunction resolveAction(glare: Glare, action: ClickAction | undefined, event: Event): ClickActionName | false | void {\n if (!action || !glare.current) return false\n return typeof action === 'function' ? action(glare.current, event) : action\n}\n\nfunction runAction(glare: Glare, action: ClickAction | undefined, event: Event): void {\n switch (resolveAction(glare, action, event)) {\n case 'close':\n return glare.close()\n case 'next':\n return glare.next()\n case 'nextOrClose':\n return glare.currIndex === glare.group.length - 1 && !glare.opts.loop ? glare.close() : glare.next()\n case 'toggleControls':\n return glare.toggleControls()\n case 'zoom': {\n const point = event instanceof MouseEvent ? { x: event.clientX, y: event.clientY } : undefined\n return glare.toggleZoom(point)\n }\n }\n}\n\nfunction onKeydown(glare: Glare, event: KeyboardEvent): void {\n if (registry.top() !== glare) return\n\n // The share overlay is its own small dialog: Escape dismisses it even from its input.\n if (event.key === 'Escape' && glare.share?.isOpen) {\n event.preventDefault()\n return glare.share.close()\n }\n if (!glare.opts.keyboard || glare.opts.modal) return\n\n const target = event.target as HTMLElement\n if (FORM_TAGS.has(target.tagName)) return\n // A focused button already activates on Space; don't toggle the slideshow as well.\n if (event.key === ' ' && target.closest('button')) return\n\n switch (event.key) {\n case 'Escape':\n event.preventDefault()\n return glare.close()\n case 'ArrowRight':\n case 'ArrowDown':\n event.preventDefault()\n return glare.next()\n case 'ArrowLeft':\n case 'ArrowUp':\n event.preventDefault()\n return glare.prev()\n case ' ':\n event.preventDefault()\n return glare.slideshow?.toggle()\n case 'f':\n case 'F':\n return glare.fullscreen?.toggle()\n }\n}\n\nfunction trapFocus(container: HTMLElement, event: KeyboardEvent): void {\n if (event.key !== 'Tab') return\n\n const focusable = $$(FOCUSABLE, container).filter(\n (el) => !el.hasAttribute('disabled') && el.offsetParent !== null && getComputedStyle(el).visibility !== 'hidden',\n )\n if (!focusable.length) return\n\n const first = focusable[0]\n const last = focusable[focusable.length - 1]\n if (event.shiftKey && document.activeElement === first) {\n event.preventDefault()\n last.focus()\n } else if (!event.shiftKey && document.activeElement === last) {\n event.preventDefault()\n first.focus()\n }\n}\n","import type { ContentType, I18nDict, ResolvedOptions, SlideItem } from '../types'\nimport { videoMime } from '../media/detect'\nimport { $, createEl, toCssSize, toText } from '../utils/dom'\nimport { translate } from '../utils/template'\n\ntype Loader = (item: SlideItem, content: HTMLElement, opts: ResolvedOptions, dict: I18nDict) => Promise<void> | void\n\nconst IFRAME_LOAD_FALLBACK = 1200\n\nconst image: Loader = (item, content, opts) =>\n new Promise((resolve, reject) => {\n const img = createEl('img', 'glare-image')\n img.alt = item.alt || toText(item.caption)\n img.decoding = 'async'\n img.draggable = false\n if (opts.protect) img.style.pointerEvents = 'none'\n\n img.onload = () => {\n item.$image = img\n item.contentWidth = img.naturalWidth\n item.contentHeight = img.naturalHeight\n content.appendChild(img)\n resolve()\n }\n img.onerror = () => reject(new Error(`Failed to load image: ${item.src}`))\n img.src = item.src\n })\n\nconst video: Loader = (item, content, opts, dict) => {\n const format = item.format || opts.video.format || videoMime(item.src)\n content.innerHTML = translate(opts.video.tpl, {\n ...dict,\n src: item.src,\n format,\n poster: item.poster ?? '',\n })\n\n const el = content.querySelector('video')\n if (el && (item.autoStart ?? opts.video.autoStart)) {\n void el.play().catch(() => undefined)\n }\n}\n\nconst iframe: Loader = (item, content, opts) =>\n new Promise((resolve) => {\n const settings = opts.iframe\n const wrap = createEl('div', 'glare-iframe-wrap', settings.tpl)\n const frame = wrap.querySelector('iframe')\n if (!frame) throw new Error('Iframe template must contain an <iframe>')\n\n for (const [name, value] of Object.entries(settings.attr)) frame.setAttribute(name, value)\n Object.assign(frame.style, settings.css)\n if (item.width) wrap.style.width = toCssSize(item.width)\n if (item.height) wrap.style.height = toCssSize(item.height)\n content.appendChild(wrap)\n\n if (!settings.preload) {\n frame.src = item.src\n resolve()\n return\n }\n\n frame.onload = () => resolve()\n frame.src = item.src\n // Cross-origin frames may never fire `load`; reveal the slide anyway.\n setTimeout(resolve, IFRAME_LOAD_FALLBACK)\n })\n\nconst inline: Loader = (item, content) => {\n const source = item.src ? $(item.src) : null\n if (!source) throw new Error(`Inline target not found: ${item.src}`)\n\n const clone = source.cloneNode(true) as HTMLElement\n clone.removeAttribute('id')\n clone.hidden = false\n clone.style.display = ''\n content.appendChild(clone)\n}\n\nconst ajax: Loader = async (item, content, opts) => {\n const response = await fetch(item.src, opts.ajax.settings)\n if (!response.ok) throw new Error(`Request failed: ${response.status} ${item.src}`)\n content.innerHTML = await response.text()\n}\n\nconst html: Loader = (item, content) => {\n if (item.content instanceof HTMLElement) {\n content.appendChild(item.content)\n } else {\n content.innerHTML = item.html ?? item.content ?? item.src\n }\n}\n\nconst loaders: Record<ContentType, Loader> = { image, video, iframe, inline, ajax, html }\n\n/** Renders the slide's content into `content` and resolves once it can be shown. */\nexport async function loadContent(item: SlideItem, content: HTMLElement, opts: ResolvedOptions, dict: I18nDict): Promise<void> {\n content.innerHTML = ''\n content.className = `glare-content glare-content--${item.type}`\n await loaders[item.type](item, content, opts, dict)\n item.isLoaded = true\n}\n\n/** Warms the browser cache for neighbouring images. */\nexport function preloadNeighbours(group: SlideItem[], index: number): void {\n for (const neighbour of [group[index - 1], group[index + 1]]) {\n if (neighbour?.type === 'image' && neighbour.src) new Image().src = neighbour.src\n }\n}\n","import type {\n BoundGroup,\n GlareInstance,\n GlareOptions,\n GlareRefs,\n I18nDict,\n LifecycleEvent,\n ResolvedOptions,\n SlideEvent,\n SlideItem,\n SlideSource,\n} from '../types'\nimport { defaults, fullscreenDefaults, slideshowDefaults, thumbsDefaults } from '../defaults'\nimport { getDict } from '../i18n'\nimport { createItems } from '../media/items'\nimport { Fullscreen } from '../modules/fullscreen'\nimport { Gestures } from '../modules/gestures'\nimport { Hash } from '../modules/hash'\nimport { Share } from '../modules/share'\nimport { Slideshow } from '../modules/slideshow'\nimport { Thumbs } from '../modules/thumbs'\nimport { WheelNav } from '../modules/wheel'\nimport { afterTransition, nextFrame } from '../utils/dom'\nimport { lockScroll, prefersReducedMotion, supportsFullscreen } from '../utils/env'\nimport { clamp } from '../utils/object'\nimport { animateOpen, applyMotionSettings, enableTransitions } from './animation'\nimport { bind, unbindAll, type BindTarget } from './bind'\nimport * as dom from './dom'\nimport { IdleTimer } from './idle'\nimport { bindInteractions } from './interactions'\nimport { loadContent, preloadNeighbours } from './loaders'\nimport { moduleOptions, resolveOptions } from './options'\nimport { registry } from './registry'\nimport { Zoom, type Point } from './zoom'\n\nlet nextId = 0\n\nexport class Glare implements GlareInstance {\n readonly id = ++nextId\n readonly opts: ResolvedOptions\n readonly group: SlideItem[]\n readonly dict: I18nDict\n readonly zoom: Zoom\n current: SlideItem | null = null\n currIndex = 0\n prevIndex = 0\n isActive = false\n isClosing = false\n isIdle = false\n $refs: GlareRefs | null = null\n\n slideshow?: Slideshow\n thumbs?: Thumbs\n fullscreen?: Fullscreen\n share?: Share\n\n private readonly galleryName: string\n private readonly idle: IdleTimer\n private hash: Hash | null = null\n private gestures: Gestures | null = null\n private wheel: WheelNav | null = null\n private cleanups: Array<() => void> = []\n private previouslyFocused: HTMLElement | null = null\n\n constructor(\n items: Array<SlideSource | string> | HTMLElement[],\n options: GlareOptions = {},\n index = 0,\n galleryName = '',\n ) {\n this.opts = resolveOptions(options)\n this.dict = getDict(this.opts)\n this.group = createItems(items, this.opts)\n this.galleryName = galleryName\n this.currIndex = this.clampIndex(index)\n\n this.zoom = new Zoom({\n image: () => this.current?.$image ?? null,\n stage: () => this.$refs?.stage ?? null,\n onChange: (zoomed) => this.syncZoomState(zoomed),\n })\n this.idle = new IdleTimer(this.opts.modal ? false : this.opts.idleTime, () => this.toggleControls(true))\n }\n\n open(index = this.currIndex): void {\n if (this.isActive) return this.jumpTo(index)\n if (!this.group.length) return\n if (this.opts.closeExisting) Glare.close(true)\n\n this.currIndex = this.clampIndex(index)\n this.current = this.group[this.currIndex]\n this.previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null\n this.emit('onInit')\n\n const refs = dom.buildContainer(this.opts, this.dict, this.id, this.group.length)\n const { container } = refs\n this.$refs = refs\n applyMotionSettings(container, this.opts)\n this.syncChrome()\n this.resolveParent().appendChild(container)\n\n this.isActive = true\n registry.add(this)\n if (this.opts.hideScrollbar) lockScroll(true)\n this.emit('onActivate')\n this.emitSlide('beforeShow', this.current)\n\n nextFrame(() => {\n if (!this.isActive) return\n\n container.classList.add('glare-is-open')\n this.showSlide(this.currIndex, true)\n this.cleanups.push(bindInteractions(this, container, () => this.onActivity()))\n this.startModules(refs)\n if (this.opts.autoFocus) this.focus()\n this.idle.reset()\n })\n }\n\n close(): void {\n if (!this.isActive || this.isClosing || !this.current || !this.$refs) return\n if (this.emitSlide('beforeClose', this.current) === false) return\n\n this.isClosing = true\n this.slideshow?.stop()\n this.idle.stop()\n\n const { container, bg } = this.$refs\n const duration = prefersReducedMotion() ? 0 : this.opts.animationDuration\n if (duration === 0) return this.teardown()\n\n container.classList.remove('glare-is-open')\n container.classList.add('glare-is-closing')\n afterTransition(bg ?? container, duration, () => this.teardown())\n }\n\n next(): void {\n this.jumpTo(this.currIndex + 1)\n }\n\n prev(): void {\n this.jumpTo(this.currIndex - 1)\n }\n\n jumpTo(index: number): void {\n if (!this.isActive || this.isClosing) return\n\n const total = this.group.length\n const target = this.opts.loop ? ((index % total) + total) % total : clamp(index, 0, total - 1)\n if (target === this.currIndex) return\n\n this.prevIndex = this.currIndex\n this.currIndex = target\n this.zoom.reset()\n this.current = this.group[target]\n this.syncChrome()\n this.showSlide(target, false)\n\n this.thumbs?.focus(target)\n this.hash?.update(target)\n this.slideshow?.onIndexChange()\n this.emitSlide('onUpdate', this.current)\n }\n\n toggleZoom(focus?: Point): void {\n if (this.current?.type !== 'image') return\n if (this.zoom.isZoomed) this.zoom.toFit()\n else this.zoom.toActual(focus)\n }\n\n update(): void {\n this.syncChrome()\n }\n\n focus(): void {\n this.$refs?.container.focus({ preventScroll: true })\n }\n\n toggleControls(force?: boolean): void {\n if (!this.$refs) return\n this.isIdle = force ?? !this.isIdle\n this.$refs.container.classList.toggle('glare-is-idle', this.isIdle)\n }\n\n /** True once per drag gesture, so the click that follows it can be ignored. */\n consumeGesture(): boolean {\n return this.gestures?.consumeMoved() ?? false\n }\n\n private async showSlide(index: number, opening: boolean): Promise<void> {\n const item = this.group[index]\n if (!this.$refs || !item) return\n\n const { container, stage } = this.$refs\n const slide = dom.mountSlide(stage, item, this.opts)\n if (dom.usesSmallButton(this.opts, item)) dom.addSmallButton(slide, this.opts, this.dict)\n dom.showSpinner(stage, this.opts, this.dict)\n this.emitSlide('beforeLoad', item)\n if (this.opts.image.preload) preloadNeighbours(this.group, index)\n\n let failed = false\n try {\n await loadContent(item, item.$content as HTMLElement, this.opts, this.dict)\n } catch (error) {\n failed = true\n dom.showError(item, error, this.opts, this.dict)\n this.emitSlide('onError', item)\n if (!this.opts.onError) console.warn('[glare]', error)\n }\n\n if (!this.isActive || this.currIndex !== index) return slide.remove()\n if (!failed) this.emitSlide('afterLoad', item)\n\n // The previous slide stays visible until the new content is ready, then they cross-fade.\n dom.hideSpinner(stage)\n if (!opening) enableTransitions(container, this.opts)\n dom.revealSlide(slide, opening)\n dom.retireSlides(stage, slide, this.opts.transitionDuration)\n this.syncZoomState(this.zoom.isZoomed)\n\n if (failed) return\n if (opening) animateOpen(container, item, this.opts)\n this.emitSlide('afterShow', item)\n }\n\n private syncChrome(): void {\n if (!this.$refs || !this.current) return\n dom.syncChrome(this.$refs, this.opts, this.dict, this.current, this.group.length, this.captionFor(this.current))\n this.syncZoomState(this.zoom.isZoomed)\n }\n\n private captionFor(item: SlideItem): string {\n const { caption } = this.opts\n if (typeof caption === 'function') return caption(this, item)\n return caption ?? item.caption\n }\n\n private syncZoomState(zoomed: boolean): void {\n if (this.$refs) dom.syncZoomButton(this.$refs.container, this.dict, zoomed, !!this.current?.$image)\n }\n\n private resolveParent(): HTMLElement {\n const { parentEl } = this.opts\n const el = typeof parentEl === 'string' ? document.querySelector<HTMLElement>(parentEl) : parentEl\n return el ?? document.body\n }\n\n private startModules({ container, stage, bg }: GlareRefs): void {\n const opts = this.opts\n\n const thumbs = moduleOptions(opts.thumbs, thumbsDefaults)\n if (thumbs) this.thumbs = new Thumbs(this, container, thumbs)\n\n const slideshow = moduleOptions(opts.slideshow, slideshowDefaults)\n if (slideshow) this.slideshow = new Slideshow(this, container, slideshow)\n\n const fullscreen = moduleOptions(opts.fullscreen, fullscreenDefaults)\n if (fullscreen && supportsFullscreen()) this.fullscreen = new Fullscreen(this, container, fullscreen)\n\n const share = moduleOptions(opts.share, {})\n if (share) this.share = new Share(this, container, share)\n\n if (opts.hash && this.galleryName) this.hash = new Hash(this, this.galleryName)\n\n if (opts.wheel) {\n this.wheel = new WheelNav(stage, {\n mode: opts.wheel,\n current: () => this.current,\n isZoomed: () => this.zoom.isZoomed,\n next: () => this.next(),\n prev: () => this.prev(),\n })\n }\n\n if (opts.touch) {\n this.gestures = new Gestures(stage, {\n zoom: this.zoom,\n touch: opts.touch,\n bg,\n canPan: () => this.current?.type === 'image',\n close: () => this.close(),\n next: () => this.next(),\n prev: () => this.prev(),\n })\n }\n }\n\n private onActivity(): void {\n if (this.isIdle) this.toggleControls(false)\n this.idle.reset()\n }\n\n private teardown(): void {\n for (const module of [\n this.gestures,\n this.wheel,\n this.hash,\n this.share,\n this.thumbs,\n this.slideshow,\n this.fullscreen,\n ]) {\n module?.destroy()\n }\n this.gestures = this.wheel = this.hash = null\n this.share = this.thumbs = this.slideshow = this.fullscreen = undefined\n\n this.cleanups.forEach((off) => off())\n this.cleanups = []\n this.$refs?.container.remove()\n this.$refs = null\n\n registry.remove(this)\n if (this.opts.hideScrollbar && registry.size === 0) lockScroll(false)\n if (this.opts.backFocus) {\n const target = this.current?.$trigger ?? this.previouslyFocused\n target?.focus({ preventScroll: true })\n }\n\n this.isActive = false\n this.isClosing = false\n if (this.current) this.emitSlide('afterClose', this.current)\n }\n\n private emit(name: LifecycleEvent): unknown {\n return this.opts[name]?.(this)\n }\n\n private emitSlide(name: SlideEvent, item: SlideItem): unknown {\n return this.opts[name]?.(this, item)\n }\n\n private clampIndex(index: number): number {\n return clamp(index, 0, Math.max(0, this.group.length - 1))\n }\n\n static defaults = defaults\n\n static open(\n items: Array<SlideSource | string> | HTMLElement[],\n options: GlareOptions = {},\n index = 0,\n ): Glare {\n const instance = new Glare(items, options, index)\n instance.open()\n return instance\n }\n\n static bind(target: BindTarget, options: GlareOptions = {}): BoundGroup {\n return bind(target, options, (elements, index, gallery) => {\n new Glare(elements, options, index, gallery).open()\n })\n }\n\n static close(all = false): void {\n if (all) registry.all().reverse().forEach((instance) => instance.close())\n else registry.top()?.close()\n }\n\n static getInstance(id?: number): Glare | null {\n return id == null ? registry.top() : registry.get(id)\n }\n\n static getInstances(): Glare[] {\n return registry.all()\n }\n\n /** Closes every instance and removes all `bind()` handlers. */\n static destroy(): void {\n Glare.close(true)\n unbindAll()\n }\n\n /** Binds every `[data-glare]` element once the DOM is ready. */\n static autoBind(options: GlareOptions = {}): void {\n const run = () => Glare.bind('[data-glare]', options)\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', run, { once: true })\n } else {\n run()\n }\n }\n}\n"],"names":["i18nEn","getDict","opts","lang","translate","template","dict","_","key","buildQuery","params","value","expandMatch","match","n","providers","tld","coords","query","search","lat","lng","zoom","z","q","resolve","src","applyProvider","media","provider","url","svg","paths","icons","button","name","label","icon","attrs","baseTemplate","buttonTemplates","spinnerTemplate","errorTemplate","videoTemplate","iframeTemplate","shareTemplate","thumbsDefaults","slideshowDefaults","fullscreenDefaults","defaults","current","IMAGE_EXT","VIDEO_EXT","PDF_EXT","SELECTOR","detectType","fallback","videoMime","ext","normalizeItem","source","index","raw","type","thumb","provided","attr","el","itemsFromElements","elements","img","caption","createItems","items","item","$","selector","root","$$","createEl","tag","className","html","fromHtml","toText","resolveElement","target","toCssSize","on","handler","options","nextFrame","callback","afterTransition","duration","done","finished","finish","timer","onEnd","event","isMobile","prefersReducedMotion","supportsFullscreen","doc","LOCK_CLASS","lockScroll","lock","scrollbar","HIDDEN","buildContainer","id","count","container","stage","refs","single","buildToolbar","toolbar","tpl","mountSlide","slide","content","revealSlide","instant","retireSlides","keep","delay","addSmallButton","showSpinner","hideSpinner","showError","error","isToolbarVisible","usesSmallButton","syncChrome","total","infobar","setTypeClass","syncToolbar","syncDownloadLink","syncInfobar","syncCaption","syncArrows","syncDialogLabel","visible","zoomable","link","href","indexEl","atStart","atEnd","setDisabled","disabled","base","live","previous","syncZoomButton","zoomed","hasImage","state","setToggleState","active","Fullscreen","glare","off","isPlainObject","proto","deepMerge","sources","result","existing","clamp","min","max","ZOOM_MIN","ZOOM_MAX","ZOOMED_THRESHOLD","Zoom","image","rect","scale","x","y","focus","center","natural","fx","fy","maxX","maxY","MOVE_THRESHOLD","MOMENTUM","SWIPE_CLOSE_DISTANCE","SWIPE_CLOSE_VELOCITY","SWIPE_NAV_DISTANCE","SWIPE_NAV_VELOCITY","IGNORED_TARGETS","distance","a","b","midpoint","pointOf","Gestures","host","moved","points","dx","dy","vertical","mid","ox","oy","last","elapsed","velocity","bg","HASH_PATTERN","parseHash","hash","formatHash","gallery","Hash","next","currentHash","parsed","pathname","Share","encoded","input","hadFocus","Slideshow","hide","Thumbs","group","STEP","SETTLE","LINE_HEIGHT","WheelNav","normalize","applyMotionSettings","reduced","effect","transition","enableTransitions","animateOpen","trigger","from","to","resolveOptions","merged","moduleOptions","groups","galleryOf","toElements","bind","open","openFrom","members","offs","restoreFromHash","unbindAll","IdleTimer","seconds","onIdle","stack","registry","instance","BUTTONS","g","CONTENT","SLIDE_AREA","FOCUSABLE","FORM_TAGS","DBLCLICK_WINDOW","bindInteractions","onActivity","pendingClick","cancelPending","slideAction","resolveAction","runAction","onKeydown","trapFocus","kind","action","point","focusable","first","IFRAME_LOAD_FALLBACK","loaders","reject","format","settings","wrap","frame","clone","response","loadContent","preloadNeighbours","neighbour","nextId","_Glare","galleryName","dom.buildContainer","force","opening","dom.mountSlide","dom.usesSmallButton","dom.addSmallButton","dom.showSpinner","failed","dom.showError","dom.hideSpinner","dom.revealSlide","dom.retireSlides","dom.syncChrome","dom.syncZoomButton","parentEl","thumbs","slideshow","fullscreen","share","module","all","run","Glare"],"mappings":"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"}