openvisengine/src/lib/version.ts
2026-10-29 08:32:21 +00:00

208 lines
15 KiB
TypeScript
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// OVE — app identity + version stamp.
//
// Single source of truth for the product name and version shown in the UI
// (header, footer, document title). Bump APP_VERSION whenever we ship a
// large change so the running build can always be identified at a glance —
// useful both for the z.ai Version History and for naming local backups
// (v6.0 = rename to Open Visualization Engine + version indicator).
//
// History:
// 7.5.1 — Link dialog width fix: text no longer escapes the dialog box.
// Root cause: Radix dialogs lay their children in an implicit CSS
// grid whose single column sizes to the widest child's min-content;
// the RECENT LINKS rows carry truncate spans (white-space: nowrap),
// and Chromium measures a nowrap flex item's full text width for
// that measurement — so a long saved title (e.g. "Bobby Foxx — This
// Is Why We Can't Have Nice Things (Official Music Video)") blew
// the column ~40 px past the 448 px dialog, and EVERY child (title,
// description, input + Load, rows, footer) laid out beyond the
// right border. Fix: the shared Dialog/AlertDialog content now pins
// the column to minmax(0,1fr) — capped at the available width, so
// no nowrap content can ever stretch a dialog again (covers every
// dialog app-wide) — the Link dialog widened to max-w-lg for
// comfier wrapping, and min-w-0 + break-words added on the
// recents/playlist containers and error text as belt-and-braces
// 7.5 — yt-dlp compatibility: single tracks resolve by DOWNLOAD + CONVERT
// instead of proxying the extractor's stream URL. The old stream
// URLs were IP-locked (googlevideo bakes in the resolver's IP),
// expired within hours, and arrived as webm/opus — a container
// Safari & co. refuse ("The media resource … was not suitable").
// The server now runs the operator's pipeline per track:
// yt-dlp -f bestaudio/best -x --audio-format mp3
// --audio-quality 0 -o "<dir>/%(title)s.%(ext)s" URL
// — audio-only download, universal MP3 at VBR-0 (~245 kbps), the
// video's real title preserved for the Playing: label. The
// finished file streams same-origin with full Range support from
// a per-track workspace dir (30-min sliding TTL + orphan sweeper);
// /api/audio/stream gained a file-serving mode. Hardening around
// it: shared failure classifier for both yt-dlp passes (metadata +
// download), 180 s download budget, 300 MB cap, bot-wall/stale-
// extractor answers unchanged, ffmpeg-missing degrades to the old
// proxy path (logged once), queue look-ahead lead 15 s → 60 s so
// playlist transitions don't stall behind conversions
// 7.4 — Sequence mode: a second mix checkbox next to Random. Ticked, it
// cycles the scope folder's presets IN ORDER (the tree's exact
// top-to-bottom order) instead of shuffling — and when it moves
// past the last preset it wraps back to the first, so the folder
// loops forever. Random and Sequence are mutually exclusive
// (ticking either one unticks the other; both share the same
// delay and folder scope), Random now never loads the same preset
// twice in a row, and Sequence holds its breath through silence
// exactly like Random does. The Demo showcase now runs SEQUENCE —
// the one play-through walks every Zai-Magic preset in order
// (20 s each) rather than repeating random picks, and when the
// demo stops, whichever mode it checked is unchecked again
// 7.3 — demo-flow refinements: the Demo Track is a single pass — it plays
// "Neural Mecha Pulse" once through and stops (a demo, not a radio
// station). However it ends (natural finish, Stop, or switching to
// another source) the showcase unwinds: the randomizer the Demo
// flow force-checked is unchecked again, and the visitor lands
// back on the "Select an audio source" overlay. Preset-change
// popups are gone ("Preset loaded" / "Random preset" / "Default
// preset running") — the footer's SCRIPT: label already echoes
// every change, so the toasts were pure intrusion; only compile
// errors still toast. Club-mode randomizer now respects silence:
// when no music is playing it never re-shuffles the selected
// preset, even with the checkbox on — it waits for the next track
// 7.2.1 — Supernova (Zai-Magic) preset fix: the particle kill condition
// (|px|+|py| > 2.4) was physically unreachable — drag caps a
// particle's total travel at vel/1.6 ≈ 1.0, so nothing ever
// crossed 1.4, nothing ever died, and since respawning requires a
// dead particle, the per-beat "budget = n" detonation could never
// fire after the initial one — the preset exploded once on load,
// then faded to permanent black. Now every beat force-clears the
// whole 620-particle field in [beat] (guaranteed full re-detonation
// on the very same frame), fully-cooled particles die by fade so
// long beat gaps leave a gentle ember drizzle instead of black,
// and each blast re-randomizes its geometry (no two explosions
// alike). Embedded library re-seeded (seed marker 7.01)
// 7.2 — new-visitor showcase flow. Defaults for first-time visitors:
// the Black + Purple Outline theme with the Blue highlight
// (previously royal purple + yellow), and Zai-Magic "Bass Bloom"
// as the startup preset (previously the first Synth-C classic).
// The idle overlay's Demo Track button now carries an animated
// reflective shimmer (skewed light band sweeping left→right every
// 3.2 s, reduced-motion safe) to draw the click — and that one
// click starts the full showcase: the demo track plays while the
// preset tree selects + expands Zai-Magic, randomize switches on
// scoped to that folder with a 20-second change interval. Music
// started with NO preset active (own draft running / selection
// cleared) auto-loads Bass Bloom. Preset changes — manual load,
// the random mix, the Demo flow — no longer hard-cut: the engine
// snapshots the outgoing frame and blur-dissolves it into the new
// preset over 700 ms (progressive blur + easeOutCubic fade + a
// slight scale-up so the softening edges never gap; plain
// crossfade where ctx.filter is unsupported)
// 7.1 — real demo track + a beat detector that survives real music.
// The Demo button now plays "Neural Mecha Pulse" (the operator's
// mastered industrial-EDM banger, public/demo-track.mp3, loops
// gaplessly) instead of the synthetic techno pattern — a real
// recording is the honest test: deep sub for the bass bands,
// driving mids, crisp highs, and a kick buried in sustained
// sub-bass. That last part exposed the 6.x detector as fundamentally
// broken on mastered music: a LEVEL threshold can never see the
// kick through the sub (peak-to-mean caps at ~1.2× → sporadic
// fires, phantom 120-BPM locks from the minInterval floor).
// v7.1 rewrites detection the way real beat trackers work
// (aubio/librosa-style): a full-band spectral-flux ONSET envelope
// → autocorrelation over 300–1000 ms lags with a log-BPM prior →
// comb-filter phase with grid hysteresis → beats fired on an
// absolute grid kept glued by a PLL pull. Headlessly validated
// against the actual track PCM (AnalyserNode chain replicated
// frame-for-frame): locks the true ~133 BPM (the song drifts
// 130.7→133.1 — the grid TRACKS it) in 1.9 s, 92% beat-gap
// regularity, confidence 0.99 through the body; techno/hip-hop
// patterns lock exactly; silence yields zero beats. Known limit:
// sparse kick-vs-snare backbeats (dnb) may lock half-tempo —
// stable, and two taps of Set Beat correct it. Visitor-stored
// beat configs migrate (floorLevel changed units, level → flux).
// The demo BPM slider is gone (a real track's tempo is detected,
// not dialed in) — replaced by a track-name chip in the header
// 7.00 — Zai-Magic: ten hand-authored presets in root/embedded/Zai-Magic
// built around BEAT-SYNCED COLOR — the color wheel turns on the
// kick, palettes swap per beat / per 4-beat bar, megabuf particles
// remember the hue of the beat that spawned them + new script
// tools: hsvr/hsvg/hsvb (HSV→RGB channels), smoothstep and the
// beatage kick-envelope variable — all documented in the help
// panel. (Numbered 7.00 rather than 6.10 — a new preset family
// plus new script-language features is a major release; 6.9.3 was
// the last patch of the 6.x line.) Beat engine fixes underneath so
// the Demo track actually
// locks tempo (was sporadic): demo synth remixed for detection
// (hot kick owning the 20–100 Hz band, off-beat bassline voiced
// C3+ with a sidechain pump — chronological envelope events!),
// and the detector's default threshold 1.4 → 1.2 (the 170 ms FFT
// window caps a clean kick's peak-to-mean at ~1.5×, so 1.4 fired
// only sporadically and the BPM never locked)
// 6.9.3 — canonical domain fix: metadataBase/og:url/og:image pointed at
// openvisualengine.com (a DEAD domain baked in by 6.9.1) while the
// real site is openvisengine.com — Facebook's "corrupted image"
// error was its crawler fetching the image from a host that serves
// nothing; all share URLs now use the correct short domain
// 6.9.2 — share-image fix: og:image re-encoded as BASELINE JPEG (the
// 6.9.1 progressive encoding rendered fine in every browser but
// Facebook's Sharing Debugger rejected it as "corrupted"), swapped
// in the title-card artwork (gradient wordmark over three
// visualizations) and added a ?v=2 cache-bust so crawlers fetch it
// 6.9.1 — social share preview: Open Graph + Twitter Card metadata with
// a 1200×630 screenshot of the app (public/og-image.jpg) — sharing
// openvisualengine.com on Facebook/X/WhatsApp/Discord now shows the
// big image card instead of a bare link
// 6.9 — house account: anonymous visitors play YouTube links through
// the operator's shared disposable-account cookie (server-side
// fallback under secrets/, never exposed) — YouTube bot walls stop
// applying to guests; visitor's own login always wins. Engine fix
// underneath: Deno runtime shipped in bin/ (YouTube requires a JS
// runtime for signature/n-challenge solving on authenticated
// sessions — without it, logged-in extractions return no formats)
// 6.8.2 — login friction cut to ~4 clicks: the exported cookies.txt /
// Cookie-Editor JSON file can be dragged straight onto the
// login box (or picked via “Import the exported file…”) — no
// opening the file, no copy/paste; “Log out” / sign-out
// revocation note added (the official Google OAuth flow can't
// power the site: Google's APIs never hand out stream URLs and
// restricted-scope verification would reject an audio player)
// 6.8.1 — cookie login made foolproof: the login dialog recognizes raw
// Cookie headers, cookies.txt exports AND Cookie-Editor JSON,
// validates the paste LIVE through one shared parser (a single
// cookie's value — like a bare LOGIN_INFO string — gets an honest
// "this will not log you in" warning), and the how-to steps lead
// with the one-click extension export for Chrome AND Firefox
// 6.8 — self-healing audio engine: when YouTube changes their mechanics
// the server detects the stale extractor, updates yt-dlp in the
// background (verified GitHub release download, atomic swap) and the
// player retries seamlessly behind an "Updating in Background"
// notice; bot walls answer "Google login required…" with an Open
// Settings action, and unfixable failures get the honest
// "A back-end problem has occurred. Please try again later."
// 6.7 — lazy playlist queue: a playlist link becomes a queue of URLs that
// streams ONE song at a time (each track is resolved by yt-dlp only
// right before it plays — next-track look-ahead at ≤15 s to go),
// queue bar with skip/jump/replay + server-side caps (max 2 parallel
// extractions); music-service framework: Spotify + Apple Music are
// registered providers whose playback ships in a later update
// (logins already save, links answer with an honest notice)
// 6.6 — music service logins (Settings tab): YouTube / YouTube Music,
// SoundCloud, Spotify, Apple Music cookie login, encrypted on the
// visitor's computer; Link button gains playlist picking + uses the
// login to bypass bot walls
// 6.5 — Settings tab (replaces the parked Native tab): theme picker with
// base chrome (Royal Purple / Matte Black / Black + Purple Outline /
// Light) × selectable highlight color (Purple, Yellow, Blue, Green,
// Red, Orange), all per-visitor; simple OVE logo as the site favicon
// 6.4 — beat detection suspends when no music is playing/loaded (no ghost
// beats after Stop, BPM resets) + dark theme restyle: royal purple
// chrome with light-yellow highlights
// 6.3 — light/dark theme tick switch in the header (white theme via .light
// palette remap; per-visitor, persisted by next-themes)
// 6.2 — security hardening: read-only embedded library (server refuses all
// writes) + per-visitor "user created" presets stored in the browser
// 6.1 — preset library quality pass: every embedded stand-in is now a UNIQUE
// generated visual (16 families × seeded parameters), approx badge
// 6.0 — renamed to "Open Visualization Engine" + footer version stamp
// 5.0 — folder-tree Presets page (Task 9–11 state, restored in Task 12)
// 4.0 — link audio source (yt-dlp resolve + stream proxy)
export const APP_NAME = 'Open Visualization Engine'
export const APP_SHORT = 'OVE'
export const APP_VERSION = '7.5.1'