| 'use strict'; |
|
|
| (function() { |
| const VERSION = "1.2.0" |
|
|
| var jq; |
|
|
| var weight_helper_data = {}; |
| var weight_helper_preview_info = {}; |
|
|
| var sampling_steps; |
|
|
| const REGEX = /<([^:]+):([^:]+):([^>]+)>/; |
| const TAG_TYPES = ["lora", "lyco"]; |
|
|
| const SPECIAL_KEYWORDS = ["XYZ"]; |
|
|
| const SPECIAL_PRESETS = { |
| lora: { |
| SD: { XYZ: "XYZ(17)" }, |
| SDXL: { XYZ: "XYZ(12)" } |
| }, |
| lycoris: { |
| SD: { XYZ: "XYZ(26)" }, |
| SDXL: { XYZ: "XYZ(20)" } |
| }, |
| unknown: { XYZ: "XYZ(26)" } |
| }; |
|
|
| const LORA_TYPE_PULLDOWN = { |
| "LoRA(LierLa)": "lora", |
| "LyCORIS,etc": "lycoris" |
| }; |
|
|
| const LBW_WEIGHT_SD_VERSIONS = ["SD", "SDXL"]; |
|
|
| const LBW_WEIGHT_SETTINGS = { |
| lora: { |
| SD: { |
| masks: [1,0,1,1,0,1,1,0,1,1,0,0,0,1,0,0,0,1,1,1,1,1,1,1,1,1], |
| block_points: ["BASE", "IN01-IN04", "IN05-IN08", "M00", "OUT03-OUT06", "OUT07-OUT11"] |
| }, |
| SDXL: { |
| masks: [1,0,0,0,0,1,1,0,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0], |
| block_points: ["BASE", "IN04-IN08", "M00", "OUT00-OUT05"] |
| } |
| }, |
| lycoris: { |
| SD: { |
| masks: [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], |
| block_points: ["BASE", "IN00-IN05", "IN06-IN11", "M00", "OUT00-OUT05", "OUT06-OUT11"] |
| }, |
| SDXL: { |
| masks: [1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0], |
| block_points: ["BASE", "IN00-IN03", "IN04-IN08", "M00", "OUT00-OUT03", "OUT04-OUT08"] |
| } |
| }, |
| unknown: { |
| masks: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], |
| block_points: [] |
| } |
| }; |
|
|
| const WEIGHT_SETTINGS = { |
| te: { |
| label: "TEnc", |
| min: undefined, max: undefined, default: 100, step: undefined |
| }, |
| unet: { |
| label: "UNet", |
| min: undefined, max: undefined, default: undefined, step: undefined |
| }, |
| dyn: { |
| label: "Dyn", |
| min: undefined, max: undefined, default: undefined, step: undefined |
| }, |
| start: { |
| label: "Start", |
| min: 0, max: undefined, default: 0, step: 100 |
| }, |
| stop: { |
| label: "Stop", |
| min: 0, max: undefined, default: undefined, step: 100 |
| }, |
| lbw: { |
| labels: ["BASE", "IN00", "IN01", "IN02", "IN03", "IN04", "IN05", "IN06", "IN07", "IN08", "IN09", "IN10", "IN11", "M00", "OUT00", "OUT01", "OUT02", "OUT03", "OUT04", "OUT05", "OUT06", "OUT07", "OUT08", "OUT09", "OUT10", "OUT11"], |
| min: undefined, max: undefined, default: 100, step: undefined |
| } |
| }; |
|
|
| class WeightSet { |
| map; |
| constructor() { |
| this.map = new Map(); |
| } |
| add(weightDataHash, weightData) { |
| return this.map.set(weightDataHash, weightData); |
| } |
| has(weightDataHash) { |
| return this.map.has(weightDataHash); |
| } |
| delete(weightDataHash) { |
| return this.map.delete(weightDataHash); |
| } |
| clear() { |
| return this.map.clear(); |
| } |
| getAll() { |
| return [...this.map.values()]; |
| } |
| } |
|
|
| var last_instance = undefined; |
|
|
| class WeightData { |
| lbw_lora_type; |
| lbw_sd_version; |
| te; |
| use_unet; |
| unet; |
| use_dyn; |
| dyn; |
| start; |
| stop; |
| lbw; |
| lbwe; |
| special; |
|
|
| constructor(data) { |
| if (data) { |
| Object.assign(this, data); |
| } |
| } |
|
|
| isSpecial() { |
| return this.special != null && this.special !== ""; |
| } |
|
|
| clone() { |
| return new WeightData(structuredClone(this)); |
| } |
|
|
| equals(other) { |
| if (other == null) { |
| return false; |
| } |
| if (this.lbw_lora_type !== other.lbw_lora_type) { |
| return false; |
| } |
| if (this.lbw_sd_version !== other.lbw_sd_version) { |
| return false; |
| } |
| if (this.te[0] !== other.te[0]) { |
| return false; |
| } |
| if (this.te[0] !== other.te[0]) { |
| return false; |
| } |
| if (this.use_unet !== other.use_unet) { |
| return false; |
| } |
| if (this.use_unet && (this.unet[0] != other.unet[0])) { |
| return false; |
| } |
| if (this.use_dyn !== other.use_dyn) { |
| return false; |
| } |
| if (this.use_dyn && (this.dyn[0] != other.dyn[0])) { |
| return false; |
| } |
| if (this.start[0] !== other.start[0]) { |
| return false; |
| } |
| let stop1 = this.stop[0] == null ? sampling_steps : this.stop[0]; |
| let stop2 = other.stop[0] == null ? sampling_steps : other.stop[0]; |
| if (stop1 !== stop2) { |
| return false; |
| } |
| if (this.lbw.length !== other.lbw.length) { |
| return false; |
| } |
| if (this.isSpecial()) { |
| if (this.special !== other.special) { |
| return false; |
| } |
| } else { |
| let masks = null; |
| if (this.lbw_lora_type && this.lbw_sd_version) { |
| masks = LBW_WEIGHT_SETTINGS[this.lbw_lora_type][this.lbw_sd_version].masks; |
| } |
| for (let i = 0; i < this.lbw.length; i++) { |
| if ((!masks || masks[i] === 1) && this.lbw[i] !== other.lbw[i]) { |
| return false; |
| } |
| } |
| } |
| return true; |
| } |
|
|
| hashCode() { |
| let hash = 0; |
| const calcHash = (v) => ((hash ^ v) << 5) - hash ^ v; |
| hash = calcHash(strHashCode(this.lbw_lora_type)); |
| hash = calcHash(strHashCode(this.lbw_sd_version)); |
| hash = calcHash(this.te[0]); |
| hash = calcHash(this.use_unet ? 1 : 0); |
| hash = calcHash(this.use_unet ? this.unet[0] : 0); |
| hash = calcHash(this.use_dyn ? 1 : 0); |
| hash = calcHash(this.use_dyn ? this.dyn[0] : 0); |
| hash = calcHash(this.start[0]/10); |
| hash = calcHash(this.stop[0] == null ? sampling_steps : this.stop[0]); |
| if (this.isSpecial()) { |
| hash = calcHash(strHashCode(this.special)); |
| } else { |
| let masks = null; |
| if (this.lbw_lora_type && this.lbw_sd_version) { |
| masks = LBW_WEIGHT_SETTINGS[this.lbw_lora_type][this.lbw_sd_version].masks; |
| } |
| for (let i = 0; i < this.lbw.length; i++) { |
| const val = !masks || masks[i] === 1 ? this.lbw[i] : 0; |
| hash = calcHash(val); |
| } |
| } |
| return hash & 0xffffffff; |
| } |
| } |
|
|
| class WeightHelper { |
|
|
| static MAIN_TEMPLATE; |
| static PREVIEW_TEMPLATE; |
| static PRESETS_TEMPLATE; |
| static LBWBLOCKS_TEMPLATE; |
| static LBWS_TEMPLATE; |
|
|
| mainBody; |
| previewBody; |
| lbwDOMs = []; |
|
|
| weightData = {}; |
| bindData = { |
| mainBindData: {}, |
| lbwPresetBindDatas: [], |
| lbwBlockBindDatas: [], |
| lbwBindDatas: [], |
| previewBindData: null |
| } |
| weightElements = {}; |
|
|
| usingExecCommand = false; |
|
|
| tabId = null; |
| offsetX = 0; |
| offsetY = 0; |
| isDragging = false; |
|
|
| lbwPresetsMap = {}; |
| lbwPresetsValueKeyMap = {}; |
|
|
| metadata = {}; |
| previewInfo = {}; |
|
|
| tagName = null; |
| name = null; |
| nameHash = null; |
| multiplier = null; |
| currentHistory = null; |
| currentLockSet = new WeightSet(); |
| weightData = new WeightData(); |
|
|
| lastSelectionStart = null; |
| lastSelectionEnd = null; |
| lastText = null; |
|
|
| historyIndex = 0; |
|
|
| openedExtraOption = false; |
|
|
| releaseFunctions = []; |
|
|
| static attach(textarea) { |
| textarea.addEventListener('contextmenu', (e) => { |
| if (!opts.weight_helper_enabled) { |
| return; |
| } |
| if (last_instance) { |
| e.preventDefault(); |
| last_instance.close(); |
| return; |
| } |
| let selectedText = window.getSelection().toString(); |
| if (selectedText) { |
| return; |
| } |
| const prompt = e.target.value; |
| let tmpSelectionStart = e.target.selectionStart; |
| const lCar = prompt.lastIndexOf("<", tmpSelectionStart - 1); |
| const rCar = prompt.indexOf(">", tmpSelectionStart); |
| if (lCar < 0 || rCar < 0) { |
| return; |
| } |
| selectedText = prompt.substring(lCar, rCar + 1); |
| if ((selectedText.match(/</g) || []).length != 1 || (selectedText.match(/>/g) || []).length != 1) { |
| return; |
| } |
| tmpSelectionStart = lCar; |
| const match = REGEX.exec(selectedText); |
| if (match) { |
| const loraType = match[1].toLowerCase(); |
| const name = match[2]; |
| const multiplier = match[3]; |
|
|
| if (TAG_TYPES.includes(loraType)) { |
| e.preventDefault(); |
| const tabId = e.target.closest("[id^='tab_'][class*='tabitem']").id.split("_")[1]; |
| const selectionStart = tmpSelectionStart + match.index; |
| const selectionEnd = selectionStart + match.input.trim().length; |
| WeightHelper.loadTemplate().then(() => { |
| const weightHelper = new WeightHelper(tabId, e.target, selectionStart, selectionEnd, loraType, name, multiplier); |
| weightHelper.setup(); |
| weightHelper.show(e.pageY + 15, e.pageX); |
| }); |
| } |
| } |
| }); |
| } |
|
|
| static async loadTemplate() { |
| if (WeightHelper.MAIN_TEMPLATE != null) { |
| return; |
| } |
| async function loadHandlebars() { |
| if ("Handlebars" in window) { |
| return Promise.resolve(); |
| } else { |
| try { |
| const res = await fetch("https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js"); |
| const script = await res.text(); |
| new Function(script).call(window); |
|
|
| Handlebars.registerHelper("lower", str => str.toLowerCase()); |
| Handlebars.registerHelper("visible", b => b ? "" : "visibility: hidden;"); |
| Handlebars.registerHelper("display", b => b ? "" : "display: none;"); |
| Handlebars.registerHelper("checked", b => b ? "checked" : ""); |
| Handlebars.registerHelper("selected", b => b ? "selected" : ""); |
| Handlebars.registerHelper("pos", array => { |
| let str = ""; |
| str += array[0] == null ? "" : `top: ${array[0]}px;`; |
| str += array[1] == null ? "" : `right: ${array[1]}px;`; |
| str += array[2] == null ? "" : `bottom: ${array[2]}px;`; |
| str += array[3] == null ? "" : `left: ${array[3]}px;`; |
| return str; |
| }) |
| } catch (error) { |
| console.error("Failed to load Handlebars:", error); |
| } |
| } |
| } |
|
|
| await loadHandlebars(); |
| const response = await fetch("/whapi/v1/get_template", { method: "POST", body: null }); |
| const hbs = await response.json(); |
| function partialize(hbs, tag) { |
| const startTag = tag; |
| const start = hbs.indexOf(startTag); |
| const endTag = `${tag.substring(0, 1)}/${tag.substring(1)}`; |
| const end = hbs.indexOf(endTag, start + startTag.length); |
| const partial = hbs.substring(start + startTag.length, end); |
| const main = hbs.substring(0, start) + hbs.substring(end + endTag.length); |
| return {"partial": partial, "main": main} |
| } |
| let main, preview, preset, lbwBlock, lbw; |
| ({ partial: preview, main: main} = partialize(hbs, "<wh:preview>")); |
| ({ partial: preset, main: main} = partialize(main, "<wh:lbwpresets>")); |
| ({ partial: lbwBlock, main: main} = partialize(main, "<wh:lbwblocks>")); |
| ({ partial: lbw, main: lbwBlock} = partialize(lbwBlock, "<wh:lbws>")); |
| WeightHelper.MAIN_TEMPLATE = Handlebars.compile(main); |
| WeightHelper.PREVIEW_TEMPLATE = Handlebars.compile(preview); |
| WeightHelper.PRESETS_TEMPLATE = Handlebars.compile(preset); |
| WeightHelper.LBWBLOCKS_TEMPLATE = Handlebars.compile(lbwBlock); |
| WeightHelper.LBWS_TEMPLATE = Handlebars.compile(lbw); |
| } |
|
|
| constructor(tabId, textarea, selectionStart, selectionEnd, tagName, name, multiplier) { |
| document.documentElement.style.setProperty('--weight-helper-slider_size', opts.weight_helper_slider_length); |
|
|
| this.tabId = tabId; |
| this.textarea = textarea; |
| this.lastSelectionStart = selectionStart; |
| this.lastSelectionEnd = selectionEnd; |
| this.lastText = this.textarea.value.substring(this.lastSelectionStart, this.lastSelectionEnd); |
|
|
| this.tagName = tagName; |
| this.name = name; |
| this.nameHash = strHashCode(name); |
| this.multiplier = multiplier; |
|
|
| const samplingSteps = gradioApp().getElementById(`${this.tabId}_steps`).querySelector("input"); |
| sampling_steps = Math.round(samplingSteps.value * 100); |
|
|
| if (opts.weight_helper_using_execCommand) { |
| if (typeof document.execCommand === 'function') { |
| this.usingExecCommand = true; |
| } else { |
| console.warn("execCommand is not supported."); |
| } |
| } |
| } |
|
|
| setup() { |
| this.initSettings(); |
| this.initWeightData(); |
| this.initHistory(); |
|
|
| this.setupMainBindData(); |
| this.setupLbwBindData(); |
|
|
| this.buildDOM(); |
| if (this.weightData.lbw_sd_version) { |
| this.redrawLbw(); |
| } |
| } |
|
|
| initSettings() { |
| const optBlockPattern = /((BASE|MID|M00|(IN|OUT)[0-9]{1,2}(-(IN|OUT)[0-9]{1,2})?) *(, *|$))+/; |
| for (let loraType of Object.values(LORA_TYPE_PULLDOWN)) { |
| for (let sdVersion of LBW_WEIGHT_SD_VERSIONS) { |
| try { |
| let optBlockPoints = opts[`weight_helper_lbw_${loraType}_${sdVersion.toLowerCase()}_block_points`] |
| optBlockPoints = optBlockPoints.replace("MID", "M00"); |
| if (optBlockPattern.exec(optBlockPoints)) { |
| const blockPoints = optBlockPoints.split(',').map(v => { |
| return v.trim().replace(/\d+/g, match => match.length === 1 ? `0${match}` : match); |
| }); |
| this.getLbwWeightSetting(loraType, sdVersion).block_points = blockPoints; |
| } |
| } catch (e) { |
| console.warn(`${loraType}_${sdVersion} block definition format is invalid.`, e); |
| } |
| } |
| } |
|
|
| for (const k of ["te", "unet", "dyn", "lbw"]) { |
| WEIGHT_SETTINGS[k].min = Math.round(opts[`weight_helper_${k}_min`] * 100); |
| WEIGHT_SETTINGS[k].max = Math.round(opts[`weight_helper_${k}_max`] * 100); |
| WEIGHT_SETTINGS[k].step = Math.round(opts[`weight_helper_${k}_step`] * 100); |
| } |
| WEIGHT_SETTINGS.start.max = sampling_steps; |
| WEIGHT_SETTINGS.stop.max = sampling_steps; |
| WEIGHT_SETTINGS.stop.default = sampling_steps; |
|
|
| const lbwPreset = gradioApp().getElementById("lbw_ratiospreset").querySelector("textarea"); |
| let lbwPresetValue = lbwPreset.value ?? ""; |
| const lbwPresets = lbwPresetValue.split("\n").filter(e => e.trim() !== ''); |
| for (const loraType of Object.values(LORA_TYPE_PULLDOWN)) { |
| this.lbwPresetsMap[loraType] = {}; |
| this.lbwPresetsValueKeyMap[loraType] = {}; |
| for (const sdVersion of LBW_WEIGHT_SD_VERSIONS) { |
| let lbwPreset = {}; |
| let lbwPresetValueKey = {}; |
|
|
| this.lbwPresetsMap[loraType][sdVersion] = lbwPreset; |
| this.lbwPresetsValueKeyMap[loraType][sdVersion] = lbwPresetValueKey; |
|
|
| const blockLength = this.getLbwWeightSetting(loraType, sdVersion).masks.filter((b) => b == 1).length; |
| for (const line of lbwPresets) { |
| const kv = line.split(":"); |
| if (kv.length == 2 && kv[1].split(",").length == blockLength) { |
| lbwPreset[kv[0]] = kv[1]; |
| lbwPresetValueKey[kv[1]] = kv[0]; |
| } |
| } |
| } |
| } |
| } |
|
|
| initWeightData() { |
| if (!(this.nameHash in weight_helper_data)) { |
| weight_helper_data[this.nameHash] = { "lock": [], "history": [], "lora_info": {} } |
| } |
|
|
| if (!("lora_info" in weight_helper_data[this.nameHash])) { |
| weight_helper_data[this.nameHash].lora_info = {}; |
| } |
| const loraInfo = weight_helper_data[this.nameHash].lora_info; |
| if ("metadata" in loraInfo) { |
| this.metadata = loraInfo.metadata; |
| this.weightData.lbw_sd_version = this.metadata.sd_version; |
| } |
| if ("selected_lora_type" in loraInfo) { |
| this.weightData.lbw_lora_type = loraInfo.selected_lora_type.lbw_lora_type; |
| this.weightData.lbw_sd_version = loraInfo.selected_lora_type.lbw_sd_version; |
| } else { |
| loraInfo.selected_lora_type = {}; |
| } |
| if (this.nameHash in weight_helper_preview_info) { |
| this.previewInfo = weight_helper_preview_info[this.nameHash]; |
| } |
|
|
| for (const weightType of Object.keys(WEIGHT_SETTINGS)) { |
| this.weightData[weightType] = [] |
| this.weightData[weightType].push(WEIGHT_SETTINGS[weightType].default); |
| } |
|
|
| this.weightData.lbw = []; |
| this.weightData.lbwe = []; |
| this.weightData.special = ""; |
|
|
| const multipliers = this.multiplier.split(":"); |
|
|
| const multiplierMap = {} |
| for (let i = 0; i < multipliers.length; i++) { |
| let key; |
| let value; |
| if (multipliers[i].indexOf("=") >= 0) { |
| const keyValue = multipliers[i].split("="); |
| key = keyValue[0].toLowerCase(); |
| value = keyValue[1]; |
| } else { |
| key = ["te", "unet", "dyn"][i]; |
| value = multipliers[i]; |
| } |
| multiplierMap[key] = value; |
| } |
|
|
| let assumedSdVersion = null; |
| let assumedLoraType = null; |
| Object.entries(multiplierMap).forEach(kv => { |
| const group = kv[0]; |
| const value = kv[1]; |
| if (group === "lbw") { |
| let blocks = value.split(','); |
| if (blocks.length === 1 && SPECIAL_KEYWORDS.includes(value)) { |
| this.weightData.special = value; |
| } else { |
| const loraSdCombination = []; |
| for (const loraType of Object.values(LORA_TYPE_PULLDOWN)) { |
| for (const sdVersion of LBW_WEIGHT_SD_VERSIONS) { |
| loraSdCombination.push({ |
| loraType: loraType, |
| sdVersion: sdVersion |
| }); |
| } |
| } |
| for (const loraSd of loraSdCombination) { |
| const loraType = loraSd.loraType; |
| const sdVersion = loraSd.sdVersion; |
| if (blocks.length === 1) { |
| const lbwPresets = this.getLbwPresets(loraType, sdVersion); |
| if (value in lbwPresets) { |
| blocks = lbwPresets[value].split(','); |
| } else { |
| continue; |
| } |
| } |
| const masks = this.getLbwWeightSetting(loraType, sdVersion).masks; |
| if (blocks.length === masks.filter((b) => b == 1).length) { |
| assumedSdVersion = sdVersion; |
| assumedLoraType = loraType; |
| let refIdx = 0; |
| for (let enable of masks) { |
| if (enable) { |
| this.weightData.lbw.push(Math.round(blocks[refIdx] * 100)); |
| refIdx++; |
| } else { |
| this.weightData.lbw.push(0); |
| } |
| } |
| break; |
| } |
| } |
| } |
| } else if (group === "step") { |
| const startStop = value.split('-'); |
| this.weightData.start[0] = Math.round(startStop[0] * 100); |
| this.weightData.stop[0] = Math.round(startStop[1] * 100); |
| } else if (group === "lbwe") { |
| this.weightData[group][0] = value; |
| } else { |
| this.weightData[group][0] = Math.round(value * 100); |
| } |
| }); |
| this.weightData.use_unet = this.weightData.unet[0] != null; |
| this.weightData.use_dyn = this.weightData.dyn[0] != null; |
|
|
| if (assumedLoraType) { |
| this.weightData.lbw_lora_type = assumedLoraType; |
| } |
| if (!this.weightData.lbw_lora_type) { |
| if (this.tagName === "lora") { |
| this.weightData.lbw_lora_type = "lora"; |
| } else { |
| this.weightData.lbw_lora_type = "lycoris"; |
| } |
| } |
| if (assumedSdVersion) { |
| this.weightData.lbw_sd_version = assumedSdVersion; |
| } |
| if (!this.weightData.lbw_sd_version) { |
| this.weightData.lbw_sd_version = this.metadata.sd_version; |
| } |
|
|
| const masks = this.getLbwWeightSetting(this.weightData.lbw_lora_type, this.weightData.lbw_sd_version).masks; |
| this.weightData.masks = masks; |
| if (this.weightData.lbw.length === 0) { |
| this.weightData.lbw = new Array(masks.length).fill(100); |
| } |
| } |
|
|
| initHistory() { |
| if (!("lock" in weight_helper_data[this.nameHash])) { |
| weight_helper_data[this.nameHash].lock = []; |
| } |
| weight_helper_data[this.nameHash].lock.forEach(lock => { |
| this.currentLockSet.add(lock.hashCode(), lock); |
| }); |
|
|
| if (!("history" in weight_helper_data[this.nameHash])) { |
| weight_helper_data[this.nameHash].history = []; |
| } |
|
|
| this.currentHistory = weight_helper_data[this.nameHash].history; |
| if (this.currentHistory.length == 0) { |
| this.currentHistory.push(this.weightData.clone()); |
| } else { |
| const historyLen = this.currentHistory.length; |
| const latestHistory = this.currentHistory[historyLen - 1]; |
| if (this.weightData.isSpecial()) { |
| this.weightData.lbw = structuredClone(latestHistory.lbw); |
| } |
| if (!this.weightData.equals(latestHistory)) { |
| this.currentHistory.push(this.weightData.clone()); |
| } |
| } |
| this.historyIndex = this.currentHistory.length - 1; |
| } |
|
|
| initWeightForm(weight, weightSetting, weightData, idx = 0) { |
| const fVal = weightData[idx]; |
| weight.sliderMin = fVal < weightSetting.min ? fVal : weightSetting.min; |
| weight.sliderMax = fVal > weightSetting.max ? fVal : weightSetting.max; |
| weight.sliderStep = weightSetting.step; |
| weight.sliderValue = fVal; |
| weight.updownStep = weightSetting.step / 100; |
| weight.updownValue = weightData[idx] / 100; |
| } |
|
|
| setupMainBindData() { |
| const mainBindData = []; |
| this.bindData.mainBindData = mainBindData; |
|
|
| mainBindData.title = this.name; |
| mainBindData.page = `${this.historyIndex + 1}/${this.currentHistory.length}`; |
| let scale = opts.weight_helper_context_menu_scale; |
| if (scale <= 0) { |
| scale = 1; |
| } |
| mainBindData.scale = scale; |
|
|
| const lock = {} |
| mainBindData.lock = lock; |
| const weightDataHash = this.weightData.hashCode(); |
| const isLocked = this.currentLockSet.has(weightDataHash); |
| lock.flag = isLocked ? "like" : "unlike"; |
| lock.visible = !this.weightData.isSpecial() && this.weightData.lbw_sd_version; |
|
|
| const weights = [] |
| mainBindData.weights = weights; |
| for (const group of Object.keys(WEIGHT_SETTINGS)) { |
| if (group === "lbw") continue; |
|
|
| const weightSetting = WEIGHT_SETTINGS[group]; |
| const weightData = this.weightData[group]; |
|
|
| const weight = {} |
| const useCheck = weightSetting.default === undefined; |
| if (useCheck) { |
| if (weightData[0] != null) { |
| weight.checked = true; |
| } else { |
| weightData[0] = 0; |
| } |
| } |
|
|
| this.initWeightForm(weight, weightSetting, weightData); |
| weight.group = group; |
| weight.label = weightSetting.label; |
| weight.useCheck = useCheck; |
| weight.visible = true; |
| if (group !== "te") { |
| if (useCheck) { |
| if (!weight.checked) { |
| weight.visible = false; |
| } |
| } else if (weightData[0] == weightSetting.default) { |
| weight.visible = false; |
| } |
| } |
| weights.push(weight); |
| } |
|
|
| const extraButton = {} |
| mainBindData.extraButton = extraButton; |
| if (weights.some(v => !v.visible)) { |
| extraButton.visible = true; |
| } else { |
| this.openedExtraOption = true; |
| } |
|
|
| const loraTypes = []; |
| mainBindData.loraTypes = loraTypes; |
| for (const entry of Object.entries(LORA_TYPE_PULLDOWN)) { |
| const loraType = {} |
| loraType.name = entry[0]; |
| loraType.value = entry[1]; |
| if (loraType.value === this.weightData.lbw_lora_type) { |
| loraType.selected = true; |
| } |
| loraTypes.push(loraType); |
| } |
|
|
| const sdvers = []; |
| mainBindData.sdvers = sdvers; |
| for (const sdVersion of LBW_WEIGHT_SD_VERSIONS) { |
| const sdver = {} |
| sdver.name = sdVersion; |
| sdver.value = sdVersion; |
| sdver.checked = sdVersion == this.weightData.lbw_sd_version; |
| sdvers.push(sdver); |
| } |
|
|
| const xyz = {}; |
| mainBindData.xyz = xyz; |
|
|
| const specialPresets = this.getLbwSpecialPreset(this.weightData.lbw_lora_type, this.weightData.lbw_sd_version); |
| xyz.checked = this.weightData.special === "XYZ"; |
| xyz.label = specialPresets.XYZ; |
| } |
|
|
| setupLbwBindData() { |
| const lbwBindDatas = []; |
| this.bindData.lbwBindDatas = lbwBindDatas; |
|
|
| const group = "lbw" |
| const lbwSetting = WEIGHT_SETTINGS[group]; |
| const lbwData = this.weightData[group]; |
| for (let idx = 0; idx < lbwData.length; idx++) { |
| const lbwWeight = {} |
| this.initWeightForm(lbwWeight, lbwSetting, lbwData, idx); |
| lbwWeight.group = group; |
| lbwWeight.label = lbwSetting.labels[idx]; |
| lbwBindDatas.push(lbwWeight); |
| } |
| } |
|
|
| buildDOM() { |
| const parser = new DOMParser(); |
| const mainHtml = WeightHelper.MAIN_TEMPLATE(this.bindData.mainBindData); |
| const mainDoc = parser.parseFromString(mainHtml, 'text/html'); |
| this.mainBody = mainDoc.body.firstChild; |
|
|
| const lbwsHtml = WeightHelper.LBWS_TEMPLATE({ lbws: this.bindData.lbwBindDatas }); |
| const lbwsDoc = parser.parseFromString(lbwsHtml, 'text/html'); |
| this.lbwDOMs = [...lbwsDoc.body.children]; |
|
|
| [...mainDoc.getElementsByClassName("wh:weight")].forEach(elem => { |
| const data = {} |
| const group = elem.dataset.group; |
| const check = elem.getElementsByClassName("wh:check"); |
| data.check = check.length > 0 ? check[0] : undefined; |
| data.slider = elem.getElementsByClassName("wh:slider")[0]; |
| data.updown = elem.getElementsByClassName("wh:updown")[0]; |
| this.weightElements[group] = [data]; |
| }); |
|
|
| this.weightElements["lbw"] = []; |
| [...lbwsDoc.getElementsByClassName("wh:lbw")].forEach(elem => { |
| const data = {} |
| data.check = undefined; |
| data.slider = elem.getElementsByClassName("wh:slider")[0]; |
| data.updown = elem.getElementsByClassName("wh:updown")[0]; |
| this.weightElements["lbw"].push(data); |
| }); |
|
|
| this.attachEvent(this.mainBody, "click", (e) => e.stopPropagation()); |
|
|
| this.attachEvent(mainDoc.getElementById("wh:header"), "mousedown", (e) => { |
| this.isDragging = true; |
| this.offsetX = e.clientX - this.mainBody.getBoundingClientRect().left; |
| this.offsetY = e.clientY - this.mainBody.getBoundingClientRect().top; |
| }); |
| this.attachEvent(document.body, "mousemove", (e) => { |
| if (!this.isDragging) return; |
|
|
| const x = e.clientX - this.offsetX + window.scrollX; |
| const y = e.clientY - this.offsetY + window.scrollY; |
|
|
| this.mainBody.style.left = x + 'px'; |
| this.mainBody.style.top = y + 'px'; |
| }); |
| this.attachEvent(document.body, "mouseup", () => { |
| this.isDragging = false; |
| }); |
|
|
| this.attachEvent(mainDoc.getElementById("wh:lock"), "click", () => { |
| const weightDataHash = this.weightData.hashCode(); |
| const isLocked = this.currentLockSet.has(weightDataHash); |
|
|
| this.updateLockedIcon(!isLocked); |
| if (isLocked) { |
| this.currentLockSet.delete(weightDataHash); |
| } else { |
| const weightDataClone = this.weightData.clone(); |
| if (weightDataClone.stop[0] == WEIGHT_SETTINGS.stop.default) { |
| weightDataClone.stop[0] = null; |
| } |
| this.currentLockSet.add(weightDataHash, weightDataClone); |
| } |
| }); |
|
|
| this.attachEvent(mainDoc.getElementById("wh:clear"), "click", () => { |
| const newHistory = this.currentLockSet.getAll(); |
| if (newHistory.length == 0 || !newHistory[newHistory.length - 1].equals(this.weightData)) { |
| newHistory.push(this.weightData); |
| } |
|
|
| weight_helper_data[this.nameHash].history = newHistory; |
| this.currentHistory = newHistory; |
|
|
| document.getElementById("wh:page__label").textContent = `${newHistory.length}/${newHistory.length}`; |
| this.historyIndex = newHistory.length - 1; |
| }); |
|
|
| this.attachEvent(mainDoc.getElementById("wh:page__prev"), "click", () => { |
| if (this.historyIndex <= 0) { |
| return; |
| } |
| this.historyIndex--; |
| this.applyFromHistory(); |
| }); |
| this.attachEvent(mainDoc.getElementById("wh:page__next"), "click", () => { |
| if (this.historyIndex >= this.currentHistory.length - 1) { |
| return; |
| } |
| this.historyIndex++; |
| this.applyFromHistory(); |
| }); |
|
|
| this.attachEvent(mainDoc.getElementById("wh:reload"), "click", () => { |
| this.loadMetadata(true); |
| }); |
|
|
| const changedEvent = (group, useCheck) => { |
| if (useCheck && !useCheck.checked) { |
| useCheck.checked = true; |
| this.weightData[`use_${group}`] = true; |
| } |
|
|
| const weightDataHash = this.weightData.hashCode(); |
| const isLocked = this.currentLockSet.has(weightDataHash); |
| this.updateLockedIcon(isLocked); |
|
|
| if (!this.usingExecCommand) { |
| const updatedText = this.makeUpdatedText(); |
| this.update(updatedText); |
| } |
| } |
| Object.entries(this.weightElements).forEach(entry => { |
| const group = entry[0]; |
| if (group === "lbw") { |
| return; |
| } |
| const weights = entry[1]; |
| weights.forEach((weight, i) => { |
| if (weight.check) { |
| this.attachEvent(weight.check, "change", (e) => { |
| this.weightData[`use_${group}`] = e.target.checked; |
|
|
| const weightDataHash = this.weightData.hashCode(); |
| const isLocked = this.currentLockSet.has(weightDataHash); |
| this.updateLockedIcon(isLocked); |
|
|
| if (!this.usingExecCommand) { |
| const updatedText = this.makeUpdatedText(); |
| this.update(updatedText); |
| } |
| }); |
| } |
| this.attachEvent(weight.slider, "input", (e) => { |
| const fVal = parseFloat(e.target.value); |
| this.weightData[group][i] = fVal; |
| weight.updown.value = Math.round(fVal) / 100; |
| changedEvent(group, weight.check); |
| }); |
| this.attachEvent(weight.updown, "input", (e) => { |
| const fVal = Math.round(e.target.value * 100); |
| this.weightData[group][i] = fVal; |
| if (fVal < weight.slider.min) { |
| weight.slider.min = fVal; |
| } |
| if (fVal > weight.slider.max) { |
| weight.slider.max = fVal; |
| } |
| weight.slider.value = Math.round(fVal); |
| changedEvent(group, weight.check); |
| }); |
| }) |
| }); |
|
|
| this.attachEvent(mainDoc.getElementById("wh:extra_button"), "click", (e) => { |
| e.target.remove(); |
| [...this.mainBody.getElementsByClassName("wh:weight")].forEach(f => { |
| f.style.display = ''; |
| }) |
| this.openedExtraOption = true; |
| }); |
|
|
| this.attachEvent(mainDoc.getElementById("wh:lora_type"), "change", (e) => { |
| this.weightData.lbw_lora_type = e.target.value; |
|
|
| const xyzLabel = document.getElementById("wh:xyz_label"); |
| const specialPreset = this.getLbwSpecialPreset(this.weightData.lbw_lora_type, this.weightData.lbw_sd_version); |
| xyzLabel.textContent = specialPreset.XYZ; |
|
|
| this.redrawLbw(); |
| if (!this.usingExecCommand) { |
| const updatedText = this.makeUpdatedText(); |
| this.update(updatedText); |
| } |
| const masks = this.getLbwWeightSetting(e.target.value, this.weightData.lbw_sd_version).masks; |
| this.weightData.masks = masks; |
| }); |
|
|
| this.attachEvent(mainDoc.getElementsByClassName("wh:sdver"), "change", (e) => { |
| this.weightData.lbw_sd_version = e.target.value; |
|
|
| const xyzLabel = document.getElementById("wh:xyz_label"); |
| const specialPreset = this.getLbwSpecialPreset(this.weightData.lbw_lora_type, this.weightData.lbw_sd_version); |
| xyzLabel.textContent = specialPreset.XYZ; |
|
|
| this.redrawLbw(); |
| if (!this.usingExecCommand) { |
| const updatedText = this.makeUpdatedText(); |
| this.update(updatedText); |
| } |
| const masks = this.getLbwWeightSetting(this.weightData.lbw_lora_type, e.target.value).masks; |
| this.weightData.masks = masks; |
| if (!this.weightData.special) { |
| const lockIcon = document.getElementById("wh:lock"); |
| lockIcon.style.visibility = ""; |
| const isLocked = this.currentLockSet.has(this.weightData.hashCode()); |
| this.updateLockedIcon(isLocked); |
| } |
| }); |
|
|
| this.attachEvent(mainDoc.getElementsByClassName("wh:preset_select"), "change", (e) => { |
| const selectVal = e.target.value; |
| if (!this.weightData.lbw_sd_version) { |
| return; |
| } |
|
|
| if (selectVal !== "") { |
| this.weightData.special = ""; |
| const xyz = document.getElementById("wh:xyz"); |
| xyz.checked = false; |
|
|
| const values = selectVal.split(",").map(v => Math.round(v * 100)); |
| const masks = this.getLbwWeightSetting(this.weightData.lbw_lora_type, this.weightData.lbw_sd_version).masks; |
| let refIdx = 0; |
| for (let idx = 0; idx < masks.length; idx++) { |
| let val = 0; |
| if (masks[idx] === 1) { |
| val = values[refIdx]; |
| refIdx++; |
| } |
| this.weightData.lbw[idx] = val; |
| this.weightElements.lbw[idx].slider.value = val; |
| this.weightElements.lbw[idx].updown.value = val / 100; |
| } |
|
|
| const lockIcon = document.getElementById("wh:lock"); |
| lockIcon.style.visibility = ""; |
|
|
| const weightDataHash = this.weightData.hashCode(); |
| const isLocked = this.currentLockSet.has(weightDataHash); |
| this.updateLockedIcon(isLocked); |
|
|
| if (!this.usingExecCommand) { |
| const updatedText = this.makeUpdatedText(); |
| this.update(updatedText); |
| } |
| } |
| }); |
|
|
| this.attachEvent(mainDoc.getElementById("wh:xyz"), "change", (e) => { |
| const lockIcon = document.getElementById("wh:lock"); |
| if (e.target.checked) { |
| this.weightData.special = e.target.value; |
| lockIcon.style.visibility = "hidden"; |
| } else { |
| this.weightData.special = ""; |
| lockIcon.style.visibility = this.weightData.lbw_sd_version ? "" : "hidden"; |
|
|
| const weightDataHash = this.weightData.hashCode(); |
| const isLocked = this.currentLockSet.has(weightDataHash); |
| this.updateLockedIcon(isLocked); |
| } |
|
|
| if (!this.usingExecCommand) { |
| const updatedText = this.makeUpdatedText(); |
| this.update(updatedText); |
| } |
| }); |
|
|
| const lbwChangedEvent = () => { |
| this.weightData.special = ""; |
| const xyz = document.getElementById("wh:xyz"); |
| xyz.checked = false; |
|
|
| const lbwValues = this.getLbwWeightData().join(","); |
| const select = this.mainBody.getElementsByClassName("wh:preset_select")[0]; |
| if (lbwValues in this.lbwPresetsValueKeyMap[this.weightData.lbw_lora_type][this.weightData.lbw_sd_version]) { |
| select.value = lbwValues; |
| } else { |
| select.selectedIndex = 0; |
| } |
|
|
| const lockIcon = document.getElementById("wh:lock"); |
| lockIcon.style.visibility = ""; |
|
|
| const weightDataHash = this.weightData.hashCode(); |
| const isLocked = this.currentLockSet.has(weightDataHash); |
| this.updateLockedIcon(isLocked); |
|
|
| if (!this.usingExecCommand) { |
| const updatedText = this.makeUpdatedText(); |
| this.update(updatedText); |
| } |
| } |
| this.weightElements.lbw.forEach(lbw => { |
| this.attachEvent(lbw.slider, "input", (e) => { |
| const fVal = parseFloat(e.target.value); |
| const idx = e.target.dataset.index; |
| this.weightData["lbw"][idx] = fVal; |
| lbw.updown.value = Math.round(fVal) / 100; |
| lbwChangedEvent(); |
| }); |
| this.attachEvent(lbw.updown, "input", (e) => { |
| const fVal = Math.round(e.target.value * 100); |
| const idx = e.target.dataset.index; |
| this.weightData["lbw"][idx] = fVal; |
| if (fVal < lbw.slider.min) { |
| lbw.slider.min = fVal; |
| } |
| if (fVal > lbw.slider.max) { |
| lbw.slider.max = fVal; |
| } |
| lbw.slider.value = fVal; |
| lbwChangedEvent(); |
| }); |
| }); |
| } |
|
|
| async loadMetadata(force = false) { |
| const domMetadata = document.getElementById("wh:metadata"); |
| const typeVal = document.getElementById("wh:metadata__alg"); |
| const sdVerVal = document.getElementById("wh:metadata__sdver"); |
| if (force) { |
| domMetadata.classList.remove("error"); |
| } |
| if (force || Object.keys(this.metadata).length == 0) { |
| const startLoading = (elem) => { |
| if (elem.dataset.interval_id == null) { |
| elem.classList.add("loading"); |
| const frames = ["-", "--", "---", "----", "-----", "------", "-------"]; |
| let currentFrame = 0; |
| elem.dataset.interval_id = setInterval(() => { |
| elem.textContent = frames[currentFrame]; |
| currentFrame = (currentFrame + 1) % frames.length; |
| }, 100); |
| } |
| } |
| const stopLoading = (elem) => { |
| if (elem.dataset.interval_id != null) { |
| elem.classList.remove("loading"); |
| clearInterval(elem.dataset.interval_id); |
| } |
| } |
| startLoading(typeVal); |
| startLoading(sdVerVal); |
| const key = encodeURIComponent(this.name); |
| this.metadata = await postAPI(`/whapi/v1/get_metadata?key=${key}`, null) ?? {}; |
| stopLoading(typeVal); |
| stopLoading(sdVerVal); |
| } |
| if (Object.keys(this.metadata).length > 0) { |
| if (this.metadata.sd_version && !this.weightData.lbw_sd_version) { |
| this.weightData.lbw_sd_version = this.metadata.sd_version === "SDXL" ? "SDXL" : "SD"; |
| if (this.currentHistory.length == 1) { |
| this.currentHistory[0].lbw_sd_version = this.weightData.lbw_sd_version; |
| } |
| let selectedRadio = undefined; |
| [...this.mainBody.getElementsByClassName("wh:sdver")].forEach((radio) => { |
| if (radio.value === this.weightData.lbw_sd_version) { |
| radio.checked = true; |
| selectedRadio = radio; |
| } |
| }); |
| if (selectedRadio) { |
| selectedRadio.dispatchEvent(new Event('change', { bubbles: true })); |
| } |
| } |
| typeVal.textContent = this.metadata.algorithm ?? "Unknown"; |
| let sdVersion = this.metadata.sd_version ?? "Unknown"; |
| if (this.metadata.base_model) { |
| sdVersion += `(${this.metadata.base_model})`; |
| } |
| sdVerVal.textContent = sdVersion; |
| } else { |
| metadata.classList.add("error"); |
| typeVal.textContent = "TIMEOUT"; |
| sdVerVal.textContent = "TIMEOUT"; |
| } |
| } |
|
|
| async loadPreviewBindData() { |
| if (Object.keys(this.previewInfo).length == 0) { |
| const key = encodeURIComponent(this.name); |
| this.previewInfo = await postAPI(`/whapi/v1/get_preview_info?key=${key}`, null); |
| } |
|
|
| const preview = {} |
| this.bindData.previewBindData = preview; |
| if (Object.keys(this.previewInfo).length > 0) { |
| preview.hasResponse = true; |
| preview.previewUrl = this.previewInfo.preview_url; |
| preview.hasMetadata = this.previewInfo.has_metadata; |
| preview.modelName = this.previewInfo.model_name; |
| if (typeof extraNetworksRequestMetadata === "function") { |
| preview.definedExtraNetworksRequestMetadata = true; |
| } |
| if (typeof extraNetworksEditUserMetadata === "function") { |
| preview.definedExtraNetworksEditUserMetadata = true; |
| } |
| preview.modelId = this.previewInfo.model_id; |
| preview.description = this.previewInfo.description; |
|
|
| preview.trgWords = this.previewInfo.trigger_words ?? []; |
| preview.negTrgWords = this.previewInfo.negative_trigger_words ?? []; |
| if (preview.trgWords.length > 0 || preview.negTrgWords.length > 0) { |
| preview.hasTriggerWords = true; |
| } |
| preview.height = opts.weight_helper_preview_height; |
| switch (opts.weight_helper_preview_position) { |
| case "Bottom Right": |
| preview.pos = [null, null, 0, this.mainBody.clientWidth + 6]; |
| break; |
| case "Top Left": |
| preview.pos = [0, this.mainBody.clientWidth + 6, null, null]; |
| break; |
| case "Bottom Left": |
| preview.pos = [null, this.mainBody.clientWidth + 6, 0, null]; |
| break; |
| default: |
| preview.pos = [0, null, null, this.mainBody.clientWidth + 6]; |
| break; |
| } |
| } |
| } |
|
|
| buildPreviewDOM() { |
| const parser = new DOMParser(); |
| const previewHtml = WeightHelper.PREVIEW_TEMPLATE({ preview: this.bindData.previewBindData }); |
| const previewDoc = parser.parseFromString(previewHtml, 'text/html'); |
| this.previewBody = previewDoc.body.firstChild; |
|
|
| const preview = this.bindData.previewBindData; |
| this.attachEvent(previewDoc.getElementById("wh:preview__metadata"), "click", (e) => { |
| extraNetworksRequestMetadata(e, 'lora', preview.modelName); |
| }); |
| this.attachEvent(previewDoc.getElementById("wh:preview__edit"), "click", (e) => { |
| extraNetworksEditUserMetadata(e, this.tabId, 'lora', preview.modelName); |
| }); |
| this.attachEvent(previewDoc.getElementById("wh:preview__civitai"), "click", () => { |
| window.open(`https://civitai.com/models/${preview.modelId}`, '_blank'); |
| }); |
| this.attachEvent(previewDoc.getElementById("wh:preview__add-trigger"), "click", (e) => { |
| let promptTextarea = document.querySelector(`#${this.tabId}_prompt textarea`); |
| let negativeTextarea = document.querySelector(`#${this.tabId}_neg_prompt textarea`); |
| if (this.textarea === negativeTextarea) { |
| } else if (this.textarea !== promptTextarea) { |
| promptTextarea = this.textarea; |
| negativeTextarea = null; |
| } |
| const negTrgWords = preview.negTrgWords; |
| const trgWords = preview.trgWords; |
| if (!this.usingExecCommand) { |
| const insert = (wordArray, textarea) => { |
| if (wordArray.length > 0 && textarea) { |
| let words = wordArray.join(", "); |
| if (textarea.value) words = ", " + words; |
| textarea.value += words; |
| } |
| } |
| insert(negTrgWords, negativeTextarea); |
| insert(trgWords, promptTextarea); |
| } else { |
| const insert = (wordArray, textarea) => { |
| if (wordArray.length > 0 && textarea) { |
| let words = wordArray.join(", "); |
| if (textarea.value) words = ", " + words; |
| textarea.focus(); |
| const eolIndex = textarea.value.length; |
| textarea.setSelectionRange(eolIndex, eolIndex); |
| document.execCommand("insertText", false, words); |
| } |
| } |
| withoutTAC(() => { |
| insert(negTrgWords, negativeTextarea); |
| insert(trgWords, promptTextarea); |
| }); |
| } |
| e.target.remove(); |
| }); |
|
|
| const topRow = previewDoc.getElementById("wh:preview__top-row"); |
| const bottomRow = previewDoc.getElementById("wh:preview__bottom-row"); |
| const desc = previewDoc.getElementById("wh:preview__desc"); |
| const open = previewDoc.getElementById("wh:preview__note-open"); |
| const close = previewDoc.getElementById("wh:preview__note-close"); |
| this.attachEvent(open, "click", () => { |
| topRow.style.visibility = "hidden"; |
| bottomRow.style.visibility = "hidden"; |
| desc.style.visibility = "visible"; |
| close.style.visibility = "visible"; |
| }); |
| this.attachEvent(close, "click", () => { |
| topRow.style.visibility = ""; |
| bottomRow.style.visibility = ""; |
| desc.style.visibility = ""; |
| close.style.visibility = ""; |
| }); |
| } |
|
|
| redrawLbw() { |
| const parser = new DOMParser(); |
|
|
| const presetBindDatas = []; |
| this.bindData.lbwPresetBindDatas = presetBindDatas; |
|
|
| const lbwSdVersion = this.weightData.lbw_sd_version; |
| if (lbwSdVersion) { |
| const lbwLoraType = this.weightData.lbw_lora_type; |
| if (Object.keys(this.getLbwPresets(lbwLoraType, lbwSdVersion)).length) { |
| const lbwWeightData = this.getLbwWeightData(); |
| const strLbwWeightData = Array.isArray(lbwWeightData) ? lbwWeightData.join(",") : lbwWeightData; |
| const lbwPresets = this.getLbwPresets(lbwLoraType, lbwSdVersion); |
| for (const key of Object.keys(lbwPresets)) { |
| const preset = {} |
| preset.name = key; |
| preset.value = lbwPresets[key]; |
| if (preset.value === strLbwWeightData) { |
| preset.selected = true; |
| } |
| presetBindDatas.push(preset); |
| } |
| } |
| } |
|
|
| const presetSelect = this.mainBody.getElementsByClassName("wh:preset_select")[0]; |
| const presetHtml = WeightHelper.PRESETS_TEMPLATE({ presets: this.bindData.lbwPresetBindDatas }); |
| const previewDoc = parser.parseFromString(presetHtml, 'text/html'); |
| while (presetSelect.firstChild) { |
| presetSelect.firstChild.remove(); |
| } |
| const presetFragment = document.createDocumentFragment(); |
| [...previewDoc.body.children].forEach(element => { |
| presetFragment.appendChild(element); |
| }); |
| presetSelect.appendChild(presetFragment); |
|
|
| const lbwBlockBindDatas = []; |
| this.bindData.lbwBlockBindDatas = lbwBlockBindDatas; |
|
|
| const lbwWeightSetting = this.getLbwWeightSetting(this.weightData.lbw_lora_type, this.weightData.lbw_sd_version); |
| for (const blockPoint of lbwWeightSetting.block_points) { |
| lbwBlockBindDatas.push({label: blockPoint}); |
| } |
|
|
| const lbwblocks = this.mainBody.getElementsByClassName("wh:lbwblocks")[0]; |
| const lbwblocksHtml = WeightHelper.LBWBLOCKS_TEMPLATE({ lbwBlocks: this.bindData.lbwBlockBindDatas }); |
| const lbwblocksDoc = parser.parseFromString(lbwblocksHtml, 'text/html'); |
| while (lbwblocks.firstChild) { |
| lbwblocks.firstChild.remove(); |
| } |
| const lbwblockFragment = document.createDocumentFragment(); |
| [...lbwblocksDoc.body.children].forEach(element => { |
| lbwblockFragment.appendChild(element); |
| }); |
|
|
| const labelMap = {}; |
| for (let idx = 0; idx < WEIGHT_SETTINGS.lbw.labels.length; idx++) { |
| labelMap[WEIGHT_SETTINGS.lbw.labels[idx]] = idx; |
| } |
| for (const blockPoint of lbwWeightSetting.block_points) { |
| const lbwblock = lbwblockFragment.getElementById(`wh:lbwblock_${blockPoint.toLowerCase()}`); |
| const points = blockPoint.split("-"); |
| let pointStart = labelMap[points[0]]; |
| let pointEnd = pointStart; |
| if (points.length > 1) { |
| pointEnd = labelMap[points[1]]; |
| } |
| for (let idx = pointStart; idx <= pointEnd; idx++) { |
| if (lbwWeightSetting.masks[idx] == 1) { |
| lbwblock.appendChild(this.lbwDOMs[idx]); |
| } |
| } |
| } |
| lbwblocks.appendChild(lbwblockFragment); |
| } |
|
|
| applyFromHistory() { |
| document.getElementById("wh:page__label").textContent = `${this.historyIndex + 1}/${this.currentHistory.length}`; |
| const oldSdVersion = this.weightData.lbw_sd_version; |
| this.weightData = this.currentHistory[this.historyIndex].clone(); |
|
|
| const lockIcon = document.getElementById("wh:lock"); |
| if (this.weightData.isSpecial() || !this.weightData.lbw_sd_version) { |
| lockIcon.style.visibility = "hidden"; |
| } else { |
| lockIcon.style.visibility = ""; |
| } |
|
|
| Object.entries(this.weightData).map(entry => { |
| const group = entry[0]; |
| const vals = entry[1]; |
| if (group === "stop" && vals[0] == null) { |
| vals[0] = WEIGHT_SETTINGS[group].default; |
| } |
| if (Array.isArray(vals) && group in this.weightElements) { |
| for (const idx in vals) { |
| let fVal = vals[idx]; |
| let isExtraType = false; |
| let show = false; |
| if (["unet", "dyn", "start", "stop"].includes(group)) { |
| isExtraType = true; |
| if (this.weightElements[group][0].check) { |
| const useCheck = this.weightData[`use_${group}`]; |
| this.weightElements[group][0].check.checked = useCheck; |
| show = useCheck; |
| } |
| if (["start", "stop"].includes(group)) { |
| if (fVal != null && fVal != WEIGHT_SETTINGS[group].default) { |
| show = true; |
| } |
| } |
| } |
| if (!this.openedExtraOption && isExtraType) { |
| const parent = document.getElementById(`wh:weight_${group}`); |
| parent.style.display = show ? "flex" : "none"; |
| } |
| if (fVal == null) { |
| fVal = 0; |
| } |
| this.weightElements[group][idx].slider.value = fVal; |
| this.weightElements[group][idx].updown.value = fVal / 100; |
| } |
| } |
| }); |
|
|
| if (oldSdVersion !== this.weightData.lbw_sd_version) { |
| const loraTypeSelect = document.getElementById("wh:lora_type"); |
| loraTypeSelect.value = this.weightData.lbw_lora_type; |
| [...this.mainBody.getElementsByClassName("wh:sdver")].forEach((radio) => { |
| radio.checked = radio.value === this.weightData.lbw_sd_version; |
| }); |
| this.redrawLbw(); |
| } else { |
| const presetSelect = this.mainBody.getElementsByClassName("wh:preset_select")[0]; |
| if (this.weightData.special) { |
| presetSelect.value = this.weightData.special; |
| } else { |
| const lbwValues = this.getLbwWeightData().join(","); |
| const presetValues = this.lbwPresetsValueKeyMap[this.weightData.lbw_lora_type][this.weightData.lbw_sd_version]; |
| try { |
| if (lbwValues in presetValues) { |
| presetSelect.value = lbwValues; |
| } else { |
| presetSelect.selectedIndex = 0; |
| } |
| } catch (error) { |
| console.error(error, presetValues, lbwValues); |
| } |
| } |
| } |
| const lbwBlocks = this.mainBody.getElementsByClassName("wh:lbwblocks")[0]; |
| lbwBlocks.style.display = this.weightData.lbw_sd_version ? "flex" : "none"; |
|
|
| if (!this.usingExecCommand) { |
| const updatedText = this.makeUpdatedText(); |
| this.update(updatedText); |
| } |
|
|
| const weightDataHash = this.weightData.hashCode(); |
| const isLocked = this.currentLockSet.has(weightDataHash); |
| this.updateLockedIcon(isLocked); |
| } |
|
|
| getLbwWeightData() { |
| if (this.weightData.isSpecial()) { |
| return this.weightData.special; |
| } |
| const masks = this.getLbwWeightSetting(this.weightData.lbw_lora_type, this.weightData.lbw_sd_version).masks; |
| return this.weightData.lbw.filter((_, i) => masks[i] === 1).map(v => v / 100); |
| } |
|
|
| getLbwPresets(lbwLoraType, lbwSdVersion) { |
| if (lbwSdVersion) { |
| if (lbwLoraType in this.lbwPresetsMap && lbwSdVersion in this.lbwPresetsMap[lbwLoraType]) { |
| return this.lbwPresetsMap[lbwLoraType][lbwSdVersion]; |
| } |
| } |
| return {}; |
| } |
|
|
| getLbwWeightSetting(lbwLoraType, lbwSdVersion) { |
| if (lbwSdVersion) { |
| if (lbwLoraType in LBW_WEIGHT_SETTINGS && lbwSdVersion in LBW_WEIGHT_SETTINGS[lbwLoraType]) { |
| return LBW_WEIGHT_SETTINGS[lbwLoraType][lbwSdVersion]; |
| } |
| } |
| return LBW_WEIGHT_SETTINGS.unknown; |
| } |
|
|
| getLbwSpecialPreset(loraType, sdVersion) { |
| if (sdVersion) { |
| if (loraType in SPECIAL_PRESETS && sdVersion in SPECIAL_PRESETS[loraType]) { |
| return SPECIAL_PRESETS[loraType][sdVersion]; |
| } |
| } |
| return SPECIAL_PRESETS.unknown; |
| } |
|
|
| updateLockedIcon(isLocked) { |
| const flag = isLocked ? "like" : "unlike"; |
| const lockIcon = document.getElementById("wh:lock"); |
| lockIcon.className = `lock ${flag}`; |
| } |
|
|
| makeUpdatedText() { |
| let updatedText = `<${this.tagName}:${this.name}`; |
| const optionalTypes = ["te", "unet", "dyn"]; |
| let refIdx = 0; |
| for (let idx = 0; idx < optionalTypes.length; idx++) { |
| const keyType = optionalTypes[idx]; |
| if (keyType in this.weightData) { |
| const defVal = WEIGHT_SETTINGS[keyType].default; |
| const val = this.weightData[keyType]; |
| let output = false; |
| if (keyType === "te") { |
| output = true; |
| } else if (this.weightElements[keyType][0].check) { |
| if (this.weightElements[keyType][0].check.checked) { |
| output = true; |
| } |
| } else if (val != defVal) { |
| output = true; |
| } |
| if (output) { |
| let rateValue = val / 100; |
| if (idx === refIdx) { |
| updatedText += `:${rateValue}`; |
| } else { |
| updatedText += `:${keyType}=${rateValue}`; |
| } |
| refIdx++; |
| } |
| } |
| } |
| const startDefVal = WEIGHT_SETTINGS.start.default; |
| const startVal = this.weightData.start; |
| const stopDefVal = WEIGHT_SETTINGS.stop.default; |
| const stopVal = this.weightData.stop; |
| if (startVal != startDefVal && stopVal != stopDefVal) { |
| updatedText += `:step=${startVal / 100}-${stopVal / 100}`; |
| } else if (startVal != startDefVal) { |
| updatedText += `:start=${startVal / 100}`; |
| } else if (stopVal != stopDefVal) { |
| updatedText += `:stop=${stopVal / 100}`; |
| } |
|
|
| let lbwWeights = []; |
| const masks = this.getLbwWeightSetting(this.weightData.lbw_lora_type, this.weightData.lbw_sd_version).masks; |
| for (let idx = 0; idx < masks.length; idx++) { |
| if (masks[idx]) { |
| lbwWeights.push(this.weightData.lbw[idx]); |
| } |
| } |
| if (!this.weightData.special) { |
| if (!lbwWeights.every(val => val === WEIGHT_SETTINGS.lbw.default)) { |
| let rateValues = lbwWeights.map(v => v / 100).join(","); |
| const lbwValues = this.getLbwWeightData().join(","); |
|
|
| let loraType = this.weightData.lbw_lora_type; |
| let sdVersion = this.weightData.lbw_sd_version; |
| if (loraType && sdVersion) { |
| if (lbwValues in this.lbwPresetsValueKeyMap[loraType][sdVersion]) { |
| rateValues = this.lbwPresetsValueKeyMap[loraType][sdVersion][lbwValues]; |
| } |
| } |
| updatedText += `:lbw=${rateValues}`; |
| } |
| } else { |
| updatedText += `:lbw=${this.weightData.special}`; |
| } |
| if (this.weightData.lbwe.length > 0) { |
| updatedText += `:lbwe=${this.weightData.lbwe[0]}`; |
| } |
| updatedText += ">"; |
| return updatedText; |
| } |
|
|
| update(updatedText) { |
| this.textarea.value = this.textarea.value.substring(0, this.lastSelectionStart) + updatedText + this.textarea.value.substring(this.lastSelectionEnd); |
| this.lastSelectionEnd = this.lastSelectionStart + updatedText.length; |
| } |
|
|
| updateWithExecCommand(updatedText) { |
| withoutTAC(() => { |
| this.textarea.focus(); |
| this.textarea.setSelectionRange(this.lastSelectionStart, this.lastSelectionEnd); |
| document.execCommand("insertText", false, updatedText); |
| }); |
| } |
|
|
| save() { |
| const loraInfo = weight_helper_data[this.nameHash].lora_info; |
| loraInfo.metadata = this.metadata; |
| loraInfo.selected_lora_type.lbw_lora_type = this.weightData.lbw_lora_type; |
| loraInfo.selected_lora_type.lbw_sd_version = this.weightData.lbw_sd_version; |
|
|
| const lbwDefault = WEIGHT_SETTINGS.lbw.default; |
| const masks = this.getLbwWeightSetting(this.weightData.lbw_lora_type, this.weightData.lbw_sd_version).masks; |
| for (let idx = 0; idx < masks.length; idx++) { |
| if (masks[idx] !== 1) { |
| this.weightData.lbw[idx] = lbwDefault; |
| } |
| } |
|
|
| if (this.weightData.lbw_sd_version) { |
| const historyLen = this.currentHistory.length; |
| let lastWeightData = this.currentHistory.at(-1); |
| let historyChanged = false; |
| if (this.historyIndex == historyLen - 1) { |
| historyChanged = !this.weightData.equals(lastWeightData); |
| if (historyChanged) { |
| this.currentHistory.push(this.weightData); |
| } |
| } else { |
| this.currentHistory.splice(this.historyIndex, 1); |
| this.currentHistory.push(this.weightData); |
| } |
| if (this.weightData.stop[0] == WEIGHT_SETTINGS.stop.default) { |
| this.weightData.stop[0] = null; |
| } |
| weight_helper_data[this.nameHash].lock = this.currentLockSet.getAll(); |
| } |
| weight_helper_data.VERSION = VERSION; |
| localStorage.setItem("weight_helper_data", JSON.stringify(weight_helper_data)); |
| } |
|
|
| attachEvent(doms, eventName, func) { |
| if (doms == null) return; |
| if (doms instanceof HTMLCollection) { |
| if (doms.length === 0) return; |
| } else { |
| doms = [doms]; |
| } |
| for (const dom of doms) { |
| dom.addEventListener(eventName, func); |
| this.releaseFunctions.push(() => dom.removeEventListener(eventName, func)); |
| } |
| } |
|
|
| show(top, left) { |
| this.mainBody.style.top = top + 'px'; |
| this.mainBody.style.left = left + 'px'; |
| document.body.appendChild(this.mainBody); |
|
|
| const diffBottom = window.innerHeight - this.mainBody.getBoundingClientRect().bottom; |
| if (diffBottom < 0) { |
| this.mainBody.style.top = (top + diffBottom) + 'px'; |
| const diffTop = this.mainBody.getBoundingClientRect().top; |
| if (diffTop < 0) { |
| this.mainBody.style.top = window.scrollY + 'px'; |
| } |
| } |
| this.attachEvent(document.body, "click", this.close); |
| this.attachEvent(document.body, "keyup", this.cancel); |
| last_instance = this; |
|
|
| this.loadMetadata(); |
|
|
| if (opts.weight_helper_show_preview) { |
| this.loadPreviewBindData().then(() => { |
| this.buildPreviewDOM(); |
| this.mainBody.prepend(this.previewBody); |
| }); |
| } |
| } |
|
|
| close = (e) => { |
| if (!this.mainBody) return; |
| if (e) { |
| if (this.mainBody.contains(e.target)) return; |
| if (e.target.id === `${this.tabId}_token_button`) return; |
| if (e.target.id === `${this.tabId}_lora_edit_user_metadata_button`) return; |
| if (e.target.className === "global-popup-close") return; |
| if (e.target.id.indexOf("_interrupt") > 0) { |
| this.finally(); |
| return; |
| } |
| } |
|
|
| const updatedText = this.makeUpdatedText(); |
| const changed = this.lastText != updatedText; |
| if (changed) { |
| if (!this.usingExecCommand) { |
| this.textarea.dispatchEvent(new InputEvent('input', { bubbles: true, cancelable: true })); |
| } else { |
| this.updateWithExecCommand(updatedText); |
| } |
| } |
| this.save(); |
| this.finally(); |
| }; |
|
|
| cancel = (e) => { |
| if (e.key === 'Escape') { |
| if (!this.usingExecCommand) { |
| this.update(this.lastText); |
| } |
| this.finally(); |
| } |
| }; |
|
|
| finally() { |
| weight_helper_preview_info[this.nameHash] = this.previewInfo; |
|
|
| last_instance = undefined; |
| this.releaseFunctions.forEach((f) => f()); |
| this.mainBody.remove(); |
| } |
| } |
|
|
| async function postAPI(url, body) { |
| let response = await fetch(url, { method: "POST", body: body }); |
| if (response.status != 200) { |
| console.error(`Error posting to API endpoint "${url}": ` + response.status, response.statusText); |
| return null; |
| } |
| return await response.json(); |
| } |
|
|
| function withoutTAC(func) { |
| let tacActiveInOrg = undefined; |
| const tacEnabled = typeof TAC_CFG !== 'undefined' && TAC_CFG; |
| try { |
| if (tacEnabled) { |
| tacActiveInOrg = TAC_CFG.activeIn.global |
| TAC_CFG.activeIn.global = false; |
| } |
| func(); |
| } finally { |
| if (tacEnabled) { |
| TAC_CFG.activeIn.global = tacActiveInOrg; |
| } |
| } |
| } |
|
|
| function strHashCode(s) { |
| let hash = 0; |
| if (!s) return hash; |
| for (let i = 0; i < s.length; i++) { |
| const char = s.charCodeAt(i); |
| hash = hash ^ char; |
| hash = (hash << 5) - hash; |
| } |
| return hash & 0xffffffff; |
| } |
|
|
| async function onPageLoaded() { |
| let tab = null; |
| while (!tab) { |
| tab = gradioApp().getElementById("tab_txt2img"); |
| if (!tab) { |
| await new Promise((resolve) => setTimeout(resolve, 200)); |
| } |
| } |
| return tab; |
| } |
|
|
| document.addEventListener('DOMContentLoaded', function() { |
| const dataTemp = JSON.parse(localStorage.getItem("weight_helper_data")) ?? {}; |
|
|
| const oldData = JSON.parse(localStorage.getItem("weight_helper")); |
| const oldDataType = JSON.parse(localStorage.getItem("weight_helper_type")); |
| try { |
| if (oldData && Object.keys(oldData).length > 0) { |
| Object.entries(oldData).forEach(kv => { |
| const key = kv[0]; |
| const datas = kv[1]; |
|
|
| delete dataTemp[key] |
| const sdType = oldDataType[key]; |
|
|
| let lbwSdVersion = sdType == "sdxl" ? "SDXL" : "SD"; |
| datas.forEach(data => { |
| delete data.VERSION; |
| delete data.DATE; |
| if (data.unet[0] != null) { |
| data.use_unet = true; |
| } else { |
| data.use_unet = false; |
| data.unet[0] = 0; |
| } |
| if (data.dyn[0] != null) { |
| data.use_dyn = true; |
| } else { |
| data.use_dyn = false; |
| data.dyn[0] = 0; |
| } |
| data.stop = [null]; |
| data.special = ""; |
| data.lbw_lora_type = "lora"; |
| data.lbw_sd_version = lbwSdVersion; |
| }); |
| dataTemp[key] = { lock: [] } |
| dataTemp[key].history = datas; |
| dataTemp[key].lora_info = { |
| "selected_lora_type": { |
| "lbw_lora_type": "lora", |
| "lbw_sd_version": lbwSdVersion |
| } |
| } |
| }); |
| } |
| localStorage.removeItem("weight_helper"); |
| localStorage.removeItem("weight_helper_type"); |
| } catch (error) { |
| console.error("An error occurred:", error); |
| } |
|
|
| weight_helper_data = dataTemp; |
| Object.entries(dataTemp).forEach(kv => { |
| const key = kv[0]; |
| if (key === "VERSION") { |
| return; |
| } |
| const val = kv[1]; |
| if (val.lock) { |
| weight_helper_data[key].lock = val.lock.map(v => new WeightData(v)); |
| } |
| if (val.history) { |
| weight_helper_data[key].history = val.history.map(v => new WeightData(v)); |
| } |
| }); |
|
|
| onPageLoaded().then(() => { |
| let textColor = getComputedStyle(document.documentElement).getPropertyValue('--body-text-color').trim(); |
| let textColorRgb = textColor.slice(1).match(/.{1,2}/g).map(hex => parseInt(hex, 16)); |
| let textColorRgba = [...textColorRgb, 0.3]; |
| document.documentElement.style.setProperty('--weight-helper-shadow', `rgba(${textColorRgba.join(",")})`); |
|
|
| if (!gradioApp().getElementById("lbw_ratiospreset")) { |
| return; |
| } |
|
|
| const genButtons = gradioApp().querySelectorAll("button:is([id*='_generate'])"); |
| genButtons.forEach((genBtn) => { |
| genBtn.addEventListener('click', () => { |
| if (last_instance) { |
| last_instance.close(); |
| } |
| }, true); |
| }); |
| const textareas = gradioApp().querySelectorAll("*:is([id*='_toprow'] [id*='_prompt'], .prompt) textarea"); |
| textareas.forEach((textarea) => { |
| WeightHelper.attach(textarea); |
| }); |
| }); |
| }); |
| })(); |
|
|