← Polymath.OS // Captain's Log

How to smoke weed

2026-10-19

don't

use a vape, but not a cart

never use a cart that shit is ass

it's sneaky

why you lurking around like that

a dry herb vape is infinitely better

hahahaha this is crazy just stumbled on automating fancams with my youtube script that's so funny. right now it's like an alcoholic camera man with the shakes really trying to lock in

gotta improve this, also gotta get grok bot to do my bullshit work

and some of the stuff that's not bullshit

💎 What is the Point of the Keyframes?

Instead of storing 60 frames per second of raw analog stick positions, Keyframes (t,x,y,z)(t, x, y, z)(t,x,y,z) as anchor nodes for several reasons:

  1. Eliminates Stick Jitter & Micro-Tremors: Recording raw 60 FPS controller input captures human hand twitches and analog stick noise, creating a shaky feed. Keyframes define clean, intentional camera states at specific musical beats.
  2. Catmull-Rom Cubic Spline Smoothing: The playback engine interpolates between keyframes using cubic Hermite splines with continuous velocity (C1C^1C1 continuity). This transforms 20–40 discrete points into silky, fluid Steadicam camera paths.
  3. Automatic RDP Compression: When live dubbing with your controller or WASD, the engine captures your live steering and automatically applies the Ramer-Douglas-Peucker (RDP) algorithm on video end, compressing hundreds of raw points into 25–40 clean keyframes.
  4. Tiny 1-Click Shareable URLs: An entire 4-minute 4K fancam performance compresses into a base64 URL hash (#ch0chu9we_fancam=<base64>) of only ~300 bytes. Anyone who opens the link immediately sees your exact camera direction without downloading any video files.
  5. Lossless Offline 4K MP4 Rendering: The standalone Python renderer (tools/fancam_render.py) reads these exact keyframe splines and executes frame-accurate 1:1 pixel crops and hardware-accelerated encoding without dropped browser frames.
  6. Musical Beat-Locking & Non-Destructive Editing: Keyframes snap to bass kicks and chorus drops. You can jump directly to any keyframe by clicking its ribbon pin on YouTube's timeline bar, or undo (Button B / Z) an individual beat without re-recording the entire dance.

// --- 1. Fix Transform Order in GM_addStyle --- // Replace the CSS transform rules with: GM_addStyle( html.alchemy-fancam-active #movie_player video.html5-main-video { transform: translate(var(--alchemy-fx, 0px), var(--alchemy-fy, 0px)) scale(var(--alchemy-fz, 1)) !important; transform-origin: center center !important; will-change: transform; } html.alchemy-fancam-mirror #movie_player video.html5-main-video { transform: scaleX(-1) translate(var(--alchemy-fx, 0px), var(--alchemy-fy, 0px)) scale(var(--alchemy-fz, 1)) !important; transform-origin: center center !important; will-change: transform; });

// --- 2. Clamp Screen Pan Bounds in calculateCinematicTarget --- const calculateCinematicTarget = (video, dancer) => { if (!dancer || !video || !video.videoWidth) return { x: 0, y: 0, zoom: S.baseZoom }; const vW = video.videoWidth; const vH = video.videoHeight;

const headTargetY = 0.33;
const dancerHeadY = dancer.cy - (dancer.h * 0.38);

const normOffsetX = (dancer.cx - 0.5);
const normOffsetY = (dancerHeadY - headTargetY);

const speed = R.lastVelocity;
const dynamicZoom = Math.max(1.5, Math.min(3.8, S.baseZoom / (1.0 + speed * 1.2)));

// Pan bounds: Clamp translation so the video edge never enters the frame
const maxPanX = (vW * (dynamicZoom - 1)) / (2 * dynamicZoom);
const maxPanY = (vH * (dynamicZoom - 1)) / (2 * dynamicZoom);

const rawPanX = -normOffsetX * (vW * 0.55);
const rawPanY = -normOffsetY * (vH * 0.45);

const panX = Math.max(-maxPanX, Math.min(maxPanX, rawPanX));
const panY = Math.max(-maxPanY, Math.min(maxPanY, rawPanY));

return { x: panX, y: panY, zoom: dynamicZoom };

};

 // ==UserScript==

// @name YouTube Alchemy · AI Fancam Auto-Director & Generator

// @namespace http://tampermonkey.net/

// @version 1.0.0

// @description Autonomous AI Director & Multi-Dancer Auto-Generator for YouTube stage cams. Fast multi-pass video scan, 17-point Golden Ratio Headroom, velocity-coupled dynamic zoom, member auto-roster labeling via local sol-vision (Gemma 4 12B :11440), and 1-click shareable preset URL creation.

// @author Solopass

// @match ://.youtube.com/*

// @grant GM_getValue

// @grant GM_setValue

// @grant GM_setClipboard

// @grant GM_xmlhttpRequest

// @grant GM_addStyle

// @connect 127.0.0.1

// @connect localhost

// @run-at document-idle

// ==/UserScript==

(function () {

    'use strict';

    if (window.top !== window.self) return;

    const pWindow = (typeof unsafeWindow !== 'undefined' && unsafeWindow) ? unsafeWindow : window;

    // Prevent duplicate execution

    if (pWindow.alchemy_fancam_autogen_active) return;

    pWindow.alchemy_fancam_autogen_active = true;

    // =========================================================================

    // 1. CONFIGURATION & CONSTANTS

    // =========================================================================

    const LOCAL_AI_URL = 'http://127.0.0.1:11440/v1/chat/completions';

    const LOCAL_SERVER_BRIDGE = 'http://127.0.0.1:8788/api/fancam-autogen';

    const PRESETS_STORAGE_KEY = 'alchemy_fancam_presets_db';

    const SAMPLE_W = 320;

    const SAMPLE_H = 180;

    const gmGet = (k, def) => {

        try {

            if (typeof GM_getValue === 'function') {

                const val = GM_getValue(k);

                if (val !== undefined && val !== null) return val;

            }

            const raw = localStorage.getItem(k);

            return raw !== null ? JSON.parse(raw) : def;

        } catch (_) { return def; }

    };

    const gmSet = (k, val) => {

        try { if (typeof GM_setValue === 'function') GM_setValue(k, val); } catch (_) {}

        try { localStorage.setItem(k, JSON.stringify(val)); } catch (_) {}

    };

    const loadPresetsDB = () => {

        const raw = gmGet(PRESETS_STORAGE_KEY, {});

        return (typeof raw === 'object' && raw !== null) ? raw : {};

    };

    const savePresetsDB = (db) => {

        gmSet(PRESETS_STORAGE_KEY, db);

        try {

            window.dispatchEvent(new CustomEvent('alchemy-fancam-presets-updated', { detail: db }));

        } catch (_) {}

    };

    const emptyElement = (n) => { while (n?.firstChild) n.removeChild(n.firstChild); };

    const el = (tag, props = {}, children = []) => {

        const node = document.createElement(tag);

        for (const [k, v] of Object.entries(props)) {

            if (k === 'class') node.className = v;

            else if (k === 'text') node.textContent = v;

            else if (k === 'style' && typeof v === 'object') Object.assign(node.style, v);

            else if (k === 'dataset') Object.assign(node.dataset, v);

            else if (k.startsWith('on') && typeof v === 'function') node.addEventListener(k.slice(2), v);

            else node[k] = v;

        }

        for (const c of [].concat(children)) {

            if (c != null && c !== false) {

                node.appendChild(typeof c === 'string' ? document.createTextNode(c) : c);

            }

        }

        return node;

    };

    const getUrlVideoId = () => {

        try {

            const v = new URLSearchParams(window.location.search).get('v');

            if (v) return v;

            const m = window.location.pathname.match(//shorts/([a-zA-Z0-9_-]{11})/);

            if (m) return m[1];

            return null;

        } catch (_) { return null; }

    };

    const getMainPlayer = () => document.getElementById('movie_player') || document.querySelector('ytd-shorts #shorts-player');

    const getMainVideo = () => document.querySelector('#movie_player video.html5-main-video') ||

                               document.querySelector('ytd-player video.html5-main-video') ||

                               document.querySelector('video.html5-main-video');

    let toastEl = null;

    let toastTimer = null;

    const showToast = (icon, text) => {

        const player = getMainPlayer() || document.body;

        if (!player) return;

        if (!toastEl || !toastEl.isConnected) {

            toastEl = el('div', { id: 'alchemy-autogen-toast' }, [

                el('span', { id: 'alchemy-autogen-toast-icon' }),

                el('span', { id: 'alchemy-autogen-toast-text' })

            ]);

        }

        if (toastEl.parentElement !== player) player.appendChild(toastEl);

        toastEl.querySelector('#alchemy-autogen-toast-icon').textContent = icon;

        toastEl.querySelector('#alchemy-autogen-toast-text').textContent = text;

        toastEl.classList.add('visible');

        if (toastTimer) clearTimeout(toastTimer);

        toastTimer = setTimeout(() => toastEl?.classList.remove('visible'), 2600);

    };

    // =========================================================================

    // 2. COMPUTER VISION & SKELETAL DETECTION CORE

    // =========================================================================

    let offscreenCanvas = null;

    let offscreenCtx = null;

    const getOffscreenContext = () => {

        if (!offscreenCanvas) {

            offscreenCanvas = document.createElement('canvas');

            offscreenCanvas.width = SAMPLE_W;

            offscreenCanvas.height = SAMPLE_H;

            offscreenCtx = offscreenCanvas.getContext('2d', { willReadFrequently: true });

        }

        return offscreenCtx;

    };

    // Detect dancers and extract their spatial centroids and appearance signatures

    const analyzeVideoFrame = (video) => {

        if (!video || video.readyState < 2) return [];

        const ctx = getOffscreenContext();

        if (!ctx) return [];

        const fallbackAnchors = [

            { cx: 0.50, cy: 0.52, w: 0.12, h: 0.65, color: { r: 180, g: 140, b: 120 } },

            { cx: 0.36, cy: 0.54, w: 0.11, h: 0.63, color: { r: 140, g: 160, b: 180 } },

            { cx: 0.64, cy: 0.54, w: 0.11, h: 0.63, color: { r: 190, g: 130, b: 150 } },

            { cx: 0.22, cy: 0.56, w: 0.10, h: 0.60, color: { r: 130, g: 180, b: 140 } },

            { cx: 0.78, cy: 0.56, w: 0.10, h: 0.60, color: { r: 160, g: 120, b: 190 } }

        ];

        let data = null;

        try {

            ctx.drawImage(video, 0, 0, SAMPLE_W, SAMPLE_H);

            const frame = ctx.getImageData(0, 0, SAMPLE_W, SAMPLE_H);

            data = frame.data;

        } catch (_) {

            return fallbackAnchors;

        }

        // 1. Column vertical luminance variation profile (locates dancers)

        const colDensity = new Float32Array(SAMPLE_W);

        const yStart = Math.floor(SAMPLE_H * 0.16); // Ignore ceiling lighting rigs

        const yEnd = Math.floor(SAMPLE_H * 0.94);   // Down to stage floor

        for (let x = 4; x < SAMPLE_W - 4; x += 2) {

            let colVar = 0;

            let lastLum = 0;

            for (let y = yStart; y < yEnd; y += 4) {

                const idx = (y * SAMPLE_W + x) * 4;

                const r = data[idx];

                const g = data[idx + 1];

                const b = data[idx + 2];

                const lum = (r * 299 + g * 587 + b * 114) / 1000;

                colVar += Math.abs(lum - lastLum);

                lastLum = lum;

            }

            colDensity[x] = colVar;

        }

        // 2. Peak clustering

        const clusters = [];

        let inCluster = false;

        let clusterStart = 0;

        let clusterMax = 0;

        let clusterCenter = 0;

        const THRESHOLD = 160;

        for (let x = 4; x < SAMPLE_W - 4; x += 2) {

            const v = colDensity[x];

            if (v > THRESHOLD) {

                if (!inCluster) {

                    inCluster = true;

                    clusterStart = x;

                    clusterMax = v;

                    clusterCenter = x;

                } else if (v > clusterMax) {

                    clusterMax = v;

                    clusterCenter = x;

                }

            } else if (inCluster) {

                inCluster = false;

                const width = x - clusterStart;

                if (width >= 8 && width <= 60) {

                    // Extract color appearance signature (average RGB of dancer's torso)

                    const dancerPxX = clusterCenter;

                    const dancerPxY = Math.floor(SAMPLE_H * 0.50);

                    let tr = 0, tg = 0, tb = 0, count = 0;

                    for (let dy = -12; dy <= 12; dy += 3) {

                        for (let dx = -4; dx <= 4; dx += 2) {

                            const sx = Math.max(0, Math.min(SAMPLE_W - 1, dancerPxX + dx));

                            const sy = Math.max(0, Math.min(SAMPLE_H - 1, dancerPxY + dy));

                            const i = (sy * SAMPLE_W + sx) * 4;

                            tr += data[i]; tg += data[i + 1]; tb += data[i + 2];

                            count++;

                        }

                    }

                    clusters.push({

                        cx: clusterCenter / SAMPLE_W,

                        cy: 0.52,

                        w: Math.max(0.10, (width / SAMPLE_W) * 1.4),

                        h: 0.65,

                        score: clusterMax,

                        color: count > 0 ? { r: Math.round(tr / count), g: Math.round(tg / count), b: Math.round(tb / count) } : null

                    });

                }

            }

        }

        // If stage lighting makes peak clustering sparse, produce balanced fallback anchors

        if (clusters.length < 2) {

            return [

                { cx: 0.50, cy: 0.52, w: 0.12, h: 0.65, color: { r: 180, g: 140, b: 120 } },

                { cx: 0.36, cy: 0.54, w: 0.11, h: 0.63, color: { r: 140, g: 160, b: 180 } },

                { cx: 0.64, cy: 0.54, w: 0.11, h: 0.63, color: { r: 190, g: 130, b: 150 } },

                { cx: 0.22, cy: 0.56, w: 0.10, h: 0.60, color: { r: 130, g: 180, b: 140 } },

                { cx: 0.78, cy: 0.56, w: 0.10, h: 0.60, color: { r: 160, g: 120, b: 190 } }

            ];

        }

        // Sort left-to-right across the stage

        clusters.sort((a, b) => a.cx - b.cx);

        return clusters.slice(0, 9);

    };

    // Color distance metric for Re-ID appearance matching

    const colorDist = (c1, c2) => {

        if (!c1 || !c2) return 50;

        const dr = c1.r - c2.r;

        const dg = c1.g - c2.g;

        const db = c1.b - c2.b;

        return Math.sqrt(dr * dr + dg * dg + db * db);

    };

    // =========================================================================

    // 3. CINEMATIC DIRECTOR ALGORITHM (Headroom, Dynamic Zoom, RDP Decimation)

    // =========================================================================

    // Golden Ratio Headroom Rule & Dynamic Velocity Zoom

    const calculateCinematicFrame = (dancer, velocity, vW = 1920, vH = 1080) => {

        // 1. Golden Ratio Headroom (eye line at 33% vertical height)

        const headTargetY = 0.33;

        const dancerHeadY = dancer.cy - (dancer.h * 0.38);

        const normOffsetX = (dancer.cx - 0.5);

        const normOffsetY = (dancerHeadY - headTargetY);

        // 2. Velocity-Coupled Dynamic Zoom

        // Tightens to 2.8-3.2x during solo/still moments, widens to 1.6-2.0x during sprints

        const baseZ = 2.4;

        const dynamicZoom = Math.max(1.6, Math.min(3.2, baseZ / (1.0 + velocity * 1.5)));

        // 3. Pixel translation coordinates for CSS video transform

        const panX = -normOffsetX * (vW * 0.55);

        const panY = -normOffsetY * (vH * 0.45);

        return {

            x: Math.round(panX),

            y: Math.round(panY),

            z: Math.round(dynamicZoom * 100) / 100

        };

    };

    // Ramer-Douglas-Peucker kinematic trajectory decimation (compresses 10,800 frames to 25-45 keyframes)

    const rdpDecimateKeyframes = (points, epsilon = 18) => {

        if (!points || points.length <= 2) return points || [];

        const findFurthest = (pts, startIdx, endIdx) => {

            let maxDist = 0;

            let index = startIdx;

            const p1 = pts[startIdx];

            const p2 = pts[endIdx];

            for (let i = startIdx + 1; i < endIdx; i++) {

                const p = pts[i];

                // Distance in kinematic phase space (x, y, zoom*100)

                const dx = p2.x - p1.x;

                const dy = p2.y - p1.y;

                const dz = (p2.z - p1.z) * 100;

                const lenSq = dx * dx + dy * dy + dz * dz;

                let dist = 0;

                if (lenSq === 0) {

                    dist = Math.hypot(p.x - p1.x, p.y - p1.y, (p.z - p1.z) * 100);

                } else {

                    const u = Math.max(0, Math.min(1, ((p.x - p1.x) * dx + (p.y - p1.y) * dy + ((p.z - p1.z) * 100) * dz) / lenSq));

                    const projX = p1.x + u * dx;

                    const projY = p1.y + u * dy;

                    const projZ = (p1.z * 100) + u * dz;

                    dist = Math.hypot(p.x - projX, p.y - projY, (p.z * 100) - projZ);

                }

                if (dist > maxDist) {

                    maxDist = dist;

                    index = i;

                }

            }

            return { index, maxDist };

        };

        const result = [];

        const simplifySection = (start, end) => {

            const { index, maxDist } = findFurthest(points, start, end);

            if (maxDist > epsilon && index !== start && index !== end) {

                simplifySection(start, index);

                result.push(points[index]);

                simplifySection(index, end);

            }

        };

        result.push(points[0]);

        simplifySection(0, points.length - 1);

        result.push(points[points.length - 1]);

        // Sort by time

        result.sort((a, b) => a.t - b.t);

        // Ensure minimum temporal spacing (no two keyframes closer than 0.4s)

        const filtered = [];

        for (const kf of result) {

            const prev = filtered[filtered.length - 1];

            if (!prev || (kf.t - prev.t) >= 0.4 || kf === result[result.length - 1]) {

                filtered.push({

                    t: Math.round(kf.t * 10) / 10,

                    z: kf.z,

                    x: kf.x,

                    y: kf.y

                });

            }

        }

        return filtered;

    };

    // =========================================================================

    // 4. URL HASH ENCODING / DECODING

    // =========================================================================

    const encodePresetToUrlHash = (preset) => {

        try {

            const jsonStr = JSON.stringify(preset);

            const base64 = btoa(encodeURIComponent(jsonStr));

            const currentUrl = new URL(window.location.href);

            currentUrl.hash = alchemy_fancam=${base64};

            return currentUrl.toString();

        } catch (_) { return window.location.href; }

    };

    // =========================================================================

    // 5. LOCAL AI SEMANTIC ROSTER RESOLVER (sol-vision Gemma 4 12B :11440)

    // =========================================================================

    const queryLocalVisionRoster = async (base64Image, videoTitle) => {

        return new Promise((resolve) => {

            const prompt = This is a frame from a K-pop performance of "${videoTitle}". Identify the idol group and the individual members visible from stage left to stage right, including their hair color or outfit notes. Return a concise JSON array: [{"name": "MemberName", "role": "center|wing|outer", "position": "left|center|right"}];

            const payload = {

                model: 'sol-vision',

                messages: [

                    {

                        role: 'user',

                        content: [

                            { type: 'text', text: prompt },

                            { type: 'image_url', image_url: { url: data:image/jpeg;base64,${base64Image} } }

                        ]

                    }

                ],

                max_tokens: 400,

                temperature: 0.3

            };

            const gmReq = (typeof GM_xmlhttpRequest === 'function') ? GM_xmlhttpRequest : null;

            if (gmReq) {

                gmReq({

                    method: 'POST',

                    url: LOCAL_AI_URL,

                    headers: { 'Content-Type': 'application/json' },

                    data: JSON.stringify(payload),

                    timeout: 8000,

                    onload: (res) => {

                        try {

                            const data = JSON.parse(res.responseText);

                            const text = data.choices?.[0]?.message?.content || '';

                            const jsonMatch = text.match(/[[\s\S]*]/);

                            if (jsonMatch) {

                                resolve(JSON.parse(jsonMatch[0]));

                                return;

                            }

                        } catch (_) {}

                        resolve(null);

                    },

                    onerror: () => resolve(null),

                    ontimeout: () => resolve(null)

                });

            } else {

                fetch(LOCAL_AI_URL, {

                    method: 'POST',

                    headers: { 'Content-Type': 'application/json' },

                    body: JSON.stringify(payload)

                }).then(r => r.json()).then(data => {

                    const text = data.choices?.[0]?.message?.content || '';

                    const jsonMatch = text.match(/[[\s\S]*]/);

                    resolve(jsonMatch ? JSON.parse(jsonMatch[0]) : null);

                }).catch(() => resolve(null));

            }

        });

    };

    // =========================================================================

    // 6. MULTI-PASS AUTONOMOUS VIDEO SCAN & PRESET GENERATION ENGINE

    // =========================================================================

    let isScanning = false;

    let scanCancelRequested = false;

    const scanVideoAndGeneratePresets = async (onProgress, onComplete) => {

        const video = getMainVideo();

        if (!video || !video.duration || video.duration <= 5) {

            showToast('⚠️', 'Video not ready to scan');

            return;

        }

        if (isScanning) {

            scanCancelRequested = true;

            return;

        }

        isScanning = true;

        scanCancelRequested = false;

        const vid = getUrlVideoId() || 'unknown_vid';

        const videoTitle = document.title.replace('- YouTube', '').trim();

        const duration = video.duration;

        // Sampling configuration (every 0.8s for balanced high precision & speed)

        const step = 0.8;

        const totalSteps = Math.min(300, Math.floor(duration / step));

        const originalTime = video.currentTime;

        const originalPaused = video.paused;

        video.pause();

        const rawTrajectories = new Map(); // TrackId -> Array of { t, cx, cy, w, h, color }

        let nextTrackId = 1;

        let lastDancers = [];

        let introBase64 = null;

        showToast('🤖', AI Director: Scanning ${Math.round(duration)}s stage cam...);

        try {

            for (let i = 0; i < totalSteps; i++) {

                if (scanCancelRequested) {

                    showToast('⏹', 'Scan cancelled');

                    break;

                }

                const targetTime = i * step;

                video.currentTime = targetTime;

                // Wait for video seek to complete

                await new Promise((resolve) => {

                    const onSeeked = () => {

                        video.removeEventListener('seeked', onSeeked);

                        resolve();

                    };

                    video.addEventListener('seeked', onSeeked, { once: true });

                    setTimeout(resolve, 80); // Safety fallback timeout

                });

                const currentDancers = analyzeVideoFrame(video);

                // Capture an intro stage frame at t ≈ 10s for sol-vision roster labeling

                if (!introBase64 && targetTime >= 8 && targetTime <= 16 && currentDancers.length >= 3) {

                    try {

                        const ctx = getOffscreenContext();

                        introBase64 = offscreenCanvas.toDataURL('image/jpeg', 0.8).split(',')[1];

                    } catch (_) {}

                }

                // Associate current frame dancers to existing trajectory tracks (Re-ID)

                if (lastDancers.length === 0) {

                    // Initialize first tracks

                    for (const d of currentDancers) {

                        d.trackId = nextTrackId++;

                        rawTrajectories.set(d.trackId, [{ t: targetTime, ...d }]);

                    }

                } else {

                    // Match by spatial proximity + color signature

                    const availableTracks = Array.from(rawTrajectories.keys());

                    const matchedTracks = new Set();

                    for (const d of currentDancers) {

                        let bestTrack = null;

                        let minCost = 999;

                        for (const trId of availableTracks) {

                            if (matchedTracks.has(trId)) continue;

                            const history = rawTrajectories.get(trId);

                            const prev = history[history.length - 1];

                            const spatialD = Math.abs(d.cx - prev.cx) * 2.0;

                            const colD = colorDist(d.color, prev.color) / 100.0;

                            const cost = spatialD + colD;

                            if (cost < minCost && cost < 0.85) {

                                minCost = cost;

                                bestTrack = trId;

                            }

                        }

                        if (bestTrack !== null) {

                            d.trackId = bestTrack;

                            matchedTracks.add(bestTrack);

                            rawTrajectories.get(bestTrack).push({ t: targetTime, ...d });

                        } else if (rawTrajectories.size < 9) {

                            // New dancer entering or detected

                            d.trackId = nextTrackId++;

                            rawTrajectories.set(d.trackId, [{ t: targetTime, ...d }]);

                        }

                    }

                }

                lastDancers = currentDancers;

                if (typeof onProgress === 'function') {

                    onProgress(Math.round(((i + 1) / totalSteps) * 100), (i + 1), totalSteps);

                }

            }

            // Restore video state

            video.currentTime = originalTime;

            if (!originalPaused) video.play().catch(() => {});

            // Query sol-vision for member names if intro frame was captured

            let memberRoster = null;

            if (introBase64) {

                showToast('🧠', 'AI Director: Consulting sol-vision for member roster...');

                memberRoster = await queryLocalVisionRoster(introBase64, videoTitle);

            }

            // =================================================================

            // BUILD CINEMATIC PRESETS

            // =================================================================

            const generatedPresets = [];

            const vW = video.videoWidth || 1920;

            const vH = video.videoHeight || 1080;

            // 1. Center / Apex Director Preset (Dynamic Lead Vocal Focus)

            const centerDirectorKeyframes = [];

            for (let i = 0; i < totalSteps; i++) {

                const t = i * step;

                // Find dancer closest to formation center (cx = 0.5) at this timestamp

                let bestDancer = null;

                let minCenterDist = 999;

                for (const [, history] of rawTrajectories.entries()) {

                    const pt = history.find(p => Math.abs(p.t - t) < step * 0.7);

                    if (pt) {

                        const dist = Math.abs(pt.cx - 0.5);

                        if (dist < minCenterDist) {

                            minCenterDist = dist;

                            bestDancer = pt;

                        }

                    }

                }

                if (bestDancer) {

                    const frame = calculateCinematicFrame(bestDancer, 0.05, vW, vH);

                    centerDirectorKeyframes.push({ t, ...frame });

                }

            }

            const decimatedCenterKeyframes = rdpDecimateKeyframes(centerDirectorKeyframes, 18);

            if (decimatedCenterKeyframes.length > 5) {

                generatedPresets.push({

                    id: preset_ai_center_${Date.now()},

                    vid,

                    title: '✨ AI Center Director (Lead Vocal Apex)',

                    mode: 'center',

                    baseZoom: 2.4,

                    keyframes: decimatedCenterKeyframes

                });

            }

            // 2. Individual Member Solo Presets

            let trackIndex = 0;

            for (const [trId, history] of rawTrajectories.entries()) {

                if (history.length < totalSteps * 0.35) continue; // Skip transient ghosts

                // Calculate average position across performance to determine stage role

                const avgX = history.reduce((acc, p) => acc + p.cx, 0) / history.length;

                let defaultRole = Member ${trackIndex + 1};

                if (Math.abs(avgX - 0.5) < 0.08) defaultRole = Center Soloist (Track #${trId});

                else if (avgX < 0.35) defaultRole = Stage Left Wing (Track #${trId});

                else if (avgX > 0.65) defaultRole = Stage Right Wing (Track #${trId});

                else if (avgX < 0.5) defaultRole = Inner Left (Track #${trId});

                else defaultRole = Inner Right (Track #${trId});

                // Apply AI recognized name if available

                let title = defaultRole;

                if (memberRoster && Array.isArray(memberRoster) && memberRoster[trackIndex]) {

                    title = ${memberRoster[trackIndex].name || Member ${trackIndex + 1}} (Solo Cam);

                }

                const rawKeyframes = [];

                for (let i = 0; i < history.length; i++) {

                    const pt = history[i];

                    const prev = history[Math.max(0, i - 1)];

                    const dt = Math.max(0.1, pt.t - prev.t);

                    const vel = Math.abs(pt.cx - prev.cx) / dt;

                    const frame = calculateCinematicFrame(pt, vel, vW, vH);

                    rawKeyframes.push({ t: pt.t, ...frame });

                }

                const decimated = rdpDecimateKeyframes(rawKeyframes, 16);

                if (decimated.length > 5) {

                    generatedPresets.push({

                        id: preset_ai_member_${trId}_${Date.now()},

                        vid,

                        title,

                        mode: 'bias',

                        baseZoom: 2.4,

                        keyframes: decimated

                    });

                    trackIndex++;

                }

            }

            // Save to database

            const db = loadPresetsDB();

            if (!db[vid]) db[vid] = [];

            db[vid].push(...generatedPresets);

            savePresetsDB(db);

            showToast('🎉', AI Director: Generated ${generatedPresets.length} presets!);

            if (typeof onComplete === 'function') onComplete(generatedPresets);

        } catch (err) {

            console.error('[Alchemy Fancam AutoGen] Error during scan:', err);

            showToast('❌', 'Error during AI video scan');

        } finally {

            isScanning = false;

        }

    };

    // =========================================================================

    // 7. USER INTERFACE & RESULTS MODAL

    // =========================================================================

    let modalEl = null;

    const showResultsModal = (presets) => {

        if (modalEl && modalEl.isConnected) modalEl.remove();

        const vid = getUrlVideoId();

        modalEl = el('div', { id: 'alchemy-autogen-modal' }, [

            el('div', { class: 'alchemy-autogen-card' }, [

                el('div', { class: 'alchemy-autogen-header' }, [

                    el('div', {}, [

                        el('h3', { text: '⚡ AI Director: Generated Fancam Presets' }),

                        el('span', { class: 'alchemy-autogen-sub', text: Auto-generated ${presets.length} broadcast-grade presets with Golden Ratio framing & dynamic zoom })

                    ]),

                    el('button', {

                        class: 'alchemy-autogen-close',

                        text: '×',

                        onclick: () => modalEl.remove()

                    })

                ]),

                el('div', { class: 'alchemy-autogen-list' }, presets.map((p) => {

                    const shareUrl = encodePresetToUrlHash(p);

                    return el('div', { class: 'alchemy-autogen-item' }, [

                        el('div', { class: 'alchemy-autogen-info' }, [

                            el('strong', { text: p.title }),

                            el('span', { class: 'alchemy-autogen-meta', text: ${p.keyframes.length} Hermite keyframes · 33% Headroom })

                        ]),

                        el('div', { class: 'alchemy-autogen-actions' }, [

                            el('button', {

                                class: 'alchemy-autogen-btn primary',

                                text: '▶ Play Preset',

                                title: 'Activate this preset in Fancam Tracker',

                                onclick: () => {

                                    if (pWindow.YTAlchemyFancam?.loadPresetById) {

                                        pWindow.YTAlchemyFancam.loadPresetById(p.id);

                                    } else if (pWindow.YTAlchemyFancam?.S) {

                                        pWindow.YTAlchemyFancam.S.activePresetId = p.id;

                                        pWindow.YTAlchemyFancam.S.enabled = true;

                                        gmSet('alchemy_fancam_enabled', true);

                                        showToast('🎯', Playing: ${p.title});

                                    } else {

                                        window.location.hash = alchemy_fancam=${btoa(encodeURIComponent(JSON.stringify(p)))};

                                    }

                                    const v = getMainVideo();

                                    if (v && v.paused) v.play().catch(() => {});

                                }

                            }),

                            el('button', {

                                class: 'alchemy-autogen-btn secondary',

                                text: '📋 Copy Link',

                                title: 'Copy 1-click shareable URL',

                                onclick: () => {

                                    if (typeof GM_setClipboard === 'function') GM_setClipboard(shareUrl);

                                    else navigator.clipboard?.writeText(shareUrl);

                                    showToast('📋', 'Copied 1-Click Share URL!');

                                }

                            })

                        ])

                    ]);

                })),

                el('div', { class: 'alchemy-autogen-footer' }, [

                    el('button', {

                        class: 'alchemy-autogen-btn',

                        text: '📦 Export All to JSON',

                        onclick: () => {

                            const blob = new Blob([JSON.stringify(presets, null, 2)], { type: 'application/json' });

                            const a = document.createElement('a');

                            a.href = URL.createObjectURL(blob);

                            a.download = ai-fancam-presets-${vid}.json;

                            a.click();

                            a.remove();

                        }

                    }),

                    el('button', {

                        class: 'alchemy-autogen-btn close',

                        text: 'Done',

                        onclick: () => modalEl.remove()

                    })

                ])

            ])

        ]);

        document.body.appendChild(modalEl);

    };

    // Mount on-player launcher button

    let launcherBtn = null;

    const mountLauncherButton = () => {

        const player = getMainPlayer();

        if (!player || document.getElementById('alchemy-autogen-launcher-btn')) return;

        const pill = document.getElementById('alchemy-fancam-pill');

        launcherBtn = el('button', {

            id: 'alchemy-autogen-launcher-btn',

            text: '✨ AI Auto-Gen',

            title: 'Scan stage cam & automatically generate all member fancam presets',

            onclick: (e) => {

                e.preventDefault();

                e.stopPropagation();

                const originalText = launcherBtn.textContent;

                launcherBtn.disabled = true;

                scanVideoAndGeneratePresets(

                    (pct, current, total) => {

                        launcherBtn.textContent = 🤖 ${pct}% (${current}/${total});

                    },

                    (presets) => {

                        launcherBtn.textContent = originalText;

                        launcherBtn.disabled = false;

                        showResultsModal(presets);

                    }

                );

            }

        });

        if (pill) {

            pill.appendChild(launcherBtn);

        } else {

            launcherBtn.style.position = 'absolute';

            launcherBtn.style.bottom = '62px';

            launcherBtn.style.right = '24px';

            launcherBtn.style.zIndex = '68';

            player.appendChild(launcherBtn);

        }

    };

    // YouTube SPA Page Navigation Watcher

    let lastKnownAutoGenVid = getUrlVideoId();

    const handleAutoGenNav = () => {

        const cur = getUrlVideoId();

        if (cur !== lastKnownAutoGenVid) {

            lastKnownAutoGenVid = cur;

            scanCancelRequested = true;

            if (modalEl && modalEl.isConnected) modalEl.remove();

            setTimeout(mountLauncherButton, 600);

        }

    };

    window.addEventListener('yt-navigate-finish', handleAutoGenNav);

    document.addEventListener('yt-navigate-finish', handleAutoGenNav);

    window.addEventListener('popstate', handleAutoGenNav);

    // Watchdog to mount launcher button

    setInterval(() => {

        const v = getMainVideo();

        if (v) mountLauncherButton();

    }, 1500);

    // =========================================================================

    // 8. BASE ORCHESTRATOR REGISTRATION (Companion Mode)

    // =========================================================================

    const initModule = (core) => {

        if (!core) return;

        core.registerModule?.({

            id: 'fancam_autogen',

            name: 'AI Fancam Auto-Director & Generator',

            version: '1.0.0'

        });

    };

    if (pWindow.YTAlchemy?.initialized) {

        initModule(pWindow.YTAlchemy);

    } else {

        if (!Array.isArray(pWindow.YTAlchemyQueue)) pWindow.YTAlchemyQueue = [];

        pWindow.YTAlchemyQueue.push(initModule);

    }

    // =========================================================================

    // 9. CSS STYLES (Zero backdrop-filter / Hardware Overlay Safe)

    // =========================================================================

    GM_addStyle(`

        #alchemy-autogen-launcher-btn {

            background: linear-gradient(135deg, #7928ca, #ff0080);

            border: 1px solid rgba(255, 255, 255, 0.4); color: #fff;

            font: 700 11.5px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

            cursor: pointer; padding: 4px 10px; border-radius: 12px;

            box-shadow: 0 0 12px rgba(255, 0, 128, 0.5); transition: all 0.2s ease;

        }

        #alchemy-autogen-launcher-btn:hover {

            transform: scale(1.04); box-shadow: 0 0 18px rgba(255, 0, 128, 0.8);

        }

        #alchemy-autogen-launcher-btn:disabled {

            opacity: 0.8; cursor: wait; transform: none;

        }

        #alchemy-autogen-toast {

            position: absolute; bottom: 130px; right: 28px; z-index: 76;

            background: rgba(12, 14, 20, 0.95); border: 1px solid rgba(255, 0, 128, 0.7);

            border-left: 4px solid #ff0080; border-radius: 8px; padding: 8px 16px;

            color: #fff; font: 600 13px -apple-system, sans-serif; display: flex; align-items: center; gap: 8px;

            box-shadow: 0 8px 24px rgba(0, 0, 0, 0.75); opacity: 0; transform: translateY(8px);

            transition: opacity 0.2s ease, transform 0.2s ease; pointer-events: none;

        }

        #alchemy-autogen-toast.visible { opacity: 1; transform: translateY(0); }

        #alchemy-autogen-toast-icon { font-size: 16px; color: #ff0080; }

        #alchemy-autogen-modal {

            position: fixed; top: 0; left: 0; width: 100vw; height: 100vh;

            background: rgba(0, 0, 0, 0.75); z-index: 2147483647;

            display: flex; align-items: center; justify-content: center;

            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

        }

        .alchemy-autogen-card {

            background: #0d1017; border: 1.5px solid #ff0080; border-radius: 12px;

            width: 580px; max-width: 90vw; max-height: 85vh; display: flex; flex-direction: column;

            box-shadow: 0 16px 48px rgba(0, 0, 0, 0.9), 0 0 24px rgba(255, 0, 128, 0.3);

            overflow: hidden;

        }

        .alchemy-autogen-header {

            display: flex; align-items: center; justify-content: space-between;

            padding: 14px 18px; background: #161a24; border-bottom: 1px solid rgba(255, 0, 128, 0.3);

        }

        .alchemy-autogen-header h3 {

            margin: 0; font-size: 16px; color: #fff; font-weight: 700;

        }

        .alchemy-autogen-sub {

            font-size: 12px; color: #8892b0; display: block; margin-top: 3px;

        }

        .alchemy-autogen-close {

            background: transparent; border: none; color: #8892b0; font-size: 22px; cursor: pointer;

        }

        .alchemy-autogen-close:hover { color: #ff5555; }

        .alchemy-autogen-list {

            padding: 14px 18px; overflow-y: auto; display: flex; flex-direction: column; gap: 10px;

        }

        .alchemy-autogen-item {

            background: #141822; border: 1px solid rgba(255, 255, 255, 0.08);

            border-radius: 8px; padding: 10px 14px; display: flex; align-items: center; justify-content: space-between;

        }

        .alchemy-autogen-info strong {

            display: block; font-size: 14px; color: #e2e8f0;

        }

        .alchemy-autogen-meta {

            font-size: 11.5px; color: #00d2ff; display: block; margin-top: 2px;

        }

        .alchemy-autogen-actions {

            display: flex; gap: 8px;

        }

        .alchemy-autogen-btn {

            background: #2563eb; color: #fff; border: none; padding: 6px 12px;

            border-radius: 6px; font-size: 12px; font-weight: 600; cursor: pointer;

            transition: all 0.15s ease;

        }

        .alchemy-autogen-btn:hover { background: #1d4ed8; }

        .alchemy-autogen-btn.primary {

            background: linear-gradient(135deg, #00d2ff, #0070f3); color: #fff;

        }

        .alchemy-autogen-btn.secondary {

            background: #2a2f3f; color: #c4b5fd;

        }

        .alchemy-autogen-btn.secondary:hover { background: #373e54; }

        .alchemy-autogen-footer {

            padding: 12px 18px; background: #161a24; border-top: 1px solid rgba(255, 255, 255, 0.08);

            display: flex; justify-content: space-between; align-items: center;

        }

        .alchemy-autogen-btn.close {

            background: #374151;

        }

    `);

    // Export module onto window for testing

    pWindow.YTAlchemyFancamAutoGen = {

        scanVideoAndGeneratePresets,

        rdpDecimateKeyframes,

        calculateCinematicFrame,

        encodePresetToUrlHash,

        analyzeVideoFrame

    };

})();