@dicelette/core 1.25.1 → 1.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -0
- package/dist/index.d.mts +23 -2
- package/dist/index.d.ts +23 -2
- package/dist/index.js +119 -73
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +115 -73
- package/dist/index.mjs.map +1 -1
- package/package.json +59 -59
package/README.md
CHANGED
|
@@ -152,6 +152,25 @@ Note: when a parameter `engine` is shown it usually defaults to the `NumberGener
|
|
|
152
152
|
#### Function: getEngine(engine: "nativeMath" | "browserCrypto" | "nodeCrypto"): Engine
|
|
153
153
|
- Returns the engine instance (from `NumberGenerator.engines`) matching the provided name.
|
|
154
154
|
|
|
155
|
+
### Similarity (`src/similarity.ts`)
|
|
156
|
+
#### Function: calculateSimilarity(str1: string, str2: string): number
|
|
157
|
+
- Calculate and return a similarity score between two strings using the levenshtein distance (value between 0 and 1).
|
|
158
|
+
|
|
159
|
+
#### Function: levenshteinDistance(str1: string, str2: string): number
|
|
160
|
+
- Calculate and return the Levenshtein distance between two strings.
|
|
161
|
+
- Used internally by `calculateSimilarity`.
|
|
162
|
+
- Returns an integer distance value.
|
|
163
|
+
|
|
164
|
+
#### Function : findBestStatMatch<T>(searchTerm: string, normalizedStat: Map<string, T>, similarityThreshold: number = 0.5, partialSearch: boolean = true): T | undefined`
|
|
165
|
+
- Find and return the best matching statistic from `normalizedStat` based on `searchTerm`.
|
|
166
|
+
- Normalized stat is a map of lowercased stat names to their original entries
|
|
167
|
+
- `partialSearch` allow to check if `normalizedStat` have a key that starts, ends or contains the `searchTerm` and return it directly.
|
|
168
|
+
- `similarityThreshold` is the minimum similarity score to consider a match. By default, it's set to 0.5.
|
|
169
|
+
|
|
170
|
+
#### Function: `findBestRecord(snippets: Record<string, string>, searchTerm: string, similarityThreshold: number = 0.5): string | undefined`
|
|
171
|
+
- Find and return the best matching string from `snippets` based on `searchTerm`.
|
|
172
|
+
- Just an alias for `findBestStatMatch` specialized for `Record<string, string>` and without partial search.
|
|
173
|
+
|
|
155
174
|
### Dice functions (`src/dice.ts`)
|
|
156
175
|
|
|
157
176
|
#### Function: roll(dice: string, engine?: Engine | null, pity?: boolean): Resultat | undefined
|
package/dist/index.d.mts
CHANGED
|
@@ -307,6 +307,26 @@ declare function replaceInFormula(element: string, diceResult: Resultat, compare
|
|
|
307
307
|
compare: Compare | undefined;
|
|
308
308
|
}, res: boolean, engine?: Engine | null, pity?: boolean): string;
|
|
309
309
|
|
|
310
|
+
/**
|
|
311
|
+
* Utility functions for string similarity and distance calculations.
|
|
312
|
+
*/
|
|
313
|
+
/**
|
|
314
|
+
* Calculates the similarity between two strings as a value between 0 and 1.
|
|
315
|
+
*/
|
|
316
|
+
declare function calculateSimilarity(str1: string, str2: string): number;
|
|
317
|
+
/**
|
|
318
|
+
* Calculates the Levenshtein distance between two strings.
|
|
319
|
+
*/
|
|
320
|
+
declare function levenshteinDistance(str1: string, str2: string): number;
|
|
321
|
+
declare function findBestStatMatch<T>(searchTerm: string, normalizedStats: Map<string, T>, similarityThreshold?: number, partialSearch?: boolean): T | undefined;
|
|
322
|
+
/**
|
|
323
|
+
* Find the snippet name with the highest similarity to `macroName`.
|
|
324
|
+
* Single-pass O(n) algorithm: keeps the best (name, similarity) seen so far.
|
|
325
|
+
* Returns `null` if no snippets or if the best similarity is < `minSimilarity`.
|
|
326
|
+
* Tie-breaker: first encountered best similarity (deterministic).
|
|
327
|
+
*/
|
|
328
|
+
declare function findBestRecord(record: Record<string, string>, searchTerm: string, similarityThreshold?: number): string | null;
|
|
329
|
+
|
|
310
330
|
/**
|
|
311
331
|
* Escape regex string
|
|
312
332
|
* @param string {string}
|
|
@@ -323,9 +343,10 @@ declare function standardizeDice(dice: string): string;
|
|
|
323
343
|
* and after evaluate any formula using `replaceFormulaInDice`
|
|
324
344
|
* @param {string} originalDice
|
|
325
345
|
* @param {Record<string,number>|undefined} stats
|
|
346
|
+
* @param {number} minThreshold Minimum similarity threshold to consider a stat name match
|
|
326
347
|
* @param {string|undefined} dollarValue
|
|
327
348
|
*/
|
|
328
|
-
declare function generateStatsDice(originalDice: string, stats?: Record<string, number>, dollarValue?: string): string;
|
|
349
|
+
declare function generateStatsDice(originalDice: string, stats?: Record<string, number>, minThreshold?: number, dollarValue?: string): string;
|
|
329
350
|
/**
|
|
330
351
|
* Replace the {{}} in the dice string and evaluate the interior if any
|
|
331
352
|
* @param dice {string}
|
|
@@ -430,4 +451,4 @@ declare function testStatCombinaison(template: StatisticalTemplate, engine?: Eng
|
|
|
430
451
|
*/
|
|
431
452
|
declare function generateRandomStat(total?: number | undefined, max?: number, min?: number, engine?: Engine | null): number;
|
|
432
453
|
|
|
433
|
-
export { COMMENT_REGEX, type Compare, type ComparedValue, type Critical, type CustomCritical, type CustomCriticalMap, DETECT_CRITICAL, DiceTypeError, EmptyObjectError, FormulaError, MaxGreater, type Modifier, NoStatisticsError, OPTIONAL_COMMENT, type Resultat, SIGN_REGEX, SIGN_REGEX_SPACE, SYMBOL_DICE, type Sign, SortOrder, type Statistic, type StatisticalSchema, type StatisticalTemplate, TooManyDice, TooManyStats, createCriticalCustom, diceRandomParse, diceTypeRandomParse, escapeRegex, evalCombinaison, evalOneCombinaison, evalStatsDice, generateRandomStat, generateStatsDice, getEngine, getEngineId, isNumber, randomInt, replaceExpByRandom, replaceFormulaInDice, replaceInFormula, roll, standardizeDice, templateSchema, testDiceRegistered, testStatCombinaison, verifyTemplateValue };
|
|
454
|
+
export { COMMENT_REGEX, type Compare, type ComparedValue, type Critical, type CustomCritical, type CustomCriticalMap, DETECT_CRITICAL, DiceTypeError, EmptyObjectError, FormulaError, MaxGreater, type Modifier, NoStatisticsError, OPTIONAL_COMMENT, type Resultat, SIGN_REGEX, SIGN_REGEX_SPACE, SYMBOL_DICE, type Sign, SortOrder, type Statistic, type StatisticalSchema, type StatisticalTemplate, TooManyDice, TooManyStats, calculateSimilarity, createCriticalCustom, diceRandomParse, diceTypeRandomParse, escapeRegex, evalCombinaison, evalOneCombinaison, evalStatsDice, findBestRecord, findBestStatMatch, generateRandomStat, generateStatsDice, getEngine, getEngineId, isNumber, levenshteinDistance, randomInt, replaceExpByRandom, replaceFormulaInDice, replaceInFormula, roll, standardizeDice, templateSchema, testDiceRegistered, testStatCombinaison, verifyTemplateValue };
|
package/dist/index.d.ts
CHANGED
|
@@ -307,6 +307,26 @@ declare function replaceInFormula(element: string, diceResult: Resultat, compare
|
|
|
307
307
|
compare: Compare | undefined;
|
|
308
308
|
}, res: boolean, engine?: Engine | null, pity?: boolean): string;
|
|
309
309
|
|
|
310
|
+
/**
|
|
311
|
+
* Utility functions for string similarity and distance calculations.
|
|
312
|
+
*/
|
|
313
|
+
/**
|
|
314
|
+
* Calculates the similarity between two strings as a value between 0 and 1.
|
|
315
|
+
*/
|
|
316
|
+
declare function calculateSimilarity(str1: string, str2: string): number;
|
|
317
|
+
/**
|
|
318
|
+
* Calculates the Levenshtein distance between two strings.
|
|
319
|
+
*/
|
|
320
|
+
declare function levenshteinDistance(str1: string, str2: string): number;
|
|
321
|
+
declare function findBestStatMatch<T>(searchTerm: string, normalizedStats: Map<string, T>, similarityThreshold?: number, partialSearch?: boolean): T | undefined;
|
|
322
|
+
/**
|
|
323
|
+
* Find the snippet name with the highest similarity to `macroName`.
|
|
324
|
+
* Single-pass O(n) algorithm: keeps the best (name, similarity) seen so far.
|
|
325
|
+
* Returns `null` if no snippets or if the best similarity is < `minSimilarity`.
|
|
326
|
+
* Tie-breaker: first encountered best similarity (deterministic).
|
|
327
|
+
*/
|
|
328
|
+
declare function findBestRecord(record: Record<string, string>, searchTerm: string, similarityThreshold?: number): string | null;
|
|
329
|
+
|
|
310
330
|
/**
|
|
311
331
|
* Escape regex string
|
|
312
332
|
* @param string {string}
|
|
@@ -323,9 +343,10 @@ declare function standardizeDice(dice: string): string;
|
|
|
323
343
|
* and after evaluate any formula using `replaceFormulaInDice`
|
|
324
344
|
* @param {string} originalDice
|
|
325
345
|
* @param {Record<string,number>|undefined} stats
|
|
346
|
+
* @param {number} minThreshold Minimum similarity threshold to consider a stat name match
|
|
326
347
|
* @param {string|undefined} dollarValue
|
|
327
348
|
*/
|
|
328
|
-
declare function generateStatsDice(originalDice: string, stats?: Record<string, number>, dollarValue?: string): string;
|
|
349
|
+
declare function generateStatsDice(originalDice: string, stats?: Record<string, number>, minThreshold?: number, dollarValue?: string): string;
|
|
329
350
|
/**
|
|
330
351
|
* Replace the {{}} in the dice string and evaluate the interior if any
|
|
331
352
|
* @param dice {string}
|
|
@@ -430,4 +451,4 @@ declare function testStatCombinaison(template: StatisticalTemplate, engine?: Eng
|
|
|
430
451
|
*/
|
|
431
452
|
declare function generateRandomStat(total?: number | undefined, max?: number, min?: number, engine?: Engine | null): number;
|
|
432
453
|
|
|
433
|
-
export { COMMENT_REGEX, type Compare, type ComparedValue, type Critical, type CustomCritical, type CustomCriticalMap, DETECT_CRITICAL, DiceTypeError, EmptyObjectError, FormulaError, MaxGreater, type Modifier, NoStatisticsError, OPTIONAL_COMMENT, type Resultat, SIGN_REGEX, SIGN_REGEX_SPACE, SYMBOL_DICE, type Sign, SortOrder, type Statistic, type StatisticalSchema, type StatisticalTemplate, TooManyDice, TooManyStats, createCriticalCustom, diceRandomParse, diceTypeRandomParse, escapeRegex, evalCombinaison, evalOneCombinaison, evalStatsDice, generateRandomStat, generateStatsDice, getEngine, getEngineId, isNumber, randomInt, replaceExpByRandom, replaceFormulaInDice, replaceInFormula, roll, standardizeDice, templateSchema, testDiceRegistered, testStatCombinaison, verifyTemplateValue };
|
|
454
|
+
export { COMMENT_REGEX, type Compare, type ComparedValue, type Critical, type CustomCritical, type CustomCriticalMap, DETECT_CRITICAL, DiceTypeError, EmptyObjectError, FormulaError, MaxGreater, type Modifier, NoStatisticsError, OPTIONAL_COMMENT, type Resultat, SIGN_REGEX, SIGN_REGEX_SPACE, SYMBOL_DICE, type Sign, SortOrder, type Statistic, type StatisticalSchema, type StatisticalTemplate, TooManyDice, TooManyStats, calculateSimilarity, createCriticalCustom, diceRandomParse, diceTypeRandomParse, escapeRegex, evalCombinaison, evalOneCombinaison, evalStatsDice, findBestRecord, findBestStatMatch, generateRandomStat, generateStatsDice, getEngine, getEngineId, isNumber, levenshteinDistance, randomInt, replaceExpByRandom, replaceFormulaInDice, replaceInFormula, roll, standardizeDice, templateSchema, testDiceRegistered, testStatCombinaison, verifyTemplateValue };
|
package/dist/index.js
CHANGED
|
@@ -34,6 +34,7 @@ __export(index_exports, {
|
|
|
34
34
|
SortOrder: () => SortOrder,
|
|
35
35
|
TooManyDice: () => TooManyDice,
|
|
36
36
|
TooManyStats: () => TooManyStats,
|
|
37
|
+
calculateSimilarity: () => calculateSimilarity,
|
|
37
38
|
createCriticalCustom: () => createCriticalCustom,
|
|
38
39
|
diceRandomParse: () => diceRandomParse,
|
|
39
40
|
diceTypeRandomParse: () => diceTypeRandomParse,
|
|
@@ -41,11 +42,14 @@ __export(index_exports, {
|
|
|
41
42
|
evalCombinaison: () => evalCombinaison,
|
|
42
43
|
evalOneCombinaison: () => evalOneCombinaison,
|
|
43
44
|
evalStatsDice: () => evalStatsDice,
|
|
45
|
+
findBestRecord: () => findBestRecord,
|
|
46
|
+
findBestStatMatch: () => findBestStatMatch,
|
|
44
47
|
generateRandomStat: () => generateRandomStat,
|
|
45
48
|
generateStatsDice: () => generateStatsDice,
|
|
46
49
|
getEngine: () => getEngine,
|
|
47
50
|
getEngineId: () => getEngineId,
|
|
48
51
|
isNumber: () => isNumber,
|
|
52
|
+
levenshteinDistance: () => levenshteinDistance,
|
|
49
53
|
randomInt: () => randomInt,
|
|
50
54
|
replaceExpByRandom: () => replaceExpByRandom,
|
|
51
55
|
replaceFormulaInDice: () => replaceFormulaInDice,
|
|
@@ -154,11 +158,11 @@ var NoStatisticsError = class extends Error {
|
|
|
154
158
|
};
|
|
155
159
|
|
|
156
160
|
// src/interfaces/index.ts
|
|
157
|
-
var SortOrder = /* @__PURE__ */ ((
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
return
|
|
161
|
+
var SortOrder = /* @__PURE__ */ ((SortOrder2) => {
|
|
162
|
+
SortOrder2["Ascending"] = "sa";
|
|
163
|
+
SortOrder2["Descending"] = "sd";
|
|
164
|
+
SortOrder2["None"] = "none";
|
|
165
|
+
return SortOrder2;
|
|
162
166
|
})(SortOrder || {});
|
|
163
167
|
|
|
164
168
|
// src/interfaces/constant.ts
|
|
@@ -242,6 +246,79 @@ var import_mathjs = require("mathjs");
|
|
|
242
246
|
var import_uniformize = require("uniformize");
|
|
243
247
|
var import_rpg_dice_roller2 = require("@dice-roller/rpg-dice-roller");
|
|
244
248
|
var import_random_js = require("random-js");
|
|
249
|
+
|
|
250
|
+
// src/similarity.ts
|
|
251
|
+
var MIN_THRESHOLD_MATCH = 0.5;
|
|
252
|
+
function calculateSimilarity(str1, str2) {
|
|
253
|
+
const longer = str1.length > str2.length ? str1 : str2;
|
|
254
|
+
const shorter = str1.length > str2.length ? str2 : str1;
|
|
255
|
+
if (longer.length === 0) return 1;
|
|
256
|
+
const distance = levenshteinDistance(longer, shorter);
|
|
257
|
+
return (longer.length - distance) / longer.length;
|
|
258
|
+
}
|
|
259
|
+
function levenshteinDistance(str1, str2) {
|
|
260
|
+
const matrix = Array(str2.length + 1).fill(null).map(() => Array(str1.length + 1).fill(null));
|
|
261
|
+
for (let i = 0; i <= str1.length; i++) matrix[0][i] = i;
|
|
262
|
+
for (let j = 0; j <= str2.length; j++) matrix[j][0] = j;
|
|
263
|
+
for (let j = 1; j <= str2.length; j++) {
|
|
264
|
+
for (let i = 1; i <= str1.length; i++) {
|
|
265
|
+
const cost = str1[i - 1] === str2[j - 1] ? 0 : 1;
|
|
266
|
+
matrix[j][i] = Math.min(
|
|
267
|
+
matrix[j][i - 1] + 1,
|
|
268
|
+
// insertion
|
|
269
|
+
matrix[j - 1][i] + 1,
|
|
270
|
+
// deletion
|
|
271
|
+
matrix[j - 1][i - 1] + cost
|
|
272
|
+
// substitution
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return matrix[str2.length][str1.length];
|
|
277
|
+
}
|
|
278
|
+
function findBestStatMatch(searchTerm, normalizedStats, similarityThreshold = MIN_THRESHOLD_MATCH, partialSearch = true) {
|
|
279
|
+
const exact = normalizedStats.get(searchTerm);
|
|
280
|
+
if (exact) return exact;
|
|
281
|
+
if (partialSearch) {
|
|
282
|
+
const candidates = [];
|
|
283
|
+
for (const [normalizedKey, original] of normalizedStats) {
|
|
284
|
+
if (normalizedKey.startsWith(searchTerm))
|
|
285
|
+
candidates.push([original, normalizedKey.length]);
|
|
286
|
+
else if (normalizedKey.endsWith(searchTerm))
|
|
287
|
+
candidates.push([original, normalizedKey.length]);
|
|
288
|
+
else if (normalizedKey.includes(searchTerm))
|
|
289
|
+
candidates.push([original, normalizedKey.length]);
|
|
290
|
+
}
|
|
291
|
+
if (candidates.length > 0) {
|
|
292
|
+
candidates.sort((a, b) => a[1] - b[1]);
|
|
293
|
+
return candidates[0][0];
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
let bestMatch;
|
|
297
|
+
let bestSimilarity = 0;
|
|
298
|
+
for (const [normalizedKey, original] of normalizedStats) {
|
|
299
|
+
const similarity = calculateSimilarity(searchTerm, normalizedKey);
|
|
300
|
+
if (similarity === 1) return original;
|
|
301
|
+
if (similarity > bestSimilarity && similarity >= similarityThreshold) {
|
|
302
|
+
bestSimilarity = similarity;
|
|
303
|
+
bestMatch = original;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return bestMatch;
|
|
307
|
+
}
|
|
308
|
+
function findBestRecord(record, searchTerm, similarityThreshold = MIN_THRESHOLD_MATCH) {
|
|
309
|
+
const normalizeRecord = /* @__PURE__ */ new Map();
|
|
310
|
+
for (const key of Object.keys(record)) {
|
|
311
|
+
normalizeRecord.set(key.standardize(), key);
|
|
312
|
+
}
|
|
313
|
+
return findBestStatMatch(
|
|
314
|
+
searchTerm.standardize(),
|
|
315
|
+
normalizeRecord,
|
|
316
|
+
similarityThreshold,
|
|
317
|
+
false
|
|
318
|
+
) || null;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// src/utils.ts
|
|
245
322
|
function escapeRegex(string) {
|
|
246
323
|
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
247
324
|
}
|
|
@@ -251,10 +328,34 @@ function standardizeDice(dice) {
|
|
|
251
328
|
(_match, insideBrackets, outsideText) => insideBrackets ? insideBrackets : outsideText.standardize().replaceAll("df", "dF")
|
|
252
329
|
);
|
|
253
330
|
}
|
|
254
|
-
function
|
|
331
|
+
function handleDiceAfterD(tokenStd, normalizedStats) {
|
|
332
|
+
const diceMatch = /^(\d*)d(.+)$/i.exec(tokenStd);
|
|
333
|
+
if (!diceMatch) return null;
|
|
334
|
+
const diceCount = diceMatch[1] || "";
|
|
335
|
+
const afterD = diceMatch[2];
|
|
336
|
+
const bestMatch = findBestStatMatch(afterD, normalizedStats, 1, false);
|
|
337
|
+
if (bestMatch) {
|
|
338
|
+
const [, value] = bestMatch;
|
|
339
|
+
return `${diceCount}d${value.toString()}`;
|
|
340
|
+
}
|
|
341
|
+
return null;
|
|
342
|
+
}
|
|
343
|
+
function handleSimpleToken(tokenStd, token, normalizedStats, minThreshold) {
|
|
344
|
+
const bestMatch = findBestStatMatch(tokenStd, normalizedStats, minThreshold, false);
|
|
345
|
+
if (bestMatch) {
|
|
346
|
+
const [, value] = bestMatch;
|
|
347
|
+
return value.toString();
|
|
348
|
+
}
|
|
349
|
+
return token;
|
|
350
|
+
}
|
|
351
|
+
function generateStatsDice(originalDice, stats, minThreshold = 0.6, dollarValue) {
|
|
255
352
|
let dice = originalDice.standardize();
|
|
256
353
|
if (stats && Object.keys(stats).length > 0) {
|
|
257
|
-
const
|
|
354
|
+
const normalizedStats = /* @__PURE__ */ new Map();
|
|
355
|
+
for (const [key, value] of Object.entries(stats)) {
|
|
356
|
+
const normalized = key.standardize();
|
|
357
|
+
normalizedStats.set(normalized, [key, value]);
|
|
358
|
+
}
|
|
258
359
|
const partsRegex = /(\[[^\]]+])|([^[]+)/g;
|
|
259
360
|
let result = "";
|
|
260
361
|
let match;
|
|
@@ -268,7 +369,7 @@ function generateStatsDice(originalDice, stats, dollarValue) {
|
|
|
268
369
|
if (!outsideText) {
|
|
269
370
|
continue;
|
|
270
371
|
}
|
|
271
|
-
const tokenRegex = /(\$?[\p{L}\p{N}_]+)/gu;
|
|
372
|
+
const tokenRegex = /(\$?[\p{L}\p{N}_.]+)/gu;
|
|
272
373
|
let lastIndex = 0;
|
|
273
374
|
let tokenMatch;
|
|
274
375
|
while ((tokenMatch = tokenRegex.exec(outsideText)) !== null) {
|
|
@@ -277,45 +378,13 @@ function generateStatsDice(originalDice, stats, dollarValue) {
|
|
|
277
378
|
const tokenHasDollar = token.startsWith("$");
|
|
278
379
|
const tokenForCompare = tokenHasDollar ? token.slice(1) : token;
|
|
279
380
|
const tokenStd = tokenForCompare.standardize();
|
|
280
|
-
const
|
|
281
|
-
if (
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
for (const key of statKeys) {
|
|
286
|
-
const keyStd = key.standardize();
|
|
287
|
-
if (afterD === keyStd) {
|
|
288
|
-
result += `${diceCount}d${stats[key].toString()}`;
|
|
289
|
-
foundStatAfterD = true;
|
|
290
|
-
break;
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
if (foundStatAfterD) {
|
|
294
|
-
lastIndex = tokenRegex.lastIndex;
|
|
295
|
-
continue;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
let bestKey = null;
|
|
299
|
-
let bestScore = 0;
|
|
300
|
-
for (const key of statKeys) {
|
|
301
|
-
const keyStd = key.standardize();
|
|
302
|
-
if (tokenStd === keyStd) {
|
|
303
|
-
bestKey = key;
|
|
304
|
-
bestScore = 1;
|
|
305
|
-
break;
|
|
306
|
-
}
|
|
307
|
-
const score = similarityScore(tokenStd, keyStd);
|
|
308
|
-
if (score > bestScore) {
|
|
309
|
-
bestScore = score;
|
|
310
|
-
bestKey = key;
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
if (bestKey && bestScore >= 0.6) {
|
|
314
|
-
const statValue = stats[bestKey];
|
|
315
|
-
result += statValue.toString();
|
|
316
|
-
} else {
|
|
317
|
-
result += token;
|
|
381
|
+
const diceReplacement = handleDiceAfterD(tokenStd, normalizedStats);
|
|
382
|
+
if (diceReplacement) {
|
|
383
|
+
result += diceReplacement;
|
|
384
|
+
lastIndex = tokenRegex.lastIndex;
|
|
385
|
+
continue;
|
|
318
386
|
}
|
|
387
|
+
result += handleSimpleToken(tokenStd, token, normalizedStats, minThreshold);
|
|
319
388
|
lastIndex = tokenRegex.lastIndex;
|
|
320
389
|
}
|
|
321
390
|
result += outsideText.slice(lastIndex);
|
|
@@ -359,33 +428,6 @@ function randomInt(min, max, engine = import_rpg_dice_roller2.NumberGenerator.en
|
|
|
359
428
|
if (!rng) rng = new import_random_js.Random(engine || void 0);
|
|
360
429
|
return rng.integer(min, max);
|
|
361
430
|
}
|
|
362
|
-
function levenshteinDistance(a, b) {
|
|
363
|
-
if (a === b) return 0;
|
|
364
|
-
const al = a.length;
|
|
365
|
-
const bl = b.length;
|
|
366
|
-
if (al === 0) return bl;
|
|
367
|
-
if (bl === 0) return al;
|
|
368
|
-
const v0 = new Array(bl + 1);
|
|
369
|
-
const v1 = new Array(bl + 1);
|
|
370
|
-
for (let i = 0; i <= bl; i++) v0[i] = i;
|
|
371
|
-
for (let i = 0; i < al; i++) {
|
|
372
|
-
v1[0] = i + 1;
|
|
373
|
-
for (let j = 0; j < bl; j++) {
|
|
374
|
-
const cost = a[i] === b[j] ? 0 : 1;
|
|
375
|
-
v1[j + 1] = Math.min(v1[j] + 1, v0[j + 1] + 1, v0[j] + cost);
|
|
376
|
-
}
|
|
377
|
-
for (let j = 0; j <= bl; j++) v0[j] = v1[j];
|
|
378
|
-
}
|
|
379
|
-
return v1[bl];
|
|
380
|
-
}
|
|
381
|
-
function similarityScore(a, b) {
|
|
382
|
-
const la = a.length;
|
|
383
|
-
const lb = b.length;
|
|
384
|
-
if (la === 0 && lb === 0) return 1;
|
|
385
|
-
const dist = levenshteinDistance(a, b);
|
|
386
|
-
const max = Math.max(la, lb);
|
|
387
|
-
return 1 - dist / max;
|
|
388
|
-
}
|
|
389
431
|
function createCriticalCustom(dice, customCritical, template, engine = import_rpg_dice_roller2.NumberGenerator.engines.nodeCrypto) {
|
|
390
432
|
const compareRegex = dice.match(SIGN_REGEX_SPACE);
|
|
391
433
|
let customDice = dice;
|
|
@@ -1505,6 +1547,7 @@ function generateRandomStat(total = 100, max, min, engine = import_rpg_dice_roll
|
|
|
1505
1547
|
SortOrder,
|
|
1506
1548
|
TooManyDice,
|
|
1507
1549
|
TooManyStats,
|
|
1550
|
+
calculateSimilarity,
|
|
1508
1551
|
createCriticalCustom,
|
|
1509
1552
|
diceRandomParse,
|
|
1510
1553
|
diceTypeRandomParse,
|
|
@@ -1512,11 +1555,14 @@ function generateRandomStat(total = 100, max, min, engine = import_rpg_dice_roll
|
|
|
1512
1555
|
evalCombinaison,
|
|
1513
1556
|
evalOneCombinaison,
|
|
1514
1557
|
evalStatsDice,
|
|
1558
|
+
findBestRecord,
|
|
1559
|
+
findBestStatMatch,
|
|
1515
1560
|
generateRandomStat,
|
|
1516
1561
|
generateStatsDice,
|
|
1517
1562
|
getEngine,
|
|
1518
1563
|
getEngineId,
|
|
1519
1564
|
isNumber,
|
|
1565
|
+
levenshteinDistance,
|
|
1520
1566
|
randomInt,
|
|
1521
1567
|
replaceExpByRandom,
|
|
1522
1568
|
replaceFormulaInDice,
|