From 88c8a1d5d68ccf87c6c18d1715045ea706385cc2 Mon Sep 17 00:00:00 2001 From: DominikDoom Date: Sat, 12 Jul 2025 19:01:13 +0200 Subject: [PATCH] Also move the TacUtils class into the namespace for consistency --- javascript/_utils.js | 3 +- javascript/ext_chants.js | 4 +- javascript/ext_embeddings.js | 4 +- javascript/ext_hypernets.js | 4 +- javascript/ext_loras.js | 6 +-- javascript/ext_lycos.js | 6 +-- javascript/ext_modelKeyword.js | 6 +-- javascript/ext_styles.js | 6 +-- javascript/ext_umi.js | 6 +-- javascript/ext_wildcards.js | 16 +++--- javascript/tagAutocomplete.js | 93 +++++++++++++++++----------------- 11 files changed, 76 insertions(+), 78 deletions(-) diff --git a/javascript/_utils.js b/javascript/_utils.js index 14e58a7..51cc28b 100644 --- a/javascript/_utils.js +++ b/javascript/_utils.js @@ -1,6 +1,5 @@ // Utility functions for tag autocomplete - -class TacUtils { +TAC.Utils = class TacUtils { /** * Parses a CSV file into a 2D array. Doesn't use regex, so it is very lightweight. * We are ignoring newlines in quote fields since we expect one-line entries and parsing would break for unclosed quotes otherwise diff --git a/javascript/ext_chants.js b/javascript/ext_chants.js index cd3e7d2..9cd35d9 100644 --- a/javascript/ext_chants.js +++ b/javascript/ext_chants.js @@ -13,7 +13,7 @@ .replace(" { - let regex = new RegExp(TacUtils.escapeRegExp(searchTerm, true), "i"); + let regex = new RegExp(TAC.Utils.escapeRegExp(searchTerm, true), "i"); return regex.test(x.terms.toLowerCase()) || regex.test(x.name.toLowerCase()); }; tempResults = TAC.Globals.chants.filter((x) => filterCondition(x)); // Filter by tagword @@ -38,7 +38,7 @@ async function load() { if (TAC.CFG.chantFile && TAC.CFG.chantFile !== "None") { try { - TAC.Globals.chants = await TacUtils.readFile( + TAC.Globals.chants = await TAC.Utils.readFile( `${TAC.Globals.tagBasePath}/${TAC.CFG.chantFile}?`, true ); diff --git a/javascript/ext_embeddings.js b/javascript/ext_embeddings.js index 3dd733a..d31c190 100644 --- a/javascript/ext_embeddings.js +++ b/javascript/ext_embeddings.js @@ -20,7 +20,7 @@ } let filterCondition = (x) => { - let regex = new RegExp(TacUtils.escapeRegExp(searchTerm, true), "i"); + let regex = new RegExp(TAC.Utils.escapeRegExp(searchTerm, true), "i"); return ( regex.test(x[0].toLowerCase()) || regex.test(x[0].toLowerCase().replaceAll(" ", "_")) @@ -60,7 +60,7 @@ if (TAC.Globals.embeddings.length === 0) { try { TAC.Globals.embeddings = ( - await TacUtils.loadCSV(`${TAC.Globals.tagBasePath}/temp/emb.txt`) + await TAC.Utils.loadCSV(`${TAC.Globals.tagBasePath}/temp/emb.txt`) ) .filter((x) => x[0]?.trim().length > 0) // Remove empty lines .map((x) => [x[0].trim(), x[1], x[2]]); // Return name, sortKey, hash tuples diff --git a/javascript/ext_hypernets.js b/javascript/ext_hypernets.js index d52e9fc..a49b695 100644 --- a/javascript/ext_hypernets.js +++ b/javascript/ext_hypernets.js @@ -16,7 +16,7 @@ .replace(" { - let regex = new RegExp(TacUtils.escapeRegExp(searchTerm, true), "i"); + let regex = new RegExp(TAC.Utils.escapeRegExp(searchTerm, true), "i"); return ( regex.test(x.toLowerCase()) || regex.test(x.toLowerCase().replaceAll(" ", "_")) @@ -44,7 +44,7 @@ if (TAC.Globals.hypernetworks.length === 0) { try { TAC.Globals.hypernetworks = ( - await TacUtils.loadCSV(`${TAC.Globals.tagBasePath}/temp/hyp.txt`) + await TAC.Utils.loadCSV(`${TAC.Globals.tagBasePath}/temp/hyp.txt`) ) .filter((x) => x[0]?.trim().length > 0) //Remove empty lines .map((x) => [x[0]?.trim(), x[1]]); // Remove carriage returns and padding if it exists diff --git a/javascript/ext_loras.js b/javascript/ext_loras.js index aadc269..ccdbaeb 100644 --- a/javascript/ext_loras.js +++ b/javascript/ext_loras.js @@ -16,7 +16,7 @@ .replace(" { - let regex = new RegExp(TacUtils.escapeRegExp(searchTerm, true), "i"); + let regex = new RegExp(TAC.Utils.escapeRegExp(searchTerm, true), "i"); return ( regex.test(x.toLowerCase()) || regex.test(x.toLowerCase().replaceAll(" ", "_")) @@ -50,7 +50,7 @@ if (TAC.Globals.loras.length === 0) { try { TAC.Globals.loras = ( - await TacUtils.loadCSV(`${TAC.Globals.tagBasePath}/temp/lora.txt`) + await TAC.Utils.loadCSV(`${TAC.Globals.tagBasePath}/temp/lora.txt`) ) .filter((x) => x[0]?.trim().length > 0) // Remove empty lines .map((x) => [x[0]?.trim(), x[1], x[2]]); // Trim filenames and return the name, sortKey, hash pairs @@ -63,7 +63,7 @@ async function sanitize(tagType, text) { if (tagType === TAC.ResultType.lora) { let multiplier = TAC.CFG.extraNetworksDefaultMultiplier; - let info = await TacUtils.fetchAPI(`tacapi/v1/lora-info/${text}`); + let info = await TAC.Utils.fetchAPI(`tacapi/v1/lora-info/${text}`); if (info && info["preferred weight"]) { multiplier = info["preferred weight"]; } diff --git a/javascript/ext_lycos.js b/javascript/ext_lycos.js index 372e108..2aaba1e 100644 --- a/javascript/ext_lycos.js +++ b/javascript/ext_lycos.js @@ -18,7 +18,7 @@ .replace(" { - let regex = new RegExp(TacUtils.escapeRegExp(searchTerm, true), "i"); + let regex = new RegExp(TAC.Utils.escapeRegExp(searchTerm, true), "i"); return ( regex.test(x.toLowerCase()) || regex.test(x.toLowerCase().replaceAll(" ", "_")) @@ -52,7 +52,7 @@ if (TAC.Globals.lycos.length === 0) { try { TAC.Globals.lycos = ( - await TacUtils.loadCSV(`${TAC.Globals.tagBasePath}/temp/lyco.txt`) + await TAC.Utils.loadCSV(`${TAC.Globals.tagBasePath}/temp/lyco.txt`) ) .filter((x) => x[0]?.trim().length > 0) // Remove empty lines .map((x) => [x[0]?.trim(), x[1], x[2]]); // Trim filenames and return the name, sortKey, hash pairs @@ -65,7 +65,7 @@ async function sanitize(tagType, text) { if (tagType === TAC.ResultType.lyco) { let multiplier = TAC.CFG.extraNetworksDefaultMultiplier; - let info = await TacUtils.fetchAPI(`tacapi/v1/lyco-info/${text}`); + let info = await TAC.Utils.fetchAPI(`tacapi/v1/lyco-info/${text}`); if (info && info["preferred weight"]) { multiplier = info["preferred weight"]; } diff --git a/javascript/ext_modelKeyword.js b/javascript/ext_modelKeyword.js index 51d108a..62e8045 100644 --- a/javascript/ext_modelKeyword.js +++ b/javascript/ext_modelKeyword.js @@ -1,6 +1,6 @@ (function ModelKeywordExtension() { async function load() { - let modelKeywordParts = (await TacUtils.readFile(`tmp/modelKeywordPath.txt`)).split(","); + let modelKeywordParts = (await TAC.Utils.readFile(`tmp/modelKeywordPath.txt`)).split(","); TAC.Globals.modelKeywordPath = modelKeywordParts[0]; let customFileExists = modelKeywordParts[1] === "True"; @@ -9,13 +9,13 @@ let csv_lines = []; // Only add default keywords if wanted by the user if (TAC.CFG.modelKeywordCompletion !== "Only user list") - csv_lines = await TacUtils.loadCSV( + csv_lines = await TAC.Utils.loadCSV( `${TAC.Globals.modelKeywordPath}/lora-keyword.txt` ); // Add custom user keywords if the file exists if (customFileExists) csv_lines = csv_lines.concat( - await TacUtils.loadCSV( + await TAC.Utils.loadCSV( `${TAC.Globals.modelKeywordPath}/lora-keyword-user.txt` ) ); diff --git a/javascript/ext_styles.js b/javascript/ext_styles.js index 4e4de58..c99f719 100644 --- a/javascript/ext_styles.js +++ b/javascript/ext_styles.js @@ -7,7 +7,7 @@ class StyleParser extends TAC.BaseTagParser { async parse() { // Refresh if needed - await TacUtils.refreshStyleNamesIfChanged(); + await TAC.Utils.refreshStyleNamesIfChanged(); // Show styles let tempResults = []; @@ -20,7 +20,7 @@ let searchTerm = TAC.Globals.tagword.replace(matchGroups[1], ""); let filterCondition = (x) => { - let regex = new RegExp(TacUtils.escapeRegExp(searchTerm, true), "i"); + let regex = new RegExp(TAC.Utils.escapeRegExp(searchTerm, true), "i"); return ( regex.test(x[0].toLowerCase()) || regex.test(x[0].toLowerCase().replaceAll(" ", "_")) @@ -47,7 +47,7 @@ if (TAC.Globals.styleNames.length === 0 || force) { try { TAC.Globals.styleNames = ( - await TacUtils.loadCSV(`${TAC.Globals.tagBasePath}/temp/styles.txt`) + await TAC.Utils.loadCSV(`${TAC.Globals.tagBasePath}/temp/styles.txt`) ) .filter((x) => x[0]?.trim().length > 0) // Remove empty lines .filter((x) => x[0] !== "None") // Remove "None" style diff --git a/javascript/ext_umi.js b/javascript/ext_umi.js index 7eb14f5..426622e 100644 --- a/javascript/ext_umi.js +++ b/javascript/ext_umi.js @@ -126,7 +126,7 @@ if (umiTags.length > 0) { // Get difference for subprompt let tagCountChange = umiTags.length - TAC.Globals.umiPreviousTags.length; - let diff = TacUtils.difference(umiTags, TAC.Globals.umiPreviousTags); + let diff = TAC.Utils.difference(umiTags, TAC.Globals.umiPreviousTags); TAC.Globals.umiPreviousTags = umiTags; // Show all condition @@ -152,7 +152,7 @@ TAC.Globals.tagword = umiTagword; let filteredWildcardsSorted = filteredWildcards(umiTagword); let searchRegex = new RegExp( - `(^|[^a-zA-Z])${TacUtils.escapeRegExp(umiTagword)}`, + `(^|[^a-zA-Z])${TAC.Utils.escapeRegExp(umiTagword)}`, "i" ); let baseFilter = (x) => x[0].toLowerCase().search(searchRegex) > -1; @@ -243,7 +243,7 @@ if (TAC.Globals.umiWildcards.length === 0) { try { let umiTags = ( - await TacUtils.readFile(`${TAC.Globals.tagBasePath}/temp/umi_tags.txt`) + await TAC.Utils.readFile(`${TAC.Globals.tagBasePath}/temp/umi_tags.txt`) ).split("\n"); // Split into tag, count pairs TAC.Globals.umiWildcards = umiTags diff --git a/javascript/ext_wildcards.js b/javascript/ext_wildcards.js index 6975ace..7978e08 100644 --- a/javascript/ext_wildcards.js +++ b/javascript/ext_wildcards.js @@ -8,7 +8,7 @@ [ ...TAC.Globals.tagword.matchAll( new RegExp( - WC_REGEX.source.replaceAll("__", TacUtils.escapeRegExp(TAC.CFG.wcWrap)), + WC_REGEX.source.replaceAll("__", TAC.Utils.escapeRegExp(TAC.CFG.wcWrap)), "g" ) ), @@ -25,7 +25,7 @@ let wcMatch = [ ...TAC.Globals.tagword.matchAll( new RegExp( - WC_REGEX.source.replaceAll("__", TacUtils.escapeRegExp(TAC.CFG.wcWrap)), + WC_REGEX.source.replaceAll("__", TAC.Utils.escapeRegExp(TAC.CFG.wcWrap)), "g" ) ), @@ -64,7 +64,7 @@ ); } else { const fileContent = ( - await TacUtils.fetchAPI( + await TAC.Utils.fetchAPI( `tacapi/v1/wildcard-contents?basepath=${basePath}&filename=${fileName}.txt`, false ) @@ -132,7 +132,7 @@ alreadyAdded.set(wcFile[1], true); }); - finalResults.sort(TacUtils.getSortFunction()); + finalResults.sort(TAC.Utils.getSortFunction()); return finalResults; } @@ -141,7 +141,7 @@ async function load() { if (TAC.Globals.wildcardFiles.length === 0 && TAC.Globals.wildcardExtFiles.length === 0) { try { - let wcFileArr = await TacUtils.loadCSV(`${TAC.Globals.tagBasePath}/temp/wc.txt`); + let wcFileArr = await TAC.Utils.loadCSV(`${TAC.Globals.tagBasePath}/temp/wc.txt`); if (wcFileArr && wcFileArr.length > 0) { let wcBasePath = wcFileArr[0][0].trim(); // First line should be the base path TAC.Globals.wildcardFiles = wcFileArr @@ -151,7 +151,7 @@ } // To support multiple sources, we need to separate them using the provided "-----" strings - let wcExtFileArr = await TacUtils.loadCSV( + let wcExtFileArr = await TAC.Utils.loadCSV( `${TAC.Globals.tagBasePath}/temp/wce.txt` ); let splitIndices = []; @@ -182,14 +182,14 @@ } // Load the yaml wildcard json file and append it as a wildcard file, appending each key as a path component until we reach the end - TAC.Globals.yamlWildcards = await TacUtils.readFile( + TAC.Globals.yamlWildcards = await TAC.Utils.readFile( `${TAC.Globals.tagBasePath}/temp/wc_yaml.json`, true ); // Append each key as a path component until we reach a leaf Object.keys(TAC.Globals.yamlWildcards).forEach((file) => { - const flattened = TacUtils.flatten(TAC.Globals.yamlWildcards[file], [], "/"); + const flattened = TAC.Utils.flatten(TAC.Globals.yamlWildcards[file], [], "/"); Object.keys(flattened).forEach((key) => { TAC.Globals.wildcardExtFiles.push([file, key]); }); diff --git a/javascript/tagAutocomplete.js b/javascript/tagAutocomplete.js index 5128529..0f5bfa8 100644 --- a/javascript/tagAutocomplete.js +++ b/javascript/tagAutocomplete.js @@ -156,7 +156,7 @@ async function loadTags(c) { // Load main tags and aliases if (TAC.Globals.allTags.length === 0 && c.tagFile && c.tagFile !== "None") { try { - TAC.Globals.allTags = await TacUtils.loadCSV(`${TAC.Globals.tagBasePath}/${c.tagFile}`); + TAC.Globals.allTags = await TAC.Utils.loadCSV(`${TAC.Globals.tagBasePath}/${c.tagFile}`); } catch (e) { console.error("Error loading tags file: " + e); return; @@ -168,7 +168,7 @@ async function loadTags(c) { async function loadExtraTags(c) { if (c.extra.extraFile && c.extra.extraFile !== "None") { try { - TAC.Globals.extras = await TacUtils.loadCSV(`${TAC.Globals.tagBasePath}/${c.extra.extraFile}`); + TAC.Globals.extras = await TAC.Utils.loadCSV(`${TAC.Globals.tagBasePath}/${c.extra.extraFile}`); // Add TAC.Globals.translations to the main translation map for extra tags that have them TAC.Globals.extras.forEach(e => { if (e[4]) TAC.Globals.translations.set(e[0], e[4]); @@ -183,7 +183,7 @@ async function loadExtraTags(c) { async function loadTranslations(c) { if (c.translation.translationFile && c.translation.translationFile !== "None") { try { - let tArray = await TacUtils.loadCSV(`${TAC.Globals.tagBasePath}/${c.translation.translationFile}`); + let tArray = await TAC.Utils.loadCSV(`${TAC.Globals.tagBasePath}/${c.translation.translationFile}`); tArray.forEach(t => { if (c.translation.oldFormat && t[2]) // if 2 doesn't exist, it's probably a new format file and the setting is on by mistake TAC.Globals.translations.set(t[0], t[2]); @@ -321,7 +321,7 @@ async function syncOptions() { TAC.CFG = newCFG; // Callback - await TacUtils.processQueue(TAC.Ext.QUEUE_AFTER_CONFIG_CHANGE, null); + await TAC.Utils.processQueue(TAC.Ext.QUEUE_AFTER_CONFIG_CHANGE, null); } // Create the result list div and necessary styling @@ -424,7 +424,7 @@ const COMPLETED_WILDCARD_REGEX = /__[^\s,_][^\t\n\r,_]*[^\s,_]__[^\s,_]*/g; const STYLE_VAR_REGEX = /\$\(?[^$|\[\],\s]*\)?/g; const NORMAL_TAG_REGEX = /[^\s,|<>\[\]:]+_\([^\s,|<>\[\]:]*\)?|[^\s,|<>():\[\]]+|?/g; -const TAG_REGEX = () => { return new RegExp(`${POINTY_REGEX.source}|${COMPLETED_WILDCARD_REGEX.source.replaceAll("__", TacUtils.escapeRegExp(TAC.CFG.wcWrap))}|${STYLE_VAR_REGEX.source}|${NORMAL_TAG_REGEX.source}`, "g"); } +const TAG_REGEX = () => { return new RegExp(`${POINTY_REGEX.source}|${COMPLETED_WILDCARD_REGEX.source.replaceAll("__", TAC.Utils.escapeRegExp(TAC.CFG.wcWrap))}|${STYLE_VAR_REGEX.source}|${NORMAL_TAG_REGEX.source}`, "g"); } // On click, insert the tag into the prompt textbox with respect to the cursor position async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithoutChoice = false) { @@ -435,7 +435,7 @@ async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithout var sanitizedText = text // Run sanitize queue and use first result as sanitized text - sanitizeResults = await TacUtils.processQueueReturn(TAC.Ext.QUEUE_SANITIZE, null, tagType, text); + sanitizeResults = await TAC.Utils.processQueueReturn(TAC.Ext.QUEUE_SANITIZE, null, tagType, text); if (sanitizeResults && sanitizeResults.length > 0) { sanitizedText = sanitizeResults[0]; @@ -460,12 +460,12 @@ async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithout && TAC.CFG.wildcardCompletionMode !== "Always fully" && sanitizedText.includes("/")) { if (TAC.CFG.wildcardCompletionMode === "To next folder level") { - let regexMatch = sanitizedText.match(new RegExp(`${TacUtils.escapeRegExp(tagword)}([^/]*\\/?)`, "i")); + let regexMatch = sanitizedText.match(new RegExp(`${TAC.Utils.escapeRegExp(tagword)}([^/]*\\/?)`, "i")); if (regexMatch) { let pathPart = regexMatch[0]; // In case the completion would have just added a slash, try again one level deeper if (pathPart === `${tagword}/`) { - pathPart = sanitizedText.match(new RegExp(`${TacUtils.escapeRegExp(tagword)}\\/([^/]*\\/?)`, "i"))[0]; + pathPart = sanitizedText.match(new RegExp(`${TAC.Utils.escapeRegExp(tagword)}\\/([^/]*\\/?)`, "i"))[0]; } sanitizedText = pathPart; } @@ -518,7 +518,7 @@ async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithout // Sanitize name for API call name = encodeURIComponent(name) // Call API & update db - TacUtils.increaseUseCount(name, tagType, isNegative) + TAC.Utils.increaseUseCount(name, tagType, isNegative) } } @@ -528,7 +528,7 @@ async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithout let editStart = Math.max(cursorPos - tagword.length, 0); let editEnd = Math.min(cursorPos + tagword.length, prompt.length); let surrounding = prompt.substring(editStart, editEnd); - let match = surrounding.match(new RegExp(TacUtils.escapeRegExp(`${tagword}`), "i")); + let match = surrounding.match(new RegExp(TAC.Utils.escapeRegExp(`${tagword}`), "i")); let afterInsertCursorPos = editStart + match.index + sanitizedText.length; var optionalSeparator = ""; @@ -536,7 +536,7 @@ async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithout let noCommaTypes = [TAC.ResultType.wildcardFile, TAC.ResultType.yamlWildcard, TAC.ResultType.umiWildcard].concat(extraNetworkTypes); if (!noCommaTypes.includes(tagType)) { // Append comma if enabled and not already present - let beforeComma = surrounding.match(new RegExp(`${TacUtils.escapeRegExp(tagword)}[,:]`, "i")) !== null; + let beforeComma = surrounding.match(new RegExp(`${TAC.Utils.escapeRegExp(tagword)}[,:]`, "i")) !== null; if (TAC.CFG.appendComma) optionalSeparator = beforeComma ? "" : ","; // Add space if enabled @@ -544,7 +544,7 @@ async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithout optionalSeparator += " "; // If at end of prompt and enabled, override the normal setting if not already added if (!TAC.CFG.appendSpace && TAC.CFG.alwaysSpaceAtEnd) - optionalSeparator += surrounding.match(new RegExp(`${TacUtils.escapeRegExp(tagword)}$`, "im")) !== null ? " " : ""; + optionalSeparator += surrounding.match(new RegExp(`${TAC.Utils.escapeRegExp(tagword)}$`, "im")) !== null ? " " : ""; } else if (extraNetworkTypes.includes(tagType)) { // Use the dedicated separator for extra networks if it's defined, otherwise fall back to space optionalSeparator = TAC.CFG.extraNetworksSeparator || " "; @@ -567,7 +567,7 @@ async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithout let keywords = null; // Check built-in activation words first if (tagType === TAC.ResultType.lora || tagType === TAC.ResultType.lyco) { - let info = await TacUtils.fetchAPI(`tacapi/v1/lora-info/${result.text}`) + let info = await TAC.Utils.fetchAPI(`tacapi/v1/lora-info/${result.text}`) if (info && info["activation text"]) { keywords = info["activation text"]; } @@ -579,7 +579,7 @@ async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithout // No match, try to find a sha256 match from the cache file if (!nameDict) { - const sha256 = await TacUtils.fetchAPI(`/tacapi/v1/lora-cached-hash/${result.text}`) + const sha256 = await TAC.Utils.fetchAPI(`/tacapi/v1/lora-cached-hash/${result.text}`) if (sha256) { nameDict = TAC.Globals.modelKeywordDict.get(sha256); } @@ -663,7 +663,7 @@ async function insertTextAtCursor(textArea, result, tagword, tabCompletedWithout TAC.Globals.previousTags = tags; // Callback - let returns = await TacUtils.processQueueReturn(TAC.Ext.QUEUE_AFTER_INSERT, null, tagType, sanitizedText, newPrompt, textArea); + let returns = await TAC.Utils.processQueueReturn(TAC.Ext.QUEUE_AFTER_INSERT, null, tagType, sanitizedText, newPrompt, textArea); // Return if any queue function returned true (has handled hide/show already) if (returns.some(x => x === true)) return; @@ -737,7 +737,7 @@ function addResultsToList(textArea, results, tagword, resetList) { let displayText = ""; // If the tag matches the tagword, we don't need to display the alias if(result.type === TAC.ResultType.chant) { - displayText = TacUtils.escapeHTML(result.aliases); + displayText = TAC.Utils.escapeHTML(result.aliases); } else if (result.aliases && !result.text.includes(tagword)) { // Alias let splitAliases = result.aliases.split(","); let bestAlias = splitAliases.find(a => a.toLowerCase().includes(tagword)); @@ -753,7 +753,7 @@ function addResultsToList(textArea, results, tagword, resetList) { } } - displayText = TacUtils.escapeHTML(bestAlias); + displayText = TAC.Utils.escapeHTML(bestAlias); // Append translation for alias if it exists and is not what the user typed if (TAC.Globals.translations.has(bestAlias) && TAC.Globals.translations.get(bestAlias) !== bestAlias && bestAlias !== result.text) @@ -762,7 +762,7 @@ function addResultsToList(textArea, results, tagword, resetList) { if (!TAC.CFG.alias.onlyShowAlias && result.text !== bestAlias) displayText += " ➝ " + result.text; } else { // No alias - displayText = TacUtils.escapeHTML(result.text); + displayText = TAC.Utils.escapeHTML(result.text); } // Append translation for result if it exists @@ -899,7 +899,7 @@ function addResultsToList(textArea, results, tagword, resetList) { // Add click listener li.addEventListener("click", (e) => { if (e.ctrlKey || e.metaKey) { - TacUtils.resetUseCount(result.text, result.type, !isNegative, isNegative); + TAC.Utils.resetUseCount(result.text, result.type, !isNegative, isNegative); flexDiv.querySelector(".acMetaText").classList.remove("biased"); } else { insertTextAtCursor(textArea, result, tagword); @@ -982,7 +982,7 @@ async function updateSelectionStyle(textArea, newIndex, oldIndex, scroll = true) // String representation of our type enum const typeString = Object.keys(TAC.ResultType)[selectedType - 1].toLowerCase(); // Get image from API - let url = await TacUtils.getExtraNetworkPreviewURL(selectedResult.text, typeString); + let url = await TAC.Utils.getExtraNetworkPreviewURL(selectedResult.text, typeString); if (url) { img.src = url; previewDiv.style.display = "block"; @@ -1028,17 +1028,17 @@ function updateRuby(textArea, prompt) { const translation = TAC.Globals.translations?.get(tag) || TAC.Globals.translations?.get(unsanitizedTag); - let escapedTag = TacUtils.escapeRegExp(tag); + let escapedTag = TAC.Utils.escapeRegExp(tag); return { tag, escapedTag, translation }; } const replaceOccurences = (text, tuple) => { let { tag, escapedTag, translation } = tuple; let searchRegex = new RegExp(`(?)(?:\\b)${escapedTag}(?:\\b|$|(?=[,|: \\t\\n\\r]))(?!)`, "g"); - return text.replaceAll(searchRegex, `${TacUtils.escapeHTML(tag)}${translation}`); + return text.replaceAll(searchRegex, `${TAC.Utils.escapeHTML(tag)}${translation}`); } - let html = TacUtils.escapeHTML(prompt); + let html = TAC.Utils.escapeHTML(prompt); // First try to find direct matches [...rubyTags].forEach(tag => { @@ -1067,11 +1067,11 @@ function updateRuby(textArea, prompt) { } // Perform n-gram sliding window search - translateNgram(TacUtils.toNgrams(subTags, 3)); - translateNgram(TacUtils.toNgrams(subTags, 1)); - translateNgram(TacUtils.toNgrams(subTags, 2)); + translateNgram(TAC.Utils.toNgrams(subTags, 3)); + translateNgram(TAC.Utils.toNgrams(subTags, 1)); + translateNgram(TAC.Utils.toNgrams(subTags, 2)); - let escapedTag = TacUtils.escapeRegExp(tuple.tag); + let escapedTag = TAC.Utils.escapeRegExp(tuple.tag); let searchRegex = new RegExp(`(?)(?:\\b)${escapedTag}(?:\\b|$|(?=[,|: \\t\\n\\r]))(?!)`, "g"); html = html.replaceAll(searchRegex, subHtml); @@ -1183,7 +1183,7 @@ async function autocomplete(textArea, prompt, fixedTag = null) { } let tagCountChange = tags.length - TAC.Globals.previousTags.length; - let diff = TacUtils.difference(tags, TAC.Globals.previousTags); + let diff = TAC.Utils.difference(tags, TAC.Globals.previousTags); TAC.Globals.previousTags = tags; // Guard for no difference / only whitespace remaining / last edited tag was fully removed @@ -1211,14 +1211,14 @@ async function autocomplete(textArea, prompt, fixedTag = null) { let normalTags = false; // Process all parsers - let resultCandidates = (await TacUtils.processParsers(textArea, prompt))?.filter(x => x.length > 0); + let resultCandidates = (await TAC.Utils.processParsers(textArea, prompt))?.filter(x => x.length > 0); // If one ore more result candidates match, use their results if (resultCandidates && resultCandidates.length > 0) { // Flatten our candidate(s) TAC.Globals.results = resultCandidates.flat(); // Sort results, but not if it's umi tags since they are sorted by count if (!(resultCandidates.length === 1 && TAC.Globals.results[0].type === TAC.ResultType.umiWildcard)) - TAC.Globals.results = TAC.Globals.results.sort(TacUtils.getSortFunction()); + TAC.Globals.results = TAC.Globals.results.sort(TAC.Utils.getSortFunction()); } // Else search the normal tag list if (!resultCandidates || resultCandidates.length === 0 @@ -1231,9 +1231,9 @@ async function autocomplete(textArea, prompt, fixedTag = null) { let searchRegex; if (TAC.Globals.tagword.startsWith("*")) { TAC.Globals.tagword = TAC.Globals.tagword.slice(1); - searchRegex = new RegExp(`${TacUtils.escapeRegExp(TAC.Globals.tagword)}`, 'i'); + searchRegex = new RegExp(`${TAC.Utils.escapeRegExp(TAC.Globals.tagword)}`, 'i'); } else { - searchRegex = new RegExp(`(^|[^a-zA-Z])${TacUtils.escapeRegExp(TAC.Globals.tagword)}`, 'i'); + searchRegex = new RegExp(`(^|[^a-zA-Z])${TAC.Utils.escapeRegExp(TAC.Globals.tagword)}`, 'i'); } // Both normal tags and aliases/TAC.Globals.translations are included depending on the config @@ -1264,7 +1264,6 @@ async function autocomplete(textArea, prompt, fixedTag = null) { // Add TAC.Globals.extras if (TAC.CFG.extra.extraFile) { let extraResults = []; - TAC.Globals.extras.filter(fil).forEach(e => { let result = new TAC.AutocompleteResult(e[0].trim(), TAC.ResultType.extra) result.category = e[1] || 0; // If no category is given, use 0 as the default @@ -1314,7 +1313,7 @@ async function autocomplete(textArea, prompt, fixedTag = null) { // Request use counts from the DB const names = TAC.CFG.frequencyIncludeAlias ? tagNames.concat(aliasNames) : tagNames; - const counts = await TacUtils.getUseCounts(names, types, isNegative) || []; + const counts = await TAC.Utils.getUseCounts(names, types, isNegative) || []; // Pre-calculate weights to prevent duplicate work const resultBiasMap = new Map(); @@ -1325,7 +1324,7 @@ async function autocomplete(textArea, prompt, fixedTag = null) { const useStats = counts.find(c => c.name === name && c.type === type); const uses = useStats?.count || 0; // Calculate & set weight - const weight = TacUtils.calculateUsageBias(result, result.count, uses) + const weight = TAC.Utils.calculateUsageBias(result, result.count, uses) resultBiasMap.set(result, weight); }); // Actual sorting with the pre-calculated weights @@ -1468,13 +1467,13 @@ async function refreshTacTempFiles(api = false) { TAC.Globals.loras = []; TAC.Globals.lycos = []; TAC.Globals.modelKeywordDict.clear(); - await TacUtils.processQueue(TAC.Ext.QUEUE_FILE_LOAD, null); + await TAC.Utils.processQueue(TAC.Ext.QUEUE_FILE_LOAD, null); console.log("TAC: Refreshed temp files"); } if (api) { - await TacUtils.postAPI("tacapi/v1/refresh-temp-files"); + await TAC.Utils.postAPI("tacapi/v1/refresh-temp-files"); await reload(); } else { setTimeout(async () => { @@ -1484,9 +1483,9 @@ async function refreshTacTempFiles(api = false) { } async function refreshEmbeddings() { - await TacUtils.postAPI("tacapi/v1/refresh-embeddings", null); + await TAC.Utils.postAPI("tacapi/v1/refresh-embeddings", null); TAC.Globals.embeddings = []; - await TacUtils.processQueue(TAC.Ext.QUEUE_FILE_LOAD, null); + await TAC.Utils.processQueue(TAC.Ext.QUEUE_FILE_LOAD, null); console.log("TAC: Refreshed embeddings"); } @@ -1522,11 +1521,11 @@ function addAutocompleteToArea(area) { setTimeout(() => { TAC.Globals.hideBlocked = false; }, 100); } - TacUtils.debounce(autocomplete(area, area.value), TAC.CFG.delayTime); + TAC.Utils.debounce(autocomplete(area, area.value), TAC.CFG.delayTime); checkKeywordInsertionUndo(area, e); }); // Add focusout event listener - area.addEventListener('focusout', TacUtils.debounce(() => { + area.addEventListener('focusout', TAC.Utils.debounce(() => { if (!TAC.Globals.hideBlocked) hideResults(area); }, 400)); @@ -1547,7 +1546,7 @@ function addAutocompleteToArea(area) { // One-time setup, triggered from onUiUpdate async function setup() { // Load external files needed by completion extensions - await TacUtils.processQueue(TAC.Ext.QUEUE_FILE_LOAD, null); + await TAC.Utils.processQueue(TAC.Ext.QUEUE_FILE_LOAD, null); // Find all textareas let textAreas = TAC.TextAreas.getTextAreas(); @@ -1574,7 +1573,7 @@ async function setup() { }); }); quicksettings?.querySelectorAll(`[id^=setting_tac].gradio-dropdown input`).forEach(e => { - TacUtils.observeElement(e, "value", () => { + TAC.Utils.observeElement(e, "value", () => { setTimeout(async () => { await syncOptions(); }, 500); @@ -1599,14 +1598,14 @@ async function setup() { // Add mutation observer for the model hash text to also allow hash-based blacklist again let modelHashText = gradioApp().querySelector("#sd_checkpoint_hash"); - TacUtils.updateModelName(); + TAC.Utils.updateModelName(); if (modelHashText) { TAC.Globals.currentModelHash = modelHashText.title let modelHashObserver = new MutationObserver((mutationList, observer) => { for (const mutation of mutationList) { if (mutation.type === "attributes" && mutation.attributeName === "title") { TAC.Globals.currentModelHash = mutation.target.title; - TacUtils.updateModelName(); + TAC.Utils.updateModelName(); refreshEmbeddings(); } } @@ -1650,7 +1649,7 @@ async function setup() { document.head.appendChild(acStyle); // Callback - await TacUtils.processQueue(TAC.Ext.QUEUE_AFTER_SETUP, null); + await TAC.Utils.processQueue(TAC.Ext.QUEUE_AFTER_SETUP, null); } var tacLoading = false; var tacSetupDone = false; @@ -1660,7 +1659,7 @@ onUiUpdate(async () => { if (tacSetupDone) return; tacLoading = true; // Get our tag base path from the temp file - TAC.Globals.tagBasePath = await TacUtils.readFile(`tmp/tagAutocompletePath.txt`); + TAC.Globals.tagBasePath = await TAC.Utils.readFile(`tmp/tagAutocompletePath.txt`); // Load config from webui opts await syncOptions(); // Rest of setup