@frybynite/image-cloud 0.11.3 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -864,6 +864,7 @@ export declare class ImageCloud {
864
864
  private counterElAutoCreated;
865
865
  private prevButtonEl;
866
866
  private nextButtonEl;
867
+ private ariaLiveEl;
867
868
  private prevButtonElAutoCreated;
868
869
  private nextButtonElAutoCreated;
869
870
  constructor(options?: ImageCloudOptions);
@@ -891,6 +892,7 @@ export declare class ImageCloud {
891
892
  private createDefaultCounterElement;
892
893
  private createDefaultPrevButtonElement;
893
894
  private createDefaultNextButtonElement;
895
+ private getImageAlt;
894
896
  private setupEventListeners;
895
897
  /**
896
898
  * Navigate to the next image (Right arrow)
@@ -583,8 +583,8 @@ function he(o) {
583
583
  return;
584
584
  }
585
585
  const R = performance.now(), M = -r / 2, T = -a / 2;
586
- function z(k) {
587
- const D = k - R, O = Math.min(D / s, 1);
586
+ function z(P) {
587
+ const D = P - R, O = Math.min(D / s, 1);
588
588
  let S;
589
589
  switch (l) {
590
590
  case "bounce": {
@@ -617,11 +617,11 @@ function he(o) {
617
617
  y: V(i.y, e.y, O)
618
618
  };
619
619
  }
620
- const P = S.x - e.x, _ = S.y - e.y;
620
+ const U = S.x - e.x, k = S.y - e.y;
621
621
  let A;
622
622
  h ? A = ce(O, c, b) : g ? A = V(p, c, O) : A = c;
623
623
  let j;
624
- E ? j = le(O, d, x) : y ? j = V(v, d, O) : j = d, t.style.transform = `translate(${M}px, ${T}px) translate(${P}px, ${_}px) rotate(${A}deg) scale(${j})`, f && O < 1 && f(O, D, {
624
+ E ? j = le(O, d, x) : y ? j = V(v, d, O) : j = d, t.style.transform = `translate(${M}px, ${T}px) translate(${U}px, ${k}px) rotate(${A}deg) scale(${j})`, f && O < 1 && f(O, D, {
625
625
  x: S.x,
626
626
  y: S.y,
627
627
  rotation: A,
@@ -1243,25 +1243,25 @@ class pe {
1243
1243
  }
1244
1244
  let E = 1, x = 1;
1245
1245
  for (; E < t; ) {
1246
- const F = x / b, R = w > 0 ? 1 - F * w * 0.5 : 1, M = Math.max(l * 0.8, y / b * 1.5 / v.tightness), T = x * M, z = T * 1.5, k = Math.PI * (3 * (z + T) - Math.sqrt((3 * z + T) * (z + 3 * T))), D = this.estimateWidth(l), O = Math.floor(k / (D * 0.7));
1246
+ const F = x / b, R = w > 0 ? 1 - F * w * 0.5 : 1, M = Math.max(l * 0.8, y / b * 1.5 / v.tightness), T = x * M, z = T * 1.5, P = Math.PI * (3 * (z + T) - Math.sqrt((3 * z + T) * (z + 3 * T))), D = this.estimateWidth(l), O = Math.floor(P / (D * 0.7));
1247
1247
  if (O === 0) {
1248
1248
  x++;
1249
1249
  continue;
1250
1250
  }
1251
- const S = 2 * Math.PI / O, P = x * (20 * Math.PI / 180);
1252
- for (let _ = 0; _ < O && E < t; _++) {
1253
- const A = _ * S + P, j = p ? this.random(f, m) : 1, N = R * j, $ = l * N;
1254
- let H = g + Math.cos(A) * z, U = h + Math.sin(A) * T;
1255
- const B = $ * 1.5 / 2, W = $ / 2;
1256
- H - B < I ? H = I + B : H + B > s - I && (H = s - I - B), U - W < I ? U = I + W : U + W > r - I && (U = r - I - W);
1251
+ const S = 2 * Math.PI / O, U = x * (20 * Math.PI / 180);
1252
+ for (let k = 0; k < O && E < t; k++) {
1253
+ const A = k * S + U, j = p ? this.random(f, m) : 1, N = R * j, _ = l * N;
1254
+ let H = g + Math.cos(A) * z, $ = h + Math.sin(A) * T;
1255
+ const B = _ * 1.5 / 2, W = _ / 2;
1256
+ H - B < I ? H = I + B : H + B > s - I && (H = s - I - B), $ - W < I ? $ = I + W : $ + W > r - I && ($ = r - I - W);
1257
1257
  const X = c === "random" ? this.random(d, u) : 0;
1258
1258
  n.push({
1259
1259
  id: E,
1260
1260
  x: H,
1261
- y: U,
1261
+ y: $,
1262
1262
  rotation: X,
1263
1263
  scale: N,
1264
- baseSize: $,
1264
+ baseSize: _,
1265
1265
  zIndex: Math.max(1, 100 - x)
1266
1266
  // Outer rings have lower z-index
1267
1267
  }), E++;
@@ -1335,27 +1335,16 @@ class ye {
1335
1335
  v,
1336
1336
  d,
1337
1337
  a
1338
- ), h = a.stagger === "row", b = a.stagger === "column", I = h ? l + 0.5 : l, y = b ? g + 0.5 : g, E = (w - a.gap * (l - 1)) / I, x = (v - a.gap * (g - 1)) / y, F = h ? E / 2 : 0, R = b ? x / 2 : 0, M = 1 + a.overlap, T = Math.min(E, x) * M, z = e.fixedHeight ? Math.min(e.fixedHeight, T) : T, k = l * E + (l - 1) * a.gap + F, D = g * x + (g - 1) * a.gap + R, O = c + (w - k) / 2, S = c + (v - D) / 2, P = l * g, _ = a.columns !== "auto" && a.rows !== "auto", A = _ && t > P;
1339
- typeof window < "u" && (window.__gridOverflowDebug = {
1340
- gridConfigColumns: a.columns,
1341
- gridConfigRows: a.rows,
1342
- columns: l,
1343
- rows: g,
1344
- cellCount: P,
1345
- hasFixedGrid: _,
1346
- imageCount: t,
1347
- isOverflowMode: A
1348
- });
1349
- const j = A ? new Array(P).fill(0) : [], N = Math.min(E, x) * a.overflowOffset;
1350
- for (let $ = 0; $ < t; $++) {
1351
- let H, U, Y = 0;
1352
- if (A && $ >= P) {
1353
- const q = $ - P, G = q % P;
1354
- Y = Math.floor(q / P) + 1, j[G]++, a.fillDirection === "row" ? (H = G % l, U = Math.floor(G / l)) : (U = G % g, H = Math.floor(G / g));
1338
+ ), h = a.stagger === "row", b = a.stagger === "column", I = h ? l + 0.5 : l, y = b ? g + 0.5 : g, E = (w - a.gap * (l - 1)) / I, x = (v - a.gap * (g - 1)) / y, F = h ? E / 2 : 0, R = b ? x / 2 : 0, M = 1 + a.overlap, T = Math.min(E, x) * M, z = e.fixedHeight ? Math.min(e.fixedHeight, T) : T, P = l * E + (l - 1) * a.gap + F, D = g * x + (g - 1) * a.gap + R, O = c + (w - P) / 2, S = c + (v - D) / 2, U = l * g, A = a.columns !== "auto" && a.rows !== "auto" && t > U, j = A ? new Array(U).fill(0) : [], N = Math.min(E, x) * a.overflowOffset;
1339
+ for (let _ = 0; _ < t; _++) {
1340
+ let H, $, Y = 0;
1341
+ if (A && _ >= U) {
1342
+ const q = _ - U, G = q % U;
1343
+ Y = Math.floor(q / U) + 1, j[G]++, a.fillDirection === "row" ? (H = G % l, $ = Math.floor(G / l)) : ($ = G % g, H = Math.floor(G / g));
1355
1344
  } else
1356
- a.fillDirection === "row" ? (H = $ % l, U = Math.floor($ / l)) : (U = $ % g, H = Math.floor($ / g));
1357
- let B = O + H * (E + a.gap) + E / 2, W = S + U * (x + a.gap) + x / 2;
1358
- if (a.stagger === "row" && U % 2 === 1 ? B += E / 2 : a.stagger === "column" && H % 2 === 1 && (W += x / 2), Y > 0) {
1345
+ a.fillDirection === "row" ? (H = _ % l, $ = Math.floor(_ / l)) : ($ = _ % g, H = Math.floor(_ / g));
1346
+ let B = O + H * (E + a.gap) + E / 2, W = S + $ * (x + a.gap) + x / 2;
1347
+ if (a.stagger === "row" && $ % 2 === 1 ? B += E / 2 : a.stagger === "column" && H % 2 === 1 && (W += x / 2), Y > 0) {
1359
1348
  const q = (Y - 1) % Lt.length, G = Lt[q];
1360
1349
  B += G.x * N, W += G.y * N;
1361
1350
  }
@@ -1366,10 +1355,10 @@ class ye {
1366
1355
  let X = B, J = W;
1367
1356
  if (!A && a.fillDirection === "row") {
1368
1357
  const q = t % l || l;
1369
- if (U === Math.floor((t - 1) / l) && q < l) {
1358
+ if ($ === Math.floor((t - 1) / l) && q < l) {
1370
1359
  const Ct = q * E + (q - 1) * a.gap;
1371
1360
  let gt = 0;
1372
- a.alignment === "center" ? gt = (k - Ct) / 2 : a.alignment === "end" && (gt = k - Ct), X += gt;
1361
+ a.alignment === "center" ? gt = (P - Ct) / 2 : a.alignment === "end" && (gt = P - Ct), X += gt;
1373
1362
  }
1374
1363
  }
1375
1364
  const ct = p ? this.random(f, m) : 1, K = z * ct, nt = K * 1.5 / 2, ot = K / 2, ht = c + nt, dt = s - c - nt, Ut = c + ot, kt = r - c - ot;
@@ -1380,8 +1369,8 @@ class ye {
1380
1369
  a.jitter > 0 ? ut = this.random(q * a.jitter, G * a.jitter) : ut = this.random(q, G);
1381
1370
  }
1382
1371
  let ft;
1383
- A && Y > 0 ? ft = 50 - Y : ft = A ? 100 + $ : $ + 1, n.push({
1384
- id: $,
1372
+ A && Y > 0 ? ft = 50 - Y : ft = A ? 100 + _ : _ + 1, n.push({
1373
+ id: _,
1385
1374
  x: X,
1386
1375
  y: J,
1387
1376
  rotation: ut,
@@ -1451,19 +1440,19 @@ class xe {
1451
1440
  const B = y * 0.3 * a.tightness;
1452
1441
  E = B * I + a.startAngle, x = this.calculateLogarithmicRadius(B, t, b, a.tightness);
1453
1442
  }
1454
- const F = g + Math.cos(E) * x, R = h + Math.sin(E) * x, M = x / b, T = l > 0 ? 1 - M * l * 0.5 : 1, z = v ? this.random(p, w) : 1, k = T * z, D = d * k, S = D * 1.5 / 2, P = D / 2, _ = c + S, A = s - c - S, j = c + P, N = r - c - P, $ = Math.max(_, Math.min(F, A)), H = Math.max(j, Math.min(R, N));
1455
- let U = 0;
1443
+ const F = g + Math.cos(E) * x, R = h + Math.sin(E) * x, M = x / b, T = l > 0 ? 1 - M * l * 0.5 : 1, z = v ? this.random(p, w) : 1, P = T * z, D = d * P, S = D * 1.5 / 2, U = D / 2, k = c + S, A = s - c - S, j = c + U, N = r - c - U, _ = Math.max(k, Math.min(F, A)), H = Math.max(j, Math.min(R, N));
1444
+ let $ = 0;
1456
1445
  if (u === "random") {
1457
1446
  const B = E * 180 / Math.PI % 360, W = this.random(f, m);
1458
- U = a.spiralType === "golden" ? W : B * 0.1 + W * 0.9;
1459
- } else u === "tangent" && (U = this.calculateSpiralTangent(E, x, a));
1447
+ $ = a.spiralType === "golden" ? W : B * 0.1 + W * 0.9;
1448
+ } else u === "tangent" && ($ = this.calculateSpiralTangent(E, x, a));
1460
1449
  const Y = t - y;
1461
1450
  n.push({
1462
1451
  id: y,
1463
- x: $,
1452
+ x: _,
1464
1453
  y: H,
1465
- rotation: U,
1466
- scale: k,
1454
+ rotation: $,
1455
+ scale: P,
1467
1456
  baseSize: D,
1468
1457
  zIndex: Y
1469
1458
  });
@@ -1561,22 +1550,22 @@ class Ie {
1561
1550
  if (a.distribution === "gaussian")
1562
1551
  F = this.gaussianRandom() * y.spread, R = this.gaussianRandom() * y.spread;
1563
1552
  else {
1564
- const U = this.random(0, Math.PI * 2), Y = this.random(0, y.spread);
1565
- F = Math.cos(U) * Y, R = Math.sin(U) * Y;
1553
+ const $ = this.random(0, Math.PI * 2), Y = this.random(0, y.spread);
1554
+ F = Math.cos($) * Y, R = Math.sin($) * Y;
1566
1555
  }
1567
1556
  const M = 1 + a.overlap * 0.5, T = 1 + a.overlap * 0.3;
1568
1557
  F /= M, R /= M;
1569
- const z = v ? this.random(p, w) : 1, k = T * z, D = d * k;
1558
+ const z = v ? this.random(p, w) : 1, P = T * z, D = d * P;
1570
1559
  let O = y.x + F, S = y.y + R;
1571
- const _ = D * 1.5 / 2, A = D / 2;
1572
- O = Math.max(c + _, Math.min(O, s - c - _)), S = Math.max(c + A, Math.min(S, r - c - A));
1573
- const j = u === "random" ? this.random(f, m) : 0, $ = Math.sqrt(F * F + R * R) / y.spread, H = Math.round((1 - $) * 50) + 1;
1560
+ const k = D * 1.5 / 2, A = D / 2;
1561
+ O = Math.max(c + k, Math.min(O, s - c - k)), S = Math.max(c + A, Math.min(S, r - c - A));
1562
+ const j = u === "random" ? this.random(f, m) : 0, _ = Math.sqrt(F * F + R * R) / y.spread, H = Math.round((1 - _) * 50) + 1;
1574
1563
  n.push({
1575
1564
  id: b,
1576
1565
  x: O,
1577
1566
  y: S,
1578
1567
  rotation: j,
1579
- scale: k,
1568
+ scale: P,
1580
1569
  baseSize: D,
1581
1570
  zIndex: H
1582
1571
  }), b++;
@@ -1659,26 +1648,26 @@ class Se {
1659
1648
  const n = [], { width: s, height: r } = i, a = e.fixedHeight ?? 200, c = this.config.spacing.padding ?? 50, d = this.imageConfig.rotation?.mode ?? "none", u = this.imageConfig.rotation?.range?.min ?? -15, f = this.imageConfig.rotation?.range?.max ?? 15, m = this.imageConfig.sizing?.variance?.min ?? 1, p = this.imageConfig.sizing?.variance?.max ?? 1, w = m !== 1 || p !== 1, v = e.fixedHeight ?? a, l = {
1660
1649
  ...Nt,
1661
1650
  ...this.config.wave
1662
- }, { rows: g, amplitude: h, frequency: b, phaseShift: I, synchronization: y } = l, E = Math.ceil(t / g), R = v * 1.5 / 2, M = c + R, T = s - c - R, z = T - M, k = E > 1 ? z / (E - 1) : 0, D = c + h + v / 2, O = r - c - h - v / 2, S = O - D, P = g > 1 ? S / (g - 1) : 0;
1663
- let _ = 0;
1664
- for (let A = 0; A < g && _ < t; A++) {
1665
- const j = g === 1 ? (D + O) / 2 : D + A * P;
1651
+ }, { rows: g, amplitude: h, frequency: b, phaseShift: I, synchronization: y } = l, E = Math.ceil(t / g), R = v * 1.5 / 2, M = c + R, T = s - c - R, z = T - M, P = E > 1 ? z / (E - 1) : 0, D = c + h + v / 2, O = r - c - h - v / 2, S = O - D, U = g > 1 ? S / (g - 1) : 0;
1652
+ let k = 0;
1653
+ for (let A = 0; A < g && k < t; A++) {
1654
+ const j = g === 1 ? (D + O) / 2 : D + A * U;
1666
1655
  let N = 0;
1667
1656
  y === "offset" ? N = A * I : y === "alternating" && (N = A * Math.PI);
1668
- for (let $ = 0; $ < E && _ < t; $++) {
1669
- const H = E === 1 ? (M + T) / 2 : M + $ * k, U = this.calculateWaveY(H, s, h, b, N), Y = H, B = j + U, W = w ? this.random(m, p) : 1, X = v * W;
1657
+ for (let _ = 0; _ < E && k < t; _++) {
1658
+ const H = E === 1 ? (M + T) / 2 : M + _ * P, $ = this.calculateWaveY(H, s, h, b, N), Y = H, B = j + $, W = w ? this.random(m, p) : 1, X = v * W;
1670
1659
  let J = 0;
1671
1660
  d === "tangent" ? J = this.calculateRotation(H, s, h, b, N) : d === "random" && (J = this.random(u, f));
1672
1661
  const K = X * 1.5 / 2, lt = X / 2, nt = c + K, ot = s - c - K, ht = c + lt, dt = r - c - lt;
1673
1662
  n.push({
1674
- id: _,
1663
+ id: k,
1675
1664
  x: Math.max(nt, Math.min(Y, ot)),
1676
1665
  y: Math.max(ht, Math.min(B, dt)),
1677
1666
  rotation: J,
1678
1667
  scale: W,
1679
1668
  baseSize: X,
1680
- zIndex: _ + 1
1681
- }), _++;
1669
+ zIndex: k + 1
1670
+ }), k++;
1682
1671
  }
1683
1672
  }
1684
1673
  return n;
@@ -3221,7 +3210,7 @@ function Ze() {
3221
3210
  }
3222
3211
  class Qe {
3223
3212
  constructor(t = {}) {
3224
- this.fullConfig = Zt(t), t.container instanceof HTMLElement ? (this.containerRef = t.container, this.containerId = null) : (this.containerRef = null, this.containerId = t.container || "imageCloud"), this.callbacks = t.on ?? {}, this.imagesLoaded = !1, this.imageElements = [], this.imageLayouts = [], this.currentImageHeight = 225, this.currentFocusIndex = null, this.hoveredImage = null, this.resizeTimeout = null, this.displayQueue = [], this.queueInterval = null, this.loadGeneration = 0, this.loadingElAutoCreated = !1, this.errorElAutoCreated = !1, this.counterEl = null, this.counterElAutoCreated = !1, this.prevButtonEl = null, this.nextButtonEl = null, this.prevButtonElAutoCreated = !1, this.nextButtonElAutoCreated = !1, this.animationEngine = new ie(this.fullConfig.animation), this.layoutEngine = new Oe({
3213
+ this.ariaLiveEl = null, this.fullConfig = Zt(t), t.container instanceof HTMLElement ? (this.containerRef = t.container, this.containerId = null) : (this.containerRef = null, this.containerId = t.container || "imageCloud"), this.callbacks = t.on ?? {}, this.imagesLoaded = !1, this.imageElements = [], this.imageLayouts = [], this.currentImageHeight = 225, this.currentFocusIndex = null, this.hoveredImage = null, this.resizeTimeout = null, this.displayQueue = [], this.queueInterval = null, this.loadGeneration = 0, this.loadingElAutoCreated = !1, this.errorElAutoCreated = !1, this.counterEl = null, this.counterElAutoCreated = !1, this.prevButtonEl = null, this.nextButtonEl = null, this.prevButtonElAutoCreated = !1, this.nextButtonElAutoCreated = !1, this.animationEngine = new ie(this.fullConfig.animation), this.layoutEngine = new Oe({
3225
3214
  layout: this.fullConfig.layout,
3226
3215
  image: this.fullConfig.image
3227
3216
  }), this.zoomEngine = new He(this.fullConfig.interaction.focus, this.animationEngine, this.fullConfig.styling), this.defaultStyles = it(this.fullConfig.styling?.default), this.defaultClassName = this.fullConfig.styling?.default?.className, this.hoverClassName = this.fullConfig.styling?.hover?.className;
@@ -3311,7 +3300,7 @@ class Qe {
3311
3300
  this.containerEl = this.containerRef;
3312
3301
  else if (this.containerEl = document.getElementById(this.containerId), !this.containerEl)
3313
3302
  throw new Error(`Container "#${this.containerId}" not found. Ensure an element with id="${this.containerId}" exists in the DOM before calling imageCloud().`);
3314
- this.containerEl.classList.add("fbn-ic-gallery"), this.containerEl.setAttribute("tabindex", "0"), this.fullConfig.interaction.navigation?.swipe !== !1 && (this.swipeEngine = new bt(this.containerEl, {
3303
+ this.containerEl.classList.add("fbn-ic-gallery"), this.containerEl.setAttribute("tabindex", "0"), this.containerEl.setAttribute("role", "region"), this.containerEl.setAttribute("aria-label", "Image gallery"), this.fullConfig.interaction.navigation?.swipe !== !1 && (this.swipeEngine = new bt(this.containerEl, {
3315
3304
  onNext: () => this.navigateToNextImage(),
3316
3305
  onPrev: () => this.navigateToPreviousImage(),
3317
3306
  onDragOffset: (t) => this.zoomEngine.setDragOffset(t),
@@ -3329,7 +3318,7 @@ class Qe {
3329
3318
  i.stopPropagation(), this.navigateToPreviousImage();
3330
3319
  }), this.nextButtonEl?.addEventListener("click", (i) => {
3331
3320
  i.stopPropagation(), this.navigateToNextImage();
3332
- }));
3321
+ })), this.ariaLiveEl = document.createElement("div"), this.ariaLiveEl.setAttribute("aria-live", "polite"), this.ariaLiveEl.setAttribute("aria-atomic", "true"), this.ariaLiveEl.className = "fbn-ic-sr-only", this.containerEl.appendChild(this.ariaLiveEl);
3333
3322
  }
3334
3323
  resolveElement(t) {
3335
3324
  return t instanceof HTMLElement ? t : document.getElementById(t);
@@ -3352,11 +3341,19 @@ class Qe {
3352
3341
  }
3353
3342
  createDefaultPrevButtonElement() {
3354
3343
  const t = document.createElement("button");
3355
- return t.className = "fbn-ic-nav-btn fbn-ic-nav-btn-prev fbn-ic-hidden", t.textContent = "‹", t.setAttribute("aria-label", "Previous image"), t.setAttribute("tabindex", "-1"), this.containerEl.appendChild(t), t;
3344
+ return t.className = "fbn-ic-nav-btn fbn-ic-nav-btn-prev fbn-ic-hidden", t.textContent = "‹", t.setAttribute("aria-label", "Previous image"), this.containerEl.appendChild(t), t;
3356
3345
  }
3357
3346
  createDefaultNextButtonElement() {
3358
3347
  const t = document.createElement("button");
3359
- return t.className = "fbn-ic-nav-btn fbn-ic-nav-btn-next fbn-ic-hidden", t.textContent = "›", t.setAttribute("aria-label", "Next image"), t.setAttribute("tabindex", "-1"), this.containerEl.appendChild(t), t;
3348
+ return t.className = "fbn-ic-nav-btn fbn-ic-nav-btn-next fbn-ic-hidden", t.textContent = "›", t.setAttribute("aria-label", "Next image"), this.containerEl.appendChild(t), t;
3349
+ }
3350
+ getImageAlt(t, i) {
3351
+ try {
3352
+ const s = (new URL(t).pathname.split("/").pop() ?? "").replace(/\.[^.]+$/, "").replace(/[-_]/g, " ").trim();
3353
+ return s.length > 0 ? s : `Image ${i + 1}`;
3354
+ } catch {
3355
+ return `Image ${i + 1}`;
3356
+ }
3360
3357
  }
3361
3358
  setupEventListeners() {
3362
3359
  this.fullConfig.interaction.navigation?.keyboard !== !1 && this.containerEl.addEventListener("keydown", (t) => {
@@ -3473,7 +3470,7 @@ class Qe {
3473
3470
  }, w = (l) => {
3474
3471
  this.containerEl && (this.containerEl.appendChild(l), this.imageElements.push(l), requestAnimationFrame(async () => {
3475
3472
  l.offsetWidth, l.style.opacity = this.defaultStyles.opacity ?? "1";
3476
- const g = parseInt(l.dataset.imageId || "0"), h = this.imageLayouts[g], b = this.entryAnimationEngine.getTiming(), I = performance.now(), y = parseFloat(l.dataset.startX || "0"), E = parseFloat(l.dataset.startY || "0"), x = parseFloat(l.dataset.endX || "0"), F = parseFloat(l.dataset.endY || "0"), R = parseFloat(l.dataset.rotation || "0"), M = parseFloat(l.dataset.scale || "1"), T = parseFloat(l.dataset.startRotation || l.dataset.rotation || "0"), z = parseFloat(l.dataset.startScale || l.dataset.scale || "1"), k = parseFloat(l.dataset.imageWidth || "0"), D = parseFloat(l.dataset.imageHeight || "0");
3473
+ const g = parseInt(l.dataset.imageId || "0"), h = this.imageLayouts[g], b = this.entryAnimationEngine.getTiming(), I = performance.now(), y = parseFloat(l.dataset.startX || "0"), E = parseFloat(l.dataset.startY || "0"), x = parseFloat(l.dataset.endX || "0"), F = parseFloat(l.dataset.endY || "0"), R = parseFloat(l.dataset.rotation || "0"), M = parseFloat(l.dataset.scale || "1"), T = parseFloat(l.dataset.startRotation || l.dataset.rotation || "0"), z = parseFloat(l.dataset.startScale || l.dataset.scale || "1"), P = parseFloat(l.dataset.imageWidth || "0"), D = parseFloat(l.dataset.imageHeight || "0");
3477
3474
  if (this.callbacks.onEntryStart && h) {
3478
3475
  const S = {
3479
3476
  element: l,
@@ -3494,7 +3491,7 @@ class Qe {
3494
3491
  endPosition: { x, y: F },
3495
3492
  pathConfig: this.entryAnimationEngine.getPathConfig(),
3496
3493
  duration: b.duration,
3497
- imageWidth: k,
3494
+ imageWidth: P,
3498
3495
  imageHeight: D,
3499
3496
  rotation: R,
3500
3497
  scale: M,
@@ -3502,7 +3499,7 @@ class Qe {
3502
3499
  startRotation: T,
3503
3500
  scaleConfig: this.entryAnimationEngine.getScaleConfig(),
3504
3501
  startScale: z,
3505
- onProgress: this.callbacks.onEntryProgress && h ? (S, P, _) => {
3502
+ onProgress: this.callbacks.onEntryProgress && h ? (S, U, k) => {
3506
3503
  const A = {
3507
3504
  element: l,
3508
3505
  index: g,
@@ -3514,8 +3511,8 @@ class Qe {
3514
3511
  duration: b.duration,
3515
3512
  progress: S,
3516
3513
  rawProgress: S,
3517
- elapsed: P,
3518
- current: _
3514
+ elapsed: U,
3515
+ current: k
3519
3516
  };
3520
3517
  this.callbacks.onEntryProgress(A);
3521
3518
  } : void 0,
@@ -3536,9 +3533,9 @@ class Qe {
3536
3533
  else {
3537
3534
  const S = l.dataset.finalTransform || "";
3538
3535
  if (l.style.transform = S, this.callbacks.onEntryComplete && h) {
3539
- const P = (_) => {
3540
- if (_.propertyName !== "transform") return;
3541
- l.removeEventListener("transitionend", P);
3536
+ const U = (k) => {
3537
+ if (k.propertyName !== "transform") return;
3538
+ l.removeEventListener("transitionend", U);
3542
3539
  const A = {
3543
3540
  element: l,
3544
3541
  index: g,
@@ -3549,7 +3546,7 @@ class Qe {
3549
3546
  };
3550
3547
  this.callbacks.onEntryComplete(A);
3551
3548
  };
3552
- l.addEventListener("transitionend", P);
3549
+ l.addEventListener("transitionend", U);
3553
3550
  }
3554
3551
  }
3555
3552
  if (this.fullConfig.config.debug?.enabled && g < 3) {
@@ -3606,7 +3603,7 @@ class Qe {
3606
3603
  h.style.left = `${b - 6}px`, h.style.top = `${I - 6}px`, h.title = `Image ${g}: center (${Math.round(b)}, ${Math.round(I)})`, this.containerEl.appendChild(h);
3607
3604
  })), t.forEach((l, g) => {
3608
3605
  const h = document.createElement("img");
3609
- h.referrerPolicy = "no-referrer", h.classList.add("fbn-ic-image"), this.fullConfig.interaction.dragging === !1 && (h.draggable = !1), h.dataset.imageId = String(g), h.dataset.createdFlag = "true";
3606
+ h.referrerPolicy = "no-referrer", h.classList.add("fbn-ic-image"), h.alt = this.getImageAlt(l, g), this.fullConfig.interaction.dragging === !1 && (h.draggable = !1), h.dataset.imageId = String(g);
3610
3607
  const b = s[g];
3611
3608
  h.style.position = "absolute", h.style.width = "auto", h.style.height = `${i}px`, h.style.left = `${b.x}px`, h.style.top = `${b.y}px`, b.zIndex && (h.style.zIndex = String(b.zIndex)), et(h, this.defaultClassName), h.addEventListener("mouseenter", () => {
3612
3609
  if (this.hoveredImage = { element: h, layout: b }, !this.zoomEngine.isInvolved(h)) {
@@ -3632,7 +3629,7 @@ class Qe {
3632
3629
  if (n !== this.loadGeneration)
3633
3630
  return;
3634
3631
  const y = h.naturalWidth / h.naturalHeight, E = i * y;
3635
- h.dataset.onloadCalled = "true", window.DEBUG_CLIPPATH && console.log(`[onload #${g}] Called with imageHeight=${i}, renderedWidth=${E}`), h.style.width = `${E}px`, h.cachedRenderedWidth = E, h.aspectRatio = y, st(h, this.fullConfig.styling?.default, i, E);
3632
+ h.style.width = `${E}px`, h.cachedRenderedWidth = E, h.aspectRatio = y, st(h, this.fullConfig.styling?.default, i, E);
3636
3633
  const x = { x: b.x, y: b.y }, F = { width: E, height: i }, R = this.entryAnimationEngine.calculateStartPosition(
3637
3634
  x,
3638
3635
  F,
@@ -3644,7 +3641,7 @@ class Qe {
3644
3641
  b.scale,
3645
3642
  E,
3646
3643
  i
3647
- ), k = this.entryAnimationEngine.buildStartTransform(
3644
+ ), P = this.entryAnimationEngine.buildStartTransform(
3648
3645
  R,
3649
3646
  x,
3650
3647
  b.rotation,
@@ -3662,7 +3659,7 @@ class Qe {
3662
3659
  finalTransform: z,
3663
3660
  renderedWidth: E,
3664
3661
  renderedHeight: i
3665
- }), h.style.transform = k, h.dataset.finalTransform = z, h.dataset.startX = String(R.x), h.dataset.startY = String(R.y), h.dataset.endX = String(x.x), h.dataset.endY = String(x.y), h.dataset.imageWidth = String(E), h.dataset.imageHeight = String(i), h.dataset.rotation = String(b.rotation), h.dataset.scale = String(b.scale), h.dataset.startRotation = String(M), h.dataset.startScale = String(T), a++, this.callbacks.onImageLoaded) {
3662
+ }), h.style.transform = P, h.dataset.finalTransform = z, h.dataset.startX = String(R.x), h.dataset.startY = String(R.y), h.dataset.endX = String(x.x), h.dataset.endY = String(x.y), h.dataset.imageWidth = String(E), h.dataset.imageHeight = String(i), h.dataset.rotation = String(b.rotation), h.dataset.scale = String(b.scale), h.dataset.startRotation = String(M), h.dataset.startScale = String(T), a++, this.callbacks.onImageLoaded) {
3666
3663
  const D = {
3667
3664
  element: h,
3668
3665
  url: l,
@@ -3712,8 +3709,8 @@ class Qe {
3712
3709
  const M = await (await fetch(F, x.fetch)).blob(), T = URL.createObjectURL(M);
3713
3710
  y = T;
3714
3711
  const z = h.onload;
3715
- h.onload = (k) => {
3716
- URL.revokeObjectURL(T), z?.call(h, k);
3712
+ h.onload = (P) => {
3713
+ URL.revokeObjectURL(T), z?.call(h, P);
3717
3714
  };
3718
3715
  } catch {
3719
3716
  I();
@@ -3732,11 +3729,15 @@ class Qe {
3732
3729
  height: this.containerEl.offsetHeight
3733
3730
  };
3734
3731
  if (e)
3735
- await this.zoomEngine.unfocusImage(), this.currentFocusIndex = null, this.swipeEngine?.disable(), this.hideCounter(), this.hideNavButtons(), this.hideFocusIndicator();
3732
+ await this.zoomEngine.unfocusImage(), this.currentFocusIndex = null, this.swipeEngine?.disable(), this.hideCounter(), this.hideNavButtons(), this.ariaLiveEl && (this.ariaLiveEl.textContent = ""), this.hideFocusIndicator();
3736
3733
  else {
3737
3734
  this.idleAnimationEngine?.pauseForImage(t);
3738
3735
  const s = t.dataset.imageId;
3739
- if (this.currentFocusIndex = s !== void 0 ? parseInt(s, 10) : null, this.swipeEngine?.enable(), this.containerEl?.focus({ preventScroll: !0 }), await this.zoomEngine.focusImage(t, n, i), this.currentFocusIndex !== null && this.updateCounter(this.currentFocusIndex), this.showNavButtons(), this.showFocusIndicator(), this.callbacks.onImageFocus && this.currentFocusIndex !== null) {
3736
+ if (this.currentFocusIndex = s !== void 0 ? parseInt(s, 10) : null, this.swipeEngine?.enable(), this.containerEl?.focus({ preventScroll: !0 }), await this.zoomEngine.focusImage(t, n, i), this.currentFocusIndex !== null && this.updateCounter(this.currentFocusIndex), this.showNavButtons(), this.ariaLiveEl && this.currentFocusIndex !== null) {
3737
+ const r = t.alt, a = this.imageLayouts.length;
3738
+ this.ariaLiveEl.textContent = `Image ${this.currentFocusIndex + 1} of ${a}: ${r}`;
3739
+ }
3740
+ if (this.showFocusIndicator(), this.callbacks.onImageFocus && this.currentFocusIndex !== null) {
3740
3741
  const r = this.imageLoader.imageURLs(), a = {
3741
3742
  element: t,
3742
3743
  index: this.currentFocusIndex,