@protontech/autofill 0.0.33835493 → 0.0.35481761

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.
Files changed (41) hide show
  1. package/features/feature.d.ts +13 -2
  2. package/features/feature.js +37 -17
  3. package/features/feature.spec.js +56 -3
  4. package/features/v1/abstract.field.d.ts +8377 -406
  5. package/features/v1/abstract.field.js +23 -23
  6. package/features/v1/abstract.form.d.ts +3428 -626
  7. package/features/v1/abstract.form.js +198 -199
  8. package/features/v1/field.email.d.ts +3421 -0
  9. package/features/v1/field.email.js +7 -7
  10. package/features/v1/field.otp.d.ts +71178 -0
  11. package/features/v1/field.otp.js +42 -42
  12. package/features/v1/field.password.d.ts +99166 -0
  13. package/features/v1/field.password.js +42 -42
  14. package/features/v1/field.username-hidden.d.ts +908 -0
  15. package/features/v1/field.username-hidden.js +7 -7
  16. package/features/v1/field.username.d.ts +42382 -0
  17. package/features/v1/field.username.js +11 -11
  18. package/features/v1/fields.sorted.gen.d.ts +1441 -0
  19. package/features/v1/fields.sorted.gen.js +344 -0
  20. package/features/v1/forms.sorted.gen.d.ts +734 -0
  21. package/features/v1/forms.sorted.gen.js +334 -0
  22. package/features/v1/index.d.ts +964 -84
  23. package/features/v1/index.js +9 -15
  24. package/features/v1/index.spec.js +34 -20
  25. package/models/perceptron/params/login-model.json +91 -91
  26. package/models/perceptron/params/new-password-model.json +21 -21
  27. package/models/perceptron/params/otp-model.json +29 -29
  28. package/models/perceptron/params/password-change-model.json +72 -72
  29. package/models/perceptron/params/password-model.json +23 -23
  30. package/models/perceptron/params/recovery-model.json +81 -81
  31. package/models/perceptron/params/register-model.json +99 -99
  32. package/models/perceptron/params/username-hidden-model.json +10 -10
  33. package/models/perceptron/params/username-model.json +7 -7
  34. package/models/random_forest/params/otp-model.json +306 -366
  35. package/package.json +3 -3
  36. package/rules/v1/index.js +2 -2
  37. package/scripts/gen-sorted-features.d.ts +1 -0
  38. package/scripts/gen-sorted-features.js +128 -0
  39. package/types/index.d.ts +2 -1
  40. package/utils/fathom.d.ts +1 -2
  41. package/utils/fathom.js +2 -2
@@ -1,5 +1,5 @@
1
1
  import { kAnchorLinkSelector, kButtonSelector, kCaptchaSelector, kFieldSelector, kLayoutSelector, kPasswordSelector, kSocialSelector } from "@protontech/autofill/constants/selectors";
2
- import { feature, featureCount, featureScaled, featuresProduct, flattenFeatures, getComputerForFeatures } from "@protontech/autofill/features/feature";
2
+ import { feature, featureCount, featureScaled, featuresProduct, flattenFeatures } from "@protontech/autofill/features/feature";
3
3
  import { getFormAttributes } from "@protontech/autofill/utils/attributes";
4
4
  import { any } from "@protontech/autofill/utils/combinators";
5
5
  import { getCCFieldType } from "@protontech/autofill/utils/credit-card";
@@ -12,119 +12,119 @@ import { getIdentityFieldType } from "@protontech/autofill/utils/identity";
12
12
  import { matchAuthenticator, matchLogin, matchMFA, matchMultiStep, matchNewsletter, matchOtpOutlier, matchOtpOutlierAction, matchPasswordConfirmAttr, matchPasswordCreateAttr, matchPasswordReset, matchPasswordResetAttr, matchRecovery, matchRegister, matchRememberMe, matchSearchAction, matchStepAction, matchTOS, matchTrouble, } from "@protontech/autofill/utils/re";
13
13
  import { sanitizeString } from "@protontech/autofill/utils/text";
14
14
  import { isVisibleEl, isVisibleField } from "@protontech/autofill/utils/visible";
15
- const form = feature("form", {}, (_, fnode) => fnode.element);
16
- const parent = feature("parent", { form }, (p) => getFormParent(p.form));
17
- const doc = feature("doc", { form }, (p) => p.form.ownerDocument);
18
- const __inputIterator = feature("__inputIterator", {}, (_, fnode) => createInputIterator(fnode.element));
19
- const fields = feature("fields", { form }, (p) => Array.from(p.form.querySelectorAll(kFieldSelector)));
20
- const visibleFields = feature("visibleFields", { fields }, (p) => p.fields.filter(isVisibleField));
21
- const inputs = feature("inputs", { fields }, (p) => p.fields.filter(isInputField));
22
- const hidden = feature("hidden", { inputs }, (p) => p.inputs.filter((el) => el.type === "hidden"));
23
- const visibleInputs = feature("visibleInputs", { visibleFields }, (p) => p.visibleFields.filter(isInputField));
24
- const fieldsets = feature("fieldsets", { form }, (p) => Array.from(p.form.querySelectorAll("fieldset")));
25
- const textareas = feature("textareas", { fields }, (p) => p.fields.filter(isTextarea));
26
- const selects = feature("selects", { fields }, (p) => p.fields.filter((el, i, arr) => { var _a; return isSelect(el) && ((_a = arr === null || arr === void 0 ? void 0 : arr[i + 1]) === null || _a === void 0 ? void 0 : _a.type) !== "tel"; }));
27
- const texts = feature("texts", { inputs }, (p) => p.inputs.filter((el) => el.type === "text"));
28
- const tels = feature("tels", { inputs }, (p) => p.inputs.filter((el) => el.type === "tel"));
29
- const readOnly = feature("readOnly", { inputs }, (p) => p.inputs.filter((el) => el.readOnly));
30
- const radios = feature("radios", { inputs }, (p) => p.inputs.filter((el) => el.type === "radio"));
31
- const checkboxes = feature("checkboxes", { inputs }, (p) => p.inputs.filter((el) => el.type === "checkbox"));
32
- const numbers = feature("numbers", { inputs }, (p) => p.inputs.filter((el) => el.type === "number"));
33
- const dates = feature("dates", { inputs }, (p) => p.inputs.filter((el) => el.type === "date"));
34
- const files = feature("files", { inputs }, (p) => p.inputs.filter((el) => el.type === "file"));
35
- const ccInputs = feature("ccInputs", { inputs }, (p) => p.inputs.filter(getCCFieldType));
36
- const ccSelects = feature("ccSelects", { selects }, (p) => p.selects.filter(getCCFieldType));
37
- const ccs = feature("ccs", { ccInputs, ccSelects }, (p) => p.ccInputs.concat(p.ccSelects));
38
- const identities = feature("identities", { inputs, ccs }, (p) => p.inputs.filter((el) => getIdentityFieldType(el) !== undefined));
39
- const required = feature("required", { visibleInputs }, (p) => p.visibleInputs.filter((el) => el.required || el.ariaRequired));
40
- const disabled = feature("disabled", { visibleInputs }, (p) => p.visibleInputs.filter((el) => el.disabled || el.ariaDisabled));
41
- const autofocused = feature("autofocused", { visibleInputs }, (p) => p.visibleInputs.find((el) => el.matches("input[autofocus]:first-of-type")));
42
- const usernames = feature("usernames", { inputs }, (p) => p.inputs.filter(isUsernameCandidate));
43
- const emails = feature("emails", { inputs }, (p) => p.inputs.filter(isEmailCandidate));
44
- const identifiers = feature("identifiers", { usernames, emails }, (p) => uniqueNodes(p.usernames, p.emails));
45
- const identifiersByVisibility = feature("identifiersByVisibility", { identifiers }, (p) => splitFieldsByVisibility(p.identifiers));
46
- const visibleIdentifiers = feature("visibleIdentifiers", { identifiersByVisibility }, (p) => p.identifiersByVisibility[0]);
47
- const hiddenIdentifiers = feature("hiddenIdentifiers", { identifiersByVisibility }, (p) => p.identifiersByVisibility[1]);
48
- const passwords = feature("passwords", { inputs }, (p) => p.inputs.filter((el) => el.matches(kPasswordSelector)));
49
- const passwordsByVisibility = feature("passwordsByVisibility", { passwords }, (p) => splitFieldsByVisibility(p.passwords));
50
- const visiblePasswords = feature("visiblePasswords", { passwordsByVisibility }, (p) => p.passwordsByVisibility[0]);
51
- const hiddenPasswords = feature("hiddenPasswords", { passwordsByVisibility }, (p) => p.passwordsByVisibility[1]);
52
- const mfaInputs = feature("mfaInputs", { inputs }, (p) => p.inputs.filter(isMFACandidate));
53
- const captchas = feature("captchas", { parent }, (p) => Array.from(p.parent.querySelectorAll(kCaptchaSelector)));
54
- const socials = feature("socials", { parent }, (p) => Array.from(p.parent.querySelectorAll(kSocialSelector)));
55
- const submits = feature("submits", { visibleFields }, (p) => p.visibleFields.filter((el) => (el === null || el === void 0 ? void 0 : el.type) === "submit"));
56
- const btns = feature("btns", { form }, (p) => Array.from(p.form.querySelectorAll(kButtonSelector)).filter(isVisibleEl));
57
- const btnsTypeSubmit = feature("btnsTypeSubmit", { btns }, (p) => p.btns.filter((el) => el.matches('[type="submit"]')));
58
- const candidateBtns = feature("candidateBtns", { btns }, (p) => p.btns.filter(isBtnCandidate));
59
- const submitBtns = feature("submitBtns", { btns, btnsTypeSubmit, candidateBtns }, (p) => (p.btnsTypeSubmit.length > 0 ? p.btnsTypeSubmit : p.candidateBtns));
60
- const anchors = feature("anchors", { form }, (p) => Array.from(p.form.querySelectorAll(kAnchorLinkSelector)).filter(isVisibleEl));
61
- const oauths = feature("oauths", { socials, candidateBtns }, (p) => p.socials.concat(p.candidateBtns).filter(isOAuthCandidate));
62
- const layouts = feature("layouts", { form }, (p) => Array.from(p.form.querySelectorAll(kLayoutSelector)));
63
- const autofocusedIsIdentifier = feature("autofocusedIsIdentifier", { autofocused, visibleIdentifiers }, (p) => Boolean(p.autofocused && p.visibleIdentifiers.includes(p.autofocused)));
64
- const autofocusedIsPassword = feature("autofocusedIsPassword", { autofocused, visiblePasswords }, (p) => Boolean(p.autofocused && p.visiblePasswords.includes(p.autofocused)));
65
- const pageDescriptionText = feature("pageDescriptionText", { doc }, (p) => getPageDescriptionText(p.doc));
66
- const nearestHeadingsText = feature("nearestHeadingsText", { form }, (p) => getNearestHeadingsText(p.form));
67
- const formTextAttrText = feature("formTextAttrText", { form }, (p) => getFormText(p.form));
68
- const formAttributes = feature("formAttributes", { form }, (p) => getFormAttributes(p.form));
69
- const pwHaystack = feature("pwHaystack", { passwords }, (p) => p.passwords.flatMap(getAllFieldHaystacks));
70
- const identifierHaystack = feature("identifierHaystack", { visibleIdentifiers }, (p) => p.visibleIdentifiers.flatMap(getAllFieldHaystacks));
71
- const btnHaystack = feature("btnHaystack", { candidateBtns }, (p) => p.candidateBtns.flatMap(getAllFieldHaystacks));
72
- const submitBtnHaystack = feature("submitBtnHaystack", { submitBtns }, (p) => p.submitBtns.flatMap(getAllFieldHaystacks));
73
- const checkboxesHaystack = feature("checkboxesHaystack", { checkboxes }, (p) => p.checkboxes.flatMap(getAllFieldHaystacks));
74
- const anchorsHaystack = feature("anchorsHaystack", { anchors }, (p) => p.anchors.flatMap(getAllNodeHaystacks));
75
- const mfaInputsHaystack = feature("mfaInputsHaystack", { mfaInputs }, (p) => p.mfaInputs.flatMap(getAllFieldHaystacks));
76
- const layoutHaystack = feature("layoutHaystack", { layouts }, (p) => p.layouts.map(getNodeAttributes));
77
- const formTextHaystack = feature("formTextHaystack", { formTextAttrText, nearestHeadingsText }, (p) => [p.formTextAttrText, p.nearestHeadingsText]);
78
- const pageLogin = feature("pageLogin", { pageDescriptionText }, (p) => matchLogin(p.pageDescriptionText));
79
- const formTextLogin = feature("formTextLogin", { formTextAttrText }, (p) => matchLogin(p.formTextAttrText));
80
- const formAttrsLogin = feature("formAttrsLogin", { formAttributes }, (p) => any(matchLogin)(p.formAttributes));
81
- const headingsLogin = feature("headingsLogin", { nearestHeadingsText }, (p) => matchLogin(p.nearestHeadingsText));
82
- const layoutLogin = feature("layoutLogin", { layoutHaystack }, (p) => any(matchLogin)(p.layoutHaystack));
83
- const rememberMeCheckbox = feature("rememberMeCheckbox", { checkboxesHaystack }, (p) => any(matchRememberMe)(p.checkboxesHaystack));
84
- const submitLogin = feature("submitLogin", { submitBtnHaystack }, (p) => any(matchLogin)(p.submitBtnHaystack));
85
- const troubleLink = feature("troubleLink", { anchorsHaystack }, (p) => any(matchTrouble)(p.anchorsHaystack));
86
- const pageRegister = feature("pageRegister", { pageDescriptionText }, (p) => matchRegister(p.pageDescriptionText));
87
- const formTextRegister = feature("formTextRegister", { formTextAttrText }, (p) => matchRegister(p.formTextAttrText));
88
- const formAttrsRegister = feature("formAttrsRegister", { formAttributes }, (p) => any(matchRegister)(p.formAttributes));
89
- const headingsRegister = feature("headingsRegister", { nearestHeadingsText }, (p) => matchRegister(p.nearestHeadingsText));
90
- const layoutRegister = feature("layoutRegister", { layoutHaystack }, (p) => any(matchRegister)(p.layoutHaystack));
91
- const TOSRef = feature("TOSRef", { checkboxesHaystack, anchorsHaystack }, (p) => any(matchTOS)(p.checkboxesHaystack.concat(p.anchorsHaystack)));
92
- const submitRegister = feature("submitRegister", { submitBtnHaystack }, (p) => any(matchRegister)(p.submitBtnHaystack));
93
- const pwNewRegister = feature("pwNewRegister", { pwHaystack }, (p) => any(matchPasswordCreateAttr)(p.pwHaystack));
94
- const pwConfirmRegister = feature("pwConfirmRegister", { pwHaystack }, (p) => any(matchPasswordConfirmAttr)(p.pwHaystack));
95
- const buttonMultistep = feature("buttonMultistep", { submitBtnHaystack }, (p) => any(matchStepAction)(p.submitBtnHaystack));
96
- const headingsMultistep = feature("headingsMultistep", { nearestHeadingsText }, (p) => matchMultiStep(p.nearestHeadingsText));
97
- const multistepForm = feature("multistepForm", { buttonMultistep, headingsMultistep }, (p) => p.buttonMultistep || p.headingsMultistep);
98
- const pageMultiAuth = feature("pageMultiAuth", { pageLogin, pageRegister }, (p) => p.pageLogin && p.pageRegister);
99
- const submitMultiAuth = feature("submitMultiAuth", { submitRegister, submitLogin, buttonMultistep }, (p) => p.submitRegister && (p.submitLogin || p.buttonMultistep));
100
- const headingsMultiAuth = feature("headingsMultiAuth", { headingsLogin, headingsRegister }, (p) => p.headingsLogin && p.headingsRegister);
101
- const multiAuthForm = feature("multiAuthForm", { pageMultiAuth, headingsMultiAuth, submitMultiAuth }, (p) => p.pageMultiAuth || p.headingsMultiAuth || p.submitMultiAuth);
102
- const pagePwReset = feature("pagePwReset", { pageDescriptionText }, (p) => matchPasswordReset(p.pageDescriptionText));
103
- const formTextPwReset = feature("formTextPwReset", { formTextAttrText }, (p) => matchPasswordReset(p.formTextAttrText));
104
- const formAttrsPwReset = feature("formAttrsPwReset", { formAttributes }, (p) => any(matchPasswordResetAttr)(p.formAttributes));
105
- const headingsPwReset = feature("headingsPwReset", { nearestHeadingsText }, (p) => matchPasswordReset(p.nearestHeadingsText));
106
- const layoutPwReset = feature("layoutPwReset", { layoutHaystack }, (p) => any(matchPasswordResetAttr)(p.layoutHaystack));
107
- const pageRecovery = feature("pageRecovery", { pageDescriptionText }, (p) => matchRecovery(p.pageDescriptionText));
108
- const formTextRecovery = feature("formTextRecovery", { formTextAttrText }, (p) => matchRecovery(p.formTextAttrText));
109
- const formAttrsRecovery = feature("formAttrsRecovery", { formAttributes }, (p) => any(matchRecovery)(p.formAttributes));
110
- const headingsRecovery = feature("headingsRecovery", { nearestHeadingsText }, (p) => matchRecovery(p.nearestHeadingsText));
111
- const layoutRecovery = feature("layoutRecovery", { layoutHaystack }, (p) => any(matchRecovery)(p.layoutHaystack));
112
- const submitRecovery = feature("submitRecovery", { submitBtnHaystack }, (p) => any(matchRecovery)(p.submitBtnHaystack));
113
- const identifierRecovery = feature("identifierRecovery", { identifierHaystack }, (p) => any(matchRecovery)(p.identifierHaystack));
114
- const inputsMFA = feature("inputsMFA", { mfaInputs, mfaInputsHaystack }, (p) => p.mfaInputs.some(({ autocomplete }) => autocomplete.includes("one-time-code")) || any(matchMFA)(p.mfaInputsHaystack));
115
- const formAttrsMFA = feature("formAttrsMFA", { formAttributes }, (p) => any(matchMFA)(p.formAttributes));
116
- const formTextMFA = feature("formTextMFA", { formTextHaystack }, (p) => any(matchMFA)(p.formTextHaystack));
117
- const maybeMFA = feature("maybeMFA", { formTextMFA, formAttrsMFA, inputsMFA }, (p) => p.inputsMFA || p.formAttrsMFA || p.formTextMFA);
118
- const haystackMFA = feature("haystackMFA", { formTextHaystack, maybeMFA, form }, (p) => [...p.formTextHaystack, maybeMFA ? sanitizeString(p.form.innerText) : ""]);
119
- const __formTextAuthenticator = feature("__formTextAuthenticator", { haystackMFA }, (p) => any(matchAuthenticator)(p.haystackMFA));
120
- const __headingsOTPOutlier = feature("__headingsOTPOutlier", { nearestHeadingsText }, (p) => matchOtpOutlier(p.nearestHeadingsText));
121
- const __formOTPOutlier = feature("__formOTPOutlier", { formAttributes }, (p) => any(matchOtpOutlier)(p.formAttributes));
122
- const __linkOTPOutlier = feature("__linkOTPOutlier", { anchorsHaystack, btnHaystack }, (p) => any(matchOtpOutlierAction)(p.anchorsHaystack.concat(p.btnHaystack)));
123
- const __formMFA = feature("__formMFA", { formTextMFA, formAttrsMFA }, (p) => p.formAttrsMFA || p.formAttrsMFA);
124
- const __formInputMFACandidates = feature("__formInputMFACandidates", { visibleInputs }, (p) => p.visibleInputs.filter(isMFACandidate).length);
125
- const newsletterForm = feature("newsletterForm", { formTextHaystack }, (p) => any(matchNewsletter)(p.formTextHaystack));
126
- const searchForm = feature("searchForm", { formTextHaystack }, (p) => any(matchSearchAction)(p.formTextHaystack));
127
- const formComplexity = featureScaled(feature("formComplexity", { form, fields, visibleFields, hidden, anchors, candidateBtns }, (p) => getFormComplexity(p.form, {
15
+ export const form = feature("form", {}, (_, fnode) => fnode.element);
16
+ export const parent = feature("parent", { form }, (p) => getFormParent(p.form));
17
+ export const doc = feature("doc", { form }, (p) => p.form.ownerDocument);
18
+ export const inputIterator = feature("inputIterator", {}, (_, fnode) => createInputIterator(fnode.element), { private: true });
19
+ export const fields = feature("fields", { form }, (p) => Array.from(p.form.querySelectorAll(kFieldSelector)));
20
+ export const visibleFields = feature("visibleFields", { fields }, (p) => p.fields.filter(isVisibleField));
21
+ export const inputs = feature("inputs", { fields }, (p) => p.fields.filter(isInputField));
22
+ export const hidden = feature("hidden", { inputs }, (p) => p.inputs.filter((el) => el.type === "hidden"));
23
+ export const visibleInputs = feature("visibleInputs", { visibleFields }, (p) => p.visibleFields.filter(isInputField));
24
+ export const fieldsets = feature("fieldsets", { form }, (p) => Array.from(p.form.querySelectorAll("fieldset")));
25
+ export const textareas = feature("textareas", { fields }, (p) => p.fields.filter(isTextarea));
26
+ export const selects = feature("selects", { fields }, (p) => p.fields.filter((el, i, arr) => { var _a; return isSelect(el) && ((_a = arr === null || arr === void 0 ? void 0 : arr[i + 1]) === null || _a === void 0 ? void 0 : _a.type) !== "tel"; }));
27
+ export const texts = feature("texts", { inputs }, (p) => p.inputs.filter((el) => el.type === "text"));
28
+ export const tels = feature("tels", { inputs }, (p) => p.inputs.filter((el) => el.type === "tel"));
29
+ export const readOnly = feature("readOnly", { inputs }, (p) => p.inputs.filter((el) => el.readOnly));
30
+ export const radios = feature("radios", { inputs }, (p) => p.inputs.filter((el) => el.type === "radio"));
31
+ export const checkboxes = feature("checkboxes", { inputs }, (p) => p.inputs.filter((el) => el.type === "checkbox"));
32
+ export const numbers = feature("numbers", { inputs }, (p) => p.inputs.filter((el) => el.type === "number"));
33
+ export const dates = feature("dates", { inputs }, (p) => p.inputs.filter((el) => el.type === "date"));
34
+ export const files = feature("files", { inputs }, (p) => p.inputs.filter((el) => el.type === "file"));
35
+ export const ccInputs = feature("ccInputs", { inputs }, (p) => p.inputs.filter(getCCFieldType));
36
+ export const ccSelects = feature("ccSelects", { selects }, (p) => p.selects.filter(getCCFieldType));
37
+ export const ccs = feature("ccs", { ccInputs, ccSelects }, (p) => p.ccInputs.concat(p.ccSelects));
38
+ export const identities = feature("identities", { inputs, ccs }, (p) => p.inputs.filter((el) => getIdentityFieldType(el) !== undefined));
39
+ export const required = feature("required", { visibleInputs }, (p) => p.visibleInputs.filter((el) => el.required || el.ariaRequired));
40
+ export const disabled = feature("disabled", { visibleInputs }, (p) => p.visibleInputs.filter((el) => el.disabled || el.ariaDisabled));
41
+ export const autofocused = feature("autofocused", { visibleInputs }, (p) => p.visibleInputs.find((el) => el.matches("input[autofocus]:first-of-type")));
42
+ export const usernames = feature("usernames", { inputs }, (p) => p.inputs.filter(isUsernameCandidate));
43
+ export const emails = feature("emails", { inputs }, (p) => p.inputs.filter(isEmailCandidate));
44
+ export const identifiers = feature("identifiers", { usernames, emails }, (p) => uniqueNodes(p.usernames, p.emails));
45
+ export const identifiersByVisibility = feature("identifiersByVisibility", { identifiers }, (p) => splitFieldsByVisibility(p.identifiers));
46
+ export const visibleIdentifiers = feature("visibleIdentifiers", { identifiersByVisibility }, (p) => p.identifiersByVisibility[0]);
47
+ export const hiddenIdentifiers = feature("hiddenIdentifiers", { identifiersByVisibility }, (p) => p.identifiersByVisibility[1]);
48
+ export const passwords = feature("passwords", { inputs }, (p) => p.inputs.filter((el) => el.matches(kPasswordSelector)));
49
+ export const passwordsByVisibility = feature("passwordsByVisibility", { passwords }, (p) => splitFieldsByVisibility(p.passwords));
50
+ export const visiblePasswords = feature("visiblePasswords", { passwordsByVisibility }, (p) => p.passwordsByVisibility[0]);
51
+ export const hiddenPasswords = feature("hiddenPasswords", { passwordsByVisibility }, (p) => p.passwordsByVisibility[1]);
52
+ export const mfaInputs = feature("mfaInputs", { inputs }, (p) => p.inputs.filter(isMFACandidate));
53
+ export const captchas = feature("captchas", { parent }, (p) => Array.from(p.parent.querySelectorAll(kCaptchaSelector)));
54
+ export const socials = feature("socials", { parent }, (p) => Array.from(p.parent.querySelectorAll(kSocialSelector)));
55
+ export const submits = feature("submits", { visibleFields }, (p) => p.visibleFields.filter((el) => (el === null || el === void 0 ? void 0 : el.type) === "submit"));
56
+ export const btns = feature("btns", { form }, (p) => Array.from(p.form.querySelectorAll(kButtonSelector)).filter(isVisibleEl));
57
+ export const btnsTypeSubmit = feature("btnsTypeSubmit", { btns }, (p) => p.btns.filter((el) => el.matches('[type="submit"]')));
58
+ export const candidateBtns = feature("candidateBtns", { btns }, (p) => p.btns.filter(isBtnCandidate));
59
+ export const submitBtns = feature("submitBtns", { btns, btnsTypeSubmit, candidateBtns }, (p) => (p.btnsTypeSubmit.length > 0 ? p.btnsTypeSubmit : p.candidateBtns));
60
+ export const anchors = feature("anchors", { form }, (p) => Array.from(p.form.querySelectorAll(kAnchorLinkSelector)).filter(isVisibleEl));
61
+ export const oauths = feature("oauths", { socials, candidateBtns }, (p) => p.socials.concat(p.candidateBtns).filter(isOAuthCandidate));
62
+ export const layouts = feature("layouts", { form }, (p) => Array.from(p.form.querySelectorAll(kLayoutSelector)));
63
+ export const autofocusedIsIdentifier = feature("autofocusedIsIdentifier", { autofocused, visibleIdentifiers }, (p) => Boolean(p.autofocused && p.visibleIdentifiers.includes(p.autofocused)));
64
+ export const autofocusedIsPassword = feature("autofocusedIsPassword", { autofocused, visiblePasswords }, (p) => Boolean(p.autofocused && p.visiblePasswords.includes(p.autofocused)));
65
+ export const pageDescriptionText = feature("pageDescriptionText", { doc }, (p) => getPageDescriptionText(p.doc));
66
+ export const nearestHeadingsText = feature("nearestHeadingsText", { form }, (p) => getNearestHeadingsText(p.form));
67
+ export const formTextAttrText = feature("formTextAttrText", { form }, (p) => getFormText(p.form));
68
+ export const formAttributes = feature("formAttributes", { form }, (p) => getFormAttributes(p.form));
69
+ export const pwHaystack = feature("pwHaystack", { passwords }, (p) => p.passwords.flatMap(getAllFieldHaystacks));
70
+ export const identifierHaystack = feature("identifierHaystack", { visibleIdentifiers }, (p) => p.visibleIdentifiers.flatMap(getAllFieldHaystacks));
71
+ export const btnHaystack = feature("btnHaystack", { candidateBtns }, (p) => p.candidateBtns.flatMap(getAllFieldHaystacks));
72
+ export const submitBtnHaystack = feature("submitBtnHaystack", { submitBtns }, (p) => p.submitBtns.flatMap(getAllFieldHaystacks));
73
+ export const checkboxesHaystack = feature("checkboxesHaystack", { checkboxes }, (p) => p.checkboxes.flatMap(getAllFieldHaystacks));
74
+ export const anchorsHaystack = feature("anchorsHaystack", { anchors }, (p) => p.anchors.flatMap(getAllNodeHaystacks));
75
+ export const mfaInputsHaystack = feature("mfaInputsHaystack", { mfaInputs }, (p) => p.mfaInputs.flatMap(getAllFieldHaystacks));
76
+ export const layoutHaystack = feature("layoutHaystack", { layouts }, (p) => p.layouts.map(getNodeAttributes));
77
+ export const formTextHaystack = feature("formTextHaystack", { formTextAttrText, nearestHeadingsText }, (p) => [p.formTextAttrText, p.nearestHeadingsText]);
78
+ export const pageLogin = feature("pageLogin", { pageDescriptionText }, (p) => matchLogin(p.pageDescriptionText));
79
+ export const formTextLogin = feature("formTextLogin", { formTextAttrText }, (p) => matchLogin(p.formTextAttrText));
80
+ export const formAttrsLogin = feature("formAttrsLogin", { formAttributes }, (p) => any(matchLogin)(p.formAttributes));
81
+ export const headingsLogin = feature("headingsLogin", { nearestHeadingsText }, (p) => matchLogin(p.nearestHeadingsText));
82
+ export const layoutLogin = feature("layoutLogin", { layoutHaystack }, (p) => any(matchLogin)(p.layoutHaystack));
83
+ export const rememberMeCheckbox = feature("rememberMeCheckbox", { checkboxesHaystack }, (p) => any(matchRememberMe)(p.checkboxesHaystack));
84
+ export const submitLogin = feature("submitLogin", { submitBtnHaystack }, (p) => any(matchLogin)(p.submitBtnHaystack));
85
+ export const troubleLink = feature("troubleLink", { anchorsHaystack }, (p) => any(matchTrouble)(p.anchorsHaystack));
86
+ export const pageRegister = feature("pageRegister", { pageDescriptionText }, (p) => matchRegister(p.pageDescriptionText));
87
+ export const formTextRegister = feature("formTextRegister", { formTextAttrText }, (p) => matchRegister(p.formTextAttrText));
88
+ export const formAttrsRegister = feature("formAttrsRegister", { formAttributes }, (p) => any(matchRegister)(p.formAttributes));
89
+ export const headingsRegister = feature("headingsRegister", { nearestHeadingsText }, (p) => matchRegister(p.nearestHeadingsText));
90
+ export const layoutRegister = feature("layoutRegister", { layoutHaystack }, (p) => any(matchRegister)(p.layoutHaystack));
91
+ export const TOSRef = feature("TOSRef", { checkboxesHaystack, anchorsHaystack }, (p) => any(matchTOS)(p.checkboxesHaystack.concat(p.anchorsHaystack)));
92
+ export const submitRegister = feature("submitRegister", { submitBtnHaystack }, (p) => any(matchRegister)(p.submitBtnHaystack));
93
+ export const pwNewRegister = feature("pwNewRegister", { pwHaystack }, (p) => any(matchPasswordCreateAttr)(p.pwHaystack));
94
+ export const pwConfirmRegister = feature("pwConfirmRegister", { pwHaystack }, (p) => any(matchPasswordConfirmAttr)(p.pwHaystack));
95
+ export const buttonMultistep = feature("buttonMultistep", { submitBtnHaystack }, (p) => any(matchStepAction)(p.submitBtnHaystack));
96
+ export const headingsMultistep = feature("headingsMultistep", { nearestHeadingsText }, (p) => matchMultiStep(p.nearestHeadingsText));
97
+ export const multistepForm = feature("multistepForm", { buttonMultistep, headingsMultistep }, (p) => p.buttonMultistep || p.headingsMultistep);
98
+ export const pageMultiAuth = feature("pageMultiAuth", { pageLogin, pageRegister }, (p) => p.pageLogin && p.pageRegister);
99
+ export const submitMultiAuth = feature("submitMultiAuth", { submitRegister, submitLogin, buttonMultistep }, (p) => p.submitRegister && (p.submitLogin || p.buttonMultistep));
100
+ export const headingsMultiAuth = feature("headingsMultiAuth", { headingsLogin, headingsRegister }, (p) => p.headingsLogin && p.headingsRegister);
101
+ export const multiAuthForm = feature("multiAuthForm", { pageMultiAuth, headingsMultiAuth, submitMultiAuth }, (p) => p.pageMultiAuth || p.headingsMultiAuth || p.submitMultiAuth);
102
+ export const pagePwReset = feature("pagePwReset", { pageDescriptionText }, (p) => matchPasswordReset(p.pageDescriptionText));
103
+ export const formTextPwReset = feature("formTextPwReset", { formTextAttrText }, (p) => matchPasswordReset(p.formTextAttrText));
104
+ export const formAttrsPwReset = feature("formAttrsPwReset", { formAttributes }, (p) => any(matchPasswordResetAttr)(p.formAttributes));
105
+ export const headingsPwReset = feature("headingsPwReset", { nearestHeadingsText }, (p) => matchPasswordReset(p.nearestHeadingsText));
106
+ export const layoutPwReset = feature("layoutPwReset", { layoutHaystack }, (p) => any(matchPasswordResetAttr)(p.layoutHaystack));
107
+ export const pageRecovery = feature("pageRecovery", { pageDescriptionText }, (p) => matchRecovery(p.pageDescriptionText));
108
+ export const formTextRecovery = feature("formTextRecovery", { formTextAttrText }, (p) => matchRecovery(p.formTextAttrText));
109
+ export const formAttrsRecovery = feature("formAttrsRecovery", { formAttributes }, (p) => any(matchRecovery)(p.formAttributes));
110
+ export const headingsRecovery = feature("headingsRecovery", { nearestHeadingsText }, (p) => matchRecovery(p.nearestHeadingsText));
111
+ export const layoutRecovery = feature("layoutRecovery", { layoutHaystack }, (p) => any(matchRecovery)(p.layoutHaystack));
112
+ export const submitRecovery = feature("submitRecovery", { submitBtnHaystack }, (p) => any(matchRecovery)(p.submitBtnHaystack));
113
+ export const identifierRecovery = feature("identifierRecovery", { identifierHaystack }, (p) => any(matchRecovery)(p.identifierHaystack));
114
+ export const inputsMFA = feature("inputsMFA", { mfaInputs, mfaInputsHaystack }, (p) => p.mfaInputs.some(({ autocomplete }) => autocomplete.includes("one-time-code")) || any(matchMFA)(p.mfaInputsHaystack));
115
+ export const formAttrsMFA = feature("formAttrsMFA", { formAttributes }, (p) => any(matchMFA)(p.formAttributes));
116
+ export const formTextMFA = feature("formTextMFA", { formTextHaystack }, (p) => any(matchMFA)(p.formTextHaystack));
117
+ export const maybeMFA = feature("maybeMFA", { formTextMFA, formAttrsMFA, inputsMFA }, (p) => p.inputsMFA || p.formAttrsMFA || p.formTextMFA);
118
+ export const haystackMFA = feature("haystackMFA", { formTextHaystack, maybeMFA, form }, (p) => [...p.formTextHaystack, p.maybeMFA ? sanitizeString(p.form.innerText) : ""]);
119
+ export const formTextAuthenticator = feature("formTextAuthenticator", { haystackMFA }, (p) => any(matchAuthenticator)(p.haystackMFA), { private: true });
120
+ export const headingsOTPOutlier = feature("headingsOTPOutlier", { nearestHeadingsText }, (p) => matchOtpOutlier(p.nearestHeadingsText), { private: true });
121
+ export const formOTPOutlier = feature("formOTPOutlier", { formAttributes }, (p) => any(matchOtpOutlier)(p.formAttributes), { private: true });
122
+ export const linkOTPOutlier = feature("linkOTPOutlier", { anchorsHaystack, btnHaystack }, (p) => any(matchOtpOutlierAction)(p.anchorsHaystack.concat(p.btnHaystack)), { private: true });
123
+ export const formMFA = feature("formMFA", { formTextMFA, formAttrsMFA }, (p) => p.formTextMFA || p.formAttrsMFA, { private: true });
124
+ export const formInputMFACandidates = feature("formInputMFACandidates", { visibleInputs }, (p) => p.visibleInputs.filter(isMFACandidate).length, { private: true });
125
+ export const newsletterForm = feature("newsletterForm", { formTextHaystack }, (p) => any(matchNewsletter)(p.formTextHaystack));
126
+ export const searchForm = feature("searchForm", { formTextHaystack }, (p) => any(matchSearchAction)(p.formTextHaystack));
127
+ export const formComplexity = featureScaled(feature("formComplexity", { form, fields, visibleFields, hidden, anchors, candidateBtns }, (p) => getFormComplexity(p.form, {
128
128
  fields: p.fields,
129
129
  visibleFields: p.visibleFields.length,
130
130
  hiddenFields: p.hidden.length,
@@ -132,91 +132,91 @@ const formComplexity = featureScaled(feature("formComplexity", { form, fields, v
132
132
  anchors: p.anchors.length,
133
133
  buttons: p.candidateBtns.length,
134
134
  })), 0, 50);
135
- const visibleFieldsCount = featureScaled(featureCount(visibleFields), 1, 5);
136
- const visibleInputsCount = featureScaled(featureCount(visibleInputs), 1, 5);
137
- const fieldsetsCount = featureScaled(featureCount(fieldsets), 1, 5);
138
- const textsCount = featureScaled(featureCount(texts), 0, 3);
139
- const readOnlyCount = featureScaled(featureCount(readOnly), 0, 3);
140
- const textareasCount = featureScaled(featureCount(textareas), 0, 2);
141
- const selectsCount = featureScaled(featureCount(selects), 0, 5);
142
- const disabledCount = featureScaled(featureCount(disabled), 0, 5);
143
- const radiosCount = featureScaled(featureCount(radios), 0, 5);
144
- const visibleIdentifiersCount = featureScaled(featureCount(visibleIdentifiers), 0, 3);
145
- const hiddenIdentifiersCount = featureScaled(featureCount(hiddenIdentifiers), 0, 2);
146
- const hiddenCount = featureScaled(featureCount(hidden), 0, 5);
147
- const visiblePasswordsCount = featureScaled(featureCount(visiblePasswords), 0, 2);
148
- const hiddenPasswordsCount = featureScaled(featureCount(hiddenPasswords), 0, 2);
149
- const usernamesCount = featureScaled(featureCount(usernames), 0, 2);
150
- const emailsCount = featureScaled(featureCount(emails), 0, 2);
151
- const submitsCount = featureScaled(featureCount(submits), 0, 2);
152
- const identitiesCount = featureScaled(featureCount(identities), 0, 5);
153
- const ccsCount = featureScaled(featureCount(ccs), 0, 5);
154
- const hasTels = feature("hasTels", { tels }, (p) => p.tels.length > 0);
155
- const hasOAuth = feature("hasOAuth", { oauths }, (p) => p.oauths.length > 0);
156
- const hasCaptchas = feature("hasCaptchas", { captchas }, (p) => p.captchas.length > 0);
157
- const hasFiles = feature("hasFiles", { files }, (p) => p.files.length > 0);
158
- const hasDate = feature("hasDate", { dates }, (p) => p.dates.length > 0);
159
- const hasNumber = feature("hasNumber", { numbers }, (p) => p.numbers.length > 0);
160
- const oneVisibleField = feature("oneVisibleField", { visibleInputs }, (p) => p.visibleInputs.length === 1);
161
- const twoVisibleFields = feature("twoVisibleFields", { visibleInputs }, (p) => p.visibleInputs.length === 2);
162
- const threeOrMoreVisibleFields = feature("threeOrMoreVisibleFields", { visibleInputs }, (p) => p.visibleInputs.length >= 3);
163
- const noPasswords = feature("noPasswords", { visiblePasswords }, (p) => p.visiblePasswords.length === 0);
164
- const onePassword = feature("onePassword", { visiblePasswords }, (p) => p.visiblePasswords.length === 1);
165
- const twoPasswords = feature("twoPasswords", { visiblePasswords }, (p) => p.visiblePasswords.length === 2);
166
- const threeOrMorePasswords = feature("threeOrMorePasswords", { visiblePasswords }, (p) => p.visiblePasswords.length >= 3);
167
- const noIdentifiers = feature("noIdentifiers", { visibleIdentifiers }, (p) => p.visibleIdentifiers.length === 0);
168
- const oneIdentifier = feature("oneIdentifier", { visibleIdentifiers }, (p) => p.visibleIdentifiers.length === 1);
169
- const twoIdentifiers = feature("twoIdentifiers", { visibleIdentifiers }, (p) => p.visibleIdentifiers.length === 2);
170
- const threeOrMoreIdentifiers = feature("threeOrMoreIdentifiers", { visibleIdentifiers }, (p) => p.visibleIdentifiers.length >= 3);
171
- const inputRatio = feature("inputRatio", { inputs, fields }, (p) => safeInt(p.inputs.length / p.fields.length));
172
- const hiddenRatio = feature("hiddenRatio", { hidden, fields }, (p) => safeInt(p.hidden.length / p.fields.length));
173
- const visibleRatio = feature("visibleRatio", { visibleInputs, fields }, (p) => safeInt(p.visibleInputs.length / p.fields.length));
174
- const checkboxRatio = feature("checkboxRatio", { checkboxes, fields }, (p) => safeInt(p.checkboxes.length / p.fields.length));
175
- const emailRatio = feature("emailRatio", { emails, fields }, (p) => safeInt(p.emails.length / p.fields.length));
176
- const usernameRatio = feature("usernameRatio", { usernames, fields }, (p) => safeInt(p.usernames.length / p.fields.length));
177
- const hiddenIdentifierRatio = feature("hiddenIdentifierRatio", { hiddenIdentifiers, identifiers }, (p) => safeInt(p.hiddenIdentifiers.length / p.identifiers.length));
178
- const hiddenPasswordRatio = feature("hiddenPasswordRatio", { hiddenPasswords, passwords }, (p) => safeInt(p.hiddenPasswords.length / p.passwords.length));
179
- const identifierRatio = feature("identifierRatio", { visibleIdentifiers, visibleFields }, (p) => safeInt(p.visibleIdentifiers.length / p.visibleFields.length));
180
- const passwordRatio = feature("passwordRatio", { visiblePasswords, visibleFields }, (p) => safeInt(p.visiblePasswords.length / p.visibleFields.length));
181
- const requiredRatio = feature("requiredRatio", { required, visibleFields }, (p) => safeInt(p.required.length / p.visibleFields.length));
182
- const disabledRatio = feature("disabledRatio", { disabled, visibleFields }, (p) => safeInt(p.disabled.length / p.visibleFields.length));
183
- const multistepForm_multiAuthForm = featuresProduct(multistepForm, multiAuthForm);
184
- const visibleRatio_visibleFieldsCount = featuresProduct(visibleRatio, visibleFieldsCount);
185
- const visibleRatio_visibleIdentifiersCount = featuresProduct(visibleRatio, visibleIdentifiersCount);
186
- const visibleRatio_visiblePasswordsCount = featuresProduct(visibleRatio, visiblePasswordsCount);
187
- const visibleRatio_hiddenIdentifiersCount = featuresProduct(visibleRatio, hiddenIdentifiersCount);
188
- const visibleRatio_hiddenPasswordsCount = featuresProduct(visibleRatio, hiddenPasswordsCount);
189
- const visibleRatio_multiAuthForm = featuresProduct(visibleRatio, multiAuthForm);
190
- const visibleRatio_multistepForm = featuresProduct(visibleRatio, multistepForm);
191
- const identifierRatio_visibleFieldsCount = featuresProduct(identifierRatio, visibleFieldsCount);
192
- const identifierRatio_visibleIdentifiersCount = featuresProduct(identifierRatio, visibleIdentifiersCount);
193
- const identifierRatio_visiblePasswordsCount = featuresProduct(identifierRatio, visiblePasswordsCount);
194
- const identifierRatio_hiddenIdentifiersCount = featuresProduct(identifierRatio, hiddenIdentifiersCount);
195
- const identifierRatio_hiddenPasswordsCount = featuresProduct(identifierRatio, hiddenPasswordsCount);
196
- const identifierRatio_multiAuthForm = featuresProduct(identifierRatio, multiAuthForm);
197
- const identifierRatio_multistepForm = featuresProduct(identifierRatio, multistepForm);
198
- const passwordRatio_visibleFieldsCount = featuresProduct(passwordRatio, visibleFieldsCount);
199
- const passwordRatio_visibleIdentifiersCount = featuresProduct(passwordRatio, visibleIdentifiersCount);
200
- const passwordRatio_visiblePasswordsCount = featuresProduct(passwordRatio, visiblePasswordsCount);
201
- const passwordRatio_hiddenIdentifiersCount = featuresProduct(passwordRatio, hiddenIdentifiersCount);
202
- const passwordRatio_hiddenPasswordsCount = featuresProduct(passwordRatio, hiddenPasswordsCount);
203
- const passwordRatio_multiAuthForm = featuresProduct(passwordRatio, multiAuthForm);
204
- const passwordRatio_multistepForm = featuresProduct(passwordRatio, multistepForm);
205
- const requiredRatio_visibleFieldsCount = featuresProduct(requiredRatio, visibleFieldsCount);
206
- const requiredRatio_visibleIdentifiersCount = featuresProduct(requiredRatio, visibleIdentifiersCount);
207
- const requiredRatio_visiblePasswordsCount = featuresProduct(requiredRatio, visiblePasswordsCount);
208
- const requiredRatio_hiddenIdentifiersCount = featuresProduct(requiredRatio, hiddenIdentifiersCount);
209
- const requiredRatio_hiddenPasswordsCount = featuresProduct(requiredRatio, hiddenPasswordsCount);
210
- const requiredRatio_multiAuthForm = featuresProduct(requiredRatio, multiAuthForm);
211
- const requiredRatio_multistepForm = featuresProduct(requiredRatio, multistepForm);
135
+ export const visibleFieldsCount = featureScaled(featureCount(visibleFields), 1, 5);
136
+ export const visibleInputsCount = featureScaled(featureCount(visibleInputs), 1, 5);
137
+ export const fieldsetsCount = featureScaled(featureCount(fieldsets), 1, 5);
138
+ export const textsCount = featureScaled(featureCount(texts), 0, 3);
139
+ export const readOnlyCount = featureScaled(featureCount(readOnly), 0, 3);
140
+ export const textareasCount = featureScaled(featureCount(textareas), 0, 2);
141
+ export const selectsCount = featureScaled(featureCount(selects), 0, 5);
142
+ export const disabledCount = featureScaled(featureCount(disabled), 0, 5);
143
+ export const radiosCount = featureScaled(featureCount(radios), 0, 5);
144
+ export const visibleIdentifiersCount = featureScaled(featureCount(visibleIdentifiers), 0, 3);
145
+ export const hiddenIdentifiersCount = featureScaled(featureCount(hiddenIdentifiers), 0, 2);
146
+ export const hiddenCount = featureScaled(featureCount(hidden), 0, 5);
147
+ export const visiblePasswordsCount = featureScaled(featureCount(visiblePasswords), 0, 2);
148
+ export const hiddenPasswordsCount = featureScaled(featureCount(hiddenPasswords), 0, 2);
149
+ export const usernamesCount = featureScaled(featureCount(usernames), 0, 2);
150
+ export const emailsCount = featureScaled(featureCount(emails), 0, 2);
151
+ export const submitsCount = featureScaled(featureCount(submits), 0, 2);
152
+ export const identitiesCount = featureScaled(featureCount(identities), 0, 5);
153
+ export const ccsCount = featureScaled(featureCount(ccs), 0, 5);
154
+ export const hasTels = feature("hasTels", { tels }, (p) => p.tels.length > 0);
155
+ export const hasOAuth = feature("hasOAuth", { oauths }, (p) => p.oauths.length > 0);
156
+ export const hasCaptchas = feature("hasCaptchas", { captchas }, (p) => p.captchas.length > 0);
157
+ export const hasFiles = feature("hasFiles", { files }, (p) => p.files.length > 0);
158
+ export const hasDate = feature("hasDate", { dates }, (p) => p.dates.length > 0);
159
+ export const hasNumber = feature("hasNumber", { numbers }, (p) => p.numbers.length > 0);
160
+ export const oneVisibleField = feature("oneVisibleField", { visibleInputs }, (p) => p.visibleInputs.length === 1);
161
+ export const twoVisibleFields = feature("twoVisibleFields", { visibleInputs }, (p) => p.visibleInputs.length === 2);
162
+ export const threeOrMoreVisibleFields = feature("threeOrMoreVisibleFields", { visibleInputs }, (p) => p.visibleInputs.length >= 3);
163
+ export const noPasswords = feature("noPasswords", { visiblePasswords }, (p) => p.visiblePasswords.length === 0);
164
+ export const onePassword = feature("onePassword", { visiblePasswords }, (p) => p.visiblePasswords.length === 1);
165
+ export const twoPasswords = feature("twoPasswords", { visiblePasswords }, (p) => p.visiblePasswords.length === 2);
166
+ export const threeOrMorePasswords = feature("threeOrMorePasswords", { visiblePasswords }, (p) => p.visiblePasswords.length >= 3);
167
+ export const noIdentifiers = feature("noIdentifiers", { visibleIdentifiers }, (p) => p.visibleIdentifiers.length === 0);
168
+ export const oneIdentifier = feature("oneIdentifier", { visibleIdentifiers }, (p) => p.visibleIdentifiers.length === 1);
169
+ export const twoIdentifiers = feature("twoIdentifiers", { visibleIdentifiers }, (p) => p.visibleIdentifiers.length === 2);
170
+ export const threeOrMoreIdentifiers = feature("threeOrMoreIdentifiers", { visibleIdentifiers }, (p) => p.visibleIdentifiers.length >= 3);
171
+ export const inputRatio = feature("inputRatio", { inputs, fields }, (p) => safeInt(p.inputs.length / p.fields.length));
172
+ export const hiddenRatio = feature("hiddenRatio", { hidden, fields }, (p) => safeInt(p.hidden.length / p.fields.length));
173
+ export const visibleRatio = feature("visibleRatio", { visibleInputs, fields }, (p) => safeInt(p.visibleInputs.length / p.fields.length));
174
+ export const checkboxRatio = feature("checkboxRatio", { checkboxes, fields }, (p) => safeInt(p.checkboxes.length / p.fields.length));
175
+ export const emailRatio = feature("emailRatio", { emails, fields }, (p) => safeInt(p.emails.length / p.fields.length));
176
+ export const usernameRatio = feature("usernameRatio", { usernames, fields }, (p) => safeInt(p.usernames.length / p.fields.length));
177
+ export const hiddenIdentifierRatio = feature("hiddenIdentifierRatio", { hiddenIdentifiers, identifiers }, (p) => safeInt(p.hiddenIdentifiers.length / p.identifiers.length));
178
+ export const hiddenPasswordRatio = feature("hiddenPasswordRatio", { hiddenPasswords, passwords }, (p) => safeInt(p.hiddenPasswords.length / p.passwords.length));
179
+ export const identifierRatio = feature("identifierRatio", { visibleIdentifiers, visibleFields }, (p) => safeInt(p.visibleIdentifiers.length / p.visibleFields.length));
180
+ export const passwordRatio = feature("passwordRatio", { visiblePasswords, visibleFields }, (p) => safeInt(p.visiblePasswords.length / p.visibleFields.length));
181
+ export const requiredRatio = feature("requiredRatio", { required, visibleFields }, (p) => safeInt(p.required.length / p.visibleFields.length));
182
+ export const disabledRatio = feature("disabledRatio", { disabled, visibleFields }, (p) => safeInt(p.disabled.length / p.visibleFields.length));
183
+ export const multistepForm_multiAuthForm = featuresProduct(multistepForm, multiAuthForm);
184
+ export const visibleRatio_visibleFieldsCount = featuresProduct(visibleRatio, visibleFieldsCount);
185
+ export const visibleRatio_visibleIdentifiersCount = featuresProduct(visibleRatio, visibleIdentifiersCount);
186
+ export const visibleRatio_visiblePasswordsCount = featuresProduct(visibleRatio, visiblePasswordsCount);
187
+ export const visibleRatio_hiddenIdentifiersCount = featuresProduct(visibleRatio, hiddenIdentifiersCount);
188
+ export const visibleRatio_hiddenPasswordsCount = featuresProduct(visibleRatio, hiddenPasswordsCount);
189
+ export const visibleRatio_multiAuthForm = featuresProduct(visibleRatio, multiAuthForm);
190
+ export const visibleRatio_multistepForm = featuresProduct(visibleRatio, multistepForm);
191
+ export const identifierRatio_visibleFieldsCount = featuresProduct(identifierRatio, visibleFieldsCount);
192
+ export const identifierRatio_visibleIdentifiersCount = featuresProduct(identifierRatio, visibleIdentifiersCount);
193
+ export const identifierRatio_visiblePasswordsCount = featuresProduct(identifierRatio, visiblePasswordsCount);
194
+ export const identifierRatio_hiddenIdentifiersCount = featuresProduct(identifierRatio, hiddenIdentifiersCount);
195
+ export const identifierRatio_hiddenPasswordsCount = featuresProduct(identifierRatio, hiddenPasswordsCount);
196
+ export const identifierRatio_multiAuthForm = featuresProduct(identifierRatio, multiAuthForm);
197
+ export const identifierRatio_multistepForm = featuresProduct(identifierRatio, multistepForm);
198
+ export const passwordRatio_visibleFieldsCount = featuresProduct(passwordRatio, visibleFieldsCount);
199
+ export const passwordRatio_visibleIdentifiersCount = featuresProduct(passwordRatio, visibleIdentifiersCount);
200
+ export const passwordRatio_visiblePasswordsCount = featuresProduct(passwordRatio, visiblePasswordsCount);
201
+ export const passwordRatio_hiddenIdentifiersCount = featuresProduct(passwordRatio, hiddenIdentifiersCount);
202
+ export const passwordRatio_hiddenPasswordsCount = featuresProduct(passwordRatio, hiddenPasswordsCount);
203
+ export const passwordRatio_multiAuthForm = featuresProduct(passwordRatio, multiAuthForm);
204
+ export const passwordRatio_multistepForm = featuresProduct(passwordRatio, multistepForm);
205
+ export const requiredRatio_visibleFieldsCount = featuresProduct(requiredRatio, visibleFieldsCount);
206
+ export const requiredRatio_visibleIdentifiersCount = featuresProduct(requiredRatio, visibleIdentifiersCount);
207
+ export const requiredRatio_visiblePasswordsCount = featuresProduct(requiredRatio, visiblePasswordsCount);
208
+ export const requiredRatio_hiddenIdentifiersCount = featuresProduct(requiredRatio, hiddenIdentifiersCount);
209
+ export const requiredRatio_hiddenPasswordsCount = featuresProduct(requiredRatio, hiddenPasswordsCount);
210
+ export const requiredRatio_multiAuthForm = featuresProduct(requiredRatio, multiAuthForm);
211
+ export const requiredRatio_multistepForm = featuresProduct(requiredRatio, multistepForm);
212
212
  export const formFeatures = flattenFeatures({
213
- __formInputMFACandidates,
214
- __formMFA,
215
- __formOTPOutlier,
216
- __formTextAuthenticator,
217
- __headingsOTPOutlier,
218
- __inputIterator,
219
- __linkOTPOutlier,
213
+ formInputMFACandidates,
214
+ formMFA,
215
+ formOTPOutlier,
216
+ formTextAuthenticator,
217
+ headingsOTPOutlier,
218
+ inputIterator,
219
+ linkOTPOutlier,
220
220
  visibleFieldsCount,
221
221
  visibleInputsCount,
222
222
  fieldsetsCount,
@@ -333,4 +333,3 @@ export const formFeatures = flattenFeatures({
333
333
  requiredRatio_multiAuthForm,
334
334
  requiredRatio_multistepForm,
335
335
  });
336
- export const formFeaturesComputer = getComputerForFeatures(formFeatures);