mirror of
https://github.com/DominikDoom/a1111-sd-webui-tagcomplete.git
synced 2026-02-26 09:54:12 +00:00
Isolate all parsers in a local self-executing function
This commit is contained in:
@@ -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()");
|
||||
}
|
||||
}
|
||||
@@ -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 !== "<c:") {
|
||||
let searchTerm = TAC.Globals.tagword.replace("<chant:", "").replace("<c:", "").replace("<", "");
|
||||
let filterCondition = x => {
|
||||
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 !== "<c:") {
|
||||
let searchTerm = TAC.Globals.tagword
|
||||
.replace("<chant:", "")
|
||||
.replace("<c:", "")
|
||||
.replace("<", "");
|
||||
let filterCondition = (x) => {
|
||||
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);
|
||||
})();
|
||||
|
||||
@@ -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 !== "<e:") {
|
||||
let searchTerm = TAC.Globals.tagword.replace("<e:", "").replace("<", "");
|
||||
let versionString;
|
||||
if (searchTerm.startsWith("v1") || searchTerm.startsWith("v2")) {
|
||||
versionString = searchTerm.slice(0, 2);
|
||||
searchTerm = searchTerm.slice(2);
|
||||
} else if (searchTerm.startsWith("vxl")) {
|
||||
versionString = searchTerm.slice(0, 3);
|
||||
searchTerm = searchTerm.slice(3);
|
||||
class EmbeddingParser extends TAC.BaseTagParser {
|
||||
parse() {
|
||||
// Show embeddings
|
||||
let tempResults = [];
|
||||
if (TAC.Globals.tagword !== "<" && TAC.Globals.tagword !== "<e:") {
|
||||
let searchTerm = TAC.Globals.tagword.replace("<e:", "").replace("<", "");
|
||||
let versionString;
|
||||
if (searchTerm.startsWith("v1") || searchTerm.startsWith("v2")) {
|
||||
versionString = searchTerm.slice(0, 2);
|
||||
searchTerm = searchTerm.slice(2);
|
||||
} else if (searchTerm.startsWith("vxl")) {
|
||||
versionString = searchTerm.slice(0, 3);
|
||||
searchTerm = searchTerm.slice(3);
|
||||
}
|
||||
|
||||
let filterCondition = (x) => {
|
||||
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);
|
||||
})();
|
||||
|
||||
@@ -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 !== "<h:" && TAC.Globals.tagword !== "<hypernet:") {
|
||||
let searchTerm = TAC.Globals.tagword.replace("<hypernet:", "").replace("<h:", "").replace("<", "");
|
||||
let filterCondition = x => {
|
||||
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 !== "<h:" &&
|
||||
TAC.Globals.tagword !== "<hypernet:"
|
||||
) {
|
||||
let searchTerm = TAC.Globals.tagword
|
||||
.replace("<hypernet:", "")
|
||||
.replace("<h:", "")
|
||||
.replace("<", "");
|
||||
let filterCondition = (x) => {
|
||||
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 `<hypernet:${text}:${TAC.CFG.extraNetworksDefaultMultiplier}>`;
|
||||
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 `<hypernet:${text}:${TAC.CFG.extraNetworksDefaultMultiplier}>`;
|
||||
}
|
||||
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);
|
||||
})();
|
||||
|
||||
@@ -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 !== "<l:" && TAC.Globals.tagword !== "<lora:") {
|
||||
let searchTerm = TAC.Globals.tagword.replace("<lora:", "").replace("<l:", "").replace("<", "");
|
||||
let filterCondition = x => {
|
||||
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 !== "<l:" &&
|
||||
TAC.Globals.tagword !== "<lora:"
|
||||
) {
|
||||
let searchTerm = TAC.Globals.tagword
|
||||
.replace("<lora:", "")
|
||||
.replace("<l:", "")
|
||||
.replace("<", "");
|
||||
let filterCondition = (x) => {
|
||||
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 `<lora:${text}:${multiplier}>`;
|
||||
}
|
||||
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 `<lora:${text}:${multiplier}>`;
|
||||
}
|
||||
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);
|
||||
})();
|
||||
|
||||
@@ -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 !== "<l:" && TAC.Globals.tagword !== "<lyco:" && TAC.Globals.tagword !== "<lora:") {
|
||||
let searchTerm = TAC.Globals.tagword.replace("<lyco:", "").replace("<lora:", "").replace("<l:", "").replace("<", "");
|
||||
let filterCondition = x => {
|
||||
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 !== "<l:" &&
|
||||
TAC.Globals.tagword !== "<lyco:" &&
|
||||
TAC.Globals.tagword !== "<lora:"
|
||||
) {
|
||||
let searchTerm = TAC.Globals.tagword
|
||||
.replace("<lyco:", "")
|
||||
.replace("<lora:", "")
|
||||
.replace("<l:", "")
|
||||
.replace("<", "");
|
||||
let filterCondition = (x) => {
|
||||
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);
|
||||
})();
|
||||
|
||||
@@ -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);
|
||||
TAC.Ext.QUEUE_FILE_LOAD.push(load);
|
||||
})();
|
||||
|
||||
@@ -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);
|
||||
})();
|
||||
|
||||
@@ -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);
|
||||
// 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);
|
||||
})();
|
||||
|
||||
@@ -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);
|
||||
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);
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user