window.opts = {}; window.localization = {}; window.titles = {}; let tabSelected = ''; let txt2img_textarea; let img2img_textarea; let fontSizeApplyRaf = 0; let pendingFontSize = null; let appliedFontSize = null; let cachedGradioRoot = null; const wait_time = 800; const token_timeouts = {}; let uiLoaded = false; let promptsInitialized = false; window.args_to_array = Array.from; // Compatibility with e.g. extensions that may expect this to be around function rememberGallerySelection(name) { // dummy } function set_theme(theme) { const gradioURL = window.location.href; if (!gradioURL.includes('?__theme=')) window.location.replace(`${gradioURL}?__theme=${theme}`); } function update_token_counter(button_id) { if (token_timeouts[button_id]) clearTimeout(token_timeouts[button_id]); token_timeouts[button_id] = setTimeout(() => gradioApp().getElementById(button_id)?.click(), wait_time); } function clip_gallery_urls(gallery) { const files = gallery.map((v) => v.data); navigator.clipboard.writeText(JSON.stringify(files)).then( () => log('clipboard:', files), (err) => error(`clipboard: ${files} ${err}`), ); } function isVisible(el) { if (!el) return false; const rect = el.getBoundingClientRect(); if (rect.width === 0 && rect.height === 0) return false; return (rect.top >= 0) && (rect.left >= 0) && (rect.bottom <= (window.innerHeight || document.documentElement.clientHeight)) && (rect.right <= (window.innerWidth || document.documentElement.clientWidth)); } function all_gallery_buttons() { let allGalleryButtons = gradioApp().querySelectorAll('[style="display: block;"].tabitem div[id$=_gallery].gradio-gallery .thumbnails > .thumbnail-item.thumbnail-small'); if (allGalleryButtons.length === 0) allGalleryButtons = gradioApp().querySelectorAll('.gradio-gallery .thumbnails > .thumbnail-item.thumbnail-small'); const visibleGalleryButtons = []; allGalleryButtons.forEach((elem) => { if (elem.parentElement.offsetParent) visibleGalleryButtons.push(elem); }); return visibleGalleryButtons; } function selected_gallery_button() { let allCurrentButtons = gradioApp().querySelectorAll('[style="display: block;"].tabitem div[id$=_gallery].gradio-gallery .thumbnail-item.thumbnail-small.selected'); if (allCurrentButtons.length === 0) allCurrentButtons = gradioApp().querySelectorAll('.gradio-gallery .thumbnails > .thumbnail-item.thumbnail-small.selected'); let visibleCurrentButton = null; allCurrentButtons.forEach((elem) => { if (elem.parentElement.offsetParent) visibleCurrentButton = elem; }); return visibleCurrentButton; } function selected_gallery_index() { const buttons = all_gallery_buttons(); const button = selected_gallery_button(); let result = -1; buttons.forEach((v, i) => { if (v === button) { result = i; } }); if (result === -1 && gradioApp().getElementById('tab-gallery-search')?.checkVisibility()) { const gallerySelection = window.getGallerySelection(); if (Number.isInteger(gallerySelection.index)) result = gallerySelection.index; } return result; } function selected_gallery_files(tabname) { let allImages = []; let allThumbnails; if (tabname && tabname !== 'gallery') allThumbnails = gradioApp().querySelectorAll('div[id$=_gallery].gradio-gallery .thumbnail-item.thumbnail-small'); else allThumbnails = gradioApp().querySelectorAll('.gradio-gallery .thumbnails > .thumbnail-item.thumbnail-small'); try { allImages = Array.from(allThumbnails).map((v) => v.querySelector('img')); if (tabname && tabname !== 'gallery') allImages = allImages.filter((img) => isVisible(img)); allImages = allImages.map((img) => { let fn = img.src; if (fn.includes('file=')) fn = fn.split('file=')[1]; return decodeURI(fn); }); } catch (err) { error(`selected_gallery_files: ${err}`); } let selectedIndex = -1; if (tabname && tabname !== 'gallery') selectedIndex = selected_gallery_index(); return [allImages, selectedIndex]; } function extract_image_from_gallery(gallery) { if (gallery.length === 0) return [null]; if (gallery.length === 1) return [gallery[0]]; let index = selected_gallery_index(); if (index < 0 || index >= gallery.length) index = 0; return [gallery[index]]; } function send_to_kanvas(gallery) { const [image] = extract_image_from_gallery(gallery); log('sendToKanvas', image); if (window.loadFromURL && image.data) window.loadFromURL(image.data); // const inputPanelEl = gradioApp().getElementById('control-template-column-input'); // if (inputPanelEl) inputPanelEl.classList.remove('hidden'); const inputPanelCb = gradioApp().getElementById('control_dynamic_input'); if (inputPanelCb && !inputPanelCb.checked) inputPanelCb.click(); } async function setTheme(val, old) { if (!old || val === old) return; old = old.replace('modern/', ''); val = val.replace('modern/', ''); const links = Array.from(document.getElementsByTagName('link')).filter((l) => l.href.includes(old)); if (links.length === 0) { log('setTheme: current theme not matched', old); return; } for (const link of links) { const href = link.href.replace(old, val); const res = await fetch(href); if (res.ok) { log('setTheme', old, val); link.href = link.href.replace(old, val); } else { log('setTheme: CSS not found', val); } } } function setFontSize(val, old) { const size = Number(val || opts.font_size); if (!Number.isFinite(size)) return; if (size === old || size === appliedFontSize || size === pendingFontSize) return; pendingFontSize = size; if (fontSizeApplyRaf) return; fontSizeApplyRaf = requestAnimationFrame(() => { const t0 = performance.now(); fontSizeApplyRaf = 0; const nextSize = pendingFontSize; pendingFontSize = null; if (!Number.isFinite(nextSize) || nextSize === appliedFontSize) return; cachedGradioRoot = cachedGradioRoot || gradioApp(); const rootStyle = cachedGradioRoot.style; document.documentElement.style.setProperty('--font-size', `${nextSize}px`); rootStyle.setProperty('--font-size', `${nextSize}px`); rootStyle.setProperty('--text-xxs', `${nextSize - 3}px`); rootStyle.setProperty('--text-xs', `${nextSize - 2}px`); rootStyle.setProperty('--text-sm', `${nextSize - 1}px`); rootStyle.setProperty('--text-md', `${nextSize}px`); rootStyle.setProperty('--text-lg', `${nextSize + 1}px`); rootStyle.setProperty('--text-xl', `${nextSize + 2}px`); rootStyle.setProperty('--text-xxl', `${nextSize + 3}px`); appliedFontSize = nextSize; const t1 = performance.now(); log('setFontSize', nextSize, `time=${Math.round(t1 - t0)}`); }); } function switchToTab(tab) { const tabs = Array.from(gradioApp().querySelectorAll('#tabs > .tab-nav > button')); const btn = tabs?.find((t) => t.innerText === tab); log('switchToTab', tab); if (btn) btn.click(); } function switch_to_txt2img(...args) { switchToTab('Text'); return Array.from(arguments); } function switch_to_img2img_tab(no) { switchToTab('Image'); gradioApp().getElementById('mode_img2img').querySelectorAll('button')[no].click(); } function switch_to_img2img(...args) { switchToTab('Image'); switch_to_img2img_tab(0); return Array.from(arguments); } function switch_to_inpaint(...args) { switchToTab('Image'); switch_to_img2img_tab(1); return Array.from(arguments); } function switch_to_sketch(...args) { switchToTab('Image'); switch_to_img2img_tab(2); return Array.from(arguments); } function switch_to_composite(...args) { switchToTab('Image'); switch_to_img2img_tab(3); return Array.from(arguments); } function switch_to_extras(...args) { switchToTab('Process'); return Array.from(arguments); } function switch_to_control(...args) { switchToTab('Control'); return Array.from(arguments); } function switch_to_video(...args) { switchToTab('Video'); return Array.from(arguments); } function switch_to_caption(...args) { switchToTab('Caption'); return Array.from(arguments); } function get_tab_index(tabId) { let res = 0; gradioApp().getElementById(tabId)?.querySelector('div').querySelectorAll('button') .forEach((button, i) => { if (button.className.indexOf('selected') !== -1) res = i; }); return res; } function create_tab_index_args(tabId, args) { const res = Array.from(args); res[0] = get_tab_index(tabId); return res; } function get_img2img_tab_index(...args) { const res = Array.from(arguments); res.splice(-2); res[0] = get_tab_index('mode_img2img'); return res; } function create_submit_args(args) { const res = Array.from(args); if (Array.isArray(res[res.length - 3])) res[res.length - 3] = null; return res; } function showSubmitButtons(tabname, show) {} function clearGallery(tabname) { const gallery = gradioApp().getElementById(`${tabname}_gallery`); gallery.classList.remove('logo'); // gallery.style.height = window.innerHeight - gallery.getBoundingClientRect().top - 200 + 'px' const footer = gradioApp().getElementById(`${tabname}_footer`); footer.style.display = 'flex'; } function submit_txt2img(...args) { log('submitTxt'); clearGallery('txt2img'); const id = randomId(); requestProgress(id, null, gradioApp().getElementById('txt2img_gallery')); const res = create_submit_args(args); res[0] = id; res[1] = window.submit_state; window.submit_state = ''; return res; } function submit_img2img(...args) { log('submitImg'); clearGallery('img2img'); const id = randomId(); requestProgress(id, null, gradioApp().getElementById('img2img_gallery')); const res = create_submit_args(args); res[0] = id; res[1] = window.submit_state; res[2] = get_tab_index('mode_img2img'); window.submit_state = ''; return res; } function submit_control(...args) { log('submitControl'); clearGallery('control'); const id = randomId(); requestProgress(id, null, gradioApp().getElementById('control_gallery')); const res = create_submit_args(args); res[0] = id; res[1] = window.submit_state; const tabs = Array.from(gradioApp().querySelectorAll('#control-tabs > .tab-nav > button')); const tabIdx = tabs.findIndex((btn) => btn.classList.contains('selected')); const tabNames = ['ControlNet', 'T2I Adapter', 'XS', 'Lite', 'Reference']; const selectedTab = tabNames[tabIdx] || 'ControlNet'; res[2] = selectedTab.toLowerCase(); window.submit_state = ''; return res; } function submit_video(...args) { log('submitVideo'); clearGallery('video'); const id = randomId(); requestProgress(id, null, gradioApp().getElementById('video_gallery')); const res = create_submit_args(args); res[0] = id; res[1] = window.submit_state; window.submit_state = ''; return res; } function submit_framepack(...args) { const id = randomId(); log('submitFramepack', id); requestProgress(id, null, null); window.submit_state = ''; args[0] = id; return args; } function submit_ltx(...args) { const id = randomId(); log('submitFramepack', id); requestProgress(id, null, null); window.submit_state = ''; args[0] = id; return args; } function submit_video_wrapper(...args) { const modernEl = gradioApp().querySelector('.video_output.fade-in'); let id = modernEl ? modernEl.id : args[0]; id = id.replace('video-selector-', ''); log('submitVideoWrapper', id); const btn = gradioApp().getElementById(`${id}_generate_btn`); if (btn) btn.click(); } function submit_postprocessing(...args) { log('SubmitExtras'); clearGallery('extras'); return args; } window.submit = submit_txt2img; window.submit_state = ''; function modelmerger(...args) { const id = randomId(); const res = create_submit_args(args); res[0] = id; return res; } function clearPrompts(prompt, negative_prompt) { prompt = ''; negative_prompt = ''; return [prompt, negative_prompt]; } const promptTokenCountUpdateFuncs = {}; const registeredPromptTextareas = new WeakSet(); const registeredPromptIds = new Set(); const pendingCounterPlacement = new Set(); const promptRegistrationConfig = [ ['txt2img_prompt', 'txt2img_token_counter', 'txt2img_token_button'], ['txt2img_neg_prompt', 'txt2img_negative_token_counter', 'txt2img_negative_token_button'], ['img2img_prompt', 'img2img_token_counter', 'img2img_token_button'], ['img2img_neg_prompt', 'img2img_negative_token_counter', 'img2img_negative_token_button'], ['control_prompt', 'control_token_counter', 'control_token_button'], ['control_neg_prompt', 'control_negative_token_counter', 'control_negative_token_button'], ]; let promptRegistrationRaf = 0; let promptRegistrationCursor = 0; let promptRegistrationInProgress = false; function scheduleIdleUI(task) { if (typeof window.requestIdleCallback === 'function') { window.requestIdleCallback(task, { timeout: 500 }); } else { setTimeout(task, 0); } } function recalculatePromptTokens(name) { if (promptTokenCountUpdateFuncs[name]) { promptTokenCountUpdateFuncs[name](); } } function recalculate_prompts_txt2img(...args) { recalculatePromptTokens('txt2img_prompt'); recalculatePromptTokens('txt2img_neg_prompt'); return Array.from(arguments); } function recalculate_prompts_img2img(...args) { recalculatePromptTokens('img2img_prompt'); recalculatePromptTokens('img2img_neg_prompt'); return Array.from(arguments); } function recalculate_prompts_inpaint(...args) { recalculatePromptTokens('img2img_prompt'); recalculatePromptTokens('img2img_neg_prompt'); return Array.from(arguments); } function recalculate_prompts_control(...args) { recalculatePromptTokens('control_prompt'); recalculatePromptTokens('control_neg_prompt'); return Array.from(arguments); } function registerDragDrop() { const qs = gradioApp().getElementById('quicksettings'); if (!qs) return; qs.addEventListener('dragover', (evt) => { evt.preventDefault(); evt.dataTransfer.dropEffect = 'copy'; }); qs.addEventListener('drop', (evt) => { evt.preventDefault(); evt.dataTransfer.dropEffect = 'copy'; for (const f of evt.dataTransfer.files) { log('QuickSettingsDrop', f); } }); } function sortUIElements() { // sort top-level tabs const currSelected = gradioApp()?.querySelector('.tab-nav > .selected')?.innerText; if (currSelected === tabSelected || !opts.ui_tab_reorder) return; tabSelected = currSelected; const tabs = gradioApp().getElementById('tabs')?.children[0]; if (!tabs) return; let tabsOrder = opts.ui_tab_reorder?.split(',').map((el) => el.trim().toLowerCase()) || []; for (const el of Array.from(tabs.children)) { const elIndex = tabsOrder.indexOf(el.innerText.toLowerCase()); if (elIndex > -1) el.style.order = elIndex - 50; // default is 0 so setting to negative values } // sort always-on scripts const find = (el, ordered) => { for (const i in ordered) { if (el.innerText.toLowerCase().startsWith(ordered[i])) return i; } return 99; }; tabsOrder = opts.ui_scripts_reorder?.split(',').map((el) => el.trim().toLowerCase()) || []; const scriptsTxt = gradioApp().getElementById('scripts_alwayson_txt2img').children; for (const el of Array.from(scriptsTxt)) el.style.order = find(el, tabsOrder); const scriptsImg = gradioApp().getElementById('scripts_alwayson_img2img').children; for (const el of Array.from(scriptsImg)) el.style.order = find(el, tabsOrder); log('sortUIElements'); } function registerTextareaCallback() { // sortUIElements(); if (promptsInitialized) return; if (promptRegistrationInProgress) return; const app = gradioApp(); if (!app) return; const registerTextarea = (id, id_counter, id_button) => { const prompt = app.getElementById(id); const counter = app.getElementById(id_counter); const localTextarea = prompt?.querySelector('label > textarea'); if (!prompt || !counter || !localTextarea || !prompt.parentElement) return false; const promptParent = prompt.parentElement; const needsCounterPlacement = counter.parentElement !== promptParent || counter.nextElementSibling !== prompt; if (needsCounterPlacement && !pendingCounterPlacement.has(id)) { pendingCounterPlacement.add(id); scheduleIdleUI(() => { pendingCounterPlacement.delete(id); const currentPrompt = app.getElementById(id); const currentCounter = app.getElementById(id_counter); if (!currentPrompt || !currentCounter || !currentPrompt.parentElement) return; const currentParent = currentPrompt.parentElement; if (currentCounter.parentElement !== currentParent || currentCounter.nextElementSibling !== currentPrompt) { currentParent.insertBefore(currentCounter, currentPrompt); } if (currentParent.style.position !== 'relative') { currentParent.style.position = 'relative'; } }); } if (!promptTokenCountUpdateFuncs[id]) promptTokenCountUpdateFuncs[id] = () => { update_token_counter(id_button); }; if (!registeredPromptTextareas.has(localTextarea)) { localTextarea.addEventListener('input', promptTokenCountUpdateFuncs[id]); registeredPromptTextareas.add(localTextarea); } return true; }; const runPromptRegistrationStep = () => { promptRegistrationRaf = 0; const total = promptRegistrationConfig.length; let cfg = null; // Process one prompt registration per frame to avoid long blocking work. for (let attempts = 0; attempts < total; attempts += 1) { const nextCfg = promptRegistrationConfig[promptRegistrationCursor]; promptRegistrationCursor = (promptRegistrationCursor + 1) % total; const [id] = nextCfg; if (!registeredPromptIds.has(id)) { cfg = nextCfg; break; } } if (cfg) { const [id] = cfg; if (registerTextarea(...cfg)) { registeredPromptIds.add(id); } else { // Prompt not available yet, retry on next onAfterUiUpdate callback. promptRegistrationInProgress = false; return; } } promptsInitialized = registeredPromptIds.size === total; if (promptsInitialized) { promptRegistrationInProgress = false; log('initPrompts', registeredPromptIds.size); return; } promptRegistrationRaf = requestAnimationFrame(runPromptRegistrationStep); }; promptRegistrationInProgress = true; promptRegistrationRaf = requestAnimationFrame(runPromptRegistrationStep); } onAfterUiUpdate(registerTextareaCallback); function update_txt2img_tokens(...args) { update_token_counter('txt2img_token_button'); if (args.length === 2) return args[0]; return args; } function update_img2img_tokens(...args) { update_token_counter('img2img_token_button'); if (args.length === 2) return args[0]; return args; } function getTranslation(...args) { return null; } function monitorServerStatus() { document.open(); document.write(`