@mango-iiif/av 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/annotations.d.ts +2 -2
- package/dist/annotations.js +3 -3
- package/dist/chapters.d.ts +2 -2
- package/dist/chapters.js +3 -3
- package/dist/chunk-6JIJRMNE.js +218 -0
- package/dist/chunk-6JIJRMNE.js.map +1 -0
- package/dist/{chunk-3LLEY7MA.js → chunk-AZFOTEAO.js} +2 -2
- package/dist/{chunk-GX7UU6V4.js → chunk-CSE4GIHB.js} +61 -21
- package/dist/chunk-CSE4GIHB.js.map +1 -0
- package/dist/{chunk-ML77YRJL.js → chunk-D7W5UINF.js} +92 -18
- package/dist/chunk-D7W5UINF.js.map +1 -0
- package/dist/{chunk-R4OUWZ3R.js → chunk-EV6YN7WV.js} +22 -8
- package/dist/chunk-EV6YN7WV.js.map +1 -0
- package/dist/{chunk-JXUHKKIX.js → chunk-HM72GHCH.js} +2 -2
- package/dist/{chunk-IFTSCRCU.js → chunk-NH6PEDNF.js} +3 -3
- package/dist/{chunk-PZ6GV6ZJ.js → chunk-RP47ZLOD.js} +6 -6
- package/dist/{chunk-YH6DS7J6.js → chunk-U3H552X2.js} +5 -4
- package/dist/chunk-U3H552X2.js.map +1 -0
- package/dist/{controller-DLy38ais.d.ts → controller-BLA8XNsG.d.ts} +10 -2
- package/dist/{controller-element-BOKM9v2S.d.ts → controller-element-BY0157ve.d.ts} +1 -1
- package/dist/core.d.ts +2 -2
- package/dist/core.js +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +9 -9
- package/dist/media.d.ts +1 -1
- package/dist/media.js +4 -4
- package/dist/player.d.ts +3 -2
- package/dist/player.js +5 -4
- package/dist/player.js.map +1 -1
- package/dist/transcript-element.d.ts +2 -2
- package/dist/transcript-element.js +4 -4
- package/docs/API.md +10 -0
- package/package.json +1 -1
- package/dist/chunk-GX7UU6V4.js.map +0 -1
- package/dist/chunk-ML77YRJL.js.map +0 -1
- package/dist/chunk-NTHMZZYJ.js +0 -38
- package/dist/chunk-NTHMZZYJ.js.map +0 -1
- package/dist/chunk-R4OUWZ3R.js.map +0 -1
- package/dist/chunk-YH6DS7J6.js.map +0 -1
- /package/dist/{chunk-3LLEY7MA.js.map → chunk-AZFOTEAO.js.map} +0 -0
- /package/dist/{chunk-JXUHKKIX.js.map → chunk-HM72GHCH.js.map} +0 -0
- /package/dist/{chunk-IFTSCRCU.js.map → chunk-NH6PEDNF.js.map} +0 -0
- /package/dist/{chunk-PZ6GV6ZJ.js.map → chunk-RP47ZLOD.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/mango-av-media.ts"],"sourcesContent":["import { AVPlayerController } from '../controller';\nimport { loadTranscript } from '../transcript';\nimport { ensureMediaChrome } from './media-chrome';\nimport { playFromInteraction } from './playback';\nimport type {\n AVAnnotation,\n AVCanvas,\n AVManifest,\n AVPlayerConfig,\n AVPlayerEventMap,\n AVStrings,\n Chapter,\n JsonObject,\n MetadataEntry,\n TranscriptCue,\n} from '../types';\nimport { escapeHtml, formatString, formatTime, resolveStrings } from '../utils';\n\nconst HTMLElementBase = (globalThis.HTMLElement ?? class {}) as typeof HTMLElement;\n\nlet hlsElementRegistration: Promise<unknown> | undefined;\nconst ensureHlsElement = (): Promise<unknown> => {\n hlsElementRegistration ??= import('hls-video-element');\n return hlsElementRegistration;\n};\n\nconst eventTypes: Array<keyof AVPlayerEventMap> = [\n 'av-loadstart',\n 'av-ready',\n 'av-error',\n 'av-canvaschange',\n 'av-sourcechange',\n 'av-play',\n 'av-pause',\n 'av-timeupdate',\n 'av-seek',\n 'av-ended',\n 'av-annotationschange',\n 'av-configchange',\n 'av-statechange',\n];\n\nconst styles = `\n :host {\n --mango-av-accent: #5b3fd6;\n --mango-av-accent-contrast: #fff;\n --mango-av-background: #fff;\n --mango-av-surface: #f5f5f8;\n --mango-av-text: #18181b;\n --mango-av-muted: #62626a;\n --mango-av-border: #d7d7de;\n --mango-av-radius: .65rem;\n --mango-av-font: ui-sans-serif, system-ui, sans-serif;\n --mango-av-panel-width: 24rem;\n --mango-av-player-aspect-ratio: 16 / 9;\n --media-primary-color: var(--mango-av-accent-contrast);\n --media-secondary-color: var(--mango-av-accent);\n color: var(--mango-av-text);\n display: block;\n font-family: var(--mango-av-font);\n }\n *, *::before, *::after { box-sizing: border-box; }\n button, input, select { font: inherit; }\n button, select { cursor: pointer; }\n .shell { background: var(--mango-av-background); border: 1px solid var(--mango-av-border); border-radius: var(--mango-av-radius); overflow: clip; }\n .header { padding: 1rem 1.1rem; }\n .header h2 { font-size: 1.15rem; margin: 0; }\n .header p { color: var(--mango-av-muted); margin: .35rem 0 0; }\n .layout { display: grid; grid-template-columns: minmax(0, 1fr) minmax(18rem, var(--mango-av-panel-width)); }\n .player-column { background: #08080a; min-width: 0; position: relative; }\n media-controller { display: block; width: 100%; }\n media-controller:not([audio]) { aspect-ratio: var(--mango-av-player-aspect-ratio); }\n video, hls-video { display: block; height: 100%; object-fit: contain; width: 100%; }\n audio { width: 100%; }\n media-control-bar { width: 100%; }\n .audio-art { align-items: center; aspect-ratio: 16 / 7; background: linear-gradient(135deg, var(--mango-av-accent), #111); color: white; display: flex; justify-content: center; padding: 2rem; text-align: center; }\n .audio-art img { height: 100%; inset: 0; object-fit: contain; position: absolute; width: 100%; }\n .audio-art span { font-size: clamp(1.1rem, 3vw, 2rem); font-weight: 700; }\n .player-toolbar { align-items: center; background: #151518; color: #fff; display: flex; flex-wrap: wrap; gap: .5rem; justify-content: space-between; padding: .55rem .7rem; }\n .player-toolbar button, .player-toolbar select { background: #29292e; border: 1px solid #44444a; border-radius: .35rem; color: white; padding: .4rem .55rem; }\n .player-toolbar .group { align-items: center; display: flex; gap: .45rem; }\n .search-markers { background: #242429; height: .45rem; position: relative; }\n .search-marker { background: #ffe24a; border: 0; border-radius: 50%; height: .7rem; padding: 0; position: absolute; top: 50%; transform: translate(-50%, -50%); width: .7rem; }\n .resume { align-items: center; background: #fff8d7; color: #312900; display: flex; gap: .5rem; justify-content: center; padding: .6rem; }\n .resume button { background: var(--mango-av-accent); border: 0; border-radius: .35rem; color: var(--mango-av-accent-contrast); padding: .35rem .65rem; }\n .panel { border-left: 1px solid var(--mango-av-border); display: flex; flex-direction: column; min-height: 22rem; min-width: 0; }\n .tabs { background: var(--mango-av-surface); display: flex; gap: .1rem; overflow-x: auto; padding: .35rem; }\n .tab { background: transparent; border: 0; border-bottom: 3px solid transparent; color: var(--mango-av-muted); padding: .55rem .6rem; white-space: nowrap; }\n .tab[aria-selected=true] { border-color: var(--mango-av-accent); color: var(--mango-av-text); font-weight: 650; }\n .panel-content { flex: 1; max-height: 34rem; overflow: auto; padding: .85rem; }\n .empty { color: var(--mango-av-muted); font-style: italic; }\n .chapter-list, .annotation-list, .cue-list, .file-list { list-style: none; margin: 0; padding: 0; }\n .chapter-list .chapter-list { border-left: 1px solid var(--mango-av-border); margin-left: .8rem; padding-left: .55rem; }\n .chapter button, .annotation button, .cue button { background: transparent; border: 0; border-radius: .35rem; color: inherit; display: grid; gap: .15rem; padding: .5rem; text-align: left; width: 100%; }\n .chapter button:hover, .annotation button:hover, .cue button:hover { background: var(--mango-av-surface); }\n .chapter button.active, .annotation button.active, .cue button.active { background: color-mix(in srgb, var(--mango-av-accent) 14%, transparent); box-shadow: inset 3px 0 var(--mango-av-accent); }\n .time { color: var(--mango-av-muted); font-size: .78rem; }\n .panel-tools { display: flex; flex-wrap: wrap; gap: .45rem; margin-bottom: .75rem; }\n .panel-tools input, .panel-tools select { border: 1px solid var(--mango-av-border); border-radius: .35rem; min-width: 0; padding: .45rem; }\n .panel-tools input { flex: 1; }\n .panel-tools a { align-content: center; color: var(--mango-av-accent); }\n .cue mark { background: #ffe770; }\n .speaker { font-weight: 700; }\n .tags { display: flex; flex-wrap: wrap; gap: .25rem; }\n .tag { background: var(--mango-av-surface); border-radius: 999px; font-size: .75rem; padding: .15rem .45rem; }\n dl { margin: 0; }\n dt { font-weight: 700; margin-top: .75rem; }\n dd { color: var(--mango-av-muted); margin: .2rem 0 0; }\n .file-list li { border-bottom: 1px solid var(--mango-av-border); padding: .55rem 0; }\n a { color: var(--mango-av-accent); }\n .error { background: #fff0f0; color: #8a1717; padding: 1rem; }\n .sr-only { clip: rect(0,0,0,0); clip-path: inset(50%); height: 1px; overflow: hidden; position: absolute; white-space: nowrap; width: 1px; }\n @media (max-width: 760px) {\n .layout { grid-template-columns: 1fr; }\n .panel { border-left: 0; border-top: 1px solid var(--mango-av-border); }\n }\n`;\n\nconst metadataHtml = (entries: MetadataEntry[], ui: AVStrings): string => {\n if (entries.length === 0) return `<p class=\"empty\">${escapeHtml(ui.noMetadata)}</p>`;\n return `<dl>${entries.map((entry) => `\n <dt>${escapeHtml(entry.label)}</dt>\n <dd>${entry.values.map((value) => escapeHtml(value.value)).join('<br>')}</dd>\n `).join('')}</dl>`;\n};\n\nconst chapterHtml = (chapters: Chapter[], canvasId: string, ui: AVStrings, level = 1): string => {\n if (chapters.length === 0 && level === 1) return `<p class=\"empty\">${escapeHtml(ui.noChapters)}</p>`;\n return `<ul class=\"chapter-list\">${chapters.map((chapter) => {\n const active = chapter.canvasId === canvasId;\n const target = chapter.canvasId ? `data-canvas=\"${escapeHtml(chapter.canvasId)}\"` : '';\n const time = chapter.time ? `data-time=\"${chapter.time.start}\"` : '';\n return `<li class=\"chapter\">\n <button type=\"button\" class=\"${active ? 'active' : ''}\" ${target} ${time} ${chapter.canvasId ? '' : 'disabled'}>\n <span>${escapeHtml(chapter.label)}</span>\n ${chapter.time ? `<span class=\"time\">${formatTime(chapter.time.start)}</span>` : ''}\n </button>\n ${chapterHtml(chapter.children, canvasId, ui, level + 1)}\n </li>`;\n }).join('')}</ul>`;\n};\n\nconst highlight = (text: string, query: string): string => {\n const escaped = escapeHtml(text);\n if (!query) return escaped;\n const safeQuery = query.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n return escaped.replace(new RegExp(`(${safeQuery})`, 'gi'), '<mark>$1</mark>');\n};\n\nexport class MangoAVMediaElement extends HTMLElementBase {\n static observedAttributes = ['manifest-url', 'config'];\n\n readonly player: AVPlayerController;\n #root: ShadowRoot;\n #inputManifest: JsonObject | string | undefined;\n #config: AVPlayerConfig = {};\n #activePanel: NonNullable<AVPlayerConfig['activePanel']> = 'chapters';\n #transcriptCues: TranscriptCue[] = [];\n #transcriptIndex = 0;\n #transcriptQuery = '';\n #resumeTime: number | undefined;\n #loadingToken = 0;\n #resolvedSourceUrl: string | undefined;\n #sourceToken = 0;\n\n constructor() {\n super();\n this.#root = this.attachShadow({ mode: 'open' });\n this.player = new AVPlayerController();\n for (const type of eventTypes) {\n this.player.addEventListener(type, ((event: CustomEvent) => {\n if (type === 'av-ready') {\n if (this.player.source?.isHls) void ensureHlsElement();\n this.#resolvedSourceUrl = undefined;\n this.#resumeTime = this.player.getSavedPosition();\n this.#activePanel = this.player.config.activePanel;\n this.#render();\n void this.#resolveSource();\n void this.#loadActiveTranscript();\n } else if (type === 'av-canvaschange' || type === 'av-sourcechange') {\n if (this.player.source?.isHls) void ensureHlsElement();\n this.#resolvedSourceUrl = undefined;\n this.#transcriptCues = [];\n this.#transcriptIndex = 0;\n this.#render();\n void this.#resolveSource();\n void this.#loadActiveTranscript();\n } else if (type === 'av-configchange') {\n this.#activePanel = this.player.config.activePanel;\n void ensureMediaChrome(this.player.config.preferredLanguages[0]).then(() => this.#render());\n } else if (type === 'av-error') {\n this.#render();\n } else if (type === 'av-annotationschange') {\n if (this.#activePanel === 'annotations') this.#renderPanelOnly();\n } else if (type === 'av-timeupdate') {\n this.#syncTimedContent();\n }\n this.dispatchEvent(new CustomEvent(type, {\n detail: event.detail,\n bubbles: true,\n composed: true,\n }));\n }) as EventListener);\n }\n }\n\n get manifest(): JsonObject | string | undefined {\n return this.#inputManifest;\n }\n\n get controller(): AVPlayerController {\n return this.player;\n }\n\n set manifest(value: JsonObject | string | undefined) {\n this.#inputManifest = value;\n if (this.isConnected && value !== undefined) void this.load(value);\n }\n\n get config(): AVPlayerConfig {\n return this.#config;\n }\n\n set config(value: AVPlayerConfig) {\n this.#config = value;\n this.player.configure(value);\n this.#activePanel = value.activePanel ?? this.player.config.activePanel;\n if (this.isConnected) this.#render();\n }\n\n connectedCallback(): void {\n this.#readConfigAttribute();\n void ensureMediaChrome(this.player.config.preferredLanguages[0]);\n this.#render();\n const source = this.#inputManifest ?? this.getAttribute('manifest-url') ?? undefined;\n if (source !== undefined) void this.load(source);\n }\n\n disconnectedCallback(): void {\n this.player.destroy();\n }\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n if (!this.isConnected || oldValue === newValue) return;\n if (name === 'manifest-url' && newValue) {\n this.#inputManifest = newValue;\n void this.load(newValue);\n }\n if (name === 'config') {\n this.#readConfigAttribute();\n this.#render();\n }\n }\n\n async load(input: JsonObject | string): Promise<AVManifest> {\n this.#inputManifest = input;\n return await this.player.load(input);\n }\n\n play(): Promise<void> {\n return this.player.play();\n }\n\n pause(): void {\n this.player.pause();\n }\n\n seekTo(time: number): void {\n this.player.seekTo(time);\n }\n\n selectCanvas(indexOrId: number | string, options?: { time?: number; autoplay?: boolean }): AVCanvas | undefined {\n return this.player.selectCanvas(indexOrId, options);\n }\n\n #readConfigAttribute(): void {\n const attribute = this.getAttribute('config');\n if (!attribute) return;\n try {\n this.#config = JSON.parse(attribute) as AVPlayerConfig;\n this.player.configure(this.#config);\n } catch (cause) {\n const error = cause instanceof Error ? cause : new Error(String(cause));\n this.dispatchEvent(new CustomEvent('av-error', { detail: { error }, bubbles: true, composed: true }));\n }\n }\n\n #render(): void {\n const state = this.player.state;\n const manifest = state.manifest;\n const canvas = this.player.canvas;\n const source = this.player.source;\n const ui = resolveStrings(this.player.config.strings);\n this.#root.innerHTML = `<style>${styles}</style><div class=\"shell\">\n <slot name=\"header\">\n ${manifest ? `<header class=\"header\"><h2>${escapeHtml(manifest.label)}</h2>${manifest.summary ? `<p>${escapeHtml(manifest.summary)}</p>` : ''}</header>` : ''}\n </slot>\n ${state.status === 'error' ? `<div class=\"error\" role=\"alert\">${escapeHtml(state.error?.message ?? ui.unableToLoadPlayer)}</div>` : ''}\n ${state.status === 'loading' ? `<p class=\"header\" role=\"status\">${escapeHtml(ui.loadingManifest)}</p>` : ''}\n ${manifest && canvas ? this.#renderReady(manifest, canvas, source?.kind ?? 'video') : ''}\n </div>`;\n this.#bindInteractions();\n const media = this.#root.querySelector('video, audio, hls-video') as HTMLMediaElement | null;\n if (media) this.player.attachMedia(media);\n }\n\n #renderReady(manifest: AVManifest, canvas: AVCanvas, kind: 'audio' | 'video'): string {\n const source = this.player.source;\n const panels = this.player.config.panels;\n const controls = this.player.config.controls;\n const ui = resolveStrings(this.player.config.strings);\n const panelTabs = [\n panels.chapters ? ['chapters', ui.chapters] : undefined,\n panels.transcript ? ['transcript', ui.transcript] : undefined,\n panels.annotations ? ['annotations', ui.annotations] : undefined,\n panels.metadata ? ['metadata', ui.metadata] : undefined,\n panels.supplementalFiles ? ['files', ui.files] : undefined,\n ].filter((value): value is [string, string] => Boolean(value));\n const showPanel = this.#activePanel !== 'none' && panelTabs.length > 0;\n return `\n ${this.#resumeTime !== undefined ? `<div class=\"resume\">${escapeHtml(formatString(ui.resumePrompt, { time: formatTime(this.#resumeTime) }))} <button type=\"button\" data-action=\"resume\">${escapeHtml(ui.resume)}</button><button type=\"button\" data-action=\"dismiss-resume\">${escapeHtml(ui.startOver)}</button></div>` : ''}\n <div class=\"layout\" ${showPanel ? '' : 'style=\"grid-template-columns: 1fr\"'}>\n <section class=\"player-column\" aria-label=\"${escapeHtml(ui.mediaPlayer)}\">\n <slot name=\"before-player\"></slot>\n <media-controller ${kind === 'audio' ? 'audio' : ''} ${this.#mediaChromeLanguage()}>\n ${kind === 'audio' ? `<div class=\"audio-art\"><span>${escapeHtml(canvas.label)}</span></div>` : ''}\n ${source ? this.#mediaHtml(canvas, source.kind) : `<div class=\"audio-art\"><span>${escapeHtml(ui.noPlayableMedia)}</span></div>`}\n <slot name=\"player-overlay\"></slot>\n <slot name=\"controls\">\n <media-control-bar>\n <media-play-button></media-play-button>\n ${controls.seek ? `<media-seek-backward-button seekoffset=\"${controls.skipSeconds ?? 10}\"></media-seek-backward-button><media-seek-forward-button seekoffset=\"${controls.skipSeconds ?? 10}\"></media-seek-forward-button>` : ''}\n <media-time-display showduration></media-time-display>\n ${controls.seek ? '<media-time-range></media-time-range>' : ''}\n ${controls.volume ? '<media-mute-button></media-mute-button><media-volume-range></media-volume-range>' : ''}\n ${controls.captions && canvas.tracks.length > 0 ? '<media-captions-menu-button></media-captions-menu-button>' : ''}\n ${controls.playbackRate ? '<media-playback-rate-menu-button></media-playback-rate-menu-button>' : ''}\n ${controls.pictureInPicture && kind === 'video' ? '<media-pip-button></media-pip-button>' : ''}\n ${controls.fullscreen && kind === 'video' ? '<media-fullscreen-button></media-fullscreen-button>' : ''}\n </media-control-bar>\n ${controls.captions && canvas.tracks.length > 0 ? '<media-captions-menu hidden></media-captions-menu>' : ''}\n ${controls.playbackRate ? `<media-playback-rate-menu rates=\"${this.player.config.playbackRates.join(' ')}\" hidden></media-playback-rate-menu>` : ''}\n </slot>\n </media-controller>\n ${this.#searchMarkersHtml()}\n <div class=\"player-toolbar\">\n <div class=\"group\">\n <button type=\"button\" data-action=\"previous\" ${canvas.index === 0 ? 'disabled' : ''} aria-label=\"${escapeHtml(ui.previousSection)}\">← ${escapeHtml(ui.previous)}</button>\n <button type=\"button\" data-action=\"next\" ${canvas.index === manifest.canvases.length - 1 && !this.player.state.repeat ? 'disabled' : ''} aria-label=\"${escapeHtml(ui.nextSection)}\">${escapeHtml(ui.next)} →</button>\n </div>\n <div class=\"group\">\n ${controls.sourceSelector && canvas.sources.length > 1 ? `<label><span class=\"sr-only\">${escapeHtml(ui.mediaSource)}</span><select data-action=\"source\">${canvas.sources.map((item, index) => `<option value=\"${index}\" ${index === this.player.state.sourceIndex ? 'selected' : ''}>${escapeHtml(item.label ?? item.format ?? formatString(ui.sourceNumber, { number: index + 1 }))}</option>`).join('')}</select></label>` : ''}\n ${controls.download && canvas.rendering.length > 0 ? `<label><span class=\"sr-only\">${escapeHtml(ui.downloadMediaFile)}</span><select data-action=\"download\"><option value=\"\">${escapeHtml(ui.download)}…</option>${canvas.rendering.map((file) => `<option value=\"${escapeHtml(file.id)}\" data-filename=\"${escapeHtml(file.filename ?? '')}\">${escapeHtml(file.label)}</option>`).join('')}</select></label>` : ''}\n <label><input type=\"checkbox\" data-action=\"auto-advance\" ${this.player.state.autoAdvance ? 'checked' : ''}> ${escapeHtml(ui.autoAdvance)}</label>\n </div>\n </div>\n <slot name=\"after-player\"></slot>\n </section>\n ${showPanel ? `<aside class=\"panel\">\n <nav class=\"tabs\" role=\"tablist\" aria-label=\"${escapeHtml(ui.mediaInformation)}\">${panelTabs.map(([id, tabLabel]) => `<button class=\"tab\" type=\"button\" role=\"tab\" data-panel=\"${id}\" aria-selected=\"${this.#activePanel === id}\">${escapeHtml(tabLabel)}</button>`).join('')}</nav>\n <div class=\"panel-content\" role=\"tabpanel\">${this.#panelHtml(manifest, canvas)}</div>\n </aside>` : ''}\n </div>`;\n }\n\n #mediaHtml(canvas: AVCanvas, kind: 'audio' | 'video'): string {\n const source = this.player.source;\n if (!source) return '';\n const tag = source.isHls ? 'hls-video' : kind;\n const sourceUrl = this.#resolvedSourceUrl ?? (this.player.config.resolveRequest ? '' : source.src);\n const attributes = [\n 'slot=\"media\"',\n sourceUrl ? `src=\"${escapeHtml(sourceUrl)}\"` : '',\n `preload=\"${this.player.config.preload}\"`,\n this.player.config.crossorigin ? `crossorigin=\"${this.player.config.crossorigin}\"` : '',\n kind === 'video' && canvas.poster ? `poster=\"${escapeHtml(canvas.poster)}\"` : '',\n `aria-label=\"${escapeHtml(canvas.label)}\"`,\n `data-canvasindex=\"${canvas.index}\"`,\n ].filter(Boolean).join(' ');\n const tracks = canvas.tracks.map((track) => `<track src=\"${escapeHtml(track.src)}\" kind=\"${track.kind}\" label=\"${escapeHtml(track.label)}\" ${track.language ? `srclang=\"${escapeHtml(track.language)}\"` : ''} ${track.default ? 'default' : ''}>`).join('');\n return `<${tag} ${attributes}>${tracks}</${tag}>`;\n }\n\n #mediaChromeLanguage(): string {\n const language = this.player.config.preferredLanguages.find((value) => value !== 'none');\n return language ? `lang=\"${escapeHtml(language)}\"` : '';\n }\n\n #panelHtml(manifest: AVManifest, canvas: AVCanvas): string {\n const ui = resolveStrings(this.player.config.strings);\n switch (this.#activePanel) {\n case 'chapters':\n return chapterHtml(manifest.chapters, canvas.id, ui);\n case 'transcript':\n return this.#transcriptHtml(canvas);\n case 'annotations':\n return this.#annotationsHtml(canvas.annotations);\n case 'metadata':\n return `<h3>${escapeHtml(canvas.label)}</h3>${metadataHtml([...manifest.metadata, ...canvas.metadata], ui)}${manifest.requiredStatement ? metadataHtml([manifest.requiredStatement], ui) : ''}${manifest.rights ? `<p><strong>${escapeHtml(ui.rights)}:</strong> <a href=\"${escapeHtml(manifest.rights)}\" target=\"_blank\" rel=\"noreferrer\">${escapeHtml(manifest.rights)}</a></p>` : ''}`;\n case 'files': {\n const files = [...manifest.rendering, ...canvas.rendering];\n return files.length > 0 ? `<ul class=\"file-list\">${files.map((file) => `<li><a href=\"${escapeHtml(file.id)}\" download=\"${escapeHtml(file.filename ?? '')}\">${escapeHtml(file.label)}</a>${file.format ? `<div class=\"time\">${escapeHtml(file.format)}</div>` : ''}</li>`).join('')}</ul>` : `<p class=\"empty\">${escapeHtml(ui.noSupplementalFiles)}</p>`;\n }\n default:\n return '';\n }\n }\n\n #transcriptHtml(canvas: AVCanvas): string {\n const ui = resolveStrings(this.player.config.strings);\n if (canvas.transcripts.length === 0) return `<p class=\"empty\">${escapeHtml(ui.noTranscript)}</p>`;\n const resource = canvas.transcripts[this.#transcriptIndex];\n const query = this.#transcriptQuery.trim();\n const visible = query\n ? this.#transcriptCues.filter((cue) => cue.text.toLowerCase().includes(query.toLowerCase()))\n : this.#transcriptCues;\n return `<div class=\"panel-tools\">\n ${canvas.transcripts.length > 1 ? `<select data-action=\"transcript\" aria-label=\"${escapeHtml(ui.transcript)}\">${canvas.transcripts.map((item, index) => `<option value=\"${index}\" ${index === this.#transcriptIndex ? 'selected' : ''}>${escapeHtml(item.label)}</option>`).join('')}</select>` : ''}\n ${this.player.config.transcript.search ? `<input type=\"search\" data-action=\"transcript-search\" value=\"${escapeHtml(this.#transcriptQuery)}\" placeholder=\"${escapeHtml(ui.searchTranscript)}\" aria-label=\"${escapeHtml(ui.searchTranscript)}\">` : ''}\n ${this.player.config.transcript.download && resource?.src ? `<a href=\"${escapeHtml(resource.src)}\" download>${escapeHtml(ui.download)}</a>` : ''}\n </div>\n ${this.#transcriptCues.length === 0 ? `<p class=\"empty\">${escapeHtml(ui.loadingTranscript)}</p>` : `<ol class=\"cue-list\">${visible.map((cue) => `<li class=\"cue\" data-cue-id=\"${escapeHtml(cue.id)}\" ${cue.start !== undefined ? `data-start=\"${cue.start}\" data-end=\"${cue.end ?? cue.start}\"` : ''}><button type=\"button\" ${cue.start === undefined ? 'disabled' : ''}>${cue.start !== undefined ? `<span class=\"time\">${formatTime(cue.start)}</span>` : ''}${cue.speaker ? `<span class=\"speaker\">${escapeHtml(cue.speaker)}</span>` : ''}<span>${highlight(cue.text, query)}</span></button></li>`).join('')}</ol>`}`;\n }\n\n #annotationsHtml(annotations: AVAnnotation[]): string {\n const ui = resolveStrings(this.player.config.strings);\n if (annotations.length === 0) return `<p class=\"empty\">${escapeHtml(ui.noAnnotations)}</p>`;\n return `<ol class=\"annotation-list\">${annotations.map((annotation) => `<li class=\"annotation\" data-start=\"${annotation.time?.start ?? ''}\" data-end=\"${annotation.time?.end ?? annotation.time?.start ?? ''}\"><button type=\"button\" ${annotation.time ? '' : 'disabled'}>${annotation.time ? `<span class=\"time\">${formatTime(annotation.time.start)}</span>` : ''}<span>${escapeHtml(annotation.text)}</span>${annotation.tags.length > 0 ? `<span class=\"tags\">${annotation.tags.map((tag) => `<span class=\"tag\">${escapeHtml(tag)}</span>`).join('')}</span>` : ''}</button></li>`).join('')}</ol>`;\n }\n\n #searchMarkersHtml(): string {\n const ui = resolveStrings(this.player.config.strings);\n const query = this.#transcriptQuery.trim().toLowerCase();\n const duration = this.player.state.duration || this.player.canvas?.duration || 0;\n if (!query || !this.player.config.transcript.showSearchMarkers || duration <= 0) return '';\n const matches = this.#transcriptCues.filter((cue) => cue.start !== undefined && cue.text.toLowerCase().includes(query));\n if (matches.length === 0) return '';\n return `<div class=\"search-markers\" aria-label=\"${escapeHtml(ui.transcriptSearchMatches)}\">${matches.map((cue) => `<button type=\"button\" class=\"search-marker\" data-search-time=\"${cue.start}\" style=\"left:${Math.min(100, Math.max(0, ((cue.start ?? 0) / duration) * 100))}%\" aria-label=\"${escapeHtml(formatString(ui.searchMatchAt, { time: formatTime(cue.start ?? 0) }))}\"></button>`).join('')}</div>`;\n }\n\n #bindInteractions(): void {\n this.#root.querySelectorAll<HTMLElement>('[data-panel]').forEach((button) => button.addEventListener('click', () => {\n this.#activePanel = button.dataset.panel as NonNullable<AVPlayerConfig['activePanel']>;\n this.#renderPanelOnly();\n if (this.#activePanel === 'transcript') void this.#loadActiveTranscript();\n }));\n this.#root.querySelector<HTMLElement>('[data-action=previous]')?.addEventListener('click', () => this.player.previous({ autoplay: this.player.state.status === 'playing' }));\n this.#root.querySelector<HTMLElement>('[data-action=next]')?.addEventListener('click', () => this.player.next({ autoplay: this.player.state.status === 'playing' }));\n this.#root.querySelector<HTMLSelectElement>('[data-action=source]')?.addEventListener('change', (event) => this.player.selectSource(Number((event.target as HTMLSelectElement).value)));\n this.#root.querySelector<HTMLSelectElement>('[data-action=download]')?.addEventListener('change', (event) => {\n const select = event.target as HTMLSelectElement;\n if (!select.value) return;\n const anchor = document.createElement('a');\n anchor.href = select.value;\n anchor.download = select.selectedOptions[0]?.dataset.filename ?? '';\n anchor.click();\n select.value = '';\n });\n this.#root.querySelector<HTMLInputElement>('[data-action=auto-advance]')?.addEventListener('change', (event) => this.player.setAutoAdvance((event.target as HTMLInputElement).checked));\n this.#root.querySelector<HTMLElement>('[data-action=resume]')?.addEventListener('click', () => {\n if (this.#resumeTime !== undefined) this.player.seekTo(this.#resumeTime);\n this.#resumeTime = undefined;\n this.#render();\n });\n this.#root.querySelector<HTMLElement>('[data-action=dismiss-resume]')?.addEventListener('click', () => {\n this.#resumeTime = undefined;\n this.#render();\n });\n this.#bindPanelInteractions();\n }\n\n #bindPanelInteractions(): void {\n this.#root.querySelectorAll<HTMLElement>('[data-canvas]').forEach((button) => button.addEventListener('click', () => {\n const canvasId = button.dataset.canvas;\n if (canvasId) this.player.selectCanvas(canvasId, { time: Number(button.dataset.time ?? 0), autoplay: true });\n }));\n this.#root.querySelector<HTMLSelectElement>('[data-action=transcript]')?.addEventListener('change', (event) => {\n this.#transcriptIndex = Number((event.target as HTMLSelectElement).value);\n this.#transcriptCues = [];\n this.#renderPanelOnly();\n void this.#loadActiveTranscript();\n });\n this.#root.querySelector<HTMLInputElement>('[data-action=transcript-search]')?.addEventListener('input', (event) => {\n this.#transcriptQuery = (event.target as HTMLInputElement).value;\n const selection = (event.target as HTMLInputElement).selectionStart;\n this.#renderPanelOnly();\n const input = this.#root.querySelector<HTMLInputElement>('[data-action=transcript-search]');\n input?.focus();\n if (selection !== null) input?.setSelectionRange(selection, selection);\n });\n this.#root.querySelectorAll<HTMLElement>('.cue[data-start] button, .annotation[data-start] button').forEach((button) => button.addEventListener('click', () => {\n const row = button.parentElement;\n const start = Number(row?.dataset.start);\n if (Number.isFinite(start)) {\n this.player.seekTo(start);\n playFromInteraction(this.player, this);\n }\n }));\n this.#root.querySelectorAll<HTMLElement>('[data-search-time]').forEach((button) => button.addEventListener('click', () => {\n const time = Number(button.dataset.searchTime);\n if (Number.isFinite(time)) this.player.seekTo(time);\n }));\n }\n\n #renderPanelOnly(): void {\n const manifest = this.player.manifest;\n const canvas = this.player.canvas;\n if (!manifest || !canvas) return;\n this.#root.querySelectorAll<HTMLElement>('[data-panel]').forEach((tab) => {\n tab.setAttribute('aria-selected', String(tab.dataset.panel === this.#activePanel));\n });\n const content = this.#root.querySelector<HTMLElement>('.panel-content');\n if (content) content.innerHTML = this.#panelHtml(manifest, canvas);\n this.#root.querySelector('.search-markers')?.remove();\n const toolbar = this.#root.querySelector('.player-toolbar');\n const markers = this.#searchMarkersHtml();\n if (toolbar && markers) toolbar.insertAdjacentHTML('beforebegin', markers);\n this.#bindPanelInteractions();\n }\n\n async #loadActiveTranscript(): Promise<void> {\n const resource = this.player.canvas?.transcripts[this.#transcriptIndex];\n if (!resource) return;\n const token = ++this.#loadingToken;\n try {\n const transcriptOptions: Parameters<typeof loadTranscript>[1] = {};\n if (this.player.config.fetch) transcriptOptions.fetch = this.player.config.fetch;\n if (this.player.config.requestInit) transcriptOptions.requestInit = this.player.config.requestInit;\n if (this.player.config.transcript.showNotes !== undefined) transcriptOptions.showNotes = this.player.config.transcript.showNotes;\n if (this.player.config.transcript.showMetadata !== undefined) transcriptOptions.showMetadata = this.player.config.transcript.showMetadata;\n const cues = await loadTranscript(resource, transcriptOptions);\n if (token !== this.#loadingToken) return;\n this.#transcriptCues = cues;\n if (this.#activePanel === 'transcript') this.#renderPanelOnly();\n } catch (cause) {\n if (token !== this.#loadingToken) return;\n const error = cause instanceof Error ? cause : new Error(String(cause));\n this.dispatchEvent(new CustomEvent('av-error', { detail: { error }, bubbles: true, composed: true }));\n this.#transcriptCues = [];\n if (this.#activePanel === 'transcript') this.#renderPanelOnly();\n }\n }\n\n async #resolveSource(): Promise<void> {\n if (!this.player.config.resolveRequest) return;\n const token = ++this.#sourceToken;\n try {\n const sourceUrl = await this.player.resolvedSourceUrl();\n if (token !== this.#sourceToken || !sourceUrl) return;\n this.#resolvedSourceUrl = sourceUrl;\n const media = this.#root.querySelector('video, audio, hls-video') as HTMLMediaElement | null;\n if (media) media.setAttribute('src', sourceUrl);\n } catch (cause) {\n const error = cause instanceof Error ? cause : new Error(String(cause));\n this.dispatchEvent(new CustomEvent('av-error', { detail: { error }, bubbles: true, composed: true }));\n }\n }\n\n #syncTimedContent(): void {\n const time = this.player.state.currentTime;\n const rows = this.#root.querySelectorAll<HTMLElement>('[data-start][data-end]');\n let active: HTMLElement | undefined;\n rows.forEach((row) => {\n const start = Number(row.dataset.start);\n const end = Number(row.dataset.end);\n const isActive = Number.isFinite(start) && time >= start && (!Number.isFinite(end) || time < end);\n row.querySelector('button')?.classList.toggle('active', isActive);\n if (isActive) active = row;\n });\n if (active && this.player.config.transcript.autoScroll) {\n active.scrollIntoView({ block: 'nearest', behavior: 'smooth' });\n }\n }\n}\n\nexport const defineMangoAVMedia = (tagName = 'mango-av-media'): typeof MangoAVMediaElement => {\n if (typeof customElements === 'undefined') return MangoAVMediaElement;\n if (!customElements.get(tagName)) customElements.define(tagName, MangoAVMediaElement);\n return MangoAVMediaElement;\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/mango-av-player.ts"],"sourcesContent":["import { AVControllerElement } from './controller-element';\nimport { componentTheme } from './component-styles';\nimport { ensureMediaChrome } from './media-chrome';\nimport type { AVCanvas, AVManifest, AVPlayerConfig, AVPlayerEventMap, JsonObject, MediaSource } from '../types';\nimport { escapeHtml, formatString, resolveStrings } from '../utils';\n\nlet hlsElementRegistration: Promise<unknown> | undefined;\nconst ensureHlsElement = (): Promise<unknown> => {\n hlsElementRegistration ??= import('hls-video-element');\n return hlsElementRegistration;\n};\n\nconst styles = `${componentTheme}\n :host { --mango-av-player-aspect-ratio: 16 / 9; }\n .player { background: #08080a; border-radius: var(--mango-av-radius); color: white; overflow: clip; position: relative; }\n media-controller { display: block; width: 100%; }\n media-controller:not([audio]) { aspect-ratio: var(--mango-av-player-aspect-ratio); }\n video, hls-video { display: block; height: 100%; object-fit: contain; width: 100%; }\n audio { width: 100%; }\n media-control-bar { width: 100%; }\n .audio-art { align-items: center; aspect-ratio: 16 / 7; background: linear-gradient(135deg, var(--mango-av-accent), #111); display: flex; justify-content: center; padding: 2rem; text-align: center; }\n .audio-art span { font-size: clamp(1.1rem, 3vw, 2rem); font-weight: 700; }\n .toolbar { align-items: center; background: #151518; display: flex; flex-wrap: wrap; gap: .5rem; justify-content: space-between; padding: .55rem .7rem; }\n .toolbar button, .toolbar select { background: #29292e; border: 1px solid #44444a; border-radius: .35rem; color: white; padding: .4rem .55rem; }\n .group { align-items: center; display: flex; gap: .45rem; }\n .error { background: #fff0f0; color: #8a1717; padding: 1rem; }\n .sr-only { clip: rect(0,0,0,0); clip-path: inset(50%); height: 1px; overflow: hidden; position: absolute; white-space: nowrap; width: 1px; }\n`;\n\nexport class MangoAVPlayerElement extends AVControllerElement {\n static observedAttributes = ['manifest-url', 'config'];\n\n #root: ShadowRoot;\n #manifestInput: JsonObject | string | undefined;\n #config: AVPlayerConfig = {};\n #resolvedSourceUrl: string | undefined;\n #sourceToken = 0;\n\n constructor() {\n super();\n this.#root = this.attachShadow({ mode: 'open' });\n }\n\n get manifest(): JsonObject | string | undefined {\n return this.#manifestInput;\n }\n\n set manifest(value: JsonObject | string | undefined) {\n this.#manifestInput = value;\n if (this.isConnected && value !== undefined) void this.load(value);\n }\n\n get config(): AVPlayerConfig {\n return this.#config;\n }\n\n set config(value: AVPlayerConfig) {\n this.#config = value;\n this.controller.configure(value);\n this.#render();\n }\n\n override connectedCallback(): void {\n this.#readConfigAttribute();\n void ensureMediaChrome(this.controller.config.preferredLanguages[0]);\n super.connectedCallback();\n const source = this.#manifestInput ?? this.getAttribute('manifest-url') ?? undefined;\n if (source !== undefined && !this.controller.manifest) void this.load(source);\n }\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n if (!this.isConnected || oldValue === newValue) return;\n if (name === 'manifest-url' && newValue) {\n this.#manifestInput = newValue;\n void this.load(newValue);\n } else if (name === 'config') {\n this.#readConfigAttribute();\n this.#render();\n }\n }\n\n async load(input: JsonObject | string): Promise<AVManifest> {\n this.#manifestInput = input;\n return await this.controller.load(input);\n }\n\n play(): Promise<void> { return this.controller.play(); }\n pause(): void { this.controller.pause(); }\n seekTo(time: number): void { this.controller.seekTo(time); }\n selectCanvas(indexOrId: number | string, options?: { time?: number; autoplay?: boolean }): AVCanvas | undefined {\n return this.controller.selectCanvas(indexOrId, options);\n }\n\n protected controllerChanged(): void {\n this.#render();\n }\n\n protected handleControllerEvent<K extends keyof AVPlayerEventMap>(type: K, event: CustomEvent<AVPlayerEventMap[K]>): void {\n if (type === 'av-configchange') {\n this.#resolvedSourceUrl = undefined;\n void ensureMediaChrome(this.controller.config.preferredLanguages[0]).then(() => {\n this.#render();\n void this.#resolveSource();\n });\n } else if (type === 'av-ready' || type === 'av-canvaschange' || type === 'av-sourcechange' || type === 'av-error') {\n this.#resolvedSourceUrl = undefined;\n if (this.controller.source?.isHls) void ensureHlsElement();\n this.#render();\n void this.#resolveSource();\n }\n this.dispatchEvent(new CustomEvent(type, { detail: event.detail, bubbles: true, composed: true }));\n }\n\n #readConfigAttribute(): void {\n const value = this.getAttribute('config');\n if (!value) return;\n try {\n this.#config = JSON.parse(value) as AVPlayerConfig;\n this.controller.configure(this.#config);\n } catch (cause) {\n const error = cause instanceof Error ? cause : new Error(String(cause));\n this.dispatchEvent(new CustomEvent('av-error', { detail: { error }, bubbles: true, composed: true }));\n }\n }\n\n #render(): void {\n const state = this.controller.state;\n const canvas = this.controller.canvas;\n const source = this.controller.source;\n const ui = resolveStrings(this.controller.config.strings);\n this.#root.innerHTML = `<style>${styles}</style>\n <div class=\"player\">\n ${state.status === 'loading' ? `<p role=\"status\">${escapeHtml(ui.loadingManifest)}</p>` : ''}\n ${state.status === 'error' ? `<div class=\"error\" role=\"alert\">${escapeHtml(state.error?.message ?? ui.unableToLoadMedia)}</div>` : ''}\n ${canvas && source ? this.#readyHtml(canvas, source) : state.status !== 'loading' && state.status !== 'error' ? `<div class=\"audio-art\"><span>${escapeHtml(ui.noMediaLoaded)}</span></div>` : ''}\n </div>`;\n const media = this.#root.querySelector('video, audio, hls-video') as HTMLMediaElement | null;\n if (media) this.controller.attachMedia(media);\n this.#bind();\n }\n\n #readyHtml(canvas: AVCanvas, source: MediaSource): string {\n const controls = this.controller.config.controls;\n const manifest = this.controller.manifest;\n const kind = source.kind;\n const ui = resolveStrings(this.controller.config.strings);\n const language = this.controller.config.preferredLanguages.find((value) => value !== 'none');\n return `<media-controller ${kind === 'audio' ? 'audio' : ''} ${language ? `lang=\"${escapeHtml(language)}\"` : ''}>\n ${kind === 'audio' ? `<div class=\"audio-art\"><span>${escapeHtml(canvas.label)}</span></div>` : ''}\n ${this.#mediaHtml(canvas, source)}\n <slot name=\"overlay\"></slot>\n <slot name=\"controls\">\n <media-control-bar>\n <media-play-button></media-play-button>\n ${controls.seek ? `<media-seek-backward-button seekoffset=\"${controls.skipSeconds ?? 10}\"></media-seek-backward-button><media-seek-forward-button seekoffset=\"${controls.skipSeconds ?? 10}\"></media-seek-forward-button>` : ''}\n <media-time-display showduration></media-time-display>\n ${controls.seek ? '<media-time-range></media-time-range>' : ''}\n ${controls.volume ? '<media-mute-button></media-mute-button><media-volume-range></media-volume-range>' : ''}\n ${controls.captions && canvas.tracks.length > 0 ? '<media-captions-menu-button></media-captions-menu-button>' : ''}\n ${controls.playbackRate ? '<media-playback-rate-menu-button></media-playback-rate-menu-button>' : ''}\n ${controls.pictureInPicture && kind === 'video' ? '<media-pip-button></media-pip-button>' : ''}\n ${controls.fullscreen && kind === 'video' ? '<media-fullscreen-button></media-fullscreen-button>' : ''}\n </media-control-bar>\n ${controls.captions && canvas.tracks.length > 0 ? '<media-captions-menu hidden></media-captions-menu>' : ''}\n ${controls.playbackRate ? `<media-playback-rate-menu rates=\"${this.controller.config.playbackRates.join(' ')}\" hidden></media-playback-rate-menu>` : ''}\n </slot>\n </media-controller>\n <div class=\"toolbar\">\n <div class=\"group\">\n <button type=\"button\" data-action=\"previous\" ${canvas.index === 0 ? 'disabled' : ''} aria-label=\"${escapeHtml(ui.previousSection)}\">← ${escapeHtml(ui.previous)}</button>\n <button type=\"button\" data-action=\"next\" ${canvas.index === (manifest?.canvases.length ?? 1) - 1 && !this.controller.state.repeat ? 'disabled' : ''} aria-label=\"${escapeHtml(ui.nextSection)}\">${escapeHtml(ui.next)} →</button>\n </div>\n <div class=\"group\">\n ${controls.sourceSelector && canvas.sources.length > 1 ? `<label><span class=\"sr-only\">${escapeHtml(ui.mediaSource)}</span><select data-action=\"source\">${canvas.sources.map((item, index) => `<option value=\"${index}\" ${index === this.controller.state.sourceIndex ? 'selected' : ''}>${escapeHtml(item.label ?? item.format ?? formatString(ui.sourceNumber, { number: index + 1 }))}</option>`).join('')}</select></label>` : ''}\n <label><input type=\"checkbox\" data-action=\"auto-advance\" ${this.controller.state.autoAdvance ? 'checked' : ''}> ${escapeHtml(ui.autoAdvance)}</label>\n </div>\n </div>`;\n }\n\n #mediaHtml(canvas: AVCanvas, source: MediaSource): string {\n const tag = source.isHls ? 'hls-video' : source.kind;\n const sourceUrl = this.#resolvedSourceUrl ?? (this.controller.config.resolveRequest ? '' : source.src);\n const attributes = [\n 'slot=\"media\"',\n sourceUrl ? `src=\"${escapeHtml(sourceUrl)}\"` : '',\n `preload=\"${this.controller.config.preload}\"`,\n this.controller.config.crossorigin ? `crossorigin=\"${this.controller.config.crossorigin}\"` : '',\n source.kind === 'video' && canvas.poster ? `poster=\"${escapeHtml(canvas.poster)}\"` : '',\n `aria-label=\"${escapeHtml(canvas.label)}\"`,\n `data-canvasindex=\"${canvas.index}\"`,\n ].filter(Boolean).join(' ');\n const tracks = canvas.tracks.map((track) => `<track src=\"${escapeHtml(track.src)}\" kind=\"${track.kind}\" label=\"${escapeHtml(track.label)}\" ${track.language ? `srclang=\"${escapeHtml(track.language)}\"` : ''} ${track.default ? 'default' : ''}>`).join('');\n return `<${tag} ${attributes}>${tracks}</${tag}>`;\n }\n\n #bind(): void {\n this.#root.querySelector<HTMLElement>('[data-action=previous]')?.addEventListener('click', () => this.controller.previous({ autoplay: this.controller.state.status === 'playing' }));\n this.#root.querySelector<HTMLElement>('[data-action=next]')?.addEventListener('click', () => this.controller.next({ autoplay: this.controller.state.status === 'playing' }));\n this.#root.querySelector<HTMLSelectElement>('[data-action=source]')?.addEventListener('change', (event) => this.controller.selectSource(Number((event.target as HTMLSelectElement).value)));\n this.#root.querySelector<HTMLInputElement>('[data-action=auto-advance]')?.addEventListener('change', (event) => this.controller.setAutoAdvance((event.target as HTMLInputElement).checked));\n }\n\n async #resolveSource(): Promise<void> {\n if (!this.controller.config.resolveRequest) return;\n const token = ++this.#sourceToken;\n try {\n const url = await this.controller.resolvedSourceUrl();\n if (token !== this.#sourceToken || !url) return;\n this.#resolvedSourceUrl = url;\n this.#root.querySelector('video, audio, hls-video')?.setAttribute('src', url);\n } catch (cause) {\n const error = cause instanceof Error ? cause : new Error(String(cause));\n this.dispatchEvent(new CustomEvent('av-error', { detail: { error }, bubbles: true, composed: true }));\n }\n }\n}\n\nexport const defineMangoAVPlayer = (tagName = 'mango-av-player'): typeof MangoAVPlayerElement => {\n if (typeof customElements === 'undefined') return MangoAVPlayerElement;\n if (!customElements.get(tagName)) customElements.define(tagName, MangoAVPlayerElement);\n return MangoAVPlayerElement;\n};\n"],"mappings":"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","names":[]}
|
package/dist/chunk-NTHMZZYJ.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
// src/components/media-chrome.ts
|
|
2
|
-
var registration;
|
|
3
|
-
var languageRegistrations = /* @__PURE__ */ new Map();
|
|
4
|
-
var loadLanguage = (language) => {
|
|
5
|
-
const normalized = language.toLowerCase();
|
|
6
|
-
const code = normalized === "zh-cn" || normalized === "zh-tw" ? normalized : normalized.split("-")[0] ?? normalized;
|
|
7
|
-
if (languageRegistrations.has(code)) return languageRegistrations.get(code);
|
|
8
|
-
const pending = (() => {
|
|
9
|
-
switch (code) {
|
|
10
|
-
case "de":
|
|
11
|
-
return import("media-chrome/lang/de");
|
|
12
|
-
case "es":
|
|
13
|
-
return import("media-chrome/lang/es");
|
|
14
|
-
case "fr":
|
|
15
|
-
return import("media-chrome/lang/fr");
|
|
16
|
-
case "pt":
|
|
17
|
-
return import("media-chrome/lang/pt");
|
|
18
|
-
case "zh-cn":
|
|
19
|
-
return import("media-chrome/lang/zh-CN");
|
|
20
|
-
case "zh-tw":
|
|
21
|
-
return import("media-chrome/lang/zh-TW");
|
|
22
|
-
default:
|
|
23
|
-
return void 0;
|
|
24
|
-
}
|
|
25
|
-
})();
|
|
26
|
-
if (pending) languageRegistrations.set(code, pending);
|
|
27
|
-
return pending;
|
|
28
|
-
};
|
|
29
|
-
var ensureMediaChrome = async (language) => {
|
|
30
|
-
if (language) await loadLanguage(language);
|
|
31
|
-
registration ??= import("media-chrome");
|
|
32
|
-
await registration;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
export {
|
|
36
|
-
ensureMediaChrome
|
|
37
|
-
};
|
|
38
|
-
//# sourceMappingURL=chunk-NTHMZZYJ.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/media-chrome.ts"],"sourcesContent":["let registration: Promise<unknown> | undefined;\nconst languageRegistrations = new Map<string, Promise<unknown>>();\n\nconst loadLanguage = (language: string): Promise<unknown> | undefined => {\n const normalized = language.toLowerCase();\n const code = normalized === 'zh-cn' || normalized === 'zh-tw'\n ? normalized\n : normalized.split('-')[0] ?? normalized;\n if (languageRegistrations.has(code)) return languageRegistrations.get(code);\n const pending = (() => {\n switch (code) {\n case 'de': return import('media-chrome/lang/de');\n case 'es': return import('media-chrome/lang/es');\n case 'fr': return import('media-chrome/lang/fr');\n case 'pt': return import('media-chrome/lang/pt');\n case 'zh-cn': return import('media-chrome/lang/zh-CN');\n case 'zh-tw': return import('media-chrome/lang/zh-TW');\n default: return undefined;\n }\n })();\n if (pending) languageRegistrations.set(code, pending);\n return pending;\n};\n\nexport const ensureMediaChrome = async (language?: string): Promise<void> => {\n if (language) await loadLanguage(language);\n registration ??= import('media-chrome');\n await registration;\n};\n"],"mappings":";AAAA,IAAI;AACJ,IAAM,wBAAwB,oBAAI,IAA8B;AAEhE,IAAM,eAAe,CAAC,aAAmD;AACvE,QAAM,aAAa,SAAS,YAAY;AACxC,QAAM,OAAO,eAAe,WAAW,eAAe,UAClD,aACA,WAAW,MAAM,GAAG,EAAE,CAAC,KAAK;AAChC,MAAI,sBAAsB,IAAI,IAAI,EAAG,QAAO,sBAAsB,IAAI,IAAI;AAC1E,QAAM,WAAW,MAAM;AACrB,YAAQ,MAAM;AAAA,MACZ,KAAK;AAAM,eAAO,OAAO,sBAAsB;AAAA,MAC/C,KAAK;AAAM,eAAO,OAAO,sBAAsB;AAAA,MAC/C,KAAK;AAAM,eAAO,OAAO,sBAAsB;AAAA,MAC/C,KAAK;AAAM,eAAO,OAAO,sBAAsB;AAAA,MAC/C,KAAK;AAAS,eAAO,OAAO,yBAAyB;AAAA,MACrD,KAAK;AAAS,eAAO,OAAO,yBAAyB;AAAA,MACrD;AAAS,eAAO;AAAA,IAClB;AAAA,EACF,GAAG;AACH,MAAI,QAAS,uBAAsB,IAAI,MAAM,OAAO;AACpD,SAAO;AACT;AAEO,IAAM,oBAAoB,OAAO,aAAqC;AAC3E,MAAI,SAAU,OAAM,aAAa,QAAQ;AACzC,mBAAiB,OAAO,cAAc;AACtC,QAAM;AACR;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/utils.ts","../src/iiif/normalize.ts","../src/controller.ts"],"sourcesContent":["export type JsonObject = { [key: string]: unknown };\nexport type IIIFPresentationVersion = 2 | 3;\nexport type MediaKind = 'audio' | 'video';\n\nexport interface LocalizedValue {\n language?: string;\n value: string;\n}\n\nexport interface TimeSpan {\n start: number;\n end?: number;\n}\n\nexport interface MediaSource {\n id: string;\n src: string;\n kind: MediaKind;\n format?: string;\n label?: string;\n width?: number;\n height?: number;\n duration?: number;\n quality?: string;\n isHls: boolean;\n segment?: TimeSpan;\n canvasTarget?: TimeSpan;\n timeMode?: 'trim' | 'scale' | 'loop';\n}\n\nexport type TextTrackKind = 'captions' | 'subtitles' | 'descriptions' | 'metadata';\n\nexport interface TextTrack {\n id: string;\n src: string;\n kind: TextTrackKind;\n label: string;\n language?: string;\n format?: string;\n default?: boolean;\n forced?: boolean;\n}\n\nexport interface TranscriptResource {\n id: string;\n src?: string;\n label: string;\n format?: string;\n language?: string;\n machineGenerated: boolean;\n cues?: TranscriptCue[];\n}\n\nexport type TranscriptCueType = 'cue' | 'note' | 'metadata' | 'text';\n\nexport interface TranscriptCue {\n id: string;\n start?: number;\n end?: number;\n text: string;\n speaker?: string;\n type: TranscriptCueType;\n}\n\nexport interface AVAnnotation {\n id: string;\n canvasId: string;\n motivation: string[];\n purpose: string[];\n label?: string;\n text: string;\n time?: TimeSpan;\n tags: string[];\n sourcePageId?: string;\n}\n\nexport interface AVAnnotationDraft {\n motivation?: string[];\n purpose?: string[];\n label?: string;\n text: string;\n time?: TimeSpan;\n tags?: string[];\n}\n\nexport interface AVAnnotationAdapter {\n create?: (canvas: AVCanvas, annotation: AVAnnotationDraft) => Promise<AVAnnotation>;\n update?: (canvas: AVCanvas, annotation: AVAnnotation) => Promise<AVAnnotation>;\n remove?: (canvas: AVCanvas, annotation: AVAnnotation) => Promise<void>;\n}\n\nexport interface DownloadResource {\n id: string;\n label: string;\n format?: string;\n filename?: string;\n}\n\nexport interface MetadataEntry {\n label: string;\n values: LocalizedValue[];\n}\n\nexport interface AuthService {\n id: string;\n profile?: string;\n label?: string;\n serviceType: 'probe' | 'access' | 'token' | 'logout' | 'unknown';\n services: AuthService[];\n}\n\nexport interface AVCanvas {\n id: string;\n index: number;\n label: string;\n summary?: string;\n duration?: number;\n width?: number;\n height?: number;\n behavior: string[];\n sources: MediaSource[];\n tracks: TextTrack[];\n transcripts: TranscriptResource[];\n annotations: AVAnnotation[];\n rendering: DownloadResource[];\n metadata: MetadataEntry[];\n poster?: string;\n accompanyingCanvas?: string;\n homepage?: string;\n authServices: AuthService[];\n}\n\nexport interface Chapter {\n id: string;\n label: string;\n canvasId?: string;\n time?: TimeSpan;\n behavior: string[];\n summary?: string;\n homepage?: string;\n children: Chapter[];\n}\n\nexport interface AVManifest {\n id: string;\n type: 'Manifest';\n version: IIIFPresentationVersion;\n label: string;\n summary?: string;\n behavior: string[];\n start?: { canvasId: string; time?: number };\n canvases: AVCanvas[];\n chapters: Chapter[];\n metadata: MetadataEntry[];\n rendering: DownloadResource[];\n rights?: string;\n requiredStatement?: MetadataEntry;\n homepage?: string;\n logo?: string;\n}\n\nexport interface AVControlsConfig {\n seek?: boolean;\n volume?: boolean;\n captions?: boolean;\n playbackRate?: boolean;\n pictureInPicture?: boolean;\n fullscreen?: boolean;\n sourceSelector?: boolean;\n download?: boolean;\n skipSeconds?: number;\n}\n\nexport interface AVPanelsConfig {\n chapters?: boolean;\n transcript?: boolean;\n annotations?: boolean;\n metadata?: boolean;\n supplementalFiles?: boolean;\n}\n\nexport interface AVTranscriptConfig {\n autoScroll?: boolean;\n search?: boolean;\n download?: boolean;\n showNotes?: boolean;\n showMetadata?: boolean;\n showSearchMarkers?: boolean;\n}\n\nexport interface AVResumeConfig {\n enabled?: boolean;\n maxItems?: number;\n ttlDays?: number;\n prompt?: boolean;\n}\n\n/** Package-owned interface strings. Values may contain `{name}` placeholders. */\nexport interface AVStrings {\n chapters: string;\n transcript: string;\n annotations: string;\n metadata: string;\n files: string;\n rights: string;\n previous: string;\n next: string;\n previousSection: string;\n nextSection: string;\n autoAdvance: string;\n mediaPlayer: string;\n mediaSource: string;\n mediaInformation: string;\n download: string;\n downloadMediaFile: string;\n searchTranscript: string;\n transcriptSearchMatches: string;\n searchMatchAt: string;\n resumePrompt: string;\n resume: string;\n startOver: string;\n loadingManifest: string;\n loadingTranscript: string;\n unableToLoadPlayer: string;\n unableToLoadMedia: string;\n noMediaLoaded: string;\n noPlayableMedia: string;\n noManifest: string;\n noTranscript: string;\n noAnnotations: string;\n noMetadata: string;\n noChapters: string;\n noSupplementalFiles: string;\n autoSource: string;\n sourceNumber: string;\n transcriptNumber: string;\n sectionNumber: string;\n chapterNumber: string;\n untitledManifest: string;\n unableToLoadManifest: string;\n expectedManifest: string;\n manifestWithoutCanvases: string;\n}\n\nexport interface AVPlayerConfig {\n controls?: AVControlsConfig;\n panels?: AVPanelsConfig;\n transcript?: AVTranscriptConfig;\n resume?: AVResumeConfig;\n strings?: Partial<AVStrings>;\n preferredLanguages?: string[];\n autoAdvance?: boolean;\n repeat?: boolean;\n startCanvasId?: string;\n startTime?: number;\n activePanel?: 'chapters' | 'transcript' | 'annotations' | 'metadata' | 'files' | 'none';\n crossorigin?: 'anonymous' | 'use-credentials' | '';\n preload?: 'none' | 'metadata' | 'auto';\n playbackRates?: number[];\n fetch?: typeof globalThis.fetch;\n requestInit?: RequestInit;\n resolveRequest?: (url: string, context: { manifest?: AVManifest; canvas?: AVCanvas }) => string | Promise<string>;\n annotationAdapter?: AVAnnotationAdapter;\n}\n\nexport interface AVPlayerState {\n status: 'idle' | 'loading' | 'ready' | 'playing' | 'paused' | 'ended' | 'error';\n manifest?: AVManifest;\n canvasIndex: number;\n sourceIndex: number;\n currentTime: number;\n duration: number;\n volume: number;\n muted: boolean;\n playbackRate: number;\n autoAdvance: boolean;\n repeat: boolean;\n error?: Error;\n}\n\nexport interface AVPlayerEventMap {\n 'av-loadstart': { source: string | JsonObject };\n 'av-ready': { manifest: AVManifest };\n 'av-error': { error: Error };\n 'av-canvaschange': { canvas: AVCanvas; canvasIndex: number };\n 'av-sourcechange': { source: MediaSource; sourceIndex: number };\n 'av-play': { canvasId: string; time: number };\n 'av-pause': { canvasId: string; time: number };\n 'av-timeupdate': { canvasId: string; time: number; duration: number };\n 'av-seek': { canvasId: string; from: number; to: number };\n 'av-ended': { canvasId: string };\n 'av-annotationschange': { canvasId: string; annotations: AVAnnotation[] };\n 'av-configchange': { config: Readonly<AVPlayerConfig> };\n 'av-statechange': AVPlayerState;\n}\n\nexport const defaultStrings: AVStrings = {\n chapters: 'Chapters',\n transcript: 'Transcript',\n annotations: 'Annotations',\n metadata: 'Metadata',\n files: 'Files',\n rights: 'Rights',\n previous: 'Previous',\n next: 'Next',\n previousSection: 'Previous section',\n nextSection: 'Next section',\n autoAdvance: 'Auto-advance',\n mediaPlayer: 'Media player',\n mediaSource: 'Media source',\n mediaInformation: 'Media information',\n download: 'Download',\n downloadMediaFile: 'Download media file',\n searchTranscript: 'Search transcript',\n transcriptSearchMatches: 'Transcript search matches',\n searchMatchAt: 'Search match at {time}',\n resumePrompt: 'Resume from {time}?',\n resume: 'Resume',\n startOver: 'Start over',\n loadingManifest: 'Loading IIIF manifest…',\n loadingTranscript: 'Loading transcript…',\n unableToLoadPlayer: 'Unable to load the player.',\n unableToLoadMedia: 'Unable to load media.',\n noMediaLoaded: 'No media loaded',\n noPlayableMedia: 'No playable audio or video source',\n noManifest: 'No manifest is loaded.',\n noTranscript: 'No transcript is available.',\n noAnnotations: 'No annotations are available.',\n noMetadata: 'No metadata is available.',\n noChapters: 'No structured navigation is available.',\n noSupplementalFiles: 'No supplemental files are available.',\n autoSource: 'Auto',\n sourceNumber: 'Source {number}',\n transcriptNumber: 'Transcript {number}',\n sectionNumber: 'Section {number}',\n chapterNumber: 'Chapter {number}',\n untitledManifest: 'Untitled manifest',\n unableToLoadManifest: 'Unable to load IIIF manifest ({status} {statusText}).',\n expectedManifest: 'Expected a IIIF Manifest, received {type}.',\n manifestWithoutCanvases: 'The IIIF Manifest does not contain any Canvases.',\n};\n\nexport const defaultConfig: Required<\n Pick<AVPlayerConfig, 'controls' | 'panels' | 'transcript' | 'resume' | 'strings' | 'preferredLanguages' | 'autoAdvance' | 'repeat' | 'activePanel' | 'crossorigin' | 'preload' | 'playbackRates'>\n> = {\n controls: {\n seek: true,\n volume: true,\n captions: true,\n playbackRate: true,\n pictureInPicture: true,\n fullscreen: true,\n sourceSelector: true,\n download: false,\n skipSeconds: 10,\n },\n panels: {\n chapters: true,\n transcript: true,\n annotations: true,\n metadata: true,\n supplementalFiles: true,\n },\n transcript: {\n autoScroll: true,\n search: true,\n download: true,\n showNotes: false,\n showMetadata: false,\n showSearchMarkers: true,\n },\n resume: {\n enabled: false,\n maxItems: 200,\n ttlDays: 30,\n prompt: true,\n },\n strings: defaultStrings,\n preferredLanguages: ['en', 'none'],\n autoAdvance: false,\n repeat: false,\n activePanel: 'chapters',\n crossorigin: 'anonymous',\n preload: 'metadata',\n playbackRates: [0.5, 0.75, 1, 1.25, 1.5, 2],\n};\n","import type { AVStrings, JsonObject, LocalizedValue, TimeSpan } from './types';\nimport { defaultStrings } from './types';\n\nexport const asObject = (value: unknown): JsonObject | undefined =>\n value !== null && typeof value === 'object' && !Array.isArray(value)\n ? (value as JsonObject)\n : undefined;\n\nexport const asArray = <T>(value: T | T[] | null | undefined): T[] => {\n if (value === null || value === undefined) return [];\n return Array.isArray(value) ? value : [value];\n};\n\nexport const readId = (value: unknown): string | undefined => {\n if (typeof value === 'string') return value;\n const object = asObject(value);\n const id = object?.id ?? object?.['@id'];\n return typeof id === 'string' ? id : undefined;\n};\n\nexport const readType = (value: unknown): string | undefined => {\n const object = asObject(value);\n const type = object?.type ?? object?.['@type'];\n return typeof type === 'string' ? type : undefined;\n};\n\nexport const languageValues = (value: unknown): LocalizedValue[] => {\n if (typeof value === 'string') return [{ value }];\n if (Array.isArray(value)) {\n return value.flatMap((item) => languageValues(item));\n }\n const object = asObject(value);\n if (!object) return [];\n if (typeof object['@value'] === 'string') {\n const result: LocalizedValue = { value: object['@value'] };\n if (typeof object['@language'] === 'string') result.language = object['@language'];\n return [result];\n }\n return Object.entries(object).flatMap(([language, values]) =>\n asArray(values).flatMap((item) =>\n typeof item === 'string'\n ? [{ language, value: item }]\n : languageValues(item).map((entry) => ({ ...entry, language: entry.language ?? language })),\n ),\n );\n};\n\nexport const label = (\n value: unknown,\n preferredLanguages: string[] = ['en', 'none'],\n fallback = '',\n): string => {\n const values = languageValues(value);\n for (const language of preferredLanguages) {\n const match = values.find((item) => item.language === language);\n if (match) return match.value;\n }\n return values[0]?.value ?? fallback;\n};\n\nexport const parseTime = (value: string | number | undefined): number | undefined => {\n if (typeof value === 'number') return Number.isFinite(value) ? value : undefined;\n if (!value) return undefined;\n if (/^\\d+(?:\\.\\d+)?$/.test(value)) return Number(value);\n const parts = value.replace(',', '.').split(':').map(Number);\n if (parts.some((part) => !Number.isFinite(part))) return undefined;\n if (parts.length === 3) return (parts[0] ?? 0) * 3600 + (parts[1] ?? 0) * 60 + (parts[2] ?? 0);\n if (parts.length === 2) return (parts[0] ?? 0) * 60 + (parts[1] ?? 0);\n return undefined;\n};\n\nexport const parseTemporalFragment = (target: unknown): TimeSpan | undefined => {\n let fragment: string | undefined;\n if (typeof target === 'string') fragment = target.split('#')[1];\n const object = asObject(target);\n if (!fragment && object) {\n const selector = asObject(object.selector);\n const value = selector?.value;\n if (typeof value === 'string') fragment = value.replace(/^#/, '');\n if (selector?.type === 'PointSelector' && typeof selector.t === 'number') {\n return { start: selector.t };\n }\n }\n const time = fragment?.match(/(?:^|&)t=([^&]+)/)?.[1];\n if (!time) return undefined;\n const [startValue, endValue] = time.split(',');\n const start = parseTime(startValue);\n const end = parseTime(endValue);\n if (start === undefined) return undefined;\n return end === undefined ? { start } : { start, end };\n};\n\nexport const withoutFragment = (value: string): string => value.split('#')[0] ?? value;\n\nexport const isHls = (src: string, format?: string): boolean =>\n /(?:\\.m3u8)(?:$|[?#])/i.test(src) ||\n format === 'application/vnd.apple.mpegurl' ||\n format === 'application/x-mpegURL';\n\nexport const mediaKind = (type?: string, format?: string, src = ''): 'audio' | 'video' | undefined => {\n const haystack = `${type ?? ''} ${format ?? ''} ${src}`.toLowerCase();\n if (/\\baudio\\b|\\.mp3(?:$|[?#])|\\.m4a(?:$|[?#])|\\.wav(?:$|[?#])|\\.aac(?:$|[?#])/.test(haystack)) return 'audio';\n if (/\\bvideo\\b|\\.mp4(?:$|[?#])|\\.webm(?:$|[?#])|\\.m3u8(?:$|[?#])|mpegurl/.test(haystack)) return 'video';\n return undefined;\n};\n\nexport const formatTime = (seconds: number): string => {\n if (!Number.isFinite(seconds)) return '0:00';\n const value = Math.max(0, Math.floor(seconds));\n const hours = Math.floor(value / 3600);\n const minutes = Math.floor((value % 3600) / 60);\n const remaining = value % 60;\n return hours > 0\n ? `${hours}:${String(minutes).padStart(2, '0')}:${String(remaining).padStart(2, '0')}`\n : `${minutes}:${String(remaining).padStart(2, '0')}`;\n};\n\nexport const resolveStrings = (strings: Partial<AVStrings> = {}): AVStrings => ({\n ...defaultStrings,\n ...strings,\n});\n\nexport const formatString = (\n template: string,\n values: Record<string, string | number> = {},\n): string => template.replace(/\\{(\\w+)\\}/g, (placeholder, name: string) =>\n Object.prototype.hasOwnProperty.call(values, name) ? String(values[name]) : placeholder,\n);\n\nexport const mergeConfig = <T extends Record<string, unknown>>(base: T, update: Partial<T>): T => {\n const result = { ...base } as T;\n for (const [key, value] of Object.entries(update)) {\n if (value !== undefined && asObject(value) && asObject(result[key])) {\n result[key as keyof T] = mergeConfig(\n asObject(result[key]) as Record<string, unknown>,\n asObject(value) as Record<string, unknown>,\n ) as T[keyof T];\n } else if (value !== undefined) {\n result[key as keyof T] = value as T[keyof T];\n }\n }\n return result;\n};\n\nexport const escapeHtml = (value: string): string =>\n value.replace(/[&<>'\"]/g, (character) => ({\n '&': '&',\n '<': '<',\n '>': '>',\n \"'\": ''',\n '\"': '"',\n })[character] ?? character);\n","import type {\n AVAnnotation,\n AVCanvas,\n AVManifest,\n AVStrings,\n AuthService,\n Chapter,\n DownloadResource,\n JsonObject,\n MediaSource,\n MetadataEntry,\n TextTrack,\n TranscriptCue,\n TranscriptResource,\n} from '../types';\nimport {\n asArray,\n asObject,\n formatString,\n isHls,\n label,\n languageValues,\n mediaKind,\n parseTemporalFragment,\n readId,\n readType,\n resolveStrings,\n withoutFragment,\n} from '../utils';\n\nexport interface NormalizeOptions {\n fetch?: typeof globalThis.fetch;\n requestInit?: RequestInit;\n preferredLanguages?: string[];\n loadExternalAnnotations?: boolean;\n strings?: Partial<AVStrings>;\n}\n\nconst strings = (value: unknown): string[] =>\n asArray(value).flatMap((item) => (typeof item === 'string' ? [item] : []));\n\nconst number = (value: unknown): number | undefined =>\n typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n\nconst readFormat = (object: JsonObject): string | undefined =>\n typeof object.format === 'string' ? object.format : undefined;\n\nconst metadata = (value: unknown, languages: string[], ui: AVStrings): MetadataEntry[] =>\n asArray(value).flatMap((item) => {\n const object = asObject(item);\n if (!object) return [];\n const values = languageValues(object.value);\n if (values.length === 0) return [];\n return [{ label: label(object.label, languages, ui.metadata), values }];\n });\n\nconst downloads = (value: unknown, languages: string[], ui: AVStrings): DownloadResource[] =>\n asArray(value).flatMap((item) => {\n const object = asObject(item);\n const id = readId(item);\n if (!object || !id) return [];\n const result: DownloadResource = {\n id,\n label: label(object.label, languages, id.split('/').pop() ?? ui.download),\n };\n const format = readFormat(object);\n if (format) result.format = format;\n const filename = typeof object.filename === 'string' ? object.filename : undefined;\n if (filename) result.filename = filename;\n return [result];\n });\n\nconst services = (value: unknown, languages: string[]): AuthService[] =>\n asArray(value).flatMap((item) => {\n const object = asObject(item);\n const id = readId(item);\n if (!object || !id) return [];\n const profile = typeof object.profile === 'string' ? object.profile : undefined;\n const type = `${readType(object) ?? ''} ${profile ?? ''}`.toLowerCase();\n let serviceType: AuthService['serviceType'] = 'unknown';\n if (type.includes('probe')) serviceType = 'probe';\n else if (type.includes('token')) serviceType = 'token';\n else if (type.includes('logout')) serviceType = 'logout';\n else if (type.includes('access') || type.includes('login') || type.includes('clickthrough') || type.includes('kiosk')) serviceType = 'access';\n const result: AuthService = {\n id,\n serviceType,\n services: services(object.service, languages),\n };\n if (profile) result.profile = profile;\n const serviceLabel = label(object.label, languages);\n if (serviceLabel) result.label = serviceLabel;\n return [result];\n });\n\nconst firstContentId = (canvasValue: unknown): string | undefined => {\n const canvas = asObject(canvasValue);\n if (!canvas) return undefined;\n const v3Page = asObject(asArray(canvas.items)[0]);\n const v3Annotation = asObject(asArray(v3Page?.items)[0]);\n const v3Body = asObject(asArray(v3Annotation?.body)[0]);\n const v2Annotation = asObject(asArray(canvas.images)[0]);\n const v2Body = asObject(v2Annotation?.resource);\n return readId(v3Body) ?? readId(v2Body);\n};\n\nconst bodyItems = (body: unknown): JsonObject[] => {\n const values = asArray(body).flatMap((item) => {\n const object = asObject(item);\n if (!object) return [];\n const type = readType(object)?.toLowerCase();\n if (type?.includes('choice') || Array.isArray(object.items) || Array.isArray(object.item)) {\n return asArray(object.items ?? object.item ?? object.default).flatMap((choice) => {\n const choiceObject = asObject(choice);\n return choiceObject ? [choiceObject] : [];\n });\n }\n return [object];\n });\n return values;\n};\n\nconst sourceFromBody = (\n body: JsonObject,\n canvas: JsonObject,\n target: unknown,\n languages: string[],\n index: number,\n ui: AVStrings,\n annotationTimeMode?: unknown,\n): MediaSource | undefined => {\n const originalId = readId(body);\n if (!originalId) return undefined;\n const format = readFormat(body);\n const kind = mediaKind(readType(body), format, originalId);\n if (!kind) return undefined;\n const result: MediaSource = {\n id: originalId,\n src: withoutFragment(originalId),\n kind,\n isHls: isHls(originalId, format),\n };\n if (format) result.format = format;\n const bodyLabel = label(body.label, languages, index === 0\n ? ui.autoSource\n : formatString(ui.sourceNumber, { number: index + 1 }));\n if (bodyLabel) result.label = bodyLabel;\n const width = number(body.width) ?? number(canvas.width);\n const height = number(body.height) ?? number(canvas.height);\n const duration = number(body.duration) ?? number(canvas.duration);\n if (width !== undefined) result.width = width;\n if (height !== undefined) result.height = height;\n if (duration !== undefined) result.duration = duration;\n const quality = typeof body.quality === 'string' ? body.quality : undefined;\n if (quality) result.quality = quality;\n const segment = parseTemporalFragment(originalId);\n if (segment) result.segment = segment;\n const canvasTarget = parseTemporalFragment(target);\n if (canvasTarget) result.canvasTarget = canvasTarget;\n const timeMode = body.timeMode ?? annotationTimeMode;\n if (timeMode === 'trim' || timeMode === 'scale' || timeMode === 'loop') result.timeMode = timeMode;\n return result;\n};\n\nconst textualBodies = (body: unknown): JsonObject[] =>\n bodyItems(body).filter((item) => {\n const type = readType(item)?.toLowerCase();\n return type?.includes('textualbody') || typeof item.value === 'string';\n });\n\nconst annotationMotivations = (annotation: JsonObject): string[] => strings(annotation.motivation);\n\nconst annotationFrom = (\n value: unknown,\n canvasId: string,\n pageId: string | undefined,\n languages: string[],\n index: number,\n): AVAnnotation | undefined => {\n const annotation = asObject(value);\n if (!annotation) return undefined;\n const bodies = textualBodies(annotation.body ?? annotation.resource);\n const text = bodies\n .flatMap((body) => (typeof body.value === 'string' ? [body.value] : languageValues(body.chars).map((entry) => entry.value)))\n .join('\\n');\n if (!text) return undefined;\n const motivation = annotationMotivations(annotation);\n const purpose = bodies.flatMap((body) => strings(body.purpose));\n const tags = bodies\n .filter((body) => strings(body.purpose).includes('tagging'))\n .flatMap((body) => (typeof body.value === 'string' ? [body.value] : []));\n const id = readId(annotation) ?? `${canvasId}/annotation/${index}`;\n const result: AVAnnotation = {\n id,\n canvasId,\n motivation,\n purpose,\n text,\n tags,\n };\n const annotationLabel = label(annotation.label, languages);\n if (annotationLabel) result.label = annotationLabel;\n const time = parseTemporalFragment(annotation.target ?? annotation.on);\n if (time) result.time = time;\n if (pageId) result.sourcePageId = pageId;\n return result;\n};\n\nconst classifySupplement = (\n body: JsonObject,\n annotation: JsonObject,\n canvasId: string,\n languages: string[],\n index: number,\n ui: AVStrings,\n): { track?: TextTrack; transcript?: TranscriptResource } => {\n const id = readId(body);\n if (!id) return {};\n const format = readFormat(body);\n const bodyLabel = label(body.label, languages, formatString(ui.transcriptNumber, { number: index + 1 }));\n const language = typeof body.language === 'string' ? body.language : undefined;\n const purpose = strings(body.purpose);\n const lower = `${bodyLabel} ${id} ${purpose.join(' ')}`.toLowerCase();\n const isTimedTrack = format === 'text/vtt' || /\\.vtt(?:$|[?#])/.test(id);\n let kind: TextTrack['kind'] = 'subtitles';\n if (lower.includes('caption')) kind = 'captions';\n if (lower.includes('description')) kind = 'descriptions';\n const result: { track?: TextTrack; transcript?: TranscriptResource } = {};\n if (isTimedTrack) {\n const track: TextTrack = { id, src: id, kind, label: bodyLabel };\n if (language) track.language = language;\n if (format) track.format = format;\n if (lower.includes('forced')) track.forced = true;\n result.track = track;\n }\n const transcript: TranscriptResource = {\n id: `${canvasId}/transcript/${index}`,\n src: id,\n label: bodyLabel,\n machineGenerated: /\\(machine[ -]generated\\)/i.test(bodyLabel),\n };\n if (format) transcript.format = format;\n if (language) transcript.language = language;\n result.transcript = transcript;\n return result;\n};\n\nconst annotationPageItems = (page: JsonObject): unknown[] => asArray(page.items ?? page.resources);\n\nconst collectSupplementing = (\n pages: JsonObject[],\n canvasId: string,\n languages: string[],\n ui: AVStrings,\n): { tracks: TextTrack[]; transcripts: TranscriptResource[]; annotations: AVAnnotation[] } => {\n const tracks: TextTrack[] = [];\n const transcripts: TranscriptResource[] = [];\n const annotations: AVAnnotation[] = [];\n let index = 0;\n for (const page of pages) {\n const pageId = readId(page);\n for (const item of annotationPageItems(page)) {\n const annotation = asObject(item);\n if (!annotation) continue;\n const motivations = annotationMotivations(annotation);\n const normalizedAnnotation = annotationFrom(annotation, canvasId, pageId, languages, index);\n if (normalizedAnnotation) annotations.push(normalizedAnnotation);\n for (const body of bodyItems(annotation.body ?? annotation.resource)) {\n const bodyId = readId(body);\n if (bodyId && (motivations.includes('supplementing') || motivations.includes('transcribing') || motivations.length === 0)) {\n const supplement = classifySupplement(body, annotation, canvasId, languages, index, ui);\n if (supplement.track) tracks.push(supplement.track);\n if (supplement.transcript) transcripts.push(supplement.transcript);\n }\n }\n const inline = textualBodies(annotation.body ?? annotation.resource);\n if (inline.length > 0 && (motivations.includes('supplementing') || motivations.includes('transcribing'))) {\n const cues: TranscriptCue[] = inline.flatMap((body, bodyIndex) => {\n const text = typeof body.value === 'string' ? body.value : label(body.chars, languages);\n if (!text) return [];\n const cue: TranscriptCue = {\n id: `${readId(annotation) ?? `${canvasId}/annotation/${index}`}/cue/${bodyIndex}`,\n text,\n type: 'cue',\n };\n const time = parseTemporalFragment(annotation.target ?? annotation.on);\n if (time) {\n cue.start = time.start;\n if (time.end !== undefined) cue.end = time.end;\n }\n return [cue];\n });\n if (cues.length > 0) {\n transcripts.push({\n id: `${pageId ?? canvasId}/inline-transcript`,\n label: label(page.label, languages, ui.transcript),\n machineGenerated: false,\n cues,\n });\n }\n }\n index += 1;\n }\n }\n return { tracks, transcripts, annotations };\n};\n\nconst paintingAnnotations = (canvas: JsonObject, version: 2 | 3): JsonObject[] => {\n if (version === 2) {\n return asArray(canvas.images).flatMap((item) => {\n const object = asObject(item);\n return object ? [object] : [];\n });\n }\n return asArray(canvas.items).flatMap((page) => {\n const object = asObject(page);\n return object ? annotationPageItems(object).flatMap((item) => (asObject(item) ? [asObject(item) as JsonObject] : [])) : [];\n });\n};\n\nconst inlineSupplementPages = (canvas: JsonObject, version: 2 | 3): JsonObject[] => {\n const raw = version === 2 ? canvas.otherContent : canvas.annotations;\n return asArray(raw).flatMap((item) => {\n const object = asObject(item);\n return object && (Array.isArray(object.items) || Array.isArray(object.resources)) ? [object] : [];\n });\n};\n\nconst externalSupplementReferences = (canvas: JsonObject, version: 2 | 3): string[] => {\n const raw = version === 2 ? canvas.otherContent : canvas.annotations;\n return asArray(raw).flatMap((item) => {\n const object = asObject(item);\n if (object && (Array.isArray(object.items) || Array.isArray(object.resources))) return [];\n const id = readId(item);\n return id ? [id] : [];\n });\n};\n\nconst posterFrom = (canvas: JsonObject): string | undefined => {\n const placeholder = asObject(canvas.placeholderCanvas);\n return firstContentId(placeholder);\n};\n\nconst canvasFrom = (\n canvas: JsonObject,\n index: number,\n version: 2 | 3,\n languages: string[],\n ui: AVStrings,\n): AVCanvas => {\n const id = readId(canvas) ?? `urn:mango:canvas:${index}`;\n const sources = paintingAnnotations(canvas, version).flatMap((annotation, annotationIndex) =>\n bodyItems(annotation.body ?? annotation.resource).flatMap((body, bodyIndex) => {\n const source = sourceFromBody(body, canvas, annotation.target ?? annotation.on, languages, annotationIndex + bodyIndex, ui, annotation.timeMode);\n return source ? [source] : [];\n }),\n );\n const supplementing = collectSupplementing(inlineSupplementPages(canvas, version), id, languages, ui);\n const result: AVCanvas = {\n id,\n index,\n label: label(canvas.label, languages, formatString(ui.sectionNumber, { number: index + 1 })),\n behavior: strings(canvas.behavior ?? canvas.viewingHint),\n sources,\n tracks: supplementing.tracks,\n transcripts: supplementing.transcripts,\n annotations: supplementing.annotations,\n rendering: downloads(canvas.rendering, languages, ui),\n metadata: metadata(canvas.metadata, languages, ui),\n authServices: services(canvas.service, languages),\n };\n const summary = label(canvas.summary ?? canvas.description, languages);\n if (summary) result.summary = summary;\n const duration = number(canvas.duration);\n const width = number(canvas.width);\n const height = number(canvas.height);\n if (duration !== undefined) result.duration = duration;\n if (width !== undefined) result.width = width;\n if (height !== undefined) result.height = height;\n const poster = posterFrom(canvas);\n if (poster) result.poster = poster;\n const accompanying = readId(canvas.accompanyingCanvas);\n if (accompanying) result.accompanyingCanvas = accompanying;\n const homepage = readId(asArray(canvas.homepage ?? canvas.related)[0]);\n if (homepage) result.homepage = homepage;\n return result;\n};\n\nconst resolveRangeTarget = (value: unknown): { canvasId?: string; time?: { start: number; end?: number } } => {\n const id = readId(value) ?? readId(asObject(value)?.source);\n if (!id) return {};\n const result: { canvasId?: string; time?: { start: number; end?: number } } = { canvasId: withoutFragment(id) };\n const time = parseTemporalFragment(id);\n if (time) result.time = time;\n return result;\n};\n\nconst chaptersFrom = (manifest: JsonObject, version: 2 | 3, languages: string[], ui: AVStrings): Chapter[] => {\n const rawStructures = asArray(manifest.structures).flatMap((item) => (asObject(item) ? [asObject(item) as JsonObject] : []));\n const byId = new Map(rawStructures.map((range) => [readId(range), range]));\n const seen = new Set<JsonObject>();\n\n const parseRange = (range: JsonObject, depth = 0): Chapter | undefined => {\n if (depth > 50 || seen.has(range)) return undefined;\n seen.add(range);\n const rangeBehavior = strings(range.behavior ?? range.viewingHint);\n if (rangeBehavior.includes('no-nav') || rangeBehavior.includes('thumbnail-nav')) return undefined;\n const id = readId(range) ?? `urn:mango:range:${seen.size}`;\n const members = version === 3\n ? asArray(range.items)\n : asArray(range.members ?? range.ranges ?? range.canvases);\n const children: Chapter[] = [];\n let target: ReturnType<typeof resolveRangeTarget> = {};\n for (const member of members) {\n const object = asObject(member);\n const memberId = readId(member);\n const memberType = readType(object)?.toLowerCase();\n const referencedRange = memberId ? byId.get(memberId) : undefined;\n if (referencedRange || memberType?.includes('range') || (object && (object.items || object.ranges || object.members))) {\n const child = parseRange(referencedRange ?? (object as JsonObject), depth + 1);\n if (child) children.push(child);\n } else if (!target.canvasId && memberId) {\n target = resolveRangeTarget(member);\n }\n }\n const result: Chapter = {\n id,\n label: label(range.label, languages, formatString(ui.chapterNumber, { number: seen.size })),\n behavior: rangeBehavior,\n children,\n };\n if (target.canvasId) result.canvasId = target.canvasId;\n if (target.time) result.time = target.time;\n const summary = label(range.summary ?? range.description, languages);\n if (summary) result.summary = summary;\n const homepage = readId(asArray(range.homepage ?? range.related)[0]);\n if (homepage) result.homepage = homepage;\n return result;\n };\n\n return rawStructures.flatMap((range) => {\n const chapter = parseRange(range);\n return chapter ? [chapter] : [];\n });\n};\n\nconst startFrom = (manifest: JsonObject, version: 2 | 3): AVManifest['start'] => {\n const value = version === 2\n ? asObject(asArray(manifest.sequences)[0])?.startCanvas ?? manifest.startCanvas\n : manifest.start;\n const id = readId(value) ?? readId(asObject(value)?.source);\n if (!id) return undefined;\n const result: NonNullable<AVManifest['start']> = { canvasId: withoutFragment(id) };\n const time = parseTemporalFragment(value) ?? parseTemporalFragment(id);\n if (time) result.time = time.start;\n return result;\n};\n\nconst manifestCanvases = (manifest: JsonObject, version: 2 | 3): JsonObject[] => {\n const raw = version === 3\n ? manifest.items\n : asObject(asArray(manifest.sequences)[0])?.canvases;\n return asArray(raw).flatMap((item) => (asObject(item) ? [asObject(item) as JsonObject] : []));\n};\n\nconst detectVersion = (manifest: JsonObject): 2 | 3 => {\n const context = JSON.stringify(manifest['@context'] ?? '');\n if (context.includes('/presentation/2/')) return 2;\n if (Array.isArray(manifest.sequences) || readType(manifest)?.startsWith('sc:')) return 2;\n return 3;\n};\n\nexport const normalizeManifest = async (\n input: JsonObject | string,\n options: NormalizeOptions = {},\n): Promise<AVManifest> => {\n const ui = resolveStrings(options.strings);\n const fetcher = options.fetch ?? globalThis.fetch;\n let source: JsonObject;\n if (typeof input === 'string') {\n if (input.trim().startsWith('{')) {\n source = JSON.parse(input) as JsonObject;\n } else {\n if (!fetcher) throw new Error('No fetch implementation is available to load the IIIF manifest.');\n const response = await fetcher(input, options.requestInit);\n if (!response.ok) throw new Error(formatString(ui.unableToLoadManifest, {\n status: response.status,\n statusText: response.statusText,\n }));\n source = await response.json() as JsonObject;\n }\n } else {\n source = input;\n }\n const type = readType(source)?.toLowerCase();\n if (type && !type.includes('manifest')) throw new Error(formatString(ui.expectedManifest, {\n type: readType(source) ?? '',\n }));\n const version = detectVersion(source);\n const languages = options.preferredLanguages ?? ['en', 'none'];\n const canvases = manifestCanvases(source, version).map((canvas, index) => canvasFrom(canvas, index, version, languages, ui));\n if (canvases.length === 0) throw new Error(ui.manifestWithoutCanvases);\n\n if (options.loadExternalAnnotations !== false && fetcher) {\n const rawCanvases = manifestCanvases(source, version);\n await Promise.all(rawCanvases.map(async (canvas, index) => {\n const target = canvases[index];\n if (!target) return;\n const references = externalSupplementReferences(canvas, version);\n const loaded = await Promise.all(references.map(async (url) => {\n try {\n const response = await fetcher(url, options.requestInit);\n if (!response.ok) return undefined;\n return asObject(await response.json());\n } catch {\n return undefined;\n }\n }));\n const parsed = collectSupplementing(loaded.filter((page): page is JsonObject => Boolean(page)), target.id, languages, ui);\n target.tracks.push(...parsed.tracks);\n target.transcripts.push(...parsed.transcripts);\n target.annotations.push(...parsed.annotations);\n }));\n }\n\n const id = readId(source) ?? 'urn:mango:manifest';\n const result: AVManifest = {\n id,\n type: 'Manifest',\n version,\n label: label(source.label, languages, ui.untitledManifest),\n behavior: strings(source.behavior ?? source.viewingHint),\n canvases,\n chapters: chaptersFrom(source, version, languages, ui),\n metadata: metadata(source.metadata, languages, ui),\n rendering: downloads(source.rendering, languages, ui),\n };\n const summary = label(source.summary ?? source.description, languages);\n if (summary) result.summary = summary;\n const start = startFrom(source, version);\n if (start) result.start = start;\n if (typeof source.rights === 'string') result.rights = source.rights;\n const requiredStatement = metadata([source.requiredStatement ?? source.attribution], languages, ui)[0];\n if (requiredStatement) result.requiredStatement = requiredStatement;\n const homepage = readId(asArray(source.homepage ?? source.related)[0]);\n if (homepage) result.homepage = homepage;\n const logo = readId(asArray(source.logo ?? source.provider)[0]);\n if (logo) result.logo = logo;\n return result;\n};\n","import { normalizeManifest } from './iiif/normalize';\nimport type {\n AVCanvas,\n AVAnnotation,\n AVAnnotationDraft,\n AVManifest,\n AVPlayerConfig,\n AVPlayerEventMap,\n AVPlayerState,\n JsonObject,\n MediaSource,\n} from './types';\nimport { defaultConfig } from './types';\nimport { mergeConfig, withoutFragment } from './utils';\n\ntype ResolvedConfig = AVPlayerConfig & typeof defaultConfig;\n\ninterface SavedPosition {\n time: number;\n savedAt: number;\n}\n\nconst positionPrefix = '@mango-iiif/av:position:';\n\nexport class AVPlayerController extends EventTarget {\n #config: ResolvedConfig;\n #state: AVPlayerState = {\n status: 'idle',\n canvasIndex: 0,\n sourceIndex: 0,\n currentTime: 0,\n duration: 0,\n volume: 1,\n muted: false,\n playbackRate: 1,\n autoAdvance: false,\n repeat: false,\n };\n #media: HTMLMediaElement | undefined;\n #lastTime = 0;\n #timelineScale = 1;\n #pendingTime: number | undefined;\n #boundListeners = new Map<string, EventListener>();\n\n constructor(config: AVPlayerConfig = {}) {\n super();\n this.#config = mergeConfig(defaultConfig, config) as ResolvedConfig;\n this.#state.autoAdvance = this.#config.autoAdvance;\n this.#state.repeat = this.#config.repeat;\n }\n\n get config(): Readonly<ResolvedConfig> {\n return this.#config;\n }\n\n get state(): Readonly<AVPlayerState> {\n return this.#state;\n }\n\n get manifest(): AVManifest | undefined {\n return this.#state.manifest;\n }\n\n get canvas(): AVCanvas | undefined {\n return this.#state.manifest?.canvases[this.#state.canvasIndex];\n }\n\n get source(): MediaSource | undefined {\n return this.canvas?.sources[this.#state.sourceIndex];\n }\n\n get media(): HTMLMediaElement | undefined {\n return this.#media;\n }\n\n on<K extends keyof AVPlayerEventMap>(\n type: K,\n listener: (event: CustomEvent<AVPlayerEventMap[K]>) => void,\n ): () => void {\n const eventListener = listener as EventListener;\n this.addEventListener(type, eventListener);\n return () => this.removeEventListener(type, eventListener);\n }\n\n configure(config: AVPlayerConfig): void {\n this.#config = mergeConfig(\n this.#config as unknown as Record<string, unknown>,\n config as unknown as Record<string, unknown>,\n ) as unknown as ResolvedConfig;\n if (config.autoAdvance !== undefined) this.#state.autoAdvance = config.autoAdvance;\n if (config.repeat !== undefined) this.#state.repeat = config.repeat;\n this.#emit('av-configchange', { config: this.#config });\n this.#emitState();\n }\n\n async load(input: JsonObject | string): Promise<AVManifest> {\n this.#state.status = 'loading';\n delete this.#state.error;\n this.#emit('av-loadstart', { source: input });\n this.#emitState();\n try {\n const normalizeOptions: Parameters<typeof normalizeManifest>[1] = {\n preferredLanguages: this.#config.preferredLanguages,\n strings: this.#config.strings,\n };\n if (this.#config.fetch) normalizeOptions.fetch = this.#config.fetch;\n if (this.#config.requestInit) normalizeOptions.requestInit = this.#config.requestInit;\n const manifest = await normalizeManifest(input, normalizeOptions);\n this.#state.manifest = manifest;\n const requestedCanvas = this.#config.startCanvasId ?? manifest.start?.canvasId;\n const canvasIndex = requestedCanvas\n ? Math.max(0, manifest.canvases.findIndex((canvas) => canvas.id === withoutFragment(requestedCanvas)))\n : 0;\n this.#state.canvasIndex = canvasIndex;\n this.#state.sourceIndex = 0;\n this.#timelineScale = 1;\n this.#state.currentTime = 0;\n this.#state.duration = this.canvas?.duration ?? 0;\n this.#state.autoAdvance = this.#config.autoAdvance || manifest.behavior.includes('auto-advance');\n this.#state.repeat = this.#config.repeat || manifest.behavior.includes('repeat');\n this.#state.status = 'ready';\n const initialTime = this.#config.startTime ?? manifest.start?.time ?? this.source?.canvasTarget?.start;\n if (initialTime !== undefined) this.#pendingTime = initialTime;\n this.#emit('av-ready', { manifest });\n const canvas = this.canvas;\n if (canvas) this.#emit('av-canvaschange', { canvas, canvasIndex });\n this.#emitState();\n return manifest;\n } catch (cause) {\n const error = cause instanceof Error ? cause : new Error(String(cause));\n this.#state.status = 'error';\n this.#state.error = error;\n this.#emit('av-error', { error });\n this.#emitState();\n throw error;\n }\n }\n\n attachMedia(media: HTMLMediaElement): void {\n if (this.#media === media) return;\n this.detachMedia();\n this.#media = media;\n const listeners: Record<string, EventListener> = {\n loadedmetadata: () => {\n const segment = this.source?.segment;\n const target = this.source?.canvasTarget;\n if (this.source?.timeMode === 'scale' && target?.end !== undefined && Number.isFinite(media.duration)) {\n const sourceDuration = segment?.end !== undefined ? segment.end - segment.start : media.duration;\n const targetDuration = target.end - target.start;\n if (sourceDuration > 0 && targetDuration > 0) {\n this.#timelineScale = sourceDuration / targetDuration;\n media.playbackRate = this.#timelineScale;\n }\n }\n const pending = this.#pendingTime ?? target?.start;\n if (pending !== undefined) {\n media.currentTime = this.#toMediaTime(pending);\n this.#pendingTime = undefined;\n }\n this.#state.duration = this.canvas?.duration ?? target?.end ?? (Number.isFinite(media.duration) ? this.#toCanvasTime(media.duration) : 0);\n this.#emitState();\n },\n play: () => {\n this.#state.status = 'playing';\n this.#emit('av-play', { canvasId: this.canvas?.id ?? '', time: this.#toCanvasTime(media.currentTime) });\n this.#emitState();\n },\n pause: () => {\n if (!media.ended) this.#state.status = 'paused';\n this.#savePosition();\n this.#emit('av-pause', { canvasId: this.canvas?.id ?? '', time: this.#toCanvasTime(media.currentTime) });\n this.#emitState();\n },\n timeupdate: () => {\n const time = this.#toCanvasTime(media.currentTime);\n const duration = this.canvas?.duration ?? this.source?.canvasTarget?.end ?? (Number.isFinite(media.duration) ? this.#toCanvasTime(media.duration) : 0);\n this.#state.currentTime = time;\n this.#state.duration = duration;\n this.#emit('av-timeupdate', { canvasId: this.canvas?.id ?? '', time, duration });\n const end = this.source?.canvasTarget?.end ?? (this.source?.segment?.end !== undefined ? this.#toCanvasTime(this.source.segment.end) : undefined);\n if (end !== undefined && time >= end) {\n if (this.source?.timeMode === 'loop') {\n media.currentTime = this.source.segment?.start ?? 0;\n } else {\n media.pause();\n void this.#advanceAfterEnd();\n }\n }\n this.#lastTime = time;\n this.#emitState();\n },\n seeking: () => {\n this.#emit('av-seek', { canvasId: this.canvas?.id ?? '', from: this.#lastTime, to: this.#toCanvasTime(media.currentTime) });\n },\n volumechange: () => {\n this.#state.volume = media.volume;\n this.#state.muted = media.muted;\n this.#emitState();\n },\n ratechange: () => {\n this.#state.playbackRate = media.playbackRate;\n this.#emitState();\n },\n ended: () => {\n this.#state.status = 'ended';\n this.#emit('av-ended', { canvasId: this.canvas?.id ?? '' });\n this.#clearPosition();\n this.#emitState();\n void this.#advanceAfterEnd();\n },\n error: () => {\n const error = new Error(media.error?.message ?? 'The media resource could not be played.');\n this.#state.status = 'error';\n this.#state.error = error;\n this.#emit('av-error', { error });\n this.#emitState();\n },\n };\n for (const [type, listener] of Object.entries(listeners)) {\n media.addEventListener(type, listener);\n this.#boundListeners.set(type, listener);\n }\n }\n\n detachMedia(): void {\n if (!this.#media) return;\n for (const [type, listener] of this.#boundListeners) this.#media.removeEventListener(type, listener);\n this.#boundListeners.clear();\n this.#media = undefined;\n }\n\n async play(): Promise<void> {\n await this.#media?.play();\n }\n\n pause(): void {\n this.#media?.pause();\n }\n\n stop(): void {\n this.pause();\n this.seekTo(this.source?.canvasTarget?.start ?? 0);\n }\n\n seekTo(time: number): void {\n const source = this.source;\n const minimum = source?.canvasTarget?.start ?? 0;\n const maximum = source?.canvasTarget?.end ?? this.#state.duration;\n const target = maximum > 0 ? Math.min(Math.max(time, minimum), maximum) : Math.max(time, minimum);\n if (this.#media && this.#media.readyState > 0) this.#media.currentTime = this.#toMediaTime(target);\n else this.#pendingTime = target;\n this.#state.currentTime = target;\n this.#emitState();\n }\n\n seekBy(delta: number): void {\n this.seekTo(this.#state.currentTime + delta);\n }\n\n selectCanvas(indexOrId: number | string, options: { time?: number; autoplay?: boolean } = {}): AVCanvas | undefined {\n const canvases = this.#state.manifest?.canvases ?? [];\n const index = typeof indexOrId === 'number'\n ? indexOrId\n : canvases.findIndex((canvas) => canvas.id === withoutFragment(indexOrId));\n if (index < 0 || index >= canvases.length) return undefined;\n const wasPlaying = options.autoplay ?? this.#state.status === 'playing';\n this.#state.canvasIndex = index;\n this.#state.sourceIndex = 0;\n this.#timelineScale = 1;\n this.#state.currentTime = options.time ?? canvases[index]?.sources[0]?.canvasTarget?.start ?? 0;\n this.#state.duration = canvases[index]?.duration ?? 0;\n this.#pendingTime = this.#state.currentTime;\n const canvas = canvases[index];\n if (canvas) this.#emit('av-canvaschange', { canvas, canvasIndex: index });\n this.#emitState();\n if (wasPlaying) queueMicrotask(() => void this.play());\n return canvas;\n }\n\n next(options: { autoplay?: boolean } = {}): AVCanvas | undefined {\n const count = this.#state.manifest?.canvases.length ?? 0;\n if (this.#state.canvasIndex + 1 < count) return this.selectCanvas(this.#state.canvasIndex + 1, options);\n if (this.#state.repeat && count > 0) return this.selectCanvas(0, options);\n return undefined;\n }\n\n previous(options: { autoplay?: boolean } = {}): AVCanvas | undefined {\n if (this.#state.canvasIndex > 0) return this.selectCanvas(this.#state.canvasIndex - 1, options);\n return undefined;\n }\n\n selectSource(index: number): MediaSource | undefined {\n const sources = this.canvas?.sources ?? [];\n const source = sources[index];\n if (!source) return undefined;\n const wasPlaying = this.#state.status === 'playing';\n const currentTime = this.#state.currentTime;\n this.#state.sourceIndex = index;\n this.#timelineScale = 1;\n this.#pendingTime = currentTime;\n this.#emit('av-sourcechange', { source, sourceIndex: index });\n this.#emitState();\n if (wasPlaying) queueMicrotask(() => void this.play());\n return source;\n }\n\n async createAnnotation(draft: AVAnnotationDraft): Promise<AVAnnotation> {\n const canvas = this.canvas;\n if (!canvas) throw new Error('A Canvas must be active before creating an annotation.');\n const created = this.#config.annotationAdapter?.create\n ? await this.#config.annotationAdapter.create(canvas, draft)\n : this.#annotationFromDraft(canvas, draft);\n canvas.annotations.push(created);\n this.#emit('av-annotationschange', { canvasId: canvas.id, annotations: [...canvas.annotations] });\n this.#emitState();\n return created;\n }\n\n async updateAnnotation(id: string, update: Partial<AVAnnotationDraft>): Promise<AVAnnotation> {\n const canvas = this.canvas;\n if (!canvas) throw new Error('A Canvas must be active before updating an annotation.');\n const index = canvas.annotations.findIndex((annotation) => annotation.id === id);\n const current = canvas.annotations[index];\n if (!current) throw new Error(`Annotation ${id} was not found on the active Canvas.`);\n const candidate: AVAnnotation = {\n ...current,\n ...update,\n motivation: update.motivation ?? current.motivation,\n purpose: update.purpose ?? current.purpose,\n tags: update.tags ?? current.tags,\n };\n const saved = this.#config.annotationAdapter?.update\n ? await this.#config.annotationAdapter.update(canvas, candidate)\n : candidate;\n canvas.annotations[index] = saved;\n this.#emit('av-annotationschange', { canvasId: canvas.id, annotations: [...canvas.annotations] });\n this.#emitState();\n return saved;\n }\n\n async removeAnnotation(id: string): Promise<void> {\n const canvas = this.canvas;\n if (!canvas) throw new Error('A Canvas must be active before removing an annotation.');\n const index = canvas.annotations.findIndex((annotation) => annotation.id === id);\n const current = canvas.annotations[index];\n if (!current) throw new Error(`Annotation ${id} was not found on the active Canvas.`);\n if (this.#config.annotationAdapter?.remove) await this.#config.annotationAdapter.remove(canvas, current);\n canvas.annotations.splice(index, 1);\n this.#emit('av-annotationschange', { canvasId: canvas.id, annotations: [...canvas.annotations] });\n this.#emitState();\n }\n\n setAutoAdvance(enabled: boolean): void {\n this.#state.autoAdvance = enabled;\n this.#emitState();\n }\n\n setRepeat(enabled: boolean): void {\n this.#state.repeat = enabled;\n this.#emitState();\n }\n\n getSavedPosition(): number | undefined {\n if (!this.#config.resume.enabled || !this.canvas || typeof localStorage === 'undefined') return undefined;\n const raw = localStorage.getItem(`${positionPrefix}${this.#state.manifest?.id}:${this.canvas.id}`);\n if (!raw) return undefined;\n try {\n const saved = JSON.parse(raw) as SavedPosition;\n const ttl = (this.#config.resume.ttlDays ?? 30) * 86_400_000;\n if (Date.now() - saved.savedAt > ttl) {\n this.#clearPosition();\n return undefined;\n }\n return saved.time;\n } catch {\n return undefined;\n }\n }\n\n destroy(): void {\n this.#savePosition();\n this.detachMedia();\n }\n\n async resolvedSourceUrl(): Promise<string | undefined> {\n const source = this.source;\n if (!source) return undefined;\n if (!this.#config.resolveRequest) return source.src;\n const context: { manifest?: AVManifest; canvas?: AVCanvas } = {};\n if (this.manifest) context.manifest = this.manifest;\n if (this.canvas) context.canvas = this.canvas;\n return await this.#config.resolveRequest(source.src, context);\n }\n\n async #advanceAfterEnd(): Promise<void> {\n if (!this.#state.autoAdvance) return;\n const next = this.next({ autoplay: true });\n if (!next) this.#state.status = 'ended';\n }\n\n #savePosition(): void {\n if (!this.#config.resume.enabled || !this.canvas || typeof localStorage === 'undefined') return;\n const time = this.#state.currentTime;\n if (time <= 0 || (this.#state.duration > 0 && time >= this.#state.duration - 2)) return;\n const key = `${positionPrefix}${this.#state.manifest?.id}:${this.canvas.id}`;\n localStorage.setItem(key, JSON.stringify({ time, savedAt: Date.now() } satisfies SavedPosition));\n const keys = Object.keys(localStorage).filter((item) => item.startsWith(positionPrefix));\n const maxItems = this.#config.resume.maxItems ?? 200;\n if (keys.length > maxItems) {\n const oldest = keys\n .map((item) => ({ item, value: JSON.parse(localStorage.getItem(item) ?? '{}') as Partial<SavedPosition> }))\n .sort((a, b) => (a.value.savedAt ?? 0) - (b.value.savedAt ?? 0))[0];\n if (oldest) localStorage.removeItem(oldest.item);\n }\n }\n\n #clearPosition(): void {\n if (!this.canvas || typeof localStorage === 'undefined') return;\n localStorage.removeItem(`${positionPrefix}${this.#state.manifest?.id}:${this.canvas.id}`);\n }\n\n #emit<K extends keyof AVPlayerEventMap>(type: K, detail: AVPlayerEventMap[K]): void {\n this.dispatchEvent(new CustomEvent(type, { detail, bubbles: false, composed: false }));\n }\n\n #emitState(): void {\n this.#emit('av-statechange', { ...this.#state });\n }\n\n #annotationFromDraft(canvas: AVCanvas, draft: AVAnnotationDraft): AVAnnotation {\n const annotation: AVAnnotation = {\n id: `${canvas.id}/annotation/${crypto.randomUUID?.() ?? Date.now()}`,\n canvasId: canvas.id,\n motivation: draft.motivation ?? ['commenting'],\n purpose: draft.purpose ?? ['commenting'],\n text: draft.text,\n tags: draft.tags ?? [],\n };\n if (draft.label) annotation.label = draft.label;\n if (draft.time) annotation.time = draft.time;\n return annotation;\n }\n\n #toCanvasTime(mediaTime: number): number {\n const sourceStart = this.source?.segment?.start ?? 0;\n const targetStart = this.source?.canvasTarget?.start ?? 0;\n const scale = this.source?.timeMode === 'scale' ? this.#timelineScale : 1;\n return targetStart + ((mediaTime - sourceStart) / scale);\n }\n\n #toMediaTime(canvasTime: number): number {\n const sourceStart = this.source?.segment?.start ?? 0;\n const targetStart = this.source?.canvasTarget?.start ?? 0;\n const scale = this.source?.timeMode === 'scale' ? this.#timelineScale : 1;\n return sourceStart + ((canvasTime - targetStart) * scale);\n }\n}\n"],"mappings":";AAwSO,IAAM,iBAA4B;AAAA,EACvC,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,UAAU;AAAA,EACV,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,MAAM;AAAA,EACN,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,UAAU;AAAA,EACV,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,yBAAyB;AAAA,EACzB,eAAe;AAAA,EACf,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,qBAAqB;AAAA,EACrB,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,sBAAsB;AAAA,EACtB,kBAAkB;AAAA,EAClB,yBAAyB;AAC3B;AAEO,IAAM,gBAET;AAAA,EACF,UAAU;AAAA,IACR,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,cAAc;AAAA,IACd,kBAAkB;AAAA,IAClB,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,UAAU;AAAA,IACV,aAAa;AAAA,EACf;AAAA,EACA,QAAQ;AAAA,IACN,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,UAAU;AAAA,IACV,mBAAmB;AAAA,EACrB;AAAA,EACA,YAAY;AAAA,IACV,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,WAAW;AAAA,IACX,cAAc;AAAA,IACd,mBAAmB;AAAA,EACrB;AAAA,EACA,QAAQ;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,IACV,SAAS;AAAA,IACT,QAAQ;AAAA,EACV;AAAA,EACA,SAAS;AAAA,EACT,oBAAoB,CAAC,MAAM,MAAM;AAAA,EACjC,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,aAAa;AAAA,EACb,SAAS;AAAA,EACT,eAAe,CAAC,KAAK,MAAM,GAAG,MAAM,KAAK,CAAC;AAC5C;;;AC9XO,IAAM,WAAW,CAAC,UACvB,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAC9D,QACD;AAEC,IAAM,UAAU,CAAI,UAA2C;AACpE,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO,CAAC;AACnD,SAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAC9C;AAEO,IAAM,SAAS,CAAC,UAAuC;AAC5D,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,SAAS,SAAS,KAAK;AAC7B,QAAM,KAAK,QAAQ,MAAM,SAAS,KAAK;AACvC,SAAO,OAAO,OAAO,WAAW,KAAK;AACvC;AAEO,IAAM,WAAW,CAAC,UAAuC;AAC9D,QAAM,SAAS,SAAS,KAAK;AAC7B,QAAM,OAAO,QAAQ,QAAQ,SAAS,OAAO;AAC7C,SAAO,OAAO,SAAS,WAAW,OAAO;AAC3C;AAEO,IAAM,iBAAiB,CAAC,UAAqC;AAClE,MAAI,OAAO,UAAU,SAAU,QAAO,CAAC,EAAE,MAAM,CAAC;AAChD,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,QAAQ,CAAC,SAAS,eAAe,IAAI,CAAC;AAAA,EACrD;AACA,QAAM,SAAS,SAAS,KAAK;AAC7B,MAAI,CAAC,OAAQ,QAAO,CAAC;AACrB,MAAI,OAAO,OAAO,QAAQ,MAAM,UAAU;AACxC,UAAM,SAAyB,EAAE,OAAO,OAAO,QAAQ,EAAE;AACzD,QAAI,OAAO,OAAO,WAAW,MAAM,SAAU,QAAO,WAAW,OAAO,WAAW;AACjF,WAAO,CAAC,MAAM;AAAA,EAChB;AACA,SAAO,OAAO,QAAQ,MAAM,EAAE;AAAA,IAAQ,CAAC,CAAC,UAAU,MAAM,MACtD,QAAQ,MAAM,EAAE;AAAA,MAAQ,CAAC,SACvB,OAAO,SAAS,WACZ,CAAC,EAAE,UAAU,OAAO,KAAK,CAAC,IAC1B,eAAe,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,GAAG,OAAO,UAAU,MAAM,YAAY,SAAS,EAAE;AAAA,IAC9F;AAAA,EACF;AACF;AAEO,IAAM,QAAQ,CACnB,OACA,qBAA+B,CAAC,MAAM,MAAM,GAC5C,WAAW,OACA;AACX,QAAM,SAAS,eAAe,KAAK;AACnC,aAAW,YAAY,oBAAoB;AACzC,UAAM,QAAQ,OAAO,KAAK,CAAC,SAAS,KAAK,aAAa,QAAQ;AAC9D,QAAI,MAAO,QAAO,MAAM;AAAA,EAC1B;AACA,SAAO,OAAO,CAAC,GAAG,SAAS;AAC7B;AAEO,IAAM,YAAY,CAAC,UAA2D;AACnF,MAAI,OAAO,UAAU,SAAU,QAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AACvE,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,kBAAkB,KAAK,KAAK,EAAG,QAAO,OAAO,KAAK;AACtD,QAAM,QAAQ,MAAM,QAAQ,KAAK,GAAG,EAAE,MAAM,GAAG,EAAE,IAAI,MAAM;AAC3D,MAAI,MAAM,KAAK,CAAC,SAAS,CAAC,OAAO,SAAS,IAAI,CAAC,EAAG,QAAO;AACzD,MAAI,MAAM,WAAW,EAAG,SAAQ,MAAM,CAAC,KAAK,KAAK,QAAQ,MAAM,CAAC,KAAK,KAAK,MAAM,MAAM,CAAC,KAAK;AAC5F,MAAI,MAAM,WAAW,EAAG,SAAQ,MAAM,CAAC,KAAK,KAAK,MAAM,MAAM,CAAC,KAAK;AACnE,SAAO;AACT;AAEO,IAAM,wBAAwB,CAAC,WAA0C;AAC9E,MAAI;AACJ,MAAI,OAAO,WAAW,SAAU,YAAW,OAAO,MAAM,GAAG,EAAE,CAAC;AAC9D,QAAM,SAAS,SAAS,MAAM;AAC9B,MAAI,CAAC,YAAY,QAAQ;AACvB,UAAM,WAAW,SAAS,OAAO,QAAQ;AACzC,UAAM,QAAQ,UAAU;AACxB,QAAI,OAAO,UAAU,SAAU,YAAW,MAAM,QAAQ,MAAM,EAAE;AAChE,QAAI,UAAU,SAAS,mBAAmB,OAAO,SAAS,MAAM,UAAU;AACxE,aAAO,EAAE,OAAO,SAAS,EAAE;AAAA,IAC7B;AAAA,EACF;AACA,QAAM,OAAO,UAAU,MAAM,kBAAkB,IAAI,CAAC;AACpD,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,CAAC,YAAY,QAAQ,IAAI,KAAK,MAAM,GAAG;AAC7C,QAAM,QAAQ,UAAU,UAAU;AAClC,QAAM,MAAM,UAAU,QAAQ;AAC9B,MAAI,UAAU,OAAW,QAAO;AAChC,SAAO,QAAQ,SAAY,EAAE,MAAM,IAAI,EAAE,OAAO,IAAI;AACtD;AAEO,IAAM,kBAAkB,CAAC,UAA0B,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK;AAE1E,IAAM,QAAQ,CAAC,KAAa,WACjC,wBAAwB,KAAK,GAAG,KAChC,WAAW,mCACX,WAAW;AAEN,IAAM,YAAY,CAAC,MAAe,QAAiB,MAAM,OAAsC;AACpG,QAAM,WAAW,GAAG,QAAQ,EAAE,IAAI,UAAU,EAAE,IAAI,GAAG,GAAG,YAAY;AACpE,MAAI,4EAA4E,KAAK,QAAQ,EAAG,QAAO;AACvG,MAAI,sEAAsE,KAAK,QAAQ,EAAG,QAAO;AACjG,SAAO;AACT;AAEO,IAAM,aAAa,CAAC,YAA4B;AACrD,MAAI,CAAC,OAAO,SAAS,OAAO,EAAG,QAAO;AACtC,QAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,CAAC;AAC7C,QAAM,QAAQ,KAAK,MAAM,QAAQ,IAAI;AACrC,QAAM,UAAU,KAAK,MAAO,QAAQ,OAAQ,EAAE;AAC9C,QAAM,YAAY,QAAQ;AAC1B,SAAO,QAAQ,IACX,GAAG,KAAK,IAAI,OAAO,OAAO,EAAE,SAAS,GAAG,GAAG,CAAC,IAAI,OAAO,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC,KAClF,GAAG,OAAO,IAAI,OAAO,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC;AACtD;AAEO,IAAM,iBAAiB,CAACA,WAA8B,CAAC,OAAkB;AAAA,EAC9E,GAAG;AAAA,EACH,GAAGA;AACL;AAEO,IAAM,eAAe,CAC1B,UACA,SAA0C,CAAC,MAChC,SAAS;AAAA,EAAQ;AAAA,EAAc,CAAC,aAAa,SACxD,OAAO,UAAU,eAAe,KAAK,QAAQ,IAAI,IAAI,OAAO,OAAO,IAAI,CAAC,IAAI;AAC9E;AAEO,IAAM,cAAc,CAAoC,MAAS,WAA0B;AAChG,QAAM,SAAS,EAAE,GAAG,KAAK;AACzB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,QAAI,UAAU,UAAa,SAAS,KAAK,KAAK,SAAS,OAAO,GAAG,CAAC,GAAG;AACnE,aAAO,GAAc,IAAI;AAAA,QACvB,SAAS,OAAO,GAAG,CAAC;AAAA,QACpB,SAAS,KAAK;AAAA,MAChB;AAAA,IACF,WAAW,UAAU,QAAW;AAC9B,aAAO,GAAc,IAAI;AAAA,IAC3B;AAAA,EACF;AACA,SAAO;AACT;AAEO,IAAM,aAAa,CAAC,UACzB,MAAM,QAAQ,YAAY,CAAC,eAAe;AAAA,EACxC,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACP,GAAG,SAAS,KAAK,SAAS;;;ACjH5B,IAAM,UAAU,CAAC,UACf,QAAQ,KAAK,EAAE,QAAQ,CAAC,SAAU,OAAO,SAAS,WAAW,CAAC,IAAI,IAAI,CAAC,CAAE;AAE3E,IAAM,SAAS,CAAC,UACd,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,IAAI,QAAQ;AAEhE,IAAM,aAAa,CAAC,WAClB,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS;AAEtD,IAAM,WAAW,CAAC,OAAgB,WAAqB,OACrD,QAAQ,KAAK,EAAE,QAAQ,CAAC,SAAS;AAC/B,QAAM,SAAS,SAAS,IAAI;AAC5B,MAAI,CAAC,OAAQ,QAAO,CAAC;AACrB,QAAM,SAAS,eAAe,OAAO,KAAK;AAC1C,MAAI,OAAO,WAAW,EAAG,QAAO,CAAC;AACjC,SAAO,CAAC,EAAE,OAAO,MAAM,OAAO,OAAO,WAAW,GAAG,QAAQ,GAAG,OAAO,CAAC;AACxE,CAAC;AAEH,IAAM,YAAY,CAAC,OAAgB,WAAqB,OACtD,QAAQ,KAAK,EAAE,QAAQ,CAAC,SAAS;AAC/B,QAAM,SAAS,SAAS,IAAI;AAC5B,QAAM,KAAK,OAAO,IAAI;AACtB,MAAI,CAAC,UAAU,CAAC,GAAI,QAAO,CAAC;AAC5B,QAAM,SAA2B;AAAA,IAC/B;AAAA,IACA,OAAO,MAAM,OAAO,OAAO,WAAW,GAAG,MAAM,GAAG,EAAE,IAAI,KAAK,GAAG,QAAQ;AAAA,EAC1E;AACA,QAAM,SAAS,WAAW,MAAM;AAChC,MAAI,OAAQ,QAAO,SAAS;AAC5B,QAAM,WAAW,OAAO,OAAO,aAAa,WAAW,OAAO,WAAW;AACzE,MAAI,SAAU,QAAO,WAAW;AAChC,SAAO,CAAC,MAAM;AAChB,CAAC;AAEH,IAAM,WAAW,CAAC,OAAgB,cAChC,QAAQ,KAAK,EAAE,QAAQ,CAAC,SAAS;AAC/B,QAAM,SAAS,SAAS,IAAI;AAC5B,QAAM,KAAK,OAAO,IAAI;AACtB,MAAI,CAAC,UAAU,CAAC,GAAI,QAAO,CAAC;AAC5B,QAAM,UAAU,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU;AACtE,QAAM,OAAO,GAAG,SAAS,MAAM,KAAK,EAAE,IAAI,WAAW,EAAE,GAAG,YAAY;AACtE,MAAI,cAA0C;AAC9C,MAAI,KAAK,SAAS,OAAO,EAAG,eAAc;AAAA,WACjC,KAAK,SAAS,OAAO,EAAG,eAAc;AAAA,WACtC,KAAK,SAAS,QAAQ,EAAG,eAAc;AAAA,WACvC,KAAK,SAAS,QAAQ,KAAK,KAAK,SAAS,OAAO,KAAK,KAAK,SAAS,cAAc,KAAK,KAAK,SAAS,OAAO,EAAG,eAAc;AACrI,QAAM,SAAsB;AAAA,IAC1B;AAAA,IACA;AAAA,IACA,UAAU,SAAS,OAAO,SAAS,SAAS;AAAA,EAC9C;AACA,MAAI,QAAS,QAAO,UAAU;AAC9B,QAAM,eAAe,MAAM,OAAO,OAAO,SAAS;AAClD,MAAI,aAAc,QAAO,QAAQ;AACjC,SAAO,CAAC,MAAM;AAChB,CAAC;AAEH,IAAM,iBAAiB,CAAC,gBAA6C;AACnE,QAAM,SAAS,SAAS,WAAW;AACnC,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,SAAS,SAAS,QAAQ,OAAO,KAAK,EAAE,CAAC,CAAC;AAChD,QAAM,eAAe,SAAS,QAAQ,QAAQ,KAAK,EAAE,CAAC,CAAC;AACvD,QAAM,SAAS,SAAS,QAAQ,cAAc,IAAI,EAAE,CAAC,CAAC;AACtD,QAAM,eAAe,SAAS,QAAQ,OAAO,MAAM,EAAE,CAAC,CAAC;AACvD,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,SAAO,OAAO,MAAM,KAAK,OAAO,MAAM;AACxC;AAEA,IAAM,YAAY,CAAC,SAAgC;AACjD,QAAM,SAAS,QAAQ,IAAI,EAAE,QAAQ,CAAC,SAAS;AAC7C,UAAM,SAAS,SAAS,IAAI;AAC5B,QAAI,CAAC,OAAQ,QAAO,CAAC;AACrB,UAAM,OAAO,SAAS,MAAM,GAAG,YAAY;AAC3C,QAAI,MAAM,SAAS,QAAQ,KAAK,MAAM,QAAQ,OAAO,KAAK,KAAK,MAAM,QAAQ,OAAO,IAAI,GAAG;AACzF,aAAO,QAAQ,OAAO,SAAS,OAAO,QAAQ,OAAO,OAAO,EAAE,QAAQ,CAAC,WAAW;AAChF,cAAM,eAAe,SAAS,MAAM;AACpC,eAAO,eAAe,CAAC,YAAY,IAAI,CAAC;AAAA,MAC1C,CAAC;AAAA,IACH;AACA,WAAO,CAAC,MAAM;AAAA,EAChB,CAAC;AACD,SAAO;AACT;AAEA,IAAM,iBAAiB,CACrB,MACA,QACA,QACA,WACA,OACA,IACA,uBAC4B;AAC5B,QAAM,aAAa,OAAO,IAAI;AAC9B,MAAI,CAAC,WAAY,QAAO;AACxB,QAAM,SAAS,WAAW,IAAI;AAC9B,QAAM,OAAO,UAAU,SAAS,IAAI,GAAG,QAAQ,UAAU;AACzD,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,SAAsB;AAAA,IAC1B,IAAI;AAAA,IACJ,KAAK,gBAAgB,UAAU;AAAA,IAC/B;AAAA,IACA,OAAO,MAAM,YAAY,MAAM;AAAA,EACjC;AACA,MAAI,OAAQ,QAAO,SAAS;AAC5B,QAAM,YAAY,MAAM,KAAK,OAAO,WAAW,UAAU,IACrD,GAAG,aACH,aAAa,GAAG,cAAc,EAAE,QAAQ,QAAQ,EAAE,CAAC,CAAC;AACxD,MAAI,UAAW,QAAO,QAAQ;AAC9B,QAAM,QAAQ,OAAO,KAAK,KAAK,KAAK,OAAO,OAAO,KAAK;AACvD,QAAM,SAAS,OAAO,KAAK,MAAM,KAAK,OAAO,OAAO,MAAM;AAC1D,QAAM,WAAW,OAAO,KAAK,QAAQ,KAAK,OAAO,OAAO,QAAQ;AAChE,MAAI,UAAU,OAAW,QAAO,QAAQ;AACxC,MAAI,WAAW,OAAW,QAAO,SAAS;AAC1C,MAAI,aAAa,OAAW,QAAO,WAAW;AAC9C,QAAM,UAAU,OAAO,KAAK,YAAY,WAAW,KAAK,UAAU;AAClE,MAAI,QAAS,QAAO,UAAU;AAC9B,QAAM,UAAU,sBAAsB,UAAU;AAChD,MAAI,QAAS,QAAO,UAAU;AAC9B,QAAM,eAAe,sBAAsB,MAAM;AACjD,MAAI,aAAc,QAAO,eAAe;AACxC,QAAM,WAAW,KAAK,YAAY;AAClC,MAAI,aAAa,UAAU,aAAa,WAAW,aAAa,OAAQ,QAAO,WAAW;AAC1F,SAAO;AACT;AAEA,IAAM,gBAAgB,CAAC,SACrB,UAAU,IAAI,EAAE,OAAO,CAAC,SAAS;AAC/B,QAAM,OAAO,SAAS,IAAI,GAAG,YAAY;AACzC,SAAO,MAAM,SAAS,aAAa,KAAK,OAAO,KAAK,UAAU;AAChE,CAAC;AAEH,IAAM,wBAAwB,CAAC,eAAqC,QAAQ,WAAW,UAAU;AAEjG,IAAM,iBAAiB,CACrB,OACA,UACA,QACA,WACA,UAC6B;AAC7B,QAAM,aAAa,SAAS,KAAK;AACjC,MAAI,CAAC,WAAY,QAAO;AACxB,QAAM,SAAS,cAAc,WAAW,QAAQ,WAAW,QAAQ;AACnE,QAAM,OAAO,OACV,QAAQ,CAAC,SAAU,OAAO,KAAK,UAAU,WAAW,CAAC,KAAK,KAAK,IAAI,eAAe,KAAK,KAAK,EAAE,IAAI,CAAC,UAAU,MAAM,KAAK,CAAE,EAC1H,KAAK,IAAI;AACZ,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,aAAa,sBAAsB,UAAU;AACnD,QAAM,UAAU,OAAO,QAAQ,CAAC,SAAS,QAAQ,KAAK,OAAO,CAAC;AAC9D,QAAM,OAAO,OACV,OAAO,CAAC,SAAS,QAAQ,KAAK,OAAO,EAAE,SAAS,SAAS,CAAC,EAC1D,QAAQ,CAAC,SAAU,OAAO,KAAK,UAAU,WAAW,CAAC,KAAK,KAAK,IAAI,CAAC,CAAE;AACzE,QAAM,KAAK,OAAO,UAAU,KAAK,GAAG,QAAQ,eAAe,KAAK;AAChE,QAAM,SAAuB;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,kBAAkB,MAAM,WAAW,OAAO,SAAS;AACzD,MAAI,gBAAiB,QAAO,QAAQ;AACpC,QAAM,OAAO,sBAAsB,WAAW,UAAU,WAAW,EAAE;AACrE,MAAI,KAAM,QAAO,OAAO;AACxB,MAAI,OAAQ,QAAO,eAAe;AAClC,SAAO;AACT;AAEA,IAAM,qBAAqB,CACzB,MACA,YACA,UACA,WACA,OACA,OAC2D;AAC3D,QAAM,KAAK,OAAO,IAAI;AACtB,MAAI,CAAC,GAAI,QAAO,CAAC;AACjB,QAAM,SAAS,WAAW,IAAI;AAC9B,QAAM,YAAY,MAAM,KAAK,OAAO,WAAW,aAAa,GAAG,kBAAkB,EAAE,QAAQ,QAAQ,EAAE,CAAC,CAAC;AACvG,QAAM,WAAW,OAAO,KAAK,aAAa,WAAW,KAAK,WAAW;AACrE,QAAM,UAAU,QAAQ,KAAK,OAAO;AACpC,QAAM,QAAQ,GAAG,SAAS,IAAI,EAAE,IAAI,QAAQ,KAAK,GAAG,CAAC,GAAG,YAAY;AACpE,QAAM,eAAe,WAAW,cAAc,kBAAkB,KAAK,EAAE;AACvE,MAAI,OAA0B;AAC9B,MAAI,MAAM,SAAS,SAAS,EAAG,QAAO;AACtC,MAAI,MAAM,SAAS,aAAa,EAAG,QAAO;AAC1C,QAAM,SAAiE,CAAC;AACxE,MAAI,cAAc;AAChB,UAAM,QAAmB,EAAE,IAAI,KAAK,IAAI,MAAM,OAAO,UAAU;AAC/D,QAAI,SAAU,OAAM,WAAW;AAC/B,QAAI,OAAQ,OAAM,SAAS;AAC3B,QAAI,MAAM,SAAS,QAAQ,EAAG,OAAM,SAAS;AAC7C,WAAO,QAAQ;AAAA,EACjB;AACA,QAAM,aAAiC;AAAA,IACrC,IAAI,GAAG,QAAQ,eAAe,KAAK;AAAA,IACnC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,kBAAkB,4BAA4B,KAAK,SAAS;AAAA,EAC9D;AACA,MAAI,OAAQ,YAAW,SAAS;AAChC,MAAI,SAAU,YAAW,WAAW;AACpC,SAAO,aAAa;AACpB,SAAO;AACT;AAEA,IAAM,sBAAsB,CAAC,SAAgC,QAAQ,KAAK,SAAS,KAAK,SAAS;AAEjG,IAAM,uBAAuB,CAC3B,OACA,UACA,WACA,OAC4F;AAC5F,QAAM,SAAsB,CAAC;AAC7B,QAAM,cAAoC,CAAC;AAC3C,QAAM,cAA8B,CAAC;AACrC,MAAI,QAAQ;AACZ,aAAW,QAAQ,OAAO;AACxB,UAAM,SAAS,OAAO,IAAI;AAC1B,eAAW,QAAQ,oBAAoB,IAAI,GAAG;AAC5C,YAAM,aAAa,SAAS,IAAI;AAChC,UAAI,CAAC,WAAY;AACjB,YAAM,cAAc,sBAAsB,UAAU;AACpD,YAAM,uBAAuB,eAAe,YAAY,UAAU,QAAQ,WAAW,KAAK;AAC1F,UAAI,qBAAsB,aAAY,KAAK,oBAAoB;AAC/D,iBAAW,QAAQ,UAAU,WAAW,QAAQ,WAAW,QAAQ,GAAG;AACpE,cAAM,SAAS,OAAO,IAAI;AAC1B,YAAI,WAAW,YAAY,SAAS,eAAe,KAAK,YAAY,SAAS,cAAc,KAAK,YAAY,WAAW,IAAI;AACzH,gBAAM,aAAa,mBAAmB,MAAM,YAAY,UAAU,WAAW,OAAO,EAAE;AACtF,cAAI,WAAW,MAAO,QAAO,KAAK,WAAW,KAAK;AAClD,cAAI,WAAW,WAAY,aAAY,KAAK,WAAW,UAAU;AAAA,QACnE;AAAA,MACF;AACA,YAAM,SAAS,cAAc,WAAW,QAAQ,WAAW,QAAQ;AACnE,UAAI,OAAO,SAAS,MAAM,YAAY,SAAS,eAAe,KAAK,YAAY,SAAS,cAAc,IAAI;AACxG,cAAM,OAAwB,OAAO,QAAQ,CAAC,MAAM,cAAc;AAChE,gBAAM,OAAO,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ,MAAM,KAAK,OAAO,SAAS;AACtF,cAAI,CAAC,KAAM,QAAO,CAAC;AACnB,gBAAM,MAAqB;AAAA,YACzB,IAAI,GAAG,OAAO,UAAU,KAAK,GAAG,QAAQ,eAAe,KAAK,EAAE,QAAQ,SAAS;AAAA,YAC/E;AAAA,YACA,MAAM;AAAA,UACR;AACA,gBAAM,OAAO,sBAAsB,WAAW,UAAU,WAAW,EAAE;AACrE,cAAI,MAAM;AACR,gBAAI,QAAQ,KAAK;AACjB,gBAAI,KAAK,QAAQ,OAAW,KAAI,MAAM,KAAK;AAAA,UAC7C;AACA,iBAAO,CAAC,GAAG;AAAA,QACb,CAAC;AACD,YAAI,KAAK,SAAS,GAAG;AACnB,sBAAY,KAAK;AAAA,YACf,IAAI,GAAG,UAAU,QAAQ;AAAA,YACzB,OAAO,MAAM,KAAK,OAAO,WAAW,GAAG,UAAU;AAAA,YACjD,kBAAkB;AAAA,YAClB;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AACA,eAAS;AAAA,IACX;AAAA,EACF;AACA,SAAO,EAAE,QAAQ,aAAa,YAAY;AAC5C;AAEA,IAAM,sBAAsB,CAAC,QAAoB,YAAiC;AAChF,MAAI,YAAY,GAAG;AACjB,WAAO,QAAQ,OAAO,MAAM,EAAE,QAAQ,CAAC,SAAS;AAC9C,YAAM,SAAS,SAAS,IAAI;AAC5B,aAAO,SAAS,CAAC,MAAM,IAAI,CAAC;AAAA,IAC9B,CAAC;AAAA,EACH;AACA,SAAO,QAAQ,OAAO,KAAK,EAAE,QAAQ,CAAC,SAAS;AAC7C,UAAM,SAAS,SAAS,IAAI;AAC5B,WAAO,SAAS,oBAAoB,MAAM,EAAE,QAAQ,CAAC,SAAU,SAAS,IAAI,IAAI,CAAC,SAAS,IAAI,CAAe,IAAI,CAAC,CAAE,IAAI,CAAC;AAAA,EAC3H,CAAC;AACH;AAEA,IAAM,wBAAwB,CAAC,QAAoB,YAAiC;AAClF,QAAM,MAAM,YAAY,IAAI,OAAO,eAAe,OAAO;AACzD,SAAO,QAAQ,GAAG,EAAE,QAAQ,CAAC,SAAS;AACpC,UAAM,SAAS,SAAS,IAAI;AAC5B,WAAO,WAAW,MAAM,QAAQ,OAAO,KAAK,KAAK,MAAM,QAAQ,OAAO,SAAS,KAAK,CAAC,MAAM,IAAI,CAAC;AAAA,EAClG,CAAC;AACH;AAEA,IAAM,+BAA+B,CAAC,QAAoB,YAA6B;AACrF,QAAM,MAAM,YAAY,IAAI,OAAO,eAAe,OAAO;AACzD,SAAO,QAAQ,GAAG,EAAE,QAAQ,CAAC,SAAS;AACpC,UAAM,SAAS,SAAS,IAAI;AAC5B,QAAI,WAAW,MAAM,QAAQ,OAAO,KAAK,KAAK,MAAM,QAAQ,OAAO,SAAS,GAAI,QAAO,CAAC;AACxF,UAAM,KAAK,OAAO,IAAI;AACtB,WAAO,KAAK,CAAC,EAAE,IAAI,CAAC;AAAA,EACtB,CAAC;AACH;AAEA,IAAM,aAAa,CAAC,WAA2C;AAC7D,QAAM,cAAc,SAAS,OAAO,iBAAiB;AACrD,SAAO,eAAe,WAAW;AACnC;AAEA,IAAM,aAAa,CACjB,QACA,OACA,SACA,WACA,OACa;AACb,QAAM,KAAK,OAAO,MAAM,KAAK,oBAAoB,KAAK;AACtD,QAAM,UAAU,oBAAoB,QAAQ,OAAO,EAAE;AAAA,IAAQ,CAAC,YAAY,oBACxE,UAAU,WAAW,QAAQ,WAAW,QAAQ,EAAE,QAAQ,CAAC,MAAM,cAAc;AAC7E,YAAM,SAAS,eAAe,MAAM,QAAQ,WAAW,UAAU,WAAW,IAAI,WAAW,kBAAkB,WAAW,IAAI,WAAW,QAAQ;AAC/I,aAAO,SAAS,CAAC,MAAM,IAAI,CAAC;AAAA,IAC9B,CAAC;AAAA,EACH;AACA,QAAM,gBAAgB,qBAAqB,sBAAsB,QAAQ,OAAO,GAAG,IAAI,WAAW,EAAE;AACpG,QAAM,SAAmB;AAAA,IACvB;AAAA,IACA;AAAA,IACA,OAAO,MAAM,OAAO,OAAO,WAAW,aAAa,GAAG,eAAe,EAAE,QAAQ,QAAQ,EAAE,CAAC,CAAC;AAAA,IAC3F,UAAU,QAAQ,OAAO,YAAY,OAAO,WAAW;AAAA,IACvD;AAAA,IACA,QAAQ,cAAc;AAAA,IACtB,aAAa,cAAc;AAAA,IAC3B,aAAa,cAAc;AAAA,IAC3B,WAAW,UAAU,OAAO,WAAW,WAAW,EAAE;AAAA,IACpD,UAAU,SAAS,OAAO,UAAU,WAAW,EAAE;AAAA,IACjD,cAAc,SAAS,OAAO,SAAS,SAAS;AAAA,EAClD;AACA,QAAM,UAAU,MAAM,OAAO,WAAW,OAAO,aAAa,SAAS;AACrE,MAAI,QAAS,QAAO,UAAU;AAC9B,QAAM,WAAW,OAAO,OAAO,QAAQ;AACvC,QAAM,QAAQ,OAAO,OAAO,KAAK;AACjC,QAAM,SAAS,OAAO,OAAO,MAAM;AACnC,MAAI,aAAa,OAAW,QAAO,WAAW;AAC9C,MAAI,UAAU,OAAW,QAAO,QAAQ;AACxC,MAAI,WAAW,OAAW,QAAO,SAAS;AAC1C,QAAM,SAAS,WAAW,MAAM;AAChC,MAAI,OAAQ,QAAO,SAAS;AAC5B,QAAM,eAAe,OAAO,OAAO,kBAAkB;AACrD,MAAI,aAAc,QAAO,qBAAqB;AAC9C,QAAM,WAAW,OAAO,QAAQ,OAAO,YAAY,OAAO,OAAO,EAAE,CAAC,CAAC;AACrE,MAAI,SAAU,QAAO,WAAW;AAChC,SAAO;AACT;AAEA,IAAM,qBAAqB,CAAC,UAAkF;AAC5G,QAAM,KAAK,OAAO,KAAK,KAAK,OAAO,SAAS,KAAK,GAAG,MAAM;AAC1D,MAAI,CAAC,GAAI,QAAO,CAAC;AACjB,QAAM,SAAwE,EAAE,UAAU,gBAAgB,EAAE,EAAE;AAC9G,QAAM,OAAO,sBAAsB,EAAE;AACrC,MAAI,KAAM,QAAO,OAAO;AACxB,SAAO;AACT;AAEA,IAAM,eAAe,CAAC,UAAsB,SAAgB,WAAqB,OAA6B;AAC5G,QAAM,gBAAgB,QAAQ,SAAS,UAAU,EAAE,QAAQ,CAAC,SAAU,SAAS,IAAI,IAAI,CAAC,SAAS,IAAI,CAAe,IAAI,CAAC,CAAE;AAC3H,QAAM,OAAO,IAAI,IAAI,cAAc,IAAI,CAAC,UAAU,CAAC,OAAO,KAAK,GAAG,KAAK,CAAC,CAAC;AACzE,QAAM,OAAO,oBAAI,IAAgB;AAEjC,QAAM,aAAa,CAAC,OAAmB,QAAQ,MAA2B;AACxE,QAAI,QAAQ,MAAM,KAAK,IAAI,KAAK,EAAG,QAAO;AAC1C,SAAK,IAAI,KAAK;AACd,UAAM,gBAAgB,QAAQ,MAAM,YAAY,MAAM,WAAW;AACjE,QAAI,cAAc,SAAS,QAAQ,KAAK,cAAc,SAAS,eAAe,EAAG,QAAO;AACxF,UAAM,KAAK,OAAO,KAAK,KAAK,mBAAmB,KAAK,IAAI;AACxD,UAAM,UAAU,YAAY,IACxB,QAAQ,MAAM,KAAK,IACnB,QAAQ,MAAM,WAAW,MAAM,UAAU,MAAM,QAAQ;AAC3D,UAAM,WAAsB,CAAC;AAC7B,QAAI,SAAgD,CAAC;AACrD,eAAW,UAAU,SAAS;AAC5B,YAAM,SAAS,SAAS,MAAM;AAC9B,YAAM,WAAW,OAAO,MAAM;AAC9B,YAAM,aAAa,SAAS,MAAM,GAAG,YAAY;AACjD,YAAM,kBAAkB,WAAW,KAAK,IAAI,QAAQ,IAAI;AACxD,UAAI,mBAAmB,YAAY,SAAS,OAAO,KAAM,WAAW,OAAO,SAAS,OAAO,UAAU,OAAO,UAAW;AACrH,cAAM,QAAQ,WAAW,mBAAoB,QAAuB,QAAQ,CAAC;AAC7E,YAAI,MAAO,UAAS,KAAK,KAAK;AAAA,MAChC,WAAW,CAAC,OAAO,YAAY,UAAU;AACvC,iBAAS,mBAAmB,MAAM;AAAA,MACpC;AAAA,IACF;AACA,UAAM,SAAkB;AAAA,MACtB;AAAA,MACA,OAAO,MAAM,MAAM,OAAO,WAAW,aAAa,GAAG,eAAe,EAAE,QAAQ,KAAK,KAAK,CAAC,CAAC;AAAA,MAC1F,UAAU;AAAA,MACV;AAAA,IACF;AACA,QAAI,OAAO,SAAU,QAAO,WAAW,OAAO;AAC9C,QAAI,OAAO,KAAM,QAAO,OAAO,OAAO;AACtC,UAAM,UAAU,MAAM,MAAM,WAAW,MAAM,aAAa,SAAS;AACnE,QAAI,QAAS,QAAO,UAAU;AAC9B,UAAM,WAAW,OAAO,QAAQ,MAAM,YAAY,MAAM,OAAO,EAAE,CAAC,CAAC;AACnE,QAAI,SAAU,QAAO,WAAW;AAChC,WAAO;AAAA,EACT;AAEA,SAAO,cAAc,QAAQ,CAAC,UAAU;AACtC,UAAM,UAAU,WAAW,KAAK;AAChC,WAAO,UAAU,CAAC,OAAO,IAAI,CAAC;AAAA,EAChC,CAAC;AACH;AAEA,IAAM,YAAY,CAAC,UAAsB,YAAwC;AAC/E,QAAM,QAAQ,YAAY,IACtB,SAAS,QAAQ,SAAS,SAAS,EAAE,CAAC,CAAC,GAAG,eAAe,SAAS,cAClE,SAAS;AACb,QAAM,KAAK,OAAO,KAAK,KAAK,OAAO,SAAS,KAAK,GAAG,MAAM;AAC1D,MAAI,CAAC,GAAI,QAAO;AAChB,QAAM,SAA2C,EAAE,UAAU,gBAAgB,EAAE,EAAE;AACjF,QAAM,OAAO,sBAAsB,KAAK,KAAK,sBAAsB,EAAE;AACrE,MAAI,KAAM,QAAO,OAAO,KAAK;AAC7B,SAAO;AACT;AAEA,IAAM,mBAAmB,CAAC,UAAsB,YAAiC;AAC/E,QAAM,MAAM,YAAY,IACpB,SAAS,QACT,SAAS,QAAQ,SAAS,SAAS,EAAE,CAAC,CAAC,GAAG;AAC9C,SAAO,QAAQ,GAAG,EAAE,QAAQ,CAAC,SAAU,SAAS,IAAI,IAAI,CAAC,SAAS,IAAI,CAAe,IAAI,CAAC,CAAE;AAC9F;AAEA,IAAM,gBAAgB,CAAC,aAAgC;AACrD,QAAM,UAAU,KAAK,UAAU,SAAS,UAAU,KAAK,EAAE;AACzD,MAAI,QAAQ,SAAS,kBAAkB,EAAG,QAAO;AACjD,MAAI,MAAM,QAAQ,SAAS,SAAS,KAAK,SAAS,QAAQ,GAAG,WAAW,KAAK,EAAG,QAAO;AACvF,SAAO;AACT;AAEO,IAAM,oBAAoB,OAC/B,OACA,UAA4B,CAAC,MACL;AACxB,QAAM,KAAK,eAAe,QAAQ,OAAO;AACzC,QAAM,UAAU,QAAQ,SAAS,WAAW;AAC5C,MAAI;AACJ,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI,MAAM,KAAK,EAAE,WAAW,GAAG,GAAG;AAChC,eAAS,KAAK,MAAM,KAAK;AAAA,IAC3B,OAAO;AACL,UAAI,CAAC,QAAS,OAAM,IAAI,MAAM,iEAAiE;AAC/F,YAAM,WAAW,MAAM,QAAQ,OAAO,QAAQ,WAAW;AACzD,UAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,aAAa,GAAG,sBAAsB;AAAA,QACtE,QAAQ,SAAS;AAAA,QACjB,YAAY,SAAS;AAAA,MACvB,CAAC,CAAC;AACF,eAAS,MAAM,SAAS,KAAK;AAAA,IAC/B;AAAA,EACF,OAAO;AACL,aAAS;AAAA,EACX;AACA,QAAM,OAAO,SAAS,MAAM,GAAG,YAAY;AAC3C,MAAI,QAAQ,CAAC,KAAK,SAAS,UAAU,EAAG,OAAM,IAAI,MAAM,aAAa,GAAG,kBAAkB;AAAA,IACxF,MAAM,SAAS,MAAM,KAAK;AAAA,EAC5B,CAAC,CAAC;AACF,QAAM,UAAU,cAAc,MAAM;AACpC,QAAM,YAAY,QAAQ,sBAAsB,CAAC,MAAM,MAAM;AAC7D,QAAM,WAAW,iBAAiB,QAAQ,OAAO,EAAE,IAAI,CAAC,QAAQ,UAAU,WAAW,QAAQ,OAAO,SAAS,WAAW,EAAE,CAAC;AAC3H,MAAI,SAAS,WAAW,EAAG,OAAM,IAAI,MAAM,GAAG,uBAAuB;AAErE,MAAI,QAAQ,4BAA4B,SAAS,SAAS;AACxD,UAAM,cAAc,iBAAiB,QAAQ,OAAO;AACpD,UAAM,QAAQ,IAAI,YAAY,IAAI,OAAO,QAAQ,UAAU;AACzD,YAAM,SAAS,SAAS,KAAK;AAC7B,UAAI,CAAC,OAAQ;AACb,YAAM,aAAa,6BAA6B,QAAQ,OAAO;AAC/D,YAAM,SAAS,MAAM,QAAQ,IAAI,WAAW,IAAI,OAAO,QAAQ;AAC7D,YAAI;AACF,gBAAM,WAAW,MAAM,QAAQ,KAAK,QAAQ,WAAW;AACvD,cAAI,CAAC,SAAS,GAAI,QAAO;AACzB,iBAAO,SAAS,MAAM,SAAS,KAAK,CAAC;AAAA,QACvC,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF,CAAC,CAAC;AACF,YAAM,SAAS,qBAAqB,OAAO,OAAO,CAAC,SAA6B,QAAQ,IAAI,CAAC,GAAG,OAAO,IAAI,WAAW,EAAE;AACxH,aAAO,OAAO,KAAK,GAAG,OAAO,MAAM;AACnC,aAAO,YAAY,KAAK,GAAG,OAAO,WAAW;AAC7C,aAAO,YAAY,KAAK,GAAG,OAAO,WAAW;AAAA,IAC/C,CAAC,CAAC;AAAA,EACJ;AAEA,QAAM,KAAK,OAAO,MAAM,KAAK;AAC7B,QAAM,SAAqB;AAAA,IACzB;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA,OAAO,MAAM,OAAO,OAAO,WAAW,GAAG,gBAAgB;AAAA,IACzD,UAAU,QAAQ,OAAO,YAAY,OAAO,WAAW;AAAA,IACvD;AAAA,IACA,UAAU,aAAa,QAAQ,SAAS,WAAW,EAAE;AAAA,IACrD,UAAU,SAAS,OAAO,UAAU,WAAW,EAAE;AAAA,IACjD,WAAW,UAAU,OAAO,WAAW,WAAW,EAAE;AAAA,EACtD;AACA,QAAM,UAAU,MAAM,OAAO,WAAW,OAAO,aAAa,SAAS;AACrE,MAAI,QAAS,QAAO,UAAU;AAC9B,QAAM,QAAQ,UAAU,QAAQ,OAAO;AACvC,MAAI,MAAO,QAAO,QAAQ;AAC1B,MAAI,OAAO,OAAO,WAAW,SAAU,QAAO,SAAS,OAAO;AAC9D,QAAM,oBAAoB,SAAS,CAAC,OAAO,qBAAqB,OAAO,WAAW,GAAG,WAAW,EAAE,EAAE,CAAC;AACrG,MAAI,kBAAmB,QAAO,oBAAoB;AAClD,QAAM,WAAW,OAAO,QAAQ,OAAO,YAAY,OAAO,OAAO,EAAE,CAAC,CAAC;AACrE,MAAI,SAAU,QAAO,WAAW;AAChC,QAAM,OAAO,OAAO,QAAQ,OAAO,QAAQ,OAAO,QAAQ,EAAE,CAAC,CAAC;AAC9D,MAAI,KAAM,QAAO,OAAO;AACxB,SAAO;AACT;;;AC/gBA,IAAM,iBAAiB;AAEhB,IAAM,qBAAN,cAAiC,YAAY;AAAA,EAClD;AAAA,EACA,SAAwB;AAAA,IACtB,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,cAAc;AAAA,IACd,aAAa;AAAA,IACb,QAAQ;AAAA,EACV;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB;AAAA,EACA,kBAAkB,oBAAI,IAA2B;AAAA,EAEjD,YAAY,SAAyB,CAAC,GAAG;AACvC,UAAM;AACN,SAAK,UAAU,YAAY,eAAe,MAAM;AAChD,SAAK,OAAO,cAAc,KAAK,QAAQ;AACvC,SAAK,OAAO,SAAS,KAAK,QAAQ;AAAA,EACpC;AAAA,EAEA,IAAI,SAAmC;AACrC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,QAAiC;AACnC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,WAAmC;AACrC,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,IAAI,SAA+B;AACjC,WAAO,KAAK,OAAO,UAAU,SAAS,KAAK,OAAO,WAAW;AAAA,EAC/D;AAAA,EAEA,IAAI,SAAkC;AACpC,WAAO,KAAK,QAAQ,QAAQ,KAAK,OAAO,WAAW;AAAA,EACrD;AAAA,EAEA,IAAI,QAAsC;AACxC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,GACE,MACA,UACY;AACZ,UAAM,gBAAgB;AACtB,SAAK,iBAAiB,MAAM,aAAa;AACzC,WAAO,MAAM,KAAK,oBAAoB,MAAM,aAAa;AAAA,EAC3D;AAAA,EAEA,UAAU,QAA8B;AACtC,SAAK,UAAU;AAAA,MACb,KAAK;AAAA,MACL;AAAA,IACF;AACA,QAAI,OAAO,gBAAgB,OAAW,MAAK,OAAO,cAAc,OAAO;AACvE,QAAI,OAAO,WAAW,OAAW,MAAK,OAAO,SAAS,OAAO;AAC7D,SAAK,MAAM,mBAAmB,EAAE,QAAQ,KAAK,QAAQ,CAAC;AACtD,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,MAAM,KAAK,OAAiD;AAC1D,SAAK,OAAO,SAAS;AACrB,WAAO,KAAK,OAAO;AACnB,SAAK,MAAM,gBAAgB,EAAE,QAAQ,MAAM,CAAC;AAC5C,SAAK,WAAW;AAChB,QAAI;AACF,YAAM,mBAA4D;AAAA,QAChE,oBAAoB,KAAK,QAAQ;AAAA,QACjC,SAAS,KAAK,QAAQ;AAAA,MACxB;AACA,UAAI,KAAK,QAAQ,MAAO,kBAAiB,QAAQ,KAAK,QAAQ;AAC9D,UAAI,KAAK,QAAQ,YAAa,kBAAiB,cAAc,KAAK,QAAQ;AAC1E,YAAM,WAAW,MAAM,kBAAkB,OAAO,gBAAgB;AAChE,WAAK,OAAO,WAAW;AACvB,YAAM,kBAAkB,KAAK,QAAQ,iBAAiB,SAAS,OAAO;AACtE,YAAM,cAAc,kBAChB,KAAK,IAAI,GAAG,SAAS,SAAS,UAAU,CAACC,YAAWA,QAAO,OAAO,gBAAgB,eAAe,CAAC,CAAC,IACnG;AACJ,WAAK,OAAO,cAAc;AAC1B,WAAK,OAAO,cAAc;AAC1B,WAAK,iBAAiB;AACtB,WAAK,OAAO,cAAc;AAC1B,WAAK,OAAO,WAAW,KAAK,QAAQ,YAAY;AAChD,WAAK,OAAO,cAAc,KAAK,QAAQ,eAAe,SAAS,SAAS,SAAS,cAAc;AAC/F,WAAK,OAAO,SAAS,KAAK,QAAQ,UAAU,SAAS,SAAS,SAAS,QAAQ;AAC/E,WAAK,OAAO,SAAS;AACrB,YAAM,cAAc,KAAK,QAAQ,aAAa,SAAS,OAAO,QAAQ,KAAK,QAAQ,cAAc;AACjG,UAAI,gBAAgB,OAAW,MAAK,eAAe;AACnD,WAAK,MAAM,YAAY,EAAE,SAAS,CAAC;AACnC,YAAM,SAAS,KAAK;AACpB,UAAI,OAAQ,MAAK,MAAM,mBAAmB,EAAE,QAAQ,YAAY,CAAC;AACjE,WAAK,WAAW;AAChB,aAAO;AAAA,IACT,SAAS,OAAO;AACd,YAAM,QAAQ,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AACtE,WAAK,OAAO,SAAS;AACrB,WAAK,OAAO,QAAQ;AACpB,WAAK,MAAM,YAAY,EAAE,MAAM,CAAC;AAChC,WAAK,WAAW;AAChB,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,YAAY,OAA+B;AACzC,QAAI,KAAK,WAAW,MAAO;AAC3B,SAAK,YAAY;AACjB,SAAK,SAAS;AACd,UAAM,YAA2C;AAAA,MAC/C,gBAAgB,MAAM;AACpB,cAAM,UAAU,KAAK,QAAQ;AAC7B,cAAM,SAAS,KAAK,QAAQ;AAC5B,YAAI,KAAK,QAAQ,aAAa,WAAW,QAAQ,QAAQ,UAAa,OAAO,SAAS,MAAM,QAAQ,GAAG;AACrG,gBAAM,iBAAiB,SAAS,QAAQ,SAAY,QAAQ,MAAM,QAAQ,QAAQ,MAAM;AACxF,gBAAM,iBAAiB,OAAO,MAAM,OAAO;AAC3C,cAAI,iBAAiB,KAAK,iBAAiB,GAAG;AAC5C,iBAAK,iBAAiB,iBAAiB;AACvC,kBAAM,eAAe,KAAK;AAAA,UAC5B;AAAA,QACF;AACA,cAAM,UAAU,KAAK,gBAAgB,QAAQ;AAC7C,YAAI,YAAY,QAAW;AACzB,gBAAM,cAAc,KAAK,aAAa,OAAO;AAC7C,eAAK,eAAe;AAAA,QACtB;AACA,aAAK,OAAO,WAAW,KAAK,QAAQ,YAAY,QAAQ,QAAQ,OAAO,SAAS,MAAM,QAAQ,IAAI,KAAK,cAAc,MAAM,QAAQ,IAAI;AACvI,aAAK,WAAW;AAAA,MAClB;AAAA,MACA,MAAM,MAAM;AACV,aAAK,OAAO,SAAS;AACrB,aAAK,MAAM,WAAW,EAAE,UAAU,KAAK,QAAQ,MAAM,IAAI,MAAM,KAAK,cAAc,MAAM,WAAW,EAAE,CAAC;AACtG,aAAK,WAAW;AAAA,MAClB;AAAA,MACA,OAAO,MAAM;AACX,YAAI,CAAC,MAAM,MAAO,MAAK,OAAO,SAAS;AACvC,aAAK,cAAc;AACnB,aAAK,MAAM,YAAY,EAAE,UAAU,KAAK,QAAQ,MAAM,IAAI,MAAM,KAAK,cAAc,MAAM,WAAW,EAAE,CAAC;AACvG,aAAK,WAAW;AAAA,MAClB;AAAA,MACA,YAAY,MAAM;AAChB,cAAM,OAAO,KAAK,cAAc,MAAM,WAAW;AACjD,cAAM,WAAW,KAAK,QAAQ,YAAY,KAAK,QAAQ,cAAc,QAAQ,OAAO,SAAS,MAAM,QAAQ,IAAI,KAAK,cAAc,MAAM,QAAQ,IAAI;AACpJ,aAAK,OAAO,cAAc;AAC1B,aAAK,OAAO,WAAW;AACvB,aAAK,MAAM,iBAAiB,EAAE,UAAU,KAAK,QAAQ,MAAM,IAAI,MAAM,SAAS,CAAC;AAC/E,cAAM,MAAM,KAAK,QAAQ,cAAc,QAAQ,KAAK,QAAQ,SAAS,QAAQ,SAAY,KAAK,cAAc,KAAK,OAAO,QAAQ,GAAG,IAAI;AACvI,YAAI,QAAQ,UAAa,QAAQ,KAAK;AACpC,cAAI,KAAK,QAAQ,aAAa,QAAQ;AACpC,kBAAM,cAAc,KAAK,OAAO,SAAS,SAAS;AAAA,UACpD,OAAO;AACL,kBAAM,MAAM;AACZ,iBAAK,KAAK,iBAAiB;AAAA,UAC7B;AAAA,QACF;AACA,aAAK,YAAY;AACjB,aAAK,WAAW;AAAA,MAClB;AAAA,MACA,SAAS,MAAM;AACb,aAAK,MAAM,WAAW,EAAE,UAAU,KAAK,QAAQ,MAAM,IAAI,MAAM,KAAK,WAAW,IAAI,KAAK,cAAc,MAAM,WAAW,EAAE,CAAC;AAAA,MAC5H;AAAA,MACA,cAAc,MAAM;AAClB,aAAK,OAAO,SAAS,MAAM;AAC3B,aAAK,OAAO,QAAQ,MAAM;AAC1B,aAAK,WAAW;AAAA,MAClB;AAAA,MACA,YAAY,MAAM;AAChB,aAAK,OAAO,eAAe,MAAM;AACjC,aAAK,WAAW;AAAA,MAClB;AAAA,MACA,OAAO,MAAM;AACX,aAAK,OAAO,SAAS;AACrB,aAAK,MAAM,YAAY,EAAE,UAAU,KAAK,QAAQ,MAAM,GAAG,CAAC;AAC1D,aAAK,eAAe;AACpB,aAAK,WAAW;AAChB,aAAK,KAAK,iBAAiB;AAAA,MAC7B;AAAA,MACA,OAAO,MAAM;AACX,cAAM,QAAQ,IAAI,MAAM,MAAM,OAAO,WAAW,yCAAyC;AACzF,aAAK,OAAO,SAAS;AACrB,aAAK,OAAO,QAAQ;AACpB,aAAK,MAAM,YAAY,EAAE,MAAM,CAAC;AAChC,aAAK,WAAW;AAAA,MAClB;AAAA,IACF;AACA,eAAW,CAAC,MAAM,QAAQ,KAAK,OAAO,QAAQ,SAAS,GAAG;AACxD,YAAM,iBAAiB,MAAM,QAAQ;AACrC,WAAK,gBAAgB,IAAI,MAAM,QAAQ;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,cAAoB;AAClB,QAAI,CAAC,KAAK,OAAQ;AAClB,eAAW,CAAC,MAAM,QAAQ,KAAK,KAAK,gBAAiB,MAAK,OAAO,oBAAoB,MAAM,QAAQ;AACnG,SAAK,gBAAgB,MAAM;AAC3B,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,OAAsB;AAC1B,UAAM,KAAK,QAAQ,KAAK;AAAA,EAC1B;AAAA,EAEA,QAAc;AACZ,SAAK,QAAQ,MAAM;AAAA,EACrB;AAAA,EAEA,OAAa;AACX,SAAK,MAAM;AACX,SAAK,OAAO,KAAK,QAAQ,cAAc,SAAS,CAAC;AAAA,EACnD;AAAA,EAEA,OAAO,MAAoB;AACzB,UAAM,SAAS,KAAK;AACpB,UAAM,UAAU,QAAQ,cAAc,SAAS;AAC/C,UAAM,UAAU,QAAQ,cAAc,OAAO,KAAK,OAAO;AACzD,UAAM,SAAS,UAAU,IAAI,KAAK,IAAI,KAAK,IAAI,MAAM,OAAO,GAAG,OAAO,IAAI,KAAK,IAAI,MAAM,OAAO;AAChG,QAAI,KAAK,UAAU,KAAK,OAAO,aAAa,EAAG,MAAK,OAAO,cAAc,KAAK,aAAa,MAAM;AAAA,QAC5F,MAAK,eAAe;AACzB,SAAK,OAAO,cAAc;AAC1B,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,OAAO,OAAqB;AAC1B,SAAK,OAAO,KAAK,OAAO,cAAc,KAAK;AAAA,EAC7C;AAAA,EAEA,aAAa,WAA4B,UAAiD,CAAC,GAAyB;AAClH,UAAM,WAAW,KAAK,OAAO,UAAU,YAAY,CAAC;AACpD,UAAM,QAAQ,OAAO,cAAc,WAC/B,YACA,SAAS,UAAU,CAACA,YAAWA,QAAO,OAAO,gBAAgB,SAAS,CAAC;AAC3E,QAAI,QAAQ,KAAK,SAAS,SAAS,OAAQ,QAAO;AAClD,UAAM,aAAa,QAAQ,YAAY,KAAK,OAAO,WAAW;AAC9D,SAAK,OAAO,cAAc;AAC1B,SAAK,OAAO,cAAc;AAC1B,SAAK,iBAAiB;AACtB,SAAK,OAAO,cAAc,QAAQ,QAAQ,SAAS,KAAK,GAAG,QAAQ,CAAC,GAAG,cAAc,SAAS;AAC9F,SAAK,OAAO,WAAW,SAAS,KAAK,GAAG,YAAY;AACpD,SAAK,eAAe,KAAK,OAAO;AAChC,UAAM,SAAS,SAAS,KAAK;AAC7B,QAAI,OAAQ,MAAK,MAAM,mBAAmB,EAAE,QAAQ,aAAa,MAAM,CAAC;AACxE,SAAK,WAAW;AAChB,QAAI,WAAY,gBAAe,MAAM,KAAK,KAAK,KAAK,CAAC;AACrD,WAAO;AAAA,EACT;AAAA,EAEA,KAAK,UAAkC,CAAC,GAAyB;AAC/D,UAAM,QAAQ,KAAK,OAAO,UAAU,SAAS,UAAU;AACvD,QAAI,KAAK,OAAO,cAAc,IAAI,MAAO,QAAO,KAAK,aAAa,KAAK,OAAO,cAAc,GAAG,OAAO;AACtG,QAAI,KAAK,OAAO,UAAU,QAAQ,EAAG,QAAO,KAAK,aAAa,GAAG,OAAO;AACxE,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,UAAkC,CAAC,GAAyB;AACnE,QAAI,KAAK,OAAO,cAAc,EAAG,QAAO,KAAK,aAAa,KAAK,OAAO,cAAc,GAAG,OAAO;AAC9F,WAAO;AAAA,EACT;AAAA,EAEA,aAAa,OAAwC;AACnD,UAAM,UAAU,KAAK,QAAQ,WAAW,CAAC;AACzC,UAAM,SAAS,QAAQ,KAAK;AAC5B,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,aAAa,KAAK,OAAO,WAAW;AAC1C,UAAM,cAAc,KAAK,OAAO;AAChC,SAAK,OAAO,cAAc;AAC1B,SAAK,iBAAiB;AACtB,SAAK,eAAe;AACpB,SAAK,MAAM,mBAAmB,EAAE,QAAQ,aAAa,MAAM,CAAC;AAC5D,SAAK,WAAW;AAChB,QAAI,WAAY,gBAAe,MAAM,KAAK,KAAK,KAAK,CAAC;AACrD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,iBAAiB,OAAiD;AACtE,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,wDAAwD;AACrF,UAAM,UAAU,KAAK,QAAQ,mBAAmB,SAC5C,MAAM,KAAK,QAAQ,kBAAkB,OAAO,QAAQ,KAAK,IACzD,KAAK,qBAAqB,QAAQ,KAAK;AAC3C,WAAO,YAAY,KAAK,OAAO;AAC/B,SAAK,MAAM,wBAAwB,EAAE,UAAU,OAAO,IAAI,aAAa,CAAC,GAAG,OAAO,WAAW,EAAE,CAAC;AAChG,SAAK,WAAW;AAChB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,iBAAiB,IAAY,QAA2D;AAC5F,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,wDAAwD;AACrF,UAAM,QAAQ,OAAO,YAAY,UAAU,CAAC,eAAe,WAAW,OAAO,EAAE;AAC/E,UAAM,UAAU,OAAO,YAAY,KAAK;AACxC,QAAI,CAAC,QAAS,OAAM,IAAI,MAAM,cAAc,EAAE,sCAAsC;AACpF,UAAM,YAA0B;AAAA,MAC9B,GAAG;AAAA,MACH,GAAG;AAAA,MACH,YAAY,OAAO,cAAc,QAAQ;AAAA,MACzC,SAAS,OAAO,WAAW,QAAQ;AAAA,MACnC,MAAM,OAAO,QAAQ,QAAQ;AAAA,IAC/B;AACA,UAAM,QAAQ,KAAK,QAAQ,mBAAmB,SAC1C,MAAM,KAAK,QAAQ,kBAAkB,OAAO,QAAQ,SAAS,IAC7D;AACJ,WAAO,YAAY,KAAK,IAAI;AAC5B,SAAK,MAAM,wBAAwB,EAAE,UAAU,OAAO,IAAI,aAAa,CAAC,GAAG,OAAO,WAAW,EAAE,CAAC;AAChG,SAAK,WAAW;AAChB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,iBAAiB,IAA2B;AAChD,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,wDAAwD;AACrF,UAAM,QAAQ,OAAO,YAAY,UAAU,CAAC,eAAe,WAAW,OAAO,EAAE;AAC/E,UAAM,UAAU,OAAO,YAAY,KAAK;AACxC,QAAI,CAAC,QAAS,OAAM,IAAI,MAAM,cAAc,EAAE,sCAAsC;AACpF,QAAI,KAAK,QAAQ,mBAAmB,OAAQ,OAAM,KAAK,QAAQ,kBAAkB,OAAO,QAAQ,OAAO;AACvG,WAAO,YAAY,OAAO,OAAO,CAAC;AAClC,SAAK,MAAM,wBAAwB,EAAE,UAAU,OAAO,IAAI,aAAa,CAAC,GAAG,OAAO,WAAW,EAAE,CAAC;AAChG,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,eAAe,SAAwB;AACrC,SAAK,OAAO,cAAc;AAC1B,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,UAAU,SAAwB;AAChC,SAAK,OAAO,SAAS;AACrB,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,mBAAuC;AACrC,QAAI,CAAC,KAAK,QAAQ,OAAO,WAAW,CAAC,KAAK,UAAU,OAAO,iBAAiB,YAAa,QAAO;AAChG,UAAM,MAAM,aAAa,QAAQ,GAAG,cAAc,GAAG,KAAK,OAAO,UAAU,EAAE,IAAI,KAAK,OAAO,EAAE,EAAE;AACjG,QAAI,CAAC,IAAK,QAAO;AACjB,QAAI;AACF,YAAM,QAAQ,KAAK,MAAM,GAAG;AAC5B,YAAM,OAAO,KAAK,QAAQ,OAAO,WAAW,MAAM;AAClD,UAAI,KAAK,IAAI,IAAI,MAAM,UAAU,KAAK;AACpC,aAAK,eAAe;AACpB,eAAO;AAAA,MACT;AACA,aAAO,MAAM;AAAA,IACf,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,UAAgB;AACd,SAAK,cAAc;AACnB,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,MAAM,oBAAiD;AACrD,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,QAAO;AACpB,QAAI,CAAC,KAAK,QAAQ,eAAgB,QAAO,OAAO;AAChD,UAAM,UAAwD,CAAC;AAC/D,QAAI,KAAK,SAAU,SAAQ,WAAW,KAAK;AAC3C,QAAI,KAAK,OAAQ,SAAQ,SAAS,KAAK;AACvC,WAAO,MAAM,KAAK,QAAQ,eAAe,OAAO,KAAK,OAAO;AAAA,EAC9D;AAAA,EAEA,MAAM,mBAAkC;AACtC,QAAI,CAAC,KAAK,OAAO,YAAa;AAC9B,UAAM,OAAO,KAAK,KAAK,EAAE,UAAU,KAAK,CAAC;AACzC,QAAI,CAAC,KAAM,MAAK,OAAO,SAAS;AAAA,EAClC;AAAA,EAEA,gBAAsB;AACpB,QAAI,CAAC,KAAK,QAAQ,OAAO,WAAW,CAAC,KAAK,UAAU,OAAO,iBAAiB,YAAa;AACzF,UAAM,OAAO,KAAK,OAAO;AACzB,QAAI,QAAQ,KAAM,KAAK,OAAO,WAAW,KAAK,QAAQ,KAAK,OAAO,WAAW,EAAI;AACjF,UAAM,MAAM,GAAG,cAAc,GAAG,KAAK,OAAO,UAAU,EAAE,IAAI,KAAK,OAAO,EAAE;AAC1E,iBAAa,QAAQ,KAAK,KAAK,UAAU,EAAE,MAAM,SAAS,KAAK,IAAI,EAAE,CAAyB,CAAC;AAC/F,UAAM,OAAO,OAAO,KAAK,YAAY,EAAE,OAAO,CAAC,SAAS,KAAK,WAAW,cAAc,CAAC;AACvF,UAAM,WAAW,KAAK,QAAQ,OAAO,YAAY;AACjD,QAAI,KAAK,SAAS,UAAU;AAC1B,YAAM,SAAS,KACZ,IAAI,CAAC,UAAU,EAAE,MAAM,OAAO,KAAK,MAAM,aAAa,QAAQ,IAAI,KAAK,IAAI,EAA4B,EAAE,EACzG,KAAK,CAAC,GAAG,OAAO,EAAE,MAAM,WAAW,MAAM,EAAE,MAAM,WAAW,EAAE,EAAE,CAAC;AACpE,UAAI,OAAQ,cAAa,WAAW,OAAO,IAAI;AAAA,IACjD;AAAA,EACF;AAAA,EAEA,iBAAuB;AACrB,QAAI,CAAC,KAAK,UAAU,OAAO,iBAAiB,YAAa;AACzD,iBAAa,WAAW,GAAG,cAAc,GAAG,KAAK,OAAO,UAAU,EAAE,IAAI,KAAK,OAAO,EAAE,EAAE;AAAA,EAC1F;AAAA,EAEA,MAAwC,MAAS,QAAmC;AAClF,SAAK,cAAc,IAAI,YAAY,MAAM,EAAE,QAAQ,SAAS,OAAO,UAAU,MAAM,CAAC,CAAC;AAAA,EACvF;AAAA,EAEA,aAAmB;AACjB,SAAK,MAAM,kBAAkB,EAAE,GAAG,KAAK,OAAO,CAAC;AAAA,EACjD;AAAA,EAEA,qBAAqB,QAAkB,OAAwC;AAC7E,UAAM,aAA2B;AAAA,MAC/B,IAAI,GAAG,OAAO,EAAE,eAAe,OAAO,aAAa,KAAK,KAAK,IAAI,CAAC;AAAA,MAClE,UAAU,OAAO;AAAA,MACjB,YAAY,MAAM,cAAc,CAAC,YAAY;AAAA,MAC7C,SAAS,MAAM,WAAW,CAAC,YAAY;AAAA,MACvC,MAAM,MAAM;AAAA,MACZ,MAAM,MAAM,QAAQ,CAAC;AAAA,IACvB;AACA,QAAI,MAAM,MAAO,YAAW,QAAQ,MAAM;AAC1C,QAAI,MAAM,KAAM,YAAW,OAAO,MAAM;AACxC,WAAO;AAAA,EACT;AAAA,EAEA,cAAc,WAA2B;AACvC,UAAM,cAAc,KAAK,QAAQ,SAAS,SAAS;AACnD,UAAM,cAAc,KAAK,QAAQ,cAAc,SAAS;AACxD,UAAM,QAAQ,KAAK,QAAQ,aAAa,UAAU,KAAK,iBAAiB;AACxE,WAAO,eAAgB,YAAY,eAAe;AAAA,EACpD;AAAA,EAEA,aAAa,YAA4B;AACvC,UAAM,cAAc,KAAK,QAAQ,SAAS,SAAS;AACnD,UAAM,cAAc,KAAK,QAAQ,cAAc,SAAS;AACxD,UAAM,QAAQ,KAAK,QAAQ,aAAa,UAAU,KAAK,iBAAiB;AACxE,WAAO,eAAgB,aAAa,eAAe;AAAA,EACrD;AACF;","names":["strings","canvas"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/mango-av-chapters.ts"],"sourcesContent":["import { AVControllerElement } from './controller-element';\nimport { componentTheme } from './component-styles';\nimport type { AVPlayerEventMap, AVStrings, Chapter } from '../types';\nimport { escapeHtml, formatTime, resolveStrings } from '../utils';\n\nconst styles = `${componentTheme}\n .chapters { background: var(--mango-av-background); border: 1px solid var(--mango-av-border); border-radius: var(--mango-av-radius); padding: .75rem; }\n h2 { font-size: 1rem; margin: 0 0 .5rem; }\n ul { list-style: none; margin: 0; padding: 0; }\n ul ul { border-left: 1px solid var(--mango-av-border); margin-left: .8rem; padding-left: .55rem; }\n button { background: transparent; border: 0; border-radius: .35rem; color: inherit; display: grid; gap: .15rem; padding: .5rem; text-align: left; width: 100%; }\n button:hover { background: var(--mango-av-surface); }\n button.active { background: color-mix(in srgb, var(--mango-av-accent) 14%, transparent); box-shadow: inset 3px 0 var(--mango-av-accent); }\n`;\n\nconst renderChapters = (chapters: Chapter[], canvasId: string, ui: AVStrings, level = 1): string => {\n if (chapters.length === 0 && level === 1) return `<p class=\"empty\">${escapeHtml(ui.noChapters)}</p>`;\n return `<ul>${chapters.map((chapter) => `<li>\n <button type=\"button\" class=\"${chapter.canvasId === canvasId ? 'active' : ''}\" ${chapter.canvasId ? `data-canvas=\"${escapeHtml(chapter.canvasId)}\"` : 'disabled'} ${chapter.time ? `data-time=\"${chapter.time.start}\"` : ''}>\n <span>${escapeHtml(chapter.label)}</span>\n ${chapter.time ? `<span class=\"time\">${formatTime(chapter.time.start)}</span>` : ''}\n </button>\n ${renderChapters(chapter.children, canvasId, ui, level + 1)}\n </li>`).join('')}</ul>`;\n};\n\nexport class MangoAVChaptersElement extends AVControllerElement {\n #root: ShadowRoot;\n\n constructor() {\n super();\n this.#root = this.attachShadow({ mode: 'open' });\n }\n\n protected controllerChanged(): void { this.#render(); }\n\n protected handleControllerEvent<K extends keyof AVPlayerEventMap>(type: K, _event: CustomEvent<AVPlayerEventMap[K]>): void {\n if (type === 'av-ready' || type === 'av-canvaschange' || type === 'av-configchange') this.#render();\n }\n\n #render(): void {\n const manifest = this.controller.manifest;\n const canvas = this.controller.canvas;\n const ui = resolveStrings(this.controller.config.strings);\n this.#root.innerHTML = `<style>${styles}</style><section class=\"chapters\" aria-label=\"${escapeHtml(ui.chapters)}\">\n <slot name=\"heading\"><h2>${escapeHtml(ui.chapters)}</h2></slot>\n ${manifest && canvas ? renderChapters(manifest.chapters, canvas.id, ui) : `<p class=\"empty\">${escapeHtml(ui.noManifest)}</p>`}\n </section>`;\n this.#root.querySelectorAll<HTMLElement>('[data-canvas]').forEach((button) => button.addEventListener('click', () => {\n const canvasId = button.dataset.canvas;\n if (!canvasId) return;\n const time = Number(button.dataset.time ?? 0);\n this.dispatchEvent(new CustomEvent('av-chapterselect', {\n detail: { canvasId, time },\n bubbles: true,\n composed: true,\n }));\n this.controller.selectCanvas(canvasId, { time, autoplay: this.controller.state.status === 'playing' });\n }));\n }\n}\n\nexport const defineMangoAVChapters = (tagName = 'mango-av-chapters'): typeof MangoAVChaptersElement => {\n if (typeof customElements === 'undefined') return MangoAVChaptersElement;\n if (!customElements.get(tagName)) customElements.define(tagName, MangoAVChaptersElement);\n return MangoAVChaptersElement;\n};\n"],"mappings":";;;;;;;;;;;AAKA,IAAM,SAAS,GAAG,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUhC,IAAM,iBAAiB,CAAC,UAAqB,UAAkB,IAAe,QAAQ,MAAc;AAClG,MAAI,SAAS,WAAW,KAAK,UAAU,EAAG,QAAO,oBAAoB,WAAW,GAAG,UAAU,CAAC;AAC9F,SAAO,OAAO,SAAS,IAAI,CAAC,YAAY;AAAA,mCACP,QAAQ,aAAa,WAAW,WAAW,EAAE,KAAK,QAAQ,WAAW,gBAAgB,WAAW,QAAQ,QAAQ,CAAC,MAAM,UAAU,IAAI,QAAQ,OAAO,cAAc,QAAQ,KAAK,KAAK,MAAM,EAAE;AAAA,cACjN,WAAW,QAAQ,KAAK,CAAC;AAAA,QAC/B,QAAQ,OAAO,sBAAsB,WAAW,QAAQ,KAAK,KAAK,CAAC,YAAY,EAAE;AAAA;AAAA,MAEnF,eAAe,QAAQ,UAAU,UAAU,IAAI,QAAQ,CAAC,CAAC;AAAA,QACvD,EAAE,KAAK,EAAE,CAAC;AAClB;AAEO,IAAM,yBAAN,cAAqC,oBAAoB;AAAA,EAC9D;AAAA,EAEA,cAAc;AACZ,UAAM;AACN,SAAK,QAAQ,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAAA,EACjD;AAAA,EAEU,oBAA0B;AAAE,SAAK,QAAQ;AAAA,EAAG;AAAA,EAE5C,sBAAwD,MAAS,QAAgD;AACzH,QAAI,SAAS,cAAc,SAAS,qBAAqB,SAAS,kBAAmB,MAAK,QAAQ;AAAA,EACpG;AAAA,EAEA,UAAgB;AACd,UAAM,WAAW,KAAK,WAAW;AACjC,UAAM,SAAS,KAAK,WAAW;AAC/B,UAAM,KAAK,eAAe,KAAK,WAAW,OAAO,OAAO;AACxD,SAAK,MAAM,YAAY,UAAU,MAAM,iDAAiD,WAAW,GAAG,QAAQ,CAAC;AAAA,iCAClF,WAAW,GAAG,QAAQ,CAAC;AAAA,QAChD,YAAY,SAAS,eAAe,SAAS,UAAU,OAAO,IAAI,EAAE,IAAI,oBAAoB,WAAW,GAAG,UAAU,CAAC,MAAM;AAAA;AAE/H,SAAK,MAAM,iBAA8B,eAAe,EAAE,QAAQ,CAAC,WAAW,OAAO,iBAAiB,SAAS,MAAM;AACnH,YAAM,WAAW,OAAO,QAAQ;AAChC,UAAI,CAAC,SAAU;AACf,YAAM,OAAO,OAAO,OAAO,QAAQ,QAAQ,CAAC;AAC5C,WAAK,cAAc,IAAI,YAAY,oBAAoB;AAAA,QACrD,QAAQ,EAAE,UAAU,KAAK;AAAA,QACzB,SAAS;AAAA,QACT,UAAU;AAAA,MACZ,CAAC,CAAC;AACF,WAAK,WAAW,aAAa,UAAU,EAAE,MAAM,UAAU,KAAK,WAAW,MAAM,WAAW,UAAU,CAAC;AAAA,IACvG,CAAC,CAAC;AAAA,EACJ;AACF;AAEO,IAAM,wBAAwB,CAAC,UAAU,wBAAuD;AACrG,MAAI,OAAO,mBAAmB,YAAa,QAAO;AAClD,MAAI,CAAC,eAAe,IAAI,OAAO,EAAG,gBAAe,OAAO,SAAS,sBAAsB;AACvF,SAAO;AACT;","names":[]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|