|
|
'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); |
|
|
}); |
|
|
}); |
|
|
}); |
|
|
})(); |
|
|
|