master
AdityaAngajala Publish 0.3.0 6d39e2e 2mo ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506
import { createConductorAnimation } from "./circuit-animation-conductor.js?v=1";
import { createHandshakeAnimation } from "./circuit-animation-handshake.js?v=2";
import { createTraceFlowReveal } from "./circuit-reveal-flow.js?v=1";
import {
  createScrollTraceReveal,
  SCROLL_REVEAL_DEFAULTS,
  TRACE_SPAWN_PRESETS,
} from "./circuit-reveal-scroll.js?v=1";
import { createHybridCircuitField } from "./circuit-field-hybrid-v8.js?v=1";
import { createStreamingCircuitFieldWorker } from "./circuit-field-hybrid-client-v8.js?v=1";
import {
  createStreamingTraceReveal,
  STREAM_REVEAL_DEFAULTS,
} from "./circuit-reveal-stream-v8.js?v=1";
import { createPageTraceStager } from "./circuit-trace-stager-v8.js?v=1";
import {
  createReflectionAnimation,
  REFLECTION_DEFAULTS,
} from "./circuit-animation-reflection.js?v=1";
import {
  createCircuitBackground as createLegacyCircuitBackground,
  DEFAULTS as GEOMETRY_DEFAULTS,
  ANIMATION_PRESETS as LEGACY_ANIMATION_PRESETS,
  generateCircuitField,
  pathData,
} from "./circuit-background-v4.js?geometry=1";

const SVG_NS = "http://www.w3.org/2000/svg";

const DEFAULTS = Object.freeze({
  ...GEOMETRY_DEFAULTS,
  animationSystem: "none",
  motion: false,
  revealSystem: "instant",
  revealMotion: false,
  revealPower: 0.72,
  revealDuration: 7600,
  revealGlow: 0.82,
  ...SCROLL_REVEAL_DEFAULTS,
  traceDuration: STREAM_REVEAL_DEFAULTS.traceDuration,
  revealLaunchRate: STREAM_REVEAL_DEFAULTS.revealLaunchRate,
  scrollSpeedResponse: 0.6,
  maxActiveTraces: STREAM_REVEAL_DEFAULTS.maxActiveTraces,
  unlockLead: 0.025,
  continuousGeneration: false,
  generationAheadScreens: 2,
  generationChunkScreens: 1,
  generationExtendScreens: 1,
  liveliness: 0,
  atmosphereStrength: 0,
  handshakeInterval: 1650,
  handshakeSpeed: 230,
  handshakeLength: 48,
  maxHandshakes: 3,
  ...REFLECTION_DEFAULTS,
});

const ANIMATION_PRESETS = Object.freeze({
  none: LEGACY_ANIMATION_PRESETS.none,
  conductor: LEGACY_ANIMATION_PRESETS.conductor,
  routed: LEGACY_ANIMATION_PRESETS.adom,
  handshake: Object.freeze({
    animationSystem: "handshake",
    motion: true,
    liveliness: 0.72,
    handshakeInterval: 1650,
    handshakeSpeed: 230,
    handshakeLength: 48,
    maxHandshakes: 3,
    atmosphereStrength: 0,
  }),
  reflection: Object.freeze({
    animationSystem: "reflection",
    motion: true,
    liveliness: 0.68,
    reflectionStrength: 0.62,
    reflectionCycle: 14800,
    reflectionWidth: 0.3,
    reflectionAngle: 18,
    reflectionDrift: 6,
    reflectionRest: 0.12,
    reflectionQuiet: 0.84,
    reflectionPointer: true,
    atmosphereStrength: 0.14,
  }),
});

const REVEAL_PRESETS = Object.freeze({
  instant: Object.freeze({
    revealSystem: "instant",
    revealMotion: false,
  }),
  flow: Object.freeze({
    revealSystem: "flow",
    revealMotion: true,
    revealPower: 0.72,
    revealDuration: 7600,
    revealGlow: 0.88,
    spawnMode: "flow",
    spawnAngle: 90,
    spawnSwirl: 0.075,
    revealMaxActiveTraces: 48,
  }),
  scroll: Object.freeze({
    revealSystem: "scroll",
    revealMotion: true,
    revealPower: 0.78,
    ...TRACE_SPAWN_PRESETS.downstream,
    traceWindow: 0.095,
    revealScrollLead: 0.74,
    revealGlow: 0.82,
    traceDuration: 950,
    revealLaunchRate: 24,
    maxActiveTraces: 72,
    scrollSpeedResponse: 0.6,
    unlockLead: 0.025,
    continuousGeneration: true,
    generationAheadScreens: 2,
  }),
});

let instanceCount = 0;

function hashSeed(value) {
  let hash = 2166136261;
  for (const char of String(value)) {
    hash ^= char.charCodeAt(0);
    hash = Math.imul(hash, 16777619);
  }
  return hash >>> 0;
}

function mulberry32(seed) {
  return function random() {
    let value = (seed += 0x6d2b79f5);
    value = Math.imul(value ^ (value >>> 15), value | 1);
    value ^= value + Math.imul(value ^ (value >>> 7), value | 61);
    return ((value ^ (value >>> 14)) >>> 0) / 4294967296;
  };
}

function svgElement(name, attributes = {}) {
  const element = document.createElementNS(SVG_NS, name);
  for (const [key, value] of Object.entries(attributes)) element.setAttribute(key, String(value));
  return element;
}

function createModernCircuitBackground(mount, options = {}) {
  if (!(mount instanceof Element)) throw new TypeError("mount must be a DOM element");
  const id = `circuit-field-${++instanceCount}`;
  let config = { ...DEFAULTS, ...options };
  let field;
  let svg;
  let conductor;
  let handshake;
  let reflection;
  let flowReveal;
  let scrollReveal;
  let resizeObserver;
  let resizeTimer;
  let pointer = null;
  let lastSize = "";
  const interactionTarget = mount.parentElement || mount;
  const readingZone = interactionTarget.querySelector?.("[data-circuit-reading-zone]") || null;
  const motionPreference = window.matchMedia("(prefers-reduced-motion: reduce)");
  let reducedMotion = motionPreference.matches;
  const originalPosition = mount.style.position;
  const originalOverflow = mount.style.overflow;
  if (getComputedStyle(mount).position === "static") mount.style.position = "relative";
  mount.style.overflow = "hidden";

  function life() {
    return Math.max(0, Math.min(1.5, config.liveliness));
  }

  function featureScale() {
    return Math.max(0.25, config.featureScale);
  }

  function addVia(group, point, role) {
    const scale = featureScale();
    const circles = [
      svgElement("circle", {
        cx: point[0], cy: point[1], r: config.viaOuterRadius * scale, fill: config.traceColor,
      }),
      svgElement("circle", {
        cx: point[0], cy: point[1], r: config.viaInnerRadius * scale,
        fill: "var(--circuit-hole, #0d1117)",
      }),
    ];
    if (!role) {
      group.append(...circles);
      return circles;
    }
    const via = svgElement("g", { "data-trace-via": role });
    via.append(...circles);
    group.append(via);
    return via;
  }

  function syncAmbientRevealClip(progress = null) {
    const bottom = progress === null ? null : Math.max(0, 100 - progress * 100);
    for (const layer of mount.querySelectorAll("[data-animation]")) {
      if (layer.getAttribute("data-animation") === "scroll-trace-reveal") continue;
      if (bottom === null) layer.style.removeProperty("clip-path");
      else layer.style.clipPath = "inset(0 0 " + bottom + "% 0)";
    }
  }

  function destroyAnimationSystems() {
    conductor?.destroy();
    handshake?.destroy();
    reflection?.destroy();
    conductor = undefined;
    handshake = undefined;
    reflection = undefined;
  }

  function destroyRevealSystems() {
    syncAmbientRevealClip(null);
    flowReveal?.destroy();
    scrollReveal?.destroy();
    flowReveal = undefined;
    scrollReveal = undefined;
  }

  function createAnimationSystems() {
    const animationNamespace = config.animationSystem === "conductor"
      ? "signals"
      : config.animationSystem === "handshake"
        ? "handshakes"
        : config.animationSystem;
    const animationRandom = mulberry32(hashSeed([config.seed, lastSize, animationNamespace].join(":")));
    if (config.animationSystem === "conductor") {
      conductor = createConductorAnimation(svg, field, config, animationRandom);
    } else if (
      config.animationSystem === "handshake"
      && config.motion
      && !reducedMotion
      && life() > 0.02
    ) {
      handshake = createHandshakeAnimation(mount, field, config, animationRandom, { readingZone });
    } else if (config.animationSystem === "reflection") {
      reflection = createReflectionAnimation(mount, field, config, animationRandom, { readingZone });
    }
  }

  function build(force = false) {
    const pixelWidth = Math.max(1, mount.clientWidth);
    const pixelHeight = Math.max(1, mount.clientHeight);
    const worldWidth = pixelWidth / config.scale;
    const worldHeight = pixelHeight / config.scale;
    const pitch = config.pitch * featureScale();
    const size = `${Math.floor(worldWidth / pitch)}x${Math.floor(worldHeight / pitch)}`;
    if (!force && size === lastSize) return false;
    lastSize = size;

    destroyAnimationSystems();
    destroyRevealSystems();
    svg?.remove();
    field = generateCircuitField({ ...config, width: worldWidth, height: worldHeight });
    const revealRandom = mulberry32(hashSeed(`${config.seed}:${size}:reveal:${config.revealSystem}`));

    svg = svgElement("svg", {
      id,
      "aria-hidden": true,
      focusable: false,
      viewBox: `0 0 ${field.width} ${field.height}`,
      preserveAspectRatio: "none",
    });
    Object.assign(svg.style, {
      position: "absolute",
      inset: "0",
      width: "100%",
      height: "100%",
      display: "block",
      pointerEvents: "none",
    });

    const traceLayer = svgElement("g", { "data-static-traces": "" });
    const flowMarkup = config.revealSystem === "flow";
    for (const [index, trace] of field.traces.entries()) {
      const tracePath = svgElement("path", {
        ...(flowMarkup ? { "data-trace-path": "" } : {}),
        d: pathData(trace.points),
        fill: "none",
        stroke: config.traceColor,
        "stroke-width": config.traceWidth * config.featureScale,
        "stroke-linecap": "butt",
        "stroke-linejoin": "miter",
      });
      if (!flowMarkup) {
        traceLayer.append(tracePath);
        if (trace.viaStart) addVia(traceLayer, trace.points[0]);
        if (trace.viaEnd) addVia(traceLayer, trace.points.at(-1));
        continue;
      }
      const traceGroup = svgElement("g", { "data-circuit-trace": index });
      traceGroup.append(tracePath);
      if (trace.viaStart) addVia(traceGroup, trace.points[0], "start");
      if (trace.viaEnd) addVia(traceGroup, trace.points.at(-1), "end");
      traceLayer.append(traceGroup);
    }
    svg.append(traceLayer);
    mount.prepend(svg);

    createAnimationSystems();

    if (config.revealSystem === "flow") {
      flowReveal = createTraceFlowReveal(svg, field, config, revealRandom, {
        traceLayer,
        onComplete: () => startMotion(),
      });
    } else if (config.revealSystem === "scroll") {
      const revealLead = Math.max(0.25, Math.min(0.95, Number(config.revealScrollLead) || 0.74));
      scrollReveal = createScrollTraceReveal(svg, field, config, {
        traceLayer,
        rangeElement: mount,
        scrollRoot: window,
        progressSource: config.progressSource || "scroll",
        spawnMode: config.spawnMode,
        spawnAngle: config.spawnAngle,
        spawnSwirl: config.spawnSwirl,
        spawnOriginX: config.spawnOriginX,
        spawnOriginY: config.spawnOriginY,
        traceWindow: config.traceWindow,
        unlockLead: config.unlockLead,
        maxActiveTraces: config.maxActiveTraces,
        traceDuration: config.traceDuration,
        revealLaunchRate: config.revealLaunchRate,
        scrollSpeedResponse: config.scrollSpeedResponse,
        revealGlow: config.revealGlow,
        startOffset: Number.isFinite(Number(config.revealStartOffset))
          ? Number(config.revealStartOffset)
          : -window.innerHeight * revealLead,
        endOffset: config.endOffset,
        once: config.once !== false,
        autoStart: false,
        onProgress: (progress) => syncAmbientRevealClip(progress),
      });
    }
    return true;
  }

  function onPointerMove(event) {
    if (!field) return;
    const rect = mount.getBoundingClientRect();
    pointer = {
      x: (event.clientX - rect.left) / rect.width * field.width,
      y: (event.clientY - rect.top) / rect.height * field.height,
      at: performance.now(),
    };
    conductor?.pointerMoved(pointer);
    handshake?.pointerMoved(pointer);
    reflection?.pointerMoved(pointer);
  }

  function onPointerLeave() {
    if (pointer) pointer.at = performance.now() - 3000;
    handshake?.pointerLeft();
    reflection?.pointerLeft();
  }

  function onClick(event) {
    onPointerMove(event);
    if (config.animationSystem === "conductor") conductor?.clicked(pointer);
    else if (config.animationSystem === "handshake") handshake?.clicked(pointer);
    else if (config.animationSystem === "reflection") reflection?.clicked(pointer);
  }

  function stopMotion() {
    conductor?.stop();
    handshake?.stop();
    reflection?.stop();
  }

  function startMotion() {
    stopMotion();
    if (config.animationSystem === "none" || !config.motion || reducedMotion || life() <= 0.02) return;
    if (flowReveal?.stats?.running) return;
    if (config.animationSystem === "conductor") conductor?.start();
    else if (config.animationSystem === "handshake") handshake?.start();
    else if (config.animationSystem === "reflection") reflection?.start();
  }

  function stopReveal() {
    syncAmbientRevealClip(null);
    flowReveal?.stop();
    scrollReveal?.stop();
  }

  function startReveal() {
    if (reducedMotion || config.revealSystem === "instant" || !config.revealMotion) {
      flowReveal?.stop();
      scrollReveal?.complete();
      return;
    }
    if (config.revealSystem === "flow") {
      flowReveal?.start();
    } else if (config.revealSystem === "scroll") {
      scrollReveal?.start();
      syncAmbientRevealClip(scrollReveal?.visualProgress || 0);
    }
  }

  function onMotionPreferenceChange(event) {
    reducedMotion = event.matches;
    if (reducedMotion) {
      stopMotion();
      stopReveal();
      scrollReveal?.complete();
      return;
    }
    lastSize = "";
    build(true);
    startReveal();
    startMotion();
  }

  function regenerate(nextOptions = {}) {
    stopMotion();
    stopReveal();
    config = { ...config, ...nextOptions };
    lastSize = "";
    build(true);
    startReveal();
    startMotion();
    return api;
  }

  function setReveal(nextOptions = {}) {
    return regenerate(nextOptions);
  }

  function setAnimation(nextOptions = {}) {
    stopMotion();
    destroyAnimationSystems();
    config = { ...config, ...nextOptions };
    createAnimationSystems();
    if (config.revealSystem === "scroll") syncAmbientRevealClip(scrollReveal?.visualProgress || 0);
    startMotion();
    return api;
  }

  function triggerAnimation(origin = null) {
    if (config.animationSystem === "conductor") return conductor?.trigger(origin) || false;
    if (config.animationSystem === "handshake") return handshake?.trigger(origin) || false;
    if (config.animationSystem === "reflection") return reflection?.trigger(origin) || false;
    return false;
  }

  function triggerReveal() {
    if (config.revealSystem === "flow") {
      stopMotion();
      startReveal();
      return true;
    }
    if (config.revealSystem === "scroll") return false;
    return false;
  }

  function setRevealProgress(progress, options) {
    scrollReveal?.setProgress(progress, options);
    return api;
  }

  function exportSvg() {
    const clone = svg.cloneNode(true);
    clone.querySelectorAll("[data-animation]").forEach((layer) => layer.remove());
    clone.querySelector("[data-static-traces]")?.style.removeProperty("visibility");
    clone.querySelector("[data-static-traces]")?.style.removeProperty("display");
    clone.querySelectorAll("[data-trace-path]").forEach((path) => {
      path.removeAttribute("stroke-dasharray");
      path.removeAttribute("stroke-dashoffset");
      path.style.removeProperty("opacity");
      path.style.removeProperty("will-change");
    });
    clone.querySelectorAll("[data-circuit-trace]").forEach((group, index) => {
      const path = group.querySelector("[data-trace-path]");
      const trace = field.traces[index];
      if (path && trace) path.setAttribute("d", pathData(trace.points));
    });
    clone.querySelectorAll("[data-trace-via]").forEach((via) => {
      via.style.removeProperty("opacity");
      via.style.removeProperty("will-change");
    });
    clone.removeAttribute("style");
    return `<?xml version="1.0" encoding="UTF-8"?>\n${clone.outerHTML}`;
  }

  function destroy() {
    stopMotion();
    stopReveal();
    destroyAnimationSystems();
    destroyRevealSystems();
    window.clearTimeout(resizeTimer);
    resizeObserver?.disconnect();
    interactionTarget.removeEventListener("pointermove", onPointerMove);
    interactionTarget.removeEventListener("pointerleave", onPointerLeave);
    interactionTarget.removeEventListener("click", onClick);
    if (motionPreference.removeEventListener) {
      motionPreference.removeEventListener("change", onMotionPreferenceChange);
    } else {
      motionPreference.removeListener?.(onMotionPreferenceChange);
    }
    svg?.remove();
    mount.style.position = originalPosition;
    mount.style.overflow = originalOverflow;
  }

  const api = {
    regenerate,
    setReveal,
    setAnimation,
    triggerAnimation,
    triggerBloom: triggerAnimation,
    triggerReveal,
    setRevealProgress,
    exportSvg,
    destroy,
    get field() { return field; },
    get animationStats() {
      if (config.animationSystem === "none") {
        return { system: "none", animationNodes: 0, frameCount: 0, reducedMotion };
      }
      if (config.animationSystem === "conductor") return conductor?.stats;
      if (config.animationSystem === "handshake") {
        return handshake?.stats || {
          system: "adom-handshake",
          animationNodes: 0,
          activeTransactions: 0,
          frameCount: 0,
          reducedMotion,
        };
      }
      if (config.animationSystem === "reflection") {
        return reflection?.stats || {
          system: "adom-reflection",
          animationNodes: 0,
          activeReflections: 0,
          frameCount: 0,
          reducedMotion,
        };
      }
      return { system: "unknown", animationNodes: 0, frameCount: 0, reducedMotion };
    },
    get revealStats() {
      if (config.revealSystem === "instant") {
        return { system: "instant", traceCount: field?.traces.length || 0, completed: true, reducedMotion };
      }
      if (config.revealSystem === "flow") {
        return flowReveal?.stats || {
          system: "trace-flow-sweep",
          traceCount: field?.traces.length || 0,
          activeTraces: 0,
          reducedMotion,
        };
      }
      if (config.revealSystem === "scroll") {
        return scrollReveal?.stats || {
          system: "scroll-trace-reveal",
          traceCount: field?.traces.length || 0,
          activeTraces: 0,
          completedTraces: 0,
          progress: 0,
          reducedMotion,
        };
      }
      return { system: "unknown", traceCount: 0, reducedMotion };
    },
  };

  build(true);
  resizeObserver = new ResizeObserver(() => {
    window.clearTimeout(resizeTimer);
    resizeTimer = window.setTimeout(() => {
      if (build()) {
        startReveal();
        startMotion();
      }
    }, 220);
  });
  resizeObserver.observe(mount);
  if (config.interactive) {
    interactionTarget.addEventListener("pointermove", onPointerMove, { passive: true });
    interactionTarget.addEventListener("pointerleave", onPointerLeave, { passive: true });
    interactionTarget.addEventListener("click", onClick);
  }
  if (motionPreference.addEventListener) {
    motionPreference.addEventListener("change", onMotionPreferenceChange);
  } else {
    motionPreference.addListener?.(onMotionPreferenceChange);
  }
  startReveal();
  startMotion();
  return api;
}


function createStreamingCircuitBackground(mount, options = {}) {
  if (!(mount instanceof Element)) throw new TypeError("mount must be a DOM element");
  const id = `circuit-stream-${++instanceCount}`;
  let config = { ...DEFAULTS, ...options };
  let stream;
  let reveal;
  let traceStager;
  let svg;
  let unsubscribe;
  let fallbackUnsubscribe;
  let conductor;
  let handshake;
  let reflection;
  let resizeObserver;
  let resizeTimer;
  let ambientRefreshTimer;
  let coordinatorFrame = 0;
  let clipFrame = 0;
  let lastAmbientClipBottom = null;
  let ambientClipLayers = null;
  let generationRequest = 0;
  let generationRequestType = "";
  let generationPromise = null;
  let streamUsesWorker = false;
  let buildEpoch = 0;
  let generationTargetWorldY = 0;
  let destroyed = false;
  let pointer = null;
  let canonicalPageWidth = Math.max(
    1,
    Number(config.canonicalPageWidth) || mount.clientWidth,
  );
  const canonicalWidthTracksViewport = Math.abs(
    canonicalPageWidth - Math.max(1, window.innerWidth || canonicalPageWidth),
  ) < 2;
  const initialPageCount = config.revealSystem === "scroll" ? 3 : 1;
  const pagePixelHeight = Math.max(
    1,
    Number(config.canonicalPageHeight) || mount.clientHeight / initialPageCount,
  );
  let lastPixelWidth = canonicalPageWidth;
  let pageWorldHeight = pagePixelHeight / Math.max(0.01, Number(config.scale) || 1);
  let logicalPixelHeight = pagePixelHeight * initialPageCount;
  let previousViewportTop = 0;
  let previousViewportTime = performance.now();
  let latestViewport = null;
  const materializedTraces = [];
  const interactionTarget = mount.parentElement || mount;
  const readingZone = interactionTarget.querySelector?.("[data-circuit-reading-zone]") || null;
  const motionPreference = window.matchMedia("(prefers-reduced-motion: reduce)");
  let reducedMotion = motionPreference.matches;
  const originalMountPosition = mount.style.position;
  const originalMountOverflow = mount.style.overflow;
  const originalTargetMinHeight = interactionTarget.style.minHeight;
  if (getComputedStyle(mount).position === "static") mount.style.position = "relative";
  mount.style.overflow = "hidden";

  function clamp(value, minimum = 0, maximum = 1) {
    return Math.max(minimum, Math.min(maximum, value));
  }

  function worldScale() {
    return Math.max(0.01, Number(config.scale) || 1);
  }

  function featureScale() {
    return Math.max(0.25, Number(config.featureScale) || 1);
  }

  function life() {
    return clamp(Number(config.liveliness) || 0, 0, 1.5);
  }

  function worldPerPixel() {
    return pageWorldHeight / pagePixelHeight;
  }

  function logicalWorldHeight() {
    return logicalPixelHeight * worldPerPixel();
  }

  function continuousMode() {
    return config.revealSystem === "scroll" && config.continuousGeneration;
  }

  function viewportPixelHeight() {
    return Math.max(1, window.innerHeight || document.documentElement.clientHeight || 1);
  }

  function viewportWorldHeight() {
    return viewportPixelHeight() * worldPerPixel();
  }

  function materializationFrontier(viewport) {
    return viewport.bottomWorldY + pageWorldHeight * 0.35;
  }

  function generationChunkRows() {
    const pitch = Math.max(1, (Number(config.pitch) || 7.895) * featureScale());
    return Math.max(24, Math.round(pageWorldHeight / pitch));
  }

  function currentViewport() {
    const rect = interactionTarget.getBoundingClientRect();
    const heightPixels = viewportPixelHeight();
    const topPixels = clamp(-rect.top, 0, Math.max(0, logicalPixelHeight - heightPixels));
    const now = performance.now();
    const elapsed = Math.max(1, now - previousViewportTime);
    const forwardPixels = Math.max(0, topPixels - previousViewportTop);
    const velocity = forwardPixels * worldPerPixel() / elapsed;
    previousViewportTop = topPixels;
    previousViewportTime = now;
    latestViewport = {
      topPixels,
      bottomPixels: Math.min(logicalPixelHeight, topPixels + heightPixels),
      heightPixels,
      topWorldY: topPixels * worldPerPixel(),
      bottomWorldY: Math.min(logicalPixelHeight, topPixels + heightPixels) * worldPerPixel(),
      heightWorld: heightPixels * worldPerPixel(),
      velocity,
    };
    return latestViewport;
  }

  const fieldFacade = {
    get width() { return stream?.width || lastPixelWidth / worldScale(); },
    get height() { return logicalWorldHeight(); },
    get traces() { return materializedTraces; },
  };

  function updateSvgExtent() {
    if (!svg || !stream) return;
    svg.setAttribute("viewBox", `0 0 ${stream.width} ${logicalWorldHeight()}`);
  }

  function syncAmbientRevealClip() {
    if (!reveal || !svg || config.animationSystem === "none") return;
    const stats = reveal.stats;
    const through = Number(stats.revealedThroughWorldY);
    const progress = Number.isFinite(through)
      ? clamp(through / Math.max(1, logicalWorldHeight()))
      : 0;
    const bottom = Math.max(0, 100 - progress * 100);
    if (bottom === lastAmbientClipBottom) return;
    lastAmbientClipBottom = bottom;
    const layers = ambientClipLayers || Array.from(mount.querySelectorAll("[data-animation]"))
      .filter((layer) => layer.getAttribute("data-animation") !== "stream-trace-reveal");
    ambientClipLayers = layers;
    const clipPath = "inset(0 0 " + bottom + "% 0)";
    for (const layer of layers) layer.style.clipPath = clipPath;
  }

  function scheduleAmbientClip() {
    if (
      clipFrame
      || destroyed
      || config.animationSystem === "none"
      || (!conductor && !handshake && !reflection)
    ) return;
    const tick = () => {
      clipFrame = 0;
      syncAmbientRevealClip();
      const stats = reveal?.stats;
      if (
        config.animationSystem !== "none"
        && (conductor || handshake || reflection)
        && stats
        && (stats.active > 0 || stats.queued > 0)
      ) {
        clipFrame = window.requestAnimationFrame(tick);
      }
    };
    clipFrame = window.requestAnimationFrame(tick);
  }

  function clearAmbientClip() {
    window.cancelAnimationFrame(clipFrame);
    clipFrame = 0;
    lastAmbientClipBottom = null;
    const layers = ambientClipLayers || Array.from(mount.querySelectorAll("[data-animation]"));
    for (const layer of layers) {
      if (layer.getAttribute("data-animation") !== "stream-trace-reveal") {
        layer.style.removeProperty("clip-path");
      }
    }
    ambientClipLayers = null;
  }

  function stopMotion() {
    conductor?.stop();
    handshake?.stop();
    reflection?.stop();
  }

  function destroyAnimationSystems() {
    window.clearTimeout(ambientRefreshTimer);
    ambientRefreshTimer = 0;
    stopMotion();
    conductor?.destroy();
    handshake?.destroy();
    reflection?.destroy();
    conductor = undefined;
    handshake = undefined;
    reflection = undefined;
    ambientClipLayers = null;
    lastAmbientClipBottom = null;
  }

  function createAnimationSystems() {
    if (!svg || !stream || config.animationSystem === "none") return;
    const namespace = config.animationSystem === "conductor"
      ? "stream-signals"
      : `stream-${config.animationSystem}`;
    const random = mulberry32(hashSeed([
      config.seed,
      Math.round(stream.width),
      Math.round(logicalWorldHeight()),
      namespace,
    ].join(":")));
    if (config.animationSystem === "conductor") {
      conductor = createConductorAnimation(svg, fieldFacade, config, random);
    } else if (config.animationSystem === "handshake") {
      handshake = createHandshakeAnimation(mount, fieldFacade, config, random, { readingZone });
    } else if (config.animationSystem === "reflection") {
      reflection = createReflectionAnimation(mount, fieldFacade, config, random, { readingZone });
    }
    ambientClipLayers = Array.from(mount.querySelectorAll("[data-animation]"))
      .filter((layer) => layer.getAttribute("data-animation") !== "stream-trace-reveal");
    syncAmbientRevealClip();
  }

  function startMotion() {
    stopMotion();
    if (config.animationSystem === "none" || !config.motion || reducedMotion || life() <= 0.02) return;
    if (config.animationSystem === "conductor") conductor?.start();
    else if (config.animationSystem === "handshake") handshake?.start();
    else if (config.animationSystem === "reflection") reflection?.start();
  }

  function refreshGrowingCanvasAnimation() {
    if (!reflection && !handshake) return;
    window.clearTimeout(ambientRefreshTimer);
    const epoch = buildEpoch;
    const candidate = stream;
    ambientRefreshTimer = window.setTimeout(() => {
      ambientRefreshTimer = 0;
      if (destroyed || epoch !== buildEpoch || candidate !== stream) return;
      destroyAnimationSystems();
      createAnimationSystems();
      startMotion();
    }, 180);
  }

  function stopReveal() {
    reveal?.stop();
  }

  function startReveal() {
    if (!reveal) return;
    if (reducedMotion || !config.revealMotion) reveal.complete();
    else reveal.start();
    scheduleAmbientClip();
  }

  function cancelGenerationRequest() {
    if (!generationRequest) return;
    if (generationRequestType === "idle" && window.cancelIdleCallback) {
      window.cancelIdleCallback(generationRequest);
    } else {
      window.clearTimeout(generationRequest);
    }
    generationRequest = 0;
    generationRequestType = "";
  }

  function extendPageWhenReady(viewport = currentViewport()) {
    if (!stream || !continuousMode()) return false;
    const distancePixels = logicalPixelHeight - viewport.bottomPixels;
    if (distancePixels > pagePixelHeight * 1.45) return false;
    const extendPages = Math.max(1, Math.round(Number(config.generationExtendScreens) || 1));
    const nextPixelHeight = logicalPixelHeight + pagePixelHeight * extendPages;
    const nextWorldHeight = logicalWorldHeight() + pageWorldHeight * extendPages;
    if (stream.generatedThrough + stream.stats.pitch * 0.25 < nextWorldHeight) return false;
    logicalPixelHeight = nextPixelHeight;
    interactionTarget.style.minHeight = Math.ceil(logicalPixelHeight) + "px";
    updateSvgExtent();
    refreshGrowingCanvasAnimation();
    return true;
  }

  function pumpGeneration() {
    generationRequest = 0;
    generationRequestType = "";
    if (destroyed || !stream || stream.generatedThrough >= generationTargetWorldY) return;
    const stats = stream.stats;
    const chunkHeight = Math.max(stats.pitch, stats.pitch * stats.chunkRows);
    const through = Math.min(generationTargetWorldY, stream.generatedThrough + chunkHeight);
    stream.ensureThrough(through);
    const viewport = latestViewport || currentViewport();
    const extended = extendPageWhenReady(viewport);
    if (extended) coordinate(viewport);
    if (stream.generatedThrough < generationTargetWorldY) scheduleGeneration();
  }

  function scheduleWorkerGeneration() {
    if (generationPromise || !stream || stream.generatedThrough >= generationTargetWorldY) return;
    const candidate = stream;
    const epoch = buildEpoch;
    const target = Math.min(
      generationTargetWorldY,
      stream.generatedThrough + pageWorldHeight,
    );
    generationPromise = candidate.ensureThrough(target)
      .then(() => {
        if (destroyed || candidate !== stream || epoch !== buildEpoch) return;
        const viewport = latestViewport || currentViewport();
        const extended = extendPageWhenReady(viewport);
        if (extended) coordinate(viewport);
      })
      .catch((error) => {
        if (
          !destroyed
          && candidate === stream
          && epoch === buildEpoch
          && error?.name !== "AbortError"
        ) {
          fallbackToSynchronousStream(candidate);
        }
      })
      .finally(() => {
        if (candidate !== stream || epoch !== buildEpoch) return;
        generationPromise = null;
        if (stream.generatedThrough < generationTargetWorldY) scheduleGeneration();
      });
  }

  function scheduleGeneration() {
    if (destroyed || !stream || stream.generatedThrough >= generationTargetWorldY) return;
    if (streamUsesWorker) {
      if (generationPromise || generationRequest) return;
      const run = () => {
        generationRequest = 0;
        generationRequestType = "";
        scheduleWorkerGeneration();
      };
      if (typeof window.requestIdleCallback === "function") {
        generationRequestType = "idle";
        generationRequest = window.requestIdleCallback(run, { timeout: 150 });
      } else {
        generationRequestType = "timer";
        generationRequest = window.setTimeout(run, 16);
      }
      return;
    }
    if (generationRequest) return;
    if (typeof window.requestIdleCallback === "function") {
      generationRequestType = "idle";
      generationRequest = window.requestIdleCallback(pumpGeneration, { timeout: 120 });
    } else {
      generationRequestType = "timer";
      generationRequest = window.setTimeout(pumpGeneration, 16);
    }
  }

  function coordinate(measured = null) {
    if (destroyed || !stream || !reveal) return;
    const requiredPages = Math.max(1, Math.ceil((mount.clientHeight - 1) / pagePixelHeight));
    const requiredPixelHeight = requiredPages * pagePixelHeight;
    if (requiredPixelHeight > logicalPixelHeight) {
      logicalPixelHeight = requiredPixelHeight;
      updateSvgExtent();
    }
    const viewport = measured || currentViewport();
    reveal.setViewport({
      topWorldY: viewport.topWorldY,
      bottomWorldY: viewport.bottomWorldY,
      height: viewport.heightWorld,
      velocity: viewport.velocity,
    });
    traceStager?.materializeThrough(materializationFrontier(viewport));
    if (continuousMode()) {
      const aheadPages = clamp(Number(config.generationAheadScreens) || 2, 1, 6);
      generationTargetWorldY = Math.max(
        generationTargetWorldY,
        logicalWorldHeight() + pageWorldHeight * aheadPages,
      );
      if (logicalPixelHeight - viewport.bottomPixels <= pagePixelHeight * 1.45) {
        const extendPages = Math.max(1, Math.round(Number(config.generationExtendScreens) || 1));
        generationTargetWorldY = Math.max(
          generationTargetWorldY,
          logicalWorldHeight() + pageWorldHeight * (aheadPages + extendPages),
        );
      }
    } else {
      generationTargetWorldY = Math.max(generationTargetWorldY, logicalWorldHeight());
    }
    extendPageWhenReady(viewport);
    scheduleGeneration();
    scheduleAmbientClip();
  }

  function scheduleCoordinate() {
    if (coordinatorFrame || destroyed) return;
    coordinatorFrame = window.requestAnimationFrame(() => {
      coordinatorFrame = 0;
      coordinate();
    });
  }

  function createSvg() {
    svg = svgElement("svg", {
      id,
      "aria-hidden": true,
      focusable: false,
      viewBox: `0 0 ${stream.width} ${logicalWorldHeight()}`,
      preserveAspectRatio: "none",
      "data-continuous-circuit": "v8",
    });
    Object.assign(svg.style, {
      position: "absolute",
      inset: "0",
      width: "100%",
      height: "100%",
      display: "block",
      pointerEvents: "none",
    });
    mount.prepend(svg);
  }

  function fallbackToSynchronousStream(candidate) {
    if (destroyed || candidate !== stream) return;
    build(false);
  }

  async function initializeStream(candidate, streamOptions, epoch, useWorker) {
    try {
      if (useWorker) await candidate.ready;
      if (destroyed || candidate !== stream || epoch !== buildEpoch) return;
      const canonicalPageHeight = Number(candidate.stats.initialPageHeight);
      if (Number.isFinite(canonicalPageHeight) && canonicalPageHeight > 0) {
        pageWorldHeight = canonicalPageHeight;
      }

      createSvg();
      reveal = createStreamingTraceReveal(svg, config, {
        ...config,
        width: candidate.width,
        autoStart: false,
      });
      traceStager = createPageTraceStager({
        materialize(traces) {
          if (destroyed || candidate !== stream || epoch !== buildEpoch || !reveal) return;
          reveal.appendTraces(traces);
          materializedTraces.push(...traces);
          if (reducedMotion || !config.revealMotion) reveal.complete();
          refreshGrowingCanvasAnimation();
          scheduleAmbientClip();
        },
      });
      const viewport = currentViewport();
      reveal.setViewport({
        topWorldY: viewport.topWorldY,
        bottomWorldY: viewport.bottomWorldY,
        height: viewport.heightWorld,
        velocity: 0,
      });
      traceStager.materializeThrough(materializationFrontier(viewport));
      unsubscribe = candidate.onAppend((traces) => {
        if (destroyed || candidate !== stream || epoch !== buildEpoch || !traceStager) return;
        traceStager.stage(traces);
      });
      const initialThrough = Math.min(logicalWorldHeight(), pageWorldHeight);
      await Promise.resolve(candidate.ensureThrough(initialThrough));
      if (destroyed || candidate !== stream || epoch !== buildEpoch) return;

      const aheadPages = continuousMode()
        ? clamp(Number(config.generationAheadScreens) || 2, 1, 6)
        : 0;
      generationTargetWorldY = logicalWorldHeight() + pageWorldHeight * aheadPages;
      createAnimationSystems();
      startReveal();
      startMotion();
      coordinate(viewport);
      scheduleGeneration();
    } catch (error) {
      if (destroyed || candidate !== stream || epoch !== buildEpoch || error?.name === "AbortError") return;
      if (useWorker) fallbackToSynchronousStream(candidate);
      else console.error("Circuit field generation failed", error, streamOptions);
    }
  }

  function build(useWorker = true) {
    buildEpoch += 1;
    const epoch = buildEpoch;
    cancelGenerationRequest();
    generationPromise = null;
    window.cancelAnimationFrame(coordinatorFrame);
    coordinatorFrame = 0;
    clearAmbientClip();
    destroyAnimationSystems();
    unsubscribe?.();
    fallbackUnsubscribe?.();
    unsubscribe = undefined;
    fallbackUnsubscribe = undefined;
    reveal?.destroy();
    reveal = undefined;
    traceStager?.destroy();
    traceStager = undefined;
    materializedTraces.length = 0;
    stream?.destroy();
    stream = undefined;
    svg?.remove();
    svg = undefined;
    lastPixelWidth = canonicalPageWidth;
    logicalPixelHeight = Math.max(logicalPixelHeight, mount.clientHeight);
    pageWorldHeight = pagePixelHeight / worldScale();
    interactionTarget.style.minHeight = Math.ceil(logicalPixelHeight) + "px";
    const streamOptions = {
      ...config,
      width: lastPixelWidth / worldScale(),
      initialPageHeight: pagePixelHeight / worldScale(),
      chunkRows: generationChunkRows(),
    };
    streamUsesWorker = useWorker;
    stream = useWorker
      ? createStreamingCircuitFieldWorker(streamOptions)
      : createHybridCircuitField(streamOptions);
    const candidate = stream;
    if (useWorker) {
      fallbackUnsubscribe = candidate.onFallback(() => {
        fallbackToSynchronousStream(candidate);
      });
    }
    initializeStream(candidate, streamOptions, epoch, useWorker);
  }

  function onPointerMove(event) {
    if (!stream) return;
    const rect = mount.getBoundingClientRect();
    if (rect.width <= 0 || rect.height <= 0) return;
    pointer = {
      x: (event.clientX - rect.left) / rect.width * fieldFacade.width,
      y: (event.clientY - rect.top) / rect.height * fieldFacade.height,
      at: performance.now(),
    };
    conductor?.pointerMoved(pointer);
    handshake?.pointerMoved(pointer);
    reflection?.pointerMoved(pointer);
  }

  function onPointerLeave() {
    if (pointer) pointer.at = performance.now() - 3000;
    handshake?.pointerLeft();
    reflection?.pointerLeft();
  }

  function onClick(event) {
    onPointerMove(event);
    if (config.animationSystem === "conductor") conductor?.clicked(pointer);
    else if (config.animationSystem === "handshake") handshake?.clicked(pointer);
    else if (config.animationSystem === "reflection") reflection?.clicked(pointer);
  }

  function onMotionPreferenceChange(event) {
    reducedMotion = event.matches;
    if (reducedMotion) {
      stopMotion();
      reveal?.complete();
    } else {
      reveal?.start();
      startMotion();
    }
    scheduleAmbientClip();
  }

  function regenerate(nextOptions = {}) {
    if (destroyed) throw new Error("Cannot regenerate a destroyed circuit background");
    config = { ...config, ...nextOptions };
    build();
    coordinate();
    return api;
  }

  function setReveal(nextOptions = {}) {
    if (destroyed) throw new Error("Cannot update a destroyed circuit background");
    config = { ...config, ...nextOptions };
    reveal?.updateOptions(config);
    if (reducedMotion || !config.revealMotion) reveal?.complete();
    else reveal?.start();
    coordinate();
    return api;
  }

  function setAnimation(nextOptions = {}) {
    if (destroyed) throw new Error("Cannot update a destroyed circuit background");
    config = { ...config, ...nextOptions };
    destroyAnimationSystems();
    createAnimationSystems();
    startMotion();
    scheduleAmbientClip();
    return api;
  }

  function triggerAnimation(origin = null) {
    if (config.animationSystem === "conductor") return conductor?.trigger(origin) || false;
    if (config.animationSystem === "handshake") return handshake?.trigger(origin) || false;
    if (config.animationSystem === "reflection") return reflection?.trigger(origin) || false;
    return false;
  }

  function triggerReveal() {
    if (!reveal || reducedMotion || !config.revealMotion) return false;
    reveal.reset();
    reveal.start();
    coordinate();
    return true;
  }

  function setRevealProgress(progress, progressOptions = {}) {
    if (!reveal) return api;
    const amount = clamp(Number(progress) || 0);
    const height = viewportWorldHeight();
    const topWorldY = Math.max(0, (logicalWorldHeight() - height) * amount);
    reveal.setViewport({
      topWorldY,
      bottomWorldY: topWorldY + height,
      height,
      velocity: Math.max(0, Number(progressOptions.velocity) || 0),
    });
    traceStager?.materializeThrough(topWorldY + height + pageWorldHeight * 0.35);
    scheduleAmbientClip();
    return api;
  }

  function addExportVia(group, point) {
    const scale = featureScale();
    group.append(
      svgElement("circle", {
        cx: point[0],
        cy: point[1],
        r: config.viaOuterRadius * scale,
        fill: config.traceColor,
      }),
      svgElement("circle", {
        cx: point[0],
        cy: point[1],
        r: config.viaInnerRadius * scale,
        fill: "var(--circuit-hole, #0d1117)",
      }),
    );
  }

  function exportSvg() {
    const exportHeight = Math.max(logicalWorldHeight(), stream?.generatedThrough || 0);
    const exported = svgElement("svg", {
      xmlns: SVG_NS,
      "aria-hidden": true,
      focusable: false,
      viewBox: `0 0 ${fieldFacade.width} ${exportHeight}`,
      preserveAspectRatio: "none",
    });
    const paths = svgElement("g", { "data-static-traces": "" });
    const vias = svgElement("g", { "data-static-vias": "" });
    for (const trace of stream?.traces || []) {
      paths.append(svgElement("path", {
        d: pathData(trace.points),
        fill: "none",
        stroke: config.traceColor,
        "stroke-width": config.traceWidth * featureScale(),
        "stroke-linecap": "butt",
        "stroke-linejoin": "miter",
      }));
      addExportVia(vias, trace.points[0]);
      addExportVia(vias, trace.points.at(-1));
    }
    exported.append(paths, vias);
    return `<?xml version="1.0" encoding="UTF-8"?>\n${exported.outerHTML}`;
  }

  function destroy() {
    if (destroyed) return;
    destroyed = true;
    buildEpoch += 1;
    generationPromise = null;
    cancelGenerationRequest();
    window.cancelAnimationFrame(coordinatorFrame);
    window.cancelAnimationFrame(clipFrame);
    window.clearTimeout(resizeTimer);
    window.clearTimeout(ambientRefreshTimer);
    resizeObserver?.disconnect();
    window.removeEventListener("scroll", scheduleCoordinate);
    window.removeEventListener("resize", scheduleCoordinate);
    interactionTarget.removeEventListener("pointermove", onPointerMove);
    interactionTarget.removeEventListener("pointerleave", onPointerLeave);
    interactionTarget.removeEventListener("click", onClick);
    if (motionPreference.removeEventListener) {
      motionPreference.removeEventListener("change", onMotionPreferenceChange);
    } else {
      motionPreference.removeListener?.(onMotionPreferenceChange);
    }
    destroyAnimationSystems();
    unsubscribe?.();
    fallbackUnsubscribe?.();
    reveal?.destroy();
    traceStager?.destroy();
    materializedTraces.length = 0;
    stream?.destroy();
    svg?.remove();
    mount.style.position = originalMountPosition;
    mount.style.overflow = originalMountOverflow;
    interactionTarget.style.minHeight = originalTargetMinHeight;
  }

  const api = {
    regenerate,
    setReveal,
    setAnimation,
    triggerAnimation,
    triggerBloom: triggerAnimation,
    triggerReveal,
    setRevealProgress,
    exportSvg,
    destroy,
    get field() { return fieldFacade; },
    get animationStats() {
      if (config.animationSystem === "none") {
        return { system: "none", animationNodes: 0, frameCount: 0, reducedMotion };
      }
      if (config.animationSystem === "conductor") return conductor?.stats;
      if (config.animationSystem === "handshake") return handshake?.stats;
      if (config.animationSystem === "reflection") return reflection?.stats;
      return { system: "unknown", animationNodes: 0, frameCount: 0, reducedMotion };
    },
    get revealStats() {
      const stats = reveal?.stats || {};
      if (config.revealSystem === "instant") {
        return {
          system: "instant",
          continuous: false,
          traceCount: fieldFacade.traces.length,
          completed: true,
          generatedThrough: stream?.generatedThrough || 0,
          canonicalPageWorldHeight: pageWorldHeight,
          reducedMotion,
        };
      }
      return {
        system: "scroll-trace-reveal",
        continuous: continuousMode(),
        traceCount: fieldFacade.traces.length,
        generatedTraceCount: stream?.traces.length || 0,
        materializedTraceCount: traceStager?.stats.materializedTraces || 0,
        bufferedTraceCount: traceStager?.stats.bufferedTraces || 0,
        activeTraces: stats.active || 0,
        queuedTraces: stats.queued || 0,
        completedTraces: stats.completed || 0,
        unlockedTraces: stats.unlocked || 0,
        generatedThrough: stream?.generatedThrough || 0,
        pageWorldHeight: logicalWorldHeight(),
        canonicalPageWorldHeight: pageWorldHeight,
        reducedMotion,
      };
    },
  };

  build();
  resizeObserver = new ResizeObserver(() => {
    const nextWidth = canonicalWidthTracksViewport
      ? Math.max(1, window.innerWidth || mount.clientWidth)
      : Math.max(1, mount.clientWidth);
    if (Math.abs(nextWidth - lastPixelWidth) < 1) return;
    canonicalPageWidth = nextWidth;
    window.clearTimeout(resizeTimer);
    resizeTimer = window.setTimeout(() => {
      if (!destroyed) regenerate();
    }, 180);
  });
  resizeObserver.observe(mount);
  window.addEventListener("scroll", scheduleCoordinate, { passive: true });
  window.addEventListener("resize", scheduleCoordinate, { passive: true });
  if (config.interactive) {
    interactionTarget.addEventListener("pointermove", onPointerMove, { passive: true });
    interactionTarget.addEventListener("pointerleave", onPointerLeave, { passive: true });
    interactionTarget.addEventListener("click", onClick);
  }
  if (motionPreference.addEventListener) {
    motionPreference.addEventListener("change", onMotionPreferenceChange);
  } else {
    motionPreference.addListener?.(onMotionPreferenceChange);
  }
  coordinate();
  return api;
}

function normalizeOptions(options = {}) {
  const normalized = { ...options };
  if (normalized.animationSystem === "growth") {
    normalized.animationSystem = "none";
    if (!normalized.revealSystem) normalized.revealSystem = "flow";
    if (normalized.revealMotion === undefined) normalized.revealMotion = true;
  }
  if (normalized.spawnSystem && !normalized.revealSystem) {
    normalized.revealSystem = normalized.spawnSystem === "front"
      ? "flow"
      : normalized.spawnSystem;
  }
  return normalized;
}

export function createCircuitBackground(mount, options = {}) {
  let config = { ...DEFAULTS, ...normalizeOptions(options) };
  let destroyed = false;
  const engineKind = (value) => {
    if (value.animationSystem === "adom") return "routed";
    if (value.revealSystem === "flow") return "finite";
    if (value.revealSystem === "scroll") return "page-scroll";
    return "finite";
  };
  const createEngine = () => {
    const kind = engineKind(config);
    if (kind === "routed") {
      return createLegacyCircuitBackground(mount, { ...config, revealSystem: "instant" });
    }
    if (kind.startsWith("page-")) return createStreamingCircuitBackground(mount, config);
    return createModernCircuitBackground(mount, config);
  };
  let engine = createEngine();

  function recreateEngine() {
    engine.destroy();
    engine = createEngine();
  }

  const api = {
    regenerate(nextOptions = {}) {
      if (destroyed) throw new Error("Cannot regenerate a destroyed circuit background");
      const previousKind = engineKind(config);
      const normalized = normalizeOptions(nextOptions);
      config = { ...config, ...normalized };
      if (previousKind !== engineKind(config)) recreateEngine();
      else engine.regenerate(normalized);
      return api;
    },
    setReveal(nextOptions = {}) {
      if (destroyed) throw new Error("Cannot update a destroyed circuit background");
      const previousKind = engineKind(config);
      const normalized = normalizeOptions(nextOptions);
      config = { ...config, ...normalized };
      if (previousKind !== engineKind(config)) recreateEngine();
      else if (engineKind(config) !== "routed") engine.setReveal?.(normalized);
      return api;
    },
    setAnimation(nextOptions = {}) {
      if (destroyed) throw new Error("Cannot update a destroyed circuit background");
      const previousKind = engineKind(config);
      const normalized = normalizeOptions(nextOptions);
      config = { ...config, ...normalized };
      if (previousKind !== engineKind(config)) recreateEngine();
      else if (engineKind(config) === "routed") engine.regenerate(normalized);
      else engine.setAnimation(normalized);
      return api;
    },
    triggerAnimation(origin = null) {
      return engine.triggerAnimation?.(origin) || false;
    },
    triggerBloom(origin = null) {
      return engine.triggerBloom?.(origin) || engine.triggerAnimation?.(origin) || false;
    },
    triggerReveal() {
      if (engineKind(config) === "routed") return false;
      return engine.triggerReveal?.() || false;
    },
    setRevealProgress(progress, progressOptions) {
      if (engineKind(config) !== "routed") {
        engine.setRevealProgress?.(progress, progressOptions);
      }
      return api;
    },
    exportSvg() {
      return engine.exportSvg();
    },
    destroy() {
      if (destroyed) return;
      destroyed = true;
      engine.destroy();
    },
    get field() { return engine.field; },
    get animationStats() { return engine.animationStats; },
    get revealStats() {
      if (engineKind(config) === "routed") {
        return { system: "unavailable-routed", traceCount: engine.field?.traces.length || 0 };
      }
      return engine.revealStats;
    },
  };

  return api;
}

export {
  DEFAULTS,
  ANIMATION_PRESETS,
  REVEAL_PRESETS,
  TRACE_SPAWN_PRESETS,
  generateCircuitField,
  pathData,
};