@vectoriox/iox-ui 5.72.1 → 5.73.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"vectoriox-iox-ui-media-core.mjs","sources":["../../../projects/iox-ui/src/media-core/video.ts","../../../projects/iox-ui/src/media-core/video-runtime.ts","../../../projects/iox-ui/src/media-core/public-api.ts","../../../projects/iox-ui/src/media-core/vectoriox-iox-ui-media-core.ts"],"sourcesContent":["import { ConsentCategory, ConsentDecision, hasConsent } from '@vectoriox/iox-ui/consent-core';\n\n/**\n * VIDEO (CC3 — complex-components plan §7b, board 5). A LEAF type with two sources:\n * - an uploaded FILE renders as a real `<video>` (poster, `preload=\"metadata\"`, captions, controls);\n * - a YouTube / Vimeo address is ALWAYS a FACADE (D5): the studio's poster and a play button named after the video,\n * behind the site's consent gate (Marketing). The player's `<iframe>` exists only after a click AND a grant —\n * never in the server's HTML, never on the builder canvas.\n *\n * `planVideo(node, consent)` is the ONE decision — the only code that knows the URL shapes, the embed hosts and the\n * consent category. Both engine paths and the canvas render from it (`videoInnerHtml`), and the runtime\n * (`video-runtime.ts`) builds the player's address from the same plan.\n */\n\nexport const VIDEO_NODE_TYPE = 'Video';\n\nexport enum VideoSource {\n File = 'file',\n YouTube = 'youtube',\n Vimeo = 'vimeo',\n}\n\nexport enum VideoMode {\n /** In the page, with the player's controls. */\n Inline = 'inline',\n /** Muted, looped, no controls, an always-visible pause button (WCAG 2.2.2) — an uploaded file only. */\n Background = 'background',\n}\n\n/** The node's traits (Bindings ▸ Media · Behaviour · Accessibility · Privacy). */\nexport enum VideoTrait {\n /** Not `source`: across the builder `source` names a DATA source (a Repeater's, a Slider's). */\n Source = 'videoSource',\n Src = 'src',\n Poster = 'poster',\n Mode = 'mode',\n Autoplay = 'autoplay',\n Title = 'title',\n Captions = 'captions',\n CaptionsLang = 'captionsLang',\n Consent = 'consentCategory',\n}\n\n/** What a plan renders. */\nexport enum VideoKind {\n /** An uploaded file: a real `<video>`. */\n File = 'file',\n /** YouTube / Vimeo: poster + play, the player loaded on a click after consent. */\n Facade = 'facade',\n /** No address yet: the poster blank (DS3) and nothing to play. */\n Empty = 'empty',\n}\n\n/** A recognised embed: which provider, its video id and (Vimeo, unlisted) its privacy hash. */\nexport interface VideoRef {\n source: VideoSource.YouTube | VideoSource.Vimeo;\n id: string;\n hash?: string;\n}\n\nexport const VIDEO_PROVIDER_LABEL: Readonly<Record<VideoRef['source'], string>> = {\n [VideoSource.YouTube]: 'YouTube',\n [VideoSource.Vimeo]: 'Vimeo',\n};\n\n/** Who the visitor's IP address and cookies go to, named in the consent prompt. */\nexport const VIDEO_PROVIDER_COMPANY: Readonly<Record<VideoRef['source'], string>> = {\n [VideoSource.YouTube]: 'Google',\n [VideoSource.Vimeo]: 'Vimeo',\n};\n\n/** The two hosts a player ever loads from — youtube-nocookie and Vimeo's player (with Do Not Track). */\nexport const VIDEO_EMBED_ORIGINS: ReadonlyArray<string> = ['https://www.youtube-nocookie.com', 'https://player.vimeo.com'];\n\nconst YOUTUBE_ID = /^[A-Za-z0-9_-]{11}$/;\nconst VIMEO_ID = /^\\d{6,12}$/;\nconst VIMEO_HASH = /^[0-9a-f]{6,20}$/i;\nconst YOUTUBE_HOSTS = new Set(['youtube.com', 'www.youtube.com', 'm.youtube.com', 'music.youtube.com', 'youtube-nocookie.com', 'www.youtube-nocookie.com']);\nconst YOUTUBE_SHORT_HOSTS = new Set(['youtu.be', 'www.youtu.be']);\nconst YOUTUBE_PATH_PREFIXES = ['embed', 'shorts', 'live', 'v'];\nconst VIMEO_HOSTS = new Set(['vimeo.com', 'www.vimeo.com', 'player.vimeo.com']);\n\nfunction toUrl(raw: string): URL | null {\n const text = raw.trim();\n if (!text) return null;\n try {\n return new URL(/^[a-z][a-z0-9+.-]*:\\/\\//i.test(text) ? text : `https://${text}`);\n } catch {\n return null;\n }\n}\n\nfunction parseYouTube(url: URL): VideoRef | null {\n const host = url.hostname.toLowerCase();\n const segments = url.pathname.split('/').filter(Boolean);\n let id: string | null = null;\n if (YOUTUBE_SHORT_HOSTS.has(host)) id = segments[0] ?? null;\n else if (YOUTUBE_HOSTS.has(host)) {\n if (segments[0] === 'watch') id = url.searchParams.get('v');\n else if (YOUTUBE_PATH_PREFIXES.includes(segments[0] ?? '')) id = segments[1] ?? null;\n } else return null;\n return id && YOUTUBE_ID.test(id) ? { source: VideoSource.YouTube, id } : null;\n}\n\nfunction parseVimeo(url: URL): VideoRef | null {\n if (!VIMEO_HOSTS.has(url.hostname.toLowerCase())) return null;\n const segments = url.pathname.split('/').filter(Boolean);\n // player.vimeo.com/video/<id>, vimeo.com/<id>[/<hash>], vimeo.com/channels/<c>/<id>, vimeo.com/groups/<g>/videos/<id>\n const index = segments.findIndex(s => VIMEO_ID.test(s));\n if (index < 0) return null;\n const id = segments[index];\n const hash = url.searchParams.get('h') ?? segments[index + 1];\n return { source: VideoSource.Vimeo, id, ...(hash && VIMEO_HASH.test(hash) ? { hash } : {}) };\n}\n\n/** The embed a pasted address names — a YouTube or Vimeo watch, share, embed or short link — or null. */\nexport function parseVideoUrl(raw: string | null | undefined): VideoRef | null {\n const url = typeof raw === 'string' ? toUrl(raw) : null;\n if (!url || !/^https?:$/.test(url.protocol)) return null;\n return parseYouTube(url) ?? parseVimeo(url);\n}\n\n/** The source a node plays: its declared source when it is one, else what its address is. */\nexport function videoSourceOf(src: unknown, declared?: unknown): VideoSource {\n if (declared === VideoSource.YouTube || declared === VideoSource.Vimeo || declared === VideoSource.File) return declared;\n return parseVideoUrl(typeof src === 'string' ? src : '')?.source ?? VideoSource.File;\n}\n\n/** The player's address — loaded only after a click and a grant. Autoplays (the visitor just pressed play). */\nexport function videoEmbedUrl(ref: VideoRef): string {\n if (ref.source === VideoSource.YouTube) {\n return `https://www.youtube-nocookie.com/embed/${encodeURIComponent(ref.id)}?autoplay=1&rel=0&playsinline=1`;\n }\n return `https://player.vimeo.com/video/${encodeURIComponent(ref.id)}?autoplay=1&dnt=1${ref.hash ? `&h=${encodeURIComponent(ref.hash)}` : ''}`;\n}\n\n/** Where the SERVER fetches an embed's thumbnail to store as the studio's own poster (never the visitor). */\nexport interface VideoThumbnailRequest {\n /** `image`: the url IS the picture; `oembed`: the url answers JSON whose `thumbnail_url` is the picture. */\n kind: 'image' | 'oembed';\n url: string;\n /** The only hosts the picture itself may come from (the server refuses anything else). */\n imageHosts: ReadonlyArray<string>;\n}\n\nexport function videoThumbnailRequest(ref: VideoRef): VideoThumbnailRequest {\n if (ref.source === VideoSource.YouTube) {\n return { kind: 'image', url: `https://i.ytimg.com/vi/${encodeURIComponent(ref.id)}/hqdefault.jpg`, imageHosts: ['i.ytimg.com'] };\n }\n const page = `https://vimeo.com/${ref.id}${ref.hash ? `/${ref.hash}` : ''}`;\n return { kind: 'oembed', url: `https://vimeo.com/api/oembed.json?url=${encodeURIComponent(page)}&width=1280`, imageHosts: ['i.vimeocdn.com'] };\n}\n\n/** A stored poster's object name — one per video, so fetching it again overwrites rather than piles up. */\nexport function videoPosterFileName(ref: VideoRef): string {\n return `video-poster-${ref.source}-${ref.id}.jpg`;\n}\n\n// ── the node, in either shape (saved props / builder traits) ───────────────────────────────────────\n\nexport interface VideoNodeLike {\n type?: string;\n props?: Record<string, unknown> | null;\n traits?: ReadonlyArray<{ name?: string; default?: unknown }> | null;\n}\n\n/** A content value of a Video node, saved (`props`) or builder (`traits[].default`) shape. */\nexport function videoProp(node: VideoNodeLike | null | undefined, name: VideoTrait | string): unknown {\n if (!node) return undefined;\n if (node.props && Object.prototype.hasOwnProperty.call(node.props, name)) return node.props[name];\n return node.traits?.find(t => t?.name === name)?.default;\n}\n\nconst str = (v: unknown): string => (typeof v === 'string' ? v.trim() : '');\nconst truthy = (v: unknown): boolean => v === true || v === 'true';\n\n/** The consent category an embed waits for — Marketing by default (D5); an uploaded file waits for none. */\nexport function videoConsentCategory(node: VideoNodeLike | null | undefined, source: VideoSource = videoSourceOf(videoProp(node, VideoTrait.Src), videoProp(node, VideoTrait.Source))): ConsentCategory | null {\n if (source === VideoSource.File) return null;\n const declared = videoProp(node, VideoTrait.Consent);\n return declared === ConsentCategory.Analytics ? ConsentCategory.Analytics : ConsentCategory.Marketing;\n}\n\nexport interface VideoPlan {\n kind: VideoKind;\n source: VideoSource;\n /** An embed's provider and id (Facade). */\n ref: VideoRef | null;\n /** An uploaded file's address (File). */\n src: string;\n /** The studio's own poster ('' = the token blank). Never a provider's thumbnail URL. */\n poster: string;\n /** The video's name — the play button's accessible name. */\n title: string;\n mode: VideoMode;\n background: boolean;\n /** Muted autoplay when motion is allowed (the runtime asks; the server never writes `autoplay`). */\n autoplay: boolean;\n muted: boolean;\n loop: boolean;\n controls: boolean;\n /** A `.vtt` file ('' = none). */\n captions: string;\n captionsLang: string;\n /** What the facade waits for (null for a file). */\n consentCategory: ConsentCategory | null;\n /** The visitor's decision grants it. */\n granted: boolean;\n /** The player's address — only when granted (the runtime loads it on a click). */\n embedUrl: string | null;\n /** \"YouTube\" / \"Vimeo\" ('' for a file). */\n providerLabel: string;\n}\n\n/**\n * The ONE decision for a Video node and a visitor's consent (null = none recorded — the server always passes null,\n * so its HTML is always the facade). A poster that is a provider's thumbnail URL is dropped: the poster is the\n * studio's own image (or the thumbnail the server fetched and stored for it), never a request to a third party.\n */\nexport function planVideo(node: VideoNodeLike | null | undefined, consent: ConsentDecision | null): VideoPlan {\n const rawSrc = str(videoProp(node, VideoTrait.Src));\n const source = videoSourceOf(rawSrc, videoProp(node, VideoTrait.Source));\n const ref = source === VideoSource.File ? null : parseVideoUrl(rawSrc);\n const background = source === VideoSource.File && videoProp(node, VideoTrait.Mode) === VideoMode.Background;\n const consentCategory = videoConsentCategory(node, source);\n const granted = consentCategory ? hasConsent(consent, consentCategory) : true;\n const kind = source === VideoSource.File ? (rawSrc ? VideoKind.File : VideoKind.Empty) : (ref ? VideoKind.Facade : VideoKind.Empty);\n const poster = str(videoProp(node, VideoTrait.Poster));\n return {\n kind,\n source,\n ref,\n src: source === VideoSource.File ? rawSrc : '',\n poster: isThirdPartyPoster(poster) ? '' : poster,\n title: str(videoProp(node, VideoTrait.Title)),\n mode: background ? VideoMode.Background : VideoMode.Inline,\n background,\n autoplay: background || (source === VideoSource.File && truthy(videoProp(node, VideoTrait.Autoplay))),\n muted: background || truthy(videoProp(node, VideoTrait.Autoplay)),\n loop: background,\n controls: !background,\n captions: background ? '' : str(videoProp(node, VideoTrait.Captions)),\n captionsLang: str(videoProp(node, VideoTrait.CaptionsLang)) || 'en',\n consentCategory,\n granted,\n embedUrl: kind === VideoKind.Facade && granted && ref ? videoEmbedUrl(ref) : null,\n providerLabel: ref ? VIDEO_PROVIDER_LABEL[ref.source] : '',\n };\n}\n\nconst THIRD_PARTY_POSTER_HOSTS = ['ytimg.com', 'youtube.com', 'vimeocdn.com', 'vimeo.com', 'googleusercontent.com'];\n\n/** A poster served by the video's provider — a request to a third party before consent, so it never renders. */\nexport function isThirdPartyPoster(url: string): boolean {\n const parsed = url ? toUrl(url) : null;\n if (!parsed || !/^https?:$/.test(parsed.protocol)) return false;\n const host = parsed.hostname.toLowerCase();\n return THIRD_PARTY_POSTER_HOSTS.some(h => host === h || host.endsWith(`.${h}`));\n}\n\n// ── words ───────────────────────────────────────────────────────────────────────────────────────────\n\n/**\n * The words the renderer draws (board 5; Q7: the consent prompt is NOT an editable part — its words are the\n * consent vocabulary's, one source, translated). English and Hebrew; the page's `lang` picks.\n */\nexport interface VideoWords {\n /** The play button's name: the video's title and its provider. */\n play(title: string, provider: string): string;\n /** The play button's name with no title. */\n playUntitled(provider: string): string;\n pauseBackground: string;\n playBackground: string;\n /** The consent prompt (a group): its name, its lead and its body. */\n promptLabel: string;\n promptLead(provider: string): string;\n promptBody(company: string): string;\n /** The same prompt where the player is narrow (board 5's phone): one shorter sentence, its lead in bold. */\n promptCompactLead(provider: string): string;\n promptCompactBody: string;\n allow: string;\n settings: string;\n}\n\nexport const VIDEO_WORDS: Readonly<Record<'en' | 'he', VideoWords>> = {\n en: {\n play: (title, provider) => (provider ? `Play: ${title} (${provider})` : `Play: ${title}`),\n playUntitled: provider => (provider ? `Play video (${provider})` : 'Play video'),\n pauseBackground: 'Pause background video',\n playBackground: 'Play background video',\n promptLabel: 'This video needs your permission',\n promptLead: provider => `This video is hosted by ${provider}.`,\n promptBody: company => `Playing it lets ${company} set cookies and see your IP address. Nothing has loaded yet.`,\n promptCompactLead: provider => `Plays from ${provider},`,\n promptCompactBody: 'which sets cookies and sees your IP address. Nothing has loaded yet.',\n allow: 'Allow and play',\n settings: 'Privacy settings',\n },\n he: {\n play: (title, provider) => (provider ? `הפעלה: ${title} (${provider})` : `הפעלה: ${title}`),\n playUntitled: provider => (provider ? `הפעלת הסרטון (${provider})` : 'הפעלת הסרטון'),\n pauseBackground: 'השהיית סרטון הרקע',\n playBackground: 'הפעלת סרטון הרקע',\n promptLabel: 'הסרטון הזה צריך את רשותך',\n promptLead: provider => `הסרטון מתארח ב-${provider}.`,\n promptBody: company => `ההפעלה מאפשרת ל-${company} להגדיר קובצי Cookie ולראות את כתובת ה-IP שלך. עדיין לא נטען דבר.`,\n promptCompactLead: provider => `מתנגן מ-${provider},`,\n promptCompactBody: 'שמגדיר קובצי Cookie ורואה את כתובת ה-IP שלך. עדיין לא נטען דבר.',\n allow: 'לאשר ולהפעיל',\n settings: 'הגדרות פרטיות',\n },\n};\n\n/** The words for a page language (`he`, `he-IL` → Hebrew; anything else → English). */\nexport function videoWords(lang?: string | null): VideoWords {\n return (lang ?? '').toLowerCase().startsWith('he') ? VIDEO_WORDS.he : VIDEO_WORDS.en;\n}\n\n/** The play button's accessible name. */\nexport function videoPlayLabel(plan: VideoPlan, words: VideoWords = VIDEO_WORDS.en): string {\n return plan.title ? words.play(plan.title, plan.providerLabel) : words.playUntitled(plan.providerLabel);\n}\n\n// ── markup (one builder for both engine paths and the canvas) ────────────────────────────────────────\n\nexport enum VideoClass {\n Root = 'iox-video',\n Poster = 'iox-video__poster',\n Play = 'iox-video__play',\n Badge = 'iox-video__badge',\n Media = 'iox-video__media',\n Frame = 'iox-video__frame',\n Toggle = 'iox-video__toggle',\n Consent = 'iox-video__consent',\n ConsentText = 'iox-video__consent-text',\n /** The prompt's text on a wide player / on a narrow one (a container query shows one). */\n ConsentWide = 'iox-video__consent-wide',\n ConsentCompact = 'iox-video__consent-compact',\n ConsentRow = 'iox-video__consent-row',\n Allow = 'iox-video__allow',\n Settings = 'iox-video__settings',\n}\n\nexport enum VideoAttribute {\n /** On the node element: its kind (`file` · `facade` · `empty`) — what the runtime attaches to. */\n Root = 'data-iox-video',\n Source = 'data-iox-video-source',\n Id = 'data-iox-video-id',\n Hash = 'data-iox-video-hash',\n Mode = 'data-iox-video-mode',\n Autoplay = 'data-iox-video-autoplay',\n Consent = 'data-iox-video-consent',\n Title = 'data-iox-video-title',\n /** The poster is the token blank (no image): the shared CSS fills it with `surface-2`. */\n PosterEmpty = 'data-iox-video-poster-empty',\n /** The player is loaded (after the click and the grant). */\n Playing = 'data-iox-video-playing',\n /** The consent prompt is showing. */\n Asking = 'data-iox-video-asking',\n}\n\nexport enum VideoIcon {\n Play = 'ph-fill ph-play',\n Pause = 'ph-fill ph-pause',\n}\n\n/** The attributes the node's own element carries (both engine paths, the canvas). */\nexport function videoRootAttributes(plan: VideoPlan): Record<string, string> {\n const attrs: Record<string, string> = { [VideoAttribute.Root]: plan.kind, [VideoAttribute.Source]: plan.source };\n if (plan.ref) {\n attrs[VideoAttribute.Id] = plan.ref.id;\n if (plan.ref.hash) attrs[VideoAttribute.Hash] = plan.ref.hash;\n }\n if (plan.background) attrs[VideoAttribute.Mode] = VideoMode.Background;\n if (plan.autoplay) attrs[VideoAttribute.Autoplay] = '';\n if (plan.consentCategory) attrs[VideoAttribute.Consent] = plan.consentCategory;\n if (plan.title) attrs[VideoAttribute.Title] = plan.title;\n if (!plan.poster) attrs[VideoAttribute.PosterEmpty] = '';\n return attrs;\n}\n\nexport interface VideoMarkupOptions {\n /** HTML-escape an attribute or text value. */\n esc: (value: string) => string;\n /** The builder canvas: the poster ONLY — no `<video>`, no player, nothing that loads or takes a click. */\n canvas?: boolean;\n words?: VideoWords;\n}\n\nconst iconHtml = (cls: string) => `<i class=\"${cls}\" aria-hidden=\"true\"></i>`;\n\n/** The element's inner markup. The server's HTML for a facade holds no `<iframe>` and requests nothing from\n * the provider: only the studio's poster, the play button and the (hidden) consent prompt. */\nexport function videoInnerHtml(plan: VideoPlan, options: VideoMarkupOptions): string {\n const { esc } = options;\n const words = options.words ?? VIDEO_WORDS.en;\n const poster = plan.poster ? `<img class=\"${VideoClass.Poster}\" src=\"${esc(plan.poster)}\" alt=\"\" loading=\"lazy\" decoding=\"async\">` : '';\n const label = esc(videoPlayLabel(plan, words));\n const playSpan = `<span class=\"${VideoClass.Play}\" aria-hidden=\"true\">${iconHtml(VideoIcon.Play)}</span>`;\n const badge = plan.providerLabel ? `<span class=\"${VideoClass.Badge}\">${iconHtml(VideoIcon.Play)}${esc(plan.providerLabel)}</span>` : '';\n\n if (options.canvas || plan.kind === VideoKind.Empty) {\n return `${poster}${plan.kind === VideoKind.Empty && !options.canvas ? '' : playSpan}${badge}`;\n }\n\n if (plan.kind === VideoKind.File) {\n const media = [\n `<video class=\"${VideoClass.Media}\" src=\"${esc(plan.src)}\" preload=\"metadata\" playsinline`,\n plan.poster ? ` poster=\"${esc(plan.poster)}\"` : '',\n // A captions file is fetched with CORS (a <track> from another origin loads only so): the studio's bucket\n // answers CORS for every object, the video included.\n plan.captions ? ' crossorigin=\"anonymous\"' : '',\n plan.controls ? ' controls' : '',\n plan.muted ? ' muted' : '',\n plan.loop ? ' loop' : '',\n plan.background ? ' aria-hidden=\"true\" tabindex=\"-1\"' : (plan.title ? ` aria-label=\"${esc(plan.title)}\"` : ''),\n '>',\n plan.captions ? `<track kind=\"captions\" src=\"${esc(plan.captions)}\" srclang=\"${esc(plan.captionsLang)}\" label=\"${esc(plan.captionsLang)}\" default>` : '',\n '</video>',\n ].join('');\n if (plan.background) {\n // Rendered paused (the server cannot know the visitor's motion setting): the runtime starts it when motion\n // is allowed and turns this into the PAUSE button. Always visible (WCAG 2.2.2).\n return `${media}<button type=\"button\" class=\"${VideoClass.Toggle}\" aria-label=\"${esc(words.playBackground)}\" aria-pressed=\"true\">${iconHtml(VideoIcon.Play)}</button>`;\n }\n return `${media}<button type=\"button\" class=\"${VideoClass.Play}\" aria-label=\"${label}\">${iconHtml(VideoIcon.Play)}</button>`;\n }\n\n const company = plan.ref ? VIDEO_PROVIDER_COMPANY[plan.ref.source] : '';\n const prompt = `<div class=\"${VideoClass.Consent}\" role=\"group\" aria-label=\"${esc(words.promptLabel)}\" hidden>` +\n `<p class=\"${VideoClass.ConsentText} ${VideoClass.ConsentWide}\"><b>${esc(words.promptLead(plan.providerLabel))}</b> ${esc(words.promptBody(company))}</p>` +\n `<p class=\"${VideoClass.ConsentText} ${VideoClass.ConsentCompact}\"><b>${esc(words.promptCompactLead(plan.providerLabel))}</b> ${esc(words.promptCompactBody)}</p>` +\n `<div class=\"${VideoClass.ConsentRow}\">` +\n `<button type=\"button\" class=\"${VideoClass.Allow}\">${esc(words.allow)}</button>` +\n `<button type=\"button\" class=\"${VideoClass.Settings}\">${esc(words.settings)}</button>` +\n `</div></div>`;\n return `${poster}<button type=\"button\" class=\"${VideoClass.Play}\" aria-label=\"${label}\">${iconHtml(VideoIcon.Play)}</button>${badge}${prompt}`;\n}\n\n/** Serialise attributes for a string renderer (a present boolean attribute is written bare). */\nexport function serializeVideoAttributes(attrs: Readonly<Record<string, string>>, esc: (value: string) => string): string {\n return Object.entries(attrs).map(([name, value]) => (value === '' ? ` ${name}` : ` ${name}=\"${esc(value)}\"`)).join('');\n}\n","import {\n CONSENT_COOKIE_NAME, ConsentCategory, ConsentDecision, cookieAttributes, decode, encode, hasConsent, setCategoryDecision,\n} from '@vectoriox/iox-ui/consent-core';\n\nimport { VIDEO_PROVIDER_LABEL, VideoAttribute, VideoClass, VideoIcon, VideoKind, VideoMode, VideoRef, VideoSource, videoEmbedUrl, VideoWords, videoWords } from './video';\n\n/**\n * The Video's RUNTIME (CC3, board 5) — DOM only, ONE copy for both engine paths (the component path attaches it from\n * its component, the string path from the page's interaction service; `attachVideoAt` is idempotent). It reads the\n * markup `videoInnerHtml` writes. The builder canvas never attaches it (the canvas shows the poster only).\n *\n * - FACADE: play → the visitor's consent grants the category → the player's `<iframe>` replaces the poster, focused,\n * autoplaying (the visitor just pressed play). Not granted → the consent prompt: \"Allow and play\" grants the\n * category in the site's ONE consent record (the banner and its preferences read the same cookie) and plays;\n * \"Privacy settings\" opens the site's own preferences dialog.\n * - FILE: the play button starts the `<video>`; muted autoplay only when motion is allowed.\n * - BACKGROUND: muted and looped; it plays only when motion is allowed (never under reduced motion), and its\n * pause button is always there (WCAG 2.2.2).\n */\n\n/** Ask the page to record a category the visitor granted (cancelable: the site's consent service handles it). */\nexport const CONSENT_GRANT_EVENT = 'iox-consent-grant';\n/** Ask the page to open its consent preferences (cancelable: handled = a dialog opened). */\nexport const CONSENT_PREFERENCES_EVENT = 'iox-consent-preferences';\n\nexport interface ConsentGrantDetail { category: ConsentCategory }\n\n/** How the runtime reads and writes the visitor's ONE consent record — the page's transport. */\nexport interface ConsentTransport {\n read(): ConsentDecision | null;\n /** Record the category as granted (synchronously, before the player loads). */\n grant(category: ConsentCategory): void;\n /** Open the site's privacy preferences; false when the page has none. */\n openPreferences(): boolean;\n}\n\nconst REDUCED_MOTION = '(prefers-reduced-motion: reduce)';\nconst RUNTIME_KEY = '__ioxVideo';\nconst IFRAME_ALLOW = 'autoplay; encrypted-media; picture-in-picture; fullscreen';\n\n/** The cookie the consent record lives in, read from a document. */\nexport function readConsentRecord(doc: Document): ConsentDecision | null {\n const raw = (doc.cookie ?? '').split('; ').find(c => c.startsWith(`${CONSENT_COOKIE_NAME}=`));\n return decode(raw ? decodeURIComponent(raw.slice(CONSENT_COOKIE_NAME.length + 1)) : null);\n}\n\n/**\n * The default transport: the page's own consent service answers the events (the engine records the decision, tells\n * Consent Mode, re-syncs the banner's switches); a page with no such service (the admin's Preview) records the cookie\n * itself, through the same consent-core decision, so the record is the same shape either way.\n */\nexport function documentConsentTransport(doc: Document): ConsentTransport {\n return {\n read: () => readConsentRecord(doc),\n grant: category => {\n const event = new CustomEvent<ConsentGrantDetail>(CONSENT_GRANT_EVENT, { detail: { category }, cancelable: true });\n doc.dispatchEvent(event);\n if (event.defaultPrevented) return;\n const previous = readConsentRecord(doc);\n const anonymousId = previous?.anonymousId ?? randomId();\n const decision = setCategoryDecision(previous, category, true, anonymousId, previous?.policyVersion ?? '1');\n const secure = doc.location?.protocol === 'https:';\n doc.cookie = `${CONSENT_COOKIE_NAME}=${encodeURIComponent(encode(decision))}; ${cookieAttributes(12, secure)}`;\n },\n openPreferences: () => {\n const event = new CustomEvent(CONSENT_PREFERENCES_EVENT, { cancelable: true });\n doc.dispatchEvent(event);\n return event.defaultPrevented;\n },\n };\n}\n\nfunction randomId(): string {\n const c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto;\n return c?.randomUUID ? c.randomUUID() : Math.random().toString(36).slice(2);\n}\n\nexport interface VideoRuntimeOptions {\n consent?: ConsentTransport;\n /** True to stop motion (default: the visitor's reduced-motion setting). */\n reducedMotion?: () => boolean;\n words?: VideoWords;\n}\n\n/** The embed a facade root names (its provider, id and hash attributes). */\nexport function videoRefOf(root: Element): VideoRef | null {\n const source = root.getAttribute(VideoAttribute.Source);\n const id = root.getAttribute(VideoAttribute.Id);\n if ((source !== VideoSource.YouTube && source !== VideoSource.Vimeo) || !id) return null;\n const hash = root.getAttribute(VideoAttribute.Hash);\n return { source, id, ...(hash ? { hash } : {}) };\n}\n\nexport class VideoRuntime {\n private readonly cleanups: Array<() => void> = [];\n private readonly consent: ConsentTransport;\n private readonly reduced: () => boolean;\n private readonly words: VideoWords;\n private readonly doc: Document;\n\n constructor(readonly root: HTMLElement, options: VideoRuntimeOptions = {}) {\n this.doc = root.ownerDocument;\n this.consent = options.consent ?? documentConsentTransport(this.doc);\n const view = this.doc.defaultView;\n this.reduced = options.reducedMotion ?? (() => !!view?.matchMedia?.(REDUCED_MOTION)?.matches);\n this.words = options.words ?? videoWords(this.doc.documentElement?.getAttribute('lang'));\n const kind = root.getAttribute(VideoAttribute.Root);\n if (kind === VideoKind.Facade) this.attachFacade();\n else if (kind === VideoKind.File) this.attachFile();\n }\n\n destroy(): void {\n this.cleanups.splice(0).forEach(fn => fn());\n delete (this.root as unknown as Record<string, unknown>)[RUNTIME_KEY];\n }\n\n /** The category a facade waits for (Marketing unless the node named another). */\n private get category(): ConsentCategory {\n const declared = this.root.getAttribute(VideoAttribute.Consent);\n return declared === ConsentCategory.Analytics ? ConsentCategory.Analytics : ConsentCategory.Marketing;\n }\n\n private on(el: Element | null, type: string, fn: (e: Event) => void): void {\n if (!el) return;\n el.addEventListener(type, fn);\n this.cleanups.push(() => el.removeEventListener(type, fn));\n }\n\n // ── facade ────────────────────────────────────────────────────────────────────────────────────\n\n private attachFacade(): void {\n const play = this.root.querySelector<HTMLButtonElement>(`button.${VideoClass.Play}`);\n const allow = this.root.querySelector<HTMLButtonElement>(`.${VideoClass.Allow}`);\n const settings = this.root.querySelector<HTMLButtonElement>(`.${VideoClass.Settings}`);\n this.on(play, 'click', () => this.requestPlay());\n this.on(allow, 'click', () => {\n this.consent.grant(this.category);\n this.loadPlayer();\n });\n this.on(settings, 'click', () => { this.consent.openPreferences(); });\n }\n\n /** Play pressed: the player when the category is granted, else the consent prompt. */\n requestPlay(): void {\n if (hasConsent(this.consent.read(), this.category)) {\n this.loadPlayer();\n return;\n }\n const prompt = this.root.querySelector<HTMLElement>(`.${VideoClass.Consent}`);\n if (!prompt) return;\n prompt.hidden = false;\n this.root.setAttribute(VideoAttribute.Asking, '');\n const play = this.root.querySelector<HTMLElement>(`button.${VideoClass.Play}`);\n if (play) play.hidden = true;\n this.root.querySelector<HTMLElement>(`.${VideoClass.Allow}`)?.focus();\n }\n\n /** The player — created only now, after the click and the grant. */\n loadPlayer(): void {\n const ref = videoRefOf(this.root);\n if (!ref || this.root.hasAttribute(VideoAttribute.Playing)) return;\n const frame = this.doc.createElement('iframe');\n frame.className = VideoClass.Frame;\n frame.src = videoEmbedUrl(ref);\n frame.title = this.root.getAttribute(VideoAttribute.Title) || this.words.playUntitled(VIDEO_PROVIDER_LABEL[ref.source]);\n frame.setAttribute('allow', IFRAME_ALLOW);\n frame.setAttribute('allowfullscreen', '');\n frame.setAttribute('referrerpolicy', 'strict-origin-when-cross-origin');\n this.root.replaceChildren(frame);\n this.root.removeAttribute(VideoAttribute.Asking);\n this.root.setAttribute(VideoAttribute.Playing, '');\n frame.focus();\n }\n\n // ── uploaded file ─────────────────────────────────────────────────────────────────────────────\n\n private attachFile(): void {\n const video = this.root.querySelector<HTMLVideoElement>(`video.${VideoClass.Media}`);\n if (!video) return;\n if (this.root.getAttribute(VideoAttribute.Mode) === VideoMode.Background) {\n this.attachBackground(video);\n return;\n }\n const play = this.root.querySelector<HTMLButtonElement>(`button.${VideoClass.Play}`);\n const hidePlay = () => { if (play) play.hidden = true; };\n this.on(play, 'click', () => { hidePlay(); void video.play()?.catch?.(() => undefined); video.focus(); });\n this.on(video, 'play', hidePlay);\n // Autoplay (muted) only while motion is allowed — never under reduced motion.\n if (this.root.hasAttribute(VideoAttribute.Autoplay) && !this.reduced()) {\n video.muted = true;\n void video.play()?.catch?.(() => undefined);\n }\n }\n\n private attachBackground(video: HTMLVideoElement): void {\n const toggle = this.root.querySelector<HTMLButtonElement>(`.${VideoClass.Toggle}`);\n video.muted = true;\n const sync = () => {\n const paused = video.paused;\n if (!toggle) return;\n toggle.setAttribute('aria-pressed', paused ? 'true' : 'false');\n toggle.setAttribute('aria-label', paused ? this.words.playBackground : this.words.pauseBackground);\n const icon = toggle.querySelector('i');\n if (icon) icon.className = paused ? VideoIcon.Play : VideoIcon.Pause;\n };\n this.on(video, 'play', sync);\n this.on(video, 'pause', sync);\n this.on(toggle, 'click', () => {\n if (video.paused) void video.play()?.catch?.(() => undefined);\n else video.pause();\n sync();\n });\n // It moves only when motion is allowed; under reduced motion it rests on its poster, paused.\n if (!this.reduced()) void video.play()?.catch?.(() => sync());\n sync();\n }\n}\n\n/** Run the video at `el` (a `[data-iox-video]` element) once; null when it is not one or already runs. */\nexport function attachVideoAt(el: HTMLElement | null | undefined, options: VideoRuntimeOptions = {}): VideoRuntime | null {\n if (!el?.hasAttribute?.(VideoAttribute.Root)) return null;\n const host = el as unknown as Record<string, unknown>;\n if (host[RUNTIME_KEY]) return null;\n const runtime = new VideoRuntime(el, options);\n host[RUNTIME_KEY] = runtime;\n return runtime;\n}\n\n/** Every video under `container` that is not running yet (the string path's globals and pages). */\nexport function attachVideos(container: ParentNode, options: VideoRuntimeOptions = {}): VideoRuntime[] {\n return Array.from(container.querySelectorAll<HTMLElement>(`[${VideoAttribute.Root}]`))\n .map(el => attachVideoAt(el, options))\n .filter((r): r is VideoRuntime => !!r);\n}\n\n/** The runtime already running at `el`, if any. */\nexport function videoRuntimeOf(el: Element | null | undefined): VideoRuntime | null {\n return ((el as unknown as Record<string, unknown> | null)?.[RUNTIME_KEY] as VideoRuntime | undefined) ?? null;\n}\n","/**\n * @vectoriox/iox-ui/media-core — media decisions shared by the builder, both engine paths and iox-cms (CC3).\n * FRAMEWORK-FREE: `planVideo` is the one place that knows a YouTube / Vimeo address, the player's host and the consent\n * category a facade waits for; the runtime is DOM-only. iox-cms reads `parseVideoUrl` / `videoThumbnailRequest` to\n * fetch and store an embed's poster (the visitor never asks the provider for it).\n * ⚠️ Consumers wire the usual trio — ng-package raw-ts assets, jest moduleNameMapper, tsconfig paths.\n */\nexport * from './video';\nexport * from './video-runtime';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vectoriox-iox-ui-media-core.mjs","sources":["../../../projects/iox-ui/src/media-core/frames.ts","../../../projects/iox-ui/src/media-core/video.ts","../../../projects/iox-ui/src/media-core/video-runtime.ts","../../../projects/iox-ui/src/media-core/public-api.ts","../../../projects/iox-ui/src/media-core/vectoriox-iox-ui-media-core.ts"],"sourcesContent":["/**\n * A video played by the scroll, as pictures (premium sites SC4). Every source, a video file or a folder of rendered frames,\n * becomes the same numbered set of pictures, prepared once in the author's browser, one set for wide screens and a lighter\n * one for phones. So there is one player and it is the same on every browser: a `<video>` seeked by the scroll needs a\n * dense-keyframe encode no pod here can run, and on an iPhone it accepts seeks it never answers.\n *\n * The saved value is a small description, never a list of addresses: a page holding 300 URLs would ship them in its HTML.\n */\n\nexport enum FrameSet {\n Wide = 'w',\n Phone = 'p',\n}\n\nexport interface FrameSetInfo {\n count: number;\n width: number;\n height: number;\n}\n\nexport interface FrameSequence {\n /** Where the numbered pictures live: `<base>/<set>/0001.<ext>`. */\n base: string;\n ext: FrameExtension;\n wide: FrameSetInfo;\n /** Absent = phones play the wide set. */\n phone?: FrameSetInfo;\n /** What the sequence weighs in storage, both sets. Shown to the author. */\n bytes?: number;\n}\n\nexport enum FrameExtension {\n Webp = 'webp',\n Jpeg = 'jpg',\n}\n\n/** The most pictures one set may hold. Past this a phone runs out of memory before the visitor runs out of scroll. */\nexport const MAX_FRAMES = 300;\n/** The most one picture may weigh when uploaded. */\nexport const MAX_FRAME_BYTES = 3 * 1024 * 1024;\n/** A sequence's name in storage: what the browser generates and what the server accepts in a key. */\nexport const FRAME_SEQUENCE_ID = /^[a-z0-9]{8,40}$/;\n\nconst SAFE_BASE = /^https:\\/\\/[^\\s\"'<>\\\\]+$/;\nconst PAD = 4;\nconst ALL_EXTENSIONS: ReadonlySet<string> = new Set(Object.values(FrameExtension));\n\nfunction setInfo(raw: unknown): FrameSetInfo | null {\n const { count, width, height } = (raw ?? {}) as Partial<FrameSetInfo>;\n const valid = (v: unknown, max: number): v is number => Number.isInteger(v) && (v as number) > 0 && (v as number) <= max;\n return valid(count, MAX_FRAMES) && valid(width, 8192) && valid(height, 8192) ? { count, width, height } : null;\n}\n\n/** The sequence a saved value really describes, or null. Never throws on what a page document holds. */\nexport function normalizeFrameSequence(raw: unknown): FrameSequence | null {\n const value = (typeof raw === 'string' ? parseJson(raw) : raw) as Partial<FrameSequence> | null;\n if (!value || typeof value !== 'object') return null;\n const wide = setInfo(value.wide);\n if (!wide || typeof value.base !== 'string' || !SAFE_BASE.test(value.base) || !ALL_EXTENSIONS.has(String(value.ext))) return null;\n const phone = setInfo(value.phone);\n return {\n base: value.base.replace(/\\/+$/, ''),\n ext: value.ext as FrameExtension,\n wide,\n ...(phone ? { phone } : {}),\n ...(Number.isFinite(value.bytes) && (value.bytes as number) > 0 ? { bytes: value.bytes } : {}),\n };\n}\n\nfunction parseJson(raw: string): unknown {\n try { return JSON.parse(raw); } catch { return null; }\n}\n\n/** The name a picture is stored under: its place in the set, from 1. */\nexport function frameFileName(index: number, ext: FrameExtension): string {\n return `${String(index + 1).padStart(PAD, '0')}.${ext}`;\n}\n\n/** Picture `index` (from 0) of a set. */\nexport function frameUrl(sequence: FrameSequence, set: FrameSet, index: number): string {\n return `${sequence.base}/${set}/${frameFileName(index, sequence.ext)}`;\n}\n\n/** The first picture of each set, for a poster's `srcset`; '' when there is only one set. */\nexport function phoneFrameSrcset(sequence: FrameSequence): string {\n if (!sequence.phone) return '';\n return `${frameUrl(sequence, FrameSet.Phone, 0)} ${sequence.phone.width}w, ${frameUrl(sequence, FrameSet.Wide, 0)} ${sequence.wide.width}w`;\n}\n\n/** Which set plays: the phone's on a phone, when there is one. */\nexport function frameSetFor(sequence: FrameSequence, phone: boolean): { set: FrameSet; info: FrameSetInfo } {\n return phone && sequence.phone ? { set: FrameSet.Phone, info: sequence.phone } : { set: FrameSet.Wide, info: sequence.wide };\n}\n\n/** The picture at `played` % of a set of `count`. */\nexport function frameIndexAt(played: number, count: number): number {\n if (count <= 1) return 0;\n return Math.round((Math.min(100, Math.max(0, played)) / 100) * (count - 1));\n}\n\n/**\n * The order to fetch a set in: the two ends, then every 16th, every 8th and so on down to all of them. Any scroll position\n * then has a near picture almost at once, and the movement sharpens as the rest arrive. Fetching in sequence would leave a\n * visitor who scrolls fast looking at the first frames.\n */\nexport function frameLoadOrder(count: number): number[] {\n const order: number[] = [];\n const seen = new Set<number>();\n const add = (i: number): void => {\n if (i >= 0 && i < count && !seen.has(i)) {\n seen.add(i);\n order.push(i);\n }\n };\n add(0);\n add(count - 1);\n for (let stride = 16; stride >= 1; stride /= 2) {\n for (let i = 0; i < count; i += stride) add(i);\n }\n return order;\n}\n\n/** The loaded picture nearest `index`, or -1 when none has arrived. Ties go backward: the picture already passed. */\nexport function nearestLoadedFrame(loaded: ReadonlyArray<unknown>, index: number): number {\n for (let distance = 0; distance < loaded.length; distance++) {\n if (loaded[index - distance]) return index - distance;\n if (loaded[index + distance]) return index + distance;\n }\n return -1;\n}\n\nexport interface FrameSizes {\n width: number;\n height: number;\n}\n\n/** The longest side of a wide picture and of a phone picture. A phone's is not its width: a landscape video covers a\n * tall stage by its height, so a picture sized to the phone's width would be enlarged five times. */\nexport const WIDE_LONG_SIDE = 1600;\nexport const PHONE_LONG_SIDE = 1100;\n/** How many pictures a second of video becomes, before the cap. */\nconst VIDEO_FRAMES_PER_SECOND = 24;\n/** A video's cap: the pictures a scroll can show, at a weight a page can carry. A set of pictures is the author's own count. */\nconst VIDEO_MAX_FRAMES = 180;\n\n/** `width`×`height` fitted inside `longSide`, never enlarged. */\nexport function fittedFrameSize(width: number, height: number, longSide: number): FrameSizes {\n const scale = Math.min(1, longSide / Math.max(width, height));\n return { width: Math.max(1, Math.round(width * scale)), height: Math.max(1, Math.round(height * scale)) };\n}\n\n/** How many pictures a video of `seconds` becomes. */\nexport function videoFrameCount(seconds: number): number {\n return Math.min(VIDEO_MAX_FRAMES, Math.max(2, Math.ceil(seconds * VIDEO_FRAMES_PER_SECOND)));\n}\n\n/** Which of `sourceCount` pictures make a set of `count`, spread evenly, first and last always in. */\nexport function sampledFrameIndexes(sourceCount: number, count: number): number[] {\n if (count >= sourceCount) return Array.from({ length: sourceCount }, (_, i) => i);\n if (count <= 1) return [0];\n return Array.from({ length: count }, (_, i) => Math.round((i * (sourceCount - 1)) / (count - 1)));\n}\n\n/** A phone plays half the pictures: it has less memory, and half is plenty on a small screen. */\nexport function phoneFrameCount(wideCount: number): number {\n return Math.max(2, Math.ceil(wideCount / 2));\n}\n\nconst NATURAL = new Intl.Collator('en', { numeric: true, sensitivity: 'base' });\n\n/** Rendered frames in their real order: `frame2` before `frame10`. */\nexport function sortFrameFiles<T extends { name: string }>(files: ReadonlyArray<T>): T[] {\n return [...files].sort((a, b) => NATURAL.compare(a.name, b.name));\n}\n\n/** A sequence's weight, for the author. */\nexport function frameSummary(sequence: FrameSequence): { frames: number; megabytes: number | null } {\n return { frames: sequence.wide.count, megabytes: sequence.bytes ? Math.round((sequence.bytes / (1024 * 1024)) * 10) / 10 : null };\n}\n\nexport enum FramesClass {\n Canvas = 'iox-video__frames',\n}\n\nconst LOAD_CONCURRENCY = 6;\nconst NEAR_MARGIN = '100% 0px';\n/** Under these the visitor keeps the poster: nobody on a metered 2G connection asked to download a film. */\nconst SLOW_CONNECTIONS: ReadonlySet<string> = new Set(['slow-2g', '2g']);\n\ninterface NetworkInformationLike {\n saveData?: boolean;\n effectiveType?: string;\n}\n\nexport interface FramePlayerOptions {\n /** Play the phone's set. */\n phone?: boolean;\n /** Start fetching when this comes near the screen. Not the layer itself: a layer clipped shut intersects nothing. */\n near?: Element;\n /** The window, for a test. */\n host?: Window;\n}\n\n/**\n * The player: draws the picture nearest what the scroll asked for on a canvas laid over the poster, and nothing until a\n * first picture has arrived, so the poster is what a visitor sees until then, and for good if the pictures never come.\n * Browser only. It writes and never reads, so the driver can call it in its write phase.\n */\nexport class FramePlayer {\n private readonly set: FrameSet;\n private readonly info: FrameSetInfo;\n private readonly images: Array<HTMLImageElement | null>;\n private readonly order: number[];\n private readonly host: Window;\n private observer: IntersectionObserver | null = null;\n private canvas: HTMLCanvasElement | null = null;\n private context: CanvasRenderingContext2D | null = null;\n private wanted = 0;\n private drawn = -1;\n private nextToLoad = 0;\n private loading = 0;\n private started = false;\n private destroyed = false;\n private readonly pending = new Set<HTMLImageElement>();\n\n constructor(private readonly el: HTMLElement, private readonly sequence: FrameSequence, options: FramePlayerOptions = {}) {\n this.host = options.host ?? window;\n const { set, info } = frameSetFor(sequence, !!options.phone);\n this.set = set;\n this.info = info;\n this.images = new Array(info.count).fill(null);\n this.order = frameLoadOrder(info.count);\n if (!this.allowed()) return;\n const Observer = (this.host as Window & { IntersectionObserver?: typeof IntersectionObserver }).IntersectionObserver;\n if (!Observer) {\n this.start();\n return;\n }\n this.observer = new Observer(entries => {\n if (entries.some(entry => entry.isIntersecting)) this.start();\n }, { rootMargin: NEAR_MARGIN });\n this.observer.observe(options.near ?? el);\n }\n\n /** Stand at `played` %. */\n seek(played: number): void {\n this.wanted = frameIndexAt(played, this.info.count);\n this.draw();\n }\n\n /** Whether a re-render took the canvas away with the markup it sat in. */\n get detached(): boolean {\n return !!this.canvas && !this.canvas.isConnected;\n }\n\n destroy(): void {\n this.destroyed = true;\n this.observer?.disconnect();\n this.observer = null;\n for (const image of this.pending) {\n image.onload = null;\n image.onerror = null;\n image.src = '';\n }\n this.pending.clear();\n this.canvas?.remove();\n this.canvas = null;\n this.context = null;\n }\n\n private allowed(): boolean {\n const connection = (this.host.navigator as Navigator & { connection?: NetworkInformationLike } | undefined)?.connection;\n return !connection?.saveData && !SLOW_CONNECTIONS.has(connection?.effectiveType ?? '');\n }\n\n private start(): void {\n if (this.started) return;\n this.started = true;\n this.observer?.disconnect();\n this.observer = null;\n this.pump();\n }\n\n private pump(): void {\n while (!this.destroyed && this.loading < LOAD_CONCURRENCY && this.nextToLoad < this.order.length) {\n this.load(this.order[this.nextToLoad++]);\n }\n }\n\n private load(index: number): void {\n const image = this.host.document.createElement('img');\n image.decoding = 'async';\n this.loading++;\n this.pending.add(image);\n const done = (arrived: boolean): void => {\n this.pending.delete(image);\n this.loading--;\n if (this.destroyed) return;\n if (arrived) {\n this.images[index] = image;\n this.draw();\n }\n this.pump();\n };\n // Decoded before it counts, or the first draw of each picture decodes on the driver's frame and the scroll stutters.\n image.onload = () => {\n const decoded = image.decode?.();\n if (decoded) void decoded.then(() => done(true), () => done(true));\n else done(true);\n };\n // A picture that failed is a gap: its neighbours stand in.\n image.onerror = () => done(false);\n image.src = frameUrl(this.sequence, this.set, index);\n }\n\n private draw(): void {\n const index = nearestLoadedFrame(this.images, this.wanted);\n if (index < 0 || index === this.drawn) return;\n const image = this.images[index]!;\n if (!this.ensureCanvas(image)) return;\n this.context!.clearRect(0, 0, this.canvas!.width, this.canvas!.height);\n this.context!.drawImage(image, 0, 0, this.canvas!.width, this.canvas!.height);\n this.drawn = index;\n }\n\n private ensureCanvas(image: HTMLImageElement): boolean {\n if (this.canvas) return !!this.context;\n const canvas = this.host.document.createElement('canvas');\n canvas.className = FramesClass.Canvas;\n canvas.setAttribute('aria-hidden', 'true');\n canvas.width = image.naturalWidth || this.info.width;\n canvas.height = image.naturalHeight || this.info.height;\n this.context = canvas.getContext('2d');\n if (!this.context) return false;\n this.canvas = canvas;\n this.el.appendChild(canvas);\n return true;\n }\n}\n","import { ConsentCategory, ConsentDecision, hasConsent } from '@vectoriox/iox-ui/consent-core';\n\nimport { FrameSequence, FrameSet, frameUrl, normalizeFrameSequence, phoneFrameSrcset } from './frames';\n\n/**\n * VIDEO (CC3 — complex-components plan §7b, board 5). A LEAF type with two sources:\n * - an uploaded FILE renders as a real `<video>` (poster, `preload=\"metadata\"`, captions, controls);\n * - a YouTube / Vimeo address is ALWAYS a FACADE (D5): the studio's poster and a play button named after the video,\n * behind the site's consent gate (Marketing). The player's `<iframe>` exists only after a click AND a grant —\n * never in the server's HTML, never on the builder canvas.\n *\n * `planVideo(node, consent)` is the ONE decision — the only code that knows the URL shapes, the embed hosts and the\n * consent category. Both engine paths and the canvas render from it (`videoInnerHtml`), and the runtime\n * (`video-runtime.ts`) builds the player's address from the same plan.\n */\n\nexport const VIDEO_NODE_TYPE = 'Video';\n\nexport enum VideoSource {\n File = 'file',\n YouTube = 'youtube',\n Vimeo = 'vimeo',\n}\n\nexport enum VideoMode {\n /** In the page, with the player's controls. */\n Inline = 'inline',\n /** Muted, looped, no controls, an always-visible pause button (WCAG 2.2.2) — an uploaded file only. */\n Background = 'background',\n}\n\n/** The node's traits (Bindings ▸ Media · Behaviour · Accessibility · Privacy). */\nexport enum VideoTrait {\n /** Not `source`: across the builder `source` names a DATA source (a Repeater's, a Slider's). */\n Source = 'videoSource',\n Src = 'src',\n Poster = 'poster',\n Mode = 'mode',\n Autoplay = 'autoplay',\n Title = 'title',\n Captions = 'captions',\n CaptionsLang = 'captionsLang',\n Consent = 'consentCategory',\n /** Pictures the scroll plays (SC4): a `FrameSequence`. Written by the Scene panel, never typed. */\n Frames = 'frames',\n}\n\n/** What a plan renders. */\nexport enum VideoKind {\n /** An uploaded file: a real `<video>`. */\n File = 'file',\n /** YouTube / Vimeo: poster + play, the player loaded on a click after consent. */\n Facade = 'facade',\n /** No address yet: the poster blank (DS3) and nothing to play. */\n Empty = 'empty',\n /** Pictures the scroll plays: the poster, and the driver's canvas over it. No player, no controls. */\n Frames = 'frames',\n}\n\n/** A recognised embed: which provider, its video id and (Vimeo, unlisted) its privacy hash. */\nexport interface VideoRef {\n source: VideoSource.YouTube | VideoSource.Vimeo;\n id: string;\n hash?: string;\n}\n\nexport const VIDEO_PROVIDER_LABEL: Readonly<Record<VideoRef['source'], string>> = {\n [VideoSource.YouTube]: 'YouTube',\n [VideoSource.Vimeo]: 'Vimeo',\n};\n\n/** Who the visitor's IP address and cookies go to, named in the consent prompt. */\nexport const VIDEO_PROVIDER_COMPANY: Readonly<Record<VideoRef['source'], string>> = {\n [VideoSource.YouTube]: 'Google',\n [VideoSource.Vimeo]: 'Vimeo',\n};\n\n/** The two hosts a player ever loads from — youtube-nocookie and Vimeo's player (with Do Not Track). */\nexport const VIDEO_EMBED_ORIGINS: ReadonlyArray<string> = ['https://www.youtube-nocookie.com', 'https://player.vimeo.com'];\n\nconst YOUTUBE_ID = /^[A-Za-z0-9_-]{11}$/;\nconst VIMEO_ID = /^\\d{6,12}$/;\nconst VIMEO_HASH = /^[0-9a-f]{6,20}$/i;\nconst YOUTUBE_HOSTS = new Set(['youtube.com', 'www.youtube.com', 'm.youtube.com', 'music.youtube.com', 'youtube-nocookie.com', 'www.youtube-nocookie.com']);\nconst YOUTUBE_SHORT_HOSTS = new Set(['youtu.be', 'www.youtu.be']);\nconst YOUTUBE_PATH_PREFIXES = ['embed', 'shorts', 'live', 'v'];\nconst VIMEO_HOSTS = new Set(['vimeo.com', 'www.vimeo.com', 'player.vimeo.com']);\n\nfunction toUrl(raw: string): URL | null {\n const text = raw.trim();\n if (!text) return null;\n try {\n return new URL(/^[a-z][a-z0-9+.-]*:\\/\\//i.test(text) ? text : `https://${text}`);\n } catch {\n return null;\n }\n}\n\nfunction parseYouTube(url: URL): VideoRef | null {\n const host = url.hostname.toLowerCase();\n const segments = url.pathname.split('/').filter(Boolean);\n let id: string | null = null;\n if (YOUTUBE_SHORT_HOSTS.has(host)) id = segments[0] ?? null;\n else if (YOUTUBE_HOSTS.has(host)) {\n if (segments[0] === 'watch') id = url.searchParams.get('v');\n else if (YOUTUBE_PATH_PREFIXES.includes(segments[0] ?? '')) id = segments[1] ?? null;\n } else return null;\n return id && YOUTUBE_ID.test(id) ? { source: VideoSource.YouTube, id } : null;\n}\n\nfunction parseVimeo(url: URL): VideoRef | null {\n if (!VIMEO_HOSTS.has(url.hostname.toLowerCase())) return null;\n const segments = url.pathname.split('/').filter(Boolean);\n // player.vimeo.com/video/<id>, vimeo.com/<id>[/<hash>], vimeo.com/channels/<c>/<id>, vimeo.com/groups/<g>/videos/<id>\n const index = segments.findIndex(s => VIMEO_ID.test(s));\n if (index < 0) return null;\n const id = segments[index];\n const hash = url.searchParams.get('h') ?? segments[index + 1];\n return { source: VideoSource.Vimeo, id, ...(hash && VIMEO_HASH.test(hash) ? { hash } : {}) };\n}\n\n/** The embed a pasted address names — a YouTube or Vimeo watch, share, embed or short link — or null. */\nexport function parseVideoUrl(raw: string | null | undefined): VideoRef | null {\n const url = typeof raw === 'string' ? toUrl(raw) : null;\n if (!url || !/^https?:$/.test(url.protocol)) return null;\n return parseYouTube(url) ?? parseVimeo(url);\n}\n\n/** The source a node plays: its declared source when it is one, else what its address is. */\nexport function videoSourceOf(src: unknown, declared?: unknown): VideoSource {\n if (declared === VideoSource.YouTube || declared === VideoSource.Vimeo || declared === VideoSource.File) return declared;\n return parseVideoUrl(typeof src === 'string' ? src : '')?.source ?? VideoSource.File;\n}\n\n/** The player's address — loaded only after a click and a grant. Autoplays (the visitor just pressed play). */\nexport function videoEmbedUrl(ref: VideoRef): string {\n if (ref.source === VideoSource.YouTube) {\n return `https://www.youtube-nocookie.com/embed/${encodeURIComponent(ref.id)}?autoplay=1&rel=0&playsinline=1`;\n }\n return `https://player.vimeo.com/video/${encodeURIComponent(ref.id)}?autoplay=1&dnt=1${ref.hash ? `&h=${encodeURIComponent(ref.hash)}` : ''}`;\n}\n\n/** Where the SERVER fetches an embed's thumbnail to store as the studio's own poster (never the visitor). */\nexport interface VideoThumbnailRequest {\n /** `image`: the url IS the picture; `oembed`: the url answers JSON whose `thumbnail_url` is the picture. */\n kind: 'image' | 'oembed';\n url: string;\n /** The only hosts the picture itself may come from (the server refuses anything else). */\n imageHosts: ReadonlyArray<string>;\n}\n\nexport function videoThumbnailRequest(ref: VideoRef): VideoThumbnailRequest {\n if (ref.source === VideoSource.YouTube) {\n return { kind: 'image', url: `https://i.ytimg.com/vi/${encodeURIComponent(ref.id)}/hqdefault.jpg`, imageHosts: ['i.ytimg.com'] };\n }\n const page = `https://vimeo.com/${ref.id}${ref.hash ? `/${ref.hash}` : ''}`;\n return { kind: 'oembed', url: `https://vimeo.com/api/oembed.json?url=${encodeURIComponent(page)}&width=1280`, imageHosts: ['i.vimeocdn.com'] };\n}\n\n/** A stored poster's object name — one per video, so fetching it again overwrites rather than piles up. */\nexport function videoPosterFileName(ref: VideoRef): string {\n return `video-poster-${ref.source}-${ref.id}.jpg`;\n}\n\n// ── the node, in either shape (saved props / builder traits) ───────────────────────────────────────\n\nexport interface VideoNodeLike {\n type?: string;\n props?: Record<string, unknown> | null;\n traits?: ReadonlyArray<{ name?: string; default?: unknown }> | null;\n}\n\n/** A content value of a Video node, saved (`props`) or builder (`traits[].default`) shape. */\nexport function videoProp(node: VideoNodeLike | null | undefined, name: VideoTrait | string): unknown {\n if (!node) return undefined;\n if (node.props && Object.prototype.hasOwnProperty.call(node.props, name)) return node.props[name];\n return node.traits?.find(t => t?.name === name)?.default;\n}\n\nconst str = (v: unknown): string => (typeof v === 'string' ? v.trim() : '');\nconst truthy = (v: unknown): boolean => v === true || v === 'true';\n\n/** The consent category an embed waits for — Marketing by default (D5); an uploaded file waits for none. */\nexport function videoConsentCategory(node: VideoNodeLike | null | undefined, source: VideoSource = videoSourceOf(videoProp(node, VideoTrait.Src), videoProp(node, VideoTrait.Source))): ConsentCategory | null {\n if (source === VideoSource.File) return null;\n const declared = videoProp(node, VideoTrait.Consent);\n return declared === ConsentCategory.Analytics ? ConsentCategory.Analytics : ConsentCategory.Marketing;\n}\n\nexport interface VideoPlan {\n kind: VideoKind;\n source: VideoSource;\n /** An embed's provider and id (Facade). */\n ref: VideoRef | null;\n /** An uploaded file's address (File). */\n src: string;\n /** The studio's own poster ('' = the token blank). Never a provider's thumbnail URL. */\n poster: string;\n /** The video's name — the play button's accessible name. */\n title: string;\n mode: VideoMode;\n background: boolean;\n /** Muted autoplay when motion is allowed (the runtime asks; the server never writes `autoplay`). */\n autoplay: boolean;\n muted: boolean;\n loop: boolean;\n controls: boolean;\n /** A `.vtt` file ('' = none). */\n captions: string;\n captionsLang: string;\n /** What the facade waits for (null for a file). */\n consentCategory: ConsentCategory | null;\n /** The visitor's decision grants it. */\n granted: boolean;\n /** The player's address — only when granted (the runtime loads it on a click). */\n embedUrl: string | null;\n /** \"YouTube\" / \"Vimeo\" ('' for a file). */\n providerLabel: string;\n /** Pictures the scroll plays (Frames). */\n frames: FrameSequence | null;\n}\n\n/**\n * The ONE decision for a Video node and a visitor's consent (null = none recorded — the server always passes null,\n * so its HTML is always the facade). A poster that is a provider's thumbnail URL is dropped: the poster is the\n * studio's own image (or the thumbnail the server fetched and stored for it), never a request to a third party.\n */\nexport function planVideo(node: VideoNodeLike | null | undefined, consent: ConsentDecision | null): VideoPlan {\n const frames = normalizeFrameSequence(videoProp(node, VideoTrait.Frames));\n if (frames) return planFrames(node, frames);\n const rawSrc = str(videoProp(node, VideoTrait.Src));\n const source = videoSourceOf(rawSrc, videoProp(node, VideoTrait.Source));\n const ref = source === VideoSource.File ? null : parseVideoUrl(rawSrc);\n const background = source === VideoSource.File && videoProp(node, VideoTrait.Mode) === VideoMode.Background;\n const consentCategory = videoConsentCategory(node, source);\n const granted = consentCategory ? hasConsent(consent, consentCategory) : true;\n const kind = source === VideoSource.File ? (rawSrc ? VideoKind.File : VideoKind.Empty) : (ref ? VideoKind.Facade : VideoKind.Empty);\n const poster = str(videoProp(node, VideoTrait.Poster));\n return {\n kind,\n source,\n ref,\n src: source === VideoSource.File ? rawSrc : '',\n poster: isThirdPartyPoster(poster) ? '' : poster,\n title: str(videoProp(node, VideoTrait.Title)),\n mode: background ? VideoMode.Background : VideoMode.Inline,\n background,\n autoplay: background || (source === VideoSource.File && truthy(videoProp(node, VideoTrait.Autoplay))),\n muted: background || truthy(videoProp(node, VideoTrait.Autoplay)),\n loop: background,\n controls: !background,\n captions: background ? '' : str(videoProp(node, VideoTrait.Captions)),\n captionsLang: str(videoProp(node, VideoTrait.CaptionsLang)) || 'en',\n consentCategory,\n granted,\n embedUrl: kind === VideoKind.Facade && granted && ref ? videoEmbedUrl(ref) : null,\n providerLabel: ref ? VIDEO_PROVIDER_LABEL[ref.source] : '',\n frames: null,\n };\n}\n\n/** Pictures win over any address the node also holds: it was turned into them. No player, no consent, nothing to press. */\nfunction planFrames(node: VideoNodeLike | null | undefined, frames: FrameSequence): VideoPlan {\n const poster = str(videoProp(node, VideoTrait.Poster));\n return {\n kind: VideoKind.Frames,\n source: VideoSource.File,\n ref: null,\n src: '',\n poster: poster && !isThirdPartyPoster(poster) ? poster : frameUrl(frames, FrameSet.Wide, 0),\n title: str(videoProp(node, VideoTrait.Title)),\n mode: VideoMode.Inline,\n background: false,\n autoplay: false,\n muted: false,\n loop: false,\n controls: false,\n captions: '',\n captionsLang: 'en',\n consentCategory: null,\n granted: true,\n embedUrl: null,\n providerLabel: '',\n frames,\n };\n}\n\nconst THIRD_PARTY_POSTER_HOSTS = ['ytimg.com', 'youtube.com', 'vimeocdn.com', 'vimeo.com', 'googleusercontent.com'];\n\n/** A poster served by the video's provider — a request to a third party before consent, so it never renders. */\nexport function isThirdPartyPoster(url: string): boolean {\n const parsed = url ? toUrl(url) : null;\n if (!parsed || !/^https?:$/.test(parsed.protocol)) return false;\n const host = parsed.hostname.toLowerCase();\n return THIRD_PARTY_POSTER_HOSTS.some(h => host === h || host.endsWith(`.${h}`));\n}\n\n// ── words ───────────────────────────────────────────────────────────────────────────────────────────\n\n/**\n * The words the renderer draws (board 5; Q7: the consent prompt is NOT an editable part — its words are the\n * consent vocabulary's, one source, translated). English and Hebrew; the page's `lang` picks.\n */\nexport interface VideoWords {\n /** The play button's name: the video's title and its provider. */\n play(title: string, provider: string): string;\n /** The play button's name with no title. */\n playUntitled(provider: string): string;\n pauseBackground: string;\n playBackground: string;\n /** The consent prompt (a group): its name, its lead and its body. */\n promptLabel: string;\n promptLead(provider: string): string;\n promptBody(company: string): string;\n /** The same prompt where the player is narrow (board 5's phone): one shorter sentence, its lead in bold. */\n promptCompactLead(provider: string): string;\n promptCompactBody: string;\n allow: string;\n settings: string;\n}\n\nexport const VIDEO_WORDS: Readonly<Record<'en' | 'he', VideoWords>> = {\n en: {\n play: (title, provider) => (provider ? `Play: ${title} (${provider})` : `Play: ${title}`),\n playUntitled: provider => (provider ? `Play video (${provider})` : 'Play video'),\n pauseBackground: 'Pause background video',\n playBackground: 'Play background video',\n promptLabel: 'This video needs your permission',\n promptLead: provider => `This video is hosted by ${provider}.`,\n promptBody: company => `Playing it lets ${company} set cookies and see your IP address. Nothing has loaded yet.`,\n promptCompactLead: provider => `Plays from ${provider},`,\n promptCompactBody: 'which sets cookies and sees your IP address. Nothing has loaded yet.',\n allow: 'Allow and play',\n settings: 'Privacy settings',\n },\n he: {\n play: (title, provider) => (provider ? `הפעלה: ${title} (${provider})` : `הפעלה: ${title}`),\n playUntitled: provider => (provider ? `הפעלת הסרטון (${provider})` : 'הפעלת הסרטון'),\n pauseBackground: 'השהיית סרטון הרקע',\n playBackground: 'הפעלת סרטון הרקע',\n promptLabel: 'הסרטון הזה צריך את רשותך',\n promptLead: provider => `הסרטון מתארח ב-${provider}.`,\n promptBody: company => `ההפעלה מאפשרת ל-${company} להגדיר קובצי Cookie ולראות את כתובת ה-IP שלך. עדיין לא נטען דבר.`,\n promptCompactLead: provider => `מתנגן מ-${provider},`,\n promptCompactBody: 'שמגדיר קובצי Cookie ורואה את כתובת ה-IP שלך. עדיין לא נטען דבר.',\n allow: 'לאשר ולהפעיל',\n settings: 'הגדרות פרטיות',\n },\n};\n\n/** The words for a page language (`he`, `he-IL` → Hebrew; anything else → English). */\nexport function videoWords(lang?: string | null): VideoWords {\n return (lang ?? '').toLowerCase().startsWith('he') ? VIDEO_WORDS.he : VIDEO_WORDS.en;\n}\n\n/** The play button's accessible name. */\nexport function videoPlayLabel(plan: VideoPlan, words: VideoWords = VIDEO_WORDS.en): string {\n return plan.title ? words.play(plan.title, plan.providerLabel) : words.playUntitled(plan.providerLabel);\n}\n\n// ── markup (one builder for both engine paths and the canvas) ────────────────────────────────────────\n\nexport enum VideoClass {\n Root = 'iox-video',\n Poster = 'iox-video__poster',\n Play = 'iox-video__play',\n Badge = 'iox-video__badge',\n Media = 'iox-video__media',\n Frame = 'iox-video__frame',\n Toggle = 'iox-video__toggle',\n Consent = 'iox-video__consent',\n ConsentText = 'iox-video__consent-text',\n /** The prompt's text on a wide player / on a narrow one (a container query shows one). */\n ConsentWide = 'iox-video__consent-wide',\n ConsentCompact = 'iox-video__consent-compact',\n ConsentRow = 'iox-video__consent-row',\n Allow = 'iox-video__allow',\n Settings = 'iox-video__settings',\n}\n\nexport enum VideoAttribute {\n /** On the node element: its kind (`file` · `facade` · `empty`) — what the runtime attaches to. */\n Root = 'data-iox-video',\n Source = 'data-iox-video-source',\n Id = 'data-iox-video-id',\n Hash = 'data-iox-video-hash',\n Mode = 'data-iox-video-mode',\n Autoplay = 'data-iox-video-autoplay',\n Consent = 'data-iox-video-consent',\n Title = 'data-iox-video-title',\n /** The poster is the token blank (no image): the shared CSS fills it with `surface-2`. */\n PosterEmpty = 'data-iox-video-poster-empty',\n /** The player is loaded (after the click and the grant). */\n Playing = 'data-iox-video-playing',\n /** The consent prompt is showing. */\n Asking = 'data-iox-video-asking',\n /** The pictures the scroll plays, as JSON: what the driver reads, so it needs no node tree. */\n Frames = 'data-iox-video-frames',\n}\n\nexport enum VideoIcon {\n Play = 'ph-fill ph-play',\n Pause = 'ph-fill ph-pause',\n}\n\n/** The attributes the node's own element carries (both engine paths, the canvas). */\nexport function videoRootAttributes(plan: VideoPlan): Record<string, string> {\n const attrs: Record<string, string> = { [VideoAttribute.Root]: plan.kind, [VideoAttribute.Source]: plan.source };\n if (plan.ref) {\n attrs[VideoAttribute.Id] = plan.ref.id;\n if (plan.ref.hash) attrs[VideoAttribute.Hash] = plan.ref.hash;\n }\n if (plan.background) attrs[VideoAttribute.Mode] = VideoMode.Background;\n if (plan.autoplay) attrs[VideoAttribute.Autoplay] = '';\n if (plan.consentCategory) attrs[VideoAttribute.Consent] = plan.consentCategory;\n if (plan.title) attrs[VideoAttribute.Title] = plan.title;\n if (!plan.poster) attrs[VideoAttribute.PosterEmpty] = '';\n if (plan.frames) attrs[VideoAttribute.Frames] = JSON.stringify(plan.frames);\n return attrs;\n}\n\nexport interface VideoMarkupOptions {\n /** HTML-escape an attribute or text value. */\n esc: (value: string) => string;\n /** The builder canvas: the poster ONLY — no `<video>`, no player, nothing that loads or takes a click. */\n canvas?: boolean;\n words?: VideoWords;\n}\n\nconst iconHtml = (cls: string) => `<i class=\"${cls}\" aria-hidden=\"true\"></i>`;\n\n/** The element's inner markup. The server's HTML for a facade holds no `<iframe>` and requests nothing from\n * the provider: only the studio's poster, the play button and the (hidden) consent prompt. */\nexport function videoInnerHtml(plan: VideoPlan, options: VideoMarkupOptions): string {\n const { esc } = options;\n const words = options.words ?? VIDEO_WORDS.en;\n // The same on the canvas and on the site: the first picture is real content, so it is fetched at once, named, and the\n // size a phone needs. A driver's canvas covers it when pictures arrive; with no script it is what there is.\n if (plan.kind === VideoKind.Frames) {\n const own = !!plan.frames && !isAuthoredPoster(plan);\n const srcset = own ? phoneFrameSrcset(plan.frames!) : '';\n // Its real size, so where a Scene flows (reduced motion, no script) the picture holds its height before it loads.\n const size = own ? ` width=\"${plan.frames!.wide.width}\" height=\"${plan.frames!.wide.height}\"` : '';\n return `<img class=\"${VideoClass.Poster}\" src=\"${esc(plan.poster)}\"${srcset ? ` srcset=\"${esc(srcset)}\" sizes=\"100vw\"` : ''}${size} alt=\"${esc(plan.title)}\" decoding=\"async\">`;\n }\n const poster = plan.poster ? `<img class=\"${VideoClass.Poster}\" src=\"${esc(plan.poster)}\" alt=\"\" loading=\"lazy\" decoding=\"async\">` : '';\n const label = esc(videoPlayLabel(plan, words));\n const playSpan = `<span class=\"${VideoClass.Play}\" aria-hidden=\"true\">${iconHtml(VideoIcon.Play)}</span>`;\n const badge = plan.providerLabel ? `<span class=\"${VideoClass.Badge}\">${iconHtml(VideoIcon.Play)}${esc(plan.providerLabel)}</span>` : '';\n\n if (options.canvas || plan.kind === VideoKind.Empty) {\n return `${poster}${plan.kind === VideoKind.Empty && !options.canvas ? '' : playSpan}${badge}`;\n }\n\n if (plan.kind === VideoKind.File) {\n const media = [\n `<video class=\"${VideoClass.Media}\" src=\"${esc(plan.src)}\" preload=\"metadata\" playsinline`,\n plan.poster ? ` poster=\"${esc(plan.poster)}\"` : '',\n // A captions file is fetched with CORS (a <track> from another origin loads only so): the studio's bucket\n // answers CORS for every object, the video included.\n plan.captions ? ' crossorigin=\"anonymous\"' : '',\n plan.controls ? ' controls' : '',\n plan.muted ? ' muted' : '',\n plan.loop ? ' loop' : '',\n plan.background ? ' aria-hidden=\"true\" tabindex=\"-1\"' : (plan.title ? ` aria-label=\"${esc(plan.title)}\"` : ''),\n '>',\n plan.captions ? `<track kind=\"captions\" src=\"${esc(plan.captions)}\" srclang=\"${esc(plan.captionsLang)}\" label=\"${esc(plan.captionsLang)}\" default>` : '',\n '</video>',\n ].join('');\n if (plan.background) {\n // Rendered paused (the server cannot know the visitor's motion setting): the runtime starts it when motion\n // is allowed and turns this into the PAUSE button. Always visible (WCAG 2.2.2).\n return `${media}<button type=\"button\" class=\"${VideoClass.Toggle}\" aria-label=\"${esc(words.playBackground)}\" aria-pressed=\"true\">${iconHtml(VideoIcon.Play)}</button>`;\n }\n return `${media}<button type=\"button\" class=\"${VideoClass.Play}\" aria-label=\"${label}\">${iconHtml(VideoIcon.Play)}</button>`;\n }\n\n const company = plan.ref ? VIDEO_PROVIDER_COMPANY[plan.ref.source] : '';\n const prompt = `<div class=\"${VideoClass.Consent}\" role=\"group\" aria-label=\"${esc(words.promptLabel)}\" hidden>` +\n `<p class=\"${VideoClass.ConsentText} ${VideoClass.ConsentWide}\"><b>${esc(words.promptLead(plan.providerLabel))}</b> ${esc(words.promptBody(company))}</p>` +\n `<p class=\"${VideoClass.ConsentText} ${VideoClass.ConsentCompact}\"><b>${esc(words.promptCompactLead(plan.providerLabel))}</b> ${esc(words.promptCompactBody)}</p>` +\n `<div class=\"${VideoClass.ConsentRow}\">` +\n `<button type=\"button\" class=\"${VideoClass.Allow}\">${esc(words.allow)}</button>` +\n `<button type=\"button\" class=\"${VideoClass.Settings}\">${esc(words.settings)}</button>` +\n `</div></div>`;\n return `${poster}<button type=\"button\" class=\"${VideoClass.Play}\" aria-label=\"${label}\">${iconHtml(VideoIcon.Play)}</button>${badge}${prompt}`;\n}\n\nconst isAuthoredPoster = (plan: VideoPlan): boolean => !!plan.frames && plan.poster !== frameUrl(plan.frames, FrameSet.Wide, 0);\n\n/** Serialise attributes for a string renderer (a present boolean attribute is written bare). */\nexport function serializeVideoAttributes(attrs: Readonly<Record<string, string>>, esc: (value: string) => string): string {\n return Object.entries(attrs).map(([name, value]) => (value === '' ? ` ${name}` : ` ${name}=\"${esc(value)}\"`)).join('');\n}\n","import {\n CONSENT_COOKIE_NAME, ConsentCategory, ConsentDecision, cookieAttributes, decode, encode, hasConsent, setCategoryDecision,\n} from '@vectoriox/iox-ui/consent-core';\n\nimport { VIDEO_PROVIDER_LABEL, VideoAttribute, VideoClass, VideoIcon, VideoKind, VideoMode, VideoRef, VideoSource, videoEmbedUrl, VideoWords, videoWords } from './video';\n\n/**\n * The Video's RUNTIME (CC3, board 5) — DOM only, ONE copy for both engine paths (the component path attaches it from\n * its component, the string path from the page's interaction service; `attachVideoAt` is idempotent). It reads the\n * markup `videoInnerHtml` writes. The builder canvas never attaches it (the canvas shows the poster only).\n *\n * - FACADE: play → the visitor's consent grants the category → the player's `<iframe>` replaces the poster, focused,\n * autoplaying (the visitor just pressed play). Not granted → the consent prompt: \"Allow and play\" grants the\n * category in the site's ONE consent record (the banner and its preferences read the same cookie) and plays;\n * \"Privacy settings\" opens the site's own preferences dialog.\n * - FILE: the play button starts the `<video>`; muted autoplay only when motion is allowed.\n * - BACKGROUND: muted and looped; it plays only when motion is allowed (never under reduced motion), and its\n * pause button is always there (WCAG 2.2.2).\n */\n\n/** Ask the page to record a category the visitor granted (cancelable: the site's consent service handles it). */\nexport const CONSENT_GRANT_EVENT = 'iox-consent-grant';\n/** Ask the page to open its consent preferences (cancelable: handled = a dialog opened). */\nexport const CONSENT_PREFERENCES_EVENT = 'iox-consent-preferences';\n\nexport interface ConsentGrantDetail { category: ConsentCategory }\n\n/** How the runtime reads and writes the visitor's ONE consent record — the page's transport. */\nexport interface ConsentTransport {\n read(): ConsentDecision | null;\n /** Record the category as granted (synchronously, before the player loads). */\n grant(category: ConsentCategory): void;\n /** Open the site's privacy preferences; false when the page has none. */\n openPreferences(): boolean;\n}\n\nconst REDUCED_MOTION = '(prefers-reduced-motion: reduce)';\nconst RUNTIME_KEY = '__ioxVideo';\nconst IFRAME_ALLOW = 'autoplay; encrypted-media; picture-in-picture; fullscreen';\n\n/** The cookie the consent record lives in, read from a document. */\nexport function readConsentRecord(doc: Document): ConsentDecision | null {\n const raw = (doc.cookie ?? '').split('; ').find(c => c.startsWith(`${CONSENT_COOKIE_NAME}=`));\n return decode(raw ? decodeURIComponent(raw.slice(CONSENT_COOKIE_NAME.length + 1)) : null);\n}\n\n/**\n * The default transport: the page's own consent service answers the events (the engine records the decision, tells\n * Consent Mode, re-syncs the banner's switches); a page with no such service (the admin's Preview) records the cookie\n * itself, through the same consent-core decision, so the record is the same shape either way.\n */\nexport function documentConsentTransport(doc: Document): ConsentTransport {\n return {\n read: () => readConsentRecord(doc),\n grant: category => {\n const event = new CustomEvent<ConsentGrantDetail>(CONSENT_GRANT_EVENT, { detail: { category }, cancelable: true });\n doc.dispatchEvent(event);\n if (event.defaultPrevented) return;\n const previous = readConsentRecord(doc);\n const anonymousId = previous?.anonymousId ?? randomId();\n const decision = setCategoryDecision(previous, category, true, anonymousId, previous?.policyVersion ?? '1');\n const secure = doc.location?.protocol === 'https:';\n doc.cookie = `${CONSENT_COOKIE_NAME}=${encodeURIComponent(encode(decision))}; ${cookieAttributes(12, secure)}`;\n },\n openPreferences: () => {\n const event = new CustomEvent(CONSENT_PREFERENCES_EVENT, { cancelable: true });\n doc.dispatchEvent(event);\n return event.defaultPrevented;\n },\n };\n}\n\nfunction randomId(): string {\n const c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto;\n return c?.randomUUID ? c.randomUUID() : Math.random().toString(36).slice(2);\n}\n\nexport interface VideoRuntimeOptions {\n consent?: ConsentTransport;\n /** True to stop motion (default: the visitor's reduced-motion setting). */\n reducedMotion?: () => boolean;\n words?: VideoWords;\n}\n\n/** The embed a facade root names (its provider, id and hash attributes). */\nexport function videoRefOf(root: Element): VideoRef | null {\n const source = root.getAttribute(VideoAttribute.Source);\n const id = root.getAttribute(VideoAttribute.Id);\n if ((source !== VideoSource.YouTube && source !== VideoSource.Vimeo) || !id) return null;\n const hash = root.getAttribute(VideoAttribute.Hash);\n return { source, id, ...(hash ? { hash } : {}) };\n}\n\nexport class VideoRuntime {\n private readonly cleanups: Array<() => void> = [];\n private readonly consent: ConsentTransport;\n private readonly reduced: () => boolean;\n private readonly words: VideoWords;\n private readonly doc: Document;\n\n constructor(readonly root: HTMLElement, options: VideoRuntimeOptions = {}) {\n this.doc = root.ownerDocument;\n this.consent = options.consent ?? documentConsentTransport(this.doc);\n const view = this.doc.defaultView;\n this.reduced = options.reducedMotion ?? (() => !!view?.matchMedia?.(REDUCED_MOTION)?.matches);\n this.words = options.words ?? videoWords(this.doc.documentElement?.getAttribute('lang'));\n const kind = root.getAttribute(VideoAttribute.Root);\n if (kind === VideoKind.Facade) this.attachFacade();\n else if (kind === VideoKind.File) this.attachFile();\n }\n\n destroy(): void {\n this.cleanups.splice(0).forEach(fn => fn());\n delete (this.root as unknown as Record<string, unknown>)[RUNTIME_KEY];\n }\n\n /** The category a facade waits for (Marketing unless the node named another). */\n private get category(): ConsentCategory {\n const declared = this.root.getAttribute(VideoAttribute.Consent);\n return declared === ConsentCategory.Analytics ? ConsentCategory.Analytics : ConsentCategory.Marketing;\n }\n\n private on(el: Element | null, type: string, fn: (e: Event) => void): void {\n if (!el) return;\n el.addEventListener(type, fn);\n this.cleanups.push(() => el.removeEventListener(type, fn));\n }\n\n // ── facade ────────────────────────────────────────────────────────────────────────────────────\n\n private attachFacade(): void {\n const play = this.root.querySelector<HTMLButtonElement>(`button.${VideoClass.Play}`);\n const allow = this.root.querySelector<HTMLButtonElement>(`.${VideoClass.Allow}`);\n const settings = this.root.querySelector<HTMLButtonElement>(`.${VideoClass.Settings}`);\n this.on(play, 'click', () => this.requestPlay());\n this.on(allow, 'click', () => {\n this.consent.grant(this.category);\n this.loadPlayer();\n });\n this.on(settings, 'click', () => { this.consent.openPreferences(); });\n }\n\n /** Play pressed: the player when the category is granted, else the consent prompt. */\n requestPlay(): void {\n if (hasConsent(this.consent.read(), this.category)) {\n this.loadPlayer();\n return;\n }\n const prompt = this.root.querySelector<HTMLElement>(`.${VideoClass.Consent}`);\n if (!prompt) return;\n prompt.hidden = false;\n this.root.setAttribute(VideoAttribute.Asking, '');\n const play = this.root.querySelector<HTMLElement>(`button.${VideoClass.Play}`);\n if (play) play.hidden = true;\n this.root.querySelector<HTMLElement>(`.${VideoClass.Allow}`)?.focus();\n }\n\n /** The player — created only now, after the click and the grant. */\n loadPlayer(): void {\n const ref = videoRefOf(this.root);\n if (!ref || this.root.hasAttribute(VideoAttribute.Playing)) return;\n const frame = this.doc.createElement('iframe');\n frame.className = VideoClass.Frame;\n frame.src = videoEmbedUrl(ref);\n frame.title = this.root.getAttribute(VideoAttribute.Title) || this.words.playUntitled(VIDEO_PROVIDER_LABEL[ref.source]);\n frame.setAttribute('allow', IFRAME_ALLOW);\n frame.setAttribute('allowfullscreen', '');\n frame.setAttribute('referrerpolicy', 'strict-origin-when-cross-origin');\n this.root.replaceChildren(frame);\n this.root.removeAttribute(VideoAttribute.Asking);\n this.root.setAttribute(VideoAttribute.Playing, '');\n frame.focus();\n }\n\n // ── uploaded file ─────────────────────────────────────────────────────────────────────────────\n\n private attachFile(): void {\n const video = this.root.querySelector<HTMLVideoElement>(`video.${VideoClass.Media}`);\n if (!video) return;\n if (this.root.getAttribute(VideoAttribute.Mode) === VideoMode.Background) {\n this.attachBackground(video);\n return;\n }\n const play = this.root.querySelector<HTMLButtonElement>(`button.${VideoClass.Play}`);\n const hidePlay = () => { if (play) play.hidden = true; };\n this.on(play, 'click', () => { hidePlay(); void video.play()?.catch?.(() => undefined); video.focus(); });\n this.on(video, 'play', hidePlay);\n // Autoplay (muted) only while motion is allowed — never under reduced motion.\n if (this.root.hasAttribute(VideoAttribute.Autoplay) && !this.reduced()) {\n video.muted = true;\n void video.play()?.catch?.(() => undefined);\n }\n }\n\n private attachBackground(video: HTMLVideoElement): void {\n const toggle = this.root.querySelector<HTMLButtonElement>(`.${VideoClass.Toggle}`);\n video.muted = true;\n const sync = () => {\n const paused = video.paused;\n if (!toggle) return;\n toggle.setAttribute('aria-pressed', paused ? 'true' : 'false');\n toggle.setAttribute('aria-label', paused ? this.words.playBackground : this.words.pauseBackground);\n const icon = toggle.querySelector('i');\n if (icon) icon.className = paused ? VideoIcon.Play : VideoIcon.Pause;\n };\n this.on(video, 'play', sync);\n this.on(video, 'pause', sync);\n this.on(toggle, 'click', () => {\n if (video.paused) void video.play()?.catch?.(() => undefined);\n else video.pause();\n sync();\n });\n // It moves only when motion is allowed; under reduced motion it rests on its poster, paused.\n if (!this.reduced()) void video.play()?.catch?.(() => sync());\n sync();\n }\n}\n\n/** Run the video at `el` (a `[data-iox-video]` element) once; null when it is not one or already runs. */\nexport function attachVideoAt(el: HTMLElement | null | undefined, options: VideoRuntimeOptions = {}): VideoRuntime | null {\n if (!el?.hasAttribute?.(VideoAttribute.Root)) return null;\n const host = el as unknown as Record<string, unknown>;\n if (host[RUNTIME_KEY]) return null;\n const runtime = new VideoRuntime(el, options);\n host[RUNTIME_KEY] = runtime;\n return runtime;\n}\n\n/** Every video under `container` that is not running yet (the string path's globals and pages). */\nexport function attachVideos(container: ParentNode, options: VideoRuntimeOptions = {}): VideoRuntime[] {\n return Array.from(container.querySelectorAll<HTMLElement>(`[${VideoAttribute.Root}]`))\n .map(el => attachVideoAt(el, options))\n .filter((r): r is VideoRuntime => !!r);\n}\n\n/** The runtime already running at `el`, if any. */\nexport function videoRuntimeOf(el: Element | null | undefined): VideoRuntime | null {\n return ((el as unknown as Record<string, unknown> | null)?.[RUNTIME_KEY] as VideoRuntime | undefined) ?? null;\n}\n","/**\n * @vectoriox/iox-ui/media-core — media decisions shared by the builder, both engine paths and iox-cms (CC3).\n * FRAMEWORK-FREE: `planVideo` is the one place that knows a YouTube / Vimeo address, the player's host and the consent\n * category a facade waits for; the runtime is DOM-only. iox-cms reads `parseVideoUrl` / `videoThumbnailRequest` to\n * fetch and store an embed's poster (the visitor never asks the provider for it).\n * ⚠️ Consumers wire the usual trio — ng-package raw-ts assets, jest moduleNameMapper, tsconfig paths.\n */\nexport * from './frames';\nexport * from './video';\nexport * from './video-runtime';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;AAAA;;;;;;;AAOG;IAES;AAAZ,CAAA,UAAY,QAAQ,EAAA;AAChB,IAAA,QAAA,CAAA,MAAA,CAAA,GAAA,GAAU;AACV,IAAA,QAAA,CAAA,OAAA,CAAA,GAAA,GAAW;AACf,CAAC,EAHW,QAAQ,KAAR,QAAQ,GAAA,EAAA,CAAA,CAAA;IAsBR;AAAZ,CAAA,UAAY,cAAc,EAAA;AACtB,IAAA,cAAA,CAAA,MAAA,CAAA,GAAA,MAAa;AACb,IAAA,cAAA,CAAA,MAAA,CAAA,GAAA,KAAY;AAChB,CAAC,EAHW,cAAc,KAAd,cAAc,GAAA,EAAA,CAAA,CAAA;AAK1B;AACO,MAAM,UAAU,GAAG;AAC1B;MACa,eAAe,GAAG,CAAC,GAAG,IAAI,GAAG;AAC1C;AACO,MAAM,iBAAiB,GAAG;AAEjC,MAAM,SAAS,GAAG,0BAA0B;AAC5C,MAAM,GAAG,GAAG,CAAC;AACb,MAAM,cAAc,GAAwB,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;AAElF,SAAS,OAAO,CAAC,GAAY,EAAA;AACzB,IAAA,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAG,IAAI,EAAE,CAA0B;IACrE,MAAM,KAAK,GAAG,CAAC,CAAU,EAAE,GAAW,KAAkB,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAK,CAAY,GAAG,CAAC,IAAK,CAAY,IAAI,GAAG;AACxH,IAAA,OAAO,KAAK,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;AAClH;AAEA;AACM,SAAU,sBAAsB,CAAC,GAAY,EAAA;AAC/C,IAAA,MAAM,KAAK,IAAI,OAAO,GAAG,KAAK,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,GAAG,CAAkC;AAC/F,IAAA,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;AAAE,QAAA,OAAO,IAAI;IACpD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;AAChC,IAAA,IAAI,CAAC,IAAI,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAAE,QAAA,OAAO,IAAI;IACjI,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;IAClC,OAAO;QACH,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QACpC,GAAG,EAAE,KAAK,CAAC,GAAqB;QAChC,IAAI;AACJ,QAAA,IAAI,KAAK,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;AAC3B,QAAA,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,IAAK,KAAK,CAAC,KAAgB,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC;KACjG;AACL;AAEA,SAAS,SAAS,CAAC,GAAW,EAAA;AAC1B,IAAA,IAAI;AAAE,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;IAAE;AAAE,IAAA,MAAM;AAAE,QAAA,OAAO,IAAI;IAAE;AACzD;AAEA;AACM,SAAU,aAAa,CAAC,KAAa,EAAE,GAAmB,EAAA;AAC5D,IAAA,OAAO,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA,CAAA,EAAI,GAAG,EAAE;AAC3D;AAEA;SACgB,QAAQ,CAAC,QAAuB,EAAE,GAAa,EAAE,KAAa,EAAA;AAC1E,IAAA,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,EAAI,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE;AAC1E;AAEA;AACM,SAAU,gBAAgB,CAAC,QAAuB,EAAA;IACpD,IAAI,CAAC,QAAQ,CAAC,KAAK;AAAE,QAAA,OAAO,EAAE;AAC9B,IAAA,OAAO,CAAA,EAAG,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA,CAAA,EAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAA,GAAA,EAAM,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA,CAAA,EAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,GAAG;AAC/I;AAEA;AACM,SAAU,WAAW,CAAC,QAAuB,EAAE,KAAc,EAAA;AAC/D,IAAA,OAAO,KAAK,IAAI,QAAQ,CAAC,KAAK,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE;AAChI;AAEA;AACM,SAAU,YAAY,CAAC,MAAc,EAAE,KAAa,EAAA;IACtD,IAAI,KAAK,IAAI,CAAC;AAAE,QAAA,OAAO,CAAC;AACxB,IAAA,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,GAAG,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC;AAC/E;AAEA;;;;AAIG;AACG,SAAU,cAAc,CAAC,KAAa,EAAA;IACxC,MAAM,KAAK,GAAa,EAAE;AAC1B,IAAA,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU;AAC9B,IAAA,MAAM,GAAG,GAAG,CAAC,CAAS,KAAU;AAC5B,QAAA,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;AACrC,YAAA,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACX,YAAA,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QACjB;AACJ,IAAA,CAAC;IACD,GAAG,CAAC,CAAC,CAAC;AACN,IAAA,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC;AACd,IAAA,KAAK,IAAI,MAAM,GAAG,EAAE,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,IAAI,CAAC,EAAE;QAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,IAAI,MAAM;YAAE,GAAG,CAAC,CAAC,CAAC;IAClD;AACA,IAAA,OAAO,KAAK;AAChB;AAEA;AACM,SAAU,kBAAkB,CAAC,MAA8B,EAAE,KAAa,EAAA;AAC5E,IAAA,KAAK,IAAI,QAAQ,GAAG,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE;AACzD,QAAA,IAAI,MAAM,CAAC,KAAK,GAAG,QAAQ,CAAC;YAAE,OAAO,KAAK,GAAG,QAAQ;AACrD,QAAA,IAAI,MAAM,CAAC,KAAK,GAAG,QAAQ,CAAC;YAAE,OAAO,KAAK,GAAG,QAAQ;IACzD;IACA,OAAO,CAAC,CAAC;AACb;AAOA;AACsG;AAC/F,MAAM,cAAc,GAAG;AACvB,MAAM,eAAe,GAAG;AAC/B;AACA,MAAM,uBAAuB,GAAG,EAAE;AAClC;AACA,MAAM,gBAAgB,GAAG,GAAG;AAE5B;SACgB,eAAe,CAAC,KAAa,EAAE,MAAc,EAAE,QAAgB,EAAA;AAC3E,IAAA,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AAC7D,IAAA,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,EAAE;AAC7G;AAEA;AACM,SAAU,eAAe,CAAC,OAAe,EAAA;IAC3C,OAAO,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,uBAAuB,CAAC,CAAC,CAAC;AAChG;AAEA;AACM,SAAU,mBAAmB,CAAC,WAAmB,EAAE,KAAa,EAAA;IAClE,IAAI,KAAK,IAAI,WAAW;AAAE,QAAA,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;IACjF,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC,CAAC;AAC1B,IAAA,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,WAAW,GAAG,CAAC,CAAC,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;AACrG;AAEA;AACM,SAAU,eAAe,CAAC,SAAiB,EAAA;AAC7C,IAAA,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;AAChD;AAEA,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;AAE/E;AACM,SAAU,cAAc,CAA6B,KAAuB,EAAA;IAC9E,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACrE;AAEA;AACM,SAAU,YAAY,CAAC,QAAuB,EAAA;AAChD,IAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE;AACrI;IAEY;AAAZ,CAAA,UAAY,WAAW,EAAA;AACnB,IAAA,WAAA,CAAA,QAAA,CAAA,GAAA,mBAA4B;AAChC,CAAC,EAFW,WAAW,KAAX,WAAW,GAAA,EAAA,CAAA,CAAA;AAIvB,MAAM,gBAAgB,GAAG,CAAC;AAC1B,MAAM,WAAW,GAAG,UAAU;AAC9B;AACA,MAAM,gBAAgB,GAAwB,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAgBxE;;;;AAIG;MACU,WAAW,CAAA;AAiBpB,IAAA,WAAA,CAA6B,EAAe,EAAmB,QAAuB,EAAE,UAA8B,EAAE,EAAA;QAA3F,IAAA,CAAA,EAAE,GAAF,EAAE;QAAgC,IAAA,CAAA,QAAQ,GAAR,QAAQ;QAX/D,IAAA,CAAA,QAAQ,GAAgC,IAAI;QAC5C,IAAA,CAAA,MAAM,GAA6B,IAAI;QACvC,IAAA,CAAA,OAAO,GAAoC,IAAI;QAC/C,IAAA,CAAA,MAAM,GAAG,CAAC;QACV,IAAA,CAAA,KAAK,GAAG,CAAC,CAAC;QACV,IAAA,CAAA,UAAU,GAAG,CAAC;QACd,IAAA,CAAA,OAAO,GAAG,CAAC;QACX,IAAA,CAAA,OAAO,GAAG,KAAK;QACf,IAAA,CAAA,SAAS,GAAG,KAAK;AACR,QAAA,IAAA,CAAA,OAAO,GAAG,IAAI,GAAG,EAAoB;QAGlD,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,MAAM;AAClC,QAAA,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;AAC5D,QAAA,IAAI,CAAC,GAAG,GAAG,GAAG;AACd,QAAA,IAAI,CAAC,IAAI,GAAG,IAAI;AAChB,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAC9C,IAAI,CAAC,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC;AACvC,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YAAE;AACrB,QAAA,MAAM,QAAQ,GAAI,IAAI,CAAC,IAAwE,CAAC,oBAAoB;QACpH,IAAI,CAAC,QAAQ,EAAE;YACX,IAAI,CAAC,KAAK,EAAE;YACZ;QACJ;QACA,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,CAAC,OAAO,IAAG;YACnC,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,cAAc,CAAC;gBAAE,IAAI,CAAC,KAAK,EAAE;AACjE,QAAA,CAAC,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC;IAC7C;;AAGA,IAAA,IAAI,CAAC,MAAc,EAAA;AACf,QAAA,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;QACnD,IAAI,CAAC,IAAI,EAAE;IACf;;AAGA,IAAA,IAAI,QAAQ,GAAA;AACR,QAAA,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW;IACpD;IAEA,OAAO,GAAA;AACH,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI;AACrB,QAAA,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE;AAC3B,QAAA,IAAI,CAAC,QAAQ,GAAG,IAAI;AACpB,QAAA,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE;AAC9B,YAAA,KAAK,CAAC,MAAM,GAAG,IAAI;AACnB,YAAA,KAAK,CAAC,OAAO,GAAG,IAAI;AACpB,YAAA,KAAK,CAAC,GAAG,GAAG,EAAE;QAClB;AACA,QAAA,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;AACpB,QAAA,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE;AACrB,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI;AAClB,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI;IACvB;IAEQ,OAAO,GAAA;QACX,MAAM,UAAU,GAAI,IAAI,CAAC,IAAI,CAAC,SAA6E,EAAE,UAAU;AACvH,QAAA,OAAO,CAAC,UAAU,EAAE,QAAQ,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,UAAU,EAAE,aAAa,IAAI,EAAE,CAAC;IAC1F;IAEQ,KAAK,GAAA;QACT,IAAI,IAAI,CAAC,OAAO;YAAE;AAClB,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI;AACnB,QAAA,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE;AAC3B,QAAA,IAAI,CAAC,QAAQ,GAAG,IAAI;QACpB,IAAI,CAAC,IAAI,EAAE;IACf;IAEQ,IAAI,GAAA;QACR,OAAO,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,GAAG,gBAAgB,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;AAC9F,YAAA,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QAC5C;IACJ;AAEQ,IAAA,IAAI,CAAC,KAAa,EAAA;AACtB,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC;AACrD,QAAA,KAAK,CAAC,QAAQ,GAAG,OAAO;QACxB,IAAI,CAAC,OAAO,EAAE;AACd,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;AACvB,QAAA,MAAM,IAAI,GAAG,CAAC,OAAgB,KAAU;AACpC,YAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;YAC1B,IAAI,CAAC,OAAO,EAAE;YACd,IAAI,IAAI,CAAC,SAAS;gBAAE;YACpB,IAAI,OAAO,EAAE;AACT,gBAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK;gBAC1B,IAAI,CAAC,IAAI,EAAE;YACf;YACA,IAAI,CAAC,IAAI,EAAE;AACf,QAAA,CAAC;;AAED,QAAA,KAAK,CAAC,MAAM,GAAG,MAAK;AAChB,YAAA,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,IAAI;AAChC,YAAA,IAAI,OAAO;gBAAE,KAAK,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;;gBAC7D,IAAI,CAAC,IAAI,CAAC;AACnB,QAAA,CAAC;;QAED,KAAK,CAAC,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC;AACjC,QAAA,KAAK,CAAC,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC;IACxD;IAEQ,IAAI,GAAA;AACR,QAAA,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;QAC1D,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK;YAAE;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAE;AACjC,QAAA,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;YAAE;QAC/B,IAAI,CAAC,OAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,MAAO,CAAC,KAAK,EAAE,IAAI,CAAC,MAAO,CAAC,MAAM,CAAC;QACtE,IAAI,CAAC,OAAQ,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,MAAO,CAAC,KAAK,EAAE,IAAI,CAAC,MAAO,CAAC,MAAM,CAAC;AAC7E,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;IACtB;AAEQ,IAAA,YAAY,CAAC,KAAuB,EAAA;QACxC,IAAI,IAAI,CAAC,MAAM;AAAE,YAAA,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO;AACtC,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC;AACzD,QAAA,MAAM,CAAC,SAAS,GAAG,WAAW,CAAC,MAAM;AACrC,QAAA,MAAM,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC;AAC1C,QAAA,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,YAAY,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK;AACpD,QAAA,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,aAAa,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM;QACvD,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;QACtC,IAAI,CAAC,IAAI,CAAC,OAAO;AAAE,YAAA,OAAO,KAAK;AAC/B,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM;AACpB,QAAA,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC;AAC3B,QAAA,OAAO,IAAI;IACf;AACH;;AC9UD;;;;;;;;;;AAUG;AAEI,MAAM,eAAe,GAAG;IAEnB;AAAZ,CAAA,UAAY,WAAW,EAAA;AACnB,IAAA,WAAA,CAAA,MAAA,CAAA,GAAA,MAAa;AACb,IAAA,WAAA,CAAA,SAAA,CAAA,GAAA,SAAmB;AACnB,IAAA,WAAA,CAAA,OAAA,CAAA,GAAA,OAAe;AACnB,CAAC,EAJW,WAAW,KAAX,WAAW,GAAA,EAAA,CAAA,CAAA;IAMX;AAAZ,CAAA,UAAY,SAAS,EAAA;;AAEjB,IAAA,SAAA,CAAA,QAAA,CAAA,GAAA,QAAiB;;AAEjB,IAAA,SAAA,CAAA,YAAA,CAAA,GAAA,YAAyB;AAC7B,CAAC,EALW,SAAS,KAAT,SAAS,GAAA,EAAA,CAAA,CAAA;AAOrB;IACY;AAAZ,CAAA,UAAY,UAAU,EAAA;;AAElB,IAAA,UAAA,CAAA,QAAA,CAAA,GAAA,aAAsB;AACtB,IAAA,UAAA,CAAA,KAAA,CAAA,GAAA,KAAW;AACX,IAAA,UAAA,CAAA,QAAA,CAAA,GAAA,QAAiB;AACjB,IAAA,UAAA,CAAA,MAAA,CAAA,GAAA,MAAa;AACb,IAAA,UAAA,CAAA,UAAA,CAAA,GAAA,UAAqB;AACrB,IAAA,UAAA,CAAA,OAAA,CAAA,GAAA,OAAe;AACf,IAAA,UAAA,CAAA,UAAA,CAAA,GAAA,UAAqB;AACrB,IAAA,UAAA,CAAA,cAAA,CAAA,GAAA,cAA6B;AAC7B,IAAA,UAAA,CAAA,SAAA,CAAA,GAAA,iBAA2B;;AAE3B,IAAA,UAAA,CAAA,QAAA,CAAA,GAAA,QAAiB;AACrB,CAAC,EAbW,UAAU,KAAV,UAAU,GAAA,EAAA,CAAA,CAAA;AAetB;IACY;AAAZ,CAAA,UAAY,SAAS,EAAA;;AAEjB,IAAA,SAAA,CAAA,MAAA,CAAA,GAAA,MAAa;;AAEb,IAAA,SAAA,CAAA,QAAA,CAAA,GAAA,QAAiB;;AAEjB,IAAA,SAAA,CAAA,OAAA,CAAA,GAAA,OAAe;;AAEf,IAAA,SAAA,CAAA,QAAA,CAAA,GAAA,QAAiB;AACrB,CAAC,EATW,SAAS,KAAT,SAAS,GAAA,EAAA,CAAA,CAAA;AAkBd,MAAM,oBAAoB,GAAiD;AAC9E,IAAA,CAAC,WAAW,CAAC,OAAO,GAAG,SAAS;AAChC,IAAA,CAAC,WAAW,CAAC,KAAK,GAAG,OAAO;;AAGhC;AACO,MAAM,sBAAsB,GAAiD;AAChF,IAAA,CAAC,WAAW,CAAC,OAAO,GAAG,QAAQ;AAC/B,IAAA,CAAC,WAAW,CAAC,KAAK,GAAG,OAAO;;AAGhC;MACa,mBAAmB,GAA0B,CAAC,kCAAkC,EAAE,0BAA0B;AAEzH,MAAM,UAAU,GAAG,qBAAqB;AACxC,MAAM,QAAQ,GAAG,YAAY;AAC7B,MAAM,UAAU,GAAG,mBAAmB;AACtC,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,aAAa,EAAE,iBAAiB,EAAE,eAAe,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,0BAA0B,CAAC,CAAC;AAC3J,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;AACjE,MAAM,qBAAqB,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC;AAC9D,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,eAAe,EAAE,kBAAkB,CAAC,CAAC;AAE/E,SAAS,KAAK,CAAC,GAAW,EAAA;AACtB,IAAA,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE;AACvB,IAAA,IAAI,CAAC,IAAI;AAAE,QAAA,OAAO,IAAI;AACtB,IAAA,IAAI;QACA,OAAO,IAAI,GAAG,CAAC,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,WAAW,IAAI,CAAA,CAAE,CAAC;IACpF;AAAE,IAAA,MAAM;AACJ,QAAA,OAAO,IAAI;IACf;AACJ;AAEA,SAAS,YAAY,CAAC,GAAQ,EAAA;IAC1B,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE;AACvC,IAAA,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;IACxD,IAAI,EAAE,GAAkB,IAAI;AAC5B,IAAA,IAAI,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC;AAAE,QAAA,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI;AACtD,SAAA,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;AAC9B,QAAA,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,OAAO;YAAE,EAAE,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC;aACtD,IAAI,qBAAqB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AAAE,YAAA,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI;IACxF;;AAAO,QAAA,OAAO,IAAI;IAClB,OAAO,EAAE,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI;AACjF;AAEA,SAAS,UAAU,CAAC,GAAQ,EAAA;IACxB,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;AAAE,QAAA,OAAO,IAAI;AAC7D,IAAA,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;;AAExD,IAAA,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvD,IAAI,KAAK,GAAG,CAAC;AAAE,QAAA,OAAO,IAAI;AAC1B,IAAA,MAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC;AAC1B,IAAA,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,KAAK,GAAG,CAAC,CAAC;AAC7D,IAAA,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,IAAI,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE;AAChG;AAEA;AACM,SAAU,aAAa,CAAC,GAA8B,EAAA;AACxD,IAAA,MAAM,GAAG,GAAG,OAAO,GAAG,KAAK,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI;IACvD,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;AAAE,QAAA,OAAO,IAAI;IACxD,OAAO,YAAY,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC;AAC/C;AAEA;AACM,SAAU,aAAa,CAAC,GAAY,EAAE,QAAkB,EAAA;AAC1D,IAAA,IAAI,QAAQ,KAAK,WAAW,CAAC,OAAO,IAAI,QAAQ,KAAK,WAAW,CAAC,KAAK,IAAI,QAAQ,KAAK,WAAW,CAAC,IAAI;AAAE,QAAA,OAAO,QAAQ;IACxH,OAAO,aAAa,CAAC,OAAO,GAAG,KAAK,QAAQ,GAAG,GAAG,GAAG,EAAE,CAAC,EAAE,MAAM,IAAI,WAAW,CAAC,IAAI;AACxF;AAEA;AACM,SAAU,aAAa,CAAC,GAAa,EAAA;IACvC,IAAI,GAAG,CAAC,MAAM,KAAK,WAAW,CAAC,OAAO,EAAE;QACpC,OAAO,CAAA,uCAAA,EAA0C,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC,iCAAiC;IAChH;IACA,OAAO,CAAA,+BAAA,EAAkC,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA,iBAAA,EAAoB,GAAG,CAAC,IAAI,GAAG,CAAA,GAAA,EAAM,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA,CAAE,GAAG,EAAE,CAAA,CAAE;AACjJ;AAWM,SAAU,qBAAqB,CAAC,GAAa,EAAA;IAC/C,IAAI,GAAG,CAAC,MAAM,KAAK,WAAW,CAAC,OAAO,EAAE;QACpC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAA,uBAAA,EAA0B,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC,gBAAgB,EAAE,UAAU,EAAE,CAAC,aAAa,CAAC,EAAE;IACpI;IACA,MAAM,IAAI,GAAG,CAAA,kBAAA,EAAqB,GAAG,CAAC,EAAE,CAAA,EAAG,GAAG,CAAC,IAAI,GAAG,CAAA,CAAA,EAAI,GAAG,CAAC,IAAI,CAAA,CAAE,GAAG,EAAE,CAAA,CAAE;IAC3E,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,yCAAyC,kBAAkB,CAAC,IAAI,CAAC,CAAA,WAAA,CAAa,EAAE,UAAU,EAAE,CAAC,gBAAgB,CAAC,EAAE;AAClJ;AAEA;AACM,SAAU,mBAAmB,CAAC,GAAa,EAAA;IAC7C,OAAO,CAAA,aAAA,EAAgB,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,EAAE,CAAA,IAAA,CAAM;AACrD;AAUA;AACM,SAAU,SAAS,CAAC,IAAsC,EAAE,IAAyB,EAAA;AACvF,IAAA,IAAI,CAAC,IAAI;AAAE,QAAA,OAAO,SAAS;AAC3B,IAAA,IAAI,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC;AAAE,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;AACjG,IAAA,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,KAAK,IAAI,CAAC,EAAE,OAAO;AAC5D;AAEA,MAAM,GAAG,GAAG,CAAC,CAAU,MAAc,OAAO,CAAC,KAAK,QAAQ,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC;AAC3E,MAAM,MAAM,GAAG,CAAC,CAAU,KAAc,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,MAAM;AAElE;AACM,SAAU,oBAAoB,CAAC,IAAsC,EAAE,SAAsB,aAAa,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,EAAA;AACjL,IAAA,IAAI,MAAM,KAAK,WAAW,CAAC,IAAI;AAAE,QAAA,OAAO,IAAI;IAC5C,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC;AACpD,IAAA,OAAO,QAAQ,KAAK,eAAe,CAAC,SAAS,GAAG,eAAe,CAAC,SAAS,GAAG,eAAe,CAAC,SAAS;AACzG;AAmCA;;;;AAIG;AACG,SAAU,SAAS,CAAC,IAAsC,EAAE,OAA+B,EAAA;AAC7F,IAAA,MAAM,MAAM,GAAG,sBAAsB,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;AACzE,IAAA,IAAI,MAAM;AAAE,QAAA,OAAO,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC;AAC3C,IAAA,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC;AACnD,IAAA,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;AACxE,IAAA,MAAM,GAAG,GAAG,MAAM,KAAK,WAAW,CAAC,IAAI,GAAG,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC;IACtE,MAAM,UAAU,GAAG,MAAM,KAAK,WAAW,CAAC,IAAI,IAAI,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC,UAAU;IAC3G,MAAM,eAAe,GAAG,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC;AAC1D,IAAA,MAAM,OAAO,GAAG,eAAe,GAAG,UAAU,CAAC,OAAO,EAAE,eAAe,CAAC,GAAG,IAAI;AAC7E,IAAA,MAAM,IAAI,GAAG,MAAM,KAAK,WAAW,CAAC,IAAI,IAAI,MAAM,GAAG,SAAS,CAAC,IAAI,GAAG,SAAS,CAAC,KAAK,KAAK,GAAG,GAAG,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC;AACnI,IAAA,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IACtD,OAAO;QACH,IAAI;QACJ,MAAM;QACN,GAAG;AACH,QAAA,GAAG,EAAE,MAAM,KAAK,WAAW,CAAC,IAAI,GAAG,MAAM,GAAG,EAAE;AAC9C,QAAA,MAAM,EAAE,kBAAkB,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,MAAM;QAChD,KAAK,EAAE,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;AAC7C,QAAA,IAAI,EAAE,UAAU,GAAG,SAAS,CAAC,UAAU,GAAG,SAAS,CAAC,MAAM;QAC1D,UAAU;QACV,QAAQ,EAAE,UAAU,KAAK,MAAM,KAAK,WAAW,CAAC,IAAI,IAAI,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;AACrG,QAAA,KAAK,EAAE,UAAU,IAAI,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;AACjE,QAAA,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,CAAC,UAAU;AACrB,QAAA,QAAQ,EAAE,UAAU,GAAG,EAAE,GAAG,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;AACrE,QAAA,YAAY,EAAE,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC,IAAI,IAAI;QACnE,eAAe;QACf,OAAO;QACP,QAAQ,EAAE,IAAI,KAAK,SAAS,CAAC,MAAM,IAAI,OAAO,IAAI,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,IAAI;AACjF,QAAA,aAAa,EAAE,GAAG,GAAG,oBAAoB,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE;AAC1D,QAAA,MAAM,EAAE,IAAI;KACf;AACL;AAEA;AACA,SAAS,UAAU,CAAC,IAAsC,EAAE,MAAqB,EAAA;AAC7E,IAAA,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IACtD,OAAO;QACH,IAAI,EAAE,SAAS,CAAC,MAAM;QACtB,MAAM,EAAE,WAAW,CAAC,IAAI;AACxB,QAAA,GAAG,EAAE,IAAI;AACT,QAAA,GAAG,EAAE,EAAE;QACP,MAAM,EAAE,MAAM,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3F,KAAK,EAAE,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,EAAE,SAAS,CAAC,MAAM;AACtB,QAAA,UAAU,EAAE,KAAK;AACjB,QAAA,QAAQ,EAAE,KAAK;AACf,QAAA,KAAK,EAAE,KAAK;AACZ,QAAA,IAAI,EAAE,KAAK;AACX,QAAA,QAAQ,EAAE,KAAK;AACf,QAAA,QAAQ,EAAE,EAAE;AACZ,QAAA,YAAY,EAAE,IAAI;AAClB,QAAA,eAAe,EAAE,IAAI;AACrB,QAAA,OAAO,EAAE,IAAI;AACb,QAAA,QAAQ,EAAE,IAAI;AACd,QAAA,aAAa,EAAE,EAAE;QACjB,MAAM;KACT;AACL;AAEA,MAAM,wBAAwB,GAAG,CAAC,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,uBAAuB,CAAC;AAEnH;AACM,SAAU,kBAAkB,CAAC,GAAW,EAAA;AAC1C,IAAA,MAAM,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI;IACtC,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;AAAE,QAAA,OAAO,KAAK;IAC/D,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE;IAC1C,OAAO,wBAAwB,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA,CAAE,CAAC,CAAC;AACnF;AA0BO,MAAM,WAAW,GAA8C;AAClE,IAAA,EAAE,EAAE;QACA,IAAI,EAAE,CAAC,KAAK,EAAE,QAAQ,MAAM,QAAQ,GAAG,CAAA,MAAA,EAAS,KAAK,CAAA,EAAA,EAAK,QAAQ,CAAA,CAAA,CAAG,GAAG,CAAA,MAAA,EAAS,KAAK,CAAA,CAAE,CAAC;AACzF,QAAA,YAAY,EAAE,QAAQ,KAAK,QAAQ,GAAG,eAAe,QAAQ,CAAA,CAAA,CAAG,GAAG,YAAY,CAAC;AAChF,QAAA,eAAe,EAAE,wBAAwB;AACzC,QAAA,cAAc,EAAE,uBAAuB;AACvC,QAAA,WAAW,EAAE,kCAAkC;AAC/C,QAAA,UAAU,EAAE,QAAQ,IAAI,CAAA,wBAAA,EAA2B,QAAQ,CAAA,CAAA,CAAG;AAC9D,QAAA,UAAU,EAAE,OAAO,IAAI,CAAA,gBAAA,EAAmB,OAAO,CAAA,6DAAA,CAA+D;AAChH,QAAA,iBAAiB,EAAE,QAAQ,IAAI,CAAA,WAAA,EAAc,QAAQ,CAAA,CAAA,CAAG;AACxD,QAAA,iBAAiB,EAAE,sEAAsE;AACzF,QAAA,KAAK,EAAE,gBAAgB;AACvB,QAAA,QAAQ,EAAE,kBAAkB;AAC/B,KAAA;AACD,IAAA,EAAE,EAAE;QACA,IAAI,EAAE,CAAC,KAAK,EAAE,QAAQ,MAAM,QAAQ,GAAG,CAAA,OAAA,EAAU,KAAK,CAAA,EAAA,EAAK,QAAQ,CAAA,CAAA,CAAG,GAAG,CAAA,OAAA,EAAU,KAAK,CAAA,CAAE,CAAC;AAC3F,QAAA,YAAY,EAAE,QAAQ,KAAK,QAAQ,GAAG,iBAAiB,QAAQ,CAAA,CAAA,CAAG,GAAG,cAAc,CAAC;AACpF,QAAA,eAAe,EAAE,mBAAmB;AACpC,QAAA,cAAc,EAAE,kBAAkB;AAClC,QAAA,WAAW,EAAE,0BAA0B;AACvC,QAAA,UAAU,EAAE,QAAQ,IAAI,CAAA,eAAA,EAAkB,QAAQ,CAAA,CAAA,CAAG;AACrD,QAAA,UAAU,EAAE,OAAO,IAAI,CAAA,gBAAA,EAAmB,OAAO,CAAA,iEAAA,CAAmE;AACpH,QAAA,iBAAiB,EAAE,QAAQ,IAAI,CAAA,QAAA,EAAW,QAAQ,CAAA,CAAA,CAAG;AACrD,QAAA,iBAAiB,EAAE,iEAAiE;AACpF,QAAA,KAAK,EAAE,cAAc;AACrB,QAAA,QAAQ,EAAE,eAAe;AAC5B,KAAA;;AAGL;AACM,SAAU,UAAU,CAAC,IAAoB,EAAA;IAC3C,OAAO,CAAC,IAAI,IAAI,EAAE,EAAE,WAAW,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,EAAE,GAAG,WAAW,CAAC,EAAE;AACxF;AAEA;AACM,SAAU,cAAc,CAAC,IAAe,EAAE,KAAA,GAAoB,WAAW,CAAC,EAAE,EAAA;AAC9E,IAAA,OAAO,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC;AAC3G;AAEA;IAEY;AAAZ,CAAA,UAAY,UAAU,EAAA;AAClB,IAAA,UAAA,CAAA,MAAA,CAAA,GAAA,WAAkB;AAClB,IAAA,UAAA,CAAA,QAAA,CAAA,GAAA,mBAA4B;AAC5B,IAAA,UAAA,CAAA,MAAA,CAAA,GAAA,iBAAwB;AACxB,IAAA,UAAA,CAAA,OAAA,CAAA,GAAA,kBAA0B;AAC1B,IAAA,UAAA,CAAA,OAAA,CAAA,GAAA,kBAA0B;AAC1B,IAAA,UAAA,CAAA,OAAA,CAAA,GAAA,kBAA0B;AAC1B,IAAA,UAAA,CAAA,QAAA,CAAA,GAAA,mBAA4B;AAC5B,IAAA,UAAA,CAAA,SAAA,CAAA,GAAA,oBAA8B;AAC9B,IAAA,UAAA,CAAA,aAAA,CAAA,GAAA,yBAAuC;;AAEvC,IAAA,UAAA,CAAA,aAAA,CAAA,GAAA,yBAAuC;AACvC,IAAA,UAAA,CAAA,gBAAA,CAAA,GAAA,4BAA6C;AAC7C,IAAA,UAAA,CAAA,YAAA,CAAA,GAAA,wBAAqC;AACrC,IAAA,UAAA,CAAA,OAAA,CAAA,GAAA,kBAA0B;AAC1B,IAAA,UAAA,CAAA,UAAA,CAAA,GAAA,qBAAgC;AACpC,CAAC,EAhBW,UAAU,KAAV,UAAU,GAAA,EAAA,CAAA,CAAA;IAkBV;AAAZ,CAAA,UAAY,cAAc,EAAA;;AAEtB,IAAA,cAAA,CAAA,MAAA,CAAA,GAAA,gBAAuB;AACvB,IAAA,cAAA,CAAA,QAAA,CAAA,GAAA,uBAAgC;AAChC,IAAA,cAAA,CAAA,IAAA,CAAA,GAAA,mBAAwB;AACxB,IAAA,cAAA,CAAA,MAAA,CAAA,GAAA,qBAA4B;AAC5B,IAAA,cAAA,CAAA,MAAA,CAAA,GAAA,qBAA4B;AAC5B,IAAA,cAAA,CAAA,UAAA,CAAA,GAAA,yBAAoC;AACpC,IAAA,cAAA,CAAA,SAAA,CAAA,GAAA,wBAAkC;AAClC,IAAA,cAAA,CAAA,OAAA,CAAA,GAAA,sBAA8B;;AAE9B,IAAA,cAAA,CAAA,aAAA,CAAA,GAAA,6BAA2C;;AAE3C,IAAA,cAAA,CAAA,SAAA,CAAA,GAAA,wBAAkC;;AAElC,IAAA,cAAA,CAAA,QAAA,CAAA,GAAA,uBAAgC;;AAEhC,IAAA,cAAA,CAAA,QAAA,CAAA,GAAA,uBAAgC;AACpC,CAAC,EAlBW,cAAc,KAAd,cAAc,GAAA,EAAA,CAAA,CAAA;IAoBd;AAAZ,CAAA,UAAY,SAAS,EAAA;AACjB,IAAA,SAAA,CAAA,MAAA,CAAA,GAAA,iBAAwB;AACxB,IAAA,SAAA,CAAA,OAAA,CAAA,GAAA,kBAA0B;AAC9B,CAAC,EAHW,SAAS,KAAT,SAAS,GAAA,EAAA,CAAA,CAAA;AAKrB;AACM,SAAU,mBAAmB,CAAC,IAAe,EAAA;IAC/C,MAAM,KAAK,GAA2B,EAAE,CAAC,cAAc,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,cAAc,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE;AAChH,IAAA,IAAI,IAAI,CAAC,GAAG,EAAE;QACV,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE;AACtC,QAAA,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI;YAAE,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI;IACjE;IACA,IAAI,IAAI,CAAC,UAAU;QAAE,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,UAAU;IACtE,IAAI,IAAI,CAAC,QAAQ;AAAE,QAAA,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,GAAG,EAAE;IACtD,IAAI,IAAI,CAAC,eAAe;QAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,eAAe;IAC9E,IAAI,IAAI,CAAC,KAAK;QAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK;IACxD,IAAI,CAAC,IAAI,CAAC,MAAM;AAAE,QAAA,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,GAAG,EAAE;IACxD,IAAI,IAAI,CAAC,MAAM;AAAE,QAAA,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;AAC3E,IAAA,OAAO,KAAK;AAChB;AAUA,MAAM,QAAQ,GAAG,CAAC,GAAW,KAAK,CAAA,UAAA,EAAa,GAAG,CAAA,yBAAA,CAA2B;AAE7E;AAC+F;AACzF,SAAU,cAAc,CAAC,IAAe,EAAE,OAA2B,EAAA;AACvE,IAAA,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO;IACvB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,WAAW,CAAC,EAAE;;;IAG7C,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,MAAM,EAAE;AAChC,QAAA,MAAM,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;AACpD,QAAA,MAAM,MAAM,GAAG,GAAG,GAAG,gBAAgB,CAAC,IAAI,CAAC,MAAO,CAAC,GAAG,EAAE;;QAExD,MAAM,IAAI,GAAG,GAAG,GAAG,CAAA,QAAA,EAAW,IAAI,CAAC,MAAO,CAAC,IAAI,CAAC,KAAK,CAAA,UAAA,EAAa,IAAI,CAAC,MAAO,CAAC,IAAI,CAAC,MAAM,CAAA,CAAA,CAAG,GAAG,EAAE;AAClG,QAAA,OAAO,eAAe,UAAU,CAAC,MAAM,CAAA,OAAA,EAAU,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA,CAAA,EAAI,MAAM,GAAG,CAAA,SAAA,EAAY,GAAG,CAAC,MAAM,CAAC,CAAA,eAAA,CAAiB,GAAG,EAAE,CAAA,EAAG,IAAI,CAAA,MAAA,EAAS,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,qBAAqB;IACnL;IACA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,CAAA,YAAA,EAAe,UAAU,CAAC,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,2CAA2C,GAAG,EAAE;IACvI,MAAM,KAAK,GAAG,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC9C,IAAA,MAAM,QAAQ,GAAG,CAAA,aAAA,EAAgB,UAAU,CAAC,IAAI,CAAA,qBAAA,EAAwB,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS;AACzG,IAAA,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,GAAG,CAAA,aAAA,EAAgB,UAAU,CAAC,KAAK,KAAK,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA,EAAG,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA,OAAA,CAAS,GAAG,EAAE;AAExI,IAAA,IAAI,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,KAAK,EAAE;QACjD,OAAO,CAAA,EAAG,MAAM,CAAA,EAAG,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,EAAE,GAAG,QAAQ,CAAA,EAAG,KAAK,CAAA,CAAE;IACjG;IAEA,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,EAAE;AAC9B,QAAA,MAAM,KAAK,GAAG;YACV,CAAA,cAAA,EAAiB,UAAU,CAAC,KAAK,CAAA,OAAA,EAAU,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA,gCAAA,CAAkC;AAC1F,YAAA,IAAI,CAAC,MAAM,GAAG,YAAY,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA,CAAA,CAAG,GAAG,EAAE;;;YAGlD,IAAI,CAAC,QAAQ,GAAG,0BAA0B,GAAG,EAAE;YAC/C,IAAI,CAAC,QAAQ,GAAG,WAAW,GAAG,EAAE;YAChC,IAAI,CAAC,KAAK,GAAG,QAAQ,GAAG,EAAE;YAC1B,IAAI,CAAC,IAAI,GAAG,OAAO,GAAG,EAAE;AACxB,YAAA,IAAI,CAAC,UAAU,GAAG,mCAAmC,IAAI,IAAI,CAAC,KAAK,GAAG,CAAA,aAAA,EAAgB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA,CAAA,CAAG,GAAG,EAAE,CAAC;YAC9G,GAAG;AACH,YAAA,IAAI,CAAC,QAAQ,GAAG,CAAA,4BAAA,EAA+B,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA,SAAA,EAAY,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA,UAAA,CAAY,GAAG,EAAE;YACxJ,UAAU;AACb,SAAA,CAAC,IAAI,CAAC,EAAE,CAAC;AACV,QAAA,IAAI,IAAI,CAAC,UAAU,EAAE;;;YAGjB,OAAO,CAAA,EAAG,KAAK,CAAA,6BAAA,EAAgC,UAAU,CAAC,MAAM,CAAA,cAAA,EAAiB,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,yBAAyB,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA,SAAA,CAAW;QAC1K;AACA,QAAA,OAAO,GAAG,KAAK,CAAA,6BAAA,EAAgC,UAAU,CAAC,IAAI,CAAA,cAAA,EAAiB,KAAK,CAAA,EAAA,EAAK,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW;IAChI;IAEA,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,GAAG,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE;AACvE,IAAA,MAAM,MAAM,GAAG,CAAA,YAAA,EAAe,UAAU,CAAC,OAAO,CAAA,2BAAA,EAA8B,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA,SAAA,CAAW;AAC3G,QAAA,CAAA,UAAA,EAAa,UAAU,CAAC,WAAW,CAAA,CAAA,EAAI,UAAU,CAAC,WAAW,CAAA,KAAA,EAAQ,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAA,KAAA,EAAQ,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAA,IAAA,CAAM;QAC1J,CAAA,UAAA,EAAa,UAAU,CAAC,WAAW,CAAA,CAAA,EAAI,UAAU,CAAC,cAAc,CAAA,KAAA,EAAQ,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAA,KAAA,EAAQ,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAA,IAAA,CAAM;QAClK,CAAA,YAAA,EAAe,UAAU,CAAC,UAAU,CAAA,EAAA,CAAI;QACxC,CAAA,6BAAA,EAAgC,UAAU,CAAC,KAAK,CAAA,EAAA,EAAK,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA,SAAA,CAAW;QAChF,CAAA,6BAAA,EAAgC,UAAU,CAAC,QAAQ,CAAA,EAAA,EAAK,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA,SAAA,CAAW;AACtF,QAAA,CAAA,YAAA,CAAc;IAClB,OAAO,CAAA,EAAG,MAAM,CAAA,6BAAA,EAAgC,UAAU,CAAC,IAAI,CAAA,cAAA,EAAiB,KAAK,CAAA,EAAA,EAAK,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA,SAAA,EAAY,KAAK,CAAA,EAAG,MAAM,EAAE;AAClJ;AAEA,MAAM,gBAAgB,GAAG,CAAC,IAAe,KAAc,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;AAE/H;AACM,SAAU,wBAAwB,CAAC,KAAuC,EAAE,GAA8B,EAAA;IAC5G,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,KAAK,KAAK,EAAE,GAAG,CAAA,CAAA,EAAI,IAAI,CAAA,CAAE,GAAG,CAAA,CAAA,EAAI,IAAI,CAAA,EAAA,EAAK,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;AAC1H;;ACveA;;;;;;;;;;;;AAYG;AAEH;AACO,MAAM,mBAAmB,GAAG;AACnC;AACO,MAAM,yBAAyB,GAAG;AAazC,MAAM,cAAc,GAAG,kCAAkC;AACzD,MAAM,WAAW,GAAG,YAAY;AAChC,MAAM,YAAY,GAAG,2DAA2D;AAEhF;AACM,SAAU,iBAAiB,CAAC,GAAa,EAAA;AAC3C,IAAA,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,CAAA,EAAG,mBAAmB,CAAA,CAAA,CAAG,CAAC,CAAC;IAC7F,OAAO,MAAM,CAAC,GAAG,GAAG,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;AAC7F;AAEA;;;;AAIG;AACG,SAAU,wBAAwB,CAAC,GAAa,EAAA;IAClD,OAAO;AACH,QAAA,IAAI,EAAE,MAAM,iBAAiB,CAAC,GAAG,CAAC;QAClC,KAAK,EAAE,QAAQ,IAAG;AACd,YAAA,MAAM,KAAK,GAAG,IAAI,WAAW,CAAqB,mBAAmB,EAAE,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;AAClH,YAAA,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC;YACxB,IAAI,KAAK,CAAC,gBAAgB;gBAAE;AAC5B,YAAA,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC;YACvC,MAAM,WAAW,GAAG,QAAQ,EAAE,WAAW,IAAI,QAAQ,EAAE;AACvD,YAAA,MAAM,QAAQ,GAAG,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,aAAa,IAAI,GAAG,CAAC;YAC3G,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,EAAE,QAAQ,KAAK,QAAQ;YAClD,GAAG,CAAC,MAAM,GAAG,CAAA,EAAG,mBAAmB,CAAA,CAAA,EAAI,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,gBAAgB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA,CAAE;QAClH,CAAC;QACD,eAAe,EAAE,MAAK;AAClB,YAAA,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,yBAAyB,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;AAC9E,YAAA,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC;YACxB,OAAO,KAAK,CAAC,gBAAgB;QACjC,CAAC;KACJ;AACL;AAEA,SAAS,QAAQ,GAAA;AACb,IAAA,MAAM,CAAC,GAAI,UAAyD,CAAC,MAAM;IAC3E,OAAO,CAAC,EAAE,UAAU,GAAG,CAAC,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AAC/E;AASA;AACM,SAAU,UAAU,CAAC,IAAa,EAAA;IACpC,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,MAAM,CAAC;IACvD,MAAM,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;AAC/C,IAAA,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,OAAO,IAAI,MAAM,KAAK,WAAW,CAAC,KAAK,KAAK,CAAC,EAAE;AAAE,QAAA,OAAO,IAAI;IACxF,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,IAAI,CAAC;IACnD,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,IAAI,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE;AACpD;MAEa,YAAY,CAAA;IAOrB,WAAA,CAAqB,IAAiB,EAAE,OAAA,GAA+B,EAAE,EAAA;QAApD,IAAA,CAAA,IAAI,GAAJ,IAAI;QANR,IAAA,CAAA,QAAQ,GAAsB,EAAE;AAO7C,QAAA,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,aAAa;AAC7B,QAAA,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,wBAAwB,CAAC,IAAI,CAAC,GAAG,CAAC;AACpE,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW;QACjC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,aAAa,KAAK,MAAM,CAAC,CAAC,IAAI,EAAE,UAAU,GAAG,cAAc,CAAC,EAAE,OAAO,CAAC;QAC7F,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;QACxF,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,IAAI,CAAC;AACnD,QAAA,IAAI,IAAI,KAAK,SAAS,CAAC,MAAM;YAAE,IAAI,CAAC,YAAY,EAAE;AAC7C,aAAA,IAAI,IAAI,KAAK,SAAS,CAAC,IAAI;YAAE,IAAI,CAAC,UAAU,EAAE;IACvD;IAEA,OAAO,GAAA;AACH,QAAA,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC;AAC3C,QAAA,OAAQ,IAAI,CAAC,IAA2C,CAAC,WAAW,CAAC;IACzE;;AAGA,IAAA,IAAY,QAAQ,GAAA;AAChB,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,OAAO,CAAC;AAC/D,QAAA,OAAO,QAAQ,KAAK,eAAe,CAAC,SAAS,GAAG,eAAe,CAAC,SAAS,GAAG,eAAe,CAAC,SAAS;IACzG;AAEQ,IAAA,EAAE,CAAC,EAAkB,EAAE,IAAY,EAAE,EAAsB,EAAA;AAC/D,QAAA,IAAI,CAAC,EAAE;YAAE;AACT,QAAA,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC;AAC7B,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,mBAAmB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC9D;;IAIQ,YAAY,GAAA;AAChB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAoB,CAAA,OAAA,EAAU,UAAU,CAAC,IAAI,CAAA,CAAE,CAAC;AACpF,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAoB,CAAA,CAAA,EAAI,UAAU,CAAC,KAAK,CAAA,CAAE,CAAC;AAChF,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAoB,CAAA,CAAA,EAAI,UAAU,CAAC,QAAQ,CAAA,CAAE,CAAC;AACtF,QAAA,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QAChD,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAK;YACzB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;YACjC,IAAI,CAAC,UAAU,EAAE;AACrB,QAAA,CAAC,CAAC;QACF,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAK,EAAG,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC;IACzE;;IAGA,WAAW,GAAA;AACP,QAAA,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE;YAChD,IAAI,CAAC,UAAU,EAAE;YACjB;QACJ;AACA,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAc,CAAA,CAAA,EAAI,UAAU,CAAC,OAAO,CAAA,CAAE,CAAC;AAC7E,QAAA,IAAI,CAAC,MAAM;YAAE;AACb,QAAA,MAAM,CAAC,MAAM,GAAG,KAAK;QACrB,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE,CAAC;AACjD,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAc,CAAA,OAAA,EAAU,UAAU,CAAC,IAAI,CAAA,CAAE,CAAC;AAC9E,QAAA,IAAI,IAAI;AAAE,YAAA,IAAI,CAAC,MAAM,GAAG,IAAI;AAC5B,QAAA,IAAI,CAAC,IAAI,CAAC,aAAa,CAAc,CAAA,CAAA,EAAI,UAAU,CAAC,KAAK,CAAA,CAAE,CAAC,EAAE,KAAK,EAAE;IACzE;;IAGA,UAAU,GAAA;QACN,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;AACjC,QAAA,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,OAAO,CAAC;YAAE;QAC5D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,QAAQ,CAAC;AAC9C,QAAA,KAAK,CAAC,SAAS,GAAG,UAAU,CAAC,KAAK;AAClC,QAAA,KAAK,CAAC,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC;QAC9B,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,oBAAoB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACvH,QAAA,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,YAAY,CAAC;AACzC,QAAA,KAAK,CAAC,YAAY,CAAC,iBAAiB,EAAE,EAAE,CAAC;AACzC,QAAA,KAAK,CAAC,YAAY,CAAC,gBAAgB,EAAE,iCAAiC,CAAC;AACvE,QAAA,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,MAAM,CAAC;QAChD,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,CAAC;QAClD,KAAK,CAAC,KAAK,EAAE;IACjB;;IAIQ,UAAU,GAAA;AACd,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAmB,CAAA,MAAA,EAAS,UAAU,CAAC,KAAK,CAAA,CAAE,CAAC;AACpF,QAAA,IAAI,CAAC,KAAK;YAAE;AACZ,QAAA,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC,UAAU,EAAE;AACtE,YAAA,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC;YAC5B;QACJ;AACA,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAoB,CAAA,OAAA,EAAU,UAAU,CAAC,IAAI,CAAA,CAAE,CAAC;AACpF,QAAA,MAAM,QAAQ,GAAG,MAAK,EAAG,IAAI,IAAI;AAAE,YAAA,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;AACxD,QAAA,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,MAAK,EAAG,QAAQ,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,EAAE,EAAE,KAAK,GAAG,MAAM,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;QACzG,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC;;AAEhC,QAAA,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE;AACpE,YAAA,KAAK,CAAC,KAAK,GAAG,IAAI;AAClB,YAAA,KAAK,KAAK,CAAC,IAAI,EAAE,EAAE,KAAK,GAAG,MAAM,SAAS,CAAC;QAC/C;IACJ;AAEQ,IAAA,gBAAgB,CAAC,KAAuB,EAAA;AAC5C,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAoB,CAAA,CAAA,EAAI,UAAU,CAAC,MAAM,CAAA,CAAE,CAAC;AAClF,QAAA,KAAK,CAAC,KAAK,GAAG,IAAI;QAClB,MAAM,IAAI,GAAG,MAAK;AACd,YAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM;AAC3B,YAAA,IAAI,CAAC,MAAM;gBAAE;AACb,YAAA,MAAM,CAAC,YAAY,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;YAC9D,MAAM,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC;YAClG,MAAM,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC;AACtC,YAAA,IAAI,IAAI;AAAE,gBAAA,IAAI,CAAC,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC,IAAI,GAAG,SAAS,CAAC,KAAK;AACxE,QAAA,CAAC;QACD,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC;QAC5B,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC;QAC7B,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,MAAK;YAC1B,IAAI,KAAK,CAAC,MAAM;AAAE,gBAAA,KAAK,KAAK,CAAC,IAAI,EAAE,EAAE,KAAK,GAAG,MAAM,SAAS,CAAC;;gBACxD,KAAK,CAAC,KAAK,EAAE;AAClB,YAAA,IAAI,EAAE;AACV,QAAA,CAAC,CAAC;;AAEF,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;AAAE,YAAA,KAAK,KAAK,CAAC,IAAI,EAAE,EAAE,KAAK,GAAG,MAAM,IAAI,EAAE,CAAC;AAC7D,QAAA,IAAI,EAAE;IACV;AACH;AAED;SACgB,aAAa,CAAC,EAAkC,EAAE,UAA+B,EAAE,EAAA;IAC/F,IAAI,CAAC,EAAE,EAAE,YAAY,GAAG,cAAc,CAAC,IAAI,CAAC;AAAE,QAAA,OAAO,IAAI;IACzD,MAAM,IAAI,GAAG,EAAwC;IACrD,IAAI,IAAI,CAAC,WAAW,CAAC;AAAE,QAAA,OAAO,IAAI;IAClC,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC;AAC7C,IAAA,IAAI,CAAC,WAAW,CAAC,GAAG,OAAO;AAC3B,IAAA,OAAO,OAAO;AAClB;AAEA;SACgB,YAAY,CAAC,SAAqB,EAAE,UAA+B,EAAE,EAAA;AACjF,IAAA,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAc,CAAA,CAAA,EAAI,cAAc,CAAC,IAAI,CAAA,CAAA,CAAG,CAAC;SAChF,GAAG,CAAC,EAAE,IAAI,aAAa,CAAC,EAAE,EAAE,OAAO,CAAC;SACpC,MAAM,CAAC,CAAC,CAAC,KAAwB,CAAC,CAAC,CAAC,CAAC;AAC9C;AAEA;AACM,SAAU,cAAc,CAAC,EAA8B,EAAA;AACzD,IAAA,OAAS,EAAgD,GAAG,WAAW,CAA8B,IAAI,IAAI;AACjH;;AC9OA;;;;;;AAMG;;ACNH;;AAEG;;;;"}
@@ -1,4 +1,5 @@
1
1
  import { SceneRole, makeCompositePart, NO_ELEMENT_STYLE, writeLayerStyles, writeStyles } from '@vectoriox/iox-ui/composite-core';
2
+ import { VideoAttribute, VideoClass, normalizeFrameSequence, FramePlayer } from '@vectoriox/iox-ui/media-core';
2
3
 
3
4
  /**
4
5
  * A Scene's data and maths (premium-sites plan §5b). A Scene is a recipe of ordinary nodes — a tall Section, a pinned
@@ -24,6 +25,8 @@ var SceneProp;
24
25
  SceneProp["Clip"] = "clip";
25
26
  /** How many of the layer's words are lit, in % (100 = all): the word-by-word light-up. Split in the browser only. */
26
27
  SceneProp["Words"] = "words";
28
+ /** How much of a Video layer's pictures have played, in % (100 = the last picture). */
29
+ SceneProp["Play"] = "play";
27
30
  /** The layer's background colour. */
28
31
  SceneProp["Ground"] = "ground";
29
32
  /** The layer's text colour. */
@@ -189,6 +192,11 @@ function sceneWordsLit(tracks, p) {
189
192
  const track = tracks.find(t => t.prop === SceneProp.Words);
190
193
  return track ? clampPercent(valueAt(track.keys, p)) : null;
191
194
  }
195
+ /** How far a layer's pictures have played at `p`, in %; null when it has no such track. */
196
+ function scenePlayed(tracks, p) {
197
+ const track = tracks.find(t => t.prop === SceneProp.Play);
198
+ return track ? clampPercent(valueAt(track.keys, p)) : null;
199
+ }
192
200
  /** Word `index` of `count`, with `lit` % lit: words light one after the other, each easing in as the last finishes. */
193
201
  function sceneWordOpacity(index, count, lit) {
194
202
  return round(SCENE_WORD_DIM + (1 - SCENE_WORD_DIM) * clamp01((lit / PERCENT$1) * count - index));
@@ -261,7 +269,10 @@ function applySceneFirstFrame(el, node) {
261
269
  */
262
270
  const SCENE_FLOW_RULES = `.iox-role-scene{height:auto!important}`
263
271
  + `.iox-role-scene-stage{position:relative!important;top:auto!important;height:auto!important;overflow:visible!important;container-type:normal!important}`
264
- + `[${SceneAttribute.Tracks}]{transform:none!important;opacity:1!important;clip-path:none!important;pointer-events:auto!important}`;
272
+ + `[${SceneAttribute.Tracks}]{transform:none!important;opacity:1!important;clip-path:none!important;pointer-events:auto!important}`
273
+ // A Video the scroll plays stands as its poster, at the poster's own height: a percent of a stage that now flows is nothing.
274
+ + `[${VideoAttribute.Frames}]{height:auto!important}`
275
+ + `[${VideoAttribute.Frames}]>.${VideoClass.Poster}{position:static!important;height:auto!important}`;
265
276
  /** Under reduced motion the driver never starts, so the same rules hold for the whole visit. */
266
277
  const SCENE_REDUCED_MOTION_CSS = `@media (prefers-reduced-motion: reduce){${SCENE_FLOW_RULES}}`;
267
278
 
@@ -289,6 +300,7 @@ const SCENE_TRACK_DEFS = [
289
300
  { prop: SceneProp.Opacity, colour: false, rest: 1, min: 0, max: 100, step: 1, factor: 100, unit: PERCENT },
290
301
  { prop: SceneProp.Clip, colour: false, rest: 100, min: 0, max: 100, step: 1, factor: 1, unit: PERCENT },
291
302
  { prop: SceneProp.Words, colour: false, rest: 100, min: 0, max: 100, step: 1, factor: 1, unit: PERCENT },
303
+ { prop: SceneProp.Play, colour: false, rest: 0, min: 0, max: 100, step: 1, factor: 1, unit: PERCENT },
292
304
  { prop: SceneProp.Ground, colour: true, rest: 0, min: 0, max: 0, step: 0, factor: 1, unit: '' },
293
305
  { prop: SceneProp.Ink, colour: true, rest: 0, min: 0, max: 0, step: 0, factor: 1, unit: '' },
294
306
  ];
@@ -350,6 +362,19 @@ function withSceneRevealFrom(tracks, from, p) {
350
362
  return [...tracks, { prop: SceneProp.Clip, from, keys: [[sceneKeyPosition(p), sceneTrackDef(SceneProp.Clip).rest]] }];
351
363
  return tracks.map(track => (track.prop === SceneProp.Clip ? { ...track, from } : track));
352
364
  }
365
+ /**
366
+ * A layer's pictures playing across the whole Scene: the start of playing them. Keys the author has set are kept, so
367
+ * replacing the pictures keeps the timing.
368
+ */
369
+ function withScenePlayback(tracks) {
370
+ if (trackOf(tracks, SceneProp.Play))
371
+ return [...tracks];
372
+ return [...tracks, { prop: SceneProp.Play, keys: [[0, 0], [1, 100]] }];
373
+ }
374
+ /** Stop playing a layer's pictures. */
375
+ function withoutScenePlayback(tracks) {
376
+ return tracks.filter(track => track.prop !== SceneProp.Play);
377
+ }
353
378
  /**
354
379
  * Set a key at `p`, in the author's units. A number is clamped to its bounds; a colour that is no colour changes nothing,
355
380
  * because `normalizeTracks` would drop it anyway and the author's other keys must survive.
@@ -785,7 +810,7 @@ class ScrollDriver {
785
810
  const Observer = this.host.MutationObserver;
786
811
  if (Observer) {
787
812
  scene.mutations = new Observer(() => this.readScene(scene));
788
- scene.mutations.observe(root, { childList: true, subtree: true, attributes: true, attributeFilter: [SceneAttribute.Tracks, SceneAttribute.PhoneTracks] });
813
+ scene.mutations.observe(root, { childList: true, subtree: true, attributes: true, attributeFilter: [SceneAttribute.Tracks, SceneAttribute.PhoneTracks, VideoAttribute.Frames] });
789
814
  }
790
815
  }
791
816
  this.readScene(scene);
@@ -801,6 +826,7 @@ class ScrollDriver {
801
826
  for (const layer of scene.layers) {
802
827
  layer.el.style.removeProperty('will-change');
803
828
  this.restoreWords(layer);
829
+ this.stopPlayer(layer);
804
830
  }
805
831
  this.scenes.delete(root);
806
832
  }
@@ -881,6 +907,12 @@ class ScrollDriver {
881
907
  for (const key of Object.keys(layer.last))
882
908
  layer.el.style[key] = '';
883
909
  this.restoreWords(layer);
910
+ this.stopPlayer(layer);
911
+ }
912
+ stopPlayer(layer) {
913
+ layer.player?.destroy();
914
+ layer.player = null;
915
+ layer.playerKey = '';
884
916
  }
885
917
  restoreWords(layer) {
886
918
  layer.words?.restore();
@@ -889,7 +921,7 @@ class ScrollDriver {
889
921
  readLayer(el, scene) {
890
922
  const previous = scene.layers.find(layer => layer.el === el);
891
923
  el.style.setProperty('will-change', TRANSFORM_WILL_CHANGE);
892
- return { el, tracks: parseTracks(el.getAttribute(SceneAttribute.Tracks)), phoneTracks: parseTracks(el.getAttribute(SceneAttribute.PhoneTracks)), last: previous?.last ?? {}, stale: true, words: previous?.words ?? null, wordsRefused: false };
924
+ return { el, tracks: parseTracks(el.getAttribute(SceneAttribute.Tracks)), phoneTracks: parseTracks(el.getAttribute(SceneAttribute.PhoneTracks)), last: previous?.last ?? {}, stale: true, words: previous?.words ?? null, wordsRefused: false, player: previous?.player ?? null, playerKey: previous?.playerKey ?? '' };
893
925
  }
894
926
  remeasureAll() {
895
927
  for (const scene of this.scenes.values())
@@ -915,6 +947,7 @@ class ScrollDriver {
915
947
  for (const layer of scene.layers) {
916
948
  const tracks = scene.phone && layer.phoneTracks.length ? layer.phoneTracks : layer.tracks;
917
949
  this.writeWords(layer, sceneWordsLit(tracks, scene.progress));
950
+ this.writePlayed(layer, scene, scenePlayed(tracks, scene.progress));
918
951
  const frame = sceneFrame(tracks, scene.progress, { inlineSign: scene.inlineSign });
919
952
  for (const key of Object.keys(frame)) {
920
953
  if (layer.stale || frame[key] !== layer.last[key])
@@ -929,6 +962,28 @@ class ScrollDriver {
929
962
  layer.stale = false;
930
963
  }
931
964
  }
965
+ /**
966
+ * The picture this moment asks for. The attribute sits on the Video's own root, which is the layer on the string path
967
+ * and inside it on the component path. A layer with no pictures, or no Play track, holds its poster.
968
+ */
969
+ writePlayed(layer, scene, played) {
970
+ const target = played === null ? null : (layer.el.hasAttribute(VideoAttribute.Frames) ? layer.el : layer.el.querySelector(`[${VideoAttribute.Frames}]`));
971
+ const raw = target?.getAttribute(VideoAttribute.Frames) ?? '';
972
+ const sequence = raw ? normalizeFrameSequence(raw) : null;
973
+ if (!target || !sequence) {
974
+ if (layer.player)
975
+ this.stopPlayer(layer);
976
+ return;
977
+ }
978
+ const key = `${scene.phone}|${raw}`;
979
+ if (layer.player && (layer.playerKey !== key || layer.player.detached))
980
+ this.stopPlayer(layer);
981
+ if (!layer.player) {
982
+ layer.player = new FramePlayer(target, sequence, { phone: scene.phone, near: scene.root, host: this.host });
983
+ layer.playerKey = key;
984
+ }
985
+ layer.player.seek(played);
986
+ }
932
987
  /** One opacity per word, and a write only for the few the scroll actually changed. */
933
988
  writeWords(layer, lit) {
934
989
  if (lit === null) {
@@ -978,5 +1033,5 @@ function attachScenes(container, options = {}) {
978
1033
  * Generated bundle index. Do not edit.
979
1034
  */
980
1035
 
981
- export { LIGHT_UP_PIECE_CAP, REVEAL_PIECE_CAP, SCENE_BUDGET, SCENE_DAMPING, SCENE_FLOW_RULES, SCENE_LENGTH, SCENE_MAX_SCREENS, SCENE_MIN_SCREENS, SCENE_PHONE_LENGTH, SCENE_PHONE_MAX_WIDTH, SCENE_REDUCED_MOTION_CSS, SCENE_REVEAL_DEFAULT, SCENE_STAGE_HEIGHT, SCENE_TRACK_DEFS, SCENE_WORDS, SCENE_WORD_DIM, SceneAttribute, SceneProp, SceneRevealFrom, ScrollDriver, TextRevealBy, applySceneFirstFrame, attachScenes, buildSceneRecipe, colourAt, dampToward, lineIndexes, movedSceneKey, normalizeTracks, playTextReveal, revealClipPath, revealStagger, sceneBudget, sceneColourKeyAt, sceneDisplayValue, sceneFirstFrame, sceneFrame, sceneFrameDeclarations, sceneHasKeyAt, sceneHeightForScreens, sceneKeyPosition, sceneLayersOf, sceneNodeAttributes, sceneRevealFromOf, sceneRootOnPath, sceneScreensOf, sceneScrollState, sceneTrackDef, sceneTrackSpan, sceneWordOpacity, sceneWordsLit, scenesIn, splitText, syncSceneAttributes, textPieces, valueAt, withSceneKey, withSceneRevealFrom, withoutSceneKey };
1036
+ export { LIGHT_UP_PIECE_CAP, REVEAL_PIECE_CAP, SCENE_BUDGET, SCENE_DAMPING, SCENE_FLOW_RULES, SCENE_LENGTH, SCENE_MAX_SCREENS, SCENE_MIN_SCREENS, SCENE_PHONE_LENGTH, SCENE_PHONE_MAX_WIDTH, SCENE_REDUCED_MOTION_CSS, SCENE_REVEAL_DEFAULT, SCENE_STAGE_HEIGHT, SCENE_TRACK_DEFS, SCENE_WORDS, SCENE_WORD_DIM, SceneAttribute, SceneProp, SceneRevealFrom, ScrollDriver, TextRevealBy, applySceneFirstFrame, attachScenes, buildSceneRecipe, colourAt, dampToward, lineIndexes, movedSceneKey, normalizeTracks, playTextReveal, revealClipPath, revealStagger, sceneBudget, sceneColourKeyAt, sceneDisplayValue, sceneFirstFrame, sceneFrame, sceneFrameDeclarations, sceneHasKeyAt, sceneHeightForScreens, sceneKeyPosition, sceneLayersOf, sceneNodeAttributes, scenePlayed, sceneRevealFromOf, sceneRootOnPath, sceneScreensOf, sceneScrollState, sceneTrackDef, sceneTrackSpan, sceneWordOpacity, sceneWordsLit, scenesIn, splitText, syncSceneAttributes, textPieces, valueAt, withSceneKey, withScenePlayback, withSceneRevealFrom, withoutSceneKey, withoutScenePlayback };
982
1037
  //# sourceMappingURL=vectoriox-iox-ui-scene-core.mjs.map