@zxcvbn-ts_core.js 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070
  1. import "./chunk-2LSFTFF7.js";
  2. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/helper.esm.js
  3. var empty = (obj) => Object.keys(obj).length === 0;
  4. var extend = (listToExtend, list) => (
  5. // eslint-disable-next-line prefer-spread
  6. listToExtend.push.apply(listToExtend, list)
  7. );
  8. var translate = (string, chrMap) => {
  9. const tempArray = string.split("");
  10. return tempArray.map((char) => chrMap[char] || char).join("");
  11. };
  12. var sorted = (matches) => matches.sort((m1, m2) => m1.i - m2.i || m1.j - m2.j);
  13. var buildRankedDictionary = (orderedList) => {
  14. const result = {};
  15. let counter = 1;
  16. orderedList.forEach((word) => {
  17. result[word] = counter;
  18. counter += 1;
  19. });
  20. return result;
  21. };
  22. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/data/dateSplits.esm.js
  23. var dateSplits = {
  24. 4: [
  25. // for length-4 strings, eg 1191 or 9111, two ways to split:
  26. [1, 2],
  27. [2, 3]
  28. // 91 1 1
  29. ],
  30. 5: [
  31. [1, 3],
  32. [2, 3],
  33. // [2, 3], // 91 1 11 <- duplicate previous one
  34. [2, 4]
  35. // 91 11 1 <- New and must be added as bug fix
  36. ],
  37. 6: [
  38. [1, 2],
  39. [2, 4],
  40. [4, 5]
  41. // 1991 1 1
  42. ],
  43. // 1111991
  44. 7: [
  45. [1, 3],
  46. [2, 3],
  47. [4, 5],
  48. [4, 6]
  49. // 1991 11 1
  50. ],
  51. 8: [
  52. [2, 4],
  53. [4, 6]
  54. // 1991 11 11
  55. ]
  56. };
  57. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/data/const.esm.js
  58. var DATE_MAX_YEAR = 2050;
  59. var DATE_MIN_YEAR = 1e3;
  60. var DATE_SPLITS = dateSplits;
  61. var BRUTEFORCE_CARDINALITY = 10;
  62. var MIN_GUESSES_BEFORE_GROWING_SEQUENCE = 1e4;
  63. var MIN_SUBMATCH_GUESSES_SINGLE_CHAR = 10;
  64. var MIN_SUBMATCH_GUESSES_MULTI_CHAR = 50;
  65. var MIN_YEAR_SPACE = 20;
  66. var START_UPPER = /^[A-Z\xbf-\xdf][^A-Z\xbf-\xdf]+$/;
  67. var END_UPPER = /^[^A-Z\xbf-\xdf]+[A-Z\xbf-\xdf]$/;
  68. var ALL_UPPER = /^[A-Z\xbf-\xdf]+$/;
  69. var ALL_UPPER_INVERTED = /^[^a-z\xdf-\xff]+$/;
  70. var ALL_LOWER = /^[a-z\xdf-\xff]+$/;
  71. var ALL_LOWER_INVERTED = /^[^A-Z\xbf-\xdf]+$/;
  72. var ONE_LOWER = /[a-z\xdf-\xff]/;
  73. var ONE_UPPER = /[A-Z\xbf-\xdf]/;
  74. var ALPHA_INVERTED = /[^A-Za-z\xbf-\xdf]/gi;
  75. var ALL_DIGIT = /^\d+$/;
  76. var REFERENCE_YEAR = (/* @__PURE__ */ new Date()).getFullYear();
  77. var REGEXEN = {
  78. recentYear: /19\d\d|200\d|201\d|202\d/g
  79. };
  80. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/date/matching.esm.js
  81. var MatchDate = class {
  82. /*
  83. * a "date" is recognized as:
  84. * any 3-tuple that starts or ends with a 2- or 4-digit year,
  85. * with 2 or 0 separator chars (1.1.91 or 1191),
  86. * maybe zero-padded (01-01-91 vs 1-1-91),
  87. * a month between 1 and 12,
  88. * a day between 1 and 31.
  89. *
  90. * note: this isn't true date parsing in that "feb 31st" is allowed,
  91. * this doesn't check for leap years, etc.
  92. *
  93. * recipe:
  94. * start with regex to find maybe-dates, then attempt to map the integers
  95. * onto month-day-year to filter the maybe-dates into dates.
  96. * finally, remove matches that are substrings of other matches to reduce noise.
  97. *
  98. * note: instead of using a lazy or greedy regex to find many dates over the full string,
  99. * this uses a ^...$ regex against every substring of the password -- less performant but leads
  100. * to every possible date match.
  101. */
  102. match({
  103. password
  104. }) {
  105. const matches = [...this.getMatchesWithoutSeparator(password), ...this.getMatchesWithSeparator(password)];
  106. const filteredMatches = this.filterNoise(matches);
  107. return sorted(filteredMatches);
  108. }
  109. getMatchesWithSeparator(password) {
  110. const matches = [];
  111. const maybeDateWithSeparator = /^(\d{1,4})([\s/\\_.-])(\d{1,2})\2(\d{1,4})$/;
  112. for (let i = 0; i <= Math.abs(password.length - 6); i += 1) {
  113. for (let j = i + 5; j <= i + 9; j += 1) {
  114. if (j >= password.length) {
  115. break;
  116. }
  117. const token = password.slice(i, +j + 1 || 9e9);
  118. const regexMatch = maybeDateWithSeparator.exec(token);
  119. if (regexMatch != null) {
  120. const dmy = this.mapIntegersToDayMonthYear([parseInt(regexMatch[1], 10), parseInt(regexMatch[3], 10), parseInt(regexMatch[4], 10)]);
  121. if (dmy != null) {
  122. matches.push({
  123. pattern: "date",
  124. token,
  125. i,
  126. j,
  127. separator: regexMatch[2],
  128. year: dmy.year,
  129. month: dmy.month,
  130. day: dmy.day
  131. });
  132. }
  133. }
  134. }
  135. }
  136. return matches;
  137. }
  138. // eslint-disable-next-line max-statements
  139. getMatchesWithoutSeparator(password) {
  140. const matches = [];
  141. const maybeDateNoSeparator = /^\d{4,8}$/;
  142. const metric = (candidate) => Math.abs(candidate.year - REFERENCE_YEAR);
  143. for (let i = 0; i <= Math.abs(password.length - 4); i += 1) {
  144. for (let j = i + 3; j <= i + 7; j += 1) {
  145. if (j >= password.length) {
  146. break;
  147. }
  148. const token = password.slice(i, +j + 1 || 9e9);
  149. if (maybeDateNoSeparator.exec(token)) {
  150. const candidates = [];
  151. const index = token.length;
  152. const splittedDates = DATE_SPLITS[index];
  153. splittedDates.forEach(([k, l]) => {
  154. const dmy = this.mapIntegersToDayMonthYear([parseInt(token.slice(0, k), 10), parseInt(token.slice(k, l), 10), parseInt(token.slice(l), 10)]);
  155. if (dmy != null) {
  156. candidates.push(dmy);
  157. }
  158. });
  159. if (candidates.length > 0) {
  160. let bestCandidate = candidates[0];
  161. let minDistance = metric(candidates[0]);
  162. candidates.slice(1).forEach((candidate) => {
  163. const distance2 = metric(candidate);
  164. if (distance2 < minDistance) {
  165. bestCandidate = candidate;
  166. minDistance = distance2;
  167. }
  168. });
  169. matches.push({
  170. pattern: "date",
  171. token,
  172. i,
  173. j,
  174. separator: "",
  175. year: bestCandidate.year,
  176. month: bestCandidate.month,
  177. day: bestCandidate.day
  178. });
  179. }
  180. }
  181. }
  182. }
  183. return matches;
  184. }
  185. /*
  186. * matches now contains all valid date strings in a way that is tricky to capture
  187. * with regexes only. while thorough, it will contain some unintuitive noise:
  188. *
  189. * '2015_06_04', in addition to matching 2015_06_04, will also contain
  190. * 5(!) other date matches: 15_06_04, 5_06_04, ..., even 2015 (matched as 5/1/2020)
  191. *
  192. * to reduce noise, remove date matches that are strict substrings of others
  193. */
  194. filterNoise(matches) {
  195. return matches.filter((match) => {
  196. let isSubmatch = false;
  197. const matchesLength = matches.length;
  198. for (let o = 0; o < matchesLength; o += 1) {
  199. const otherMatch = matches[o];
  200. if (match !== otherMatch) {
  201. if (otherMatch.i <= match.i && otherMatch.j >= match.j) {
  202. isSubmatch = true;
  203. break;
  204. }
  205. }
  206. }
  207. return !isSubmatch;
  208. });
  209. }
  210. /*
  211. * given a 3-tuple, discard if:
  212. * middle int is over 31 (for all dmy formats, years are never allowed in the middle)
  213. * middle int is zero
  214. * any int is over the max allowable year
  215. * any int is over two digits but under the min allowable year
  216. * 2 integers are over 31, the max allowable day
  217. * 2 integers are zero
  218. * all integers are over 12, the max allowable month
  219. */
  220. // eslint-disable-next-line complexity, max-statements
  221. mapIntegersToDayMonthYear(integers) {
  222. if (integers[1] > 31 || integers[1] <= 0) {
  223. return null;
  224. }
  225. let over12 = 0;
  226. let over31 = 0;
  227. let under1 = 0;
  228. for (let o = 0, len1 = integers.length; o < len1; o += 1) {
  229. const int = integers[o];
  230. if (int > 99 && int < DATE_MIN_YEAR || int > DATE_MAX_YEAR) {
  231. return null;
  232. }
  233. if (int > 31) {
  234. over31 += 1;
  235. }
  236. if (int > 12) {
  237. over12 += 1;
  238. }
  239. if (int <= 0) {
  240. under1 += 1;
  241. }
  242. }
  243. if (over31 >= 2 || over12 === 3 || under1 >= 2) {
  244. return null;
  245. }
  246. return this.getDayMonth(integers);
  247. }
  248. // eslint-disable-next-line max-statements
  249. getDayMonth(integers) {
  250. const possibleYearSplits = [
  251. [integers[2], integers.slice(0, 2)],
  252. [integers[0], integers.slice(1, 3)]
  253. // year first
  254. ];
  255. const possibleYearSplitsLength = possibleYearSplits.length;
  256. for (let j = 0; j < possibleYearSplitsLength; j += 1) {
  257. const [y, rest] = possibleYearSplits[j];
  258. if (DATE_MIN_YEAR <= y && y <= DATE_MAX_YEAR) {
  259. const dm = this.mapIntegersToDayMonth(rest);
  260. if (dm != null) {
  261. return {
  262. year: y,
  263. month: dm.month,
  264. day: dm.day
  265. };
  266. }
  267. return null;
  268. }
  269. }
  270. for (let k = 0; k < possibleYearSplitsLength; k += 1) {
  271. const [y, rest] = possibleYearSplits[k];
  272. const dm = this.mapIntegersToDayMonth(rest);
  273. if (dm != null) {
  274. return {
  275. year: this.twoToFourDigitYear(y),
  276. month: dm.month,
  277. day: dm.day
  278. };
  279. }
  280. }
  281. return null;
  282. }
  283. mapIntegersToDayMonth(integers) {
  284. const temp = [integers, integers.slice().reverse()];
  285. for (let i = 0; i < temp.length; i += 1) {
  286. const data = temp[i];
  287. const day = data[0];
  288. const month = data[1];
  289. if (day >= 1 && day <= 31 && month >= 1 && month <= 12) {
  290. return {
  291. day,
  292. month
  293. };
  294. }
  295. }
  296. return null;
  297. }
  298. twoToFourDigitYear(year) {
  299. if (year > 99) {
  300. return year;
  301. }
  302. if (year > 50) {
  303. return year + 1900;
  304. }
  305. return year + 2e3;
  306. }
  307. };
  308. // node_modules/.pnpm/fastest-levenshtein@1.0.16/node_modules/fastest-levenshtein/esm/mod.js
  309. var peq = new Uint32Array(65536);
  310. var myers_32 = (a, b) => {
  311. const n = a.length;
  312. const m = b.length;
  313. const lst = 1 << n - 1;
  314. let pv = -1;
  315. let mv = 0;
  316. let sc = n;
  317. let i = n;
  318. while (i--) {
  319. peq[a.charCodeAt(i)] |= 1 << i;
  320. }
  321. for (i = 0; i < m; i++) {
  322. let eq = peq[b.charCodeAt(i)];
  323. const xv = eq | mv;
  324. eq |= (eq & pv) + pv ^ pv;
  325. mv |= ~(eq | pv);
  326. pv &= eq;
  327. if (mv & lst) {
  328. sc++;
  329. }
  330. if (pv & lst) {
  331. sc--;
  332. }
  333. mv = mv << 1 | 1;
  334. pv = pv << 1 | ~(xv | mv);
  335. mv &= xv;
  336. }
  337. i = n;
  338. while (i--) {
  339. peq[a.charCodeAt(i)] = 0;
  340. }
  341. return sc;
  342. };
  343. var myers_x = (b, a) => {
  344. const n = a.length;
  345. const m = b.length;
  346. const mhc = [];
  347. const phc = [];
  348. const hsize = Math.ceil(n / 32);
  349. const vsize = Math.ceil(m / 32);
  350. for (let i = 0; i < hsize; i++) {
  351. phc[i] = -1;
  352. mhc[i] = 0;
  353. }
  354. let j = 0;
  355. for (; j < vsize - 1; j++) {
  356. let mv2 = 0;
  357. let pv2 = -1;
  358. const start2 = j * 32;
  359. const vlen2 = Math.min(32, m) + start2;
  360. for (let k = start2; k < vlen2; k++) {
  361. peq[b.charCodeAt(k)] |= 1 << k;
  362. }
  363. for (let i = 0; i < n; i++) {
  364. const eq = peq[a.charCodeAt(i)];
  365. const pb = phc[i / 32 | 0] >>> i & 1;
  366. const mb = mhc[i / 32 | 0] >>> i & 1;
  367. const xv = eq | mv2;
  368. const xh = ((eq | mb) & pv2) + pv2 ^ pv2 | eq | mb;
  369. let ph = mv2 | ~(xh | pv2);
  370. let mh = pv2 & xh;
  371. if (ph >>> 31 ^ pb) {
  372. phc[i / 32 | 0] ^= 1 << i;
  373. }
  374. if (mh >>> 31 ^ mb) {
  375. mhc[i / 32 | 0] ^= 1 << i;
  376. }
  377. ph = ph << 1 | pb;
  378. mh = mh << 1 | mb;
  379. pv2 = mh | ~(xv | ph);
  380. mv2 = ph & xv;
  381. }
  382. for (let k = start2; k < vlen2; k++) {
  383. peq[b.charCodeAt(k)] = 0;
  384. }
  385. }
  386. let mv = 0;
  387. let pv = -1;
  388. const start = j * 32;
  389. const vlen = Math.min(32, m - start) + start;
  390. for (let k = start; k < vlen; k++) {
  391. peq[b.charCodeAt(k)] |= 1 << k;
  392. }
  393. let score = m;
  394. for (let i = 0; i < n; i++) {
  395. const eq = peq[a.charCodeAt(i)];
  396. const pb = phc[i / 32 | 0] >>> i & 1;
  397. const mb = mhc[i / 32 | 0] >>> i & 1;
  398. const xv = eq | mv;
  399. const xh = ((eq | mb) & pv) + pv ^ pv | eq | mb;
  400. let ph = mv | ~(xh | pv);
  401. let mh = pv & xh;
  402. score += ph >>> m - 1 & 1;
  403. score -= mh >>> m - 1 & 1;
  404. if (ph >>> 31 ^ pb) {
  405. phc[i / 32 | 0] ^= 1 << i;
  406. }
  407. if (mh >>> 31 ^ mb) {
  408. mhc[i / 32 | 0] ^= 1 << i;
  409. }
  410. ph = ph << 1 | pb;
  411. mh = mh << 1 | mb;
  412. pv = mh | ~(xv | ph);
  413. mv = ph & xv;
  414. }
  415. for (let k = start; k < vlen; k++) {
  416. peq[b.charCodeAt(k)] = 0;
  417. }
  418. return score;
  419. };
  420. var distance = (a, b) => {
  421. if (a.length < b.length) {
  422. const tmp = b;
  423. b = a;
  424. a = tmp;
  425. }
  426. if (b.length === 0) {
  427. return a.length;
  428. }
  429. if (a.length <= 32) {
  430. return myers_32(a, b);
  431. }
  432. return myers_x(a, b);
  433. };
  434. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/levenshtein.esm.js
  435. var getUsedThreshold = (password, entry, threshold) => {
  436. const isPasswordToShort = password.length <= entry.length;
  437. const isThresholdLongerThanPassword = password.length <= threshold;
  438. const shouldUsePasswordLength = isPasswordToShort || isThresholdLongerThanPassword;
  439. return shouldUsePasswordLength ? Math.ceil(password.length / 4) : threshold;
  440. };
  441. var findLevenshteinDistance = (password, rankedDictionary, threshold) => {
  442. let foundDistance = 0;
  443. const found = Object.keys(rankedDictionary).find((entry) => {
  444. const usedThreshold = getUsedThreshold(password, entry, threshold);
  445. const foundEntryDistance = distance(password, entry);
  446. const isInThreshold = foundEntryDistance <= usedThreshold;
  447. if (isInThreshold) {
  448. foundDistance = foundEntryDistance;
  449. }
  450. return isInThreshold;
  451. });
  452. if (found) {
  453. return {
  454. levenshteinDistance: foundDistance,
  455. levenshteinDistanceEntry: found
  456. };
  457. }
  458. return {};
  459. };
  460. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/data/l33tTable.esm.js
  461. var l33tTable = {
  462. a: ["4", "@"],
  463. b: ["8"],
  464. c: ["(", "{", "[", "<"],
  465. e: ["3"],
  466. g: ["6", "9"],
  467. i: ["1", "!", "|"],
  468. l: ["1", "|", "7"],
  469. o: ["0"],
  470. s: ["$", "5"],
  471. t: ["+", "7"],
  472. x: ["%"],
  473. z: ["2"]
  474. };
  475. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/data/translationKeys.esm.js
  476. var translationKeys = {
  477. warnings: {
  478. straightRow: "straightRow",
  479. keyPattern: "keyPattern",
  480. simpleRepeat: "simpleRepeat",
  481. extendedRepeat: "extendedRepeat",
  482. sequences: "sequences",
  483. recentYears: "recentYears",
  484. dates: "dates",
  485. topTen: "topTen",
  486. topHundred: "topHundred",
  487. common: "common",
  488. similarToCommon: "similarToCommon",
  489. wordByItself: "wordByItself",
  490. namesByThemselves: "namesByThemselves",
  491. commonNames: "commonNames",
  492. userInputs: "userInputs",
  493. pwned: "pwned"
  494. },
  495. suggestions: {
  496. l33t: "l33t",
  497. reverseWords: "reverseWords",
  498. allUppercase: "allUppercase",
  499. capitalization: "capitalization",
  500. dates: "dates",
  501. recentYears: "recentYears",
  502. associatedYears: "associatedYears",
  503. sequences: "sequences",
  504. repeated: "repeated",
  505. longerKeyboardPattern: "longerKeyboardPattern",
  506. anotherWord: "anotherWord",
  507. useWords: "useWords",
  508. noNeed: "noNeed",
  509. pwned: "pwned"
  510. },
  511. timeEstimation: {
  512. ltSecond: "ltSecond",
  513. second: "second",
  514. seconds: "seconds",
  515. minute: "minute",
  516. minutes: "minutes",
  517. hour: "hour",
  518. hours: "hours",
  519. day: "day",
  520. days: "days",
  521. month: "month",
  522. months: "months",
  523. year: "year",
  524. years: "years",
  525. centuries: "centuries"
  526. }
  527. };
  528. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/Options.esm.js
  529. var Options = class {
  530. constructor() {
  531. this.matchers = {};
  532. this.l33tTable = l33tTable;
  533. this.dictionary = {
  534. userInputs: []
  535. };
  536. this.rankedDictionaries = {};
  537. this.rankedDictionariesMaxWordSize = {};
  538. this.translations = translationKeys;
  539. this.graphs = {};
  540. this.useLevenshteinDistance = false;
  541. this.levenshteinThreshold = 2;
  542. this.l33tMaxSubstitutions = 100;
  543. this.maxLength = 256;
  544. this.setRankedDictionaries();
  545. }
  546. // eslint-disable-next-line max-statements,complexity
  547. setOptions(options = {}) {
  548. if (options.l33tTable) {
  549. this.l33tTable = options.l33tTable;
  550. }
  551. if (options.dictionary) {
  552. this.dictionary = options.dictionary;
  553. this.setRankedDictionaries();
  554. }
  555. if (options.translations) {
  556. this.setTranslations(options.translations);
  557. }
  558. if (options.graphs) {
  559. this.graphs = options.graphs;
  560. }
  561. if (options.useLevenshteinDistance !== void 0) {
  562. this.useLevenshteinDistance = options.useLevenshteinDistance;
  563. }
  564. if (options.levenshteinThreshold !== void 0) {
  565. this.levenshteinThreshold = options.levenshteinThreshold;
  566. }
  567. if (options.l33tMaxSubstitutions !== void 0) {
  568. this.l33tMaxSubstitutions = options.l33tMaxSubstitutions;
  569. }
  570. if (options.maxLength !== void 0) {
  571. this.maxLength = options.maxLength;
  572. }
  573. }
  574. setTranslations(translations) {
  575. if (this.checkCustomTranslations(translations)) {
  576. this.translations = translations;
  577. } else {
  578. throw new Error("Invalid translations object fallback to keys");
  579. }
  580. }
  581. checkCustomTranslations(translations) {
  582. let valid = true;
  583. Object.keys(translationKeys).forEach((type) => {
  584. if (type in translations) {
  585. const translationType = type;
  586. Object.keys(translationKeys[translationType]).forEach((key) => {
  587. if (!(key in translations[translationType])) {
  588. valid = false;
  589. }
  590. });
  591. } else {
  592. valid = false;
  593. }
  594. });
  595. return valid;
  596. }
  597. setRankedDictionaries() {
  598. const rankedDictionaries = {};
  599. const rankedDictionariesMaxWorkSize = {};
  600. Object.keys(this.dictionary).forEach((name) => {
  601. rankedDictionaries[name] = this.getRankedDictionary(name);
  602. rankedDictionariesMaxWorkSize[name] = this.getRankedDictionariesMaxWordSize(name);
  603. });
  604. this.rankedDictionaries = rankedDictionaries;
  605. this.rankedDictionariesMaxWordSize = rankedDictionariesMaxWorkSize;
  606. }
  607. getRankedDictionariesMaxWordSize(name) {
  608. const data = this.dictionary[name].map((el) => {
  609. if (typeof el !== "string") {
  610. return el.toString().length;
  611. }
  612. return el.length;
  613. });
  614. if (data.length === 0) {
  615. return 0;
  616. }
  617. return data.reduce((a, b) => Math.max(a, b), -Infinity);
  618. }
  619. getRankedDictionary(name) {
  620. const list = this.dictionary[name];
  621. if (name === "userInputs") {
  622. const sanitizedInputs = [];
  623. list.forEach((input) => {
  624. const inputType = typeof input;
  625. if (inputType === "string" || inputType === "number" || inputType === "boolean") {
  626. sanitizedInputs.push(input.toString().toLowerCase());
  627. }
  628. });
  629. return buildRankedDictionary(sanitizedInputs);
  630. }
  631. return buildRankedDictionary(list);
  632. }
  633. extendUserInputsDictionary(dictionary) {
  634. if (this.dictionary.userInputs) {
  635. this.dictionary.userInputs = [...this.dictionary.userInputs, ...dictionary];
  636. } else {
  637. this.dictionary.userInputs = dictionary;
  638. }
  639. this.rankedDictionaries.userInputs = this.getRankedDictionary("userInputs");
  640. this.rankedDictionariesMaxWordSize.userInputs = this.getRankedDictionariesMaxWordSize("userInputs");
  641. }
  642. addMatcher(name, matcher) {
  643. if (this.matchers[name]) {
  644. console.info(`Matcher ${name} already exists`);
  645. } else {
  646. this.matchers[name] = matcher;
  647. }
  648. }
  649. };
  650. var zxcvbnOptions = new Options();
  651. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/dictionary/variants/matching/reverse.esm.js
  652. var MatchReverse = class {
  653. constructor(defaultMatch) {
  654. this.defaultMatch = defaultMatch;
  655. }
  656. match({
  657. password
  658. }) {
  659. const passwordReversed = password.split("").reverse().join("");
  660. return this.defaultMatch({
  661. password: passwordReversed
  662. }).map((match) => ({
  663. ...match,
  664. token: match.token.split("").reverse().join(""),
  665. reversed: true,
  666. // map coordinates back to original string
  667. i: password.length - 1 - match.j,
  668. j: password.length - 1 - match.i
  669. }));
  670. }
  671. };
  672. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/dictionary/variants/matching/l33t.esm.js
  673. var MatchL33t = class {
  674. constructor(defaultMatch) {
  675. this.defaultMatch = defaultMatch;
  676. }
  677. match({
  678. password
  679. }) {
  680. const matches = [];
  681. const enumeratedSubs = this.enumerateL33tSubs(this.relevantL33tSubtable(password, zxcvbnOptions.l33tTable));
  682. const length = Math.min(enumeratedSubs.length, zxcvbnOptions.l33tMaxSubstitutions);
  683. for (let i = 0; i < length; i += 1) {
  684. const sub = enumeratedSubs[i];
  685. if (empty(sub)) {
  686. break;
  687. }
  688. const subbedPassword = translate(password, sub);
  689. const matchedDictionary = this.defaultMatch({
  690. password: subbedPassword
  691. });
  692. matchedDictionary.forEach((match) => {
  693. const token = password.slice(match.i, +match.j + 1 || 9e9);
  694. if (token.toLowerCase() !== match.matchedWord) {
  695. const matchSub = {};
  696. Object.keys(sub).forEach((subbedChr) => {
  697. const chr = sub[subbedChr];
  698. if (token.indexOf(subbedChr) !== -1) {
  699. matchSub[subbedChr] = chr;
  700. }
  701. });
  702. const subDisplay = Object.keys(matchSub).map((k) => `${k} -> ${matchSub[k]}`).join(", ");
  703. matches.push({
  704. ...match,
  705. l33t: true,
  706. token,
  707. sub: matchSub,
  708. subDisplay
  709. });
  710. }
  711. });
  712. }
  713. return matches.filter((match) => match.token.length > 1);
  714. }
  715. // makes a pruned copy of l33t_table that only includes password's possible substitutions
  716. relevantL33tSubtable(password, table) {
  717. const passwordChars = {};
  718. const subTable = {};
  719. password.split("").forEach((char) => {
  720. passwordChars[char] = true;
  721. });
  722. Object.keys(table).forEach((letter) => {
  723. const subs = table[letter];
  724. const relevantSubs = subs.filter((sub) => sub in passwordChars);
  725. if (relevantSubs.length > 0) {
  726. subTable[letter] = relevantSubs;
  727. }
  728. });
  729. return subTable;
  730. }
  731. // returns the list of possible 1337 replacement dictionaries for a given password
  732. enumerateL33tSubs(table) {
  733. const tableKeys = Object.keys(table);
  734. const subs = this.getSubs(tableKeys, [[]], table);
  735. return subs.map((sub) => {
  736. const subDict = {};
  737. sub.forEach(([l33tChr, chr]) => {
  738. subDict[l33tChr] = chr;
  739. });
  740. return subDict;
  741. });
  742. }
  743. getSubs(keys, subs, table) {
  744. if (!keys.length) {
  745. return subs;
  746. }
  747. const firstKey = keys[0];
  748. const restKeys = keys.slice(1);
  749. const nextSubs = [];
  750. table[firstKey].forEach((l33tChr) => {
  751. subs.forEach((sub) => {
  752. let dupL33tIndex = -1;
  753. for (let i = 0; i < sub.length; i += 1) {
  754. if (sub[i][0] === l33tChr) {
  755. dupL33tIndex = i;
  756. break;
  757. }
  758. }
  759. if (dupL33tIndex === -1) {
  760. const subExtension = sub.concat([[l33tChr, firstKey]]);
  761. nextSubs.push(subExtension);
  762. } else {
  763. const subAlternative = sub.slice(0);
  764. subAlternative.splice(dupL33tIndex, 1);
  765. subAlternative.push([l33tChr, firstKey]);
  766. nextSubs.push(sub);
  767. nextSubs.push(subAlternative);
  768. }
  769. });
  770. });
  771. const newSubs = this.dedup(nextSubs);
  772. if (restKeys.length) {
  773. return this.getSubs(restKeys, newSubs, table);
  774. }
  775. return newSubs;
  776. }
  777. dedup(subs) {
  778. const deduped = [];
  779. const members = {};
  780. subs.forEach((sub) => {
  781. const assoc = sub.map((k, index) => [k, index]);
  782. assoc.sort();
  783. const label = assoc.map(([k, v]) => `${k},${v}`).join("-");
  784. if (!(label in members)) {
  785. members[label] = true;
  786. deduped.push(sub);
  787. }
  788. });
  789. return deduped;
  790. }
  791. };
  792. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/dictionary/matching.esm.js
  793. var MatchDictionary = class {
  794. constructor() {
  795. this.l33t = new MatchL33t(this.defaultMatch);
  796. this.reverse = new MatchReverse(this.defaultMatch);
  797. }
  798. match({
  799. password
  800. }) {
  801. const matches = [...this.defaultMatch({
  802. password
  803. }), ...this.reverse.match({
  804. password
  805. }), ...this.l33t.match({
  806. password
  807. })];
  808. return sorted(matches);
  809. }
  810. defaultMatch({
  811. password
  812. }) {
  813. const matches = [];
  814. const passwordLength = password.length;
  815. const passwordLower = password.toLowerCase();
  816. Object.keys(zxcvbnOptions.rankedDictionaries).forEach((dictionaryName) => {
  817. const rankedDict = zxcvbnOptions.rankedDictionaries[dictionaryName];
  818. const longestDictionaryWordSize = zxcvbnOptions.rankedDictionariesMaxWordSize[dictionaryName];
  819. const searchWidth = Math.min(longestDictionaryWordSize, passwordLength);
  820. for (let i = 0; i < passwordLength; i += 1) {
  821. const searchEnd = Math.min(i + searchWidth, passwordLength);
  822. for (let j = i; j < searchEnd; j += 1) {
  823. const usedPassword = passwordLower.slice(i, +j + 1 || 9e9);
  824. const isInDictionary = usedPassword in rankedDict;
  825. let foundLevenshteinDistance = {};
  826. const isFullPassword = i === 0 && j === passwordLength - 1;
  827. if (zxcvbnOptions.useLevenshteinDistance && isFullPassword && !isInDictionary) {
  828. foundLevenshteinDistance = findLevenshteinDistance(usedPassword, rankedDict, zxcvbnOptions.levenshteinThreshold);
  829. }
  830. const isLevenshteinMatch = Object.keys(foundLevenshteinDistance).length !== 0;
  831. if (isInDictionary || isLevenshteinMatch) {
  832. const usedRankPassword = isLevenshteinMatch ? foundLevenshteinDistance.levenshteinDistanceEntry : usedPassword;
  833. const rank = rankedDict[usedRankPassword];
  834. matches.push({
  835. pattern: "dictionary",
  836. i,
  837. j,
  838. token: password.slice(i, +j + 1 || 9e9),
  839. matchedWord: usedPassword,
  840. rank,
  841. dictionaryName,
  842. reversed: false,
  843. l33t: false,
  844. ...foundLevenshteinDistance
  845. });
  846. }
  847. }
  848. }
  849. });
  850. return matches;
  851. }
  852. };
  853. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/regex/matching.esm.js
  854. var MatchRegex = class {
  855. match({
  856. password,
  857. regexes = REGEXEN
  858. }) {
  859. const matches = [];
  860. Object.keys(regexes).forEach((name) => {
  861. const regex = regexes[name];
  862. regex.lastIndex = 0;
  863. const regexMatch = regex.exec(password);
  864. if (regexMatch) {
  865. const token = regexMatch[0];
  866. matches.push({
  867. pattern: "regex",
  868. token,
  869. i: regexMatch.index,
  870. j: regexMatch.index + regexMatch[0].length - 1,
  871. regexName: name,
  872. regexMatch
  873. });
  874. }
  875. });
  876. return sorted(matches);
  877. }
  878. };
  879. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/scoring/utils.esm.js
  880. var utils = {
  881. // binomial coefficients
  882. // src: http://blog.plover.com/math/choose.html
  883. nCk(n, k) {
  884. let count = n;
  885. if (k > count) {
  886. return 0;
  887. }
  888. if (k === 0) {
  889. return 1;
  890. }
  891. let coEff = 1;
  892. for (let i = 1; i <= k; i += 1) {
  893. coEff *= count;
  894. coEff /= i;
  895. count -= 1;
  896. }
  897. return coEff;
  898. },
  899. log10(n) {
  900. return Math.log(n) / Math.log(10);
  901. },
  902. log2(n) {
  903. return Math.log(n) / Math.log(2);
  904. },
  905. factorial(num) {
  906. let rval = 1;
  907. for (let i = 2; i <= num; i += 1)
  908. rval *= i;
  909. return rval;
  910. }
  911. };
  912. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/bruteforce/scoring.esm.js
  913. var bruteforceMatcher = ({
  914. token
  915. }) => {
  916. let guesses = BRUTEFORCE_CARDINALITY ** token.length;
  917. if (guesses === Number.POSITIVE_INFINITY) {
  918. guesses = Number.MAX_VALUE;
  919. }
  920. let minGuesses;
  921. if (token.length === 1) {
  922. minGuesses = MIN_SUBMATCH_GUESSES_SINGLE_CHAR + 1;
  923. } else {
  924. minGuesses = MIN_SUBMATCH_GUESSES_MULTI_CHAR + 1;
  925. }
  926. return Math.max(guesses, minGuesses);
  927. };
  928. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/date/scoring.esm.js
  929. var dateMatcher = ({
  930. year,
  931. separator
  932. }) => {
  933. const yearSpace = Math.max(Math.abs(year - REFERENCE_YEAR), MIN_YEAR_SPACE);
  934. let guesses = yearSpace * 365;
  935. if (separator) {
  936. guesses *= 4;
  937. }
  938. return guesses;
  939. };
  940. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/dictionary/variants/scoring/uppercase.esm.js
  941. var getVariations = (cleanedWord) => {
  942. const wordArray = cleanedWord.split("");
  943. const upperCaseCount = wordArray.filter((char) => char.match(ONE_UPPER)).length;
  944. const lowerCaseCount = wordArray.filter((char) => char.match(ONE_LOWER)).length;
  945. let variations = 0;
  946. const variationLength = Math.min(upperCaseCount, lowerCaseCount);
  947. for (let i = 1; i <= variationLength; i += 1) {
  948. variations += utils.nCk(upperCaseCount + lowerCaseCount, i);
  949. }
  950. return variations;
  951. };
  952. var uppercaseVariant = (word) => {
  953. const cleanedWord = word.replace(ALPHA_INVERTED, "");
  954. if (cleanedWord.match(ALL_LOWER_INVERTED) || cleanedWord.toLowerCase() === cleanedWord) {
  955. return 1;
  956. }
  957. const commonCases = [START_UPPER, END_UPPER, ALL_UPPER_INVERTED];
  958. const commonCasesLength = commonCases.length;
  959. for (let i = 0; i < commonCasesLength; i += 1) {
  960. const regex = commonCases[i];
  961. if (cleanedWord.match(regex)) {
  962. return 2;
  963. }
  964. }
  965. return getVariations(cleanedWord);
  966. };
  967. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/dictionary/variants/scoring/l33t.esm.js
  968. var getCounts = ({
  969. subs,
  970. subbed,
  971. token
  972. }) => {
  973. const unsubbed = subs[subbed];
  974. const chrs = token.toLowerCase().split("");
  975. const subbedCount = chrs.filter((char) => char === subbed).length;
  976. const unsubbedCount = chrs.filter((char) => char === unsubbed).length;
  977. return {
  978. subbedCount,
  979. unsubbedCount
  980. };
  981. };
  982. var l33tVariant = ({
  983. l33t,
  984. sub,
  985. token
  986. }) => {
  987. if (!l33t) {
  988. return 1;
  989. }
  990. let variations = 1;
  991. const subs = sub;
  992. Object.keys(subs).forEach((subbed) => {
  993. const {
  994. subbedCount,
  995. unsubbedCount
  996. } = getCounts({
  997. subs,
  998. subbed,
  999. token
  1000. });
  1001. if (subbedCount === 0 || unsubbedCount === 0) {
  1002. variations *= 2;
  1003. } else {
  1004. const p = Math.min(unsubbedCount, subbedCount);
  1005. let possibilities = 0;
  1006. for (let i = 1; i <= p; i += 1) {
  1007. possibilities += utils.nCk(unsubbedCount + subbedCount, i);
  1008. }
  1009. variations *= possibilities;
  1010. }
  1011. });
  1012. return variations;
  1013. };
  1014. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/dictionary/scoring.esm.js
  1015. var dictionaryMatcher = ({
  1016. rank,
  1017. reversed,
  1018. l33t,
  1019. sub,
  1020. token
  1021. }) => {
  1022. const baseGuesses = rank;
  1023. const uppercaseVariations = uppercaseVariant(token);
  1024. const l33tVariations = l33tVariant({
  1025. l33t,
  1026. sub,
  1027. token
  1028. });
  1029. const reversedVariations = reversed && 2 || 1;
  1030. const calculation = baseGuesses * uppercaseVariations * l33tVariations * reversedVariations;
  1031. return {
  1032. baseGuesses,
  1033. uppercaseVariations,
  1034. l33tVariations,
  1035. calculation
  1036. };
  1037. };
  1038. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/regex/scoring.esm.js
  1039. var regexMatcher = ({
  1040. regexName,
  1041. regexMatch,
  1042. token
  1043. }) => {
  1044. const charClassBases = {
  1045. alphaLower: 26,
  1046. alphaUpper: 26,
  1047. alpha: 52,
  1048. alphanumeric: 62,
  1049. digits: 10,
  1050. symbols: 33
  1051. };
  1052. if (regexName in charClassBases) {
  1053. return charClassBases[regexName] ** token.length;
  1054. }
  1055. switch (regexName) {
  1056. case "recentYear":
  1057. return Math.max(Math.abs(parseInt(regexMatch[0], 10) - REFERENCE_YEAR), MIN_YEAR_SPACE);
  1058. }
  1059. return 0;
  1060. };
  1061. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/repeat/scoring.esm.js
  1062. var repeatMatcher = ({
  1063. baseGuesses,
  1064. repeatCount
  1065. }) => baseGuesses * repeatCount;
  1066. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/sequence/scoring.esm.js
  1067. var sequenceMatcher = ({
  1068. token,
  1069. ascending
  1070. }) => {
  1071. const firstChr = token.charAt(0);
  1072. let baseGuesses = 0;
  1073. const startingPoints = ["a", "A", "z", "Z", "0", "1", "9"];
  1074. if (startingPoints.includes(firstChr)) {
  1075. baseGuesses = 4;
  1076. } else if (firstChr.match(/\d/)) {
  1077. baseGuesses = 10;
  1078. } else {
  1079. baseGuesses = 26;
  1080. }
  1081. if (!ascending) {
  1082. baseGuesses *= 2;
  1083. }
  1084. return baseGuesses * token.length;
  1085. };
  1086. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/spatial/scoring.esm.js
  1087. var calcAverageDegree = (graph) => {
  1088. let average = 0;
  1089. Object.keys(graph).forEach((key) => {
  1090. const neighbors = graph[key];
  1091. average += neighbors.filter((entry) => !!entry).length;
  1092. });
  1093. average /= Object.entries(graph).length;
  1094. return average;
  1095. };
  1096. var estimatePossiblePatterns = ({
  1097. token,
  1098. graph,
  1099. turns
  1100. }) => {
  1101. const startingPosition = Object.keys(zxcvbnOptions.graphs[graph]).length;
  1102. const averageDegree = calcAverageDegree(zxcvbnOptions.graphs[graph]);
  1103. let guesses = 0;
  1104. const tokenLength = token.length;
  1105. for (let i = 2; i <= tokenLength; i += 1) {
  1106. const possibleTurns = Math.min(turns, i - 1);
  1107. for (let j = 1; j <= possibleTurns; j += 1) {
  1108. guesses += utils.nCk(i - 1, j - 1) * startingPosition * averageDegree ** j;
  1109. }
  1110. }
  1111. return guesses;
  1112. };
  1113. var spatialMatcher = ({
  1114. graph,
  1115. token,
  1116. shiftedCount,
  1117. turns
  1118. }) => {
  1119. let guesses = estimatePossiblePatterns({
  1120. token,
  1121. graph,
  1122. turns
  1123. });
  1124. if (shiftedCount) {
  1125. const unShiftedCount = token.length - shiftedCount;
  1126. if (shiftedCount === 0 || unShiftedCount === 0) {
  1127. guesses *= 2;
  1128. } else {
  1129. let shiftedVariations = 0;
  1130. for (let i = 1; i <= Math.min(shiftedCount, unShiftedCount); i += 1) {
  1131. shiftedVariations += utils.nCk(shiftedCount + unShiftedCount, i);
  1132. }
  1133. guesses *= shiftedVariations;
  1134. }
  1135. }
  1136. return Math.round(guesses);
  1137. };
  1138. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/scoring/estimate.esm.js
  1139. var getMinGuesses = (match, password) => {
  1140. let minGuesses = 1;
  1141. if (match.token.length < password.length) {
  1142. if (match.token.length === 1) {
  1143. minGuesses = MIN_SUBMATCH_GUESSES_SINGLE_CHAR;
  1144. } else {
  1145. minGuesses = MIN_SUBMATCH_GUESSES_MULTI_CHAR;
  1146. }
  1147. }
  1148. return minGuesses;
  1149. };
  1150. var matchers = {
  1151. bruteforce: bruteforceMatcher,
  1152. date: dateMatcher,
  1153. dictionary: dictionaryMatcher,
  1154. regex: regexMatcher,
  1155. repeat: repeatMatcher,
  1156. sequence: sequenceMatcher,
  1157. spatial: spatialMatcher
  1158. };
  1159. var getScoring = (name, match) => {
  1160. if (matchers[name]) {
  1161. return matchers[name](match);
  1162. }
  1163. if (zxcvbnOptions.matchers[name] && "scoring" in zxcvbnOptions.matchers[name]) {
  1164. return zxcvbnOptions.matchers[name].scoring(match);
  1165. }
  1166. return 0;
  1167. };
  1168. var estimateGuesses = (match, password) => {
  1169. const extraData = {};
  1170. if ("guesses" in match && match.guesses != null) {
  1171. return match;
  1172. }
  1173. const minGuesses = getMinGuesses(match, password);
  1174. const estimationResult = getScoring(match.pattern, match);
  1175. let guesses = 0;
  1176. if (typeof estimationResult === "number") {
  1177. guesses = estimationResult;
  1178. } else if (match.pattern === "dictionary") {
  1179. guesses = estimationResult.calculation;
  1180. extraData.baseGuesses = estimationResult.baseGuesses;
  1181. extraData.uppercaseVariations = estimationResult.uppercaseVariations;
  1182. extraData.l33tVariations = estimationResult.l33tVariations;
  1183. }
  1184. const matchGuesses = Math.max(guesses, minGuesses);
  1185. return {
  1186. ...match,
  1187. ...extraData,
  1188. guesses: matchGuesses,
  1189. guessesLog10: utils.log10(matchGuesses)
  1190. };
  1191. };
  1192. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/scoring/index.esm.js
  1193. var scoringHelper = {
  1194. password: "",
  1195. optimal: {},
  1196. excludeAdditive: false,
  1197. fillArray(size, valueType) {
  1198. const result = [];
  1199. for (let i = 0; i < size; i += 1) {
  1200. let value = [];
  1201. if (valueType === "object") {
  1202. value = {};
  1203. }
  1204. result.push(value);
  1205. }
  1206. return result;
  1207. },
  1208. // helper: make bruteforce match objects spanning i to j, inclusive.
  1209. makeBruteforceMatch(i, j) {
  1210. return {
  1211. pattern: "bruteforce",
  1212. token: this.password.slice(i, +j + 1 || 9e9),
  1213. i,
  1214. j
  1215. };
  1216. },
  1217. // helper: considers whether a length-sequenceLength
  1218. // sequence ending at match m is better (fewer guesses)
  1219. // than previously encountered sequences, updating state if so.
  1220. update(match, sequenceLength) {
  1221. const k = match.j;
  1222. const estimatedMatch = estimateGuesses(match, this.password);
  1223. let pi = estimatedMatch.guesses;
  1224. if (sequenceLength > 1) {
  1225. pi *= this.optimal.pi[estimatedMatch.i - 1][sequenceLength - 1];
  1226. }
  1227. let g = utils.factorial(sequenceLength) * pi;
  1228. if (!this.excludeAdditive) {
  1229. g += MIN_GUESSES_BEFORE_GROWING_SEQUENCE ** (sequenceLength - 1);
  1230. }
  1231. let shouldSkip = false;
  1232. Object.keys(this.optimal.g[k]).forEach((competingPatternLength) => {
  1233. const competingMetricMatch = this.optimal.g[k][competingPatternLength];
  1234. if (parseInt(competingPatternLength, 10) <= sequenceLength) {
  1235. if (competingMetricMatch <= g) {
  1236. shouldSkip = true;
  1237. }
  1238. }
  1239. });
  1240. if (!shouldSkip) {
  1241. this.optimal.g[k][sequenceLength] = g;
  1242. this.optimal.m[k][sequenceLength] = estimatedMatch;
  1243. this.optimal.pi[k][sequenceLength] = pi;
  1244. }
  1245. },
  1246. // helper: evaluate bruteforce matches ending at passwordCharIndex.
  1247. bruteforceUpdate(passwordCharIndex) {
  1248. let match = this.makeBruteforceMatch(0, passwordCharIndex);
  1249. this.update(match, 1);
  1250. for (let i = 1; i <= passwordCharIndex; i += 1) {
  1251. match = this.makeBruteforceMatch(i, passwordCharIndex);
  1252. const tmp = this.optimal.m[i - 1];
  1253. Object.keys(tmp).forEach((sequenceLength) => {
  1254. const lastMatch = tmp[sequenceLength];
  1255. if (lastMatch.pattern !== "bruteforce") {
  1256. this.update(match, parseInt(sequenceLength, 10) + 1);
  1257. }
  1258. });
  1259. }
  1260. },
  1261. // helper: step backwards through optimal.m starting at the end,
  1262. // constructing the final optimal match sequence.
  1263. unwind(passwordLength) {
  1264. const optimalMatchSequence = [];
  1265. let k = passwordLength - 1;
  1266. let sequenceLength = 0;
  1267. let g = Infinity;
  1268. const temp = this.optimal.g[k];
  1269. if (temp) {
  1270. Object.keys(temp).forEach((candidateSequenceLength) => {
  1271. const candidateMetricMatch = temp[candidateSequenceLength];
  1272. if (candidateMetricMatch < g) {
  1273. sequenceLength = parseInt(candidateSequenceLength, 10);
  1274. g = candidateMetricMatch;
  1275. }
  1276. });
  1277. }
  1278. while (k >= 0) {
  1279. const match = this.optimal.m[k][sequenceLength];
  1280. optimalMatchSequence.unshift(match);
  1281. k = match.i - 1;
  1282. sequenceLength -= 1;
  1283. }
  1284. return optimalMatchSequence;
  1285. }
  1286. };
  1287. var scoring = {
  1288. // ------------------------------------------------------------------------------
  1289. // search --- most guessable match sequence -------------------------------------
  1290. // ------------------------------------------------------------------------------
  1291. //
  1292. // takes a sequence of overlapping matches, returns the non-overlapping sequence with
  1293. // minimum guesses. the following is a O(l_max * (n + m)) dynamic programming algorithm
  1294. // for a length-n password with m candidate matches. l_max is the maximum optimal
  1295. // sequence length spanning each prefix of the password. In practice it rarely exceeds 5 and the
  1296. // search terminates rapidly.
  1297. //
  1298. // the optimal "minimum guesses" sequence is here defined to be the sequence that
  1299. // minimizes the following function:
  1300. //
  1301. // g = sequenceLength! * Product(m.guesses for m in sequence) + D^(sequenceLength - 1)
  1302. //
  1303. // where sequenceLength is the length of the sequence.
  1304. //
  1305. // the factorial term is the number of ways to order sequenceLength patterns.
  1306. //
  1307. // the D^(sequenceLength-1) term is another length penalty, roughly capturing the idea that an
  1308. // attacker will try lower-length sequences first before trying length-sequenceLength sequences.
  1309. //
  1310. // for example, consider a sequence that is date-repeat-dictionary.
  1311. // - an attacker would need to try other date-repeat-dictionary combinations,
  1312. // hence the product term.
  1313. // - an attacker would need to try repeat-date-dictionary, dictionary-repeat-date,
  1314. // ..., hence the factorial term.
  1315. // - an attacker would also likely try length-1 (dictionary) and length-2 (dictionary-date)
  1316. // sequences before length-3. assuming at minimum D guesses per pattern type,
  1317. // D^(sequenceLength-1) approximates Sum(D^i for i in [1..sequenceLength-1]
  1318. //
  1319. // ------------------------------------------------------------------------------
  1320. mostGuessableMatchSequence(password, matches, excludeAdditive = false) {
  1321. scoringHelper.password = password;
  1322. scoringHelper.excludeAdditive = excludeAdditive;
  1323. const passwordLength = password.length;
  1324. let matchesByCoordinateJ = scoringHelper.fillArray(passwordLength, "array");
  1325. matches.forEach((match) => {
  1326. matchesByCoordinateJ[match.j].push(match);
  1327. });
  1328. matchesByCoordinateJ = matchesByCoordinateJ.map((match) => match.sort((m1, m2) => m1.i - m2.i));
  1329. scoringHelper.optimal = {
  1330. // optimal.m[k][sequenceLength] holds final match in the best length-sequenceLength
  1331. // match sequence covering the
  1332. // password prefix up to k, inclusive.
  1333. // if there is no length-sequenceLength sequence that scores better (fewer guesses) than
  1334. // a shorter match sequence spanning the same prefix,
  1335. // optimal.m[k][sequenceLength] is undefined.
  1336. m: scoringHelper.fillArray(passwordLength, "object"),
  1337. // same structure as optimal.m -- holds the product term Prod(m.guesses for m in sequence).
  1338. // optimal.pi allows for fast (non-looping) updates to the minimization function.
  1339. pi: scoringHelper.fillArray(passwordLength, "object"),
  1340. // same structure as optimal.m -- holds the overall metric.
  1341. g: scoringHelper.fillArray(passwordLength, "object")
  1342. };
  1343. for (let k = 0; k < passwordLength; k += 1) {
  1344. matchesByCoordinateJ[k].forEach((match) => {
  1345. if (match.i > 0) {
  1346. Object.keys(scoringHelper.optimal.m[match.i - 1]).forEach((sequenceLength) => {
  1347. scoringHelper.update(match, parseInt(sequenceLength, 10) + 1);
  1348. });
  1349. } else {
  1350. scoringHelper.update(match, 1);
  1351. }
  1352. });
  1353. scoringHelper.bruteforceUpdate(k);
  1354. }
  1355. const optimalMatchSequence = scoringHelper.unwind(passwordLength);
  1356. const optimalSequenceLength = optimalMatchSequence.length;
  1357. const guesses = this.getGuesses(password, optimalSequenceLength);
  1358. return {
  1359. password,
  1360. guesses,
  1361. guessesLog10: utils.log10(guesses),
  1362. sequence: optimalMatchSequence
  1363. };
  1364. },
  1365. getGuesses(password, optimalSequenceLength) {
  1366. const passwordLength = password.length;
  1367. let guesses = 0;
  1368. if (password.length === 0) {
  1369. guesses = 1;
  1370. } else {
  1371. guesses = scoringHelper.optimal.g[passwordLength - 1][optimalSequenceLength];
  1372. }
  1373. return guesses;
  1374. }
  1375. };
  1376. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/repeat/matching.esm.js
  1377. var MatchRepeat = class {
  1378. // eslint-disable-next-line max-statements
  1379. match({
  1380. password,
  1381. omniMatch
  1382. }) {
  1383. const matches = [];
  1384. let lastIndex = 0;
  1385. while (lastIndex < password.length) {
  1386. const greedyMatch = this.getGreedyMatch(password, lastIndex);
  1387. const lazyMatch = this.getLazyMatch(password, lastIndex);
  1388. if (greedyMatch == null) {
  1389. break;
  1390. }
  1391. const {
  1392. match,
  1393. baseToken
  1394. } = this.setMatchToken(greedyMatch, lazyMatch);
  1395. if (match) {
  1396. const j = match.index + match[0].length - 1;
  1397. const baseGuesses = this.getBaseGuesses(baseToken, omniMatch);
  1398. matches.push(this.normalizeMatch(baseToken, j, match, baseGuesses));
  1399. lastIndex = j + 1;
  1400. }
  1401. }
  1402. const hasPromises = matches.some((match) => {
  1403. return match instanceof Promise;
  1404. });
  1405. if (hasPromises) {
  1406. return Promise.all(matches);
  1407. }
  1408. return matches;
  1409. }
  1410. // eslint-disable-next-line max-params
  1411. normalizeMatch(baseToken, j, match, baseGuesses) {
  1412. const baseMatch = {
  1413. pattern: "repeat",
  1414. i: match.index,
  1415. j,
  1416. token: match[0],
  1417. baseToken,
  1418. baseGuesses: 0,
  1419. repeatCount: match[0].length / baseToken.length
  1420. };
  1421. if (baseGuesses instanceof Promise) {
  1422. return baseGuesses.then((resolvedBaseGuesses) => {
  1423. return {
  1424. ...baseMatch,
  1425. baseGuesses: resolvedBaseGuesses
  1426. };
  1427. });
  1428. }
  1429. return {
  1430. ...baseMatch,
  1431. baseGuesses
  1432. };
  1433. }
  1434. getGreedyMatch(password, lastIndex) {
  1435. const greedy = /(.+)\1+/g;
  1436. greedy.lastIndex = lastIndex;
  1437. return greedy.exec(password);
  1438. }
  1439. getLazyMatch(password, lastIndex) {
  1440. const lazy = /(.+?)\1+/g;
  1441. lazy.lastIndex = lastIndex;
  1442. return lazy.exec(password);
  1443. }
  1444. setMatchToken(greedyMatch, lazyMatch) {
  1445. const lazyAnchored = /^(.+?)\1+$/;
  1446. let match;
  1447. let baseToken = "";
  1448. if (lazyMatch && greedyMatch[0].length > lazyMatch[0].length) {
  1449. match = greedyMatch;
  1450. const temp = lazyAnchored.exec(match[0]);
  1451. if (temp) {
  1452. baseToken = temp[1];
  1453. }
  1454. } else {
  1455. match = lazyMatch;
  1456. if (match) {
  1457. baseToken = match[1];
  1458. }
  1459. }
  1460. return {
  1461. match,
  1462. baseToken
  1463. };
  1464. }
  1465. getBaseGuesses(baseToken, omniMatch) {
  1466. const matches = omniMatch.match(baseToken);
  1467. if (matches instanceof Promise) {
  1468. return matches.then((resolvedMatches) => {
  1469. const baseAnalysis2 = scoring.mostGuessableMatchSequence(baseToken, resolvedMatches);
  1470. return baseAnalysis2.guesses;
  1471. });
  1472. }
  1473. const baseAnalysis = scoring.mostGuessableMatchSequence(baseToken, matches);
  1474. return baseAnalysis.guesses;
  1475. }
  1476. };
  1477. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/sequence/matching.esm.js
  1478. var MatchSequence = class {
  1479. constructor() {
  1480. this.MAX_DELTA = 5;
  1481. }
  1482. // eslint-disable-next-line max-statements
  1483. match({
  1484. password
  1485. }) {
  1486. const result = [];
  1487. if (password.length === 1) {
  1488. return [];
  1489. }
  1490. let i = 0;
  1491. let lastDelta = null;
  1492. const passwordLength = password.length;
  1493. for (let k = 1; k < passwordLength; k += 1) {
  1494. const delta = password.charCodeAt(k) - password.charCodeAt(k - 1);
  1495. if (lastDelta == null) {
  1496. lastDelta = delta;
  1497. }
  1498. if (delta !== lastDelta) {
  1499. const j = k - 1;
  1500. this.update({
  1501. i,
  1502. j,
  1503. delta: lastDelta,
  1504. password,
  1505. result
  1506. });
  1507. i = j;
  1508. lastDelta = delta;
  1509. }
  1510. }
  1511. this.update({
  1512. i,
  1513. j: passwordLength - 1,
  1514. delta: lastDelta,
  1515. password,
  1516. result
  1517. });
  1518. return result;
  1519. }
  1520. update({
  1521. i,
  1522. j,
  1523. delta,
  1524. password,
  1525. result
  1526. }) {
  1527. if (j - i > 1 || Math.abs(delta) === 1) {
  1528. const absoluteDelta = Math.abs(delta);
  1529. if (absoluteDelta > 0 && absoluteDelta <= this.MAX_DELTA) {
  1530. const token = password.slice(i, +j + 1 || 9e9);
  1531. const {
  1532. sequenceName,
  1533. sequenceSpace
  1534. } = this.getSequence(token);
  1535. return result.push({
  1536. pattern: "sequence",
  1537. i,
  1538. j,
  1539. token: password.slice(i, +j + 1 || 9e9),
  1540. sequenceName,
  1541. sequenceSpace,
  1542. ascending: delta > 0
  1543. });
  1544. }
  1545. }
  1546. return null;
  1547. }
  1548. getSequence(token) {
  1549. let sequenceName = "unicode";
  1550. let sequenceSpace = 26;
  1551. if (ALL_LOWER.test(token)) {
  1552. sequenceName = "lower";
  1553. sequenceSpace = 26;
  1554. } else if (ALL_UPPER.test(token)) {
  1555. sequenceName = "upper";
  1556. sequenceSpace = 26;
  1557. } else if (ALL_DIGIT.test(token)) {
  1558. sequenceName = "digits";
  1559. sequenceSpace = 10;
  1560. }
  1561. return {
  1562. sequenceName,
  1563. sequenceSpace
  1564. };
  1565. }
  1566. };
  1567. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/spatial/matching.esm.js
  1568. var MatchSpatial = class {
  1569. constructor() {
  1570. this.SHIFTED_RX = /[~!@#$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:"ZXCVBNM<>?]/;
  1571. }
  1572. match({
  1573. password
  1574. }) {
  1575. const matches = [];
  1576. Object.keys(zxcvbnOptions.graphs).forEach((graphName) => {
  1577. const graph = zxcvbnOptions.graphs[graphName];
  1578. extend(matches, this.helper(password, graph, graphName));
  1579. });
  1580. return sorted(matches);
  1581. }
  1582. checkIfShifted(graphName, password, index) {
  1583. if (!graphName.includes("keypad") && // initial character is shifted
  1584. this.SHIFTED_RX.test(password.charAt(index))) {
  1585. return 1;
  1586. }
  1587. return 0;
  1588. }
  1589. // eslint-disable-next-line complexity, max-statements
  1590. helper(password, graph, graphName) {
  1591. let shiftedCount;
  1592. const matches = [];
  1593. let i = 0;
  1594. const passwordLength = password.length;
  1595. while (i < passwordLength - 1) {
  1596. let j = i + 1;
  1597. let lastDirection = 0;
  1598. let turns = 0;
  1599. shiftedCount = this.checkIfShifted(graphName, password, i);
  1600. while (true) {
  1601. const prevChar = password.charAt(j - 1);
  1602. const adjacents = graph[prevChar] || [];
  1603. let found = false;
  1604. let foundDirection = -1;
  1605. let curDirection = -1;
  1606. if (j < passwordLength) {
  1607. const curChar = password.charAt(j);
  1608. const adjacentsLength = adjacents.length;
  1609. for (let k = 0; k < adjacentsLength; k += 1) {
  1610. const adjacent = adjacents[k];
  1611. curDirection += 1;
  1612. if (adjacent) {
  1613. const adjacentIndex = adjacent.indexOf(curChar);
  1614. if (adjacentIndex !== -1) {
  1615. found = true;
  1616. foundDirection = curDirection;
  1617. if (adjacentIndex === 1) {
  1618. shiftedCount += 1;
  1619. }
  1620. if (lastDirection !== foundDirection) {
  1621. turns += 1;
  1622. lastDirection = foundDirection;
  1623. }
  1624. break;
  1625. }
  1626. }
  1627. }
  1628. }
  1629. if (found) {
  1630. j += 1;
  1631. } else {
  1632. if (j - i > 2) {
  1633. matches.push({
  1634. pattern: "spatial",
  1635. i,
  1636. j: j - 1,
  1637. token: password.slice(i, j),
  1638. graph: graphName,
  1639. turns,
  1640. shiftedCount
  1641. });
  1642. }
  1643. i = j;
  1644. break;
  1645. }
  1646. }
  1647. }
  1648. return matches;
  1649. }
  1650. };
  1651. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/Matching.esm.js
  1652. var Matching = class {
  1653. constructor() {
  1654. this.matchers = {
  1655. date: MatchDate,
  1656. dictionary: MatchDictionary,
  1657. regex: MatchRegex,
  1658. // @ts-ignore => TODO resolve this type issue. This is because it is possible to be async
  1659. repeat: MatchRepeat,
  1660. sequence: MatchSequence,
  1661. spatial: MatchSpatial
  1662. };
  1663. }
  1664. match(password) {
  1665. const matches = [];
  1666. const promises = [];
  1667. const matchers2 = [...Object.keys(this.matchers), ...Object.keys(zxcvbnOptions.matchers)];
  1668. matchers2.forEach((key) => {
  1669. if (!this.matchers[key] && !zxcvbnOptions.matchers[key]) {
  1670. return;
  1671. }
  1672. const Matcher = this.matchers[key] ? this.matchers[key] : zxcvbnOptions.matchers[key].Matching;
  1673. const usedMatcher = new Matcher();
  1674. const result = usedMatcher.match({
  1675. password,
  1676. omniMatch: this
  1677. });
  1678. if (result instanceof Promise) {
  1679. result.then((response) => {
  1680. extend(matches, response);
  1681. });
  1682. promises.push(result);
  1683. } else {
  1684. extend(matches, result);
  1685. }
  1686. });
  1687. if (promises.length > 0) {
  1688. return new Promise((resolve) => {
  1689. Promise.all(promises).then(() => {
  1690. resolve(sorted(matches));
  1691. });
  1692. });
  1693. }
  1694. return sorted(matches);
  1695. }
  1696. };
  1697. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/TimeEstimates.esm.js
  1698. var SECOND = 1;
  1699. var MINUTE = SECOND * 60;
  1700. var HOUR = MINUTE * 60;
  1701. var DAY = HOUR * 24;
  1702. var MONTH = DAY * 31;
  1703. var YEAR = MONTH * 12;
  1704. var CENTURY = YEAR * 100;
  1705. var times = {
  1706. second: SECOND,
  1707. minute: MINUTE,
  1708. hour: HOUR,
  1709. day: DAY,
  1710. month: MONTH,
  1711. year: YEAR,
  1712. century: CENTURY
  1713. };
  1714. var TimeEstimates = class {
  1715. translate(displayStr, value) {
  1716. let key = displayStr;
  1717. if (value !== void 0 && value !== 1) {
  1718. key += "s";
  1719. }
  1720. const {
  1721. timeEstimation
  1722. } = zxcvbnOptions.translations;
  1723. return timeEstimation[key].replace("{base}", `${value}`);
  1724. }
  1725. estimateAttackTimes(guesses) {
  1726. const crackTimesSeconds = {
  1727. onlineThrottling100PerHour: guesses / (100 / 3600),
  1728. onlineNoThrottling10PerSecond: guesses / 10,
  1729. offlineSlowHashing1e4PerSecond: guesses / 1e4,
  1730. offlineFastHashing1e10PerSecond: guesses / 1e10
  1731. };
  1732. const crackTimesDisplay = {
  1733. onlineThrottling100PerHour: "",
  1734. onlineNoThrottling10PerSecond: "",
  1735. offlineSlowHashing1e4PerSecond: "",
  1736. offlineFastHashing1e10PerSecond: ""
  1737. };
  1738. Object.keys(crackTimesSeconds).forEach((scenario) => {
  1739. const seconds = crackTimesSeconds[scenario];
  1740. crackTimesDisplay[scenario] = this.displayTime(seconds);
  1741. });
  1742. return {
  1743. crackTimesSeconds,
  1744. crackTimesDisplay,
  1745. score: this.guessesToScore(guesses)
  1746. };
  1747. }
  1748. guessesToScore(guesses) {
  1749. const DELTA = 5;
  1750. if (guesses < 1e3 + DELTA) {
  1751. return 0;
  1752. }
  1753. if (guesses < 1e6 + DELTA) {
  1754. return 1;
  1755. }
  1756. if (guesses < 1e8 + DELTA) {
  1757. return 2;
  1758. }
  1759. if (guesses < 1e10 + DELTA) {
  1760. return 3;
  1761. }
  1762. return 4;
  1763. }
  1764. displayTime(seconds) {
  1765. let displayStr = "centuries";
  1766. let base;
  1767. const timeKeys = Object.keys(times);
  1768. const foundIndex = timeKeys.findIndex((time2) => seconds < times[time2]);
  1769. if (foundIndex > -1) {
  1770. displayStr = timeKeys[foundIndex - 1];
  1771. if (foundIndex !== 0) {
  1772. base = Math.round(seconds / times[displayStr]);
  1773. } else {
  1774. displayStr = "ltSecond";
  1775. }
  1776. }
  1777. return this.translate(displayStr, base);
  1778. }
  1779. };
  1780. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/bruteforce/feedback.esm.js
  1781. var bruteforceMatcher2 = () => {
  1782. return null;
  1783. };
  1784. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/date/feedback.esm.js
  1785. var dateMatcher2 = () => {
  1786. return {
  1787. warning: zxcvbnOptions.translations.warnings.dates,
  1788. suggestions: [zxcvbnOptions.translations.suggestions.dates]
  1789. };
  1790. };
  1791. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/dictionary/feedback.esm.js
  1792. var getDictionaryWarningPassword = (match, isSoleMatch) => {
  1793. let warning = "";
  1794. if (isSoleMatch && !match.l33t && !match.reversed) {
  1795. if (match.rank <= 10) {
  1796. warning = zxcvbnOptions.translations.warnings.topTen;
  1797. } else if (match.rank <= 100) {
  1798. warning = zxcvbnOptions.translations.warnings.topHundred;
  1799. } else {
  1800. warning = zxcvbnOptions.translations.warnings.common;
  1801. }
  1802. } else if (match.guessesLog10 <= 4) {
  1803. warning = zxcvbnOptions.translations.warnings.similarToCommon;
  1804. }
  1805. return warning;
  1806. };
  1807. var getDictionaryWarningWikipedia = (match, isSoleMatch) => {
  1808. let warning = "";
  1809. if (isSoleMatch) {
  1810. warning = zxcvbnOptions.translations.warnings.wordByItself;
  1811. }
  1812. return warning;
  1813. };
  1814. var getDictionaryWarningNames = (match, isSoleMatch) => {
  1815. if (isSoleMatch) {
  1816. return zxcvbnOptions.translations.warnings.namesByThemselves;
  1817. }
  1818. return zxcvbnOptions.translations.warnings.commonNames;
  1819. };
  1820. var getDictionaryWarning = (match, isSoleMatch) => {
  1821. let warning = "";
  1822. const dictName = match.dictionaryName;
  1823. const isAName = dictName === "lastnames" || dictName.toLowerCase().includes("firstnames");
  1824. if (dictName === "passwords") {
  1825. warning = getDictionaryWarningPassword(match, isSoleMatch);
  1826. } else if (dictName.includes("wikipedia")) {
  1827. warning = getDictionaryWarningWikipedia(match, isSoleMatch);
  1828. } else if (isAName) {
  1829. warning = getDictionaryWarningNames(match, isSoleMatch);
  1830. } else if (dictName === "userInputs") {
  1831. warning = zxcvbnOptions.translations.warnings.userInputs;
  1832. }
  1833. return warning;
  1834. };
  1835. var dictionaryMatcher2 = (match, isSoleMatch) => {
  1836. const warning = getDictionaryWarning(match, isSoleMatch);
  1837. const suggestions = [];
  1838. const word = match.token;
  1839. if (word.match(START_UPPER)) {
  1840. suggestions.push(zxcvbnOptions.translations.suggestions.capitalization);
  1841. } else if (word.match(ALL_UPPER_INVERTED) && word.toLowerCase() !== word) {
  1842. suggestions.push(zxcvbnOptions.translations.suggestions.allUppercase);
  1843. }
  1844. if (match.reversed && match.token.length >= 4) {
  1845. suggestions.push(zxcvbnOptions.translations.suggestions.reverseWords);
  1846. }
  1847. if (match.l33t) {
  1848. suggestions.push(zxcvbnOptions.translations.suggestions.l33t);
  1849. }
  1850. return {
  1851. warning,
  1852. suggestions
  1853. };
  1854. };
  1855. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/regex/feedback.esm.js
  1856. var regexMatcher2 = (match) => {
  1857. if (match.regexName === "recentYear") {
  1858. return {
  1859. warning: zxcvbnOptions.translations.warnings.recentYears,
  1860. suggestions: [zxcvbnOptions.translations.suggestions.recentYears, zxcvbnOptions.translations.suggestions.associatedYears]
  1861. };
  1862. }
  1863. return {
  1864. warning: "",
  1865. suggestions: []
  1866. };
  1867. };
  1868. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/repeat/feedback.esm.js
  1869. var repeatMatcher2 = (match) => {
  1870. let warning = zxcvbnOptions.translations.warnings.extendedRepeat;
  1871. if (match.baseToken.length === 1) {
  1872. warning = zxcvbnOptions.translations.warnings.simpleRepeat;
  1873. }
  1874. return {
  1875. warning,
  1876. suggestions: [zxcvbnOptions.translations.suggestions.repeated]
  1877. };
  1878. };
  1879. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/sequence/feedback.esm.js
  1880. var sequenceMatcher2 = () => {
  1881. return {
  1882. warning: zxcvbnOptions.translations.warnings.sequences,
  1883. suggestions: [zxcvbnOptions.translations.suggestions.sequences]
  1884. };
  1885. };
  1886. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/matcher/spatial/feedback.esm.js
  1887. var spatialMatcher2 = (match) => {
  1888. let warning = zxcvbnOptions.translations.warnings.keyPattern;
  1889. if (match.turns === 1) {
  1890. warning = zxcvbnOptions.translations.warnings.straightRow;
  1891. }
  1892. return {
  1893. warning,
  1894. suggestions: [zxcvbnOptions.translations.suggestions.longerKeyboardPattern]
  1895. };
  1896. };
  1897. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/Feedback.esm.js
  1898. var defaultFeedback = {
  1899. warning: "",
  1900. suggestions: []
  1901. };
  1902. var Feedback = class {
  1903. constructor() {
  1904. this.matchers = {
  1905. bruteforce: bruteforceMatcher2,
  1906. date: dateMatcher2,
  1907. dictionary: dictionaryMatcher2,
  1908. regex: regexMatcher2,
  1909. repeat: repeatMatcher2,
  1910. sequence: sequenceMatcher2,
  1911. spatial: spatialMatcher2
  1912. };
  1913. this.defaultFeedback = {
  1914. warning: "",
  1915. suggestions: []
  1916. };
  1917. this.setDefaultSuggestions();
  1918. }
  1919. setDefaultSuggestions() {
  1920. this.defaultFeedback.suggestions.push(zxcvbnOptions.translations.suggestions.useWords, zxcvbnOptions.translations.suggestions.noNeed);
  1921. }
  1922. getFeedback(score, sequence) {
  1923. if (sequence.length === 0) {
  1924. return this.defaultFeedback;
  1925. }
  1926. if (score > 2) {
  1927. return defaultFeedback;
  1928. }
  1929. const extraFeedback = zxcvbnOptions.translations.suggestions.anotherWord;
  1930. const longestMatch = this.getLongestMatch(sequence);
  1931. let feedback = this.getMatchFeedback(longestMatch, sequence.length === 1);
  1932. if (feedback !== null && feedback !== void 0) {
  1933. feedback.suggestions.unshift(extraFeedback);
  1934. if (feedback.warning == null) {
  1935. feedback.warning = "";
  1936. }
  1937. } else {
  1938. feedback = {
  1939. warning: "",
  1940. suggestions: [extraFeedback]
  1941. };
  1942. }
  1943. return feedback;
  1944. }
  1945. getLongestMatch(sequence) {
  1946. let longestMatch = sequence[0];
  1947. const slicedSequence = sequence.slice(1);
  1948. slicedSequence.forEach((match) => {
  1949. if (match.token.length > longestMatch.token.length) {
  1950. longestMatch = match;
  1951. }
  1952. });
  1953. return longestMatch;
  1954. }
  1955. getMatchFeedback(match, isSoleMatch) {
  1956. if (this.matchers[match.pattern]) {
  1957. return this.matchers[match.pattern](match, isSoleMatch);
  1958. }
  1959. if (zxcvbnOptions.matchers[match.pattern] && "feedback" in zxcvbnOptions.matchers[match.pattern]) {
  1960. return zxcvbnOptions.matchers[match.pattern].feedback(match, isSoleMatch);
  1961. }
  1962. return defaultFeedback;
  1963. }
  1964. };
  1965. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/debounce.esm.js
  1966. var debounce = (func, wait, isImmediate) => {
  1967. let timeout;
  1968. return function debounce2(...args) {
  1969. const context = this;
  1970. const later = () => {
  1971. timeout = void 0;
  1972. if (!isImmediate) {
  1973. func.apply(context, args);
  1974. }
  1975. };
  1976. const shouldCallNow = isImmediate && !timeout;
  1977. if (timeout !== void 0) {
  1978. clearTimeout(timeout);
  1979. }
  1980. timeout = setTimeout(later, wait);
  1981. if (shouldCallNow) {
  1982. return func.apply(context, args);
  1983. }
  1984. return void 0;
  1985. };
  1986. };
  1987. // node_modules/.pnpm/@zxcvbn-ts+core@2.2.1/node_modules/@zxcvbn-ts/core/dist/index.esm.js
  1988. var time = () => (/* @__PURE__ */ new Date()).getTime();
  1989. var createReturnValue = (resolvedMatches, password, start) => {
  1990. const feedback = new Feedback();
  1991. const timeEstimates = new TimeEstimates();
  1992. const matchSequence = scoring.mostGuessableMatchSequence(password, resolvedMatches);
  1993. const calcTime = time() - start;
  1994. const attackTimes = timeEstimates.estimateAttackTimes(matchSequence.guesses);
  1995. return {
  1996. calcTime,
  1997. ...matchSequence,
  1998. ...attackTimes,
  1999. feedback: feedback.getFeedback(attackTimes.score, matchSequence.sequence)
  2000. };
  2001. };
  2002. var main = (password, userInputs) => {
  2003. if (userInputs) {
  2004. zxcvbnOptions.extendUserInputsDictionary(userInputs);
  2005. }
  2006. const matching = new Matching();
  2007. return matching.match(password);
  2008. };
  2009. var zxcvbn = (password, userInputs) => {
  2010. const start = time();
  2011. const matches = main(password, userInputs);
  2012. if (matches instanceof Promise) {
  2013. throw new Error("You are using a Promised matcher, please use `zxcvbnAsync` for it.");
  2014. }
  2015. return createReturnValue(matches, password, start);
  2016. };
  2017. var zxcvbnAsync = async (password, userInputs) => {
  2018. const usedPassword = password.substring(0, zxcvbnOptions.maxLength);
  2019. const start = time();
  2020. const matches = await main(usedPassword, userInputs);
  2021. return createReturnValue(matches, usedPassword, start);
  2022. };
  2023. export {
  2024. Options,
  2025. debounce,
  2026. zxcvbn,
  2027. zxcvbnAsync,
  2028. zxcvbnOptions
  2029. };
  2030. //# sourceMappingURL=@zxcvbn-ts_core.js.map