Download fc/sd-webui-format-prompt/javascript/index.js from dikdimon/fac: direct link, hf CLI and curl.
- Browser
- Download file 4.78 kB
-
https://huggingface.co/dikdimon/fac/resolve/main/fc/sd-webui-format-prompt/javascript/index.js
- Command line
-
hf download hf://dikdimon/fac/fc/sd-webui-format-prompt/javascript/index.js
-
curl -L -o index.js https://huggingface.co/dikdimon/fac/resolve/main/fc/sd-webui-format-prompt/javascript/index.js
4.78 kB
| onUiLoaded(() => { | |
| addFormatButton('txt2img'); | |
| addFormatButton('img2img'); | |
| }); | |
| function addFormatButton(type) { | |
| let formatButton = gradioApp().querySelector(`#${type}_format_prompt`); | |
| const lastButton = gradioApp().querySelector(`#${type}_clear_prompt`); | |
| if (formatButton || !lastButton || !lastButton.parentNode) | |
| return; | |
| formatButton = createFormatButton(`${type}_format_prompt`, type); | |
| lastButton.parentNode.append(formatButton); | |
| } | |
| function createFormatButton(id, type) { | |
| const button = document.createElement('button'); | |
| button.id = id; | |
| button.type = 'button'; | |
| button.innerHTML = '🪄'; | |
| button.title = 'Format prompt~🪄' | |
| button.className = 'lg secondary gradio-button tool svelte-cmf5ev'; | |
| button.addEventListener('click', () => formatPrompts(type)); | |
| return button; | |
| } | |
| function formatPrompts(type) { | |
| for (let kind of ['_prompt', '_neg_prompt']) { | |
| const prompt = gradioApp().querySelector(`#${type + kind} > label > textarea`); | |
| const result = formatPrompt(prompt.value); | |
| prompt.value = result; | |
| dispatchInputEvent(prompt); | |
| } | |
| } | |
| function dispatchInputEvent(target) { | |
| let inputEvent = new Event('input'); | |
| Object.defineProperty(inputEvent, 'target', { value: target }); | |
| target.dispatchEvent(inputEvent); | |
| } | |
| function round(value) { | |
| return Math.round(value * 10000) / 10000 | |
| } | |
| function convertStr(str) { | |
| return str.replace(/:/g, ':').replace(/(/g, '(').replace(/)/g, ')') | |
| } | |
| function convertStr2Array(str) { | |
| const bracketRegex = /([()<>[\]])/g | |
| const splitByBracket = str => { | |
| const arr = [] | |
| let start = 0 | |
| let depth = 0 | |
| let match | |
| while ((match = bracketRegex.exec(str)) !== null) { | |
| if (depth === 0 && match.index > start) { | |
| arr.push(str.substring(start, match.index)) | |
| start = match.index | |
| } | |
| if (match[0] === '(' || match[0] === '<' || match[0] === '[') { | |
| depth++ | |
| } else if (match[0] === ')' || match[0] === '>' || match[0] === ']') { | |
| depth-- | |
| } | |
| if (depth === 0) { | |
| arr.push(str.substring(start, match.index + 1)) | |
| start = match.index + 1 | |
| } | |
| } | |
| if (start < str.length) { | |
| arr.push(str.substring(start)) | |
| } | |
| return arr | |
| } | |
| const splitByComma = str => { | |
| const arr = [] | |
| let start = 0 | |
| let inBracket = false | |
| for (let i = 0; i < str.length; i++) { | |
| if (str[i] === ',' && !inBracket) { | |
| arr.push(str.substring(start, i).trim()) | |
| start = i + 1 | |
| } else if (str[i].match(bracketRegex)) { | |
| inBracket = !inBracket | |
| } | |
| } | |
| arr.push(str.substring(start).trim()) | |
| return arr | |
| } | |
| const cleanStr = str => { | |
| let arr = splitByBracket(str) | |
| arr = arr.flatMap((s) => splitByComma(s)) | |
| return arr.filter((s) => s !== '') | |
| } | |
| return cleanStr(str) | |
| .filter((item) => { | |
| const pattern = /^[,\s, ]+$/ | |
| return !pattern.test(item) | |
| }) | |
| .filter(Boolean) | |
| .sort((a, b) => { | |
| return a.includes('<') && !b.includes('<') ? 1 : b.includes('<') && !a.includes('<') ? -1 : 0 | |
| }) | |
| } | |
| function convertArray2Str(array) { | |
| const newArray = array.map((item) => { | |
| if (item.includes('<')) return item | |
| const newItem = item | |
| .replace(/\s+/g, ' ') | |
| .replace(/,|\.\|。/g, ',') | |
| .replace(/“|‘|”|"|\/'/g, '') | |
| .replace(/, /g, ',') | |
| .replace(/,,/g, ',') | |
| .replace(/,/g, ', ') | |
| return convertStr2Array(newItem).join(', ') | |
| }) | |
| return newArray.join(', ') | |
| } | |
| function formatPrompt(input) { | |
| const re_attention = /\{|\[|\}|\]|[^{}[\]]+/gmu | |
| let text = convertStr(input) | |
| const textArray = convertStr2Array(text) | |
| text = convertArray2Str(textArray) | |
| let res = [] | |
| const curly_bracket_multiplier = 1.05 | |
| const square_bracket_multiplier = 1 / 1.05 | |
| const brackets = { | |
| '{': { stack: [], multiplier: curly_bracket_multiplier }, | |
| '[': { stack: [], multiplier: square_bracket_multiplier }, | |
| } | |
| function multiply_range(start_position, multiplier) { | |
| for (let pos = start_position; pos < res.length; pos++) { | |
| res[pos][1] = round(res[pos][1] * multiplier) | |
| } | |
| } | |
| for (const match of text.matchAll(re_attention)) { | |
| let word = match[0] | |
| if (word in brackets) { | |
| brackets[word].stack.push(res.length) | |
| } else if (word === '}' || word === ']') { | |
| const bracket = brackets[word === '}' ? '{' : '['] | |
| if (bracket.stack.length > 0) { | |
| multiply_range(bracket.stack.pop(), bracket.multiplier) | |
| } | |
| } else { | |
| res.push([word, 1.0]) | |
| } | |
| } | |
| Object.keys(brackets).forEach((bracketType) => { | |
| brackets[bracketType].stack.forEach((pos) => { | |
| multiply_range(pos, brackets[bracketType].multiplier) | |
| }) | |
| }) | |
| if (res.length === 0) { | |
| res = [['', 1.0]] | |
| } | |
| let i = 0 | |
| while (i + 1 < res.length) { | |
| if (res[i][1] === res[i + 1][1]) { | |
| res[i][0] += res[i + 1][0] | |
| res.splice(i + 1, 1) | |
| } else { | |
| i += 1 | |
| } | |
| } | |
| let result = '' | |
| for (const [word, value] of res) { | |
| result += value === 1.0 ? word : `(${word}:${value.toString()})` | |
| } | |
| return result | |
| } | |