@hopeplayer/core 1.0.17 → 1.0.18

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 (62) hide show
  1. package/dist/HopePlayerElement.d.ts +2 -0
  2. package/dist/HopePlayerElement.d.ts.map +1 -1
  3. package/dist/chunks/{adTriggers-4SueRFgK.js → adTriggers-DXmtF4t2.js} +112 -117
  4. package/dist/chunks/adTriggers-DXmtF4t2.js.map +1 -0
  5. package/dist/chunks/{ads-DPL7m9PV.js → ads-MCG5a6eK.js} +2 -2
  6. package/dist/chunks/{ads-DPL7m9PV.js.map → ads-MCG5a6eK.js.map} +1 -1
  7. package/dist/chunks/{cast-DCAT2agI.js → cast-bMrkGGuD.js} +70 -66
  8. package/dist/chunks/cast-bMrkGGuD.js.map +1 -0
  9. package/dist/chunks/{markers-DE4O8xbw.js → markers-BhMJLPqj.js} +2 -2
  10. package/dist/chunks/{markers-DE4O8xbw.js.map → markers-BhMJLPqj.js.map} +1 -1
  11. package/dist/chunks/{player-C886oKP-.js → player-DW5iWvPs.js} +260 -229
  12. package/dist/chunks/player-DW5iWvPs.js.map +1 -0
  13. package/dist/chunks/{playlist-CI3mRZjo.js → playlist-DYGbJ5wz.js} +24 -24
  14. package/dist/chunks/playlist-DYGbJ5wz.js.map +1 -0
  15. package/dist/chunks/{qrResume-BNy8XCp_.js → qrResume-DXwD3oSA.js} +29 -30
  16. package/dist/chunks/{qrResume-BNy8XCp_.js.map → qrResume-DXwD3oSA.js.map} +1 -1
  17. package/dist/chunks/{redirectScreen-CJ3q9OX4.js → redirectScreen-CSjrS8Kg.js} +2 -2
  18. package/dist/chunks/{redirectScreen-CJ3q9OX4.js.map → redirectScreen-CSjrS8Kg.js.map} +1 -1
  19. package/dist/chunks/{rewardedUnlock-EyGMB9PK.js → rewardedUnlock-DZ_qPcDG.js} +2 -2
  20. package/dist/chunks/{rewardedUnlock-EyGMB9PK.js.map → rewardedUnlock-DZ_qPcDG.js.map} +1 -1
  21. package/dist/chunks/seekWhenReady-Clzne3-S.js +32 -0
  22. package/dist/chunks/seekWhenReady-Clzne3-S.js.map +1 -0
  23. package/dist/chunks/{segments-C2HKU6XK.js → segments-LsZPlbYi.js} +2 -2
  24. package/dist/chunks/{segments-C2HKU6XK.js.map → segments-LsZPlbYi.js.map} +1 -1
  25. package/dist/chunks/{sponsorship-DyFwGmEb.js → sponsorship-BT21uwN5.js} +36 -41
  26. package/dist/chunks/sponsorship-BT21uwN5.js.map +1 -0
  27. package/dist/chunks/{spriteThumbnails-D0NQ5CCp.js → spriteThumbnails-BQkEBRu-.js} +2 -2
  28. package/dist/chunks/{spriteThumbnails-D0NQ5CCp.js.map → spriteThumbnails-BQkEBRu-.js.map} +1 -1
  29. package/dist/chunks/{story-D5Got6-6.js → story-H6f7gSoX.js} +27 -15
  30. package/dist/chunks/story-H6f7gSoX.js.map +1 -0
  31. package/dist/chunks/trackingPixel-D2wxdCEz.js +20 -0
  32. package/dist/chunks/trackingPixel-D2wxdCEz.js.map +1 -0
  33. package/dist/controls/SeekBar.d.ts.map +1 -1
  34. package/dist/hls/SourceManager.d.ts.map +1 -1
  35. package/dist/hope-player.js +1 -1
  36. package/dist/keyboard/KeyboardController.d.ts.map +1 -1
  37. package/dist/plugins/ad-triggers/AdTriggers.d.ts.map +1 -1
  38. package/dist/plugins/cast/CastController.d.ts.map +1 -1
  39. package/dist/plugins/playlist/PlaylistRunner.d.ts.map +1 -1
  40. package/dist/plugins/qr-resume/QrResume.d.ts.map +1 -1
  41. package/dist/plugins/shared/seekWhenReady.d.ts +22 -0
  42. package/dist/plugins/shared/seekWhenReady.d.ts.map +1 -0
  43. package/dist/plugins/shared/trackingPixel.d.ts +8 -0
  44. package/dist/plugins/shared/trackingPixel.d.ts.map +1 -0
  45. package/dist/plugins/sponsorship/SponsorshipLayer.d.ts.map +1 -1
  46. package/dist/plugins/story/HopeStory.d.ts +2 -0
  47. package/dist/plugins/story/HopeStory.d.ts.map +1 -1
  48. package/dist/screens/ErrorScreen.d.ts +7 -0
  49. package/dist/screens/ErrorScreen.d.ts.map +1 -1
  50. package/dist/types/index.d.ts +2 -0
  51. package/dist/types/index.d.ts.map +1 -1
  52. package/dist/utils/media-error.d.ts +10 -0
  53. package/dist/utils/media-error.d.ts.map +1 -0
  54. package/dist/utils/seek-by.d.ts +8 -0
  55. package/dist/utils/seek-by.d.ts.map +1 -1
  56. package/package.json +2 -1
  57. package/dist/chunks/adTriggers-4SueRFgK.js.map +0 -1
  58. package/dist/chunks/cast-DCAT2agI.js.map +0 -1
  59. package/dist/chunks/player-C886oKP-.js.map +0 -1
  60. package/dist/chunks/playlist-CI3mRZjo.js.map +0 -1
  61. package/dist/chunks/sponsorship-DyFwGmEb.js.map +0 -1
  62. package/dist/chunks/story-D5Got6-6.js.map +0 -1
@@ -1,13 +1,14 @@
1
- var k = Object.defineProperty;
2
- var w = (i, t, e) => t in i ? k(i, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : i[t] = e;
3
- var a = (i, t, e) => w(i, typeof t != "symbol" ? t + "" : t, e);
4
- const T = {
1
+ var w = Object.defineProperty;
2
+ var S = (i, t, e) => t in i ? w(i, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : i[t] = e;
3
+ var a = (i, t, e) => S(i, typeof t != "symbol" ? t + "" : t, e);
4
+ import { f as m } from "./trackingPixel-D2wxdCEz.js";
5
+ const A = 5e3, T = 96, k = 3500, x = {
5
6
  accent: "--hp-color-accent",
6
7
  onAccent: "--hp-color-on-accent",
7
8
  surface: "--hp-color-surface",
8
9
  onSurface: "--hp-color-on-surface"
9
- }, S = ["top-left", "top-right", "bottom-left", "bottom-right"];
10
- function m(i) {
10
+ }, C = ["top-left", "top-right", "bottom-left", "bottom-right"];
11
+ function f(i) {
11
12
  if (typeof i != "string" || !i.trim()) return null;
12
13
  try {
13
14
  const t = new URL(i, document.baseURI);
@@ -16,56 +17,50 @@ function m(i) {
16
17
  return null;
17
18
  }
18
19
  }
19
- function x(i) {
20
+ function M(i) {
20
21
  return typeof i == "string" && i.length < 64 && CSS.supports("color", i) ? i : null;
21
22
  }
22
- function f(i, t, e, o) {
23
+ function g(i, t, e, o) {
23
24
  return typeof i == "number" && Number.isFinite(i) ? Math.min(e, Math.max(t, i)) : o;
24
25
  }
25
- function A(i) {
26
- var p, l, n, c, v, E, y, b;
26
+ function L(i) {
27
+ var p, l, n, c, v, y, E, b;
27
28
  if (!i || typeof i != "object") return null;
28
29
  const t = i;
29
30
  if (t.active !== !0 || !t.sponsor || typeof t.sponsor.name != "string" || !t.sponsor.name.trim()) return null;
30
31
  const e = Date.now(), o = t.validFrom ? Date.parse(t.validFrom) : NaN, s = t.validUntil ? Date.parse(t.validUntil) : NaN;
31
32
  if (Number.isFinite(o) && e < o || Number.isFinite(s) && e > s) return null;
32
33
  const r = {};
33
- for (const d of Object.keys(T)) {
34
- const u = x((p = t.theme) == null ? void 0 : p[d]);
34
+ for (const d of Object.keys(x)) {
35
+ const u = M((p = t.theme) == null ? void 0 : p[d]);
35
36
  u && (r[d] = u);
36
37
  }
37
- const h = (d) => Array.isArray(d) ? d.map(m).filter((u) => !!u).slice(0, 10) : [];
38
+ const h = (d) => Array.isArray(d) ? d.map(f).filter((u) => !!u).slice(0, 10) : [];
38
39
  return {
39
40
  active: !0,
40
41
  id: typeof t.id == "string" ? t.id.slice(0, 120) : void 0,
41
42
  sponsor: {
42
43
  name: t.sponsor.name.slice(0, 80),
43
- logo: m(t.sponsor.logo) ?? void 0,
44
- url: m(t.sponsor.url) ?? void 0
44
+ logo: f(t.sponsor.logo) ?? void 0,
45
+ url: f(t.sponsor.url) ?? void 0
45
46
  },
46
47
  theme: r,
47
48
  logo: {
48
- position: S.includes((l = t.logo) == null ? void 0 : l.position) ? t.logo.position : "top-left",
49
- width: f((n = t.logo) == null ? void 0 : n.width, 32, 240, 96),
50
- opacity: f((c = t.logo) == null ? void 0 : c.opacity, 0.2, 1, 0.9),
49
+ position: C.includes((l = t.logo) == null ? void 0 : l.position) ? t.logo.position : "top-left",
50
+ width: g((n = t.logo) == null ? void 0 : n.width, 32, 240, T),
51
+ opacity: g((c = t.logo) == null ? void 0 : c.opacity, 0.2, 1, 0.9),
51
52
  label: typeof ((v = t.logo) == null ? void 0 : v.label) == "string" ? t.logo.label.slice(0, 40) : void 0
52
53
  },
53
54
  intro: t.intro ? {
54
55
  text: typeof t.intro.text == "string" ? t.intro.text.slice(0, 120) : void 0,
55
- durationMs: f(t.intro.durationMs, 1e3, 15e3, 3500),
56
+ durationMs: g(t.intro.durationMs, 1e3, 15e3, k),
56
57
  repeatMinutes: typeof t.intro.repeatMinutes == "number" && t.intro.repeatMinutes > 0 ? Math.min(240, Math.max(1, t.intro.repeatMinutes)) : void 0,
57
58
  maxShows: typeof t.intro.maxShows == "number" && t.intro.maxShows >= 1 ? Math.min(100, Math.floor(t.intro.maxShows)) : void 0
58
59
  } : void 0,
59
- tracking: { impression: h((E = t.tracking) == null ? void 0 : E.impression), click: h((y = t.tracking) == null ? void 0 : y.click), intro: h((b = t.tracking) == null ? void 0 : b.intro) }
60
+ tracking: { impression: h((y = t.tracking) == null ? void 0 : y.impression), click: h((E = t.tracking) == null ? void 0 : E.click), intro: h((b = t.tracking) == null ? void 0 : b.intro) }
60
61
  };
61
62
  }
62
- function g(i) {
63
- for (const t of i ?? []) {
64
- const e = new Image();
65
- e.referrerPolicy = "no-referrer-when-downgrade", e.src = t;
66
- }
67
- }
68
- class L {
63
+ class I {
69
64
  constructor(t, e) {
70
65
  a(this, "options");
71
66
  a(this, "config", null);
@@ -93,7 +88,7 @@ class L {
93
88
  const t = this.config;
94
89
  if (!t) return;
95
90
  const e = this.key(t);
96
- this.impressed.has(e) || (this.impressed.add(e), g((o = t.tracking) == null ? void 0 : o.impression), this.ctx.hostEl.dispatchEvent(new CustomEvent("hp:sponsorimpression", { detail: { id: t.id, sponsor: t.sponsor.name } }))), t.intro && !this.introCount.has(e) && this.showIntro(t);
91
+ this.impressed.has(e) || (this.impressed.add(e), m((o = t.tracking) == null ? void 0 : o.impression), this.ctx.hostEl.dispatchEvent(new CustomEvent("hp:sponsorimpression", { detail: { id: t.id, sponsor: t.sponsor.name } }))), t.intro && !this.introCount.has(e) && this.showIntro(t);
97
92
  });
98
93
  /**
99
94
  * intro.repeatMinutes: yalnızca gerçekten izlenirken sayar (oynuyor, sekme önde, reklam yok); süre dolunca giriş
@@ -141,7 +136,7 @@ class L {
141
136
  return t.href;
142
137
  }
143
138
  async load() {
144
- const t = ++this.requestSeq, e = typeof AbortController < "u" ? new AbortController() : null, o = setTimeout(() => e == null ? void 0 : e.abort(), this.options.timeoutMs ?? 5e3);
139
+ const t = ++this.requestSeq, e = typeof AbortController < "u" ? new AbortController() : null, o = setTimeout(() => e == null ? void 0 : e.abort(), this.options.timeoutMs ?? A);
145
140
  let s = "";
146
141
  try {
147
142
  s = this.buildUrl();
@@ -149,7 +144,7 @@ class L {
149
144
  if (!r.ok) throw new Error(`HTTP ${r.status}`);
150
145
  const h = await r.json();
151
146
  if (this.destroyed || t !== this.requestSeq) return;
152
- this.apply(A(h));
147
+ this.apply(L(h));
153
148
  } catch (r) {
154
149
  if (this.destroyed || t !== this.requestSeq) return;
155
150
  this.ctx.log({ message: `Sponsorship API failed: ${String(r)}`, details: { url: s } });
@@ -169,7 +164,7 @@ class L {
169
164
  for (const [o, s] of this.previousTokens)
170
165
  s ? e.setProperty(o, s) : e.removeProperty(o);
171
166
  if (this.previousTokens.clear(), !!t)
172
- for (const [o, s] of Object.entries(T)) {
167
+ for (const [o, s] of Object.entries(x)) {
173
168
  const r = t[o];
174
169
  r && (this.previousTokens.set(s, e.getPropertyValue(s)), e.setProperty(s, r));
175
170
  }
@@ -180,9 +175,9 @@ class L {
180
175
  const t = this.config;
181
176
  if (!t || !t.sponsor.logo && !((s = t.logo) != null && s.label)) return;
182
177
  const e = t.sponsor.url ? document.createElement("a") : document.createElement("div");
183
- if (e.className = "hp-sponsor-logo", e.setAttribute("part", "sponsor-logo"), e.setAttribute("data-position", ((r = t.logo) == null ? void 0 : r.position) ?? "top-left"), e.style.setProperty("--hp-sponsor-logo-w", `${((h = t.logo) == null ? void 0 : h.width) ?? 96}px`), e.style.opacity = String(((p = t.logo) == null ? void 0 : p.opacity) ?? 0.9), e instanceof HTMLAnchorElement && (e.href = t.sponsor.url, e.target = "_blank", e.rel = "noopener sponsored", e.addEventListener("click", (n) => {
178
+ if (e.className = "hp-sponsor-logo", e.setAttribute("part", "sponsor-logo"), e.setAttribute("data-position", ((r = t.logo) == null ? void 0 : r.position) ?? "top-left"), e.style.setProperty("--hp-sponsor-logo-w", `${((h = t.logo) == null ? void 0 : h.width) ?? T}px`), e.style.opacity = String(((p = t.logo) == null ? void 0 : p.opacity) ?? 0.9), e instanceof HTMLAnchorElement && (e.href = t.sponsor.url, e.target = "_blank", e.rel = "noopener sponsored", e.addEventListener("click", (n) => {
184
179
  var c;
185
- n.stopPropagation(), g((c = t.tracking) == null ? void 0 : c.click), this.ctx.hostEl.dispatchEvent(new CustomEvent("hp:sponsorclick", { detail: { id: t.id, sponsor: t.sponsor.name } }));
180
+ n.stopPropagation(), m((c = t.tracking) == null ? void 0 : c.click), this.ctx.hostEl.dispatchEvent(new CustomEvent("hp:sponsorclick", { detail: { id: t.id, sponsor: t.sponsor.name } }));
186
181
  })), e.setAttribute("aria-label", t.sponsor.name), t.sponsor.logo) {
187
182
  const n = document.createElement("img");
188
183
  n.src = t.sponsor.logo, n.alt = t.sponsor.name, n.decoding = "async", n.addEventListener("error", () => n.remove()), e.appendChild(n);
@@ -216,7 +211,7 @@ class L {
216
211
  showIntro(t) {
217
212
  var h, p, l, n;
218
213
  const e = this.key(t), o = (this.introCount.get(e) ?? 0) + 1;
219
- this.introCount.set(e, o), this.watchedSinceIntro = 0, g((h = t.tracking) == null ? void 0 : h.intro), this.ctx.hostEl.dispatchEvent(new CustomEvent("hp:sponsorintro", { detail: { id: t.id, sponsor: t.sponsor.name, count: o } })), this.introTimer && clearTimeout(this.introTimer), (p = this.introEl) == null || p.remove();
214
+ this.introCount.set(e, o), this.watchedSinceIntro = 0, m((h = t.tracking) == null ? void 0 : h.intro), this.ctx.hostEl.dispatchEvent(new CustomEvent("hp:sponsorintro", { detail: { id: t.id, sponsor: t.sponsor.name, count: o } })), this.introTimer && clearTimeout(this.introTimer), (p = this.introEl) == null || p.remove();
220
215
  const s = document.createElement("div");
221
216
  if (s.className = "hp-sponsor-intro", s.setAttribute("part", "sponsor-intro"), s.setAttribute("role", "status"), t.sponsor.logo) {
222
217
  const c = document.createElement("img");
@@ -227,19 +222,19 @@ class L {
227
222
  s.setAttribute("data-leaving", ""), this.ctx.hostEl.removeAttribute("data-sponsor-intro"), this.introTimer = setTimeout(() => {
228
223
  s.remove(), this.introEl === s && (this.introEl = null);
229
224
  }, 400);
230
- }, ((n = t.intro) == null ? void 0 : n.durationMs) ?? 3500);
225
+ }, ((n = t.intro) == null ? void 0 : n.durationMs) ?? k);
231
226
  }
232
227
  destroy() {
233
228
  var t, e, o;
234
229
  this.destroyed = !0, clearInterval(this.tickTimer), (t = this.resizeObserver) == null || t.disconnect(), this.refreshTimer && clearInterval(this.refreshTimer), this.introTimer && clearTimeout(this.introTimer), this.ctx.videoEl.removeEventListener("play", this.onPlay), this.ctx.hostEl.removeEventListener("hp:adstart", this.onAdStart), this.ctx.hostEl.removeEventListener("hp:adend", this.onAdEnd), this.applyTheme(null), (e = this.logoEl) == null || e.remove(), (o = this.introEl) == null || o.remove(), this.ctx.hostEl.removeAttribute("data-sponsored"), this.ctx.hostEl.removeAttribute("data-sponsor-hidden"), this.ctx.hostEl.removeAttribute("data-sponsor-intro");
235
230
  }
236
231
  }
237
- function I(i, t) {
238
- return new L(i, t);
232
+ function N(i, t) {
233
+ return new I(i, t);
239
234
  }
240
235
  export {
241
- L as SponsorshipLayer,
242
- I as installSponsorship,
243
- A as normalizeSponsorship
236
+ I as SponsorshipLayer,
237
+ N as installSponsorship,
238
+ L as normalizeSponsorship
244
239
  };
245
- //# sourceMappingURL=sponsorship-DyFwGmEb.js.map
240
+ //# sourceMappingURL=sponsorship-BT21uwN5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sponsorship-BT21uwN5.js","sources":["../../src/plugins/sponsorship/SponsorshipLayer.ts","../../src/plugins/sponsorship/index.ts"],"sourcesContent":["import type { SponsorshipConfig, SponsorshipOptions } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\nimport { firePixels as fire } from '../shared/trackingPixel';\n\nexport interface SponsorshipContext {\n hostEl: HTMLElement;\n videoEl: HTMLVideoElement;\n /** Logo ve giriş kartının ekleneceği alan (video alanı). */\n overlayEl: HTMLElement;\n i18n: HopeLocaleStrings;\n log(entry: { message: string; fatal?: boolean; details?: Record<string, string | number | boolean | undefined> }): void;\n}\n\nconst DEFAULT_TIMEOUT_MS = 5000;\nconst DEFAULT_LOGO_WIDTH = 96;\nconst DEFAULT_INTRO_MS = 3500;\n/** API'den gelen tema değerleri → player'ın CSS değişkenleri. */\nconst THEME_TOKENS: Record<keyof NonNullable<SponsorshipConfig['theme']>, string> = {\n accent: '--hp-color-accent',\n onAccent: '--hp-color-on-accent',\n surface: '--hp-color-surface',\n onSurface: '--hp-color-on-surface',\n};\nconst POSITIONS = ['top-left', 'top-right', 'bottom-left', 'bottom-right'] as const;\n\n/** Yalnızca http(s) ya da göreli adresler — `javascript:` / `data:` gibi şemalar reddedilir. */\nfunction safeUrl(value: unknown): string | null {\n if (typeof value !== 'string' || !value.trim()) return null;\n try {\n const u = new URL(value, document.baseURI);\n return u.protocol === 'https:' || u.protocol === 'http:' ? u.href : null;\n } catch {\n return null;\n }\n}\n\nfunction safeColor(value: unknown): string | null {\n return typeof value === 'string' && value.length < 64 && CSS.supports('color', value) ? value : null;\n}\n\nfunction clamp(n: unknown, min: number, max: number, fallback: number): number {\n return typeof n === 'number' && Number.isFinite(n) ? Math.min(max, Math.max(min, n)) : fallback;\n}\n\n/** API yanıtını doğrular, geçersiz alanları atar; katman kapalıysa null. */\nexport function normalizeSponsorship(raw: unknown): SponsorshipConfig | null {\n if (!raw || typeof raw !== 'object') return null;\n const r = raw as Partial<SponsorshipConfig>;\n if (r.active !== true || !r.sponsor || typeof r.sponsor.name !== 'string' || !r.sponsor.name.trim()) return null;\n const now = Date.now();\n const from = r.validFrom ? Date.parse(r.validFrom) : NaN;\n const until = r.validUntil ? Date.parse(r.validUntil) : NaN;\n if ((Number.isFinite(from) && now < from) || (Number.isFinite(until) && now > until)) return null;\n const theme: NonNullable<SponsorshipConfig['theme']> = {};\n for (const key of Object.keys(THEME_TOKENS) as Array<keyof typeof THEME_TOKENS>) {\n const c = safeColor(r.theme?.[key]);\n if (c) theme[key] = c;\n }\n const urls = (list: unknown): string[] => (Array.isArray(list) ? list.map(safeUrl).filter((u): u is string => !!u).slice(0, 10) : []);\n return {\n active: true,\n id: typeof r.id === 'string' ? r.id.slice(0, 120) : undefined,\n sponsor: {\n name: r.sponsor.name.slice(0, 80),\n logo: safeUrl(r.sponsor.logo) ?? undefined,\n url: safeUrl(r.sponsor.url) ?? undefined,\n },\n theme,\n logo: {\n position: POSITIONS.includes(r.logo?.position as (typeof POSITIONS)[number]) ? r.logo!.position : 'top-left',\n width: clamp(r.logo?.width, 32, 240, DEFAULT_LOGO_WIDTH),\n opacity: clamp(r.logo?.opacity, 0.2, 1, 0.9),\n label: typeof r.logo?.label === 'string' ? r.logo.label.slice(0, 40) : undefined,\n },\n intro: r.intro\n ? {\n text: typeof r.intro.text === 'string' ? r.intro.text.slice(0, 120) : undefined,\n durationMs: clamp(r.intro.durationMs, 1000, 15000, DEFAULT_INTRO_MS),\n repeatMinutes: typeof r.intro.repeatMinutes === 'number' && r.intro.repeatMinutes > 0 ? Math.min(240, Math.max(1, r.intro.repeatMinutes)) : undefined,\n maxShows: typeof r.intro.maxShows === 'number' && r.intro.maxShows >= 1 ? Math.min(100, Math.floor(r.intro.maxShows)) : undefined,\n }\n : undefined,\n tracking: { impression: urls(r.tracking?.impression), click: urls(r.tracking?.click), intro: urls(r.tracking?.intro) },\n };\n}\n\n\n/**\n * Sponsorluk katmanı: `endpoint`'ten JSON çeker (SponsorshipConfig), player renklerini değiştirir, köşeye logo koyar,\n * oynatma başlarken \"X sunar\" kartını gösterir. Canlıda `refreshSeconds` ile kampanya değişimi izlenir. API hatasında\n * son geçerli ayar korunur; hiç alınamadıysa katman kapalı kalır — player normal çalışır.\n */\nexport class SponsorshipLayer {\n private options: SponsorshipOptions;\n private config: SponsorshipConfig | null = null;\n private logoEl: HTMLAnchorElement | HTMLDivElement | null = null;\n private introEl: HTMLDivElement | null = null;\n private introTimer: ReturnType<typeof setTimeout> | null = null;\n private refreshTimer: ReturnType<typeof setInterval> | null = null;\n /** Player boyutu / kontrol düzeni değişince logo kontrollerin üstüne binmesin diye yeniden konumlanır. */\n private readonly resizeObserver: ResizeObserver | null;\n /** Uygulanan tema değişkenlerinin önceki satır içi değerleri — katman kalkınca geri yüklenir. */\n private previousTokens = new Map<string, string>();\n /** Gösterim pikseli kampanya başına bir kez. */\n private impressed = new Set<string>();\n /** Kampanya başına giriş gösterim sayısı. */\n private introCount = new Map<string, number>();\n /** Son girişten bu yana gerçek izleme süresi (ms) — intro.repeatMinutes için. */\n private watchedSinceIntro = 0;\n private lastTick = 0;\n private readonly tickTimer: ReturnType<typeof setInterval>;\n private destroyed = false;\n private requestSeq = 0;\n\n constructor(\n private readonly ctx: SponsorshipContext,\n options: SponsorshipOptions\n ) {\n this.options = options;\n ctx.videoEl.addEventListener('play', this.onPlay);\n ctx.hostEl.addEventListener('hp:adstart', this.onAdStart);\n ctx.hostEl.addEventListener('hp:adend', this.onAdEnd);\n this.lastTick = performance.now();\n this.tickTimer = setInterval(this.tick, 1000);\n this.resizeObserver = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(() => this.positionLogo()) : null;\n this.resizeObserver?.observe(ctx.overlayEl);\n const topBar = ctx.overlayEl.querySelector('.hp-top-bar');\n if (topBar) this.resizeObserver?.observe(topBar);\n void this.load();\n this.scheduleRefresh();\n }\n\n update(options: SponsorshipOptions): void {\n const changed = options.endpoint !== this.options.endpoint || JSON.stringify(options.params) !== JSON.stringify(this.options.params);\n const refreshChanged = options.refreshSeconds !== this.options.refreshSeconds;\n this.options = options;\n if (changed) void this.load();\n if (refreshChanged) this.scheduleRefresh();\n }\n\n /** Şu an uygulanan kampanya (yoksa null). */\n get current(): SponsorshipConfig | null {\n return this.config;\n }\n\n private scheduleRefresh(): void {\n if (this.refreshTimer) clearInterval(this.refreshTimer);\n this.refreshTimer = null;\n const s = this.options.refreshSeconds;\n if (typeof s === 'number' && s >= 10) this.refreshTimer = setInterval(() => void this.load(), s * 1000);\n }\n\n private buildUrl(): string {\n const u = new URL(this.options.endpoint, document.baseURI);\n for (const [k, v] of Object.entries(this.options.params ?? {})) u.searchParams.set(k, v);\n return u.href;\n }\n\n private async load(): Promise<void> {\n const seq = ++this.requestSeq;\n const ctrl = typeof AbortController !== 'undefined' ? new AbortController() : null;\n const timer = setTimeout(() => ctrl?.abort(), this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n let url = '';\n try {\n url = this.buildUrl();\n const res = await fetch(url, { ...this.options.fetchInit, signal: ctrl?.signal });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const json: unknown = await res.json();\n if (this.destroyed || seq !== this.requestSeq) return; // daha yeni bir istek var\n this.apply(normalizeSponsorship(json));\n } catch (err) {\n if (this.destroyed || seq !== this.requestSeq) return;\n // Son geçerli kampanya korunur — geçici API hatası katmanı söndürmesin.\n this.ctx.log({ message: `Sponsorship API failed: ${String(err)}`, details: { url } });\n } finally {\n clearTimeout(timer);\n }\n }\n\n private apply(config: SponsorshipConfig | null): void {\n const prevKey = this.key(this.config);\n this.config = config;\n this.applyTheme(config?.theme ?? null);\n this.renderLogo();\n this.ctx.hostEl.toggleAttribute('data-sponsored', !!config);\n if (this.key(config) !== prevKey) {\n this.watchedSinceIntro = 0;\n this.ctx.hostEl.dispatchEvent(new CustomEvent('hp:sponsorship', { detail: { config } }));\n // Yeni kampanya oynarken geldiyse (canlı yenileme) girişi hemen göster.\n if (config && !this.ctx.videoEl.paused) this.onPlay();\n }\n }\n\n private key(c: SponsorshipConfig | null): string {\n return c ? c.id || c.sponsor.name : '';\n }\n\n private applyTheme(theme: SponsorshipConfig['theme'] | null): void {\n const style = this.ctx.hostEl.style;\n // Önce önceki kampanyanın değerlerini geri al.\n for (const [prop, value] of this.previousTokens) {\n if (value) style.setProperty(prop, value);\n else style.removeProperty(prop);\n }\n this.previousTokens.clear();\n if (!theme) return;\n for (const [key, prop] of Object.entries(THEME_TOKENS) as Array<[keyof typeof THEME_TOKENS, string]>) {\n const value = theme[key];\n if (!value) continue;\n this.previousTokens.set(prop, style.getPropertyValue(prop));\n style.setProperty(prop, value);\n }\n }\n\n private renderLogo(): void {\n this.logoEl?.remove();\n this.logoEl = null;\n const c = this.config;\n if (!c || (!c.sponsor.logo && !c.logo?.label)) return;\n const el = c.sponsor.url ? document.createElement('a') : document.createElement('div');\n el.className = 'hp-sponsor-logo';\n el.setAttribute('part', 'sponsor-logo');\n el.setAttribute('data-position', c.logo?.position ?? 'top-left');\n el.style.setProperty('--hp-sponsor-logo-w', `${c.logo?.width ?? DEFAULT_LOGO_WIDTH}px`);\n el.style.opacity = String(c.logo?.opacity ?? 0.9);\n if (el instanceof HTMLAnchorElement) {\n el.href = c.sponsor.url!;\n el.target = '_blank';\n el.rel = 'noopener sponsored';\n el.addEventListener('click', (e) => {\n e.stopPropagation();\n fire(c.tracking?.click);\n this.ctx.hostEl.dispatchEvent(new CustomEvent('hp:sponsorclick', { detail: { id: c.id, sponsor: c.sponsor.name } }));\n });\n }\n el.setAttribute('aria-label', c.sponsor.name);\n if (c.sponsor.logo) {\n const img = document.createElement('img');\n img.src = c.sponsor.logo;\n img.alt = c.sponsor.name;\n img.decoding = 'async';\n img.addEventListener('error', () => img.remove());\n el.appendChild(img);\n }\n // Etiket logonun altında, ortalı.\n if (c.logo?.label) {\n const label = document.createElement('span');\n label.className = 'hp-sponsor-label';\n label.textContent = c.logo.label;\n el.appendChild(label);\n }\n for (const t of ['pointerdown', 'dblclick'] as const) el.addEventListener(t, (e) => e.stopPropagation());\n this.ctx.overlayEl.appendChild(el);\n this.logoEl = el;\n this.positionLogo();\n }\n\n /**\n * Logo kontrollerin üstüne binmesin: sağ üstte (dar player'da ayarlar / PiP oraya taşınır) üst çubuğun soluna,\n * altta seek bar'ın hemen üstüne yerleşir. Dar player'da logo en fazla 48 px.\n */\n private positionLogo(): void {\n const el = this.logoEl;\n if (!el) return;\n const area = this.ctx.overlayEl;\n const compact = area.hasAttribute('data-compact');\n const position = el.getAttribute('data-position');\n // Kontroller görünürken kaçınılacak mesafe CSS değişkenine yazılır; kontroller gizliyken CSS logoyu köşeye\n // alır (bkz. :host([data-chrome-hidden])) ve geçiş animasyonlu olur.\n el.style.removeProperty('--hp-sponsor-avoid-right');\n el.style.removeProperty('--hp-sponsor-avoid-bottom');\n el.toggleAttribute('data-compact', compact);\n const a = area.getBoundingClientRect();\n if (position === 'top-right') {\n const bar = area.querySelector('.hp-top-bar')?.getBoundingClientRect();\n if (bar && bar.width > 0) el.style.setProperty('--hp-sponsor-avoid-right', `${Math.round(a.right - bar.left + 8)}px`);\n } else if (position === 'bottom-left' || position === 'bottom-right') {\n const seek = area.querySelector('[part=\"seek-bar\"]')?.getBoundingClientRect();\n if (seek && seek.height > 0) el.style.setProperty('--hp-sponsor-avoid-bottom', `${Math.round(a.bottom - seek.top + 6)}px`);\n }\n }\n\n /** Oynatma başladı: kampanya başına bir kez gösterim pikseli + \"X sunar\" kartı. */\n private readonly onPlay = (): void => {\n const c = this.config;\n if (!c) return;\n const key = this.key(c);\n if (!this.impressed.has(key)) {\n this.impressed.add(key);\n fire(c.tracking?.impression);\n this.ctx.hostEl.dispatchEvent(new CustomEvent('hp:sponsorimpression', { detail: { id: c.id, sponsor: c.sponsor.name } }));\n }\n if (c.intro && !this.introCount.has(key)) this.showIntro(c);\n };\n\n /**\n * intro.repeatMinutes: yalnızca gerçekten izlenirken sayar (oynuyor, sekme önde, reklam yok); süre dolunca giriş\n * tekrar gösterilir — maxShows'a kadar.\n */\n private readonly tick = (): void => {\n const now = performance.now();\n // Sekme uyuyunca setInterval seyrekleşir — tek seferde en fazla 2 sn sayılır.\n const delta = Math.min(2000, Math.max(0, now - this.lastTick));\n this.lastTick = now;\n const c = this.config;\n const repeat = c?.intro?.repeatMinutes;\n if (!c || !repeat) return;\n const watching =\n !this.ctx.videoEl.paused && !this.ctx.videoEl.ended && !document.hidden && !this.ctx.hostEl.hasAttribute('data-sponsor-hidden');\n if (!watching || !this.introCount.has(this.key(c))) return;\n this.watchedSinceIntro += delta;\n if (this.watchedSinceIntro < repeat * 60_000) return;\n const max = c.intro?.maxShows;\n if (max && (this.introCount.get(this.key(c)) ?? 0) >= max) return;\n this.showIntro(c);\n };\n\n private showIntro(c: SponsorshipConfig): void {\n const key = this.key(c);\n const count = (this.introCount.get(key) ?? 0) + 1;\n this.introCount.set(key, count);\n this.watchedSinceIntro = 0;\n fire(c.tracking?.intro);\n this.ctx.hostEl.dispatchEvent(new CustomEvent('hp:sponsorintro', { detail: { id: c.id, sponsor: c.sponsor.name, count } }));\n if (this.introTimer) clearTimeout(this.introTimer);\n this.introEl?.remove();\n const el = document.createElement('div');\n el.className = 'hp-sponsor-intro';\n el.setAttribute('part', 'sponsor-intro');\n el.setAttribute('role', 'status');\n if (c.sponsor.logo) {\n const img = document.createElement('img');\n img.src = c.sponsor.logo;\n img.alt = '';\n img.addEventListener('error', () => img.remove());\n el.appendChild(img);\n }\n const text = document.createElement('span');\n text.textContent = c.intro?.text || this.ctx.i18n.sponsorPresents.replace('{name}', c.sponsor.name);\n el.appendChild(text);\n this.ctx.overlayEl.appendChild(el);\n this.introEl = el;\n // Giriş kartı sponsoru zaten gösteriyor — kart görünürken köşe logosu gizli (küçük player'da üst üste binmesin).\n this.ctx.hostEl.setAttribute('data-sponsor-intro', '');\n this.introTimer = setTimeout(() => {\n el.setAttribute('data-leaving', '');\n this.ctx.hostEl.removeAttribute('data-sponsor-intro');\n this.introTimer = setTimeout(() => {\n el.remove();\n if (this.introEl === el) this.introEl = null;\n }, 400);\n }, c.intro?.durationMs ?? DEFAULT_INTRO_MS);\n }\n\n /** Lineer reklam sırasında logo / giriş gizlenir (reklamın üstüne binmesin). */\n private readonly onAdStart = (e: Event): void => {\n if ((e as CustomEvent<{ linear?: boolean }>).detail?.linear === false) return;\n this.ctx.hostEl.setAttribute('data-sponsor-hidden', '');\n };\n\n private readonly onAdEnd = (e: Event): void => {\n if ((e as CustomEvent<{ linear?: boolean }>).detail?.linear === false) return;\n this.ctx.hostEl.removeAttribute('data-sponsor-hidden');\n };\n\n destroy(): void {\n this.destroyed = true;\n clearInterval(this.tickTimer);\n this.resizeObserver?.disconnect();\n if (this.refreshTimer) clearInterval(this.refreshTimer);\n if (this.introTimer) clearTimeout(this.introTimer);\n this.ctx.videoEl.removeEventListener('play', this.onPlay);\n this.ctx.hostEl.removeEventListener('hp:adstart', this.onAdStart);\n this.ctx.hostEl.removeEventListener('hp:adend', this.onAdEnd);\n this.applyTheme(null);\n this.logoEl?.remove();\n this.introEl?.remove();\n this.ctx.hostEl.removeAttribute('data-sponsored');\n this.ctx.hostEl.removeAttribute('data-sponsor-hidden');\n this.ctx.hostEl.removeAttribute('data-sponsor-intro');\n }\n}\n","import { SponsorshipLayer, normalizeSponsorship, type SponsorshipContext } from './SponsorshipLayer';\nimport type { SponsorshipOptions } from '../../types';\n\n/** Sponsorluk katmanını kurar (ayarları `endpoint`'ten alır). */\nexport function installSponsorship(ctx: SponsorshipContext, options: SponsorshipOptions): SponsorshipLayer {\n return new SponsorshipLayer(ctx, options);\n}\n\nexport { SponsorshipLayer, normalizeSponsorship };\nexport type { SponsorshipContext };\n"],"names":["DEFAULT_TIMEOUT_MS","DEFAULT_LOGO_WIDTH","DEFAULT_INTRO_MS","THEME_TOKENS","POSITIONS","safeUrl","value","u","safeColor","clamp","n","min","max","fallback","normalizeSponsorship","raw","r","now","from","until","theme","key","c","_a","urls","list","_b","_c","_d","_e","_f","_g","_h","SponsorshipLayer","ctx","options","__publicField","fire","delta","repeat","e","topBar","changed","refreshChanged","s","k","v","seq","ctrl","timer","url","res","json","err","config","prevKey","style","prop","el","img","label","t","area","compact","position","a","bar","seek","count","text","installSponsorship"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  var E = Object.defineProperty;
2
2
  var y = (a, t, e) => t in a ? E(a, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : a[t] = e;
3
3
  var l = (a, t, e) => y(a, typeof t != "symbol" ? t + "" : t, e);
4
- import { f as x } from "./player-C886oKP-.js";
4
+ import { f as x } from "./player-DW5iWvPs.js";
5
5
  const w = 8, f = /%(0(\d+))?d/;
6
6
  class M {
7
7
  constructor(t, e) {
@@ -222,4 +222,4 @@ export {
222
222
  M as SpriteThumbnails,
223
223
  I as installSpriteThumbnails
224
224
  };
225
- //# sourceMappingURL=spriteThumbnails-D0NQ5CCp.js.map
225
+ //# sourceMappingURL=spriteThumbnails-BQkEBRu-.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"spriteThumbnails-D0NQ5CCp.js","sources":["../../src/plugins/sprite-thumbnails/SpriteThumbnails.ts","../../src/plugins/sprite-thumbnails/index.ts"],"sourcesContent":["import type { SpriteThumbnailsOptions } from '../../types';\nimport { formatTime } from '../../utils/format-time';\n\nexport interface SpriteThumbnailsPlayerContext {\n videoEl: HTMLVideoElement;\n /** Önizlemenin bağlandığı seek bar — zaman eşlemesi (chapter boşlukları dahil) onun `ratioAtClientX`'inden. */\n seekBar: {\n readonly el: HTMLElement;\n ratioAtClientX(clientX: number): number;\n suppressHoverTime(key: string, suppressed: boolean): void;\n };\n /** Responsive ölçekleme için referans genişlik — genelde player/video alanının genişliği. */\n playerWidth(): number;\n}\n\n/** Bir önizleme karesi: hangi görselin hangi dikdörtgeni. */\ninterface Frame {\n url: string;\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\ninterface Sheet {\n img: HTMLImageElement;\n ready: boolean;\n failed: boolean;\n promise: Promise<void>;\n}\n\nexport interface VttCue {\n start: number;\n end: number;\n url: string;\n /** `#xywh` yoksa null → görselin tamamı. */\n rect: { x: number; y: number; w: number; h: number } | null;\n}\n\n/** Aynı anda bellekte (decode edilmiş) tutulan en fazla sheet — uzun videolarda bellek sınırsız büyümesin. */\nconst MAX_CACHED_SHEETS = 8;\n/** Sheet numarası şablonu: `%d` ya da sıfır dolgulu `%03d`. */\nconst SHEET_TEMPLATE = /%(0(\\d+))?d/;\n\n/**\n * Seek bar hover önizlemesi. Kaynak: tek görsel, çok parçalı (%d / %03d şablonu ya da sheets) veya WebVTT (#xywh).\n * sheetDuration verilmezse ilk sheet'in ızgarasından hesaplanır. Kurulumda hiçbir şey indirilmez; yalnızca imlecin\n * altındaki sheet + komşuları yüklenir, decode bitmeden gösterilmez, LRU cache.\n */\nexport class SpriteThumbnails {\n private readonly tooltip: HTMLElement;\n private readonly imageEl: HTMLElement;\n private readonly timeEl: HTMLElement;\n private readonly sheets = new Map<string, Sheet>();\n private vttCues: VttCue[] | null = null;\n private vttLoading: Promise<void> | null = null;\n /** Çok parçalı modda otomatik hesaplanan sheet süresi (ilk sheet yüklenince). */\n private derivedSheetDuration: number | null = null;\n private warmed = false;\n private hovering = false;\n private lastClientX = 0;\n private rafId: number | null = null;\n private destroyed = false;\n\n constructor(\n private readonly ctx: SpriteThumbnailsPlayerContext,\n private readonly options: SpriteThumbnailsOptions\n ) {\n this.tooltip = document.createElement('div');\n this.tooltip.setAttribute('part', 'sprite-tooltip');\n this.tooltip.className = 'hp-sprite-tooltip';\n this.imageEl = document.createElement('div');\n this.imageEl.className = 'hp-sprite-image';\n this.timeEl = document.createElement('div');\n this.timeEl.className = 'hp-sprite-time';\n this.tooltip.append(this.imageEl, this.timeEl);\n ctx.seekBar.el.appendChild(this.tooltip);\n // Önizlemenin altında zaman zaten yazıyor — varsayılan hover zamanı ikinci kez göstermesin.\n ctx.seekBar.suppressHoverTime('sprite', true);\n\n ctx.seekBar.el.addEventListener('pointerenter', this.onPointerEnter);\n ctx.seekBar.el.addEventListener('pointermove', this.onPointerMove);\n ctx.seekBar.el.addEventListener('pointerleave', this.onPointerLeave);\n ctx.videoEl.addEventListener('play', this.warm);\n }\n\n destroy(): void {\n this.destroyed = true;\n if (this.rafId !== null) cancelAnimationFrame(this.rafId);\n this.ctx.seekBar.el.removeEventListener('pointerenter', this.onPointerEnter);\n this.ctx.seekBar.el.removeEventListener('pointermove', this.onPointerMove);\n this.ctx.seekBar.el.removeEventListener('pointerleave', this.onPointerLeave);\n this.ctx.videoEl.removeEventListener('play', this.warm);\n this.tooltip.remove();\n this.ctx.seekBar.suppressHoverTime('sprite', false);\n for (const sheet of this.sheets.values()) sheet.img.src = '';\n this.sheets.clear();\n }\n\n // ── olaylar ──\n\n private readonly onPointerEnter = (e: PointerEvent): void => {\n this.hovering = true;\n this.lastClientX = e.clientX;\n this.warm();\n this.scheduleRender();\n };\n\n private readonly onPointerMove = (e: PointerEvent): void => {\n this.hovering = true;\n this.lastClientX = e.clientX;\n this.scheduleRender();\n };\n\n private readonly onPointerLeave = (): void => {\n this.hovering = false;\n this.tooltip.removeAttribute('data-visible');\n };\n\n /** İlk ihtiyaç anında (hover / oynatma) kaynağı hazırla — kurulumda hiçbir şey indirilmiyor. */\n private readonly warm = (): void => {\n if (this.warmed || this.destroyed) return;\n this.warmed = true;\n if (this.options.vtt) {\n void this.loadVtt();\n return;\n }\n const duration = this.ctx.videoEl.duration;\n const t = Number.isFinite(duration) ? this.ctx.videoEl.currentTime : 0;\n // Şablonlu/çok parçalı modda sheet süresi henüz bilinmiyorsa ilk sheet'ten öğrenilecek.\n void this.ensureSheet(this.sheetUrl(this.isMultiSheet() && this.sheetDuration() === null ? 0 : this.sheetIndexAt(t)));\n };\n\n private scheduleRender(): void {\n if (this.rafId !== null) return;\n this.rafId = requestAnimationFrame(() => {\n this.rafId = null;\n this.render();\n });\n }\n\n // ── çizim ──\n\n private render(): void {\n if (!this.hovering || this.destroyed) return;\n const duration = this.ctx.videoEl.duration;\n if (!Number.isFinite(duration) || duration <= 0) return;\n\n const seconds = this.ctx.seekBar.ratioAtClientX(this.lastClientX) * duration;\n this.timeEl.textContent = formatTime(seconds);\n\n const frame = this.isNetworkEligible() ? this.frameAt(seconds, duration) : null;\n const scale = this.scale();\n if (frame) {\n const sheet = this.sheets.get(frame.url)!;\n const { naturalWidth, naturalHeight } = sheet.img;\n this.imageEl.style.display = '';\n this.imageEl.style.width = `${frame.w * scale}px`;\n this.imageEl.style.height = `${frame.h * scale}px`;\n this.imageEl.style.backgroundImage = `url(\"${frame.url}\")`;\n this.imageEl.style.backgroundSize = `${naturalWidth * scale}px ${naturalHeight * scale}px`;\n this.imageEl.style.backgroundPosition = `${-frame.x * scale}px ${-frame.y * scale}px`;\n } else if (!this.imageEl.style.backgroundImage) {\n // Henüz hiçbir kare yüklenmedi — yalnızca zaman (yükleme bitince yeniden çizilir).\n this.imageEl.style.display = 'none';\n }\n\n // Kenarlarda taşmasın: imleci ortala ama seek bar sınırlarında kal.\n this.tooltip.setAttribute('data-visible', '');\n const barRect = this.ctx.seekBar.el.getBoundingClientRect();\n const tipWidth = this.tooltip.offsetWidth;\n const x = Math.min(Math.max(this.lastClientX - barRect.left - tipWidth / 2, 0), Math.max(barRect.width - tipWidth, 0));\n this.tooltip.style.transform = `translateX(${x}px)`;\n }\n\n private scale(): number {\n const responsive = this.options.responsive;\n const playerWidth = this.ctx.playerWidth();\n return responsive && playerWidth && playerWidth < responsive ? playerWidth / responsive : 1;\n }\n\n private isNetworkEligible(): boolean {\n const nav = navigator as Navigator & { connection?: { downlink?: number } };\n const downlink = nav.connection?.downlink;\n const anyReady = Array.from(this.sheets.values()).some((s) => s.ready);\n return downlink === undefined || downlink >= (this.options.downlink ?? 2) || anyReady;\n }\n\n // ── kare çözümleme ──\n\n /** Saniyedeki kareyi döner; gereken sheet hazır değilse yüklemeyi başlatıp null döner (yüklenince render tekrar çağrılır). */\n private frameAt(seconds: number, duration: number): Frame | null {\n return this.options.vtt ? this.vttFrameAt(seconds) : this.gridFrameAt(seconds, duration);\n }\n\n private isMultiSheet(): boolean {\n return !!this.options.sheets?.length || SHEET_TEMPLATE.test(this.options.url ?? '');\n }\n\n /** Tek sheet → Infinity (tüm video); çok parçalı → verilen ya da ilk sheet'ten hesaplanan süre; henüz bilinmiyorsa null. */\n private sheetDuration(): number | null {\n if (!this.isMultiSheet()) return Infinity;\n return this.options.sheetDuration ?? this.derivedSheetDuration;\n }\n\n private sheetIndexAt(seconds: number): number {\n const d = this.sheetDuration();\n if (d === null || d === Infinity) return 0;\n // floor (ceil DEĞİL): tam sınırda (ör. 60. sn) bir SONRAKİ sheet'in ilk karesi.\n let index = Math.floor(Math.max(0, seconds) / d);\n if (this.options.sheets?.length) index = Math.min(index, this.options.sheets.length - 1);\n return index;\n }\n\n /** 0 tabanlı sheet index'inden URL. */\n private sheetUrl(index: number): string {\n if (this.options.sheets?.length) return this.options.sheets[Math.min(index, this.options.sheets.length - 1)]!;\n const url = this.options.url ?? '';\n const number = index + (this.options.firstSheetIndex ?? 1);\n return url.replace(SHEET_TEMPLATE, (_m, _p, width?: string) => String(number).padStart(width ? Number(width) : 0, '0'));\n }\n\n private gridFrameAt(seconds: number, duration: number): Frame | null {\n const { width, height } = this.options;\n if (!width || !height) return null;\n const interval = this.options.interval || 1;\n\n const sheetDuration = this.sheetDuration();\n if (sheetDuration === null) {\n // Çok parçalı ama süre bilinmiyor — ilk sheet yüklenince hesaplanacak.\n void this.ensureSheet(this.sheetUrl(0));\n return null;\n }\n\n const lastIndex = sheetDuration === Infinity ? 0 : this.sheetIndexAt(Math.max(0, duration - 0.001));\n const index = Math.min(this.sheetIndexAt(seconds), lastIndex);\n const url = this.sheetUrl(index);\n this.preloadAround(index, lastIndex);\n\n const sheet = this.sheets.get(url);\n if (!sheet?.ready) {\n void this.ensureSheet(url);\n return null;\n }\n this.touch(url);\n\n // Her sheet'in KENDİ boyutu (son sheet daha kısa olabilir).\n const columns = Math.max(1, Math.floor(sheet.img.naturalWidth / width));\n const rows = Math.max(1, Math.floor(sheet.img.naturalHeight / height));\n const local = sheetDuration === Infinity ? seconds : seconds - index * sheetDuration;\n const frameIndex = Math.min(Math.max(0, Math.floor(local / interval)), columns * rows - 1);\n return { url, x: (frameIndex % columns) * width, y: Math.floor(frameIndex / columns) * height, w: width, h: height };\n }\n\n private preloadAround(index: number, lastIndex: number): void {\n const n = this.options.preloadSheets ?? 1;\n for (let d = 1; d <= n; d++) {\n if (index + d <= lastIndex) void this.ensureSheet(this.sheetUrl(index + d));\n if (index - d >= 0) void this.ensureSheet(this.sheetUrl(index - d));\n }\n }\n\n private vttFrameAt(seconds: number): Frame | null {\n if (!this.vttCues) {\n void this.loadVtt();\n return null;\n }\n const cues = this.vttCues;\n if (!cues.length) return null;\n // İkili arama — saatlerce süren videolarda binlerce cue olabilir.\n let lo = 0;\n let hi = cues.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n if (cues[mid]!.start <= seconds) lo = mid;\n else hi = mid - 1;\n }\n const cue = cues[lo]!;\n const neighbours = [cues[lo + 1], cues[lo - 1]].filter((c): c is VttCue => !!c && c.url !== cue.url);\n neighbours.forEach((c) => void this.ensureSheet(c.url));\n\n const sheet = this.sheets.get(cue.url);\n if (!sheet?.ready) {\n void this.ensureSheet(cue.url);\n return null;\n }\n this.touch(cue.url);\n const rect = cue.rect ?? { x: 0, y: 0, w: sheet.img.naturalWidth, h: sheet.img.naturalHeight };\n return { url: cue.url, ...rect };\n }\n\n // ── yükleme / cache ──\n\n private ensureSheet(url: string): Promise<void> {\n if (!url) return Promise.resolve();\n const existing = this.sheets.get(url);\n if (existing) return existing.promise;\n\n const img = new Image();\n img.decoding = 'async';\n const sheet: Sheet = { img, ready: false, failed: false, promise: Promise.resolve() };\n sheet.promise = new Promise<void>((resolve) => {\n img.onload = () => {\n // decode() bitmeden gösterme — yeni sheet'e geçerken boş/yanlış kare titremesi olmasın.\n const done = () => {\n if (this.destroyed) return resolve();\n sheet.ready = true;\n this.learnSheetDuration(img);\n if (this.hovering) this.scheduleRender();\n resolve();\n };\n img.decode ? img.decode().then(done, done) : done();\n };\n img.onerror = () => {\n sheet.failed = true;\n resolve();\n };\n });\n img.src = url;\n this.sheets.set(url, sheet);\n this.evict();\n return sheet.promise;\n }\n\n /** Çok parçalı modda `sheetDuration` verilmediyse ilk yüklenen sheet'in ızgara kapasitesinden hesapla. */\n private learnSheetDuration(img: HTMLImageElement): void {\n if (this.derivedSheetDuration !== null || this.options.vtt || !this.isMultiSheet() || this.options.sheetDuration) return;\n const { width, height } = this.options;\n if (!width || !height) return;\n const capacity = Math.max(1, Math.floor(img.naturalWidth / width)) * Math.max(1, Math.floor(img.naturalHeight / height));\n this.derivedSheetDuration = capacity * (this.options.interval || 1);\n }\n\n /** LRU: kullanılan sheet'i sona taşı. */\n private touch(url: string): void {\n const sheet = this.sheets.get(url);\n if (!sheet) return;\n this.sheets.delete(url);\n this.sheets.set(url, sheet);\n }\n\n private evict(): void {\n while (this.sheets.size > MAX_CACHED_SHEETS) {\n const oldest = this.sheets.keys().next().value as string;\n const sheet = this.sheets.get(oldest)!;\n sheet.img.onload = null;\n sheet.img.onerror = null;\n this.sheets.delete(oldest);\n }\n }\n\n private loadVtt(): Promise<void> {\n if (this.vttLoading) return this.vttLoading;\n const vttUrl = this.options.vtt!;\n this.vttLoading = fetch(vttUrl)\n .then((r) => {\n if (!r.ok) throw new Error(`HTTP ${r.status}`);\n return r.text();\n })\n .then((text) => {\n if (this.destroyed) return;\n this.vttCues = parseThumbnailVtt(text, new URL(vttUrl, document.baseURI).href);\n if (this.vttCues.length) void this.ensureSheet(this.vttCues[0]!.url);\n if (this.hovering) this.scheduleRender();\n })\n .catch((err) => {\n console.warn('[HopePlayer sprite-thumbnails] VTT yüklenemedi:', err);\n this.vttCues = [];\n });\n return this.vttLoading;\n }\n}\n\n/** \"01:02:03.500\" / \"02:03.500\" → saniye. */\nfunction parseVttTime(value: string): number {\n const parts = value.trim().split(':').map(Number);\n return parts.reduce((acc, n) => acc * 60 + n, 0);\n}\n\n/** WebVTT thumbnail dosyası → sıralı cue listesi. Görsel yolları VTT dosyasına göre çözümlenir. */\nexport function parseThumbnailVtt(text: string, baseUrl: string): VttCue[] {\n const cues: VttCue[] = [];\n const blocks = text.replace(/\\r/g, '').split(/\\n\\n+/);\n for (const block of blocks) {\n const lines = block.split('\\n').filter(Boolean);\n const timingIndex = lines.findIndex((l) => l.includes('-->'));\n if (timingIndex === -1) continue;\n const [startStr, endStr] = lines[timingIndex]!.split('-->');\n const target = lines[timingIndex + 1]?.trim();\n if (!startStr || !endStr || !target) continue;\n\n const [path, hash] = target.split('#');\n const match = hash?.match(/xywh=(\\d+),(\\d+),(\\d+),(\\d+)/);\n cues.push({\n start: parseVttTime(startStr),\n end: parseVttTime(endStr.trim().split(/\\s+/)[0]!),\n url: new URL(path!, baseUrl).href,\n rect: match ? { x: +match[1]!, y: +match[2]!, w: +match[3]!, h: +match[4]! } : null,\n });\n }\n return cues.sort((a, b) => a.start - b.start);\n}\n","import { SpriteThumbnails, type SpriteThumbnailsPlayerContext } from './SpriteThumbnails';\nimport type { SpriteThumbnailsOptions } from '../../types';\n\nexport function installSpriteThumbnails(ctx: SpriteThumbnailsPlayerContext, options: SpriteThumbnailsOptions): SpriteThumbnails {\n return new SpriteThumbnails(ctx, options);\n}\n\nexport { SpriteThumbnails };\nexport type { SpriteThumbnailsPlayerContext };\n"],"names":["MAX_CACHED_SHEETS","SHEET_TEMPLATE","SpriteThumbnails","ctx","options","__publicField","e","duration","t","sheet","seconds","formatTime","frame","scale","naturalWidth","naturalHeight","barRect","tipWidth","x","responsive","playerWidth","downlink","_a","anyReady","s","d","index","url","number","_m","_p","width","height","interval","sheetDuration","lastIndex","columns","rows","local","frameIndex","n","cues","lo","hi","mid","cue","c","rect","existing","img","resolve","done","capacity","oldest","vttUrl","r","text","parseThumbnailVtt","err","parseVttTime","value","acc","baseUrl","blocks","block","lines","timingIndex","l","startStr","endStr","target","path","hash","match","a","b","installSpriteThumbnails"],"mappings":"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"}
1
+ {"version":3,"file":"spriteThumbnails-BQkEBRu-.js","sources":["../../src/plugins/sprite-thumbnails/SpriteThumbnails.ts","../../src/plugins/sprite-thumbnails/index.ts"],"sourcesContent":["import type { SpriteThumbnailsOptions } from '../../types';\nimport { formatTime } from '../../utils/format-time';\n\nexport interface SpriteThumbnailsPlayerContext {\n videoEl: HTMLVideoElement;\n /** Önizlemenin bağlandığı seek bar — zaman eşlemesi (chapter boşlukları dahil) onun `ratioAtClientX`'inden. */\n seekBar: {\n readonly el: HTMLElement;\n ratioAtClientX(clientX: number): number;\n suppressHoverTime(key: string, suppressed: boolean): void;\n };\n /** Responsive ölçekleme için referans genişlik — genelde player/video alanının genişliği. */\n playerWidth(): number;\n}\n\n/** Bir önizleme karesi: hangi görselin hangi dikdörtgeni. */\ninterface Frame {\n url: string;\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\ninterface Sheet {\n img: HTMLImageElement;\n ready: boolean;\n failed: boolean;\n promise: Promise<void>;\n}\n\nexport interface VttCue {\n start: number;\n end: number;\n url: string;\n /** `#xywh` yoksa null → görselin tamamı. */\n rect: { x: number; y: number; w: number; h: number } | null;\n}\n\n/** Aynı anda bellekte (decode edilmiş) tutulan en fazla sheet — uzun videolarda bellek sınırsız büyümesin. */\nconst MAX_CACHED_SHEETS = 8;\n/** Sheet numarası şablonu: `%d` ya da sıfır dolgulu `%03d`. */\nconst SHEET_TEMPLATE = /%(0(\\d+))?d/;\n\n/**\n * Seek bar hover önizlemesi. Kaynak: tek görsel, çok parçalı (%d / %03d şablonu ya da sheets) veya WebVTT (#xywh).\n * sheetDuration verilmezse ilk sheet'in ızgarasından hesaplanır. Kurulumda hiçbir şey indirilmez; yalnızca imlecin\n * altındaki sheet + komşuları yüklenir, decode bitmeden gösterilmez, LRU cache.\n */\nexport class SpriteThumbnails {\n private readonly tooltip: HTMLElement;\n private readonly imageEl: HTMLElement;\n private readonly timeEl: HTMLElement;\n private readonly sheets = new Map<string, Sheet>();\n private vttCues: VttCue[] | null = null;\n private vttLoading: Promise<void> | null = null;\n /** Çok parçalı modda otomatik hesaplanan sheet süresi (ilk sheet yüklenince). */\n private derivedSheetDuration: number | null = null;\n private warmed = false;\n private hovering = false;\n private lastClientX = 0;\n private rafId: number | null = null;\n private destroyed = false;\n\n constructor(\n private readonly ctx: SpriteThumbnailsPlayerContext,\n private readonly options: SpriteThumbnailsOptions\n ) {\n this.tooltip = document.createElement('div');\n this.tooltip.setAttribute('part', 'sprite-tooltip');\n this.tooltip.className = 'hp-sprite-tooltip';\n this.imageEl = document.createElement('div');\n this.imageEl.className = 'hp-sprite-image';\n this.timeEl = document.createElement('div');\n this.timeEl.className = 'hp-sprite-time';\n this.tooltip.append(this.imageEl, this.timeEl);\n ctx.seekBar.el.appendChild(this.tooltip);\n // Önizlemenin altında zaman zaten yazıyor — varsayılan hover zamanı ikinci kez göstermesin.\n ctx.seekBar.suppressHoverTime('sprite', true);\n\n ctx.seekBar.el.addEventListener('pointerenter', this.onPointerEnter);\n ctx.seekBar.el.addEventListener('pointermove', this.onPointerMove);\n ctx.seekBar.el.addEventListener('pointerleave', this.onPointerLeave);\n ctx.videoEl.addEventListener('play', this.warm);\n }\n\n destroy(): void {\n this.destroyed = true;\n if (this.rafId !== null) cancelAnimationFrame(this.rafId);\n this.ctx.seekBar.el.removeEventListener('pointerenter', this.onPointerEnter);\n this.ctx.seekBar.el.removeEventListener('pointermove', this.onPointerMove);\n this.ctx.seekBar.el.removeEventListener('pointerleave', this.onPointerLeave);\n this.ctx.videoEl.removeEventListener('play', this.warm);\n this.tooltip.remove();\n this.ctx.seekBar.suppressHoverTime('sprite', false);\n for (const sheet of this.sheets.values()) sheet.img.src = '';\n this.sheets.clear();\n }\n\n // ── olaylar ──\n\n private readonly onPointerEnter = (e: PointerEvent): void => {\n this.hovering = true;\n this.lastClientX = e.clientX;\n this.warm();\n this.scheduleRender();\n };\n\n private readonly onPointerMove = (e: PointerEvent): void => {\n this.hovering = true;\n this.lastClientX = e.clientX;\n this.scheduleRender();\n };\n\n private readonly onPointerLeave = (): void => {\n this.hovering = false;\n this.tooltip.removeAttribute('data-visible');\n };\n\n /** İlk ihtiyaç anında (hover / oynatma) kaynağı hazırla — kurulumda hiçbir şey indirilmiyor. */\n private readonly warm = (): void => {\n if (this.warmed || this.destroyed) return;\n this.warmed = true;\n if (this.options.vtt) {\n void this.loadVtt();\n return;\n }\n const duration = this.ctx.videoEl.duration;\n const t = Number.isFinite(duration) ? this.ctx.videoEl.currentTime : 0;\n // Şablonlu/çok parçalı modda sheet süresi henüz bilinmiyorsa ilk sheet'ten öğrenilecek.\n void this.ensureSheet(this.sheetUrl(this.isMultiSheet() && this.sheetDuration() === null ? 0 : this.sheetIndexAt(t)));\n };\n\n private scheduleRender(): void {\n if (this.rafId !== null) return;\n this.rafId = requestAnimationFrame(() => {\n this.rafId = null;\n this.render();\n });\n }\n\n // ── çizim ──\n\n private render(): void {\n if (!this.hovering || this.destroyed) return;\n const duration = this.ctx.videoEl.duration;\n if (!Number.isFinite(duration) || duration <= 0) return;\n\n const seconds = this.ctx.seekBar.ratioAtClientX(this.lastClientX) * duration;\n this.timeEl.textContent = formatTime(seconds);\n\n const frame = this.isNetworkEligible() ? this.frameAt(seconds, duration) : null;\n const scale = this.scale();\n if (frame) {\n const sheet = this.sheets.get(frame.url)!;\n const { naturalWidth, naturalHeight } = sheet.img;\n this.imageEl.style.display = '';\n this.imageEl.style.width = `${frame.w * scale}px`;\n this.imageEl.style.height = `${frame.h * scale}px`;\n this.imageEl.style.backgroundImage = `url(\"${frame.url}\")`;\n this.imageEl.style.backgroundSize = `${naturalWidth * scale}px ${naturalHeight * scale}px`;\n this.imageEl.style.backgroundPosition = `${-frame.x * scale}px ${-frame.y * scale}px`;\n } else if (!this.imageEl.style.backgroundImage) {\n // Henüz hiçbir kare yüklenmedi — yalnızca zaman (yükleme bitince yeniden çizilir).\n this.imageEl.style.display = 'none';\n }\n\n // Kenarlarda taşmasın: imleci ortala ama seek bar sınırlarında kal.\n this.tooltip.setAttribute('data-visible', '');\n const barRect = this.ctx.seekBar.el.getBoundingClientRect();\n const tipWidth = this.tooltip.offsetWidth;\n const x = Math.min(Math.max(this.lastClientX - barRect.left - tipWidth / 2, 0), Math.max(barRect.width - tipWidth, 0));\n this.tooltip.style.transform = `translateX(${x}px)`;\n }\n\n private scale(): number {\n const responsive = this.options.responsive;\n const playerWidth = this.ctx.playerWidth();\n return responsive && playerWidth && playerWidth < responsive ? playerWidth / responsive : 1;\n }\n\n private isNetworkEligible(): boolean {\n const nav = navigator as Navigator & { connection?: { downlink?: number } };\n const downlink = nav.connection?.downlink;\n const anyReady = Array.from(this.sheets.values()).some((s) => s.ready);\n return downlink === undefined || downlink >= (this.options.downlink ?? 2) || anyReady;\n }\n\n // ── kare çözümleme ──\n\n /** Saniyedeki kareyi döner; gereken sheet hazır değilse yüklemeyi başlatıp null döner (yüklenince render tekrar çağrılır). */\n private frameAt(seconds: number, duration: number): Frame | null {\n return this.options.vtt ? this.vttFrameAt(seconds) : this.gridFrameAt(seconds, duration);\n }\n\n private isMultiSheet(): boolean {\n return !!this.options.sheets?.length || SHEET_TEMPLATE.test(this.options.url ?? '');\n }\n\n /** Tek sheet → Infinity (tüm video); çok parçalı → verilen ya da ilk sheet'ten hesaplanan süre; henüz bilinmiyorsa null. */\n private sheetDuration(): number | null {\n if (!this.isMultiSheet()) return Infinity;\n return this.options.sheetDuration ?? this.derivedSheetDuration;\n }\n\n private sheetIndexAt(seconds: number): number {\n const d = this.sheetDuration();\n if (d === null || d === Infinity) return 0;\n // floor (ceil DEĞİL): tam sınırda (ör. 60. sn) bir SONRAKİ sheet'in ilk karesi.\n let index = Math.floor(Math.max(0, seconds) / d);\n if (this.options.sheets?.length) index = Math.min(index, this.options.sheets.length - 1);\n return index;\n }\n\n /** 0 tabanlı sheet index'inden URL. */\n private sheetUrl(index: number): string {\n if (this.options.sheets?.length) return this.options.sheets[Math.min(index, this.options.sheets.length - 1)]!;\n const url = this.options.url ?? '';\n const number = index + (this.options.firstSheetIndex ?? 1);\n return url.replace(SHEET_TEMPLATE, (_m, _p, width?: string) => String(number).padStart(width ? Number(width) : 0, '0'));\n }\n\n private gridFrameAt(seconds: number, duration: number): Frame | null {\n const { width, height } = this.options;\n if (!width || !height) return null;\n const interval = this.options.interval || 1;\n\n const sheetDuration = this.sheetDuration();\n if (sheetDuration === null) {\n // Çok parçalı ama süre bilinmiyor — ilk sheet yüklenince hesaplanacak.\n void this.ensureSheet(this.sheetUrl(0));\n return null;\n }\n\n const lastIndex = sheetDuration === Infinity ? 0 : this.sheetIndexAt(Math.max(0, duration - 0.001));\n const index = Math.min(this.sheetIndexAt(seconds), lastIndex);\n const url = this.sheetUrl(index);\n this.preloadAround(index, lastIndex);\n\n const sheet = this.sheets.get(url);\n if (!sheet?.ready) {\n void this.ensureSheet(url);\n return null;\n }\n this.touch(url);\n\n // Her sheet'in KENDİ boyutu (son sheet daha kısa olabilir).\n const columns = Math.max(1, Math.floor(sheet.img.naturalWidth / width));\n const rows = Math.max(1, Math.floor(sheet.img.naturalHeight / height));\n const local = sheetDuration === Infinity ? seconds : seconds - index * sheetDuration;\n const frameIndex = Math.min(Math.max(0, Math.floor(local / interval)), columns * rows - 1);\n return { url, x: (frameIndex % columns) * width, y: Math.floor(frameIndex / columns) * height, w: width, h: height };\n }\n\n private preloadAround(index: number, lastIndex: number): void {\n const n = this.options.preloadSheets ?? 1;\n for (let d = 1; d <= n; d++) {\n if (index + d <= lastIndex) void this.ensureSheet(this.sheetUrl(index + d));\n if (index - d >= 0) void this.ensureSheet(this.sheetUrl(index - d));\n }\n }\n\n private vttFrameAt(seconds: number): Frame | null {\n if (!this.vttCues) {\n void this.loadVtt();\n return null;\n }\n const cues = this.vttCues;\n if (!cues.length) return null;\n // İkili arama — saatlerce süren videolarda binlerce cue olabilir.\n let lo = 0;\n let hi = cues.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n if (cues[mid]!.start <= seconds) lo = mid;\n else hi = mid - 1;\n }\n const cue = cues[lo]!;\n const neighbours = [cues[lo + 1], cues[lo - 1]].filter((c): c is VttCue => !!c && c.url !== cue.url);\n neighbours.forEach((c) => void this.ensureSheet(c.url));\n\n const sheet = this.sheets.get(cue.url);\n if (!sheet?.ready) {\n void this.ensureSheet(cue.url);\n return null;\n }\n this.touch(cue.url);\n const rect = cue.rect ?? { x: 0, y: 0, w: sheet.img.naturalWidth, h: sheet.img.naturalHeight };\n return { url: cue.url, ...rect };\n }\n\n // ── yükleme / cache ──\n\n private ensureSheet(url: string): Promise<void> {\n if (!url) return Promise.resolve();\n const existing = this.sheets.get(url);\n if (existing) return existing.promise;\n\n const img = new Image();\n img.decoding = 'async';\n const sheet: Sheet = { img, ready: false, failed: false, promise: Promise.resolve() };\n sheet.promise = new Promise<void>((resolve) => {\n img.onload = () => {\n // decode() bitmeden gösterme — yeni sheet'e geçerken boş/yanlış kare titremesi olmasın.\n const done = () => {\n if (this.destroyed) return resolve();\n sheet.ready = true;\n this.learnSheetDuration(img);\n if (this.hovering) this.scheduleRender();\n resolve();\n };\n img.decode ? img.decode().then(done, done) : done();\n };\n img.onerror = () => {\n sheet.failed = true;\n resolve();\n };\n });\n img.src = url;\n this.sheets.set(url, sheet);\n this.evict();\n return sheet.promise;\n }\n\n /** Çok parçalı modda `sheetDuration` verilmediyse ilk yüklenen sheet'in ızgara kapasitesinden hesapla. */\n private learnSheetDuration(img: HTMLImageElement): void {\n if (this.derivedSheetDuration !== null || this.options.vtt || !this.isMultiSheet() || this.options.sheetDuration) return;\n const { width, height } = this.options;\n if (!width || !height) return;\n const capacity = Math.max(1, Math.floor(img.naturalWidth / width)) * Math.max(1, Math.floor(img.naturalHeight / height));\n this.derivedSheetDuration = capacity * (this.options.interval || 1);\n }\n\n /** LRU: kullanılan sheet'i sona taşı. */\n private touch(url: string): void {\n const sheet = this.sheets.get(url);\n if (!sheet) return;\n this.sheets.delete(url);\n this.sheets.set(url, sheet);\n }\n\n private evict(): void {\n while (this.sheets.size > MAX_CACHED_SHEETS) {\n const oldest = this.sheets.keys().next().value as string;\n const sheet = this.sheets.get(oldest)!;\n sheet.img.onload = null;\n sheet.img.onerror = null;\n this.sheets.delete(oldest);\n }\n }\n\n private loadVtt(): Promise<void> {\n if (this.vttLoading) return this.vttLoading;\n const vttUrl = this.options.vtt!;\n this.vttLoading = fetch(vttUrl)\n .then((r) => {\n if (!r.ok) throw new Error(`HTTP ${r.status}`);\n return r.text();\n })\n .then((text) => {\n if (this.destroyed) return;\n this.vttCues = parseThumbnailVtt(text, new URL(vttUrl, document.baseURI).href);\n if (this.vttCues.length) void this.ensureSheet(this.vttCues[0]!.url);\n if (this.hovering) this.scheduleRender();\n })\n .catch((err) => {\n console.warn('[HopePlayer sprite-thumbnails] VTT yüklenemedi:', err);\n this.vttCues = [];\n });\n return this.vttLoading;\n }\n}\n\n/** \"01:02:03.500\" / \"02:03.500\" → saniye. */\nfunction parseVttTime(value: string): number {\n const parts = value.trim().split(':').map(Number);\n return parts.reduce((acc, n) => acc * 60 + n, 0);\n}\n\n/** WebVTT thumbnail dosyası → sıralı cue listesi. Görsel yolları VTT dosyasına göre çözümlenir. */\nexport function parseThumbnailVtt(text: string, baseUrl: string): VttCue[] {\n const cues: VttCue[] = [];\n const blocks = text.replace(/\\r/g, '').split(/\\n\\n+/);\n for (const block of blocks) {\n const lines = block.split('\\n').filter(Boolean);\n const timingIndex = lines.findIndex((l) => l.includes('-->'));\n if (timingIndex === -1) continue;\n const [startStr, endStr] = lines[timingIndex]!.split('-->');\n const target = lines[timingIndex + 1]?.trim();\n if (!startStr || !endStr || !target) continue;\n\n const [path, hash] = target.split('#');\n const match = hash?.match(/xywh=(\\d+),(\\d+),(\\d+),(\\d+)/);\n cues.push({\n start: parseVttTime(startStr),\n end: parseVttTime(endStr.trim().split(/\\s+/)[0]!),\n url: new URL(path!, baseUrl).href,\n rect: match ? { x: +match[1]!, y: +match[2]!, w: +match[3]!, h: +match[4]! } : null,\n });\n }\n return cues.sort((a, b) => a.start - b.start);\n}\n","import { SpriteThumbnails, type SpriteThumbnailsPlayerContext } from './SpriteThumbnails';\nimport type { SpriteThumbnailsOptions } from '../../types';\n\nexport function installSpriteThumbnails(ctx: SpriteThumbnailsPlayerContext, options: SpriteThumbnailsOptions): SpriteThumbnails {\n return new SpriteThumbnails(ctx, options);\n}\n\nexport { SpriteThumbnails };\nexport type { SpriteThumbnailsPlayerContext };\n"],"names":["MAX_CACHED_SHEETS","SHEET_TEMPLATE","SpriteThumbnails","ctx","options","__publicField","e","duration","t","sheet","seconds","formatTime","frame","scale","naturalWidth","naturalHeight","barRect","tipWidth","x","responsive","playerWidth","downlink","_a","anyReady","s","d","index","url","number","_m","_p","width","height","interval","sheetDuration","lastIndex","columns","rows","local","frameIndex","n","cues","lo","hi","mid","cue","c","rect","existing","img","resolve","done","capacity","oldest","vttUrl","r","text","parseThumbnailVtt","err","parseVttTime","value","acc","baseUrl","blocks","block","lines","timingIndex","l","startStr","endStr","target","path","hash","match","a","b","installSpriteThumbnails"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  var A = Object.defineProperty;
2
- var P = (h, t, e) => t in h ? A(h, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : h[t] = e;
3
- var r = (h, t, e) => P(h, typeof t != "symbol" ? t + "" : t, e);
4
- import { c as b } from "./player-C886oKP-.js";
5
- const L = {
2
+ var N = (h, t, e) => t in h ? A(h, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : h[t] = e;
3
+ var r = (h, t, e) => N(h, typeof t != "symbol" ? t + "" : t, e);
4
+ import { c as b } from "./player-DW5iWvPs.js";
5
+ const P = {
6
6
  startIndex: 0,
7
7
  loop: !0,
8
8
  autoplayNext: !0,
@@ -10,7 +10,7 @@ const L = {
10
10
  transitionMs: 380,
11
11
  adsOnItemChange: !0
12
12
  };
13
- class N {
13
+ class L {
14
14
  constructor(t, e) {
15
15
  r(this, "options");
16
16
  r(this, "gestureOpts");
@@ -19,6 +19,8 @@ class N {
19
19
  r(this, "index");
20
20
  r(this, "destroyed", !1);
21
21
  r(this, "switching", !1);
22
+ /** Geçiş sürerken gelen buton / klavye isteği — yok sayılmaz, geçiş bitince uygulanır (yalnızca sonuncusu). */
23
+ r(this, "pendingNav", null);
22
24
  r(this, "listOpen", !1);
23
25
  r(this, "userHasStartedPlayback", !1);
24
26
  r(this, "lastAdsIndex", null);
@@ -82,7 +84,7 @@ class N {
82
84
  const e = (s = document.activeElement) == null ? void 0 : s.tagName;
83
85
  e === "INPUT" || e === "TEXTAREA" || this.isInViewport() && (t.key === "ArrowDown" || t.key === "PageDown" || t.key === "j" ? (t.preventDefault(), this.next()) : (t.key === "ArrowUp" || t.key === "PageUp" || t.key === "k") && (t.preventDefault(), this.prev()));
84
86
  });
85
- this.ctx = t, this.rawOptions = e, this.options = { ...L, ...e }, this.gestureOpts = {
87
+ this.ctx = t, this.rawOptions = e, this.options = { ...P, ...e }, this.gestureOpts = {
86
88
  swipe: !0,
87
89
  swipeThreshold: 0.12,
88
90
  wheel: !0,
@@ -100,6 +102,10 @@ class N {
100
102
  }
101
103
  // ── public api ──
102
104
  next(t = !0) {
105
+ if (this.switching) {
106
+ this.pendingNav = { dir: "next", userInitiated: t };
107
+ return;
108
+ }
103
109
  const e = this.index + 1;
104
110
  if (e >= this.items.length) {
105
111
  if (!this.options.loop) return;
@@ -109,6 +115,10 @@ class N {
109
115
  this.goTo(e, "next", t);
110
116
  }
111
117
  prev(t = !0) {
118
+ if (this.switching) {
119
+ this.pendingNav = { dir: "prev", userInitiated: t };
120
+ return;
121
+ }
112
122
  const e = this.index - 1;
113
123
  if (e < 0) {
114
124
  if (!this.options.loop) return;
@@ -128,6 +138,8 @@ class N {
128
138
  } finally {
129
139
  this.switching = !1;
130
140
  }
141
+ const o = this.pendingNav;
142
+ this.pendingNav = null, o && !this.destroyed && (o.dir === "next" ? this.next(o.userInitiated) : this.prev(o.userInitiated));
131
143
  }
132
144
  toggleList(t) {
133
145
  this.listOpen = typeof t == "boolean" ? t : !this.listOpen, this.els.panel.setAttribute("aria-hidden", this.listOpen ? "false" : "true"), this.els.listBtn.setAttribute("aria-expanded", this.listOpen ? "true" : "false"), this.els.panel.style.transform = this.listOpen ? "translateX(0)" : "translateX(100%)";
@@ -157,16 +169,16 @@ class N {
157
169
  f.className = "hp:text-sm";
158
170
  const v = document.createElement("span");
159
171
  v.className = "hp:text-xs hp:opacity-80", m.append(d, f, v);
160
- const x = document.createElement("div");
161
- x.className = "hp:absolute hp:right-2 hp:top-1/2 hp-center-y hp:flex hp:flex-col hp:gap-1 hp:pointer-events-none";
162
172
  const g = document.createElement("div");
163
- g.className = "hp:flex hp:flex-col hp:gap-2 hp:self-end hp:pointer-events-auto hp:mb-16";
173
+ g.className = "hp:absolute hp:right-2 hp:top-1/2 hp-center-y hp:flex hp:flex-col hp:gap-1 hp:pointer-events-none";
174
+ const x = document.createElement("div");
175
+ x.className = "hp:flex hp:flex-col hp:gap-2 hp:self-end hp:pointer-events-auto hp:mb-16";
164
176
  const y = this.navBtn("chevron-left", this.ctx.i18n.storyPrev);
165
177
  y.style.transform = "rotate(90deg)";
166
178
  const w = this.navBtn("chevron-left", this.ctx.i18n.storyNext);
167
- w.style.transform = "rotate(-90deg)", g.append(y, w);
179
+ w.style.transform = "rotate(-90deg)", x.append(y, w);
168
180
  const a = document.createElement("button");
169
- a.type = "button", a.setAttribute("aria-label", this.ctx.i18n.storyAllVideos), a.setAttribute("aria-expanded", "false"), a.className = "hp-story-list-btn hp:absolute hp:flex hp:items-center hp:justify-center hp:w-9 hp:h-9 hp:rounded-full hp:bg-black/40 hp:text-white hp:border-0 hp:cursor-pointer hp:pointer-events-auto", a.setAttribute("part", "story-list-button"), a.appendChild(b("grid", "hp:text-base")), o.append(p, m, x, g, a);
181
+ a.type = "button", a.setAttribute("aria-label", this.ctx.i18n.storyAllVideos), a.setAttribute("aria-expanded", "false"), a.className = "hp-story-list-btn hp:absolute hp:flex hp:items-center hp:justify-center hp:w-9 hp:h-9 hp:rounded-full hp:bg-black/40 hp:text-white hp:border-0 hp:cursor-pointer hp:pointer-events-auto", a.setAttribute("part", "story-list-button"), a.appendChild(b("grid", "hp:text-base")), o.append(p, m, g, x, a);
170
182
  const l = document.createElement("aside");
171
183
  l.className = "hp:absolute hp:inset-y-0 hp:right-0 hp:w-72 hp:max-w-[80%] hp:bg-surface-elev hp:z-30 hp:overflow-y-auto hp:p-3 hp:transition-transform hp:duration-300", l.style.transform = "translateX(100%)", l.setAttribute("aria-hidden", "true");
172
184
  const c = document.createElement("div");
@@ -180,7 +192,7 @@ class N {
180
192
  counter: d,
181
193
  titleEl: f,
182
194
  spotEl: v,
183
- dots: x,
195
+ dots: g,
184
196
  progressBar: u,
185
197
  upBtn: y,
186
198
  downBtn: w,
@@ -313,10 +325,10 @@ class N {
313
325
  }
314
326
  }
315
327
  function M(h, t) {
316
- return new N(h, t);
328
+ return new L(h, t);
317
329
  }
318
330
  export {
319
- N as HopeStory,
331
+ L as HopeStory,
320
332
  M as installStory
321
333
  };
322
- //# sourceMappingURL=story-D5Got6-6.js.map
334
+ //# sourceMappingURL=story-H6f7gSoX.js.map