SOURCE / PINNED RELEASE
Made of little things.
Packaged Loader Evidence
- Release
- a08adc548a9f…
- Author-recorded commit
- Not provided
- License
- Check the original source
The hash-verified playable HTML, which may contain bundled or minified code. This view does not execute it.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Packaged Loader Evidence</title>
<meta name="description" content="Production evidence fixture for packaged resource loading." />
<script type="module" crossorigin>(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const e of document.querySelectorAll('link[rel="modulepreload"]'))s(e);new MutationObserver(e=>{for(const t of e)if(t.type==="childList")for(const a of t.addedNodes)a.tagName==="LINK"&&a.rel==="modulepreload"&&s(a)}).observe(document,{childList:!0,subtree:!0});function n(e){const t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin==="use-credentials"?t.credentials="include":e.crossOrigin==="anonymous"?t.credentials="omit":t.credentials="same-origin",t}function s(e){if(e.ep)return;e.ep=!0;const t=n(e);fetch(e.href,t)}})();async function o(){const i=await Promise.all([window.__nappletPrivateResourceLoader.response("assets/resource-01.bin"),window.__nappletPrivateResourceLoader.response("assets/resource-02.bin"),window.__nappletPrivateResourceLoader.response("assets/resource-03.bin"),window.__nappletPrivateResourceLoader.response("assets/resource-04.bin"),window.__nappletPrivateResourceLoader.response("assets/resource-05.bin"),window.__nappletPrivateResourceLoader.response("assets/resource-06.bin"),window.__nappletPrivateResourceLoader.response("assets/resource-07.bin"),window.__nappletPrivateResourceLoader.response("assets/resource-08.bin"),window.__nappletPrivateResourceLoader.response("assets/resource-09.bin"),window.__nappletPrivateResourceLoader.response("assets/resource-10.bin")]),r=await Promise.all(i.map(async n=>{const s=new Uint8Array(await n.arrayBuffer());return{bytes:s.byteLength,marker:s[0]}}));requestAnimationFrame(()=>{document.open(),document.write(`<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Packaged application ready</title><style>body{margin:0;min-height:100vh;display:grid;place-items:center;background:#f5f7f2;color:#16211c;font:16px/1.5 system-ui,sans-serif}.ready{width:min(760px,calc(100% - 48px));padding:32px;border:1px solid #d6dfd7;border-radius:30px;background:#fff;box-shadow:0 28px 70px rgba(11,22,16,.14)}h1{margin:0;font-size:42px;letter-spacing:-.04em}.ready p{margin:12px 0 0;color:#5a6761}</style></head><body><main id="production-app-ready" class="ready"><h1>Packaged application ready</h1><p id="production-resource-summary">${r.length} verified resources opened in original order.</p></main></body></html>`),document.close()})}o();
</script>
<style data-napplet-private-loader>:root {
color-scheme: light dark;
--napplet-loader-canvas: #f5f7f2;
--napplet-loader-panel: #ffffff;
--napplet-loader-panel-strong: #eef3ed;
--napplet-loader-text: #16211c;
--napplet-loader-muted: #5a6761;
--napplet-loader-border: #d6dfd7;
--napplet-loader-accent: #2f6f58;
--napplet-loader-accent-ink: #ffffff;
--napplet-loader-error: #b42318;
--napplet-loader-error-soft: #fce8e6;
}
.napplet-loader, .napplet-loader * { box-sizing: border-box; }
.napplet-loader {
position: fixed;
inset: 0;
z-index: 2147483647;
min-width: 0;
min-height: 100dvh;
display: grid;
place-items: center;
padding: clamp(16px, 4vw, 32px);
overflow: auto;
background: var(--napplet-loader-canvas);
color: var(--napplet-loader-text);
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
.napplet-loader-card {
position: relative;
width: min(760px, 100%);
padding: clamp(22px, 4vw, 32px);
overflow: hidden;
border: 1px solid var(--napplet-loader-border);
border-radius: 30px;
background: var(--napplet-loader-panel);
box-shadow: 0 28px 70px rgba(11, 22, 16, 0.14);
}
.napplet-loader-card::after {
content: "";
position: absolute;
inset: 10px;
border: 1px solid rgba(118, 139, 128, 0.14);
border-radius: 22px;
pointer-events: none;
}
.napplet-loader-eyebrow {
display: inline-flex;
align-items: center;
min-height: 28px;
margin: 0;
padding: 0 12px;
border: 1px solid var(--napplet-loader-border);
border-radius: 999px;
background: var(--napplet-loader-panel-strong);
color: var(--napplet-loader-muted);
font-size: 11px;
font-weight: 700;
letter-spacing: 0.14em;
text-transform: uppercase;
}
.napplet-loader-eyebrow::before {
content: "";
width: 8px;
height: 8px;
margin-right: 8px;
border-radius: 50%;
background: var(--napplet-loader-accent);
}
.napplet-loader h1 {
margin: 16px 0 0;
color: var(--napplet-loader-text);
font-size: clamp(28px, 6vw, 42px);
line-height: 1.04;
letter-spacing: -0.04em;
}
.napplet-loader-status {
margin: 12px 0 0;
color: var(--napplet-loader-muted);
font-size: 16px;
line-height: 1.55;
font-variant-numeric: tabular-nums;
}
.napplet-loader-progress-panel {
position: relative;
margin-top: 22px;
padding: 18px;
border: 1px solid var(--napplet-loader-border);
border-radius: 22px;
background: var(--napplet-loader-panel-strong);
}
.napplet-loader-progress-panel[hidden] { display: none; }
.napplet-loader-progress-panel::before {
content: "";
position: absolute;
z-index: 1;
top: 19px;
left: 19px;
width: 14%;
height: 12px;
border-radius: 999px;
background: var(--napplet-loader-accent);
pointer-events: none;
animation: napplet-loader-activity 1.15s linear infinite alternate;
}
.napplet-loader-progress {
position: relative;
display: block;
width: 100%;
height: 14px;
margin: 0;
overflow: hidden;
appearance: none;
-webkit-appearance: none;
border: 1px solid var(--napplet-loader-border);
border-radius: 999px;
background: var(--napplet-loader-panel);
color: var(--napplet-loader-accent);
accent-color: var(--napplet-loader-accent);
}
.napplet-loader-progress[hidden] { display: none; }
.napplet-loader-progress::-webkit-progress-bar {
border-radius: inherit;
background: var(--napplet-loader-panel);
}
.napplet-loader-progress:not([value])::-webkit-progress-value {
border-radius: inherit;
background: transparent;
}
.napplet-loader-progress:not([value])::-moz-progress-bar {
border-radius: inherit;
background: transparent;
}
.napplet-loader-helper {
display: flex;
align-items: center;
min-height: 22px;
margin: 10px 0 0;
color: var(--napplet-loader-muted);
font-size: 13px;
line-height: 1.45;
}
.napplet-loader-helper::before {
content: "";
width: 10px;
height: 10px;
margin-right: 10px;
flex: none;
border-radius: 50%;
background: var(--napplet-loader-accent);
}
.napplet-loader-resource-panel {
margin: 20px 0 0;
padding: 14px 16px;
border: 1px solid var(--napplet-loader-error);
border-radius: 16px;
background: var(--napplet-loader-error-soft);
color: var(--napplet-loader-error);
font-size: 14px;
line-height: 1.5;
}
.napplet-loader-resource-panel[hidden] { display: none; }
.napplet-loader-resource-panel strong { display: block; }
.napplet-loader-resource-panel p {
margin: 6px 0 0;
overflow-wrap: anywhere;
color: var(--napplet-loader-text);
}
.napplet-loader-actions {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-top: 18px;
}
.napplet-loader-actions[hidden] { display: none; }
.napplet-loader button {
min-width: 88px;
min-height: 44px;
padding: 0 18px;
border: 1px solid var(--napplet-loader-border);
border-radius: 14px;
background: var(--napplet-loader-panel);
color: var(--napplet-loader-text);
font: inherit;
font-weight: 700;
cursor: pointer;
transition: transform 120ms ease, border-color 120ms ease, background-color 120ms ease, box-shadow 120ms ease;
}
.napplet-loader button[hidden] { display: none; }
.napplet-loader button:hover { transform: translateY(-1px); }
.napplet-loader button:active { transform: translateY(0) scale(0.98); }
.napplet-loader button:focus-visible {
outline: 3px solid var(--napplet-loader-accent);
outline-offset: 3px;
box-shadow: 0 0 0 2px var(--napplet-loader-panel);
}
.napplet-loader .napplet-loader-primary {
border-color: var(--napplet-loader-accent);
background: var(--napplet-loader-accent);
color: var(--napplet-loader-accent-ink);
}
@keyframes napplet-loader-activity {
from { transform: translateX(0); }
to { transform: translateX(600%); }
}
@media (prefers-color-scheme: dark) {
:root {
--napplet-loader-canvas: #0f1412;
--napplet-loader-panel: #171d1a;
--napplet-loader-panel-strong: #1d241f;
--napplet-loader-text: #f1f5f2;
--napplet-loader-muted: #a8b6af;
--napplet-loader-border: #3d4842;
--napplet-loader-accent: #70d6aa;
--napplet-loader-accent-ink: #0f1412;
--napplet-loader-error: #ff8b82;
--napplet-loader-error-soft: #361916;
}
.napplet-loader-card { box-shadow: 0 28px 70px rgba(0, 0, 0, 0.38); }
}
@media (prefers-reduced-motion: reduce) {
.napplet-loader-progress-panel::before {
width: 28%;
animation: none;
transform: translateX(0);
}
.napplet-loader button { transition-duration: 0ms; }
}
@media (max-width: 640px) {
.napplet-loader-card { border-radius: 22px; }
.napplet-loader-actions, .napplet-loader button { width: 100%; }
}</style><script type="application/json" data-napplet-private-resource-table>[{"source":"assets/resource-01.bin","uri":"blossom:sha256:2a5f3e710787fef2cab50c7f38ea6f8ed9d16b500e75e6855a7bf79f2dd5dcff","sha256":"2a5f3e710787fef2cab50c7f38ea6f8ed9d16b500e75e6855a7bf79f2dd5dcff","bytes":9437184,"mime":"application/octet-stream"},{"source":"assets/resource-02.bin","uri":"blossom:sha256:133519935dff60330e25fb2b96c3526f0a00d116a7abe80d28611c5b42f5b35a","sha256":"133519935dff60330e25fb2b96c3526f0a00d116a7abe80d28611c5b42f5b35a","bytes":9437184,"mime":"application/octet-stream"},{"source":"assets/resource-03.bin","uri":"blossom:sha256:4c81a80c532327a49f423a7d27bcfeacea9e3d36e3b803d0fdff1cb2267492cc","sha256":"4c81a80c532327a49f423a7d27bcfeacea9e3d36e3b803d0fdff1cb2267492cc","bytes":8388608,"mime":"application/octet-stream"},{"source":"assets/resource-04.bin","uri":"blossom:sha256:3df06c1fd8db4c6b62c79a22c2a1fa03b14df29c07095e6f623389626263ded5","sha256":"3df06c1fd8db4c6b62c79a22c2a1fa03b14df29c07095e6f623389626263ded5","bytes":8388608,"mime":"application/octet-stream"},{"source":"assets/resource-05.bin","uri":"blossom:sha256:05e2c5e3dc114de65c2df4031549658b8126f79923850d381bdbe9ed54c2909f","sha256":"05e2c5e3dc114de65c2df4031549658b8126f79923850d381bdbe9ed54c2909f","bytes":8388608,"mime":"application/octet-stream"},{"source":"assets/resource-06.bin","uri":"blossom:sha256:bb144adff328c62bbf1ffc3d589974cfdd0a2037ff626471ce772b4c644f6198","sha256":"bb144adff328c62bbf1ffc3d589974cfdd0a2037ff626471ce772b4c644f6198","bytes":8388608,"mime":"application/octet-stream"},{"source":"assets/resource-07.bin","uri":"blossom:sha256:3115e26a0b2a1e0cf33556eff76998c6bd0be904eecce5a672fa8ae1f6994645","sha256":"3115e26a0b2a1e0cf33556eff76998c6bd0be904eecce5a672fa8ae1f6994645","bytes":7340032,"mime":"application/octet-stream"},{"source":"assets/resource-08.bin","uri":"blossom:sha256:d7307f8d35985354f138b4b4d99fd89a8bde08d9ffbb9c6c37df08a2aed60db7","sha256":"d7307f8d35985354f138b4b4d99fd89a8bde08d9ffbb9c6c37df08a2aed60db7","bytes":7340032,"mime":"application/octet-stream"},{"source":"assets/resource-09.bin","uri":"blossom:sha256:25e2acf130a6f9bf7419ae12a11ff5680cfd69696353d82559244d09645ee5e1","sha256":"25e2acf130a6f9bf7419ae12a11ff5680cfd69696353d82559244d09645ee5e1","bytes":7340032,"mime":"application/octet-stream"},{"source":"assets/resource-10.bin","uri":"blossom:sha256:ebb47b5037c48d63e2edf16169c771529721662474cfdf774add15cd76d7b7a0","sha256":"ebb47b5037c48d63e2edf16169c771529721662474cfdf774add15cd76d7b7a0","bytes":7340032,"mime":"application/octet-stream"}]</script><script>(() => {
const table = new Map([{"source":"assets/resource-01.bin","uri":"blossom:sha256:2a5f3e710787fef2cab50c7f38ea6f8ed9d16b500e75e6855a7bf79f2dd5dcff","sha256":"2a5f3e710787fef2cab50c7f38ea6f8ed9d16b500e75e6855a7bf79f2dd5dcff","bytes":9437184,"mime":"application/octet-stream"},{"source":"assets/resource-02.bin","uri":"blossom:sha256:133519935dff60330e25fb2b96c3526f0a00d116a7abe80d28611c5b42f5b35a","sha256":"133519935dff60330e25fb2b96c3526f0a00d116a7abe80d28611c5b42f5b35a","bytes":9437184,"mime":"application/octet-stream"},{"source":"assets/resource-03.bin","uri":"blossom:sha256:4c81a80c532327a49f423a7d27bcfeacea9e3d36e3b803d0fdff1cb2267492cc","sha256":"4c81a80c532327a49f423a7d27bcfeacea9e3d36e3b803d0fdff1cb2267492cc","bytes":8388608,"mime":"application/octet-stream"},{"source":"assets/resource-04.bin","uri":"blossom:sha256:3df06c1fd8db4c6b62c79a22c2a1fa03b14df29c07095e6f623389626263ded5","sha256":"3df06c1fd8db4c6b62c79a22c2a1fa03b14df29c07095e6f623389626263ded5","bytes":8388608,"mime":"application/octet-stream"},{"source":"assets/resource-05.bin","uri":"blossom:sha256:05e2c5e3dc114de65c2df4031549658b8126f79923850d381bdbe9ed54c2909f","sha256":"05e2c5e3dc114de65c2df4031549658b8126f79923850d381bdbe9ed54c2909f","bytes":8388608,"mime":"application/octet-stream"},{"source":"assets/resource-06.bin","uri":"blossom:sha256:bb144adff328c62bbf1ffc3d589974cfdd0a2037ff626471ce772b4c644f6198","sha256":"bb144adff328c62bbf1ffc3d589974cfdd0a2037ff626471ce772b4c644f6198","bytes":8388608,"mime":"application/octet-stream"},{"source":"assets/resource-07.bin","uri":"blossom:sha256:3115e26a0b2a1e0cf33556eff76998c6bd0be904eecce5a672fa8ae1f6994645","sha256":"3115e26a0b2a1e0cf33556eff76998c6bd0be904eecce5a672fa8ae1f6994645","bytes":7340032,"mime":"application/octet-stream"},{"source":"assets/resource-08.bin","uri":"blossom:sha256:d7307f8d35985354f138b4b4d99fd89a8bde08d9ffbb9c6c37df08a2aed60db7","sha256":"d7307f8d35985354f138b4b4d99fd89a8bde08d9ffbb9c6c37df08a2aed60db7","bytes":7340032,"mime":"application/octet-stream"},{"source":"assets/resource-09.bin","uri":"blossom:sha256:25e2acf130a6f9bf7419ae12a11ff5680cfd69696353d82559244d09645ee5e1","sha256":"25e2acf130a6f9bf7419ae12a11ff5680cfd69696353d82559244d09645ee5e1","bytes":7340032,"mime":"application/octet-stream"},{"source":"assets/resource-10.bin","uri":"blossom:sha256:ebb47b5037c48d63e2edf16169c771529721662474cfdf774add15cd76d7b7a0","sha256":"ebb47b5037c48d63e2edf16169c771529721662474cfdf774add15cd76d7b7a0","bytes":7340032,"mime":"application/octet-stream"}].map((entry) => [entry.source, entry]));
const cache = new Map();
const urls = new Map();
const pending = new Map();
const failures = new Map();
const attempts = new Set();
const requested = new Set();
const verifiedSources = new Set();
const digestWaiters = [];
let liveBytes = 0;
let digestActive = 0;
let cohortClosed = false;
let cohortFrameScheduled = false;
let lastFailureSource;
let controlsInstalled = false;
const MAX_ASSET_BYTES = 10485760;
const MAX_LIVE_BYTES = 52428800;
const MAX_BATCH_SIZE = 8;
const MAX_CONCURRENT_DIGESTS = 2;
function sanitizeScreenResource(source) { return source.replace(/[\u0000-\u001f\u007f-\u009f]/g, '�'); }
function applyLoaderScreenState(state) {
const root = document.getElementById('napplet-loader');
if (!root) return;
const title = document.getElementById('napplet-loader-title');
const status = document.getElementById('napplet-loader-status');
const progressPanel = document.getElementById('napplet-loader-progress-panel');
const progress = document.getElementById('napplet-loader-progress');
const resourcePanel = document.getElementById('napplet-loader-resource-panel');
const resourceName = document.getElementById('napplet-loader-resource');
const actions = document.getElementById('napplet-loader-actions');
const retryButton = document.getElementById('napplet-loader-retry');
const cancelButton = document.getElementById('napplet-loader-cancel');
const isError = state.phase === 'error' || state.phase === 'cancelled';
root.setAttribute('aria-busy', String(state.active));
root.setAttribute('data-state', state.phase);
if (title) title.textContent = state.phase === 'success' ? 'Resources ready' : state.phase === 'error' ? 'Resource loading failed' : state.phase === 'cancelled' ? 'Loading cancelled' : state.phase === 'active' && state.cohortClosed && state.completed >= 3 ? 'Loading resources ' + state.completed + ' of ' + state.total : state.phase === 'active' ? 'Loading packaged resources' : 'Preparing packaged application';
if (status) status.textContent = state.phase === 'success' ? 'Resources ready. Opening application…' : state.phase === 'error' ? 'A packaged resource could not be loaded safely.' : state.phase === 'cancelled' ? 'Loading cancelled.' : state.phase === 'active' && state.cohortClosed && state.total > 0 ? state.completed >= 3 ? state.completed + ' of ' + state.total + ' resources ready.' : 'Loading resources ' + state.completed + ' of ' + state.total + '.' : state.phase === 'active' ? 'Loading packaged resources.' : 'Getting everything ready.';
if (progressPanel) progressPanel.hidden = !state.active;
if (progress) { progress.hidden = !state.active; progress.removeAttribute('value'); }
if (resourcePanel) resourcePanel.hidden = !isError;
if (resourceName) resourceName.textContent = isError && state.source ? 'Resource ' + sanitizeScreenResource(state.source) + ' could not be loaded safely. Retry only this resource.' : '';
if (retryButton) retryButton.hidden = !isError;
if (cancelButton) cancelButton.hidden = !state.active || isError;
if (actions) actions.hidden = !isError && !state.active;
if (isError && retryButton) retryButton.focus();
}
function resource() {
if (!window.napplet || !window.napplet.resource) throw new Error('window.napplet.resource is unavailable; this optimized artifact requires the existing resource capability');
return window.napplet.resource;
}
function resourceBytes(uri, signal) { resource(); return window.napplet.resource.bytes(uri, { signal: signal }); }
function resourceBytesMany(requests, signal) { resource(); return window.napplet.resource.bytesMany(requests, { signal: signal }); }
function entryFor(source) {
const entry = table.get(source);
if (!entry || !/^blossom:sha256:[a-f0-9]{64}$/.test(entry.uri) || !/^[a-f0-9]{64}$/.test(entry.sha256) || entry.uri !== 'blossom:sha256:' + entry.sha256 || !Number.isSafeInteger(entry.bytes) || entry.bytes < 0 || entry.bytes > MAX_ASSET_BYTES) throw new Error('invalid optimized resource mapping: ' + source);
return entry;
}
function loaderState() {
const active = attempts.size > 0;
const failed = lastFailureSource ? failures.get(lastFailureSource) : undefined;
let completed = 0;
for (const source of requested) if (verifiedSources.has(source)) completed += 1;
let phase = failed ? failed.cancelled ? 'cancelled' : 'error' : active || requested.size > 0 ? 'active' : 'initial';
if (!failed && !active && cohortClosed && requested.size > 0 && completed === requested.size) phase = 'success';
return { phase: phase, active: active, cohortClosed: cohortClosed, completed: completed, total: requested.size, source: failed ? lastFailureSource : undefined };
}
function installControls() {
if (controlsInstalled) return;
const retryButton = document.getElementById('napplet-loader-retry');
const cancelButton = document.getElementById('napplet-loader-cancel');
if (!retryButton || !cancelButton) return;
retryButton.addEventListener('click', retry);
cancelButton.addEventListener('click', cancel);
controlsInstalled = true;
}
function syncScreen() { applyLoaderScreenState(loaderState()); installControls(); }
function observe(source) {
requested.add(source);
if (!cohortFrameScheduled) {
cohortFrameScheduled = true;
requestAnimationFrame(() => { cohortClosed = true; syncScreen(); });
}
syncScreen();
}
function createPending() {
let resolve;
let reject;
const promise = new Promise((resolvePromise, rejectPromise) => { resolve = resolvePromise; reject = rejectPromise; });
return { promise: promise, resolve: resolve, reject: reject };
}
async function digestBlob(blob) {
if (digestActive >= MAX_CONCURRENT_DIGESTS) await new Promise((resolve) => digestWaiters.push(resolve));
digestActive += 1;
try {
return Array.from(new Uint8Array(await crypto.subtle.digest('SHA-256', await blob.arrayBuffer()))).map((byte) => byte.toString(16).padStart(2, '0')).join('');
} finally {
digestActive -= 1;
const next = digestWaiters.shift();
if (next) next();
}
}
async function verify(entry, blob) {
if (blob.size !== entry.bytes) throw new Error('optimized resource length mismatch');
if (await digestBlob(blob) !== entry.sha256) throw new Error('optimized resource digest mismatch');
return blob;
}
function cacheVerified(source, blob) {
if (!cache.has(source)) {
if (liveBytes + blob.size > MAX_LIVE_BYTES) throw new Error('optimized resource live-byte limit exceeded');
cache.set(source, blob);
liveBytes += blob.size;
}
verifiedSources.add(source);
}
function complete(source, blob) {
cacheVerified(source, blob);
failures.delete(source);
const waiter = pending.get(source);
if (waiter) { pending.delete(source); waiter.resolve(blob); }
syncScreen();
}
function createOperation(kind, sources) {
const operation = { kind: kind, sources: sources.slice(), start: undefined };
operation.start = () => kind === 'single' ? startSingle(operation) : startBatch(operation);
return operation;
}
function prepareAttempt(operation) {
const sources = operation.sources.filter((source) => pending.has(source) && !cache.has(source));
if (!sources.length) return undefined;
for (const source of sources) failures.delete(source);
const attempt = { active: true, controller: new AbortController(), kind: operation.kind, sources: sources };
attempts.add(attempt);
syncScreen();
return attempt;
}
function finishAttempt(attempt) {
if (!attempt.active) return;
attempt.active = false;
attempts.delete(attempt);
syncScreen();
}
function recordFailures(sources, cancelled, kind) {
const unresolved = sources.filter((source) => pending.has(source) && !cache.has(source));
if (!unresolved.length) return;
const operation = createOperation(kind, unresolved);
for (const source of unresolved) failures.set(source, { cancelled: cancelled, operation: operation });
lastFailureSource = unresolved[0];
}
async function startSingle(operation) {
const attempt = prepareAttempt(operation);
if (!attempt) return;
const source = attempt.sources[0];
try {
const entry = entryFor(source);
const blob = await resourceBytes(entry.uri, attempt.controller.signal);
const checked = await verify(entry, blob);
if (attempt.active) complete(source, checked);
} catch (_) {
if (attempt.active) recordFailures([source], attempt.controller.signal.aborted, 'single');
} finally { finishAttempt(attempt); }
}
async function startBatch(operation) {
const attempt = prepareAttempt(operation);
if (!attempt) return;
const entries = attempt.sources.map(entryFor);
const requests = entries.map((entry) => ({ url: entry.uri }));
try {
const items = await resourceBytesMany(requests, attempt.controller.signal);
if (!attempt.active) return;
if (items.length !== requests.length || items.some((item, index) => item.url !== requests[index].url)) {
recordFailures(attempt.sources, false, 'batch');
return;
}
const failed = [];
await Promise.all(entries.map(async (entry, index) => {
const item = items[index];
if (!item.ok || !item.blob) { failed.push(entry.source); return; }
try {
const checked = await verify(entry, item.blob);
if (attempt.active) complete(entry.source, checked);
} catch (_) { failed.push(entry.source); }
}));
if (attempt.active && failed.length) recordFailures(failed, attempt.controller.signal.aborted, 'batch');
} catch (_) {
if (attempt.active) recordFailures(attempt.sources, attempt.controller.signal.aborted, 'batch');
} finally { finishAttempt(attempt); }
}
function resolve(source) {
let entry;
try { entry = entryFor(source); } catch (error) { return Promise.reject(error); }
if (cache.has(source)) return Promise.resolve(cache.get(source));
if (pending.has(source)) return pending.get(source).promise;
const waiter = createPending();
pending.set(source, waiter);
observe(source);
createOperation('single', [entry.source]).start();
return waiter.promise;
}
function resolveMany(sources) {
try { for (const source of sources) entryFor(source); } catch (error) { return Promise.reject(error); }
const created = [];
const results = sources.map((source) => {
if (cache.has(source)) return Promise.resolve(cache.get(source));
if (pending.has(source)) return pending.get(source).promise;
const waiter = createPending();
pending.set(source, waiter);
observe(source);
created.push(source);
return waiter.promise;
});
for (let index = 0; index < created.length; index += MAX_BATCH_SIZE) createOperation('batch', created.slice(index, index + MAX_BATCH_SIZE)).start();
return Promise.all(results);
}
async function retry() {
const operations = new Set(Array.from(failures.values(), (failure) => failure.operation));
for (const operation of operations) for (const source of operation.sources) failures.delete(source);
syncScreen();
await Promise.all(Array.from(operations, (operation) => operation.start()));
}
function cancel() {
for (const attempt of Array.from(attempts)) {
attempt.active = false;
attempts.delete(attempt);
attempt.controller.abort();
recordFailures(attempt.sources, true, attempt.kind);
}
syncScreen();
}
async function response(source) { const entry = entryFor(source); const value = new Response(await resolve(source), { headers: { 'content-type': entry.mime } }); release(source); return value; }
async function objectUrl(source) { const current = urls.get(source); if (current) { current.references += 1; return current.url; } const url = URL.createObjectURL(await resolve(source)); urls.set(source, { url: url, references: 1 }); return url; }
function release(source) { if (source === undefined) { for (const handle of urls.values()) URL.revokeObjectURL(handle.url); urls.clear(); cache.clear(); liveBytes = 0; return; } const handle = urls.get(source); if (handle && --handle.references <= 0) { URL.revokeObjectURL(handle.url); urls.delete(source); } if (!urls.has(source) && cache.has(source)) { liveBytes -= cache.get(source).size; cache.delete(source); } }
function teardown() { for (const attempt of attempts) { attempt.active = false; attempt.controller.abort(); } attempts.clear(); for (const waiter of pending.values()) waiter.reject(new Error('optimized resource loader was torn down')); pending.clear(); failures.clear(); release(); }
window.__nappletPrivateResourceLoader = { resolve: resolve, resolveMany: resolveMany, response: response, objectUrl: objectUrl, release: release, cancel: cancel, retry: retry, teardown: teardown };
requestAnimationFrame(syncScreen);
})();</script></head>
<body><main id="napplet-loader" class="napplet-loader" data-state="initial" aria-busy="false" aria-labelledby="napplet-loader-title">
<section class="napplet-loader-card">
<p class="napplet-loader-eyebrow" aria-hidden="true">Packaged application</p>
<h1 id="napplet-loader-title">Preparing packaged application</h1>
<p id="napplet-loader-status" class="napplet-loader-status" role="status" aria-live="polite" aria-atomic="true">Getting everything ready.</p>
<div id="napplet-loader-progress-panel" class="napplet-loader-progress-panel" hidden>
<progress id="napplet-loader-progress" class="napplet-loader-progress" aria-label="Packaged resources loading" hidden></progress>
<p class="napplet-loader-helper">Resources are checked as they arrive.</p>
</div>
<div id="napplet-loader-resource-panel" class="napplet-loader-resource-panel" hidden>
<strong>Resource unavailable</strong>
<p id="napplet-loader-resource" dir="auto"></p>
</div>
<div id="napplet-loader-actions" class="napplet-loader-actions" hidden>
<button id="napplet-loader-retry" class="napplet-loader-primary" type="button" hidden>Retry</button>
<button id="napplet-loader-cancel" type="button" hidden>Cancel</button>
</div>
</section>
</main>
</body>
</html>
