mirror of
https://github.com/dirtydishes/dreamio.git
synced 2026-06-06 21:38:15 +00:00
196 lines
No EOL
97 KiB
HTML
196 lines
No EOL
97 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Fix Native Playback Resolution</title>
|
|
<style>
|
|
:root {
|
|
color-scheme: light;
|
|
--ink: oklch(24% 0.022 282);
|
|
--muted: oklch(48% 0.028 282);
|
|
--paper: oklch(98% 0.006 285);
|
|
--panel: oklch(94% 0.012 285);
|
|
--line: oklch(83% 0.024 285);
|
|
--accent: oklch(58% 0.16 292);
|
|
--good: oklch(54% 0.13 165);
|
|
--warn: oklch(62% 0.14 58);
|
|
}
|
|
body { margin: 0; background: var(--paper); color: var(--ink); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; line-height: 1.55; }
|
|
main { max-width: 1060px; margin: 0 auto; padding: 56px 28px 72px; }
|
|
header { margin-bottom: 36px; }
|
|
h1 { font-size: clamp(2rem, 4vw, 4.1rem); line-height: 1; margin: 0 0 18px; letter-spacing: 0; max-width: 780px; }
|
|
h2 { font-size: 1.25rem; margin: 34px 0 10px; }
|
|
p { max-width: 74ch; }
|
|
ul { max-width: 78ch; padding-left: 1.2rem; }
|
|
code { font-family: "SFMono-Regular", Consolas, monospace; font-size: 0.95em; background: var(--panel); padding: 0.08rem 0.28rem; border-radius: 4px; }
|
|
.summary { font-size: 1.1rem; color: var(--muted); max-width: 76ch; }
|
|
.meta { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 18px; }
|
|
.pill { border: 1px solid var(--line); border-radius: 999px; padding: 5px 10px; color: var(--muted); background: oklch(96% 0.01 285); font-size: 0.9rem; }
|
|
.panel { border: 1px solid var(--line); background: oklch(99% 0.004 285); border-radius: 8px; padding: 18px 20px; margin: 16px 0; }
|
|
.callout { border: 1px solid oklch(78% 0.08 58); background: oklch(95% 0.035 68); border-radius: 8px; padding: 14px 16px; max-width: 78ch; }
|
|
.diff-shell { overflow: auto; border: 1px solid var(--line); border-radius: 8px; background: oklch(99% 0.004 285); padding: 8px; }
|
|
.diff-note { color: var(--muted); font-size: 0.95rem; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<main>
|
|
<header>
|
|
<h1>Fix Native Playback Resolution</h1>
|
|
<p class="summary">Dreamio now resolves known Stremio addon stream responses before opening native playback, gives VLC the final direct media URL when one is available, and recovers visibly when stream resolution or VLC startup fails.</p>
|
|
<div class="meta">
|
|
<span class="pill">Beads: dreamio-vxs</span>
|
|
<span class="pill">Native playback</span>
|
|
<span class="pill">Stream resolution</span>
|
|
<span class="pill">2026-05-25</span>
|
|
</div>
|
|
</header>
|
|
|
|
<section>
|
|
<h2>Summary</h2>
|
|
<p>Fixed the native playback path so direct-file selections no longer default to the Debridio or Torrentio resolver URL. Dreamio either uses the observed direct media URL immediately or fetches a known addon resolver and selects a playable direct URL from its Stremio JSON response.</p>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Changes Made</h2>
|
|
<ul>
|
|
<li>Changed native request creation to prefer the observed direct media URL instead of the resolver URL.</li>
|
|
<li>Added <code>StremioStreamResolver</code> to fetch known addon resolver URLs, parse <code>streams</code> JSON, inspect <code>url</code>, <code>externalUrl</code>, and related fields, and merge required request headers.</li>
|
|
<li>Stopped intercepted WebKit media elements before handing the selection to native playback.</li>
|
|
<li>Added a closeable resolver failure alert so bad, expired, or unresolvable streams return the user to Stremio.</li>
|
|
<li>Hardened VLC startup with state logging, a 20 second startup timeout, failure messages, and explicit media/drawable detachment on stop.</li>
|
|
<li>Added focused Swift tests for stream classification and resolver stream selection.</li>
|
|
</ul>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Context</h2>
|
|
<p>The prior native playback bridge intercepted unsupported direct-file streams, but it could pass VLC the resolver/addon URL instead of a final file URL. That made VLC try to play an endpoint intended to return JSON or perform resolution, while WebKit could still continue attempting unsupported playback underneath.</p>
|
|
<p>The <code>127.0.0.1:11470</code> companion-service errors remain treated as secondary noise. This change focuses on the direct stream URL that Dreamio controls before opening MobileVLCKit.</p>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Important Implementation Details</h2>
|
|
<ul>
|
|
<li><code>NativePlaybackRequest</code> now carries merged headers so resolver-provided <code>Referer</code> and <code>User-Agent</code> values can reach VLC.</li>
|
|
<li><code>StremioStreamResolver</code> accepts resolver redirects to direct files and JSON responses containing direct stream fields.</li>
|
|
<li>The resolver selects unsupported direct files first, so MKV, AVI, and WebM go native while HLS-only resolver responses stay out of VLC.</li>
|
|
<li>Duplicate suppression keys by resolver when present, preventing repeated bridge posts during async resolution while still allowing retry after dismiss or failure.</li>
|
|
</ul>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Relevant Diff Snippets</h2>
|
|
<p class="diff-note">Rendered with <code>@pierre/diffs</code>; this excerpt shows the core classifier change that stops preferring resolver URLs by default.</p>
|
|
<div class="diff-shell"><svg data-icon-sprite aria-hidden="true" width="0" height="0">
|
|
<symbol id="diffs-icon-arrow-right-short" viewBox="0 0 16 16">
|
|
<path d="M8.47 4.22a.75.75 0 0 0 0 1.06l1.97 1.97H3.75a.75.75 0 0 0 0 1.5h6.69l-1.97 1.97a.75.75 0 1 0 1.06 1.06l3.25-3.25a.75.75 0 0 0 0-1.06L9.53 4.22a.75.75 0 0 0-1.06 0"/>
|
|
</symbol>
|
|
<symbol id="diffs-icon-brand-github" viewBox="0 0 16 16">
|
|
<path d="M8 0c4.42 0 8 3.58 8 8a8.01 8.01 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27s-1.36.09-2 .27c-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8"/>
|
|
</symbol>
|
|
<symbol id="diffs-icon-chevron" viewBox="0 0 16 16">
|
|
<path d="M1.47 4.47a.75.75 0 0 1 1.06 0L8 9.94l5.47-5.47a.75.75 0 1 1 1.06 1.06l-6 6a.75.75 0 0 1-1.06 0l-6-6a.75.75 0 0 1 0-1.06"/>
|
|
</symbol>
|
|
<symbol id="diffs-icon-chevrons-narrow" viewBox="0 0 10 16">
|
|
<path d="M4.47 2.22a.75.75 0 0 1 1.06 0l3.25 3.25a.75.75 0 0 1-1.06 1.06L5 3.81 2.28 6.53a.75.75 0 0 1-1.06-1.06zM1.22 9.47a.75.75 0 0 1 1.06 0L5 12.19l2.72-2.72a.75.75 0 0 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0l-3.25-3.25a.75.75 0 0 1 0-1.06"/>
|
|
</symbol>
|
|
<symbol id="diffs-icon-diff-split" viewBox="0 0 16 16">
|
|
<path d="M14 0H8.5v16H14a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2m-1.5 6.5v1h1a.5.5 0 0 1 0 1h-1v1a.5.5 0 0 1-1 0v-1h-1a.5.5 0 0 1 0-1h1v-1a.5.5 0 0 1 1 0"/><path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h5.5V0zm.5 7.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1 0-1" opacity=".3"/>
|
|
</symbol>
|
|
<symbol id="diffs-icon-diff-unified" viewBox="0 0 16 16">
|
|
<path fill-rule="evenodd" d="M16 14a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V8.5h16zm-8-4a.5.5 0 0 0-.5.5v1h-1a.5.5 0 0 0 0 1h1v1a.5.5 0 0 0 1 0v-1h1a.5.5 0 0 0 0-1h-1v-1A.5.5 0 0 0 8 10" clip-rule="evenodd"/><path fill-rule="evenodd" d="M14 0a2 2 0 0 1 2 2v5.5H0V2a2 2 0 0 1 2-2zM6.5 3.5a.5.5 0 0 0 0 1h3a.5.5 0 0 0 0-1z" clip-rule="evenodd" opacity=".4"/>
|
|
</symbol>
|
|
<symbol id="diffs-icon-expand" viewBox="0 0 16 16">
|
|
<path d="M3.47 5.47a.75.75 0 0 1 1.06 0L8 8.94l3.47-3.47a.75.75 0 1 1 1.06 1.06l-4 4a.75.75 0 0 1-1.06 0l-4-4a.75.75 0 0 1 0-1.06"/>
|
|
</symbol>
|
|
<symbol id="diffs-icon-expand-all" viewBox="0 0 16 16">
|
|
<path d="M11.47 9.47a.75.75 0 1 1 1.06 1.06l-4 4a.75.75 0 0 1-1.06 0l-4-4a.75.75 0 1 1 1.06-1.06L8 12.94zM7.526 1.418a.75.75 0 0 1 1.004.052l4 4a.75.75 0 1 1-1.06 1.06L8 3.06 4.53 6.53a.75.75 0 1 1-1.06-1.06l4-4z"/>
|
|
</symbol>
|
|
<symbol id="diffs-icon-file-code" viewBox="0 0 16 16">
|
|
<path d="M10.75 0c.199 0 .39.08.53.22l3.5 3.5c.14.14.22.331.22.53v9A2.75 2.75 0 0 1 12.25 16h-8.5A2.75 2.75 0 0 1 1 13.25V2.75A2.75 2.75 0 0 1 3.75 0zm-7 1.5c-.69 0-1.25.56-1.25 1.25v10.5c0 .69.56 1.25 1.25 1.25h8.5c.69 0 1.25-.56 1.25-1.25V5h-1.25A2.25 2.25 0 0 1 10 2.75V1.5z"/><path d="M7.248 6.19a.75.75 0 0 1 .063 1.058L5.753 9l1.558 1.752a.75.75 0 0 1-1.122.996l-2-2.25a.75.75 0 0 1 0-.996l2-2.25a.75.75 0 0 1 1.06-.063M8.69 7.248a.75.75 0 1 1 1.12-.996l2 2.25a.75.75 0 0 1 0 .996l-2 2.25a.75.75 0 1 1-1.12-.996L10.245 9z"/>
|
|
</symbol>
|
|
<symbol id="diffs-icon-plus" viewBox="0 0 16 16">
|
|
<path d="M8 3a.75.75 0 0 1 .75.75v3.5h3.5a.75.75 0 0 1 0 1.5h-3.5v3.5a.75.75 0 0 1-1.5 0v-3.5h-3.5a.75.75 0 0 1 0-1.5h3.5v-3.5A.75.75 0 0 1 8 3"/>
|
|
</symbol>
|
|
<symbol id="diffs-icon-symbol-added" viewBox="0 0 16 16">
|
|
<path d="M8 4a.75.75 0 0 1 .75.75v2.5h2.5a.75.75 0 0 1 0 1.5h-2.5v2.5a.75.75 0 0 1-1.5 0v-2.5h-2.5a.75.75 0 0 1 0-1.5h2.5v-2.5A.75.75 0 0 1 8 4"/><path d="M1.788 4.296c.196-.88.478-1.381.802-1.706s.826-.606 1.706-.802C5.194 1.588 6.387 1.5 8 1.5s2.806.088 3.704.288c.88.196 1.381.478 1.706.802s.607.826.802 1.706c.2.898.288 2.091.288 3.704s-.088 2.806-.288 3.704c-.195.88-.478 1.381-.802 1.706s-.826.607-1.706.802c-.898.2-2.091.288-3.704.288s-2.806-.088-3.704-.288c-.88-.195-1.381-.478-1.706-.802s-.606-.826-.802-1.706C1.588 10.806 1.5 9.613 1.5 8s.088-2.806.288-3.704M8 0C1.412 0 0 1.412 0 8s1.412 8 8 8 8-1.412 8-8-1.412-8-8-8"/>
|
|
</symbol>
|
|
<symbol id="diffs-icon-symbol-deleted" viewBox="0 0 16 16">
|
|
<path d="M4 8a.75.75 0 0 1 .75-.75h6.5a.75.75 0 0 1 0 1.5h-6.5A.75.75 0 0 1 4 8"/><path d="M1.788 4.296c.196-.88.478-1.381.802-1.706s.826-.606 1.706-.802C5.194 1.588 6.387 1.5 8 1.5s2.806.088 3.704.288c.88.196 1.381.478 1.706.802s.607.826.802 1.706c.2.898.288 2.091.288 3.704s-.088 2.806-.288 3.704c-.195.88-.478 1.381-.802 1.706s-.826.607-1.706.802c-.898.2-2.091.288-3.704.288s-2.806-.088-3.704-.288c-.88-.195-1.381-.478-1.706-.802s-.606-.826-.802-1.706C1.588 10.806 1.5 9.613 1.5 8s.088-2.806.288-3.704M8 0C1.412 0 0 1.412 0 8s1.412 8 8 8 8-1.412 8-8-1.412-8-8-8"/>
|
|
</symbol>
|
|
<symbol id="diffs-icon-symbol-diffstat" viewBox="0 0 16 16">
|
|
<path d="M1.788 4.296c.196-.88.478-1.381.802-1.706s.826-.606 1.706-.802C5.194 1.588 6.387 1.5 8 1.5s2.806.088 3.704.288c.88.196 1.381.478 1.706.802s.607.826.802 1.706c.2.898.288 2.091.288 3.704s-.088 2.806-.288 3.704c-.195.88-.478 1.381-.802 1.706s-.826.607-1.706.802c-.898.2-2.091.288-3.704.288s-2.806-.088-3.704-.288c-.88-.195-1.381-.478-1.706-.802s-.606-.826-.802-1.706C1.588 10.806 1.5 9.613 1.5 8s.088-2.806.288-3.704M8 0C1.412 0 0 1.412 0 8s1.412 8 8 8 8-1.412 8-8-1.412-8-8-8"/><path d="M8.75 4.296a.75.75 0 0 0-1.5 0V6.25h-2a.75.75 0 0 0 0 1.5h2v1.5h1.5v-1.5h2a.75.75 0 0 0 0-1.5h-2zM5.25 10a.75.75 0 0 0 0 1.5h5.5a.75.75 0 0 0 0-1.5z"/>
|
|
</symbol>
|
|
<symbol id="diffs-icon-symbol-ignored" viewBox="0 0 16 16">
|
|
<path d="M1.5 8c0 1.613.088 2.806.288 3.704.196.88.478 1.381.802 1.706s.826.607 1.706.802c.898.2 2.091.288 3.704.288s2.806-.088 3.704-.288c.88-.195 1.381-.478 1.706-.802s.607-.826.802-1.706c.2-.898.288-2.091.288-3.704s-.088-2.806-.288-3.704c-.195-.88-.478-1.381-.802-1.706s-.826-.606-1.706-.802C10.806 1.588 9.613 1.5 8 1.5s-2.806.088-3.704.288c-.88.196-1.381.478-1.706.802s-.606.826-.802 1.706C1.588 5.194 1.5 6.387 1.5 8M0 8c0-6.588 1.412-8 8-8s8 1.412 8 8-1.412 8-8 8-8-1.412-8-8m11.53-2.47a.75.75 0 0 0-1.06-1.06l-6 6a.75.75 0 1 0 1.06 1.06z"/>
|
|
</symbol>
|
|
<symbol id="diffs-icon-symbol-modified" viewBox="0 0 16 16">
|
|
<path d="M1.5 8c0 1.613.088 2.806.288 3.704.196.88.478 1.381.802 1.706s.826.607 1.706.802c.898.2 2.091.288 3.704.288s2.806-.088 3.704-.288c.88-.195 1.381-.478 1.706-.802s.607-.826.802-1.706c.2-.898.288-2.091.288-3.704s-.088-2.806-.288-3.704c-.195-.88-.478-1.381-.802-1.706s-.826-.606-1.706-.802C10.806 1.588 9.613 1.5 8 1.5s-2.806.088-3.704.288c-.88.196-1.381.478-1.706.802s-.606.826-.802 1.706C1.588 5.194 1.5 6.387 1.5 8M0 8c0-6.588 1.412-8 8-8s8 1.412 8 8-1.412 8-8 8-8-1.412-8-8m8 3a3 3 0 1 0 0-6 3 3 0 0 0 0 6"/>
|
|
</symbol>
|
|
<symbol id="diffs-icon-symbol-moved" viewBox="0 0 16 16">
|
|
<path d="M1.788 4.296c.196-.88.478-1.381.802-1.706s.826-.606 1.706-.802C5.194 1.588 6.387 1.5 8 1.5s2.806.088 3.704.288c.88.196 1.381.478 1.706.802s.607.826.802 1.706c.2.898.288 2.091.288 3.704s-.088 2.806-.288 3.704c-.195.88-.478 1.381-.802 1.706s-.826.607-1.706.802c-.898.2-2.091.288-3.704.288s-2.806-.088-3.704-.288c-.88-.195-1.381-.478-1.706-.802s-.606-.826-.802-1.706C1.588 10.806 1.5 9.613 1.5 8s.088-2.806.288-3.704M8 0C1.412 0 0 1.412 0 8s1.412 8 8 8 8-1.412 8-8-1.412-8-8-8"/><path d="M8.495 4.695a.75.75 0 0 0-.05 1.06L10.486 8l-2.041 2.246a.75.75 0 0 0 1.11 1.008l2.5-2.75a.75.75 0 0 0 0-1.008l-2.5-2.75a.75.75 0 0 0-1.06-.051m-4 0a.75.75 0 0 0-.05 1.06l2.044 2.248-1.796 1.995a.75.75 0 0 0 1.114 1.004l2.25-2.5a.75.75 0 0 0-.002-1.007l-2.5-2.75a.75.75 0 0 0-1.06-.05"/>
|
|
</symbol>
|
|
<symbol id="diffs-icon-symbol-ref" viewBox="0 0 16 16">
|
|
<path d="M1.5 8c0 1.613.088 2.806.288 3.704.196.88.478 1.381.802 1.706.286.286.71.54 1.41.73V1.86c-.7.19-1.124.444-1.41.73-.324.325-.606.826-.802 1.706C1.588 5.194 1.5 6.387 1.5 8m4 6.397c.697.07 1.522.103 2.5.103 1.613 0 2.806-.088 3.704-.288.88-.195 1.381-.478 1.706-.802s.607-.826.802-1.706c.2-.898.288-2.091.288-3.704s-.088-2.806-.288-3.704c-.195-.88-.478-1.381-.802-1.706s-.826-.606-1.706-.802C10.806 1.588 9.613 1.5 8 1.5c-.978 0-1.803.033-2.5.103zM0 8c0-6.588 1.412-8 8-8s8 1.412 8 8-1.412 8-8 8-8-1.412-8-8m7-2a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H8a1 1 0 0 1-1-1z"/>
|
|
</symbol>
|
|
</svg><style data-core-css="">@layer base, theme, rendered, unsafe;
|
|
@layer base,theme,rendered,unsafe;@layer base{:host{--diffs-font-fallback:"SF Mono", Monaco, Consolas, "Ubuntu Mono", "Liberation Mono", "Courier New", monospace;--diffs-header-font-fallback:system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif;--diffs-mixer:light-dark(#000,#fff);--diffs-gap-fallback:8px;--diffs-scrollbar-gutter-fallback:6px;--diffs-scrollbar-gutter:var(--diffs-scrollbar-gutter-override,var(--diffs-scrollbar-gutter-measured,var(--diffs-scrollbar-gutter-fallback)));--diffs-added-light:#0dbe4e;--diffs-added-dark:#5ecc71;--diffs-modified-light:#009fff;--diffs-modified-dark:#69b1ff;--diffs-deleted-light:#ff2e3f;--diffs-deleted-dark:#ff6762;color-scheme:light dark;font-family:var(--diffs-header-font-family,var(--diffs-header-font-fallback));font-size:var(--diffs-font-size,13px);line-height:var(--diffs-line-height,20px);font-feature-settings:var(--diffs-font-features);--diffs-bg:light-dark(var(--diffs-light-bg,#fff),var(--diffs-dark-bg,#000));--diffs-bg-buffer:var(--diffs-bg-buffer-override,light-dark(color-mix(in lab, var(--diffs-bg) 92%, var(--diffs-mixer)),color-mix(in lab, var(--diffs-bg) 92%, var(--diffs-mixer))));--diffs-bg-context:var(--diffs-bg-context-override,light-dark(color-mix(in lab, var(--diffs-bg) 98.5%, var(--diffs-mixer)),color-mix(in lab, var(--diffs-bg) 92.5%, var(--diffs-mixer))));--diffs-bg-context-gutter:var(--diffs-bg-context-gutter-override,light-dark(color-mix(in lab, var(--diffs-bg-context) 90%, var(--diffs-bg)),color-mix(in lab, var(--diffs-bg-context) 45%, var(--diffs-bg))));--diffs-bg-separator:var(--diffs-bg-separator-override,light-dark(color-mix(in lab, var(--diffs-bg) 96%, var(--diffs-mixer)),color-mix(in lab, var(--diffs-bg) 85%, var(--diffs-mixer))));--diffs-fg:light-dark(var(--diffs-light,#000),var(--diffs-dark,#fff));--diffs-fg-number:var(--diffs-fg-number-override,light-dark(color-mix(in lab, var(--diffs-fg) 65%, var(--diffs-bg)),color-mix(in lab, var(--diffs-fg) 65%, var(--diffs-bg))));--diffs-fg-conflict-marker:var(--diffs-fg-conflict-marker-override,var(--diffs-fg-number));--diffs-deletion-base:var(--diffs-deletion-color-override,light-dark(var(--diffs-light-deletion-color,var(--diffs-deletion-color,var(--diffs-deleted-light))),var(--diffs-dark-deletion-color,var(--diffs-deletion-color,var(--diffs-deleted-dark)))));--diffs-addition-base:var(--diffs-addition-color-override,light-dark(var(--diffs-light-addition-color,var(--diffs-addition-color,var(--diffs-added-light))),var(--diffs-dark-addition-color,var(--diffs-addition-color,var(--diffs-added-dark)))));--diffs-modified-base:var(--diffs-modified-color-override,light-dark(var(--diffs-light-modified-color,var(--diffs-modified-color,var(--diffs-modified-light))),var(--diffs-dark-modified-color,var(--diffs-modified-color,var(--diffs-modified-dark)))));--diffs-bg-deletion:var(--diffs-bg-deletion-override,light-dark(color-mix(in lab, var(--diffs-bg) 88%, var(--diffs-deletion-base)),color-mix(in lab, var(--diffs-bg) 80%, var(--diffs-deletion-base))));--diffs-bg-deletion-emphasis:var(--diffs-bg-deletion-emphasis-override,light-dark(rgb(from var(--diffs-deletion-base) r g b / .15),rgb(from var(--diffs-deletion-base) r g b / .2)));--diffs-bg-addition:var(--diffs-bg-addition-override,light-dark(color-mix(in lab, var(--diffs-bg) 88%, var(--diffs-addition-base)),color-mix(in lab, var(--diffs-bg) 80%, var(--diffs-addition-base))));--diffs-bg-addition-emphasis:var(--diffs-bg-addition-emphasis-override,light-dark(rgb(from var(--diffs-addition-base) r g b / .15),rgb(from var(--diffs-addition-base) r g b / .2)));--diffs-selection-base:var(--diffs-modified-base);--diffs-selection-number-fg:light-dark(color-mix(in lab, var(--diffs-selection-base) 65%, var(--diffs-mixer)),color-mix(in lab, var(--diffs-selection-base) 75%, var(--diffs-mixer)));background-color:var(--diffs-bg);color:var(--diffs-fg);display:block}pre,code,[data-error-wrapper]{isolation:isolate;font-family:var(--diffs-font-family,var(--diffs-font-fallback));outline:none;margin:0;padding:0;display:block}pre,code{background-color:var(--diffs-bg)}code{contain:content}*,:before,:after{box-sizing:border-box}[data-icon-sprite]{display:none}[data-diffs-header],[data-separator]{font-family:var(--diffs-header-font-family,var(--diffs-header-font-fallback))}[data-diffs-header][data-sticky]{z-index:1;background-color:var(--diffs-bg);position:sticky;top:0}[data-file-info]{color:var(--fg);background-color:color-mix(in lab, var(--bg) 98%, var(--fg));border-block:1px solid color-mix(in lab, var(--bg) 95%, var(--fg));padding:10px;font-weight:700}[data-diff],[data-file]{--diffs-grid-number-column-width:minmax(min-content, max-content);--diffs-code-grid:var(--diffs-grid-number-column-width) 1fr}[data-dehydrated]:is([data-diff],[data-file]){--diffs-code-grid:var(--diffs-grid-number-column-width) minmax(0, 1fr)}:is([data-diff],[data-file]):hover [data-code]::-webkit-scrollbar-thumb{background-color:var(--diffs-bg-context)}@supports (-webkit-touch-callout:none){:host{--diffs-scrollbar-gutter-fallback:0px}}[data-line] span{color:light-dark(var(--diffs-token-light,var(--diffs-light)),var(--diffs-token-dark,var(--diffs-dark)));background-color:light-dark(var(--diffs-token-light-bg,inherit),var(--diffs-token-dark-bg,inherit));font-weight:light-dark(var(--diffs-token-light-font-weight,inherit),var(--diffs-token-dark-font-weight,inherit));font-style:light-dark(var(--diffs-token-light-font-style,inherit),var(--diffs-token-dark-font-style,inherit));-webkit-text-decoration:light-dark(var(--diffs-token-light-text-decoration,inherit),var(--diffs-token-dark-text-decoration,inherit));text-decoration:light-dark(var(--diffs-token-light-text-decoration,inherit),var(--diffs-token-dark-text-decoration,inherit))}[data-line],[data-gutter-buffer],[data-column-number],[data-line-annotation],[data-no-newline],[data-merge-conflict],[data-merge-conflict-actions]{--diffs-computed-decoration-bg:var(--diffs-bg);--diffs-computed-diff-line-bg:var(--diffs-bg);--diffs-computed-selected-line-bg:var(--diffs-bg);color:var(--diffs-fg);background-color:var(--diffs-line-bg,var(--diffs-bg))}@media (pointer:fine){:is([data-line],[data-gutter-buffer],[data-column-number],[data-line-annotation],[data-no-newline],[data-merge-conflict],[data-merge-conflict-actions]):where([data-hovered]){--diffs-computed-hovered-line-bg:light-dark(color-mix(in lab, var(--diffs-computed-selected-line-bg) 97%, var(--diffs-bg-hover-override,var(--diffs-mixer))),color-mix(in lab, var(--diffs-computed-selected-line-bg) 91%, var(--diffs-bg-hover-override,var(--diffs-mixer))));--diffs-line-bg:var(--diffs-computed-hovered-line-bg,inherit)}}[data-decoration-bg]:is([data-line],[data-no-newline]){--mix-deco-light:92%;--mix-deco-dark:85%}[data-decoration-bg][data-decoration-bg-depth="2"]:is([data-line],[data-no-newline]){--mix-deco-light:88%;--mix-deco-dark:80%}[data-decoration-bg][data-decoration-bg-depth="3"]:is([data-line],[data-no-newline]){--mix-deco-light:85%;--mix-deco-dark:78%}@media (pointer:fine){[data-decoration-bg][data-hovered]:is([data-line],[data-no-newline]):not([data-selected-line]){--mix-deco-light:85%;--mix-deco-dark:85%}[data-decoration-bg][data-hovered][data-decoration-bg-depth="2"]:is([data-line],[data-no-newline]):not([data-selected-line]){--mix-deco-light:83%;--mix-deco-dark:83%}[data-decoration-bg][data-hovered][data-decoration-bg-depth="3"]:is([data-line],[data-no-newline]):not([data-selected-line]){--mix-deco-light:81%;--mix-deco-dark:81%}}[data-decoration-bg]:is([data-line],[data-no-newline]){--diffs-computed-decoration-bg:light-dark(color-mix(in lab, var(--diffs-bg) var(--mix-deco-light), var(--diffs-decoration-bg)),color-mix(in lab, var(--diffs-bg) var(--mix-deco-dark), var(--diffs-decoration-bg)));--diffs-computed-diff-line-bg:var(--diffs-computed-decoration-bg);--diffs-computed-selected-line-bg:var(--diffs-computed-decoration-bg);--diffs-line-bg:var(--diffs-computed-decoration-bg)}[data-line-annotation],[data-gutter-buffer=annotation]{--diffs-annotation-bg:var(--diffs-bg-context);--diffs-computed-decoration-bg:var(--diffs-annotation-bg);--diffs-computed-diff-line-bg:var(--diffs-annotation-bg);--diffs-computed-selected-line-bg:var(--diffs-annotation-bg);--diffs-line-bg:var(--diffs-annotation-bg)}[data-merge-conflict-actions],[data-gutter-buffer=merge-conflict-action],[data-gutter-buffer=merge-conflict-marker-base],[data-gutter-buffer=merge-conflict-marker-separator],[data-merge-conflict=marker-base],[data-merge-conflict=marker-separator]{--diffs-computed-decoration-bg:var(--diffs-bg-context);--diffs-computed-diff-line-bg:var(--diffs-bg-context);--diffs-computed-selected-line-bg:var(--diffs-bg-context);--diffs-line-bg:var(--diffs-bg-context)}[data-gutter-buffer=merge-conflict-marker-start],[data-merge-conflict=marker-start]{--diffs-computed-decoration-bg:light-dark(color-mix(in lab, var(--diffs-bg) 78%, var(--conflict-bg-current-header-override,var(--diffs-addition-base))),color-mix(in lab, var(--diffs-bg) 68%, var(--conflict-bg-current-header-override,var(--diffs-addition-base))));--diffs-computed-diff-line-bg:var(--diffs-computed-decoration-bg);--diffs-computed-selected-line-bg:var(--diffs-computed-decoration-bg);--diffs-line-bg:var(--diffs-computed-decoration-bg)}[data-gutter-buffer=merge-conflict-marker-end],[data-merge-conflict=marker-end]{--diffs-computed-decoration-bg:light-dark(color-mix(in lab, var(--diffs-bg) 78%, var(--conflict-bg-incoming-header-override,var(--diffs-modified-base))),color-mix(in lab, var(--diffs-bg) 68%, var(--conflict-bg-incoming-header-override,var(--diffs-modified-base))));--diffs-computed-diff-line-bg:var(--diffs-computed-decoration-bg);--diffs-computed-selected-line-bg:var(--diffs-computed-decoration-bg);--diffs-line-bg:var(--diffs-computed-decoration-bg)}[data-has-merge-conflict] [data-line-annotation],[data-has-merge-conflict] [data-gutter-buffer=annotation]{--diffs-computed-decoration-bg:var(--diffs-bg);--diffs-computed-diff-line-bg:var(--diffs-bg);--diffs-computed-selected-line-bg:var(--diffs-bg);--diffs-line-bg:var(--diffs-bg)}:where([data-background]) [data-gutter-buffer],:where([data-background]) [data-column-number]{--mix-light:91%;--mix-dark:85%}:where([data-background]) [data-line],:where([data-background]) [data-no-newline]{--mix-light:88%;--mix-dark:80%}:where([data-background]) [data-gutter-buffer],:where([data-background]) [data-column-number],:where([data-background]) [data-line],:where([data-background]) [data-no-newline]{--diffs-diff-line-mix-target:var(--diffs-bg)}[data-line-type=change-deletion]:is(:where([data-background]) [data-gutter-buffer],:where([data-background]) [data-column-number],:where([data-background]) [data-line],:where([data-background]) [data-no-newline]){--diffs-diff-line-mix-target:var(--diffs-bg-deletion-override,var(--diffs-deletion-base))}@media (pointer:fine){[data-line-type=change-deletion][data-hovered]:is(:where([data-background]) [data-gutter-buffer],:where([data-background]) [data-column-number],:where([data-background]) [data-line],:where([data-background]) [data-no-newline]){--mix-light:80%;--mix-dark:75%}}[data-line-type=change-deletion]:is(:where([data-background]) [data-gutter-buffer],:where([data-background]) [data-column-number],:where([data-background]) [data-line],:where([data-background]) [data-no-newline]):where([data-gutter-buffer],[data-column-number]){color:var(--diffs-fg-number-deletion-override,var(--diffs-deletion-base));--diffs-diff-line-mix-target:var(--diffs-bg-deletion-number-override,var(--diffs-deletion-base))}[data-line-type=change-deletion]:is(:where([data-background]) [data-gutter-buffer],:where([data-background]) [data-column-number],:where([data-background]) [data-line],:where([data-background]) [data-no-newline]){--diffs-computed-diff-line-bg:light-dark(color-mix(in lab, var(--diffs-computed-decoration-bg) var(--mix-light), var(--diffs-diff-line-mix-target)),color-mix(in lab, var(--diffs-computed-decoration-bg) var(--mix-dark), var(--diffs-diff-line-mix-target)));--diffs-computed-selected-line-bg:var(--diffs-computed-diff-line-bg);--diffs-line-bg:var(--diffs-computed-diff-line-bg,inherit)}[data-line-type=change-addition]:is(:where([data-background]) [data-gutter-buffer],:where([data-background]) [data-column-number],:where([data-background]) [data-line],:where([data-background]) [data-no-newline]){--diffs-diff-line-mix-target:var(--diffs-bg-addition-override,var(--diffs-addition-base))}@media (pointer:fine){[data-line-type=change-addition][data-hovered]:is(:where([data-background]) [data-gutter-buffer],:where([data-background]) [data-column-number],:where([data-background]) [data-line],:where([data-background]) [data-no-newline]){--mix-light:80%;--mix-dark:70%}}[data-line-type=change-addition]:is(:where([data-background]) [data-gutter-buffer],:where([data-background]) [data-column-number],:where([data-background]) [data-line],:where([data-background]) [data-no-newline]):where([data-gutter-buffer],[data-column-number]){color:var(--diffs-fg-number-addition-override,var(--diffs-addition-base));--diffs-diff-line-mix-target:var(--diffs-bg-addition-number-override,var(--diffs-addition-base))}[data-line-type=change-addition]:is(:where([data-background]) [data-gutter-buffer],:where([data-background]) [data-column-number],:where([data-background]) [data-line],:where([data-background]) [data-no-newline]){--diffs-computed-diff-line-bg:light-dark(color-mix(in lab, var(--diffs-computed-decoration-bg) var(--mix-light), var(--diffs-diff-line-mix-target)),color-mix(in lab, var(--diffs-computed-decoration-bg) var(--mix-dark), var(--diffs-diff-line-mix-target)));--diffs-computed-selected-line-bg:var(--diffs-computed-diff-line-bg);--diffs-line-bg:var(--diffs-computed-diff-line-bg,inherit)}[data-merge-conflict=current]:is(:where([data-background]) [data-gutter-buffer],:where([data-background]) [data-column-number],:where([data-background]) [data-line],:where([data-background]) [data-no-newline]){--diffs-diff-line-mix-target:var(--conflict-bg-current-override,var(--diffs-addition-base))}[data-merge-conflict=current]:is(:where([data-background]) [data-gutter-buffer],:where([data-background]) [data-column-number],:where([data-background]) [data-line],:where([data-background]) [data-no-newline]):where([data-gutter-buffer],[data-column-number]){color:var(--diffs-fg-number-addition-override,var(--diffs-addition-base));--diffs-diff-line-mix-target:var(--conflict-bg-current-number-override,var(--diffs-addition-base))}@media (pointer:fine){[data-merge-conflict=current][data-hovered]:is(:where([data-background]) [data-gutter-buffer],:where([data-background]) [data-column-number],:where([data-background]) [data-line],:where([data-background]) [data-no-newline]){--mix-light:80%;--mix-dark:70%}}[data-merge-conflict=current]:is(:where([data-background]) [data-gutter-buffer],:where([data-background]) [data-column-number],:where([data-background]) [data-line],:where([data-background]) [data-no-newline]){--diffs-computed-diff-line-bg:light-dark(color-mix(in lab, var(--diffs-computed-decoration-bg) var(--mix-light), var(--diffs-diff-line-mix-target)),color-mix(in lab, var(--diffs-computed-decoration-bg) var(--mix-dark), var(--diffs-diff-line-mix-target)));--diffs-computed-selected-line-bg:var(--diffs-computed-diff-line-bg);--diffs-line-bg:var(--diffs-computed-diff-line-bg,inherit)}[data-merge-conflict=incoming]:is(:where([data-background]) [data-gutter-buffer],:where([data-background]) [data-column-number],:where([data-background]) [data-line],:where([data-background]) [data-no-newline]){--diffs-diff-line-mix-target:var(--conflict-bg-incoming-override,var(--diffs-modified-base))}[data-merge-conflict=incoming]:is(:where([data-background]) [data-gutter-buffer],:where([data-background]) [data-column-number],:where([data-background]) [data-line],:where([data-background]) [data-no-newline]):where([data-gutter-buffer],[data-column-number]){color:var(--diffs-modified-base);--diffs-diff-line-mix-target:var(--conflict-bg-incoming-number-override,var(--diffs-modified-base))}@media (pointer:fine){[data-merge-conflict=incoming][data-hovered]:is(:where([data-background]) [data-gutter-buffer],:where([data-background]) [data-column-number],:where([data-background]) [data-line],:where([data-background]) [data-no-newline]){--mix-light:80%;--mix-dark:70%}}[data-merge-conflict=incoming]:is(:where([data-background]) [data-gutter-buffer],:where([data-background]) [data-column-number],:where([data-background]) [data-line],:where([data-background]) [data-no-newline]){--diffs-computed-diff-line-bg:light-dark(color-mix(in lab, var(--diffs-computed-decoration-bg) var(--mix-light), var(--diffs-diff-line-mix-target)),color-mix(in lab, var(--diffs-computed-decoration-bg) var(--mix-dark), var(--diffs-diff-line-mix-target)));--diffs-computed-selected-line-bg:var(--diffs-computed-diff-line-bg);--diffs-line-bg:var(--diffs-computed-diff-line-bg,inherit)}[data-gutter-buffer],[data-column-number],[data-line],[data-line-annotation],[data-merge-conflict],[data-merge-conflict-actions],[data-no-newline]{--diffs-selection-mix-target:var(--diffs-bg-selection-override,var(--diffs-selection-base))}[data-selected-line]:is([data-gutter-buffer],[data-column-number],[data-line],[data-line-annotation],[data-merge-conflict],[data-merge-conflict-actions],[data-no-newline]):where([data-line],[data-line-annotation],[data-merge-conflict],[data-merge-conflict-actions],[data-no-newline]){--mix-selection-light:82%;--mix-selection-dark:75%}@media (pointer:fine){[data-selected-line][data-hovered]:is([data-gutter-buffer],[data-column-number],[data-line],[data-line-annotation],[data-merge-conflict],[data-merge-conflict-actions],[data-no-newline]):where([data-line],[data-line-annotation],[data-merge-conflict],[data-merge-conflict-actions],[data-no-newline]):not([data-merge-conflict],[data-line-type=change-addition],[data-line-type=change-deletion]){--mix-selection-light:75%;--mix-selection-dark:70%}}[data-selected-line]:is([data-gutter-buffer],[data-column-number],[data-line],[data-line-annotation],[data-merge-conflict],[data-merge-conflict-actions],[data-no-newline]):where([data-gutter-buffer],[data-column-number]){--mix-selection-light:75%;--mix-selection-dark:60%;--diffs-selection-mix-target:var(--diffs-bg-selection-number-override,var(--diffs-selection-base))}@media (pointer:fine){[data-selected-line][data-hovered]:is([data-gutter-buffer],[data-column-number],[data-line],[data-line-annotation],[data-merge-conflict],[data-merge-conflict-actions],[data-no-newline]):where([data-gutter-buffer],[data-column-number]):not([data-merge-conflict],[data-line-type=change-addition],[data-line-type=change-deletion]){--mix-selection-light:70%;--mix-selection-dark:55%}}[data-selected-line]:is([data-gutter-buffer],[data-column-number],[data-line],[data-line-annotation],[data-merge-conflict],[data-merge-conflict-actions],[data-no-newline]){--diffs-computed-selected-line-bg:light-dark(color-mix(in lab, var(--diffs-computed-diff-line-bg) var(--mix-selection-light), var(--diffs-selection-mix-target)),color-mix(in lab, var(--diffs-computed-diff-line-bg) var(--mix-selection-dark), var(--diffs-selection-mix-target)));--diffs-line-bg:var(--diffs-computed-selected-line-bg,inherit)}[data-selected-line]:is([data-gutter-buffer],[data-column-number]){color:var(--diffs-selection-number-fg)}[data-no-newline]{-webkit-user-select:none;user-select:none}[data-no-newline] span{opacity:.6}[data-diff-type=split][data-overflow=scroll]{grid-template-columns:1fr 1fr;display:grid}[data-diff-type=split][data-overflow=scroll] [data-additions]{border-left:1px solid var(--diffs-bg)}[data-diff-type=split][data-overflow=scroll] [data-deletions]{border-right:1px solid var(--diffs-bg)}[data-code]{grid-auto-flow:dense;grid-template-columns:var(--diffs-code-grid);overflow:var(--diffs-overflow-override,scroll) clip;overscroll-behavior-x:none;tab-size:var(--diffs-tab-size,2);padding-top:var(--diffs-gap-block,var(--diffs-gap-fallback));padding-bottom:max(0px, calc(var(--diffs-gap-block,var(--diffs-gap-fallback)) - var(--diffs-scrollbar-gutter)));scrollbar-gutter:stable;align-self:flex-start;display:grid}[data-diffs-scrollbar-measure]{opacity:0;pointer-events:none;scrollbar-gutter:auto;grid-template-columns:none;width:100px;height:100px;padding:0;position:absolute;top:-200px;left:-200px}[data-container-size]{container-type:inline-size}[data-code]::-webkit-scrollbar{width:0;height:var(--diffs-scrollbar-gutter)}[data-code]::-webkit-scrollbar-track{background:0 0}[data-code]::-webkit-scrollbar-thumb{background-color:#0000;background-clip:content-box;border:1px solid #0000;border-radius:3px}[data-code]::-webkit-scrollbar-corner{background-color:#0000}@supports ((-moz-appearance:none)){[data-code]{scrollbar-width:thin;scrollbar-color:var(--diffs-bg-context) transparent;padding-bottom:var(--diffs-gap-block,var(--diffs-gap-fallback))}}:is([data-diffs-header]~[data-diff],[data-diffs-header]~[data-file]) [data-code],[data-overflow=wrap]:is([data-diffs-header]~[data-diff],[data-diffs-header]~[data-file]){padding-top:0}[data-gutter]{grid-template-rows:subgrid;grid-template-columns:subgrid;z-index:3;background-color:var(--diffs-bg);grid-column:1;display:grid;position:relative}[data-gutter] [data-gutter-buffer],[data-gutter] [data-column-number]{border-right:var(--diffs-gap-style,2px solid var(--diffs-bg))}[data-content]{grid-template-rows:subgrid;grid-template-columns:subgrid;background-color:var(--diffs-bg);grid-column:2;min-width:0;display:grid}[data-diff-type=split][data-overflow=wrap]{grid-auto-flow:dense;grid-template-columns:repeat(2, var(--diffs-code-grid));padding-block:var(--diffs-gap-block,var(--diffs-gap-fallback));display:grid}[data-diff-type=split][data-overflow=wrap] [data-deletions]{display:contents}:is([data-diff-type=split][data-overflow=wrap] [data-deletions]) [data-gutter]{grid-column:1}:is([data-diff-type=split][data-overflow=wrap] [data-deletions]) [data-content]{border-right:1px solid var(--diffs-bg);grid-column:2}[data-diff-type=split][data-overflow=wrap] [data-additions]{display:contents}:is([data-diff-type=split][data-overflow=wrap] [data-additions]) [data-gutter]{border-left:1px solid var(--diffs-bg);grid-column:3}:is([data-diff-type=split][data-overflow=wrap] [data-additions]) [data-content]{grid-column:4}[data-overflow=scroll] [data-gutter]{position:sticky;left:0}[data-interactive-lines] [data-line]{cursor:pointer}[data-interactive-line-numbers] [data-column-number]{cursor:pointer;touch-action:none}[data-content-buffer],[data-gutter-buffer]{-webkit-user-select:none;user-select:none;min-height:1lh;position:relative}[data-gutter-buffer]{padding-left:2ch;padding-right:1ch}[data-gutter-buffer]:before{content:"";min-width:var(--diffs-min-number-column-width,var(--diffs-min-number-column-width-default,3ch));display:block}[data-gutter-buffer=annotation]{--diffs-annotation-bg:var(--diffs-bg-context-gutter);min-height:0}[data-gutter-buffer=buffer]{--diffs-line-bg:var(--diffs-bg-context-gutter)}[data-content-buffer]{background-position:5px 0;background-size:8px 8px;background-origin:border-box;background-image:repeating-linear-gradient(-45deg, transparent, transparent 4.242px, var(--diffs-bg-buffer) 4.242px, var(--diffs-bg-buffer) 5.656px);grid-column:1}[data-separator]{box-sizing:content-box;background-color:var(--diffs-bg)}[data-separator=simple]{min-height:4px}[data-separator=line-info],[data-separator=line-info-basic],[data-separator=metadata],[data-separator=simple]{background-color:var(--diffs-bg-separator)}[data-separator=line-info],[data-separator=line-info-basic],[data-separator=metadata]{height:32px;position:relative}[data-separator-wrapper]{-webkit-user-select:none;user-select:none;fill:currentColor;background-color:var(--diffs-bg);align-items:center;height:100%;display:flex;position:absolute;inset-inline:0}[data-content] [data-separator-wrapper]{display:none}[data-separator=metadata] [data-separator-wrapper]{background-color:var(--diffs-bg-separator);height:100%;color:var(--diffs-fg-number);white-space:nowrap;text-overflow:ellipsis;min-width:min-content;padding-inline:1ch;inset-inline:100% auto;overflow:hidden}[data-separator=line-info]{margin-block:var(--diffs-gap-block,var(--diffs-gap-fallback))}[data-separator=line-info] [data-separator-wrapper]{min-width:16px}[data-separator=line-info-basic],[data-separator=metadata]{margin-block:0}[data-separator=line-info][data-separator-first]{margin-top:0}[data-separator=line-info][data-separator-last]{margin-bottom:0}[data-expand-index] [data-separator-wrapper]{grid-template-columns:32px auto;display:grid}[data-expand-index] [data-separator-wrapper][data-separator-multi-button]{grid-template-columns:32px 32px auto}[data-expand-button],[data-separator-content]{background-color:var(--diffs-bg-separator);flex:none;align-items:center;display:flex}[data-expand-index] [data-separator-content]:hover{cursor:pointer;text-decoration:underline}[data-expand-button]{cursor:pointer;min-width:32px;color:var(--diffs-fg-number);border-right:2px solid var(--diffs-bg);flex-shrink:0;justify-content:center;align-self:stretch}[data-expand-button]:hover{color:var(--diffs-fg)}[data-expand-button][data-expand-all-button]{display:none}[data-expand-down] [data-icon]{transform:scaleY(-1)}[data-separator-content]{height:100%;color:var(--diffs-fg-number);flex:auto;justify-content:flex-start;padding:0 1ch;overflow:hidden}:is([data-separator=line-info],[data-separator=line-info-basic]) [data-separator-content]{-webkit-user-select:none;user-select:none;height:100%;overflow:clip}[data-unmodified-lines]{text-overflow:ellipsis;white-space:nowrap;flex:0 auto;min-width:0;display:block;overflow:hidden}@supports (width:1cqi){[data-unified] [data-separator=line-info] [data-separator-wrapper]{padding-inline:var(--diffs-gap-inline,var(--diffs-gap-fallback));width:100cqi}:is([data-unified] [data-separator=line-info] [data-separator-wrapper]) [data-separator-content]{border-radius:6px}[data-unified] [data-separator=line-info][data-expand-index] [data-separator-wrapper] [data-separator-content]{border-top-left-radius:unset;border-bottom-left-radius:unset}[data-gutter] [data-separator=line-info] [data-separator-wrapper]{padding-left:var(--diffs-gap-inline,var(--diffs-gap-fallback))}[data-gutter] [data-separator=line-info] [data-separator-content]{border-top-left-radius:6px;border-bottom-left-radius:6px}[data-gutter] [data-separator=line-info][data-expand-index] [data-separator-content]{border-top-left-radius:unset;border-bottom-left-radius:unset}[data-additions] [data-content] [data-separator=line-info]{background-color:var(--diffs-bg)}:is([data-additions] [data-content] [data-separator=line-info]) [data-separator-wrapper]{display:none}[data-additions] [data-gutter] [data-separator=line-info] [data-separator-wrapper]{background-color:var(--diffs-bg-separator);border-top-right-radius:6px;border-bottom-right-radius:6px;height:100%;display:block}:is([data-additions] [data-gutter] [data-separator=line-info] [data-separator-wrapper]) [data-separator-content],:is([data-additions] [data-gutter] [data-separator=line-info] [data-separator-wrapper]) [data-expand-button]{display:none}[data-overflow=scroll] [data-additions] [data-gutter] [data-separator=line-info] [data-separator-wrapper]{width:calc(100cqi - var(--diffs-gap-inline,var(--diffs-gap-fallback)))}[data-overflow=wrap] [data-additions] [data-content] [data-separator=line-info] [data-separator-wrapper]{background-color:var(--diffs-bg-separator);height:100%;margin-right:var(--diffs-gap-inline,var(--diffs-gap-fallback));border-top-right-radius:6px;border-bottom-right-radius:6px;display:block}:is([data-overflow=wrap] [data-additions] [data-content] [data-separator=line-info] [data-separator-wrapper]) [data-separator-content],:is([data-overflow=wrap] [data-additions] [data-content] [data-separator=line-info] [data-separator-wrapper]) [data-expand-button]{display:none}:is([data-separator=line-info] [data-separator-wrapper]) [data-expand-both],:is([data-separator=line-info] [data-separator-wrapper]) [data-expand-down],:is([data-separator=line-info] [data-separator-wrapper]) [data-expand-up]{border-top-left-radius:6px;border-bottom-left-radius:6px}@media (pointer:fine){[data-separator-multi-button]:is([data-separator=line-info] [data-separator-wrapper]) [data-expand-up]{border-top-left-radius:6px;border-bottom-left-radius:unset}[data-separator-multi-button]:is([data-separator=line-info] [data-separator-wrapper]) [data-expand-down]{border-bottom-left-radius:6px;border-top-left-radius:unset}}}@media (pointer:coarse){[data-separator=line-info-basic] [data-separator-wrapper][data-separator-multi-button]{grid-template-columns:34px 34px auto}:is([data-separator=line-info-basic] [data-separator-wrapper][data-separator-multi-button]) [data-separator-content]{grid-column:unset;grid-row:unset}@supports (width:1cqi){:is([data-separator=line-info] [data-separator-wrapper]) [data-expand-both],:is([data-separator=line-info] [data-separator-wrapper]) [data-expand-down],:is([data-separator=line-info] [data-separator-wrapper]) [data-expand-up],[data-separator-multi-button]:is([data-separator=line-info] [data-separator-wrapper]) [data-expand-up]{border-top-left-radius:6px;border-bottom-left-radius:6px}[data-separator-multi-button]:is([data-separator=line-info] [data-separator-wrapper]) [data-expand-down]{border-bottom-left-radius:unset;border-top-left-radius:unset}}}@media (pointer:fine){[data-separator-wrapper][data-separator-multi-button]{grid-template-rows:50% 50%;display:grid}[data-separator-wrapper][data-separator-multi-button] [data-separator-content]{grid-area:1/2/-1;min-width:min-content}[data-separator-wrapper][data-separator-multi-button] [data-expand-button]{grid-column:1}[data-separator=line-info] [data-separator-wrapper],[data-separator=line-info] [data-separator-wrapper][data-separator-multi-button]{grid-template-columns:34px auto}[data-separator=line-info-basic][data-expand-index] [data-separator-wrapper]{grid-template-columns:100% auto}:is(:is([data-separator=line-info],[data-separator=line-info-basic]) [data-separator-multi-button]) [data-expand-up]{border-bottom:1px solid var(--diffs-bg);border-right:2px solid var(--diffs-bg)}:is(:is([data-separator=line-info],[data-separator=line-info-basic]) [data-separator-multi-button]) [data-expand-down]{border-top:1px solid var(--diffs-bg);border-right:2px solid var(--diffs-bg)}}[data-additions] [data-gutter] [data-separator-wrapper],[data-additions] [data-separator=line-info-basic] [data-separator-wrapper],[data-content] [data-separator-wrapper]{display:none}[data-line-annotation]{min-height:var(--diffs-annotation-min-height,0);z-index:2}[data-merge-conflict-actions]{z-index:2}[data-separator=custom]{grid-template-columns:subgrid;display:grid}[data-line],[data-column-number],[data-no-newline]{padding-inline:1ch;position:relative}[data-indicators=classic] [data-line]{padding-inline-start:2ch}:is([data-no-newline]:is([data-indicators=classic] [data-line-type=change-addition],[data-indicators=classic] [data-line-type=change-deletion]),[data-line]:is([data-indicators=classic] [data-line-type=change-addition],[data-indicators=classic] [data-line-type=change-deletion])):before{-webkit-user-select:none;user-select:none;width:1ch;height:1lh;display:inline-block;position:absolute;top:0;left:0}:is([data-line]:is([data-indicators=classic] [data-line-type=change-addition]),[data-no-newline]:is([data-indicators=classic] [data-line-type=change-addition])):before{content:"+";color:var(--diffs-addition-base)}:is([data-line]:is([data-indicators=classic] [data-line-type=change-deletion]),[data-no-newline]:is([data-indicators=classic] [data-line-type=change-deletion])):before{content:"-";color:var(--diffs-deletion-base)}[data-column-number]:is([data-indicators=bars] [data-line-type=change-deletion],[data-indicators=bars] [data-line-type=change-addition]):before{content:"";-webkit-user-select:none;user-select:none;contain:strict;width:4px;height:100%;display:block;position:absolute;top:0;left:0}[data-column-number]:is([data-indicators=bars] [data-line-type=change-deletion]):before{background-image:linear-gradient(0deg, var(--diffs-bg-deletion) 50%, var(--diffs-deletion-base) 50%);background-repeat:repeat;background-size:2px 2px;background-size:calc(1lh/round(1lh / 2px)) calc(1lh/round(1lh / 2px))}[data-column-number]:is([data-indicators=bars] [data-line-type=change-addition]):before{background-color:var(--diffs-addition-base)}[data-overflow=wrap] [data-line],[data-overflow=wrap] [data-annotation-content]{white-space:pre-wrap;word-break:break-word}[data-overflow=scroll] [data-line]{white-space:pre;min-height:1lh}[data-column-number]{box-sizing:content-box;text-align:right;-webkit-user-select:none;user-select:none;color:var(--diffs-fg-number);padding-left:2ch}[data-line-number-content]{min-width:var(--diffs-min-number-column-width,var(--diffs-min-number-column-width-default,3ch));z-index:1;display:inline-block;position:relative}[data-disable-line-numbers] [data-gutter-buffer],[data-disable-line-numbers] [data-column-number]{min-width:4px;padding:0}:is([data-disable-line-numbers] [data-gutter-buffer],[data-disable-line-numbers] [data-column-number]):before{min-width:0}[data-disable-line-numbers] [data-line-number-content]{display:none}[data-disable-line-numbers] [data-gutter-utility-slot]{right:unset;justify-content:flex-start;left:0}[data-disable-line-numbers][data-indicators=bars] [data-gutter-utility-slot]{left:6px}[data-file][data-disable-line-numbers] [data-gutter-buffer],[data-file][data-disable-line-numbers] [data-column-number]{border-right:0;min-width:0}[data-diff-span]{-webkit-box-decoration-break:clone;box-decoration-break:clone;border-radius:3px}[data-line-type=change-addition] [data-diff-span]{background-color:var(--diffs-bg-addition-emphasis)}[data-line-type=change-deletion] [data-diff-span]{background-color:var(--diffs-bg-deletion-emphasis)}[data-merge-conflict=marker-start],[data-merge-conflict=marker-base],[data-merge-conflict=marker-separator],[data-merge-conflict=marker-end]{color:var(--diffs-fg);padding-left:1ch}[data-merge-conflict=marker-start],[data-merge-conflict=marker-end]{align-items:center;display:flex}:is([data-merge-conflict=marker-start],[data-merge-conflict=marker-end]):after{color:var(--diffs-fg-conflict-marker);font-size:.75rem;font-style:normal;line-height:1.25rem;font-family:var(--diffs-header-font-family,var(--diffs-header-font-fallback));padding-left:1ch}[data-merge-conflict=marker-start]:after{content:"(Current Change)"}[data-merge-conflict=marker-end]:after{content:"(Incoming Change)"}[data-merge-conflict-actions-content]{min-height:1.75rem;font-family:var(--diffs-header-font-family,var(--diffs-header-font-fallback));color:var(--diffs-fg);align-items:center;gap:.25rem;padding-inline:.5rem;font-size:.75rem;line-height:1.2;display:flex}[data-merge-conflict-action]{appearance:none;color:var(--diffs-fg-number);font:inherit;cursor:pointer;background:0 0;border:0;padding:0;font-style:normal}[data-merge-conflict-action]:hover{color:var(--diffs-fg)}[data-merge-conflict-action=current]:hover{color:var(--diffs-addition-base)}[data-merge-conflict-action=incoming]:hover{color:var(--diffs-modified-base)}[data-merge-conflict-action-separator]{color:var(--diffs-fg-number);opacity:.6;-webkit-user-select:none;user-select:none}[data-diffs-header=default]{background-color:var(--diffs-bg);justify-content:space-between;align-items:center;gap:var(--diffs-gap-inline,var(--diffs-gap-fallback));min-height:calc(1lh + var(--diffs-gap-block,var(--diffs-gap-fallback))*3);z-index:2;flex-direction:row;padding-inline:16px;display:flex;position:relative;top:0}[data-header-content]{align-items:center;gap:var(--diffs-gap-inline,var(--diffs-gap-fallback));white-space:nowrap;flex-direction:row;min-width:0;display:flex}[data-header-content] [data-prev-name],[data-header-content] [data-title]{text-overflow:ellipsis;white-space:nowrap;direction:rtl;min-width:0;overflow:hidden}[data-prev-name]{opacity:.7}[data-rename-icon]{fill:currentColor;flex-grow:0;flex-shrink:0}[data-diffs-header=default] [data-metadata]{white-space:nowrap;align-items:center;gap:1ch;display:flex}[data-diffs-header=default] [data-additions-count]{font-family:var(--diffs-font-family,var(--diffs-font-fallback));color:var(--diffs-addition-base)}[data-diffs-header=default] [data-deletions-count]{font-family:var(--diffs-font-family,var(--diffs-font-fallback));color:var(--diffs-deletion-base)}[data-change-icon]{fill:currentColor;flex-shrink:0}[data-change-icon=change],[data-change-icon=rename-pure],[data-change-icon=rename-changed]{color:var(--diffs-modified-base)}[data-change-icon=new]{color:var(--diffs-addition-base)}[data-change-icon=deleted]{color:var(--diffs-deletion-base)}[data-change-icon=file]{opacity:.6}[data-annotation-content]{z-index:2;isolation:isolate;align-self:flex-start;min-width:0;display:flow-root;position:relative}[data-overflow=scroll] [data-annotation-content],[data-overflow=scroll] [data-merge-conflict-actions-content]{width:var(--diffs-column-content-width,auto);left:var(--diffs-column-number-width,0);position:sticky}[data-annotation-slot]{text-wrap-mode:wrap;word-break:normal;white-space-collapse:collapse}[data-gutter-utility-slot]{touch-action:none;justify-content:flex-end;display:flex;position:absolute;top:0;bottom:0;right:0}[data-utility-button]{appearance:none;cursor:pointer;width:1lh;height:1lh;font-size:var(--diffs-font-size,13px);line-height:var(--diffs-line-height,20px);background-color:var(--diffs-modified-base);color:var(--diffs-bg);fill:currentColor;z-index:4;touch-action:none;border:none;border-radius:4px;justify-content:center;align-items:center;margin-right:calc(1ch - 1lh);padding:0;display:flex;position:relative}[data-utility-button]:before{content:"";display:block;position:absolute;inset:0 0 0 -4px}[data-decoration-bar-stack]{pointer-events:none;isolation:isolate;z-index:1;background-color:var(--diffs-decoration-bar-color,transparent);box-sizing:content-box;border-left:2px solid var(--diffs-bg);border-right:2px solid var(--diffs-bg);width:6px;position:absolute;top:0;bottom:0;right:-2px}[data-decoration-bar-depth="1"] [data-decoration-bar-stack]{background-color:color-mix(in lab, var(--diffs-bg) 20%, var(--diffs-decoration-bar-color,transparent))}[data-decoration-bar-depth="2"] [data-decoration-bar-stack]{background-color:color-mix(in lab, var(--diffs-bg) 45%, var(--diffs-decoration-bar-color,transparent))}[data-decoration-bar-depth="3"] [data-decoration-bar-stack]{background-color:color-mix(in lab, var(--diffs-bg) 65%, var(--diffs-decoration-bar-color,transparent))}[data-decoration-bar-start] [data-decoration-bar-stack]{border-top-left-radius:5px;border-top-right-radius:5px}[data-decoration-bar-end] [data-decoration-bar-stack]{z-index:3;border-bottom-right-radius:5px;border-bottom-left-radius:5px}[data-placeholder]{contain:strict}[data-error-wrapper]{padding:var(--diffs-gap-block,var(--diffs-gap-fallback)) var(--diffs-gap-inline,var(--diffs-gap-fallback));scrollbar-width:none;max-height:400px;overflow:auto}[data-error-wrapper] [data-error-message]{color:var(--diffs-deletion-base);font-size:18px;font-weight:700}[data-error-wrapper] [data-error-stack]{color:var(--diffs-fg-number)}}@layer theme,rendered,unsafe;
|
|
@layer theme {
|
|
|
|
}</style><style data-theme-css="">@layer base, theme, rendered, unsafe;
|
|
@layer rendered {
|
|
:host {
|
|
--diffs-scrollbar-gutter-measured: var(--diffs-scrollbar-gutter-fallback);
|
|
--diffs-dark:#fafafa;--diffs-dark-bg:#0a0a0a;--diffs-dark-addition-color:#07c480;--diffs-dark-deletion-color:#ff2e3f;--diffs-dark-modified-color:#009fff;--diffs-light:#0a0a0a;--diffs-light-bg:#ffffff;--diffs-light-addition-color:#18a46c;--diffs-light-deletion-color:#d52c36;--diffs-light-modified-color:#009fff;
|
|
}
|
|
}</style><div data-diffs-header="default" data-change-type="change"><div data-header-content=""><slot name="header-prefix"></slot><svg width="16" height="16" viewBox="0 0 16 16" data-change-icon="change"><use href="#diffs-icon-symbol-modified"></use></svg><div data-title=""><bdi>Dreamio/StreamCandidate.swift</bdi></div></div><div data-metadata=""><span data-deletions-count="">-1</span><span data-additions-count="">+26</span><slot name="header-metadata"></slot></div></div><pre data-diff="" data-diff-type="split" data-overflow="scroll" data-background="" data-indicators="bars" tabindex="0" style="--diffs-min-number-column-width-default:3ch;" data-dehydrated=""><code data-code="" data-container-size="" data-deletions=""><div data-gutter="" style="grid-row: span 49"><div data-separator="line-info" data-separator-first=""><div data-separator-wrapper=""><div data-separator-content=""><span data-unmodified-lines="">23 unmodified lines</span></div></div></div><div data-line-type="context" data-column-number="24" data-line-index="23,23"><span data-line-number-content="">24</span></div><div data-line-type="context" data-column-number="25" data-line-index="24,24"><span data-line-number-content="">25</span></div><div data-line-type="context" data-column-number="26" data-line-index="25,25"><span data-line-number-content="">26</span></div><div data-gutter-buffer="buffer" data-buffer-size="1" style="grid-row: span 1;min-height:calc(1 * 1lh);"></div><div data-line-type="context" data-column-number="27" data-line-index="27,27"><span data-line-number-content="">27</span></div><div data-line-type="context" data-column-number="28" data-line-index="28,28"><span data-line-number-content="">28</span></div><div data-line-type="context" data-column-number="29" data-line-index="29,29"><span data-line-number-content="">29</span></div><div data-separator="line-info"><div data-separator-wrapper=""><div data-separator-content=""><span data-unmodified-lines="">45 unmodified lines</span></div></div></div><div data-line-type="context" data-column-number="75" data-line-index="75,75"><span data-line-number-content="">75</span></div><div data-line-type="context" data-column-number="76" data-line-index="76,76"><span data-line-number-content="">76</span></div><div data-line-type="context" data-column-number="77" data-line-index="77,77"><span data-line-number-content="">77</span></div><div data-line-type="change-deletion" data-column-number="78" data-line-index="78,78"><span data-line-number-content="">78</span></div><div data-line-type="context" data-column-number="79" data-line-index="80,79"><span data-line-number-content="">79</span></div><div data-line-type="context" data-column-number="80" data-line-index="81,80"><span data-line-number-content="">80</span></div><div data-line-type="context" data-column-number="81" data-line-index="82,81"><span data-line-number-content="">81</span></div><div data-line-type="context" data-column-number="82" data-line-index="83,82"><span data-line-number-content="">82</span></div><div data-line-type="context" data-column-number="83" data-line-index="84,83"><span data-line-number-content="">83</span></div><div data-gutter-buffer="buffer" data-buffer-size="1" style="grid-row: span 1;min-height:calc(1 * 1lh);"></div><div data-line-type="context" data-column-number="84" data-line-index="86,85"><span data-line-number-content="">84</span></div><div data-line-type="context" data-column-number="85" data-line-index="87,86"><span data-line-number-content="">85</span></div><div data-line-type="context" data-column-number="86" data-line-index="88,87"><span data-line-number-content="">86</span></div><div data-line-type="context" data-column-number="87" data-line-index="89,88"><span data-line-number-content="">87</span></div><div data-gutter-buffer="buffer" data-buffer-size="23" style="grid-row: span 23;min-height:calc(23 * 1lh);"></div><div data-line-type="context" data-column-number="88" data-line-index="113,112"><span data-line-number-content="">88</span></div><div data-line-type="context" data-column-number="89" data-line-index="114,113"><span data-line-number-content="">89</span></div><div data-line-type="context" data-column-number="90" data-line-index="115,114"><span data-line-number-content="">90</span></div></div><div data-content="" style="grid-row: span 49"><div data-separator="line-info" data-separator-first=""><div data-separator-wrapper=""><div data-separator-content=""><span data-unmodified-lines="">23 unmodified lines</span></div></div></div><div data-line="24" data-alt-line="24" data-line-type="context" data-line-index="23,23"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> let</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> pageURL: URL</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">?</span></div><div data-line="25" data-alt-line="25" data-line-type="context" data-line-index="24,24"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> let</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> userAgent: </span><span style="--diffs-token-dark:#FFAB16;--diffs-token-light:#D5901C">String</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">?</span></div><div data-line="26" data-alt-line="26" data-line-type="context" data-line-index="25,25"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> let</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> referer: </span><span style="--diffs-token-dark:#FFAB16;--diffs-token-light:#D5901C">String</span></div><div data-content-buffer="" data-buffer-size="1" style="grid-row: span 1;min-height:calc(1 * 1lh)"></div><div data-line="27" data-alt-line="28" data-line-type="context" data-line-index="27,27"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> let</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> classification: StreamClassification</span></div><div data-line="28" data-alt-line="29" data-line-type="context" data-line-index="28,28"><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A">}</span></div><div data-line="29" data-alt-line="30" data-line-type="context" data-line-index="29,29">
|
|
</div><div data-separator="line-info"><div data-separator-wrapper=""><div data-separator-content=""><span data-unmodified-lines="">45 unmodified lines</span></div></div></div><div data-line="75" data-alt-line="76" data-line-type="context" data-line-index="75,75"><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> }</span></div><div data-line="76" data-alt-line="77" data-line-type="context" data-line-index="76,76">
|
|
</div><div data-line="77" data-alt-line="78" data-line-type="context" data-line-index="77,77"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> return</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> NativePlaybackRequest</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">(</span></div><div data-line="78" data-line-type="change-deletion" data-line-index="78,78"><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> playbackURL</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> candidate.</span><span data-diff-span=""><span style="--diffs-token-dark:#FFA359;--diffs-token-light:#D47628">resolverURL</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363"> ??</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> candidate.</span></span><span style="--diffs-token-dark:#FFA359;--diffs-token-light:#D47628">observedURL</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">,</span></div><div data-line="79" data-alt-line="80" data-line-type="context" data-line-index="80,79"><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> observedURL</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> candidate.</span><span style="--diffs-token-dark:#FFA359;--diffs-token-light:#D47628">observedURL</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">,</span></div><div data-line="80" data-alt-line="81" data-line-type="context" data-line-index="81,80"><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> resolverURL</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> candidate.</span><span style="--diffs-token-dark:#FFA359;--diffs-token-light:#D47628">resolverURL</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">,</span></div><div data-line="81" data-alt-line="82" data-line-type="context" data-line-index="82,81"><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> pageURL</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> candidate.</span><span style="--diffs-token-dark:#FFA359;--diffs-token-light:#D47628">pageURL</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">,</span></div><div data-line="82" data-alt-line="83" data-line-type="context" data-line-index="83,82"><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> userAgent</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> userAgent,</span></div><div data-line="83" data-alt-line="84" data-line-type="context" data-line-index="84,83"><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> referer</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> referer,</span></div><div data-content-buffer="" data-buffer-size="1" style="grid-row: span 1;min-height:calc(1 * 1lh)"></div><div data-line="84" data-alt-line="86" data-line-type="context" data-line-index="86,85"><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> classification</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> classification</span></div><div data-line="85" data-alt-line="87" data-line-type="context" data-line-index="87,86"><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363"> )</span></div><div data-line="86" data-alt-line="88" data-line-type="context" data-line-index="88,87"><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> }</span></div><div data-line="87" data-alt-line="89" data-line-type="context" data-line-index="89,88">
|
|
</div><div data-content-buffer="" data-buffer-size="23" style="grid-row: span 23;min-height:calc(23 * 1lh)"></div><div data-line="88" data-alt-line="113" data-line-type="context" data-line-index="113,112"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> static</span><span style="--diffs-token-dark:#D568EA;--diffs-token-light:#A631BE"> func</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> classify</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">(</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">candidate</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A">: StreamCandidate</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">)</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363"> -></span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> StreamClassification </span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">{</span></div><div data-line="89" data-alt-line="114" data-line-type="context" data-line-index="114,113"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> let</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> observed </span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">=</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> candidate.</span><span style="--diffs-token-dark:#FFA359;--diffs-token-light:#D47628">observedURL</span></div><div data-line="90" data-alt-line="115" data-line-type="context" data-line-index="115,114"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> let</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> resolver </span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">=</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> candidate.</span><span style="--diffs-token-dark:#FFA359;--diffs-token-light:#D47628">resolverURL</span></div></div></code><code data-code="" data-container-size="" data-additions=""><div data-gutter="" style="grid-row: span 49"><div data-separator="line-info" data-separator-first=""><div data-separator-wrapper=""><div data-separator-content=""><span data-unmodified-lines="">23 unmodified lines</span></div></div></div><div data-line-type="context" data-column-number="24" data-line-index="23,23"><span data-line-number-content="">24</span></div><div data-line-type="context" data-column-number="25" data-line-index="24,24"><span data-line-number-content="">25</span></div><div data-line-type="context" data-column-number="26" data-line-index="25,25"><span data-line-number-content="">26</span></div><div data-line-type="change-addition" data-column-number="27" data-line-index="26,26"><span data-line-number-content="">27</span></div><div data-line-type="context" data-column-number="28" data-line-index="27,27"><span data-line-number-content="">28</span></div><div data-line-type="context" data-column-number="29" data-line-index="28,28"><span data-line-number-content="">29</span></div><div data-line-type="context" data-column-number="30" data-line-index="29,29"><span data-line-number-content="">30</span></div><div data-separator="line-info"><div data-separator-wrapper=""><div data-separator-content=""><span data-unmodified-lines="">45 unmodified lines</span></div></div></div><div data-line-type="context" data-column-number="76" data-line-index="75,75"><span data-line-number-content="">76</span></div><div data-line-type="context" data-column-number="77" data-line-index="76,76"><span data-line-number-content="">77</span></div><div data-line-type="context" data-column-number="78" data-line-index="77,77"><span data-line-number-content="">78</span></div><div data-line-type="change-addition" data-column-number="79" data-line-index="79,78"><span data-line-number-content="">79</span></div><div data-line-type="context" data-column-number="80" data-line-index="80,79"><span data-line-number-content="">80</span></div><div data-line-type="context" data-column-number="81" data-line-index="81,80"><span data-line-number-content="">81</span></div><div data-line-type="context" data-column-number="82" data-line-index="82,81"><span data-line-number-content="">82</span></div><div data-line-type="context" data-column-number="83" data-line-index="83,82"><span data-line-number-content="">83</span></div><div data-line-type="context" data-column-number="84" data-line-index="84,83"><span data-line-number-content="">84</span></div><div data-line-type="change-addition" data-column-number="85" data-line-index="85,84"><span data-line-number-content="">85</span></div><div data-line-type="context" data-column-number="86" data-line-index="86,85"><span data-line-number-content="">86</span></div><div data-line-type="context" data-column-number="87" data-line-index="87,86"><span data-line-number-content="">87</span></div><div data-line-type="context" data-column-number="88" data-line-index="88,87"><span data-line-number-content="">88</span></div><div data-line-type="context" data-column-number="89" data-line-index="89,88"><span data-line-number-content="">89</span></div><div data-line-type="change-addition" data-column-number="90" data-line-index="90,89"><span data-line-number-content="">90</span></div><div data-line-type="change-addition" data-column-number="91" data-line-index="91,90"><span data-line-number-content="">91</span></div><div data-line-type="change-addition" data-column-number="92" data-line-index="92,91"><span data-line-number-content="">92</span></div><div data-line-type="change-addition" data-column-number="93" data-line-index="93,92"><span data-line-number-content="">93</span></div><div data-line-type="change-addition" data-column-number="94" data-line-index="94,93"><span data-line-number-content="">94</span></div><div data-line-type="change-addition" data-column-number="95" data-line-index="95,94"><span data-line-number-content="">95</span></div><div data-line-type="change-addition" data-column-number="96" data-line-index="96,95"><span data-line-number-content="">96</span></div><div data-line-type="change-addition" data-column-number="97" data-line-index="97,96"><span data-line-number-content="">97</span></div><div data-line-type="change-addition" data-column-number="98" data-line-index="98,97"><span data-line-number-content="">98</span></div><div data-line-type="change-addition" data-column-number="99" data-line-index="99,98"><span data-line-number-content="">99</span></div><div data-line-type="change-addition" data-column-number="100" data-line-index="100,99"><span data-line-number-content="">100</span></div><div data-line-type="change-addition" data-column-number="101" data-line-index="101,100"><span data-line-number-content="">101</span></div><div data-line-type="change-addition" data-column-number="102" data-line-index="102,101"><span data-line-number-content="">102</span></div><div data-line-type="change-addition" data-column-number="103" data-line-index="103,102"><span data-line-number-content="">103</span></div><div data-line-type="change-addition" data-column-number="104" data-line-index="104,103"><span data-line-number-content="">104</span></div><div data-line-type="change-addition" data-column-number="105" data-line-index="105,104"><span data-line-number-content="">105</span></div><div data-line-type="change-addition" data-column-number="106" data-line-index="106,105"><span data-line-number-content="">106</span></div><div data-line-type="change-addition" data-column-number="107" data-line-index="107,106"><span data-line-number-content="">107</span></div><div data-line-type="change-addition" data-column-number="108" data-line-index="108,107"><span data-line-number-content="">108</span></div><div data-line-type="change-addition" data-column-number="109" data-line-index="109,108"><span data-line-number-content="">109</span></div><div data-line-type="change-addition" data-column-number="110" data-line-index="110,109"><span data-line-number-content="">110</span></div><div data-line-type="change-addition" data-column-number="111" data-line-index="111,110"><span data-line-number-content="">111</span></div><div data-line-type="change-addition" data-column-number="112" data-line-index="112,111"><span data-line-number-content="">112</span></div><div data-line-type="context" data-column-number="113" data-line-index="113,112"><span data-line-number-content="">113</span></div><div data-line-type="context" data-column-number="114" data-line-index="114,113"><span data-line-number-content="">114</span></div><div data-line-type="context" data-column-number="115" data-line-index="115,114"><span data-line-number-content="">115</span></div></div><div data-content="" style="grid-row: span 49"><div data-separator="line-info" data-separator-first=""><div data-separator-wrapper=""><div data-separator-content=""><span data-unmodified-lines="">23 unmodified lines</span></div></div></div><div data-line="24" data-alt-line="24" data-line-type="context" data-line-index="23,23"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> let</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> pageURL: URL</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">?</span></div><div data-line="25" data-alt-line="25" data-line-type="context" data-line-index="24,24"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> let</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> userAgent: </span><span style="--diffs-token-dark:#FFAB16;--diffs-token-light:#D5901C">String</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">?</span></div><div data-line="26" data-alt-line="26" data-line-type="context" data-line-index="25,25"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> let</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> referer: </span><span style="--diffs-token-dark:#FFAB16;--diffs-token-light:#D5901C">String</span></div><div data-line="27" data-line-type="change-addition" data-line-index="26,26"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> let</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> headers: </span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">[</span><span style="--diffs-token-dark:#FFAB16;--diffs-token-light:#D5901C">String</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#FFAB16;--diffs-token-light:#D5901C"> String</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">]</span></div><div data-line="28" data-alt-line="27" data-line-type="context" data-line-index="27,27"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> let</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> classification: StreamClassification</span></div><div data-line="29" data-alt-line="28" data-line-type="context" data-line-index="28,28"><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A">}</span></div><div data-line="30" data-alt-line="29" data-line-type="context" data-line-index="29,29">
|
|
</div><div data-separator="line-info"><div data-separator-wrapper=""><div data-separator-content=""><span data-unmodified-lines="">45 unmodified lines</span></div></div></div><div data-line="76" data-alt-line="75" data-line-type="context" data-line-index="75,75"><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> }</span></div><div data-line="77" data-alt-line="76" data-line-type="context" data-line-index="76,76">
|
|
</div><div data-line="78" data-alt-line="77" data-line-type="context" data-line-index="77,77"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> return</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> NativePlaybackRequest</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">(</span></div><div data-line="79" data-line-type="change-addition" data-line-index="79,78"><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> playbackURL</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> candidate.</span><span style="--diffs-token-dark:#FFA359;--diffs-token-light:#D47628">observedURL</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">,</span></div><div data-line="80" data-alt-line="79" data-line-type="context" data-line-index="80,79"><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> observedURL</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> candidate.</span><span style="--diffs-token-dark:#FFA359;--diffs-token-light:#D47628">observedURL</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">,</span></div><div data-line="81" data-alt-line="80" data-line-type="context" data-line-index="81,80"><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> resolverURL</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> candidate.</span><span style="--diffs-token-dark:#FFA359;--diffs-token-light:#D47628">resolverURL</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">,</span></div><div data-line="82" data-alt-line="81" data-line-type="context" data-line-index="82,81"><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> pageURL</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> candidate.</span><span style="--diffs-token-dark:#FFA359;--diffs-token-light:#D47628">pageURL</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">,</span></div><div data-line="83" data-alt-line="82" data-line-type="context" data-line-index="83,82"><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> userAgent</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> userAgent,</span></div><div data-line="84" data-alt-line="83" data-line-type="context" data-line-index="84,83"><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> referer</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> referer,</span></div><div data-line="85" data-line-type="change-addition" data-line-index="85,84"><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> headers</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#FFAB16;--diffs-token-light:#D5901C"> Self</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">.defaultHeaders</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">(</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">userAgent</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> userAgent</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">)</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">,</span></div><div data-line="86" data-alt-line="84" data-line-type="context" data-line-index="86,85"><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> classification</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> classification</span></div><div data-line="87" data-alt-line="85" data-line-type="context" data-line-index="87,86"><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363"> )</span></div><div data-line="88" data-alt-line="86" data-line-type="context" data-line-index="88,87"><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> }</span></div><div data-line="89" data-alt-line="87" data-line-type="context" data-line-index="89,88">
|
|
</div><div data-line="90" data-line-type="change-addition" data-line-index="90,89"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> static</span><span style="--diffs-token-dark:#D568EA;--diffs-token-light:#A631BE"> func</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> defaultHeaders</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">(</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">userAgent</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A">: </span><span style="--diffs-token-dark:#FFAB16;--diffs-token-light:#D5901C">String</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">?)</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363"> -></span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363"> [</span><span style="--diffs-token-dark:#FFAB16;--diffs-token-light:#D5901C">String</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#FFAB16;--diffs-token-light:#D5901C"> String</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">]</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363"> {</span></div><div data-line="91" data-line-type="change-addition" data-line-index="91,90"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> var</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> headers </span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">=</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> [</span><span style="--diffs-token-dark:#5ECC71;--diffs-token-light:#199F43">"Referer"</span><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61">:</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> referer]</span></div><div data-line="92" data-line-type="change-addition" data-line-index="92,91"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> if</span><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> let</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> userAgent, </span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">!</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A">userAgent.isEmpty </span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">{</span></div><div data-line="93" data-line-type="change-addition" data-line-index="93,92"><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> headers</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">[</span><span style="--diffs-token-dark:#5ECC71;--diffs-token-light:#199F43">"User-Agent"</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">]</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363"> =</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> userAgent</span></div><div data-line="94" data-line-type="change-addition" data-line-index="94,93"><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363"> }</span></div><div data-line="95" data-line-type="change-addition" data-line-index="95,94"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> return</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> headers</span></div><div data-line="96" data-line-type="change-addition" data-line-index="96,95"><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363"> }</span></div><div data-line="97" data-line-type="change-addition" data-line-index="97,96">
|
|
</div><div data-line="98" data-line-type="change-addition" data-line-index="98,97"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> static</span><span style="--diffs-token-dark:#D568EA;--diffs-token-light:#A631BE"> func</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> isDirectPlayableFileURL</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">(</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">_</span><span style="--diffs-token-dark:#A3A3A3;--diffs-token-light:#636363"> url</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A">: URL</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">)</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363"> -></span><span style="--diffs-token-dark:#FFAB16;--diffs-token-light:#D5901C"> Bool</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363"> {</span></div><div data-line="99" data-line-type="change-addition" data-line-index="99,98"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> let</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> container </span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">=</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> containerGuess</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">(</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">for</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> url, resolverURL</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#68CDF2;--diffs-token-light:#1CA1C7"> nil</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">)</span></div><div data-line="100" data-line-type="change-addition" data-line-index="100,99"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> return</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363"> [</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A">.</span><span style="--diffs-token-dark:#FFA359;--diffs-token-light:#D47628">mp4</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A">, .</span><span style="--diffs-token-dark:#FFA359;--diffs-token-light:#D47628">mkv</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A">, .</span><span style="--diffs-token-dark:#FFA359;--diffs-token-light:#D47628">avi</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A">, .</span><span style="--diffs-token-dark:#FFA359;--diffs-token-light:#D47628">webm</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">]</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A">.</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">contains</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">(</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">container</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">)</span></div><div data-line="101" data-line-type="change-addition" data-line-index="101,100"><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363"> }</span></div><div data-line="102" data-line-type="change-addition" data-line-index="102,101">
|
|
</div><div data-line="103" data-line-type="change-addition" data-line-index="103,102"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> static</span><span style="--diffs-token-dark:#D568EA;--diffs-token-light:#A631BE"> func</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> isWebKitCompatibleURL</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">(</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">_</span><span style="--diffs-token-dark:#A3A3A3;--diffs-token-light:#636363"> url</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A">: URL</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">)</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363"> -></span><span style="--diffs-token-dark:#FFAB16;--diffs-token-light:#D5901C"> Bool</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363"> {</span></div><div data-line="104" data-line-type="change-addition" data-line-index="104,103"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> let</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> container </span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">=</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> containerGuess</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">(</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">for</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> url, resolverURL</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#68CDF2;--diffs-token-light:#1CA1C7"> nil</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">)</span></div><div data-line="105" data-line-type="change-addition" data-line-index="105,104"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> return</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> container </span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">==</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> .</span><span style="--diffs-token-dark:#FFA359;--diffs-token-light:#D47628">hls</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363"> ||</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> container </span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">==</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> .</span><span style="--diffs-token-dark:#FFA359;--diffs-token-light:#D47628">mp4</span></div><div data-line="106" data-line-type="change-addition" data-line-index="106,105"><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363"> }</span></div><div data-line="107" data-line-type="change-addition" data-line-index="107,106">
|
|
</div><div data-line="108" data-line-type="change-addition" data-line-index="108,107"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> static</span><span style="--diffs-token-dark:#D568EA;--diffs-token-light:#A631BE"> func</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> isKnownResolverURL</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">(</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">_</span><span style="--diffs-token-dark:#A3A3A3;--diffs-token-light:#636363"> url</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A">: URL</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">)</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363"> -></span><span style="--diffs-token-dark:#FFAB16;--diffs-token-light:#D5901C"> Bool</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363"> {</span></div><div data-line="109" data-line-type="change-addition" data-line-index="109,108"><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> matches</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">(</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">url, host</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#5ECC71;--diffs-token-light:#199F43"> "addon.debridio.com"</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">, pathPrefix</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#5ECC71;--diffs-token-light:#199F43"> "/play/"</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">)</span></div><div data-line="110" data-line-type="change-addition" data-line-index="110,109"><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363"> ||</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> matches</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">(</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">url, host</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#5ECC71;--diffs-token-light:#199F43"> "torrentio.strem.fun"</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">, pathPrefix</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">:</span><span style="--diffs-token-dark:#5ECC71;--diffs-token-light:#199F43"> "/resolve/"</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">)</span></div><div data-line="111" data-line-type="change-addition" data-line-index="111,110"><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363"> }</span></div><div data-line="112" data-line-type="change-addition" data-line-index="112,111">
|
|
</div><div data-line="113" data-alt-line="88" data-line-type="context" data-line-index="113,112"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> static</span><span style="--diffs-token-dark:#D568EA;--diffs-token-light:#A631BE"> func</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF"> classify</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">(</span><span style="--diffs-token-dark:#9D6AFB;--diffs-token-light:#693ACF">candidate</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A">: StreamCandidate</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">)</span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363"> -></span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> StreamClassification </span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">{</span></div><div data-line="114" data-alt-line="89" data-line-type="context" data-line-index="114,113"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> let</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> observed </span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">=</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> candidate.</span><span style="--diffs-token-dark:#FFA359;--diffs-token-light:#D47628">observedURL</span></div><div data-line="115" data-alt-line="90" data-line-type="context" data-line-index="115,114"><span style="--diffs-token-dark:#FF678D;--diffs-token-light:#D32A61"> let</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> resolver </span><span style="--diffs-token-dark:#636363;--diffs-token-light:#636363">=</span><span style="--diffs-token-dark:#FAFAFA;--diffs-token-light:#0A0A0A"> candidate.</span><span style="--diffs-token-dark:#FFA359;--diffs-token-light:#D47628">resolverURL</span></div></div></code></pre></div>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Expected Impact for End-Users</h2>
|
|
<p>Users still pick streams inside Stremio Web. Direct MKV, AVI, WebM, and known debrid resolver selections should now open the native player with a final playable file URL when one can be resolved. When resolution or startup fails, Dreamio shows a visible failure state and stays usable.</p>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Validation</h2>
|
|
<ul>
|
|
<li>Ran <code>swiftc Dreamio/StreamCandidate.swift Dreamio/StreamResolver.swift Tests/StreamResolverTests.swift -o /tmp/dreamio-stream-tests && /tmp/dreamio-stream-tests</code>: passed.</li>
|
|
<li>Ran <code>swiftc -typecheck Dreamio/StreamCandidate.swift Dreamio/StreamResolver.swift</code>: passed.</li>
|
|
<li>Ran <code>git diff --check</code>: passed.</li>
|
|
<li><code>pod install</code> could not be run because CocoaPods is not installed in this environment.</li>
|
|
<li><code>xcodebuild</code> could not be run because the active developer directory is Command Line Tools, not full Xcode.</li>
|
|
</ul>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Issues, Limitations, and Mitigations</h2>
|
|
<div class="callout">Manual real-device validation is still required for the South Park MKV-style stream and any live Debridio or Torrentio resolver behavior.</div>
|
|
<ul>
|
|
<li>Expired or revoked debrid URLs can still fail after successful resolution. The failure should now be visible and recoverable.</li>
|
|
<li>Resolver parsing covers common Stremio stream fields and headers, but unusual addon response shapes may need another field mapping.</li>
|
|
<li>MobileVLCKit codec limitations remain possible even when Dreamio supplies the correct URL.</li>
|
|
</ul>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Follow-up Work</h2>
|
|
<ul>
|
|
<li>Run <code>pod install</code> and build <code>Dreamio.xcworkspace</code> on a machine with CocoaPods and full Xcode.</li>
|
|
<li>Validate a real Debridio or Torrentio MKV selection on device and confirm logs show <code>[DreamioStreamResolver]</code> with a final direct URL.</li>
|
|
<li>Add mappings for any addon-specific stream fields discovered during device testing.</li>
|
|
</ul>
|
|
</section>
|
|
</main>
|
|
</body>
|
|
</html> |