diff --git a/javascript/_baseParser.js b/javascript/_baseParser.js index c88b8ef..33c57c3 100644 --- a/javascript/_baseParser.js +++ b/javascript/_baseParser.js @@ -1,21 +1,21 @@ -class FunctionNotOverriddenError extends Error { +TAC.FunctionNotOverriddenError = class FunctionNotOverriddenError extends Error { constructor(message = "", ...args) { super(message, ...args); this.message = message + " is an abstract base function and must be overwritten."; } } -class BaseTagParser { +TAC.BaseTagParser = class BaseTagParser { triggerCondition = null; constructor (triggerCondition) { - if (new.target === BaseTagParser) { + if (new.target === TAC.BaseTagParser) { throw new TypeError("Cannot construct abstract BaseCompletionParser directly"); } this.triggerCondition = triggerCondition; } parse() { - throw new FunctionNotOverriddenError("parse()"); + throw new TAC.FunctionNotOverriddenError("parse()"); } } \ No newline at end of file diff --git a/javascript/ext_chants.js b/javascript/ext_chants.js index 993463b..cd3e7d2 100644 --- a/javascript/ext_chants.js +++ b/javascript/ext_chants.js @@ -1,57 +1,66 @@ -const CHANT_REGEX = /<(?!e:|h:|l:)[^,> ]*>?/g; -const CHANT_TRIGGER = () => TAC.CFG.chantFile && TAC.CFG.chantFile !== "None" && TAC.Globals.tagword.match(CHANT_REGEX); +(function ChantExtension() { + const CHANT_REGEX = /<(?!e:|h:|l:)[^,> ]*>?/g; + const CHANT_TRIGGER = () => + TAC.CFG.chantFile && TAC.CFG.chantFile !== "None" && TAC.Globals.tagword.match(CHANT_REGEX); -class ChantParser extends BaseTagParser { - parse() { - // Show Chant - let tempResults = []; - if (TAC.Globals.tagword !== "<" && TAC.Globals.tagword !== " { - let regex = new RegExp(TacUtils.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 + class ChantParser extends TAC.BaseTagParser { + parse() { + // Show Chant + let tempResults = []; + if (TAC.Globals.tagword !== "<" && TAC.Globals.tagword !== " { + let regex = new RegExp(TacUtils.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 + } else { + tempResults = TAC.Globals.chants; + } + + // Add final results + let finalResults = []; + tempResults.forEach((t) => { + let result = new TAC.TAC.AutocompleteResult(t.content.trim(), TAC.ResultType.chant); + result.meta = "Chant"; + result.aliases = t.name; + result.category = t.color; + finalResults.push(result); + }); + + return finalResults; + } + } + + async function load() { + if (TAC.CFG.chantFile && TAC.CFG.chantFile !== "None") { + try { + TAC.Globals.chants = await TacUtils.readFile( + `${TAC.Globals.tagBasePath}/${TAC.CFG.chantFile}?`, + true + ); + } catch (e) { + console.error("Error loading chants.json: " + e); + } } else { - tempResults = TAC.Globals.chants; + TAC.Globals.chants = []; } - - // Add final results - let finalResults = []; - tempResults.forEach(t => { - let result = new TAC.TAC.AutocompleteResult(t.content.trim(), TAC.ResultType.chant) - result.meta = "Chant"; - result.aliases = t.name; - result.category = t.color; - finalResults.push(result); - }); - - return finalResults; } -} -async function load() { - if (TAC.CFG.chantFile && TAC.CFG.chantFile !== "None") { - try { - TAC.Globals.chants = await TacUtils.readFile(`${TAC.Globals.tagBasePath}/${TAC.CFG.chantFile}?`, true); - } catch (e) { - console.error("Error loading chants.json: " + e); + function sanitize(tagType, text) { + if (tagType === TAC.ResultType.chant) { + return text; } - } else { - TAC.Globals.chants = []; + return null; } -} -function sanitize(tagType, text) { - if (tagType === TAC.ResultType.chant) { - return text; - } - return null; -} + TAC.Ext.PARSERS.push(new ChantParser(CHANT_TRIGGER)); -TAC.Ext.PARSERS.push(new ChantParser(CHANT_TRIGGER)); - -// Add our utility functions to their respective queues -TAC.Ext.QUEUE_FILE_LOAD.push(load); -TAC.Ext.QUEUE_SANITIZE.push(sanitize); -TAC.Ext.QUEUE_AFTER_CONFIG_CHANGE.push(load); + // Add our utility functions to their respective queues + TAC.Ext.QUEUE_FILE_LOAD.push(load); + TAC.Ext.QUEUE_SANITIZE.push(sanitize); + TAC.Ext.QUEUE_AFTER_CONFIG_CHANGE.push(load); +})(); diff --git a/javascript/ext_embeddings.js b/javascript/ext_embeddings.js index 562fa22..3dd733a 100644 --- a/javascript/ext_embeddings.js +++ b/javascript/ext_embeddings.js @@ -1,72 +1,85 @@ -const EMB_REGEX = /<(?!l:|h:|c:)[^,> ]*>?/g; -const EMB_TRIGGER = () => TAC.CFG.useEmbeddings && (TAC.Globals.tagword.match(EMB_REGEX) || TAC.CFG.includeEmbeddingsInNormalResults); +(function EmbeddingExtension() { + const EMB_REGEX = /<(?!l:|h:|c:)[^,> ]*>?/g; + const EMB_TRIGGER = () => + TAC.CFG.useEmbeddings && + (TAC.Globals.tagword.match(EMB_REGEX) || TAC.CFG.includeEmbeddingsInNormalResults); -class EmbeddingParser extends BaseTagParser { - parse() { - // Show embeddings - let tempResults = []; - if (TAC.Globals.tagword !== "<" && TAC.Globals.tagword !== " { + let regex = new RegExp(TacUtils.escapeRegExp(searchTerm, true), "i"); + return ( + regex.test(x[0].toLowerCase()) || + regex.test(x[0].toLowerCase().replaceAll(" ", "_")) + ); + }; + + if (versionString) + tempResults = TAC.Globals.embeddings.filter( + (x) => + filterCondition(x) && + x[2] && + x[2].toLowerCase() === versionString.toLowerCase() + ); // Filter by tagword + else tempResults = TAC.Globals.embeddings.filter((x) => filterCondition(x)); // Filter by tagword + } else { + tempResults = TAC.Globals.embeddings; } - let filterCondition = x => { - let regex = new RegExp(TacUtils.escapeRegExp(searchTerm, true), 'i'); - return regex.test(x[0].toLowerCase()) || regex.test(x[0].toLowerCase().replaceAll(" ", "_")); - }; + // Add final results + let finalResults = []; + tempResults.forEach((t) => { + let lastDot = t[0].lastIndexOf(".") > -1 ? t[0].lastIndexOf(".") : t[0].length; + let lastSlash = t[0].lastIndexOf("/") > -1 ? t[0].lastIndexOf("/") : -1; + let name = t[0].trim().substring(lastSlash + 1, lastDot); - if (versionString) - tempResults = TAC.Globals.embeddings.filter(x => filterCondition(x) && x[2] && x[2].toLowerCase() === versionString.toLowerCase()); // Filter by tagword - else - tempResults = TAC.Globals.embeddings.filter(x => filterCondition(x)); // Filter by tagword - } else { - tempResults = TAC.Globals.embeddings; - } + let result = new TAC.AutocompleteResult(name, TAC.ResultType.embedding); + result.sortKey = t[1]; + result.meta = t[2] + " Embedding"; + finalResults.push(result); + }); - // Add final results - let finalResults = []; - tempResults.forEach(t => { - let lastDot = t[0].lastIndexOf(".") > -1 ? t[0].lastIndexOf(".") : t[0].length; - let lastSlash = t[0].lastIndexOf("/") > -1 ? t[0].lastIndexOf("/") : -1; - let name = t[0].trim().substring(lastSlash + 1, lastDot); - - let result = new TAC.AutocompleteResult(name, TAC.ResultType.embedding) - result.sortKey = t[1]; - result.meta = t[2] + " Embedding"; - finalResults.push(result); - }); - - return finalResults; - } -} - -async function load() { - if (TAC.Globals.embeddings.length === 0) { - try { - TAC.Globals.embeddings = (await TacUtils.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 - } catch (e) { - console.error("Error loading embeddings.txt: " + e); + return finalResults; } } -} -function sanitize(tagType, text) { - if (tagType === TAC.ResultType.embedding) { - return text; + async function load() { + if (TAC.Globals.embeddings.length === 0) { + try { + TAC.Globals.embeddings = ( + await TacUtils.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 + } catch (e) { + console.error("Error loading embeddings.txt: " + e); + } + } } - return null; -} -TAC.Ext.PARSERS.push(new EmbeddingParser(EMB_TRIGGER)); + function sanitize(tagType, text) { + if (tagType === TAC.ResultType.embedding) { + return text; + } + return null; + } -// Add our utility functions to their respective queues -TAC.Ext.QUEUE_FILE_LOAD.push(load); -TAC.Ext.QUEUE_SANITIZE.push(sanitize); + TAC.Ext.PARSERS.push(new EmbeddingParser(EMB_TRIGGER)); + + // Add our utility functions to their respective queues + TAC.Ext.QUEUE_FILE_LOAD.push(load); + TAC.Ext.QUEUE_SANITIZE.push(sanitize); +})(); diff --git a/javascript/ext_hypernets.js b/javascript/ext_hypernets.js index 3400266..d52e9fc 100644 --- a/javascript/ext_hypernets.js +++ b/javascript/ext_hypernets.js @@ -1,55 +1,69 @@ -const HYP_REGEX = /<(?!e:|l:|c:)[^,> ]*>?/g; -const HYP_TRIGGER = () => TAC.CFG.useHypernetworks && TAC.Globals.tagword.match(HYP_REGEX); +(function HypernetExtension() { + const HYP_REGEX = /<(?!e:|l:|c:)[^,> ]*>?/g; + const HYP_TRIGGER = () => TAC.CFG.useHypernetworks && TAC.Globals.tagword.match(HYP_REGEX); -class HypernetParser extends BaseTagParser { - parse() { - // Show hypernetworks - let tempResults = []; - if (TAC.Globals.tagword !== "<" && TAC.Globals.tagword !== " { - let regex = new RegExp(TacUtils.escapeRegExp(searchTerm, true), 'i'); - return regex.test(x.toLowerCase()) || regex.test(x.toLowerCase().replaceAll(" ", "_")); - }; - tempResults = TAC.Globals.hypernetworks.filter(x => filterCondition(x[0])); // Filter by tagword - } else { - tempResults = TAC.Globals.hypernetworks; - } + class HypernetParser extends TAC.BaseTagParser { + parse() { + // Show hypernetworks + let tempResults = []; + if ( + TAC.Globals.tagword !== "<" && + TAC.Globals.tagword !== " { + let regex = new RegExp(TacUtils.escapeRegExp(searchTerm, true), "i"); + return ( + regex.test(x.toLowerCase()) || + regex.test(x.toLowerCase().replaceAll(" ", "_")) + ); + }; + tempResults = TAC.Globals.hypernetworks.filter((x) => filterCondition(x[0])); // Filter by tagword + } else { + tempResults = TAC.Globals.hypernetworks; + } - // Add final results - let finalResults = []; - tempResults.forEach(t => { - let result = new TAC.AutocompleteResult(t[0].trim(), TAC.ResultType.hypernetwork) - result.meta = "Hypernetwork"; - result.sortKey = t[1]; - finalResults.push(result); - }); + // Add final results + let finalResults = []; + tempResults.forEach((t) => { + let result = new TAC.AutocompleteResult(t[0].trim(), TAC.ResultType.hypernetwork); + result.meta = "Hypernetwork"; + result.sortKey = t[1]; + finalResults.push(result); + }); - return finalResults; - } -} - -async function load() { - if (TAC.Globals.hypernetworks.length === 0) { - try { - TAC.Globals.hypernetworks = (await TacUtils.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 - } catch (e) { - console.error("Error loading hypernetworks.txt: " + e); + return finalResults; } } -} -function sanitize(tagType, text) { - if (tagType === TAC.ResultType.hypernetwork) { - return ``; + async function load() { + if (TAC.Globals.hypernetworks.length === 0) { + try { + TAC.Globals.hypernetworks = ( + await TacUtils.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 + } catch (e) { + console.error("Error loading hypernetworks.txt: " + e); + } + } } - return null; -} -TAC.Ext.PARSERS.push(new HypernetParser(HYP_TRIGGER)); + function sanitize(tagType, text) { + if (tagType === TAC.ResultType.hypernetwork) { + return ``; + } + return null; + } -// Add our utility functions to their respective queues -TAC.Ext.QUEUE_FILE_LOAD.push(load); -TAC.Ext.QUEUE_SANITIZE.push(sanitize); + TAC.Ext.PARSERS.push(new HypernetParser(HYP_TRIGGER)); + + // Add our utility functions to their respective queues + TAC.Ext.QUEUE_FILE_LOAD.push(load); + TAC.Ext.QUEUE_SANITIZE.push(sanitize); +})(); diff --git a/javascript/ext_loras.js b/javascript/ext_loras.js index 249fcde..aadc269 100644 --- a/javascript/ext_loras.js +++ b/javascript/ext_loras.js @@ -1,67 +1,81 @@ -const LORA_REGEX = /<(?!e:|h:|c:)[^,> ]*>?/g; -const LORA_TRIGGER = () => TAC.CFG.useLoras && TAC.Globals.tagword.match(LORA_REGEX); +(function LoraExtension() { + const LORA_REGEX = /<(?!e:|h:|c:)[^,> ]*>?/g; + const LORA_TRIGGER = () => TAC.CFG.useLoras && TAC.Globals.tagword.match(LORA_REGEX); -class LoraParser extends BaseTagParser { - parse() { - // Show lora - let tempResults = []; - if (TAC.Globals.tagword !== "<" && TAC.Globals.tagword !== " { - let regex = new RegExp(TacUtils.escapeRegExp(searchTerm, true), 'i'); - return regex.test(x.toLowerCase()) || regex.test(x.toLowerCase().replaceAll(" ", "_")); - }; - tempResults = TAC.Globals.loras.filter(x => filterCondition(x[0])); // Filter by tagword - } else { - tempResults = TAC.Globals.loras; - } + class LoraParser extends TAC.BaseTagParser { + parse() { + // Show lora + let tempResults = []; + if ( + TAC.Globals.tagword !== "<" && + TAC.Globals.tagword !== " { + let regex = new RegExp(TacUtils.escapeRegExp(searchTerm, true), "i"); + return ( + regex.test(x.toLowerCase()) || + regex.test(x.toLowerCase().replaceAll(" ", "_")) + ); + }; + tempResults = TAC.Globals.loras.filter((x) => filterCondition(x[0])); // Filter by tagword + } else { + tempResults = TAC.Globals.loras; + } - // Add final results - let finalResults = []; - tempResults.forEach(t => { - const text = t[0].trim(); - let lastDot = text.lastIndexOf(".") > -1 ? text.lastIndexOf(".") : text.length; - let lastSlash = text.lastIndexOf("/") > -1 ? text.lastIndexOf("/") : -1; - let name = text.substring(lastSlash + 1, lastDot); + // Add final results + let finalResults = []; + tempResults.forEach((t) => { + const text = t[0].trim(); + let lastDot = text.lastIndexOf(".") > -1 ? text.lastIndexOf(".") : text.length; + let lastSlash = text.lastIndexOf("/") > -1 ? text.lastIndexOf("/") : -1; + let name = text.substring(lastSlash + 1, lastDot); - let result = new TAC.AutocompleteResult(name, TAC.ResultType.lora) - result.meta = "Lora"; - result.sortKey = t[1]; - result.hash = t[2]; - finalResults.push(result); - }); + let result = new TAC.AutocompleteResult(name, TAC.ResultType.lora); + result.meta = "Lora"; + result.sortKey = t[1]; + result.hash = t[2]; + finalResults.push(result); + }); - return finalResults; - } -} - -async function load() { - if (TAC.Globals.loras.length === 0) { - try { - TAC.Globals.loras = (await TacUtils.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 - } catch (e) { - console.error("Error loading lora.txt: " + e); + return finalResults; } } -} -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}`) - if (info && info["preferred weight"]) { - multiplier = info["preferred weight"]; + async function load() { + if (TAC.Globals.loras.length === 0) { + try { + TAC.Globals.loras = ( + await TacUtils.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 + } catch (e) { + console.error("Error loading lora.txt: " + e); + } } - - return ``; } - return null; -} -TAC.Ext.PARSERS.push(new LoraParser(LORA_TRIGGER)); + 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}`); + if (info && info["preferred weight"]) { + multiplier = info["preferred weight"]; + } -// Add our utility functions to their respective queues -TAC.Ext.QUEUE_FILE_LOAD.push(load); -TAC.Ext.QUEUE_SANITIZE.push(sanitize); + return ``; + } + return null; + } + + TAC.Ext.PARSERS.push(new LoraParser(LORA_TRIGGER)); + + // Add our utility functions to their respective queues + TAC.Ext.QUEUE_FILE_LOAD.push(load); + TAC.Ext.QUEUE_SANITIZE.push(sanitize); +})(); diff --git a/javascript/ext_lycos.js b/javascript/ext_lycos.js index 5ca21bb..372e108 100644 --- a/javascript/ext_lycos.js +++ b/javascript/ext_lycos.js @@ -1,68 +1,84 @@ -const LYCO_REGEX = /<(?!e:|h:|c:)[^,> ]*>?/g; -const LYCO_TRIGGER = () => TAC.CFG.useLycos && TAC.Globals.tagword.match(LYCO_REGEX); +(function LycoExtension() { + const LYCO_REGEX = /<(?!e:|h:|c:)[^,> ]*>?/g; + const LYCO_TRIGGER = () => TAC.CFG.useLycos && TAC.Globals.tagword.match(LYCO_REGEX); -class LycoParser extends BaseTagParser { - parse() { - // Show lyco - let tempResults = []; - if (TAC.Globals.tagword !== "<" && TAC.Globals.tagword !== " { - let regex = new RegExp(TacUtils.escapeRegExp(searchTerm, true), 'i'); - return regex.test(x.toLowerCase()) || regex.test(x.toLowerCase().replaceAll(" ", "_")); - }; - tempResults = TAC.Globals.lycos.filter(x => filterCondition(x[0])); // Filter by tagword - } else { - tempResults = TAC.Globals.lycos; - } + class LycoParser extends TAC.BaseTagParser { + parse() { + // Show lyco + let tempResults = []; + if ( + TAC.Globals.tagword !== "<" && + TAC.Globals.tagword !== " { + let regex = new RegExp(TacUtils.escapeRegExp(searchTerm, true), "i"); + return ( + regex.test(x.toLowerCase()) || + regex.test(x.toLowerCase().replaceAll(" ", "_")) + ); + }; + tempResults = TAC.Globals.lycos.filter((x) => filterCondition(x[0])); // Filter by tagword + } else { + tempResults = TAC.Globals.lycos; + } - // Add final results - let finalResults = []; - tempResults.forEach(t => { - const text = t[0].trim(); - let lastDot = text.lastIndexOf(".") > -1 ? text.lastIndexOf(".") : text.length; - let lastSlash = text.lastIndexOf("/") > -1 ? text.lastIndexOf("/") : -1; - let name = text.substring(lastSlash + 1, lastDot); + // Add final results + let finalResults = []; + tempResults.forEach((t) => { + const text = t[0].trim(); + let lastDot = text.lastIndexOf(".") > -1 ? text.lastIndexOf(".") : text.length; + let lastSlash = text.lastIndexOf("/") > -1 ? text.lastIndexOf("/") : -1; + let name = text.substring(lastSlash + 1, lastDot); - let result = new TAC.AutocompleteResult(name, TAC.ResultType.lyco) - result.meta = "Lyco"; - result.sortKey = t[1]; - result.hash = t[2]; - finalResults.push(result); - }); + let result = new TAC.AutocompleteResult(name, TAC.ResultType.lyco); + result.meta = "Lyco"; + result.sortKey = t[1]; + result.hash = t[2]; + finalResults.push(result); + }); - return finalResults; - } -} - -async function load() { - if (TAC.Globals.lycos.length === 0) { - try { - TAC.Globals.lycos = (await TacUtils.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 - } catch (e) { - console.error("Error loading lyco.txt: " + e); + return finalResults; } } -} -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}`) - if (info && info["preferred weight"]) { - multiplier = info["preferred weight"]; + async function load() { + if (TAC.Globals.lycos.length === 0) { + try { + TAC.Globals.lycos = ( + await TacUtils.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 + } catch (e) { + console.error("Error loading lyco.txt: " + e); + } } - - let prefix = TAC.CFG.useLoraPrefixForLycos ? "lora" : "lyco"; - return `<${prefix}:${text}:${multiplier}>`; } - return null; -} -TAC.Ext.PARSERS.push(new LycoParser(LYCO_TRIGGER)); + 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}`); + if (info && info["preferred weight"]) { + multiplier = info["preferred weight"]; + } -// Add our utility functions to their respective queues -TAC.Ext.QUEUE_FILE_LOAD.push(load); -TAC.Ext.QUEUE_SANITIZE.push(sanitize); + let prefix = TAC.CFG.useLoraPrefixForLycos ? "lora" : "lyco"; + return `<${prefix}:${text}:${multiplier}>`; + } + return null; + } + + TAC.Ext.PARSERS.push(new LycoParser(LYCO_TRIGGER)); + + // Add our utility functions to their respective queues + TAC.Ext.QUEUE_FILE_LOAD.push(load); + TAC.Ext.QUEUE_SANITIZE.push(sanitize); +})(); diff --git a/javascript/ext_modelKeyword.js b/javascript/ext_modelKeyword.js index 5a01ed9..51d108a 100644 --- a/javascript/ext_modelKeyword.js +++ b/javascript/ext_modelKeyword.js @@ -1,42 +1,56 @@ -async function load() { - let modelKeywordParts = (await TacUtils.readFile(`tmp/modelKeywordPath.txt`)).split(",") - TAC.Globals.modelKeywordPath = modelKeywordParts[0]; - let customFileExists = modelKeywordParts[1] === "True"; +(function ModelKeywordExtension() { + async function load() { + let modelKeywordParts = (await TacUtils.readFile(`tmp/modelKeywordPath.txt`)).split(","); + TAC.Globals.modelKeywordPath = modelKeywordParts[0]; + let customFileExists = modelKeywordParts[1] === "True"; - if (TAC.Globals.modelKeywordPath.length > 0 && TAC.Globals.modelKeywordDict.size === 0) { - try { - let csv_lines = []; - // Only add default keywords if wanted by the user - if (TAC.CFG.modelKeywordCompletion !== "Only user list") - csv_lines = (await TacUtils.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(`${TAC.Globals.modelKeywordPath}/lora-keyword-user.txt`))); + if (TAC.Globals.modelKeywordPath.length > 0 && TAC.Globals.modelKeywordDict.size === 0) { + try { + let csv_lines = []; + // Only add default keywords if wanted by the user + if (TAC.CFG.modelKeywordCompletion !== "Only user list") + csv_lines = await TacUtils.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( + `${TAC.Globals.modelKeywordPath}/lora-keyword-user.txt` + ) + ); - if (csv_lines.length === 0) return; + if (csv_lines.length === 0) return; - csv_lines = csv_lines.filter(x => x[0].trim().length > 0 && x[0].trim()[0] !== "#") // Remove empty lines and comments + csv_lines = csv_lines.filter( + (x) => x[0].trim().length > 0 && x[0].trim()[0] !== "#" + ); // Remove empty lines and comments - // Add to the dict - csv_lines.forEach(parts => { - const hash = parts[0]; - const keywords = parts[1]?.replaceAll("| ", ", ")?.replaceAll("|", ", ")?.trim(); - const lastSepIndex = parts[2]?.lastIndexOf("/") + 1 || parts[2]?.lastIndexOf("\\") + 1 || 0; - const name = parts[2]?.substring(lastSepIndex).trim() || "none" + // Add to the dict + csv_lines.forEach((parts) => { + const hash = parts[0]; + const keywords = parts[1] + ?.replaceAll("| ", ", ") + ?.replaceAll("|", ", ") + ?.trim(); + const lastSepIndex = + parts[2]?.lastIndexOf("/") + 1 || parts[2]?.lastIndexOf("\\") + 1 || 0; + const name = parts[2]?.substring(lastSepIndex).trim() || "none"; - if (TAC.Globals.modelKeywordDict.has(hash) && name !== "none") { - // Add a new name key if the hash already exists - TAC.Globals.modelKeywordDict.get(hash).set(name, keywords); - } else { - // Create new hash entry - let map = new Map().set(name, keywords); - TAC.Globals.modelKeywordDict.set(hash, map); - } - }); - } catch (e) { - console.error("Error loading model-keywords list: " + e); + if (TAC.Globals.modelKeywordDict.has(hash) && name !== "none") { + // Add a new name key if the hash already exists + TAC.Globals.modelKeywordDict.get(hash).set(name, keywords); + } else { + // Create new hash entry + let map = new Map().set(name, keywords); + TAC.Globals.modelKeywordDict.set(hash, map); + } + }); + } catch (e) { + console.error("Error loading model-keywords list: " + e); + } } } -} -TAC.Ext.QUEUE_FILE_LOAD.push(load); \ No newline at end of file + TAC.Ext.QUEUE_FILE_LOAD.push(load); +})(); diff --git a/javascript/ext_styles.js b/javascript/ext_styles.js index 5b56e16..4e4de58 100644 --- a/javascript/ext_styles.js +++ b/javascript/ext_styles.js @@ -1,70 +1,77 @@ -const STYLE_REGEX = /(\$(\d*)\(?)[^$|\[\],\s]*\)?/; -const STYLE_TRIGGER = () => TAC.CFG.useStyleVars && TAC.Globals.tagword.match(STYLE_REGEX); +(function StyleExtension() { + const STYLE_REGEX = /(\$(\d*)\(?)[^$|\[\],\s]*\)?/; + const STYLE_TRIGGER = () => TAC.CFG.useStyleVars && TAC.Globals.tagword.match(STYLE_REGEX); -var lastStyleVarIndex = ""; + var lastStyleVarIndex = ""; -class StyleParser extends BaseTagParser { - async parse() { - // Refresh if needed - await TacUtils.refreshStyleNamesIfChanged(); + class StyleParser extends TAC.BaseTagParser { + async parse() { + // Refresh if needed + await TacUtils.refreshStyleNamesIfChanged(); - // Show styles - let tempResults = []; - let matchGroups = TAC.Globals.tagword.match(STYLE_REGEX); - - // Save index to insert again later or clear last one - lastStyleVarIndex = matchGroups[2] ? matchGroups[2] : ""; + // Show styles + let tempResults = []; + let matchGroups = TAC.Globals.tagword.match(STYLE_REGEX); - if (TAC.Globals.tagword !== matchGroups[1]) { - let searchTerm = TAC.Globals.tagword.replace(matchGroups[1], ""); - - let filterCondition = x => { - let regex = new RegExp(TacUtils.escapeRegExp(searchTerm, true), 'i'); - return regex.test(x[0].toLowerCase()) || regex.test(x[0].toLowerCase().replaceAll(" ", "_")); - }; - tempResults = TAC.Globals.styleNames.filter(x => filterCondition(x)); // Filter by tagword - } else { - tempResults = TAC.Globals.styleNames; - } + // Save index to insert again later or clear last one + lastStyleVarIndex = matchGroups[2] ? matchGroups[2] : ""; - // Add final results - let finalResults = []; - tempResults.forEach(t => { - let result = new TAC.AutocompleteResult(t[0].trim(), TAC.ResultType.styleName) - result.meta = "Style"; - finalResults.push(result); - }); + if (TAC.Globals.tagword !== matchGroups[1]) { + let searchTerm = TAC.Globals.tagword.replace(matchGroups[1], ""); - return finalResults; - } -} + let filterCondition = (x) => { + let regex = new RegExp(TacUtils.escapeRegExp(searchTerm, true), "i"); + return ( + regex.test(x[0].toLowerCase()) || + regex.test(x[0].toLowerCase().replaceAll(" ", "_")) + ); + }; + tempResults = TAC.Globals.styleNames.filter((x) => filterCondition(x)); // Filter by tagword + } else { + tempResults = TAC.Globals.styleNames; + } -async function load(force = false) { - if (TAC.Globals.styleNames.length === 0 || force) { - try { - TAC.Globals.styleNames = (await TacUtils.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 - .map(x => [x[0].trim()]); // Trim name - } catch (e) { - console.error("Error loading styles.txt: " + e); + // Add final results + let finalResults = []; + tempResults.forEach((t) => { + let result = new TAC.AutocompleteResult(t[0].trim(), TAC.ResultType.styleName); + result.meta = "Style"; + finalResults.push(result); + }); + + return finalResults; } } -} -function sanitize(tagType, text) { - if (tagType === TAC.ResultType.styleName) { - if (text.includes(" ")) { - return `$${lastStyleVarIndex}(${text})`; - } else { - return`$${lastStyleVarIndex}${text}` + async function load(force = false) { + if (TAC.Globals.styleNames.length === 0 || force) { + try { + TAC.Globals.styleNames = ( + await TacUtils.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 + .map((x) => [x[0].trim()]); // Trim name + } catch (e) { + console.error("Error loading styles.txt: " + e); + } } } - return null; -} -TAC.Ext.PARSERS.push(new StyleParser(STYLE_TRIGGER)); + function sanitize(tagType, text) { + if (tagType === TAC.ResultType.styleName) { + if (text.includes(" ")) { + return `$${lastStyleVarIndex}(${text})`; + } else { + return `$${lastStyleVarIndex}${text}`; + } + } + return null; + } -// Add our utility functions to their respective queues -TAC.Ext.QUEUE_FILE_LOAD.push(load); -TAC.Ext.QUEUE_SANITIZE.push(sanitize); + TAC.Ext.PARSERS.push(new StyleParser(STYLE_TRIGGER)); + + // Add our utility functions to their respective queues + TAC.Ext.QUEUE_FILE_LOAD.push(load); + TAC.Ext.QUEUE_SANITIZE.push(sanitize); +})(); diff --git a/javascript/ext_umi.js b/javascript/ext_umi.js index 0c5ab8c..7eb14f5 100644 --- a/javascript/ext_umi.js +++ b/javascript/ext_umi.js @@ -1,163 +1,210 @@ -const UMI_PROMPT_REGEX = /<[^\s]*?\[[^,<>]*[\]|]?>?/gi; -const UMI_TAG_REGEX = /(?:\[|\||--)([^<>\[\]\-|]+)/gi; +(function UmiExtension() { + const UMI_PROMPT_REGEX = /<[^\s]*?\[[^,<>]*[\]|]?>?/gi; + const UMI_TAG_REGEX = /(?:\[|\||--)([^<>\[\]\-|]+)/gi; -const UMI_TRIGGER = () => TAC.CFG.useWildcards && [...TAC.Globals.tagword.matchAll(UMI_PROMPT_REGEX)].length > 0; + const UMI_TRIGGER = () => + TAC.CFG.useWildcards && [...TAC.Globals.tagword.matchAll(UMI_PROMPT_REGEX)].length > 0; -class UmiParser extends BaseTagParser { - parse(textArea, prompt) { - // We are in a UMI yaml tag definition, parse further - let umiSubPrompts = [...prompt.matchAll(UMI_PROMPT_REGEX)]; + class UmiParser extends TAC.BaseTagParser { + parse(textArea, prompt) { + // We are in a UMI yaml tag definition, parse further + let umiSubPrompts = [...prompt.matchAll(UMI_PROMPT_REGEX)]; - let umiTags = []; - let umiTagsWithOperators = [] + let umiTags = []; + let umiTagsWithOperators = []; - const insertAt = (str,char,pos) => str.slice(0,pos) + char + str.slice(pos); + const insertAt = (str, char, pos) => str.slice(0, pos) + char + str.slice(pos); - umiSubPrompts.forEach(umiSubPrompt => { - umiTags = umiTags.concat([...umiSubPrompt[0].matchAll(UMI_TAG_REGEX)].map(x => x[1].toLowerCase())); - - const start = umiSubPrompt.index; - const end = umiSubPrompt.index + umiSubPrompt[0].length; - if (textArea.selectionStart >= start && textArea.selectionStart <= end) { - umiTagsWithOperators = insertAt(umiSubPrompt[0], '###', textArea.selectionStart - start); - } - }); - - // Safety check since UMI parsing sometimes seems to trigger outside of an UMI subprompt and thus fails - if (umiTagsWithOperators.length === 0) { - return null; - } - - const promptSplitToTags = umiTagsWithOperators.replace(']###[', '][').split("]["); - - const clean = (str) => str - .replaceAll('>', '') - .replaceAll('<', '') - .replaceAll('[', '') - .replaceAll(']', '') - .trim(); - - const matches = promptSplitToTags.reduce((acc, curr) => { - let isOptional = curr.includes("|"); - let isNegative = curr.startsWith("--"); - let out; - if (isOptional) { - out = { - hasCursor: curr.includes("###"), - tags: clean(curr).split('|').map(x => ({ - hasCursor: x.includes("###"), - isNegative: x.startsWith("--"), - tag: clean(x).replaceAll("###", '').replaceAll("--", '') - })) - }; - acc.optional.push(out); - acc.all.push(...out.tags.map(x => x.tag)); - } else if (isNegative) { - out = { - hasCursor: curr.includes("###"), - tags: clean(curr).replaceAll("###", '').split('|'), - }; - out.tags = out.tags.map(x => x.startsWith("--") ? x.substring(2) : x); - acc.negative.push(out); - acc.all.push(...out.tags); - } else { - out = { - hasCursor: curr.includes("###"), - tags: clean(curr).replaceAll("###", '').split('|'), - }; - acc.positive.push(out); - acc.all.push(...out.tags); - } - return acc; - }, { positive: [], negative: [], optional: [], all: [] }); - - //console.log({ matches }) - - const filteredWildcards = (tagword) => { - const wildcards = TAC.Globals.umiWildcards.filter(x => { - let tags = x[1]; - const matchesNeg = - matches.negative.length === 0 - || matches.negative.every(x => - x.hasCursor - || x.tags.every(t => !tags[t]) - ); - if (!matchesNeg) return false; - const matchesPos = - matches.positive.length === 0 - || matches.positive.every(x => - x.hasCursor - || x.tags.every(t => tags[t]) - ); - if (!matchesPos) return false; - const matchesOpt = - matches.optional.length === 0 - || matches.optional.some(x => - x.tags.some(t => - t.hasCursor - || t.isNegative - ? !tags[t.tag] - : tags[t.tag] - )); - if (!matchesOpt) return false; - return true; - }).reduce((acc, val) => { - Object.keys(val[1]).forEach(tag => acc[tag] = acc[tag] + 1 || 1); - return acc; - }, {}); - - return Object.entries(wildcards) - .sort((a, b) => b[1] - a[1]) - .filter(x => - x[0] === tagword - || !matches.all.includes(x[0]) + umiSubPrompts.forEach((umiSubPrompt) => { + umiTags = umiTags.concat( + [...umiSubPrompt[0].matchAll(UMI_TAG_REGEX)].map((x) => x[1].toLowerCase()) ); - } - if (umiTags.length > 0) { - // Get difference for subprompt - let tagCountChange = umiTags.length - TAC.Globals.umiPreviousTags.length; - let diff = TacUtils.difference(umiTags, TAC.Globals.umiPreviousTags); - TAC.Globals.umiPreviousTags = umiTags; + const start = umiSubPrompt.index; + const end = umiSubPrompt.index + umiSubPrompt[0].length; + if (textArea.selectionStart >= start && textArea.selectionStart <= end) { + umiTagsWithOperators = insertAt( + umiSubPrompt[0], + "###", + textArea.selectionStart - start + ); + } + }); - // Show all condition - let showAll = TAC.Globals.tagword.endsWith("[") || TAC.Globals.tagword.endsWith("[--") || TAC.Globals.tagword.endsWith("|"); - - // Exit early if the user closed the bracket manually - if ((!diff || diff.length === 0 || (diff.length === 1 && tagCountChange < 0)) && !showAll) { - if (!TAC.Globals.hideBlocked) hideResults(textArea); - return; + // Safety check since UMI parsing sometimes seems to trigger outside of an UMI subprompt and thus fails + if (umiTagsWithOperators.length === 0) { + return null; } - let umiTagword = tagCountChange < 0 ? '' : diff[0] || ''; - let tempResults = []; - if (umiTagword && umiTagword.length > 0) { - umiTagword = umiTagword.toLowerCase().replace(/[\n\r]/g, ""); - TAC.Globals.originalTagword = TAC.Globals.tagword; - TAC.Globals.tagword = umiTagword; - let filteredWildcardsSorted = filteredWildcards(umiTagword); - let searchRegex = new RegExp(`(^|[^a-zA-Z])${TacUtils.escapeRegExp(umiTagword)}`, 'i') - let baseFilter = x => x[0].toLowerCase().search(searchRegex) > -1; - let spaceIncludeFilter = x => x[0].toLowerCase().replaceAll(" ", "_").search(searchRegex) > -1; - tempResults = filteredWildcardsSorted.filter(x => baseFilter(x) || spaceIncludeFilter(x)) // Filter by tagword + const promptSplitToTags = umiTagsWithOperators.replace("]###[", "][").split("]["); - // Add final results - let finalResults = []; - tempResults.forEach(t => { - let result = new TAC.AutocompleteResult(t[0].trim(), TAC.ResultType.umiWildcard) - result.count = t[1]; - finalResults.push(result); - }); + const clean = (str) => + str + .replaceAll(">", "") + .replaceAll("<", "") + .replaceAll("[", "") + .replaceAll("]", "") + .trim(); - finalResults = finalResults.sort((a, b) => b.count - a.count); - return finalResults; - } else if (showAll) { + const matches = promptSplitToTags.reduce( + (acc, curr) => { + let isOptional = curr.includes("|"); + let isNegative = curr.startsWith("--"); + let out; + if (isOptional) { + out = { + hasCursor: curr.includes("###"), + tags: clean(curr) + .split("|") + .map((x) => ({ + hasCursor: x.includes("###"), + isNegative: x.startsWith("--"), + tag: clean(x).replaceAll("###", "").replaceAll("--", ""), + })), + }; + acc.optional.push(out); + acc.all.push(...out.tags.map((x) => x.tag)); + } else if (isNegative) { + out = { + hasCursor: curr.includes("###"), + tags: clean(curr).replaceAll("###", "").split("|"), + }; + out.tags = out.tags.map((x) => (x.startsWith("--") ? x.substring(2) : x)); + acc.negative.push(out); + acc.all.push(...out.tags); + } else { + out = { + hasCursor: curr.includes("###"), + tags: clean(curr).replaceAll("###", "").split("|"), + }; + acc.positive.push(out); + acc.all.push(...out.tags); + } + return acc; + }, + { positive: [], negative: [], optional: [], all: [] } + ); + + //console.log({ matches }) + + const filteredWildcards = (tagword) => { + const wildcards = TAC.Globals.umiWildcards + .filter((x) => { + let tags = x[1]; + const matchesNeg = + matches.negative.length === 0 || + matches.negative.every( + (x) => x.hasCursor || x.tags.every((t) => !tags[t]) + ); + if (!matchesNeg) return false; + const matchesPos = + matches.positive.length === 0 || + matches.positive.every( + (x) => x.hasCursor || x.tags.every((t) => tags[t]) + ); + if (!matchesPos) return false; + const matchesOpt = + matches.optional.length === 0 || + matches.optional.some((x) => + x.tags.some((t) => + t.hasCursor || t.isNegative ? !tags[t.tag] : tags[t.tag] + ) + ); + if (!matchesOpt) return false; + return true; + }) + .reduce((acc, val) => { + Object.keys(val[1]).forEach((tag) => (acc[tag] = acc[tag] + 1 || 1)); + return acc; + }, {}); + + return Object.entries(wildcards) + .sort((a, b) => b[1] - a[1]) + .filter((x) => x[0] === tagword || !matches.all.includes(x[0])); + }; + + if (umiTags.length > 0) { + // Get difference for subprompt + let tagCountChange = umiTags.length - TAC.Globals.umiPreviousTags.length; + let diff = TacUtils.difference(umiTags, TAC.Globals.umiPreviousTags); + TAC.Globals.umiPreviousTags = umiTags; + + // Show all condition + let showAll = + TAC.Globals.tagword.endsWith("[") || + TAC.Globals.tagword.endsWith("[--") || + TAC.Globals.tagword.endsWith("|"); + + // Exit early if the user closed the bracket manually + if ( + (!diff || diff.length === 0 || (diff.length === 1 && tagCountChange < 0)) && + !showAll + ) { + if (!TAC.Globals.hideBlocked) hideResults(textArea); + return; + } + + let umiTagword = tagCountChange < 0 ? "" : diff[0] || ""; + let tempResults = []; + if (umiTagword && umiTagword.length > 0) { + umiTagword = umiTagword.toLowerCase().replace(/[\n\r]/g, ""); + TAC.Globals.originalTagword = TAC.Globals.tagword; + TAC.Globals.tagword = umiTagword; + let filteredWildcardsSorted = filteredWildcards(umiTagword); + let searchRegex = new RegExp( + `(^|[^a-zA-Z])${TacUtils.escapeRegExp(umiTagword)}`, + "i" + ); + let baseFilter = (x) => x[0].toLowerCase().search(searchRegex) > -1; + let spaceIncludeFilter = (x) => + x[0].toLowerCase().replaceAll(" ", "_").search(searchRegex) > -1; + tempResults = filteredWildcardsSorted.filter( + (x) => baseFilter(x) || spaceIncludeFilter(x) + ); // Filter by tagword + + // Add final results + let finalResults = []; + tempResults.forEach((t) => { + let result = new TAC.AutocompleteResult( + t[0].trim(), + TAC.ResultType.umiWildcard + ); + result.count = t[1]; + finalResults.push(result); + }); + + finalResults = finalResults.sort((a, b) => b.count - a.count); + return finalResults; + } else if (showAll) { + let filteredWildcardsSorted = filteredWildcards(""); + + // Add final results + let finalResults = []; + filteredWildcardsSorted.forEach((t) => { + let result = new TAC.AutocompleteResult( + t[0].trim(), + TAC.ResultType.umiWildcard + ); + result.count = t[1]; + finalResults.push(result); + }); + + TAC.Globals.originalTagword = TAC.Globals.tagword; + TAC.Globals.tagword = ""; + + finalResults = finalResults.sort((a, b) => b.count - a.count); + return finalResults; + } + } else { let filteredWildcardsSorted = filteredWildcards(""); // Add final results let finalResults = []; - filteredWildcardsSorted.forEach(t => { - let result = new TAC.AutocompleteResult(t[0].trim(), TAC.ResultType.umiWildcard) + filteredWildcardsSorted.forEach((t) => { + let result = new TAC.AutocompleteResult( + t[0].trim(), + TAC.ResultType.umiWildcard + ); result.count = t[1]; finalResults.push(result); }); @@ -168,78 +215,65 @@ class UmiParser extends BaseTagParser { finalResults = finalResults.sort((a, b) => b.count - a.count); return finalResults; } - } else { - let filteredWildcardsSorted = filteredWildcards(""); + } + } - // Add final results - let finalResults = []; - filteredWildcardsSorted.forEach(t => { - let result = new TAC.AutocompleteResult(t[0].trim(), TAC.ResultType.umiWildcard) - result.count = t[1]; - finalResults.push(result); + function updateUmiTags(tagType, sanitizedText, newPrompt, textArea) { + // If it was a umi wildcard, also update the TAC.Globals.umiPreviousTags + if (tagType === TAC.ResultType.umiWildcard && TAC.Globals.originalTagword.length > 0) { + let umiSubPrompts = [...newPrompt.matchAll(UMI_PROMPT_REGEX)]; + + let umiTags = []; + umiSubPrompts.forEach((umiSubPrompt) => { + umiTags = umiTags.concat( + [...umiSubPrompt[0].matchAll(UMI_TAG_REGEX)].map((x) => x[1].toLowerCase()) + ); }); - TAC.Globals.originalTagword = TAC.Globals.tagword; - TAC.Globals.tagword = ""; + TAC.Globals.umiPreviousTags = umiTags; - finalResults = finalResults.sort((a, b) => b.count - a.count); - return finalResults; + hideResults(textArea); + + return true; + } + return false; + } + + async function load() { + if (TAC.Globals.umiWildcards.length === 0) { + try { + let umiTags = ( + await TacUtils.readFile(`${TAC.Globals.tagBasePath}/temp/umi_tags.txt`) + ).split("\n"); + // Split into tag, count pairs + TAC.Globals.umiWildcards = umiTags + .map((x) => x.trim().split(",")) + .map(([i, ...rest]) => [ + i, + rest.reduce((a, b) => { + a[b.toLowerCase()] = true; + return a; + }, {}), + ]); + } catch (e) { + console.error("Error loading umi wildcards: " + e); + } } } -} -function updateUmiTags(tagType, sanitizedText, newPrompt, textArea) { - // If it was a umi wildcard, also update the TAC.Globals.umiPreviousTags - if (tagType === TAC.ResultType.umiWildcard && TAC.Globals.originalTagword.length > 0) { - let umiSubPrompts = [...newPrompt.matchAll(UMI_PROMPT_REGEX)]; - - let umiTags = []; - umiSubPrompts.forEach(umiSubPrompt => { - umiTags = umiTags.concat([...umiSubPrompt[0].matchAll(UMI_TAG_REGEX)].map(x => x[1].toLowerCase())); - }); - - TAC.Globals.umiPreviousTags = umiTags; - - hideResults(textArea); - - return true; - } - return false; -} - -async function load() { - if (TAC.Globals.umiWildcards.length === 0) { - try { - let umiTags = (await TacUtils.readFile(`${TAC.Globals.tagBasePath}/temp/umi_tags.txt`)).split("\n"); - // Split into tag, count pairs - TAC.Globals.umiWildcards = umiTags.map(x => x - .trim() - .split(",")) - .map(([i, ...rest]) => [ - i, - rest.reduce((a, b) => { - a[b.toLowerCase()] = true; - return a; - }, {}), - ]); - } catch (e) { - console.error("Error loading umi wildcards: " + e); + function sanitize(tagType, text) { + // Replace underscores only if the umi tag is not using them + if (tagType === TAC.ResultType.umiWildcard && !TAC.Globals.umiWildcards.includes(text)) { + return text.replaceAll("_", " "); } + return null; } -} -function sanitize(tagType, text) { - // Replace underscores only if the umi tag is not using them - if (tagType === TAC.ResultType.umiWildcard && !TAC.Globals.umiWildcards.includes(text)) { - return text.replaceAll("_", " "); - } - return null; -} + // Add UMI parser + TAC.Ext.PARSERS.push(new UmiParser(UMI_TRIGGER)); -// Add UMI parser -TAC.Ext.PARSERS.push(new UmiParser(UMI_TRIGGER)); - -// Add our utility functions to their respective queues -TAC.Ext.QUEUE_FILE_LOAD.push(load); -TAC.Ext.QUEUE_SANITIZE.push(sanitize); -TAC.Ext.QUEUE_AFTER_INSERT.push(updateUmiTags); \ No newline at end of file + // Add our utility functions to their respective queues + TAC.Ext.QUEUE_FILE_LOAD.push(load); + TAC.Ext.QUEUE_SANITIZE.push(sanitize); + TAC.Ext.QUEUE_AFTER_INSERT.push(updateUmiTags); +})(); diff --git a/javascript/ext_wildcards.js b/javascript/ext_wildcards.js index b789a4d..6975ace 100644 --- a/javascript/ext_wildcards.js +++ b/javascript/ext_wildcards.js @@ -1,178 +1,232 @@ -// Regex -const WC_REGEX = new RegExp(/__([^,]+)__([^, ]*)/g); +(function WildcardExtension() { + // Regex + const WC_REGEX = new RegExp(/__([^,]+)__([^, ]*)/g); -// Trigger conditions -const WC_TRIGGER = () => TAC.CFG.useWildcards && [...TAC.Globals.tagword.matchAll(new RegExp(WC_REGEX.source.replaceAll("__", TacUtils.escapeRegExp(TAC.CFG.wcWrap)), "g"))].length > 0; -const WC_FILE_TRIGGER = () => TAC.CFG.useWildcards && (TAC.Globals.tagword.startsWith(TAC.CFG.wcWrap) && !TAC.Globals.tagword.endsWith(TAC.CFG.wcWrap) || TAC.Globals.tagword === TAC.CFG.wcWrap); + // Trigger conditions + const WC_TRIGGER = () => + TAC.CFG.useWildcards && + [ + ...TAC.Globals.tagword.matchAll( + new RegExp( + WC_REGEX.source.replaceAll("__", TacUtils.escapeRegExp(TAC.CFG.wcWrap)), + "g" + ) + ), + ].length > 0; + const WC_FILE_TRIGGER = () => + TAC.CFG.useWildcards && + ((TAC.Globals.tagword.startsWith(TAC.CFG.wcWrap) && + !TAC.Globals.tagword.endsWith(TAC.CFG.wcWrap)) || + TAC.Globals.tagword === TAC.CFG.wcWrap); -class WildcardParser extends BaseTagParser { - async parse() { - // Show wildcards from a file with that name - let wcMatch = [...TAC.Globals.tagword.matchAll(new RegExp(WC_REGEX.source.replaceAll("__", TacUtils.escapeRegExp(TAC.CFG.wcWrap)), "g"))]; - let wcFile = wcMatch[0][1]; - let wcWord = wcMatch[0][2]; + class WildcardParser extends TAC.BaseTagParser { + async parse() { + // Show wildcards from a file with that name + let wcMatch = [ + ...TAC.Globals.tagword.matchAll( + new RegExp( + WC_REGEX.source.replaceAll("__", TacUtils.escapeRegExp(TAC.CFG.wcWrap)), + "g" + ) + ), + ]; + let wcFile = wcMatch[0][1]; + let wcWord = wcMatch[0][2]; - // Look in normal wildcard files - let wcFound = TAC.Globals.wildcardFiles.filter(x => x[1].toLowerCase() === wcFile); - if (wcFound.length === 0) wcFound = null; - // Use found wildcard file or look in external wildcard files - let wcPairs = wcFound || TAC.Globals.wildcardExtFiles.filter(x => x[1].toLowerCase() === wcFile); + // Look in normal wildcard files + let wcFound = TAC.Globals.wildcardFiles.filter((x) => x[1].toLowerCase() === wcFile); + if (wcFound.length === 0) wcFound = null; + // Use found wildcard file or look in external wildcard files + let wcPairs = + wcFound || + TAC.Globals.wildcardExtFiles.filter((x) => x[1].toLowerCase() === wcFile); - if (!wcPairs) return []; + if (!wcPairs) return []; - let wildcards = []; - for (let i = 0; i < wcPairs.length; i++) { - const basePath = wcPairs[i][0]; - const fileName = wcPairs[i][1]; - if (!basePath || !fileName) return; + let wildcards = []; + for (let i = 0; i < wcPairs.length; i++) { + const basePath = wcPairs[i][0]; + const fileName = wcPairs[i][1]; + if (!basePath || !fileName) return; - // YAML wildcards are already loaded as json, so we can get the values directly. - // basePath is the name of the file in this case, and fileName the key - if (basePath.endsWith(".yaml")) { - const getDescendantProp = (obj, desc) => { - const arr = desc.split("/"); - while (arr.length) { - obj = obj[arr.shift()]; - } - return obj; - } - wildcards = wildcards.concat(getDescendantProp(TAC.Globals.yamlWildcards[basePath], fileName)); - } else { - const fileContent = (await TacUtils.fetchAPI(`tacapi/v1/wildcard-contents?basepath=${basePath}&filename=${fileName}.txt`, false)) - .split("\n") - .filter(x => x.trim().length > 0 && !x.startsWith('#')); // Remove empty lines and comments - wildcards = wildcards.concat(fileContent); - } - } - - if (TAC.CFG.sortWildcardResults) - wildcards.sort((a, b) => a.localeCompare(b)); - - let finalResults = []; - let tempResults = wildcards.filter(x => (wcWord !== null && wcWord.length > 0) ? x.toLowerCase().includes(wcWord) : x) // Filter by tagword - tempResults.forEach(t => { - let result = new TAC.AutocompleteResult(t.trim(), TAC.ResultType.wildcardTag); - result.meta = wcFile; - finalResults.push(result); - }); - - return finalResults; - } -} - -class WildcardFileParser extends BaseTagParser { - parse() { - // Show available wildcard files - let tempResults = []; - if (TAC.Globals.tagword !== TAC.CFG.wcWrap) { - let lmb = (x) => x[1].toLowerCase().includes(TAC.Globals.tagword.replace(TAC.CFG.wcWrap, "")) - tempResults = TAC.Globals.wildcardFiles.filter(lmb).concat(TAC.Globals.wildcardExtFiles.filter(lmb)) // Filter by tagword - } else { - tempResults = TAC.Globals.wildcardFiles.concat(TAC.Globals.wildcardExtFiles); - } - - let finalResults = []; - const alreadyAdded = new Map(); - // Get final results - tempResults.forEach(wcFile => { - // Skip duplicate entries incase multiple files have the same name or yaml category - if (alreadyAdded.has(wcFile[1])) return; - - let result = null; - if (wcFile[0].endsWith(".yaml")) { - result = new TAC.AutocompleteResult(wcFile[1].trim(), TAC.ResultType.yamlWildcard); - result.meta = "YAML wildcard collection"; - } else { - result = new TAC.AutocompleteResult(wcFile[1].trim(), TAC.ResultType.wildcardFile); - result.meta = "Wildcard file"; - result.sortKey = wcFile[2].trim(); - } - - finalResults.push(result); - alreadyAdded.set(wcFile[1], true); - }); - - finalResults.sort(TacUtils.getSortFunction()); - - return finalResults; - } -} - -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`); - if (wcFileArr && wcFileArr.length > 0) { - let wcBasePath = wcFileArr[0][0].trim(); // First line should be the base path - TAC.Globals.wildcardFiles = wcFileArr.slice(1) - .filter(x => x[0]?.trim().length > 0) //Remove empty lines - .map(x => [wcBasePath, x[0]?.trim().replace(".txt", ""), x[1]]); // Remove file extension & newlines - } - - // To support multiple sources, we need to separate them using the provided "-----" strings - let wcExtFileArr = await TacUtils.loadCSV(`${TAC.Globals.tagBasePath}/temp/wce.txt`); - let splitIndices = []; - for (let index = 0; index < wcExtFileArr.length; index++) { - if (wcExtFileArr[index][0].trim() === "-----") { - splitIndices.push(index); - } - } - // For each group, add them to the wildcardFiles array with the base path as the first element - for (let i = 0; i < splitIndices.length; i++) { - let start = splitIndices[i - 1] || 0; - if (i > 0) start++; // Skip the "-----" line - let end = splitIndices[i]; - - let wcExtFile = wcExtFileArr.slice(start, end); - if (wcExtFile && wcExtFile.length > 0) { - let base = wcExtFile[0][0].trim() + "/"; - wcExtFile = wcExtFile.slice(1) - .filter(x => x[0]?.trim().length > 0) //Remove empty lines - .map(x => [base, x[0]?.trim().replace(base, "").replace(".txt", ""), x[1]]); - TAC.Globals.wildcardExtFiles.push(...wcExtFile); + // YAML wildcards are already loaded as json, so we can get the values directly. + // basePath is the name of the file in this case, and fileName the key + if (basePath.endsWith(".yaml")) { + const getDescendantProp = (obj, desc) => { + const arr = desc.split("/"); + while (arr.length) { + obj = obj[arr.shift()]; + } + return obj; + }; + wildcards = wildcards.concat( + getDescendantProp(TAC.Globals.yamlWildcards[basePath], fileName) + ); + } else { + const fileContent = ( + await TacUtils.fetchAPI( + `tacapi/v1/wildcard-contents?basepath=${basePath}&filename=${fileName}.txt`, + false + ) + ) + .split("\n") + .filter((x) => x.trim().length > 0 && !x.startsWith("#")); // Remove empty lines and comments + wildcards = wildcards.concat(fileContent); } } - // 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.tagBasePath}/temp/wc_yaml.json`, true); + if (TAC.CFG.sortWildcardResults) wildcards.sort((a, b) => a.localeCompare(b)); - // 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], [], "/"); - Object.keys(flattened).forEach(key => { - TAC.Globals.wildcardExtFiles.push([file, key]); - }); + let finalResults = []; + let tempResults = wildcards.filter((x) => + wcWord !== null && wcWord.length > 0 ? x.toLowerCase().includes(wcWord) : x + ); // Filter by tagword + tempResults.forEach((t) => { + let result = new TAC.AutocompleteResult(t.trim(), TAC.ResultType.wildcardTag); + result.meta = wcFile; + finalResults.push(result); }); - } catch (e) { - console.error("Error loading wildcards: " + e); + + return finalResults; } } -} -function sanitize(tagType, text) { - if (tagType === TAC.ResultType.wildcardFile || tagType === TAC.ResultType.yamlWildcard) { - return `${TAC.CFG.wcWrap}${text}${TAC.CFG.wcWrap}`; - } else if (tagType === TAC.ResultType.wildcardTag) { - return text; + class WildcardFileParser extends TAC.BaseTagParser { + parse() { + // Show available wildcard files + let tempResults = []; + if (TAC.Globals.tagword !== TAC.CFG.wcWrap) { + let lmb = (x) => + x[1].toLowerCase().includes(TAC.Globals.tagword.replace(TAC.CFG.wcWrap, "")); + tempResults = TAC.Globals.wildcardFiles + .filter(lmb) + .concat(TAC.Globals.wildcardExtFiles.filter(lmb)); // Filter by tagword + } else { + tempResults = TAC.Globals.wildcardFiles.concat(TAC.Globals.wildcardExtFiles); + } + + let finalResults = []; + const alreadyAdded = new Map(); + // Get final results + tempResults.forEach((wcFile) => { + // Skip duplicate entries incase multiple files have the same name or yaml category + if (alreadyAdded.has(wcFile[1])) return; + + let result = null; + if (wcFile[0].endsWith(".yaml")) { + result = new TAC.AutocompleteResult( + wcFile[1].trim(), + TAC.ResultType.yamlWildcard + ); + result.meta = "YAML wildcard collection"; + } else { + result = new TAC.AutocompleteResult( + wcFile[1].trim(), + TAC.ResultType.wildcardFile + ); + result.meta = "Wildcard file"; + result.sortKey = wcFile[2].trim(); + } + + finalResults.push(result); + alreadyAdded.set(wcFile[1], true); + }); + + finalResults.sort(TacUtils.getSortFunction()); + + return finalResults; + } } - return null; -} -function keepOpenIfWildcard(tagType, sanitizedText, newPrompt, textArea) { - // If it's a wildcard, we want to keep the results open so the user can select another wildcard - if (tagType === TAC.ResultType.wildcardFile || tagType === TAC.ResultType.yamlWildcard) { - TAC.Globals.hideBlocked = true; - setTimeout(() => { TAC.Globals.hideBlocked = false; }, 450); - return true; + 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`); + if (wcFileArr && wcFileArr.length > 0) { + let wcBasePath = wcFileArr[0][0].trim(); // First line should be the base path + TAC.Globals.wildcardFiles = wcFileArr + .slice(1) + .filter((x) => x[0]?.trim().length > 0) //Remove empty lines + .map((x) => [wcBasePath, x[0]?.trim().replace(".txt", ""), x[1]]); // Remove file extension & newlines + } + + // To support multiple sources, we need to separate them using the provided "-----" strings + let wcExtFileArr = await TacUtils.loadCSV( + `${TAC.Globals.tagBasePath}/temp/wce.txt` + ); + let splitIndices = []; + for (let index = 0; index < wcExtFileArr.length; index++) { + if (wcExtFileArr[index][0].trim() === "-----") { + splitIndices.push(index); + } + } + // For each group, add them to the wildcardFiles array with the base path as the first element + for (let i = 0; i < splitIndices.length; i++) { + let start = splitIndices[i - 1] || 0; + if (i > 0) start++; // Skip the "-----" line + let end = splitIndices[i]; + + let wcExtFile = wcExtFileArr.slice(start, end); + if (wcExtFile && wcExtFile.length > 0) { + let base = wcExtFile[0][0].trim() + "/"; + wcExtFile = wcExtFile + .slice(1) + .filter((x) => x[0]?.trim().length > 0) //Remove empty lines + .map((x) => [ + base, + x[0]?.trim().replace(base, "").replace(".txt", ""), + x[1], + ]); + TAC.Globals.wildcardExtFiles.push(...wcExtFile); + } + } + + // 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.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], [], "/"); + Object.keys(flattened).forEach((key) => { + TAC.Globals.wildcardExtFiles.push([file, key]); + }); + }); + } catch (e) { + console.error("Error loading wildcards: " + e); + } + } } - return false; -} -// Register the parsers -TAC.Ext.PARSERS.push(new WildcardParser(WC_TRIGGER)); -TAC.Ext.PARSERS.push(new WildcardFileParser(WC_FILE_TRIGGER)); + function sanitize(tagType, text) { + if (tagType === TAC.ResultType.wildcardFile || tagType === TAC.ResultType.yamlWildcard) { + return `${TAC.CFG.wcWrap}${text}${TAC.CFG.wcWrap}`; + } else if (tagType === TAC.ResultType.wildcardTag) { + return text; + } + return null; + } -// Add our utility functions to their respective queues -TAC.Ext.QUEUE_FILE_LOAD.push(load); -TAC.Ext.QUEUE_SANITIZE.push(sanitize); -TAC.Ext.QUEUE_AFTER_INSERT.push(keepOpenIfWildcard); \ No newline at end of file + function keepOpenIfWildcard(tagType, sanitizedText, newPrompt, textArea) { + // If it's a wildcard, we want to keep the results open so the user can select another wildcard + if (tagType === TAC.ResultType.wildcardFile || tagType === TAC.ResultType.yamlWildcard) { + TAC.Globals.hideBlocked = true; + setTimeout(() => { + TAC.Globals.hideBlocked = false; + }, 450); + return true; + } + return false; + } + + // Register the parsers + TAC.Ext.PARSERS.push(new WildcardParser(WC_TRIGGER)); + TAC.Ext.PARSERS.push(new WildcardFileParser(WC_FILE_TRIGGER)); + + // Add our utility functions to their respective queues + TAC.Ext.QUEUE_FILE_LOAD.push(load); + TAC.Ext.QUEUE_SANITIZE.push(sanitize); + TAC.Ext.QUEUE_AFTER_INSERT.push(keepOpenIfWildcard); +})();