This commit is contained in:
nik
2025-10-03 22:27:28 +03:00
parent 829fad0e17
commit 871cf7e792
16520 changed files with 2967597 additions and 3 deletions

74
node_modules/@iconify/utils/lib/emoji/regex/base.d.ts generated vendored Normal file
View File

@@ -0,0 +1,74 @@
/**
* Regex in item
*/
interface BaseEmojiItemRegex {
type: 'utf16' | 'sequence' | 'set' | 'optional';
regex: string;
group: boolean;
length: number;
}
interface EmojiItemRegexWithNumbers {
numbers?: number[];
}
interface UTF16EmojiItemRegex extends BaseEmojiItemRegex, Required<EmojiItemRegexWithNumbers> {
type: 'utf16';
group: true;
}
type SequenceEmojiItemRegexItem = UTF16EmojiItemRegex | SetEmojiItemRegex | OptionalEmojiItemRegex;
interface SequenceEmojiItemRegex extends BaseEmojiItemRegex, EmojiItemRegexWithNumbers {
type: 'sequence';
items: SequenceEmojiItemRegexItem[];
}
type SetEmojiItemRegexItem = UTF16EmojiItemRegex | SequenceEmojiItemRegex | OptionalEmojiItemRegex;
interface SetEmojiItemRegex extends BaseEmojiItemRegex, EmojiItemRegexWithNumbers {
type: 'set';
sets: SetEmojiItemRegexItem[];
}
type OptionalEmojiItemRegexItem = UTF16EmojiItemRegex | SequenceEmojiItemRegex | SetEmojiItemRegex;
interface OptionalEmojiItemRegex extends BaseEmojiItemRegex {
type: 'optional';
item: OptionalEmojiItemRegexItem;
group: true;
}
type EmojiItemRegex = UTF16EmojiItemRegex | SequenceEmojiItemRegex | SetEmojiItemRegex | OptionalEmojiItemRegex;
/**
* Wrap regex in group
*/
declare function wrapRegexInGroup(regex: string): string;
/**
* Update UTF16 item, return regex
*/
declare function updateUTF16EmojiRegexItem(item: UTF16EmojiItemRegex): string;
/**
* Create UTF-16 regex
*/
declare function createUTF16EmojiRegexItem(numbers: number[]): UTF16EmojiItemRegex;
/**
* Update sequence regex. Does not update group
*/
declare function updateSequenceEmojiRegexItem(item: SequenceEmojiItemRegex): string;
/**
* Create sequence regex
*/
declare function createSequenceEmojiRegexItem(sequence: EmojiItemRegex[], numbers?: number[]): SequenceEmojiItemRegex;
/**
* Update set regex and group
*/
declare function updateSetEmojiRegexItem(item: SetEmojiItemRegex): string;
/**
* Create set regex
*/
declare function createSetEmojiRegexItem(set: EmojiItemRegex[]): SetEmojiItemRegex;
/**
* Update optional regex
*/
declare function updateOptionalEmojiRegexItem(item: OptionalEmojiItemRegex): string;
/**
* Create optional item
*/
declare function createOptionalEmojiRegexItem(item: EmojiItemRegex): OptionalEmojiItemRegex;
/**
* Clone item
*/
declare function cloneEmojiRegexItem<T extends BaseEmojiItemRegex>(item: T, shallow?: boolean): T;
export { EmojiItemRegex, OptionalEmojiItemRegex, SequenceEmojiItemRegex, SetEmojiItemRegex, SetEmojiItemRegexItem, UTF16EmojiItemRegex, cloneEmojiRegexItem, createOptionalEmojiRegexItem, createSequenceEmojiRegexItem, createSetEmojiRegexItem, createUTF16EmojiRegexItem, updateOptionalEmojiRegexItem, updateSequenceEmojiRegexItem, updateSetEmojiRegexItem, updateUTF16EmojiRegexItem, wrapRegexInGroup };

208
node_modules/@iconify/utils/lib/emoji/regex/base.js generated vendored Normal file
View File

@@ -0,0 +1,208 @@
/**
* Convert number to string
*/
function toString(number) {
if (number < 255) {
if (number > 32 && number < 127) {
const char = String.fromCharCode(number);
if (number > 47 && number < 58 || number > 64 && number < 91 || number > 94 && number < 123) return char;
return "\\" + char;
}
return "\\x" + (number < 16 ? "0" : "") + number.toString(16).toUpperCase();
}
return "\\u" + number.toString(16).toUpperCase();
}
/**
* Typescript stuff
*/
function assertNever(v) {}
/**
* Wrap regex in group
*/
function wrapRegexInGroup(regex) {
return "(?:" + regex + ")";
}
/**
* Update UTF16 item, return regex
*/
function updateUTF16EmojiRegexItem(item) {
const numbers = item.numbers;
if (numbers.length === 1) {
const num = numbers[0];
return item.regex = toString(num);
}
numbers.sort((a, b) => a - b);
const chars = [];
let range = null;
const addRange = () => {
if (range) {
const { start, last, numbers: numbers$1 } = range;
range = null;
if (last > start + 1) chars.push(toString(start) + "-" + toString(last));
else for (let i = 0; i < numbers$1.length; i++) chars.push(toString(numbers$1[i]));
}
};
for (let i = 0; i < numbers.length; i++) {
const num = numbers[i];
if (range) {
if (range.last === num) continue;
if (range.last === num - 1) {
range.numbers.push(num);
range.last = num;
continue;
}
}
addRange();
range = {
start: num,
last: num,
numbers: [num]
};
}
addRange();
if (!chars.length) throw new Error("Unexpected empty range");
return item.regex = "[" + chars.join("") + "]";
}
/**
* Create UTF-16 regex
*/
function createUTF16EmojiRegexItem(numbers) {
const result = {
type: "utf16",
regex: "",
numbers,
length: 1,
group: true
};
updateUTF16EmojiRegexItem(result);
return result;
}
/**
* Update sequence regex. Does not update group
*/
function updateSequenceEmojiRegexItem(item) {
return item.regex = item.items.map((childItem) => {
if (!childItem.group && childItem.type === "set") return wrapRegexInGroup(childItem.regex);
return childItem.regex;
}).join("");
}
/**
* Create sequence regex
*/
function createSequenceEmojiRegexItem(sequence, numbers) {
let items = [];
sequence.forEach((item) => {
if (item.type === "sequence") items = items.concat(item.items);
else items.push(item);
});
if (!items.length) throw new Error("Empty sequence");
const result = {
type: "sequence",
items,
regex: "",
length: items.reduce((length, item) => item.length + length, 0),
group: false
};
if (sequence.length === 1) {
const firstItem = sequence[0];
result.group = firstItem.group;
if (firstItem.type !== "optional") {
const numbers$1 = firstItem.numbers;
if (numbers$1) result.numbers = numbers$1;
}
}
if (numbers) result.numbers = numbers;
updateSequenceEmojiRegexItem(result);
return result;
}
/**
* Update set regex and group
*/
function updateSetEmojiRegexItem(item) {
if (item.sets.length === 1) {
const firstItem = item.sets[0];
item.group = firstItem.group;
return item.regex = firstItem.regex;
}
item.group = false;
return item.regex = item.sets.map((childItem) => childItem.regex).join("|");
}
/**
* Create set regex
*/
function createSetEmojiRegexItem(set) {
let sets = [];
let numbers = [];
set.forEach((item) => {
if (item.type === "set") sets = sets.concat(item.sets);
else sets.push(item);
if (numbers) if (item.type === "optional" || !item.numbers) numbers = null;
else numbers = [...numbers, ...item.numbers];
});
sets.sort((a, b) => {
if (a.length === b.length) return a.regex.localeCompare(b.regex);
return b.length - a.length;
});
const result = {
type: "set",
sets,
regex: "",
length: sets.reduce((length, item) => length ? Math.min(length, item.length) : item.length, 0),
group: false
};
if (numbers) result.numbers = numbers;
if (set.length === 1) {
const firstItem = set[0];
result.group = firstItem.group;
}
updateSetEmojiRegexItem(result);
return result;
}
/**
* Update optional regex
*/
function updateOptionalEmojiRegexItem(item) {
const childItem = item.item;
const regex = (childItem.group ? childItem.regex : wrapRegexInGroup(childItem.regex)) + "?";
return item.regex = regex;
}
/**
* Create optional item
*/
function createOptionalEmojiRegexItem(item) {
if (item.type === "optional") return item;
const result = {
type: "optional",
item,
regex: "",
length: item.length,
group: true
};
updateOptionalEmojiRegexItem(result);
return result;
}
/**
* Clone item
*/
function cloneEmojiRegexItem(item, shallow = false) {
const result = { ...item };
if (result.type !== "optional" && result.numbers) result.numbers = [...result.numbers];
switch (result.type) {
case "utf16": break;
case "sequence":
if (shallow) result.items = [...result.items];
else result.items = result.items.map((item$1) => cloneEmojiRegexItem(item$1, false));
break;
case "set":
if (shallow) result.sets = [...result.sets];
else result.sets = result.sets.map((item$1) => cloneEmojiRegexItem(item$1, false));
break;
case "optional":
if (!shallow) result.item = cloneEmojiRegexItem(result.item, false);
break;
default: assertNever(result);
}
return result;
}
export { cloneEmojiRegexItem, createOptionalEmojiRegexItem, createSequenceEmojiRegexItem, createSetEmojiRegexItem, createUTF16EmojiRegexItem, updateOptionalEmojiRegexItem, updateSequenceEmojiRegexItem, updateSetEmojiRegexItem, updateUTF16EmojiRegexItem, wrapRegexInGroup };

View File

@@ -0,0 +1,20 @@
/**
* Create optimised regex
*/
declare function createOptimisedRegexForEmojiSequences(sequences: number[][]): string;
/**
* Create optimised regex for emojis
*
* First parameter is array of emojis, entry can be either list of
* code points or emoji sequence as a string
*
* Examples of acceptable strings (case insensitive):
* '1F636 200D 1F32B FE0F' - space separated UTF32 sequence
* '1f636-200d-1f32b-fe0f' - dash separated UTF32 sequence
* 'd83d-de36-200d-d83c-df2b-fe0f' - dash separated UTF16 sequence
* '\\uD83D\\uDE36\\u200D\\uD83C\\uDF2B\\uFE0F' - UTF16 sequence escaped with '\\u'
*
* All examples above refer to the same emoji and will generate the same regex result
*/
declare function createOptimisedRegex(emojis: (string | number[])[]): string;
export { createOptimisedRegex, createOptimisedRegexForEmojiSequences };

37
node_modules/@iconify/utils/lib/emoji/regex/create.js generated vendored Normal file
View File

@@ -0,0 +1,37 @@
import { convertEmojiSequenceToUTF32 } from "../convert.js";
import { getSequenceFromEmojiStringOrKeyword } from "../cleanup.js";
import { getQualifiedEmojiVariations } from "../test/variations.js";
import { createEmojisTree, parseEmojiTree } from "./tree.js";
/**
* Create optimised regex
*/
function createOptimisedRegexForEmojiSequences(sequences) {
sequences = sequences.map((item) => convertEmojiSequenceToUTF32(item));
const tree = createEmojisTree(sequences);
const regex = parseEmojiTree(tree);
return regex.regex;
}
/**
* Create optimised regex for emojis
*
* First parameter is array of emojis, entry can be either list of
* code points or emoji sequence as a string
*
* Examples of acceptable strings (case insensitive):
* '1F636 200D 1F32B FE0F' - space separated UTF32 sequence
* '1f636-200d-1f32b-fe0f' - dash separated UTF32 sequence
* 'd83d-de36-200d-d83c-df2b-fe0f' - dash separated UTF16 sequence
* '\\uD83D\\uDE36\\u200D\\uD83C\\uDF2B\\uFE0F' - UTF16 sequence escaped with '\\u'
*
* All examples above refer to the same emoji and will generate the same regex result
*/
function createOptimisedRegex(emojis) {
let sequences = emojis.map((item) => typeof item === "string" ? getSequenceFromEmojiStringOrKeyword(item) : item);
sequences = getQualifiedEmojiVariations(sequences.map((sequence) => {
return { sequence };
})).map((item) => item.sequence);
return createOptimisedRegexForEmojiSequences(sequences);
}
export { createOptimisedRegex, createOptimisedRegexForEmojiSequences };

View File

@@ -0,0 +1,14 @@
import { EmojiItemRegex, OptionalEmojiItemRegex, SequenceEmojiItemRegex, SetEmojiItemRegex, UTF16EmojiItemRegex } from "./base.js";
/**
* Create regex item for set of numbers
*/
declare function createEmojiRegexItemForNumbers(numbers: number[]): UTF16EmojiItemRegex | SequenceEmojiItemRegex | SetEmojiItemRegex;
/**
* Create sequence of numbers
*/
declare function createRegexForNumbersSequence(numbers: number[], optionalVariations?: boolean): SequenceEmojiItemRegex | UTF16EmojiItemRegex | OptionalEmojiItemRegex;
/**
* Attempt to optimise numbers in a set
*/
declare function optimiseNumbersSet(set: SetEmojiItemRegex): EmojiItemRegex;
export { createEmojiRegexItemForNumbers, createRegexForNumbersSequence, optimiseNumbersSet };

134
node_modules/@iconify/utils/lib/emoji/regex/numbers.js generated vendored Normal file
View File

@@ -0,0 +1,134 @@
import { vs16Emoji } from "../data.js";
import { splitUTF32Number } from "../convert.js";
import { createOptionalEmojiRegexItem, createSequenceEmojiRegexItem, createSetEmojiRegexItem, createUTF16EmojiRegexItem } from "./base.js";
/**
* Create regex item for set of numbers
*/
function createEmojiRegexItemForNumbers(numbers) {
const utf32 = [];
const utf16 = [];
numbers.sort((a, b) => a - b);
let lastNumber;
for (let i = 0; i < numbers.length; i++) {
const number = numbers[i];
if (number === lastNumber) continue;
lastNumber = number;
const split = splitUTF32Number(number);
if (!split) {
utf16.push(number);
continue;
}
const [first, second] = split;
const item = utf32.find((item$1) => item$1.first === first);
if (item) {
item.second.push(second);
item.numbers.push(number);
} else utf32.push({
first,
second: [second],
numbers: [number]
});
}
const results = [];
if (utf16.length) results.push(createUTF16EmojiRegexItem(utf16));
if (utf32.length) {
const utf32Set = [];
for (let i = 0; i < utf32.length; i++) {
const item = utf32[i];
const secondRegex = createUTF16EmojiRegexItem(item.second);
const listItem = utf32Set.find((item$1) => item$1.second.regex === secondRegex.regex);
if (listItem) {
listItem.first.push(item.first);
listItem.numbers = [...listItem.numbers, ...item.numbers];
} else utf32Set.push({
second: secondRegex,
first: [item.first],
numbers: [...item.numbers]
});
}
for (let i = 0; i < utf32Set.length; i++) {
const item = utf32Set[i];
const firstRegex = createUTF16EmojiRegexItem(item.first);
const secondRegex = item.second;
results.push(createSequenceEmojiRegexItem([firstRegex, secondRegex], item.numbers));
}
}
return results.length === 1 ? results[0] : createSetEmojiRegexItem(results);
}
/**
* Create sequence of numbers
*/
function createRegexForNumbersSequence(numbers, optionalVariations = true) {
const items = [];
for (let i = 0; i < numbers.length; i++) {
const num = numbers[i];
const split = splitUTF32Number(num);
if (!split) {
const item = createUTF16EmojiRegexItem([num]);
if (optionalVariations && num === vs16Emoji) items.push(createOptionalEmojiRegexItem(item));
else items.push(item);
} else {
items.push(createUTF16EmojiRegexItem([split[0]]));
items.push(createUTF16EmojiRegexItem([split[1]]));
}
}
if (items.length === 1) return items[0];
const result = createSequenceEmojiRegexItem(items);
if (numbers.length === 1 && items[0].type === "utf16") result.numbers = [...numbers];
return result;
}
/**
* Attempt to optimise numbers in a set
*/
function optimiseNumbersSet(set) {
const mandatoryMatches = {
numbers: [],
items: []
};
const optionalMatches = {
numbers: [],
items: []
};
const filteredItems = set.sets.filter((item) => {
if (item.type === "optional") {
const parentItem = item.item;
if (parentItem.numbers) {
optionalMatches.items.push(item);
optionalMatches.numbers = optionalMatches.numbers.concat(parentItem.numbers);
return false;
}
return true;
}
if (item.numbers) {
mandatoryMatches.items.push(item);
mandatoryMatches.numbers = mandatoryMatches.numbers.concat(item.numbers);
return false;
}
return true;
});
if (mandatoryMatches.items.length + optionalMatches.items.length < 2) return set;
const optionalNumbers = new Set(optionalMatches.numbers);
let foundMatches = false;
mandatoryMatches.numbers = mandatoryMatches.numbers.filter((number) => {
if (optionalNumbers.has(number)) {
foundMatches = true;
return false;
}
return true;
});
if (mandatoryMatches.items.length) {
if (!foundMatches && mandatoryMatches.items.length === 1) filteredItems.push(mandatoryMatches.items[0]);
else if (mandatoryMatches.numbers.length) filteredItems.push(createEmojiRegexItemForNumbers(mandatoryMatches.numbers));
}
switch (optionalMatches.items.length) {
case 0: break;
case 1:
filteredItems.push(optionalMatches.items[0]);
break;
default: filteredItems.push(createOptionalEmojiRegexItem(createEmojiRegexItemForNumbers(optionalMatches.numbers)));
}
return filteredItems.length === 1 ? filteredItems[0] : createSetEmojiRegexItem(filteredItems);
}
export { createEmojiRegexItemForNumbers, createRegexForNumbersSequence, optimiseNumbersSet };

View File

@@ -0,0 +1,46 @@
import { EmojiItemRegex, SetEmojiItemRegex } from "./base.js";
type SlicePosition = 'start' | 'end';
type SliceValue = number | 'full';
/**
* Slice of sequence
*/
interface SimilarRegexItemSlice {
index: number;
slice: SliceValue;
}
/**
* Similar sequence
*/
interface SimilarRegexItemSequence {
type: SlicePosition;
slices: SimilarRegexItemSlice[];
}
/**
* Result if findSimilarRegexItemSequences()
*/
interface SimilarRegexItemSequenceResult {
score: number;
sequences: SimilarRegexItemSequence[];
}
/**
* Find similar item sequences
*
* Returns sequence(s) with highest score. Only one of results should be
* applied to items. If there are multiple sequences, clone items list,
* attempt to apply each sequence, run further optimisations on each fork
* and see which one returns better result.
*
* Returns undefined if no common sequences found
*/
declare function findSimilarRegexItemSequences(items: EmojiItemRegex[]): SimilarRegexItemSequenceResult | undefined;
/**
* Merge similar sequences
*
* Accepts callback to run optimisation on created subset
*/
declare function mergeSimilarRegexItemSequences(items: EmojiItemRegex[], merge: SimilarRegexItemSequence, optimise?: (set: SetEmojiItemRegex) => EmojiItemRegex): EmojiItemRegex[];
/**
* Merge similar items
*/
declare function mergeSimilarItemsInSet(set: SetEmojiItemRegex): EmojiItemRegex;
export { findSimilarRegexItemSequences, mergeSimilarItemsInSet, mergeSimilarRegexItemSequences };

169
node_modules/@iconify/utils/lib/emoji/regex/similar.js generated vendored Normal file
View File

@@ -0,0 +1,169 @@
import { cloneEmojiRegexItem, createOptionalEmojiRegexItem, createSequenceEmojiRegexItem, createSetEmojiRegexItem } from "./base.js";
import { optimiseNumbersSet } from "./numbers.js";
/**
* Typescript stuff
*/
function assertNever(v) {}
/**
* Find similar item sequences
*
* Returns sequence(s) with highest score. Only one of results should be
* applied to items. If there are multiple sequences, clone items list,
* attempt to apply each sequence, run further optimisations on each fork
* and see which one returns better result.
*
* Returns undefined if no common sequences found
*/
function findSimilarRegexItemSequences(items) {
const startRegex = Object.create(null);
const endRegex = Object.create(null);
const addMapItem = (target, index, regex, slice) => {
if (!target[regex]) {
target[regex] = {
score: 0,
slices: [{
index,
slice
}]
};
return;
}
const item = target[regex];
item.score += regex.length;
item.slices.push({
index,
slice
});
};
for (let index = 0; index < items.length; index++) {
const baseItem = items[index];
switch (baseItem.type) {
case "optional":
case "utf16": {
addMapItem(startRegex, index, baseItem.regex, "full");
addMapItem(endRegex, index, baseItem.regex, "full");
break;
}
case "sequence": {
addMapItem(startRegex, index, baseItem.regex, "full");
addMapItem(endRegex, index, baseItem.regex, "full");
const sequence = baseItem.items;
for (let i = 1; i < sequence.length; i++) {
const startSequence = createSequenceEmojiRegexItem(sequence.slice(0, i));
addMapItem(startRegex, index, startSequence.regex, i);
const endSequence = createSequenceEmojiRegexItem(sequence.slice(i));
addMapItem(endRegex, index, endSequence.regex, i);
}
break;
}
case "set": throw new Error("Unexpected set within a set");
default: assertNever(baseItem);
}
}
let result;
const checkResults = (target, type) => {
for (const regex in target) {
const item = target[regex];
if (!item.score) continue;
if (!result || result.score < item.score) {
result = {
score: item.score,
sequences: [{
type,
slices: item.slices
}]
};
continue;
}
if (result.score === item.score) result.sequences.push({
type,
slices: item.slices
});
}
};
checkResults(startRegex, "start");
checkResults(endRegex, "end");
return result;
}
/**
* Merge similar sequences
*
* Accepts callback to run optimisation on created subset
*/
function mergeSimilarRegexItemSequences(items, merge, optimise) {
const { type, slices } = merge;
const indexes = /* @__PURE__ */ new Set();
let hasFullSequence = false;
let longestMatch = 0;
let longestMatchIndex = -1;
const differentSequences = [];
for (let i = 0; i < slices.length; i++) {
const { index, slice } = slices[i];
const item = items[index];
let length;
if (slice === "full") {
hasFullSequence = true;
if (item.type === "sequence") length = item.items.length;
else length = 1;
} else {
if (item.type !== "sequence") throw new Error(`Unexpected partial match for type "${item.type}"`);
length = type === "start" ? slice : item.items.length - slice;
differentSequences.push(type === "start" ? item.items.slice(slice) : item.items.slice(0, slice));
}
if (length > longestMatch) {
longestMatchIndex = index;
longestMatch = length;
}
indexes.add(index);
}
if (longestMatch < 1 || longestMatchIndex < 0) throw new Error("Cannot find common sequence");
const commonItem = items[longestMatchIndex];
let sequence;
if (commonItem.type !== "sequence") {
if (longestMatch !== 1) throw new Error("Something went wrong. Cannot have long match in non-sequence");
sequence = [commonItem];
} else sequence = type === "start" ? commonItem.items.slice(0, longestMatch) : commonItem.items.slice(commonItem.items.length - longestMatch);
const setItems = [];
for (let i = 0; i < differentSequences.length; i++) {
const list = differentSequences[i];
if (list.length === 1) setItems.push(list[0]);
else setItems.push(createSequenceEmojiRegexItem(list));
}
const set = createSetEmojiRegexItem(setItems);
let mergedChunk = set.sets.length === 1 ? set.sets[0] : optimise ? optimise(set) : set;
if (hasFullSequence) mergedChunk = createOptionalEmojiRegexItem(mergedChunk);
sequence[type === "start" ? "push" : "unshift"](mergedChunk);
const results = [createSequenceEmojiRegexItem(sequence), ...items.filter((item, index) => !indexes.has(index))];
return results;
}
/**
* Merge similar items
*/
function mergeSimilarItemsInSet(set) {
const updatedSet = optimiseNumbersSet(set);
if (updatedSet.type !== "set") return updatedSet;
set = updatedSet;
let merges;
while (merges = findSimilarRegexItemSequences(set.sets)) {
const sequences = merges.sequences;
if (sequences.length === 1) {
const merged = mergeSimilarRegexItemSequences(set.sets.map((item) => cloneEmojiRegexItem(item, true)), sequences[0], mergeSimilarItemsInSet);
if (merged.length === 1) return merged[0];
set = createSetEmojiRegexItem(merged);
continue;
}
let newItem;
for (let i = 0; i < sequences.length; i++) {
const merged = mergeSimilarRegexItemSequences(set.sets.map((item) => cloneEmojiRegexItem(item, true)), sequences[i], mergeSimilarItemsInSet);
const mergedItem = merged.length === 1 ? merged[0] : createSetEmojiRegexItem(merged);
if (!newItem || mergedItem.regex.length < newItem.regex.length) newItem = mergedItem;
}
if (!newItem) throw new Error("Empty sequences list");
if (newItem.type !== "set") return newItem;
set = newItem;
}
return set;
}
export { findSimilarRegexItemSequences, mergeSimilarItemsInSet, mergeSimilarRegexItemSequences };

18
node_modules/@iconify/utils/lib/emoji/regex/tree.d.ts generated vendored Normal file
View File

@@ -0,0 +1,18 @@
import { EmojiItemRegex } from "./base.js";
/**
* Tree item
*/
interface TreeItem {
regex: EmojiItemRegex;
end?: true;
children?: TreeItem[];
}
/**
* Create tree
*/
declare function createEmojisTree(sequences: number[][]): TreeItem[];
/**
* Parse tree
*/
declare function parseEmojiTree(items: TreeItem[]): EmojiItemRegex;
export { createEmojisTree, parseEmojiTree };

85
node_modules/@iconify/utils/lib/emoji/regex/tree.js generated vendored Normal file
View File

@@ -0,0 +1,85 @@
import { joinerEmoji } from "../data.js";
import { convertEmojiSequenceToUTF32 } from "../convert.js";
import { splitEmojiSequences } from "../cleanup.js";
import { createOptionalEmojiRegexItem, createSequenceEmojiRegexItem, createSetEmojiRegexItem, createUTF16EmojiRegexItem } from "./base.js";
import { createRegexForNumbersSequence } from "./numbers.js";
import { mergeSimilarItemsInSet } from "./similar.js";
/**
* Create tree
*/
function createEmojisTree(sequences) {
const root = [];
for (let i = 0; i < sequences.length; i++) {
const split = splitEmojiSequences(convertEmojiSequenceToUTF32(sequences[i]));
let parent = root;
for (let j = 0; j < split.length; j++) {
const regex = createRegexForNumbersSequence(split[j]);
let item;
const match = parent.find((item$1) => item$1.regex.regex === regex.regex);
if (!match) {
item = { regex };
parent.push(item);
} else item = match;
if (j === split.length - 1) {
item.end = true;
break;
}
parent = item.children || (item.children = []);
}
}
return root;
}
/**
* Parse tree
*/
function parseEmojiTree(items) {
function mergeParsedChildren(items$1) {
const parsedItems = [];
const mapWithoutEnd = Object.create(null);
const mapWithEnd = Object.create(null);
for (let i = 0; i < items$1.length; i++) {
const item = items$1[i];
const children = item.children;
if (children) {
const fullItem = item;
const target = item.end ? mapWithEnd : mapWithoutEnd;
const regex = children.regex;
if (!target[regex]) target[regex] = [fullItem];
else target[regex].push(fullItem);
} else parsedItems.push(item.regex);
}
[mapWithEnd, mapWithoutEnd].forEach((source) => {
for (const regex in source) {
const items$2 = source[regex];
const firstItem = items$2[0];
let childSequence = [createUTF16EmojiRegexItem([joinerEmoji]), firstItem.children];
if (firstItem.end) childSequence = [createOptionalEmojiRegexItem(createSequenceEmojiRegexItem(childSequence))];
let mergedRegex;
if (items$2.length === 1) mergedRegex = firstItem.regex;
else mergedRegex = mergeSimilarItemsInSet(createSetEmojiRegexItem(items$2.map((item) => item.regex)));
const sequence = createSequenceEmojiRegexItem([mergedRegex, ...childSequence]);
parsedItems.push(sequence);
}
});
if (parsedItems.length === 1) return parsedItems[0];
const set = createSetEmojiRegexItem(parsedItems);
const result = mergeSimilarItemsInSet(set);
return result;
}
function parseItemChildren(item) {
const result = {
regex: item.regex,
end: !!item.end
};
const children = item.children;
if (!children) return result;
const parsedChildren = children.map(parseItemChildren);
result.children = mergeParsedChildren(parsedChildren);
return result;
}
const parsed = items.map(parseItemChildren);
return mergeParsedChildren(parsed);
}
export { createEmojisTree, parseEmojiTree };