| window.state = window.state || {}; |
| state = window.state; |
| let selectingQueue = 0; |
|
|
| state.utils = { |
|
|
| testFunction: function testFunction() { |
| |
| |
| |
| value = "新建文件夹\\anything-v5-PrtRE.safetensors" |
| value = value.replace("/","\\") |
| parts = value.split("\\") |
| console.log(parts[parts.length - 1]) |
| }, |
|
|
| target_is_newer_version: function(cur_version, target_version){ |
|
|
| let cur = cur_version.replace("v","") |
| cur = cur.split(".") |
|
|
| let target = target_version.replace("v","") |
| target = target.split(".") |
| let version_len = Math.min(cur.length, target.length) |
|
|
| |
| for (let i=0; i < version_len; i++){ |
| if(Number(cur[i]) > Number(target[i])){ |
| return false |
| } |
| else if(Number(cur[i]) < Number(target[i])){ |
| return true |
| } |
| } |
|
|
| |
| if(cur.length >= target.length){ |
| return false |
| } |
|
|
| return true |
| }, |
|
|
| searchCheckPointByHash: async function searchCheckPointByHash(hash){ |
| let downloadUrl = undefined |
| hash_str = hash.replace("[","").replace("]","").replace(/^\s+|\s+$/g,"") |
| await fetch("https://civitai.com/api/v1/model-versions/by-hash/"+hash_str) |
| .then(response => response.json()) |
| .then(data => { |
| |
| |
| for (file of data["files"]){ |
| for (key of Object.keys(file["hashes"])){ |
| if(file["hashes"][key].toLowerCase() === hash_str.toLowerCase()) |
| { |
| downloadUrl = file["downloadUrl"] |
| console.log(downloadUrl) |
| break |
| } |
| } |
| } |
| if(downloadUrl == undefined){downloadUrl = data["files"][0]["downloadUrl"]} |
| |
| }).catch(function(e) { |
| console.log("search model error!"); |
| }); |
|
|
| return downloadUrl |
| }, |
|
|
| getTranslation: function getTranslation(key){ |
| new_key = key |
| try{ |
| if(window.localization[new_key.replace(/^\s+|\s+$/g,"")] != undefined){ |
| new_key = window.localization[new_key] |
| } |
| } catch (error) { |
| console.warn('getTranslation error:', error); |
| } |
| return new_key |
| }, |
|
|
| reverseTranslation: function reverseTranslation(key){ |
| new_key = [] |
| try{ |
| |
| for (localize_key of Object.keys(window.localization)) { |
| if(key.replace(/^\s+|\s+$/g,"") === window.localization[localize_key].replace(/^\s+|\s+$/g,"")){ |
| tmp_key = localize_key |
| new_key.push(tmp_key) |
| |
| } |
| } |
| } catch (error) { |
| console.warn('reverseTranslation error:', error); |
| } |
|
|
| if(new_key.length == 0){new_key.push(key)} |
| |
| |
| return new_key |
| }, |
|
|
| sleep: function sleep(time) { |
| return new Promise((resolve) => setTimeout(resolve, time)); |
| }, |
|
|
| switch_to_img_inpaint: function switch_to_img_inpaint() { |
| switch_to_img2img_tab(4); |
| return Array.from(arguments); |
| }, |
| switch_to_txt2img_ControlNet: function switch_to_txt2img_ControlNet(unit) { |
|
|
| switch_to_txt2img() |
|
|
| let elem = undefined |
| elem = gradioApp().getElementById('txt2img_controlnet') |
| elem = elem.querySelector("#controlnet") |
|
|
| try{ |
| if(elem.className.split(' ').pop() != "open"){ |
| state.utils.triggerMouseEvent(elem, 'click') |
| } |
| for(e of elem.children){ |
| if(e.className.split(' ').pop() != "open"){ |
| state.utils.triggerMouseEvent(e, 'click') |
| } |
| } |
| } catch(error){console.log(error)} |
|
|
| try{ |
| gradioApp().getElementById('txt2img_controlnet_tabs').querySelectorAll('button')[Number(unit)].click() |
| } catch (error) { |
| console.warn('[switch_to_txt2img_ControlNet]: Error:', error); |
| } |
| }, |
| switch_to_img2img_ControlNet: function switch_to_img2img_ControlNet(unit) { |
| |
| switch_to_img2img() |
| |
| let elem = undefined |
| elem = gradioApp().getElementById('img2img_controlnet') |
| elem = elem.querySelector("#controlnet") |
| |
| try{ |
| if(elem.className.split(' ').pop() != "open"){ |
| state.utils.triggerMouseEvent(elem, 'click') |
| } |
| for(e of elem.children){ |
| if(e.className.split(' ').pop() != "open"){ |
| state.utils.triggerMouseEvent(e, 'click') |
| } |
| } |
| } catch(error){console.log(error)} |
|
|
| try{ |
| gradioApp().getElementById('img2img_controlnet_tabs').querySelectorAll('button')[Number(unit)].click() |
| } catch (error) { |
| console.warn('[switch_to_img2img_ControlNet]: Error:', error); |
| } |
| }, |
| triggerEvent: function triggerEvent(element, event) { |
| if (! element) { |
| return; |
| } |
| element.dispatchEvent(new Event(event.trim())); |
| return element; |
| }, |
| triggerMouseEvent: function triggerMouseEvent(element, event) { |
| if (! element) { |
| return; |
| } |
| event = event || 'click'; |
| element.dispatchEvent(new MouseEvent(event, { |
| view: window, |
| bubbles: true, |
| cancelable: true, |
| })); |
| return element; |
| }, |
| setValue: function setValue(element, value, event) { |
| switch (element.type) { |
| case 'checkbox': |
| element.checked = value === 'true'; |
| this.triggerEvent(element, event); |
| break; |
| case 'radio': |
| if (element.value === value) { |
| element.checked = true; |
| this.triggerEvent(element, event); |
| } |
| else if(element.value == "Scribble/Sketch" && value == "Scribble"){ |
| element.checked = true; |
| this.triggerEvent(element, event); |
| } |
| else { |
| element.checked = false; |
| } |
| break; |
| default: |
| element.value = value; |
| this.triggerEvent(element, event); |
| } |
| }, |
| onFrameContentChange: function onFrameContentChange(targetNode, func) { |
| if(targetNode) { |
| const observer = new MutationObserver((mutationsList, observer) => { |
| for (const mutation of mutationsList) { |
| if (mutation.type === 'childList' || |
| (mutation.type === 'attributes' && mutation.attributeName == 'src') |
| ) { |
| |
| func(targetNode); |
| } |
| } |
| }); |
| observer.observe(targetNode, { |
| |
| childList: true, |
| |
| subtree: true |
| }); |
| } |
| }, |
|
|
| onContentChange: function onContentChange(targetNode, func) { |
| if(targetNode) { |
| const observer = new MutationObserver((mutationsList, observer) => { |
| for (const mutation of mutationsList) { |
| if (mutation.type === 'childList' || |
| (mutation.type === 'attributes' && mutation.attributeName == 'src') |
| ) { |
| func(targetNode); |
| } |
| } |
| }); |
| observer.observe(targetNode, { |
| attributes: true, |
| childList: true, |
| characterData: true, |
| subtree: true |
| }); |
| } |
| }, |
|
|
| onAccordionChange: function onAccordionChange(targetNode, func) { |
| if(targetNode) { |
| const observer = new MutationObserver((mutationsList, observer) => { |
| for (const mutation of mutationsList) { |
| if (mutation.type === 'attributes' ) { |
| func(targetNode); |
| } |
| } |
| }); |
| observer.observe(targetNode, { |
| attributes: true, |
| }); |
| } |
| }, |
|
|
| getCurSeed: function getCurSeed(tab) { |
| const elements = gradioApp().getElementById(`html_info_${tab}`).querySelectorAll(`#html_info_${tab}`); |
| if (! elements || ! elements.length || !elements[0].innerText) { |
| return undefined; |
| } |
| seed = undefined |
| values = elements[0].innerText.split(',') |
| for (value of values){ |
| pair = value.split(':') |
| if(pair[0].replace(/^\s+|\s+$/g,"") == 'Seed'){ |
| seed = pair[1].replace(/^\s+|\s+$/g,"") |
| } |
| } |
| return seed |
| }, |
|
|
| handleImage: function handleImage(select, id, store, addEvtLsner=true) { |
| if(addEvtLsner){ |
| setTimeout(() => { |
| state.utils.onContentChange(select, function (el) { |
| |
| let data = { |
| method: 'POST', |
| headers: { 'Content-Type': 'application/json' }, |
| body: JSON.stringify({ |
| "id":id, |
| "img":"" |
| }) |
| } |
| |
| try { |
| |
| let img = el.querySelector('img'); |
| if (img) { |
| data.body = JSON.stringify({ |
| "id":id, |
| "img":img.src |
| }) |
| } |
| } catch (error) { |
| console.warn('[state]: Error:', error); |
| } |
| |
| fetch(`/lightdiffusionflow/local/imgs_callback`, data) |
| }); |
| }, 150); |
| } |
| }, |
|
|
| clearImage: function clearImage(select) { |
| try { |
| if(select){ |
| |
| let buttons = select.querySelectorAll('button'); |
| buttons.forEach(button => { |
| if(button.getAttribute("aria-label") == "Clear"){ |
| button.click(); |
| |
| } |
| }); |
| |
| } |
| } catch (error) { |
| console.warn('[state]: Error:', error); |
| } |
| }, |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| forceSaveSelect: function forceSaveSelect(select, id, store) { |
| let selected = select.querySelector('span.single-select'); |
| if (selected) { |
| store.set(id, selected.textContent); |
| } else { |
| |
| let input = select.querySelector('input'); |
| if (input) { |
| store.set(id, input.value); |
| } |
| } |
| }, |
| handleAccordion: function handleAccordion(accordion, id, store, addEvtLsner=true){ |
| try{ |
| let value = store.get(id); |
| let child = accordion.querySelector('div.cursor-pointer, .label-wrap'); |
| if (value) { |
| |
| |
| |
| if(child.className.split(' ').pop() != "open"){ |
| state.utils.triggerMouseEvent(child, 'click') |
| } |
| |
| } |
|
|
| if(addEvtLsner){ |
| setTimeout(() => { |
| state.utils.onAccordionChange(child, function (el) { |
| store.set(id, el.className.split(' ').pop() == "open"); |
| |
| |
| |
| }); |
| }, 150); |
| } |
| } catch (error) { |
| console.warn(`accordion:${accordion}, id:${id}`) |
| console.warn('[state]: Error:', error); |
| } |
| }, |
| handleSelect: function handleSelect(select, id, store, force=false, addEvtLsner=true) { |
| try { |
|
|
| let value = store.get(id); |
| if ( value ) { |
| value = value.replace("/","\\") |
| let parts = value.split("\\") |
| value = parts[parts.length - 1] |
|
|
| selectingQueue += 1; |
| setTimeout(() => { |
|
|
| let input = select.querySelector('input'); |
| state.utils.triggerMouseEvent(input, 'focus'); |
| setTimeout(() => { |
| let items = Array.from(select.querySelectorAll('ul li')); |
| let localized_value = this.getTranslation(value) |
| let successed = false |
| for (li of items){ |
| |
| let option = li.lastChild.wholeText.trim().replace(/^\s+|\s+$/g,"") |
| option = option.replace("/","\\") |
| let parts = option.split("\\") |
| option = parts[parts.length - 1] |
| if (localized_value.replace(/^\s+|\s+$/g,"") === option) { |
| state.utils.triggerMouseEvent(li, 'mousedown'); |
| successed = true |
| break |
| } |
| } |
|
|
| let hash_res = localized_value.match(/\[[0-9A-Fa-f]{8,10}\]/) |
| if(!successed){ |
| for (li of items){ |
| |
| |
| let text = li.lastChild.wholeText.trim() |
| text = text.replace("/","\\") |
| let parts = text.split("\\") |
| text = parts[parts.length - 1] |
| |
| let localized_value_no_hash = localized_value.replace(/\[[0-9A-Fa-f]{8,10}\]/,"").replace(/^\s+|\s+$/g,"") |
| let text_no_hash = text.replace(/\[[0-9A-Fa-f]{8,10}\]/, "").replace(/^\s+|\s+$/g,"") |
| |
| if (localized_value_no_hash === text_no_hash) { |
| successed = true |
| } |
| |
| |
| if(!successed && hash_res != null){ |
| let hash_str = hash_res[0].replace(/^\s+|\s+$/g,"") |
| let text_hash_res = text.match(/\[[0-9A-Fa-f]{8,10}\]/) |
| if(text_hash_res != null){ |
| let text_hash = text_hash_res[0].replace(/^\s+|\s+$/g,"") |
| if (hash_str === text_hash) { |
| successed = true |
| } |
| } |
| } |
|
|
| if(successed){ |
| state.utils.triggerMouseEvent(li, 'mousedown'); |
| |
| |
| |
| state.core.actions.preset_output_log("alt_option", value, li.lastChild.wholeText.trim()) |
| break |
| } |
| } |
| } |
|
|
| if(!successed && items.length > 0) |
| { |
| let option_name = store.prefix + id |
| if(option_name === "state-setting_sd_model_checkpoint"){ |
| |
| |
| state.core.actions.preset_output_log("no_option", "stable diffusion checkpoint", value) |
| } |
| else{ |
| |
| state.core.actions.preset_output_log("no_option", option_name, value) |
| } |
| if(hash_res != null){ |
| let model_name = value |
| let hash_str = hash_res[0] |
| state.utils.searchCheckPointByHash(hash_str).then( downloadUrl => { |
| if(downloadUrl != undefined){ |
| |
| |
| |
| state.core.actions.preset_output_log("download_url", model_name, downloadUrl) |
| } |
| }); |
| } |
| } |
|
|
| state.utils.triggerMouseEvent(input, 'blur'); |
| selectingQueue -= 1; |
| |
| }, 100); |
|
|
| }, selectingQueue * 200) |
| } |
|
|
| if(addEvtLsner) |
| { |
| setTimeout(() => { |
| state.utils.onContentChange(select, function (el) { |
| let selected = el.querySelector('span.single-select'); |
| if(force){ |
| let localized_id = state.utils.getTranslation(id) |
| let id_translations = state.utils.reverseTranslation(localized_id) |
| |
| for (trans_id of id_translations){ |
| if (selected) { |
| store.set(trans_id, selected.textContent); |
| } else { |
| |
| let input = el.querySelector('input'); |
| if (input) { |
| store.set(trans_id, input.value); |
| } |
| } |
| } |
| } |
| else{ |
| if (selected) { |
| store.set(id, selected.textContent); |
| } else { |
| |
| let input = el.querySelector('input'); |
| if (input) { |
| store.set(id, input.value); |
| } |
| } |
| } |
| }); |
| }, 150); |
| } |
| } catch (error) { |
| console.warn('[state]: Error:', error); |
| } |
| }, |
| handleMultipleSelect: function handleMultipleSelect(select, id, store, addEvtLsner=true) { |
| try { |
| let value = store.get(id); |
|
|
| if (value) { |
|
|
| value = value.split(',').reverse(); |
|
|
| if (value.length) { |
|
|
| let input = select.querySelector('input'); |
|
|
| let selectOption = function () { |
|
|
| if (! value.length) { |
| state.utils.triggerMouseEvent(input, 'blur'); |
| return; |
| } |
|
|
| let option = value.pop(); |
| state.utils.triggerMouseEvent(input, 'focus'); |
|
|
| setTimeout(() => { |
| let successed = false |
| let items = Array.from(select.querySelectorAll('ul li')); |
| items.forEach(li => { |
| if (li.lastChild.wholeText.trim() === option) { |
| state.utils.triggerMouseEvent(li, 'mousedown'); |
| successed = true |
| return false; |
| } |
| }); |
| if(!successed){ |
| state.core.actions.preset_output_log("no_option", store.prefix + id, value) |
| |
| } |
| setTimeout(selectOption, 100); |
| }, 100); |
| } |
| selectOption(); |
| } |
| } |
|
|
| if(addEvtLsner){ |
| state.utils.onContentChange(select, function (el) { |
| const selected = Array.from(el.querySelectorAll('.token > span')).map(item => item.textContent); |
| store.set(id, selected); |
| }); |
| } |
| } catch (error) { |
| console.warn('[state]: Error:', error); |
| } |
| }, |
| txtToId: function txtToId(txt) { |
| return txt.split(' ').join('-').toLowerCase(); |
| }, |
| callXTimes: function callXTimes(func, times) { |
| let called = 0; |
| return function() { |
| if (called < times) { |
| called++; |
| return func.apply(this); |
| } |
| } |
| }, |
| saveFile: function saveJSON(fileName ,data) { |
| const json = JSON.stringify(data, null, 4); |
| const blob = new Blob([json], {type: 'application/json'}); |
| const url = URL.createObjectURL(blob); |
| console.log(url) |
| const link = document.createElement('a'); |
| link.href = url; |
| link.download = fileName; |
|
|
| document.body.appendChild(link); |
| link.click(); |
| link.parentNode.removeChild(link); |
| }, |
| debounce: function debounce(func, delay) { |
| let lastCallTime = 0; |
| return function() { |
| const currentCallTime = new Date().getTime(); |
| if (currentCallTime - lastCallTime > delay) { |
| lastCallTime = currentCallTime; |
| func.apply(this, arguments); |
| } |
| } |
| }, |
| onNextUiUpdates: function (func) { |
| |
| onUiUpdate(this.callXTimes(function () { setTimeout(func, 5); }, 150)); |
| } |
| }; |
|
|
| state.utils.html = { |
| setStyle: function setStyle(elements, style) { |
| if (elements instanceof NodeList) { |
| elements = Array.from(elements); |
| } else if (elements instanceof Node){ |
| elements = [elements]; |
| } else { |
| return; |
| } |
| elements.forEach(element => { |
| for (let key in style) { |
| if (style.hasOwnProperty(key)) { |
| element.style[key] = style[key]; |
| } |
| } |
| }); |
| }, |
| create: function create(type, props, style) { |
| const element = document.createElement(type); |
| if (props) { |
| for (let key in props) { |
| if (props.hasOwnProperty(key)) { |
| element[key] = props[key]; |
| } |
| } |
| } |
| if (style) { |
| this.setStyle(element, style); |
| } |
| return element; |
| }, |
| createButton: function createButton(text, onclick) { |
| const btn = document.createElement('button'); |
| btn.innerHTML = text; |
| btn.onclick = onclick || function () {}; |
| btn.className = 'gr-button gr-button-lg gr-button-primary'; |
| return btn; |
| } |
| }; |
|
|