@wenathlan/extension 1.1.39 → 1.1.41

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../policy.ts", "../pageactions.ts", "../pagexpath.ts", "../pageresolve.ts", "../pagereads.ts", "../pagecontrols.ts", "../pagepointer.ts", "../pageinteract.ts", "../pagenav.ts", "../pagedialogs.ts", "../pageobserve.ts", "../pagedetect.ts", "../pagewatch.ts", "../pageforms.ts", "../pagewizards.ts", "../pagedata.ts", "../datacommand.ts", "../pagebridge.ts"],
4
- "sourcesContent": ["import type { actionkind, agentplan, agentsession, cleanuprule, downloadspec, endpointconfig, fieldkind, formprofile, mimefilter, observationmode, policyevaluation, quarantineentry, runsettings, safetyverdict, toolstep, transformrule } from \"./types.js\";\n\nconst sensitiveactions = new Set<actionkind>([\"click\", \"type\", \"navigate\", \"select\", \"presskey\", \"drag\", \"drop\", \"upload\", \"clear\", \"check\", \"uncheck\", \"toggle\", \"submit\", \"reload\", \"back\", \"forward\", \"writestorage\", \"setattribute\", \"removeattribute\", \"evaluate\", \"tabcreate\", \"tabactivate\", \"tabclose\", \"tabreload\", \"windowcreate\", \"windowclose\", \"windowresize\", \"downloadfile\", \"clickpoint\", \"shiftclick\", \"dismissdialog\", \"enterframe\", \"typetime\", \"appendtext\", \"setvalue\", \"typeedit\", \"keyhold\", \"keyrelease\", \"submitsearch\", \"selectmulti\", \"chooseradio\", \"setslider\", \"setdate\", \"setcolor\", \"openlink\", \"openprivate\", \"reloadcache\", \"stopnav\", \"followlink\", \"spanav\", \"rewritequery\", \"setfragment\", \"navlist\", \"navprofile\", \"handleauth\", \"printpdf\", \"prefetch\", \"preconnect\", \"deeplink\", \"reopentab\", \"pausenav\", \"navrate\", \"openclipboard\", \"batchopen\", \"duplicatetab\", \"closepattern\", \"pintab\", \"mutetab\", \"movetab\", \"movetabwindow\", \"grouptabs\", \"colorgroup\", \"collapsegroup\", \"discardtab\", \"reloadtabs\", \"zoomin\", \"zoomout\", \"switchtab\", \"maximizewindow\", \"minimizewindow\", \"restorewindow\", \"focuswindow\", \"scratchwindow\", \"incognitowindow\", \"restoretab\", \"restorelayout\", \"reopenrun\", \"badgetab\", \"fillform\", \"filllabel\", \"fillplaceholder\", \"submitform\", \"retryform\", \"runwizard\", \"selectchain\", \"picktypeahead\", \"pickdate\", \"attachfile\", \"fillcard\", \"fillcode\", \"consentpassword\", \"exportcsv\", \"exportjson\", \"exportexcel\", \"copytable\", \"pushsheets\", \"streamdisk\", \"paginateextract\", \"resumeextract\", \"batchdownload\", \"pausedownload\", \"resumedownload\", \"interceptmime\", \"readclipboard\", \"writeclipboard\", \"copyscreen\", \"quarantinedownload\", \"scanvirus\", \"cleanupartifacts\"]);\nconst interactionactions = new Set<actionkind>([\"focus\", \"scroll\", \"hover\", \"clickdeep\", \"rightclick\", \"doubleclick\", \"scrollpage\", \"scrollby\", \"scrollend\", \"scrolltop\", \"fullscreen\", \"zoomset\", \"movepointer\", \"clicktext\", \"clickaria\", \"clickname\", \"expanddetails\", \"pierceshadow\", \"retryaction\"]);\nconst readactions = new Set<actionkind>([\"observe\", \"inspect\", \"extract\", \"wait\", \"waitfor\", \"waittext\", \"readattribute\", \"readstyle\", \"readgeometry\", \"readvalue\", \"readtext\", \"readhtml\", \"countelements\", \"readtable\", \"readlinks\", \"readimages\", \"readmeta\", \"readforms\", \"readstorage\", \"highlight\", \"tablist\", \"windowlist\", \"tabsnapshot\", \"mapclicks\", \"verifyvisible\", \"verifyenabled\", \"resolvexpath\", \"a11ytree\", \"readvisible\", \"readertree\", \"detectlists\", \"detecttables\", \"readjson\", \"watchmutate\", \"waitquiet\", \"watchbanner\", \"detectinfinitescroll\", \"detectvirtual\", \"detectlazy\", \"readscrollpos\", \"readlang\", \"readoutline\", \"countpages\", \"listshadow\", \"listframes\", \"classifypage\", \"fingerprintsection\", \"diffsnapshots\", \"readselection\", \"watchfocus\", \"detectsticky\", \"detectscrolllock\", \"readopengraph\", \"detectlanguage\", \"deriveselector\", \"waitload\", \"waiturl\", \"spawait\", \"detecthttp\", \"readredirects\", \"readfinalurl\", \"trailaudit\", \"navintent\", \"checksafe\", \"querytabs\", \"watchtab\", \"findclones\", \"searchtabs\", \"listaudio\", \"snapshotsession\", \"savelayout\", \"attachmeta\", \"detectfields\", \"generatevalues\", \"saveprofiles\", \"asksubmit\", \"readerrors\", \"skiphoneypot\", \"detectlogin\", \"detecttemplate\", \"handoffcaptcha\", \"scrapetable\", \"importcsv\", \"looprows\", \"transformvalues\", \"deduperows\", \"mergepages\", \"stamplerows\", \"previewgrid\", \"logprovenance\", \"verifydownload\", \"exportnetlog\", \"namecaptures\"]);\nconst allowedactions = new Set<actionkind>([...sensitiveactions, ...interactionactions, ...readactions]);\nconst watchactions = new Set<actionkind>([\"watchmutate\", \"watchbanner\", \"watchfocus\", \"watchtab\"]);\nconst targetactions = new Set<actionkind>([\"inspect\", \"focus\", \"click\", \"type\", \"scroll\", \"select\", \"hover\", \"clickdeep\", \"rightclick\", \"doubleclick\", \"drag\", \"drop\", \"upload\", \"clear\", \"check\", \"uncheck\", \"toggle\", \"submit\", \"readattribute\", \"readstyle\", \"readgeometry\", \"readvalue\", \"readtext\", \"readhtml\", \"countelements\", \"readtable\", \"highlight\", \"setattribute\", \"removeattribute\", \"waitfor\", \"shiftclick\", \"typetime\", \"appendtext\", \"setvalue\", \"typeedit\", \"submitsearch\", \"selectmulti\", \"chooseradio\", \"setslider\", \"setdate\", \"setcolor\", \"expanddetails\", \"verifyvisible\", \"verifyenabled\", \"pierceshadow\", \"deriveselector\", \"fingerprintsection\", \"submitform\", \"retryform\", \"selectchain\", \"picktypeahead\", \"pickdate\", \"attachfile\", \"fillcode\", \"consentpassword\", \"scrapetable\", \"paginateextract\"]);\nconst valueactions = new Set<actionkind>([\"presskey\", \"drag\", \"drop\", \"upload\", \"readattribute\", \"removeattribute\", \"waittext\", \"evaluate\", \"zoomset\", \"tabactivate\", \"tabclose\", \"tabreload\", \"windowclose\", \"windowresize\", \"tabcreate\", \"windowcreate\", \"downloadfile\", \"typetime\", \"appendtext\", \"setvalue\", \"typeedit\", \"keyhold\", \"keyrelease\", \"chooseradio\", \"setslider\", \"setdate\", \"setcolor\", \"followlink\", \"setfragment\", \"handleauth\", \"navintent\", \"openclipboard\", \"checksafe\", \"reopentab\", \"spanav\", \"duplicatetab\", \"pintab\", \"mutetab\", \"movetab\", \"movetabwindow\", \"searchtabs\", \"badgetab\", \"attachmeta\", \"focuswindow\", \"maximizewindow\", \"minimizewindow\", \"restorewindow\", \"incognitowindow\", \"asksubmit\", \"selectchain\", \"picktypeahead\", \"pickdate\", \"attachfile\", \"fillcode\", \"consentpassword\", \"pausedownload\", \"resumedownload\", \"verifydownload\", \"writeclipboard\", \"quarantinedownload\", \"scanvirus\"]);\nconst tabscommandactions = new Set<actionkind>([\"querytabs\", \"duplicatetab\", \"closepattern\", \"pintab\", \"mutetab\", \"movetab\", \"movetabwindow\", \"grouptabs\", \"colorgroup\", \"collapsegroup\", \"discardtab\", \"reloadtabs\", \"zoomin\", \"zoomout\", \"watchtab\", \"switchtab\", \"maximizewindow\", \"minimizewindow\", \"restorewindow\", \"focuswindow\", \"scratchwindow\", \"incognitowindow\", \"restoretab\", \"savelayout\", \"restorelayout\", \"findclones\", \"searchtabs\", \"badgetab\", \"attachmeta\", \"listaudio\", \"reopenrun\", \"snapshotsession\"]);\nconst formactions = new Set<actionkind>([\"fillform\", \"filllabel\", \"fillplaceholder\", \"detectfields\", \"generatevalues\", \"saveprofiles\", \"asksubmit\", \"submitform\", \"readerrors\", \"retryform\", \"runwizard\", \"selectchain\", \"picktypeahead\", \"pickdate\", \"attachfile\", \"handoffcaptcha\", \"fillcard\", \"fillcode\", \"consentpassword\", \"skiphoneypot\", \"detectlogin\", \"detecttemplate\"]);\n/** Extraction, transform, export and provenance kinds of the forms and data part two family. */\nconst datasetactions = new Set<actionkind>([\"scrapetable\", \"exportcsv\", \"exportjson\", \"exportexcel\", \"copytable\", \"pushsheets\", \"importcsv\", \"looprows\", \"transformvalues\", \"deduperows\", \"paginateextract\", \"mergepages\", \"stamplerows\", \"previewgrid\", \"streamdisk\", \"resumeextract\", \"logprovenance\"]);\n/** Export kinds that move extracted data out of local memory to disk, the clipboard or a reviewed sheet endpoint. */\nconst exportactions = new Set<actionkind>([\"exportcsv\", \"exportjson\", \"exportexcel\", \"copytable\", \"pushsheets\", \"streamdisk\"]);\n/** Files, clipboard and downloads kinds of the batch queue, interception, clipboard, quarantine, naming and cleanup family. */\nconst filesactions = new Set<actionkind>([\"batchdownload\", \"pausedownload\", \"resumedownload\", \"verifydownload\", \"interceptmime\", \"exportnetlog\", \"readclipboard\", \"writeclipboard\", \"copyscreen\", \"quarantinedownload\", \"scanvirus\", \"namecaptures\", \"cleanupartifacts\"]);\n/** Field kinds the form grammar accepts inside records, profiles and value rules. */\nconst fieldkinds: fieldkind[] = [\"text\", \"email\", \"phone\", \"date\", \"number\", \"select\", \"check\", \"radio\", \"file\", \"password\", \"card\", \"code\"];\nconst layoutmutationactions = new Set<actionkind>([\"grouptabs\", \"colorgroup\", \"collapsegroup\", \"savelayout\", \"restorelayout\"]);\n/** Chromium tab group colors accepted as reviewed group color choices. */\nconst groupcolors = [\"grey\", \"blue\", \"red\", \"yellow\", \"green\", \"pink\", \"purple\", \"cyan\", \"orange\"];\n\n/** Normalizes a user supplied HTTPS endpoint without preserving a provider lock-in. */\nexport function normalizeendpoint(value: string): endpointconfig {\n const endpoint = new URL(value.trim());\n if (endpoint.protocol !== \"https:\") throw new Error(\"Devthink accepts HTTPS endpoints only.\");\n if (endpoint.username || endpoint.password) throw new Error(\"Endpoint credentials are not allowed in the URL.\");\n return { endpoint: endpoint.toString(), origin: endpoint.origin, configuredat: Date.now() };\n}\n\n/** Creates the exact optional host pattern requested from Chromium. */\nexport function hostpattern(origin: string): string {\n const parsed = new URL(origin);\n if (parsed.protocol !== \"https:\") throw new Error(\"Only HTTPS origins can be granted.\");\n return `${parsed.origin}/*`;\n}\n\n/** True when the action kind observes the page over a reviewed lifetime window. */\nexport function iswatchkind(kind: actionkind): boolean {\n return watchactions.has(kind);\n}\n\n/** Grades the observation mode of a kind: passive capture, watched lifetimes or diffing passes. */\nexport function observationmodeof(kind: actionkind): observationmode {\n if (watchactions.has(kind) || kind === \"waitquiet\") return \"watching\";\n if (kind === \"diffsnapshots\") return \"diffing\";\n return \"passive\";\n}\n\n/** Defines action risk from the fixed local allowlist. */\nexport function actionrisk(kind: actionkind): \"read\" | \"interaction\" | \"sensitive\" {\n if (!allowedactions.has(kind)) throw new Error(\"Unsupported browser action.\");\n if (sensitiveactions.has(kind)) return \"sensitive\";\n return interactionactions.has(kind) ? \"interaction\" : \"read\";\n}\n\n/** True when the action kind accepts a css selector target or a reviewed targetref. */\nexport function needstarget(kind: actionkind): boolean {\n return targetactions.has(kind);\n}\n\n/** Parses the reviewed JSON options of a step; malformed payloads are rejected early. */\nexport function parseoptions(step: toolstep): Record<string, unknown> {\n if (step.options === undefined) return {};\n let parsed: unknown;\n try { parsed = JSON.parse(step.options); } catch { throw new Error(\"Step options must be a JSON object.\"); }\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) throw new Error(\"Step options must be a JSON object.\");\n return parsed as Record<string, unknown>;\n}\n\n/** Maps an action kind to the optional browser permission it requires, if any. */\nexport function requiredcapability(kind: actionkind): string | undefined {\n if (kind === \"tablist\") return \"tabs\";\n if (kind === \"downloadfile\") return \"downloads\";\n if (kind === \"openclipboard\") return \"clipboardRead\";\n if (kind === \"copytable\") return \"clipboardWrite\";\n if (kind === \"batchdownload\" || kind === \"pausedownload\" || kind === \"resumedownload\" || kind === \"verifydownload\" || kind === \"interceptmime\" || kind === \"quarantinedownload\" || kind === \"scanvirus\") return \"downloads\";\n if (kind === \"readclipboard\") return \"clipboardRead\";\n if (kind === \"writeclipboard\" || kind === \"copyscreen\") return \"clipboardWrite\";\n if (kind === \"openlink\" || kind === \"openprivate\" || kind === \"navlist\" || kind === \"batchopen\" || kind === \"reopentab\" || kind === \"deeplink\") return \"tabs\";\n if (tabscommandactions.has(kind)) return \"tabs\";\n return undefined;\n}\n\n/** True when the kind commands tabs or windows beyond the active tab and needs the optional tabs capability. */\nexport function istabscommandkind(kind: actionkind): boolean {\n return tabscommandactions.has(kind);\n}\n\n/** True when the kind mutates tab groups or layouts and therefore stays inside the active session. */\nexport function islayoutkind(kind: actionkind): boolean {\n return layoutmutationactions.has(kind);\n}\n\n/** True when the kind belongs to the forms and data family. */\nexport function isformkind(kind: actionkind): boolean {\n return formactions.has(kind);\n}\n\n/** True when the kind belongs to the extraction, transform, export and provenance family. */\nexport function isdatasetkind(kind: actionkind): boolean {\n return datasetactions.has(kind);\n}\n\n/** True when the kind exports extracted data out of local memory to disk, the clipboard or a reviewed sheet endpoint. */\nexport function isexportkind(kind: actionkind): boolean {\n return exportactions.has(kind);\n}\n\n/** True when the kind belongs to the files, clipboard and downloads family. */\nexport function isfileskind(kind: actionkind): boolean {\n return filesactions.has(kind);\n}\n\n/** Refuses any export that would leave local memory while the session origin grants do not cover the active origin. */\nexport function exportgranted(session: agentsession | undefined, origin: string): policyevaluation {\n if (!origingranted(session, origin)) return { allowed: false, reason: `The export of extracted data from ${origin} needs the session origin grants before it leaves local memory.` };\n return { allowed: true };\n}\n\n/** Validates the reviewed fieldmatch grammar of one form field entry. */\nexport function validatefieldmatch(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed field match is required in options.\" };\n const match = value as Record<string, unknown>;\n if (match.mode !== \"label\" && match.mode !== \"placeholder\" && match.mode !== \"arialabel\" && match.mode !== \"name\") return { allowed: false, reason: \"The reviewed field match mode must be label, placeholder, arialabel or name.\" };\n const key = match.mode === \"label\" ? \"label\" : match.mode === \"placeholder\" ? \"placeholder\" : match.mode === \"arialabel\" ? \"arialabel\" : \"name\";\n if (!isnonempty(match[key])) return { allowed: false, reason: `The reviewed ${match.mode} field match needs a non-empty ${key}.` };\n return { allowed: true };\n}\n\n/** Validates a reviewed structured form record; password entries are refused because passwords need the explicit consentpassword consent. */\nexport function validateformrecord(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed form record with entries is required in options.\" };\n const record = value as Record<string, unknown>;\n if (record.form !== undefined && !isnonempty(record.form)) return { allowed: false, reason: \"The reviewed form record form selector must be a non-empty string.\" };\n if (!Array.isArray(record.entries) || record.entries.length === 0) return { allowed: false, reason: \"The reviewed form record needs a non-empty list of entries.\" };\n for (const item of record.entries) {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) return { allowed: false, reason: \"Every reviewed form record entry must be an object.\" };\n const entry = item as Record<string, unknown>;\n const matchcheck = validatefieldmatch(entry.match);\n if (!matchcheck.allowed) return matchcheck;\n if (typeof entry.kind !== \"string\" || !fieldkinds.includes(entry.kind as fieldkind)) return { allowed: false, reason: \"Every reviewed form record entry needs a known field kind.\" };\n if (typeof entry.value !== \"string\") return { allowed: false, reason: \"Every reviewed form record entry needs a string value.\" };\n if (entry.kind === \"password\") return { allowed: false, reason: \"Password entries are refused inside form records; use consentpassword with a reviewed consent ref.\" };\n }\n return { allowed: true };\n}\n\n/** Validates the reviewed valuegen grammar of a generatevalues step. */\nexport function validatevaluegen(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed valuegen rule with a field kind is required in options.\" };\n const rule = value as Record<string, unknown>;\n if (typeof rule.kind !== \"string\" || !fieldkinds.includes(rule.kind as fieldkind)) return { allowed: false, reason: \"The reviewed valuegen kind must be a known field kind.\" };\n if (rule.locale !== undefined && !isnonempty(rule.locale)) return { allowed: false, reason: \"The reviewed valuegen locale must be a non-empty string.\" };\n if (rule.seed !== undefined && (typeof rule.seed !== \"number\" || !Number.isFinite(rule.seed))) return { allowed: false, reason: \"The reviewed valuegen seed must be a finite number.\" };\n return { allowed: true };\n}\n\n/** Validates a reviewed list of label or placeholder value pairs for filllabel and fillplaceholder steps. */\nfunction validatefieldpairs(options: Record<string, unknown>, mode: \"label\" | \"placeholder\"): policyevaluation {\n const pairs = options.fields;\n if (!Array.isArray(pairs) || pairs.length === 0) return { allowed: false, reason: \"A reviewed non-empty list of field pairs is required in options.\" };\n for (const item of pairs) {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) return { allowed: false, reason: \"Every reviewed field pair must be an object.\" };\n const pair = item as Record<string, unknown>;\n if (!isnonempty(pair[mode])) return { allowed: false, reason: `Every reviewed field pair needs a non-empty ${mode}.` };\n if (typeof pair.value !== \"string\" || !pair.value.trim()) return { allowed: false, reason: \"Every reviewed field pair needs a non-empty value.\" };\n }\n return { allowed: true };\n}\n\n/** Validates the reviewed card segment grammar of a fillcard step. */\nfunction validatecardsegments(value: unknown): policyevaluation {\n if (!Array.isArray(value) || value.length === 0) return { allowed: false, reason: \"A reviewed non-empty list of card segments is required in options.\" };\n for (const item of value) {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) return { allowed: false, reason: \"Every reviewed card segment must be an object.\" };\n const segment = item as Record<string, unknown>;\n const matchcheck = validatefieldmatch(segment.match);\n if (!matchcheck.allowed) return matchcheck;\n if (typeof segment.value !== \"string\" || !segment.value.trim()) return { allowed: false, reason: \"Every reviewed card segment needs a non-empty value.\" };\n }\n return { allowed: true };\n}\n\n/** Validates the reviewed forms and data parameter grammar of the form family. */\nfunction validateformgrammar(step: toolstep, options: Record<string, unknown>): policyevaluation {\n const kind = step.kind;\n if (kind === \"fillform\" || (kind === \"saveprofiles\" && options.formrecord !== undefined)) {\n const recordcheck = validateformrecord(options.formrecord);\n if (!recordcheck.allowed) return recordcheck;\n }\n if (kind === \"filllabel\" || kind === \"fillplaceholder\") {\n const paircheck = validatefieldpairs(options, kind === \"filllabel\" ? \"label\" : \"placeholder\");\n if (!paircheck.allowed) return paircheck;\n }\n if (kind === \"generatevalues\" && options.valuegen !== undefined) {\n const rulecheck = validatevaluegen(options.valuegen);\n if (!rulecheck.allowed) return rulecheck;\n }\n if (kind === \"saveprofiles\" && !isnonempty(options.name)) return { allowed: false, reason: \"A reviewed profile name is required in options.\" };\n if (kind === \"submitform\" && !isnonempty(options.consentref)) return { allowed: false, reason: \"A reviewed consent ref of an approved asksubmit ticket is required in options.\" };\n if (kind === \"retryform\") {\n const backoff = options.backoff;\n if (!backoff || typeof backoff !== \"object\" || Array.isArray(backoff)) return { allowed: false, reason: \"A reviewed backoff rule with wait and factor is required in options.\" };\n const rule = backoff as Record<string, unknown>;\n if (typeof rule.wait !== \"number\" || !Number.isFinite(rule.wait) || rule.wait <= 0) return { allowed: false, reason: \"The reviewed retry backoff wait must be a positive number of milliseconds with no code ceiling.\" };\n if (typeof rule.factor !== \"number\" || !Number.isFinite(rule.factor) || rule.factor < 1) return { allowed: false, reason: \"The reviewed retry backoff factor must be one or greater with no code ceiling.\" };\n if (options.attempts !== undefined && (typeof options.attempts !== \"number\" || !Number.isInteger(options.attempts) || options.attempts < 1)) return { allowed: false, reason: \"The reviewed retry attempts must be a positive integer with no code ceiling.\" };\n }\n if (kind === \"runwizard\" && options.steps !== undefined && (typeof options.steps !== \"number\" || !Number.isInteger(options.steps) || options.steps < 1)) return { allowed: false, reason: \"The reviewed wizard step count must be a positive integer with no code ceiling.\" };\n if (kind === \"selectchain\") {\n if (!isnonempty(options.child)) return { allowed: false, reason: \"A reviewed child selector of the dependent control is required in options.\" };\n if (!nonnegativeoption(options, \"wait\")) return { allowed: false, reason: \"The reviewed dependent wait must be zero or a positive number of milliseconds.\" };\n }\n if (kind === \"picktypeahead\") {\n if (!isnonempty(options.pick)) return { allowed: false, reason: \"A reviewed suggestion entry to pick is required in options.\" };\n if (!nonnegativeoption(options, \"timeout\")) return { allowed: false, reason: \"The reviewed typeahead timeout must be zero or a positive number of milliseconds.\" };\n }\n if (kind === \"pickdate\" && !/^\\d{4}-\\d{2}-\\d{2}$/.test(step.value ?? \"\")) return { allowed: false, reason: \"The reviewed date must use the yyyy-mm-dd form.\" };\n if (kind === \"fillcard\") {\n const segmentcheck = validatecardsegments(options.segments);\n if (!segmentcheck.allowed) return segmentcheck;\n if (!nonnegativeoption(options, \"pause\")) return { allowed: false, reason: \"The reviewed card typing pause must be zero or a positive number of milliseconds.\" };\n }\n if (kind === \"fillcode\" && !isnonempty(options.source)) return { allowed: false, reason: \"A reviewed one time code source is required in options.\" };\n if (kind === \"consentpassword\" && !isnonempty(options.consentref)) return { allowed: false, reason: \"A reviewed consent ref is required in options before any password is filled.\" };\n return { allowed: true };\n}\n\n/** Validates one reviewed transform rule: a supported expression, source columns and a target column. */\nexport function validatetransformrule(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed transform rule with an expression, sources and a target is required in options.\" };\n const rule = value as Record<string, unknown>;\n const expression = rule.expression;\n if (typeof expression !== \"string\" || !/^(trim|upper|lower|number|prefix|suffix|replace)(?::.+)?$/.test(expression)) return { allowed: false, reason: \"The reviewed transform expression must be trim, upper, lower, number, prefix, suffix or replace with an optional argument.\" };\n if (expression.startsWith(\"replace\") && !expression.slice(\"replace\".length).includes(\"=>\")) return { allowed: false, reason: \"The reviewed replace expression needs the from=>to separator.\" };\n if (expression.startsWith(\"replace\") && expression.slice(\"replace:\".length).split(\"=>\")[0] === \"\") return { allowed: false, reason: \"The reviewed replace expression needs a non-empty from part.\" };\n if (!Array.isArray(rule.sources) || rule.sources.length === 0 || !rule.sources.every(source => isnonempty(source))) return { allowed: false, reason: \"Every reviewed transform rule needs a non-empty list of source columns.\" };\n if (!isnonempty(rule.target)) return { allowed: false, reason: \"Every reviewed transform rule needs a non-empty target column.\" };\n return { allowed: true };\n}\n\n/** Validates a reviewed dataset id list in options. */\nfunction validatedatasetids(options: Record<string, unknown>, key: string): policyevaluation {\n const ids = options[key];\n if (!Array.isArray(ids) || ids.length === 0 || !ids.every(id => isnonempty(id))) return { allowed: false, reason: `A reviewed non-empty list of dataset ids is required in options as ${key}.` };\n return { allowed: true };\n}\n\n/** Validates the reviewed extraction, transform, export and provenance parameter grammar of the data family. */\nfunction validatedatagrammar(step: toolstep, options: Record<string, unknown>, origin: string): policyevaluation {\n const kind = step.kind;\n if (kind === \"scrapetable\") {\n if (options.name !== undefined && !isnonempty(options.name)) return { allowed: false, reason: \"The reviewed dataset name must be a non-empty string.\" };\n if (options.rowlimit !== undefined && (typeof options.rowlimit !== \"number\" || !Number.isInteger(options.rowlimit) || options.rowlimit < 1)) return { allowed: false, reason: \"The reviewed row limit must be a positive integer with no code ceiling.\" };\n }\n if (kind === \"paginateextract\") {\n if (!isnonempty(options.next)) return { allowed: false, reason: \"A reviewed next control selector is required in options.\" };\n if (options.pages !== undefined && (typeof options.pages !== \"number\" || !Number.isInteger(options.pages) || options.pages < 1)) return { allowed: false, reason: \"The reviewed page count must be a positive integer with no code ceiling.\" };\n if (!nonnegativeoption(options, \"wait\")) return { allowed: false, reason: \"The reviewed row freshness wait must be zero or a positive number of milliseconds.\" };\n }\n if (kind === \"exportcsv\" || kind === \"exportjson\" || kind === \"exportexcel\" || kind === \"copytable\" || kind === \"streamdisk\") {\n if (!isnonempty(options.dataset)) return { allowed: false, reason: \"A reviewed dataset id is required in options.\" };\n if (options.name !== undefined && !isnonempty(options.name)) return { allowed: false, reason: \"The reviewed artifact name must be a non-empty string.\" };\n }\n if (kind === \"exportcsv\" && options.delimiter !== undefined && (typeof options.delimiter !== \"string\" || options.delimiter.length !== 1)) return { allowed: false, reason: \"The reviewed csv delimiter must be a single character.\" };\n if (kind === \"streamdisk\" && (typeof options.chunk !== \"number\" || !Number.isInteger(options.chunk) || options.chunk < 1)) return { allowed: false, reason: \"The reviewed streaming chunk size must be a positive integer with no code ceiling.\" };\n if (kind === \"pushsheets\") {\n if (!isnonempty(options.dataset)) return { allowed: false, reason: \"A reviewed dataset id is required in options.\" };\n if (!isnonempty(options.sheet)) return { allowed: false, reason: \"A reviewed sheet endpoint url is required in options.\" };\n if (!ishttpsurl(options.sheet)) return { allowed: false, reason: \"The reviewed sheet endpoint url must use HTTPS.\" };\n if (options.reviewed !== true) return { allowed: false, reason: \"The sheet push needs the explicit reviewed flag before any data leaves local memory.\" };\n }\n if (kind === \"importcsv\") {\n if (typeof options.csv !== \"string\" || !options.csv.trim()) return { allowed: false, reason: \"Reviewed csv content is required in options.\" };\n if (options.name !== undefined && !isnonempty(options.name)) return { allowed: false, reason: \"The reviewed dataset name must be a non-empty string.\" };\n if (options.mapping !== undefined) {\n const mapping = options.mapping;\n if (!mapping || typeof mapping !== \"object\" || Array.isArray(mapping) || !Object.values(mapping).every(item => typeof item === \"string\")) return { allowed: false, reason: \"The reviewed csv column mapping must be an object of string values.\" };\n }\n }\n if (kind === \"looprows\") {\n if (!isnonempty(options.dataset)) return { allowed: false, reason: \"A reviewed dataset id is required in options.\" };\n if (options.variable !== undefined && !isnonempty(options.variable)) return { allowed: false, reason: \"The reviewed row variable name must be a non-empty string.\" };\n const inner = validateinnerstep(options, origin);\n if (!inner.allowed) return inner;\n }\n if (kind === \"transformvalues\") {\n if (!isnonempty(options.dataset)) return { allowed: false, reason: \"A reviewed dataset id is required in options.\" };\n const rules = options.rules;\n if (!Array.isArray(rules) || rules.length === 0) return { allowed: false, reason: \"A reviewed non-empty list of transform rules is required in options.\" };\n for (const item of rules) {\n const rulecheck = validatetransformrule(item);\n if (!rulecheck.allowed) return rulecheck;\n }\n }\n if (kind === \"deduperows\") {\n if (!isnonempty(options.dataset)) return { allowed: false, reason: \"A reviewed dataset id is required in options.\" };\n const keys = options.keys;\n if (!Array.isArray(keys) || keys.length === 0 || !keys.every(key => isnonempty(key))) return { allowed: false, reason: \"A reviewed non-empty list of dedupe column keys is required in options.\" };\n }\n if (kind === \"mergepages\") {\n const listcheck = validatedatasetids(options, \"datasets\");\n if (!listcheck.allowed) return listcheck;\n }\n if (kind === \"stamplerows\") {\n if (!isnonempty(options.dataset)) return { allowed: false, reason: \"A reviewed dataset id is required in options.\" };\n if (options.url !== undefined && !ishttpsurl(options.url)) return { allowed: false, reason: \"The reviewed source url must use HTTPS.\" };\n }\n if (kind === \"previewgrid\") {\n if (!isnonempty(options.dataset)) return { allowed: false, reason: \"A reviewed dataset id is required in options.\" };\n if (options.sample !== undefined && (typeof options.sample !== \"number\" || !Number.isInteger(options.sample) || options.sample < 1)) return { allowed: false, reason: \"The reviewed sample row count must be a positive integer with no code ceiling.\" };\n }\n if (kind === \"resumeextract\" && !isnonempty(options.session)) return { allowed: false, reason: \"A reviewed extract session id is required in options.\" };\n if (kind === \"logprovenance\" && !isnonempty(options.artifact)) return { allowed: false, reason: \"A reviewed artifact id or name is required in options.\" };\n return { allowed: true };\n}\n\n/** Validates a reviewed batch download specification: a non-empty HTTPS url list, an optional filename rule and an optional completion criterion. */\nexport function validatedownloadspec(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed downloadspec with a url list is required in options.\" };\n const spec = value as Record<string, unknown>;\n if (!Array.isArray(spec.urls) || spec.urls.length === 0 || !spec.urls.every(url => ishttpsurl(url))) return { allowed: false, reason: \"The reviewed downloadspec needs a non-empty list of HTTPS urls.\" };\n if (spec.filename !== undefined && !isnonempty(spec.filename)) return { allowed: false, reason: \"The reviewed downloadspec filename rule must be a non-empty string.\" };\n if (spec.complete !== undefined && spec.complete !== \"size\" && spec.complete !== \"checksum\") return { allowed: false, reason: \"The reviewed downloadspec completion criterion must be size or checksum.\" };\n return { allowed: true };\n}\n\n/** Validates a reviewed mime interception filter: include and exclude patterns plus the deny default for unlisted mime types. */\nexport function validatemimefilter(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed mimefilter with include and exclude patterns is required in options.\" };\n const filter = value as Record<string, unknown>;\n if (!Array.isArray(filter.include) || filter.include.length === 0 || !filter.include.every(pattern => isnonempty(pattern))) return { allowed: false, reason: \"The reviewed mimefilter needs a non-empty list of include patterns.\" };\n if (filter.exclude !== undefined && (!Array.isArray(filter.exclude) || !filter.exclude.every(pattern => isnonempty(pattern)))) return { allowed: false, reason: \"The reviewed mimefilter exclude patterns must be a list of non-empty strings.\" };\n if (filter.default !== \"deny\" && filter.default !== \"allow\") return { allowed: false, reason: \"The reviewed mimefilter needs the deny or allow default for unlisted mime types.\" };\n return { allowed: true };\n}\n\n/** Validates one reviewed cleanup rule: a positive age window with no code ceiling, an artifact kind and a keep policy. */\nexport function validatecleanuprule(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed cleanuprule with an age, a kind and a keep policy is required.\" };\n const rule = value as Record<string, unknown>;\n if (typeof rule.age !== \"number\" || !Number.isFinite(rule.age) || rule.age <= 0) return { allowed: false, reason: \"The reviewed cleanup age window must be a positive number of milliseconds with no code ceiling.\" };\n if (!isnonempty(rule.kind)) return { allowed: false, reason: \"The reviewed cleanup rule needs a non-empty artifact kind, or any to match every kind.\" };\n if (rule.keep !== \"none\" && rule.keep !== \"latest\" && rule.keep !== \"all\") return { allowed: false, reason: \"The reviewed cleanup keep policy must be none, latest or all.\" };\n return { allowed: true };\n}\n\n/** Validates the reviewed files, clipboard and downloads parameter grammar; batch sizes, concurrent windows and cleanup ages stay user configured with no code ceilings. */\nfunction validatefilesgrammar(step: toolstep, options: Record<string, unknown>): policyevaluation {\n const kind = step.kind;\n if (kind === \"batchdownload\") {\n const speccheck = validatedownloadspec(options.downloadspec);\n if (!speccheck.allowed) return speccheck;\n if (options.concurrent !== undefined && (typeof options.concurrent !== \"number\" || !Number.isInteger(options.concurrent) || options.concurrent < 1)) return { allowed: false, reason: \"The reviewed concurrent download window must be a positive integer with no code ceiling.\" };\n }\n if (kind === \"pausedownload\" || kind === \"resumedownload\" || kind === \"verifydownload\" || kind === \"quarantinedownload\" || kind === \"scanvirus\") {\n if (!isnonempty(step.value)) return { allowed: false, reason: \"A reviewed download or quarantine reference is required.\" };\n if (kind === \"verifydownload\") {\n if (options.checksum !== undefined && !isnonempty(options.checksum)) return { allowed: false, reason: \"The reviewed expected checksum must be a non-empty string.\" };\n if (options.bytes !== undefined && (typeof options.bytes !== \"number\" || !Number.isFinite(options.bytes) || options.bytes < 0)) return { allowed: false, reason: \"The reviewed expected size must be zero or a positive number of bytes.\" };\n }\n if (kind === \"scanvirus\" && options.scanner !== undefined && !isnonempty(options.scanner)) return { allowed: false, reason: \"The reviewed scanner name must be a non-empty string.\" };\n if (kind === \"quarantinedownload\" && options.reason !== undefined && !isnonempty(options.reason)) return { allowed: false, reason: \"The reviewed quarantine reason must be a non-empty string.\" };\n }\n if (kind === \"interceptmime\") {\n const filtercheck = validatemimefilter(options.mimefilter);\n if (!filtercheck.allowed) return filtercheck;\n }\n if (kind === \"readclipboard\") {\n if (!isnonempty(options.consentref)) return { allowed: false, reason: \"A clipboard read requires a reviewed consent ref of an approved consent prompt in options.\" };\n if (options.prompt !== undefined && !isnonempty(options.prompt)) return { allowed: false, reason: \"The reviewed clipboard consent prompt must be a non-empty string.\" };\n }\n if (kind === \"exportnetlog\" && options.stepid !== undefined && !isnonempty(options.stepid)) return { allowed: false, reason: \"The reviewed netlog step filter must be a non-empty step id.\" };\n if (kind === \"namecaptures\") {\n if (!isnonempty(options.task)) return { allowed: false, reason: \"A reviewed task id is required in options for capture naming.\" };\n if (options.steps !== undefined && (!Array.isArray(options.steps) || options.steps.length === 0 || !options.steps.every(item => isnonempty(item)))) return { allowed: false, reason: \"The reviewed capture steps must be a non-empty list of step ids when present.\" };\n if (options.extension !== undefined && !isnonempty(options.extension)) return { allowed: false, reason: \"The reviewed capture extension must be a non-empty string.\" };\n }\n if (kind === \"cleanupartifacts\" && options.rules !== undefined) {\n const rules = options.rules;\n if (!Array.isArray(rules) || rules.length === 0) return { allowed: false, reason: \"The reviewed cleanup rules must be a non-empty list when present.\" };\n for (const item of rules) {\n const rulecheck = validatecleanuprule(item);\n if (!rulecheck.allowed) return rulecheck;\n }\n }\n return { allowed: true };\n}\n\n/** Requires an approved consent prompt before any clipboard read; every read consumes its own prompt. */\nexport function clipboardconsentgranted(step: toolstep): policyevaluation {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n const consentref = options.consentref;\n if (typeof consentref !== \"string\" || !consentref.trim()) return { allowed: false, reason: \"A clipboard read requires a reviewed consent ref in options.\" };\n return { allowed: true };\n}\n\n/** Refuses to release any quarantined file before a clean scan verdict exists. */\nexport function quarantinereleasegranted(entry: quarantineentry): policyevaluation {\n if (entry.scan !== \"clean\") return { allowed: false, reason: `The quarantined file ${entry.path} cannot leave quarantine with the ${entry.scan} scan verdict; only a clean verdict releases it.` };\n return { allowed: true };\n}\n\n/** Refuses downloads and download interception that fall outside the session origin grants. */\nexport function downloadgranted(session: agentsession | undefined, url: string): policyevaluation {\n let origin = \"\";\n try { origin = new URL(url).origin; } catch { return { allowed: false, reason: \"The reviewed download URL is invalid.\" }; }\n if (!origingranted(session, origin)) return { allowed: false, reason: `The download from ${origin} leaves the session origin grants and needs a session grant first.` };\n return { allowed: true };\n}\n\n/** Masks a clipboard payload for every log line; the full text never persists anywhere. */\nexport function maskclipboard(payload: string): string {\n return `[clipboard payload of ${payload.length} character${payload.length === 1 ? \"\" : \"s\"}]`;\n}\n\n/** Requires an asksubmit review step before every form submission step. */\nexport function submitreviewgranted(steps: toolstep[], submitid: string): policyevaluation {\n const position = steps.findIndex(candidate => candidate.id === submitid);\n const asked = steps.some((candidate, index) => candidate.kind === \"asksubmit\" && (position === -1 || index < position));\n return asked ? { allowed: true } : { allowed: false, reason: \"Form submission requires an asksubmit review step before it.\" };\n}\n\n/** Requires a reviewed consent ref before any password field is filled. */\nexport function passwordconsentgranted(step: toolstep): policyevaluation {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n const consentref = options.consentref;\n if (typeof consentref !== \"string\" || !consentref.trim()) return { allowed: false, reason: \"A password fill requires a reviewed consent ref in options.\" };\n return { allowed: true };\n}\n\n/** True when a numeric value passes the Luhn checksum used by card networks. */\nfunction luhnvalid(digits: string): boolean {\n let sum = 0;\n let double = false;\n for (let index = digits.length - 1; index >= 0; index -= 1) {\n let value = Number.parseInt(digits[index] ?? \"\", 10);\n if (!Number.isFinite(value)) return false;\n if (double) { value *= 2; if (value > 9) value -= 9; }\n sum += value;\n double = !double;\n }\n return sum % 10 === 0;\n}\n\n/** Refuses generated values that look like real card numbers or personal identifiers; test prefixed card values stay allowed. */\nexport function generatedvalueallowed(value: string): policyevaluation {\n const compact = value.replace(/[\\s-]/g, \"\");\n if (/^\\d{13,19}$/.test(compact) && luhnvalid(compact) && !compact.startsWith(\"4111\")) return { allowed: false, reason: \"The generated value looks like a real card number and is refused; generated card values use the 4111 test prefix.\" };\n if (/^\\d{3}-\\d{2}-\\d{4}$/.test(value.trim())) return { allowed: false, reason: \"The generated value looks like a personal identifier and is refused.\" };\n return { allowed: true };\n}\n\n/** Requires the origin grants of a saved profile to cover the origin before its values fill a page. */\nexport function profilegrantgranted(profile: formprofile, origin: string): policyevaluation {\n if (!profile.grants.includes(origin)) return { allowed: false, reason: `The saved profile ${profile.name} is not granted to ${origin}; add the origin to the profile grants first.` };\n return { allowed: true };\n}\n\n/** Restricts group and layout mutations to the active session: they refuse without a live session. */\nexport function layoutmutationgranted(session: agentsession | undefined, now: number): policyevaluation {\n if (!session || session.stoppedat || session.expiresat <= now) return { allowed: false, reason: \"Group and layout mutations stay inside the active session.\" };\n return { allowed: true };\n}\n\n/** Requires explicit review before closing a window that holds more than one task tab. */\nexport function windowclosegate(tasktabcount: number, reviewed: boolean): policyevaluation {\n if (tasktabcount > 1 && !reviewed) return { allowed: false, reason: `The window holds ${tasktabcount} task tabs and needs explicit review before it closes.` };\n return { allowed: true };\n}\n\n/** Reads the user configured concurrent task tab ceiling; an absent value never refuses a tab. */\nexport function tasktabceiling(settings: runsettings | undefined): number | undefined {\n const ceiling = settings?.tasktabceiling;\n return typeof ceiling === \"number\" && Number.isFinite(ceiling) && ceiling >= 0 ? ceiling : undefined;\n}\n\n/** Parses the reviewed wait duration of a wait step with no upper bound. */\nexport function waitduration(step: toolstep): number {\n const requested = step.value ? Number.parseInt(step.value, 10) : 250;\n if (!Number.isFinite(requested) || requested < 0) throw new Error(\"Wait duration must be zero or a positive number of milliseconds.\");\n return requested;\n}\n\nfunction isnumericid(value: unknown): value is string {\n return typeof value === \"string\" && /^\\d+$/.test(value);\n}\n\nfunction numericoption(options: Record<string, unknown>, key: string): boolean {\n return options[key] === undefined || (typeof options[key] === \"number\" && Number.isFinite(options[key] as number));\n}\n\n/** True when an optional numeric option is absent or a finite number of zero or more. */\nfunction nonnegativeoption(options: Record<string, unknown>, key: string): boolean {\n return numericoption(options, key) && !(typeof options[key] === \"number\" && (options[key] as number) < 0);\n}\n\nfunction isnonempty(value: unknown): value is string {\n return typeof value === \"string\" && value.trim().length > 0;\n}\n\nfunction ispoint(value: unknown): boolean {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n const point = value as Record<string, unknown>;\n return typeof point.x === \"number\" && Number.isFinite(point.x) && typeof point.y === \"number\" && Number.isFinite(point.y);\n}\n\n/** Grades a resolution match count: zero is absent, one is resolved and more than one is refused as ambiguous. */\nexport function resolutionverdict(count: number): \"absent\" | \"resolved\" | \"ambiguous\" {\n if (!Number.isFinite(count) || count <= 0) return \"absent\";\n return count === 1 ? \"resolved\" : \"ambiguous\";\n}\n\n/** Validates the reviewed targetref grammar of every resolution mode and rejects empty references. */\nexport function validatetargetref(reference: unknown): policyevaluation {\n if (!reference || typeof reference !== \"object\" || Array.isArray(reference)) return { allowed: false, reason: \"The reviewed target reference must be an object.\" };\n const ref = reference as Record<string, unknown>;\n if (ref.mode === \"selector\") return isnonempty(ref.selector) ? { allowed: true } : { allowed: false, reason: \"The selector target reference needs a non-empty selector.\" };\n if (ref.mode === \"text\") return isnonempty(ref.text) ? { allowed: true } : { allowed: false, reason: \"The text target reference needs non-empty text.\" };\n if (ref.mode === \"aria\") {\n if (!isnonempty(ref.role)) return { allowed: false, reason: \"The aria target reference needs a non-empty role.\" };\n return isnonempty(ref.name) ? { allowed: true } : { allowed: false, reason: \"The aria target reference needs a non-empty name.\" };\n }\n if (ref.mode === \"name\") return isnonempty(ref.name) ? { allowed: true } : { allowed: false, reason: \"The name target reference needs a non-empty name.\" };\n if (ref.mode === \"xpath\") return isnonempty(ref.xpath) ? { allowed: true } : { allowed: false, reason: \"The xpath target reference needs a non-empty expression.\" };\n if (ref.mode === \"index\") {\n const index = ref.index;\n return typeof index === \"number\" && Number.isInteger(index) && index >= 1 ? { allowed: true } : { allowed: false, reason: \"The index target reference needs a positive integer map number.\" };\n }\n if (ref.mode === \"point\") {\n const pointok = typeof ref.x === \"number\" && Number.isFinite(ref.x) && typeof ref.y === \"number\" && Number.isFinite(ref.y);\n return pointok ? { allowed: true } : { allowed: false, reason: \"The point target reference needs numeric x and y coordinates.\" };\n }\n return { allowed: false, reason: \"The target reference mode must be selector, text, aria, name, xpath, index or point.\" };\n}\n\n/** True when the session origin grants cover the given origin; a session without grants only allows its own origin. */\nexport function origingranted(session: agentsession | undefined, origin: string): boolean {\n if (!session) return false;\n const grants = session.grants ?? [session.origin];\n return grants.includes(origin);\n}\n\n/** Decides whether an unreviewed origin may open: the session grants cover it or a safe checksafe verdict vouches for it. */\nexport function originverified(url: string, grants: string[], verdicts: safetyverdict[]): policyevaluation {\n let origin = \"\";\n try { origin = new URL(url).origin; } catch { return { allowed: false, reason: \"The reviewed navigation URL is invalid.\" }; }\n if (grants.includes(origin)) return { allowed: true };\n const covered = verdicts.find(verdict => verdict.safe && (verdict.url === url || (safeorigin(verdict.url) === origin)));\n if (covered) return { allowed: true };\n return { allowed: false, reason: `The origin ${origin} is outside the session grants and has no safe checksafe verdict; run checksafe and review it first.` };\n}\n\nfunction safeorigin(url: string): string {\n try { return new URL(url).origin; } catch { return \"\"; }\n}\n\n/** Refuses navigation that would move a granted task tab outside the session origin grants until the user consents. */\nexport function navigationgranted(session: agentsession | undefined, url: string): policyevaluation {\n let origin = \"\";\n try { origin = new URL(url).origin; } catch { return { allowed: false, reason: \"The reviewed navigation URL is invalid.\" }; }\n if (origingranted(session, origin)) return { allowed: true };\n return { allowed: false, reason: `Navigation to ${origin} leaves the task tab origins and needs the user consent of a session grant first.` };\n}\n\n/** Validates the reviewed inner step of a retry or frame wrapper against the same rules as a top-level step. */\nfunction validateinnerstep(options: Record<string, unknown>, origin: string): policyevaluation {\n const stepid = options.stepid;\n const kind = options.kind;\n if (isnonempty(stepid)) {\n if (kind !== undefined) return { allowed: false, reason: \"The reviewed wrapper must reference a step id or an inline step, not both.\" };\n return { allowed: true };\n }\n if (typeof kind !== \"string\" || !kind.trim()) return { allowed: false, reason: \"A reviewed step id or inline step kind is required in options.\" };\n if (kind === \"retryaction\" || kind === \"enterframe\" || kind === \"looprows\") return { allowed: false, reason: \"The reviewed inner step cannot be another wrapper kind.\" };\n if (!allowedactions.has(kind as actionkind)) return { allowed: false, reason: \"The reviewed inner step kind is unsupported.\" };\n const inneroptions = options.options;\n if (inneroptions !== undefined && (!inneroptions || typeof inneroptions !== \"object\" || Array.isArray(inneroptions))) return { allowed: false, reason: \"The reviewed inner step options must be an object.\" };\n const inner: toolstep = {\n id: \"inner\",\n kind: kind as actionkind,\n summary: \"Reviewed inner step.\",\n risk: actionrisk(kind as actionkind),\n ...(isnonempty(options.target) ? { target: options.target } : {}),\n ...(isnonempty(options.value) ? { value: options.value } : {}),\n ...(inneroptions !== undefined ? { options: JSON.stringify(inneroptions) } : {}),\n };\n return validatestep(inner, origin);\n}\n\n/** True when a reviewed https url parses. */\nfunction ishttpsurl(value: unknown): value is string {\n if (typeof value !== \"string\" || !value.trim()) return false;\n try { return new URL(value).protocol === \"https:\"; } catch { return false; }\n}\n\n/** Validates the reviewed navtarget grammar of a navigation step. */\nfunction validatenavtarget(value: unknown, kind: string): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed navtarget with a url is required in options.\" };\n const target = value as Record<string, unknown>;\n if (!ishttpsurl(target.url)) return { allowed: false, reason: \"The reviewed navtarget url must use HTTPS.\" };\n const container = target.container ?? \"tab\";\n if (container !== \"current\" && container !== \"tab\" && container !== \"window\" && container !== \"private\") return { allowed: false, reason: \"The reviewed navtarget container must be current, tab, window or private.\" };\n if (target.position !== undefined && target.position !== \"adjacent\" && target.position !== \"end\") return { allowed: false, reason: \"The reviewed navtarget position must be adjacent or end.\" };\n if (kind === \"openprivate\" && container !== \"private\") return { allowed: false, reason: \"The openprivate step requires the private container.\" };\n if (kind === \"openlink\" && container === \"private\") return { allowed: false, reason: \"The openlink step cannot open the private container; use openprivate.\" };\n return { allowed: true };\n}\n\n/** Validates the reviewed waitprofile grammar with its load signals, thresholds and per origin overrides. */\nfunction validatewaitprofile(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed waitprofile with load signals is required in options.\" };\n const profile = value as Record<string, unknown>;\n if (!Array.isArray(profile.signals) || profile.signals.length === 0 || !profile.signals.every(signal => isnonempty(signal))) return { allowed: false, reason: \"The reviewed waitprofile needs a non-empty list of load signals.\" };\n if (!nonnegativeoption(profile, \"idle\")) return { allowed: false, reason: \"The reviewed waitprofile idle threshold must be zero or a positive number of milliseconds.\" };\n if (!nonnegativeoption(profile, \"timeout\")) return { allowed: false, reason: \"The reviewed waitprofile timeout must be zero or a positive number of milliseconds.\" };\n if (profile.overrides !== undefined) {\n if (!Array.isArray(profile.overrides) || profile.overrides.length === 0) return { allowed: false, reason: \"The reviewed waitprofile overrides must be a non-empty list when present.\" };\n for (const entry of profile.overrides) {\n if (!entry || typeof entry !== \"object\" || Array.isArray(entry)) return { allowed: false, reason: \"Every reviewed waitprofile override must be an object with an origin.\" };\n const override = entry as Record<string, unknown>;\n if (!ishttpsurl(override.origin)) return { allowed: false, reason: \"Every reviewed waitprofile override origin must use HTTPS.\" };\n if (override.signals !== undefined && (!Array.isArray(override.signals) || !override.signals.every(signal => isnonempty(signal)))) return { allowed: false, reason: \"The reviewed waitprofile override signals must be a list of non-empty strings.\" };\n if (!nonnegativeoption(override, \"idle\") || !nonnegativeoption(override, \"timeout\")) return { allowed: false, reason: \"The reviewed waitprofile override thresholds must be zero or positive numbers.\" };\n }\n }\n return { allowed: true };\n}\n\n/** Validates the reviewed urlpattern grammar with its match mode plus query and fragment parts. */\nexport function validateurlpattern(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed urlpattern is required in options.\" };\n const pattern = value as Record<string, unknown>;\n if (pattern.mode !== \"exact\" && pattern.mode !== \"prefix\" && pattern.mode !== \"host\" && pattern.mode !== \"pattern\") return { allowed: false, reason: \"The reviewed urlpattern mode must be exact, prefix, host or pattern.\" };\n if (!ishttpsurl(pattern.url)) return { allowed: false, reason: \"The reviewed urlpattern url must use HTTPS.\" };\n if (pattern.query !== undefined) {\n if (!pattern.query || typeof pattern.query !== \"object\" || Array.isArray(pattern.query)) return { allowed: false, reason: \"The reviewed urlpattern query part must be an object of parameter names and values.\" };\n for (const item of Object.values(pattern.query)) if (typeof item !== \"string\") return { allowed: false, reason: \"The reviewed urlpattern query values must be strings.\" };\n }\n if (pattern.fragment !== undefined && !isnonempty(pattern.fragment)) return { allowed: false, reason: \"The reviewed urlpattern fragment must be a non-empty string.\" };\n return { allowed: true };\n}\n\n/** Validates a reviewed non-empty list of HTTPS urls in options. */\nfunction validateurllist(options: Record<string, unknown>, key: string): policyevaluation {\n const urls = options[key];\n if (!Array.isArray(urls) || urls.length === 0 || !urls.every(url => ishttpsurl(url))) return { allowed: false, reason: `A reviewed non-empty list of HTTPS urls is required in options as ${key}.` };\n return { allowed: true };\n}\n\n/** Validates the reviewed ratelimit grammar of a navrate step; the window and ceiling stay user configured with no hardcoded cap. */\nfunction validateratelimit(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed ratelimit with a window and a ceiling is required in options.\" };\n const limit = value as Record<string, unknown>;\n if (limit.domain !== undefined && !isnonempty(limit.domain)) return { allowed: false, reason: \"The reviewed ratelimit domain must be a non-empty string.\" };\n if (typeof limit.window !== \"number\" || !Number.isFinite(limit.window) || limit.window <= 0) return { allowed: false, reason: \"The reviewed ratelimit window must be a positive number of milliseconds with no code ceiling.\" };\n if (typeof limit.ceiling !== \"number\" || !Number.isInteger(limit.ceiling) || limit.ceiling < 1) return { allowed: false, reason: \"The reviewed ratelimit ceiling must be a positive integer with no code ceiling.\" };\n return { allowed: true };\n}\n\n/** Validates the reviewed tabquery grammar with url, title, id and pattern matchers; at least one matcher is required. */\nexport function validatetabquery(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed tabquery with at least one matcher is required in options.\" };\n const query = value as Record<string, unknown>;\n const hasmatcher = query.url !== undefined || query.title !== undefined || query.id !== undefined || query.pattern !== undefined;\n if (!hasmatcher) return { allowed: false, reason: \"The reviewed tabquery needs a url, title, id or pattern matcher.\" };\n if (query.url !== undefined && !isnonempty(query.url)) return { allowed: false, reason: \"The reviewed tabquery url matcher must be a non-empty string.\" };\n if (query.title !== undefined && !isnonempty(query.title)) return { allowed: false, reason: \"The reviewed tabquery title matcher must be a non-empty string.\" };\n if (query.pattern !== undefined && !isnonempty(query.pattern)) return { allowed: false, reason: \"The reviewed tabquery pattern matcher must be a non-empty string.\" };\n if (query.id !== undefined && (typeof query.id !== \"number\" || !Number.isInteger(query.id) || query.id < 0)) return { allowed: false, reason: \"The reviewed tabquery id matcher must be a non-negative integer tab id.\" };\n return { allowed: true };\n}\n\n/** Validates a reviewed group color choice against the Chromium tab group palette. */\nfunction validategroupcolor(value: unknown): boolean {\n return typeof value === \"string\" && (groupcolors as string[]).includes(value);\n}\n\n/** Validates a reviewed list of numeric browser ids in options. */\nfunction validateidlist(options: Record<string, unknown>, key: string): boolean {\n const ids = options[key];\n return Array.isArray(ids) && ids.length > 0 && ids.every(id => typeof id === \"number\" && Number.isInteger(id) && id >= 0);\n}\n\n/** Validates the reviewed tab and window parameter grammar of the tabs and windows command family. */\nfunction validatetabsgrammar(step: toolstep, options: Record<string, unknown>): policyevaluation {\n const kind = step.kind;\n if (kind === \"querytabs\" || kind === \"closepattern\") {\n const querycheck = validatetabquery(options.tabquery);\n if (!querycheck.allowed) return querycheck;\n if (kind === \"closepattern\" && options.reviewed !== true) return { allowed: false, reason: \"The close pattern needs the explicit reviewed flag before any tab closes.\" };\n }\n if (kind === \"duplicatetab\" || kind === \"pintab\" || kind === \"mutetab\" || kind === \"movetab\" || kind === \"movetabwindow\" || kind === \"badgetab\" || kind === \"attachmeta\") {\n if (!isnumericid(step.value)) return { allowed: false, reason: \"A numeric browser tab id is required.\" };\n }\n if (kind === \"focuswindow\" || kind === \"maximizewindow\" || kind === \"minimizewindow\" || kind === \"restorewindow\") {\n if (!isnumericid(step.value)) return { allowed: false, reason: \"A numeric browser window id is required.\" };\n }\n if (kind === \"pintab\" && typeof options.pinned !== \"boolean\") return { allowed: false, reason: \"A reviewed pinned flag is required in options.\" };\n if (kind === \"mutetab\" && typeof options.muted !== \"boolean\") return { allowed: false, reason: \"A reviewed muted flag is required in options.\" };\n if (kind === \"movetab\") {\n if (typeof options.index !== \"number\" || !Number.isInteger(options.index) || options.index < 0) return { allowed: false, reason: \"A reviewed non-negative target index is required in options.\" };\n }\n if (kind === \"movetabwindow\") {\n if (typeof options.windowid !== \"number\" || !Number.isInteger(options.windowid) || options.windowid < 0) return { allowed: false, reason: \"A reviewed target window id is required in options.\" };\n }\n if (kind === \"grouptabs\") {\n const group = options.group;\n if (!group || typeof group !== \"object\" || Array.isArray(group)) return { allowed: false, reason: \"A reviewed group with a name is required in options.\" };\n const spec = group as Record<string, unknown>;\n if (!isnonempty(spec.name)) return { allowed: false, reason: \"The reviewed group needs a non-empty name.\" };\n if (!validategroupcolor(spec.color)) return { allowed: false, reason: \"The reviewed group color must be a Chromium tab group color.\" };\n if (!validateidlist(spec, \"tabids\")) return { allowed: false, reason: \"The reviewed group needs a non-empty list of member tab ids.\" };\n }\n if (kind === \"colorgroup\") {\n if (!isnonempty(options.name)) return { allowed: false, reason: \"A reviewed group name is required in options.\" };\n if (!validategroupcolor(options.color)) return { allowed: false, reason: \"The reviewed group color must be a Chromium tab group color.\" };\n }\n if (kind === \"collapsegroup\") {\n if (!isnonempty(options.name)) return { allowed: false, reason: \"A reviewed group name is required in options.\" };\n if (typeof options.collapsed !== \"boolean\") return { allowed: false, reason: \"A reviewed collapsed flag is required in options.\" };\n }\n if (kind === \"discardtab\" || kind === \"reloadtabs\") {\n if (!isnumericid(step.value) && !validateidlist(options, \"tabs\")) return { allowed: false, reason: \"A numeric tab id or a reviewed list of tab ids is required.\" };\n }\n if (kind === \"zoomin\" || kind === \"zoomout\") {\n if (options.step !== undefined && (typeof options.step !== \"number\" || !Number.isFinite(options.step) || options.step <= 0)) return { allowed: false, reason: \"The reviewed zoom step must be a positive number with no code ceiling.\" };\n if (step.value !== undefined && step.value !== \"\" && !isnumericid(step.value)) return { allowed: false, reason: \"The reviewed zoom target must be a numeric tab id.\" };\n }\n if (kind === \"switchtab\") {\n if (options.direction !== \"next\" && options.direction !== \"previous\") return { allowed: false, reason: \"A reviewed switch direction of next or previous is required in options.\" };\n }\n if (kind === \"restorewindow\") {\n const bounds = options.bounds;\n if (bounds !== undefined) {\n if (!bounds || typeof bounds !== \"object\" || Array.isArray(bounds)) return { allowed: false, reason: \"The reviewed window bounds must be an object.\" };\n const shape = bounds as Record<string, unknown>;\n for (const field of [\"left\", \"top\", \"width\", \"height\"]) {\n if (typeof shape[field] !== \"number\" || !Number.isFinite(shape[field])) return { allowed: false, reason: \"The reviewed window bounds need numeric left, top, width and height.\" };\n }\n }\n }\n if (kind === \"scratchwindow\") {\n if (step.value !== undefined && step.value !== \"\" && !ishttpsurl(step.value)) return { allowed: false, reason: \"The reviewed scratch window url must use HTTPS.\" };\n }\n if (kind === \"incognitowindow\" && !ishttpsurl(step.value)) return { allowed: false, reason: \"A reviewed HTTPS url is required to open an incognito window.\" };\n if (kind === \"restoretab\" && step.value !== undefined && step.value !== \"\" && !ishttpsurl(step.value)) return { allowed: false, reason: \"The reviewed restore url must use HTTPS.\" };\n if (kind === \"savelayout\" || kind === \"restorelayout\") {\n if (!isnonempty(options.name)) return { allowed: false, reason: \"A reviewed layout name is required in options.\" };\n }\n if (kind === \"badgetab\") {\n if (!isnonempty(options.label)) return { allowed: false, reason: \"A reviewed badge label is required in options.\" };\n if (options.taskid !== undefined && !isnonempty(options.taskid)) return { allowed: false, reason: \"The reviewed badge task id must be a non-empty string.\" };\n }\n if (kind === \"attachmeta\") {\n const labels = options.labels;\n const taskrefs = options.taskrefs;\n const haslabels = Array.isArray(labels) && labels.length > 0 && labels.every(label => isnonempty(label));\n const hastaskrefs = Array.isArray(taskrefs) && taskrefs.length > 0 && taskrefs.every(ref => isnonempty(ref));\n if (!haslabels && !hastaskrefs) return { allowed: false, reason: \"Reviewed labels or task refs are required in options to attach metadata.\" };\n if (options.provenance !== undefined && !isnonempty(options.provenance)) return { allowed: false, reason: \"The reviewed provenance must be a non-empty string.\" };\n }\n if (kind === \"reopenrun\" && !isnonempty(options.run)) return { allowed: false, reason: \"A reviewed run id is required in options to reopen its tabs.\" };\n return { allowed: true };\n}\n\n/** Validates a single proposal against the active tab origin and local policy. */\nexport function validatestep(step: toolstep, origin: string): policyevaluation {\n if (!allowedactions.has(step.kind)) return { allowed: false, reason: \"Unsupported action kind.\" };\n if (!step.summary.trim()) return { allowed: false, reason: \"A human-readable action summary is required.\" };\n let options: Record<string, unknown>;\n try { options = parseoptions(step); } catch { return { allowed: false, reason: \"Step options must be a JSON object.\" }; }\n const hastargetref = options.targetref !== undefined;\n if (targetactions.has(step.kind) && !step.target?.trim() && !hastargetref) return { allowed: false, reason: \"A page target is required.\" };\n if (valueactions.has(step.kind) && !step.value?.trim()) return { allowed: false, reason: \"A reviewed value is required.\" };\n if (step.kind === \"select\" && !step.value?.trim()) return { allowed: false, reason: \"A reviewed option value is required.\" };\n if (step.kind === \"navigate\" && !step.value) return { allowed: false, reason: \"A navigation URL is required.\" };\n if (hastargetref) {\n const reference = validatetargetref(options.targetref);\n if (!reference.allowed) return reference;\n }\n if (step.kind === \"wait\") {\n try { waitduration(step); } catch { return { allowed: false, reason: \"Wait duration must be zero or a positive number of milliseconds.\" }; }\n }\n if (step.kind === \"navigate\") {\n try {\n if (new URL(step.value ?? \"\").origin !== origin) return { allowed: false, reason: \"Navigation must remain within the approved origin.\" };\n } catch {\n return { allowed: false, reason: \"Navigation URL is invalid.\" };\n }\n }\n if (step.kind === \"tabcreate\" || step.kind === \"windowcreate\" || step.kind === \"downloadfile\") {\n try {\n const url = new URL(step.value ?? \"\");\n if (url.protocol !== \"https:\") return { allowed: false, reason: \"The reviewed URL must use HTTPS.\" };\n } catch {\n return { allowed: false, reason: \"The reviewed URL is invalid.\" };\n }\n }\n if (step.kind === \"tabactivate\" || step.kind === \"tabclose\" || step.kind === \"tabreload\" || step.kind === \"windowclose\" || step.kind === \"windowresize\") {\n if (!isnumericid(step.value)) return { allowed: false, reason: \"A numeric browser id is required.\" };\n }\n if (step.kind === \"zoomset\") {\n const zoom = Number(step.value);\n if (!Number.isFinite(zoom) || zoom <= 0) return { allowed: false, reason: \"The reviewed zoom must be a positive number.\" };\n }\n if (step.kind === \"setattribute\" || step.kind === \"writestorage\") {\n const keyname = step.kind === \"setattribute\" ? \"name\" : \"key\";\n if (typeof options[keyname] !== \"string\" || !(options[keyname] as string).trim()) return { allowed: false, reason: `A reviewed ${keyname} is required in options.` };\n if (typeof options.value !== \"string\") return { allowed: false, reason: \"A reviewed value is required in options.\" };\n }\n if (step.kind === \"windowresize\") {\n if (typeof options.width !== \"number\" || typeof options.height !== \"number\" || !Number.isFinite(options.width) || !Number.isFinite(options.height)) return { allowed: false, reason: \"Reviewed width and height numbers are required in options.\" };\n }\n if ((step.kind === \"scrollpage\" || step.kind === \"scrollby\") && (!numericoption(options, \"x\") || !numericoption(options, \"y\"))) return { allowed: false, reason: \"Scroll amounts must be numbers in options.\" };\n if (step.kind === \"waitfor\" && options.timeout !== undefined && (typeof options.timeout !== \"number\" || options.timeout < 0)) return { allowed: false, reason: \"The waitfor timeout must be zero or a positive number of milliseconds.\" };\n if (step.kind === \"movepointer\") {\n const path = options.pointpath;\n if (!path || typeof path !== \"object\" || Array.isArray(path)) return { allowed: false, reason: \"A reviewed pointpath with start and end points is required in options.\" };\n const points = path as Record<string, unknown>;\n if (!ispoint(points.start) || !ispoint(points.end)) return { allowed: false, reason: \"The reviewed pointpath needs numeric start and end points.\" };\n if (points.waypoints !== undefined && (!Array.isArray(points.waypoints) || !points.waypoints.every(waypoint => ispoint(waypoint)))) return { allowed: false, reason: \"The reviewed pointpath waypoints must be numeric points.\" };\n if (!nonnegativeoption(points, \"duration\")) return { allowed: false, reason: \"The reviewed pointpath duration must be zero or a positive number of milliseconds.\" };\n const speed = options.speedprofile;\n if (speed !== undefined) {\n if (!speed || typeof speed !== \"object\" || Array.isArray(speed)) return { allowed: false, reason: \"The reviewed speed profile must be an object.\" };\n const profile = speed as Record<string, unknown>;\n if (profile.easing !== undefined && profile.easing !== \"linear\" && profile.easing !== \"easeinout\") return { allowed: false, reason: \"The reviewed easing must be linear or easeinout.\" };\n if (!nonnegativeoption(profile, \"peak\")) return { allowed: false, reason: \"The reviewed peak velocity must be zero or a positive number.\" };\n if (!nonnegativeoption(profile, \"jitter\")) return { allowed: false, reason: \"The reviewed jitter window must be zero or a positive number of milliseconds.\" };\n }\n }\n if (step.kind === \"clickpoint\" && (!hastargetref || (options.targetref as Record<string, unknown>).mode !== \"point\")) return { allowed: false, reason: \"A reviewed point target reference is required in options.\" };\n if (step.kind === \"clicktext\" && (!hastargetref || (options.targetref as Record<string, unknown>).mode !== \"text\")) return { allowed: false, reason: \"A reviewed text target reference is required in options.\" };\n if (step.kind === \"clickaria\" && (!hastargetref || (options.targetref as Record<string, unknown>).mode !== \"aria\")) return { allowed: false, reason: \"A reviewed aria target reference is required in options.\" };\n if (step.kind === \"clickname\" && (!hastargetref || (options.targetref as Record<string, unknown>).mode !== \"name\")) return { allowed: false, reason: \"A reviewed name target reference is required in options.\" };\n if (step.kind === \"resolvexpath\" && (!hastargetref || (options.targetref as Record<string, unknown>).mode !== \"xpath\")) return { allowed: false, reason: \"A reviewed xpath target reference is required in options.\" };\n if (step.kind === \"typetime\" && options.delay !== undefined && (typeof options.delay !== \"number\" || !Number.isFinite(options.delay) || options.delay < 0)) return { allowed: false, reason: \"The reviewed per keystroke delay must be zero or a positive number of milliseconds.\" };\n if (step.kind === \"submitsearch\") {\n if (!isnonempty(options.results)) return { allowed: false, reason: \"A reviewed results region selector is required in options.\" };\n if (options.timeout !== undefined && (typeof options.timeout !== \"number\" || !Number.isFinite(options.timeout) || options.timeout < 0)) return { allowed: false, reason: \"The submitsearch timeout must be zero or a positive number of milliseconds.\" };\n }\n if (step.kind === \"selectmulti\") {\n const values = options.values;\n if (!Array.isArray(values) || values.length === 0 || !values.every(value => isnonempty(value))) return { allowed: false, reason: \"A reviewed list of option values is required in options.\" };\n }\n if (step.kind === \"setslider\") {\n const slider = Number(step.value);\n if (!Number.isFinite(slider)) return { allowed: false, reason: \"The reviewed slider value must be a number.\" };\n }\n if (step.kind === \"setdate\" && !/^\\d{4}-\\d{2}-\\d{2}$/.test(step.value ?? \"\")) return { allowed: false, reason: \"The reviewed date must use the yyyy-mm-dd form.\" };\n if (step.kind === \"setcolor\" && !/^#[0-9a-fA-F]{6}$/.test(step.value ?? \"\")) return { allowed: false, reason: \"The reviewed color must use the #rrggbb form.\" };\n if (step.kind === \"keyhold\" && options.holdid !== undefined && !isnonempty(options.holdid)) return { allowed: false, reason: \"The reviewed hold id must be a non-empty string.\" };\n if (step.kind === \"dismissdialog\") {\n const accept = options.accept;\n const answer = options.answer;\n if (accept === undefined && !isnonempty(answer)) return { allowed: false, reason: \"A reviewed accept flag or prompt answer is required in options.\" };\n if (accept !== undefined && typeof accept !== \"boolean\") return { allowed: false, reason: \"The reviewed dialog accept flag must be a boolean.\" };\n if (answer !== undefined && !isnonempty(answer)) return { allowed: false, reason: \"The reviewed prompt answer must be a non-empty string.\" };\n }\n if (step.kind === \"pierceshadow\" && options.shadow !== undefined) {\n if (!Array.isArray(options.shadow) || !options.shadow.every(item => isnonempty(item))) return { allowed: false, reason: \"The reviewed shadow path must be a list of non-empty selectors.\" };\n }\n if (step.kind === \"enterframe\") {\n const path = options.framepath;\n if (!Array.isArray(path) || path.length === 0 || !path.every(item => typeof item === \"number\" && Number.isInteger(item) && item >= 0)) return { allowed: false, reason: \"A reviewed frame path of frame indexes is required in options.\" };\n return validateinnerstep(options, origin);\n }\n if (step.kind === \"retryaction\") {\n const inner = validateinnerstep(options, origin);\n if (!inner.allowed) return inner;\n const rule = options.retryrule;\n if (!rule || typeof rule !== \"object\" || Array.isArray(rule)) return { allowed: false, reason: \"A reviewed retry rule with attempts is required in options.\" };\n const retry = rule as Record<string, unknown>;\n if (typeof retry.attempts !== \"number\" || !Number.isInteger(retry.attempts) || retry.attempts < 1) return { allowed: false, reason: \"The reviewed retry attempts must be a positive integer with no code ceiling.\" };\n if (!nonnegativeoption(retry, \"settle\")) return { allowed: false, reason: \"The reviewed retry settle window must be zero or a positive number of milliseconds.\" };\n if (!nonnegativeoption(retry, \"tolerance\")) return { allowed: false, reason: \"The reviewed retry movement tolerance must be zero or a positive number of pixels.\" };\n }\n if (watchactions.has(step.kind)) {\n if (typeof options.lifetime !== \"number\" || !Number.isFinite(options.lifetime) || options.lifetime <= 0) return { allowed: false, reason: \"A reviewed watch lifetime window in milliseconds is required in options.\" };\n if (options.scopes !== undefined && (!Array.isArray(options.scopes) || !options.scopes.every(scope => isnonempty(scope)))) return { allowed: false, reason: \"The reviewed watch scopes must be a list of non-empty selectors.\" };\n if (options.events !== undefined && (!Array.isArray(options.events) || !options.events.every(event => isnonempty(event)))) return { allowed: false, reason: \"The reviewed watch event kinds must be a list of non-empty strings.\" };\n if (!nonnegativeoption(options, \"poll\")) return { allowed: false, reason: \"The reviewed watch poll interval must be zero or a positive number of milliseconds.\" };\n }\n if (step.kind === \"waitquiet\") {\n const rule = options.quietrule;\n if (!rule || typeof rule !== \"object\" || Array.isArray(rule)) return { allowed: false, reason: \"A reviewed quietrule with an idle threshold is required in options.\" };\n const quiet = rule as Record<string, unknown>;\n if (typeof quiet.idle !== \"number\" || !Number.isFinite(quiet.idle) || quiet.idle <= 0) return { allowed: false, reason: \"The reviewed quiet idle threshold must be a positive number of milliseconds with no code ceiling.\" };\n if (!nonnegativeoption(quiet, \"poll\")) return { allowed: false, reason: \"The reviewed quiet poll interval must be zero or a positive number of milliseconds.\" };\n if (!nonnegativeoption(quiet, \"timeout\")) return { allowed: false, reason: \"The reviewed quiet timeout must be zero or a positive number of milliseconds.\" };\n }\n if (step.kind === \"diffsnapshots\") {\n const versions = options.versions;\n if (!Array.isArray(versions) || versions.length !== 2 || !versions.every(version => typeof version === \"number\" && Number.isInteger(version) && version >= 1)) return { allowed: false, reason: \"Two reviewed observation version numbers are required in options.\" };\n }\n if (step.kind === \"openlink\" || step.kind === \"openprivate\" || step.kind === \"deeplink\") {\n const targetcheck = validatenavtarget(options.navtarget, step.kind);\n if (!targetcheck.allowed) return targetcheck;\n if (step.kind === \"deeplink\") {\n const app = options.app;\n if (!isnonempty(app)) return { allowed: false, reason: \"A reviewed deep link app pattern is required in options.\" };\n const params = options.params;\n if (params !== undefined && (!params || typeof params !== \"object\" || Array.isArray(params) || !Object.values(params).every(item => typeof item === \"string\"))) return { allowed: false, reason: \"The reviewed deep link params must be an object of string values.\" };\n }\n }\n if (step.kind === \"waitload\" && !nonnegativeoption(options, \"timeout\")) return { allowed: false, reason: \"The waitload timeout must be zero or a positive number of milliseconds.\" };\n if (step.kind === \"waiturl\" || step.kind === \"spawait\") {\n if (step.kind === \"waiturl\") {\n const patterncheck = validateurlpattern(options.urlpattern);\n if (!patterncheck.allowed) return patterncheck;\n }\n if (!nonnegativeoption(options, \"timeout\")) return { allowed: false, reason: \"The wait timeout must be zero or a positive number of milliseconds.\" };\n if (!nonnegativeoption(options, \"poll\")) return { allowed: false, reason: \"The wait poll interval must be zero or a positive number of milliseconds.\" };\n }\n if (step.kind === \"followlink\") {\n if (options.fragment !== undefined && typeof options.fragment !== \"boolean\") return { allowed: false, reason: \"The reviewed followlink fragment flag must be a boolean.\" };\n }\n if (step.kind === \"spanav\") {\n if (options.routepattern !== undefined) {\n const routecheck = validateurlpattern(options.routepattern);\n if (!routecheck.allowed) return routecheck;\n }\n if (!nonnegativeoption(options, \"timeout\")) return { allowed: false, reason: \"The spanav route timeout must be zero or a positive number of milliseconds.\" };\n }\n if (step.kind === \"rewritequery\") {\n const set = options.set;\n const remove = options.remove;\n if (set === undefined && remove === undefined) return { allowed: false, reason: \"Reviewed query parameters to set or remove are required in options.\" };\n if (set !== undefined && (!set || typeof set !== \"object\" || Array.isArray(set) || !Object.values(set).every(item => typeof item === \"string\"))) return { allowed: false, reason: \"The reviewed query parameters to set must be an object of string values.\" };\n if (remove !== undefined && (!Array.isArray(remove) || !remove.every(item => isnonempty(item)))) return { allowed: false, reason: \"The reviewed query parameters to remove must be a list of non-empty names.\" };\n }\n if (step.kind === \"navlist\") {\n const listcheck = validateurllist(options, \"urls\");\n if (!listcheck.allowed) return listcheck;\n }\n if (step.kind === \"navprofile\") {\n const profilecheck = validatewaitprofile(options.waitprofile);\n if (!profilecheck.allowed) return profilecheck;\n }\n if (step.kind === \"handleauth\" && !ishttpsurl(step.value)) return { allowed: false, reason: \"A reviewed HTTPS origin or url is required as the auth target.\" };\n if (step.kind === \"printpdf\" && options.name !== undefined && !isnonempty(options.name)) return { allowed: false, reason: \"The reviewed artifact name must be a non-empty string.\" };\n if (step.kind === \"prefetch\") {\n const listcheck = validateurllist(options, \"urls\");\n if (!listcheck.allowed) return listcheck;\n }\n if (step.kind === \"preconnect\") {\n const origins = options.origins;\n if (!Array.isArray(origins) || origins.length === 0 || !origins.every(originurl => ishttpsurl(originurl))) return { allowed: false, reason: \"A reviewed non-empty list of HTTPS origins is required in options.\" };\n }\n if (step.kind === \"reopentab\" && step.value !== undefined && !ishttpsurl(step.value)) return { allowed: false, reason: \"The reviewed reopen url must use HTTPS.\" };\n if (step.kind === \"navrate\") {\n const limitcheck = validateratelimit(options.ratelimit);\n if (!limitcheck.allowed) return limitcheck;\n }\n if (step.kind === \"checksafe\" && !ishttpsurl(step.value)) return { allowed: false, reason: \"A reviewed HTTPS url is required for the safety check.\" };\n if (step.kind === \"batchopen\") {\n const listcheck = validateurllist(options, \"urls\");\n if (!listcheck.allowed) return listcheck;\n }\n if (istabscommandkind(step.kind)) {\n const tabscheck = validatetabsgrammar(step, options);\n if (!tabscheck.allowed) return tabscheck;\n }\n if (isformkind(step.kind)) {\n const formcheck = validateformgrammar(step, options);\n if (!formcheck.allowed) return formcheck;\n }\n if (isdatasetkind(step.kind)) {\n const datacheck = validatedatagrammar(step, options, origin);\n if (!datacheck.allowed) return datacheck;\n }\n if (isfileskind(step.kind)) {\n const filescheck = validatefilesgrammar(step, options);\n if (!filescheck.allowed) return filescheck;\n }\n if (step.kind === \"tabcreate\") {\n if (options.background !== undefined && typeof options.background !== \"boolean\") return { allowed: false, reason: \"The reviewed background flag must be a boolean.\" };\n if (options.window !== undefined && (typeof options.window !== \"number\" || !Number.isInteger(options.window) || options.window < 0)) return { allowed: false, reason: \"The reviewed target window id must be a non-negative integer.\" };\n }\n if (step.kind === \"windowcreate\") {\n for (const field of [\"left\", \"top\", \"width\", \"height\"]) {\n if (options[field] !== undefined && (typeof options[field] !== \"number\" || !Number.isFinite(options[field]))) return { allowed: false, reason: `The reviewed window ${field} must be a number.` };\n }\n if (options.state !== undefined && ![\"normal\", \"maximized\", \"minimized\", \"fullscreen\"].includes(options.state as string)) return { allowed: false, reason: \"The reviewed window state must be normal, maximized, minimized or fullscreen.\" };\n }\n return { allowed: true };\n}\n\n/** Shared session gate: a live, unpaused session that still matches the active tab. */\nfunction sessiongate(input: { session: agentsession | undefined; tabid: number; origin: string; now: number; action: string }): policyevaluation {\n if (!input.session || input.session.stoppedat) return { allowed: false, reason: \"No active browser session exists.\" };\n if (input.session.expiresat <= input.now) return { allowed: false, reason: \"The browser session has expired.\" };\n if (input.session.pausedat) return { allowed: false, reason: `The browser session is paused and cannot ${input.action}.` };\n if (input.session.tabid !== input.tabid || input.session.origin !== input.origin) return { allowed: false, reason: `The ${input.action} is outside the approved tab or origin.` };\n return { allowed: true };\n}\n\n/** Applies the consent gate immediately before an action reaches the page bridge. */\nexport function canexecute(input: { session: agentsession | undefined; plan: agentplan | undefined; step: toolstep; tabid: number; origin: string; now?: number; verdicts?: safetyverdict[] }): policyevaluation {\n const now = input.now ?? Date.now();\n const gate = sessiongate({ session: input.session, tabid: input.tabid, origin: input.origin, now, action: \"execute an action\" });\n if (!gate.allowed) return gate;\n if (!input.plan || input.plan.state !== \"approved\") return { allowed: false, reason: \"The plan has not received explicit approval.\" };\n if (input.plan.expiresat <= now) return { allowed: false, reason: \"The approved plan has expired.\" };\n if ((input.step.kind === \"pierceshadow\" || input.step.kind === \"enterframe\") && !origingranted(input.session, input.origin)) return { allowed: false, reason: \"The shadow or frame step is outside the session origin grants.\" };\n if (input.step.kind === \"readjson\" && !origingranted(input.session, input.origin)) return { allowed: false, reason: \"The json state read is outside the session origin grants.\" };\n if (isexportkind(input.step.kind)) {\n const exportgate = exportgranted(input.session, input.origin);\n if (!exportgate.allowed) return exportgate;\n }\n if (input.step.kind === \"navlist\") {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(input.step); } catch { options = {}; }\n for (const url of Array.isArray(options.urls) ? options.urls : []) {\n if (typeof url !== \"string\") continue;\n const navigation = navigationgranted(input.session, url);\n if (!navigation.allowed) return navigation;\n }\n }\n if (islayoutkind(input.step.kind) && !layoutmutationgranted(input.session, now).allowed) return { allowed: false, reason: \"Group and layout mutations stay inside the active session.\" };\n if (input.step.kind === \"submitform\" || input.step.kind === \"retryform\") {\n if (!input.plan) return { allowed: false, reason: \"Form submission requires an asksubmit review step before it.\" };\n const reviewgate = submitreviewgranted(input.plan.steps, input.step.id);\n if (!reviewgate.allowed) return reviewgate;\n }\n if (input.step.kind === \"consentpassword\") {\n const consentgate = passwordconsentgranted(input.step);\n if (!consentgate.allowed) return consentgate;\n }\n if (input.step.kind === \"readclipboard\") {\n const clipgate = clipboardconsentgranted(input.step);\n if (!clipgate.allowed) return clipgate;\n }\n if (input.step.kind === \"interceptmime\" && !origingranted(input.session, input.origin)) return { allowed: false, reason: \"The download interception is outside the session origin grants.\" };\n if (input.step.kind === \"openlink\" || input.step.kind === \"openprivate\" || input.step.kind === \"batchopen\" || input.step.kind === \"prefetch\" || input.step.kind === \"deeplink\" || input.step.kind === \"reopentab\") {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(input.step); } catch { options = {}; }\n const grammar = validatestep(input.step, input.origin);\n if (!grammar.allowed) return grammar;\n const grants = input.session?.grants ?? [input.session?.origin ?? input.origin];\n const targets: unknown[] = input.step.kind === \"batchopen\" || input.step.kind === \"prefetch\" ? (Array.isArray(options.urls) ? options.urls : []) : input.step.kind === \"reopentab\" ? [input.step.value] : [(options.navtarget as Record<string, unknown> | undefined)?.url];\n for (const target of targets) {\n if (typeof target !== \"string\" || !target) continue;\n const verified = originverified(target, grants, input.verdicts ?? []);\n if (!verified.allowed) return verified;\n }\n }\n return validatestep(input.step, input.origin);\n}\n\n/** Allows a non-mutating, temporary target preview during plan review. */\nexport function canpreview(input: { session: agentsession | undefined; plan: agentplan | undefined; step: toolstep; tabid: number; origin: string; now?: number }): policyevaluation {\n const now = input.now ?? Date.now();\n const gate = sessiongate({ session: input.session, tabid: input.tabid, origin: input.origin, now, action: \"preview a target\" });\n if (!gate.allowed) return gate;\n if (!input.plan || ![\"pending\", \"approved\"].includes(input.plan.state)) return { allowed: false, reason: \"Only a reviewed pending or approved plan can be previewed.\" };\n if (input.plan.expiresat <= now) return { allowed: false, reason: \"The reviewed plan has expired.\" };\n let options: Record<string, unknown> = {};\n try { options = parseoptions(input.step); } catch { options = {}; }\n if (!targetactions.has(input.step.kind) && options.targetref === undefined) return { allowed: false, reason: \"Only a target-based action can be previewed.\" };\n return validatestep(input.step, input.origin);\n}\n", "import type { toolstep } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\n\n/**\n * Mutating page interactions for reviewed steps.\n * Every correlated rule for pointer, key, drag, upload, form, attribute, storage and evaluation actions lives in this file.\n */\n\nexport type stepresult = { ok: boolean; summary: string; details?: Record<string, unknown> };\n\nfunction events(target: Element): void {\n target.dispatchEvent(new Event(\"input\", { bubbles: true }));\n target.dispatchEvent(new Event(\"change\", { bubbles: true }));\n}\n\nfunction modifiers(options: Record<string, unknown>): string[] {\n return Array.isArray(options.modifiers) ? options.modifiers.filter((item): item is string => typeof item === \"string\") : [];\n}\n\nfunction keyevent(type: \"keydown\" | \"keypress\" | \"keyup\", key: string, mods: string[]): KeyboardEvent {\n const code = key.length === 1 ? `Key${key.toUpperCase()}` : key;\n return new KeyboardEvent(type, { key, code, bubbles: true, cancelable: true, composed: true, ctrlKey: mods.includes(\"ctrl\"), shiftKey: mods.includes(\"shift\"), altKey: mods.includes(\"alt\"), metaKey: mods.includes(\"meta\") });\n}\n\nfunction fieldlike(target: Element | null): HTMLInputElement | HTMLTextAreaElement | null {\n return target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement ? target : null;\n}\n\nfunction stringify(value: unknown): unknown {\n try { return JSON.parse(JSON.stringify(value)) ?? null; } catch { return String(value); }\n}\n\n/** Runs one mutating page action after the background policy gate and a fresh target check. */\nexport function runpageaction(step: toolstep, target: Element | null): stepresult | Promise<stepresult> {\n const options = (() => { try { return parseoptions(step); } catch { return {} as Record<string, unknown>; } })();\n switch (step.kind) {\n case \"presskey\": {\n const receiver = target instanceof HTMLElement ? target : document.activeElement instanceof HTMLElement ? document.activeElement : document.body;\n const key = step.value ?? \"\";\n const mods = modifiers(options);\n receiver.dispatchEvent(keyevent(\"keydown\", key, mods));\n receiver.dispatchEvent(keyevent(\"keypress\", key, mods));\n receiver.dispatchEvent(keyevent(\"keyup\", key, mods));\n return { ok: true, summary: `Key ${key} delivered with ${mods.length} modifier${mods.length === 1 ? \"\" : \"s\"}.` };\n }\n case \"clickdeep\": {\n if (!(target instanceof HTMLElement)) return { ok: false, summary: \"Action target is no longer available.\" };\n target.dispatchEvent(new PointerEvent(\"pointerdown\", { bubbles: true, cancelable: true, composed: true }));\n target.dispatchEvent(new MouseEvent(\"mousedown\", { bubbles: true, cancelable: true }));\n target.dispatchEvent(new PointerEvent(\"pointerup\", { bubbles: true, cancelable: true, composed: true }));\n target.dispatchEvent(new MouseEvent(\"mouseup\", { bubbles: true, cancelable: true }));\n target.click();\n return { ok: true, summary: \"Full pointer click sequence delivered.\" };\n }\n case \"rightclick\": {\n if (!(target instanceof HTMLElement)) return { ok: false, summary: \"Action target is no longer available.\" };\n const init: MouseEventInit = { bubbles: true, cancelable: true, button: 2, buttons: 2 };\n target.dispatchEvent(new PointerEvent(\"pointerdown\", { ...init, composed: true }));\n target.dispatchEvent(new MouseEvent(\"mousedown\", init));\n target.dispatchEvent(new MouseEvent(\"contextmenu\", init));\n return { ok: true, summary: \"Context menu events delivered.\" };\n }\n case \"doubleclick\": {\n if (!(target instanceof HTMLElement)) return { ok: false, summary: \"Action target is no longer available.\" };\n target.click();\n target.click();\n target.dispatchEvent(new MouseEvent(\"dblclick\", { bubbles: true, cancelable: true, detail: 2 }));\n return { ok: true, summary: \"Double click sequence delivered.\" };\n }\n case \"drag\": {\n if (!(target instanceof HTMLElement)) return { ok: false, summary: \"Drag source is no longer available.\" };\n const destination = document.querySelector(step.value ?? \"\");\n if (!destination) return { ok: false, summary: \"Drag destination is no longer available.\" };\n const transfer = new DataTransfer();\n if (typeof options.data === \"string\") transfer.setData(\"text/plain\", options.data);\n target.dispatchEvent(new DragEvent(\"dragstart\", { bubbles: true, cancelable: true, dataTransfer: transfer }));\n destination.dispatchEvent(new DragEvent(\"dragenter\", { bubbles: true, cancelable: true, dataTransfer: transfer }));\n destination.dispatchEvent(new DragEvent(\"dragover\", { bubbles: true, cancelable: true, dataTransfer: transfer }));\n destination.dispatchEvent(new DragEvent(\"drop\", { bubbles: true, cancelable: true, dataTransfer: transfer }));\n target.dispatchEvent(new DragEvent(\"dragend\", { bubbles: true, cancelable: true, dataTransfer: transfer }));\n return { ok: true, summary: \"Drag and drop sequence delivered.\" };\n }\n case \"drop\": {\n if (!(target instanceof HTMLElement)) return { ok: false, summary: \"Drop zone is no longer available.\" };\n const transfer = new DataTransfer();\n transfer.setData(\"text/plain\", step.value ?? \"\");\n target.dispatchEvent(new DragEvent(\"dragenter\", { bubbles: true, cancelable: true, dataTransfer: transfer }));\n target.dispatchEvent(new DragEvent(\"dragover\", { bubbles: true, cancelable: true, dataTransfer: transfer }));\n target.dispatchEvent(new DragEvent(\"drop\", { bubbles: true, cancelable: true, dataTransfer: transfer }));\n return { ok: true, summary: \"Drop payload delivered.\" };\n }\n case \"upload\": {\n if (!(target instanceof HTMLInputElement) || target.type !== \"file\") return { ok: false, summary: \"Target is not a file input.\" };\n const transfer = new DataTransfer();\n transfer.items.add(new File([typeof options.content === \"string\" ? options.content : \"\"], step.value ?? \"upload\", { type: typeof options.type === \"string\" ? options.type : \"text/plain\" }));\n target.files = transfer.files;\n events(target);\n return { ok: true, summary: `Uploaded ${step.value ?? \"file\"} into the reviewed input.` };\n }\n case \"clear\": {\n const field = fieldlike(target);\n if (!field) return { ok: false, summary: \"Target cannot hold a value.\" };\n field.value = \"\";\n events(field);\n return { ok: true, summary: \"Field cleared.\" };\n }\n case \"check\":\n case \"uncheck\":\n case \"toggle\": {\n if (!(target instanceof HTMLInputElement) || (target.type !== \"checkbox\" && target.type !== \"radio\")) return { ok: false, summary: \"Target is not a checkbox or radio control.\" };\n if (step.kind === \"uncheck\" && target.type === \"radio\") return { ok: false, summary: \"A radio control cannot be unchecked.\" };\n target.checked = step.kind === \"toggle\" ? !target.checked : step.kind === \"check\";\n events(target);\n return { ok: true, summary: `Control is now ${target.checked ? \"checked\" : \"unchecked\"}.` };\n }\n case \"submit\": {\n const form = target instanceof HTMLFormElement ? target : target instanceof HTMLElement ? target.closest(\"form\") : null;\n if (!form) return { ok: false, summary: \"No form owns the reviewed target.\" };\n try { form.requestSubmit(target instanceof HTMLFormElement ? undefined : (target as HTMLElement)); } catch { form.submit(); }\n return { ok: true, summary: \"Form submission requested.\" };\n }\n case \"setattribute\": {\n if (!target) return { ok: false, summary: \"Action target is no longer available.\" };\n const name = typeof options.name === \"string\" ? options.name : \"\";\n target.setAttribute(name, typeof options.value === \"string\" ? options.value : \"\");\n return { ok: true, summary: `Attribute ${name} set.` };\n }\n case \"removeattribute\": {\n if (!target) return { ok: false, summary: \"Action target is no longer available.\" };\n const name = step.value ?? \"\";\n target.removeAttribute(name);\n return { ok: true, summary: `Attribute ${name} removed.` };\n }\n case \"writestorage\": {\n try {\n localStorage.setItem(typeof options.key === \"string\" ? options.key : \"\", typeof options.value === \"string\" ? options.value : \"\");\n return { ok: true, summary: `Local storage entry ${String(options.key)} written.` };\n } catch (error) { return { ok: false, summary: `Local storage refused the write: ${error instanceof Error ? error.message : String(error)}` }; }\n }\n case \"evaluate\": {\n try {\n let outcome: unknown;\n try { outcome = new Function(`\"use strict\"; return (${step.value ?? \"undefined\"});`)(); } catch { outcome = new Function(`\"use strict\"; ${step.value ?? \"\"}`)(); }\n return { ok: true, summary: `Reviewed expression returned ${outcome === undefined ? \"no value\" : \"a value\"}.`, details: { result: stringify(outcome) } };\n } catch (error) { return { ok: false, summary: `Reviewed expression failed: ${error instanceof Error ? error.message : String(error)}` }; }\n }\n case \"fullscreen\": {\n const element = target instanceof HTMLElement ? target : document.documentElement;\n return document.fullscreenElement === element\n ? document.exitFullscreen().then(() => ({ ok: true, summary: \"Fullscreen state cleared.\" }) as stepresult)\n : element.requestFullscreen().then(() => ({ ok: true, summary: \"Fullscreen state entered.\" }) as stepresult).catch(error => ({ ok: false, summary: `Fullscreen was refused: ${error instanceof Error ? error.message : String(error)}` }));\n }\n default: return { ok: false, summary: \"Unsupported page action.\" };\n }\n}\n", "/**\n * Xpath resolution subset for reviewed steps.\n * Every correlated rule for expression parsing, node trees and evaluation of the supported xpath grammar lives in this file.\n * The engine supports absolute and descendant steps, tag or wildcard names, attribute predicates, text predicates and positional predicates.\n */\n\n/** Serializable dom node used by the xpath engine; the live glue attaches the element. */\nexport interface xnode {\n tag: string;\n attributes: Record<string, string>;\n text: string;\n children: xnode[];\n element?: Element;\n}\n\ntype xpathpredicate =\n | { kind: \"attr\"; name: string; value?: string; contains?: boolean }\n | { kind: \"text\"; value: string; contains?: boolean }\n | { kind: \"position\"; index: number };\n\ninterface xpathstep {\n descendant: boolean;\n tag: string;\n predicates: xpathpredicate[];\n}\n\nfunction owntext(element: Element): string {\n let combined = \"\";\n for (const node of element.childNodes) if (node.nodeType === Node.TEXT_NODE) combined += node.textContent ?? \"\";\n return combined.replace(/\\s+/g, \" \").trim();\n}\n\nfunction attributesof(element: Element): Record<string, string> {\n const attributes: Record<string, string> = {};\n for (const attribute of [...element.attributes]) attributes[attribute.name] = attribute.value;\n return attributes;\n}\n\nfunction wrap(element: Element): xnode {\n return { tag: element.tagName.toLowerCase(), attributes: attributesof(element), text: owntext(element), children: [...element.children].map(wrap), element };\n}\n\n/** Builds the serializable node tree of one live document for the xpath engine. */\nexport function buildxtree(root: Document): xnode {\n return { tag: \"#document\", attributes: {}, text: \"\", children: root.documentElement ? [wrap(root.documentElement)] : [] };\n}\n\n/** Parses one predicate body into the supported predicate shapes. */\nfunction parsepredicate(raw: string): xpathpredicate | null {\n const body = raw.trim();\n let match = /^@([\\w-]+)$/.exec(body);\n if (match) return { kind: \"attr\", name: match[1] as string };\n match = /^@([\\w-]+)\\s*=\\s*['\"]([^'\"]*)['\"]$/.exec(body);\n if (match) return { kind: \"attr\", name: match[1] as string, value: match[2] as string };\n match = /^contains\\(\\s*@([\\w-]+)\\s*,\\s*['\"]([^'\"]*)['\"]\\s*\\)$/.exec(body);\n if (match) return { kind: \"attr\", name: match[1] as string, value: match[2] as string, contains: true };\n match = /^text\\(\\)\\s*=\\s*['\"]([^'\"]*)['\"]$/.exec(body);\n if (match) return { kind: \"text\", value: match[1] as string };\n match = /^contains\\(\\s*text\\(\\)\\s*,\\s*['\"]([^'\"]*)['\"]\\s*\\)$/.exec(body);\n if (match) return { kind: \"text\", value: match[1] as string, contains: true };\n match = /^(\\d+)$/.exec(body);\n if (match) return { kind: \"position\", index: Number.parseInt(match[1] as string, 10) };\n return null;\n}\n\n/** Parses the reviewed xpath expression into evaluation steps; unsupported syntax is refused. */\nexport function parsexpath(expression: string): xpathstep[] {\n const trimmed = expression.trim();\n if (!trimmed.startsWith(\"/\")) throw new Error(\"The reviewed xpath expression must start with a slash.\");\n const steps: xpathstep[] = [];\n let index = 0;\n while (index < trimmed.length) {\n if (trimmed[index] !== \"/\") throw new Error(\"The reviewed xpath expression contains an unsupported segment.\");\n let slashes = 0;\n while (index < trimmed.length && trimmed[index] === \"/\") { slashes += 1; index += 1; }\n const start = index;\n let quote = \"\";\n while (index < trimmed.length) {\n const character = trimmed[index];\n if (quote) { if (character === quote) quote = \"\"; }\n else if (character === \"'\" || character === '\"') quote = character;\n else if (character === \"/\") break;\n index += 1;\n }\n const body = trimmed.slice(start, index);\n if (!body) throw new Error(\"The reviewed xpath expression contains an empty step.\");\n const parsed = /^(\\*|[a-zA-Z][\\w-]*)((?:\\[[^\\]]*\\])*)$/.exec(body);\n if (!parsed) throw new Error(`The reviewed xpath step ${body} is not supported.`);\n const predicates: xpathpredicate[] = [];\n const pattern = /\\[([^\\]]*)\\]/g;\n let predicate: RegExpExecArray | null;\n while ((predicate = pattern.exec(parsed[2] ?? \"\")) !== null) {\n const parsedpredicate = parsepredicate(predicate[1] as string);\n if (!parsedpredicate) throw new Error(`The reviewed xpath predicate [${predicate[1]}] is not supported.`);\n predicates.push(parsedpredicate);\n }\n steps.push({ descendant: slashes > 1, tag: (parsed[1] as string).toLowerCase(), predicates });\n }\n return steps;\n}\n\nfunction descendants(node: xnode, includeself: boolean): xnode[] {\n const result: xnode[] = includeself ? [node] : [];\n for (const child of node.children) { result.push(child); result.push(...descendants(child, false)); }\n return result;\n}\n\nfunction applypredicates(nodes: xnode[], predicates: xpathpredicate[]): xnode[] {\n let result = nodes;\n for (const predicate of predicates) {\n if (predicate.kind === \"position\") {\n const entry = result[predicate.index - 1];\n result = entry ? [entry] : [];\n continue;\n }\n result = result.filter(node => {\n if (predicate.kind === \"attr\") {\n const value = node.attributes[predicate.name];\n if (value === undefined) return false;\n if (predicate.value === undefined) return true;\n return predicate.contains ? value.includes(predicate.value) : value === predicate.value;\n }\n return predicate.contains ? node.text.includes(predicate.value) : node.text === predicate.value;\n });\n }\n return result;\n}\n\n/** Evaluates the supported xpath subset against a serializable node tree and returns every matched node in document order. */\nexport function evaluatexpath(root: xnode, expression: string): xnode[] {\n const steps = parsexpath(expression);\n let current: xnode[] = [root];\n let first = true;\n for (const step of steps) {\n let matched: xnode[] = [];\n for (const node of current) {\n const pool = step.descendant ? descendants(node, first) : node.children;\n matched = matched.concat(pool.filter(candidate => candidate.tag === step.tag || step.tag === \"*\"));\n }\n current = applypredicates(matched, step.predicates);\n first = false;\n }\n return current;\n}\n", "import { parseoptions, resolutionverdict } from \"../policy.js\";\nimport type { clickablemap, mapentry, resolvedtarget, targetmode, toolstep } from \"../types.js\";\nimport { buildxtree, evaluatexpath } from \"./pagexpath.js\";\n\n/**\n * Target resolution engine for reviewed steps.\n * Every correlated rule for element summaries, targetref modes, ambiguity reports, shadow piercing, frame walking and the numbered clickable map lives in this file.\n */\n\n/** Descriptive fields shared by every resolution candidate; the live dom glue attaches the element. */\nexport interface candidatefields {\n tag: string;\n id: string;\n role: string;\n name: string;\n label: string;\n text: string;\n selector: string;\n}\n\n/** One live dom candidate: descriptive fields plus the element itself. */\nexport interface livecandidate extends candidatefields {\n element: Element;\n}\n\n/** Serializable description of one document with nested frames; the glue attaches the live document. */\nexport interface framedescription {\n frames: frameentry[];\n live?: Document;\n}\n\n/** One nested frame: same origin frames expose their document, cross origin frames do not. */\nexport interface frameentry {\n sameorigin: boolean;\n document?: framedescription;\n}\n\n/** Serializable scope tree: one scope's candidates plus the open shadow scopes nested inside it. */\nexport interface scopetree<T extends candidatefields = livecandidate> {\n host?: T;\n candidates: T[];\n shadows: scopetree<T>[];\n}\n\nexport function clean(value: string): string {\n return value.replace(/\\s+/g, \" \").trim();\n}\n\nfunction cssescape(value: string): string {\n return typeof CSS !== \"undefined\" && typeof CSS.escape === \"function\" ? CSS.escape(value) : value.replace(/[^a-zA-Z0-9_-]/g, \"\\\\$&\");\n}\n\n/** Computes the accessible style label of an element from aria hints, linked labels, title and content. */\nexport function elementlabel(element: Element): string {\n const aria = element.getAttribute(\"aria-label\");\n let linked = \"\";\n const labelledby = element.getAttribute(\"aria-labelledby\");\n if (labelledby) {\n try {\n const owner = element.ownerDocument?.getElementById(labelledby);\n if (owner) linked = owner.textContent ?? \"\";\n } catch { /* detached documents refuse lookups; the label falls back */ }\n }\n let forlabel = \"\";\n if (element.id) {\n try {\n const label = element.ownerDocument?.querySelector(`label[for=\"${cssescape(element.id)}\"]`);\n if (label instanceof HTMLElement) forlabel = label.textContent ?? \"\";\n } catch { /* the document may be detached; the label falls back */ }\n }\n return clean(aria || linked || forlabel || element.getAttribute(\"title\") || element.textContent || \"\");\n}\n\n/** Computes the implicit aria role of common elements when no explicit role attribute exists. */\nexport function implicitrole(element: Element): string {\n const tag = element.tagName.toLowerCase();\n if (tag === \"button\") return \"button\";\n if (tag === \"a\" && element.getAttribute(\"href\")) return \"link\";\n if (tag === \"select\") return \"combobox\";\n if (tag === \"textarea\") return \"textbox\";\n if (tag === \"details\") return \"group\";\n if (tag === \"input\") {\n const type = element.getAttribute(\"type\") ?? \"text\";\n if (type === \"checkbox\") return \"checkbox\";\n if (type === \"radio\") return \"radio\";\n if (type === \"button\" || type === \"submit\" || type === \"reset\") return \"button\";\n if (type === \"range\") return \"slider\";\n return \"textbox\";\n }\n return \"\";\n}\n\n/** Builds the css selector that re-finds one element inside its document. */\nexport function elementselector(element: Element): string {\n if (element.id) return `#${cssescape(element.id)}`;\n const role = element.getAttribute(\"role\");\n const name = element.getAttribute(\"name\");\n if (role && name) return `[role=\"${cssescape(role)}\"][name=\"${cssescape(name)}\"]`;\n if (name) return `${element.tagName.toLowerCase()}[name=\"${cssescape(name)}\"]`;\n const tag = element.tagName.toLowerCase();\n const parent = element.parentElement;\n if (!parent) return tag;\n const peers = [...parent.children].filter(node => node.tagName === element.tagName);\n return `${tag}:nth-of-type(${peers.indexOf(element) + 1})`;\n}\n\n/** Own text of an element: only its direct text nodes, so parents do not shadow their children. */\nexport function owntext(element: Element): string {\n let combined = \"\";\n for (const node of element.childNodes) if (node.nodeType === Node.TEXT_NODE) combined += node.textContent ?? \"\";\n return clean(combined);\n}\n\n/** Summarizes one live element into the candidate shape used by every resolution mode. */\nexport function summarize(element: Element): livecandidate {\n return {\n tag: element.tagName.toLowerCase(),\n id: element.id,\n role: element.getAttribute(\"role\")?.toLowerCase() || implicitrole(element),\n name: element.getAttribute(\"name\") ?? \"\",\n label: elementlabel(element),\n text: owntext(element),\n selector: elementselector(element),\n element,\n };\n}\n\nconst clickableselector = \"a[href], button, input, textarea, select, summary, [role=button], [role=link], [role=combobox], [role=option], [role=checkbox], [role=radio], [role=switch], [role=tab]\";\n\n/** Collects every clickable candidate in document order. */\nexport function collectclickable(root: ParentNode): livecandidate[] {\n return [...root.querySelectorAll(clickableselector)].map(summarize);\n}\n\n/** Collects every element as a resolution candidate in document order. */\nexport function collectcandidates(root: ParentNode): livecandidate[] {\n return [...root.querySelectorAll(\"*\")].map(summarize);\n}\n\n/** Matches candidates whose visible own text or label equals or contains the reviewed text. */\nexport function matchtext<T extends candidatefields>(candidates: T[], text: string): T[] {\n const wanted = clean(text).toLowerCase();\n if (!wanted) return [];\n const exact = candidates.filter(candidate => candidate.text.toLowerCase() === wanted || candidate.label.toLowerCase() === wanted);\n if (exact.length > 0) return exact;\n return candidates.filter(candidate => candidate.text.toLowerCase().includes(wanted) || candidate.label.toLowerCase().includes(wanted));\n}\n\n/** Matches candidates by the aria role and accessible name pair. */\nexport function matcharia<T extends candidatefields>(candidates: T[], role: string, name: string): T[] {\n const wantedrole = clean(role).toLowerCase();\n const wantedname = clean(name).toLowerCase();\n if (!wantedrole || !wantedname) return [];\n return candidates.filter(candidate => candidate.role.toLowerCase() === wantedrole && (candidate.label.toLowerCase() === wantedname || candidate.name.toLowerCase() === wantedname));\n}\n\n/** Matches candidates by accessible name, preferring clickable elements when several share one name. */\nexport function matchname<T extends candidatefields>(candidates: T[], name: string, clickable?: (candidate: T) => boolean): T[] {\n const wanted = clean(name).toLowerCase();\n if (!wanted) return [];\n const matches = candidates.filter(candidate => candidate.label.toLowerCase() === wanted || candidate.name.toLowerCase() === wanted);\n if (matches.length > 1 && clickable) {\n const interactive = matches.filter(clickable);\n if (interactive.length === 1) return interactive;\n }\n return matches;\n}\n\n/** Matches one clickable map number; map numbers are one based and stable inside one observation version. */\nexport function matchindex<T extends candidatefields>(candidates: T[], index: number): T[] {\n if (!Number.isInteger(index) || index < 1) return [];\n const entry = candidates[index - 1];\n return entry ? [entry] : [];\n}\n\n/** Builds the numbered clickable map from clickable candidates in document order. */\nexport function buildclickablemap<T extends candidatefields>(candidates: T[], version: number, builtat = 0): clickablemap {\n const entries: mapentry[] = candidates.map((candidate, position) => ({ number: position + 1, selector: candidate.selector, role: candidate.role || candidate.tag, label: candidate.label, mode: \"selector\" as const }));\n return { version, entries, builtat };\n}\n\n/** Describes the nested frame structure of one live document; cross origin frames stay opaque. */\nexport function describeframes(root: Document): framedescription {\n const frames = [...root.querySelectorAll(\"iframe\")].map(frame => {\n let content: Document | null = null;\n try { content = frame.contentDocument; } catch { content = null; }\n let sameorigin = false;\n try { sameorigin = content !== null && frame.contentWindow?.location.origin === location.origin; } catch { sameorigin = false; }\n return sameorigin && content ? { sameorigin: true, document: describeframes(content) } : { sameorigin: false };\n });\n return { frames, live: root };\n}\n\n/** Walks a reviewed frame path through same origin frames and refuses cross origin or absent hops. */\nexport function walkframepath(root: framedescription, path: number[]): { ok: true; document: framedescription } | { ok: false; reason: string } {\n let current = root;\n for (const index of path) {\n if (!Number.isInteger(index) || index < 0) return { ok: false, reason: \"The reviewed frame path contains an invalid frame index.\" };\n const entry = current.frames[index];\n if (!entry) return { ok: false, reason: `Frame ${index} of the reviewed frame path is absent.` };\n if (!entry.sameorigin || !entry.document) return { ok: false, reason: `Frame ${index} of the reviewed frame path is cross origin and was refused.` };\n current = entry.document;\n }\n return { ok: true, document: current };\n}\n\n/** Describes one document or shadow root scope with every nested open shadow scope. */\nexport function describescopes(root: ParentNode): scopetree {\n const elements = [...root.querySelectorAll(\"*\")];\n const shadows: scopetree[] = [];\n for (const element of elements) {\n const shadow = element.shadowRoot;\n if (shadow) {\n const nested = describescopes(shadow);\n nested.host = summarize(element);\n shadows.push(nested);\n }\n }\n return { candidates: elements.map(summarize), shadows };\n}\n\n/** Searches one scope tree depth first for candidates matching the predicate, piercing open shadow scopes recursively. */\nexport function piercescopes<T extends candidatefields>(scope: scopetree<T>, match: (candidate: T) => boolean): T[] {\n const found: T[] = [];\n for (const candidate of scope.candidates) if (match(candidate)) found.push(candidate);\n for (const shadow of scope.shadows) found.push(...piercescopes(shadow, match));\n return found;\n}\n\n/** Resolves a reviewed selector chain through open shadow roots: each selector resolves inside the previous scope. */\nexport function queryshadowchain(root: ParentNode, selectors: string[]): Element | null {\n let scope: ParentNode = root;\n for (let position = 0; position < selectors.length; position += 1) {\n const found = scope.querySelector(selectors[position] as string);\n if (!found) return null;\n if (position === selectors.length - 1) return found;\n const shadow = found.shadowRoot;\n if (!shadow) return null;\n scope = shadow;\n }\n return null;\n}\n\n/** Finds the first element matching a selector in the scope or any nested open shadow root. */\nexport function queryscoped(root: ParentNode, selector: string): Element | null {\n const direct = root.querySelector(selector);\n if (direct) return direct;\n for (const element of [...root.querySelectorAll(\"*\")]) {\n const shadow = element.shadowRoot;\n if (shadow) {\n const found = queryscoped(shadow, selector);\n if (found) return found;\n }\n }\n return null;\n}\n\nfunction parseoptionssafe(step: toolstep): Record<string, unknown> {\n try { return parseoptions(step); } catch { return {}; }\n}\n\n/** Builds the matched element summary attached to step results for review. */\nexport function targetsummary(mode: targetmode, element: HTMLElement): resolvedtarget {\n const rect = element.getBoundingClientRect();\n return { mode, selector: elementselector(element), tag: element.tagName.toLowerCase(), label: elementlabel(element), geometry: { x: rect.x, y: rect.y, width: rect.width, height: rect.height } };\n}\n\nexport type stepresolution =\n | { status: \"none\" }\n | { status: \"resolved\"; element: HTMLElement; target: resolvedtarget }\n | { status: \"ambiguous\"; mode: targetmode; candidates: string[] }\n | { status: \"absent\"; mode?: targetmode };\n\nfunction singleresolution(mode: targetmode, matches: livecandidate[]): stepresolution {\n const verdict = resolutionverdict(matches.length);\n if (verdict === \"resolved\") {\n const winner = matches[0];\n if (winner && winner.element instanceof HTMLElement) return { status: \"resolved\", element: winner.element, target: targetsummary(mode, winner.element) };\n return { status: \"absent\", mode };\n }\n if (verdict === \"ambiguous\") return { status: \"ambiguous\", mode, candidates: matches.slice(0, 8).map(candidate => candidate.label || candidate.selector) };\n return { status: \"absent\", mode };\n}\n\n/** Resolves one reviewed targetref mode against the live dom in a single pass. */\nfunction resolvetargetref(reference: Record<string, unknown>, root: Document): stepresolution {\n const mode = reference.mode;\n if (mode === \"selector\") {\n const selector = typeof reference.selector === \"string\" ? reference.selector : \"\";\n const element = selector ? root.querySelector(selector) : null;\n return element instanceof HTMLElement ? { status: \"resolved\", element, target: targetsummary(\"selector\", element) } : { status: \"absent\", mode: \"selector\" };\n }\n if (mode === \"point\") {\n const x = Number(reference.x);\n const y = Number(reference.y);\n if (!Number.isFinite(x) || !Number.isFinite(y)) return { status: \"absent\", mode: \"point\" };\n const element = root.elementFromPoint(x, y);\n return element instanceof HTMLElement ? { status: \"resolved\", element, target: targetsummary(\"point\", element) } : { status: \"absent\", mode: \"point\" };\n }\n if (mode === \"xpath\") {\n const expression = typeof reference.xpath === \"string\" ? reference.xpath : \"\";\n if (!expression) return { status: \"absent\", mode: \"xpath\" };\n const matches = evaluatexpath(buildxtree(root), expression);\n const first = matches[0];\n return first?.element instanceof HTMLElement ? { status: \"resolved\", element: first.element, target: targetsummary(\"xpath\", first.element) } : { status: \"absent\", mode: \"xpath\" };\n }\n if (mode === \"index\") {\n const matches = matchindex(collectclickable(root), Number(reference.index));\n return singleresolution(\"index\", matches);\n }\n const candidates = collectcandidates(root);\n if (mode === \"text\") return singleresolution(\"text\", matchtext(candidates, typeof reference.text === \"string\" ? reference.text : \"\"));\n if (mode === \"aria\") return singleresolution(\"aria\", matcharia(candidates, typeof reference.role === \"string\" ? reference.role : \"\", typeof reference.name === \"string\" ? reference.name : \"\"));\n if (mode === \"name\") return singleresolution(\"name\", matchname(candidates, typeof reference.name === \"string\" ? reference.name : \"\"));\n return { status: \"absent\" };\n}\n\n/** Resolves the reviewed target of a step: the options targetref when present, otherwise the css target. */\nexport function resolvestep(step: toolstep, root: Document): stepresolution {\n const reference = parseoptionssafe(step).targetref;\n if (reference && typeof reference === \"object\" && !Array.isArray(reference)) return resolvetargetref(reference as Record<string, unknown>, root);\n if (!step.target?.trim()) return { status: \"none\" };\n const element = root.querySelector(step.target);\n if (element instanceof HTMLElement) return { status: \"resolved\", element, target: targetsummary(\"selector\", element) };\n return { status: \"absent\", mode: \"selector\" };\n}\n", "import type { toolstep } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\n\n/**\n * Read-only page observation for reviewed steps.\n * Every correlated rule for attribute, style, geometry, value, content, table, link, image, meta, form, storage reads, bounded-free waits, clickable maps and verify reads lives in this file.\n */\n\nimport type { stepresult } from \"./pageactions.js\";\nimport { buildclickablemap, collectclickable, elementlabel, elementselector } from \"./pageresolve.js\";\nimport { buildxtree, evaluatexpath } from \"./pagexpath.js\";\n\nconst highlightid = \"devthinkactionhighlight\";\n\nfunction clearhighlight(): void {\n document.getElementById(highlightid)?.remove();\n}\n\n/** Outlines one reviewed target without dispatching page events. */\nfunction highlighttarget(target: Element): stepresult {\n clearhighlight();\n const rect = target.getBoundingClientRect();\n const overlay = document.createElement(\"div\");\n overlay.id = highlightid;\n overlay.setAttribute(\"aria-hidden\", \"true\");\n Object.assign(overlay.style, { position: \"fixed\", left: `${Math.max(0, rect.left - 3)}px`, top: `${Math.max(0, rect.top - 3)}px`, width: `${rect.width + 6}px`, height: `${rect.height + 6}px`, border: \"3px solid #2f9e44\", borderRadius: \"6px\", pointerEvents: \"none\", zIndex: \"2147483647\", boxSizing: \"border-box\" });\n document.documentElement.append(overlay);\n window.setTimeout(clearhighlight, 5000);\n return { ok: true, summary: \"Target outlined for five seconds.\" };\n}\n\nfunction poll(root: Document, predicate: () => boolean, description: string, timeout: number): Promise<stepresult> {\n return new Promise(resolve => {\n const started = Date.now();\n const check = (): void => {\n if (predicate()) { resolve({ ok: true, summary: `${description} is now present on the page.` }); return; }\n if (timeout > 0 && Date.now() - started >= timeout) { resolve({ ok: false, summary: `${description} did not appear within ${timeout} milliseconds.` }); return; }\n window.setTimeout(check, 100);\n };\n check();\n });\n}\n\nfunction formstate(root: Document): Array<Record<string, unknown>> {\n return [...root.querySelectorAll(\"input, textarea, select\")].map(element => ({\n type: element.getAttribute(\"type\") ?? element.tagName.toLowerCase(),\n name: element.getAttribute(\"name\") ?? \"\",\n value: element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement ? element.value : \"\",\n ...(element instanceof HTMLInputElement && (element.type === \"checkbox\" || element.type === \"radio\") ? { checked: element.checked } : {}),\n }));\n}\n\n/** Runs one read-only page observation after the background policy gate. */\nexport function runpageread(step: toolstep, target: Element | null, root: Document = document): stepresult | Promise<stepresult> {\n const options = (() => { try { return parseoptions(step); } catch { return {} as Record<string, unknown>; } })();\n switch (step.kind) {\n case \"highlight\": {\n if (!target) return { ok: false, summary: \"Highlight target is no longer available.\" };\n return highlighttarget(target);\n }\n case \"readattribute\": {\n if (!target) return { ok: false, summary: \"Read target is no longer available.\" };\n const value = target.getAttribute(step.value ?? \"\");\n return value === null ? { ok: false, summary: `Attribute ${step.value} is absent.` } : { ok: true, summary: `Attribute ${step.value} read.`, details: { value } };\n }\n case \"readstyle\": {\n if (!target) return { ok: false, summary: \"Read target is no longer available.\" };\n const computed = getComputedStyle(target);\n const styles: Record<string, string> = {};\n for (let index = 0; index < computed.length; index += 1) { const property = computed.item(index); styles[property] = computed.getPropertyValue(property); }\n return { ok: true, summary: `Read ${computed.length} computed style properties.`, details: { styles } };\n }\n case \"readgeometry\": {\n if (!target) return { ok: false, summary: \"Read target is no longer available.\" };\n const rect = target.getBoundingClientRect();\n const geometry = { x: rect.x, y: rect.y, width: rect.width, height: rect.height, top: rect.top, right: rect.right, bottom: rect.bottom, left: rect.left };\n return { ok: true, summary: \"Target geometry read.\", details: { geometry } };\n }\n case \"readvalue\": {\n if (!(target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || target instanceof HTMLSelectElement)) return { ok: false, summary: \"Target does not hold a form value.\" };\n return { ok: true, summary: \"Form value read.\", details: { value: target.value } };\n }\n case \"readtext\": {\n if (!target) return { ok: false, summary: \"Read target is no longer available.\" };\n const text = target.textContent ?? \"\";\n return { ok: true, summary: `Read ${text.length} characters of text.`, details: { text } };\n }\n case \"readhtml\": {\n if (!target) return { ok: false, summary: \"Read target is no longer available.\" };\n return { ok: true, summary: \"Target markup read.\", details: { html: target.outerHTML } };\n }\n case \"countelements\": {\n const count = root.querySelectorAll(step.target ?? \"\").length;\n return { ok: true, summary: `Selector matches ${count} element${count === 1 ? \"\" : \"s\"}.`, details: { count } };\n }\n case \"readtable\": {\n if (!(target instanceof HTMLTableElement)) return { ok: false, summary: \"Read target is not a table element.\" };\n const rows = [...target.querySelectorAll(\"tr\")].map(row => [...row.querySelectorAll(\"th, td\")].map(cell => cell.textContent?.trim() ?? \"\"));\n const headers = rows[0] ?? [];\n const body = rows.slice(1);\n return { ok: true, summary: `Read table with ${headers.length} column${headers.length === 1 ? \"\" : \"s\"} and ${body.length} row${body.length === 1 ? \"\" : \"s\"}.`, details: { headers, rows: body } };\n }\n case \"readlinks\": {\n const links = [...root.querySelectorAll(\"a[href]\")].map(element => ({ text: element.textContent?.trim() ?? \"\", href: element.getAttribute(\"href\") ?? \"\" }));\n return { ok: true, summary: `Read ${links.length} link${links.length === 1 ? \"\" : \"s\"}.`, details: { links } };\n }\n case \"readimages\": {\n const images = [...root.querySelectorAll(\"img\")].map(element => ({ src: element.getAttribute(\"src\") ?? \"\", alt: element.getAttribute(\"alt\") ?? \"\" }));\n return { ok: true, summary: `Read ${images.length} image${images.length === 1 ? \"\" : \"s\"}.`, details: { images } };\n }\n case \"readmeta\": {\n const meta = [...root.querySelectorAll(\"meta\")].map(element => ({ name: element.getAttribute(\"name\") ?? \"\", property: element.getAttribute(\"property\") ?? \"\", content: element.getAttribute(\"content\") ?? \"\" }));\n return { ok: true, summary: `Read ${meta.length} meta entr${meta.length === 1 ? \"y\" : \"ies\"}.`, details: { meta } };\n }\n case \"readforms\": {\n const forms = formstate(root);\n return { ok: true, summary: `Read ${forms.length} form control${forms.length === 1 ? \"\" : \"s\"}.`, details: { forms } };\n }\n case \"readstorage\": {\n try {\n if (step.value) {\n const value = localStorage.getItem(step.value);\n return { ok: true, summary: `Read local storage entry ${step.value}.`, details: { value } };\n }\n const entries: Record<string, string | null> = {};\n for (let index = 0; index < localStorage.length; index += 1) { const key = localStorage.key(index); if (key !== null) entries[key] = localStorage.getItem(key); }\n return { ok: true, summary: `Read ${Object.keys(entries).length} local storage entr${Object.keys(entries).length === 1 ? \"y\" : \"ies\"}.`, details: { entries } };\n } catch (error) { return { ok: false, summary: `Local storage refused the read: ${error instanceof Error ? error.message : String(error)}` }; }\n }\n case \"waitfor\": {\n const selector = step.target ?? \"\";\n const timeout = typeof options.timeout === \"number\" ? options.timeout : 0;\n return poll(root, () => Boolean(root.querySelector(selector)), `Selector ${selector}`, timeout);\n }\n case \"waittext\": {\n const text = step.value ?? \"\";\n const timeout = typeof options.timeout === \"number\" ? options.timeout : 0;\n return poll(root, () => (root.body?.innerText ?? \"\").includes(text), `Text ${text}`, timeout);\n }\n case \"mapclicks\": {\n const candidates = collectclickable(root);\n const map = buildclickablemap(candidates, 0, 0);\n return { ok: true, summary: `Mapped ${map.entries.length} clickable element${map.entries.length === 1 ? \"\" : \"s\"}.`, details: { entries: map.entries } };\n }\n case \"verifyvisible\": {\n if (!target) return { ok: false, summary: \"Verify target is no longer available.\" };\n const rect = target.getBoundingClientRect();\n const rendered = rect.width > 0 && rect.height > 0;\n return { ok: rendered, summary: rendered ? `Target is rendered at ${Math.round(rect.x)},${Math.round(rect.y)} with size ${Math.round(rect.width)}x${Math.round(rect.height)}.` : \"Target is not rendered.\", details: { visible: rendered, geometry: { x: rect.x, y: rect.y, width: rect.width, height: rect.height } } };\n }\n case \"verifyenabled\": {\n if (!target) return { ok: false, summary: \"Verify target is no longer available.\" };\n const control = target as HTMLInputElement;\n const disabled = control.disabled === true || target.hasAttribute(\"disabled\");\n const readonly = control.readOnly === true || target.hasAttribute(\"readonly\");\n const enabled = !disabled && !readonly;\n return { ok: enabled, summary: enabled ? \"Target is enabled and writable.\" : disabled ? \"Target is disabled.\" : \"Target is readonly.\", details: { enabled, disabled, readonly } };\n }\n case \"resolvexpath\": {\n const reference = options.targetref as Record<string, unknown> | undefined;\n const expression = typeof reference?.xpath === \"string\" ? reference.xpath : \"\";\n if (!expression) return { ok: false, summary: \"The reviewed xpath expression is absent.\" };\n let matches: ReturnType<typeof evaluatexpath> = [];\n try { matches = evaluatexpath(buildxtree(root), expression); } catch (error) { return { ok: false, summary: `The reviewed xpath expression failed: ${error instanceof Error ? error.message : String(error)}` }; }\n const summaries = matches.map(node => ({ tag: node.tag, ...(node.element ? { selector: elementselector(node.element), label: elementlabel(node.element) } : {}) }));\n return { ok: matches.length > 0, summary: matches.length > 0 ? `Resolved ${matches.length} element${matches.length === 1 ? \"\" : \"s\"} for the reviewed xpath.` : \"The reviewed xpath matched no elements.\", details: { mode: \"xpath\", matches: summaries } };\n }\n default: return { ok: false, summary: \"Unsupported page read.\" };\n }\n}\n", "import type { keyholdstate, toolstep } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\nimport type { stepresult } from \"./pageactions.js\";\nimport { clean } from \"./pageresolve.js\";\n\n/**\n * Field and control interactions for reviewed steps.\n * Every correlated rule for timed typing, value setting, key holds, search submission, multi selects, radio choices, sliders, dates, colors, details sections and the hold registry lives in this file.\n */\n\n/** Builds the per keystroke schedule of one reviewed typetime step. */\nexport function typetimeschedule(text: string, delay: number): Array<{ key: string; delay: number }> {\n return [...text].map((character, position) => ({ key: character, delay: position === 0 ? 0 : delay }));\n}\n\n/** Appends reviewed text to the current field value. */\nexport function appendvalue(current: string, addition: string): string {\n return current + addition;\n}\n\n/** Event order delivered after one reviewed value change. */\nexport function valueevents(): string[] {\n return [\"input\", \"change\"];\n}\n\n/** Splits reviewed multi select values into present and missing entries against the declared options. */\nexport function multichoices(values: string[], options: Array<{ value: string; label: string }>): { present: string[]; missing: string[] } {\n const present: string[] = [];\n const missing: string[] = [];\n for (const value of values) {\n const option = options.find(candidate => candidate.value === value || candidate.label === value);\n if (option) present.push(option.value);\n else missing.push(value);\n }\n return { present, missing };\n}\n\n/** Picks the reviewed radio input by value or label from one radio group; the index of the match or minus one. */\nexport function radiochoice(inputs: Array<{ value: string; label: string }>, choice: string): number {\n return inputs.findIndex(candidate => candidate.value === choice || candidate.label === choice);\n}\n\n/** Clamps one reviewed slider value to the declared range and step grid. */\nexport function slidervalue(requested: number, min: number, max: number, step: number): number {\n const lower = Math.min(min, max);\n const upper = Math.max(min, max);\n const clamped = Math.min(upper, Math.max(lower, requested));\n if (!Number.isFinite(step) || step <= 0) return clamped;\n return Math.round((clamped - lower) / step) * step + lower;\n}\n\n/** Validates and normalizes one reviewed yyyy-mm-dd date. */\nexport function datevalue(requested: string): string | null {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(requested)) return null;\n const parts = requested.split(\"-\").map(part => Number.parseInt(part, 10));\n const year = parts[0];\n const month = parts[1];\n const day = parts[2];\n if (!year || !month || !day || month < 1 || month > 12 || day < 1 || day > 31) return null;\n return requested;\n}\n\n/** Validates and normalizes one reviewed #rrggbb color. */\nexport function colorvalue(requested: string): string | null {\n if (!/^#[0-9a-fA-F]{6}$/.test(requested)) return null;\n return requested.toLowerCase();\n}\n\n/** Decides whether one reviewed details section still needs opening. */\nexport function expandstate(open: boolean): { open: boolean; changed: boolean } {\n return open ? { open: true, changed: false } : { open: true, changed: true };\n}\n\n/** Records one held key under its hold id; a repeated active hold id is refused. */\nexport function presshold(holds: keyholdstate[], hold: keyholdstate): { holds: keyholdstate[]; ok: boolean } {\n if (holds.some(existing => existing.holdid === hold.holdid && existing.releasedat === undefined)) return { holds, ok: false };\n return { holds: [...holds, hold], ok: true };\n}\n\n/** Releases one held key by hold id, keeping the release timestamp. */\nexport function releasehold(holds: keyholdstate[], holdid: string, releasedat: number): { holds: keyholdstate[]; released?: keyholdstate } {\n let released: keyholdstate | undefined;\n const next = holds.map(hold => {\n if (hold.holdid !== holdid || hold.releasedat !== undefined) return hold;\n released = { ...hold, releasedat };\n return released;\n });\n return { holds: next, ...(released ? { released } : {}) };\n}\n\n/** Returns the keys currently held, optionally filtered to one tab. */\nexport function heldkeys(holds: keyholdstate[], tabid?: number): keyholdstate[] {\n return holds.filter(hold => hold.releasedat === undefined && (tabid === undefined || hold.tabid === undefined || hold.tabid === tabid));\n}\n\nfunction events(target: Element): void {\n target.dispatchEvent(new Event(\"input\", { bubbles: true }));\n target.dispatchEvent(new Event(\"change\", { bubbles: true }));\n}\n\nfunction modifiers(options: Record<string, unknown>): string[] {\n return Array.isArray(options.modifiers) ? options.modifiers.filter((item): item is string => typeof item === \"string\") : [];\n}\n\nfunction keyevent(type: \"keydown\" | \"keyup\", key: string, mods: string[]): KeyboardEvent {\n const code = key.length === 1 ? `Key${key.toUpperCase()}` : key;\n return new KeyboardEvent(type, { key, code, bubbles: true, cancelable: true, composed: true, ctrlKey: mods.includes(\"ctrl\"), shiftKey: mods.includes(\"shift\"), altKey: mods.includes(\"alt\"), metaKey: mods.includes(\"meta\") });\n}\n\nfunction fieldlike(target: Element | null): HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement | null {\n return target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || target instanceof HTMLSelectElement ? target : null;\n}\n\nfunction receiver(target: Element | null): HTMLElement {\n return target instanceof HTMLElement ? target : document.activeElement instanceof HTMLElement ? document.activeElement : document.body;\n}\n\nfunction wait(delay: number): Promise<void> {\n return new Promise(resolve => window.setTimeout(resolve, delay));\n}\n\n/** Focuses the reviewed target before typing; an explicit reviewed focus option forces or suppresses the focus. */\nfunction focuswhenneeded(target: Element, options: Record<string, unknown>): void {\n if (!(target instanceof HTMLElement)) return;\n if (options.focus === false) return;\n if (options.focus === true || document.activeElement !== target) target.focus();\n}\n\nfunction pollfor(predicate: () => boolean, description: string, timeout: number): Promise<stepresult> {\n return new Promise(resolve => {\n const started = Date.now();\n const check = (): void => {\n if (predicate()) { resolve({ ok: true, summary: `${description} is now present on the page.` }); return; }\n if (timeout > 0 && Date.now() - started >= timeout) { resolve({ ok: false, summary: `${description} did not appear within ${timeout} milliseconds.` }); return; }\n window.setTimeout(check, 100);\n };\n check();\n });\n}\n\n/** Runs one reviewed control interaction after the background policy gate and a fresh target check; frame routed steps receive their frame document as the root. */\nexport function runpagecontrol(step: toolstep, target: Element | null, root: Document = document): stepresult | Promise<stepresult> {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n switch (step.kind) {\n case \"typetime\": {\n const field = fieldlike(target);\n if (!field) return { ok: false, summary: \"Target cannot receive timed text.\" };\n const text = step.value ?? \"\";\n const delay = typeof options.delay === \"number\" && options.delay > 0 ? options.delay : 0;\n focuswhenneeded(field, options);\n const schedule = typetimeschedule(text, delay);\n return (async (): Promise<stepresult> => {\n for (const entry of schedule) {\n await wait(entry.delay);\n field.dispatchEvent(keyevent(\"keydown\", entry.key, []));\n field.dispatchEvent(new KeyboardEvent(\"keypress\", { key: entry.key, bubbles: true, cancelable: true }));\n field.value = `${field.value}${entry.key}`;\n field.dispatchEvent(new Event(\"input\", { bubbles: true }));\n }\n field.dispatchEvent(new Event(\"change\", { bubbles: true }));\n return { ok: true, summary: `Typed ${text.length} character${text.length === 1 ? \"\" : \"s\"} with a per keystroke delay of ${delay} milliseconds.` };\n })();\n }\n case \"appendtext\": {\n const field = fieldlike(target);\n if (!field) return { ok: false, summary: \"Target cannot hold a value.\" };\n focuswhenneeded(field, options);\n field.value = appendvalue(field.value, step.value ?? \"\");\n events(field);\n return { ok: true, summary: \"Reviewed text appended to the current field value.\" };\n }\n case \"setvalue\": {\n const field = fieldlike(target);\n if (!field) return { ok: false, summary: \"Target cannot hold a value.\" };\n focuswhenneeded(field, options);\n field.value = step.value ?? \"\";\n events(field);\n return { ok: true, summary: `Field value set through the dom property with ${valueevents().join(\" and \")} events.` };\n }\n case \"typeedit\": {\n if (!(target instanceof HTMLElement) || !target.isContentEditable) return { ok: false, summary: \"Target is not a content editable region.\" };\n focuswhenneeded(target, options);\n const text = step.value ?? \"\";\n return (async (): Promise<stepresult> => {\n for (const character of [...text]) {\n target.dispatchEvent(new InputEvent(\"beforeinput\", { bubbles: true, cancelable: true, data: character, inputType: \"insertText\" }));\n target.append(document.createTextNode(character));\n target.dispatchEvent(new InputEvent(\"input\", { bubbles: true, data: character, inputType: \"insertText\" }));\n }\n return { ok: true, summary: `Typed ${text.length} character${text.length === 1 ? \"\" : \"s\"} into the content editable region.` };\n })();\n }\n case \"keyhold\": {\n const key = step.value ?? \"\";\n const mods = modifiers(options);\n receiver(target).dispatchEvent(keyevent(\"keydown\", key, mods));\n const holdid = typeof options.holdid === \"string\" && options.holdid ? options.holdid : \"\";\n return { ok: true, summary: `Key ${key} pressed and held${holdid ? ` under hold id ${holdid}` : \"\"}.`, details: { ...(holdid ? { holdid } : {}), modifiers: mods } };\n }\n case \"keyrelease\": {\n const key = step.value ?? \"\";\n const mods = modifiers(options);\n receiver(target).dispatchEvent(keyevent(\"keyup\", key, mods));\n return { ok: true, summary: `Key ${key} released.`, details: { modifiers: mods } };\n }\n case \"submitsearch\": {\n const field = fieldlike(target);\n if (!field) return { ok: false, summary: \"Target is not a search field.\" };\n const results = typeof options.results === \"string\" ? options.results : \"\";\n const timeout = typeof options.timeout === \"number\" ? options.timeout : 0;\n focuswhenneeded(field, options);\n field.dispatchEvent(keyevent(\"keydown\", \"Enter\", []));\n field.dispatchEvent(new KeyboardEvent(\"keypress\", { key: \"Enter\", bubbles: true, cancelable: true }));\n field.dispatchEvent(keyevent(\"keyup\", \"Enter\", []));\n return pollfor(() => Boolean(document.querySelector(results)), `Results region ${results}`, timeout);\n }\n case \"selectmulti\": {\n if (!(target instanceof HTMLSelectElement) || !target.multiple) return { ok: false, summary: \"Target is not a multi select control.\" };\n const choices = [...target.options].map(option => ({ value: option.value, label: clean(option.textContent || option.value) }));\n const requested = Array.isArray(options.values) ? options.values.filter((item): item is string => typeof item === \"string\") : [];\n const outcome = multichoices(requested, choices);\n if (outcome.missing.length > 0) return { ok: false, summary: `Reviewed option${outcome.missing.length === 1 ? \"\" : \"s\"} ${outcome.missing.join(\", \")} ${outcome.missing.length === 1 ? \"is\" : \"are\"} not part of the select control.` };\n for (const option of target.options) option.selected = outcome.present.includes(option.value);\n events(target);\n return { ok: true, summary: `Selected ${outcome.present.length} reviewed option${outcome.present.length === 1 ? \"\" : \"s\"} in the multi select control.`, details: { selected: outcome.present } };\n }\n case \"chooseradio\": {\n const radios = target instanceof HTMLInputElement && target.type === \"radio\"\n ? [...root.querySelectorAll<HTMLInputElement>(`input[type=radio][name=\"${CSS.escape(target.name)}\"]`)]\n : target ? [...(target as ParentNode).querySelectorAll<HTMLInputElement>(\"input[type=radio]\")] : [];\n if (radios.length === 0) return { ok: false, summary: \"No radio group owns the reviewed target.\" };\n const inputs = radios.map(radio => ({ value: radio.value, label: radio.labels && radio.labels.length > 0 ? clean(radio.labels[0]?.textContent || \"\") || radio.value : radio.value }));\n const index = radiochoice(inputs, step.value ?? \"\");\n const chosen = radios[index];\n if (!chosen) return { ok: false, summary: \"The reviewed radio option is not part of the group.\" };\n chosen.checked = true;\n events(chosen);\n return { ok: true, summary: `Picked reviewed radio option ${step.value}.`, details: { value: chosen.value } };\n }\n case \"setslider\": {\n if (!(target instanceof HTMLInputElement) || target.type !== \"range\") return { ok: false, summary: \"Target is not a range slider.\" };\n const requested = Number(step.value);\n if (!Number.isFinite(requested)) return { ok: false, summary: \"The reviewed slider value is not a number.\" };\n focuswhenneeded(target, options);\n const value = slidervalue(requested, Number(target.min), Number(target.max), Number(target.step));\n target.value = String(value);\n events(target);\n return { ok: true, summary: `Slider dragged to the reviewed value ${value}.`, details: { value } };\n }\n case \"setdate\": {\n if (!(target instanceof HTMLInputElement) || target.type !== \"date\") return { ok: false, summary: \"Target is not a date input.\" };\n const value = datevalue(step.value ?? \"\");\n if (value === null) return { ok: false, summary: \"The reviewed date is invalid.\" };\n focuswhenneeded(target, options);\n target.value = value;\n events(target);\n return { ok: true, summary: `Date input set to ${value}.`, details: { value } };\n }\n case \"setcolor\": {\n if (!(target instanceof HTMLInputElement) || target.type !== \"color\") return { ok: false, summary: \"Target is not a color input.\" };\n const value = colorvalue(step.value ?? \"\");\n if (value === null) return { ok: false, summary: \"The reviewed color is invalid.\" };\n focuswhenneeded(target, options);\n target.value = value;\n events(target);\n return { ok: true, summary: `Color input set to ${value}.`, details: { value } };\n }\n case \"expanddetails\": {\n const details = target instanceof HTMLElement ? target.closest(\"details\") : null;\n if (!details) return { ok: false, summary: \"Target is not inside a details section.\" };\n const outcome = expandstate(details.open);\n details.open = outcome.open;\n return { ok: true, summary: outcome.changed ? \"Collapsed details section opened.\" : \"Details section was already open.\", details: { changed: outcome.changed } };\n }\n default: return { ok: false, summary: \"Unsupported control action.\" };\n }\n}\n", "import type { pointpath, speedprofile, toolstep } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\nimport type { stepresult } from \"./pageactions.js\";\nimport { resolvestep, type stepresolution } from \"./pageresolve.js\";\n\n/**\n * Pointer path and coordinate click logics for reviewed steps.\n * Every correlated rule for waypoint interpolation, easing, jitter, hop settling, pointer sequences and coordinate clicks lives in this file.\n */\n\n/** One interpolated pointer position with the settle delay before it is dispatched. */\nexport interface pointerhop {\n x: number;\n y: number;\n delay: number;\n}\n\n/** One planned pointer or mouse event of a coordinate click sequence. */\nexport interface plannedevent {\n type: string;\n eventkind: \"pointer\" | \"mouse\";\n x: number;\n y: number;\n shift: boolean;\n}\n\nconst basecadence = 16;\n\nfunction distance(a: { x: number; y: number }, b: { x: number; y: number }): number {\n return Math.hypot(b.x - a.x, b.y - a.y);\n}\n\nfunction ease(easing: \"linear\" | \"easeinout\", progress: number): number {\n if (easing === \"easeinout\") return progress * progress * (3 - 2 * progress);\n return progress;\n}\n\nfunction ispointref(value: unknown): value is { x: number; y: number } {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n const point = value as Record<string, unknown>;\n return typeof point.x === \"number\" && Number.isFinite(point.x) && typeof point.y === \"number\" && Number.isFinite(point.y);\n}\n\n/** Interpolates one reviewed pointer path into settle-delimited hops, honoring the reviewed easing, peak velocity and jitter window. */\nexport function pathhops(path: pointpath, profile: speedprofile | undefined, random: () => number = Math.random, cadence: number = basecadence): pointerhop[] {\n const easing = profile?.easing === \"easeinout\" ? \"easeinout\" : \"linear\";\n const peak = typeof profile?.peak === \"number\" && profile.peak > 0 ? profile.peak : undefined;\n const jitter = typeof profile?.jitter === \"number\" && profile.jitter > 0 ? profile.jitter : 0;\n const points: Array<{ x: number; y: number }> = [path.start, ...(path.waypoints ?? []), path.end];\n const lengths: number[] = [];\n let total = 0;\n for (let index = 1; index < points.length; index += 1) {\n const length = distance(points[index - 1] as { x: number; y: number }, points[index] as { x: number; y: number });\n lengths.push(length);\n total += length;\n }\n const reviewedduration = typeof path.duration === \"number\" && Number.isFinite(path.duration) && path.duration > 0 ? path.duration : undefined;\n const duration = reviewedduration ?? (peak !== undefined && total > 0 ? (total / peak) * 1000 : 300);\n const hops: pointerhop[] = [];\n let previous = points[0] as { x: number; y: number };\n for (let index = 1; index < points.length; index += 1) {\n const from = points[index - 1] as { x: number; y: number };\n const to = points[index] as { x: number; y: number };\n const length = lengths[index - 1] ?? 0;\n if (total <= 0 || length <= 0) {\n hops.push({ x: to.x, y: to.y, delay: 0 });\n previous = to;\n continue;\n }\n const segmentduration = (duration * length) / total;\n const count = Math.max(1, Math.ceil(segmentduration / Math.max(1, cadence)));\n for (let hop = 1; hop <= count; hop += 1) {\n const progress = hop / count;\n const eased = ease(easing, progress);\n const position = { x: from.x + (to.x - from.x) * eased, y: from.y + (to.y - from.y) * eased };\n const step = distance(previous, position);\n const base = segmentduration / count;\n const capped = peak !== undefined ? Math.max(base, (step / peak) * 1000) : base;\n hops.push({ x: position.x, y: position.y, delay: Math.max(0, capped + (jitter > 0 ? random() * jitter : 0)) });\n previous = position;\n }\n }\n return hops;\n}\n\n/** Builds the pointer event sequence around a reviewed path: pointerover, one pointermove per hop, then pointerout. */\nexport function pointersequence(hopcount: number): string[] {\n return [\"pointerover\", ...Array.from({ length: Math.max(0, hopcount) }, () => \"pointermove\"), \"pointerout\"];\n}\n\n/** Builds the full pointer click sequence for reviewed coordinates and modifiers. */\nexport function clickplan(x: number, y: number, modifiers: string[]): plannedevent[] {\n const shift = modifiers.includes(\"shift\");\n const pointer = (type: string): plannedevent => ({ type, eventkind: \"pointer\", x, y, shift });\n const mouse = (type: string): plannedevent => ({ type, eventkind: \"mouse\", x, y, shift });\n return [pointer(\"pointerover\"), pointer(\"pointermove\"), pointer(\"pointerdown\"), mouse(\"mousedown\"), pointer(\"pointerup\"), mouse(\"mouseup\"), mouse(\"click\")];\n}\n\n/** Dispatches one planned event on an element with the reviewed coordinates and modifier flags. */\nfunction dispatchplanned(element: Element, event: plannedevent): void {\n const init: MouseEventInit & PointerEventInit = { bubbles: true, cancelable: true, composed: true, clientX: event.x, clientY: event.y, shiftKey: event.shift };\n if (event.eventkind === \"pointer\") element.dispatchEvent(new PointerEvent(event.type, init));\n else element.dispatchEvent(new MouseEvent(event.type, init));\n}\n\n/** Dispatches the full pointer click sequence on one element with the reviewed modifiers. */\nexport function dispatchclick(element: HTMLElement, modifiers: string[] = []): void {\n const rect = element.getBoundingClientRect();\n const x = rect.left + rect.width / 2;\n const y = rect.top + rect.height / 2;\n for (const event of clickplan(x, y, modifiers)) dispatchplanned(element, event);\n}\n\n/** Scrolls one target into view before any pointer interaction. */\nexport function ensurevisible(element: HTMLElement): void {\n try { element.scrollIntoView({ block: \"center\", inline: \"nearest\", behavior: \"auto\" }); } catch { /* scroll containers may refuse; the interaction still proceeds */ }\n}\n\nfunction settle(delay: number): Promise<void> {\n return new Promise(resolve => window.setTimeout(resolve, delay));\n}\n\n/** Dispatches a pointermove event at one viewport position on the element under the pointer. */\nfunction dispatchmove(x: number, y: number): void {\n const element = document.elementFromPoint(x, y);\n const receiver = element ?? document.documentElement;\n receiver.dispatchEvent(new PointerEvent(\"pointermove\", { bubbles: true, cancelable: true, composed: true, clientX: x, clientY: y }));\n}\n\n/** Travels one reviewed pointpath with dispatched pointermove events, settling each hop before the next one. */\nasync function travel(path: pointpath, profile: speedprofile | undefined): Promise<stepresult> {\n const hops = pathhops(path, profile);\n const startelement = document.elementFromPoint(path.start.x, path.start.y) ?? document.documentElement;\n startelement.dispatchEvent(new PointerEvent(\"pointerover\", { bubbles: true, cancelable: true, composed: true, clientX: path.start.x, clientY: path.start.y }));\n for (const hop of hops) {\n await settle(hop.delay);\n dispatchmove(hop.x, hop.y);\n }\n const endelement = document.elementFromPoint(path.end.x, path.end.y) ?? document.documentElement;\n endelement.dispatchEvent(new PointerEvent(\"pointerout\", { bubbles: true, cancelable: true, composed: true, clientX: path.end.x, clientY: path.end.y }));\n return { ok: true, summary: `Pointer traveled ${hops.length} hop${hops.length === 1 ? \"\" : \"s\"} to the reviewed end point.` };\n}\n\n/** Runs one reviewed pointer step: movepointer paths, clickpoint coordinate clicks and shiftclick modified clicks. */\nexport function runpointerstep(step: toolstep, resolution: stepresolution): stepresult | Promise<stepresult> {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n if (step.kind === \"movepointer\") {\n const path = options.pointpath as Record<string, unknown> | undefined;\n if (!path || !ispointref(path.start) || !ispointref(path.end)) return { ok: false, summary: \"The reviewed pointer path is absent.\" };\n const waypoints = Array.isArray(path.waypoints) && path.waypoints.every(item => ispointref(item)) ? path.waypoints as pointpath[\"waypoints\"] : undefined;\n const fullpath: pointpath = { start: path.start, end: path.end, ...(waypoints ? { waypoints } : {}), ...(typeof path.duration === \"number\" && Number.isFinite(path.duration) ? { duration: path.duration } : {}) };\n return travel(fullpath, options.speedprofile as speedprofile | undefined);\n }\n if (step.kind === \"clickpoint\") {\n const reference = options.targetref as Record<string, unknown> | undefined;\n const x = Number(reference?.x);\n const y = Number(reference?.y);\n if (!Number.isFinite(x) || !Number.isFinite(y)) return { ok: false, summary: \"The reviewed click coordinates are absent.\" };\n const element = document.elementFromPoint(x, y);\n if (!(element instanceof HTMLElement)) return { ok: false, summary: \"No element is rendered at the reviewed coordinates.\" };\n ensurevisible(element);\n for (const event of clickplan(x, y, [])) dispatchplanned(element, event);\n return { ok: true, summary: `Clicked the element at the reviewed coordinates ${x},${y}.` };\n }\n if (step.kind === \"shiftclick\") {\n if (resolution.status === \"ambiguous\") return { ok: false, summary: `The reviewed reference matched ${resolution.candidates.length} elements; choose one candidate.`, details: { mode: resolution.mode, candidates: resolution.candidates } };\n if (resolution.status !== \"resolved\") return { ok: false, summary: \"Action target is no longer available.\" };\n ensurevisible(resolution.element);\n dispatchclick(resolution.element, [\"shift\"]);\n return { ok: true, summary: `Shift click delivered to ${resolution.target.label || resolution.target.tag}.`, details: { mode: resolution.target.mode, resolvedtarget: resolution.target } };\n }\n return { ok: false, summary: \"Unsupported pointer action.\" };\n}\n", "import type { retryrule, toolstep } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\nimport type { stepresult } from \"./pageactions.js\";\nimport { describeframes, queryscoped, queryshadowchain, resolvestep, targetsummary, walkframepath } from \"./pageresolve.js\";\nimport { dispatchclick, ensurevisible } from \"./pagepointer.js\";\n\n/**\n * Resolution driven interactions for reviewed steps.\n * Every correlated rule for text, aria and name clicks, shadow piercing, frame routing, wrapper step extraction and the retry loop lives in this file.\n */\n\n/** Reads the reviewed options of a step without throwing on malformed payloads. */\nfunction optionsof(step: toolstep): Record<string, unknown> {\n try { return parseoptions(step); } catch { return {}; }\n}\n\n/** Extracts the reviewed inner step of a retry or frame wrapper from its inline options. */\nexport function innerstep(step: toolstep): toolstep | null {\n const options = optionsof(step);\n const kind = options.kind;\n if (typeof kind !== \"string\" || !kind.trim()) return null;\n const inneroptions = options.options;\n return {\n id: `${step.id}inner`,\n kind: kind as toolstep[\"kind\"],\n summary: step.summary,\n risk: step.risk,\n ...(typeof options.target === \"string\" ? { target: options.target } : {}),\n ...(typeof options.value === \"string\" ? { value: options.value } : {}),\n ...(inneroptions && typeof inneroptions === \"object\" && !Array.isArray(inneroptions) ? { options: JSON.stringify(inneroptions) } : {}),\n };\n}\n\nfunction pointdistance(a: { x: number; y: number }, b: { x: number; y: number }): number {\n return Math.hypot(b.x - a.x, b.y - a.y);\n}\n\nfunction settle(delay: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, delay));\n}\n\nexport interface retryoutcomeplan {\n ok: boolean;\n attempts: number;\n movement: number;\n summary: string;\n}\n\n/** Runs the reviewed retry loop: each failed attempt waits the settle window, revalidates the target geometry and reruns only when the element moved beyond the tolerance. */\nexport async function runretries(rule: retryrule, probe: () => Promise<{ x: number; y: number } | null>, execute: (attempt: number) => Promise<{ ok: boolean; summary: string }>): Promise<retryoutcomeplan> {\n const attempts = Math.max(1, Number.isFinite(rule.attempts) ? Math.floor(rule.attempts) : 1);\n const tolerance = typeof rule.tolerance === \"number\" && Number.isFinite(rule.tolerance) ? rule.tolerance : 0;\n const settles = typeof rule.settle === \"number\" && Number.isFinite(rule.settle) ? rule.settle : 0;\n let previous = await probe();\n let movement = 0;\n let made = 0;\n let last = \"\";\n for (let attempt = 1; attempt <= attempts; attempt += 1) {\n made = attempt;\n const result = await execute(attempt);\n last = result.summary;\n if (result.ok) return { ok: true, attempts: made, movement, summary: `Retry interaction succeeded on attempt ${made} after ${movement.toFixed(1)} pixels of observed movement.` };\n if (attempt >= attempts) break;\n if (settles > 0) await settle(settles);\n const current = await probe();\n if (!current) { previous = null; continue; }\n if (previous) {\n const delta = pointdistance(previous, current);\n movement = Math.max(movement, delta);\n if (delta <= tolerance) return { ok: false, attempts: made, movement, summary: `The target stayed within the reviewed tolerance of ${tolerance} pixels; retry stopped after attempt ${made}. ${last}` };\n }\n previous = current;\n }\n return { ok: false, attempts: made, movement, summary: `Retry interaction failed after ${made} attempt${made === 1 ? \"\" : \"s\"} with ${movement.toFixed(1)} pixels of observed movement. ${last}` };\n}\n\n/** Dispatches one reviewed click on a resolved element and reports the target mode used. */\nfunction clickresolved(stepkind: string, resolution: ReturnType<typeof resolvestep>): stepresult {\n if (resolution.status === \"ambiguous\") return { ok: false, summary: `The reviewed ${resolution.mode} reference matched ${resolution.candidates.length} elements: ${resolution.candidates.join(\"; \")}.`, details: { mode: resolution.mode, candidates: resolution.candidates } };\n if (resolution.status !== \"resolved\") return { ok: false, summary: \"The reviewed target is no longer available.\" };\n ensurevisible(resolution.element);\n dispatchclick(resolution.element);\n return { ok: true, summary: `Clicked ${resolution.target.label || resolution.target.tag} resolved by ${stepkind} ${resolution.target.mode} mode.`, details: { mode: resolution.target.mode, resolvedtarget: resolution.target } };\n}\n\n/** Runs one resolution driven interaction: text, aria and name clicks, shadow piercing and frame routing. */\nexport function runinteractstep(step: toolstep, expectedorigin: string, dispatch: (inner: toolstep, origin: string, root?: Document) => stepresult | Promise<stepresult>): stepresult | Promise<stepresult> {\n if (step.kind === \"clicktext\" || step.kind === \"clickaria\" || step.kind === \"clickname\") {\n return clickresolved(step.kind, resolvestep(step, document));\n }\n if (step.kind === \"pierceshadow\") {\n const options = optionsof(step);\n const shadow = Array.isArray(options.shadow) ? options.shadow.filter((item): item is string => typeof item === \"string\" && item.trim().length > 0) : [];\n const element = shadow.length > 0 ? queryshadowchain(document, shadow) : queryscoped(document, step.target ?? \"\");\n if (!(element instanceof HTMLElement)) return { ok: false, summary: \"The reviewed shadow target is not available.\" };\n ensurevisible(element);\n dispatchclick(element);\n const summary = targetsummary(\"selector\", element);\n return { ok: true, summary: `Clicked ${summary.label || summary.tag} resolved through ${shadow.length > 0 ? \"the reviewed shadow path\" : \"open shadow roots\"}.`, details: { mode: \"selector\", resolvedtarget: summary } };\n }\n if (step.kind === \"enterframe\") {\n const options = optionsof(step);\n const path = Array.isArray(options.framepath) ? options.framepath.filter((item): item is number => typeof item === \"number\" && Number.isInteger(item) && item >= 0) : [];\n const walk = walkframepath(describeframes(document), path);\n if (!walk.ok) return { ok: false, summary: walk.reason };\n const framedocument = walk.document.live;\n if (!framedocument) return { ok: false, summary: \"The reviewed frame document is not available.\" };\n const inner = innerstep(step);\n if (!inner) return { ok: false, summary: \"The reviewed inner step is absent.\" };\n return dispatch(inner, expectedorigin, framedocument);\n }\n return { ok: false, summary: \"Unsupported interaction action.\" };\n}\n", "import type { navtarget, toolstep, urlpattern, waitoverride, waitprofile } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\nimport type { stepresult } from \"./pageactions.js\";\n\n/**\n * Page navigation logics for reviewed steps.\n * Every correlated rule for navigation targets, container resolution, wait profiles, url patterns, link following, spa routing, query rewriting, deep links and recent tabs lives in this file.\n */\n\n/** One link shape matched by followlink and spanav, serializable for fixtures. */\nexport interface linkshape {\n text: string;\n href: string;\n selector: string;\n}\n\n/** One collected load signal sample with the signals that held true at its time. */\nexport interface signalsample {\n at: number;\n signals: string[];\n}\n\n/** Resolved container plan of one navigation target across tabs, windows and private profiles. */\nexport interface containerplan {\n kind: \"current\" | \"tab\" | \"window\" | \"private\";\n incognito: boolean;\n windowid?: number;\n position: \"adjacent\" | \"end\";\n}\n\n/** Reads the reviewed navtarget of a navigation step; null when the step reviews none. */\nexport function parsenavtarget(step: toolstep): navtarget | null {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n const value = options.navtarget;\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return null;\n const target = value as Record<string, unknown>;\n if (typeof target.url !== \"string\" || !target.url) return null;\n const container = target.container === \"current\" || target.container === \"window\" || target.container === \"private\" ? target.container : \"tab\";\n return {\n url: target.url,\n container,\n ...(target.position === \"end\" ? { position: \"end\" } : { position: \"adjacent\" }),\n private: container === \"private\" || target.private === true,\n };\n}\n\n/** Resolves the container plan of one navigation target: the current task tab, a new tab, a new window or a private window profile separated from normal windows. */\nexport function resolvecontainer(target: navtarget, windows: Array<{ id: number; incognito: boolean; focused: boolean }>): containerplan {\n if (target.container === \"current\") return { kind: \"current\", incognito: false, position: target.position ?? \"adjacent\" };\n if (target.container === \"private\" || target.private) return { kind: \"private\", incognito: true, position: target.position ?? \"adjacent\" };\n if (target.container === \"window\") {\n const focused = windows.find(item => item.focused);\n return { kind: \"window\", incognito: false, ...(focused ? { windowid: focused.id } : {}), position: target.position ?? \"adjacent\" };\n }\n const normal = windows.find(item => !item.incognito && item.focused) ?? windows.find(item => !item.incognito);\n return { kind: \"tab\", incognito: false, ...(normal ? { windowid: normal.id } : {}), position: target.position ?? \"adjacent\" };\n}\n\n/** Reads the reviewed waitprofile of a navprofile step; null when the step reviews none. */\nexport function parsewaitprofile(step: toolstep): waitprofile | null {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n const value = options.waitprofile;\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return null;\n const profile = value as Record<string, unknown>;\n const signals = Array.isArray(profile.signals) ? profile.signals.filter((item): item is string => typeof item === \"string\" && item.trim().length > 0) : [];\n if (signals.length === 0) return null;\n const overrides: waitoverride[] = [];\n if (Array.isArray(profile.overrides)) {\n for (const item of profile.overrides) {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) continue;\n const override = item as Record<string, unknown>;\n if (typeof override.origin !== \"string\" || !override.origin) continue;\n const overridesignals = Array.isArray(override.signals) ? override.signals.filter((entry): entry is string => typeof entry === \"string\" && entry.trim().length > 0) : undefined;\n overrides.push({\n origin: override.origin,\n ...(overridesignals && overridesignals.length > 0 ? { signals: overridesignals } : {}),\n ...(typeof override.idle === \"number\" && Number.isFinite(override.idle) && override.idle >= 0 ? { idle: override.idle } : {}),\n ...(typeof override.timeout === \"number\" && Number.isFinite(override.timeout) && override.timeout >= 0 ? { timeout: override.timeout } : {}),\n });\n }\n }\n return {\n signals,\n ...(typeof profile.idle === \"number\" && Number.isFinite(profile.idle) && profile.idle >= 0 ? { idle: profile.idle } : {}),\n ...(typeof profile.timeout === \"number\" && Number.isFinite(profile.timeout) && profile.timeout >= 0 ? { timeout: profile.timeout } : {}),\n ...(overrides.length > 0 ? { overrides } : {}),\n };\n}\n\n/** Resolves the effective signals and thresholds of one wait profile for an origin by folding the per origin overrides in. */\nexport function profilefororigin(profile: waitprofile, origin: string): { signals: string[]; idle: number; timeout: number } {\n let signals = [...profile.signals];\n let idle = profile.idle ?? 0;\n let timeout = profile.timeout ?? 0;\n for (const override of profile.overrides ?? []) {\n if (!override.origin || new URL(override.origin).origin !== origin) continue;\n if (override.signals && override.signals.length > 0) signals = [...override.signals];\n if (override.idle !== undefined) idle = override.idle;\n if (override.timeout !== undefined) timeout = override.timeout;\n }\n return { signals, idle, timeout };\n}\n\n/** Maps a document ready state onto the live navigation load phase. */\nexport function loadphase(readystate: string): \"loading\" | \"interactive\" | \"complete\" {\n if (readystate === \"interactive\") return \"interactive\";\n if (readystate === \"complete\") return \"complete\";\n return \"loading\";\n}\n\n/** Decides the wait outcome of a wait profile from collected load signal samples: every required signal must hold in the latest sample inside the timeout. */\nexport function evaluatesignals(required: string[], samples: signalsample[], timeout: number): { ok: boolean; satisfied: string[]; waited: number; samples: number } {\n const start = samples[0]?.at ?? 0;\n const last = samples[samples.length - 1];\n const waited = Math.max(0, (last?.at ?? 0) - start);\n const held = last?.signals ?? [];\n const satisfied = required.filter(signal => held.includes(signal));\n if (required.length > 0 && satisfied.length === required.length) return { ok: true, satisfied, waited, samples: samples.length };\n if (timeout > 0 && waited >= timeout) return { ok: false, satisfied, waited, samples: samples.length };\n return { ok: false, satisfied, waited, samples: samples.length };\n}\n\n/** Reads the reviewed urlpattern of a waiturl, spanav or spawait step; null when the step reviews none. */\nexport function parseurlpattern(step: toolstep, key: string = \"urlpattern\"): urlpattern | null {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n const value = options[key];\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return null;\n const pattern = value as Record<string, unknown>;\n if (typeof pattern.url !== \"string\" || !pattern.url) return null;\n const mode = pattern.mode === \"exact\" || pattern.mode === \"host\" || pattern.mode === \"pattern\" ? pattern.mode : \"prefix\";\n const query: Record<string, string> = {};\n if (pattern.query && typeof pattern.query === \"object\" && !Array.isArray(pattern.query)) {\n for (const [name, item] of Object.entries(pattern.query as Record<string, unknown>)) if (typeof item === \"string\") query[name] = item;\n }\n return {\n mode,\n url: pattern.url,\n ...(Object.keys(query).length > 0 ? { query } : {}),\n ...(typeof pattern.fragment === \"string\" && pattern.fragment ? { fragment: pattern.fragment } : {}),\n };\n}\n\n/** Matches a wildcard path segment against one url path segment. */\nfunction segmentmatches(pattern: string, actual: string): boolean {\n if (pattern === \"*\" || pattern === \"**\") return true;\n if (!pattern.includes(\"*\")) return pattern === actual;\n const parts = pattern.split(\"*\");\n let index = 0;\n for (let position = 0; position < parts.length; position += 1) {\n const part = parts[position] as string;\n if (part === \"\") continue;\n const found = actual.indexOf(part, index);\n if (found < 0) return false;\n if (position === 0 && found !== 0) return false;\n index = found + part.length;\n }\n const last = parts[parts.length - 1] as string;\n return last === \"\" || actual.endsWith(last);\n}\n\n/** Matches one url against a reviewed urlpattern by mode plus required query and fragment parts. */\nexport function urlmatches(url: string, pattern: urlpattern): boolean {\n let parsed: URL;\n try { parsed = new URL(url); } catch { return false; }\n let expected: URL;\n try { expected = new URL(pattern.url); } catch { return false; }\n if (pattern.mode === \"exact\" && parsed.toString() !== expected.toString()) return false;\n if (pattern.mode === \"prefix\" && !parsed.toString().startsWith(pattern.url)) return false;\n if (pattern.mode === \"host\" && parsed.origin !== expected.origin) return false;\n if (pattern.mode === \"pattern\") {\n if (parsed.origin !== expected.origin) return false;\n const expectedsegments = expected.pathname.split(\"/\").filter(segment => segment !== \"\");\n const actualsegments = parsed.pathname.split(\"/\").filter(segment => segment !== \"\");\n if (expectedsegments.includes(\"**\")) {\n const cut = expectedsegments.indexOf(\"**\");\n const head = expectedsegments.slice(0, cut);\n const tail = expectedsegments.slice(cut + 1);\n if (actualsegments.length < head.length + tail.length) return false;\n if (!head.every((segment, position) => segmentmatches(segment, actualsegments[position] ?? \"\"))) return false;\n if (!tail.every((segment, position) => segmentmatches(segment, actualsegments[actualsegments.length - tail.length + position] ?? \"\"))) return false;\n } else if (expectedsegments.length !== actualsegments.length || !expectedsegments.every((segment, position) => segmentmatches(segment, actualsegments[position] ?? \"\"))) return false;\n }\n const values = parsed.searchParams;\n for (const [name, value] of Object.entries(pattern.query ?? {})) {\n if (!values.has(name)) return false;\n if (value !== \"*\" && values.get(name) !== value) return false;\n }\n if (pattern.fragment !== undefined && parsed.hash.slice(1) !== pattern.fragment) return false;\n return true;\n}\n\n/** Reads the current query parameters of a url. */\nfunction readquery(url: string): Record<string, string> {\n const values: Record<string, string> = {};\n try {\n for (const [name, value] of new URL(url).searchParams.entries()) values[name] = value;\n } catch { /* an unparseable url has no readable parameters */ }\n return values;\n}\n\n/** Result of one query rewrite with the parameters read, written and the new url. */\nexport interface queryrewriteoutcome {\n url: string;\n before: Record<string, string>;\n after: Record<string, string>;\n set: string[];\n removed: string[];\n}\n\n/** Rewrites the query parameters of one url: reviewed values are set, reviewed names removed and the rest preserved. */\nexport function rewritequeryurl(url: string, set: Record<string, string>, remove: string[]): queryrewriteoutcome {\n const parsed = new URL(url);\n const before = readquery(url);\n for (const name of remove) parsed.searchParams.delete(name);\n for (const [name, value] of Object.entries(set)) parsed.searchParams.set(name, value);\n parsed.hash = \"\";\n return { url: parsed.toString(), before, after: readquery(parsed.toString()), set: Object.keys(set), removed: [...remove] };\n}\n\n/** Applies one reviewed fragment to a url, keeping every other part untouched. */\nexport function fragmenturl(url: string, fragment: string): string {\n const parsed = new URL(url);\n parsed.hash = fragment.replace(/^#/, \"\");\n return parsed.toString();\n}\n\n/** Matches links by their visible text, case insensitively, refusing ambiguity through multiple matches. */\nexport function matchlinktext(links: linkshape[], text: string): linkshape[] {\n const wanted = text.trim().toLowerCase();\n return links.filter(link => link.text.trim().toLowerCase() === wanted);\n}\n\n/** Matches links by their href fragment when the reviewed option asks for fragment resolution. */\nexport function matchlinkfragment(links: linkshape[], fragment: string): linkshape[] {\n const wanted = fragment.trim().replace(/^#/, \"\");\n return links.filter(link => {\n try { return new URL(link.href, \"https://example.invalid\").hash.replace(/^#/, \"\") === wanted; } catch { return false; }\n });\n}\n\n/** Builds a deep link into a common web app from a reviewed app pattern and its string params; unknown apps are refused. */\nexport function deeplinkurl(app: string, params: Record<string, string>): string | null {\n const value = (name: string): string | undefined => {\n const item = params[name];\n return typeof item === \"string\" && item.trim() ? item.trim() : undefined;\n };\n switch (app.trim().toLowerCase()) {\n case \"github\": {\n const owner = value(\"owner\");\n const repo = value(\"repo\");\n if (!owner || !repo) return null;\n const path = value(\"path\");\n return `https://github.com/${owner}/${repo}${path ? `/${path.replace(/^\\/+/, \"\")}` : \"\"}`;\n }\n case \"youtube\": {\n const id = value(\"id\");\n if (id) return `https://www.youtube.com/watch?v=${encodeURIComponent(id)}`;\n const search = value(\"search\");\n if (search) return `https://www.youtube.com/results?search_query=${encodeURIComponent(search)}`;\n return null;\n }\n case \"maps\": {\n const query = value(\"query\");\n if (!query) return null;\n return `https://www.google.com/maps/search/${encodeURIComponent(query)}`;\n }\n case \"wikipedia\": {\n const title = value(\"title\");\n if (!title) return null;\n const language = value(\"language\") ?? \"en\";\n return `https://${language}.wikipedia.org/wiki/${encodeURIComponent(title.replace(/\\s+/g, \"_\"))}`;\n }\n case \"amazon\": {\n const search = value(\"search\");\n if (!search) return null;\n return `https://www.amazon.com/s?k=${encodeURIComponent(search)}`;\n }\n case \"x\": {\n const user = value(\"user\");\n if (!user) return null;\n return `https://x.com/${user.replace(/^@/, \"\")}`;\n }\n default: return null;\n }\n}\n\n/** True when the current url of a single page app changed without a reload, keeping the origin. */\nexport function spauroutechanged(previousurl: string, currenturl: string): boolean {\n if (previousurl === currenturl) return false;\n try {\n return new URL(previousurl).origin === new URL(currenturl).origin;\n } catch { return false; }\n}\n\n/** Picks the most recently closed tab whose url is no longer open; null when every recent tab is already restored. */\nexport function pickrecenttab(recenttabs: Array<{ url: string; tabid: number; closedat: number }>, openurls: string[]): { url: string; tabid: number; closedat: number } | null {\n return recenttabs.find(tab => !openurls.includes(tab.url)) ?? null;\n}\n\nfunction wait(ms: number): Promise<void> {\n return new Promise(resolve => window.setTimeout(resolve, ms));\n}\n\nfunction stepoptions(step: toolstep): Record<string, unknown> {\n try { return parseoptions(step); } catch { return {}; }\n}\n\nfunction collectlinks(root: Document): linkshape[] {\n return [...root.querySelectorAll(\"a[href]\")].map(element => ({\n text: element.textContent?.trim() ?? \"\",\n href: element instanceof HTMLAnchorElement ? element.href : element.getAttribute(\"href\") ?? \"\",\n selector: element.getAttribute(\"href\") ?? \"\",\n }));\n}\n\n/** Resolves the reviewed link of a followlink or spanav step by visible text or href fragment, refusing links outside the allowed origins. */\nfunction resolvelink(step: toolstep, root: Document): { ok: true; element: HTMLAnchorElement } | { ok: false; summary: string } {\n const options = stepoptions(step);\n const allowedorigins = Array.isArray(options.allowedorigins) ? options.allowedorigins.filter((item): item is string => typeof item === \"string\") : [];\n const links = collectlinks(root);\n const matches = options.fragment === true ? matchlinkfragment(links, step.value ?? \"\") : matchlinktext(links, step.value ?? \"\");\n if (matches.length === 0) return { ok: false, summary: `No link matches the reviewed reference \"${step.value ?? \"\"}\".` };\n if (matches.length > 1) return { ok: false, summary: `The reviewed link reference matched ${matches.length} links; review a unique one.` };\n const element = [...root.querySelectorAll(\"a[href]\")].find(candidate => (candidate instanceof HTMLAnchorElement ? candidate.href : candidate.getAttribute(\"href\") ?? \"\") === matches[0]?.href);\n if (!(element instanceof HTMLAnchorElement)) return { ok: false, summary: \"The reviewed link is no longer available.\" };\n if (allowedorigins.length > 0) {\n let origin = \"\";\n try { origin = new URL(element.href).origin; } catch { origin = \"\"; }\n if (!allowedorigins.includes(origin)) return { ok: false, summary: `The reviewed link leaves the session origin grants for ${origin}.` };\n }\n return { ok: true, element };\n}\n\n/** Waits for the page load event and reports the ready state and load phase. */\nasync function runwaitload(step: toolstep): Promise<stepresult> {\n const options = stepoptions(step);\n const timeout = typeof options.timeout === \"number\" && Number.isFinite(options.timeout) && options.timeout > 0 ? options.timeout : 0;\n const started = Date.now();\n for (;;) {\n const phase = loadphase(document.readyState);\n if (phase === \"complete\") return { ok: true, summary: `The page load event fired and the document is complete after ${Date.now() - started} milliseconds.`, details: { phase, readystate: document.readyState, waited: Date.now() - started } };\n if (timeout > 0 && Date.now() - started >= timeout) return { ok: false, summary: `The page did not reach the complete load phase within the reviewed timeout of ${timeout} milliseconds.`, details: { phase, readystate: document.readyState, waited: Date.now() - started } };\n await wait(50);\n }\n}\n\n/** Waits until the current url matches the reviewed urlpattern. */\nasync function runwaiturl(step: toolstep): Promise<stepresult> {\n const options = stepoptions(step);\n const pattern = parseurlpattern(step);\n if (!pattern) return { ok: false, summary: \"A reviewed urlpattern is required.\" };\n const timeout = typeof options.timeout === \"number\" && Number.isFinite(options.timeout) && options.timeout > 0 ? options.timeout : 0;\n const poll = typeof options.poll === \"number\" && Number.isFinite(options.poll) && options.poll > 0 ? options.poll : 100;\n const started = Date.now();\n for (;;) {\n if (urlmatches(location.href, pattern)) return { ok: true, summary: `The url matched the reviewed ${pattern.mode} pattern after ${Date.now() - started} milliseconds.`, details: { url: location.href, mode: pattern.mode, waited: Date.now() - started } };\n if (timeout > 0 && Date.now() - started >= timeout) return { ok: false, summary: `The url did not match the reviewed ${pattern.mode} pattern within the reviewed timeout of ${timeout} milliseconds.`, details: { url: location.href, mode: pattern.mode, waited: Date.now() - started } };\n await wait(poll);\n }\n}\n\n/** Follows one reviewed link, reporting the href travelled to. */\nasync function runfollowlink(step: toolstep, root: Document): Promise<stepresult> {\n const resolution = resolvelink(step, root);\n if (!resolution.ok) return { ok: false, summary: resolution.summary };\n const href = resolution.element.href;\n resolution.element.click();\n return { ok: true, summary: `Followed the reviewed link to ${href}.`, details: { href } };\n}\n\n/** Navigates a single page app by clicking the reviewed control and waiting for the route change without a reload. */\nasync function runspanav(step: toolstep, root: Document): Promise<stepresult> {\n const options = stepoptions(step);\n const resolution = resolvelink(step, root);\n if (!resolution.ok) return { ok: false, summary: resolution.summary };\n const timeout = typeof options.timeout === \"number\" && Number.isFinite(options.timeout) && options.timeout > 0 ? options.timeout : 0;\n const pattern = parseurlpattern(step, \"routepattern\");\n const before = location.href;\n resolution.element.click();\n const started = Date.now();\n for (;;) {\n const changed = spauroutechanged(before, location.href);\n const matched = pattern ? urlmatches(location.href, pattern) : changed;\n if (matched) return { ok: true, summary: `The single page app route changed to ${location.href} without a reload.`, details: { from: before, to: location.href, waited: Date.now() - started } };\n if (timeout > 0 && Date.now() - started >= timeout) return { ok: false, summary: `The single page app route did not change within the reviewed timeout of ${timeout} milliseconds.`, details: { from: before, to: location.href, waited: Date.now() - started } };\n await wait(50);\n }\n}\n\n/** Waits for a url change inside a single page app without a reload, through popstate, hashchange and history polling. */\nasync function runspawait(step: toolstep): Promise<stepresult> {\n const options = stepoptions(step);\n const timeout = typeof options.timeout === \"number\" && Number.isFinite(options.timeout) && options.timeout > 0 ? options.timeout : 0;\n const poll = typeof options.poll === \"number\" && Number.isFinite(options.poll) && options.poll > 0 ? options.poll : 100;\n const pattern = parseurlpattern(step);\n const before = location.href;\n const started = Date.now();\n let detected = false;\n const onroute = (): void => { if (spauroutechanged(before, location.href)) detected = true; };\n window.addEventListener(\"popstate\", onroute);\n window.addEventListener(\"hashchange\", onroute);\n try {\n for (;;) {\n if (pattern ? urlmatches(location.href, pattern) : detected || spauroutechanged(before, location.href)) {\n return { ok: true, summary: `The single page app url changed to ${location.href} without a reload.`, details: { from: before, to: location.href, waited: Date.now() - started } };\n }\n if (timeout > 0 && Date.now() - started >= timeout) return { ok: false, summary: `The single page app url did not change within the reviewed timeout of ${timeout} milliseconds.`, details: { from: before, to: location.href, waited: Date.now() - started } };\n await wait(poll);\n }\n } finally {\n window.removeEventListener(\"popstate\", onroute);\n window.removeEventListener(\"hashchange\", onroute);\n }\n}\n\n/** Reads and rewrites the query parameters of the current url with pushstate, reporting the parameters read and the new url. */\nfunction runrewritequery(step: toolstep): stepresult {\n const options = stepoptions(step);\n const set: Record<string, string> = {};\n if (options.set && typeof options.set === \"object\" && !Array.isArray(options.set)) {\n for (const [name, value] of Object.entries(options.set as Record<string, unknown>)) if (typeof value === \"string\") set[name] = value;\n }\n const remove = Array.isArray(options.remove) ? options.remove.filter((item): item is string => typeof item === \"string\" && item.trim().length > 0) : [];\n const outcome = rewritequeryurl(location.href, set, remove);\n history.pushState(history.state, document.title, outcome.url);\n return { ok: true, summary: `Rewrote ${outcome.set.length + outcome.removed.length} query parameter${outcome.set.length + outcome.removed.length === 1 ? \"\" : \"s\"}; the url is now ${outcome.url}.`, details: { url: outcome.url, before: outcome.before, after: outcome.after, set: outcome.set, removed: outcome.removed } };\n}\n\n/** Sets the reviewed url fragment and scrolls to its anchor with smooth behavior. */\nasync function runsetfragment(step: toolstep): Promise<stepresult> {\n const fragment = (step.value ?? \"\").replace(/^#/, \"\");\n if (!fragment) return { ok: false, summary: \"A reviewed fragment is required.\" };\n const url = fragmenturl(location.href, fragment);\n history.pushState(history.state, document.title, url);\n const anchor = document.getElementById(fragment);\n anchor?.scrollIntoView({ behavior: \"smooth\", block: \"start\" });\n return { ok: true, summary: `Set the url fragment to ${fragment} and scrolled to its anchor.`, details: { url, fragment, anchored: Boolean(anchor) } };\n}\n\n/** Stops a pending navigation by halting the document load. */\nfunction runstopnav(): stepresult {\n window.stop();\n return { ok: true, summary: \"Stopped the pending navigation of the page.\" };\n}\n\n/** Prefetches the reviewed urls by injecting prefetch hints into the document head. */\nfunction runprefetch(step: toolstep): stepresult {\n const options = stepoptions(step);\n const urls = Array.isArray(options.urls) ? options.urls.filter((item): item is string => typeof item === \"string\" && item.trim().length > 0) : [];\n if (urls.length === 0) return { ok: false, summary: \"A reviewed list of prefetch urls is required.\" };\n for (const url of urls) {\n const hint = document.createElement(\"link\");\n hint.rel = \"prefetch\";\n hint.href = url;\n document.head.append(hint);\n }\n return { ok: true, summary: `Queued ${urls.length} prefetch hint${urls.length === 1 ? \"\" : \"s\"}.`, details: { urls } };\n}\n\n/** Preconnects to the reviewed origins by injecting preconnect hints into the document head. */\nfunction runpreconnect(step: toolstep): stepresult {\n const options = stepoptions(step);\n const origins = Array.isArray(options.origins) ? options.origins.filter((item): item is string => typeof item === \"string\" && item.trim().length > 0) : [];\n if (origins.length === 0) return { ok: false, summary: \"A reviewed list of preconnect origins is required.\" };\n for (const origin of origins) {\n const hint = document.createElement(\"link\");\n hint.rel = \"preconnect\";\n hint.href = origin;\n document.head.append(hint);\n }\n return { ok: true, summary: `Opened ${origins.length} preconnect hint${origins.length === 1 ? \"\" : \"s\"}.`, details: { origins } };\n}\n\n/** Prints the page through the browser print pipeline; the artifact routing happens in the background. */\nfunction runprintpdf(): stepresult {\n window.print();\n return { ok: true, summary: \"Sent the page to the browser print pipeline.\" };\n}\n\n/** Runs one reviewed page navigation kind inside the page world. */\nexport function runpagenav(step: toolstep, root: Document = document): stepresult | Promise<stepresult> {\n switch (step.kind) {\n case \"waitload\": return runwaitload(step);\n case \"waiturl\": return runwaiturl(step);\n case \"followlink\": return runfollowlink(step, root);\n case \"spanav\": return runspanav(step, root);\n case \"spawait\": return runspawait(step);\n case \"rewritequery\": return runrewritequery(step);\n case \"setfragment\": return runsetfragment(step);\n case \"stopnav\": return runstopnav();\n case \"prefetch\": return runprefetch(step);\n case \"preconnect\": return runpreconnect(step);\n case \"printpdf\": return runprintpdf();\n default: return { ok: false, summary: \"Unsupported navigation action.\" };\n }\n}\n", "import type { dialogpolicy, toolstep } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\n\n/**\n * Dialog policy logics for reviewed steps.\n * Every correlated rule for policy parsing, dialog answers, main world handler installation and observed dialog harvesting lives in this file.\n * The isolated world cannot override window.confirm, window.alert or window.prompt, so the background installs these wrappers through the scripting api in the main world.\n */\n\n/** One dialog observed by the main world handler, recorded on the shared document. */\nexport interface observeddialog {\n dialog: string;\n text: string;\n result: string | boolean | null;\n at: number;\n}\n\n/** Parses the reviewed dialog policy from step options; prompts need a reviewed answer. */\nexport function parsedialogpolicy(step: toolstep): dialogpolicy | null {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { return null; }\n const accept = options.accept;\n const answer = options.answer;\n if (typeof accept !== \"boolean\" && typeof answer !== \"string\") return null;\n return { accept: accept === true, ...(typeof answer === \"string\" && answer.trim() ? { answer } : {}) };\n}\n\n/** Decides how the reviewed policy answers one dialog kind; a prompt without a reviewed answer is dismissed. */\nexport function dialoganswer(policy: dialogpolicy, dialog: \"confirm\" | \"alert\" | \"prompt\"): { accept: boolean; answer?: string } {\n if (dialog === \"prompt\") {\n if (policy.answer === undefined || policy.answer === \"\") return { accept: false };\n return { accept: policy.accept !== false, ...(policy.answer !== undefined ? { answer: policy.answer } : {}) };\n }\n return { accept: policy.accept };\n}\n\n/** Reads and clears the dialog log the main world handler recorded on the shared document. */\nexport function harvestdialoglog(root: Document): observeddialog[] {\n const raw = root.documentElement.dataset.devthinkdialoglog;\n if (!raw) return [];\n delete root.documentElement.dataset.devthinkdialoglog;\n try {\n const parsed: unknown = JSON.parse(raw);\n if (!Array.isArray(parsed)) return [];\n return parsed.filter((item): item is observeddialog => Boolean(item) && typeof item === \"object\" && typeof (item as Record<string, unknown>).dialog === \"string\");\n } catch { return []; }\n}\n\n/** Installs confirm, alert and prompt wrappers in the page main world answering per the reviewed policy; runs through chrome.scripting with world main. */\nexport function installdialoghandler(accept: boolean, answer: string, persistent: boolean): void {\n const world = globalThis as typeof globalThis & { devthinkoriginaldialogs?: { confirm: (text?: string) => boolean; alert: (text?: string) => void; prompt: (text?: string, defaultvalue?: string) => string | null } };\n const originals = world.devthinkoriginaldialogs ?? { confirm: window.confirm.bind(window), alert: window.alert.bind(window), prompt: window.prompt.bind(window) };\n world.devthinkoriginaldialogs = originals;\n const decide = (dialog: string): { accept: boolean; answer: string | null } => {\n if (dialog === \"prompt\") return answer ? { accept: true, answer } : { accept: false, answer: null };\n return { accept, answer: null };\n };\n const record = (dialog: string, text: string, result: string | boolean | null): void => {\n try {\n const root = document.documentElement;\n const log = JSON.parse(root.dataset.devthinkdialoglog ?? \"[]\") as unknown[];\n log.push({ dialog, text, result, at: Date.now() });\n root.dataset.devthinkdialoglog = JSON.stringify(log);\n } catch { /* a locked down page refuses dataset writes; the handler still answers */ }\n };\n window.confirm = (text?: string): boolean => {\n const decision = decide(\"confirm\");\n record(\"confirm\", text ?? \"\", decision.accept);\n if (!persistent) window.confirm = originals.confirm;\n return decision.accept;\n };\n window.alert = (text?: string): void => {\n record(\"alert\", text ?? \"\", true);\n if (!persistent) window.alert = originals.alert;\n };\n window.prompt = (text?: string, defaultvalue?: string): string | null => {\n const decision = decide(\"prompt\");\n const outcome = decision.accept ? (decision.answer ?? defaultvalue ?? \"\") : null;\n record(\"prompt\", text ?? \"\", outcome);\n if (!persistent) window.prompt = originals.prompt;\n return outcome;\n };\n}\n", "import type { a11ynode, readerarticle, toolstep } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\nimport type { stepresult } from \"./pageactions.js\";\nimport { clean, describescopes, elementlabel, elementselector, implicitrole, owntext, type candidatefields, type scopetree } from \"./pageresolve.js\";\n\n/**\n * Semantic page observation for reviewed steps.\n * Every correlated rule for the shadow and frame piercing walker, the accessibility tree, visible text, the reader heuristic, the heading outline, the selection read, open graph extraction, language detection and the shadow and frame inventories lives in this file.\n */\n\n/** Serializable page node used by the observation engine; the live glue attaches the element. */\nexport interface pagenode {\n tag: string;\n selector: string;\n id: string;\n classes: string[];\n role: string;\n name: string;\n text: string;\n value: string;\n states: string[];\n hidden: boolean;\n children: pagenode[];\n element?: Element;\n}\n\n/** Deepest same origin frame nesting the walker pierces; deeper frames stay opaque so recursive self embedding cannot loop. */\nconst maxframedepth = 4;\n\nfunction elementstates(element: Element): string[] {\n const states: string[] = [];\n if (element.hasAttribute(\"disabled\") || element.getAttribute(\"aria-disabled\") === \"true\") states.push(\"disabled\");\n if (element instanceof HTMLInputElement && (element.type === \"checkbox\" || element.type === \"radio\") && element.checked) states.push(\"checked\");\n const expanded = element.getAttribute(\"aria-expanded\");\n if (expanded !== null) states.push(`expanded ${expanded}`);\n if (element.getAttribute(\"aria-selected\") === \"true\") states.push(\"selected\");\n if (element.hasAttribute(\"required\") || element.getAttribute(\"aria-required\") === \"true\") states.push(\"required\");\n if (element.hasAttribute(\"readonly\") || element.getAttribute(\"aria-readonly\") === \"true\") states.push(\"readonly\");\n if (element.getAttribute(\"aria-hidden\") === \"true\") states.push(\"hidden\");\n return states;\n}\n\nfunction elementvalue(element: Element): string {\n if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement) return element.value;\n return \"\";\n}\n\nfunction elementhidden(element: Element): boolean {\n if (element instanceof HTMLInputElement && element.type === \"hidden\") return true;\n if (element.hasAttribute(\"hidden\") || element.getAttribute(\"aria-hidden\") === \"true\") return true;\n try {\n const style = element.ownerDocument?.defaultView?.getComputedStyle(element);\n if (style && (style.display === \"none\" || style.visibility === \"hidden\")) return true;\n } catch { /* detached documents refuse computed styles; the node stays visible */ }\n return false;\n}\n\nfunction framenode(frame: HTMLIFrameElement, depth: number): pagenode {\n let content: Document | null = null;\n try { content = frame.contentDocument; } catch { content = null; }\n let sameorigin = false;\n try { sameorigin = content !== null && frame.contentWindow?.location.origin === location.origin; } catch { sameorigin = false; }\n const node = wrap(frame, depth);\n if (sameorigin && content && depth < maxframedepth) node.children.push(...wrapchildren(content, depth + 1));\n return node;\n}\n\nfunction wrap(element: Element, depth: number): pagenode {\n const shadow = element.shadowRoot;\n const node: pagenode = {\n tag: element.tagName.toLowerCase(),\n selector: elementselector(element),\n id: element.id,\n classes: [...element.classList],\n role: element.getAttribute(\"role\")?.toLowerCase() || implicitrole(element),\n name: elementlabel(element),\n text: owntext(element),\n value: elementvalue(element),\n states: elementstates(element),\n hidden: elementhidden(element),\n children: [],\n element,\n };\n if (shadow) node.children.push(...wrapchildren(shadow, depth));\n if (element instanceof HTMLIFrameElement) return framenode(element, depth);\n node.children.push(...wrapchildren(element, depth));\n return node;\n}\n\nfunction wrapchildren(scope: ParentNode, depth: number): pagenode[] {\n return [...scope.querySelectorAll(\":scope > *\")].map(child => wrap(child, depth));\n}\n\n/** Builds the serializable page node tree, piercing open shadow roots and same origin iframes. */\nexport function buildpagetree(scope: ParentNode): pagenode {\n const root: pagenode = {\n tag: \"#document\",\n selector: \"\",\n id: \"\",\n classes: [],\n role: \"document\",\n name: \"\",\n text: \"\",\n value: \"\",\n states: [],\n hidden: false,\n children: [],\n };\n if (scope instanceof Document) {\n root.children = scope.documentElement ? [wrap(scope.documentElement, 0)] : [];\n } else {\n root.children = [...wrapchildren(scope, 0)];\n }\n return root;\n}\n\nfunction countnodes(node: a11ynode): number {\n return 1 + node.children.reduce((total, child) => total + countnodes(child), 0);\n}\n\n/** Converts one page node tree into the accessibility tree with roles, names, states and child refs; hidden subtrees stay excluded. */\nexport function builda11ytree(node: pagenode): a11ynode {\n const children = node.children.filter(child => !child.hidden).map(builda11ytree);\n return {\n role: node.role || \"generic\",\n name: node.name,\n states: node.states,\n ...(node.value ? { value: node.value } : {}),\n childcount: children.length,\n children,\n };\n}\n\n/** Returns the rendered text of each visible element; hidden nodes and their subtrees stay excluded. */\nexport function visibleentries(node: pagenode): Array<{ selector: string; text: string }> {\n if (node.hidden) return [];\n const entries: Array<{ selector: string; text: string }> = node.text ? [{ selector: node.selector || node.tag, text: node.text }] : [];\n for (const child of node.children) entries.push(...visibleentries(child));\n return entries;\n}\n\n/** Joins the rendered text of every visible node into one stream. */\nexport function visibletext(node: pagenode): string {\n return visibleentries(node).map(entry => entry.text).join(\" \");\n}\n\nfunction nodetextlength(node: pagenode): number {\n return node.text.length + node.children.reduce((total, child) => total + nodetextlength(child), 0);\n}\n\nfunction nodelinktext(node: pagenode): number {\n const own = node.tag === \"a\" ? node.text.length : 0;\n return own + node.children.reduce((total, child) => total + nodelinktext(child), 0);\n}\n\nfunction wordsin(text: string): number {\n return text.split(/\\s+/).filter(Boolean).length;\n}\n\nfunction findbyline(node: pagenode): string {\n const markers = [\"byline\", \"author\"];\n const direct = node.classes.some(item => markers.some(marker => item.toLowerCase().includes(marker))) || markers.some(marker => node.id.toLowerCase().includes(marker));\n if (direct && node.text) return node.text;\n for (const child of node.children) {\n const found = findbyline(child);\n if (found) return found;\n }\n return \"\";\n}\n\nfunction findheading(node: pagenode, tags: string[]): string {\n if (tags.includes(node.tag) && node.text) return node.text;\n for (const child of node.children) {\n const found = findheading(child, tags);\n if (found) return found;\n }\n return \"\";\n}\n\n/** Scores page nodes by text density and splits the densest article region into reader blocks, separating them from page chrome. */\nexport function buildreader(root: pagenode, title: string): readerarticle {\n let best: pagenode | undefined;\n let bestscore = 0;\n const walk = (node: pagenode): void => {\n if (node.tag !== \"#document\") {\n const length = nodetextlength(node);\n const links = nodelinktext(node);\n const score = length * (1 - (length > 0 ? links / length : 0));\n if (score > bestscore) { bestscore = score; best = node; }\n }\n for (const child of node.children) walk(child);\n };\n walk(root);\n const article = best ?? root;\n const blocks = article.children.filter(child => !child.hidden && child.text).map(child => ({ kind: child.tag, text: child.text, words: wordsin(child.text) }));\n const ownblock = article.text ? [{ kind: article.tag, text: article.text, words: wordsin(article.text) }] : [];\n const allblocks = [...ownblock, ...blocks];\n return {\n title: findheading(article, [\"h1\"]) || findheading(root, [\"h1\"]) || title,\n byline: findbyline(article) || findbyline(root),\n blocks: allblocks,\n words: allblocks.reduce((total, block) => total + block.words, 0),\n characters: allblocks.reduce((total, block) => total + block.text.length, 0),\n };\n}\n\n/** Returns the title and headings outline of the page. */\nexport function pageoutline(root: pagenode, title: string): { title: string; headings: Array<{ level: number; text: string }> } {\n const headings: Array<{ level: number; text: string }> = [];\n const walk = (node: pagenode): void => {\n const level = /^h([1-6])$/.exec(node.tag);\n if (level && node.text) headings.push({ level: Number.parseInt(level[1] as string, 10), text: node.text });\n for (const child of node.children) walk(child);\n };\n walk(root);\n return { title: findheading(root, [\"h1\"]) || title, headings };\n}\n\n/** Reads the text of the current user selection through the document selection api. */\nexport function captureselection(root: { getSelection?: () => { toString(): string } | null }): { text: string; length: number } {\n const selection = root.getSelection?.() ?? null;\n const text = selection ? clean(selection.toString()) : \"\";\n return { text, length: text.length };\n}\n\n/** Extracts open graph meta properties and structured data payloads; malformed structured payloads are refused and counted. */\nexport function opengraphfields(meta: Array<{ property: string; name: string; content: string }>, jsonld: string[]): { graph: Record<string, string>; structured: unknown[]; refused: number } {\n const graph: Record<string, string> = {};\n for (const entry of meta) {\n if (entry.property.startsWith(\"og:\") && entry.content) graph[entry.property] = entry.content;\n }\n const structured: unknown[] = [];\n let refused = 0;\n for (const raw of jsonld) {\n try { structured.push(JSON.parse(raw)); } catch { refused += 1; }\n }\n return { graph, structured, refused };\n}\n\nconst stopwords: Record<string, string[]> = {\n en: [\"the\", \"is\", \"at\", \"which\", \"on\", \"and\", \"of\", \"to\", \"in\", \"that\", \"it\", \"with\"],\n pt: [\"de\", \"que\", \"n\u00E3o\", \"uma\", \"para\", \"com\", \"por\", \"mais\", \"como\", \"p\u00E1gina\", \"este\", \"voc\u00EA\"],\n es: [\"que\", \"el\", \"las\", \"los\", \"por\", \"una\", \"para\", \"con\", \"como\", \"p\u00E1gina\", \"m\u00E1s\", \"este\"],\n fr: [\"le\", \"les\", \"des\", \"que\", \"pour\", \"dans\", \"est\", \"sur\", \"avec\", \"page\", \"plus\", \"cette\"],\n de: [\"der\", \"die\", \"und\", \"das\", \"ist\", \"von\", \"mit\", \"f\u00FCr\", \"auf\", \"den\", \"nicht\", \"seite\"],\n it: [\"che\", \"il\", \"la\", \"per\", \"una\", \"del\", \"sono\", \"non\", \"con\", \"pagina\", \"pi\u00F9\", \"questo\"],\n nl: [\"het\", \"een\", \"en\", \"van\", \"is\", \"dat\", \"op\", \"te\", \"voor\", \"met\", \"niet\", \"pagina\"],\n};\n\n/** Detects the language of extracted text from stopword frequency; an undetermined text returns an empty code. */\nexport function detecttextlanguage(text: string): string {\n const words = text.toLowerCase().split(/[^a-z\u00E0-\u00FF]+/).filter(Boolean);\n if (words.length === 0) return \"\";\n let best = \"\";\n let bestscore = 0;\n for (const [language, dictionary] of Object.entries(stopwords)) {\n const score = words.filter(word => dictionary.includes(word)).length;\n if (score > bestscore) { bestscore = score; best = language; }\n }\n return best;\n}\n\n/** Tags extracted text with its detected language code, routing it to the matching language stream. */\nexport function taglanguage(text: string): { text: string; language: string } {\n return { text, language: detecttextlanguage(text) };\n}\n\n/** Resolves the page language from the document lang attribute, the content language meta and the content signals, in that order. */\nexport function documentlanguage(signals: { lang: string; meta: string; text: string }): { language: string; source: string } {\n if (signals.lang.trim()) return { language: signals.lang.trim(), source: \"document\" };\n if (signals.meta.trim()) return { language: signals.meta.trim(), source: \"meta\" };\n return { language: detecttextlanguage(signals.text), source: \"content\" };\n}\n\n/** Lists the host paths of every open shadow root nested inside one scope tree. */\nexport function shadowpaths(scope: scopetree<candidatefields>): string[] {\n const paths: string[] = [];\n const walk = (tree: scopetree<candidatefields>, prefix: string): void => {\n for (const shadow of tree.shadows) {\n if (!shadow.host) continue;\n const path = prefix ? `${prefix} > ${shadow.host.selector}` : shadow.host.selector;\n paths.push(path);\n walk(shadow, path);\n }\n };\n walk(scope, \"\");\n return paths;\n}\n\n/** Enumerates the iframes of one document with their origins and sizes; cross origin frames report no origin. */\nexport function framelist(root: Document): Array<{ index: number; origin: string; sameorigin: boolean; width: number; height: number }> {\n return [...root.querySelectorAll(\"iframe\")].map((frame, index) => {\n let origin = \"\";\n try { origin = frame.contentWindow?.location.origin ?? \"\"; } catch { origin = \"\"; }\n const rect = frame.getBoundingClientRect();\n return { index, origin, sameorigin: origin !== \"\" && origin === location.origin, width: Math.round(rect.width), height: Math.round(rect.height) };\n });\n}\n\nfunction stepoptions(step: toolstep): Record<string, unknown> {\n try { return parseoptions(step); } catch { return {} as Record<string, unknown>; }\n}\n\n/** Runs one passive page observation after the background policy gate; frame routed steps receive their frame document as the root. */\nexport function runpageobservation(step: toolstep, target: Element | null, root: Document = document): stepresult | Promise<stepresult> {\n switch (step.kind) {\n case \"a11ytree\": {\n const tree = builda11ytree(buildpagetree(root));\n const count = countnodes(tree);\n return { ok: true, summary: `Captured the accessibility tree with ${count} node${count === 1 ? \"\" : \"s\"}.`, details: { tree, nodecount: count } };\n }\n case \"readvisible\": {\n const scope: ParentNode = target ?? root;\n const tree = buildpagetree(scope);\n const entries = visibleentries(tree);\n return { ok: true, summary: `Read the rendered text of ${entries.length} visible element${entries.length === 1 ? \"\" : \"s\"}.`, details: { entries, text: visibletext(tree) } };\n }\n case \"readertree\": {\n const article = buildreader(buildpagetree(root), root.title);\n return { ok: true, summary: `Extracted the reader view with ${article.blocks.length} block${article.blocks.length === 1 ? \"\" : \"s\"} and ${article.words} words.`, details: { article } };\n }\n case \"readoutline\": {\n const outline = pageoutline(buildpagetree(root), root.title);\n return { ok: true, summary: `Read the outline with ${outline.headings.length} heading${outline.headings.length === 1 ? \"\" : \"s\"}.`, details: { title: outline.title, headings: outline.headings } };\n }\n case \"readselection\": {\n const selection = captureselection(root);\n return { ok: true, summary: selection.text ? `Read ${selection.length} characters of the current selection.` : \"No text is currently selected.\", details: { text: selection.text, length: selection.length } };\n }\n case \"readopengraph\": {\n const meta = [...root.querySelectorAll(\"meta\")].map(element => ({ property: element.getAttribute(\"property\") ?? \"\", name: element.getAttribute(\"name\") ?? \"\", content: element.getAttribute(\"content\") ?? \"\" }));\n const jsonld = [...root.querySelectorAll('script[type=\"application/ld+json\"]')].map(element => element.textContent ?? \"\");\n const fields = opengraphfields(meta, jsonld);\n return { ok: true, summary: `Read ${Object.keys(fields.graph).length} open graph entr${Object.keys(fields.graph).length === 1 ? \"y\" : \"ies\"} and ${fields.structured.length} structured payload${fields.structured.length === 1 ? \"\" : \"s\"}${fields.refused > 0 ? `; ${fields.refused} malformed payload${fields.refused === 1 ? \" was\" : \"s were\"} refused` : \"\"}.`, details: { graph: fields.graph, structured: fields.structured, refused: fields.refused } };\n }\n case \"readlang\": {\n const metatag = root.querySelector('meta[http-equiv=\"content-language\"]')?.getAttribute(\"content\") ?? \"\";\n const outcome = documentlanguage({ lang: root.documentElement?.getAttribute(\"lang\") ?? \"\", meta: metatag, text: root.body?.innerText ?? \"\" });\n return { ok: true, summary: `Detected page language ${outcome.language || \"unknown\"} from the ${outcome.source} signal.`, details: { language: outcome.language, source: outcome.source } };\n }\n case \"detectlanguage\": {\n const options = stepoptions(step);\n const text = typeof options.text === \"string\" && options.text ? options.text : target?.textContent ?? root.body?.innerText ?? \"\";\n const routed = taglanguage(clean(text));\n return { ok: routed.language !== \"\", summary: routed.language ? `Detected language ${routed.language} for the extracted text.` : \"The extracted text language is undetermined.\", details: { language: routed.language, routed } };\n }\n case \"listshadow\": {\n const paths = shadowpaths(describescopes(root));\n return { ok: true, summary: `Listed ${paths.length} open shadow root${paths.length === 1 ? \"\" : \"s\"}.`, details: { shadows: paths } };\n }\n case \"listframes\": {\n const frames = framelist(root);\n return { ok: true, summary: `Listed ${frames.length} iframe${frames.length === 1 ? \"\" : \"s\"}.`, details: { frames } };\n }\n default: return { ok: false, summary: \"Unsupported page observation.\" };\n }\n}\n", "import type { bannerreport, listpattern, tableshape, toolstep } from \"../types.js\";\nimport type { stepresult } from \"./pageactions.js\";\nimport { clean, elementselector } from \"./pageresolve.js\";\n\n/**\n * Page shape detection for reviewed steps.\n * Every correlated rule for repeated list detection, table shape normalization, pagination estimates, infinite scroll ranges, virtualization, lazy images, sticky overlays, scroll locks, consent banner shapes, template classification, section fingerprints and scroll positions lives in this file.\n */\n\n/** Serializable sibling sample of one container element used by the list detector. */\nexport interface siblingsample {\n container: string;\n children: Array<{ tag: string; classes: string; text: string; selector: string }>;\n}\n\n/** Finds repeated item lists with a shared item selector from sibling samples. */\nexport function detectlistpatterns(samples: siblingsample[]): listpattern[] {\n const patterns: listpattern[] = [];\n for (const sample of samples) {\n const groups = new Map<string, Array<{ tag: string; classes: string; text: string }>>();\n for (const child of sample.children) {\n const key = `${child.tag}|${child.classes}`;\n const group = groups.get(key) ?? [];\n group.push(child);\n groups.set(key, group);\n }\n for (const [key, group] of groups) {\n if (group.length < 2) continue;\n if (!group.some(item => item.text)) continue;\n const [tag, classes] = key.split(\"|\") as [string, string?];\n const classpart = (classes ?? \"\").split(\" \").filter(Boolean).map(name => `.${name}`).join(\"\");\n patterns.push({ container: sample.container, itemselector: `${tag}${classpart}`, repeat: group.length, samples: group.map(item => item.text).filter(Boolean) });\n }\n }\n return patterns;\n}\n\n/** Normalizes one table row structure into header row, column specs and caption. */\nexport function normalizetable(rows: Array<{ cells: string[]; header: boolean }>, caption: string): { headers: string[]; columns: Array<{ label: string; cells: number }>; rows: number; caption: string } {\n const firstheader = rows.find(row => row.header);\n const headers = firstheader?.cells ?? [];\n const body = firstheader ? rows.filter(row => row !== firstheader) : rows;\n const width = rows.reduce((largest, row) => Math.max(largest, row.cells.length), 0);\n const columns: Array<{ label: string; cells: number }> = [];\n for (let index = 0; index < width; index += 1) {\n const label = headers[index] ?? `column ${index + 1}`;\n const cells = body.filter(row => Boolean((row.cells[index] ?? \"\").trim())).length;\n columns.push({ label, cells });\n }\n return { headers, columns, rows: body.length, caption };\n}\n\n/** Counts pagination entries and estimates the total page count from the numbers they carry. */\nexport function paginationestimate(entries: Array<{ text: string; selector: string; current: boolean }>): { current: number; total: number; links: number; pages: number[] } {\n const pages: number[] = [];\n let current = 0;\n for (const entry of entries) {\n const parsed = /^\\d+$/.exec(entry.text.trim());\n if (parsed) {\n const page = Number.parseInt(parsed[0] as string, 10);\n pages.push(page);\n if (entry.current) current = page;\n }\n }\n const total = Math.max(0, ...pages, current);\n return { current, total, links: entries.length, pages };\n}\n\n/** Serializable scroll range input of one scrollable container. */\nexport interface scrollrangeshape {\n selector: string;\n scrollheight: number;\n clientheight: number;\n triggers: string[];\n}\n\n/** Flags infinite scroll containers from measured scroll ranges and their load more triggers. */\nexport function infinitescrollranges(ranges: scrollrangeshape[]): Array<{ selector: string; scrollrange: number; triggers: string[] }> {\n return ranges\n .filter(range => range.scrollheight > range.clientheight && range.triggers.length > 0)\n .map(range => ({ selector: range.selector, scrollrange: range.scrollheight - range.clientheight, triggers: range.triggers }));\n}\n\n/** Detects virtualized lists whose uniform rendered rows do not fill the measured scroll range. */\nexport function virtualizedcontainers(containers: Array<{ selector: string; scrollheight: number; rows: Array<{ selector: string; height: number; classes: string }> }>): Array<{ selector: string; rendered: number; estimated: number }> {\n const results: Array<{ selector: string; rendered: number; estimated: number }> = [];\n for (const container of containers) {\n const first = container.rows[0];\n if (!first || container.rows.length < 2 || first.height <= 0) continue;\n if (!container.rows.every(row => row.height === first.height)) continue;\n if (container.scrollheight <= container.rows.length * first.height) continue;\n results.push({ selector: container.selector, rendered: container.rows.length, estimated: Math.floor(container.scrollheight / first.height) });\n }\n return results;\n}\n\n/** Serializable image shape used by the lazy detector. */\nexport interface imageshape {\n selector: string;\n src: string;\n datasrc: string;\n loading: string;\n width: number;\n height: number;\n}\n\n/** Detects lazy loaded images from loading attributes and deferred sources, and placeholder states from inline data or empty sources. */\nexport function lazysurvey(images: imageshape[]): { lazy: Array<{ selector: string; reason: string }>; placeholders: Array<{ selector: string; reason: string }> } {\n const lazy: Array<{ selector: string; reason: string }> = [];\n const placeholders: Array<{ selector: string; reason: string }> = [];\n for (const image of images) {\n if (image.loading === \"lazy\") lazy.push({ selector: image.selector, reason: \"loading attribute\" });\n else if (image.datasrc) lazy.push({ selector: image.selector, reason: \"deferred source\" });\n if (!image.src) placeholders.push({ selector: image.selector, reason: \"empty source\" });\n else if (image.src.startsWith(\"data:\")) placeholders.push({ selector: image.selector, reason: \"inline data placeholder\" });\n }\n return { lazy, placeholders };\n}\n\n/** Detects sticky headers and overlays from fixed and sticky geometry measured against the viewport. */\nexport function overlaygeometry(elements: Array<{ selector: string; position: string; top: number; height: number; width: number }>, viewport: { width: number; height: number }): Array<{ selector: string; position: string; coverage: number; hides: boolean }> {\n const area = viewport.width * viewport.height;\n return elements\n .filter(element => (element.position === \"sticky\" || element.position === \"fixed\") && element.top <= 0 && element.height > 0)\n .map(element => {\n const coverage = area > 0 ? (element.height * element.width) / area : 0;\n return { selector: element.selector, position: element.position, coverage: Math.round(coverage * 1000) / 1000, hides: coverage >= overlaythreshold };\n });\n}\n\n/** Detects scroll locks and modal states from body overflow, body position and modal presence signals. */\nexport function scrolllockstate(signals: { bodyoverflow: string; htmloverflow: string; bodyposition: string; modal: boolean; scrollable: boolean }): { locked: boolean; reasons: string[]; scrollable: boolean } {\n const reasons: string[] = [];\n if (signals.bodyoverflow.includes(\"hidden\") || signals.htmloverflow.includes(\"hidden\")) reasons.push(\"overflow hidden\");\n if (signals.bodyposition === \"fixed\") reasons.push(\"fixed body\");\n if (signals.modal) reasons.push(\"modal open\");\n return { locked: reasons.length > 0, reasons, scrollable: signals.scrollable };\n}\n\n/** Serializable consent banner candidate collected by the banner watcher glue. */\nexport interface bannercandidate {\n selector: string;\n id: string;\n classes: string[];\n text: string;\n controls: string[];\n}\n\n/** Consent banner keywords the shape matcher recognizes across locales. */\nexport const consentkeywords = [\"cookie\", \"consent\", \"gdpr\", \"lgpd\", \"privacy\", \"ccpa\"];\n\n/** Matches consent banner shapes against the known keyword vocabulary and reports their controls. */\nexport function bannermatches(candidates: bannercandidate[], at: number): bannerreport[] {\n const reports: bannerreport[] = [];\n for (const candidate of candidates) {\n const haystack = `${candidate.id} ${candidate.classes.join(\" \")} ${candidate.text}`.toLowerCase();\n const keyword = consentkeywords.find(word => haystack.includes(word));\n if (!keyword) continue;\n if (!candidate.text && candidate.controls.length === 0) continue;\n reports.push({ kind: keyword, selector: candidate.selector, text: candidate.text.slice(0, 200), controls: candidate.controls, at });\n }\n return reports;\n}\n\n/** Classifies the page template from its dominant structural signals. */\nexport function classifytemplate(signals: { paragraphs: number; headings: number; lists: number; tables: number; forms: number; inputs: number; password: boolean }): string {\n if (signals.password) return \"login\";\n if (signals.paragraphs >= 3) return \"article\";\n if (signals.tables > 0) return \"table\";\n if (signals.forms > 0 && signals.inputs > 0) return \"form\";\n if (signals.lists > 0) return \"list\";\n return \"generic\";\n}\n\n/** Computes a stable structural fingerprint of one page section from its tag, attributes, child count and text length. */\nexport function sectionfingerprint(section: { tag: string; attributes: Record<string, string>; children: number; textlength: number }): string {\n const canonical = [section.tag, String(section.children), String(section.textlength), ...Object.keys(section.attributes).sort().map(key => `${key}=${section.attributes[key] ?? \"\"}`)].join(\"|\");\n let hash = 5381;\n for (let index = 0; index < canonical.length; index += 1) hash = ((hash << 5) + hash + canonical.charCodeAt(index)) >>> 0;\n return `fp${hash.toString(16)}`;\n}\n\n/** Normalizes the scroll position of the window and its scrollable containers with edge flags. */\nexport function scrollreport(window: { scrollx: number; scrolly: number; scrollheight: number; clientheight: number }, containers: Array<{ selector: string; scrolltop: number; scrollleft: number; scrollheight: number; clientheight: number }>): { window: { x: number; y: number; attop: boolean; atbottom: boolean; height: number }; containers: Array<{ selector: string; scrolltop: number; scrollleft: number; scrollrange: number; atbottom: boolean }> } {\n const range = Math.max(0, window.scrollheight - window.clientheight);\n return {\n window: { x: window.scrollx, y: window.scrolly, attop: window.scrolly <= 0, atbottom: window.scrolly >= range, height: window.scrollheight },\n containers: containers.map(container => {\n const containerrange = Math.max(0, container.scrollheight - container.clientheight);\n return { selector: container.selector, scrolltop: container.scrolltop, scrollleft: container.scrollleft, scrollrange: containerrange, atbottom: container.scrolltop >= containerrange };\n }),\n };\n}\n\nconst loadmorepattern = /(load more|show more|see more|ver mais|carregar mais|load older|afficher plus|mehr anzeigen)/i;\nconst paginationtext = /^(next|prev|previous|last|first|next page|previous page|\u00BB|\u00AB|\u203A|\u2039|\\d+)$/i;\n/** Viewport coverage fraction at which a sticky or fixed overlay is reported as hiding content. */\nconst overlaythreshold = 0.25;\n\nfunction signatureof(element: Element): string {\n return `${element.tagName.toLowerCase()}|${[...element.classList].sort().join(\" \")}`;\n}\n\n/** Collects the sibling samples of one document for the list detector. */\nexport function collectsiblings(root: Document): siblingsample[] {\n const samples: siblingsample[] = [];\n for (const element of [...root.querySelectorAll(\"*\")]) {\n const children = [...element.children];\n if (children.length < 2) continue;\n const counts = new Map<string, number>();\n for (const child of children) {\n const key = signatureof(child);\n counts.set(key, (counts.get(key) ?? 0) + 1);\n }\n if (![...counts.values()].some(count => count >= 2)) continue;\n samples.push({\n container: elementselector(element),\n children: children.map(child => ({ tag: child.tagName.toLowerCase(), classes: [...child.classList].sort().join(\" \"), text: clean(child.textContent ?? \"\"), selector: elementselector(child) })),\n });\n }\n return samples;\n}\n\n/** Collects the data table structures of one document for the table shape normalizer. */\nexport function collecttables(root: Document): Array<{ selector: string; rows: Array<{ cells: string[]; header: boolean }>; caption: string }> {\n return [...root.querySelectorAll(\"table\")].map(table => ({\n selector: elementselector(table),\n rows: [...table.querySelectorAll(\"tr\")].map(row => ({ cells: [...row.querySelectorAll(\"th, td\")].map(cell => clean(cell.textContent ?? \"\")), header: Boolean(row.querySelector(\"th\")) })),\n caption: clean(table.querySelector(\"caption\")?.textContent ?? \"\"),\n }));\n}\n\nfunction collectpagination(root: Document): Array<{ text: string; selector: string; current: boolean }> {\n const entries: Array<{ text: string; selector: string; current: boolean }> = [];\n for (const element of [...root.querySelectorAll(\"a[href], button, [role=button], [role=link], li, span\")]) {\n const text = clean(element.textContent ?? \"\");\n if (!text || !paginationtext.test(text)) continue;\n if (!element.closest(\"nav, footer, [class*=pag i], [id*=pag i]\")) continue;\n const current = element.getAttribute(\"aria-current\") === \"page\" || [...element.classList].some(name => /current|active|selecionado/i.test(name));\n entries.push({ text, selector: elementselector(element), current });\n }\n return entries;\n}\n\nfunction collecttriggers(scope: ParentNode): string[] {\n const triggers: string[] = [];\n for (const element of [...scope.querySelectorAll(\"button, a[href], [role=button], [class*=loading i], [class*=sentinel i], [class*=spinner i]\")]) {\n const label = clean(element.getAttribute(\"aria-label\") ?? element.textContent ?? \"\");\n if (loadmorepattern.test(label)) triggers.push(elementselector(element));\n }\n return triggers;\n}\n\nfunction collectscrollranges(root: Document): scrollrangeshape[] {\n const ranges: scrollrangeshape[] = [];\n const scrolling = root.scrollingElement ?? root.documentElement;\n const viewheight = root.defaultView?.innerHeight ?? 0;\n if (scrolling && scrolling.scrollHeight > viewheight) ranges.push({ selector: \"window\", scrollheight: scrolling.scrollHeight, clientheight: viewheight, triggers: collecttriggers(root) });\n for (const element of [...root.querySelectorAll(\"*\")]) {\n if (!(element instanceof HTMLElement)) continue;\n if (element.scrollHeight <= element.clientHeight) continue;\n ranges.push({ selector: elementselector(element), scrollheight: element.scrollHeight, clientheight: element.clientHeight, triggers: collecttriggers(element) });\n }\n return ranges;\n}\n\nfunction collectvirtual(root: Document): Array<{ selector: string; scrollheight: number; rows: Array<{ selector: string; height: number; classes: string }> }> {\n const containers: Array<{ selector: string; scrollheight: number; rows: Array<{ selector: string; height: number; classes: string }> }> = [];\n for (const element of [...root.querySelectorAll(\"*\")]) {\n const children = [...element.children];\n const first = children[0];\n if (!first || children.length < 2) continue;\n if (!children.every(child => signatureof(child) === signatureof(first))) continue;\n const heights = children.map(child => child.getBoundingClientRect().height);\n if (!heights.every(height => height > 0 && height === heights[0])) continue;\n containers.push({ selector: elementselector(element), scrollheight: element.scrollHeight, rows: children.map(child => ({ selector: elementselector(child), height: child.getBoundingClientRect().height, classes: [...child.classList].join(\" \") })) });\n }\n return containers;\n}\n\nfunction collectimages(root: Document): imageshape[] {\n return [...root.querySelectorAll(\"img\")].map(image => ({\n selector: elementselector(image),\n src: image.getAttribute(\"src\") ?? \"\",\n datasrc: image.getAttribute(\"data-src\") ?? image.getAttribute(\"data-original\") ?? \"\",\n loading: image.getAttribute(\"loading\") ?? \"\",\n width: image.naturalWidth,\n height: image.naturalHeight,\n }));\n}\n\nfunction collectoverlays(root: Document): Array<{ selector: string; position: string; top: number; height: number; width: number }> {\n const elements: Array<{ selector: string; position: string; top: number; height: number; width: number }> = [];\n for (const element of [...root.querySelectorAll(\"*\")]) {\n if (!(element instanceof HTMLElement)) continue;\n const view = element.ownerDocument.defaultView;\n const position = view ? view.getComputedStyle(element).position : \"\";\n if (position !== \"sticky\" && position !== \"fixed\") continue;\n const rect = element.getBoundingClientRect();\n elements.push({ selector: elementselector(element), position, top: rect.top, height: rect.height, width: rect.width });\n }\n return elements;\n}\n\nfunction collectlocksignals(root: Document): { bodyoverflow: string; htmloverflow: string; bodyposition: string; modal: boolean; scrollable: boolean } {\n const view = root.defaultView;\n const bodystyle = root.body ? (view ? view.getComputedStyle(root.body) : undefined) : undefined;\n const htmlstyle = view ? view.getComputedStyle(root.documentElement) : undefined;\n return {\n bodyoverflow: bodystyle?.overflow ?? \"\",\n htmloverflow: htmlstyle?.overflow ?? \"\",\n bodyposition: bodystyle?.position ?? \"\",\n modal: Boolean(root.querySelector(\"dialog[open], [aria-modal=true]\")),\n scrollable: root.documentElement.scrollHeight > root.documentElement.clientHeight,\n };\n}\n\nconst bannerselector = '[id*=\"cookie\" i], [class*=\"cookie\" i], [id*=\"consent\" i], [class*=\"consent\" i], [id*=\"gdpr\" i], [class*=\"gdpr\" i], [id*=\"privacy\" i], [class*=\"privacy\" i], [id*=\"banner\" i], [class*=\"banner\" i], dialog, [role=\"dialog\"], [aria-modal=\"true\"]';\n\n/** Collects the consent banner candidates of one document for the banner shape matcher. */\nexport function collectbannercandidates(root: Document): bannercandidate[] {\n const found = [...root.querySelectorAll(bannerselector)];\n return found\n .filter(element => !found.some(other => other !== element && other.contains(element)))\n .map(element => ({\n selector: elementselector(element),\n id: element.id,\n classes: [...element.classList],\n text: clean(element.textContent ?? \"\").slice(0, 200),\n controls: [...element.querySelectorAll(\"button, a[href], [role=button]\")].map(control => clean(control.getAttribute(\"aria-label\") ?? control.textContent ?? \"\")).filter(Boolean),\n }));\n}\n\n/** Runs one page shape detection after the background policy gate; frame routed steps receive their frame document as the root. */\nexport function runpagedetection(step: toolstep, target: Element | null, root: Document = document): stepresult | Promise<stepresult> {\n switch (step.kind) {\n case \"detectlists\": {\n const patterns = detectlistpatterns(collectsiblings(root));\n return { ok: true, summary: `Detected ${patterns.length} repeated list${patterns.length === 1 ? \"\" : \"s\"}.`, details: { lists: patterns } };\n }\n case \"detecttables\": {\n const tables: tableshape[] = collecttables(root).map(entry => {\n const shape = normalizetable(entry.rows, entry.caption);\n return { selector: entry.selector, headers: shape.headers, columns: shape.columns, rows: shape.rows, caption: shape.caption };\n });\n return { ok: true, summary: `Detected ${tables.length} data table${tables.length === 1 ? \"\" : \"s\"}.`, details: { tables } };\n }\n case \"countpages\": {\n const estimate = paginationestimate(collectpagination(root));\n return { ok: true, summary: `Counted ${estimate.links} pagination entr${estimate.links === 1 ? \"y\" : \"ies\"} and estimated ${estimate.total} total page${estimate.total === 1 ? \"\" : \"s\"}.`, details: { current: estimate.current, total: estimate.total, links: estimate.links, pages: estimate.pages } };\n }\n case \"detectinfinitescroll\": {\n const containers = infinitescrollranges(collectscrollranges(root));\n return { ok: true, summary: `Detected ${containers.length} infinite scroll container${containers.length === 1 ? \"\" : \"s\"}.`, details: { containers } };\n }\n case \"detectvirtual\": {\n const containers = virtualizedcontainers(collectvirtual(root));\n return { ok: true, summary: `Detected ${containers.length} virtualized list${containers.length === 1 ? \"\" : \"s\"}.`, details: { containers } };\n }\n case \"detectlazy\": {\n const survey = lazysurvey(collectimages(root));\n return { ok: true, summary: `Detected ${survey.lazy.length} lazy image${survey.lazy.length === 1 ? \"\" : \"s\"} and ${survey.placeholders.length} placeholder${survey.placeholders.length === 1 ? \"\" : \"s\"}.`, details: { lazy: survey.lazy, placeholders: survey.placeholders } };\n }\n case \"detectsticky\": {\n const overlays = overlaygeometry(collectoverlays(root), { width: root.defaultView?.innerWidth ?? 0, height: root.defaultView?.innerHeight ?? 0 });\n return { ok: true, summary: `Detected ${overlays.length} sticky or fixed overlay${overlays.length === 1 ? \"\" : \"s\"}.`, details: { overlays } };\n }\n case \"detectscrolllock\": {\n const lock = scrolllockstate(collectlocksignals(root));\n return { ok: true, summary: lock.locked ? `Scroll is locked: ${lock.reasons.join(\", \")}.` : \"Scroll is not locked.\", details: { locked: lock.locked, reasons: lock.reasons, scrollable: lock.scrollable } };\n }\n case \"classifypage\": {\n const signals = {\n paragraphs: root.querySelectorAll(\"p\").length,\n headings: root.querySelectorAll(\"h1, h2, h3, h4, h5, h6\").length,\n lists: root.querySelectorAll(\"ul, ol\").length,\n tables: root.querySelectorAll(\"table\").length,\n forms: root.querySelectorAll(\"form\").length,\n inputs: root.querySelectorAll(\"input, textarea, select\").length,\n password: Boolean(root.querySelector(\"input[type=password]\")),\n };\n const template = classifytemplate(signals);\n const fingerprint = sectionfingerprint({ tag: \"body\", attributes: {}, children: root.body?.children.length ?? 0, textlength: (root.body?.innerText ?? \"\").length });\n return { ok: true, summary: `Classified the page template as ${template}.`, details: { template, fingerprint } };\n }\n case \"fingerprintsection\": {\n if (!target) return { ok: false, summary: \"Fingerprint target is no longer available.\" };\n const attributes: Record<string, string> = {};\n for (const attribute of [...target.attributes]) attributes[attribute.name] = attribute.value;\n const fingerprint = sectionfingerprint({ tag: target.tagName.toLowerCase(), attributes, children: target.children.length, textlength: (target.textContent ?? \"\").length });\n return { ok: true, summary: `Computed section fingerprint ${fingerprint}.`, details: { fingerprint, section: elementselector(target) } };\n }\n case \"readscrollpos\": {\n const report = scrollreport(\n { scrollx: root.defaultView?.scrollX ?? 0, scrolly: root.defaultView?.scrollY ?? 0, scrollheight: root.documentElement.scrollHeight, clientheight: root.defaultView?.innerHeight ?? 0 },\n [...root.querySelectorAll(\"*\")].filter(element => element instanceof HTMLElement && element.scrollHeight > element.clientHeight).map(element => ({ selector: elementselector(element), scrolltop: element.scrollTop, scrollleft: element.scrollLeft, scrollheight: element.scrollHeight, clientheight: element.clientHeight })),\n );\n return { ok: true, summary: `Read the scroll position at ${Math.round(report.window.x)},${Math.round(report.window.y)} with ${report.containers.length} scrollable container${report.containers.length === 1 ? \"\" : \"s\"}.`, details: { scroll: report } };\n }\n default: return { ok: false, summary: \"Unsupported page detection.\" };\n }\n}\n", "import type { bannerreport, diffentry, focusevent, jsonstate, mutationevent, mutationwatch, quietrule, selectorcandidate, toolstep } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\nimport type { stepresult } from \"./pageactions.js\";\nimport { bannermatches, collectbannercandidates } from \"./pagedetect.js\";\nimport { clean, elementselector } from \"./pageresolve.js\";\n\n/**\n * Watched page observation for reviewed steps.\n * Every correlated rule for watch option parsing, mutation batching, focus tracking, the network quiet probe, the snapshot diff engine, the json state scanner and the selector scorer lives in this file.\n */\n\n/** Internal sampling cadence used when a watch step reviews no poll interval. */\nconst defaultpoll = 250;\n\n/** Parsed watch options of one watch step: the mutationwatch fields plus the poll interval. */\nexport type watchoptions = mutationwatch & { watchid: string; poll: number };\n\n/** Parses the reviewed watch options of one watch step into its mutationwatch shape with a poll interval. */\nexport function parsewatchoptions(step: toolstep, fallbackid: string): watchoptions {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n const scopes = Array.isArray(options.scopes) ? options.scopes.filter((item): item is string => typeof item === \"string\" && item.trim().length > 0) : undefined;\n const events = Array.isArray(options.events) ? options.events.filter((item): item is string => typeof item === \"string\" && item.trim().length > 0) : undefined;\n const lifetime = typeof options.lifetime === \"number\" && Number.isFinite(options.lifetime) && options.lifetime > 0 ? options.lifetime : 0;\n return {\n watchid: typeof options.watchid === \"string\" && options.watchid.trim() ? options.watchid : fallbackid,\n ...(scopes ? { scopes } : {}),\n ...(events ? { events } : {}),\n lifetime,\n poll: typeof options.poll === \"number\" && Number.isFinite(options.poll) && options.poll >= 0 ? options.poll : defaultpoll,\n };\n}\n\n/** Batches mutation records so records arriving inside one throttle window flush to the bridge together. */\nexport function batchmutations(records: mutationevent[], windowms: number): mutationevent[][] {\n const batches: mutationevent[][] = [];\n let current: mutationevent[] = [];\n let opened = -1;\n for (const record of records) {\n if (current.length === 0 || (windowms > 0 && record.at - opened >= windowms)) {\n if (current.length > 0) batches.push(current);\n current = [record];\n opened = record.at;\n } else current.push(record);\n }\n if (current.length > 0) batches.push(current);\n return batches;\n}\n\n/** Measures how long the network has stayed quiet from the resource timing entries completed so far. */\nexport function quietfor(entries: Array<{ responseend: number }>, now: number): number {\n let last = 0;\n for (const entry of entries) if (entry.responseend > last) last = entry.responseend;\n return Math.max(0, now - last);\n}\n\n/** Decides the network quiet outcome from collected probe samples against the reviewed idle threshold and timeout. */\nexport function quietresolution(samples: Array<{ at: number; quietfor: number }>, idle: number, timeout: number): { ok: boolean; quietfor: number; waited: number; samples: number } {\n const start = samples[0]?.at ?? 0;\n const last = samples[samples.length - 1];\n const waited = Math.max(0, (last?.at ?? 0) - start);\n const reached = samples.find(sample => sample.quietfor >= idle);\n if (reached) return { ok: true, quietfor: reached.quietfor, waited: reached.at - start, samples: samples.length };\n return { ok: false, quietfor: last?.quietfor ?? 0, waited, samples: samples.length };\n}\n\n/** Serializable node summary the diff engine compares between observation versions. */\nexport interface nodesummary {\n selector: string;\n tag: string;\n text: string;\n attributes: Record<string, string>;\n}\n\n/** Hashes one node summary into a stable digest used by the diff engine. */\nexport function nodehash(summary: nodesummary): string {\n const canonical = [summary.tag, summary.text, ...Object.keys(summary.attributes).sort().map(key => `${key}=${summary.attributes[key] ?? \"\"}`)].join(\"|\");\n let hash = 5381;\n for (let index = 0; index < canonical.length; index += 1) hash = ((hash << 5) + hash + canonical.charCodeAt(index)) >>> 0;\n return hash.toString(16);\n}\n\n/** Diffs two node summary sets into added, removed and changed entries by hashing node summaries. */\nexport function diffsummaries(base: nodesummary[], target: nodesummary[]): { added: diffentry[]; removed: diffentry[]; changed: diffentry[] } {\n const basemap = new Map(base.map(node => [node.selector, node]));\n const targetmap = new Map(target.map(node => [node.selector, node]));\n const added: diffentry[] = [];\n const removed: diffentry[] = [];\n const changed: diffentry[] = [];\n for (const [selector, node] of targetmap) {\n const previous = basemap.get(selector);\n if (!previous) { added.push({ kind: \"added\", selector, summary: node.text || node.tag }); continue; }\n if (nodehash(previous) !== nodehash(node)) changed.push({ kind: \"changed\", selector, summary: `${previous.text || previous.tag} became ${node.text || node.tag}` });\n }\n for (const [selector, node] of basemap) {\n if (!targetmap.has(selector)) removed.push({ kind: \"removed\", selector, summary: node.text || node.tag });\n }\n return { added, removed, changed };\n}\n\n/** Scans inline script payloads for embedded json state; malformed payloads are refused and counted. */\nexport function scanjson(scripts: Array<{ src: string; type: string; id: string; content: string }>): { states: jsonstate[]; refused: number } {\n const states: jsonstate[] = [];\n let refused = 0;\n for (const script of scripts) {\n if (script.src) continue;\n const content = script.content.trim();\n if (!(script.type.includes(\"json\") || content.startsWith(\"{\") || content.startsWith(\"[\"))) continue;\n try { states.push({ scripturl: script.src, rootpath: script.id, payload: JSON.parse(content) }); } catch { refused += 1; }\n }\n return { states, refused };\n}\n\n/** Ranks selector candidates of one element shape by stability: id, attribute, text and structural strategies. */\nexport function rankselectors(shape: { id: string; tag: string; attributes: Record<string, string>; text: string; index: number; siblings: number }): selectorcandidate[] {\n const candidates: selectorcandidate[] = [];\n if (shape.id) candidates.push({ selector: `#${shape.id}`, strategy: \"id\", score: 100 });\n for (const [name, value] of Object.entries(shape.attributes)) {\n if (!value) continue;\n if (name === \"name\" || name.startsWith(\"data-\") || name.startsWith(\"aria-\")) candidates.push({ selector: `${shape.tag}[${name}=\"${value}\"]`, strategy: \"attribute\", score: 80 });\n }\n if (shape.text) candidates.push({ selector: shape.text, strategy: \"text\", score: 60 });\n if (shape.index > 0) candidates.push({ selector: `${shape.tag}:nth-of-type(${shape.index})`, strategy: \"structural\", score: 40 });\n return candidates.sort((left, right) => right.score - left.score);\n}\n\nfunction wait(ms: number): Promise<void> {\n return new Promise(resolve => window.setTimeout(resolve, ms));\n}\n\nfunction quietruleof(step: toolstep): quietrule {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n const rule = options.quietrule;\n if (!rule || typeof rule !== \"object\" || Array.isArray(rule)) return { idle: 0 };\n const quiet = rule as Record<string, unknown>;\n return {\n idle: typeof quiet.idle === \"number\" && Number.isFinite(quiet.idle) && quiet.idle > 0 ? quiet.idle : 0,\n ...(typeof quiet.poll === \"number\" && Number.isFinite(quiet.poll) && quiet.poll >= 0 ? { poll: quiet.poll } : {}),\n ...(typeof quiet.timeout === \"number\" && Number.isFinite(quiet.timeout) && quiet.timeout >= 0 ? { timeout: quiet.timeout } : {}),\n };\n}\n\n/** Observes dom mutations inside the reviewed selector scopes for the reviewed lifetime, batching records through the throttle window. */\nasync function watchmutations(step: toolstep, root: Document): Promise<stepresult> {\n const options = parsewatchoptions(step, step.id);\n if (options.lifetime <= 0) return { ok: false, summary: \"The reviewed mutation watch lifetime is absent.\" };\n const roots: ParentNode[] = options.scopes ? options.scopes.flatMap(selector => [...root.querySelectorAll(selector)]) : [root];\n if (roots.length === 0) return { ok: false, summary: \"The reviewed watch scopes match no elements.\" };\n const allowed = options.events;\n const collected: mutationevent[] = [];\n const observer = new MutationObserver(records => {\n for (const record of records) {\n if (allowed && !allowed.includes(record.type)) continue;\n const target = record.target instanceof Element ? record.target : null;\n collected.push({ watchid: options.watchid, event: record.type, targetpath: target ? elementselector(target) : \"#text\", at: Date.now() });\n }\n });\n for (const scope of roots) observer.observe(scope, { childList: true, attributes: true, characterData: true, subtree: true });\n await wait(options.lifetime);\n observer.disconnect();\n const batches = batchmutations(collected, options.poll);\n return { ok: true, summary: `Watched ${collected.length} mutation${collected.length === 1 ? \"\" : \"s\"} in ${batches.length} batch${batches.length === 1 ? \"\" : \"es\"} for the reviewed lifetime of ${options.lifetime} milliseconds.`, details: { events: collected, batches: batches.length, watchid: options.watchid, lifetime: options.lifetime, scopes: options.scopes ?? [] } };\n}\n\n/** Records focus and blur events with element paths for the reviewed lifetime. */\nasync function watchfocus(step: toolstep, root: Document): Promise<stepresult> {\n const options = parsewatchoptions(step, step.id);\n if (options.lifetime <= 0) return { ok: false, summary: \"The reviewed focus watch lifetime is absent.\" };\n const collected: focusevent[] = [];\n const record = (kind: \"focus\" | \"blur\") => (event: Event): void => {\n const target = event.target instanceof Element ? event.target : null;\n collected.push({ watchid: options.watchid, kind, targetpath: target ? elementselector(target) : \"#document\", at: Date.now() });\n };\n const onfocus = record(\"focus\");\n const onblur = record(\"blur\");\n root.addEventListener(\"focusin\", onfocus, true);\n root.addEventListener(\"focusout\", onblur, true);\n await wait(options.lifetime);\n root.removeEventListener(\"focusin\", onfocus, true);\n root.removeEventListener(\"focusout\", onblur, true);\n return { ok: true, summary: `Watched ${collected.length} focus change${collected.length === 1 ? \"\" : \"s\"} for the reviewed lifetime of ${options.lifetime} milliseconds.`, details: { events: collected, watchid: options.watchid, lifetime: options.lifetime } };\n}\n\n/** Watches for cookie and consent banners for the reviewed lifetime and reports their controls. */\nasync function watchbanners(step: toolstep, root: Document): Promise<stepresult> {\n const options = parsewatchoptions(step, step.id);\n if (options.lifetime <= 0) return { ok: false, summary: \"The reviewed banner watch lifetime is absent.\" };\n const started = Date.now();\n const seen = new Map<string, bannerreport>();\n while (Date.now() - started < options.lifetime) {\n const at = Date.now();\n for (const report of bannermatches(collectbannercandidates(root), at)) {\n if (!seen.has(report.selector)) seen.set(report.selector, report);\n }\n await wait(options.poll);\n }\n const reports = [...seen.values()];\n return { ok: true, summary: `Watched for consent banners for the reviewed lifetime of ${options.lifetime} milliseconds and observed ${reports.length} banner${reports.length === 1 ? \"\" : \"s\"}.`, details: { banners: reports, watchid: options.watchid, lifetime: options.lifetime } };\n}\n\n/** Waits until the network stays quiet for the reviewed idle threshold, sampling in flight requests through the performance timeline. */\nasync function waitquiet(step: toolstep): Promise<stepresult> {\n const rule = quietruleof(step);\n if (rule.idle <= 0) return { ok: false, summary: \"The reviewed quiet idle threshold is absent.\" };\n const poll = rule.poll ?? 100;\n const timeout = rule.timeout ?? 0;\n const started = performance.now();\n const samples: Array<{ at: number; quietfor: number }> = [];\n for (;;) {\n const now = performance.now();\n const entries = (performance.getEntriesByType(\"resource\") as PerformanceResourceTiming[]).map(entry => ({ responseend: entry.responseEnd }));\n samples.push({ at: now - started, quietfor: quietfor(entries, now) });\n const latest = samples[samples.length - 1];\n if (latest && latest.quietfor >= rule.idle) break;\n if (timeout > 0 && now - started >= timeout) break;\n await wait(poll);\n }\n const outcome = quietresolution(samples, rule.idle, timeout);\n return {\n ok: outcome.ok,\n summary: outcome.ok\n ? `The network stayed quiet for ${Math.round(outcome.quietfor)} milliseconds, meeting the reviewed idle threshold of ${rule.idle} milliseconds.`\n : `The network did not stay quiet for ${rule.idle} milliseconds${timeout > 0 ? ` within the reviewed timeout of ${timeout} milliseconds` : \"\"}.`,\n details: { samples, idle: rule.idle, timeout, waited: Math.round(outcome.waited) },\n };\n}\n\nfunction scriptsurfaces(target: Element | null, root: Document): Array<{ src: string; type: string; id: string; content: string }> {\n const elements = target ? [target] : [...root.querySelectorAll(\"script\")];\n return elements.map(element => ({ src: element.getAttribute(\"src\") ?? \"\", type: element.getAttribute(\"type\") ?? \"\", id: element.id, content: element.textContent ?? \"\" }));\n}\n\n/** Extracts embedded json state from inline scripts and refuses malformed payloads. */\nfunction readjson(step: toolstep, target: Element | null, root: Document): stepresult {\n const outcome = scanjson(scriptsurfaces(target, root));\n if (target && outcome.states.length === 0 && outcome.refused > 0) return { ok: false, summary: \"The reviewed json payload is malformed and was refused.\" };\n return { ok: true, summary: `Extracted ${outcome.states.length} embedded json state${outcome.states.length === 1 ? \"\" : \"s\"}${outcome.refused > 0 ? ` and refused ${outcome.refused} malformed payload${outcome.refused === 1 ? \"\" : \"s\"}` : \"\"}.`, details: { states: outcome.states, refused: outcome.refused } };\n}\n\nfunction tonodesummaries(value: unknown): nodesummary[] | null {\n if (!Array.isArray(value)) return null;\n const summaries: nodesummary[] = [];\n for (const entry of value) {\n if (!entry || typeof entry !== \"object\" || Array.isArray(entry)) continue;\n const candidate = entry as Record<string, unknown>;\n if (typeof candidate.selector !== \"string\") continue;\n const attributes: Record<string, string> = {};\n if (candidate.attributes && typeof candidate.attributes === \"object\" && !Array.isArray(candidate.attributes)) {\n for (const [key, item] of Object.entries(candidate.attributes as Record<string, unknown>)) if (typeof item === \"string\") attributes[key] = item;\n }\n summaries.push({ selector: candidate.selector, tag: typeof candidate.tag === \"string\" ? candidate.tag : \"\", text: typeof candidate.text === \"string\" ? candidate.text : \"\", attributes });\n }\n return summaries;\n}\n\n/** Diffs the two reviewed observation versions injected by the background into added, removed and changed nodes. */\nfunction diffsnapshots(step: toolstep): stepresult {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n const base = tonodesummaries(options.base);\n const target = tonodesummaries(options.target);\n if (!base || !target) return { ok: false, summary: \"Two stored observation versions must be reviewed before diffing.\" };\n const versions = Array.isArray(options.versions) && options.versions.length === 2 ? (options.versions as number[]) : [0, 0];\n const diff = diffsummaries(base, target);\n return { ok: true, summary: `Diffed observation versions ${versions[0] ?? 0} and ${versions[1] ?? 0}: ${diff.added.length} added, ${diff.removed.length} removed and ${diff.changed.length} changed node${diff.added.length + diff.removed.length + diff.changed.length === 1 ? \"\" : \"s\"}.`, details: { versions, added: diff.added, removed: diff.removed, changed: diff.changed } };\n}\n\n/** Derives ranked selector candidates for one reviewed element. */\nfunction deriveselector(target: Element | null): stepresult {\n if (!(target instanceof Element)) return { ok: false, summary: \"Derivation target is no longer available.\" };\n const attributes: Record<string, string> = {};\n for (const attribute of [...target.attributes]) attributes[attribute.name] = attribute.value;\n const parent = target.parentElement;\n const siblings = parent ? [...parent.children].filter(node => node.tagName === target.tagName) : [target];\n const candidates = rankselectors({ id: target.id, tag: target.tagName.toLowerCase(), attributes, text: clean(target.textContent ?? \"\").slice(0, 80), index: siblings.indexOf(target) + 1, siblings: siblings.length });\n const best = candidates[0];\n return { ok: candidates.length > 0, summary: best ? `Derived ${candidates.length} selector candidate${candidates.length === 1 ? \"\" : \"s\"}; the most stable is ${best.selector} through the ${best.strategy} strategy with stability ${best.score}.` : \"No selector candidate could be derived.\", details: { candidates } };\n}\n\n/** Runs one watched observation after the background policy gate; the reviewed lifetime window bounds every watch. */\nexport function runpagewatch(step: toolstep, target: Element | null, root: Document = document): stepresult | Promise<stepresult> {\n switch (step.kind) {\n case \"watchmutate\": return watchmutations(step, root);\n case \"watchfocus\": return watchfocus(step, root);\n case \"watchbanner\": return watchbanners(step, root);\n case \"waitquiet\": return waitquiet(step);\n case \"readjson\": return readjson(step, target, root);\n case \"diffsnapshots\": return diffsnapshots(step);\n case \"deriveselector\": return deriveselector(target);\n default: return { ok: false, summary: \"Unsupported watched observation.\" };\n }\n}\n", "import type { fielderror, fieldkind, fieldmatch, formrecord, formentry, formreport, toolstep } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\nimport type { stepresult } from \"./pageactions.js\";\nimport { clean, elementlabel as label, elementselector as selector } from \"./pageresolve.js\";\n\n/**\n * Form field logics for reviewed steps.\n * Every correlated rule for field matching, field kind classification, seeded value generation, native value fills, honeypot detection, login and template detection, error association and form record parsing lives in this file.\n */\n\n/** One serializable form field shape resolved against the page controls. */\nexport interface fieldshape {\n selector: string;\n tag: string;\n type: string;\n name: string;\n label: string;\n placeholder: string;\n arialabel: string;\n autocomplete: string;\n options?: string[];\n}\n\n/** One surveyed field shape carrying the visibility, geometry and timing evidence the honeypot detector reads. */\nexport interface fieldsurvey extends fieldshape {\n hidden: boolean;\n offscreen: boolean;\n createdat?: number;\n}\n\n/** One honeypot field flagged by hidden, offscreen or time trap evidence. */\nexport interface honeypotevidence {\n selector: string;\n reason: \"hidden\" | \"offscreen\" | \"timetrap\";\n}\n\n/** One surveyed field with the aria describedby ref and the sibling message texts the error reader associates. */\nexport interface errorcontext extends fieldshape {\n describedby?: string;\n siblings: string[];\n}\n\n/** Resolves controls by label, placeholder, aria label and name attributes; matches are case insensitive substrings. */\nexport function matchfield(fields: fieldshape[], match: fieldmatch): fieldshape[] {\n const key = match.mode === \"label\" ? \"label\" : match.mode === \"placeholder\" ? \"placeholder\" : match.mode === \"arialabel\" ? \"arialabel\" : \"name\";\n const needle = (match[key] ?? \"\").trim().toLowerCase();\n if (!needle) return [];\n return fields.filter(field => {\n const primary = (field[key] as string).toLowerCase();\n const secondary = match.mode === \"label\" || match.mode === \"name\" ? field.name.toLowerCase() : match.mode === \"placeholder\" ? field.arialabel.toLowerCase() : field.placeholder.toLowerCase();\n return primary.includes(needle) || secondary.includes(needle);\n });\n}\n\n/** Infers the field kind of one control from its input type, autocomplete hint and label text. */\nexport function classifyfield(input: { type: string; autocomplete: string; label: string }): fieldkind {\n const type = input.type.toLowerCase();\n const autocomplete = input.autocomplete.toLowerCase();\n const label = input.label.toLowerCase();\n if (type === \"password\") return \"password\";\n if (autocomplete.startsWith(\"cc-\") || label.includes(\"card number\") || label.includes(\"credit card\") || label.includes(\"cardholder\")) return \"card\";\n if (autocomplete.includes(\"one-time-code\") || autocomplete.includes(\"otp\") || label.includes(\"one time code\") || label.includes(\"verification code\") || label.includes(\"otp\")) return \"code\";\n if (type === \"email\" || autocomplete.includes(\"email\") || label.includes(\"email\")) return \"email\";\n if (type === \"tel\" || autocomplete.includes(\"tel\") || label.includes(\"phone\") || label.includes(\"telephone\")) return \"phone\";\n if (type === \"date\") return \"date\";\n if (type === \"number\") return \"number\";\n if (type === \"checkbox\") return \"check\";\n if (type === \"radio\") return \"radio\";\n if (type === \"file\") return \"file\";\n if (type === \"select\" || type === \"select-one\") return \"select\";\n return \"text\";\n}\n\nconst firstnames: Record<string, string[]> = { en: [\"alex\", \"jordan\", \"taylor\", \"morgan\", \"casey\"], pt: [\"ana\", \"bruno\", \"carla\", \"diego\", \"helena\"] };\nconst lastnames: Record<string, string[]> = { en: [\"brooks\", \"carter\", \"diaz\", \"evans\", \"reyes\"], pt: [\"alves\", \"costa\", \"lima\", \"souza\", \"moraes\"] };\n\nfunction localekey(locale: string): string {\n const normalized = locale.toLowerCase();\n if (normalized.startsWith(\"pt\")) return \"pt\";\n return \"en\";\n}\n\n/** Generates one realistic value for a field kind, deterministically seeded and locale aware for names, emails and phones. */\nexport function generatevalue(kind: fieldkind, rule: { locale?: string; seed?: number }): string {\n const seed = typeof rule.seed === \"number\" && Number.isFinite(rule.seed) ? Math.abs(Math.floor(rule.seed)) : 1;\n const names = firstnames[localekey(rule.locale ?? \"en\")] ?? firstnames.en ?? [\"alex\"];\n const surnames = lastnames[localekey(rule.locale ?? \"en\")] ?? lastnames.en ?? [\"brooks\"];\n let state = seed * 1103515245 + 12345;\n const next = (): number => { state = (state * 1103515245 + 12345) % 2147483648; return state / 2147483648; };\n const pick = <T>(items: T[]): T => items[Math.floor(next() * items.length) % items.length] ?? items[0] as T;\n const digits = (count: number): string => Array.from({ length: count }, () => String(Math.floor(next() * 10))).join(\"\");\n const person = `${pick(names)} ${pick(surnames)}`;\n switch (kind) {\n case \"email\": return `${person.replace(\" \", \".\")}${digits(2)}@example.com`;\n case \"phone\": return localekey(rule.locale ?? \"en\") === \"pt\" ? `+55 (11) 9${digits(4)}-${digits(4)}` : `+1 (555) 010-${digits(4)}`;\n case \"date\": return `${2024 + Math.floor(next() * 2)}-${String(1 + Math.floor(next() * 12)).padStart(2, \"0\")}-${String(1 + Math.floor(next() * 28)).padStart(2, \"0\")}`;\n case \"number\": return String(Math.floor(next() * 1000));\n case \"select\": return `option ${1 + Math.floor(next() * 5)}`;\n case \"check\": return next() > 0.5 ? \"true\" : \"false\";\n case \"radio\": return `choice ${1 + Math.floor(next() * 4)}`;\n case \"file\": return `sample${digits(2)}.pdf`;\n case \"password\": return `pw-${digits(6)}-${pick(names)}`;\n case \"card\": return `4111 ${digits(4)} ${digits(4)} ${digits(4)}`;\n case \"code\": return digits(6);\n default: return person;\n }\n}\n\n/** Builds a deterministic values hash of the reviewed field values a submission ticket records. */\nexport function valueshash(values: Array<{ label: string; value: string }>): string {\n const source = values.map(entry => `${entry.label}=${entry.value}`).join(\"|\");\n let hash = 5381;\n for (let index = 0; index < source.length; index += 1) hash = ((hash * 33) ^ source.charCodeAt(index)) >>> 0;\n return hash.toString(16);\n}\n\n/** Parses the reviewed structured form record of a step; null when the step reviews none or the shape is invalid. */\nexport function parseformrecord(value: unknown): formrecord | null {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return null;\n const record = value as Record<string, unknown>;\n if (!Array.isArray(record.entries)) return null;\n const entries: formentry[] = [];\n for (const item of record.entries) {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) continue;\n const entry = item as Record<string, unknown>;\n const match = entry.match;\n if (!match || typeof match !== \"object\" || Array.isArray(match)) continue;\n const shapes = match as Record<string, unknown>;\n if (typeof shapes.mode !== \"string\") continue;\n const fieldmatch: fieldmatch = {\n mode: shapes.mode as fieldmatch[\"mode\"],\n ...(typeof shapes.label === \"string\" ? { label: shapes.label } : {}),\n ...(typeof shapes.placeholder === \"string\" ? { placeholder: shapes.placeholder } : {}),\n ...(typeof shapes.arialabel === \"string\" ? { arialabel: shapes.arialabel } : {}),\n ...(typeof shapes.name === \"string\" ? { name: shapes.name } : {}),\n };\n if (typeof entry.kind !== \"string\" || typeof entry.value !== \"string\") continue;\n entries.push({ match: fieldmatch, kind: entry.kind as fieldkind, value: entry.value });\n }\n if (entries.length === 0) return null;\n return { ...(typeof record.form === \"string\" && record.form ? { form: record.form } : {}), entries };\n}\n\n/** Builds form record entries from reviewed label or placeholder value pairs. */\nexport function pairentries(pairs: Array<{ label?: string; placeholder?: string; value: string }>, mode: \"label\" | \"placeholder\"): formrecord {\n return { entries: pairs.map(pair => ({ match: mode === \"label\" ? { mode, label: pair.label ?? \"\" } : { mode, placeholder: pair.placeholder ?? \"\" }, kind: \"text\", value: pair.value })) };\n}\n\n/** One fill operation outcome: the entry, the matched control, the honeypot skip flag or the refusal reason. */\nexport interface filloutcome {\n entry: formentry;\n matched?: fieldshape;\n skipped?: boolean;\n reason?: string;\n}\n\n/** Resolves every entry of a form record against the surveyed fields, skipping honeypots and refusing unmatched or ambiguous entries. */\nexport function filloperations(record: formrecord, fields: fieldshape[], skippedselectors: string[] = []): filloutcome[] {\n return record.entries.map(entry => {\n const matches = matchfield(fields, entry.match);\n if (matches.length === 0) return { entry, reason: \"unmatched\" };\n if (matches.length > 1) return { entry, reason: \"ambiguous\" };\n const matched = matches[0] as fieldshape;\n if (skippedselectors.includes(matched.selector)) return { entry, matched, skipped: true };\n return { entry, matched };\n });\n}\n\n/** Masks one card segment so side panels can render card fills without exposing the full value. */\nexport function cardmask(value: string): string {\n const trimmed = value.trim();\n if (/^\\d[\\d\\s-]{11,18}$/.test(trimmed)) {\n const compact = trimmed.replace(/[\\s-]/g, \"\");\n const last = compact.slice(-4);\n return `${\"\u2022\".repeat(Math.max(0, compact.length - 4))}${last}`;\n }\n return \"\u2022\".repeat(trimmed.length);\n}\n\n/** Flags hidden, offscreen and time trap fields so fill steps skip them instead of tripping anti bot defenses. */\nexport function detecthoneypots(surveys: fieldsurvey[], loadedat: number): honeypotevidence[] {\n const traps: honeypotevidence[] = [];\n for (const field of surveys) {\n if (field.hidden) traps.push({ selector: field.selector, reason: \"hidden\" });\n else if (field.offscreen) traps.push({ selector: field.selector, reason: \"offscreen\" });\n else if (field.createdat !== undefined && loadedat > 0 && field.createdat > loadedat) traps.push({ selector: field.selector, reason: \"timetrap\" });\n }\n return traps;\n}\n\n/** Detects a login form: a password field plus an identifier field with session links nearby. */\nexport function detectlogin(fields: fieldshape[], links: string[]): { login: boolean; markers: string[] } {\n const markers: string[] = [];\n const password = fields.find(field => classifyfield(field) === \"password\");\n if (password) markers.push(\"password field\");\n const identifier = fields.find(field => {\n const kind = classifyfield(field);\n return kind === \"email\" || (kind === \"text\" && /user|login|account|identifier/i.test(`${field.name} ${field.label}`));\n });\n if (identifier) markers.push(\"identifier field\");\n const sessionlink = links.some(link => /sign in|log in|log on|forgot|create account|sign up/i.test(link));\n if (sessionlink) markers.push(\"session link\");\n return { login: Boolean(password && identifier && sessionlink), markers };\n}\n\nconst signupmarkers = [\"sign up\", \"create account\", \"register\", \"confirm password\", \"terms\"];\nconst checkoutmarkers = [\"checkout\", \"payment\", \"billing\", \"shipping\", \"card number\", \"place order\", \"cart\"];\n\n/** Detects signup and checkout templates by matching the field labels, autocompletes and page text against known markers. */\nexport function detecttemplate(fields: fieldshape[], text: string): { template: \"signup\" | \"checkout\" | \"unknown\"; markers: string[] } {\n const corpus = [text, ...fields.map(field => `${field.label} ${field.name} ${field.placeholder} ${field.arialabel} ${field.autocomplete}`)].join(\" \").toLowerCase();\n const signup = signupmarkers.filter(marker => corpus.includes(marker));\n const checkout = checkoutmarkers.filter(marker => corpus.includes(marker));\n if (signup.length >= 2 && signup.length >= checkout.length) return { template: \"signup\", markers: signup };\n if (checkout.length >= 2) return { template: \"checkout\", markers: checkout };\n return { template: \"unknown\", markers: [...signup, ...checkout] };\n}\n\n/** Associates validation messages with fields through aria describedby refs and the sibling text next to each field. */\nexport function associateerrors(contexts: errorcontext[], messages: Array<{ id?: string; text: string }>): fielderror[] {\n const errors: fielderror[] = [];\n for (const field of contexts) {\n const byref = field.describedby ? messages.find(message => message.id === field.describedby && message.text.trim()) : undefined;\n if (byref) { errors.push({ field: field.selector, message: byref.text.trim() }); continue; }\n const sibling = field.siblings.map(text => text.trim()).find(text => text.length > 0);\n if (sibling) errors.push({ field: field.selector, message: sibling });\n }\n return errors;\n}\n\n/** Resolves one reviewed artifact name against the run store before a file input is filled. */\nexport function attachplan(name: string, artifacts: Array<{ id: string; name: string; kind: string }>): { artifact?: { id: string; name: string; kind: string }; reason?: string } {\n const artifact = artifacts.find(item => item.name === name || item.id === name);\n if (!artifact) return { reason: \"The reviewed artifact name is not part of the run store.\" };\n return { artifact };\n}\n\n/** Selectors the captcha detector probes; a hit hands control back to the user instead of forcing the page. */\nexport const captchamarkers = ['iframe[src*=\"recaptcha\"]', 'iframe[title*=\"recaptcha\" i]', '.g-recaptcha', '[data-sitekey]', 'iframe[title*=\"captcha\" i]', '.h-captcha'];\n\n/** True when any captcha marker matched, so the plan pauses and hands control to the user. */\nexport function captchadetected(matched: string[]): boolean {\n return matched.length > 0;\n}\n\nfunction events(target: Element): void {\n target.dispatchEvent(new Event(\"input\", { bubbles: true }));\n target.dispatchEvent(new Event(\"change\", { bubbles: true }));\n}\n\n/** Fills one control through the native setter with input and change events; checks, radios and selects use their own grammar. */\nexport function fillcontrol(element: Element, entry: formentry): boolean {\n if (element instanceof HTMLInputElement && (entry.kind === \"check\" || element.type === \"checkbox\")) { element.checked = entry.value === \"true\" || entry.value === \"on\" || entry.value === \"checked\"; events(element); return true; }\n if (element instanceof HTMLInputElement && (entry.kind === \"radio\" || element.type === \"radio\")) { element.checked = true; events(element); return true; }\n if (element instanceof HTMLSelectElement) {\n const option = [...element.options].find(candidate => candidate.value === entry.value || candidate.textContent?.trim() === entry.value);\n if (!option) return false;\n element.value = option.value;\n events(element);\n return true;\n }\n if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {\n if (element instanceof HTMLInputElement && element.type === \"file\") return false;\n element.focus();\n const setter = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(element), \"value\")?.set;\n if (setter) setter.call(element, entry.value); else element.value = entry.value;\n events(element);\n return true;\n }\n return false;\n}\n\nfunction controlshape(element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement): fieldshape {\n return {\n selector: selector(element),\n tag: element.tagName.toLowerCase(),\n type: element instanceof HTMLSelectElement ? \"select\" : element.getAttribute(\"type\") || \"text\",\n name: element.getAttribute(\"name\") || \"\",\n label: label(element),\n placeholder: element.getAttribute(\"placeholder\") || \"\",\n arialabel: element.getAttribute(\"aria-label\") || \"\",\n autocomplete: element.getAttribute(\"autocomplete\") || \"\",\n ...(element instanceof HTMLSelectElement ? { options: [...element.options].map(option => option.value) } : {}),\n };\n}\n\n/** Collects the serializable field shapes of one form scope; absent scopes survey the whole document. */\nfunction collectfields(root: Document, formscope?: string): Array<{ shape: fieldshape; element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement }> {\n const scope = formscope ? root.querySelector(formscope) : root;\n if (!scope) return [];\n const controls = [...scope.querySelectorAll<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>(\"input, select, textarea\")];\n return controls.filter(element => element.type !== \"hidden\").map(element => ({ shape: controlshape(element), element }));\n}\n\n/** Surveys the visibility and geometry evidence the honeypot detector reads for one form scope. */\nfunction surveyfields(root: Document, formscope?: string): Array<{ survey: fieldsurvey; element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement }> {\n const viewport = { left: 0, top: 0, right: window.innerWidth || 0, bottom: window.innerHeight || 0 };\n return collectfields(root, formscope).map(({ shape, element }) => {\n const rect = element.getBoundingClientRect();\n const hidden = element.getAttribute(\"aria-hidden\") === \"true\" || element.tabIndex < 0 && (element as HTMLElement).offsetParent === null || (element as HTMLElement).offsetParent === null && rect.width === 0 && rect.height === 0;\n const offscreen = rect.width > 0 && rect.height > 0 && (rect.bottom < viewport.top || rect.top > viewport.bottom || rect.right < viewport.left || rect.left > viewport.right);\n return { survey: { ...shape, hidden, offscreen }, element };\n });\n}\n\n/** Reads the error context of one form scope: describedby refs and the sibling texts after each field. */\nfunction collecterrorcontext(root: Document, formscope?: string): Array<{ context: errorcontext; element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement }> {\n return collectfields(root, formscope).map(({ shape, element }) => {\n const siblings: string[] = [];\n let neighbor = element.nextElementSibling;\n for (let index = 0; neighbor && index < 3; index += 1) {\n const text = clean(neighbor.textContent || \"\");\n if (text && text !== shape.label) siblings.push(text);\n neighbor = neighbor.nextElementSibling;\n }\n const describedby = element.getAttribute(\"aria-describedby\");\n return { context: { ...shape, ...(describedby ? { describedby } : {}), siblings }, element };\n });\n}\n\n/** Runs one reviewed forms and data step inside the page: fills, surveys, detects and reads errors without leaving the form scope. */\nexport function runpageform(step: toolstep, target: Element | null, root: Document = document): stepresult | Promise<stepresult> {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n const formscope = typeof options.form === \"string\" && options.form ? options.form : step.target;\n switch (step.kind) {\n case \"fillform\": {\n const record = parseformrecord(options.formrecord);\n if (!record) return { ok: false, summary: \"A reviewed form record with entries is required in options.\" };\n const surveys = surveyfields(root, record.form);\n const honeypots = detecthoneypots(surveys.map(entry => entry.survey), 0);\n const operations = filloperations(record, surveys.map(entry => entry.survey), honeypots.map(trap => trap.selector));\n let filled = 0;\n const skipped: string[] = [];\n const failures: string[] = [];\n const values: Array<{ label: string; value: string }> = [];\n for (const operation of operations) {\n if (operation.skipped && operation.matched) { skipped.push(operation.matched.selector); continue; }\n if (!operation.matched) { failures.push(`${operation.reason}: ${operation.entry.match.label ?? operation.entry.match.name ?? operation.entry.match.placeholder ?? \"field\"}`); continue; }\n const element = surveys.find(entry => entry.survey.selector === operation.matched?.selector)?.element;\n if (!element || !fillcontrol(element, operation.entry)) { failures.push(`unfillable: ${operation.matched.selector}`); continue; }\n filled += 1;\n values.push({ label: operation.matched.label || operation.matched.name, value: operation.entry.kind === \"password\" ? \"\" : operation.entry.value });\n }\n const report: formreport = { form: record.form ?? \"\", fields: operations.map(operation => ({ selector: operation.matched?.selector ?? \"\", label: operation.matched?.label ?? operation.entry.match.label ?? \"\", kind: operation.entry.kind, matched: Boolean(operation.matched) })) };\n return {\n ok: failures.length === 0,\n summary: failures.length === 0 ? `Filled ${filled} reviewed field${filled === 1 ? \"\" : \"s\"} from the structured record${skipped.length > 0 ? ` and skipped ${skipped.length} honeypot field${skipped.length === 1 ? \"\" : \"s\"}` : \"\"}.` : `Filled ${filled} of ${record.entries.length} reviewed fields; ${failures.length} refusals: ${failures.join(\"; \")}.`,\n details: { filled, skipped, failures, values, report },\n };\n }\n case \"filllabel\":\n case \"fillplaceholder\": {\n const mode = step.kind === \"filllabel\" ? \"label\" : \"placeholder\";\n const pairs = Array.isArray(options.fields) ? (options.fields as Array<Record<string, unknown>>).filter(item => item && typeof item === \"object\") : [];\n const record = pairentries(pairs.map(pair => ({ label: typeof pair.label === \"string\" ? pair.label : \"\", placeholder: typeof pair.placeholder === \"string\" ? pair.placeholder : \"\", value: typeof pair.value === \"string\" ? pair.value : \"\" })), mode);\n if (record.entries.length === 0) return { ok: false, summary: \"A reviewed non-empty list of field pairs is required in options.\" };\n const surveys = surveyfields(root, formscope);\n const honeypots = detecthoneypots(surveys.map(entry => entry.survey), 0);\n const operations = filloperations(record, surveys.map(entry => entry.survey), honeypots.map(trap => trap.selector));\n let filled = 0;\n const failures: string[] = [];\n for (const operation of operations) {\n if (operation.skipped) continue;\n if (!operation.matched) { failures.push(`${operation.reason}: ${mode === \"label\" ? operation.entry.match.label : operation.entry.match.placeholder}`); continue; }\n const element = surveys.find(entry => entry.survey.selector === operation.matched?.selector)?.element;\n const refined: formentry = { ...operation.entry, kind: classifyfield(operation.matched) };\n if (!element || !fillcontrol(element, refined)) { failures.push(`unfillable: ${operation.matched.selector}`); continue; }\n filled += 1;\n }\n return { ok: failures.length === 0, summary: failures.length === 0 ? `Filled ${filled} field${filled === 1 ? \"\" : \"s\"} matched by ${mode}.` : `Filled ${filled} of ${record.entries.length} fields matched by ${mode}; ${failures.join(\"; \")}.`, details: { filled, failures, mode } };\n }\n case \"detectfields\": {\n const collected = collectfields(root, formscope);\n const report: formreport = { form: formscope ?? \"\", fields: collected.map(entry => ({ selector: entry.shape.selector, label: entry.shape.label || entry.shape.name, kind: classifyfield(entry.shape), matched: Boolean(entry.shape.label || entry.shape.name) })) };\n return { ok: true, summary: `Detected ${collected.length} form field${collected.length === 1 ? \"\" : \"s\"} with their kinds.`, details: { report, count: collected.length } };\n }\n case \"generatevalues\": {\n const rule = options.valuegen && typeof options.valuegen === \"object\" && !Array.isArray(options.valuegen) ? options.valuegen as Record<string, unknown> : {};\n const locale = typeof rule.locale === \"string\" ? rule.locale : \"en\";\n const seed = typeof rule.seed === \"number\" && Number.isFinite(rule.seed) ? rule.seed : 1;\n const surveys = surveyfields(root, formscope);\n const honeypots = detecthoneypots(surveys.map(entry => entry.survey), 0);\n const skippedselectors = new Set(honeypots.map(trap => trap.selector));\n const candidates = surveys.filter(entry => !skippedselectors.has(entry.survey.selector));\n const values = candidates.map(entry => ({ label: entry.survey.label || entry.survey.name || entry.survey.selector, kind: classifyfield(entry.survey), value: generatevalue(classifyfield(entry.survey), { locale, seed }) }));\n const single = values.length === 0 && typeof rule.kind === \"string\" ? [{ label: rule.kind, kind: rule.kind, value: generatevalue(rule.kind as fieldkind, { locale, seed }) }] : values;\n return { ok: true, summary: `Generated ${single.length} realistic value${single.length === 1 ? \"\" : \"s\"} for the detected field kinds.`, details: { values: single, locale, seed } };\n }\n case \"readerrors\": {\n const contexts = collecterrorcontext(root, formscope);\n const messages = [...root.querySelectorAll<HTMLElement>(\"[id]\")].map(element => ({ id: element.id, text: clean(element.textContent || \"\") })).filter(message => message.text.length > 0);\n const errors = associateerrors(contexts.map(entry => entry.context), messages);\n return { ok: true, summary: errors.length === 0 ? \"No validation error was found next to the reviewed fields.\" : `Collected ${errors.length} inline validation message${errors.length === 1 ? \"\" : \"s\"}.`, details: { errors, form: formscope ?? \"\" } };\n }\n case \"skiphoneypot\": {\n const surveys = surveyfields(root, formscope);\n const traps = detecthoneypots(surveys.map(entry => entry.survey), 0);\n return { ok: true, summary: traps.length === 0 ? \"No honeypot field was detected.\" : `Skipped ${traps.length} honeypot field${traps.length === 1 ? \"\" : \"s\"}: ${traps.map(trap => `${trap.selector} (${trap.reason})`).join(\", \")}.`, details: { skipped: traps } };\n }\n case \"detectlogin\": {\n const collected = collectfields(root, formscope);\n const links = [...(formscope ? root.querySelectorAll(formscope) : [root] as unknown as Element[])].flatMap(scope => [...scope.querySelectorAll(\"a[href], button\")]).map(element => clean(element.textContent || \"\"));\n const detection = detectlogin(collected.map(entry => entry.shape), links);\n return { ok: true, summary: detection.login ? `Login form detected with ${detection.markers.join(\", \")}.` : \"No login form was detected.\", details: { login: detection.login, markers: detection.markers } };\n }\n case \"detecttemplate\": {\n const collected = collectfields(root, formscope);\n const text = clean(root.body?.innerText || \"\");\n const detection = detecttemplate(collected.map(entry => entry.shape), text);\n return { ok: true, summary: detection.template === \"unknown\" ? \"No signup or checkout template was detected.\" : `${detection.template} template detected with markers ${detection.markers.join(\", \")}.`, details: { template: detection.template, markers: detection.markers } };\n }\n case \"handoffcaptcha\": {\n const matched = captchamarkers.filter(marker => root.querySelector(marker) !== null);\n return { ok: true, summary: captchadetected(matched) ? `Captcha presence detected (${matched.join(\", \")}); control hands back to the user.` : \"No captcha was detected.\", details: { captcha: captchadetected(matched), markers: matched } };\n }\n case \"asksubmit\": {\n const collected = collectfields(root, step.value || undefined);\n const values = collected.map(entry => ({ label: entry.shape.label || entry.shape.name || entry.shape.selector, value: entry.element instanceof HTMLSelectElement ? entry.element.value : (entry.element as HTMLInputElement).value }));\n return { ok: true, summary: `Read ${values.length} field value${values.length === 1 ? \"\" : \"s\"} for the submission review.`, details: { values } };\n }\n case \"submitform\": {\n const form = target instanceof HTMLFormElement ? target : target instanceof HTMLElement ? target.closest(\"form\") : null;\n if (!form) return { ok: false, summary: \"No owning form was found for the reviewed submission.\" };\n form.requestSubmit();\n return { ok: true, summary: \"Form submitted programmatically through its owning form.\" };\n }\n case \"consentpassword\": {\n if (!(target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement)) return { ok: false, summary: \"The reviewed password target cannot receive text.\" };\n const entry: formentry = { match: { mode: \"name\", name: target.name || target.getAttribute(\"id\") || \"\" }, kind: \"password\", value: step.value ?? \"\" };\n if (!fillcontrol(target, entry)) return { ok: false, summary: \"The password field refused the native setter fill.\" };\n return { ok: true, summary: \"Password field filled after the reviewed consent; the value never appears in the audit trail.\" };\n }\n case \"attachfile\": {\n if (!(target instanceof HTMLInputElement) || target.type !== \"file\") return { ok: false, summary: \"The reviewed target is not a file input.\" };\n const artifactname = typeof options.artifactname === \"string\" && options.artifactname ? options.artifactname : \"artifact\";\n try {\n const file = new File([new Blob([\"devthink artifact\"], { type: \"application/octet-stream\" })], artifactname);\n const transfer = new DataTransfer();\n transfer.items.add(file);\n target.files = transfer.files;\n events(target);\n return { ok: true, summary: `Artifact ${artifactname} attached to the reviewed file input.`, details: { artifact: options.artifact, artifactname } };\n } catch {\n return { ok: false, summary: \"The reviewed file input refused the artifact attachment.\" };\n }\n }\n default: return { ok: false, summary: \"Unsupported forms and data action.\" };\n }\n}\n", "import type { toolstep, wizardstate } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\nimport type { stepresult } from \"./pageactions.js\";\nimport { cardmask } from \"./pageforms.js\";\nimport { clean } from \"./pageresolve.js\";\n\n/**\n * Wizard, dependent control and payment field logics for reviewed steps.\n * Every correlated rule for wizard tracking, dependent option waits, typeahead picks, calendar navigation, card segment typing, one time code sources and submission retry backoff lives in this file.\n */\n\n/** Advances one wizard step, recording the completion signal of the executed step and the new step index. */\nexport function wizardadvance(state: wizardstate, completed: boolean, at: number): wizardstate {\n const flags = [...state.completed];\n while (flags.length < state.index + 1) flags.push(false);\n flags[state.index] = completed;\n return { ...state, index: Math.min(state.index + 1, state.steps), completed: flags, at };\n}\n\n/** True when the dependent child options finished loading after a parent selection changed their count. */\nexport function dependentloaded(previouscount: number, currentcount: number): boolean {\n return currentcount !== previouscount;\n}\n\n/** Picks the reviewed suggestion entry from a typeahead list, case insensitive; undefined when the entry is absent. */\nexport function typeaheadpick(suggestions: string[], pick: string): string | undefined {\n const needle = pick.trim().toLowerCase();\n return suggestions.find(suggestion => suggestion.trim().toLowerCase() === needle);\n}\n\n/** Parses one reviewed yyyy-mm-dd date into its year, month and day parts; null when the form is invalid. */\nexport function parsedateparts(value: string): { year: number; month: number; day: number } | null {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(value)) return null;\n const parts = value.split(\"-\").map(part => Number.parseInt(part, 10));\n const year = parts[0] ?? 0;\n const month = parts[1] ?? 0;\n const day = parts[2] ?? 0;\n if (month < 1 || month > 12 || day < 1 || day > 31) return null;\n return { year, month, day };\n}\n\n/** Plans the calendar navigation to the reviewed date: the month delta and the day cell to click. */\nexport function calendarplan(view: { year: number; month: number }, date: { year: number; month: number; day: number }): { months: number; day: number } {\n return { months: (date.year - view.year) * 12 + (date.month - view.month), day: date.day };\n}\n\n/** Splits one card number into its typed groups so the filler pauses between groups. */\nexport function cardgroups(number: string): string[] {\n const groups = number.replace(/[-\\s]+/g, \" \").trim().split(\" \");\n return groups.filter(group => group.length > 0);\n}\n\n/** True when the reviewed one time code source is ready to deliver the code before typing. */\nexport function codeready(source: string, value: string | undefined): boolean {\n if (source === \"reviewed\") return typeof value === \"string\" && value.trim().length > 0;\n return false;\n}\n\n/** One reviewed retry backoff rule with an attempt count, a wait window and a growth factor, all user configured. */\nexport interface backoffrule {\n attempts: number;\n wait: number;\n factor: number;\n}\n\n/** Parses the reviewed backoff rule of a retryform step; null when the step reviews none. */\nexport function parsebackoff(step: toolstep): backoffrule | null {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n const backoff = options.backoff;\n if (!backoff || typeof backoff !== \"object\" || Array.isArray(backoff)) return null;\n const rule = backoff as Record<string, unknown>;\n const wait = rule.wait;\n const factor = rule.factor;\n if (typeof wait !== \"number\" || !Number.isFinite(wait) || wait <= 0) return null;\n if (typeof factor !== \"number\" || !Number.isFinite(factor) || factor < 1) return null;\n const attempts = typeof options.attempts === \"number\" && Number.isInteger(options.attempts) && options.attempts >= 1 ? options.attempts : 2;\n return { attempts, wait, factor };\n}\n\n/** Computes the reviewed backoff windows between submission retries; no code ceiling applies. */\nexport function backoffwaits(attempts: number, wait: number, factor: number): number[] {\n const windows: number[] = [];\n let current = wait;\n for (let index = 1; index < attempts; index += 1) {\n windows.push(current);\n current *= factor;\n }\n return windows;\n}\n\nfunction wait(delay: number): Promise<void> {\n return new Promise(resolve => window.setTimeout(resolve, delay));\n}\n\nfunction pollfor(predicate: () => boolean, description: string, timeout: number): Promise<stepresult> {\n return new Promise(resolve => {\n const started = Date.now();\n const check = (): void => {\n if (predicate()) { resolve({ ok: true, summary: `${description} is now present on the page.` }); return; }\n if (timeout > 0 && Date.now() - started >= timeout) { resolve({ ok: false, summary: `${description} did not appear within ${timeout} milliseconds.` }); return; }\n window.setTimeout(check, 100);\n };\n check();\n });\n}\n\n/** Runs one reviewed wizard or payment field step inside the page, from multi step wizards to card segments and one time codes. */\nexport function runpagewizard(step: toolstep, target: Element | null, root: Document = document): stepresult | Promise<stepresult> {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n switch (step.kind) {\n case \"runwizard\": {\n const scope = target instanceof HTMLElement ? target : root.body ?? root.documentElement;\n const steps = typeof options.steps === \"number\" && Number.isInteger(options.steps) && options.steps > 0 ? options.steps : 1;\n const state: wizardstate = { index: 0, steps, completed: [], at: Date.now() };\n const next = scope.querySelector<HTMLElement>(\"button[type=submit], button[name=next], [data-next]\");\n if (!next) return { ok: false, summary: \"No next step control was found inside the wizard scope.\", details: { wizard: state } };\n next.click();\n const advanced = wizardadvance(state, true, Date.now());\n return { ok: advanced.index >= steps, summary: `Wizard advanced to step ${advanced.index + 1} of ${steps}${advanced.index >= steps ? \" and completed\" : \"\"}.`, details: { wizard: advanced } };\n }\n case \"selectchain\": {\n if (!(target instanceof HTMLSelectElement)) return { ok: false, summary: \"The reviewed parent target is not a select element.\" };\n const childselector = typeof options.child === \"string\" ? options.child : \"\";\n const child = root.querySelector<HTMLSelectElement>(childselector);\n if (!child) return { ok: false, summary: \"The reviewed dependent child control was not found.\" };\n const previouscount = child.options.length;\n const option = [...target.options].find(candidate => candidate.value === step.value || candidate.textContent?.trim() === step.value);\n if (!option) return { ok: false, summary: \"The reviewed parent option is not part of the select element.\" };\n target.value = option.value;\n target.dispatchEvent(new Event(\"input\", { bubbles: true }));\n target.dispatchEvent(new Event(\"change\", { bubbles: true }));\n const waitwindow = typeof options.wait === \"number\" && options.wait > 0 ? options.wait : 0;\n return pollfor(() => dependentloaded(previouscount, child.options.length), \"Dependent options of the child control\", waitwindow);\n }\n case \"picktypeahead\": {\n const field = target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement ? target : null;\n if (!field) return { ok: false, summary: \"The reviewed typeahead target cannot receive text.\" };\n const pick = typeof options.pick === \"string\" ? options.pick : \"\";\n const timeout = typeof options.timeout === \"number\" && options.timeout > 0 ? options.timeout : 0;\n field.focus();\n field.value = step.value ?? \"\";\n field.dispatchEvent(new Event(\"input\", { bubbles: true }));\n const list = root.querySelector<HTMLElement>('[role=listbox], .suggestions, ul.autocomplete, [data-typeahead]');\n const suggestions = list ? [...list.querySelectorAll<HTMLElement>(\"[role=option], li, .suggestion\")].map(entry => clean(entry.textContent || \"\")) : [];\n const chosen = typeaheadpick(suggestions, pick);\n if (chosen === undefined) return { ok: false, summary: `The reviewed suggestion \"${pick}\" is not part of the typeahead list.`, details: { suggestions } };\n const entry = [...(list?.querySelectorAll<HTMLElement>(\"[role=option], li, .suggestion\") ?? [])].find(item => clean(item.textContent || \"\").trim().toLowerCase() === chosen.trim().toLowerCase());\n entry?.click();\n field.dispatchEvent(new Event(\"change\", { bubbles: true }));\n return { ok: Boolean(entry), summary: `Picked the reviewed typeahead entry \"${chosen}\".`, details: { pick: chosen, query: step.value ?? \"\" } };\n }\n case \"pickdate\": {\n const calendar = target instanceof HTMLElement ? target : root.body ?? root.documentElement;\n const date = parsedateparts(step.value ?? \"\");\n if (!date) return { ok: false, summary: \"The reviewed date must use the yyyy-mm-dd form.\" };\n const header = clean(calendar.querySelector<HTMLElement>(\"[data-calendar-title], .calendar-title, header\")?.textContent || \"\");\n const match = /(\\d{4})/.exec(header);\n const monthnames = [\"january\", \"february\", \"march\", \"april\", \"may\", \"june\", \"july\", \"august\", \"september\", \"october\", \"november\", \"december\"];\n const viewyear = match ? Number.parseInt(match[1] ?? \"0\", 10) : new Date().getFullYear();\n const viewmonth = monthnames.findIndex(name => header.toLowerCase().includes(name)) >= 0 ? monthnames.findIndex(name => header.toLowerCase().includes(name)) : new Date().getMonth() + 1;\n const plan = calendarplan({ year: viewyear, month: viewmonth }, date);\n const forward = plan.months >= 0;\n for (let index = 0; index < Math.abs(plan.months); index += 1) {\n calendar.querySelector<HTMLElement>(forward ? \"[data-next-month], .next-month, [aria-label=next]\" : \"[data-prev-month], .prev-month, [aria-label=previous]\")?.click();\n }\n const day = [...calendar.querySelectorAll<HTMLElement>(\"[role=gridcell], [data-day], td\")].find(cell => Number.parseInt(clean(cell.textContent || \"\"), 10) === plan.day);\n if (!day) return { ok: false, summary: `The reviewed day cell ${plan.day} was not found in the calendar widget.` };\n day.click();\n return { ok: true, summary: `Picked ${step.value} from the calendar widget after ${Math.abs(plan.months)} month navigation${Math.abs(plan.months) === 1 ? \"\" : \"s\"}.`, details: { months: plan.months, day: plan.day } };\n }\n case \"fillcard\": {\n const segments = Array.isArray(options.segments) ? (options.segments as Array<Record<string, unknown>>).filter(item => item && typeof item === \"object\") : [];\n if (segments.length === 0) return { ok: false, summary: \"A reviewed non-empty list of card segments is required in options.\" };\n const pause = typeof options.pause === \"number\" && options.pause > 0 ? options.pause : 0;\n const filled: Array<{ label: string; masked: string }> = [];\n const failures: string[] = [];\n const fillsegment = async (segment: Record<string, unknown>): Promise<void> => {\n const match = segment.match as Record<string, unknown> | undefined;\n const value = typeof segment.value === \"string\" ? segment.value : \"\";\n if (!match || typeof match !== \"object\") { failures.push(\"segment without a reviewed match\"); return; }\n const scope = root.body ?? root.documentElement;\n const candidates = [...scope.querySelectorAll<HTMLInputElement>(\"input, select\")];\n const key = match.mode === \"label\" ? \"label\" : match.mode === \"placeholder\" ? \"placeholder\" : match.mode === \"arialabel\" ? \"arialabel\" : \"name\";\n const needle = String(match[key] ?? \"\").toLowerCase();\n const element = candidates.find(input => (key === \"label\" ? input.name.toLowerCase() || input.getAttribute(\"aria-label\")?.toLowerCase() || \"\" : (input.getAttribute(key) ?? input.name).toLowerCase()).includes(needle) || (input.getAttribute(\"aria-label\") ?? \"\").toLowerCase().includes(needle));\n if (!element) { failures.push(`unmatched: ${needle}`); return; }\n element.focus();\n for (const group of cardgroups(value)) {\n element.value = group;\n element.dispatchEvent(new Event(\"input\", { bubbles: true }));\n if (pause > 0) await wait(pause);\n }\n element.dispatchEvent(new Event(\"change\", { bubbles: true }));\n filled.push({ label: String(match[key] ?? \"\"), masked: cardmask(value) });\n };\n return (async (): Promise<stepresult> => {\n for (const segment of segments) await fillsegment(segment);\n return {\n ok: failures.length === 0,\n summary: failures.length === 0 ? `Filled ${filled.length} card segment${filled.length === 1 ? \"\" : \"s\"} with pauses between card number groups.` : `Filled ${filled.length} of ${segments.length} card segments; ${failures.join(\"; \")}.`,\n details: { segments: filled, failures, pause },\n };\n })();\n }\n case \"fillcode\": {\n const field = target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement ? target : null;\n if (!field) return { ok: false, summary: \"The reviewed one time code target cannot receive text.\" };\n const source = typeof options.source === \"string\" ? options.source : \"\";\n const timeout = typeof options.timeout === \"number\" && options.timeout > 0 ? options.timeout : 0;\n const code = step.value ?? \"\";\n return pollfor(() => codeready(source, code), \"The reviewed one time code source\", timeout).then(result => {\n if (!codeready(source, code)) return { ok: false, summary: `The reviewed code source ${source} is not ready to deliver the code yet.` };\n field.focus();\n field.value = code;\n field.dispatchEvent(new Event(\"input\", { bubbles: true }));\n field.dispatchEvent(new Event(\"change\", { bubbles: true }));\n return { ok: true, summary: `One time code typed from the reviewed source ${source}.`, details: { source } };\n });\n }\n default: return { ok: false, summary: \"Unsupported wizard action.\" };\n }\n}\n", "import type { columnspec, datasetrow, sourceref, toolstep, transformrule } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\nimport type { stepresult } from \"./pageactions.js\";\nimport { clean, elementselector as selector } from \"./pageresolve.js\";\n\n/**\n * Table and dataset logics for reviewed steps.\n * Every correlated rule for header normalization, span expansion, nested table walking, pagination following, row hashing, transform expressions, dataset merging, row sampling and csv, json and excel serialization lives in this file.\n */\n\n/** One raw table cell with its text, header flag, span geometry and an optional nested table. */\nexport interface cellshape {\n text: string;\n header: boolean;\n rowspan: number;\n colspan: number;\n nested?: { selector: string; rows: rowshape[] };\n}\n\n/** One raw table row of span carrying cells. */\nexport interface rowshape {\n cells: cellshape[];\n header: boolean;\n}\n\n/** One nested child table linked to the body row it belongs to. */\nexport interface childtable {\n parentrow: number;\n selector: string;\n columns: columnspec[];\n rows: datasetrow[];\n}\n\n/** Result of the table reader: normalized column specs, keyed body rows and child datasets. */\nexport interface gridresult {\n columns: columnspec[];\n rows: datasetrow[];\n children: childtable[];\n}\n\n/** Trims, lowercases and slugifies one header cell into a stable column key. */\nexport function normalizeheader(label: string): string {\n const slug = label.trim().toLowerCase().replace(/[^\\p{L}\\p{N}]+/gu, \"-\").replace(/^-+|-+$/g, \"\");\n return slug || \"column\";\n}\n\n/** Builds one column spec from a header label with a unique stable key and the normalized name. */\nexport function columnspecof(label: string, used: Set<string> = new Set()): columnspec {\n const base = normalizeheader(label);\n let key = base;\n let suffix = 2;\n while (used.has(key)) {\n key = `${base}${suffix}`;\n suffix += 1;\n }\n used.add(key);\n return { key, label: label.trim(), kind: \"text\", normalized: label.trim().toLowerCase() };\n}\n\n/** Classifies a column as number only when every non-empty value parses as a number. */\nexport function classifycolumn(values: string[]): \"text\" | \"number\" {\n const present = values.filter(value => value.trim().length > 0);\n if (present.length === 0) return \"text\";\n return present.every(value => Number.isFinite(Number(value.replace(/,/g, \".\")))) ? \"number\" : \"text\";\n}\n\n/** Expands rowspan and colspan cells into a filled rectangular grid of values. */\nexport function expandspans(rows: rowshape[]): string[][] {\n const filled: Array<Array<string | undefined>> = [];\n const pending = new Map<string, string>();\n for (let index = 0; index < rows.length; index += 1) {\n const row: Array<string | undefined> = filled[index] ?? (filled[index] = []);\n let column = 0;\n for (const cell of rows[index]!.cells) {\n while (row[column] !== undefined || pending.has(`${index},${column}`)) {\n if (row[column] === undefined) row[column] = pending.get(`${index},${column}`);\n column += 1;\n }\n row[column] = cell.text;\n for (let spanrow = 0; spanrow < Math.max(1, cell.rowspan); spanrow += 1) {\n for (let spancol = 0; spancol < Math.max(1, cell.colspan); spancol += 1) {\n if (spanrow === 0 && spancol === 0) continue;\n pending.set(`${index + spanrow},${column + spancol}`, cell.text);\n }\n }\n column += Math.max(1, cell.colspan);\n }\n }\n for (const [key, value] of pending) {\n const [rowpart, columnpart] = key.split(\",\");\n const rowindex = Number.parseInt(rowpart ?? \"0\", 10);\n const columnindex = Number.parseInt(columnpart ?? \"0\", 10);\n const target = filled[rowindex] ?? (filled[rowindex] = []);\n if (target[columnindex] === undefined) target[columnindex] = value;\n }\n const width = filled.reduce((largest, row) => Math.max(largest, row.length), 0);\n return filled.map(row => Array.from({ length: width }, (_, column) => row[column] ?? \"\"));\n}\n\n/** Reads header and body rows into normalized column specs and keyed body rows, extracting nested tables into child datasets. */\nexport function readgrid(rows: rowshape[]): gridresult {\n const headerindex = rows.findIndex(row => row.header || (row.cells[0]?.header ?? false));\n const useheader = headerindex !== -1 ? headerindex : 0;\n const hasheader = headerindex !== -1 || rows.length > 0;\n const grid = expandspans(rows);\n const headercells = hasheader ? (grid[useheader] ?? []) : [];\n const used = new Set<string>();\n const columns = Array.from({ length: headercells.length || (grid[0]?.length ?? 0) }, (_, index) => columnspecof(headercells[index] ?? `column${index + 1}`, used));\n const bodyrows = grid.filter((_, index) => hasheader ? index !== useheader : true)\n .filter(line => line.some(value => value.trim().length > 0))\n .map(line => {\n const row: datasetrow = {};\n columns.forEach((column, index) => { row[column.key] = line[index] ?? \"\"; });\n return row;\n });\n for (const column of columns) column.kind = classifycolumn(bodyrows.map(row => row[column.key] ?? \"\"));\n const children: childtable[] = [];\n rows.forEach((row, rowindex) => {\n if (hasheader && rowindex === useheader) return;\n const parentrow = hasheader && rowindex > useheader ? rowindex - 1 : rowindex;\n row.cells.forEach(cell => {\n if (!cell.nested) return;\n const child = readgrid(cell.nested.rows);\n children.push({ parentrow, selector: cell.nested!.selector, columns: child.columns, rows: child.rows });\n });\n });\n return { columns, rows: bodyrows, children };\n}\n\n/** Resolves the next pagination control from numbered page entries: the entry after the current one or a next word control. */\nexport function nextcontrol(entries: Array<{ text: string; selector: string; current: boolean }>): string | undefined {\n const current = entries.findIndex(entry => entry.current);\n if (current !== -1 && current + 1 < entries.length) return entries[current + 1]?.selector;\n const nextwords = [\"next\", \"next page\", \">\", \">>\", \"\u203A\", \"\u00BB\", \"pr\u00F3xima\", \"seguinte\"];\n return entries.find(entry => nextwords.includes(entry.text.trim().toLowerCase()))?.selector;\n}\n\n/** True when the current row set contains at least one row the previous set did not carry. */\nexport function rowsfresh(previous: datasetrow[], current: datasetrow[]): boolean {\n if (current.length === 0) return false;\n const known = new Set(previous.map(row => JSON.stringify(row)));\n return current.some(row => !known.has(JSON.stringify(row)));\n}\n\n/** Computes a stable row hash over the reviewed keys; an empty key list hashes every column. */\nexport function rowhash(row: datasetrow, keys: string[]): string {\n const source = (keys.length > 0 ? keys : Object.keys(row).sort()).map(key => `${key}=${row[key] ?? \"\"}`).join(\"|\");\n let hash = 5381;\n for (let index = 0; index < source.length; index += 1) hash = ((hash * 33) ^ source.charCodeAt(index)) >>> 0;\n return hash.toString(16);\n}\n\n/** Deduplicates rows by reviewed keys, keeping the first occurrence of every key set. */\nexport function dedupebykeys(rows: datasetrow[], keys: string[]): { kept: datasetrow[]; removed: number } {\n const seen = new Set<string>();\n const kept: datasetrow[] = [];\n for (const row of rows) {\n const hash = rowhash(row, keys);\n if (seen.has(hash)) continue;\n seen.add(hash);\n kept.push(row);\n }\n return { kept, removed: rows.length - kept.length };\n}\n\n/** Applies one reviewed transform expression to a value; unsupported expressions are refused. */\nexport function applyexpression(value: string, expression: string): string {\n const split = expression.indexOf(\":\");\n const op = split === -1 ? expression : expression.slice(0, split);\n const argument = split === -1 ? undefined : expression.slice(split + 1);\n if (op === \"trim\") return value.trim();\n if (op === \"upper\") return value.toUpperCase();\n if (op === \"lower\") return value.toLowerCase();\n if (op === \"number\") return value.replace(/[^\\d.\\-]/g, \"\");\n if (op === \"prefix\") return `${argument ?? \"\"}${value}`;\n if (op === \"suffix\") return `${value}${argument ?? \"\"}`;\n if (op === \"replace\") {\n const separator = argument?.indexOf(\"=>\") ?? -1;\n if (separator === -1 || separator === 0) throw new Error(`The reviewed transform expression ${expression} needs the from=>to separator.`);\n const from = argument!.slice(0, separator);\n const to = argument!.slice(separator + 2);\n return value.split(from).join(to);\n }\n throw new Error(`The reviewed transform expression ${op} is not supported.`);\n}\n\n/** Applies reviewed transform rules to dataset rows, surfacing per rule errors and keeping the original values on failure. */\nexport function transformrows(rows: datasetrow[], rules: transformrule[]): { rows: datasetrow[]; errors: string[] } {\n const errors: string[] = [];\n const output = rows.map(row => ({ ...row }));\n for (const rule of rules) {\n const updated: datasetrow[] = [];\n try {\n for (const row of output) updated.push({ ...row, [rule.target]: applyexpression(rule.sources.map(source => row[source] ?? \"\").join(\" \"), rule.expression) });\n } catch (error) {\n errors.push(`${rule.target}: ${error instanceof Error ? error.message : String(error)}`);\n continue;\n }\n output.splice(0, output.length, ...updated);\n }\n return { rows: output, errors };\n}\n\n/** Merges datasets across pages: columns align by key with gaps filled empty and rows concatenate in page order. */\nexport function mergedatasets(datasets: Array<{ columns: columnspec[]; rows: datasetrow[] }>): { columns: columnspec[]; rows: datasetrow[] } {\n const columns: columnspec[] = [];\n const seen = new Set<string>();\n for (const dataset of datasets) {\n for (const column of dataset.columns) {\n if (seen.has(column.key)) continue;\n seen.add(column.key);\n columns.push(column);\n }\n }\n const rows = datasets.flatMap(dataset => dataset.rows.map(row => {\n const merged: datasetrow = {};\n for (const column of columns) merged[column.key] = row[column.key] ?? \"\";\n return merged;\n }));\n return { columns, rows };\n}\n\n/** Attaches the source url, timestamp and step ref to every row and returns the matching source refs. */\nexport function samplerows(rows: datasetrow[], url: string, stepid: string, at: number): { rows: datasetrow[]; sources: sourceref[] } {\n const stamped = rows.map(row => ({ ...row, source: url, capturedat: String(at), step: stepid }));\n const sources = stamped.map((row, index) => ({ row: index, url, at, stepid }));\n return { rows: stamped, sources };\n}\n\n/** Escapes one csv field, wrapping values that carry the delimiter, quotes or line breaks. */\nfunction csvfield(value: string, delimiter: string): string {\n return value.includes(delimiter) || value.includes(\"\\\"\") || value.includes(\"\\n\") ? `\"${value.replace(/\"/g, \"\\\"\\\"\")}\"` : value;\n}\n\n/** Serializes columns and rows into csv text. */\nexport function tocsv(columns: columnspec[], rows: datasetrow[], delimiter = \",\"): string {\n const lines = [columns.map(column => csvfield(column.label || column.key, delimiter)).join(delimiter)];\n for (const row of rows) lines.push(columns.map(column => csvfield(row[column.key] ?? \"\", delimiter)).join(delimiter));\n return lines.join(\"\\n\");\n}\n\n/** Parses csv text into headers and raw rows, honoring quoted fields and escaped quotes. */\nexport function parsecsv(text: string, delimiter = \",\"): { headers: string[]; rows: string[][] } {\n const records: string[][] = [];\n let field = \"\";\n let record: string[] = [];\n let quoted = false;\n for (let index = 0; index < text.length; index += 1) {\n const character = text[index]!;\n if (quoted) {\n if (character === \"\\\"\") {\n if (text[index + 1] === \"\\\"\") { field += \"\\\"\"; index += 1; }\n else quoted = false;\n } else field += character;\n continue;\n }\n if (character === \"\\\"\") { quoted = true; continue; }\n if (character === delimiter) { record.push(field); field = \"\"; continue; }\n if (character === \"\\n\" || character === \"\\r\") {\n if (character === \"\\r\" && text[index + 1] === \"\\n\") index += 1;\n record.push(field);\n field = \"\";\n if (record.some(value => value.length > 0) || record.length > 1) records.push(record);\n record = [];\n continue;\n }\n field += character;\n }\n record.push(field);\n if (record.some(value => value.length > 0) || record.length > 1) records.push(record);\n const [headers = [], ...rows] = records;\n return { headers, rows };\n}\n\n/** Maps parsed csv headers onto dataset column specs through a reviewed mapping of csv names to target keys. */\nexport function mapcolumns(headers: string[], mapping: Record<string, string> = {}): columnspec[] {\n const used = new Set<string>();\n return headers.map(header => {\n const target = mapping[header] ?? mapping[normalizeheader(header)] ?? header;\n return columnspecof(target, used);\n });\n}\n\n/** Serializes columns and rows into a json dataset payload. */\nexport function tojson(columns: columnspec[], rows: datasetrow[]): string {\n return JSON.stringify({ columns, rows });\n}\n\n/** Escapes one xml text node. */\nfunction xmltext(value: string): string {\n return value.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\").replace(/\"/g, \"&quot;\");\n}\n\n/** Serializes columns and rows into an Excel SpreadsheetML 2003 workbook that Excel opens natively. */\nexport function toexcel(columns: columnspec[], rows: datasetrow[], name: string): string {\n const head = columns.map(column => `<Cell ss:StyleID=\"head\"><Data ss:Type=\"String\">${xmltext(column.label || column.key)}</Data></Cell>`).join(\"\");\n const body = rows.map(row => `<Row>${columns.map(column => {\n const value = row[column.key] ?? \"\";\n const numeric = column.kind === \"number\" && value.trim() !== \"\" && Number.isFinite(Number(value));\n return numeric ? `<Cell><Data ss:Type=\"Number\">${xmltext(value)}</Data></Cell>` : `<Cell><Data ss:Type=\"String\">${xmltext(value)}</Data></Cell>`;\n }).join(\"\")}</Row>`).join(\"\");\n return `<?xml version=\"1.0\"?><?mso-application progid=\"Excel.Sheet\"?><Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\" xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\"><Styles><Style ss:ID=\"head\"><Font ss:Bold=\"1\"/></Style></Styles><Worksheet ss:Name=\"${xmltext(name || \"dataset\").slice(0, 31)}\"><Table><Row>${head}</Row>${body}</Table></Worksheet></Workbook>`;\n}\n\n/** Collects the raw span carrying row shapes of one html table, separating nested tables into cell refs. */\nfunction collectrowshapes(table: HTMLTableElement): rowshape[] {\n return [...table.rows].map(row => ({\n header: [...row.cells].every(cell => cell.tagName === \"TH\") && row.cells.length > 0,\n cells: [...row.cells].map(cell => {\n const nested = cell.querySelector(\"table\");\n return {\n text: clean(nested ? `${nested.rows.length} rows` : cell.textContent ?? \"\"),\n header: cell.tagName === \"TH\",\n rowspan: cell.rowSpan,\n colspan: cell.colSpan,\n ...(nested instanceof HTMLTableElement ? { nested: { selector: selector(nested), rows: collectrowshapes(nested) } } : {}),\n };\n }),\n }));\n}\n\n/** Reads the reviewed table element into a grid result. */\nfunction readtable(target: Element | null, root: Document, fallbackselector: string | undefined): gridresult | null {\n const table = target instanceof HTMLTableElement ? target : (fallbackselector ? root.querySelector<HTMLTableElement>(fallbackselector) : root.querySelector<HTMLTableElement>(\"table\"));\n if (!table) return null;\n return readgrid(collectrowshapes(table));\n}\n\n/** Reads the live pagination entries of a table container for the next control resolution. */\nfunction paginationentries(root: Document, scope: string | undefined): Array<{ text: string; selector: string; current: boolean }> {\n const container = scope ? root.querySelector(scope) : root;\n if (!container) return [];\n return [...container.querySelectorAll(\"a[href], button\")].map(element => ({\n text: clean(element.textContent ?? \"\"),\n selector: selector(element),\n current: element.getAttribute(\"aria-current\") === \"page\" || element.classList.contains(\"active\") || element.classList.contains(\"current\"),\n }));\n}\n\n/** Runs one reviewed data step on the page: table scraping into datasets and pagination following with fresh row waits. */\nexport async function runpagedata(step: toolstep, target: Element | null, root: Document = document): Promise<stepresult> {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n if (step.kind === \"scrapetable\") {\n const grid = readtable(target, root, step.target);\n if (!grid) return { ok: false, summary: \"The reviewed table selector matches no table element.\" };\n const rowlimit = typeof options.rowlimit === \"number\" && Number.isInteger(options.rowlimit) && options.rowlimit > 0 ? options.rowlimit : grid.rows.length;\n const limited = grid.rows.slice(0, rowlimit);\n return {\n ok: true,\n summary: `Scraped ${limited.length} row${limited.length === 1 ? \"\" : \"s\"} into ${grid.columns.length} normalized column${grid.columns.length === 1 ? \"\" : \"s\"}${grid.children.length > 0 ? ` with ${grid.children.length} nested child table${grid.children.length === 1 ? \"\" : \"s\"}` : \"\"}.`,\n details: { grid: { columns: grid.columns, rows: limited, children: grid.children }, rows: limited.length, columns: grid.columns.length },\n };\n }\n if (step.kind === \"paginateextract\") {\n const nextselector = typeof options.next === \"string\" ? options.next : \"\";\n const pages = typeof options.pages === \"number\" && Number.isInteger(options.pages) && options.pages > 0 ? options.pages : 1;\n const wait = typeof options.wait === \"number\" && Number.isFinite(options.wait) && options.wait > 0 ? options.wait : 0;\n const cursor = typeof options.cursor === \"number\" && Number.isInteger(options.cursor) && options.cursor > 0 ? options.cursor : 0;\n const grids: gridresult[] = [];\n let previous: datasetrow[] = [];\n for (let page = 0; page < pages + cursor; page += 1) {\n if (page < cursor) {\n const control = root.querySelector<HTMLElement>(nextselector);\n if (!control) break;\n control.click();\n await new Promise(resolve => window.setTimeout(resolve, 0));\n continue;\n }\n if (page > cursor) {\n const control = root.querySelector<HTMLElement>(nextselector);\n if (!control) break;\n control.click();\n const deadline = Date.now() + wait;\n let fresh = false;\n while (!fresh && Date.now() < deadline) {\n await new Promise(resolve => window.setTimeout(resolve, Math.min(100, Math.max(16, deadline - Date.now()))));\n const probe = readtable(target, root, step.target);\n fresh = probe !== null && rowsfresh(previous, probe.rows);\n }\n }\n const grid = readtable(target, root, step.target);\n if (!grid) return { ok: false, summary: \"The reviewed table selector matches no table element.\" };\n grids.push(grid);\n previous = grid.rows;\n }\n const merged = mergedatasets(grids);\n const hasnext = Boolean(root.querySelector(nextselector));\n return {\n ok: grids.length > 0,\n summary: grids.length > 0 ? `Followed ${grids.length} page${grids.length === 1 ? \"\" : \"s\"} of the reviewed table into ${merged.rows.length} row${merged.rows.length === 1 ? \"\" : \"s\"}${hasnext ? \"; a next control remains\" : \"\"}.` : \"No page of the reviewed table was extracted.\",\n details: { grid: { columns: merged.columns, rows: merged.rows, children: grids.flatMap(grid => grid.children) }, pages: grids.length, rows: merged.rows.length, next: hasnext },\n };\n }\n return { ok: false, summary: \"Unsupported data step.\" };\n}\n\n/** Exposes the pagination entries of the current document so plan review can suggest next controls. */\nexport function pagepagination(root: Document = document): Array<{ text: string; selector: string; current: boolean }> {\n return paginationentries(root, undefined);\n}\n", "import type { artifactrecord, columnspec, dataset, datasetrow, exportedartifact, extractsession, provenancerecord, streamstate, toolstep, transformrule } from \"../types.js\";\nimport { tocsv, toexcel, tojson } from \"./pagedata.js\";\n\n/**\n * Dataset command logics for the background executors.\n * Every correlated rule for dataset records, artifact exports with checksums, chunked streaming with backpressure, extraction cursors, loop row variables, provenance records and artifact retention lives in this file.\n */\n\n/** Builds one dataset record from a scraped grid result. */\nexport function builddataset(id: string, name: string, grid: { columns: columnspec[]; rows: datasetrow[]; children?: Array<{ parentrow: number; selector: string; columns: columnspec[]; rows: datasetrow[] }> }, at: number): dataset {\n return { id, name: name || id, columns: grid.columns, rows: grid.rows, sources: [], at };\n}\n\n/** Computes the deterministic checksum of an exported artifact's content. */\nexport function checksum(value: string): string {\n let hash = 5381;\n for (let index = 0; index < value.length; index += 1) hash = ((hash * 33) ^ value.charCodeAt(index)) >>> 0;\n return `fnv1a-${hash.toString(16)}`;\n}\n\n/** Serializes one dataset into the reviewed export format. */\nexport function exportcontent(datasetvalue: dataset, format: \"csv\" | \"json\" | \"excel\", delimiter = \",\"): string {\n if (format === \"json\") return tojson(datasetvalue.columns, datasetvalue.rows);\n if (format === \"excel\") return toexcel(datasetvalue.columns, datasetvalue.rows, datasetvalue.name);\n return tocsv(datasetvalue.columns, datasetvalue.rows, delimiter);\n}\n\n/** Builds one exported artifact record with its content and checksum for the task artifact store. */\nexport function exportartifact(id: string, datasetvalue: dataset, format: \"csv\" | \"json\" | \"excel\", stepid: string, content: string, at: number): exportedartifact {\n const extension = format === \"excel\" ? \"xml\" : format;\n return { id, kind: format, name: `${datasetvalue.name || datasetvalue.id}.${extension}`, stepid, rowcount: datasetvalue.rows.length, content, checksum: checksum(content), at };\n}\n\n/** Converts one exported artifact into the artifact record shape the run store keeps. */\nexport function artifactrecordof(artifact: exportedartifact): artifactrecord {\n return { id: artifact.id, kind: artifact.kind, name: artifact.name, stepid: artifact.stepid, at: artifact.at };\n}\n\n/** Plans the chunk boundaries of a streaming export from a user configured chunk size with no code ceiling. */\nexport function chunkplan(rows: number, chunk: number): Array<{ index: number; from: number; to: number }> {\n const size = Math.max(1, Math.floor(chunk));\n const chunks: Array<{ index: number; from: number; to: number }> = [];\n for (let from = 0; from < rows || chunks.length === 0; from += size) {\n const to = Math.min(rows, from + size);\n chunks.push({ index: chunks.length, from, to });\n if (to >= rows) break;\n }\n return chunks;\n}\n\n/** True when the stream writer must wait for acknowledgements: pending writes reached the in-flight budget of one. */\nexport function backpressure(written: number, acknowledged: number): boolean {\n return written - acknowledged >= 1;\n}\n\n/** Advances one stream state by one acknowledged chunk of rows. */\nexport function advancestream(state: streamstate, chunk: { index: number; to: number }, at: number, done: boolean): streamstate {\n return { datasetid: state.datasetid, name: state.name, chunk: chunk.index + 1, chunks: state.chunks, written: chunk.to, ...(done ? { done: true } : {}), at };\n}\n\n/** Returns the first unwritten row index of a stream, starting a fresh stream at zero. */\nexport function streamfrom(state: streamstate | undefined, rows: number): number {\n if (!state || state.done) return 0;\n return Math.min(state.written, rows);\n}\n\n/** Builds the initial stream state of one dataset. */\nexport function newstream(datasetvalue: dataset, chunks: number, at: number): streamstate {\n return { datasetid: datasetvalue.id, name: datasetvalue.name, chunk: 0, chunks, written: 0, at };\n}\n\n/** Advances one extraction session by one extracted page with its row count. */\nexport function advancecursor(sessionvalue: extractsession, page: string, rows: number, at: number, done: boolean): extractsession {\n return {\n id: sessionvalue.id,\n datasetid: sessionvalue.datasetid,\n name: sessionvalue.name,\n target: sessionvalue.target,\n next: sessionvalue.next,\n planned: sessionvalue.planned,\n pages: [...sessionvalue.pages, page],\n rows: sessionvalue.rows + rows,\n cursor: sessionvalue.cursor + 1,\n ...(done || sessionvalue.cursor + 1 >= sessionvalue.planned ? { done: true } : {}),\n startedat: sessionvalue.startedat,\n updatedat: at,\n };\n}\n\n/** Builds the initial extraction session of one dataset extraction. */\nexport function newextractsession(id: string, datasetid: string, name: string, target: string, next: string, planned: number, at: number): extractsession {\n return { id, datasetid, name, target, next, planned, pages: [], rows: 0, cursor: 0, startedat: at, updatedat: at };\n}\n\n/** Returns the pages an interrupted extraction still owes after its stored cursor. */\nexport function remainingpages(sessionvalue: extractsession, planned: number): number {\n if (sessionvalue.done) return 0;\n return Math.max(0, Math.max(sessionvalue.planned, planned) - sessionvalue.cursor);\n}\n\n/** Builds one provenance record of an exported artifact with its source url, step ref, row range and checksum. */\nexport function provenancefor(artifact: { id: string; name: string; rowcount: number; checksum: string }, url: string, stepid: string, at: number): provenancerecord {\n return { artifact: artifact.id, name: artifact.name, url, stepid, rowstart: artifact.rowcount > 0 ? 1 : 0, rowend: artifact.rowcount, checksum: artifact.checksum, at };\n}\n\n/** Applies the user configured artifact retention to exported artifacts; an absent setting keeps everything. */\nexport function retainedexports<T>(records: T[], retention: number | undefined): T[] {\n return retention === undefined ? records : records.slice(0, retention);\n}\n\n/** Interpolates one text through the {{column}} tokens of a dataset row. */\nexport function interpolate(text: string, row: datasetrow): string {\n return text.replace(/\\{\\{([^}]+)\\}\\}/g, (_, key: string) => row[key.trim()] ?? \"\");\n}\n\n/** Substitutes the row variables of one looprows iteration into the target, value and options of the inner step. */\nexport function loopstep(step: toolstep, row: datasetrow): toolstep {\n return {\n ...step,\n ...(step.target !== undefined ? { target: interpolate(step.target, row) } : {}),\n ...(step.value !== undefined ? { value: interpolate(step.value, row) } : {}),\n ...(step.options !== undefined ? { options: interpolate(step.options, row) } : {}),\n };\n}\n\n/** Exposes one dataset row as the step variables of a looprows iteration. */\nexport function loopvariables(row: datasetrow): datasetrow {\n return { ...row };\n}\n\n/** Builds the grid preview of a dataset with its column order, total rows and sampled rows. */\nexport function gridpreview(datasetvalue: dataset, sample: number): { datasetid: string; columns: string[]; rows: number; sample: datasetrow[] } {\n return { datasetid: datasetvalue.id, columns: datasetvalue.columns.map(column => column.key), rows: datasetvalue.rows.length, sample: datasetvalue.rows.slice(0, Math.max(0, Math.floor(sample))) };\n}\n\n/** Sorts dataset rows by one column key in the reviewed direction with a stable fallback for equal values. */\nexport function sortrows(rows: datasetrow[], key: string, direction: \"asc\" | \"desc\"): datasetrow[] {\n const sign = direction === \"desc\" ? -1 : 1;\n return [...rows].sort((left, right) => {\n const a = left[key] ?? \"\";\n const b = right[key] ?? \"\";\n const numeric = Number(a);\n const numericb = Number(b);\n if (Number.isFinite(numeric) && Number.isFinite(numericb) && a.trim() !== \"\" && b.trim() !== \"\") return (numeric - numericb) * sign;\n return a.localeCompare(b) * sign;\n });\n}\n\n/** Builds the sheet push payload of one dataset for a reviewed sheet endpoint. */\nexport function sheetpayload(datasetvalue: dataset, sheet: string): { sheet: string; columns: string[]; rows: datasetrow[] } {\n return { sheet, columns: datasetvalue.columns.map(column => column.key), rows: datasetvalue.rows };\n}\n\n/** Merges reviewed transform rules and dedupe keys into the task rules record of one task. */\nexport function mergetaskrules(existing: { taskid: string; transforms: transformrule[]; dedupekeys: string[] } | undefined, taskid: string, transforms: transformrule[], dedupekeys: string[], at: number): { taskid: string; transforms: transformrule[]; dedupekeys: string[]; at: number } {\n return {\n taskid,\n transforms: transforms.length > 0 ? transforms : (existing?.transforms ?? []),\n dedupekeys: dedupekeys.length > 0 ? dedupekeys : (existing?.dedupekeys ?? []),\n at,\n };\n}\n", "import type { observation, resolvedtarget, toolstep } from \"../types.js\";\nimport { runpageaction, type stepresult } from \"./pageactions.js\";\nimport { runpageread } from \"./pagereads.js\";\nimport { runpagecontrol } from \"./pagecontrols.js\";\nimport { runinteractstep } from \"./pageinteract.js\";\nimport { runpointerstep } from \"./pagepointer.js\";\nimport { runpagenav } from \"./pagenav.js\";\nimport { harvestdialoglog, type observeddialog } from \"./pagedialogs.js\";\nimport { builda11ytree, buildpagetree, buildreader, runpageobservation } from \"./pageobserve.js\";\nimport { collecttables, detectlistpatterns, collectsiblings, normalizetable, runpagedetection } from \"./pagedetect.js\";\nimport { runpagewatch } from \"./pagewatch.js\";\nimport { runpageform } from \"./pageforms.js\";\nimport { runpagewizard } from \"./pagewizards.js\";\nimport { runpagedata } from \"./pagedata.js\";\nimport { checksum } from \"./datacommand.js\";\nimport { clean, elementlabel as label, elementselector as selector, resolvestep } from \"./pageresolve.js\";\n\n/**\n * Page bridge for reviewed steps.\n * Correlated rules for the dispatch seam, semantic snapshots, target preview with resolution, dialog log reads and the original action set live in this file.\n */\n\nfunction stepoptions(step: toolstep): Record<string, unknown> {\n if (!step.options) return {};\n try {\n const parsed = JSON.parse(step.options);\n return parsed && typeof parsed === \"object\" && !Array.isArray(parsed) ? (parsed as Record<string, unknown>) : {};\n } catch { return {}; }\n}\n\nconst previewid = \"devthinktargetpreview\";\n\nfunction clearpreview(): void {\n document.getElementById(previewid)?.remove();\n}\n\n/** Shows an ephemeral outline only; it neither mutates page data nor dispatches page events. */\nexport function previewtarget(step: toolstep, expectedorigin: string): { ok: boolean; summary: string; resolvedtarget?: resolvedtarget; candidates?: string[] } {\n if (location.origin !== expectedorigin) return { ok: false, summary: \"Page origin changed before preview.\" };\n clearpreview();\n const resolution = resolvestep(step, document);\n if (resolution.status === \"ambiguous\") return { ok: false, summary: `The reviewed ${resolution.mode} reference matched ${resolution.candidates.length} elements: ${resolution.candidates.join(\"; \")}.`, candidates: resolution.candidates };\n if (resolution.status !== \"resolved\") return { ok: false, summary: \"Reviewed target is no longer available.\" };\n const target = resolution.element;\n const rect = target.getBoundingClientRect();\n if (rect.width <= 0 || rect.height <= 0) return { ok: false, summary: \"Reviewed target is not currently visible.\" };\n const overlay = document.createElement(\"div\");\n overlay.id = previewid;\n overlay.setAttribute(\"aria-hidden\", \"true\");\n Object.assign(overlay.style, { position: \"fixed\", left: `${Math.max(0, rect.left - 3)}px`, top: `${Math.max(0, rect.top - 3)}px`, width: `${rect.width + 6}px`, height: `${rect.height + 6}px`, border: \"3px solid #2f80ed\", borderRadius: \"6px\", boxShadow: \"0 0 0 3px rgba(47,128,237,.28)\", pointerEvents: \"none\", zIndex: \"2147483647\", boxSizing: \"border-box\" });\n document.documentElement.append(overlay);\n window.setTimeout(clearpreview, 5000);\n return { ok: true, summary: `Previewing ${label(target) || target.tagName.toLowerCase()} for five seconds.`, resolvedtarget: resolution.target };\n}\n\n/** Captures the complete semantic page context for a user-approved active tab, including the a11y, reader, listpattern and tableshape observation sections. */\nexport function capturesnapshot(): observation {\n const candidates = [...document.querySelectorAll(\"a[href], button, input, textarea, select, [role=button], [role=link], [role=combobox], [role=option], [role=checkbox], [role=radio], [role=switch], [role=tab], details, summary\")];\n const interactive = candidates.map(element => ({ selector: selector(element), role: element.getAttribute(\"role\") || element.tagName.toLowerCase(), label: label(element) })).filter(item => item.label || item.role);\n const forms = [...document.querySelectorAll(\"input, textarea, select\")].map(element => ({\n label: label(element),\n type: element.getAttribute(\"type\") || element.tagName.toLowerCase(),\n name: element.getAttribute(\"name\") || \"\",\n ...(element instanceof HTMLSelectElement ? { options: [...element.options].map(option => clean(option.textContent || option.value)) } : {}),\n }));\n const text = clean(document.body?.innerText || \"\");\n const tree = buildpagetree(document);\n const tables = collecttables(document).map(entry => {\n const shape = normalizetable(entry.rows, entry.caption);\n return { selector: entry.selector, headers: shape.headers, columns: shape.columns, rows: shape.rows, caption: shape.caption };\n });\n return {\n schemaversion: 3,\n url: location.href,\n title: clean(document.title),\n textpreview: text,\n textlength: document.body?.innerText.length ?? 0,\n forms,\n interactive,\n capturedat: Date.now(),\n mode: \"passive\",\n a11y: builda11ytree(tree),\n reader: buildreader(tree, clean(document.title)),\n listpattern: detectlistpatterns(collectsiblings(document)),\n tableshape: tables,\n };\n}\n\n/** Reads and clears the dialog log the main world handler recorded on the shared document. */\nexport function readdialogs(): observeddialog[] {\n return harvestdialoglog(document);\n}\n\n/** Extracts full, read-only structured content for a reviewed extraction step. */\nfunction extractcontent(targetselector: string | undefined, root: Document): stepresult {\n if (!targetselector) {\n const links = [...root.querySelectorAll(\"a[href]\")].map(element => {\n const href = element instanceof HTMLAnchorElement ? element.getAttribute(\"href\") ?? \"\" : \"\";\n return { text: element.textContent?.trim() ?? \"\", href };\n });\n return { ok: true, summary: `Extracted ${links.length} link entries.`, details: { links } };\n }\n const target = root.querySelector(targetselector);\n if (!target) return { ok: false, summary: \"Extraction target is no longer available.\" };\n const text = target.textContent ?? \"\";\n return { ok: true, summary: `Extracted ${text.length} characters of content.`, details: { text } };\n}\n\n/** Scrolls one reviewed target into view without reading or changing other page state. */\nfunction scrolltarget(target: HTMLElement): stepresult {\n target.scrollIntoView({ block: \"center\", inline: \"nearest\", behavior: \"auto\" });\n return { ok: true, summary: `Scrolled ${label(target) || target.tagName.toLowerCase()} into view.` };\n}\n\n/** Dispatches hover events on one reviewed target. */\nfunction hovertarget(target: HTMLElement): stepresult {\n for (const type of [\"pointerover\", \"mouseover\", \"pointerenter\"] as const) {\n target.dispatchEvent(new PointerEvent(type, { bubbles: type !== \"pointerenter\", cancelable: true, composed: true }));\n }\n target.dispatchEvent(new MouseEvent(\"mouseenter\", { bubbles: false, cancelable: true }));\n return { ok: true, summary: `Hover events delivered to ${label(target) || target.tagName.toLowerCase()}.` };\n}\n\n/** Selects one reviewed existing option; values outside the declared options are refused. */\nfunction selectoption(target: HTMLElement, value: string): stepresult {\n if (!(target instanceof HTMLSelectElement)) return { ok: false, summary: \"Target is not a select element.\" };\n const option = [...target.options].find(candidate => candidate.value === value || candidate.textContent?.trim() === value);\n if (!option) return { ok: false, summary: \"Reviewed option is not part of the select element.\" };\n target.value = option.value;\n target.dispatchEvent(new Event(\"input\", { bubbles: true }));\n target.dispatchEvent(new Event(\"change\", { bubbles: true }));\n return { ok: true, summary: `Selected ${clean(option.textContent || option.value)}.` };\n}\n\nconst readkinds: ReadonlySet<string> = new Set([\"readattribute\", \"readstyle\", \"readgeometry\", \"readvalue\", \"readtext\", \"readhtml\", \"countelements\", \"readtable\", \"readlinks\", \"readimages\", \"readmeta\", \"readforms\", \"readstorage\", \"waitfor\", \"waittext\", \"highlight\", \"mapclicks\", \"verifyvisible\", \"verifyenabled\", \"resolvexpath\"]);\nconst mutatingkinds: ReadonlySet<string> = new Set([\"presskey\", \"clickdeep\", \"rightclick\", \"doubleclick\", \"drag\", \"drop\", \"upload\", \"clear\", \"check\", \"uncheck\", \"toggle\", \"submit\", \"setattribute\", \"removeattribute\", \"writestorage\", \"evaluate\", \"fullscreen\"]);\nconst controlkinds: ReadonlySet<string> = new Set([\"typetime\", \"appendtext\", \"setvalue\", \"typeedit\", \"keyhold\", \"keyrelease\", \"submitsearch\", \"selectmulti\", \"chooseradio\", \"setslider\", \"setdate\", \"setcolor\", \"expanddetails\"]);\nconst interactkinds: ReadonlySet<string> = new Set([\"clicktext\", \"clickaria\", \"clickname\", \"pierceshadow\", \"enterframe\"]);\nconst pointerkinds: ReadonlySet<string> = new Set([\"movepointer\", \"clickpoint\", \"shiftclick\"]);\nconst observationkinds: ReadonlySet<string> = new Set([\"a11ytree\", \"readvisible\", \"readertree\", \"readoutline\", \"readselection\", \"readopengraph\", \"readlang\", \"detectlanguage\", \"listshadow\", \"listframes\"]);\nconst detectionkinds: ReadonlySet<string> = new Set([\"detectlists\", \"detecttables\", \"detectinfinitescroll\", \"detectvirtual\", \"detectlazy\", \"detectsticky\", \"detectscrolllock\", \"countpages\", \"classifypage\", \"fingerprintsection\", \"readscrollpos\"]);\nconst watchstepkinds: ReadonlySet<string> = new Set([\"watchmutate\", \"watchbanner\", \"watchfocus\", \"waitquiet\", \"readjson\", \"diffsnapshots\", \"deriveselector\"]);\nconst navstepkinds: ReadonlySet<string> = new Set([\"waitload\", \"waiturl\", \"followlink\", \"spanav\", \"spawait\", \"rewritequery\", \"setfragment\", \"stopnav\", \"prefetch\", \"preconnect\", \"printpdf\"]);\nconst formkinds: ReadonlySet<string> = new Set([\"fillform\", \"filllabel\", \"fillplaceholder\", \"detectfields\", \"generatevalues\", \"readerrors\", \"skiphoneypot\", \"detectlogin\", \"detecttemplate\", \"handoffcaptcha\", \"asksubmit\", \"submitform\", \"consentpassword\", \"attachfile\"]);\nconst wizardkinds: ReadonlySet<string> = new Set([\"runwizard\", \"selectchain\", \"picktypeahead\", \"pickdate\", \"fillcard\", \"fillcode\"]);\nconst datastepkinds: ReadonlySet<string> = new Set([\"scrapetable\", \"paginateextract\"]);\n\n/** Performs one local action after the background policy gate and a fresh target resolution. */\nexport async function performstep(step: toolstep, expectedorigin: string, rootdocument: Document = document): Promise<stepresult> {\n if (location.origin !== expectedorigin) return { ok: false, summary: \"Page origin changed before action.\" };\n if (step.kind === \"observe\") return { ok: true, summary: \"Observation completed.\" };\n if (step.kind === \"wait\") {\n const requested = step.value ? Number.parseInt(step.value, 10) : 250;\n const duration = Number.isFinite(requested) && requested > 0 ? requested : 0;\n return new Promise(resolve => window.setTimeout(() => resolve({ ok: true, summary: `Reviewed wait of ${duration} milliseconds completed.` }), duration));\n }\n if (step.kind === \"extract\") return extractcontent(step.target, rootdocument);\n if (step.kind === \"navigate\") {\n if (!step.value || new URL(step.value).origin !== expectedorigin) return { ok: false, summary: \"Navigation target is outside the approved origin.\" };\n location.assign(step.value);\n return { ok: true, summary: \"Navigation request sent.\" };\n }\n if (step.kind === \"reload\") { location.reload(); return { ok: true, summary: \"Page reload requested.\" }; }\n if (step.kind === \"back\") { history.back(); return { ok: true, summary: \"History back requested.\" }; }\n if (step.kind === \"forward\") { history.forward(); return { ok: true, summary: \"History forward requested.\" }; }\n if (navstepkinds.has(step.kind)) return await runpagenav(step, rootdocument);\n if (step.kind === \"writeclipboard\") {\n const text = step.value ?? \"\";\n await navigator.clipboard.writeText(text);\n return { ok: true, summary: `Wrote ${text.length} reviewed character${text.length === 1 ? \"\" : \"s\"} to the clipboard with payload hash ${checksum(text)}.`, details: { length: text.length, hash: checksum(text), destination: \"clipboard\" } };\n }\n if (step.kind === \"scrollpage\") {\n const options = stepoptions(step);\n window.scrollBy({ left: typeof options.x === \"number\" ? options.x : 0, top: typeof options.y === \"number\" ? options.y : 600, behavior: \"auto\" });\n return { ok: true, summary: \"Window scrolled by the reviewed amounts.\" };\n }\n if (step.kind === \"scrollend\") { window.scrollTo(0, document.documentElement.scrollHeight); return { ok: true, summary: \"Window scrolled to the page end.\" }; }\n if (step.kind === \"scrolltop\") { window.scrollTo(0, 0); return { ok: true, summary: \"Window scrolled to the page top.\" }; }\n const resolution = resolvestep(step, rootdocument);\n if (resolution.status === \"ambiguous\") {\n return { ok: false, summary: `The reviewed ${resolution.mode} reference matched ${resolution.candidates.length} elements: ${resolution.candidates.join(\"; \")}.`, details: { mode: resolution.mode, candidates: resolution.candidates } };\n }\n const element = resolution.status === \"resolved\" ? resolution.element : null;\n let result: stepresult | Promise<stepresult>;\n if (formkinds.has(step.kind)) result = runpageform(step, element, rootdocument);\n else if (wizardkinds.has(step.kind)) result = runpagewizard(step, element, rootdocument);\n else if (datastepkinds.has(step.kind)) result = runpagedata(step, element, rootdocument);\n else if (readkinds.has(step.kind)) result = runpageread(step, element, rootdocument);\n else if (controlkinds.has(step.kind)) result = runpagecontrol(step, element, rootdocument);\n else if (interactkinds.has(step.kind)) return await runinteractstep(step, expectedorigin, performstep);\n else if (pointerkinds.has(step.kind)) result = runpointerstep(step, resolution);\n else if (observationkinds.has(step.kind)) result = runpageobservation(step, element, rootdocument);\n else if (detectionkinds.has(step.kind)) result = runpagedetection(step, element, rootdocument);\n else if (watchstepkinds.has(step.kind)) result = runpagewatch(step, element, rootdocument);\n else if (mutatingkinds.has(step.kind)) result = runpageaction(step, element);\n else {\n if (!element) return { ok: false, summary: \"Action target is no longer available.\" };\n if (step.kind === \"scrollby\") {\n const options = stepoptions(step);\n element.scrollBy({ left: typeof options.x === \"number\" ? options.x : 0, top: typeof options.y === \"number\" ? options.y : 600, behavior: \"auto\" });\n result = { ok: true, summary: \"Container scrolled by the reviewed amounts.\" };\n } else if (step.kind === \"focus\") { element.focus(); result = { ok: true, summary: \"Target focused.\" }; }\n else if (step.kind === \"inspect\") result = { ok: true, summary: `Target: ${label(element) || element.tagName.toLowerCase()}.` };\n else if (step.kind === \"click\") { element.click(); result = { ok: true, summary: \"Reviewed click completed.\" }; }\n else if (step.kind === \"scroll\") result = scrolltarget(element);\n else if (step.kind === \"hover\") result = hovertarget(element);\n else if (step.kind === \"select\") result = selectoption(element, step.value ?? \"\");\n else if (step.kind === \"type\") {\n if (!(element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement)) return { ok: false, summary: \"Target cannot receive text.\" };\n if (typeof step.value !== \"string\") return { ok: false, summary: \"Approved text is absent.\" };\n element.focus();\n element.value = step.value;\n element.dispatchEvent(new Event(\"input\", { bubbles: true }));\n element.dispatchEvent(new Event(\"change\", { bubbles: true }));\n result = { ok: true, summary: \"Approved text entered.\" };\n } else return { ok: false, summary: \"Unsupported action.\" };\n }\n const output = await result;\n if (resolution.status === \"resolved\") {\n return { ...output, details: { ...(output.details ?? {}), mode: resolution.target.mode, resolvedtarget: resolution.target } };\n }\n return output;\n}\n\nObject.assign(globalThis, { devthinkbridge: { capturesnapshot, previewtarget, performstep, readdialogs } });\n"],
5
- "mappings": "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",
6
- "names": ["receiver", "owntext", "events", "modifiers", "keyevent", "fieldlike", "modifiers", "receiver", "wait", "poll", "wrap", "owntext", "stepoptions", "window", "events", "wait", "poll", "events", "wait", "pollfor", "entry", "wait", "stepoptions"]
4
+ "sourcesContent": ["import type { actionkind, agentplan, agentsession, captureexport, captureformat, capturenaming, captureoptions, cleanuprule, downloadspec, endpointconfig, fieldkind, formprofile, mimefilter, observationmode, policyevaluation, quarantineentry, regionrect, runsettings, safetyverdict, toolstep, transformrule } from \"./types.js\";\n\nconst sensitiveactions = new Set<actionkind>([\"click\", \"type\", \"navigate\", \"select\", \"presskey\", \"drag\", \"drop\", \"upload\", \"clear\", \"check\", \"uncheck\", \"toggle\", \"submit\", \"reload\", \"back\", \"forward\", \"writestorage\", \"setattribute\", \"removeattribute\", \"evaluate\", \"tabcreate\", \"tabactivate\", \"tabclose\", \"tabreload\", \"windowcreate\", \"windowclose\", \"windowresize\", \"downloadfile\", \"clickpoint\", \"shiftclick\", \"dismissdialog\", \"enterframe\", \"typetime\", \"appendtext\", \"setvalue\", \"typeedit\", \"keyhold\", \"keyrelease\", \"submitsearch\", \"selectmulti\", \"chooseradio\", \"setslider\", \"setdate\", \"setcolor\", \"openlink\", \"openprivate\", \"reloadcache\", \"stopnav\", \"followlink\", \"spanav\", \"rewritequery\", \"setfragment\", \"navlist\", \"navprofile\", \"handleauth\", \"printpdf\", \"prefetch\", \"preconnect\", \"deeplink\", \"reopentab\", \"pausenav\", \"navrate\", \"openclipboard\", \"batchopen\", \"duplicatetab\", \"closepattern\", \"pintab\", \"mutetab\", \"movetab\", \"movetabwindow\", \"grouptabs\", \"colorgroup\", \"collapsegroup\", \"discardtab\", \"reloadtabs\", \"zoomin\", \"zoomout\", \"switchtab\", \"maximizewindow\", \"minimizewindow\", \"restorewindow\", \"focuswindow\", \"scratchwindow\", \"incognitowindow\", \"restoretab\", \"restorelayout\", \"reopenrun\", \"badgetab\", \"fillform\", \"filllabel\", \"fillplaceholder\", \"submitform\", \"retryform\", \"runwizard\", \"selectchain\", \"picktypeahead\", \"pickdate\", \"attachfile\", \"fillcard\", \"fillcode\", \"consentpassword\", \"exportcsv\", \"exportjson\", \"exportexcel\", \"copytable\", \"pushsheets\", \"streamdisk\", \"paginateextract\", \"resumeextract\", \"batchdownload\", \"pausedownload\", \"resumedownload\", \"interceptmime\", \"readclipboard\", \"writeclipboard\", \"copyscreen\", \"quarantinedownload\", \"scanvirus\", \"cleanupartifacts\", \"recordscreen\", \"captureaudio\", \"downloadimages\"]);\nconst interactionactions = new Set<actionkind>([\"focus\", \"scroll\", \"hover\", \"clickdeep\", \"rightclick\", \"doubleclick\", \"scrollpage\", \"scrollby\", \"scrollend\", \"scrolltop\", \"fullscreen\", \"zoomset\", \"movepointer\", \"clicktext\", \"clickaria\", \"clickname\", \"expanddetails\", \"pierceshadow\", \"retryaction\"]);\nconst readactions = new Set<actionkind>([\"observe\", \"inspect\", \"extract\", \"wait\", \"waitfor\", \"waittext\", \"readattribute\", \"readstyle\", \"readgeometry\", \"readvalue\", \"readtext\", \"readhtml\", \"countelements\", \"readtable\", \"readlinks\", \"readimages\", \"readmeta\", \"readforms\", \"readstorage\", \"highlight\", \"tablist\", \"windowlist\", \"tabsnapshot\", \"mapclicks\", \"verifyvisible\", \"verifyenabled\", \"resolvexpath\", \"a11ytree\", \"readvisible\", \"readertree\", \"detectlists\", \"detecttables\", \"readjson\", \"watchmutate\", \"waitquiet\", \"watchbanner\", \"detectinfinitescroll\", \"detectvirtual\", \"detectlazy\", \"readscrollpos\", \"readlang\", \"readoutline\", \"countpages\", \"listshadow\", \"listframes\", \"classifypage\", \"fingerprintsection\", \"diffsnapshots\", \"readselection\", \"watchfocus\", \"detectsticky\", \"detectscrolllock\", \"readopengraph\", \"detectlanguage\", \"deriveselector\", \"waitload\", \"waiturl\", \"spawait\", \"detecthttp\", \"readredirects\", \"readfinalurl\", \"trailaudit\", \"navintent\", \"checksafe\", \"querytabs\", \"watchtab\", \"findclones\", \"searchtabs\", \"listaudio\", \"snapshotsession\", \"savelayout\", \"attachmeta\", \"detectfields\", \"generatevalues\", \"saveprofiles\", \"asksubmit\", \"readerrors\", \"skiphoneypot\", \"detectlogin\", \"detecttemplate\", \"handoffcaptcha\", \"scrapetable\", \"importcsv\", \"looprows\", \"transformvalues\", \"deduperows\", \"mergepages\", \"stamplerows\", \"previewgrid\", \"logprovenance\", \"verifydownload\", \"exportnetlog\", \"namecaptures\", \"shotview\", \"shotfullpage\", \"shotelement\", \"shotregion\", \"contactsheet\", \"capturepdf\", \"captureframe\", \"readmedia\", \"readassets\", \"probestream\", \"timelapse\", \"shotcanvas\", \"convertimage\", \"makethumbs\"]);\nconst allowedactions = new Set<actionkind>([...sensitiveactions, ...interactionactions, ...readactions]);\nconst watchactions = new Set<actionkind>([\"watchmutate\", \"watchbanner\", \"watchfocus\", \"watchtab\"]);\nconst targetactions = new Set<actionkind>([\"inspect\", \"focus\", \"click\", \"type\", \"scroll\", \"select\", \"hover\", \"clickdeep\", \"rightclick\", \"doubleclick\", \"drag\", \"drop\", \"upload\", \"clear\", \"check\", \"uncheck\", \"toggle\", \"submit\", \"readattribute\", \"readstyle\", \"readgeometry\", \"readvalue\", \"readtext\", \"readhtml\", \"countelements\", \"readtable\", \"highlight\", \"setattribute\", \"removeattribute\", \"waitfor\", \"shiftclick\", \"typetime\", \"appendtext\", \"setvalue\", \"typeedit\", \"submitsearch\", \"selectmulti\", \"chooseradio\", \"setslider\", \"setdate\", \"setcolor\", \"expanddetails\", \"verifyvisible\", \"verifyenabled\", \"pierceshadow\", \"deriveselector\", \"fingerprintsection\", \"submitform\", \"retryform\", \"selectchain\", \"picktypeahead\", \"pickdate\", \"attachfile\", \"fillcode\", \"consentpassword\", \"scrapetable\", \"paginateextract\", \"shotelement\", \"captureframe\", \"shotcanvas\"]);\nconst valueactions = new Set<actionkind>([\"presskey\", \"drag\", \"drop\", \"upload\", \"readattribute\", \"removeattribute\", \"waittext\", \"evaluate\", \"zoomset\", \"tabactivate\", \"tabclose\", \"tabreload\", \"windowclose\", \"windowresize\", \"tabcreate\", \"windowcreate\", \"downloadfile\", \"typetime\", \"appendtext\", \"setvalue\", \"typeedit\", \"keyhold\", \"keyrelease\", \"chooseradio\", \"setslider\", \"setdate\", \"setcolor\", \"followlink\", \"setfragment\", \"handleauth\", \"navintent\", \"openclipboard\", \"checksafe\", \"reopentab\", \"spanav\", \"duplicatetab\", \"pintab\", \"mutetab\", \"movetab\", \"movetabwindow\", \"searchtabs\", \"badgetab\", \"attachmeta\", \"focuswindow\", \"maximizewindow\", \"minimizewindow\", \"restorewindow\", \"incognitowindow\", \"asksubmit\", \"selectchain\", \"picktypeahead\", \"pickdate\", \"attachfile\", \"fillcode\", \"consentpassword\", \"pausedownload\", \"resumedownload\", \"verifydownload\", \"writeclipboard\", \"quarantinedownload\", \"scanvirus\"]);\nconst tabscommandactions = new Set<actionkind>([\"querytabs\", \"duplicatetab\", \"closepattern\", \"pintab\", \"mutetab\", \"movetab\", \"movetabwindow\", \"grouptabs\", \"colorgroup\", \"collapsegroup\", \"discardtab\", \"reloadtabs\", \"zoomin\", \"zoomout\", \"watchtab\", \"switchtab\", \"maximizewindow\", \"minimizewindow\", \"restorewindow\", \"focuswindow\", \"scratchwindow\", \"incognitowindow\", \"restoretab\", \"savelayout\", \"restorelayout\", \"findclones\", \"searchtabs\", \"badgetab\", \"attachmeta\", \"listaudio\", \"reopenrun\", \"snapshotsession\"]);\nconst formactions = new Set<actionkind>([\"fillform\", \"filllabel\", \"fillplaceholder\", \"detectfields\", \"generatevalues\", \"saveprofiles\", \"asksubmit\", \"submitform\", \"readerrors\", \"retryform\", \"runwizard\", \"selectchain\", \"picktypeahead\", \"pickdate\", \"attachfile\", \"handoffcaptcha\", \"fillcard\", \"fillcode\", \"consentpassword\", \"skiphoneypot\", \"detectlogin\", \"detecttemplate\"]);\n/** Extraction, transform, export and provenance kinds of the forms and data part two family. */\nconst datasetactions = new Set<actionkind>([\"scrapetable\", \"exportcsv\", \"exportjson\", \"exportexcel\", \"copytable\", \"pushsheets\", \"importcsv\", \"looprows\", \"transformvalues\", \"deduperows\", \"paginateextract\", \"mergepages\", \"stamplerows\", \"previewgrid\", \"streamdisk\", \"resumeextract\", \"logprovenance\"]);\n/** Export kinds that move extracted data out of local memory to disk, the clipboard or a reviewed sheet endpoint. */\nconst exportactions = new Set<actionkind>([\"exportcsv\", \"exportjson\", \"exportexcel\", \"copytable\", \"pushsheets\", \"streamdisk\"]);\n/** Files, clipboard and downloads kinds of the batch queue, interception, clipboard, quarantine, naming and cleanup family. */\nconst filesactions = new Set<actionkind>([\"batchdownload\", \"pausedownload\", \"resumedownload\", \"verifydownload\", \"interceptmime\", \"exportnetlog\", \"readclipboard\", \"writeclipboard\", \"copyscreen\", \"quarantinedownload\", \"scanvirus\", \"namecaptures\", \"cleanupartifacts\"]);\nconst captureactions = new Set<actionkind>([\"shotview\", \"shotfullpage\", \"shotelement\", \"shotregion\", \"contactsheet\"]);\n/** Media capture part two kinds of the pdf, recording, image, canvas, stream, asset, lapse, conversion and thumbnail family. */\nconst mediaactions = new Set<actionkind>([\"capturepdf\", \"recordscreen\", \"captureaudio\", \"captureframe\", \"downloadimages\", \"shotcanvas\", \"probestream\", \"readmedia\", \"readassets\", \"timelapse\", \"convertimage\", \"makethumbs\"]);\n/** Field kinds the form grammar accepts inside records, profiles and value rules. */\nconst fieldkinds: fieldkind[] = [\"text\", \"email\", \"phone\", \"date\", \"number\", \"select\", \"check\", \"radio\", \"file\", \"password\", \"card\", \"code\"];\nconst layoutmutationactions = new Set<actionkind>([\"grouptabs\", \"colorgroup\", \"collapsegroup\", \"savelayout\", \"restorelayout\"]);\n/** Chromium tab group colors accepted as reviewed group color choices. */\nconst groupcolors = [\"grey\", \"blue\", \"red\", \"yellow\", \"green\", \"pink\", \"purple\", \"cyan\", \"orange\"];\n\n/** Normalizes a user supplied HTTPS endpoint without preserving a provider lock-in. */\nexport function normalizeendpoint(value: string): endpointconfig {\n const endpoint = new URL(value.trim());\n if (endpoint.protocol !== \"https:\") throw new Error(\"Devthink accepts HTTPS endpoints only.\");\n if (endpoint.username || endpoint.password) throw new Error(\"Endpoint credentials are not allowed in the URL.\");\n return { endpoint: endpoint.toString(), origin: endpoint.origin, configuredat: Date.now() };\n}\n\n/** Creates the exact optional host pattern requested from Chromium. */\nexport function hostpattern(origin: string): string {\n const parsed = new URL(origin);\n if (parsed.protocol !== \"https:\") throw new Error(\"Only HTTPS origins can be granted.\");\n return `${parsed.origin}/*`;\n}\n\n/** True when the action kind observes the page over a reviewed lifetime window. */\nexport function iswatchkind(kind: actionkind): boolean {\n return watchactions.has(kind);\n}\n\n/** Grades the observation mode of a kind: passive capture, watched lifetimes or diffing passes. */\nexport function observationmodeof(kind: actionkind): observationmode {\n if (watchactions.has(kind) || kind === \"waitquiet\") return \"watching\";\n if (kind === \"diffsnapshots\") return \"diffing\";\n return \"passive\";\n}\n\n/** Defines action risk from the fixed local allowlist. */\nexport function actionrisk(kind: actionkind): \"read\" | \"interaction\" | \"sensitive\" {\n if (!allowedactions.has(kind)) throw new Error(\"Unsupported browser action.\");\n if (sensitiveactions.has(kind)) return \"sensitive\";\n return interactionactions.has(kind) ? \"interaction\" : \"read\";\n}\n\n/** True when the action kind accepts a css selector target or a reviewed targetref. */\nexport function needstarget(kind: actionkind): boolean {\n return targetactions.has(kind);\n}\n\n/** Parses the reviewed JSON options of a step; malformed payloads are rejected early. */\nexport function parseoptions(step: toolstep): Record<string, unknown> {\n if (step.options === undefined) return {};\n let parsed: unknown;\n try { parsed = JSON.parse(step.options); } catch { throw new Error(\"Step options must be a JSON object.\"); }\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) throw new Error(\"Step options must be a JSON object.\");\n return parsed as Record<string, unknown>;\n}\n\n/** Maps an action kind to the optional browser permission it requires, if any. */\nexport function requiredcapability(kind: actionkind): string | undefined {\n if (kind === \"tablist\") return \"tabs\";\n if (kind === \"downloadfile\") return \"downloads\";\n if (kind === \"openclipboard\") return \"clipboardRead\";\n if (kind === \"copytable\") return \"clipboardWrite\";\n if (kind === \"batchdownload\" || kind === \"pausedownload\" || kind === \"resumedownload\" || kind === \"verifydownload\" || kind === \"interceptmime\" || kind === \"quarantinedownload\" || kind === \"scanvirus\") return \"downloads\";\n if (kind === \"readclipboard\") return \"clipboardRead\";\n if (kind === \"writeclipboard\" || kind === \"copyscreen\") return \"clipboardWrite\";\n if (kind === \"downloadimages\") return \"downloads\";\n if (kind === \"openlink\" || kind === \"openprivate\" || kind === \"navlist\" || kind === \"batchopen\" || kind === \"reopentab\" || kind === \"deeplink\") return \"tabs\";\n if (tabscommandactions.has(kind)) return \"tabs\";\n return undefined;\n}\n\n/** True when the kind commands tabs or windows beyond the active tab and needs the optional tabs capability. */\nexport function istabscommandkind(kind: actionkind): boolean {\n return tabscommandactions.has(kind);\n}\n\n/** True when the kind mutates tab groups or layouts and therefore stays inside the active session. */\nexport function islayoutkind(kind: actionkind): boolean {\n return layoutmutationactions.has(kind);\n}\n\n/** True when the kind belongs to the forms and data family. */\nexport function isformkind(kind: actionkind): boolean {\n return formactions.has(kind);\n}\n\n/** True when the kind belongs to the extraction, transform, export and provenance family. */\nexport function isdatasetkind(kind: actionkind): boolean {\n return datasetactions.has(kind);\n}\n\n/** True when the kind exports extracted data out of local memory to disk, the clipboard or a reviewed sheet endpoint. */\nexport function isexportkind(kind: actionkind): boolean {\n return exportactions.has(kind);\n}\n\n/** True when the kind belongs to the files, clipboard and downloads family. */\nexport function isfileskind(kind: actionkind): boolean {\n return filesactions.has(kind);\n}\n\n/** True when the kind belongs to the media capture family of viewport, full page, element, region and contact sheet shots. */\nexport function iscapturekind(kind: actionkind): boolean {\n return captureactions.has(kind);\n}\n\n/** Requires the active tab grant of the live session before any capture kind runs: the session tab and origin must match and the origin grant must cover the active origin. */\nexport function capturegate(session: agentsession | undefined, tabid: number, origin: string, now: number): policyevaluation {\n if (!session || session.stoppedat) return { allowed: false, reason: \"No active browser session exists for the capture.\" };\n if (session.expiresat <= now) return { allowed: false, reason: \"The browser session has expired and cannot capture.\" };\n if (session.pausedat) return { allowed: false, reason: \"The browser session is paused and cannot capture.\" };\n if (session.tabid !== tabid) return { allowed: false, reason: `The capture needs the active tab grant of session tab ${session.tabid} and refuses tab ${tabid}.` };\n if (!origingranted(session, origin)) return { allowed: false, reason: `The capture of ${origin} needs the session origin grants first.` };\n return { allowed: true };\n}\n\n/** Validates one reviewed capture options payload: format inside the png, jpeg and webp set, quality bounded only by the format range, pixel ratio from one up with no code ceiling, and a known export target. */\nexport function validatecaptureoptions(value: unknown): policyevaluation {\n if (value === undefined) return { allowed: true };\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"The reviewed capture options must be an object in options.capture.\" };\n const options = value as Record<string, unknown>;\n if (options.format !== undefined && options.format !== \"png\" && options.format !== \"jpeg\" && options.format !== \"webp\") return { allowed: false, reason: \"The reviewed capture format must be png, jpeg or webp.\" };\n if (options.quality !== undefined && (typeof options.quality !== \"number\" || !Number.isFinite(options.quality) || options.quality < 0 || options.quality > 100)) return { allowed: false, reason: \"The reviewed capture quality must stay between zero and one hundred; any value in that range is the user choice with no code cap.\" };\n if (options.pixelratio !== undefined && (typeof options.pixelratio !== \"number\" || !Number.isFinite(options.pixelratio) || options.pixelratio < 1)) return { allowed: false, reason: \"The reviewed pixel ratio starts at one and climbs to any user configured ceiling with no code ceiling.\" };\n if (options.annotate !== undefined && typeof options.annotate !== \"boolean\") return { allowed: false, reason: \"The reviewed capture annotation flag must be a boolean.\" };\n if (options.exporttarget !== undefined && options.exporttarget !== \"memory\" && options.exporttarget !== \"download\" && options.exporttarget !== \"clipboard\") return { allowed: false, reason: \"The reviewed capture export target must be memory, download or clipboard.\" };\n return { allowed: true };\n}\n\n/** Validates one reviewed region rectangle in css pixels; negative coordinates and non positive sizes are refused. */\nexport function validateregionrect(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed regionrect with x, y, width and height in css pixels is required in options.\" };\n const rect = value as Record<string, unknown>;\n for (const field of [\"x\", \"y\", \"width\", \"height\"]) {\n if (typeof rect[field] !== \"number\" || !Number.isFinite(rect[field] as number)) return { allowed: false, reason: `The reviewed regionrect needs a numeric ${field} in css pixels.` };\n }\n if ((rect.x as number) < 0 || (rect.y as number) < 0) return { allowed: false, reason: \"The reviewed regionrect refuses negative coordinates.\" };\n if ((rect.width as number) <= 0 || (rect.height as number) <= 0) return { allowed: false, reason: \"The reviewed regionrect needs positive width and height values.\" };\n return { allowed: true };\n}\n\n/** Validates one reviewed capture naming rule against the allowed segment set: run, step, sequence and kind flags only. */\nexport function validatecapturenaming(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed capturenaming rule with run, step, sequence and kind flags is required.\" };\n const rule = value as Record<string, unknown>;\n const segments = [\"run\", \"step\", \"sequence\", \"kind\"];\n for (const key of Object.keys(rule)) {\n if (!segments.includes(key)) return { allowed: false, reason: `The reviewed capturenaming rule refuses the unknown ${key} segment; only run, step, sequence and kind participate.` };\n }\n for (const segment of segments) {\n if (rule[segment] !== undefined && typeof rule[segment] !== \"boolean\") return { allowed: false, reason: `The reviewed capturenaming ${segment} flag must be a boolean.` };\n }\n if (!segments.some(segment => rule[segment] === true)) return { allowed: false, reason: \"The reviewed capturenaming rule needs at least one enabled segment of run, step, sequence and kind.\" };\n return { allowed: true };\n}\n\n/** Routes the capture export target: memory stays local, clipboard needs the clipboardwrite grant and disk writes only run through the reviewed download flow. */\nexport function captureexportgranted(target: captureexport | undefined): policyevaluation {\n if (target === undefined || target === \"memory\") return { allowed: true };\n if (target === \"clipboard\") return { allowed: true, reason: \"The clipboard capture export runs behind the optional clipboardwrite capability, negotiated through the permissions api before the copy.\" };\n if (target === \"download\") return { allowed: true, reason: \"The download capture export runs only through the reviewed download flow behind the optional downloads capability.\" };\n return { allowed: false, reason: \"The capture export target must be memory, download or clipboard; no other disk route exists.\" };\n}\n\n/** Keeps the stitching scroll budget inside the reviewed wait window: the settle windows of every tile must fit the reviewed wait window with no code ceiling on either side. */\nexport function stitchbudgetallowed(tiles: number, settle: number, wait: number): policyevaluation {\n if (tiles <= 0) return { allowed: false, reason: \"The stitch budget needs at least one tile.\" };\n if (settle < 0 || wait < 0) return { allowed: false, reason: \"The reviewed settle and wait windows must be zero or positive milliseconds.\" };\n if (tiles * settle > wait) return { allowed: false, reason: `The stitching scroll budget of ${tiles} tiles at ${settle} milliseconds exceeds the reviewed wait window of ${wait} milliseconds; review a wider window or a smaller settle.` };\n return { allowed: true };\n}\n\n/** Allows beforeafter state capture to wrap any existing action kind except the capture kinds themselves; pixel evidence around sensitive actions grades as reviewable evidence. */\nexport function beforeafterwrapallowed(kind: actionkind): boolean {\n return allowedactions.has(kind) && !captureactions.has(kind);\n}\n\n/** Exposes the capture retention window as a user configured choice; an absent value keeps every capture byte forever with no code ceiling. */\nexport function captureretentionwindow(settings: runsettings | undefined): number | undefined {\n return settings?.captureretention;\n}\n\n/** Validates the reviewed media capture parameter grammar; pixel ratios, quality values, cell counts and retention windows stay user choices with no code ceilings. */\nfunction validatecapturegrammar(step: toolstep, options: Record<string, unknown>): policyevaluation {\n const kind = step.kind;\n const optioncheck = validatecaptureoptions(options.capture);\n if (!optioncheck.allowed) return optioncheck;\n if (options.settle !== undefined && (typeof options.settle !== \"number\" || !Number.isFinite(options.settle) || options.settle < 0)) return { allowed: false, reason: \"The reviewed capture settle window must be zero or a positive number of milliseconds.\" };\n if (options.overlap !== undefined && (typeof options.overlap !== \"number\" || !Number.isInteger(options.overlap) || options.overlap < 0)) return { allowed: false, reason: \"The reviewed stitch overlap must be zero or a positive number of rows.\" };\n if (options.wait !== undefined && (typeof options.wait !== \"number\" || !Number.isFinite(options.wait) || options.wait < 0)) return { allowed: false, reason: \"The reviewed capture wait window must be zero or a positive number of milliseconds.\" };\n if (options.naming !== undefined) {\n const namingcheck = validatecapturenaming(options.naming);\n if (!namingcheck.allowed) return namingcheck;\n }\n if (kind === \"shotregion\") {\n const rectcheck = validateregionrect(options.regionrect);\n if (!rectcheck.allowed) return rectcheck;\n if (options.reviewed !== true) return { allowed: false, reason: \"Every reviewed regionrect needs the explicit reviewed flag before shotregion runs.\" };\n if (options.container !== undefined && !isnonempty(options.container)) return { allowed: false, reason: \"The reviewed scrollable container selector must be a non-empty string.\" };\n if (options.steps !== undefined && (typeof options.steps !== \"number\" || !Number.isInteger(options.steps) || options.steps < 1)) return { allowed: false, reason: \"The reviewed container scroll steps must be a positive integer with no code ceiling.\" };\n }\n if (kind === \"contactsheet\") {\n const elements = options.elements;\n if (!Array.isArray(elements) || elements.length === 0 || !elements.every(item => isnonempty(item))) return { allowed: false, reason: \"A reviewed non-empty list of element selectors is required in options for the contact sheet; the cell count stays the user choice.\" };\n const layout = options.sheet;\n if (layout !== undefined) {\n if (!layout || typeof layout !== \"object\" || Array.isArray(layout)) return { allowed: false, reason: \"The reviewed sheetlayout must be an object with cellsize, columns and label.\" };\n const sheet = layout as Record<string, unknown>;\n if (typeof sheet.cellsize !== \"number\" || !Number.isFinite(sheet.cellsize) || sheet.cellsize <= 0) return { allowed: false, reason: \"The reviewed contact sheet cell size must be a positive number of pixels.\" };\n if (typeof sheet.columns !== \"number\" || !Number.isInteger(sheet.columns) || sheet.columns < 1) return { allowed: false, reason: \"The reviewed contact sheet column count must be a positive integer with no code ceiling.\" };\n if (sheet.label !== undefined && sheet.label !== \"none\" && sheet.label !== \"index\" && sheet.label !== \"selector\" && sheet.label !== \"both\") return { allowed: false, reason: \"The reviewed contact sheet label style must be none, index, selector or both.\" };\n }\n }\n return { allowed: true };\n}\n\n/** Refuses any export that would leave local memory while the session origin grants do not cover the active origin. */\nexport function exportgranted(session: agentsession | undefined, origin: string): policyevaluation {\n if (!origingranted(session, origin)) return { allowed: false, reason: `The export of extracted data from ${origin} needs the session origin grants before it leaves local memory.` };\n return { allowed: true };\n}\n\n/** Validates the reviewed fieldmatch grammar of one form field entry. */\nexport function validatefieldmatch(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed field match is required in options.\" };\n const match = value as Record<string, unknown>;\n if (match.mode !== \"label\" && match.mode !== \"placeholder\" && match.mode !== \"arialabel\" && match.mode !== \"name\") return { allowed: false, reason: \"The reviewed field match mode must be label, placeholder, arialabel or name.\" };\n const key = match.mode === \"label\" ? \"label\" : match.mode === \"placeholder\" ? \"placeholder\" : match.mode === \"arialabel\" ? \"arialabel\" : \"name\";\n if (!isnonempty(match[key])) return { allowed: false, reason: `The reviewed ${match.mode} field match needs a non-empty ${key}.` };\n return { allowed: true };\n}\n\n/** Validates a reviewed structured form record; password entries are refused because passwords need the explicit consentpassword consent. */\nexport function validateformrecord(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed form record with entries is required in options.\" };\n const record = value as Record<string, unknown>;\n if (record.form !== undefined && !isnonempty(record.form)) return { allowed: false, reason: \"The reviewed form record form selector must be a non-empty string.\" };\n if (!Array.isArray(record.entries) || record.entries.length === 0) return { allowed: false, reason: \"The reviewed form record needs a non-empty list of entries.\" };\n for (const item of record.entries) {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) return { allowed: false, reason: \"Every reviewed form record entry must be an object.\" };\n const entry = item as Record<string, unknown>;\n const matchcheck = validatefieldmatch(entry.match);\n if (!matchcheck.allowed) return matchcheck;\n if (typeof entry.kind !== \"string\" || !fieldkinds.includes(entry.kind as fieldkind)) return { allowed: false, reason: \"Every reviewed form record entry needs a known field kind.\" };\n if (typeof entry.value !== \"string\") return { allowed: false, reason: \"Every reviewed form record entry needs a string value.\" };\n if (entry.kind === \"password\") return { allowed: false, reason: \"Password entries are refused inside form records; use consentpassword with a reviewed consent ref.\" };\n }\n return { allowed: true };\n}\n\n/** Validates the reviewed valuegen grammar of a generatevalues step. */\nexport function validatevaluegen(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed valuegen rule with a field kind is required in options.\" };\n const rule = value as Record<string, unknown>;\n if (typeof rule.kind !== \"string\" || !fieldkinds.includes(rule.kind as fieldkind)) return { allowed: false, reason: \"The reviewed valuegen kind must be a known field kind.\" };\n if (rule.locale !== undefined && !isnonempty(rule.locale)) return { allowed: false, reason: \"The reviewed valuegen locale must be a non-empty string.\" };\n if (rule.seed !== undefined && (typeof rule.seed !== \"number\" || !Number.isFinite(rule.seed))) return { allowed: false, reason: \"The reviewed valuegen seed must be a finite number.\" };\n return { allowed: true };\n}\n\n/** Validates a reviewed list of label or placeholder value pairs for filllabel and fillplaceholder steps. */\nfunction validatefieldpairs(options: Record<string, unknown>, mode: \"label\" | \"placeholder\"): policyevaluation {\n const pairs = options.fields;\n if (!Array.isArray(pairs) || pairs.length === 0) return { allowed: false, reason: \"A reviewed non-empty list of field pairs is required in options.\" };\n for (const item of pairs) {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) return { allowed: false, reason: \"Every reviewed field pair must be an object.\" };\n const pair = item as Record<string, unknown>;\n if (!isnonempty(pair[mode])) return { allowed: false, reason: `Every reviewed field pair needs a non-empty ${mode}.` };\n if (typeof pair.value !== \"string\" || !pair.value.trim()) return { allowed: false, reason: \"Every reviewed field pair needs a non-empty value.\" };\n }\n return { allowed: true };\n}\n\n/** Validates the reviewed card segment grammar of a fillcard step. */\nfunction validatecardsegments(value: unknown): policyevaluation {\n if (!Array.isArray(value) || value.length === 0) return { allowed: false, reason: \"A reviewed non-empty list of card segments is required in options.\" };\n for (const item of value) {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) return { allowed: false, reason: \"Every reviewed card segment must be an object.\" };\n const segment = item as Record<string, unknown>;\n const matchcheck = validatefieldmatch(segment.match);\n if (!matchcheck.allowed) return matchcheck;\n if (typeof segment.value !== \"string\" || !segment.value.trim()) return { allowed: false, reason: \"Every reviewed card segment needs a non-empty value.\" };\n }\n return { allowed: true };\n}\n\n/** Validates the reviewed forms and data parameter grammar of the form family. */\nfunction validateformgrammar(step: toolstep, options: Record<string, unknown>): policyevaluation {\n const kind = step.kind;\n if (kind === \"fillform\" || (kind === \"saveprofiles\" && options.formrecord !== undefined)) {\n const recordcheck = validateformrecord(options.formrecord);\n if (!recordcheck.allowed) return recordcheck;\n }\n if (kind === \"filllabel\" || kind === \"fillplaceholder\") {\n const paircheck = validatefieldpairs(options, kind === \"filllabel\" ? \"label\" : \"placeholder\");\n if (!paircheck.allowed) return paircheck;\n }\n if (kind === \"generatevalues\" && options.valuegen !== undefined) {\n const rulecheck = validatevaluegen(options.valuegen);\n if (!rulecheck.allowed) return rulecheck;\n }\n if (kind === \"saveprofiles\" && !isnonempty(options.name)) return { allowed: false, reason: \"A reviewed profile name is required in options.\" };\n if (kind === \"submitform\" && !isnonempty(options.consentref)) return { allowed: false, reason: \"A reviewed consent ref of an approved asksubmit ticket is required in options.\" };\n if (kind === \"retryform\") {\n const backoff = options.backoff;\n if (!backoff || typeof backoff !== \"object\" || Array.isArray(backoff)) return { allowed: false, reason: \"A reviewed backoff rule with wait and factor is required in options.\" };\n const rule = backoff as Record<string, unknown>;\n if (typeof rule.wait !== \"number\" || !Number.isFinite(rule.wait) || rule.wait <= 0) return { allowed: false, reason: \"The reviewed retry backoff wait must be a positive number of milliseconds with no code ceiling.\" };\n if (typeof rule.factor !== \"number\" || !Number.isFinite(rule.factor) || rule.factor < 1) return { allowed: false, reason: \"The reviewed retry backoff factor must be one or greater with no code ceiling.\" };\n if (options.attempts !== undefined && (typeof options.attempts !== \"number\" || !Number.isInteger(options.attempts) || options.attempts < 1)) return { allowed: false, reason: \"The reviewed retry attempts must be a positive integer with no code ceiling.\" };\n }\n if (kind === \"runwizard\" && options.steps !== undefined && (typeof options.steps !== \"number\" || !Number.isInteger(options.steps) || options.steps < 1)) return { allowed: false, reason: \"The reviewed wizard step count must be a positive integer with no code ceiling.\" };\n if (kind === \"selectchain\") {\n if (!isnonempty(options.child)) return { allowed: false, reason: \"A reviewed child selector of the dependent control is required in options.\" };\n if (!nonnegativeoption(options, \"wait\")) return { allowed: false, reason: \"The reviewed dependent wait must be zero or a positive number of milliseconds.\" };\n }\n if (kind === \"picktypeahead\") {\n if (!isnonempty(options.pick)) return { allowed: false, reason: \"A reviewed suggestion entry to pick is required in options.\" };\n if (!nonnegativeoption(options, \"timeout\")) return { allowed: false, reason: \"The reviewed typeahead timeout must be zero or a positive number of milliseconds.\" };\n }\n if (kind === \"pickdate\" && !/^\\d{4}-\\d{2}-\\d{2}$/.test(step.value ?? \"\")) return { allowed: false, reason: \"The reviewed date must use the yyyy-mm-dd form.\" };\n if (kind === \"fillcard\") {\n const segmentcheck = validatecardsegments(options.segments);\n if (!segmentcheck.allowed) return segmentcheck;\n if (!nonnegativeoption(options, \"pause\")) return { allowed: false, reason: \"The reviewed card typing pause must be zero or a positive number of milliseconds.\" };\n }\n if (kind === \"fillcode\" && !isnonempty(options.source)) return { allowed: false, reason: \"A reviewed one time code source is required in options.\" };\n if (kind === \"consentpassword\" && !isnonempty(options.consentref)) return { allowed: false, reason: \"A reviewed consent ref is required in options before any password is filled.\" };\n return { allowed: true };\n}\n\n/** Validates one reviewed transform rule: a supported expression, source columns and a target column. */\nexport function validatetransformrule(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed transform rule with an expression, sources and a target is required in options.\" };\n const rule = value as Record<string, unknown>;\n const expression = rule.expression;\n if (typeof expression !== \"string\" || !/^(trim|upper|lower|number|prefix|suffix|replace)(?::.+)?$/.test(expression)) return { allowed: false, reason: \"The reviewed transform expression must be trim, upper, lower, number, prefix, suffix or replace with an optional argument.\" };\n if (expression.startsWith(\"replace\") && !expression.slice(\"replace\".length).includes(\"=>\")) return { allowed: false, reason: \"The reviewed replace expression needs the from=>to separator.\" };\n if (expression.startsWith(\"replace\") && expression.slice(\"replace:\".length).split(\"=>\")[0] === \"\") return { allowed: false, reason: \"The reviewed replace expression needs a non-empty from part.\" };\n if (!Array.isArray(rule.sources) || rule.sources.length === 0 || !rule.sources.every(source => isnonempty(source))) return { allowed: false, reason: \"Every reviewed transform rule needs a non-empty list of source columns.\" };\n if (!isnonempty(rule.target)) return { allowed: false, reason: \"Every reviewed transform rule needs a non-empty target column.\" };\n return { allowed: true };\n}\n\n/** Validates a reviewed dataset id list in options. */\nfunction validatedatasetids(options: Record<string, unknown>, key: string): policyevaluation {\n const ids = options[key];\n if (!Array.isArray(ids) || ids.length === 0 || !ids.every(id => isnonempty(id))) return { allowed: false, reason: `A reviewed non-empty list of dataset ids is required in options as ${key}.` };\n return { allowed: true };\n}\n\n/** Validates the reviewed extraction, transform, export and provenance parameter grammar of the data family. */\nfunction validatedatagrammar(step: toolstep, options: Record<string, unknown>, origin: string): policyevaluation {\n const kind = step.kind;\n if (kind === \"scrapetable\") {\n if (options.name !== undefined && !isnonempty(options.name)) return { allowed: false, reason: \"The reviewed dataset name must be a non-empty string.\" };\n if (options.rowlimit !== undefined && (typeof options.rowlimit !== \"number\" || !Number.isInteger(options.rowlimit) || options.rowlimit < 1)) return { allowed: false, reason: \"The reviewed row limit must be a positive integer with no code ceiling.\" };\n }\n if (kind === \"paginateextract\") {\n if (!isnonempty(options.next)) return { allowed: false, reason: \"A reviewed next control selector is required in options.\" };\n if (options.pages !== undefined && (typeof options.pages !== \"number\" || !Number.isInteger(options.pages) || options.pages < 1)) return { allowed: false, reason: \"The reviewed page count must be a positive integer with no code ceiling.\" };\n if (!nonnegativeoption(options, \"wait\")) return { allowed: false, reason: \"The reviewed row freshness wait must be zero or a positive number of milliseconds.\" };\n }\n if (kind === \"exportcsv\" || kind === \"exportjson\" || kind === \"exportexcel\" || kind === \"copytable\" || kind === \"streamdisk\") {\n if (!isnonempty(options.dataset)) return { allowed: false, reason: \"A reviewed dataset id is required in options.\" };\n if (options.name !== undefined && !isnonempty(options.name)) return { allowed: false, reason: \"The reviewed artifact name must be a non-empty string.\" };\n }\n if (kind === \"exportcsv\" && options.delimiter !== undefined && (typeof options.delimiter !== \"string\" || options.delimiter.length !== 1)) return { allowed: false, reason: \"The reviewed csv delimiter must be a single character.\" };\n if (kind === \"streamdisk\" && (typeof options.chunk !== \"number\" || !Number.isInteger(options.chunk) || options.chunk < 1)) return { allowed: false, reason: \"The reviewed streaming chunk size must be a positive integer with no code ceiling.\" };\n if (kind === \"pushsheets\") {\n if (!isnonempty(options.dataset)) return { allowed: false, reason: \"A reviewed dataset id is required in options.\" };\n if (!isnonempty(options.sheet)) return { allowed: false, reason: \"A reviewed sheet endpoint url is required in options.\" };\n if (!ishttpsurl(options.sheet)) return { allowed: false, reason: \"The reviewed sheet endpoint url must use HTTPS.\" };\n if (options.reviewed !== true) return { allowed: false, reason: \"The sheet push needs the explicit reviewed flag before any data leaves local memory.\" };\n }\n if (kind === \"importcsv\") {\n if (typeof options.csv !== \"string\" || !options.csv.trim()) return { allowed: false, reason: \"Reviewed csv content is required in options.\" };\n if (options.name !== undefined && !isnonempty(options.name)) return { allowed: false, reason: \"The reviewed dataset name must be a non-empty string.\" };\n if (options.mapping !== undefined) {\n const mapping = options.mapping;\n if (!mapping || typeof mapping !== \"object\" || Array.isArray(mapping) || !Object.values(mapping).every(item => typeof item === \"string\")) return { allowed: false, reason: \"The reviewed csv column mapping must be an object of string values.\" };\n }\n }\n if (kind === \"looprows\") {\n if (!isnonempty(options.dataset)) return { allowed: false, reason: \"A reviewed dataset id is required in options.\" };\n if (options.variable !== undefined && !isnonempty(options.variable)) return { allowed: false, reason: \"The reviewed row variable name must be a non-empty string.\" };\n const inner = validateinnerstep(options, origin);\n if (!inner.allowed) return inner;\n }\n if (kind === \"transformvalues\") {\n if (!isnonempty(options.dataset)) return { allowed: false, reason: \"A reviewed dataset id is required in options.\" };\n const rules = options.rules;\n if (!Array.isArray(rules) || rules.length === 0) return { allowed: false, reason: \"A reviewed non-empty list of transform rules is required in options.\" };\n for (const item of rules) {\n const rulecheck = validatetransformrule(item);\n if (!rulecheck.allowed) return rulecheck;\n }\n }\n if (kind === \"deduperows\") {\n if (!isnonempty(options.dataset)) return { allowed: false, reason: \"A reviewed dataset id is required in options.\" };\n const keys = options.keys;\n if (!Array.isArray(keys) || keys.length === 0 || !keys.every(key => isnonempty(key))) return { allowed: false, reason: \"A reviewed non-empty list of dedupe column keys is required in options.\" };\n }\n if (kind === \"mergepages\") {\n const listcheck = validatedatasetids(options, \"datasets\");\n if (!listcheck.allowed) return listcheck;\n }\n if (kind === \"stamplerows\") {\n if (!isnonempty(options.dataset)) return { allowed: false, reason: \"A reviewed dataset id is required in options.\" };\n if (options.url !== undefined && !ishttpsurl(options.url)) return { allowed: false, reason: \"The reviewed source url must use HTTPS.\" };\n }\n if (kind === \"previewgrid\") {\n if (!isnonempty(options.dataset)) return { allowed: false, reason: \"A reviewed dataset id is required in options.\" };\n if (options.sample !== undefined && (typeof options.sample !== \"number\" || !Number.isInteger(options.sample) || options.sample < 1)) return { allowed: false, reason: \"The reviewed sample row count must be a positive integer with no code ceiling.\" };\n }\n if (kind === \"resumeextract\" && !isnonempty(options.session)) return { allowed: false, reason: \"A reviewed extract session id is required in options.\" };\n if (kind === \"logprovenance\" && !isnonempty(options.artifact)) return { allowed: false, reason: \"A reviewed artifact id or name is required in options.\" };\n return { allowed: true };\n}\n\n/** Validates a reviewed batch download specification: a non-empty HTTPS url list, an optional filename rule and an optional completion criterion. */\nexport function validatedownloadspec(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed downloadspec with a url list is required in options.\" };\n const spec = value as Record<string, unknown>;\n if (!Array.isArray(spec.urls) || spec.urls.length === 0 || !spec.urls.every(url => ishttpsurl(url))) return { allowed: false, reason: \"The reviewed downloadspec needs a non-empty list of HTTPS urls.\" };\n if (spec.filename !== undefined && !isnonempty(spec.filename)) return { allowed: false, reason: \"The reviewed downloadspec filename rule must be a non-empty string.\" };\n if (spec.complete !== undefined && spec.complete !== \"size\" && spec.complete !== \"checksum\") return { allowed: false, reason: \"The reviewed downloadspec completion criterion must be size or checksum.\" };\n return { allowed: true };\n}\n\n/** Validates a reviewed mime interception filter: include and exclude patterns plus the deny default for unlisted mime types. */\nexport function validatemimefilter(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed mimefilter with include and exclude patterns is required in options.\" };\n const filter = value as Record<string, unknown>;\n if (!Array.isArray(filter.include) || filter.include.length === 0 || !filter.include.every(pattern => isnonempty(pattern))) return { allowed: false, reason: \"The reviewed mimefilter needs a non-empty list of include patterns.\" };\n if (filter.exclude !== undefined && (!Array.isArray(filter.exclude) || !filter.exclude.every(pattern => isnonempty(pattern)))) return { allowed: false, reason: \"The reviewed mimefilter exclude patterns must be a list of non-empty strings.\" };\n if (filter.default !== \"deny\" && filter.default !== \"allow\") return { allowed: false, reason: \"The reviewed mimefilter needs the deny or allow default for unlisted mime types.\" };\n return { allowed: true };\n}\n\n/** Validates one reviewed cleanup rule: a positive age window with no code ceiling, an artifact kind and a keep policy. */\nexport function validatecleanuprule(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed cleanuprule with an age, a kind and a keep policy is required.\" };\n const rule = value as Record<string, unknown>;\n if (typeof rule.age !== \"number\" || !Number.isFinite(rule.age) || rule.age <= 0) return { allowed: false, reason: \"The reviewed cleanup age window must be a positive number of milliseconds with no code ceiling.\" };\n if (!isnonempty(rule.kind)) return { allowed: false, reason: \"The reviewed cleanup rule needs a non-empty artifact kind, or any to match every kind.\" };\n if (rule.keep !== \"none\" && rule.keep !== \"latest\" && rule.keep !== \"all\") return { allowed: false, reason: \"The reviewed cleanup keep policy must be none, latest or all.\" };\n return { allowed: true };\n}\n\n/** Validates the reviewed files, clipboard and downloads parameter grammar; batch sizes, concurrent windows and cleanup ages stay user configured with no code ceilings. */\nfunction validatefilesgrammar(step: toolstep, options: Record<string, unknown>): policyevaluation {\n const kind = step.kind;\n if (kind === \"batchdownload\") {\n const speccheck = validatedownloadspec(options.downloadspec);\n if (!speccheck.allowed) return speccheck;\n if (options.concurrent !== undefined && (typeof options.concurrent !== \"number\" || !Number.isInteger(options.concurrent) || options.concurrent < 1)) return { allowed: false, reason: \"The reviewed concurrent download window must be a positive integer with no code ceiling.\" };\n }\n if (kind === \"pausedownload\" || kind === \"resumedownload\" || kind === \"verifydownload\" || kind === \"quarantinedownload\" || kind === \"scanvirus\") {\n if (!isnonempty(step.value)) return { allowed: false, reason: \"A reviewed download or quarantine reference is required.\" };\n if (kind === \"verifydownload\") {\n if (options.checksum !== undefined && !isnonempty(options.checksum)) return { allowed: false, reason: \"The reviewed expected checksum must be a non-empty string.\" };\n if (options.bytes !== undefined && (typeof options.bytes !== \"number\" || !Number.isFinite(options.bytes) || options.bytes < 0)) return { allowed: false, reason: \"The reviewed expected size must be zero or a positive number of bytes.\" };\n }\n if (kind === \"scanvirus\" && options.scanner !== undefined && !isnonempty(options.scanner)) return { allowed: false, reason: \"The reviewed scanner name must be a non-empty string.\" };\n if (kind === \"quarantinedownload\" && options.reason !== undefined && !isnonempty(options.reason)) return { allowed: false, reason: \"The reviewed quarantine reason must be a non-empty string.\" };\n }\n if (kind === \"interceptmime\") {\n const filtercheck = validatemimefilter(options.mimefilter);\n if (!filtercheck.allowed) return filtercheck;\n }\n if (kind === \"readclipboard\") {\n if (!isnonempty(options.consentref)) return { allowed: false, reason: \"A clipboard read requires a reviewed consent ref of an approved consent prompt in options.\" };\n if (options.prompt !== undefined && !isnonempty(options.prompt)) return { allowed: false, reason: \"The reviewed clipboard consent prompt must be a non-empty string.\" };\n }\n if (kind === \"exportnetlog\" && options.stepid !== undefined && !isnonempty(options.stepid)) return { allowed: false, reason: \"The reviewed netlog step filter must be a non-empty step id.\" };\n if (kind === \"namecaptures\") {\n if (!isnonempty(options.task)) return { allowed: false, reason: \"A reviewed task id is required in options for capture naming.\" };\n if (options.steps !== undefined && (!Array.isArray(options.steps) || options.steps.length === 0 || !options.steps.every(item => isnonempty(item)))) return { allowed: false, reason: \"The reviewed capture steps must be a non-empty list of step ids when present.\" };\n if (options.extension !== undefined && !isnonempty(options.extension)) return { allowed: false, reason: \"The reviewed capture extension must be a non-empty string.\" };\n }\n if (kind === \"cleanupartifacts\" && options.rules !== undefined) {\n const rules = options.rules;\n if (!Array.isArray(rules) || rules.length === 0) return { allowed: false, reason: \"The reviewed cleanup rules must be a non-empty list when present.\" };\n for (const item of rules) {\n const rulecheck = validatecleanuprule(item);\n if (!rulecheck.allowed) return rulecheck;\n }\n }\n return { allowed: true };\n}\n\n/** Requires an approved consent prompt before any clipboard read; every read consumes its own prompt. */\nexport function clipboardconsentgranted(step: toolstep): policyevaluation {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n const consentref = options.consentref;\n if (typeof consentref !== \"string\" || !consentref.trim()) return { allowed: false, reason: \"A clipboard read requires a reviewed consent ref in options.\" };\n return { allowed: true };\n}\n\n/** Refuses to release any quarantined file before a clean scan verdict exists. */\nexport function quarantinereleasegranted(entry: quarantineentry): policyevaluation {\n if (entry.scan !== \"clean\") return { allowed: false, reason: `The quarantined file ${entry.path} cannot leave quarantine with the ${entry.scan} scan verdict; only a clean verdict releases it.` };\n return { allowed: true };\n}\n\n/** Refuses downloads and download interception that fall outside the session origin grants. */\nexport function downloadgranted(session: agentsession | undefined, url: string): policyevaluation {\n let origin = \"\";\n try { origin = new URL(url).origin; } catch { return { allowed: false, reason: \"The reviewed download URL is invalid.\" }; }\n if (!origingranted(session, origin)) return { allowed: false, reason: `The download from ${origin} leaves the session origin grants and needs a session grant first.` };\n return { allowed: true };\n}\n\n/** Masks a clipboard payload for every log line; the full text never persists anywhere. */\nexport function maskclipboard(payload: string): string {\n return `[clipboard payload of ${payload.length} character${payload.length === 1 ? \"\" : \"s\"}]`;\n}\n\n/** Requires an asksubmit review step before every form submission step. */\nexport function submitreviewgranted(steps: toolstep[], submitid: string): policyevaluation {\n const position = steps.findIndex(candidate => candidate.id === submitid);\n const asked = steps.some((candidate, index) => candidate.kind === \"asksubmit\" && (position === -1 || index < position));\n return asked ? { allowed: true } : { allowed: false, reason: \"Form submission requires an asksubmit review step before it.\" };\n}\n\n/** Requires a reviewed consent ref before any password field is filled. */\nexport function passwordconsentgranted(step: toolstep): policyevaluation {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n const consentref = options.consentref;\n if (typeof consentref !== \"string\" || !consentref.trim()) return { allowed: false, reason: \"A password fill requires a reviewed consent ref in options.\" };\n return { allowed: true };\n}\n\n/** True when a numeric value passes the Luhn checksum used by card networks. */\nfunction luhnvalid(digits: string): boolean {\n let sum = 0;\n let double = false;\n for (let index = digits.length - 1; index >= 0; index -= 1) {\n let value = Number.parseInt(digits[index] ?? \"\", 10);\n if (!Number.isFinite(value)) return false;\n if (double) { value *= 2; if (value > 9) value -= 9; }\n sum += value;\n double = !double;\n }\n return sum % 10 === 0;\n}\n\n/** Refuses generated values that look like real card numbers or personal identifiers; test prefixed card values stay allowed. */\nexport function generatedvalueallowed(value: string): policyevaluation {\n const compact = value.replace(/[\\s-]/g, \"\");\n if (/^\\d{13,19}$/.test(compact) && luhnvalid(compact) && !compact.startsWith(\"4111\")) return { allowed: false, reason: \"The generated value looks like a real card number and is refused; generated card values use the 4111 test prefix.\" };\n if (/^\\d{3}-\\d{2}-\\d{4}$/.test(value.trim())) return { allowed: false, reason: \"The generated value looks like a personal identifier and is refused.\" };\n return { allowed: true };\n}\n\n/** Requires the origin grants of a saved profile to cover the origin before its values fill a page. */\nexport function profilegrantgranted(profile: formprofile, origin: string): policyevaluation {\n if (!profile.grants.includes(origin)) return { allowed: false, reason: `The saved profile ${profile.name} is not granted to ${origin}; add the origin to the profile grants first.` };\n return { allowed: true };\n}\n\n/** Restricts group and layout mutations to the active session: they refuse without a live session. */\nexport function layoutmutationgranted(session: agentsession | undefined, now: number): policyevaluation {\n if (!session || session.stoppedat || session.expiresat <= now) return { allowed: false, reason: \"Group and layout mutations stay inside the active session.\" };\n return { allowed: true };\n}\n\n/** Requires explicit review before closing a window that holds more than one task tab. */\nexport function windowclosegate(tasktabcount: number, reviewed: boolean): policyevaluation {\n if (tasktabcount > 1 && !reviewed) return { allowed: false, reason: `The window holds ${tasktabcount} task tabs and needs explicit review before it closes.` };\n return { allowed: true };\n}\n\n/** Reads the user configured concurrent task tab ceiling; an absent value never refuses a tab. */\nexport function tasktabceiling(settings: runsettings | undefined): number | undefined {\n const ceiling = settings?.tasktabceiling;\n return typeof ceiling === \"number\" && Number.isFinite(ceiling) && ceiling >= 0 ? ceiling : undefined;\n}\n\n/** Parses the reviewed wait duration of a wait step with no upper bound. */\nexport function waitduration(step: toolstep): number {\n const requested = step.value ? Number.parseInt(step.value, 10) : 250;\n if (!Number.isFinite(requested) || requested < 0) throw new Error(\"Wait duration must be zero or a positive number of milliseconds.\");\n return requested;\n}\n\nfunction isnumericid(value: unknown): value is string {\n return typeof value === \"string\" && /^\\d+$/.test(value);\n}\n\nfunction numericoption(options: Record<string, unknown>, key: string): boolean {\n return options[key] === undefined || (typeof options[key] === \"number\" && Number.isFinite(options[key] as number));\n}\n\n/** True when an optional numeric option is absent or a finite number of zero or more. */\nfunction nonnegativeoption(options: Record<string, unknown>, key: string): boolean {\n return numericoption(options, key) && !(typeof options[key] === \"number\" && (options[key] as number) < 0);\n}\n\nfunction isnonempty(value: unknown): value is string {\n return typeof value === \"string\" && value.trim().length > 0;\n}\n\nfunction ispoint(value: unknown): boolean {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n const point = value as Record<string, unknown>;\n return typeof point.x === \"number\" && Number.isFinite(point.x) && typeof point.y === \"number\" && Number.isFinite(point.y);\n}\n\n/** Grades a resolution match count: zero is absent, one is resolved and more than one is refused as ambiguous. */\nexport function resolutionverdict(count: number): \"absent\" | \"resolved\" | \"ambiguous\" {\n if (!Number.isFinite(count) || count <= 0) return \"absent\";\n return count === 1 ? \"resolved\" : \"ambiguous\";\n}\n\n/** Validates the reviewed targetref grammar of every resolution mode and rejects empty references. */\nexport function validatetargetref(reference: unknown): policyevaluation {\n if (!reference || typeof reference !== \"object\" || Array.isArray(reference)) return { allowed: false, reason: \"The reviewed target reference must be an object.\" };\n const ref = reference as Record<string, unknown>;\n if (ref.mode === \"selector\") return isnonempty(ref.selector) ? { allowed: true } : { allowed: false, reason: \"The selector target reference needs a non-empty selector.\" };\n if (ref.mode === \"text\") return isnonempty(ref.text) ? { allowed: true } : { allowed: false, reason: \"The text target reference needs non-empty text.\" };\n if (ref.mode === \"aria\") {\n if (!isnonempty(ref.role)) return { allowed: false, reason: \"The aria target reference needs a non-empty role.\" };\n return isnonempty(ref.name) ? { allowed: true } : { allowed: false, reason: \"The aria target reference needs a non-empty name.\" };\n }\n if (ref.mode === \"name\") return isnonempty(ref.name) ? { allowed: true } : { allowed: false, reason: \"The name target reference needs a non-empty name.\" };\n if (ref.mode === \"xpath\") return isnonempty(ref.xpath) ? { allowed: true } : { allowed: false, reason: \"The xpath target reference needs a non-empty expression.\" };\n if (ref.mode === \"index\") {\n const index = ref.index;\n return typeof index === \"number\" && Number.isInteger(index) && index >= 1 ? { allowed: true } : { allowed: false, reason: \"The index target reference needs a positive integer map number.\" };\n }\n if (ref.mode === \"point\") {\n const pointok = typeof ref.x === \"number\" && Number.isFinite(ref.x) && typeof ref.y === \"number\" && Number.isFinite(ref.y);\n return pointok ? { allowed: true } : { allowed: false, reason: \"The point target reference needs numeric x and y coordinates.\" };\n }\n return { allowed: false, reason: \"The target reference mode must be selector, text, aria, name, xpath, index or point.\" };\n}\n\n/** True when the session origin grants cover the given origin; a session without grants only allows its own origin. */\nexport function origingranted(session: agentsession | undefined, origin: string): boolean {\n if (!session) return false;\n const grants = session.grants ?? [session.origin];\n return grants.includes(origin);\n}\n\n/** Decides whether an unreviewed origin may open: the session grants cover it or a safe checksafe verdict vouches for it. */\nexport function originverified(url: string, grants: string[], verdicts: safetyverdict[]): policyevaluation {\n let origin = \"\";\n try { origin = new URL(url).origin; } catch { return { allowed: false, reason: \"The reviewed navigation URL is invalid.\" }; }\n if (grants.includes(origin)) return { allowed: true };\n const covered = verdicts.find(verdict => verdict.safe && (verdict.url === url || (safeorigin(verdict.url) === origin)));\n if (covered) return { allowed: true };\n return { allowed: false, reason: `The origin ${origin} is outside the session grants and has no safe checksafe verdict; run checksafe and review it first.` };\n}\n\nfunction safeorigin(url: string): string {\n try { return new URL(url).origin; } catch { return \"\"; }\n}\n\n/** Refuses navigation that would move a granted task tab outside the session origin grants until the user consents. */\nexport function navigationgranted(session: agentsession | undefined, url: string): policyevaluation {\n let origin = \"\";\n try { origin = new URL(url).origin; } catch { return { allowed: false, reason: \"The reviewed navigation URL is invalid.\" }; }\n if (origingranted(session, origin)) return { allowed: true };\n return { allowed: false, reason: `Navigation to ${origin} leaves the task tab origins and needs the user consent of a session grant first.` };\n}\n\n/** Validates the reviewed inner step of a retry or frame wrapper against the same rules as a top-level step. */\nfunction validateinnerstep(options: Record<string, unknown>, origin: string): policyevaluation {\n const stepid = options.stepid;\n const kind = options.kind;\n if (isnonempty(stepid)) {\n if (kind !== undefined) return { allowed: false, reason: \"The reviewed wrapper must reference a step id or an inline step, not both.\" };\n return { allowed: true };\n }\n if (typeof kind !== \"string\" || !kind.trim()) return { allowed: false, reason: \"A reviewed step id or inline step kind is required in options.\" };\n if (kind === \"retryaction\" || kind === \"enterframe\" || kind === \"looprows\") return { allowed: false, reason: \"The reviewed inner step cannot be another wrapper kind.\" };\n if (!allowedactions.has(kind as actionkind)) return { allowed: false, reason: \"The reviewed inner step kind is unsupported.\" };\n const inneroptions = options.options;\n if (inneroptions !== undefined && (!inneroptions || typeof inneroptions !== \"object\" || Array.isArray(inneroptions))) return { allowed: false, reason: \"The reviewed inner step options must be an object.\" };\n const inner: toolstep = {\n id: \"inner\",\n kind: kind as actionkind,\n summary: \"Reviewed inner step.\",\n risk: actionrisk(kind as actionkind),\n ...(isnonempty(options.target) ? { target: options.target } : {}),\n ...(isnonempty(options.value) ? { value: options.value } : {}),\n ...(inneroptions !== undefined ? { options: JSON.stringify(inneroptions) } : {}),\n };\n return validatestep(inner, origin);\n}\n\n/** True when a reviewed https url parses. */\nfunction ishttpsurl(value: unknown): value is string {\n if (typeof value !== \"string\" || !value.trim()) return false;\n try { return new URL(value).protocol === \"https:\"; } catch { return false; }\n}\n\n/** Validates the reviewed navtarget grammar of a navigation step. */\nfunction validatenavtarget(value: unknown, kind: string): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed navtarget with a url is required in options.\" };\n const target = value as Record<string, unknown>;\n if (!ishttpsurl(target.url)) return { allowed: false, reason: \"The reviewed navtarget url must use HTTPS.\" };\n const container = target.container ?? \"tab\";\n if (container !== \"current\" && container !== \"tab\" && container !== \"window\" && container !== \"private\") return { allowed: false, reason: \"The reviewed navtarget container must be current, tab, window or private.\" };\n if (target.position !== undefined && target.position !== \"adjacent\" && target.position !== \"end\") return { allowed: false, reason: \"The reviewed navtarget position must be adjacent or end.\" };\n if (kind === \"openprivate\" && container !== \"private\") return { allowed: false, reason: \"The openprivate step requires the private container.\" };\n if (kind === \"openlink\" && container === \"private\") return { allowed: false, reason: \"The openlink step cannot open the private container; use openprivate.\" };\n return { allowed: true };\n}\n\n/** Validates the reviewed waitprofile grammar with its load signals, thresholds and per origin overrides. */\nfunction validatewaitprofile(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed waitprofile with load signals is required in options.\" };\n const profile = value as Record<string, unknown>;\n if (!Array.isArray(profile.signals) || profile.signals.length === 0 || !profile.signals.every(signal => isnonempty(signal))) return { allowed: false, reason: \"The reviewed waitprofile needs a non-empty list of load signals.\" };\n if (!nonnegativeoption(profile, \"idle\")) return { allowed: false, reason: \"The reviewed waitprofile idle threshold must be zero or a positive number of milliseconds.\" };\n if (!nonnegativeoption(profile, \"timeout\")) return { allowed: false, reason: \"The reviewed waitprofile timeout must be zero or a positive number of milliseconds.\" };\n if (profile.overrides !== undefined) {\n if (!Array.isArray(profile.overrides) || profile.overrides.length === 0) return { allowed: false, reason: \"The reviewed waitprofile overrides must be a non-empty list when present.\" };\n for (const entry of profile.overrides) {\n if (!entry || typeof entry !== \"object\" || Array.isArray(entry)) return { allowed: false, reason: \"Every reviewed waitprofile override must be an object with an origin.\" };\n const override = entry as Record<string, unknown>;\n if (!ishttpsurl(override.origin)) return { allowed: false, reason: \"Every reviewed waitprofile override origin must use HTTPS.\" };\n if (override.signals !== undefined && (!Array.isArray(override.signals) || !override.signals.every(signal => isnonempty(signal)))) return { allowed: false, reason: \"The reviewed waitprofile override signals must be a list of non-empty strings.\" };\n if (!nonnegativeoption(override, \"idle\") || !nonnegativeoption(override, \"timeout\")) return { allowed: false, reason: \"The reviewed waitprofile override thresholds must be zero or positive numbers.\" };\n }\n }\n return { allowed: true };\n}\n\n/** Validates the reviewed urlpattern grammar with its match mode plus query and fragment parts. */\nexport function validateurlpattern(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed urlpattern is required in options.\" };\n const pattern = value as Record<string, unknown>;\n if (pattern.mode !== \"exact\" && pattern.mode !== \"prefix\" && pattern.mode !== \"host\" && pattern.mode !== \"pattern\") return { allowed: false, reason: \"The reviewed urlpattern mode must be exact, prefix, host or pattern.\" };\n if (!ishttpsurl(pattern.url)) return { allowed: false, reason: \"The reviewed urlpattern url must use HTTPS.\" };\n if (pattern.query !== undefined) {\n if (!pattern.query || typeof pattern.query !== \"object\" || Array.isArray(pattern.query)) return { allowed: false, reason: \"The reviewed urlpattern query part must be an object of parameter names and values.\" };\n for (const item of Object.values(pattern.query)) if (typeof item !== \"string\") return { allowed: false, reason: \"The reviewed urlpattern query values must be strings.\" };\n }\n if (pattern.fragment !== undefined && !isnonempty(pattern.fragment)) return { allowed: false, reason: \"The reviewed urlpattern fragment must be a non-empty string.\" };\n return { allowed: true };\n}\n\n/** Validates a reviewed non-empty list of HTTPS urls in options. */\nfunction validateurllist(options: Record<string, unknown>, key: string): policyevaluation {\n const urls = options[key];\n if (!Array.isArray(urls) || urls.length === 0 || !urls.every(url => ishttpsurl(url))) return { allowed: false, reason: `A reviewed non-empty list of HTTPS urls is required in options as ${key}.` };\n return { allowed: true };\n}\n\n/** Validates the reviewed ratelimit grammar of a navrate step; the window and ceiling stay user configured with no hardcoded cap. */\nfunction validateratelimit(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed ratelimit with a window and a ceiling is required in options.\" };\n const limit = value as Record<string, unknown>;\n if (limit.domain !== undefined && !isnonempty(limit.domain)) return { allowed: false, reason: \"The reviewed ratelimit domain must be a non-empty string.\" };\n if (typeof limit.window !== \"number\" || !Number.isFinite(limit.window) || limit.window <= 0) return { allowed: false, reason: \"The reviewed ratelimit window must be a positive number of milliseconds with no code ceiling.\" };\n if (typeof limit.ceiling !== \"number\" || !Number.isInteger(limit.ceiling) || limit.ceiling < 1) return { allowed: false, reason: \"The reviewed ratelimit ceiling must be a positive integer with no code ceiling.\" };\n return { allowed: true };\n}\n\n/** Validates the reviewed tabquery grammar with url, title, id and pattern matchers; at least one matcher is required. */\nexport function validatetabquery(value: unknown): policyevaluation {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return { allowed: false, reason: \"A reviewed tabquery with at least one matcher is required in options.\" };\n const query = value as Record<string, unknown>;\n const hasmatcher = query.url !== undefined || query.title !== undefined || query.id !== undefined || query.pattern !== undefined;\n if (!hasmatcher) return { allowed: false, reason: \"The reviewed tabquery needs a url, title, id or pattern matcher.\" };\n if (query.url !== undefined && !isnonempty(query.url)) return { allowed: false, reason: \"The reviewed tabquery url matcher must be a non-empty string.\" };\n if (query.title !== undefined && !isnonempty(query.title)) return { allowed: false, reason: \"The reviewed tabquery title matcher must be a non-empty string.\" };\n if (query.pattern !== undefined && !isnonempty(query.pattern)) return { allowed: false, reason: \"The reviewed tabquery pattern matcher must be a non-empty string.\" };\n if (query.id !== undefined && (typeof query.id !== \"number\" || !Number.isInteger(query.id) || query.id < 0)) return { allowed: false, reason: \"The reviewed tabquery id matcher must be a non-negative integer tab id.\" };\n return { allowed: true };\n}\n\n/** Validates a reviewed group color choice against the Chromium tab group palette. */\nfunction validategroupcolor(value: unknown): boolean {\n return typeof value === \"string\" && (groupcolors as string[]).includes(value);\n}\n\n/** Validates a reviewed list of numeric browser ids in options. */\nfunction validateidlist(options: Record<string, unknown>, key: string): boolean {\n const ids = options[key];\n return Array.isArray(ids) && ids.length > 0 && ids.every(id => typeof id === \"number\" && Number.isInteger(id) && id >= 0);\n}\n\n/** Validates the reviewed tab and window parameter grammar of the tabs and windows command family. */\nfunction validatetabsgrammar(step: toolstep, options: Record<string, unknown>): policyevaluation {\n const kind = step.kind;\n if (kind === \"querytabs\" || kind === \"closepattern\") {\n const querycheck = validatetabquery(options.tabquery);\n if (!querycheck.allowed) return querycheck;\n if (kind === \"closepattern\" && options.reviewed !== true) return { allowed: false, reason: \"The close pattern needs the explicit reviewed flag before any tab closes.\" };\n }\n if (kind === \"duplicatetab\" || kind === \"pintab\" || kind === \"mutetab\" || kind === \"movetab\" || kind === \"movetabwindow\" || kind === \"badgetab\" || kind === \"attachmeta\") {\n if (!isnumericid(step.value)) return { allowed: false, reason: \"A numeric browser tab id is required.\" };\n }\n if (kind === \"focuswindow\" || kind === \"maximizewindow\" || kind === \"minimizewindow\" || kind === \"restorewindow\") {\n if (!isnumericid(step.value)) return { allowed: false, reason: \"A numeric browser window id is required.\" };\n }\n if (kind === \"pintab\" && typeof options.pinned !== \"boolean\") return { allowed: false, reason: \"A reviewed pinned flag is required in options.\" };\n if (kind === \"mutetab\" && typeof options.muted !== \"boolean\") return { allowed: false, reason: \"A reviewed muted flag is required in options.\" };\n if (kind === \"movetab\") {\n if (typeof options.index !== \"number\" || !Number.isInteger(options.index) || options.index < 0) return { allowed: false, reason: \"A reviewed non-negative target index is required in options.\" };\n }\n if (kind === \"movetabwindow\") {\n if (typeof options.windowid !== \"number\" || !Number.isInteger(options.windowid) || options.windowid < 0) return { allowed: false, reason: \"A reviewed target window id is required in options.\" };\n }\n if (kind === \"grouptabs\") {\n const group = options.group;\n if (!group || typeof group !== \"object\" || Array.isArray(group)) return { allowed: false, reason: \"A reviewed group with a name is required in options.\" };\n const spec = group as Record<string, unknown>;\n if (!isnonempty(spec.name)) return { allowed: false, reason: \"The reviewed group needs a non-empty name.\" };\n if (!validategroupcolor(spec.color)) return { allowed: false, reason: \"The reviewed group color must be a Chromium tab group color.\" };\n if (!validateidlist(spec, \"tabids\")) return { allowed: false, reason: \"The reviewed group needs a non-empty list of member tab ids.\" };\n }\n if (kind === \"colorgroup\") {\n if (!isnonempty(options.name)) return { allowed: false, reason: \"A reviewed group name is required in options.\" };\n if (!validategroupcolor(options.color)) return { allowed: false, reason: \"The reviewed group color must be a Chromium tab group color.\" };\n }\n if (kind === \"collapsegroup\") {\n if (!isnonempty(options.name)) return { allowed: false, reason: \"A reviewed group name is required in options.\" };\n if (typeof options.collapsed !== \"boolean\") return { allowed: false, reason: \"A reviewed collapsed flag is required in options.\" };\n }\n if (kind === \"discardtab\" || kind === \"reloadtabs\") {\n if (!isnumericid(step.value) && !validateidlist(options, \"tabs\")) return { allowed: false, reason: \"A numeric tab id or a reviewed list of tab ids is required.\" };\n }\n if (kind === \"zoomin\" || kind === \"zoomout\") {\n if (options.step !== undefined && (typeof options.step !== \"number\" || !Number.isFinite(options.step) || options.step <= 0)) return { allowed: false, reason: \"The reviewed zoom step must be a positive number with no code ceiling.\" };\n if (step.value !== undefined && step.value !== \"\" && !isnumericid(step.value)) return { allowed: false, reason: \"The reviewed zoom target must be a numeric tab id.\" };\n }\n if (kind === \"switchtab\") {\n if (options.direction !== \"next\" && options.direction !== \"previous\") return { allowed: false, reason: \"A reviewed switch direction of next or previous is required in options.\" };\n }\n if (kind === \"restorewindow\") {\n const bounds = options.bounds;\n if (bounds !== undefined) {\n if (!bounds || typeof bounds !== \"object\" || Array.isArray(bounds)) return { allowed: false, reason: \"The reviewed window bounds must be an object.\" };\n const shape = bounds as Record<string, unknown>;\n for (const field of [\"left\", \"top\", \"width\", \"height\"]) {\n if (typeof shape[field] !== \"number\" || !Number.isFinite(shape[field])) return { allowed: false, reason: \"The reviewed window bounds need numeric left, top, width and height.\" };\n }\n }\n }\n if (kind === \"scratchwindow\") {\n if (step.value !== undefined && step.value !== \"\" && !ishttpsurl(step.value)) return { allowed: false, reason: \"The reviewed scratch window url must use HTTPS.\" };\n }\n if (kind === \"incognitowindow\" && !ishttpsurl(step.value)) return { allowed: false, reason: \"A reviewed HTTPS url is required to open an incognito window.\" };\n if (kind === \"restoretab\" && step.value !== undefined && step.value !== \"\" && !ishttpsurl(step.value)) return { allowed: false, reason: \"The reviewed restore url must use HTTPS.\" };\n if (kind === \"savelayout\" || kind === \"restorelayout\") {\n if (!isnonempty(options.name)) return { allowed: false, reason: \"A reviewed layout name is required in options.\" };\n }\n if (kind === \"badgetab\") {\n if (!isnonempty(options.label)) return { allowed: false, reason: \"A reviewed badge label is required in options.\" };\n if (options.taskid !== undefined && !isnonempty(options.taskid)) return { allowed: false, reason: \"The reviewed badge task id must be a non-empty string.\" };\n }\n if (kind === \"attachmeta\") {\n const labels = options.labels;\n const taskrefs = options.taskrefs;\n const haslabels = Array.isArray(labels) && labels.length > 0 && labels.every(label => isnonempty(label));\n const hastaskrefs = Array.isArray(taskrefs) && taskrefs.length > 0 && taskrefs.every(ref => isnonempty(ref));\n if (!haslabels && !hastaskrefs) return { allowed: false, reason: \"Reviewed labels or task refs are required in options to attach metadata.\" };\n if (options.provenance !== undefined && !isnonempty(options.provenance)) return { allowed: false, reason: \"The reviewed provenance must be a non-empty string.\" };\n }\n if (kind === \"reopenrun\" && !isnonempty(options.run)) return { allowed: false, reason: \"A reviewed run id is required in options to reopen its tabs.\" };\n return { allowed: true };\n}\n\n/** True when the kind belongs to the media capture family of pdf documents, recordings, images, canvases, streams, assets, lapses, conversions and thumbnails. */\nexport function ismediakind(kind: actionkind): boolean {\n return mediaactions.has(kind);\n}\n\n/** True when the kind records user activity and needs the reviewed recording consent before it starts. */\nexport function isrecordingkind(kind: actionkind): boolean {\n return kind === \"recordscreen\" || kind === \"captureaudio\";\n}\n\n/** Requires the active tab grant of the live session for every media kind: the session tab and origin must match and the origin grant must cover the active origin. */\nexport function mediagate(session: agentsession | undefined, tabid: number, origin: string, now: number): policyevaluation {\n if (!session || session.stoppedat) return { allowed: false, reason: \"No active browser session exists for the media capture.\" };\n if (session.expiresat <= now) return { allowed: false, reason: \"The browser session has expired and cannot capture media.\" };\n if (session.pausedat) return { allowed: false, reason: \"The browser session is paused and cannot capture media.\" };\n if (session.tabid !== tabid) return { allowed: false, reason: `The media capture needs the active tab grant of session tab ${session.tabid} and refuses tab ${tabid}.` };\n if (!origingranted(session, origin)) return { allowed: false, reason: `The media capture of ${origin} needs the session origin grants first.` };\n return { allowed: true };\n}\n\n/** Requires an approved recording consent prompt before any recording of user activity starts; every start consumes its own prompt. */\nexport function recordingconsentgranted(step: toolstep): policyevaluation {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n const consentref = options.consentref;\n if (typeof consentref !== \"string\" || !consentref.trim()) return { allowed: false, reason: \"A recording of user activity requires a reviewed consent ref in options before it starts.\" };\n return { allowed: true };\n}\n\n/** Exposes the recording duration window as a user configured choice in milliseconds; an absent window leaves the duration to the reviewed step options with no code ceiling. */\nexport function recordingwindow(settings: runsettings | undefined): number | undefined {\n const window = settings?.recordingwindow;\n return typeof window === \"number\" && Number.isFinite(window) && window > 0 ? window : undefined;\n}\n\n/** Keeps the reviewed lapse plan inside the reviewed wait budget: the whole lapse duration must fit the wait window with no code ceiling on either side. */\nexport function lapsebudgetallowed(interval: number, duration: number, wait: number | undefined): policyevaluation {\n if (!(interval > 0)) return { allowed: false, reason: \"The reviewed lapse interval must be a positive number of milliseconds.\" };\n if (!(duration > 0)) return { allowed: false, reason: \"The reviewed lapse duration must be a positive number of milliseconds.\" };\n if (wait !== undefined && !(wait >= 0)) return { allowed: false, reason: \"The reviewed wait budget must be zero or a positive number of milliseconds.\" };\n if (wait !== undefined && duration > wait) return { allowed: false, reason: `The lapse duration of ${duration} milliseconds exceeds the reviewed wait budget of ${wait} milliseconds; review a wider budget or a shorter duration.` };\n return { allowed: true };\n}\n\n/** Validates the reviewed media capture parameter grammar of the 1.1.41 family: pdf paper sizes, recording scopes and windows, image filters, lapse plans, conversion targets and thumbnail directives stay user choices with no code ceilings. */\nfunction validatemediagrammar(step: toolstep, options: Record<string, unknown>): policyevaluation {\n const kind = step.kind;\n if (kind === \"capturepdf\") {\n const pdf = options.pdf;\n if (pdf !== undefined) {\n if (!pdf || typeof pdf !== \"object\" || Array.isArray(pdf)) return { allowed: false, reason: \"The reviewed pdf options must be an object in options.pdf.\" };\n const pdfoptions = pdf as Record<string, unknown>;\n if (pdfoptions.paperwidth !== undefined && (typeof pdfoptions.paperwidth !== \"number\" || !Number.isFinite(pdfoptions.paperwidth) || pdfoptions.paperwidth <= 0)) return { allowed: false, reason: \"The reviewed pdf paper width must be a positive number of inches with no code cap.\" };\n if (pdfoptions.paperheight !== undefined && (typeof pdfoptions.paperheight !== \"number\" || !Number.isFinite(pdfoptions.paperheight) || pdfoptions.paperheight <= 0)) return { allowed: false, reason: \"The reviewed pdf paper height must be a positive number of inches with no code cap.\" };\n if (pdfoptions.margins !== undefined) {\n const margins = pdfoptions.margins;\n if (!margins || typeof margins !== \"object\" || Array.isArray(margins)) return { allowed: false, reason: \"The reviewed pdf margins must be an object with top, right, bottom and left inches.\" };\n for (const side of [\"top\", \"right\", \"bottom\", \"left\"]) {\n const value = (margins as Record<string, unknown>)[side];\n if (value === undefined) continue;\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) return { allowed: false, reason: `The reviewed pdf ${side} margin must be zero or a positive number of inches; negative margins are refused.` };\n }\n }\n if (pdfoptions.scale !== undefined && (typeof pdfoptions.scale !== \"number\" || !Number.isFinite(pdfoptions.scale) || pdfoptions.scale <= 0)) return { allowed: false, reason: \"The reviewed pdf scale must be a positive number with no code cap.\" };\n if (pdfoptions.landscape !== undefined && typeof pdfoptions.landscape !== \"boolean\") return { allowed: false, reason: \"The reviewed pdf landscape flag must be a boolean.\" };\n if (pdfoptions.paginate !== undefined && typeof pdfoptions.paginate !== \"boolean\") return { allowed: false, reason: \"The reviewed pdf paginate flag must be a boolean.\" };\n }\n if (options.breakpoints !== undefined && (!Array.isArray(options.breakpoints) || options.breakpoints.length === 0 || !options.breakpoints.every(item => isnonempty(item)))) return { allowed: false, reason: \"The reviewed pdf break points must be a non-empty list of selectors when present.\" };\n if (options.exporttarget !== undefined && options.exporttarget !== \"memory\" && options.exporttarget !== \"download\") return { allowed: false, reason: \"The reviewed pdf export target must be memory or download; pdf documents do not route to the clipboard.\" };\n if (options.name !== undefined && !isnonempty(options.name)) return { allowed: false, reason: \"The reviewed pdf artifact name must be a non-empty string.\" };\n }\n if (kind === \"recordscreen\" || kind === \"captureaudio\") {\n const recording = options.recording;\n if (recording !== undefined) {\n if (!recording || typeof recording !== \"object\" || Array.isArray(recording)) return { allowed: false, reason: \"The reviewed recording options must be an object in options.recording.\" };\n const recordoptions = recording as Record<string, unknown>;\n if (recordoptions.scope !== undefined && recordoptions.scope !== \"tab\" && recordoptions.scope !== \"run\") return { allowed: false, reason: \"The reviewed recording scope must be tab or run.\" };\n if (recordoptions.fps !== undefined && (typeof recordoptions.fps !== \"number\" || !Number.isFinite(recordoptions.fps) || recordoptions.fps <= 0)) return { allowed: false, reason: \"The reviewed recording fps must be a positive number with no code ceiling.\" };\n if (recordoptions.bitrate !== undefined && (typeof recordoptions.bitrate !== \"number\" || !Number.isFinite(recordoptions.bitrate) || recordoptions.bitrate <= 0)) return { allowed: false, reason: \"The reviewed recording bitrate must be a positive number with no code ceiling.\" };\n if (recordoptions.audio !== undefined && typeof recordoptions.audio !== \"boolean\") return { allowed: false, reason: \"The reviewed recording audio flag must be a boolean.\" };\n }\n if (options.duration !== undefined && (typeof options.duration !== \"number\" || !Number.isFinite(options.duration) || options.duration <= 0)) return { allowed: false, reason: \"The reviewed recording duration must be a positive number of milliseconds with no code ceiling.\" };\n const consent = recordingconsentgranted(step);\n if (!consent.allowed) return consent;\n }\n if (kind === \"captureframe\") {\n if (options.timestamp !== undefined && (typeof options.timestamp !== \"number\" || !Number.isFinite(options.timestamp) || options.timestamp < 0)) return { allowed: false, reason: \"The reviewed frame timestamp must be zero or a positive number of seconds.\" };\n if (options.poster !== undefined && typeof options.poster !== \"boolean\") return { allowed: false, reason: \"The reviewed poster flag must be a boolean.\" };\n const capturecheck = validatecaptureoptions(options.capture);\n if (!capturecheck.allowed) return capturecheck;\n }\n if (kind === \"downloadimages\") {\n const filter = options.imagefilter;\n if (!filter || typeof filter !== \"object\" || Array.isArray(filter)) return { allowed: false, reason: \"A reviewed imagefilter is required in options before any image downloads.\" };\n const imagefilter = filter as Record<string, unknown>;\n if (imagefilter.selector !== undefined && !isnonempty(imagefilter.selector)) return { allowed: false, reason: \"The reviewed imagefilter selector must be a non-empty selector from the reviewed selector grammar.\" };\n if (imagefilter.minwidth !== undefined && (typeof imagefilter.minwidth !== \"number\" || !Number.isFinite(imagefilter.minwidth) || imagefilter.minwidth < 0)) return { allowed: false, reason: \"The reviewed imagefilter minimum width must be zero or a positive number of pixels.\" };\n if (imagefilter.minheight !== undefined && (typeof imagefilter.minheight !== \"number\" || !Number.isFinite(imagefilter.minheight) || imagefilter.minheight < 0)) return { allowed: false, reason: \"The reviewed imagefilter minimum height must be zero or a positive number of pixels.\" };\n if (imagefilter.formats !== undefined && (!Array.isArray(imagefilter.formats) || imagefilter.formats.length === 0 || !imagefilter.formats.every(item => isnonempty(item)))) return { allowed: false, reason: \"The reviewed imagefilter format list must be a non-empty list of mime or extension patterns when present.\" };\n if (options.naming !== undefined) {\n const namingcheck = validatecapturenaming(options.naming);\n if (!namingcheck.allowed) return namingcheck;\n }\n }\n if (kind === \"shotcanvas\") {\n const capturecheck = validatecaptureoptions(options.capture);\n if (!capturecheck.allowed) return capturecheck;\n }\n if (kind === \"probestream\" && options.selector !== undefined && !isnonempty(options.selector)) return { allowed: false, reason: \"The reviewed stream probe scope selector must be a non-empty string.\" };\n if (kind === \"timelapse\") {\n const lapse = options.lapse;\n if (!lapse || typeof lapse !== \"object\" || Array.isArray(lapse)) return { allowed: false, reason: \"A reviewed lapse plan with interval, duration and format is required in options.\" };\n const plan = lapse as Record<string, unknown>;\n if (typeof plan.interval !== \"number\" || !Number.isFinite(plan.interval) || plan.interval <= 0) return { allowed: false, reason: \"The reviewed lapse interval must be a positive number of milliseconds with no code ceiling.\" };\n if (typeof plan.duration !== \"number\" || !Number.isFinite(plan.duration) || plan.duration <= 0) return { allowed: false, reason: \"The reviewed lapse duration must be a positive number of milliseconds with no code ceiling.\" };\n if (plan.format !== undefined && plan.format !== \"png\" && plan.format !== \"jpeg\" && plan.format !== \"webp\") return { allowed: false, reason: \"The reviewed lapse format must be png, jpeg or webp.\" };\n const budget = lapsebudgetallowed(plan.interval as number, plan.duration as number, typeof options.wait === \"number\" ? options.wait : undefined);\n if (!budget.allowed) return budget;\n const capturecheck = validatecaptureoptions(options.capture);\n if (!capturecheck.allowed) return capturecheck;\n }\n if (kind === \"convertimage\" || kind === \"makethumbs\") {\n const single = options.capture;\n const list = options.captures;\n const hasone = isnonempty(single);\n const haslist = Array.isArray(list) && list.length > 0 && list.every(item => isnonempty(item));\n if (!hasone && !haslist) return { allowed: false, reason: \"A reviewed capture id or a reviewed non-empty capture id list is required in options.\" };\n if (hasone && haslist) return { allowed: false, reason: \"The reviewed step needs one capture id or a capture id list, not both.\" };\n }\n if (kind === \"convertimage\") {\n const convert = options.convert;\n if (!convert || typeof convert !== \"object\" || Array.isArray(convert)) return { allowed: false, reason: \"A reviewed convert directive with a target format is required in options.\" };\n const directive = convert as Record<string, unknown>;\n if (directive.target !== \"png\" && directive.target !== \"jpeg\" && directive.target !== \"webp\") return { allowed: false, reason: \"The reviewed conversion target must be png, jpeg or webp.\" };\n if (directive.source !== undefined && directive.source !== \"png\" && directive.source !== \"jpeg\" && directive.source !== \"webp\") return { allowed: false, reason: \"The reviewed conversion source must be png, jpeg or webp.\" };\n if (directive.quality !== undefined && (typeof directive.quality !== \"number\" || !Number.isFinite(directive.quality) || directive.quality < 0 || directive.quality > 100)) return { allowed: false, reason: \"The reviewed conversion quality must stay between zero and one hundred with no code cap inside that range.\" };\n }\n if (kind === \"makethumbs\") {\n const thumb = options.thumb;\n if (!thumb || typeof thumb !== \"object\" || Array.isArray(thumb)) return { allowed: false, reason: \"A reviewed thumb directive with size, fit and suffix is required in options.\" };\n const directive = thumb as Record<string, unknown>;\n if (typeof directive.size !== \"number\" || !Number.isFinite(directive.size) || directive.size <= 0) return { allowed: false, reason: \"The reviewed thumbnail size must be a positive number of pixels with no fixed set.\" };\n if (directive.fit !== \"cover\" && directive.fit !== \"contain\") return { allowed: false, reason: \"The reviewed thumbnail fit must be cover or contain.\" };\n if (!isnonempty(directive.suffix)) return { allowed: false, reason: \"The reviewed thumbnail naming suffix must be a non-empty string.\" };\n }\n return { allowed: true };\n}\n\n/** Validates a single proposal against the active tab origin and local policy. */\nexport function validatestep(step: toolstep, origin: string): policyevaluation {\n if (!allowedactions.has(step.kind)) return { allowed: false, reason: \"Unsupported action kind.\" };\n if (!step.summary.trim()) return { allowed: false, reason: \"A human-readable action summary is required.\" };\n let options: Record<string, unknown>;\n try { options = parseoptions(step); } catch { return { allowed: false, reason: \"Step options must be a JSON object.\" }; }\n const hastargetref = options.targetref !== undefined;\n if (targetactions.has(step.kind) && !step.target?.trim() && !hastargetref) return { allowed: false, reason: \"A page target is required.\" };\n if (valueactions.has(step.kind) && !step.value?.trim()) return { allowed: false, reason: \"A reviewed value is required.\" };\n if (step.kind === \"select\" && !step.value?.trim()) return { allowed: false, reason: \"A reviewed option value is required.\" };\n if (step.kind === \"navigate\" && !step.value) return { allowed: false, reason: \"A navigation URL is required.\" };\n if (hastargetref) {\n const reference = validatetargetref(options.targetref);\n if (!reference.allowed) return reference;\n }\n if (step.kind === \"wait\") {\n try { waitduration(step); } catch { return { allowed: false, reason: \"Wait duration must be zero or a positive number of milliseconds.\" }; }\n }\n if (step.kind === \"navigate\") {\n try {\n if (new URL(step.value ?? \"\").origin !== origin) return { allowed: false, reason: \"Navigation must remain within the approved origin.\" };\n } catch {\n return { allowed: false, reason: \"Navigation URL is invalid.\" };\n }\n }\n if (step.kind === \"tabcreate\" || step.kind === \"windowcreate\" || step.kind === \"downloadfile\") {\n try {\n const url = new URL(step.value ?? \"\");\n if (url.protocol !== \"https:\") return { allowed: false, reason: \"The reviewed URL must use HTTPS.\" };\n } catch {\n return { allowed: false, reason: \"The reviewed URL is invalid.\" };\n }\n }\n if (step.kind === \"tabactivate\" || step.kind === \"tabclose\" || step.kind === \"tabreload\" || step.kind === \"windowclose\" || step.kind === \"windowresize\") {\n if (!isnumericid(step.value)) return { allowed: false, reason: \"A numeric browser id is required.\" };\n }\n if (step.kind === \"zoomset\") {\n const zoom = Number(step.value);\n if (!Number.isFinite(zoom) || zoom <= 0) return { allowed: false, reason: \"The reviewed zoom must be a positive number.\" };\n }\n if (step.kind === \"setattribute\" || step.kind === \"writestorage\") {\n const keyname = step.kind === \"setattribute\" ? \"name\" : \"key\";\n if (typeof options[keyname] !== \"string\" || !(options[keyname] as string).trim()) return { allowed: false, reason: `A reviewed ${keyname} is required in options.` };\n if (typeof options.value !== \"string\") return { allowed: false, reason: \"A reviewed value is required in options.\" };\n }\n if (step.kind === \"windowresize\") {\n if (typeof options.width !== \"number\" || typeof options.height !== \"number\" || !Number.isFinite(options.width) || !Number.isFinite(options.height)) return { allowed: false, reason: \"Reviewed width and height numbers are required in options.\" };\n }\n if ((step.kind === \"scrollpage\" || step.kind === \"scrollby\") && (!numericoption(options, \"x\") || !numericoption(options, \"y\"))) return { allowed: false, reason: \"Scroll amounts must be numbers in options.\" };\n if (step.kind === \"waitfor\" && options.timeout !== undefined && (typeof options.timeout !== \"number\" || options.timeout < 0)) return { allowed: false, reason: \"The waitfor timeout must be zero or a positive number of milliseconds.\" };\n if (step.kind === \"movepointer\") {\n const path = options.pointpath;\n if (!path || typeof path !== \"object\" || Array.isArray(path)) return { allowed: false, reason: \"A reviewed pointpath with start and end points is required in options.\" };\n const points = path as Record<string, unknown>;\n if (!ispoint(points.start) || !ispoint(points.end)) return { allowed: false, reason: \"The reviewed pointpath needs numeric start and end points.\" };\n if (points.waypoints !== undefined && (!Array.isArray(points.waypoints) || !points.waypoints.every(waypoint => ispoint(waypoint)))) return { allowed: false, reason: \"The reviewed pointpath waypoints must be numeric points.\" };\n if (!nonnegativeoption(points, \"duration\")) return { allowed: false, reason: \"The reviewed pointpath duration must be zero or a positive number of milliseconds.\" };\n const speed = options.speedprofile;\n if (speed !== undefined) {\n if (!speed || typeof speed !== \"object\" || Array.isArray(speed)) return { allowed: false, reason: \"The reviewed speed profile must be an object.\" };\n const profile = speed as Record<string, unknown>;\n if (profile.easing !== undefined && profile.easing !== \"linear\" && profile.easing !== \"easeinout\") return { allowed: false, reason: \"The reviewed easing must be linear or easeinout.\" };\n if (!nonnegativeoption(profile, \"peak\")) return { allowed: false, reason: \"The reviewed peak velocity must be zero or a positive number.\" };\n if (!nonnegativeoption(profile, \"jitter\")) return { allowed: false, reason: \"The reviewed jitter window must be zero or a positive number of milliseconds.\" };\n }\n }\n if (step.kind === \"clickpoint\" && (!hastargetref || (options.targetref as Record<string, unknown>).mode !== \"point\")) return { allowed: false, reason: \"A reviewed point target reference is required in options.\" };\n if (step.kind === \"clicktext\" && (!hastargetref || (options.targetref as Record<string, unknown>).mode !== \"text\")) return { allowed: false, reason: \"A reviewed text target reference is required in options.\" };\n if (step.kind === \"clickaria\" && (!hastargetref || (options.targetref as Record<string, unknown>).mode !== \"aria\")) return { allowed: false, reason: \"A reviewed aria target reference is required in options.\" };\n if (step.kind === \"clickname\" && (!hastargetref || (options.targetref as Record<string, unknown>).mode !== \"name\")) return { allowed: false, reason: \"A reviewed name target reference is required in options.\" };\n if (step.kind === \"resolvexpath\" && (!hastargetref || (options.targetref as Record<string, unknown>).mode !== \"xpath\")) return { allowed: false, reason: \"A reviewed xpath target reference is required in options.\" };\n if (step.kind === \"typetime\" && options.delay !== undefined && (typeof options.delay !== \"number\" || !Number.isFinite(options.delay) || options.delay < 0)) return { allowed: false, reason: \"The reviewed per keystroke delay must be zero or a positive number of milliseconds.\" };\n if (step.kind === \"submitsearch\") {\n if (!isnonempty(options.results)) return { allowed: false, reason: \"A reviewed results region selector is required in options.\" };\n if (options.timeout !== undefined && (typeof options.timeout !== \"number\" || !Number.isFinite(options.timeout) || options.timeout < 0)) return { allowed: false, reason: \"The submitsearch timeout must be zero or a positive number of milliseconds.\" };\n }\n if (step.kind === \"selectmulti\") {\n const values = options.values;\n if (!Array.isArray(values) || values.length === 0 || !values.every(value => isnonempty(value))) return { allowed: false, reason: \"A reviewed list of option values is required in options.\" };\n }\n if (step.kind === \"setslider\") {\n const slider = Number(step.value);\n if (!Number.isFinite(slider)) return { allowed: false, reason: \"The reviewed slider value must be a number.\" };\n }\n if (step.kind === \"setdate\" && !/^\\d{4}-\\d{2}-\\d{2}$/.test(step.value ?? \"\")) return { allowed: false, reason: \"The reviewed date must use the yyyy-mm-dd form.\" };\n if (step.kind === \"setcolor\" && !/^#[0-9a-fA-F]{6}$/.test(step.value ?? \"\")) return { allowed: false, reason: \"The reviewed color must use the #rrggbb form.\" };\n if (step.kind === \"keyhold\" && options.holdid !== undefined && !isnonempty(options.holdid)) return { allowed: false, reason: \"The reviewed hold id must be a non-empty string.\" };\n if (step.kind === \"dismissdialog\") {\n const accept = options.accept;\n const answer = options.answer;\n if (accept === undefined && !isnonempty(answer)) return { allowed: false, reason: \"A reviewed accept flag or prompt answer is required in options.\" };\n if (accept !== undefined && typeof accept !== \"boolean\") return { allowed: false, reason: \"The reviewed dialog accept flag must be a boolean.\" };\n if (answer !== undefined && !isnonempty(answer)) return { allowed: false, reason: \"The reviewed prompt answer must be a non-empty string.\" };\n }\n if (step.kind === \"pierceshadow\" && options.shadow !== undefined) {\n if (!Array.isArray(options.shadow) || !options.shadow.every(item => isnonempty(item))) return { allowed: false, reason: \"The reviewed shadow path must be a list of non-empty selectors.\" };\n }\n if (step.kind === \"enterframe\") {\n const path = options.framepath;\n if (!Array.isArray(path) || path.length === 0 || !path.every(item => typeof item === \"number\" && Number.isInteger(item) && item >= 0)) return { allowed: false, reason: \"A reviewed frame path of frame indexes is required in options.\" };\n return validateinnerstep(options, origin);\n }\n if (step.kind === \"retryaction\") {\n const inner = validateinnerstep(options, origin);\n if (!inner.allowed) return inner;\n const rule = options.retryrule;\n if (!rule || typeof rule !== \"object\" || Array.isArray(rule)) return { allowed: false, reason: \"A reviewed retry rule with attempts is required in options.\" };\n const retry = rule as Record<string, unknown>;\n if (typeof retry.attempts !== \"number\" || !Number.isInteger(retry.attempts) || retry.attempts < 1) return { allowed: false, reason: \"The reviewed retry attempts must be a positive integer with no code ceiling.\" };\n if (!nonnegativeoption(retry, \"settle\")) return { allowed: false, reason: \"The reviewed retry settle window must be zero or a positive number of milliseconds.\" };\n if (!nonnegativeoption(retry, \"tolerance\")) return { allowed: false, reason: \"The reviewed retry movement tolerance must be zero or a positive number of pixels.\" };\n }\n if (watchactions.has(step.kind)) {\n if (typeof options.lifetime !== \"number\" || !Number.isFinite(options.lifetime) || options.lifetime <= 0) return { allowed: false, reason: \"A reviewed watch lifetime window in milliseconds is required in options.\" };\n if (options.scopes !== undefined && (!Array.isArray(options.scopes) || !options.scopes.every(scope => isnonempty(scope)))) return { allowed: false, reason: \"The reviewed watch scopes must be a list of non-empty selectors.\" };\n if (options.events !== undefined && (!Array.isArray(options.events) || !options.events.every(event => isnonempty(event)))) return { allowed: false, reason: \"The reviewed watch event kinds must be a list of non-empty strings.\" };\n if (!nonnegativeoption(options, \"poll\")) return { allowed: false, reason: \"The reviewed watch poll interval must be zero or a positive number of milliseconds.\" };\n }\n if (step.kind === \"waitquiet\") {\n const rule = options.quietrule;\n if (!rule || typeof rule !== \"object\" || Array.isArray(rule)) return { allowed: false, reason: \"A reviewed quietrule with an idle threshold is required in options.\" };\n const quiet = rule as Record<string, unknown>;\n if (typeof quiet.idle !== \"number\" || !Number.isFinite(quiet.idle) || quiet.idle <= 0) return { allowed: false, reason: \"The reviewed quiet idle threshold must be a positive number of milliseconds with no code ceiling.\" };\n if (!nonnegativeoption(quiet, \"poll\")) return { allowed: false, reason: \"The reviewed quiet poll interval must be zero or a positive number of milliseconds.\" };\n if (!nonnegativeoption(quiet, \"timeout\")) return { allowed: false, reason: \"The reviewed quiet timeout must be zero or a positive number of milliseconds.\" };\n }\n if (step.kind === \"diffsnapshots\") {\n const versions = options.versions;\n if (!Array.isArray(versions) || versions.length !== 2 || !versions.every(version => typeof version === \"number\" && Number.isInteger(version) && version >= 1)) return { allowed: false, reason: \"Two reviewed observation version numbers are required in options.\" };\n }\n if (step.kind === \"openlink\" || step.kind === \"openprivate\" || step.kind === \"deeplink\") {\n const targetcheck = validatenavtarget(options.navtarget, step.kind);\n if (!targetcheck.allowed) return targetcheck;\n if (step.kind === \"deeplink\") {\n const app = options.app;\n if (!isnonempty(app)) return { allowed: false, reason: \"A reviewed deep link app pattern is required in options.\" };\n const params = options.params;\n if (params !== undefined && (!params || typeof params !== \"object\" || Array.isArray(params) || !Object.values(params).every(item => typeof item === \"string\"))) return { allowed: false, reason: \"The reviewed deep link params must be an object of string values.\" };\n }\n }\n if (step.kind === \"waitload\" && !nonnegativeoption(options, \"timeout\")) return { allowed: false, reason: \"The waitload timeout must be zero or a positive number of milliseconds.\" };\n if (step.kind === \"waiturl\" || step.kind === \"spawait\") {\n if (step.kind === \"waiturl\") {\n const patterncheck = validateurlpattern(options.urlpattern);\n if (!patterncheck.allowed) return patterncheck;\n }\n if (!nonnegativeoption(options, \"timeout\")) return { allowed: false, reason: \"The wait timeout must be zero or a positive number of milliseconds.\" };\n if (!nonnegativeoption(options, \"poll\")) return { allowed: false, reason: \"The wait poll interval must be zero or a positive number of milliseconds.\" };\n }\n if (step.kind === \"followlink\") {\n if (options.fragment !== undefined && typeof options.fragment !== \"boolean\") return { allowed: false, reason: \"The reviewed followlink fragment flag must be a boolean.\" };\n }\n if (step.kind === \"spanav\") {\n if (options.routepattern !== undefined) {\n const routecheck = validateurlpattern(options.routepattern);\n if (!routecheck.allowed) return routecheck;\n }\n if (!nonnegativeoption(options, \"timeout\")) return { allowed: false, reason: \"The spanav route timeout must be zero or a positive number of milliseconds.\" };\n }\n if (step.kind === \"rewritequery\") {\n const set = options.set;\n const remove = options.remove;\n if (set === undefined && remove === undefined) return { allowed: false, reason: \"Reviewed query parameters to set or remove are required in options.\" };\n if (set !== undefined && (!set || typeof set !== \"object\" || Array.isArray(set) || !Object.values(set).every(item => typeof item === \"string\"))) return { allowed: false, reason: \"The reviewed query parameters to set must be an object of string values.\" };\n if (remove !== undefined && (!Array.isArray(remove) || !remove.every(item => isnonempty(item)))) return { allowed: false, reason: \"The reviewed query parameters to remove must be a list of non-empty names.\" };\n }\n if (step.kind === \"navlist\") {\n const listcheck = validateurllist(options, \"urls\");\n if (!listcheck.allowed) return listcheck;\n }\n if (step.kind === \"navprofile\") {\n const profilecheck = validatewaitprofile(options.waitprofile);\n if (!profilecheck.allowed) return profilecheck;\n }\n if (step.kind === \"handleauth\" && !ishttpsurl(step.value)) return { allowed: false, reason: \"A reviewed HTTPS origin or url is required as the auth target.\" };\n if (step.kind === \"printpdf\" && options.name !== undefined && !isnonempty(options.name)) return { allowed: false, reason: \"The reviewed artifact name must be a non-empty string.\" };\n if (step.kind === \"prefetch\") {\n const listcheck = validateurllist(options, \"urls\");\n if (!listcheck.allowed) return listcheck;\n }\n if (step.kind === \"preconnect\") {\n const origins = options.origins;\n if (!Array.isArray(origins) || origins.length === 0 || !origins.every(originurl => ishttpsurl(originurl))) return { allowed: false, reason: \"A reviewed non-empty list of HTTPS origins is required in options.\" };\n }\n if (step.kind === \"reopentab\" && step.value !== undefined && !ishttpsurl(step.value)) return { allowed: false, reason: \"The reviewed reopen url must use HTTPS.\" };\n if (step.kind === \"navrate\") {\n const limitcheck = validateratelimit(options.ratelimit);\n if (!limitcheck.allowed) return limitcheck;\n }\n if (step.kind === \"checksafe\" && !ishttpsurl(step.value)) return { allowed: false, reason: \"A reviewed HTTPS url is required for the safety check.\" };\n if (step.kind === \"batchopen\") {\n const listcheck = validateurllist(options, \"urls\");\n if (!listcheck.allowed) return listcheck;\n }\n if (istabscommandkind(step.kind)) {\n const tabscheck = validatetabsgrammar(step, options);\n if (!tabscheck.allowed) return tabscheck;\n }\n if (isformkind(step.kind)) {\n const formcheck = validateformgrammar(step, options);\n if (!formcheck.allowed) return formcheck;\n }\n if (isdatasetkind(step.kind)) {\n const datacheck = validatedatagrammar(step, options, origin);\n if (!datacheck.allowed) return datacheck;\n }\n if (isfileskind(step.kind)) {\n const filescheck = validatefilesgrammar(step, options);\n if (!filescheck.allowed) return filescheck;\n }\n if (iscapturekind(step.kind)) {\n const capturecheck = validatecapturegrammar(step, options);\n if (!capturecheck.allowed) return capturecheck;\n }\n if (ismediakind(step.kind)) {\n const mediacheck = validatemediagrammar(step, options);\n if (!mediacheck.allowed) return mediacheck;\n }\n if (step.kind === \"tabcreate\") {\n if (options.background !== undefined && typeof options.background !== \"boolean\") return { allowed: false, reason: \"The reviewed background flag must be a boolean.\" };\n if (options.window !== undefined && (typeof options.window !== \"number\" || !Number.isInteger(options.window) || options.window < 0)) return { allowed: false, reason: \"The reviewed target window id must be a non-negative integer.\" };\n }\n if (step.kind === \"windowcreate\") {\n for (const field of [\"left\", \"top\", \"width\", \"height\"]) {\n if (options[field] !== undefined && (typeof options[field] !== \"number\" || !Number.isFinite(options[field]))) return { allowed: false, reason: `The reviewed window ${field} must be a number.` };\n }\n if (options.state !== undefined && ![\"normal\", \"maximized\", \"minimized\", \"fullscreen\"].includes(options.state as string)) return { allowed: false, reason: \"The reviewed window state must be normal, maximized, minimized or fullscreen.\" };\n }\n return { allowed: true };\n}\n\n/** Shared session gate: a live, unpaused session that still matches the active tab. */\nfunction sessiongate(input: { session: agentsession | undefined; tabid: number; origin: string; now: number; action: string }): policyevaluation {\n if (!input.session || input.session.stoppedat) return { allowed: false, reason: \"No active browser session exists.\" };\n if (input.session.expiresat <= input.now) return { allowed: false, reason: \"The browser session has expired.\" };\n if (input.session.pausedat) return { allowed: false, reason: `The browser session is paused and cannot ${input.action}.` };\n if (input.session.tabid !== input.tabid || input.session.origin !== input.origin) return { allowed: false, reason: `The ${input.action} is outside the approved tab or origin.` };\n return { allowed: true };\n}\n\n/** Applies the consent gate immediately before an action reaches the page bridge. */\nexport function canexecute(input: { session: agentsession | undefined; plan: agentplan | undefined; step: toolstep; tabid: number; origin: string; now?: number; verdicts?: safetyverdict[] }): policyevaluation {\n const now = input.now ?? Date.now();\n const gate = sessiongate({ session: input.session, tabid: input.tabid, origin: input.origin, now, action: \"execute an action\" });\n if (!gate.allowed) return gate;\n if (!input.plan || input.plan.state !== \"approved\") return { allowed: false, reason: \"The plan has not received explicit approval.\" };\n if (input.plan.expiresat <= now) return { allowed: false, reason: \"The approved plan has expired.\" };\n if ((input.step.kind === \"pierceshadow\" || input.step.kind === \"enterframe\") && !origingranted(input.session, input.origin)) return { allowed: false, reason: \"The shadow or frame step is outside the session origin grants.\" };\n if (input.step.kind === \"readjson\" && !origingranted(input.session, input.origin)) return { allowed: false, reason: \"The json state read is outside the session origin grants.\" };\n if (isexportkind(input.step.kind)) {\n const exportgate = exportgranted(input.session, input.origin);\n if (!exportgate.allowed) return exportgate;\n }\n if (input.step.kind === \"navlist\") {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(input.step); } catch { options = {}; }\n for (const url of Array.isArray(options.urls) ? options.urls : []) {\n if (typeof url !== \"string\") continue;\n const navigation = navigationgranted(input.session, url);\n if (!navigation.allowed) return navigation;\n }\n }\n if (islayoutkind(input.step.kind) && !layoutmutationgranted(input.session, now).allowed) return { allowed: false, reason: \"Group and layout mutations stay inside the active session.\" };\n if (input.step.kind === \"submitform\" || input.step.kind === \"retryform\") {\n if (!input.plan) return { allowed: false, reason: \"Form submission requires an asksubmit review step before it.\" };\n const reviewgate = submitreviewgranted(input.plan.steps, input.step.id);\n if (!reviewgate.allowed) return reviewgate;\n }\n if (input.step.kind === \"consentpassword\") {\n const consentgate = passwordconsentgranted(input.step);\n if (!consentgate.allowed) return consentgate;\n }\n if (input.step.kind === \"readclipboard\") {\n const clipgate = clipboardconsentgranted(input.step);\n if (!clipgate.allowed) return clipgate;\n }\n if (input.step.kind === \"interceptmime\" && !origingranted(input.session, input.origin)) return { allowed: false, reason: \"The download interception is outside the session origin grants.\" };\n if (iscapturekind(input.step.kind)) {\n const capturegatecheck = capturegate(input.session, input.tabid, input.origin, now);\n if (!capturegatecheck.allowed) return capturegatecheck;\n let captureoptions: Record<string, unknown> = {};\n try { captureoptions = parseoptions(input.step); } catch { captureoptions = {}; }\n const target = (captureoptions.capture as Record<string, unknown> | undefined)?.exporttarget;\n if (target !== undefined && target !== \"memory\" && target !== \"download\" && target !== \"clipboard\") return { allowed: false, reason: \"The capture export target must be memory, download or clipboard.\" };\n }\n if (ismediakind(input.step.kind)) {\n const mediagatecheck = mediagate(input.session, input.tabid, input.origin, now);\n if (!mediagatecheck.allowed) return mediagatecheck;\n }\n if (isrecordingkind(input.step.kind)) {\n const recordinggate = recordingconsentgranted(input.step);\n if (!recordinggate.allowed) return recordinggate;\n }\n if (input.step.kind === \"openlink\" || input.step.kind === \"openprivate\" || input.step.kind === \"batchopen\" || input.step.kind === \"prefetch\" || input.step.kind === \"deeplink\" || input.step.kind === \"reopentab\") {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(input.step); } catch { options = {}; }\n const grammar = validatestep(input.step, input.origin);\n if (!grammar.allowed) return grammar;\n const grants = input.session?.grants ?? [input.session?.origin ?? input.origin];\n const targets: unknown[] = input.step.kind === \"batchopen\" || input.step.kind === \"prefetch\" ? (Array.isArray(options.urls) ? options.urls : []) : input.step.kind === \"reopentab\" ? [input.step.value] : [(options.navtarget as Record<string, unknown> | undefined)?.url];\n for (const target of targets) {\n if (typeof target !== \"string\" || !target) continue;\n const verified = originverified(target, grants, input.verdicts ?? []);\n if (!verified.allowed) return verified;\n }\n }\n return validatestep(input.step, input.origin);\n}\n\n/** Allows a non-mutating, temporary target preview during plan review. */\nexport function canpreview(input: { session: agentsession | undefined; plan: agentplan | undefined; step: toolstep; tabid: number; origin: string; now?: number }): policyevaluation {\n const now = input.now ?? Date.now();\n const gate = sessiongate({ session: input.session, tabid: input.tabid, origin: input.origin, now, action: \"preview a target\" });\n if (!gate.allowed) return gate;\n if (!input.plan || ![\"pending\", \"approved\"].includes(input.plan.state)) return { allowed: false, reason: \"Only a reviewed pending or approved plan can be previewed.\" };\n if (input.plan.expiresat <= now) return { allowed: false, reason: \"The reviewed plan has expired.\" };\n let options: Record<string, unknown> = {};\n try { options = parseoptions(input.step); } catch { options = {}; }\n if (!targetactions.has(input.step.kind) && options.targetref === undefined) return { allowed: false, reason: \"Only a target-based action can be previewed.\" };\n return validatestep(input.step, input.origin);\n}\n", "import type { toolstep } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\n\n/**\n * Mutating page interactions for reviewed steps.\n * Every correlated rule for pointer, key, drag, upload, form, attribute, storage and evaluation actions lives in this file.\n */\n\nexport type stepresult = { ok: boolean; summary: string; details?: Record<string, unknown> };\n\nfunction events(target: Element): void {\n target.dispatchEvent(new Event(\"input\", { bubbles: true }));\n target.dispatchEvent(new Event(\"change\", { bubbles: true }));\n}\n\nfunction modifiers(options: Record<string, unknown>): string[] {\n return Array.isArray(options.modifiers) ? options.modifiers.filter((item): item is string => typeof item === \"string\") : [];\n}\n\nfunction keyevent(type: \"keydown\" | \"keypress\" | \"keyup\", key: string, mods: string[]): KeyboardEvent {\n const code = key.length === 1 ? `Key${key.toUpperCase()}` : key;\n return new KeyboardEvent(type, { key, code, bubbles: true, cancelable: true, composed: true, ctrlKey: mods.includes(\"ctrl\"), shiftKey: mods.includes(\"shift\"), altKey: mods.includes(\"alt\"), metaKey: mods.includes(\"meta\") });\n}\n\nfunction fieldlike(target: Element | null): HTMLInputElement | HTMLTextAreaElement | null {\n return target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement ? target : null;\n}\n\nfunction stringify(value: unknown): unknown {\n try { return JSON.parse(JSON.stringify(value)) ?? null; } catch { return String(value); }\n}\n\n/** Runs one mutating page action after the background policy gate and a fresh target check. */\nexport function runpageaction(step: toolstep, target: Element | null): stepresult | Promise<stepresult> {\n const options = (() => { try { return parseoptions(step); } catch { return {} as Record<string, unknown>; } })();\n switch (step.kind) {\n case \"presskey\": {\n const receiver = target instanceof HTMLElement ? target : document.activeElement instanceof HTMLElement ? document.activeElement : document.body;\n const key = step.value ?? \"\";\n const mods = modifiers(options);\n receiver.dispatchEvent(keyevent(\"keydown\", key, mods));\n receiver.dispatchEvent(keyevent(\"keypress\", key, mods));\n receiver.dispatchEvent(keyevent(\"keyup\", key, mods));\n return { ok: true, summary: `Key ${key} delivered with ${mods.length} modifier${mods.length === 1 ? \"\" : \"s\"}.` };\n }\n case \"clickdeep\": {\n if (!(target instanceof HTMLElement)) return { ok: false, summary: \"Action target is no longer available.\" };\n target.dispatchEvent(new PointerEvent(\"pointerdown\", { bubbles: true, cancelable: true, composed: true }));\n target.dispatchEvent(new MouseEvent(\"mousedown\", { bubbles: true, cancelable: true }));\n target.dispatchEvent(new PointerEvent(\"pointerup\", { bubbles: true, cancelable: true, composed: true }));\n target.dispatchEvent(new MouseEvent(\"mouseup\", { bubbles: true, cancelable: true }));\n target.click();\n return { ok: true, summary: \"Full pointer click sequence delivered.\" };\n }\n case \"rightclick\": {\n if (!(target instanceof HTMLElement)) return { ok: false, summary: \"Action target is no longer available.\" };\n const init: MouseEventInit = { bubbles: true, cancelable: true, button: 2, buttons: 2 };\n target.dispatchEvent(new PointerEvent(\"pointerdown\", { ...init, composed: true }));\n target.dispatchEvent(new MouseEvent(\"mousedown\", init));\n target.dispatchEvent(new MouseEvent(\"contextmenu\", init));\n return { ok: true, summary: \"Context menu events delivered.\" };\n }\n case \"doubleclick\": {\n if (!(target instanceof HTMLElement)) return { ok: false, summary: \"Action target is no longer available.\" };\n target.click();\n target.click();\n target.dispatchEvent(new MouseEvent(\"dblclick\", { bubbles: true, cancelable: true, detail: 2 }));\n return { ok: true, summary: \"Double click sequence delivered.\" };\n }\n case \"drag\": {\n if (!(target instanceof HTMLElement)) return { ok: false, summary: \"Drag source is no longer available.\" };\n const destination = document.querySelector(step.value ?? \"\");\n if (!destination) return { ok: false, summary: \"Drag destination is no longer available.\" };\n const transfer = new DataTransfer();\n if (typeof options.data === \"string\") transfer.setData(\"text/plain\", options.data);\n target.dispatchEvent(new DragEvent(\"dragstart\", { bubbles: true, cancelable: true, dataTransfer: transfer }));\n destination.dispatchEvent(new DragEvent(\"dragenter\", { bubbles: true, cancelable: true, dataTransfer: transfer }));\n destination.dispatchEvent(new DragEvent(\"dragover\", { bubbles: true, cancelable: true, dataTransfer: transfer }));\n destination.dispatchEvent(new DragEvent(\"drop\", { bubbles: true, cancelable: true, dataTransfer: transfer }));\n target.dispatchEvent(new DragEvent(\"dragend\", { bubbles: true, cancelable: true, dataTransfer: transfer }));\n return { ok: true, summary: \"Drag and drop sequence delivered.\" };\n }\n case \"drop\": {\n if (!(target instanceof HTMLElement)) return { ok: false, summary: \"Drop zone is no longer available.\" };\n const transfer = new DataTransfer();\n transfer.setData(\"text/plain\", step.value ?? \"\");\n target.dispatchEvent(new DragEvent(\"dragenter\", { bubbles: true, cancelable: true, dataTransfer: transfer }));\n target.dispatchEvent(new DragEvent(\"dragover\", { bubbles: true, cancelable: true, dataTransfer: transfer }));\n target.dispatchEvent(new DragEvent(\"drop\", { bubbles: true, cancelable: true, dataTransfer: transfer }));\n return { ok: true, summary: \"Drop payload delivered.\" };\n }\n case \"upload\": {\n if (!(target instanceof HTMLInputElement) || target.type !== \"file\") return { ok: false, summary: \"Target is not a file input.\" };\n const transfer = new DataTransfer();\n transfer.items.add(new File([typeof options.content === \"string\" ? options.content : \"\"], step.value ?? \"upload\", { type: typeof options.type === \"string\" ? options.type : \"text/plain\" }));\n target.files = transfer.files;\n events(target);\n return { ok: true, summary: `Uploaded ${step.value ?? \"file\"} into the reviewed input.` };\n }\n case \"clear\": {\n const field = fieldlike(target);\n if (!field) return { ok: false, summary: \"Target cannot hold a value.\" };\n field.value = \"\";\n events(field);\n return { ok: true, summary: \"Field cleared.\" };\n }\n case \"check\":\n case \"uncheck\":\n case \"toggle\": {\n if (!(target instanceof HTMLInputElement) || (target.type !== \"checkbox\" && target.type !== \"radio\")) return { ok: false, summary: \"Target is not a checkbox or radio control.\" };\n if (step.kind === \"uncheck\" && target.type === \"radio\") return { ok: false, summary: \"A radio control cannot be unchecked.\" };\n target.checked = step.kind === \"toggle\" ? !target.checked : step.kind === \"check\";\n events(target);\n return { ok: true, summary: `Control is now ${target.checked ? \"checked\" : \"unchecked\"}.` };\n }\n case \"submit\": {\n const form = target instanceof HTMLFormElement ? target : target instanceof HTMLElement ? target.closest(\"form\") : null;\n if (!form) return { ok: false, summary: \"No form owns the reviewed target.\" };\n try { form.requestSubmit(target instanceof HTMLFormElement ? undefined : (target as HTMLElement)); } catch { form.submit(); }\n return { ok: true, summary: \"Form submission requested.\" };\n }\n case \"setattribute\": {\n if (!target) return { ok: false, summary: \"Action target is no longer available.\" };\n const name = typeof options.name === \"string\" ? options.name : \"\";\n target.setAttribute(name, typeof options.value === \"string\" ? options.value : \"\");\n return { ok: true, summary: `Attribute ${name} set.` };\n }\n case \"removeattribute\": {\n if (!target) return { ok: false, summary: \"Action target is no longer available.\" };\n const name = step.value ?? \"\";\n target.removeAttribute(name);\n return { ok: true, summary: `Attribute ${name} removed.` };\n }\n case \"writestorage\": {\n try {\n localStorage.setItem(typeof options.key === \"string\" ? options.key : \"\", typeof options.value === \"string\" ? options.value : \"\");\n return { ok: true, summary: `Local storage entry ${String(options.key)} written.` };\n } catch (error) { return { ok: false, summary: `Local storage refused the write: ${error instanceof Error ? error.message : String(error)}` }; }\n }\n case \"evaluate\": {\n try {\n let outcome: unknown;\n try { outcome = new Function(`\"use strict\"; return (${step.value ?? \"undefined\"});`)(); } catch { outcome = new Function(`\"use strict\"; ${step.value ?? \"\"}`)(); }\n return { ok: true, summary: `Reviewed expression returned ${outcome === undefined ? \"no value\" : \"a value\"}.`, details: { result: stringify(outcome) } };\n } catch (error) { return { ok: false, summary: `Reviewed expression failed: ${error instanceof Error ? error.message : String(error)}` }; }\n }\n case \"fullscreen\": {\n const element = target instanceof HTMLElement ? target : document.documentElement;\n return document.fullscreenElement === element\n ? document.exitFullscreen().then(() => ({ ok: true, summary: \"Fullscreen state cleared.\" }) as stepresult)\n : element.requestFullscreen().then(() => ({ ok: true, summary: \"Fullscreen state entered.\" }) as stepresult).catch(error => ({ ok: false, summary: `Fullscreen was refused: ${error instanceof Error ? error.message : String(error)}` }));\n }\n default: return { ok: false, summary: \"Unsupported page action.\" };\n }\n}\n", "/**\n * Xpath resolution subset for reviewed steps.\n * Every correlated rule for expression parsing, node trees and evaluation of the supported xpath grammar lives in this file.\n * The engine supports absolute and descendant steps, tag or wildcard names, attribute predicates, text predicates and positional predicates.\n */\n\n/** Serializable dom node used by the xpath engine; the live glue attaches the element. */\nexport interface xnode {\n tag: string;\n attributes: Record<string, string>;\n text: string;\n children: xnode[];\n element?: Element;\n}\n\ntype xpathpredicate =\n | { kind: \"attr\"; name: string; value?: string; contains?: boolean }\n | { kind: \"text\"; value: string; contains?: boolean }\n | { kind: \"position\"; index: number };\n\ninterface xpathstep {\n descendant: boolean;\n tag: string;\n predicates: xpathpredicate[];\n}\n\nfunction owntext(element: Element): string {\n let combined = \"\";\n for (const node of element.childNodes) if (node.nodeType === Node.TEXT_NODE) combined += node.textContent ?? \"\";\n return combined.replace(/\\s+/g, \" \").trim();\n}\n\nfunction attributesof(element: Element): Record<string, string> {\n const attributes: Record<string, string> = {};\n for (const attribute of [...element.attributes]) attributes[attribute.name] = attribute.value;\n return attributes;\n}\n\nfunction wrap(element: Element): xnode {\n return { tag: element.tagName.toLowerCase(), attributes: attributesof(element), text: owntext(element), children: [...element.children].map(wrap), element };\n}\n\n/** Builds the serializable node tree of one live document for the xpath engine. */\nexport function buildxtree(root: Document): xnode {\n return { tag: \"#document\", attributes: {}, text: \"\", children: root.documentElement ? [wrap(root.documentElement)] : [] };\n}\n\n/** Parses one predicate body into the supported predicate shapes. */\nfunction parsepredicate(raw: string): xpathpredicate | null {\n const body = raw.trim();\n let match = /^@([\\w-]+)$/.exec(body);\n if (match) return { kind: \"attr\", name: match[1] as string };\n match = /^@([\\w-]+)\\s*=\\s*['\"]([^'\"]*)['\"]$/.exec(body);\n if (match) return { kind: \"attr\", name: match[1] as string, value: match[2] as string };\n match = /^contains\\(\\s*@([\\w-]+)\\s*,\\s*['\"]([^'\"]*)['\"]\\s*\\)$/.exec(body);\n if (match) return { kind: \"attr\", name: match[1] as string, value: match[2] as string, contains: true };\n match = /^text\\(\\)\\s*=\\s*['\"]([^'\"]*)['\"]$/.exec(body);\n if (match) return { kind: \"text\", value: match[1] as string };\n match = /^contains\\(\\s*text\\(\\)\\s*,\\s*['\"]([^'\"]*)['\"]\\s*\\)$/.exec(body);\n if (match) return { kind: \"text\", value: match[1] as string, contains: true };\n match = /^(\\d+)$/.exec(body);\n if (match) return { kind: \"position\", index: Number.parseInt(match[1] as string, 10) };\n return null;\n}\n\n/** Parses the reviewed xpath expression into evaluation steps; unsupported syntax is refused. */\nexport function parsexpath(expression: string): xpathstep[] {\n const trimmed = expression.trim();\n if (!trimmed.startsWith(\"/\")) throw new Error(\"The reviewed xpath expression must start with a slash.\");\n const steps: xpathstep[] = [];\n let index = 0;\n while (index < trimmed.length) {\n if (trimmed[index] !== \"/\") throw new Error(\"The reviewed xpath expression contains an unsupported segment.\");\n let slashes = 0;\n while (index < trimmed.length && trimmed[index] === \"/\") { slashes += 1; index += 1; }\n const start = index;\n let quote = \"\";\n while (index < trimmed.length) {\n const character = trimmed[index];\n if (quote) { if (character === quote) quote = \"\"; }\n else if (character === \"'\" || character === '\"') quote = character;\n else if (character === \"/\") break;\n index += 1;\n }\n const body = trimmed.slice(start, index);\n if (!body) throw new Error(\"The reviewed xpath expression contains an empty step.\");\n const parsed = /^(\\*|[a-zA-Z][\\w-]*)((?:\\[[^\\]]*\\])*)$/.exec(body);\n if (!parsed) throw new Error(`The reviewed xpath step ${body} is not supported.`);\n const predicates: xpathpredicate[] = [];\n const pattern = /\\[([^\\]]*)\\]/g;\n let predicate: RegExpExecArray | null;\n while ((predicate = pattern.exec(parsed[2] ?? \"\")) !== null) {\n const parsedpredicate = parsepredicate(predicate[1] as string);\n if (!parsedpredicate) throw new Error(`The reviewed xpath predicate [${predicate[1]}] is not supported.`);\n predicates.push(parsedpredicate);\n }\n steps.push({ descendant: slashes > 1, tag: (parsed[1] as string).toLowerCase(), predicates });\n }\n return steps;\n}\n\nfunction descendants(node: xnode, includeself: boolean): xnode[] {\n const result: xnode[] = includeself ? [node] : [];\n for (const child of node.children) { result.push(child); result.push(...descendants(child, false)); }\n return result;\n}\n\nfunction applypredicates(nodes: xnode[], predicates: xpathpredicate[]): xnode[] {\n let result = nodes;\n for (const predicate of predicates) {\n if (predicate.kind === \"position\") {\n const entry = result[predicate.index - 1];\n result = entry ? [entry] : [];\n continue;\n }\n result = result.filter(node => {\n if (predicate.kind === \"attr\") {\n const value = node.attributes[predicate.name];\n if (value === undefined) return false;\n if (predicate.value === undefined) return true;\n return predicate.contains ? value.includes(predicate.value) : value === predicate.value;\n }\n return predicate.contains ? node.text.includes(predicate.value) : node.text === predicate.value;\n });\n }\n return result;\n}\n\n/** Evaluates the supported xpath subset against a serializable node tree and returns every matched node in document order. */\nexport function evaluatexpath(root: xnode, expression: string): xnode[] {\n const steps = parsexpath(expression);\n let current: xnode[] = [root];\n let first = true;\n for (const step of steps) {\n let matched: xnode[] = [];\n for (const node of current) {\n const pool = step.descendant ? descendants(node, first) : node.children;\n matched = matched.concat(pool.filter(candidate => candidate.tag === step.tag || step.tag === \"*\"));\n }\n current = applypredicates(matched, step.predicates);\n first = false;\n }\n return current;\n}\n", "import { parseoptions, resolutionverdict } from \"../policy.js\";\nimport type { clickablemap, mapentry, resolvedtarget, targetmode, toolstep } from \"../types.js\";\nimport { buildxtree, evaluatexpath } from \"./pagexpath.js\";\n\n/**\n * Target resolution engine for reviewed steps.\n * Every correlated rule for element summaries, targetref modes, ambiguity reports, shadow piercing, frame walking and the numbered clickable map lives in this file.\n */\n\n/** Descriptive fields shared by every resolution candidate; the live dom glue attaches the element. */\nexport interface candidatefields {\n tag: string;\n id: string;\n role: string;\n name: string;\n label: string;\n text: string;\n selector: string;\n}\n\n/** One live dom candidate: descriptive fields plus the element itself. */\nexport interface livecandidate extends candidatefields {\n element: Element;\n}\n\n/** Serializable description of one document with nested frames; the glue attaches the live document. */\nexport interface framedescription {\n frames: frameentry[];\n live?: Document;\n}\n\n/** One nested frame: same origin frames expose their document, cross origin frames do not. */\nexport interface frameentry {\n sameorigin: boolean;\n document?: framedescription;\n}\n\n/** Serializable scope tree: one scope's candidates plus the open shadow scopes nested inside it. */\nexport interface scopetree<T extends candidatefields = livecandidate> {\n host?: T;\n candidates: T[];\n shadows: scopetree<T>[];\n}\n\nexport function clean(value: string): string {\n return value.replace(/\\s+/g, \" \").trim();\n}\n\nfunction cssescape(value: string): string {\n return typeof CSS !== \"undefined\" && typeof CSS.escape === \"function\" ? CSS.escape(value) : value.replace(/[^a-zA-Z0-9_-]/g, \"\\\\$&\");\n}\n\n/** Computes the accessible style label of an element from aria hints, linked labels, title and content. */\nexport function elementlabel(element: Element): string {\n const aria = element.getAttribute(\"aria-label\");\n let linked = \"\";\n const labelledby = element.getAttribute(\"aria-labelledby\");\n if (labelledby) {\n try {\n const owner = element.ownerDocument?.getElementById(labelledby);\n if (owner) linked = owner.textContent ?? \"\";\n } catch { /* detached documents refuse lookups; the label falls back */ }\n }\n let forlabel = \"\";\n if (element.id) {\n try {\n const label = element.ownerDocument?.querySelector(`label[for=\"${cssescape(element.id)}\"]`);\n if (label instanceof HTMLElement) forlabel = label.textContent ?? \"\";\n } catch { /* the document may be detached; the label falls back */ }\n }\n return clean(aria || linked || forlabel || element.getAttribute(\"title\") || element.textContent || \"\");\n}\n\n/** Computes the implicit aria role of common elements when no explicit role attribute exists. */\nexport function implicitrole(element: Element): string {\n const tag = element.tagName.toLowerCase();\n if (tag === \"button\") return \"button\";\n if (tag === \"a\" && element.getAttribute(\"href\")) return \"link\";\n if (tag === \"select\") return \"combobox\";\n if (tag === \"textarea\") return \"textbox\";\n if (tag === \"details\") return \"group\";\n if (tag === \"input\") {\n const type = element.getAttribute(\"type\") ?? \"text\";\n if (type === \"checkbox\") return \"checkbox\";\n if (type === \"radio\") return \"radio\";\n if (type === \"button\" || type === \"submit\" || type === \"reset\") return \"button\";\n if (type === \"range\") return \"slider\";\n return \"textbox\";\n }\n return \"\";\n}\n\n/** Builds the css selector that re-finds one element inside its document. */\nexport function elementselector(element: Element): string {\n if (element.id) return `#${cssescape(element.id)}`;\n const role = element.getAttribute(\"role\");\n const name = element.getAttribute(\"name\");\n if (role && name) return `[role=\"${cssescape(role)}\"][name=\"${cssescape(name)}\"]`;\n if (name) return `${element.tagName.toLowerCase()}[name=\"${cssescape(name)}\"]`;\n const tag = element.tagName.toLowerCase();\n const parent = element.parentElement;\n if (!parent) return tag;\n const peers = [...parent.children].filter(node => node.tagName === element.tagName);\n return `${tag}:nth-of-type(${peers.indexOf(element) + 1})`;\n}\n\n/** Own text of an element: only its direct text nodes, so parents do not shadow their children. */\nexport function owntext(element: Element): string {\n let combined = \"\";\n for (const node of element.childNodes) if (node.nodeType === Node.TEXT_NODE) combined += node.textContent ?? \"\";\n return clean(combined);\n}\n\n/** Summarizes one live element into the candidate shape used by every resolution mode. */\nexport function summarize(element: Element): livecandidate {\n return {\n tag: element.tagName.toLowerCase(),\n id: element.id,\n role: element.getAttribute(\"role\")?.toLowerCase() || implicitrole(element),\n name: element.getAttribute(\"name\") ?? \"\",\n label: elementlabel(element),\n text: owntext(element),\n selector: elementselector(element),\n element,\n };\n}\n\nconst clickableselector = \"a[href], button, input, textarea, select, summary, [role=button], [role=link], [role=combobox], [role=option], [role=checkbox], [role=radio], [role=switch], [role=tab]\";\n\n/** Collects every clickable candidate in document order. */\nexport function collectclickable(root: ParentNode): livecandidate[] {\n return [...root.querySelectorAll(clickableselector)].map(summarize);\n}\n\n/** Collects every element as a resolution candidate in document order. */\nexport function collectcandidates(root: ParentNode): livecandidate[] {\n return [...root.querySelectorAll(\"*\")].map(summarize);\n}\n\n/** Matches candidates whose visible own text or label equals or contains the reviewed text. */\nexport function matchtext<T extends candidatefields>(candidates: T[], text: string): T[] {\n const wanted = clean(text).toLowerCase();\n if (!wanted) return [];\n const exact = candidates.filter(candidate => candidate.text.toLowerCase() === wanted || candidate.label.toLowerCase() === wanted);\n if (exact.length > 0) return exact;\n return candidates.filter(candidate => candidate.text.toLowerCase().includes(wanted) || candidate.label.toLowerCase().includes(wanted));\n}\n\n/** Matches candidates by the aria role and accessible name pair. */\nexport function matcharia<T extends candidatefields>(candidates: T[], role: string, name: string): T[] {\n const wantedrole = clean(role).toLowerCase();\n const wantedname = clean(name).toLowerCase();\n if (!wantedrole || !wantedname) return [];\n return candidates.filter(candidate => candidate.role.toLowerCase() === wantedrole && (candidate.label.toLowerCase() === wantedname || candidate.name.toLowerCase() === wantedname));\n}\n\n/** Matches candidates by accessible name, preferring clickable elements when several share one name. */\nexport function matchname<T extends candidatefields>(candidates: T[], name: string, clickable?: (candidate: T) => boolean): T[] {\n const wanted = clean(name).toLowerCase();\n if (!wanted) return [];\n const matches = candidates.filter(candidate => candidate.label.toLowerCase() === wanted || candidate.name.toLowerCase() === wanted);\n if (matches.length > 1 && clickable) {\n const interactive = matches.filter(clickable);\n if (interactive.length === 1) return interactive;\n }\n return matches;\n}\n\n/** Matches one clickable map number; map numbers are one based and stable inside one observation version. */\nexport function matchindex<T extends candidatefields>(candidates: T[], index: number): T[] {\n if (!Number.isInteger(index) || index < 1) return [];\n const entry = candidates[index - 1];\n return entry ? [entry] : [];\n}\n\n/** Builds the numbered clickable map from clickable candidates in document order. */\nexport function buildclickablemap<T extends candidatefields>(candidates: T[], version: number, builtat = 0): clickablemap {\n const entries: mapentry[] = candidates.map((candidate, position) => ({ number: position + 1, selector: candidate.selector, role: candidate.role || candidate.tag, label: candidate.label, mode: \"selector\" as const }));\n return { version, entries, builtat };\n}\n\n/** Describes the nested frame structure of one live document; cross origin frames stay opaque. */\nexport function describeframes(root: Document): framedescription {\n const frames = [...root.querySelectorAll(\"iframe\")].map(frame => {\n let content: Document | null = null;\n try { content = frame.contentDocument; } catch { content = null; }\n let sameorigin = false;\n try { sameorigin = content !== null && frame.contentWindow?.location.origin === location.origin; } catch { sameorigin = false; }\n return sameorigin && content ? { sameorigin: true, document: describeframes(content) } : { sameorigin: false };\n });\n return { frames, live: root };\n}\n\n/** Walks a reviewed frame path through same origin frames and refuses cross origin or absent hops. */\nexport function walkframepath(root: framedescription, path: number[]): { ok: true; document: framedescription } | { ok: false; reason: string } {\n let current = root;\n for (const index of path) {\n if (!Number.isInteger(index) || index < 0) return { ok: false, reason: \"The reviewed frame path contains an invalid frame index.\" };\n const entry = current.frames[index];\n if (!entry) return { ok: false, reason: `Frame ${index} of the reviewed frame path is absent.` };\n if (!entry.sameorigin || !entry.document) return { ok: false, reason: `Frame ${index} of the reviewed frame path is cross origin and was refused.` };\n current = entry.document;\n }\n return { ok: true, document: current };\n}\n\n/** Describes one document or shadow root scope with every nested open shadow scope. */\nexport function describescopes(root: ParentNode): scopetree {\n const elements = [...root.querySelectorAll(\"*\")];\n const shadows: scopetree[] = [];\n for (const element of elements) {\n const shadow = element.shadowRoot;\n if (shadow) {\n const nested = describescopes(shadow);\n nested.host = summarize(element);\n shadows.push(nested);\n }\n }\n return { candidates: elements.map(summarize), shadows };\n}\n\n/** Searches one scope tree depth first for candidates matching the predicate, piercing open shadow scopes recursively. */\nexport function piercescopes<T extends candidatefields>(scope: scopetree<T>, match: (candidate: T) => boolean): T[] {\n const found: T[] = [];\n for (const candidate of scope.candidates) if (match(candidate)) found.push(candidate);\n for (const shadow of scope.shadows) found.push(...piercescopes(shadow, match));\n return found;\n}\n\n/** Resolves a reviewed selector chain through open shadow roots: each selector resolves inside the previous scope. */\nexport function queryshadowchain(root: ParentNode, selectors: string[]): Element | null {\n let scope: ParentNode = root;\n for (let position = 0; position < selectors.length; position += 1) {\n const found = scope.querySelector(selectors[position] as string);\n if (!found) return null;\n if (position === selectors.length - 1) return found;\n const shadow = found.shadowRoot;\n if (!shadow) return null;\n scope = shadow;\n }\n return null;\n}\n\n/** Finds the first element matching a selector in the scope or any nested open shadow root. */\nexport function queryscoped(root: ParentNode, selector: string): Element | null {\n const direct = root.querySelector(selector);\n if (direct) return direct;\n for (const element of [...root.querySelectorAll(\"*\")]) {\n const shadow = element.shadowRoot;\n if (shadow) {\n const found = queryscoped(shadow, selector);\n if (found) return found;\n }\n }\n return null;\n}\n\nfunction parseoptionssafe(step: toolstep): Record<string, unknown> {\n try { return parseoptions(step); } catch { return {}; }\n}\n\n/** Builds the matched element summary attached to step results for review. */\nexport function targetsummary(mode: targetmode, element: HTMLElement): resolvedtarget {\n const rect = element.getBoundingClientRect();\n return { mode, selector: elementselector(element), tag: element.tagName.toLowerCase(), label: elementlabel(element), geometry: { x: rect.x, y: rect.y, width: rect.width, height: rect.height } };\n}\n\nexport type stepresolution =\n | { status: \"none\" }\n | { status: \"resolved\"; element: HTMLElement; target: resolvedtarget }\n | { status: \"ambiguous\"; mode: targetmode; candidates: string[] }\n | { status: \"absent\"; mode?: targetmode };\n\nfunction singleresolution(mode: targetmode, matches: livecandidate[]): stepresolution {\n const verdict = resolutionverdict(matches.length);\n if (verdict === \"resolved\") {\n const winner = matches[0];\n if (winner && winner.element instanceof HTMLElement) return { status: \"resolved\", element: winner.element, target: targetsummary(mode, winner.element) };\n return { status: \"absent\", mode };\n }\n if (verdict === \"ambiguous\") return { status: \"ambiguous\", mode, candidates: matches.slice(0, 8).map(candidate => candidate.label || candidate.selector) };\n return { status: \"absent\", mode };\n}\n\n/** Resolves one reviewed targetref mode against the live dom in a single pass. */\nfunction resolvetargetref(reference: Record<string, unknown>, root: Document): stepresolution {\n const mode = reference.mode;\n if (mode === \"selector\") {\n const selector = typeof reference.selector === \"string\" ? reference.selector : \"\";\n const element = selector ? root.querySelector(selector) : null;\n return element instanceof HTMLElement ? { status: \"resolved\", element, target: targetsummary(\"selector\", element) } : { status: \"absent\", mode: \"selector\" };\n }\n if (mode === \"point\") {\n const x = Number(reference.x);\n const y = Number(reference.y);\n if (!Number.isFinite(x) || !Number.isFinite(y)) return { status: \"absent\", mode: \"point\" };\n const element = root.elementFromPoint(x, y);\n return element instanceof HTMLElement ? { status: \"resolved\", element, target: targetsummary(\"point\", element) } : { status: \"absent\", mode: \"point\" };\n }\n if (mode === \"xpath\") {\n const expression = typeof reference.xpath === \"string\" ? reference.xpath : \"\";\n if (!expression) return { status: \"absent\", mode: \"xpath\" };\n const matches = evaluatexpath(buildxtree(root), expression);\n const first = matches[0];\n return first?.element instanceof HTMLElement ? { status: \"resolved\", element: first.element, target: targetsummary(\"xpath\", first.element) } : { status: \"absent\", mode: \"xpath\" };\n }\n if (mode === \"index\") {\n const matches = matchindex(collectclickable(root), Number(reference.index));\n return singleresolution(\"index\", matches);\n }\n const candidates = collectcandidates(root);\n if (mode === \"text\") return singleresolution(\"text\", matchtext(candidates, typeof reference.text === \"string\" ? reference.text : \"\"));\n if (mode === \"aria\") return singleresolution(\"aria\", matcharia(candidates, typeof reference.role === \"string\" ? reference.role : \"\", typeof reference.name === \"string\" ? reference.name : \"\"));\n if (mode === \"name\") return singleresolution(\"name\", matchname(candidates, typeof reference.name === \"string\" ? reference.name : \"\"));\n return { status: \"absent\" };\n}\n\n/** Resolves the reviewed target of a step: the options targetref when present, otherwise the css target. */\nexport function resolvestep(step: toolstep, root: Document): stepresolution {\n const reference = parseoptionssafe(step).targetref;\n if (reference && typeof reference === \"object\" && !Array.isArray(reference)) return resolvetargetref(reference as Record<string, unknown>, root);\n if (!step.target?.trim()) return { status: \"none\" };\n const element = root.querySelector(step.target);\n if (element instanceof HTMLElement) return { status: \"resolved\", element, target: targetsummary(\"selector\", element) };\n return { status: \"absent\", mode: \"selector\" };\n}\n", "import type { toolstep } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\n\n/**\n * Read-only page observation for reviewed steps.\n * Every correlated rule for attribute, style, geometry, value, content, table, link, image, meta, form, storage reads, bounded-free waits, clickable maps and verify reads lives in this file.\n */\n\nimport type { stepresult } from \"./pageactions.js\";\nimport { buildclickablemap, collectclickable, elementlabel, elementselector } from \"./pageresolve.js\";\nimport { buildxtree, evaluatexpath } from \"./pagexpath.js\";\n\nconst highlightid = \"devthinkactionhighlight\";\n\nfunction clearhighlight(): void {\n document.getElementById(highlightid)?.remove();\n}\n\n/** Outlines one reviewed target without dispatching page events. */\nfunction highlighttarget(target: Element): stepresult {\n clearhighlight();\n const rect = target.getBoundingClientRect();\n const overlay = document.createElement(\"div\");\n overlay.id = highlightid;\n overlay.setAttribute(\"aria-hidden\", \"true\");\n Object.assign(overlay.style, { position: \"fixed\", left: `${Math.max(0, rect.left - 3)}px`, top: `${Math.max(0, rect.top - 3)}px`, width: `${rect.width + 6}px`, height: `${rect.height + 6}px`, border: \"3px solid #2f9e44\", borderRadius: \"6px\", pointerEvents: \"none\", zIndex: \"2147483647\", boxSizing: \"border-box\" });\n document.documentElement.append(overlay);\n window.setTimeout(clearhighlight, 5000);\n return { ok: true, summary: \"Target outlined for five seconds.\" };\n}\n\nfunction poll(root: Document, predicate: () => boolean, description: string, timeout: number): Promise<stepresult> {\n return new Promise(resolve => {\n const started = Date.now();\n const check = (): void => {\n if (predicate()) { resolve({ ok: true, summary: `${description} is now present on the page.` }); return; }\n if (timeout > 0 && Date.now() - started >= timeout) { resolve({ ok: false, summary: `${description} did not appear within ${timeout} milliseconds.` }); return; }\n window.setTimeout(check, 100);\n };\n check();\n });\n}\n\nfunction formstate(root: Document): Array<Record<string, unknown>> {\n return [...root.querySelectorAll(\"input, textarea, select\")].map(element => ({\n type: element.getAttribute(\"type\") ?? element.tagName.toLowerCase(),\n name: element.getAttribute(\"name\") ?? \"\",\n value: element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement ? element.value : \"\",\n ...(element instanceof HTMLInputElement && (element.type === \"checkbox\" || element.type === \"radio\") ? { checked: element.checked } : {}),\n }));\n}\n\n/** Runs one read-only page observation after the background policy gate. */\nexport function runpageread(step: toolstep, target: Element | null, root: Document = document): stepresult | Promise<stepresult> {\n const options = (() => { try { return parseoptions(step); } catch { return {} as Record<string, unknown>; } })();\n switch (step.kind) {\n case \"highlight\": {\n if (!target) return { ok: false, summary: \"Highlight target is no longer available.\" };\n return highlighttarget(target);\n }\n case \"readattribute\": {\n if (!target) return { ok: false, summary: \"Read target is no longer available.\" };\n const value = target.getAttribute(step.value ?? \"\");\n return value === null ? { ok: false, summary: `Attribute ${step.value} is absent.` } : { ok: true, summary: `Attribute ${step.value} read.`, details: { value } };\n }\n case \"readstyle\": {\n if (!target) return { ok: false, summary: \"Read target is no longer available.\" };\n const computed = getComputedStyle(target);\n const styles: Record<string, string> = {};\n for (let index = 0; index < computed.length; index += 1) { const property = computed.item(index); styles[property] = computed.getPropertyValue(property); }\n return { ok: true, summary: `Read ${computed.length} computed style properties.`, details: { styles } };\n }\n case \"readgeometry\": {\n if (!target) return { ok: false, summary: \"Read target is no longer available.\" };\n const rect = target.getBoundingClientRect();\n const geometry = { x: rect.x, y: rect.y, width: rect.width, height: rect.height, top: rect.top, right: rect.right, bottom: rect.bottom, left: rect.left };\n return { ok: true, summary: \"Target geometry read.\", details: { geometry } };\n }\n case \"readvalue\": {\n if (!(target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || target instanceof HTMLSelectElement)) return { ok: false, summary: \"Target does not hold a form value.\" };\n return { ok: true, summary: \"Form value read.\", details: { value: target.value } };\n }\n case \"readtext\": {\n if (!target) return { ok: false, summary: \"Read target is no longer available.\" };\n const text = target.textContent ?? \"\";\n return { ok: true, summary: `Read ${text.length} characters of text.`, details: { text } };\n }\n case \"readhtml\": {\n if (!target) return { ok: false, summary: \"Read target is no longer available.\" };\n return { ok: true, summary: \"Target markup read.\", details: { html: target.outerHTML } };\n }\n case \"countelements\": {\n const count = root.querySelectorAll(step.target ?? \"\").length;\n return { ok: true, summary: `Selector matches ${count} element${count === 1 ? \"\" : \"s\"}.`, details: { count } };\n }\n case \"readtable\": {\n if (!(target instanceof HTMLTableElement)) return { ok: false, summary: \"Read target is not a table element.\" };\n const rows = [...target.querySelectorAll(\"tr\")].map(row => [...row.querySelectorAll(\"th, td\")].map(cell => cell.textContent?.trim() ?? \"\"));\n const headers = rows[0] ?? [];\n const body = rows.slice(1);\n return { ok: true, summary: `Read table with ${headers.length} column${headers.length === 1 ? \"\" : \"s\"} and ${body.length} row${body.length === 1 ? \"\" : \"s\"}.`, details: { headers, rows: body } };\n }\n case \"readlinks\": {\n const links = [...root.querySelectorAll(\"a[href]\")].map(element => ({ text: element.textContent?.trim() ?? \"\", href: element.getAttribute(\"href\") ?? \"\" }));\n return { ok: true, summary: `Read ${links.length} link${links.length === 1 ? \"\" : \"s\"}.`, details: { links } };\n }\n case \"readimages\": {\n const images = [...root.querySelectorAll(\"img\")].map(element => ({ src: element.getAttribute(\"src\") ?? \"\", alt: element.getAttribute(\"alt\") ?? \"\" }));\n return { ok: true, summary: `Read ${images.length} image${images.length === 1 ? \"\" : \"s\"}.`, details: { images } };\n }\n case \"readmeta\": {\n const meta = [...root.querySelectorAll(\"meta\")].map(element => ({ name: element.getAttribute(\"name\") ?? \"\", property: element.getAttribute(\"property\") ?? \"\", content: element.getAttribute(\"content\") ?? \"\" }));\n return { ok: true, summary: `Read ${meta.length} meta entr${meta.length === 1 ? \"y\" : \"ies\"}.`, details: { meta } };\n }\n case \"readforms\": {\n const forms = formstate(root);\n return { ok: true, summary: `Read ${forms.length} form control${forms.length === 1 ? \"\" : \"s\"}.`, details: { forms } };\n }\n case \"readstorage\": {\n try {\n if (step.value) {\n const value = localStorage.getItem(step.value);\n return { ok: true, summary: `Read local storage entry ${step.value}.`, details: { value } };\n }\n const entries: Record<string, string | null> = {};\n for (let index = 0; index < localStorage.length; index += 1) { const key = localStorage.key(index); if (key !== null) entries[key] = localStorage.getItem(key); }\n return { ok: true, summary: `Read ${Object.keys(entries).length} local storage entr${Object.keys(entries).length === 1 ? \"y\" : \"ies\"}.`, details: { entries } };\n } catch (error) { return { ok: false, summary: `Local storage refused the read: ${error instanceof Error ? error.message : String(error)}` }; }\n }\n case \"waitfor\": {\n const selector = step.target ?? \"\";\n const timeout = typeof options.timeout === \"number\" ? options.timeout : 0;\n return poll(root, () => Boolean(root.querySelector(selector)), `Selector ${selector}`, timeout);\n }\n case \"waittext\": {\n const text = step.value ?? \"\";\n const timeout = typeof options.timeout === \"number\" ? options.timeout : 0;\n return poll(root, () => (root.body?.innerText ?? \"\").includes(text), `Text ${text}`, timeout);\n }\n case \"mapclicks\": {\n const candidates = collectclickable(root);\n const map = buildclickablemap(candidates, 0, 0);\n return { ok: true, summary: `Mapped ${map.entries.length} clickable element${map.entries.length === 1 ? \"\" : \"s\"}.`, details: { entries: map.entries } };\n }\n case \"verifyvisible\": {\n if (!target) return { ok: false, summary: \"Verify target is no longer available.\" };\n const rect = target.getBoundingClientRect();\n const rendered = rect.width > 0 && rect.height > 0;\n return { ok: rendered, summary: rendered ? `Target is rendered at ${Math.round(rect.x)},${Math.round(rect.y)} with size ${Math.round(rect.width)}x${Math.round(rect.height)}.` : \"Target is not rendered.\", details: { visible: rendered, geometry: { x: rect.x, y: rect.y, width: rect.width, height: rect.height } } };\n }\n case \"verifyenabled\": {\n if (!target) return { ok: false, summary: \"Verify target is no longer available.\" };\n const control = target as HTMLInputElement;\n const disabled = control.disabled === true || target.hasAttribute(\"disabled\");\n const readonly = control.readOnly === true || target.hasAttribute(\"readonly\");\n const enabled = !disabled && !readonly;\n return { ok: enabled, summary: enabled ? \"Target is enabled and writable.\" : disabled ? \"Target is disabled.\" : \"Target is readonly.\", details: { enabled, disabled, readonly } };\n }\n case \"resolvexpath\": {\n const reference = options.targetref as Record<string, unknown> | undefined;\n const expression = typeof reference?.xpath === \"string\" ? reference.xpath : \"\";\n if (!expression) return { ok: false, summary: \"The reviewed xpath expression is absent.\" };\n let matches: ReturnType<typeof evaluatexpath> = [];\n try { matches = evaluatexpath(buildxtree(root), expression); } catch (error) { return { ok: false, summary: `The reviewed xpath expression failed: ${error instanceof Error ? error.message : String(error)}` }; }\n const summaries = matches.map(node => ({ tag: node.tag, ...(node.element ? { selector: elementselector(node.element), label: elementlabel(node.element) } : {}) }));\n return { ok: matches.length > 0, summary: matches.length > 0 ? `Resolved ${matches.length} element${matches.length === 1 ? \"\" : \"s\"} for the reviewed xpath.` : \"The reviewed xpath matched no elements.\", details: { mode: \"xpath\", matches: summaries } };\n }\n default: return { ok: false, summary: \"Unsupported page read.\" };\n }\n}\n", "import type { keyholdstate, toolstep } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\nimport type { stepresult } from \"./pageactions.js\";\nimport { clean } from \"./pageresolve.js\";\n\n/**\n * Field and control interactions for reviewed steps.\n * Every correlated rule for timed typing, value setting, key holds, search submission, multi selects, radio choices, sliders, dates, colors, details sections and the hold registry lives in this file.\n */\n\n/** Builds the per keystroke schedule of one reviewed typetime step. */\nexport function typetimeschedule(text: string, delay: number): Array<{ key: string; delay: number }> {\n return [...text].map((character, position) => ({ key: character, delay: position === 0 ? 0 : delay }));\n}\n\n/** Appends reviewed text to the current field value. */\nexport function appendvalue(current: string, addition: string): string {\n return current + addition;\n}\n\n/** Event order delivered after one reviewed value change. */\nexport function valueevents(): string[] {\n return [\"input\", \"change\"];\n}\n\n/** Splits reviewed multi select values into present and missing entries against the declared options. */\nexport function multichoices(values: string[], options: Array<{ value: string; label: string }>): { present: string[]; missing: string[] } {\n const present: string[] = [];\n const missing: string[] = [];\n for (const value of values) {\n const option = options.find(candidate => candidate.value === value || candidate.label === value);\n if (option) present.push(option.value);\n else missing.push(value);\n }\n return { present, missing };\n}\n\n/** Picks the reviewed radio input by value or label from one radio group; the index of the match or minus one. */\nexport function radiochoice(inputs: Array<{ value: string; label: string }>, choice: string): number {\n return inputs.findIndex(candidate => candidate.value === choice || candidate.label === choice);\n}\n\n/** Clamps one reviewed slider value to the declared range and step grid. */\nexport function slidervalue(requested: number, min: number, max: number, step: number): number {\n const lower = Math.min(min, max);\n const upper = Math.max(min, max);\n const clamped = Math.min(upper, Math.max(lower, requested));\n if (!Number.isFinite(step) || step <= 0) return clamped;\n return Math.round((clamped - lower) / step) * step + lower;\n}\n\n/** Validates and normalizes one reviewed yyyy-mm-dd date. */\nexport function datevalue(requested: string): string | null {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(requested)) return null;\n const parts = requested.split(\"-\").map(part => Number.parseInt(part, 10));\n const year = parts[0];\n const month = parts[1];\n const day = parts[2];\n if (!year || !month || !day || month < 1 || month > 12 || day < 1 || day > 31) return null;\n return requested;\n}\n\n/** Validates and normalizes one reviewed #rrggbb color. */\nexport function colorvalue(requested: string): string | null {\n if (!/^#[0-9a-fA-F]{6}$/.test(requested)) return null;\n return requested.toLowerCase();\n}\n\n/** Decides whether one reviewed details section still needs opening. */\nexport function expandstate(open: boolean): { open: boolean; changed: boolean } {\n return open ? { open: true, changed: false } : { open: true, changed: true };\n}\n\n/** Records one held key under its hold id; a repeated active hold id is refused. */\nexport function presshold(holds: keyholdstate[], hold: keyholdstate): { holds: keyholdstate[]; ok: boolean } {\n if (holds.some(existing => existing.holdid === hold.holdid && existing.releasedat === undefined)) return { holds, ok: false };\n return { holds: [...holds, hold], ok: true };\n}\n\n/** Releases one held key by hold id, keeping the release timestamp. */\nexport function releasehold(holds: keyholdstate[], holdid: string, releasedat: number): { holds: keyholdstate[]; released?: keyholdstate } {\n let released: keyholdstate | undefined;\n const next = holds.map(hold => {\n if (hold.holdid !== holdid || hold.releasedat !== undefined) return hold;\n released = { ...hold, releasedat };\n return released;\n });\n return { holds: next, ...(released ? { released } : {}) };\n}\n\n/** Returns the keys currently held, optionally filtered to one tab. */\nexport function heldkeys(holds: keyholdstate[], tabid?: number): keyholdstate[] {\n return holds.filter(hold => hold.releasedat === undefined && (tabid === undefined || hold.tabid === undefined || hold.tabid === tabid));\n}\n\nfunction events(target: Element): void {\n target.dispatchEvent(new Event(\"input\", { bubbles: true }));\n target.dispatchEvent(new Event(\"change\", { bubbles: true }));\n}\n\nfunction modifiers(options: Record<string, unknown>): string[] {\n return Array.isArray(options.modifiers) ? options.modifiers.filter((item): item is string => typeof item === \"string\") : [];\n}\n\nfunction keyevent(type: \"keydown\" | \"keyup\", key: string, mods: string[]): KeyboardEvent {\n const code = key.length === 1 ? `Key${key.toUpperCase()}` : key;\n return new KeyboardEvent(type, { key, code, bubbles: true, cancelable: true, composed: true, ctrlKey: mods.includes(\"ctrl\"), shiftKey: mods.includes(\"shift\"), altKey: mods.includes(\"alt\"), metaKey: mods.includes(\"meta\") });\n}\n\nfunction fieldlike(target: Element | null): HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement | null {\n return target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || target instanceof HTMLSelectElement ? target : null;\n}\n\nfunction receiver(target: Element | null): HTMLElement {\n return target instanceof HTMLElement ? target : document.activeElement instanceof HTMLElement ? document.activeElement : document.body;\n}\n\nfunction wait(delay: number): Promise<void> {\n return new Promise(resolve => window.setTimeout(resolve, delay));\n}\n\n/** Focuses the reviewed target before typing; an explicit reviewed focus option forces or suppresses the focus. */\nfunction focuswhenneeded(target: Element, options: Record<string, unknown>): void {\n if (!(target instanceof HTMLElement)) return;\n if (options.focus === false) return;\n if (options.focus === true || document.activeElement !== target) target.focus();\n}\n\nfunction pollfor(predicate: () => boolean, description: string, timeout: number): Promise<stepresult> {\n return new Promise(resolve => {\n const started = Date.now();\n const check = (): void => {\n if (predicate()) { resolve({ ok: true, summary: `${description} is now present on the page.` }); return; }\n if (timeout > 0 && Date.now() - started >= timeout) { resolve({ ok: false, summary: `${description} did not appear within ${timeout} milliseconds.` }); return; }\n window.setTimeout(check, 100);\n };\n check();\n });\n}\n\n/** Runs one reviewed control interaction after the background policy gate and a fresh target check; frame routed steps receive their frame document as the root. */\nexport function runpagecontrol(step: toolstep, target: Element | null, root: Document = document): stepresult | Promise<stepresult> {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n switch (step.kind) {\n case \"typetime\": {\n const field = fieldlike(target);\n if (!field) return { ok: false, summary: \"Target cannot receive timed text.\" };\n const text = step.value ?? \"\";\n const delay = typeof options.delay === \"number\" && options.delay > 0 ? options.delay : 0;\n focuswhenneeded(field, options);\n const schedule = typetimeschedule(text, delay);\n return (async (): Promise<stepresult> => {\n for (const entry of schedule) {\n await wait(entry.delay);\n field.dispatchEvent(keyevent(\"keydown\", entry.key, []));\n field.dispatchEvent(new KeyboardEvent(\"keypress\", { key: entry.key, bubbles: true, cancelable: true }));\n field.value = `${field.value}${entry.key}`;\n field.dispatchEvent(new Event(\"input\", { bubbles: true }));\n }\n field.dispatchEvent(new Event(\"change\", { bubbles: true }));\n return { ok: true, summary: `Typed ${text.length} character${text.length === 1 ? \"\" : \"s\"} with a per keystroke delay of ${delay} milliseconds.` };\n })();\n }\n case \"appendtext\": {\n const field = fieldlike(target);\n if (!field) return { ok: false, summary: \"Target cannot hold a value.\" };\n focuswhenneeded(field, options);\n field.value = appendvalue(field.value, step.value ?? \"\");\n events(field);\n return { ok: true, summary: \"Reviewed text appended to the current field value.\" };\n }\n case \"setvalue\": {\n const field = fieldlike(target);\n if (!field) return { ok: false, summary: \"Target cannot hold a value.\" };\n focuswhenneeded(field, options);\n field.value = step.value ?? \"\";\n events(field);\n return { ok: true, summary: `Field value set through the dom property with ${valueevents().join(\" and \")} events.` };\n }\n case \"typeedit\": {\n if (!(target instanceof HTMLElement) || !target.isContentEditable) return { ok: false, summary: \"Target is not a content editable region.\" };\n focuswhenneeded(target, options);\n const text = step.value ?? \"\";\n return (async (): Promise<stepresult> => {\n for (const character of [...text]) {\n target.dispatchEvent(new InputEvent(\"beforeinput\", { bubbles: true, cancelable: true, data: character, inputType: \"insertText\" }));\n target.append(document.createTextNode(character));\n target.dispatchEvent(new InputEvent(\"input\", { bubbles: true, data: character, inputType: \"insertText\" }));\n }\n return { ok: true, summary: `Typed ${text.length} character${text.length === 1 ? \"\" : \"s\"} into the content editable region.` };\n })();\n }\n case \"keyhold\": {\n const key = step.value ?? \"\";\n const mods = modifiers(options);\n receiver(target).dispatchEvent(keyevent(\"keydown\", key, mods));\n const holdid = typeof options.holdid === \"string\" && options.holdid ? options.holdid : \"\";\n return { ok: true, summary: `Key ${key} pressed and held${holdid ? ` under hold id ${holdid}` : \"\"}.`, details: { ...(holdid ? { holdid } : {}), modifiers: mods } };\n }\n case \"keyrelease\": {\n const key = step.value ?? \"\";\n const mods = modifiers(options);\n receiver(target).dispatchEvent(keyevent(\"keyup\", key, mods));\n return { ok: true, summary: `Key ${key} released.`, details: { modifiers: mods } };\n }\n case \"submitsearch\": {\n const field = fieldlike(target);\n if (!field) return { ok: false, summary: \"Target is not a search field.\" };\n const results = typeof options.results === \"string\" ? options.results : \"\";\n const timeout = typeof options.timeout === \"number\" ? options.timeout : 0;\n focuswhenneeded(field, options);\n field.dispatchEvent(keyevent(\"keydown\", \"Enter\", []));\n field.dispatchEvent(new KeyboardEvent(\"keypress\", { key: \"Enter\", bubbles: true, cancelable: true }));\n field.dispatchEvent(keyevent(\"keyup\", \"Enter\", []));\n return pollfor(() => Boolean(document.querySelector(results)), `Results region ${results}`, timeout);\n }\n case \"selectmulti\": {\n if (!(target instanceof HTMLSelectElement) || !target.multiple) return { ok: false, summary: \"Target is not a multi select control.\" };\n const choices = [...target.options].map(option => ({ value: option.value, label: clean(option.textContent || option.value) }));\n const requested = Array.isArray(options.values) ? options.values.filter((item): item is string => typeof item === \"string\") : [];\n const outcome = multichoices(requested, choices);\n if (outcome.missing.length > 0) return { ok: false, summary: `Reviewed option${outcome.missing.length === 1 ? \"\" : \"s\"} ${outcome.missing.join(\", \")} ${outcome.missing.length === 1 ? \"is\" : \"are\"} not part of the select control.` };\n for (const option of target.options) option.selected = outcome.present.includes(option.value);\n events(target);\n return { ok: true, summary: `Selected ${outcome.present.length} reviewed option${outcome.present.length === 1 ? \"\" : \"s\"} in the multi select control.`, details: { selected: outcome.present } };\n }\n case \"chooseradio\": {\n const radios = target instanceof HTMLInputElement && target.type === \"radio\"\n ? [...root.querySelectorAll<HTMLInputElement>(`input[type=radio][name=\"${CSS.escape(target.name)}\"]`)]\n : target ? [...(target as ParentNode).querySelectorAll<HTMLInputElement>(\"input[type=radio]\")] : [];\n if (radios.length === 0) return { ok: false, summary: \"No radio group owns the reviewed target.\" };\n const inputs = radios.map(radio => ({ value: radio.value, label: radio.labels && radio.labels.length > 0 ? clean(radio.labels[0]?.textContent || \"\") || radio.value : radio.value }));\n const index = radiochoice(inputs, step.value ?? \"\");\n const chosen = radios[index];\n if (!chosen) return { ok: false, summary: \"The reviewed radio option is not part of the group.\" };\n chosen.checked = true;\n events(chosen);\n return { ok: true, summary: `Picked reviewed radio option ${step.value}.`, details: { value: chosen.value } };\n }\n case \"setslider\": {\n if (!(target instanceof HTMLInputElement) || target.type !== \"range\") return { ok: false, summary: \"Target is not a range slider.\" };\n const requested = Number(step.value);\n if (!Number.isFinite(requested)) return { ok: false, summary: \"The reviewed slider value is not a number.\" };\n focuswhenneeded(target, options);\n const value = slidervalue(requested, Number(target.min), Number(target.max), Number(target.step));\n target.value = String(value);\n events(target);\n return { ok: true, summary: `Slider dragged to the reviewed value ${value}.`, details: { value } };\n }\n case \"setdate\": {\n if (!(target instanceof HTMLInputElement) || target.type !== \"date\") return { ok: false, summary: \"Target is not a date input.\" };\n const value = datevalue(step.value ?? \"\");\n if (value === null) return { ok: false, summary: \"The reviewed date is invalid.\" };\n focuswhenneeded(target, options);\n target.value = value;\n events(target);\n return { ok: true, summary: `Date input set to ${value}.`, details: { value } };\n }\n case \"setcolor\": {\n if (!(target instanceof HTMLInputElement) || target.type !== \"color\") return { ok: false, summary: \"Target is not a color input.\" };\n const value = colorvalue(step.value ?? \"\");\n if (value === null) return { ok: false, summary: \"The reviewed color is invalid.\" };\n focuswhenneeded(target, options);\n target.value = value;\n events(target);\n return { ok: true, summary: `Color input set to ${value}.`, details: { value } };\n }\n case \"expanddetails\": {\n const details = target instanceof HTMLElement ? target.closest(\"details\") : null;\n if (!details) return { ok: false, summary: \"Target is not inside a details section.\" };\n const outcome = expandstate(details.open);\n details.open = outcome.open;\n return { ok: true, summary: outcome.changed ? \"Collapsed details section opened.\" : \"Details section was already open.\", details: { changed: outcome.changed } };\n }\n default: return { ok: false, summary: \"Unsupported control action.\" };\n }\n}\n", "import type { pointpath, speedprofile, toolstep } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\nimport type { stepresult } from \"./pageactions.js\";\nimport { resolvestep, type stepresolution } from \"./pageresolve.js\";\n\n/**\n * Pointer path and coordinate click logics for reviewed steps.\n * Every correlated rule for waypoint interpolation, easing, jitter, hop settling, pointer sequences and coordinate clicks lives in this file.\n */\n\n/** One interpolated pointer position with the settle delay before it is dispatched. */\nexport interface pointerhop {\n x: number;\n y: number;\n delay: number;\n}\n\n/** One planned pointer or mouse event of a coordinate click sequence. */\nexport interface plannedevent {\n type: string;\n eventkind: \"pointer\" | \"mouse\";\n x: number;\n y: number;\n shift: boolean;\n}\n\nconst basecadence = 16;\n\nfunction distance(a: { x: number; y: number }, b: { x: number; y: number }): number {\n return Math.hypot(b.x - a.x, b.y - a.y);\n}\n\nfunction ease(easing: \"linear\" | \"easeinout\", progress: number): number {\n if (easing === \"easeinout\") return progress * progress * (3 - 2 * progress);\n return progress;\n}\n\nfunction ispointref(value: unknown): value is { x: number; y: number } {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n const point = value as Record<string, unknown>;\n return typeof point.x === \"number\" && Number.isFinite(point.x) && typeof point.y === \"number\" && Number.isFinite(point.y);\n}\n\n/** Interpolates one reviewed pointer path into settle-delimited hops, honoring the reviewed easing, peak velocity and jitter window. */\nexport function pathhops(path: pointpath, profile: speedprofile | undefined, random: () => number = Math.random, cadence: number = basecadence): pointerhop[] {\n const easing = profile?.easing === \"easeinout\" ? \"easeinout\" : \"linear\";\n const peak = typeof profile?.peak === \"number\" && profile.peak > 0 ? profile.peak : undefined;\n const jitter = typeof profile?.jitter === \"number\" && profile.jitter > 0 ? profile.jitter : 0;\n const points: Array<{ x: number; y: number }> = [path.start, ...(path.waypoints ?? []), path.end];\n const lengths: number[] = [];\n let total = 0;\n for (let index = 1; index < points.length; index += 1) {\n const length = distance(points[index - 1] as { x: number; y: number }, points[index] as { x: number; y: number });\n lengths.push(length);\n total += length;\n }\n const reviewedduration = typeof path.duration === \"number\" && Number.isFinite(path.duration) && path.duration > 0 ? path.duration : undefined;\n const duration = reviewedduration ?? (peak !== undefined && total > 0 ? (total / peak) * 1000 : 300);\n const hops: pointerhop[] = [];\n let previous = points[0] as { x: number; y: number };\n for (let index = 1; index < points.length; index += 1) {\n const from = points[index - 1] as { x: number; y: number };\n const to = points[index] as { x: number; y: number };\n const length = lengths[index - 1] ?? 0;\n if (total <= 0 || length <= 0) {\n hops.push({ x: to.x, y: to.y, delay: 0 });\n previous = to;\n continue;\n }\n const segmentduration = (duration * length) / total;\n const count = Math.max(1, Math.ceil(segmentduration / Math.max(1, cadence)));\n for (let hop = 1; hop <= count; hop += 1) {\n const progress = hop / count;\n const eased = ease(easing, progress);\n const position = { x: from.x + (to.x - from.x) * eased, y: from.y + (to.y - from.y) * eased };\n const step = distance(previous, position);\n const base = segmentduration / count;\n const capped = peak !== undefined ? Math.max(base, (step / peak) * 1000) : base;\n hops.push({ x: position.x, y: position.y, delay: Math.max(0, capped + (jitter > 0 ? random() * jitter : 0)) });\n previous = position;\n }\n }\n return hops;\n}\n\n/** Builds the pointer event sequence around a reviewed path: pointerover, one pointermove per hop, then pointerout. */\nexport function pointersequence(hopcount: number): string[] {\n return [\"pointerover\", ...Array.from({ length: Math.max(0, hopcount) }, () => \"pointermove\"), \"pointerout\"];\n}\n\n/** Builds the full pointer click sequence for reviewed coordinates and modifiers. */\nexport function clickplan(x: number, y: number, modifiers: string[]): plannedevent[] {\n const shift = modifiers.includes(\"shift\");\n const pointer = (type: string): plannedevent => ({ type, eventkind: \"pointer\", x, y, shift });\n const mouse = (type: string): plannedevent => ({ type, eventkind: \"mouse\", x, y, shift });\n return [pointer(\"pointerover\"), pointer(\"pointermove\"), pointer(\"pointerdown\"), mouse(\"mousedown\"), pointer(\"pointerup\"), mouse(\"mouseup\"), mouse(\"click\")];\n}\n\n/** Dispatches one planned event on an element with the reviewed coordinates and modifier flags. */\nfunction dispatchplanned(element: Element, event: plannedevent): void {\n const init: MouseEventInit & PointerEventInit = { bubbles: true, cancelable: true, composed: true, clientX: event.x, clientY: event.y, shiftKey: event.shift };\n if (event.eventkind === \"pointer\") element.dispatchEvent(new PointerEvent(event.type, init));\n else element.dispatchEvent(new MouseEvent(event.type, init));\n}\n\n/** Dispatches the full pointer click sequence on one element with the reviewed modifiers. */\nexport function dispatchclick(element: HTMLElement, modifiers: string[] = []): void {\n const rect = element.getBoundingClientRect();\n const x = rect.left + rect.width / 2;\n const y = rect.top + rect.height / 2;\n for (const event of clickplan(x, y, modifiers)) dispatchplanned(element, event);\n}\n\n/** Scrolls one target into view before any pointer interaction. */\nexport function ensurevisible(element: HTMLElement): void {\n try { element.scrollIntoView({ block: \"center\", inline: \"nearest\", behavior: \"auto\" }); } catch { /* scroll containers may refuse; the interaction still proceeds */ }\n}\n\nfunction settle(delay: number): Promise<void> {\n return new Promise(resolve => window.setTimeout(resolve, delay));\n}\n\n/** Dispatches a pointermove event at one viewport position on the element under the pointer. */\nfunction dispatchmove(x: number, y: number): void {\n const element = document.elementFromPoint(x, y);\n const receiver = element ?? document.documentElement;\n receiver.dispatchEvent(new PointerEvent(\"pointermove\", { bubbles: true, cancelable: true, composed: true, clientX: x, clientY: y }));\n}\n\n/** Travels one reviewed pointpath with dispatched pointermove events, settling each hop before the next one. */\nasync function travel(path: pointpath, profile: speedprofile | undefined): Promise<stepresult> {\n const hops = pathhops(path, profile);\n const startelement = document.elementFromPoint(path.start.x, path.start.y) ?? document.documentElement;\n startelement.dispatchEvent(new PointerEvent(\"pointerover\", { bubbles: true, cancelable: true, composed: true, clientX: path.start.x, clientY: path.start.y }));\n for (const hop of hops) {\n await settle(hop.delay);\n dispatchmove(hop.x, hop.y);\n }\n const endelement = document.elementFromPoint(path.end.x, path.end.y) ?? document.documentElement;\n endelement.dispatchEvent(new PointerEvent(\"pointerout\", { bubbles: true, cancelable: true, composed: true, clientX: path.end.x, clientY: path.end.y }));\n return { ok: true, summary: `Pointer traveled ${hops.length} hop${hops.length === 1 ? \"\" : \"s\"} to the reviewed end point.` };\n}\n\n/** Runs one reviewed pointer step: movepointer paths, clickpoint coordinate clicks and shiftclick modified clicks. */\nexport function runpointerstep(step: toolstep, resolution: stepresolution): stepresult | Promise<stepresult> {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n if (step.kind === \"movepointer\") {\n const path = options.pointpath as Record<string, unknown> | undefined;\n if (!path || !ispointref(path.start) || !ispointref(path.end)) return { ok: false, summary: \"The reviewed pointer path is absent.\" };\n const waypoints = Array.isArray(path.waypoints) && path.waypoints.every(item => ispointref(item)) ? path.waypoints as pointpath[\"waypoints\"] : undefined;\n const fullpath: pointpath = { start: path.start, end: path.end, ...(waypoints ? { waypoints } : {}), ...(typeof path.duration === \"number\" && Number.isFinite(path.duration) ? { duration: path.duration } : {}) };\n return travel(fullpath, options.speedprofile as speedprofile | undefined);\n }\n if (step.kind === \"clickpoint\") {\n const reference = options.targetref as Record<string, unknown> | undefined;\n const x = Number(reference?.x);\n const y = Number(reference?.y);\n if (!Number.isFinite(x) || !Number.isFinite(y)) return { ok: false, summary: \"The reviewed click coordinates are absent.\" };\n const element = document.elementFromPoint(x, y);\n if (!(element instanceof HTMLElement)) return { ok: false, summary: \"No element is rendered at the reviewed coordinates.\" };\n ensurevisible(element);\n for (const event of clickplan(x, y, [])) dispatchplanned(element, event);\n return { ok: true, summary: `Clicked the element at the reviewed coordinates ${x},${y}.` };\n }\n if (step.kind === \"shiftclick\") {\n if (resolution.status === \"ambiguous\") return { ok: false, summary: `The reviewed reference matched ${resolution.candidates.length} elements; choose one candidate.`, details: { mode: resolution.mode, candidates: resolution.candidates } };\n if (resolution.status !== \"resolved\") return { ok: false, summary: \"Action target is no longer available.\" };\n ensurevisible(resolution.element);\n dispatchclick(resolution.element, [\"shift\"]);\n return { ok: true, summary: `Shift click delivered to ${resolution.target.label || resolution.target.tag}.`, details: { mode: resolution.target.mode, resolvedtarget: resolution.target } };\n }\n return { ok: false, summary: \"Unsupported pointer action.\" };\n}\n", "import type { retryrule, toolstep } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\nimport type { stepresult } from \"./pageactions.js\";\nimport { describeframes, queryscoped, queryshadowchain, resolvestep, targetsummary, walkframepath } from \"./pageresolve.js\";\nimport { dispatchclick, ensurevisible } from \"./pagepointer.js\";\n\n/**\n * Resolution driven interactions for reviewed steps.\n * Every correlated rule for text, aria and name clicks, shadow piercing, frame routing, wrapper step extraction and the retry loop lives in this file.\n */\n\n/** Reads the reviewed options of a step without throwing on malformed payloads. */\nfunction optionsof(step: toolstep): Record<string, unknown> {\n try { return parseoptions(step); } catch { return {}; }\n}\n\n/** Extracts the reviewed inner step of a retry or frame wrapper from its inline options. */\nexport function innerstep(step: toolstep): toolstep | null {\n const options = optionsof(step);\n const kind = options.kind;\n if (typeof kind !== \"string\" || !kind.trim()) return null;\n const inneroptions = options.options;\n return {\n id: `${step.id}inner`,\n kind: kind as toolstep[\"kind\"],\n summary: step.summary,\n risk: step.risk,\n ...(typeof options.target === \"string\" ? { target: options.target } : {}),\n ...(typeof options.value === \"string\" ? { value: options.value } : {}),\n ...(inneroptions && typeof inneroptions === \"object\" && !Array.isArray(inneroptions) ? { options: JSON.stringify(inneroptions) } : {}),\n };\n}\n\nfunction pointdistance(a: { x: number; y: number }, b: { x: number; y: number }): number {\n return Math.hypot(b.x - a.x, b.y - a.y);\n}\n\nfunction settle(delay: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, delay));\n}\n\nexport interface retryoutcomeplan {\n ok: boolean;\n attempts: number;\n movement: number;\n summary: string;\n}\n\n/** Runs the reviewed retry loop: each failed attempt waits the settle window, revalidates the target geometry and reruns only when the element moved beyond the tolerance. */\nexport async function runretries(rule: retryrule, probe: () => Promise<{ x: number; y: number } | null>, execute: (attempt: number) => Promise<{ ok: boolean; summary: string }>): Promise<retryoutcomeplan> {\n const attempts = Math.max(1, Number.isFinite(rule.attempts) ? Math.floor(rule.attempts) : 1);\n const tolerance = typeof rule.tolerance === \"number\" && Number.isFinite(rule.tolerance) ? rule.tolerance : 0;\n const settles = typeof rule.settle === \"number\" && Number.isFinite(rule.settle) ? rule.settle : 0;\n let previous = await probe();\n let movement = 0;\n let made = 0;\n let last = \"\";\n for (let attempt = 1; attempt <= attempts; attempt += 1) {\n made = attempt;\n const result = await execute(attempt);\n last = result.summary;\n if (result.ok) return { ok: true, attempts: made, movement, summary: `Retry interaction succeeded on attempt ${made} after ${movement.toFixed(1)} pixels of observed movement.` };\n if (attempt >= attempts) break;\n if (settles > 0) await settle(settles);\n const current = await probe();\n if (!current) { previous = null; continue; }\n if (previous) {\n const delta = pointdistance(previous, current);\n movement = Math.max(movement, delta);\n if (delta <= tolerance) return { ok: false, attempts: made, movement, summary: `The target stayed within the reviewed tolerance of ${tolerance} pixels; retry stopped after attempt ${made}. ${last}` };\n }\n previous = current;\n }\n return { ok: false, attempts: made, movement, summary: `Retry interaction failed after ${made} attempt${made === 1 ? \"\" : \"s\"} with ${movement.toFixed(1)} pixels of observed movement. ${last}` };\n}\n\n/** Dispatches one reviewed click on a resolved element and reports the target mode used. */\nfunction clickresolved(stepkind: string, resolution: ReturnType<typeof resolvestep>): stepresult {\n if (resolution.status === \"ambiguous\") return { ok: false, summary: `The reviewed ${resolution.mode} reference matched ${resolution.candidates.length} elements: ${resolution.candidates.join(\"; \")}.`, details: { mode: resolution.mode, candidates: resolution.candidates } };\n if (resolution.status !== \"resolved\") return { ok: false, summary: \"The reviewed target is no longer available.\" };\n ensurevisible(resolution.element);\n dispatchclick(resolution.element);\n return { ok: true, summary: `Clicked ${resolution.target.label || resolution.target.tag} resolved by ${stepkind} ${resolution.target.mode} mode.`, details: { mode: resolution.target.mode, resolvedtarget: resolution.target } };\n}\n\n/** Runs one resolution driven interaction: text, aria and name clicks, shadow piercing and frame routing. */\nexport function runinteractstep(step: toolstep, expectedorigin: string, dispatch: (inner: toolstep, origin: string, root?: Document) => stepresult | Promise<stepresult>): stepresult | Promise<stepresult> {\n if (step.kind === \"clicktext\" || step.kind === \"clickaria\" || step.kind === \"clickname\") {\n return clickresolved(step.kind, resolvestep(step, document));\n }\n if (step.kind === \"pierceshadow\") {\n const options = optionsof(step);\n const shadow = Array.isArray(options.shadow) ? options.shadow.filter((item): item is string => typeof item === \"string\" && item.trim().length > 0) : [];\n const element = shadow.length > 0 ? queryshadowchain(document, shadow) : queryscoped(document, step.target ?? \"\");\n if (!(element instanceof HTMLElement)) return { ok: false, summary: \"The reviewed shadow target is not available.\" };\n ensurevisible(element);\n dispatchclick(element);\n const summary = targetsummary(\"selector\", element);\n return { ok: true, summary: `Clicked ${summary.label || summary.tag} resolved through ${shadow.length > 0 ? \"the reviewed shadow path\" : \"open shadow roots\"}.`, details: { mode: \"selector\", resolvedtarget: summary } };\n }\n if (step.kind === \"enterframe\") {\n const options = optionsof(step);\n const path = Array.isArray(options.framepath) ? options.framepath.filter((item): item is number => typeof item === \"number\" && Number.isInteger(item) && item >= 0) : [];\n const walk = walkframepath(describeframes(document), path);\n if (!walk.ok) return { ok: false, summary: walk.reason };\n const framedocument = walk.document.live;\n if (!framedocument) return { ok: false, summary: \"The reviewed frame document is not available.\" };\n const inner = innerstep(step);\n if (!inner) return { ok: false, summary: \"The reviewed inner step is absent.\" };\n return dispatch(inner, expectedorigin, framedocument);\n }\n return { ok: false, summary: \"Unsupported interaction action.\" };\n}\n", "import type { navtarget, toolstep, urlpattern, waitoverride, waitprofile } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\nimport type { stepresult } from \"./pageactions.js\";\n\n/**\n * Page navigation logics for reviewed steps.\n * Every correlated rule for navigation targets, container resolution, wait profiles, url patterns, link following, spa routing, query rewriting, deep links and recent tabs lives in this file.\n */\n\n/** One link shape matched by followlink and spanav, serializable for fixtures. */\nexport interface linkshape {\n text: string;\n href: string;\n selector: string;\n}\n\n/** One collected load signal sample with the signals that held true at its time. */\nexport interface signalsample {\n at: number;\n signals: string[];\n}\n\n/** Resolved container plan of one navigation target across tabs, windows and private profiles. */\nexport interface containerplan {\n kind: \"current\" | \"tab\" | \"window\" | \"private\";\n incognito: boolean;\n windowid?: number;\n position: \"adjacent\" | \"end\";\n}\n\n/** Reads the reviewed navtarget of a navigation step; null when the step reviews none. */\nexport function parsenavtarget(step: toolstep): navtarget | null {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n const value = options.navtarget;\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return null;\n const target = value as Record<string, unknown>;\n if (typeof target.url !== \"string\" || !target.url) return null;\n const container = target.container === \"current\" || target.container === \"window\" || target.container === \"private\" ? target.container : \"tab\";\n return {\n url: target.url,\n container,\n ...(target.position === \"end\" ? { position: \"end\" } : { position: \"adjacent\" }),\n private: container === \"private\" || target.private === true,\n };\n}\n\n/** Resolves the container plan of one navigation target: the current task tab, a new tab, a new window or a private window profile separated from normal windows. */\nexport function resolvecontainer(target: navtarget, windows: Array<{ id: number; incognito: boolean; focused: boolean }>): containerplan {\n if (target.container === \"current\") return { kind: \"current\", incognito: false, position: target.position ?? \"adjacent\" };\n if (target.container === \"private\" || target.private) return { kind: \"private\", incognito: true, position: target.position ?? \"adjacent\" };\n if (target.container === \"window\") {\n const focused = windows.find(item => item.focused);\n return { kind: \"window\", incognito: false, ...(focused ? { windowid: focused.id } : {}), position: target.position ?? \"adjacent\" };\n }\n const normal = windows.find(item => !item.incognito && item.focused) ?? windows.find(item => !item.incognito);\n return { kind: \"tab\", incognito: false, ...(normal ? { windowid: normal.id } : {}), position: target.position ?? \"adjacent\" };\n}\n\n/** Reads the reviewed waitprofile of a navprofile step; null when the step reviews none. */\nexport function parsewaitprofile(step: toolstep): waitprofile | null {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n const value = options.waitprofile;\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return null;\n const profile = value as Record<string, unknown>;\n const signals = Array.isArray(profile.signals) ? profile.signals.filter((item): item is string => typeof item === \"string\" && item.trim().length > 0) : [];\n if (signals.length === 0) return null;\n const overrides: waitoverride[] = [];\n if (Array.isArray(profile.overrides)) {\n for (const item of profile.overrides) {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) continue;\n const override = item as Record<string, unknown>;\n if (typeof override.origin !== \"string\" || !override.origin) continue;\n const overridesignals = Array.isArray(override.signals) ? override.signals.filter((entry): entry is string => typeof entry === \"string\" && entry.trim().length > 0) : undefined;\n overrides.push({\n origin: override.origin,\n ...(overridesignals && overridesignals.length > 0 ? { signals: overridesignals } : {}),\n ...(typeof override.idle === \"number\" && Number.isFinite(override.idle) && override.idle >= 0 ? { idle: override.idle } : {}),\n ...(typeof override.timeout === \"number\" && Number.isFinite(override.timeout) && override.timeout >= 0 ? { timeout: override.timeout } : {}),\n });\n }\n }\n return {\n signals,\n ...(typeof profile.idle === \"number\" && Number.isFinite(profile.idle) && profile.idle >= 0 ? { idle: profile.idle } : {}),\n ...(typeof profile.timeout === \"number\" && Number.isFinite(profile.timeout) && profile.timeout >= 0 ? { timeout: profile.timeout } : {}),\n ...(overrides.length > 0 ? { overrides } : {}),\n };\n}\n\n/** Resolves the effective signals and thresholds of one wait profile for an origin by folding the per origin overrides in. */\nexport function profilefororigin(profile: waitprofile, origin: string): { signals: string[]; idle: number; timeout: number } {\n let signals = [...profile.signals];\n let idle = profile.idle ?? 0;\n let timeout = profile.timeout ?? 0;\n for (const override of profile.overrides ?? []) {\n if (!override.origin || new URL(override.origin).origin !== origin) continue;\n if (override.signals && override.signals.length > 0) signals = [...override.signals];\n if (override.idle !== undefined) idle = override.idle;\n if (override.timeout !== undefined) timeout = override.timeout;\n }\n return { signals, idle, timeout };\n}\n\n/** Maps a document ready state onto the live navigation load phase. */\nexport function loadphase(readystate: string): \"loading\" | \"interactive\" | \"complete\" {\n if (readystate === \"interactive\") return \"interactive\";\n if (readystate === \"complete\") return \"complete\";\n return \"loading\";\n}\n\n/** Decides the wait outcome of a wait profile from collected load signal samples: every required signal must hold in the latest sample inside the timeout. */\nexport function evaluatesignals(required: string[], samples: signalsample[], timeout: number): { ok: boolean; satisfied: string[]; waited: number; samples: number } {\n const start = samples[0]?.at ?? 0;\n const last = samples[samples.length - 1];\n const waited = Math.max(0, (last?.at ?? 0) - start);\n const held = last?.signals ?? [];\n const satisfied = required.filter(signal => held.includes(signal));\n if (required.length > 0 && satisfied.length === required.length) return { ok: true, satisfied, waited, samples: samples.length };\n if (timeout > 0 && waited >= timeout) return { ok: false, satisfied, waited, samples: samples.length };\n return { ok: false, satisfied, waited, samples: samples.length };\n}\n\n/** Reads the reviewed urlpattern of a waiturl, spanav or spawait step; null when the step reviews none. */\nexport function parseurlpattern(step: toolstep, key: string = \"urlpattern\"): urlpattern | null {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n const value = options[key];\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return null;\n const pattern = value as Record<string, unknown>;\n if (typeof pattern.url !== \"string\" || !pattern.url) return null;\n const mode = pattern.mode === \"exact\" || pattern.mode === \"host\" || pattern.mode === \"pattern\" ? pattern.mode : \"prefix\";\n const query: Record<string, string> = {};\n if (pattern.query && typeof pattern.query === \"object\" && !Array.isArray(pattern.query)) {\n for (const [name, item] of Object.entries(pattern.query as Record<string, unknown>)) if (typeof item === \"string\") query[name] = item;\n }\n return {\n mode,\n url: pattern.url,\n ...(Object.keys(query).length > 0 ? { query } : {}),\n ...(typeof pattern.fragment === \"string\" && pattern.fragment ? { fragment: pattern.fragment } : {}),\n };\n}\n\n/** Matches a wildcard path segment against one url path segment. */\nfunction segmentmatches(pattern: string, actual: string): boolean {\n if (pattern === \"*\" || pattern === \"**\") return true;\n if (!pattern.includes(\"*\")) return pattern === actual;\n const parts = pattern.split(\"*\");\n let index = 0;\n for (let position = 0; position < parts.length; position += 1) {\n const part = parts[position] as string;\n if (part === \"\") continue;\n const found = actual.indexOf(part, index);\n if (found < 0) return false;\n if (position === 0 && found !== 0) return false;\n index = found + part.length;\n }\n const last = parts[parts.length - 1] as string;\n return last === \"\" || actual.endsWith(last);\n}\n\n/** Matches one url against a reviewed urlpattern by mode plus required query and fragment parts. */\nexport function urlmatches(url: string, pattern: urlpattern): boolean {\n let parsed: URL;\n try { parsed = new URL(url); } catch { return false; }\n let expected: URL;\n try { expected = new URL(pattern.url); } catch { return false; }\n if (pattern.mode === \"exact\" && parsed.toString() !== expected.toString()) return false;\n if (pattern.mode === \"prefix\" && !parsed.toString().startsWith(pattern.url)) return false;\n if (pattern.mode === \"host\" && parsed.origin !== expected.origin) return false;\n if (pattern.mode === \"pattern\") {\n if (parsed.origin !== expected.origin) return false;\n const expectedsegments = expected.pathname.split(\"/\").filter(segment => segment !== \"\");\n const actualsegments = parsed.pathname.split(\"/\").filter(segment => segment !== \"\");\n if (expectedsegments.includes(\"**\")) {\n const cut = expectedsegments.indexOf(\"**\");\n const head = expectedsegments.slice(0, cut);\n const tail = expectedsegments.slice(cut + 1);\n if (actualsegments.length < head.length + tail.length) return false;\n if (!head.every((segment, position) => segmentmatches(segment, actualsegments[position] ?? \"\"))) return false;\n if (!tail.every((segment, position) => segmentmatches(segment, actualsegments[actualsegments.length - tail.length + position] ?? \"\"))) return false;\n } else if (expectedsegments.length !== actualsegments.length || !expectedsegments.every((segment, position) => segmentmatches(segment, actualsegments[position] ?? \"\"))) return false;\n }\n const values = parsed.searchParams;\n for (const [name, value] of Object.entries(pattern.query ?? {})) {\n if (!values.has(name)) return false;\n if (value !== \"*\" && values.get(name) !== value) return false;\n }\n if (pattern.fragment !== undefined && parsed.hash.slice(1) !== pattern.fragment) return false;\n return true;\n}\n\n/** Reads the current query parameters of a url. */\nfunction readquery(url: string): Record<string, string> {\n const values: Record<string, string> = {};\n try {\n for (const [name, value] of new URL(url).searchParams.entries()) values[name] = value;\n } catch { /* an unparseable url has no readable parameters */ }\n return values;\n}\n\n/** Result of one query rewrite with the parameters read, written and the new url. */\nexport interface queryrewriteoutcome {\n url: string;\n before: Record<string, string>;\n after: Record<string, string>;\n set: string[];\n removed: string[];\n}\n\n/** Rewrites the query parameters of one url: reviewed values are set, reviewed names removed and the rest preserved. */\nexport function rewritequeryurl(url: string, set: Record<string, string>, remove: string[]): queryrewriteoutcome {\n const parsed = new URL(url);\n const before = readquery(url);\n for (const name of remove) parsed.searchParams.delete(name);\n for (const [name, value] of Object.entries(set)) parsed.searchParams.set(name, value);\n parsed.hash = \"\";\n return { url: parsed.toString(), before, after: readquery(parsed.toString()), set: Object.keys(set), removed: [...remove] };\n}\n\n/** Applies one reviewed fragment to a url, keeping every other part untouched. */\nexport function fragmenturl(url: string, fragment: string): string {\n const parsed = new URL(url);\n parsed.hash = fragment.replace(/^#/, \"\");\n return parsed.toString();\n}\n\n/** Matches links by their visible text, case insensitively, refusing ambiguity through multiple matches. */\nexport function matchlinktext(links: linkshape[], text: string): linkshape[] {\n const wanted = text.trim().toLowerCase();\n return links.filter(link => link.text.trim().toLowerCase() === wanted);\n}\n\n/** Matches links by their href fragment when the reviewed option asks for fragment resolution. */\nexport function matchlinkfragment(links: linkshape[], fragment: string): linkshape[] {\n const wanted = fragment.trim().replace(/^#/, \"\");\n return links.filter(link => {\n try { return new URL(link.href, \"https://example.invalid\").hash.replace(/^#/, \"\") === wanted; } catch { return false; }\n });\n}\n\n/** Builds a deep link into a common web app from a reviewed app pattern and its string params; unknown apps are refused. */\nexport function deeplinkurl(app: string, params: Record<string, string>): string | null {\n const value = (name: string): string | undefined => {\n const item = params[name];\n return typeof item === \"string\" && item.trim() ? item.trim() : undefined;\n };\n switch (app.trim().toLowerCase()) {\n case \"github\": {\n const owner = value(\"owner\");\n const repo = value(\"repo\");\n if (!owner || !repo) return null;\n const path = value(\"path\");\n return `https://github.com/${owner}/${repo}${path ? `/${path.replace(/^\\/+/, \"\")}` : \"\"}`;\n }\n case \"youtube\": {\n const id = value(\"id\");\n if (id) return `https://www.youtube.com/watch?v=${encodeURIComponent(id)}`;\n const search = value(\"search\");\n if (search) return `https://www.youtube.com/results?search_query=${encodeURIComponent(search)}`;\n return null;\n }\n case \"maps\": {\n const query = value(\"query\");\n if (!query) return null;\n return `https://www.google.com/maps/search/${encodeURIComponent(query)}`;\n }\n case \"wikipedia\": {\n const title = value(\"title\");\n if (!title) return null;\n const language = value(\"language\") ?? \"en\";\n return `https://${language}.wikipedia.org/wiki/${encodeURIComponent(title.replace(/\\s+/g, \"_\"))}`;\n }\n case \"amazon\": {\n const search = value(\"search\");\n if (!search) return null;\n return `https://www.amazon.com/s?k=${encodeURIComponent(search)}`;\n }\n case \"x\": {\n const user = value(\"user\");\n if (!user) return null;\n return `https://x.com/${user.replace(/^@/, \"\")}`;\n }\n default: return null;\n }\n}\n\n/** True when the current url of a single page app changed without a reload, keeping the origin. */\nexport function spauroutechanged(previousurl: string, currenturl: string): boolean {\n if (previousurl === currenturl) return false;\n try {\n return new URL(previousurl).origin === new URL(currenturl).origin;\n } catch { return false; }\n}\n\n/** Picks the most recently closed tab whose url is no longer open; null when every recent tab is already restored. */\nexport function pickrecenttab(recenttabs: Array<{ url: string; tabid: number; closedat: number }>, openurls: string[]): { url: string; tabid: number; closedat: number } | null {\n return recenttabs.find(tab => !openurls.includes(tab.url)) ?? null;\n}\n\nfunction wait(ms: number): Promise<void> {\n return new Promise(resolve => window.setTimeout(resolve, ms));\n}\n\nfunction stepoptions(step: toolstep): Record<string, unknown> {\n try { return parseoptions(step); } catch { return {}; }\n}\n\nfunction collectlinks(root: Document): linkshape[] {\n return [...root.querySelectorAll(\"a[href]\")].map(element => ({\n text: element.textContent?.trim() ?? \"\",\n href: element instanceof HTMLAnchorElement ? element.href : element.getAttribute(\"href\") ?? \"\",\n selector: element.getAttribute(\"href\") ?? \"\",\n }));\n}\n\n/** Resolves the reviewed link of a followlink or spanav step by visible text or href fragment, refusing links outside the allowed origins. */\nfunction resolvelink(step: toolstep, root: Document): { ok: true; element: HTMLAnchorElement } | { ok: false; summary: string } {\n const options = stepoptions(step);\n const allowedorigins = Array.isArray(options.allowedorigins) ? options.allowedorigins.filter((item): item is string => typeof item === \"string\") : [];\n const links = collectlinks(root);\n const matches = options.fragment === true ? matchlinkfragment(links, step.value ?? \"\") : matchlinktext(links, step.value ?? \"\");\n if (matches.length === 0) return { ok: false, summary: `No link matches the reviewed reference \"${step.value ?? \"\"}\".` };\n if (matches.length > 1) return { ok: false, summary: `The reviewed link reference matched ${matches.length} links; review a unique one.` };\n const element = [...root.querySelectorAll(\"a[href]\")].find(candidate => (candidate instanceof HTMLAnchorElement ? candidate.href : candidate.getAttribute(\"href\") ?? \"\") === matches[0]?.href);\n if (!(element instanceof HTMLAnchorElement)) return { ok: false, summary: \"The reviewed link is no longer available.\" };\n if (allowedorigins.length > 0) {\n let origin = \"\";\n try { origin = new URL(element.href).origin; } catch { origin = \"\"; }\n if (!allowedorigins.includes(origin)) return { ok: false, summary: `The reviewed link leaves the session origin grants for ${origin}.` };\n }\n return { ok: true, element };\n}\n\n/** Waits for the page load event and reports the ready state and load phase. */\nasync function runwaitload(step: toolstep): Promise<stepresult> {\n const options = stepoptions(step);\n const timeout = typeof options.timeout === \"number\" && Number.isFinite(options.timeout) && options.timeout > 0 ? options.timeout : 0;\n const started = Date.now();\n for (;;) {\n const phase = loadphase(document.readyState);\n if (phase === \"complete\") return { ok: true, summary: `The page load event fired and the document is complete after ${Date.now() - started} milliseconds.`, details: { phase, readystate: document.readyState, waited: Date.now() - started } };\n if (timeout > 0 && Date.now() - started >= timeout) return { ok: false, summary: `The page did not reach the complete load phase within the reviewed timeout of ${timeout} milliseconds.`, details: { phase, readystate: document.readyState, waited: Date.now() - started } };\n await wait(50);\n }\n}\n\n/** Waits until the current url matches the reviewed urlpattern. */\nasync function runwaiturl(step: toolstep): Promise<stepresult> {\n const options = stepoptions(step);\n const pattern = parseurlpattern(step);\n if (!pattern) return { ok: false, summary: \"A reviewed urlpattern is required.\" };\n const timeout = typeof options.timeout === \"number\" && Number.isFinite(options.timeout) && options.timeout > 0 ? options.timeout : 0;\n const poll = typeof options.poll === \"number\" && Number.isFinite(options.poll) && options.poll > 0 ? options.poll : 100;\n const started = Date.now();\n for (;;) {\n if (urlmatches(location.href, pattern)) return { ok: true, summary: `The url matched the reviewed ${pattern.mode} pattern after ${Date.now() - started} milliseconds.`, details: { url: location.href, mode: pattern.mode, waited: Date.now() - started } };\n if (timeout > 0 && Date.now() - started >= timeout) return { ok: false, summary: `The url did not match the reviewed ${pattern.mode} pattern within the reviewed timeout of ${timeout} milliseconds.`, details: { url: location.href, mode: pattern.mode, waited: Date.now() - started } };\n await wait(poll);\n }\n}\n\n/** Follows one reviewed link, reporting the href travelled to. */\nasync function runfollowlink(step: toolstep, root: Document): Promise<stepresult> {\n const resolution = resolvelink(step, root);\n if (!resolution.ok) return { ok: false, summary: resolution.summary };\n const href = resolution.element.href;\n resolution.element.click();\n return { ok: true, summary: `Followed the reviewed link to ${href}.`, details: { href } };\n}\n\n/** Navigates a single page app by clicking the reviewed control and waiting for the route change without a reload. */\nasync function runspanav(step: toolstep, root: Document): Promise<stepresult> {\n const options = stepoptions(step);\n const resolution = resolvelink(step, root);\n if (!resolution.ok) return { ok: false, summary: resolution.summary };\n const timeout = typeof options.timeout === \"number\" && Number.isFinite(options.timeout) && options.timeout > 0 ? options.timeout : 0;\n const pattern = parseurlpattern(step, \"routepattern\");\n const before = location.href;\n resolution.element.click();\n const started = Date.now();\n for (;;) {\n const changed = spauroutechanged(before, location.href);\n const matched = pattern ? urlmatches(location.href, pattern) : changed;\n if (matched) return { ok: true, summary: `The single page app route changed to ${location.href} without a reload.`, details: { from: before, to: location.href, waited: Date.now() - started } };\n if (timeout > 0 && Date.now() - started >= timeout) return { ok: false, summary: `The single page app route did not change within the reviewed timeout of ${timeout} milliseconds.`, details: { from: before, to: location.href, waited: Date.now() - started } };\n await wait(50);\n }\n}\n\n/** Waits for a url change inside a single page app without a reload, through popstate, hashchange and history polling. */\nasync function runspawait(step: toolstep): Promise<stepresult> {\n const options = stepoptions(step);\n const timeout = typeof options.timeout === \"number\" && Number.isFinite(options.timeout) && options.timeout > 0 ? options.timeout : 0;\n const poll = typeof options.poll === \"number\" && Number.isFinite(options.poll) && options.poll > 0 ? options.poll : 100;\n const pattern = parseurlpattern(step);\n const before = location.href;\n const started = Date.now();\n let detected = false;\n const onroute = (): void => { if (spauroutechanged(before, location.href)) detected = true; };\n window.addEventListener(\"popstate\", onroute);\n window.addEventListener(\"hashchange\", onroute);\n try {\n for (;;) {\n if (pattern ? urlmatches(location.href, pattern) : detected || spauroutechanged(before, location.href)) {\n return { ok: true, summary: `The single page app url changed to ${location.href} without a reload.`, details: { from: before, to: location.href, waited: Date.now() - started } };\n }\n if (timeout > 0 && Date.now() - started >= timeout) return { ok: false, summary: `The single page app url did not change within the reviewed timeout of ${timeout} milliseconds.`, details: { from: before, to: location.href, waited: Date.now() - started } };\n await wait(poll);\n }\n } finally {\n window.removeEventListener(\"popstate\", onroute);\n window.removeEventListener(\"hashchange\", onroute);\n }\n}\n\n/** Reads and rewrites the query parameters of the current url with pushstate, reporting the parameters read and the new url. */\nfunction runrewritequery(step: toolstep): stepresult {\n const options = stepoptions(step);\n const set: Record<string, string> = {};\n if (options.set && typeof options.set === \"object\" && !Array.isArray(options.set)) {\n for (const [name, value] of Object.entries(options.set as Record<string, unknown>)) if (typeof value === \"string\") set[name] = value;\n }\n const remove = Array.isArray(options.remove) ? options.remove.filter((item): item is string => typeof item === \"string\" && item.trim().length > 0) : [];\n const outcome = rewritequeryurl(location.href, set, remove);\n history.pushState(history.state, document.title, outcome.url);\n return { ok: true, summary: `Rewrote ${outcome.set.length + outcome.removed.length} query parameter${outcome.set.length + outcome.removed.length === 1 ? \"\" : \"s\"}; the url is now ${outcome.url}.`, details: { url: outcome.url, before: outcome.before, after: outcome.after, set: outcome.set, removed: outcome.removed } };\n}\n\n/** Sets the reviewed url fragment and scrolls to its anchor with smooth behavior. */\nasync function runsetfragment(step: toolstep): Promise<stepresult> {\n const fragment = (step.value ?? \"\").replace(/^#/, \"\");\n if (!fragment) return { ok: false, summary: \"A reviewed fragment is required.\" };\n const url = fragmenturl(location.href, fragment);\n history.pushState(history.state, document.title, url);\n const anchor = document.getElementById(fragment);\n anchor?.scrollIntoView({ behavior: \"smooth\", block: \"start\" });\n return { ok: true, summary: `Set the url fragment to ${fragment} and scrolled to its anchor.`, details: { url, fragment, anchored: Boolean(anchor) } };\n}\n\n/** Stops a pending navigation by halting the document load. */\nfunction runstopnav(): stepresult {\n window.stop();\n return { ok: true, summary: \"Stopped the pending navigation of the page.\" };\n}\n\n/** Prefetches the reviewed urls by injecting prefetch hints into the document head. */\nfunction runprefetch(step: toolstep): stepresult {\n const options = stepoptions(step);\n const urls = Array.isArray(options.urls) ? options.urls.filter((item): item is string => typeof item === \"string\" && item.trim().length > 0) : [];\n if (urls.length === 0) return { ok: false, summary: \"A reviewed list of prefetch urls is required.\" };\n for (const url of urls) {\n const hint = document.createElement(\"link\");\n hint.rel = \"prefetch\";\n hint.href = url;\n document.head.append(hint);\n }\n return { ok: true, summary: `Queued ${urls.length} prefetch hint${urls.length === 1 ? \"\" : \"s\"}.`, details: { urls } };\n}\n\n/** Preconnects to the reviewed origins by injecting preconnect hints into the document head. */\nfunction runpreconnect(step: toolstep): stepresult {\n const options = stepoptions(step);\n const origins = Array.isArray(options.origins) ? options.origins.filter((item): item is string => typeof item === \"string\" && item.trim().length > 0) : [];\n if (origins.length === 0) return { ok: false, summary: \"A reviewed list of preconnect origins is required.\" };\n for (const origin of origins) {\n const hint = document.createElement(\"link\");\n hint.rel = \"preconnect\";\n hint.href = origin;\n document.head.append(hint);\n }\n return { ok: true, summary: `Opened ${origins.length} preconnect hint${origins.length === 1 ? \"\" : \"s\"}.`, details: { origins } };\n}\n\n/** Prints the page through the browser print pipeline; the artifact routing happens in the background. */\nfunction runprintpdf(): stepresult {\n window.print();\n return { ok: true, summary: \"Sent the page to the browser print pipeline.\" };\n}\n\n/** Runs one reviewed page navigation kind inside the page world. */\nexport function runpagenav(step: toolstep, root: Document = document): stepresult | Promise<stepresult> {\n switch (step.kind) {\n case \"waitload\": return runwaitload(step);\n case \"waiturl\": return runwaiturl(step);\n case \"followlink\": return runfollowlink(step, root);\n case \"spanav\": return runspanav(step, root);\n case \"spawait\": return runspawait(step);\n case \"rewritequery\": return runrewritequery(step);\n case \"setfragment\": return runsetfragment(step);\n case \"stopnav\": return runstopnav();\n case \"prefetch\": return runprefetch(step);\n case \"preconnect\": return runpreconnect(step);\n case \"printpdf\": return runprintpdf();\n default: return { ok: false, summary: \"Unsupported navigation action.\" };\n }\n}\n", "import type { dialogpolicy, toolstep } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\n\n/**\n * Dialog policy logics for reviewed steps.\n * Every correlated rule for policy parsing, dialog answers, main world handler installation and observed dialog harvesting lives in this file.\n * The isolated world cannot override window.confirm, window.alert or window.prompt, so the background installs these wrappers through the scripting api in the main world.\n */\n\n/** One dialog observed by the main world handler, recorded on the shared document. */\nexport interface observeddialog {\n dialog: string;\n text: string;\n result: string | boolean | null;\n at: number;\n}\n\n/** Parses the reviewed dialog policy from step options; prompts need a reviewed answer. */\nexport function parsedialogpolicy(step: toolstep): dialogpolicy | null {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { return null; }\n const accept = options.accept;\n const answer = options.answer;\n if (typeof accept !== \"boolean\" && typeof answer !== \"string\") return null;\n return { accept: accept === true, ...(typeof answer === \"string\" && answer.trim() ? { answer } : {}) };\n}\n\n/** Decides how the reviewed policy answers one dialog kind; a prompt without a reviewed answer is dismissed. */\nexport function dialoganswer(policy: dialogpolicy, dialog: \"confirm\" | \"alert\" | \"prompt\"): { accept: boolean; answer?: string } {\n if (dialog === \"prompt\") {\n if (policy.answer === undefined || policy.answer === \"\") return { accept: false };\n return { accept: policy.accept !== false, ...(policy.answer !== undefined ? { answer: policy.answer } : {}) };\n }\n return { accept: policy.accept };\n}\n\n/** Reads and clears the dialog log the main world handler recorded on the shared document. */\nexport function harvestdialoglog(root: Document): observeddialog[] {\n const raw = root.documentElement.dataset.devthinkdialoglog;\n if (!raw) return [];\n delete root.documentElement.dataset.devthinkdialoglog;\n try {\n const parsed: unknown = JSON.parse(raw);\n if (!Array.isArray(parsed)) return [];\n return parsed.filter((item): item is observeddialog => Boolean(item) && typeof item === \"object\" && typeof (item as Record<string, unknown>).dialog === \"string\");\n } catch { return []; }\n}\n\n/** Installs confirm, alert and prompt wrappers in the page main world answering per the reviewed policy; runs through chrome.scripting with world main. */\nexport function installdialoghandler(accept: boolean, answer: string, persistent: boolean): void {\n const world = globalThis as typeof globalThis & { devthinkoriginaldialogs?: { confirm: (text?: string) => boolean; alert: (text?: string) => void; prompt: (text?: string, defaultvalue?: string) => string | null } };\n const originals = world.devthinkoriginaldialogs ?? { confirm: window.confirm.bind(window), alert: window.alert.bind(window), prompt: window.prompt.bind(window) };\n world.devthinkoriginaldialogs = originals;\n const decide = (dialog: string): { accept: boolean; answer: string | null } => {\n if (dialog === \"prompt\") return answer ? { accept: true, answer } : { accept: false, answer: null };\n return { accept, answer: null };\n };\n const record = (dialog: string, text: string, result: string | boolean | null): void => {\n try {\n const root = document.documentElement;\n const log = JSON.parse(root.dataset.devthinkdialoglog ?? \"[]\") as unknown[];\n log.push({ dialog, text, result, at: Date.now() });\n root.dataset.devthinkdialoglog = JSON.stringify(log);\n } catch { /* a locked down page refuses dataset writes; the handler still answers */ }\n };\n window.confirm = (text?: string): boolean => {\n const decision = decide(\"confirm\");\n record(\"confirm\", text ?? \"\", decision.accept);\n if (!persistent) window.confirm = originals.confirm;\n return decision.accept;\n };\n window.alert = (text?: string): void => {\n record(\"alert\", text ?? \"\", true);\n if (!persistent) window.alert = originals.alert;\n };\n window.prompt = (text?: string, defaultvalue?: string): string | null => {\n const decision = decide(\"prompt\");\n const outcome = decision.accept ? (decision.answer ?? defaultvalue ?? \"\") : null;\n record(\"prompt\", text ?? \"\", outcome);\n if (!persistent) window.prompt = originals.prompt;\n return outcome;\n };\n}\n", "import type { a11ynode, readerarticle, toolstep } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\nimport type { stepresult } from \"./pageactions.js\";\nimport { clean, describescopes, elementlabel, elementselector, implicitrole, owntext, type candidatefields, type scopetree } from \"./pageresolve.js\";\n\n/**\n * Semantic page observation for reviewed steps.\n * Every correlated rule for the shadow and frame piercing walker, the accessibility tree, visible text, the reader heuristic, the heading outline, the selection read, open graph extraction, language detection and the shadow and frame inventories lives in this file.\n */\n\n/** Serializable page node used by the observation engine; the live glue attaches the element. */\nexport interface pagenode {\n tag: string;\n selector: string;\n id: string;\n classes: string[];\n role: string;\n name: string;\n text: string;\n value: string;\n states: string[];\n hidden: boolean;\n children: pagenode[];\n element?: Element;\n}\n\n/** Deepest same origin frame nesting the walker pierces; deeper frames stay opaque so recursive self embedding cannot loop. */\nconst maxframedepth = 4;\n\nfunction elementstates(element: Element): string[] {\n const states: string[] = [];\n if (element.hasAttribute(\"disabled\") || element.getAttribute(\"aria-disabled\") === \"true\") states.push(\"disabled\");\n if (element instanceof HTMLInputElement && (element.type === \"checkbox\" || element.type === \"radio\") && element.checked) states.push(\"checked\");\n const expanded = element.getAttribute(\"aria-expanded\");\n if (expanded !== null) states.push(`expanded ${expanded}`);\n if (element.getAttribute(\"aria-selected\") === \"true\") states.push(\"selected\");\n if (element.hasAttribute(\"required\") || element.getAttribute(\"aria-required\") === \"true\") states.push(\"required\");\n if (element.hasAttribute(\"readonly\") || element.getAttribute(\"aria-readonly\") === \"true\") states.push(\"readonly\");\n if (element.getAttribute(\"aria-hidden\") === \"true\") states.push(\"hidden\");\n return states;\n}\n\nfunction elementvalue(element: Element): string {\n if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement) return element.value;\n return \"\";\n}\n\nfunction elementhidden(element: Element): boolean {\n if (element instanceof HTMLInputElement && element.type === \"hidden\") return true;\n if (element.hasAttribute(\"hidden\") || element.getAttribute(\"aria-hidden\") === \"true\") return true;\n try {\n const style = element.ownerDocument?.defaultView?.getComputedStyle(element);\n if (style && (style.display === \"none\" || style.visibility === \"hidden\")) return true;\n } catch { /* detached documents refuse computed styles; the node stays visible */ }\n return false;\n}\n\nfunction framenode(frame: HTMLIFrameElement, depth: number): pagenode {\n let content: Document | null = null;\n try { content = frame.contentDocument; } catch { content = null; }\n let sameorigin = false;\n try { sameorigin = content !== null && frame.contentWindow?.location.origin === location.origin; } catch { sameorigin = false; }\n const node = wrap(frame, depth);\n if (sameorigin && content && depth < maxframedepth) node.children.push(...wrapchildren(content, depth + 1));\n return node;\n}\n\nfunction wrap(element: Element, depth: number): pagenode {\n const shadow = element.shadowRoot;\n const node: pagenode = {\n tag: element.tagName.toLowerCase(),\n selector: elementselector(element),\n id: element.id,\n classes: [...element.classList],\n role: element.getAttribute(\"role\")?.toLowerCase() || implicitrole(element),\n name: elementlabel(element),\n text: owntext(element),\n value: elementvalue(element),\n states: elementstates(element),\n hidden: elementhidden(element),\n children: [],\n element,\n };\n if (shadow) node.children.push(...wrapchildren(shadow, depth));\n if (element instanceof HTMLIFrameElement) return framenode(element, depth);\n node.children.push(...wrapchildren(element, depth));\n return node;\n}\n\nfunction wrapchildren(scope: ParentNode, depth: number): pagenode[] {\n return [...scope.querySelectorAll(\":scope > *\")].map(child => wrap(child, depth));\n}\n\n/** Builds the serializable page node tree, piercing open shadow roots and same origin iframes. */\nexport function buildpagetree(scope: ParentNode): pagenode {\n const root: pagenode = {\n tag: \"#document\",\n selector: \"\",\n id: \"\",\n classes: [],\n role: \"document\",\n name: \"\",\n text: \"\",\n value: \"\",\n states: [],\n hidden: false,\n children: [],\n };\n if (scope instanceof Document) {\n root.children = scope.documentElement ? [wrap(scope.documentElement, 0)] : [];\n } else {\n root.children = [...wrapchildren(scope, 0)];\n }\n return root;\n}\n\nfunction countnodes(node: a11ynode): number {\n return 1 + node.children.reduce((total, child) => total + countnodes(child), 0);\n}\n\n/** Converts one page node tree into the accessibility tree with roles, names, states and child refs; hidden subtrees stay excluded. */\nexport function builda11ytree(node: pagenode): a11ynode {\n const children = node.children.filter(child => !child.hidden).map(builda11ytree);\n return {\n role: node.role || \"generic\",\n name: node.name,\n states: node.states,\n ...(node.value ? { value: node.value } : {}),\n childcount: children.length,\n children,\n };\n}\n\n/** Returns the rendered text of each visible element; hidden nodes and their subtrees stay excluded. */\nexport function visibleentries(node: pagenode): Array<{ selector: string; text: string }> {\n if (node.hidden) return [];\n const entries: Array<{ selector: string; text: string }> = node.text ? [{ selector: node.selector || node.tag, text: node.text }] : [];\n for (const child of node.children) entries.push(...visibleentries(child));\n return entries;\n}\n\n/** Joins the rendered text of every visible node into one stream. */\nexport function visibletext(node: pagenode): string {\n return visibleentries(node).map(entry => entry.text).join(\" \");\n}\n\nfunction nodetextlength(node: pagenode): number {\n return node.text.length + node.children.reduce((total, child) => total + nodetextlength(child), 0);\n}\n\nfunction nodelinktext(node: pagenode): number {\n const own = node.tag === \"a\" ? node.text.length : 0;\n return own + node.children.reduce((total, child) => total + nodelinktext(child), 0);\n}\n\nfunction wordsin(text: string): number {\n return text.split(/\\s+/).filter(Boolean).length;\n}\n\nfunction findbyline(node: pagenode): string {\n const markers = [\"byline\", \"author\"];\n const direct = node.classes.some(item => markers.some(marker => item.toLowerCase().includes(marker))) || markers.some(marker => node.id.toLowerCase().includes(marker));\n if (direct && node.text) return node.text;\n for (const child of node.children) {\n const found = findbyline(child);\n if (found) return found;\n }\n return \"\";\n}\n\nfunction findheading(node: pagenode, tags: string[]): string {\n if (tags.includes(node.tag) && node.text) return node.text;\n for (const child of node.children) {\n const found = findheading(child, tags);\n if (found) return found;\n }\n return \"\";\n}\n\n/** Scores page nodes by text density and splits the densest article region into reader blocks, separating them from page chrome. */\nexport function buildreader(root: pagenode, title: string): readerarticle {\n let best: pagenode | undefined;\n let bestscore = 0;\n const walk = (node: pagenode): void => {\n if (node.tag !== \"#document\") {\n const length = nodetextlength(node);\n const links = nodelinktext(node);\n const score = length * (1 - (length > 0 ? links / length : 0));\n if (score > bestscore) { bestscore = score; best = node; }\n }\n for (const child of node.children) walk(child);\n };\n walk(root);\n const article = best ?? root;\n const blocks = article.children.filter(child => !child.hidden && child.text).map(child => ({ kind: child.tag, text: child.text, words: wordsin(child.text) }));\n const ownblock = article.text ? [{ kind: article.tag, text: article.text, words: wordsin(article.text) }] : [];\n const allblocks = [...ownblock, ...blocks];\n return {\n title: findheading(article, [\"h1\"]) || findheading(root, [\"h1\"]) || title,\n byline: findbyline(article) || findbyline(root),\n blocks: allblocks,\n words: allblocks.reduce((total, block) => total + block.words, 0),\n characters: allblocks.reduce((total, block) => total + block.text.length, 0),\n };\n}\n\n/** Returns the title and headings outline of the page. */\nexport function pageoutline(root: pagenode, title: string): { title: string; headings: Array<{ level: number; text: string }> } {\n const headings: Array<{ level: number; text: string }> = [];\n const walk = (node: pagenode): void => {\n const level = /^h([1-6])$/.exec(node.tag);\n if (level && node.text) headings.push({ level: Number.parseInt(level[1] as string, 10), text: node.text });\n for (const child of node.children) walk(child);\n };\n walk(root);\n return { title: findheading(root, [\"h1\"]) || title, headings };\n}\n\n/** Reads the text of the current user selection through the document selection api. */\nexport function captureselection(root: { getSelection?: () => { toString(): string } | null }): { text: string; length: number } {\n const selection = root.getSelection?.() ?? null;\n const text = selection ? clean(selection.toString()) : \"\";\n return { text, length: text.length };\n}\n\n/** Extracts open graph meta properties and structured data payloads; malformed structured payloads are refused and counted. */\nexport function opengraphfields(meta: Array<{ property: string; name: string; content: string }>, jsonld: string[]): { graph: Record<string, string>; structured: unknown[]; refused: number } {\n const graph: Record<string, string> = {};\n for (const entry of meta) {\n if (entry.property.startsWith(\"og:\") && entry.content) graph[entry.property] = entry.content;\n }\n const structured: unknown[] = [];\n let refused = 0;\n for (const raw of jsonld) {\n try { structured.push(JSON.parse(raw)); } catch { refused += 1; }\n }\n return { graph, structured, refused };\n}\n\nconst stopwords: Record<string, string[]> = {\n en: [\"the\", \"is\", \"at\", \"which\", \"on\", \"and\", \"of\", \"to\", \"in\", \"that\", \"it\", \"with\"],\n pt: [\"de\", \"que\", \"n\u00E3o\", \"uma\", \"para\", \"com\", \"por\", \"mais\", \"como\", \"p\u00E1gina\", \"este\", \"voc\u00EA\"],\n es: [\"que\", \"el\", \"las\", \"los\", \"por\", \"una\", \"para\", \"con\", \"como\", \"p\u00E1gina\", \"m\u00E1s\", \"este\"],\n fr: [\"le\", \"les\", \"des\", \"que\", \"pour\", \"dans\", \"est\", \"sur\", \"avec\", \"page\", \"plus\", \"cette\"],\n de: [\"der\", \"die\", \"und\", \"das\", \"ist\", \"von\", \"mit\", \"f\u00FCr\", \"auf\", \"den\", \"nicht\", \"seite\"],\n it: [\"che\", \"il\", \"la\", \"per\", \"una\", \"del\", \"sono\", \"non\", \"con\", \"pagina\", \"pi\u00F9\", \"questo\"],\n nl: [\"het\", \"een\", \"en\", \"van\", \"is\", \"dat\", \"op\", \"te\", \"voor\", \"met\", \"niet\", \"pagina\"],\n};\n\n/** Detects the language of extracted text from stopword frequency; an undetermined text returns an empty code. */\nexport function detecttextlanguage(text: string): string {\n const words = text.toLowerCase().split(/[^a-z\u00E0-\u00FF]+/).filter(Boolean);\n if (words.length === 0) return \"\";\n let best = \"\";\n let bestscore = 0;\n for (const [language, dictionary] of Object.entries(stopwords)) {\n const score = words.filter(word => dictionary.includes(word)).length;\n if (score > bestscore) { bestscore = score; best = language; }\n }\n return best;\n}\n\n/** Tags extracted text with its detected language code, routing it to the matching language stream. */\nexport function taglanguage(text: string): { text: string; language: string } {\n return { text, language: detecttextlanguage(text) };\n}\n\n/** Resolves the page language from the document lang attribute, the content language meta and the content signals, in that order. */\nexport function documentlanguage(signals: { lang: string; meta: string; text: string }): { language: string; source: string } {\n if (signals.lang.trim()) return { language: signals.lang.trim(), source: \"document\" };\n if (signals.meta.trim()) return { language: signals.meta.trim(), source: \"meta\" };\n return { language: detecttextlanguage(signals.text), source: \"content\" };\n}\n\n/** Lists the host paths of every open shadow root nested inside one scope tree. */\nexport function shadowpaths(scope: scopetree<candidatefields>): string[] {\n const paths: string[] = [];\n const walk = (tree: scopetree<candidatefields>, prefix: string): void => {\n for (const shadow of tree.shadows) {\n if (!shadow.host) continue;\n const path = prefix ? `${prefix} > ${shadow.host.selector}` : shadow.host.selector;\n paths.push(path);\n walk(shadow, path);\n }\n };\n walk(scope, \"\");\n return paths;\n}\n\n/** Enumerates the iframes of one document with their origins and sizes; cross origin frames report no origin. */\nexport function framelist(root: Document): Array<{ index: number; origin: string; sameorigin: boolean; width: number; height: number }> {\n return [...root.querySelectorAll(\"iframe\")].map((frame, index) => {\n let origin = \"\";\n try { origin = frame.contentWindow?.location.origin ?? \"\"; } catch { origin = \"\"; }\n const rect = frame.getBoundingClientRect();\n return { index, origin, sameorigin: origin !== \"\" && origin === location.origin, width: Math.round(rect.width), height: Math.round(rect.height) };\n });\n}\n\nfunction stepoptions(step: toolstep): Record<string, unknown> {\n try { return parseoptions(step); } catch { return {} as Record<string, unknown>; }\n}\n\n/** Runs one passive page observation after the background policy gate; frame routed steps receive their frame document as the root. */\nexport function runpageobservation(step: toolstep, target: Element | null, root: Document = document): stepresult | Promise<stepresult> {\n switch (step.kind) {\n case \"a11ytree\": {\n const tree = builda11ytree(buildpagetree(root));\n const count = countnodes(tree);\n return { ok: true, summary: `Captured the accessibility tree with ${count} node${count === 1 ? \"\" : \"s\"}.`, details: { tree, nodecount: count } };\n }\n case \"readvisible\": {\n const scope: ParentNode = target ?? root;\n const tree = buildpagetree(scope);\n const entries = visibleentries(tree);\n return { ok: true, summary: `Read the rendered text of ${entries.length} visible element${entries.length === 1 ? \"\" : \"s\"}.`, details: { entries, text: visibletext(tree) } };\n }\n case \"readertree\": {\n const article = buildreader(buildpagetree(root), root.title);\n return { ok: true, summary: `Extracted the reader view with ${article.blocks.length} block${article.blocks.length === 1 ? \"\" : \"s\"} and ${article.words} words.`, details: { article } };\n }\n case \"readoutline\": {\n const outline = pageoutline(buildpagetree(root), root.title);\n return { ok: true, summary: `Read the outline with ${outline.headings.length} heading${outline.headings.length === 1 ? \"\" : \"s\"}.`, details: { title: outline.title, headings: outline.headings } };\n }\n case \"readselection\": {\n const selection = captureselection(root);\n return { ok: true, summary: selection.text ? `Read ${selection.length} characters of the current selection.` : \"No text is currently selected.\", details: { text: selection.text, length: selection.length } };\n }\n case \"readopengraph\": {\n const meta = [...root.querySelectorAll(\"meta\")].map(element => ({ property: element.getAttribute(\"property\") ?? \"\", name: element.getAttribute(\"name\") ?? \"\", content: element.getAttribute(\"content\") ?? \"\" }));\n const jsonld = [...root.querySelectorAll('script[type=\"application/ld+json\"]')].map(element => element.textContent ?? \"\");\n const fields = opengraphfields(meta, jsonld);\n return { ok: true, summary: `Read ${Object.keys(fields.graph).length} open graph entr${Object.keys(fields.graph).length === 1 ? \"y\" : \"ies\"} and ${fields.structured.length} structured payload${fields.structured.length === 1 ? \"\" : \"s\"}${fields.refused > 0 ? `; ${fields.refused} malformed payload${fields.refused === 1 ? \" was\" : \"s were\"} refused` : \"\"}.`, details: { graph: fields.graph, structured: fields.structured, refused: fields.refused } };\n }\n case \"readlang\": {\n const metatag = root.querySelector('meta[http-equiv=\"content-language\"]')?.getAttribute(\"content\") ?? \"\";\n const outcome = documentlanguage({ lang: root.documentElement?.getAttribute(\"lang\") ?? \"\", meta: metatag, text: root.body?.innerText ?? \"\" });\n return { ok: true, summary: `Detected page language ${outcome.language || \"unknown\"} from the ${outcome.source} signal.`, details: { language: outcome.language, source: outcome.source } };\n }\n case \"detectlanguage\": {\n const options = stepoptions(step);\n const text = typeof options.text === \"string\" && options.text ? options.text : target?.textContent ?? root.body?.innerText ?? \"\";\n const routed = taglanguage(clean(text));\n return { ok: routed.language !== \"\", summary: routed.language ? `Detected language ${routed.language} for the extracted text.` : \"The extracted text language is undetermined.\", details: { language: routed.language, routed } };\n }\n case \"listshadow\": {\n const paths = shadowpaths(describescopes(root));\n return { ok: true, summary: `Listed ${paths.length} open shadow root${paths.length === 1 ? \"\" : \"s\"}.`, details: { shadows: paths } };\n }\n case \"listframes\": {\n const frames = framelist(root);\n return { ok: true, summary: `Listed ${frames.length} iframe${frames.length === 1 ? \"\" : \"s\"}.`, details: { frames } };\n }\n default: return { ok: false, summary: \"Unsupported page observation.\" };\n }\n}\n", "import type { bannerreport, listpattern, tableshape, toolstep } from \"../types.js\";\nimport type { stepresult } from \"./pageactions.js\";\nimport { clean, elementselector } from \"./pageresolve.js\";\n\n/**\n * Page shape detection for reviewed steps.\n * Every correlated rule for repeated list detection, table shape normalization, pagination estimates, infinite scroll ranges, virtualization, lazy images, sticky overlays, scroll locks, consent banner shapes, template classification, section fingerprints and scroll positions lives in this file.\n */\n\n/** Serializable sibling sample of one container element used by the list detector. */\nexport interface siblingsample {\n container: string;\n children: Array<{ tag: string; classes: string; text: string; selector: string }>;\n}\n\n/** Finds repeated item lists with a shared item selector from sibling samples. */\nexport function detectlistpatterns(samples: siblingsample[]): listpattern[] {\n const patterns: listpattern[] = [];\n for (const sample of samples) {\n const groups = new Map<string, Array<{ tag: string; classes: string; text: string }>>();\n for (const child of sample.children) {\n const key = `${child.tag}|${child.classes}`;\n const group = groups.get(key) ?? [];\n group.push(child);\n groups.set(key, group);\n }\n for (const [key, group] of groups) {\n if (group.length < 2) continue;\n if (!group.some(item => item.text)) continue;\n const [tag, classes] = key.split(\"|\") as [string, string?];\n const classpart = (classes ?? \"\").split(\" \").filter(Boolean).map(name => `.${name}`).join(\"\");\n patterns.push({ container: sample.container, itemselector: `${tag}${classpart}`, repeat: group.length, samples: group.map(item => item.text).filter(Boolean) });\n }\n }\n return patterns;\n}\n\n/** Normalizes one table row structure into header row, column specs and caption. */\nexport function normalizetable(rows: Array<{ cells: string[]; header: boolean }>, caption: string): { headers: string[]; columns: Array<{ label: string; cells: number }>; rows: number; caption: string } {\n const firstheader = rows.find(row => row.header);\n const headers = firstheader?.cells ?? [];\n const body = firstheader ? rows.filter(row => row !== firstheader) : rows;\n const width = rows.reduce((largest, row) => Math.max(largest, row.cells.length), 0);\n const columns: Array<{ label: string; cells: number }> = [];\n for (let index = 0; index < width; index += 1) {\n const label = headers[index] ?? `column ${index + 1}`;\n const cells = body.filter(row => Boolean((row.cells[index] ?? \"\").trim())).length;\n columns.push({ label, cells });\n }\n return { headers, columns, rows: body.length, caption };\n}\n\n/** Counts pagination entries and estimates the total page count from the numbers they carry. */\nexport function paginationestimate(entries: Array<{ text: string; selector: string; current: boolean }>): { current: number; total: number; links: number; pages: number[] } {\n const pages: number[] = [];\n let current = 0;\n for (const entry of entries) {\n const parsed = /^\\d+$/.exec(entry.text.trim());\n if (parsed) {\n const page = Number.parseInt(parsed[0] as string, 10);\n pages.push(page);\n if (entry.current) current = page;\n }\n }\n const total = Math.max(0, ...pages, current);\n return { current, total, links: entries.length, pages };\n}\n\n/** Serializable scroll range input of one scrollable container. */\nexport interface scrollrangeshape {\n selector: string;\n scrollheight: number;\n clientheight: number;\n triggers: string[];\n}\n\n/** Flags infinite scroll containers from measured scroll ranges and their load more triggers. */\nexport function infinitescrollranges(ranges: scrollrangeshape[]): Array<{ selector: string; scrollrange: number; triggers: string[] }> {\n return ranges\n .filter(range => range.scrollheight > range.clientheight && range.triggers.length > 0)\n .map(range => ({ selector: range.selector, scrollrange: range.scrollheight - range.clientheight, triggers: range.triggers }));\n}\n\n/** Detects virtualized lists whose uniform rendered rows do not fill the measured scroll range. */\nexport function virtualizedcontainers(containers: Array<{ selector: string; scrollheight: number; rows: Array<{ selector: string; height: number; classes: string }> }>): Array<{ selector: string; rendered: number; estimated: number }> {\n const results: Array<{ selector: string; rendered: number; estimated: number }> = [];\n for (const container of containers) {\n const first = container.rows[0];\n if (!first || container.rows.length < 2 || first.height <= 0) continue;\n if (!container.rows.every(row => row.height === first.height)) continue;\n if (container.scrollheight <= container.rows.length * first.height) continue;\n results.push({ selector: container.selector, rendered: container.rows.length, estimated: Math.floor(container.scrollheight / first.height) });\n }\n return results;\n}\n\n/** Serializable image shape used by the lazy detector. */\nexport interface imageshape {\n selector: string;\n src: string;\n datasrc: string;\n loading: string;\n width: number;\n height: number;\n}\n\n/** Detects lazy loaded images from loading attributes and deferred sources, and placeholder states from inline data or empty sources. */\nexport function lazysurvey(images: imageshape[]): { lazy: Array<{ selector: string; reason: string }>; placeholders: Array<{ selector: string; reason: string }> } {\n const lazy: Array<{ selector: string; reason: string }> = [];\n const placeholders: Array<{ selector: string; reason: string }> = [];\n for (const image of images) {\n if (image.loading === \"lazy\") lazy.push({ selector: image.selector, reason: \"loading attribute\" });\n else if (image.datasrc) lazy.push({ selector: image.selector, reason: \"deferred source\" });\n if (!image.src) placeholders.push({ selector: image.selector, reason: \"empty source\" });\n else if (image.src.startsWith(\"data:\")) placeholders.push({ selector: image.selector, reason: \"inline data placeholder\" });\n }\n return { lazy, placeholders };\n}\n\n/** Detects sticky headers and overlays from fixed and sticky geometry measured against the viewport. */\nexport function overlaygeometry(elements: Array<{ selector: string; position: string; top: number; height: number; width: number }>, viewport: { width: number; height: number }): Array<{ selector: string; position: string; coverage: number; hides: boolean }> {\n const area = viewport.width * viewport.height;\n return elements\n .filter(element => (element.position === \"sticky\" || element.position === \"fixed\") && element.top <= 0 && element.height > 0)\n .map(element => {\n const coverage = area > 0 ? (element.height * element.width) / area : 0;\n return { selector: element.selector, position: element.position, coverage: Math.round(coverage * 1000) / 1000, hides: coverage >= overlaythreshold };\n });\n}\n\n/** Detects scroll locks and modal states from body overflow, body position and modal presence signals. */\nexport function scrolllockstate(signals: { bodyoverflow: string; htmloverflow: string; bodyposition: string; modal: boolean; scrollable: boolean }): { locked: boolean; reasons: string[]; scrollable: boolean } {\n const reasons: string[] = [];\n if (signals.bodyoverflow.includes(\"hidden\") || signals.htmloverflow.includes(\"hidden\")) reasons.push(\"overflow hidden\");\n if (signals.bodyposition === \"fixed\") reasons.push(\"fixed body\");\n if (signals.modal) reasons.push(\"modal open\");\n return { locked: reasons.length > 0, reasons, scrollable: signals.scrollable };\n}\n\n/** Serializable consent banner candidate collected by the banner watcher glue. */\nexport interface bannercandidate {\n selector: string;\n id: string;\n classes: string[];\n text: string;\n controls: string[];\n}\n\n/** Consent banner keywords the shape matcher recognizes across locales. */\nexport const consentkeywords = [\"cookie\", \"consent\", \"gdpr\", \"lgpd\", \"privacy\", \"ccpa\"];\n\n/** Matches consent banner shapes against the known keyword vocabulary and reports their controls. */\nexport function bannermatches(candidates: bannercandidate[], at: number): bannerreport[] {\n const reports: bannerreport[] = [];\n for (const candidate of candidates) {\n const haystack = `${candidate.id} ${candidate.classes.join(\" \")} ${candidate.text}`.toLowerCase();\n const keyword = consentkeywords.find(word => haystack.includes(word));\n if (!keyword) continue;\n if (!candidate.text && candidate.controls.length === 0) continue;\n reports.push({ kind: keyword, selector: candidate.selector, text: candidate.text.slice(0, 200), controls: candidate.controls, at });\n }\n return reports;\n}\n\n/** Classifies the page template from its dominant structural signals. */\nexport function classifytemplate(signals: { paragraphs: number; headings: number; lists: number; tables: number; forms: number; inputs: number; password: boolean }): string {\n if (signals.password) return \"login\";\n if (signals.paragraphs >= 3) return \"article\";\n if (signals.tables > 0) return \"table\";\n if (signals.forms > 0 && signals.inputs > 0) return \"form\";\n if (signals.lists > 0) return \"list\";\n return \"generic\";\n}\n\n/** Computes a stable structural fingerprint of one page section from its tag, attributes, child count and text length. */\nexport function sectionfingerprint(section: { tag: string; attributes: Record<string, string>; children: number; textlength: number }): string {\n const canonical = [section.tag, String(section.children), String(section.textlength), ...Object.keys(section.attributes).sort().map(key => `${key}=${section.attributes[key] ?? \"\"}`)].join(\"|\");\n let hash = 5381;\n for (let index = 0; index < canonical.length; index += 1) hash = ((hash << 5) + hash + canonical.charCodeAt(index)) >>> 0;\n return `fp${hash.toString(16)}`;\n}\n\n/** Normalizes the scroll position of the window and its scrollable containers with edge flags. */\nexport function scrollreport(window: { scrollx: number; scrolly: number; scrollheight: number; clientheight: number }, containers: Array<{ selector: string; scrolltop: number; scrollleft: number; scrollheight: number; clientheight: number }>): { window: { x: number; y: number; attop: boolean; atbottom: boolean; height: number }; containers: Array<{ selector: string; scrolltop: number; scrollleft: number; scrollrange: number; atbottom: boolean }> } {\n const range = Math.max(0, window.scrollheight - window.clientheight);\n return {\n window: { x: window.scrollx, y: window.scrolly, attop: window.scrolly <= 0, atbottom: window.scrolly >= range, height: window.scrollheight },\n containers: containers.map(container => {\n const containerrange = Math.max(0, container.scrollheight - container.clientheight);\n return { selector: container.selector, scrolltop: container.scrolltop, scrollleft: container.scrollleft, scrollrange: containerrange, atbottom: container.scrolltop >= containerrange };\n }),\n };\n}\n\nconst loadmorepattern = /(load more|show more|see more|ver mais|carregar mais|load older|afficher plus|mehr anzeigen)/i;\nconst paginationtext = /^(next|prev|previous|last|first|next page|previous page|\u00BB|\u00AB|\u203A|\u2039|\\d+)$/i;\n/** Viewport coverage fraction at which a sticky or fixed overlay is reported as hiding content. */\nconst overlaythreshold = 0.25;\n\nfunction signatureof(element: Element): string {\n return `${element.tagName.toLowerCase()}|${[...element.classList].sort().join(\" \")}`;\n}\n\n/** Collects the sibling samples of one document for the list detector. */\nexport function collectsiblings(root: Document): siblingsample[] {\n const samples: siblingsample[] = [];\n for (const element of [...root.querySelectorAll(\"*\")]) {\n const children = [...element.children];\n if (children.length < 2) continue;\n const counts = new Map<string, number>();\n for (const child of children) {\n const key = signatureof(child);\n counts.set(key, (counts.get(key) ?? 0) + 1);\n }\n if (![...counts.values()].some(count => count >= 2)) continue;\n samples.push({\n container: elementselector(element),\n children: children.map(child => ({ tag: child.tagName.toLowerCase(), classes: [...child.classList].sort().join(\" \"), text: clean(child.textContent ?? \"\"), selector: elementselector(child) })),\n });\n }\n return samples;\n}\n\n/** Collects the data table structures of one document for the table shape normalizer. */\nexport function collecttables(root: Document): Array<{ selector: string; rows: Array<{ cells: string[]; header: boolean }>; caption: string }> {\n return [...root.querySelectorAll(\"table\")].map(table => ({\n selector: elementselector(table),\n rows: [...table.querySelectorAll(\"tr\")].map(row => ({ cells: [...row.querySelectorAll(\"th, td\")].map(cell => clean(cell.textContent ?? \"\")), header: Boolean(row.querySelector(\"th\")) })),\n caption: clean(table.querySelector(\"caption\")?.textContent ?? \"\"),\n }));\n}\n\nfunction collectpagination(root: Document): Array<{ text: string; selector: string; current: boolean }> {\n const entries: Array<{ text: string; selector: string; current: boolean }> = [];\n for (const element of [...root.querySelectorAll(\"a[href], button, [role=button], [role=link], li, span\")]) {\n const text = clean(element.textContent ?? \"\");\n if (!text || !paginationtext.test(text)) continue;\n if (!element.closest(\"nav, footer, [class*=pag i], [id*=pag i]\")) continue;\n const current = element.getAttribute(\"aria-current\") === \"page\" || [...element.classList].some(name => /current|active|selecionado/i.test(name));\n entries.push({ text, selector: elementselector(element), current });\n }\n return entries;\n}\n\nfunction collecttriggers(scope: ParentNode): string[] {\n const triggers: string[] = [];\n for (const element of [...scope.querySelectorAll(\"button, a[href], [role=button], [class*=loading i], [class*=sentinel i], [class*=spinner i]\")]) {\n const label = clean(element.getAttribute(\"aria-label\") ?? element.textContent ?? \"\");\n if (loadmorepattern.test(label)) triggers.push(elementselector(element));\n }\n return triggers;\n}\n\nfunction collectscrollranges(root: Document): scrollrangeshape[] {\n const ranges: scrollrangeshape[] = [];\n const scrolling = root.scrollingElement ?? root.documentElement;\n const viewheight = root.defaultView?.innerHeight ?? 0;\n if (scrolling && scrolling.scrollHeight > viewheight) ranges.push({ selector: \"window\", scrollheight: scrolling.scrollHeight, clientheight: viewheight, triggers: collecttriggers(root) });\n for (const element of [...root.querySelectorAll(\"*\")]) {\n if (!(element instanceof HTMLElement)) continue;\n if (element.scrollHeight <= element.clientHeight) continue;\n ranges.push({ selector: elementselector(element), scrollheight: element.scrollHeight, clientheight: element.clientHeight, triggers: collecttriggers(element) });\n }\n return ranges;\n}\n\nfunction collectvirtual(root: Document): Array<{ selector: string; scrollheight: number; rows: Array<{ selector: string; height: number; classes: string }> }> {\n const containers: Array<{ selector: string; scrollheight: number; rows: Array<{ selector: string; height: number; classes: string }> }> = [];\n for (const element of [...root.querySelectorAll(\"*\")]) {\n const children = [...element.children];\n const first = children[0];\n if (!first || children.length < 2) continue;\n if (!children.every(child => signatureof(child) === signatureof(first))) continue;\n const heights = children.map(child => child.getBoundingClientRect().height);\n if (!heights.every(height => height > 0 && height === heights[0])) continue;\n containers.push({ selector: elementselector(element), scrollheight: element.scrollHeight, rows: children.map(child => ({ selector: elementselector(child), height: child.getBoundingClientRect().height, classes: [...child.classList].join(\" \") })) });\n }\n return containers;\n}\n\nfunction collectimages(root: Document): imageshape[] {\n return [...root.querySelectorAll(\"img\")].map(image => ({\n selector: elementselector(image),\n src: image.getAttribute(\"src\") ?? \"\",\n datasrc: image.getAttribute(\"data-src\") ?? image.getAttribute(\"data-original\") ?? \"\",\n loading: image.getAttribute(\"loading\") ?? \"\",\n width: image.naturalWidth,\n height: image.naturalHeight,\n }));\n}\n\nfunction collectoverlays(root: Document): Array<{ selector: string; position: string; top: number; height: number; width: number }> {\n const elements: Array<{ selector: string; position: string; top: number; height: number; width: number }> = [];\n for (const element of [...root.querySelectorAll(\"*\")]) {\n if (!(element instanceof HTMLElement)) continue;\n const view = element.ownerDocument.defaultView;\n const position = view ? view.getComputedStyle(element).position : \"\";\n if (position !== \"sticky\" && position !== \"fixed\") continue;\n const rect = element.getBoundingClientRect();\n elements.push({ selector: elementselector(element), position, top: rect.top, height: rect.height, width: rect.width });\n }\n return elements;\n}\n\nfunction collectlocksignals(root: Document): { bodyoverflow: string; htmloverflow: string; bodyposition: string; modal: boolean; scrollable: boolean } {\n const view = root.defaultView;\n const bodystyle = root.body ? (view ? view.getComputedStyle(root.body) : undefined) : undefined;\n const htmlstyle = view ? view.getComputedStyle(root.documentElement) : undefined;\n return {\n bodyoverflow: bodystyle?.overflow ?? \"\",\n htmloverflow: htmlstyle?.overflow ?? \"\",\n bodyposition: bodystyle?.position ?? \"\",\n modal: Boolean(root.querySelector(\"dialog[open], [aria-modal=true]\")),\n scrollable: root.documentElement.scrollHeight > root.documentElement.clientHeight,\n };\n}\n\nconst bannerselector = '[id*=\"cookie\" i], [class*=\"cookie\" i], [id*=\"consent\" i], [class*=\"consent\" i], [id*=\"gdpr\" i], [class*=\"gdpr\" i], [id*=\"privacy\" i], [class*=\"privacy\" i], [id*=\"banner\" i], [class*=\"banner\" i], dialog, [role=\"dialog\"], [aria-modal=\"true\"]';\n\n/** Collects the consent banner candidates of one document for the banner shape matcher. */\nexport function collectbannercandidates(root: Document): bannercandidate[] {\n const found = [...root.querySelectorAll(bannerselector)];\n return found\n .filter(element => !found.some(other => other !== element && other.contains(element)))\n .map(element => ({\n selector: elementselector(element),\n id: element.id,\n classes: [...element.classList],\n text: clean(element.textContent ?? \"\").slice(0, 200),\n controls: [...element.querySelectorAll(\"button, a[href], [role=button]\")].map(control => clean(control.getAttribute(\"aria-label\") ?? control.textContent ?? \"\")).filter(Boolean),\n }));\n}\n\n/** Runs one page shape detection after the background policy gate; frame routed steps receive their frame document as the root. */\nexport function runpagedetection(step: toolstep, target: Element | null, root: Document = document): stepresult | Promise<stepresult> {\n switch (step.kind) {\n case \"detectlists\": {\n const patterns = detectlistpatterns(collectsiblings(root));\n return { ok: true, summary: `Detected ${patterns.length} repeated list${patterns.length === 1 ? \"\" : \"s\"}.`, details: { lists: patterns } };\n }\n case \"detecttables\": {\n const tables: tableshape[] = collecttables(root).map(entry => {\n const shape = normalizetable(entry.rows, entry.caption);\n return { selector: entry.selector, headers: shape.headers, columns: shape.columns, rows: shape.rows, caption: shape.caption };\n });\n return { ok: true, summary: `Detected ${tables.length} data table${tables.length === 1 ? \"\" : \"s\"}.`, details: { tables } };\n }\n case \"countpages\": {\n const estimate = paginationestimate(collectpagination(root));\n return { ok: true, summary: `Counted ${estimate.links} pagination entr${estimate.links === 1 ? \"y\" : \"ies\"} and estimated ${estimate.total} total page${estimate.total === 1 ? \"\" : \"s\"}.`, details: { current: estimate.current, total: estimate.total, links: estimate.links, pages: estimate.pages } };\n }\n case \"detectinfinitescroll\": {\n const containers = infinitescrollranges(collectscrollranges(root));\n return { ok: true, summary: `Detected ${containers.length} infinite scroll container${containers.length === 1 ? \"\" : \"s\"}.`, details: { containers } };\n }\n case \"detectvirtual\": {\n const containers = virtualizedcontainers(collectvirtual(root));\n return { ok: true, summary: `Detected ${containers.length} virtualized list${containers.length === 1 ? \"\" : \"s\"}.`, details: { containers } };\n }\n case \"detectlazy\": {\n const survey = lazysurvey(collectimages(root));\n return { ok: true, summary: `Detected ${survey.lazy.length} lazy image${survey.lazy.length === 1 ? \"\" : \"s\"} and ${survey.placeholders.length} placeholder${survey.placeholders.length === 1 ? \"\" : \"s\"}.`, details: { lazy: survey.lazy, placeholders: survey.placeholders } };\n }\n case \"detectsticky\": {\n const overlays = overlaygeometry(collectoverlays(root), { width: root.defaultView?.innerWidth ?? 0, height: root.defaultView?.innerHeight ?? 0 });\n return { ok: true, summary: `Detected ${overlays.length} sticky or fixed overlay${overlays.length === 1 ? \"\" : \"s\"}.`, details: { overlays } };\n }\n case \"detectscrolllock\": {\n const lock = scrolllockstate(collectlocksignals(root));\n return { ok: true, summary: lock.locked ? `Scroll is locked: ${lock.reasons.join(\", \")}.` : \"Scroll is not locked.\", details: { locked: lock.locked, reasons: lock.reasons, scrollable: lock.scrollable } };\n }\n case \"classifypage\": {\n const signals = {\n paragraphs: root.querySelectorAll(\"p\").length,\n headings: root.querySelectorAll(\"h1, h2, h3, h4, h5, h6\").length,\n lists: root.querySelectorAll(\"ul, ol\").length,\n tables: root.querySelectorAll(\"table\").length,\n forms: root.querySelectorAll(\"form\").length,\n inputs: root.querySelectorAll(\"input, textarea, select\").length,\n password: Boolean(root.querySelector(\"input[type=password]\")),\n };\n const template = classifytemplate(signals);\n const fingerprint = sectionfingerprint({ tag: \"body\", attributes: {}, children: root.body?.children.length ?? 0, textlength: (root.body?.innerText ?? \"\").length });\n return { ok: true, summary: `Classified the page template as ${template}.`, details: { template, fingerprint } };\n }\n case \"fingerprintsection\": {\n if (!target) return { ok: false, summary: \"Fingerprint target is no longer available.\" };\n const attributes: Record<string, string> = {};\n for (const attribute of [...target.attributes]) attributes[attribute.name] = attribute.value;\n const fingerprint = sectionfingerprint({ tag: target.tagName.toLowerCase(), attributes, children: target.children.length, textlength: (target.textContent ?? \"\").length });\n return { ok: true, summary: `Computed section fingerprint ${fingerprint}.`, details: { fingerprint, section: elementselector(target) } };\n }\n case \"readscrollpos\": {\n const report = scrollreport(\n { scrollx: root.defaultView?.scrollX ?? 0, scrolly: root.defaultView?.scrollY ?? 0, scrollheight: root.documentElement.scrollHeight, clientheight: root.defaultView?.innerHeight ?? 0 },\n [...root.querySelectorAll(\"*\")].filter(element => element instanceof HTMLElement && element.scrollHeight > element.clientHeight).map(element => ({ selector: elementselector(element), scrolltop: element.scrollTop, scrollleft: element.scrollLeft, scrollheight: element.scrollHeight, clientheight: element.clientHeight })),\n );\n return { ok: true, summary: `Read the scroll position at ${Math.round(report.window.x)},${Math.round(report.window.y)} with ${report.containers.length} scrollable container${report.containers.length === 1 ? \"\" : \"s\"}.`, details: { scroll: report } };\n }\n default: return { ok: false, summary: \"Unsupported page detection.\" };\n }\n}\n", "import type { bannerreport, diffentry, focusevent, jsonstate, mutationevent, mutationwatch, quietrule, selectorcandidate, toolstep } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\nimport type { stepresult } from \"./pageactions.js\";\nimport { bannermatches, collectbannercandidates } from \"./pagedetect.js\";\nimport { clean, elementselector } from \"./pageresolve.js\";\n\n/**\n * Watched page observation for reviewed steps.\n * Every correlated rule for watch option parsing, mutation batching, focus tracking, the network quiet probe, the snapshot diff engine, the json state scanner and the selector scorer lives in this file.\n */\n\n/** Internal sampling cadence used when a watch step reviews no poll interval. */\nconst defaultpoll = 250;\n\n/** Parsed watch options of one watch step: the mutationwatch fields plus the poll interval. */\nexport type watchoptions = mutationwatch & { watchid: string; poll: number };\n\n/** Parses the reviewed watch options of one watch step into its mutationwatch shape with a poll interval. */\nexport function parsewatchoptions(step: toolstep, fallbackid: string): watchoptions {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n const scopes = Array.isArray(options.scopes) ? options.scopes.filter((item): item is string => typeof item === \"string\" && item.trim().length > 0) : undefined;\n const events = Array.isArray(options.events) ? options.events.filter((item): item is string => typeof item === \"string\" && item.trim().length > 0) : undefined;\n const lifetime = typeof options.lifetime === \"number\" && Number.isFinite(options.lifetime) && options.lifetime > 0 ? options.lifetime : 0;\n return {\n watchid: typeof options.watchid === \"string\" && options.watchid.trim() ? options.watchid : fallbackid,\n ...(scopes ? { scopes } : {}),\n ...(events ? { events } : {}),\n lifetime,\n poll: typeof options.poll === \"number\" && Number.isFinite(options.poll) && options.poll >= 0 ? options.poll : defaultpoll,\n };\n}\n\n/** Batches mutation records so records arriving inside one throttle window flush to the bridge together. */\nexport function batchmutations(records: mutationevent[], windowms: number): mutationevent[][] {\n const batches: mutationevent[][] = [];\n let current: mutationevent[] = [];\n let opened = -1;\n for (const record of records) {\n if (current.length === 0 || (windowms > 0 && record.at - opened >= windowms)) {\n if (current.length > 0) batches.push(current);\n current = [record];\n opened = record.at;\n } else current.push(record);\n }\n if (current.length > 0) batches.push(current);\n return batches;\n}\n\n/** Measures how long the network has stayed quiet from the resource timing entries completed so far. */\nexport function quietfor(entries: Array<{ responseend: number }>, now: number): number {\n let last = 0;\n for (const entry of entries) if (entry.responseend > last) last = entry.responseend;\n return Math.max(0, now - last);\n}\n\n/** Decides the network quiet outcome from collected probe samples against the reviewed idle threshold and timeout. */\nexport function quietresolution(samples: Array<{ at: number; quietfor: number }>, idle: number, timeout: number): { ok: boolean; quietfor: number; waited: number; samples: number } {\n const start = samples[0]?.at ?? 0;\n const last = samples[samples.length - 1];\n const waited = Math.max(0, (last?.at ?? 0) - start);\n const reached = samples.find(sample => sample.quietfor >= idle);\n if (reached) return { ok: true, quietfor: reached.quietfor, waited: reached.at - start, samples: samples.length };\n return { ok: false, quietfor: last?.quietfor ?? 0, waited, samples: samples.length };\n}\n\n/** Serializable node summary the diff engine compares between observation versions. */\nexport interface nodesummary {\n selector: string;\n tag: string;\n text: string;\n attributes: Record<string, string>;\n}\n\n/** Hashes one node summary into a stable digest used by the diff engine. */\nexport function nodehash(summary: nodesummary): string {\n const canonical = [summary.tag, summary.text, ...Object.keys(summary.attributes).sort().map(key => `${key}=${summary.attributes[key] ?? \"\"}`)].join(\"|\");\n let hash = 5381;\n for (let index = 0; index < canonical.length; index += 1) hash = ((hash << 5) + hash + canonical.charCodeAt(index)) >>> 0;\n return hash.toString(16);\n}\n\n/** Diffs two node summary sets into added, removed and changed entries by hashing node summaries. */\nexport function diffsummaries(base: nodesummary[], target: nodesummary[]): { added: diffentry[]; removed: diffentry[]; changed: diffentry[] } {\n const basemap = new Map(base.map(node => [node.selector, node]));\n const targetmap = new Map(target.map(node => [node.selector, node]));\n const added: diffentry[] = [];\n const removed: diffentry[] = [];\n const changed: diffentry[] = [];\n for (const [selector, node] of targetmap) {\n const previous = basemap.get(selector);\n if (!previous) { added.push({ kind: \"added\", selector, summary: node.text || node.tag }); continue; }\n if (nodehash(previous) !== nodehash(node)) changed.push({ kind: \"changed\", selector, summary: `${previous.text || previous.tag} became ${node.text || node.tag}` });\n }\n for (const [selector, node] of basemap) {\n if (!targetmap.has(selector)) removed.push({ kind: \"removed\", selector, summary: node.text || node.tag });\n }\n return { added, removed, changed };\n}\n\n/** Scans inline script payloads for embedded json state; malformed payloads are refused and counted. */\nexport function scanjson(scripts: Array<{ src: string; type: string; id: string; content: string }>): { states: jsonstate[]; refused: number } {\n const states: jsonstate[] = [];\n let refused = 0;\n for (const script of scripts) {\n if (script.src) continue;\n const content = script.content.trim();\n if (!(script.type.includes(\"json\") || content.startsWith(\"{\") || content.startsWith(\"[\"))) continue;\n try { states.push({ scripturl: script.src, rootpath: script.id, payload: JSON.parse(content) }); } catch { refused += 1; }\n }\n return { states, refused };\n}\n\n/** Ranks selector candidates of one element shape by stability: id, attribute, text and structural strategies. */\nexport function rankselectors(shape: { id: string; tag: string; attributes: Record<string, string>; text: string; index: number; siblings: number }): selectorcandidate[] {\n const candidates: selectorcandidate[] = [];\n if (shape.id) candidates.push({ selector: `#${shape.id}`, strategy: \"id\", score: 100 });\n for (const [name, value] of Object.entries(shape.attributes)) {\n if (!value) continue;\n if (name === \"name\" || name.startsWith(\"data-\") || name.startsWith(\"aria-\")) candidates.push({ selector: `${shape.tag}[${name}=\"${value}\"]`, strategy: \"attribute\", score: 80 });\n }\n if (shape.text) candidates.push({ selector: shape.text, strategy: \"text\", score: 60 });\n if (shape.index > 0) candidates.push({ selector: `${shape.tag}:nth-of-type(${shape.index})`, strategy: \"structural\", score: 40 });\n return candidates.sort((left, right) => right.score - left.score);\n}\n\nfunction wait(ms: number): Promise<void> {\n return new Promise(resolve => window.setTimeout(resolve, ms));\n}\n\nfunction quietruleof(step: toolstep): quietrule {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n const rule = options.quietrule;\n if (!rule || typeof rule !== \"object\" || Array.isArray(rule)) return { idle: 0 };\n const quiet = rule as Record<string, unknown>;\n return {\n idle: typeof quiet.idle === \"number\" && Number.isFinite(quiet.idle) && quiet.idle > 0 ? quiet.idle : 0,\n ...(typeof quiet.poll === \"number\" && Number.isFinite(quiet.poll) && quiet.poll >= 0 ? { poll: quiet.poll } : {}),\n ...(typeof quiet.timeout === \"number\" && Number.isFinite(quiet.timeout) && quiet.timeout >= 0 ? { timeout: quiet.timeout } : {}),\n };\n}\n\n/** Observes dom mutations inside the reviewed selector scopes for the reviewed lifetime, batching records through the throttle window. */\nasync function watchmutations(step: toolstep, root: Document): Promise<stepresult> {\n const options = parsewatchoptions(step, step.id);\n if (options.lifetime <= 0) return { ok: false, summary: \"The reviewed mutation watch lifetime is absent.\" };\n const roots: ParentNode[] = options.scopes ? options.scopes.flatMap(selector => [...root.querySelectorAll(selector)]) : [root];\n if (roots.length === 0) return { ok: false, summary: \"The reviewed watch scopes match no elements.\" };\n const allowed = options.events;\n const collected: mutationevent[] = [];\n const observer = new MutationObserver(records => {\n for (const record of records) {\n if (allowed && !allowed.includes(record.type)) continue;\n const target = record.target instanceof Element ? record.target : null;\n collected.push({ watchid: options.watchid, event: record.type, targetpath: target ? elementselector(target) : \"#text\", at: Date.now() });\n }\n });\n for (const scope of roots) observer.observe(scope, { childList: true, attributes: true, characterData: true, subtree: true });\n await wait(options.lifetime);\n observer.disconnect();\n const batches = batchmutations(collected, options.poll);\n return { ok: true, summary: `Watched ${collected.length} mutation${collected.length === 1 ? \"\" : \"s\"} in ${batches.length} batch${batches.length === 1 ? \"\" : \"es\"} for the reviewed lifetime of ${options.lifetime} milliseconds.`, details: { events: collected, batches: batches.length, watchid: options.watchid, lifetime: options.lifetime, scopes: options.scopes ?? [] } };\n}\n\n/** Records focus and blur events with element paths for the reviewed lifetime. */\nasync function watchfocus(step: toolstep, root: Document): Promise<stepresult> {\n const options = parsewatchoptions(step, step.id);\n if (options.lifetime <= 0) return { ok: false, summary: \"The reviewed focus watch lifetime is absent.\" };\n const collected: focusevent[] = [];\n const record = (kind: \"focus\" | \"blur\") => (event: Event): void => {\n const target = event.target instanceof Element ? event.target : null;\n collected.push({ watchid: options.watchid, kind, targetpath: target ? elementselector(target) : \"#document\", at: Date.now() });\n };\n const onfocus = record(\"focus\");\n const onblur = record(\"blur\");\n root.addEventListener(\"focusin\", onfocus, true);\n root.addEventListener(\"focusout\", onblur, true);\n await wait(options.lifetime);\n root.removeEventListener(\"focusin\", onfocus, true);\n root.removeEventListener(\"focusout\", onblur, true);\n return { ok: true, summary: `Watched ${collected.length} focus change${collected.length === 1 ? \"\" : \"s\"} for the reviewed lifetime of ${options.lifetime} milliseconds.`, details: { events: collected, watchid: options.watchid, lifetime: options.lifetime } };\n}\n\n/** Watches for cookie and consent banners for the reviewed lifetime and reports their controls. */\nasync function watchbanners(step: toolstep, root: Document): Promise<stepresult> {\n const options = parsewatchoptions(step, step.id);\n if (options.lifetime <= 0) return { ok: false, summary: \"The reviewed banner watch lifetime is absent.\" };\n const started = Date.now();\n const seen = new Map<string, bannerreport>();\n while (Date.now() - started < options.lifetime) {\n const at = Date.now();\n for (const report of bannermatches(collectbannercandidates(root), at)) {\n if (!seen.has(report.selector)) seen.set(report.selector, report);\n }\n await wait(options.poll);\n }\n const reports = [...seen.values()];\n return { ok: true, summary: `Watched for consent banners for the reviewed lifetime of ${options.lifetime} milliseconds and observed ${reports.length} banner${reports.length === 1 ? \"\" : \"s\"}.`, details: { banners: reports, watchid: options.watchid, lifetime: options.lifetime } };\n}\n\n/** Waits until the network stays quiet for the reviewed idle threshold, sampling in flight requests through the performance timeline. */\nasync function waitquiet(step: toolstep): Promise<stepresult> {\n const rule = quietruleof(step);\n if (rule.idle <= 0) return { ok: false, summary: \"The reviewed quiet idle threshold is absent.\" };\n const poll = rule.poll ?? 100;\n const timeout = rule.timeout ?? 0;\n const started = performance.now();\n const samples: Array<{ at: number; quietfor: number }> = [];\n for (;;) {\n const now = performance.now();\n const entries = (performance.getEntriesByType(\"resource\") as PerformanceResourceTiming[]).map(entry => ({ responseend: entry.responseEnd }));\n samples.push({ at: now - started, quietfor: quietfor(entries, now) });\n const latest = samples[samples.length - 1];\n if (latest && latest.quietfor >= rule.idle) break;\n if (timeout > 0 && now - started >= timeout) break;\n await wait(poll);\n }\n const outcome = quietresolution(samples, rule.idle, timeout);\n return {\n ok: outcome.ok,\n summary: outcome.ok\n ? `The network stayed quiet for ${Math.round(outcome.quietfor)} milliseconds, meeting the reviewed idle threshold of ${rule.idle} milliseconds.`\n : `The network did not stay quiet for ${rule.idle} milliseconds${timeout > 0 ? ` within the reviewed timeout of ${timeout} milliseconds` : \"\"}.`,\n details: { samples, idle: rule.idle, timeout, waited: Math.round(outcome.waited) },\n };\n}\n\nfunction scriptsurfaces(target: Element | null, root: Document): Array<{ src: string; type: string; id: string; content: string }> {\n const elements = target ? [target] : [...root.querySelectorAll(\"script\")];\n return elements.map(element => ({ src: element.getAttribute(\"src\") ?? \"\", type: element.getAttribute(\"type\") ?? \"\", id: element.id, content: element.textContent ?? \"\" }));\n}\n\n/** Extracts embedded json state from inline scripts and refuses malformed payloads. */\nfunction readjson(step: toolstep, target: Element | null, root: Document): stepresult {\n const outcome = scanjson(scriptsurfaces(target, root));\n if (target && outcome.states.length === 0 && outcome.refused > 0) return { ok: false, summary: \"The reviewed json payload is malformed and was refused.\" };\n return { ok: true, summary: `Extracted ${outcome.states.length} embedded json state${outcome.states.length === 1 ? \"\" : \"s\"}${outcome.refused > 0 ? ` and refused ${outcome.refused} malformed payload${outcome.refused === 1 ? \"\" : \"s\"}` : \"\"}.`, details: { states: outcome.states, refused: outcome.refused } };\n}\n\nfunction tonodesummaries(value: unknown): nodesummary[] | null {\n if (!Array.isArray(value)) return null;\n const summaries: nodesummary[] = [];\n for (const entry of value) {\n if (!entry || typeof entry !== \"object\" || Array.isArray(entry)) continue;\n const candidate = entry as Record<string, unknown>;\n if (typeof candidate.selector !== \"string\") continue;\n const attributes: Record<string, string> = {};\n if (candidate.attributes && typeof candidate.attributes === \"object\" && !Array.isArray(candidate.attributes)) {\n for (const [key, item] of Object.entries(candidate.attributes as Record<string, unknown>)) if (typeof item === \"string\") attributes[key] = item;\n }\n summaries.push({ selector: candidate.selector, tag: typeof candidate.tag === \"string\" ? candidate.tag : \"\", text: typeof candidate.text === \"string\" ? candidate.text : \"\", attributes });\n }\n return summaries;\n}\n\n/** Diffs the two reviewed observation versions injected by the background into added, removed and changed nodes. */\nfunction diffsnapshots(step: toolstep): stepresult {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n const base = tonodesummaries(options.base);\n const target = tonodesummaries(options.target);\n if (!base || !target) return { ok: false, summary: \"Two stored observation versions must be reviewed before diffing.\" };\n const versions = Array.isArray(options.versions) && options.versions.length === 2 ? (options.versions as number[]) : [0, 0];\n const diff = diffsummaries(base, target);\n return { ok: true, summary: `Diffed observation versions ${versions[0] ?? 0} and ${versions[1] ?? 0}: ${diff.added.length} added, ${diff.removed.length} removed and ${diff.changed.length} changed node${diff.added.length + diff.removed.length + diff.changed.length === 1 ? \"\" : \"s\"}.`, details: { versions, added: diff.added, removed: diff.removed, changed: diff.changed } };\n}\n\n/** Derives ranked selector candidates for one reviewed element. */\nfunction deriveselector(target: Element | null): stepresult {\n if (!(target instanceof Element)) return { ok: false, summary: \"Derivation target is no longer available.\" };\n const attributes: Record<string, string> = {};\n for (const attribute of [...target.attributes]) attributes[attribute.name] = attribute.value;\n const parent = target.parentElement;\n const siblings = parent ? [...parent.children].filter(node => node.tagName === target.tagName) : [target];\n const candidates = rankselectors({ id: target.id, tag: target.tagName.toLowerCase(), attributes, text: clean(target.textContent ?? \"\").slice(0, 80), index: siblings.indexOf(target) + 1, siblings: siblings.length });\n const best = candidates[0];\n return { ok: candidates.length > 0, summary: best ? `Derived ${candidates.length} selector candidate${candidates.length === 1 ? \"\" : \"s\"}; the most stable is ${best.selector} through the ${best.strategy} strategy with stability ${best.score}.` : \"No selector candidate could be derived.\", details: { candidates } };\n}\n\n/** Runs one watched observation after the background policy gate; the reviewed lifetime window bounds every watch. */\nexport function runpagewatch(step: toolstep, target: Element | null, root: Document = document): stepresult | Promise<stepresult> {\n switch (step.kind) {\n case \"watchmutate\": return watchmutations(step, root);\n case \"watchfocus\": return watchfocus(step, root);\n case \"watchbanner\": return watchbanners(step, root);\n case \"waitquiet\": return waitquiet(step);\n case \"readjson\": return readjson(step, target, root);\n case \"diffsnapshots\": return diffsnapshots(step);\n case \"deriveselector\": return deriveselector(target);\n default: return { ok: false, summary: \"Unsupported watched observation.\" };\n }\n}\n", "import type { fielderror, fieldkind, fieldmatch, formrecord, formentry, formreport, toolstep } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\nimport type { stepresult } from \"./pageactions.js\";\nimport { clean, elementlabel as label, elementselector as selector } from \"./pageresolve.js\";\n\n/**\n * Form field logics for reviewed steps.\n * Every correlated rule for field matching, field kind classification, seeded value generation, native value fills, honeypot detection, login and template detection, error association and form record parsing lives in this file.\n */\n\n/** One serializable form field shape resolved against the page controls. */\nexport interface fieldshape {\n selector: string;\n tag: string;\n type: string;\n name: string;\n label: string;\n placeholder: string;\n arialabel: string;\n autocomplete: string;\n options?: string[];\n}\n\n/** One surveyed field shape carrying the visibility, geometry and timing evidence the honeypot detector reads. */\nexport interface fieldsurvey extends fieldshape {\n hidden: boolean;\n offscreen: boolean;\n createdat?: number;\n}\n\n/** One honeypot field flagged by hidden, offscreen or time trap evidence. */\nexport interface honeypotevidence {\n selector: string;\n reason: \"hidden\" | \"offscreen\" | \"timetrap\";\n}\n\n/** One surveyed field with the aria describedby ref and the sibling message texts the error reader associates. */\nexport interface errorcontext extends fieldshape {\n describedby?: string;\n siblings: string[];\n}\n\n/** Resolves controls by label, placeholder, aria label and name attributes; matches are case insensitive substrings. */\nexport function matchfield(fields: fieldshape[], match: fieldmatch): fieldshape[] {\n const key = match.mode === \"label\" ? \"label\" : match.mode === \"placeholder\" ? \"placeholder\" : match.mode === \"arialabel\" ? \"arialabel\" : \"name\";\n const needle = (match[key] ?? \"\").trim().toLowerCase();\n if (!needle) return [];\n return fields.filter(field => {\n const primary = (field[key] as string).toLowerCase();\n const secondary = match.mode === \"label\" || match.mode === \"name\" ? field.name.toLowerCase() : match.mode === \"placeholder\" ? field.arialabel.toLowerCase() : field.placeholder.toLowerCase();\n return primary.includes(needle) || secondary.includes(needle);\n });\n}\n\n/** Infers the field kind of one control from its input type, autocomplete hint and label text. */\nexport function classifyfield(input: { type: string; autocomplete: string; label: string }): fieldkind {\n const type = input.type.toLowerCase();\n const autocomplete = input.autocomplete.toLowerCase();\n const label = input.label.toLowerCase();\n if (type === \"password\") return \"password\";\n if (autocomplete.startsWith(\"cc-\") || label.includes(\"card number\") || label.includes(\"credit card\") || label.includes(\"cardholder\")) return \"card\";\n if (autocomplete.includes(\"one-time-code\") || autocomplete.includes(\"otp\") || label.includes(\"one time code\") || label.includes(\"verification code\") || label.includes(\"otp\")) return \"code\";\n if (type === \"email\" || autocomplete.includes(\"email\") || label.includes(\"email\")) return \"email\";\n if (type === \"tel\" || autocomplete.includes(\"tel\") || label.includes(\"phone\") || label.includes(\"telephone\")) return \"phone\";\n if (type === \"date\") return \"date\";\n if (type === \"number\") return \"number\";\n if (type === \"checkbox\") return \"check\";\n if (type === \"radio\") return \"radio\";\n if (type === \"file\") return \"file\";\n if (type === \"select\" || type === \"select-one\") return \"select\";\n return \"text\";\n}\n\nconst firstnames: Record<string, string[]> = { en: [\"alex\", \"jordan\", \"taylor\", \"morgan\", \"casey\"], pt: [\"ana\", \"bruno\", \"carla\", \"diego\", \"helena\"] };\nconst lastnames: Record<string, string[]> = { en: [\"brooks\", \"carter\", \"diaz\", \"evans\", \"reyes\"], pt: [\"alves\", \"costa\", \"lima\", \"souza\", \"moraes\"] };\n\nfunction localekey(locale: string): string {\n const normalized = locale.toLowerCase();\n if (normalized.startsWith(\"pt\")) return \"pt\";\n return \"en\";\n}\n\n/** Generates one realistic value for a field kind, deterministically seeded and locale aware for names, emails and phones. */\nexport function generatevalue(kind: fieldkind, rule: { locale?: string; seed?: number }): string {\n const seed = typeof rule.seed === \"number\" && Number.isFinite(rule.seed) ? Math.abs(Math.floor(rule.seed)) : 1;\n const names = firstnames[localekey(rule.locale ?? \"en\")] ?? firstnames.en ?? [\"alex\"];\n const surnames = lastnames[localekey(rule.locale ?? \"en\")] ?? lastnames.en ?? [\"brooks\"];\n let state = seed * 1103515245 + 12345;\n const next = (): number => { state = (state * 1103515245 + 12345) % 2147483648; return state / 2147483648; };\n const pick = <T>(items: T[]): T => items[Math.floor(next() * items.length) % items.length] ?? items[0] as T;\n const digits = (count: number): string => Array.from({ length: count }, () => String(Math.floor(next() * 10))).join(\"\");\n const person = `${pick(names)} ${pick(surnames)}`;\n switch (kind) {\n case \"email\": return `${person.replace(\" \", \".\")}${digits(2)}@example.com`;\n case \"phone\": return localekey(rule.locale ?? \"en\") === \"pt\" ? `+55 (11) 9${digits(4)}-${digits(4)}` : `+1 (555) 010-${digits(4)}`;\n case \"date\": return `${2024 + Math.floor(next() * 2)}-${String(1 + Math.floor(next() * 12)).padStart(2, \"0\")}-${String(1 + Math.floor(next() * 28)).padStart(2, \"0\")}`;\n case \"number\": return String(Math.floor(next() * 1000));\n case \"select\": return `option ${1 + Math.floor(next() * 5)}`;\n case \"check\": return next() > 0.5 ? \"true\" : \"false\";\n case \"radio\": return `choice ${1 + Math.floor(next() * 4)}`;\n case \"file\": return `sample${digits(2)}.pdf`;\n case \"password\": return `pw-${digits(6)}-${pick(names)}`;\n case \"card\": return `4111 ${digits(4)} ${digits(4)} ${digits(4)}`;\n case \"code\": return digits(6);\n default: return person;\n }\n}\n\n/** Builds a deterministic values hash of the reviewed field values a submission ticket records. */\nexport function valueshash(values: Array<{ label: string; value: string }>): string {\n const source = values.map(entry => `${entry.label}=${entry.value}`).join(\"|\");\n let hash = 5381;\n for (let index = 0; index < source.length; index += 1) hash = ((hash * 33) ^ source.charCodeAt(index)) >>> 0;\n return hash.toString(16);\n}\n\n/** Parses the reviewed structured form record of a step; null when the step reviews none or the shape is invalid. */\nexport function parseformrecord(value: unknown): formrecord | null {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return null;\n const record = value as Record<string, unknown>;\n if (!Array.isArray(record.entries)) return null;\n const entries: formentry[] = [];\n for (const item of record.entries) {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) continue;\n const entry = item as Record<string, unknown>;\n const match = entry.match;\n if (!match || typeof match !== \"object\" || Array.isArray(match)) continue;\n const shapes = match as Record<string, unknown>;\n if (typeof shapes.mode !== \"string\") continue;\n const fieldmatch: fieldmatch = {\n mode: shapes.mode as fieldmatch[\"mode\"],\n ...(typeof shapes.label === \"string\" ? { label: shapes.label } : {}),\n ...(typeof shapes.placeholder === \"string\" ? { placeholder: shapes.placeholder } : {}),\n ...(typeof shapes.arialabel === \"string\" ? { arialabel: shapes.arialabel } : {}),\n ...(typeof shapes.name === \"string\" ? { name: shapes.name } : {}),\n };\n if (typeof entry.kind !== \"string\" || typeof entry.value !== \"string\") continue;\n entries.push({ match: fieldmatch, kind: entry.kind as fieldkind, value: entry.value });\n }\n if (entries.length === 0) return null;\n return { ...(typeof record.form === \"string\" && record.form ? { form: record.form } : {}), entries };\n}\n\n/** Builds form record entries from reviewed label or placeholder value pairs. */\nexport function pairentries(pairs: Array<{ label?: string; placeholder?: string; value: string }>, mode: \"label\" | \"placeholder\"): formrecord {\n return { entries: pairs.map(pair => ({ match: mode === \"label\" ? { mode, label: pair.label ?? \"\" } : { mode, placeholder: pair.placeholder ?? \"\" }, kind: \"text\", value: pair.value })) };\n}\n\n/** One fill operation outcome: the entry, the matched control, the honeypot skip flag or the refusal reason. */\nexport interface filloutcome {\n entry: formentry;\n matched?: fieldshape;\n skipped?: boolean;\n reason?: string;\n}\n\n/** Resolves every entry of a form record against the surveyed fields, skipping honeypots and refusing unmatched or ambiguous entries. */\nexport function filloperations(record: formrecord, fields: fieldshape[], skippedselectors: string[] = []): filloutcome[] {\n return record.entries.map(entry => {\n const matches = matchfield(fields, entry.match);\n if (matches.length === 0) return { entry, reason: \"unmatched\" };\n if (matches.length > 1) return { entry, reason: \"ambiguous\" };\n const matched = matches[0] as fieldshape;\n if (skippedselectors.includes(matched.selector)) return { entry, matched, skipped: true };\n return { entry, matched };\n });\n}\n\n/** Masks one card segment so side panels can render card fills without exposing the full value. */\nexport function cardmask(value: string): string {\n const trimmed = value.trim();\n if (/^\\d[\\d\\s-]{11,18}$/.test(trimmed)) {\n const compact = trimmed.replace(/[\\s-]/g, \"\");\n const last = compact.slice(-4);\n return `${\"\u2022\".repeat(Math.max(0, compact.length - 4))}${last}`;\n }\n return \"\u2022\".repeat(trimmed.length);\n}\n\n/** Flags hidden, offscreen and time trap fields so fill steps skip them instead of tripping anti bot defenses. */\nexport function detecthoneypots(surveys: fieldsurvey[], loadedat: number): honeypotevidence[] {\n const traps: honeypotevidence[] = [];\n for (const field of surveys) {\n if (field.hidden) traps.push({ selector: field.selector, reason: \"hidden\" });\n else if (field.offscreen) traps.push({ selector: field.selector, reason: \"offscreen\" });\n else if (field.createdat !== undefined && loadedat > 0 && field.createdat > loadedat) traps.push({ selector: field.selector, reason: \"timetrap\" });\n }\n return traps;\n}\n\n/** Detects a login form: a password field plus an identifier field with session links nearby. */\nexport function detectlogin(fields: fieldshape[], links: string[]): { login: boolean; markers: string[] } {\n const markers: string[] = [];\n const password = fields.find(field => classifyfield(field) === \"password\");\n if (password) markers.push(\"password field\");\n const identifier = fields.find(field => {\n const kind = classifyfield(field);\n return kind === \"email\" || (kind === \"text\" && /user|login|account|identifier/i.test(`${field.name} ${field.label}`));\n });\n if (identifier) markers.push(\"identifier field\");\n const sessionlink = links.some(link => /sign in|log in|log on|forgot|create account|sign up/i.test(link));\n if (sessionlink) markers.push(\"session link\");\n return { login: Boolean(password && identifier && sessionlink), markers };\n}\n\nconst signupmarkers = [\"sign up\", \"create account\", \"register\", \"confirm password\", \"terms\"];\nconst checkoutmarkers = [\"checkout\", \"payment\", \"billing\", \"shipping\", \"card number\", \"place order\", \"cart\"];\n\n/** Detects signup and checkout templates by matching the field labels, autocompletes and page text against known markers. */\nexport function detecttemplate(fields: fieldshape[], text: string): { template: \"signup\" | \"checkout\" | \"unknown\"; markers: string[] } {\n const corpus = [text, ...fields.map(field => `${field.label} ${field.name} ${field.placeholder} ${field.arialabel} ${field.autocomplete}`)].join(\" \").toLowerCase();\n const signup = signupmarkers.filter(marker => corpus.includes(marker));\n const checkout = checkoutmarkers.filter(marker => corpus.includes(marker));\n if (signup.length >= 2 && signup.length >= checkout.length) return { template: \"signup\", markers: signup };\n if (checkout.length >= 2) return { template: \"checkout\", markers: checkout };\n return { template: \"unknown\", markers: [...signup, ...checkout] };\n}\n\n/** Associates validation messages with fields through aria describedby refs and the sibling text next to each field. */\nexport function associateerrors(contexts: errorcontext[], messages: Array<{ id?: string; text: string }>): fielderror[] {\n const errors: fielderror[] = [];\n for (const field of contexts) {\n const byref = field.describedby ? messages.find(message => message.id === field.describedby && message.text.trim()) : undefined;\n if (byref) { errors.push({ field: field.selector, message: byref.text.trim() }); continue; }\n const sibling = field.siblings.map(text => text.trim()).find(text => text.length > 0);\n if (sibling) errors.push({ field: field.selector, message: sibling });\n }\n return errors;\n}\n\n/** Resolves one reviewed artifact name against the run store before a file input is filled. */\nexport function attachplan(name: string, artifacts: Array<{ id: string; name: string; kind: string }>): { artifact?: { id: string; name: string; kind: string }; reason?: string } {\n const artifact = artifacts.find(item => item.name === name || item.id === name);\n if (!artifact) return { reason: \"The reviewed artifact name is not part of the run store.\" };\n return { artifact };\n}\n\n/** Selectors the captcha detector probes; a hit hands control back to the user instead of forcing the page. */\nexport const captchamarkers = ['iframe[src*=\"recaptcha\"]', 'iframe[title*=\"recaptcha\" i]', '.g-recaptcha', '[data-sitekey]', 'iframe[title*=\"captcha\" i]', '.h-captcha'];\n\n/** True when any captcha marker matched, so the plan pauses and hands control to the user. */\nexport function captchadetected(matched: string[]): boolean {\n return matched.length > 0;\n}\n\nfunction events(target: Element): void {\n target.dispatchEvent(new Event(\"input\", { bubbles: true }));\n target.dispatchEvent(new Event(\"change\", { bubbles: true }));\n}\n\n/** Fills one control through the native setter with input and change events; checks, radios and selects use their own grammar. */\nexport function fillcontrol(element: Element, entry: formentry): boolean {\n if (element instanceof HTMLInputElement && (entry.kind === \"check\" || element.type === \"checkbox\")) { element.checked = entry.value === \"true\" || entry.value === \"on\" || entry.value === \"checked\"; events(element); return true; }\n if (element instanceof HTMLInputElement && (entry.kind === \"radio\" || element.type === \"radio\")) { element.checked = true; events(element); return true; }\n if (element instanceof HTMLSelectElement) {\n const option = [...element.options].find(candidate => candidate.value === entry.value || candidate.textContent?.trim() === entry.value);\n if (!option) return false;\n element.value = option.value;\n events(element);\n return true;\n }\n if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {\n if (element instanceof HTMLInputElement && element.type === \"file\") return false;\n element.focus();\n const setter = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(element), \"value\")?.set;\n if (setter) setter.call(element, entry.value); else element.value = entry.value;\n events(element);\n return true;\n }\n return false;\n}\n\nfunction controlshape(element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement): fieldshape {\n return {\n selector: selector(element),\n tag: element.tagName.toLowerCase(),\n type: element instanceof HTMLSelectElement ? \"select\" : element.getAttribute(\"type\") || \"text\",\n name: element.getAttribute(\"name\") || \"\",\n label: label(element),\n placeholder: element.getAttribute(\"placeholder\") || \"\",\n arialabel: element.getAttribute(\"aria-label\") || \"\",\n autocomplete: element.getAttribute(\"autocomplete\") || \"\",\n ...(element instanceof HTMLSelectElement ? { options: [...element.options].map(option => option.value) } : {}),\n };\n}\n\n/** Collects the serializable field shapes of one form scope; absent scopes survey the whole document. */\nfunction collectfields(root: Document, formscope?: string): Array<{ shape: fieldshape; element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement }> {\n const scope = formscope ? root.querySelector(formscope) : root;\n if (!scope) return [];\n const controls = [...scope.querySelectorAll<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>(\"input, select, textarea\")];\n return controls.filter(element => element.type !== \"hidden\").map(element => ({ shape: controlshape(element), element }));\n}\n\n/** Surveys the visibility and geometry evidence the honeypot detector reads for one form scope. */\nfunction surveyfields(root: Document, formscope?: string): Array<{ survey: fieldsurvey; element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement }> {\n const viewport = { left: 0, top: 0, right: window.innerWidth || 0, bottom: window.innerHeight || 0 };\n return collectfields(root, formscope).map(({ shape, element }) => {\n const rect = element.getBoundingClientRect();\n const hidden = element.getAttribute(\"aria-hidden\") === \"true\" || element.tabIndex < 0 && (element as HTMLElement).offsetParent === null || (element as HTMLElement).offsetParent === null && rect.width === 0 && rect.height === 0;\n const offscreen = rect.width > 0 && rect.height > 0 && (rect.bottom < viewport.top || rect.top > viewport.bottom || rect.right < viewport.left || rect.left > viewport.right);\n return { survey: { ...shape, hidden, offscreen }, element };\n });\n}\n\n/** Reads the error context of one form scope: describedby refs and the sibling texts after each field. */\nfunction collecterrorcontext(root: Document, formscope?: string): Array<{ context: errorcontext; element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement }> {\n return collectfields(root, formscope).map(({ shape, element }) => {\n const siblings: string[] = [];\n let neighbor = element.nextElementSibling;\n for (let index = 0; neighbor && index < 3; index += 1) {\n const text = clean(neighbor.textContent || \"\");\n if (text && text !== shape.label) siblings.push(text);\n neighbor = neighbor.nextElementSibling;\n }\n const describedby = element.getAttribute(\"aria-describedby\");\n return { context: { ...shape, ...(describedby ? { describedby } : {}), siblings }, element };\n });\n}\n\n/** Runs one reviewed forms and data step inside the page: fills, surveys, detects and reads errors without leaving the form scope. */\nexport function runpageform(step: toolstep, target: Element | null, root: Document = document): stepresult | Promise<stepresult> {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n const formscope = typeof options.form === \"string\" && options.form ? options.form : step.target;\n switch (step.kind) {\n case \"fillform\": {\n const record = parseformrecord(options.formrecord);\n if (!record) return { ok: false, summary: \"A reviewed form record with entries is required in options.\" };\n const surveys = surveyfields(root, record.form);\n const honeypots = detecthoneypots(surveys.map(entry => entry.survey), 0);\n const operations = filloperations(record, surveys.map(entry => entry.survey), honeypots.map(trap => trap.selector));\n let filled = 0;\n const skipped: string[] = [];\n const failures: string[] = [];\n const values: Array<{ label: string; value: string }> = [];\n for (const operation of operations) {\n if (operation.skipped && operation.matched) { skipped.push(operation.matched.selector); continue; }\n if (!operation.matched) { failures.push(`${operation.reason}: ${operation.entry.match.label ?? operation.entry.match.name ?? operation.entry.match.placeholder ?? \"field\"}`); continue; }\n const element = surveys.find(entry => entry.survey.selector === operation.matched?.selector)?.element;\n if (!element || !fillcontrol(element, operation.entry)) { failures.push(`unfillable: ${operation.matched.selector}`); continue; }\n filled += 1;\n values.push({ label: operation.matched.label || operation.matched.name, value: operation.entry.kind === \"password\" ? \"\" : operation.entry.value });\n }\n const report: formreport = { form: record.form ?? \"\", fields: operations.map(operation => ({ selector: operation.matched?.selector ?? \"\", label: operation.matched?.label ?? operation.entry.match.label ?? \"\", kind: operation.entry.kind, matched: Boolean(operation.matched) })) };\n return {\n ok: failures.length === 0,\n summary: failures.length === 0 ? `Filled ${filled} reviewed field${filled === 1 ? \"\" : \"s\"} from the structured record${skipped.length > 0 ? ` and skipped ${skipped.length} honeypot field${skipped.length === 1 ? \"\" : \"s\"}` : \"\"}.` : `Filled ${filled} of ${record.entries.length} reviewed fields; ${failures.length} refusals: ${failures.join(\"; \")}.`,\n details: { filled, skipped, failures, values, report },\n };\n }\n case \"filllabel\":\n case \"fillplaceholder\": {\n const mode = step.kind === \"filllabel\" ? \"label\" : \"placeholder\";\n const pairs = Array.isArray(options.fields) ? (options.fields as Array<Record<string, unknown>>).filter(item => item && typeof item === \"object\") : [];\n const record = pairentries(pairs.map(pair => ({ label: typeof pair.label === \"string\" ? pair.label : \"\", placeholder: typeof pair.placeholder === \"string\" ? pair.placeholder : \"\", value: typeof pair.value === \"string\" ? pair.value : \"\" })), mode);\n if (record.entries.length === 0) return { ok: false, summary: \"A reviewed non-empty list of field pairs is required in options.\" };\n const surveys = surveyfields(root, formscope);\n const honeypots = detecthoneypots(surveys.map(entry => entry.survey), 0);\n const operations = filloperations(record, surveys.map(entry => entry.survey), honeypots.map(trap => trap.selector));\n let filled = 0;\n const failures: string[] = [];\n for (const operation of operations) {\n if (operation.skipped) continue;\n if (!operation.matched) { failures.push(`${operation.reason}: ${mode === \"label\" ? operation.entry.match.label : operation.entry.match.placeholder}`); continue; }\n const element = surveys.find(entry => entry.survey.selector === operation.matched?.selector)?.element;\n const refined: formentry = { ...operation.entry, kind: classifyfield(operation.matched) };\n if (!element || !fillcontrol(element, refined)) { failures.push(`unfillable: ${operation.matched.selector}`); continue; }\n filled += 1;\n }\n return { ok: failures.length === 0, summary: failures.length === 0 ? `Filled ${filled} field${filled === 1 ? \"\" : \"s\"} matched by ${mode}.` : `Filled ${filled} of ${record.entries.length} fields matched by ${mode}; ${failures.join(\"; \")}.`, details: { filled, failures, mode } };\n }\n case \"detectfields\": {\n const collected = collectfields(root, formscope);\n const report: formreport = { form: formscope ?? \"\", fields: collected.map(entry => ({ selector: entry.shape.selector, label: entry.shape.label || entry.shape.name, kind: classifyfield(entry.shape), matched: Boolean(entry.shape.label || entry.shape.name) })) };\n return { ok: true, summary: `Detected ${collected.length} form field${collected.length === 1 ? \"\" : \"s\"} with their kinds.`, details: { report, count: collected.length } };\n }\n case \"generatevalues\": {\n const rule = options.valuegen && typeof options.valuegen === \"object\" && !Array.isArray(options.valuegen) ? options.valuegen as Record<string, unknown> : {};\n const locale = typeof rule.locale === \"string\" ? rule.locale : \"en\";\n const seed = typeof rule.seed === \"number\" && Number.isFinite(rule.seed) ? rule.seed : 1;\n const surveys = surveyfields(root, formscope);\n const honeypots = detecthoneypots(surveys.map(entry => entry.survey), 0);\n const skippedselectors = new Set(honeypots.map(trap => trap.selector));\n const candidates = surveys.filter(entry => !skippedselectors.has(entry.survey.selector));\n const values = candidates.map(entry => ({ label: entry.survey.label || entry.survey.name || entry.survey.selector, kind: classifyfield(entry.survey), value: generatevalue(classifyfield(entry.survey), { locale, seed }) }));\n const single = values.length === 0 && typeof rule.kind === \"string\" ? [{ label: rule.kind, kind: rule.kind, value: generatevalue(rule.kind as fieldkind, { locale, seed }) }] : values;\n return { ok: true, summary: `Generated ${single.length} realistic value${single.length === 1 ? \"\" : \"s\"} for the detected field kinds.`, details: { values: single, locale, seed } };\n }\n case \"readerrors\": {\n const contexts = collecterrorcontext(root, formscope);\n const messages = [...root.querySelectorAll<HTMLElement>(\"[id]\")].map(element => ({ id: element.id, text: clean(element.textContent || \"\") })).filter(message => message.text.length > 0);\n const errors = associateerrors(contexts.map(entry => entry.context), messages);\n return { ok: true, summary: errors.length === 0 ? \"No validation error was found next to the reviewed fields.\" : `Collected ${errors.length} inline validation message${errors.length === 1 ? \"\" : \"s\"}.`, details: { errors, form: formscope ?? \"\" } };\n }\n case \"skiphoneypot\": {\n const surveys = surveyfields(root, formscope);\n const traps = detecthoneypots(surveys.map(entry => entry.survey), 0);\n return { ok: true, summary: traps.length === 0 ? \"No honeypot field was detected.\" : `Skipped ${traps.length} honeypot field${traps.length === 1 ? \"\" : \"s\"}: ${traps.map(trap => `${trap.selector} (${trap.reason})`).join(\", \")}.`, details: { skipped: traps } };\n }\n case \"detectlogin\": {\n const collected = collectfields(root, formscope);\n const links = [...(formscope ? root.querySelectorAll(formscope) : [root] as unknown as Element[])].flatMap(scope => [...scope.querySelectorAll(\"a[href], button\")]).map(element => clean(element.textContent || \"\"));\n const detection = detectlogin(collected.map(entry => entry.shape), links);\n return { ok: true, summary: detection.login ? `Login form detected with ${detection.markers.join(\", \")}.` : \"No login form was detected.\", details: { login: detection.login, markers: detection.markers } };\n }\n case \"detecttemplate\": {\n const collected = collectfields(root, formscope);\n const text = clean(root.body?.innerText || \"\");\n const detection = detecttemplate(collected.map(entry => entry.shape), text);\n return { ok: true, summary: detection.template === \"unknown\" ? \"No signup or checkout template was detected.\" : `${detection.template} template detected with markers ${detection.markers.join(\", \")}.`, details: { template: detection.template, markers: detection.markers } };\n }\n case \"handoffcaptcha\": {\n const matched = captchamarkers.filter(marker => root.querySelector(marker) !== null);\n return { ok: true, summary: captchadetected(matched) ? `Captcha presence detected (${matched.join(\", \")}); control hands back to the user.` : \"No captcha was detected.\", details: { captcha: captchadetected(matched), markers: matched } };\n }\n case \"asksubmit\": {\n const collected = collectfields(root, step.value || undefined);\n const values = collected.map(entry => ({ label: entry.shape.label || entry.shape.name || entry.shape.selector, value: entry.element instanceof HTMLSelectElement ? entry.element.value : (entry.element as HTMLInputElement).value }));\n return { ok: true, summary: `Read ${values.length} field value${values.length === 1 ? \"\" : \"s\"} for the submission review.`, details: { values } };\n }\n case \"submitform\": {\n const form = target instanceof HTMLFormElement ? target : target instanceof HTMLElement ? target.closest(\"form\") : null;\n if (!form) return { ok: false, summary: \"No owning form was found for the reviewed submission.\" };\n form.requestSubmit();\n return { ok: true, summary: \"Form submitted programmatically through its owning form.\" };\n }\n case \"consentpassword\": {\n if (!(target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement)) return { ok: false, summary: \"The reviewed password target cannot receive text.\" };\n const entry: formentry = { match: { mode: \"name\", name: target.name || target.getAttribute(\"id\") || \"\" }, kind: \"password\", value: step.value ?? \"\" };\n if (!fillcontrol(target, entry)) return { ok: false, summary: \"The password field refused the native setter fill.\" };\n return { ok: true, summary: \"Password field filled after the reviewed consent; the value never appears in the audit trail.\" };\n }\n case \"attachfile\": {\n if (!(target instanceof HTMLInputElement) || target.type !== \"file\") return { ok: false, summary: \"The reviewed target is not a file input.\" };\n const artifactname = typeof options.artifactname === \"string\" && options.artifactname ? options.artifactname : \"artifact\";\n try {\n const file = new File([new Blob([\"devthink artifact\"], { type: \"application/octet-stream\" })], artifactname);\n const transfer = new DataTransfer();\n transfer.items.add(file);\n target.files = transfer.files;\n events(target);\n return { ok: true, summary: `Artifact ${artifactname} attached to the reviewed file input.`, details: { artifact: options.artifact, artifactname } };\n } catch {\n return { ok: false, summary: \"The reviewed file input refused the artifact attachment.\" };\n }\n }\n default: return { ok: false, summary: \"Unsupported forms and data action.\" };\n }\n}\n", "import type { toolstep, wizardstate } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\nimport type { stepresult } from \"./pageactions.js\";\nimport { cardmask } from \"./pageforms.js\";\nimport { clean } from \"./pageresolve.js\";\n\n/**\n * Wizard, dependent control and payment field logics for reviewed steps.\n * Every correlated rule for wizard tracking, dependent option waits, typeahead picks, calendar navigation, card segment typing, one time code sources and submission retry backoff lives in this file.\n */\n\n/** Advances one wizard step, recording the completion signal of the executed step and the new step index. */\nexport function wizardadvance(state: wizardstate, completed: boolean, at: number): wizardstate {\n const flags = [...state.completed];\n while (flags.length < state.index + 1) flags.push(false);\n flags[state.index] = completed;\n return { ...state, index: Math.min(state.index + 1, state.steps), completed: flags, at };\n}\n\n/** True when the dependent child options finished loading after a parent selection changed their count. */\nexport function dependentloaded(previouscount: number, currentcount: number): boolean {\n return currentcount !== previouscount;\n}\n\n/** Picks the reviewed suggestion entry from a typeahead list, case insensitive; undefined when the entry is absent. */\nexport function typeaheadpick(suggestions: string[], pick: string): string | undefined {\n const needle = pick.trim().toLowerCase();\n return suggestions.find(suggestion => suggestion.trim().toLowerCase() === needle);\n}\n\n/** Parses one reviewed yyyy-mm-dd date into its year, month and day parts; null when the form is invalid. */\nexport function parsedateparts(value: string): { year: number; month: number; day: number } | null {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(value)) return null;\n const parts = value.split(\"-\").map(part => Number.parseInt(part, 10));\n const year = parts[0] ?? 0;\n const month = parts[1] ?? 0;\n const day = parts[2] ?? 0;\n if (month < 1 || month > 12 || day < 1 || day > 31) return null;\n return { year, month, day };\n}\n\n/** Plans the calendar navigation to the reviewed date: the month delta and the day cell to click. */\nexport function calendarplan(view: { year: number; month: number }, date: { year: number; month: number; day: number }): { months: number; day: number } {\n return { months: (date.year - view.year) * 12 + (date.month - view.month), day: date.day };\n}\n\n/** Splits one card number into its typed groups so the filler pauses between groups. */\nexport function cardgroups(number: string): string[] {\n const groups = number.replace(/[-\\s]+/g, \" \").trim().split(\" \");\n return groups.filter(group => group.length > 0);\n}\n\n/** True when the reviewed one time code source is ready to deliver the code before typing. */\nexport function codeready(source: string, value: string | undefined): boolean {\n if (source === \"reviewed\") return typeof value === \"string\" && value.trim().length > 0;\n return false;\n}\n\n/** One reviewed retry backoff rule with an attempt count, a wait window and a growth factor, all user configured. */\nexport interface backoffrule {\n attempts: number;\n wait: number;\n factor: number;\n}\n\n/** Parses the reviewed backoff rule of a retryform step; null when the step reviews none. */\nexport function parsebackoff(step: toolstep): backoffrule | null {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n const backoff = options.backoff;\n if (!backoff || typeof backoff !== \"object\" || Array.isArray(backoff)) return null;\n const rule = backoff as Record<string, unknown>;\n const wait = rule.wait;\n const factor = rule.factor;\n if (typeof wait !== \"number\" || !Number.isFinite(wait) || wait <= 0) return null;\n if (typeof factor !== \"number\" || !Number.isFinite(factor) || factor < 1) return null;\n const attempts = typeof options.attempts === \"number\" && Number.isInteger(options.attempts) && options.attempts >= 1 ? options.attempts : 2;\n return { attempts, wait, factor };\n}\n\n/** Computes the reviewed backoff windows between submission retries; no code ceiling applies. */\nexport function backoffwaits(attempts: number, wait: number, factor: number): number[] {\n const windows: number[] = [];\n let current = wait;\n for (let index = 1; index < attempts; index += 1) {\n windows.push(current);\n current *= factor;\n }\n return windows;\n}\n\nfunction wait(delay: number): Promise<void> {\n return new Promise(resolve => window.setTimeout(resolve, delay));\n}\n\nfunction pollfor(predicate: () => boolean, description: string, timeout: number): Promise<stepresult> {\n return new Promise(resolve => {\n const started = Date.now();\n const check = (): void => {\n if (predicate()) { resolve({ ok: true, summary: `${description} is now present on the page.` }); return; }\n if (timeout > 0 && Date.now() - started >= timeout) { resolve({ ok: false, summary: `${description} did not appear within ${timeout} milliseconds.` }); return; }\n window.setTimeout(check, 100);\n };\n check();\n });\n}\n\n/** Runs one reviewed wizard or payment field step inside the page, from multi step wizards to card segments and one time codes. */\nexport function runpagewizard(step: toolstep, target: Element | null, root: Document = document): stepresult | Promise<stepresult> {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n switch (step.kind) {\n case \"runwizard\": {\n const scope = target instanceof HTMLElement ? target : root.body ?? root.documentElement;\n const steps = typeof options.steps === \"number\" && Number.isInteger(options.steps) && options.steps > 0 ? options.steps : 1;\n const state: wizardstate = { index: 0, steps, completed: [], at: Date.now() };\n const next = scope.querySelector<HTMLElement>(\"button[type=submit], button[name=next], [data-next]\");\n if (!next) return { ok: false, summary: \"No next step control was found inside the wizard scope.\", details: { wizard: state } };\n next.click();\n const advanced = wizardadvance(state, true, Date.now());\n return { ok: advanced.index >= steps, summary: `Wizard advanced to step ${advanced.index + 1} of ${steps}${advanced.index >= steps ? \" and completed\" : \"\"}.`, details: { wizard: advanced } };\n }\n case \"selectchain\": {\n if (!(target instanceof HTMLSelectElement)) return { ok: false, summary: \"The reviewed parent target is not a select element.\" };\n const childselector = typeof options.child === \"string\" ? options.child : \"\";\n const child = root.querySelector<HTMLSelectElement>(childselector);\n if (!child) return { ok: false, summary: \"The reviewed dependent child control was not found.\" };\n const previouscount = child.options.length;\n const option = [...target.options].find(candidate => candidate.value === step.value || candidate.textContent?.trim() === step.value);\n if (!option) return { ok: false, summary: \"The reviewed parent option is not part of the select element.\" };\n target.value = option.value;\n target.dispatchEvent(new Event(\"input\", { bubbles: true }));\n target.dispatchEvent(new Event(\"change\", { bubbles: true }));\n const waitwindow = typeof options.wait === \"number\" && options.wait > 0 ? options.wait : 0;\n return pollfor(() => dependentloaded(previouscount, child.options.length), \"Dependent options of the child control\", waitwindow);\n }\n case \"picktypeahead\": {\n const field = target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement ? target : null;\n if (!field) return { ok: false, summary: \"The reviewed typeahead target cannot receive text.\" };\n const pick = typeof options.pick === \"string\" ? options.pick : \"\";\n const timeout = typeof options.timeout === \"number\" && options.timeout > 0 ? options.timeout : 0;\n field.focus();\n field.value = step.value ?? \"\";\n field.dispatchEvent(new Event(\"input\", { bubbles: true }));\n const list = root.querySelector<HTMLElement>('[role=listbox], .suggestions, ul.autocomplete, [data-typeahead]');\n const suggestions = list ? [...list.querySelectorAll<HTMLElement>(\"[role=option], li, .suggestion\")].map(entry => clean(entry.textContent || \"\")) : [];\n const chosen = typeaheadpick(suggestions, pick);\n if (chosen === undefined) return { ok: false, summary: `The reviewed suggestion \"${pick}\" is not part of the typeahead list.`, details: { suggestions } };\n const entry = [...(list?.querySelectorAll<HTMLElement>(\"[role=option], li, .suggestion\") ?? [])].find(item => clean(item.textContent || \"\").trim().toLowerCase() === chosen.trim().toLowerCase());\n entry?.click();\n field.dispatchEvent(new Event(\"change\", { bubbles: true }));\n return { ok: Boolean(entry), summary: `Picked the reviewed typeahead entry \"${chosen}\".`, details: { pick: chosen, query: step.value ?? \"\" } };\n }\n case \"pickdate\": {\n const calendar = target instanceof HTMLElement ? target : root.body ?? root.documentElement;\n const date = parsedateparts(step.value ?? \"\");\n if (!date) return { ok: false, summary: \"The reviewed date must use the yyyy-mm-dd form.\" };\n const header = clean(calendar.querySelector<HTMLElement>(\"[data-calendar-title], .calendar-title, header\")?.textContent || \"\");\n const match = /(\\d{4})/.exec(header);\n const monthnames = [\"january\", \"february\", \"march\", \"april\", \"may\", \"june\", \"july\", \"august\", \"september\", \"october\", \"november\", \"december\"];\n const viewyear = match ? Number.parseInt(match[1] ?? \"0\", 10) : new Date().getFullYear();\n const viewmonth = monthnames.findIndex(name => header.toLowerCase().includes(name)) >= 0 ? monthnames.findIndex(name => header.toLowerCase().includes(name)) : new Date().getMonth() + 1;\n const plan = calendarplan({ year: viewyear, month: viewmonth }, date);\n const forward = plan.months >= 0;\n for (let index = 0; index < Math.abs(plan.months); index += 1) {\n calendar.querySelector<HTMLElement>(forward ? \"[data-next-month], .next-month, [aria-label=next]\" : \"[data-prev-month], .prev-month, [aria-label=previous]\")?.click();\n }\n const day = [...calendar.querySelectorAll<HTMLElement>(\"[role=gridcell], [data-day], td\")].find(cell => Number.parseInt(clean(cell.textContent || \"\"), 10) === plan.day);\n if (!day) return { ok: false, summary: `The reviewed day cell ${plan.day} was not found in the calendar widget.` };\n day.click();\n return { ok: true, summary: `Picked ${step.value} from the calendar widget after ${Math.abs(plan.months)} month navigation${Math.abs(plan.months) === 1 ? \"\" : \"s\"}.`, details: { months: plan.months, day: plan.day } };\n }\n case \"fillcard\": {\n const segments = Array.isArray(options.segments) ? (options.segments as Array<Record<string, unknown>>).filter(item => item && typeof item === \"object\") : [];\n if (segments.length === 0) return { ok: false, summary: \"A reviewed non-empty list of card segments is required in options.\" };\n const pause = typeof options.pause === \"number\" && options.pause > 0 ? options.pause : 0;\n const filled: Array<{ label: string; masked: string }> = [];\n const failures: string[] = [];\n const fillsegment = async (segment: Record<string, unknown>): Promise<void> => {\n const match = segment.match as Record<string, unknown> | undefined;\n const value = typeof segment.value === \"string\" ? segment.value : \"\";\n if (!match || typeof match !== \"object\") { failures.push(\"segment without a reviewed match\"); return; }\n const scope = root.body ?? root.documentElement;\n const candidates = [...scope.querySelectorAll<HTMLInputElement>(\"input, select\")];\n const key = match.mode === \"label\" ? \"label\" : match.mode === \"placeholder\" ? \"placeholder\" : match.mode === \"arialabel\" ? \"arialabel\" : \"name\";\n const needle = String(match[key] ?? \"\").toLowerCase();\n const element = candidates.find(input => (key === \"label\" ? input.name.toLowerCase() || input.getAttribute(\"aria-label\")?.toLowerCase() || \"\" : (input.getAttribute(key) ?? input.name).toLowerCase()).includes(needle) || (input.getAttribute(\"aria-label\") ?? \"\").toLowerCase().includes(needle));\n if (!element) { failures.push(`unmatched: ${needle}`); return; }\n element.focus();\n for (const group of cardgroups(value)) {\n element.value = group;\n element.dispatchEvent(new Event(\"input\", { bubbles: true }));\n if (pause > 0) await wait(pause);\n }\n element.dispatchEvent(new Event(\"change\", { bubbles: true }));\n filled.push({ label: String(match[key] ?? \"\"), masked: cardmask(value) });\n };\n return (async (): Promise<stepresult> => {\n for (const segment of segments) await fillsegment(segment);\n return {\n ok: failures.length === 0,\n summary: failures.length === 0 ? `Filled ${filled.length} card segment${filled.length === 1 ? \"\" : \"s\"} with pauses between card number groups.` : `Filled ${filled.length} of ${segments.length} card segments; ${failures.join(\"; \")}.`,\n details: { segments: filled, failures, pause },\n };\n })();\n }\n case \"fillcode\": {\n const field = target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement ? target : null;\n if (!field) return { ok: false, summary: \"The reviewed one time code target cannot receive text.\" };\n const source = typeof options.source === \"string\" ? options.source : \"\";\n const timeout = typeof options.timeout === \"number\" && options.timeout > 0 ? options.timeout : 0;\n const code = step.value ?? \"\";\n return pollfor(() => codeready(source, code), \"The reviewed one time code source\", timeout).then(result => {\n if (!codeready(source, code)) return { ok: false, summary: `The reviewed code source ${source} is not ready to deliver the code yet.` };\n field.focus();\n field.value = code;\n field.dispatchEvent(new Event(\"input\", { bubbles: true }));\n field.dispatchEvent(new Event(\"change\", { bubbles: true }));\n return { ok: true, summary: `One time code typed from the reviewed source ${source}.`, details: { source } };\n });\n }\n default: return { ok: false, summary: \"Unsupported wizard action.\" };\n }\n}\n", "import type { columnspec, datasetrow, sourceref, toolstep, transformrule } from \"../types.js\";\nimport { parseoptions } from \"../policy.js\";\nimport type { stepresult } from \"./pageactions.js\";\nimport { clean, elementselector as selector } from \"./pageresolve.js\";\n\n/**\n * Table and dataset logics for reviewed steps.\n * Every correlated rule for header normalization, span expansion, nested table walking, pagination following, row hashing, transform expressions, dataset merging, row sampling and csv, json and excel serialization lives in this file.\n */\n\n/** One raw table cell with its text, header flag, span geometry and an optional nested table. */\nexport interface cellshape {\n text: string;\n header: boolean;\n rowspan: number;\n colspan: number;\n nested?: { selector: string; rows: rowshape[] };\n}\n\n/** One raw table row of span carrying cells. */\nexport interface rowshape {\n cells: cellshape[];\n header: boolean;\n}\n\n/** One nested child table linked to the body row it belongs to. */\nexport interface childtable {\n parentrow: number;\n selector: string;\n columns: columnspec[];\n rows: datasetrow[];\n}\n\n/** Result of the table reader: normalized column specs, keyed body rows and child datasets. */\nexport interface gridresult {\n columns: columnspec[];\n rows: datasetrow[];\n children: childtable[];\n}\n\n/** Trims, lowercases and slugifies one header cell into a stable column key. */\nexport function normalizeheader(label: string): string {\n const slug = label.trim().toLowerCase().replace(/[^\\p{L}\\p{N}]+/gu, \"-\").replace(/^-+|-+$/g, \"\");\n return slug || \"column\";\n}\n\n/** Builds one column spec from a header label with a unique stable key and the normalized name. */\nexport function columnspecof(label: string, used: Set<string> = new Set()): columnspec {\n const base = normalizeheader(label);\n let key = base;\n let suffix = 2;\n while (used.has(key)) {\n key = `${base}${suffix}`;\n suffix += 1;\n }\n used.add(key);\n return { key, label: label.trim(), kind: \"text\", normalized: label.trim().toLowerCase() };\n}\n\n/** Classifies a column as number only when every non-empty value parses as a number. */\nexport function classifycolumn(values: string[]): \"text\" | \"number\" {\n const present = values.filter(value => value.trim().length > 0);\n if (present.length === 0) return \"text\";\n return present.every(value => Number.isFinite(Number(value.replace(/,/g, \".\")))) ? \"number\" : \"text\";\n}\n\n/** Expands rowspan and colspan cells into a filled rectangular grid of values. */\nexport function expandspans(rows: rowshape[]): string[][] {\n const filled: Array<Array<string | undefined>> = [];\n const pending = new Map<string, string>();\n for (let index = 0; index < rows.length; index += 1) {\n const row: Array<string | undefined> = filled[index] ?? (filled[index] = []);\n let column = 0;\n for (const cell of rows[index]!.cells) {\n while (row[column] !== undefined || pending.has(`${index},${column}`)) {\n if (row[column] === undefined) row[column] = pending.get(`${index},${column}`);\n column += 1;\n }\n row[column] = cell.text;\n for (let spanrow = 0; spanrow < Math.max(1, cell.rowspan); spanrow += 1) {\n for (let spancol = 0; spancol < Math.max(1, cell.colspan); spancol += 1) {\n if (spanrow === 0 && spancol === 0) continue;\n pending.set(`${index + spanrow},${column + spancol}`, cell.text);\n }\n }\n column += Math.max(1, cell.colspan);\n }\n }\n for (const [key, value] of pending) {\n const [rowpart, columnpart] = key.split(\",\");\n const rowindex = Number.parseInt(rowpart ?? \"0\", 10);\n const columnindex = Number.parseInt(columnpart ?? \"0\", 10);\n const target = filled[rowindex] ?? (filled[rowindex] = []);\n if (target[columnindex] === undefined) target[columnindex] = value;\n }\n const width = filled.reduce((largest, row) => Math.max(largest, row.length), 0);\n return filled.map(row => Array.from({ length: width }, (_, column) => row[column] ?? \"\"));\n}\n\n/** Reads header and body rows into normalized column specs and keyed body rows, extracting nested tables into child datasets. */\nexport function readgrid(rows: rowshape[]): gridresult {\n const headerindex = rows.findIndex(row => row.header || (row.cells[0]?.header ?? false));\n const useheader = headerindex !== -1 ? headerindex : 0;\n const hasheader = headerindex !== -1 || rows.length > 0;\n const grid = expandspans(rows);\n const headercells = hasheader ? (grid[useheader] ?? []) : [];\n const used = new Set<string>();\n const columns = Array.from({ length: headercells.length || (grid[0]?.length ?? 0) }, (_, index) => columnspecof(headercells[index] ?? `column${index + 1}`, used));\n const bodyrows = grid.filter((_, index) => hasheader ? index !== useheader : true)\n .filter(line => line.some(value => value.trim().length > 0))\n .map(line => {\n const row: datasetrow = {};\n columns.forEach((column, index) => { row[column.key] = line[index] ?? \"\"; });\n return row;\n });\n for (const column of columns) column.kind = classifycolumn(bodyrows.map(row => row[column.key] ?? \"\"));\n const children: childtable[] = [];\n rows.forEach((row, rowindex) => {\n if (hasheader && rowindex === useheader) return;\n const parentrow = hasheader && rowindex > useheader ? rowindex - 1 : rowindex;\n row.cells.forEach(cell => {\n if (!cell.nested) return;\n const child = readgrid(cell.nested.rows);\n children.push({ parentrow, selector: cell.nested!.selector, columns: child.columns, rows: child.rows });\n });\n });\n return { columns, rows: bodyrows, children };\n}\n\n/** Resolves the next pagination control from numbered page entries: the entry after the current one or a next word control. */\nexport function nextcontrol(entries: Array<{ text: string; selector: string; current: boolean }>): string | undefined {\n const current = entries.findIndex(entry => entry.current);\n if (current !== -1 && current + 1 < entries.length) return entries[current + 1]?.selector;\n const nextwords = [\"next\", \"next page\", \">\", \">>\", \"\u203A\", \"\u00BB\", \"pr\u00F3xima\", \"seguinte\"];\n return entries.find(entry => nextwords.includes(entry.text.trim().toLowerCase()))?.selector;\n}\n\n/** True when the current row set contains at least one row the previous set did not carry. */\nexport function rowsfresh(previous: datasetrow[], current: datasetrow[]): boolean {\n if (current.length === 0) return false;\n const known = new Set(previous.map(row => JSON.stringify(row)));\n return current.some(row => !known.has(JSON.stringify(row)));\n}\n\n/** Computes a stable row hash over the reviewed keys; an empty key list hashes every column. */\nexport function rowhash(row: datasetrow, keys: string[]): string {\n const source = (keys.length > 0 ? keys : Object.keys(row).sort()).map(key => `${key}=${row[key] ?? \"\"}`).join(\"|\");\n let hash = 5381;\n for (let index = 0; index < source.length; index += 1) hash = ((hash * 33) ^ source.charCodeAt(index)) >>> 0;\n return hash.toString(16);\n}\n\n/** Deduplicates rows by reviewed keys, keeping the first occurrence of every key set. */\nexport function dedupebykeys(rows: datasetrow[], keys: string[]): { kept: datasetrow[]; removed: number } {\n const seen = new Set<string>();\n const kept: datasetrow[] = [];\n for (const row of rows) {\n const hash = rowhash(row, keys);\n if (seen.has(hash)) continue;\n seen.add(hash);\n kept.push(row);\n }\n return { kept, removed: rows.length - kept.length };\n}\n\n/** Applies one reviewed transform expression to a value; unsupported expressions are refused. */\nexport function applyexpression(value: string, expression: string): string {\n const split = expression.indexOf(\":\");\n const op = split === -1 ? expression : expression.slice(0, split);\n const argument = split === -1 ? undefined : expression.slice(split + 1);\n if (op === \"trim\") return value.trim();\n if (op === \"upper\") return value.toUpperCase();\n if (op === \"lower\") return value.toLowerCase();\n if (op === \"number\") return value.replace(/[^\\d.\\-]/g, \"\");\n if (op === \"prefix\") return `${argument ?? \"\"}${value}`;\n if (op === \"suffix\") return `${value}${argument ?? \"\"}`;\n if (op === \"replace\") {\n const separator = argument?.indexOf(\"=>\") ?? -1;\n if (separator === -1 || separator === 0) throw new Error(`The reviewed transform expression ${expression} needs the from=>to separator.`);\n const from = argument!.slice(0, separator);\n const to = argument!.slice(separator + 2);\n return value.split(from).join(to);\n }\n throw new Error(`The reviewed transform expression ${op} is not supported.`);\n}\n\n/** Applies reviewed transform rules to dataset rows, surfacing per rule errors and keeping the original values on failure. */\nexport function transformrows(rows: datasetrow[], rules: transformrule[]): { rows: datasetrow[]; errors: string[] } {\n const errors: string[] = [];\n const output = rows.map(row => ({ ...row }));\n for (const rule of rules) {\n const updated: datasetrow[] = [];\n try {\n for (const row of output) updated.push({ ...row, [rule.target]: applyexpression(rule.sources.map(source => row[source] ?? \"\").join(\" \"), rule.expression) });\n } catch (error) {\n errors.push(`${rule.target}: ${error instanceof Error ? error.message : String(error)}`);\n continue;\n }\n output.splice(0, output.length, ...updated);\n }\n return { rows: output, errors };\n}\n\n/** Merges datasets across pages: columns align by key with gaps filled empty and rows concatenate in page order. */\nexport function mergedatasets(datasets: Array<{ columns: columnspec[]; rows: datasetrow[] }>): { columns: columnspec[]; rows: datasetrow[] } {\n const columns: columnspec[] = [];\n const seen = new Set<string>();\n for (const dataset of datasets) {\n for (const column of dataset.columns) {\n if (seen.has(column.key)) continue;\n seen.add(column.key);\n columns.push(column);\n }\n }\n const rows = datasets.flatMap(dataset => dataset.rows.map(row => {\n const merged: datasetrow = {};\n for (const column of columns) merged[column.key] = row[column.key] ?? \"\";\n return merged;\n }));\n return { columns, rows };\n}\n\n/** Attaches the source url, timestamp and step ref to every row and returns the matching source refs. */\nexport function samplerows(rows: datasetrow[], url: string, stepid: string, at: number): { rows: datasetrow[]; sources: sourceref[] } {\n const stamped = rows.map(row => ({ ...row, source: url, capturedat: String(at), step: stepid }));\n const sources = stamped.map((row, index) => ({ row: index, url, at, stepid }));\n return { rows: stamped, sources };\n}\n\n/** Escapes one csv field, wrapping values that carry the delimiter, quotes or line breaks. */\nfunction csvfield(value: string, delimiter: string): string {\n return value.includes(delimiter) || value.includes(\"\\\"\") || value.includes(\"\\n\") ? `\"${value.replace(/\"/g, \"\\\"\\\"\")}\"` : value;\n}\n\n/** Serializes columns and rows into csv text. */\nexport function tocsv(columns: columnspec[], rows: datasetrow[], delimiter = \",\"): string {\n const lines = [columns.map(column => csvfield(column.label || column.key, delimiter)).join(delimiter)];\n for (const row of rows) lines.push(columns.map(column => csvfield(row[column.key] ?? \"\", delimiter)).join(delimiter));\n return lines.join(\"\\n\");\n}\n\n/** Parses csv text into headers and raw rows, honoring quoted fields and escaped quotes. */\nexport function parsecsv(text: string, delimiter = \",\"): { headers: string[]; rows: string[][] } {\n const records: string[][] = [];\n let field = \"\";\n let record: string[] = [];\n let quoted = false;\n for (let index = 0; index < text.length; index += 1) {\n const character = text[index]!;\n if (quoted) {\n if (character === \"\\\"\") {\n if (text[index + 1] === \"\\\"\") { field += \"\\\"\"; index += 1; }\n else quoted = false;\n } else field += character;\n continue;\n }\n if (character === \"\\\"\") { quoted = true; continue; }\n if (character === delimiter) { record.push(field); field = \"\"; continue; }\n if (character === \"\\n\" || character === \"\\r\") {\n if (character === \"\\r\" && text[index + 1] === \"\\n\") index += 1;\n record.push(field);\n field = \"\";\n if (record.some(value => value.length > 0) || record.length > 1) records.push(record);\n record = [];\n continue;\n }\n field += character;\n }\n record.push(field);\n if (record.some(value => value.length > 0) || record.length > 1) records.push(record);\n const [headers = [], ...rows] = records;\n return { headers, rows };\n}\n\n/** Maps parsed csv headers onto dataset column specs through a reviewed mapping of csv names to target keys. */\nexport function mapcolumns(headers: string[], mapping: Record<string, string> = {}): columnspec[] {\n const used = new Set<string>();\n return headers.map(header => {\n const target = mapping[header] ?? mapping[normalizeheader(header)] ?? header;\n return columnspecof(target, used);\n });\n}\n\n/** Serializes columns and rows into a json dataset payload. */\nexport function tojson(columns: columnspec[], rows: datasetrow[]): string {\n return JSON.stringify({ columns, rows });\n}\n\n/** Escapes one xml text node. */\nfunction xmltext(value: string): string {\n return value.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\").replace(/\"/g, \"&quot;\");\n}\n\n/** Serializes columns and rows into an Excel SpreadsheetML 2003 workbook that Excel opens natively. */\nexport function toexcel(columns: columnspec[], rows: datasetrow[], name: string): string {\n const head = columns.map(column => `<Cell ss:StyleID=\"head\"><Data ss:Type=\"String\">${xmltext(column.label || column.key)}</Data></Cell>`).join(\"\");\n const body = rows.map(row => `<Row>${columns.map(column => {\n const value = row[column.key] ?? \"\";\n const numeric = column.kind === \"number\" && value.trim() !== \"\" && Number.isFinite(Number(value));\n return numeric ? `<Cell><Data ss:Type=\"Number\">${xmltext(value)}</Data></Cell>` : `<Cell><Data ss:Type=\"String\">${xmltext(value)}</Data></Cell>`;\n }).join(\"\")}</Row>`).join(\"\");\n return `<?xml version=\"1.0\"?><?mso-application progid=\"Excel.Sheet\"?><Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\" xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\"><Styles><Style ss:ID=\"head\"><Font ss:Bold=\"1\"/></Style></Styles><Worksheet ss:Name=\"${xmltext(name || \"dataset\").slice(0, 31)}\"><Table><Row>${head}</Row>${body}</Table></Worksheet></Workbook>`;\n}\n\n/** Collects the raw span carrying row shapes of one html table, separating nested tables into cell refs. */\nfunction collectrowshapes(table: HTMLTableElement): rowshape[] {\n return [...table.rows].map(row => ({\n header: [...row.cells].every(cell => cell.tagName === \"TH\") && row.cells.length > 0,\n cells: [...row.cells].map(cell => {\n const nested = cell.querySelector(\"table\");\n return {\n text: clean(nested ? `${nested.rows.length} rows` : cell.textContent ?? \"\"),\n header: cell.tagName === \"TH\",\n rowspan: cell.rowSpan,\n colspan: cell.colSpan,\n ...(nested instanceof HTMLTableElement ? { nested: { selector: selector(nested), rows: collectrowshapes(nested) } } : {}),\n };\n }),\n }));\n}\n\n/** Reads the reviewed table element into a grid result. */\nfunction readtable(target: Element | null, root: Document, fallbackselector: string | undefined): gridresult | null {\n const table = target instanceof HTMLTableElement ? target : (fallbackselector ? root.querySelector<HTMLTableElement>(fallbackselector) : root.querySelector<HTMLTableElement>(\"table\"));\n if (!table) return null;\n return readgrid(collectrowshapes(table));\n}\n\n/** Reads the live pagination entries of a table container for the next control resolution. */\nfunction paginationentries(root: Document, scope: string | undefined): Array<{ text: string; selector: string; current: boolean }> {\n const container = scope ? root.querySelector(scope) : root;\n if (!container) return [];\n return [...container.querySelectorAll(\"a[href], button\")].map(element => ({\n text: clean(element.textContent ?? \"\"),\n selector: selector(element),\n current: element.getAttribute(\"aria-current\") === \"page\" || element.classList.contains(\"active\") || element.classList.contains(\"current\"),\n }));\n}\n\n/** Runs one reviewed data step on the page: table scraping into datasets and pagination following with fresh row waits. */\nexport async function runpagedata(step: toolstep, target: Element | null, root: Document = document): Promise<stepresult> {\n let options: Record<string, unknown> = {};\n try { options = parseoptions(step); } catch { options = {}; }\n if (step.kind === \"scrapetable\") {\n const grid = readtable(target, root, step.target);\n if (!grid) return { ok: false, summary: \"The reviewed table selector matches no table element.\" };\n const rowlimit = typeof options.rowlimit === \"number\" && Number.isInteger(options.rowlimit) && options.rowlimit > 0 ? options.rowlimit : grid.rows.length;\n const limited = grid.rows.slice(0, rowlimit);\n return {\n ok: true,\n summary: `Scraped ${limited.length} row${limited.length === 1 ? \"\" : \"s\"} into ${grid.columns.length} normalized column${grid.columns.length === 1 ? \"\" : \"s\"}${grid.children.length > 0 ? ` with ${grid.children.length} nested child table${grid.children.length === 1 ? \"\" : \"s\"}` : \"\"}.`,\n details: { grid: { columns: grid.columns, rows: limited, children: grid.children }, rows: limited.length, columns: grid.columns.length },\n };\n }\n if (step.kind === \"paginateextract\") {\n const nextselector = typeof options.next === \"string\" ? options.next : \"\";\n const pages = typeof options.pages === \"number\" && Number.isInteger(options.pages) && options.pages > 0 ? options.pages : 1;\n const wait = typeof options.wait === \"number\" && Number.isFinite(options.wait) && options.wait > 0 ? options.wait : 0;\n const cursor = typeof options.cursor === \"number\" && Number.isInteger(options.cursor) && options.cursor > 0 ? options.cursor : 0;\n const grids: gridresult[] = [];\n let previous: datasetrow[] = [];\n for (let page = 0; page < pages + cursor; page += 1) {\n if (page < cursor) {\n const control = root.querySelector<HTMLElement>(nextselector);\n if (!control) break;\n control.click();\n await new Promise(resolve => window.setTimeout(resolve, 0));\n continue;\n }\n if (page > cursor) {\n const control = root.querySelector<HTMLElement>(nextselector);\n if (!control) break;\n control.click();\n const deadline = Date.now() + wait;\n let fresh = false;\n while (!fresh && Date.now() < deadline) {\n await new Promise(resolve => window.setTimeout(resolve, Math.min(100, Math.max(16, deadline - Date.now()))));\n const probe = readtable(target, root, step.target);\n fresh = probe !== null && rowsfresh(previous, probe.rows);\n }\n }\n const grid = readtable(target, root, step.target);\n if (!grid) return { ok: false, summary: \"The reviewed table selector matches no table element.\" };\n grids.push(grid);\n previous = grid.rows;\n }\n const merged = mergedatasets(grids);\n const hasnext = Boolean(root.querySelector(nextselector));\n return {\n ok: grids.length > 0,\n summary: grids.length > 0 ? `Followed ${grids.length} page${grids.length === 1 ? \"\" : \"s\"} of the reviewed table into ${merged.rows.length} row${merged.rows.length === 1 ? \"\" : \"s\"}${hasnext ? \"; a next control remains\" : \"\"}.` : \"No page of the reviewed table was extracted.\",\n details: { grid: { columns: merged.columns, rows: merged.rows, children: grids.flatMap(grid => grid.children) }, pages: grids.length, rows: merged.rows.length, next: hasnext },\n };\n }\n return { ok: false, summary: \"Unsupported data step.\" };\n}\n\n/** Exposes the pagination entries of the current document so plan review can suggest next controls. */\nexport function pagepagination(root: Document = document): Array<{ text: string; selector: string; current: boolean }> {\n return paginationentries(root, undefined);\n}\n", "import type { artifactrecord, columnspec, dataset, datasetrow, exportedartifact, extractsession, provenancerecord, streamstate, toolstep, transformrule } from \"../types.js\";\nimport { tocsv, toexcel, tojson } from \"./pagedata.js\";\n\n/**\n * Dataset command logics for the background executors.\n * Every correlated rule for dataset records, artifact exports with checksums, chunked streaming with backpressure, extraction cursors, loop row variables, provenance records and artifact retention lives in this file.\n */\n\n/** Builds one dataset record from a scraped grid result. */\nexport function builddataset(id: string, name: string, grid: { columns: columnspec[]; rows: datasetrow[]; children?: Array<{ parentrow: number; selector: string; columns: columnspec[]; rows: datasetrow[] }> }, at: number): dataset {\n return { id, name: name || id, columns: grid.columns, rows: grid.rows, sources: [], at };\n}\n\n/** Computes the deterministic checksum of an exported artifact's content. */\nexport function checksum(value: string): string {\n let hash = 5381;\n for (let index = 0; index < value.length; index += 1) hash = ((hash * 33) ^ value.charCodeAt(index)) >>> 0;\n return `fnv1a-${hash.toString(16)}`;\n}\n\n/** Serializes one dataset into the reviewed export format. */\nexport function exportcontent(datasetvalue: dataset, format: \"csv\" | \"json\" | \"excel\", delimiter = \",\"): string {\n if (format === \"json\") return tojson(datasetvalue.columns, datasetvalue.rows);\n if (format === \"excel\") return toexcel(datasetvalue.columns, datasetvalue.rows, datasetvalue.name);\n return tocsv(datasetvalue.columns, datasetvalue.rows, delimiter);\n}\n\n/** Builds one exported artifact record with its content and checksum for the task artifact store. */\nexport function exportartifact(id: string, datasetvalue: dataset, format: \"csv\" | \"json\" | \"excel\", stepid: string, content: string, at: number): exportedartifact {\n const extension = format === \"excel\" ? \"xml\" : format;\n return { id, kind: format, name: `${datasetvalue.name || datasetvalue.id}.${extension}`, stepid, rowcount: datasetvalue.rows.length, content, checksum: checksum(content), at };\n}\n\n/** Converts one exported artifact into the artifact record shape the run store keeps. */\nexport function artifactrecordof(artifact: exportedartifact): artifactrecord {\n return { id: artifact.id, kind: artifact.kind, name: artifact.name, stepid: artifact.stepid, at: artifact.at };\n}\n\n/** Plans the chunk boundaries of a streaming export from a user configured chunk size with no code ceiling. */\nexport function chunkplan(rows: number, chunk: number): Array<{ index: number; from: number; to: number }> {\n const size = Math.max(1, Math.floor(chunk));\n const chunks: Array<{ index: number; from: number; to: number }> = [];\n for (let from = 0; from < rows || chunks.length === 0; from += size) {\n const to = Math.min(rows, from + size);\n chunks.push({ index: chunks.length, from, to });\n if (to >= rows) break;\n }\n return chunks;\n}\n\n/** True when the stream writer must wait for acknowledgements: pending writes reached the in-flight budget of one. */\nexport function backpressure(written: number, acknowledged: number): boolean {\n return written - acknowledged >= 1;\n}\n\n/** Advances one stream state by one acknowledged chunk of rows. */\nexport function advancestream(state: streamstate, chunk: { index: number; to: number }, at: number, done: boolean): streamstate {\n return { datasetid: state.datasetid, name: state.name, chunk: chunk.index + 1, chunks: state.chunks, written: chunk.to, ...(done ? { done: true } : {}), at };\n}\n\n/** Returns the first unwritten row index of a stream, starting a fresh stream at zero. */\nexport function streamfrom(state: streamstate | undefined, rows: number): number {\n if (!state || state.done) return 0;\n return Math.min(state.written, rows);\n}\n\n/** Builds the initial stream state of one dataset. */\nexport function newstream(datasetvalue: dataset, chunks: number, at: number): streamstate {\n return { datasetid: datasetvalue.id, name: datasetvalue.name, chunk: 0, chunks, written: 0, at };\n}\n\n/** Advances one extraction session by one extracted page with its row count. */\nexport function advancecursor(sessionvalue: extractsession, page: string, rows: number, at: number, done: boolean): extractsession {\n return {\n id: sessionvalue.id,\n datasetid: sessionvalue.datasetid,\n name: sessionvalue.name,\n target: sessionvalue.target,\n next: sessionvalue.next,\n planned: sessionvalue.planned,\n pages: [...sessionvalue.pages, page],\n rows: sessionvalue.rows + rows,\n cursor: sessionvalue.cursor + 1,\n ...(done || sessionvalue.cursor + 1 >= sessionvalue.planned ? { done: true } : {}),\n startedat: sessionvalue.startedat,\n updatedat: at,\n };\n}\n\n/** Builds the initial extraction session of one dataset extraction. */\nexport function newextractsession(id: string, datasetid: string, name: string, target: string, next: string, planned: number, at: number): extractsession {\n return { id, datasetid, name, target, next, planned, pages: [], rows: 0, cursor: 0, startedat: at, updatedat: at };\n}\n\n/** Returns the pages an interrupted extraction still owes after its stored cursor. */\nexport function remainingpages(sessionvalue: extractsession, planned: number): number {\n if (sessionvalue.done) return 0;\n return Math.max(0, Math.max(sessionvalue.planned, planned) - sessionvalue.cursor);\n}\n\n/** Builds one provenance record of an exported artifact with its source url, step ref, row range and checksum. */\nexport function provenancefor(artifact: { id: string; name: string; rowcount: number; checksum: string }, url: string, stepid: string, at: number): provenancerecord {\n return { artifact: artifact.id, name: artifact.name, url, stepid, rowstart: artifact.rowcount > 0 ? 1 : 0, rowend: artifact.rowcount, checksum: artifact.checksum, at };\n}\n\n/** Applies the user configured artifact retention to exported artifacts; an absent setting keeps everything. */\nexport function retainedexports<T>(records: T[], retention: number | undefined): T[] {\n return retention === undefined ? records : records.slice(0, retention);\n}\n\n/** Interpolates one text through the {{column}} tokens of a dataset row. */\nexport function interpolate(text: string, row: datasetrow): string {\n return text.replace(/\\{\\{([^}]+)\\}\\}/g, (_, key: string) => row[key.trim()] ?? \"\");\n}\n\n/** Substitutes the row variables of one looprows iteration into the target, value and options of the inner step. */\nexport function loopstep(step: toolstep, row: datasetrow): toolstep {\n return {\n ...step,\n ...(step.target !== undefined ? { target: interpolate(step.target, row) } : {}),\n ...(step.value !== undefined ? { value: interpolate(step.value, row) } : {}),\n ...(step.options !== undefined ? { options: interpolate(step.options, row) } : {}),\n };\n}\n\n/** Exposes one dataset row as the step variables of a looprows iteration. */\nexport function loopvariables(row: datasetrow): datasetrow {\n return { ...row };\n}\n\n/** Builds the grid preview of a dataset with its column order, total rows and sampled rows. */\nexport function gridpreview(datasetvalue: dataset, sample: number): { datasetid: string; columns: string[]; rows: number; sample: datasetrow[] } {\n return { datasetid: datasetvalue.id, columns: datasetvalue.columns.map(column => column.key), rows: datasetvalue.rows.length, sample: datasetvalue.rows.slice(0, Math.max(0, Math.floor(sample))) };\n}\n\n/** Sorts dataset rows by one column key in the reviewed direction with a stable fallback for equal values. */\nexport function sortrows(rows: datasetrow[], key: string, direction: \"asc\" | \"desc\"): datasetrow[] {\n const sign = direction === \"desc\" ? -1 : 1;\n return [...rows].sort((left, right) => {\n const a = left[key] ?? \"\";\n const b = right[key] ?? \"\";\n const numeric = Number(a);\n const numericb = Number(b);\n if (Number.isFinite(numeric) && Number.isFinite(numericb) && a.trim() !== \"\" && b.trim() !== \"\") return (numeric - numericb) * sign;\n return a.localeCompare(b) * sign;\n });\n}\n\n/** Builds the sheet push payload of one dataset for a reviewed sheet endpoint. */\nexport function sheetpayload(datasetvalue: dataset, sheet: string): { sheet: string; columns: string[]; rows: datasetrow[] } {\n return { sheet, columns: datasetvalue.columns.map(column => column.key), rows: datasetvalue.rows };\n}\n\n/** Merges reviewed transform rules and dedupe keys into the task rules record of one task. */\nexport function mergetaskrules(existing: { taskid: string; transforms: transformrule[]; dedupekeys: string[] } | undefined, taskid: string, transforms: transformrule[], dedupekeys: string[], at: number): { taskid: string; transforms: transformrule[]; dedupekeys: string[]; at: number } {\n return {\n taskid,\n transforms: transforms.length > 0 ? transforms : (existing?.transforms ?? []),\n dedupekeys: dedupekeys.length > 0 ? dedupekeys : (existing?.dedupekeys ?? []),\n at,\n };\n}\n", "import type { observation, regionrect, resolvedtarget, toolstep } from \"../types.js\";\nimport { runpageaction, type stepresult } from \"./pageactions.js\";\nimport { runpageread } from \"./pagereads.js\";\nimport { runpagecontrol } from \"./pagecontrols.js\";\nimport { runinteractstep } from \"./pageinteract.js\";\nimport { runpointerstep } from \"./pagepointer.js\";\nimport { runpagenav } from \"./pagenav.js\";\nimport { harvestdialoglog, type observeddialog } from \"./pagedialogs.js\";\nimport { builda11ytree, buildpagetree, buildreader, runpageobservation } from \"./pageobserve.js\";\nimport { collecttables, detectlistpatterns, collectsiblings, normalizetable, runpagedetection } from \"./pagedetect.js\";\nimport { runpagewatch } from \"./pagewatch.js\";\nimport { runpageform } from \"./pageforms.js\";\nimport { runpagewizard } from \"./pagewizards.js\";\nimport { runpagedata } from \"./pagedata.js\";\nimport { checksum } from \"./datacommand.js\";\nimport { clean, elementlabel as label, elementselector as selector, resolvestep } from \"./pageresolve.js\";\n\n/**\n * Page bridge for reviewed steps.\n * Correlated rules for the dispatch seam, semantic snapshots, target preview with resolution, dialog log reads and the original action set live in this file.\n */\n\nfunction stepoptions(step: toolstep): Record<string, unknown> {\n if (!step.options) return {};\n try {\n const parsed = JSON.parse(step.options);\n return parsed && typeof parsed === \"object\" && !Array.isArray(parsed) ? (parsed as Record<string, unknown>) : {};\n } catch { return {}; }\n}\n\nconst previewid = \"devthinktargetpreview\";\n\nfunction clearpreview(): void {\n document.getElementById(previewid)?.remove();\n}\n\n/** Shows an ephemeral outline only; it neither mutates page data nor dispatches page events. */\nexport function previewtarget(step: toolstep, expectedorigin: string): { ok: boolean; summary: string; resolvedtarget?: resolvedtarget; candidates?: string[] } {\n if (location.origin !== expectedorigin) return { ok: false, summary: \"Page origin changed before preview.\" };\n clearpreview();\n const resolution = resolvestep(step, document);\n if (resolution.status === \"ambiguous\") return { ok: false, summary: `The reviewed ${resolution.mode} reference matched ${resolution.candidates.length} elements: ${resolution.candidates.join(\"; \")}.`, candidates: resolution.candidates };\n if (resolution.status !== \"resolved\") return { ok: false, summary: \"Reviewed target is no longer available.\" };\n const target = resolution.element;\n const rect = target.getBoundingClientRect();\n if (rect.width <= 0 || rect.height <= 0) return { ok: false, summary: \"Reviewed target is not currently visible.\" };\n const overlay = document.createElement(\"div\");\n overlay.id = previewid;\n overlay.setAttribute(\"aria-hidden\", \"true\");\n Object.assign(overlay.style, { position: \"fixed\", left: `${Math.max(0, rect.left - 3)}px`, top: `${Math.max(0, rect.top - 3)}px`, width: `${rect.width + 6}px`, height: `${rect.height + 6}px`, border: \"3px solid #2f80ed\", borderRadius: \"6px\", boxShadow: \"0 0 0 3px rgba(47,128,237,.28)\", pointerEvents: \"none\", zIndex: \"2147483647\", boxSizing: \"border-box\" });\n document.documentElement.append(overlay);\n window.setTimeout(clearpreview, 5000);\n return { ok: true, summary: `Previewing ${label(target) || target.tagName.toLowerCase()} for five seconds.`, resolvedtarget: resolution.target };\n}\n\n/** Captures the complete semantic page context for a user-approved active tab, including the a11y, reader, listpattern and tableshape observation sections. */\nexport function capturesnapshot(): observation {\n const candidates = [...document.querySelectorAll(\"a[href], button, input, textarea, select, [role=button], [role=link], [role=combobox], [role=option], [role=checkbox], [role=radio], [role=switch], [role=tab], details, summary\")];\n const interactive = candidates.map(element => ({ selector: selector(element), role: element.getAttribute(\"role\") || element.tagName.toLowerCase(), label: label(element) })).filter(item => item.label || item.role);\n const forms = [...document.querySelectorAll(\"input, textarea, select\")].map(element => ({\n label: label(element),\n type: element.getAttribute(\"type\") || element.tagName.toLowerCase(),\n name: element.getAttribute(\"name\") || \"\",\n ...(element instanceof HTMLSelectElement ? { options: [...element.options].map(option => clean(option.textContent || option.value)) } : {}),\n }));\n const text = clean(document.body?.innerText || \"\");\n const tree = buildpagetree(document);\n const tables = collecttables(document).map(entry => {\n const shape = normalizetable(entry.rows, entry.caption);\n return { selector: entry.selector, headers: shape.headers, columns: shape.columns, rows: shape.rows, caption: shape.caption };\n });\n return {\n schemaversion: 3,\n url: location.href,\n title: clean(document.title),\n textpreview: text,\n textlength: document.body?.innerText.length ?? 0,\n forms,\n interactive,\n capturedat: Date.now(),\n mode: \"passive\",\n a11y: builda11ytree(tree),\n reader: buildreader(tree, clean(document.title)),\n listpattern: detectlistpatterns(collectsiblings(document)),\n tableshape: tables,\n };\n}\n\n/** Reads and clears the dialog log the main world handler recorded on the shared document. */\nexport function readdialogs(): observeddialog[] {\n return harvestdialoglog(document);\n}\n\n/** Extracts full, read-only structured content for a reviewed extraction step. */\nfunction extractcontent(targetselector: string | undefined, root: Document): stepresult {\n if (!targetselector) {\n const links = [...root.querySelectorAll(\"a[href]\")].map(element => {\n const href = element instanceof HTMLAnchorElement ? element.getAttribute(\"href\") ?? \"\" : \"\";\n return { text: element.textContent?.trim() ?? \"\", href };\n });\n return { ok: true, summary: `Extracted ${links.length} link entries.`, details: { links } };\n }\n const target = root.querySelector(targetselector);\n if (!target) return { ok: false, summary: \"Extraction target is no longer available.\" };\n const text = target.textContent ?? \"\";\n return { ok: true, summary: `Extracted ${text.length} characters of content.`, details: { text } };\n}\n\n/** Scrolls one reviewed target into view without reading or changing other page state. */\nfunction scrolltarget(target: HTMLElement): stepresult {\n target.scrollIntoView({ block: \"center\", inline: \"nearest\", behavior: \"auto\" });\n return { ok: true, summary: `Scrolled ${label(target) || target.tagName.toLowerCase()} into view.` };\n}\n\n/** Dispatches hover events on one reviewed target. */\nfunction hovertarget(target: HTMLElement): stepresult {\n for (const type of [\"pointerover\", \"mouseover\", \"pointerenter\"] as const) {\n target.dispatchEvent(new PointerEvent(type, { bubbles: type !== \"pointerenter\", cancelable: true, composed: true }));\n }\n target.dispatchEvent(new MouseEvent(\"mouseenter\", { bubbles: false, cancelable: true }));\n return { ok: true, summary: `Hover events delivered to ${label(target) || target.tagName.toLowerCase()}.` };\n}\n\n/** Selects one reviewed existing option; values outside the declared options are refused. */\nfunction selectoption(target: HTMLElement, value: string): stepresult {\n if (!(target instanceof HTMLSelectElement)) return { ok: false, summary: \"Target is not a select element.\" };\n const option = [...target.options].find(candidate => candidate.value === value || candidate.textContent?.trim() === value);\n if (!option) return { ok: false, summary: \"Reviewed option is not part of the select element.\" };\n target.value = option.value;\n target.dispatchEvent(new Event(\"input\", { bubbles: true }));\n target.dispatchEvent(new Event(\"change\", { bubbles: true }));\n return { ok: true, summary: `Selected ${clean(option.textContent || option.value)}.` };\n}\n\nconst readkinds: ReadonlySet<string> = new Set([\"readattribute\", \"readstyle\", \"readgeometry\", \"readvalue\", \"readtext\", \"readhtml\", \"countelements\", \"readtable\", \"readlinks\", \"readimages\", \"readmeta\", \"readforms\", \"readstorage\", \"waitfor\", \"waittext\", \"highlight\", \"mapclicks\", \"verifyvisible\", \"verifyenabled\", \"resolvexpath\"]);\nconst mutatingkinds: ReadonlySet<string> = new Set([\"presskey\", \"clickdeep\", \"rightclick\", \"doubleclick\", \"drag\", \"drop\", \"upload\", \"clear\", \"check\", \"uncheck\", \"toggle\", \"submit\", \"setattribute\", \"removeattribute\", \"writestorage\", \"evaluate\", \"fullscreen\"]);\nconst controlkinds: ReadonlySet<string> = new Set([\"typetime\", \"appendtext\", \"setvalue\", \"typeedit\", \"keyhold\", \"keyrelease\", \"submitsearch\", \"selectmulti\", \"chooseradio\", \"setslider\", \"setdate\", \"setcolor\", \"expanddetails\"]);\nconst interactkinds: ReadonlySet<string> = new Set([\"clicktext\", \"clickaria\", \"clickname\", \"pierceshadow\", \"enterframe\"]);\nconst pointerkinds: ReadonlySet<string> = new Set([\"movepointer\", \"clickpoint\", \"shiftclick\"]);\nconst observationkinds: ReadonlySet<string> = new Set([\"a11ytree\", \"readvisible\", \"readertree\", \"readoutline\", \"readselection\", \"readopengraph\", \"readlang\", \"detectlanguage\", \"listshadow\", \"listframes\"]);\nconst detectionkinds: ReadonlySet<string> = new Set([\"detectlists\", \"detecttables\", \"detectinfinitescroll\", \"detectvirtual\", \"detectlazy\", \"detectsticky\", \"detectscrolllock\", \"countpages\", \"classifypage\", \"fingerprintsection\", \"readscrollpos\"]);\nconst watchstepkinds: ReadonlySet<string> = new Set([\"watchmutate\", \"watchbanner\", \"watchfocus\", \"waitquiet\", \"readjson\", \"diffsnapshots\", \"deriveselector\"]);\nconst navstepkinds: ReadonlySet<string> = new Set([\"waitload\", \"waiturl\", \"followlink\", \"spanav\", \"spawait\", \"rewritequery\", \"setfragment\", \"stopnav\", \"prefetch\", \"preconnect\", \"printpdf\"]);\nconst formkinds: ReadonlySet<string> = new Set([\"fillform\", \"filllabel\", \"fillplaceholder\", \"detectfields\", \"generatevalues\", \"readerrors\", \"skiphoneypot\", \"detectlogin\", \"detecttemplate\", \"handoffcaptcha\", \"asksubmit\", \"submitform\", \"consentpassword\", \"attachfile\"]);\nconst wizardkinds: ReadonlySet<string> = new Set([\"runwizard\", \"selectchain\", \"picktypeahead\", \"pickdate\", \"fillcard\", \"fillcode\"]);\nconst datastepkinds: ReadonlySet<string> = new Set([\"scrapetable\", \"paginateextract\"]);\n\n/** Performs one local action after the background policy gate and a fresh target resolution. */\nexport async function performstep(step: toolstep, expectedorigin: string, rootdocument: Document = document): Promise<stepresult> {\n if (location.origin !== expectedorigin) return { ok: false, summary: \"Page origin changed before action.\" };\n if (step.kind === \"observe\") return { ok: true, summary: \"Observation completed.\" };\n if (step.kind === \"wait\") {\n const requested = step.value ? Number.parseInt(step.value, 10) : 250;\n const duration = Number.isFinite(requested) && requested > 0 ? requested : 0;\n return new Promise(resolve => window.setTimeout(() => resolve({ ok: true, summary: `Reviewed wait of ${duration} milliseconds completed.` }), duration));\n }\n if (step.kind === \"extract\") return extractcontent(step.target, rootdocument);\n if (step.kind === \"navigate\") {\n if (!step.value || new URL(step.value).origin !== expectedorigin) return { ok: false, summary: \"Navigation target is outside the approved origin.\" };\n location.assign(step.value);\n return { ok: true, summary: \"Navigation request sent.\" };\n }\n if (step.kind === \"reload\") { location.reload(); return { ok: true, summary: \"Page reload requested.\" }; }\n if (step.kind === \"back\") { history.back(); return { ok: true, summary: \"History back requested.\" }; }\n if (step.kind === \"forward\") { history.forward(); return { ok: true, summary: \"History forward requested.\" }; }\n if (navstepkinds.has(step.kind)) return await runpagenav(step, rootdocument);\n if (step.kind === \"writeclipboard\") {\n const text = step.value ?? \"\";\n await navigator.clipboard.writeText(text);\n return { ok: true, summary: `Wrote ${text.length} reviewed character${text.length === 1 ? \"\" : \"s\"} to the clipboard with payload hash ${checksum(text)}.`, details: { length: text.length, hash: checksum(text), destination: \"clipboard\" } };\n }\n if (step.kind === \"scrollpage\") {\n const options = stepoptions(step);\n window.scrollBy({ left: typeof options.x === \"number\" ? options.x : 0, top: typeof options.y === \"number\" ? options.y : 600, behavior: \"auto\" });\n return { ok: true, summary: \"Window scrolled by the reviewed amounts.\" };\n }\n if (step.kind === \"scrollend\") { window.scrollTo(0, document.documentElement.scrollHeight); return { ok: true, summary: \"Window scrolled to the page end.\" }; }\n if (step.kind === \"scrolltop\") { window.scrollTo(0, 0); return { ok: true, summary: \"Window scrolled to the page top.\" }; }\n const resolution = resolvestep(step, rootdocument);\n if (resolution.status === \"ambiguous\") {\n return { ok: false, summary: `The reviewed ${resolution.mode} reference matched ${resolution.candidates.length} elements: ${resolution.candidates.join(\"; \")}.`, details: { mode: resolution.mode, candidates: resolution.candidates } };\n }\n const element = resolution.status === \"resolved\" ? resolution.element : null;\n let result: stepresult | Promise<stepresult>;\n if (formkinds.has(step.kind)) result = runpageform(step, element, rootdocument);\n else if (wizardkinds.has(step.kind)) result = runpagewizard(step, element, rootdocument);\n else if (datastepkinds.has(step.kind)) result = runpagedata(step, element, rootdocument);\n else if (readkinds.has(step.kind)) result = runpageread(step, element, rootdocument);\n else if (controlkinds.has(step.kind)) result = runpagecontrol(step, element, rootdocument);\n else if (interactkinds.has(step.kind)) return await runinteractstep(step, expectedorigin, performstep);\n else if (pointerkinds.has(step.kind)) result = runpointerstep(step, resolution);\n else if (observationkinds.has(step.kind)) result = runpageobservation(step, element, rootdocument);\n else if (detectionkinds.has(step.kind)) result = runpagedetection(step, element, rootdocument);\n else if (watchstepkinds.has(step.kind)) result = runpagewatch(step, element, rootdocument);\n else if (mutatingkinds.has(step.kind)) result = runpageaction(step, element);\n else {\n if (!element) return { ok: false, summary: \"Action target is no longer available.\" };\n if (step.kind === \"scrollby\") {\n const options = stepoptions(step);\n element.scrollBy({ left: typeof options.x === \"number\" ? options.x : 0, top: typeof options.y === \"number\" ? options.y : 600, behavior: \"auto\" });\n result = { ok: true, summary: \"Container scrolled by the reviewed amounts.\" };\n } else if (step.kind === \"focus\") { element.focus(); result = { ok: true, summary: \"Target focused.\" }; }\n else if (step.kind === \"inspect\") result = { ok: true, summary: `Target: ${label(element) || element.tagName.toLowerCase()}.` };\n else if (step.kind === \"click\") { element.click(); result = { ok: true, summary: \"Reviewed click completed.\" }; }\n else if (step.kind === \"scroll\") result = scrolltarget(element);\n else if (step.kind === \"hover\") result = hovertarget(element);\n else if (step.kind === \"select\") result = selectoption(element, step.value ?? \"\");\n else if (step.kind === \"type\") {\n if (!(element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement)) return { ok: false, summary: \"Target cannot receive text.\" };\n if (typeof step.value !== \"string\") return { ok: false, summary: \"Approved text is absent.\" };\n element.focus();\n element.value = step.value;\n element.dispatchEvent(new Event(\"input\", { bubbles: true }));\n element.dispatchEvent(new Event(\"change\", { bubbles: true }));\n result = { ok: true, summary: \"Approved text entered.\" };\n } else return { ok: false, summary: \"Unsupported action.\" };\n }\n const output = await result;\n if (resolution.status === \"resolved\") {\n return { ...output, details: { ...(output.details ?? {}), mode: resolution.target.mode, resolvedtarget: resolution.target } };\n }\n return output;\n}\n\n/** Measures the full scroll width and height before any stitching begins, beside the viewport geometry, the device pixel ratio and the current scroll position. */\nexport function measurepage(): { scrollwidth: number; scrollheight: number; viewportwidth: number; viewportheight: number; pixelratio: number; scrollx: number; scrolly: number } {\n const root = document.documentElement;\n return {\n scrollwidth: Math.max(root.scrollWidth, document.body?.scrollWidth ?? 0),\n scrollheight: Math.max(root.scrollHeight, document.body?.scrollHeight ?? 0),\n viewportwidth: window.innerWidth,\n viewportheight: window.innerHeight,\n pixelratio: window.devicePixelRatio || 1,\n scrollx: window.scrollX,\n scrolly: window.scrollY,\n };\n}\n\n/** Returns the pixel ratio scaled rect of one target element with the viewport crossing flag for the tiled fallback. */\nexport function elementrect(selector: string): { ok: boolean; rect?: regionrect; pixelratio?: number; crossesviewport?: boolean; summary: string } {\n const target = document.querySelector(selector);\n if (!target) return { ok: false, summary: \"The reviewed capture element is no longer available.\" };\n const bounds = target.getBoundingClientRect();\n if (bounds.width <= 0 || bounds.height <= 0) return { ok: false, summary: \"The reviewed capture element is not currently visible.\" };\n const viewport = { width: window.innerWidth, height: window.innerHeight };\n const rect: regionrect = { x: Math.round(bounds.left + window.scrollX), y: Math.round(bounds.top + window.scrollY), width: Math.round(bounds.width), height: Math.round(bounds.height) };\n const viewrect: regionrect = { x: bounds.left, y: bounds.top, width: bounds.width, height: bounds.height };\n return { ok: true, rect, pixelratio: window.devicePixelRatio || 1, crossesviewport: viewrect.x < 0 || viewrect.y < 0 || viewrect.x + viewrect.width > viewport.width || viewrect.y + viewrect.height > viewport.height, summary: `Measured the capture element at ${rect.width} by ${rect.height} css pixels.` };\n}\n\nconst scrollbarstyleid = \"devthinkcapturehider\";\n\n/** Prepares the page for capture: hides the capture scrollbars through a scoped style rule and returns the original scroll position. */\nexport function preparecapture(): { scrollx: number; scrolly: number } {\n if (!document.getElementById(scrollbarstyleid)) {\n const style = document.createElement(\"style\");\n style.id = scrollbarstyleid;\n style.setAttribute(\"aria-hidden\", \"true\");\n style.textContent = \"html::-webkit-scrollbar,body::-webkit-scrollbar{display:none!important}html{scrollbar-width:none!important}\";\n document.documentElement.append(style);\n }\n return { scrollx: window.scrollX, scrolly: window.scrollY };\n}\n\n/** Scrolls the page to one reviewed tile offset and reports the settled position. */\nexport function scrollcapture(x: number, y: number): { x: number; y: number } {\n window.scrollTo(x, y);\n return { x: window.scrollX, y: window.scrollY };\n}\n\n/** Restores the original scroll position after the last tile and removes the capture scrollbar hider. */\nexport function restorecapture(state: { scrollx: number; scrolly: number }): void {\n document.getElementById(scrollbarstyleid)?.remove();\n window.scrollTo(state.scrollx, state.scrolly);\n}\n\n/** Scrolls one scrollable container to a reviewed step top and reports its geometry. */\nexport function scrollcontainercapture(selector: string, top: number): { ok: boolean; top?: number; height?: number; viewportheight?: number; summary: string } {\n const container = document.querySelector(selector);\n if (!container) return { ok: false, summary: \"The reviewed scrollable container is no longer available.\" };\n if (!(container instanceof HTMLElement)) return { ok: false, summary: \"The reviewed scrollable container cannot scroll.\" };\n container.scrollTo({ top, behavior: \"auto\" });\n return { ok: true, top: container.scrollTop, height: container.scrollHeight, viewportheight: container.clientHeight, summary: `Scrolled the container to ${container.scrollTop} of ${container.scrollHeight} pixels.` };\n}\n\n/** Waits the reviewed settle time between capture tiles. */\nexport function waitsettle(milliseconds: number): Promise<void> {\n return new Promise(resolve => window.setTimeout(resolve, Math.max(0, milliseconds)));\n}\n\n\n/** Collects the visible text of one pdf report segment: every block element whose bounds intersect the reviewed vertical range contributes its text, so paginated reports split at reviewed break points. */\nexport function pdfsegment(top: number, height: number): { ok: boolean; text: string; summary: string } {\n const blocks = [...document.querySelectorAll(\"h1,h2,h3,h4,h5,h6,p,li,td,th,blockquote,pre,figcaption,section,article > div\")];\n const lines: string[] = [];\n for (const block of blocks) {\n const bounds = block.getBoundingClientRect();\n const blocktop = bounds.top + window.scrollY;\n const blockbottom = blocktop + bounds.height;\n if (blockbottom <= top || blocktop >= top + height) continue;\n const text = clean(block.textContent ?? \"\");\n if (text) lines.push(text);\n }\n const text = lines.join(\"\\n\");\n return { ok: true, text, summary: `Collected ${text.length} characters of the report segment at ${Math.round(top)} to ${Math.round(top + height)} pixels.` };\n}\n\n/** Resolves the scroll tops of the reviewed pdf break point selectors for paginated reports. */\nexport function pdfbreaks(selectors: string[]): Array<{ selector: string; top: number }> {\n const resolved: Array<{ selector: string; top: number }> = [];\n for (const selector of selectors) {\n const target = document.querySelector(selector);\n if (!target) continue;\n resolved.push({ selector, top: Math.round(target.getBoundingClientRect().top + window.scrollY) });\n }\n return resolved;\n}\n\n/** Grabs one still frame of a video element at the reviewed timestamp: the video seeks, pauses and draws to a canvas that encodes as an image; cross origin videos without cors refuse the draw honestly. */\nexport async function videoframe(selector: string, timestamp: number | undefined, poster: boolean): Promise<{ ok: boolean; dataurl?: string; width?: number; height?: number; summary: string }> {\n const target = document.querySelector(selector);\n if (!(target instanceof HTMLVideoElement)) return { ok: false, summary: \"The reviewed frame source is not a video element.\" };\n target.pause();\n if (typeof timestamp === \"number\" && Number.isFinite(timestamp) && timestamp >= 0 && timestamp <= (target.duration || 0)) {\n await new Promise<void>(resolve => {\n const done = (): void => resolve();\n target.addEventListener(\"seeked\", done, { once: true });\n target.currentTime = timestamp;\n window.setTimeout(done, 1500);\n });\n }\n const width = target.videoWidth || target.clientWidth || 1;\n const height = target.videoHeight || target.clientHeight || 1;\n try {\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n const context = canvas.getContext(\"2d\");\n if (!context) return { ok: false, summary: \"The frame grab could not create a canvas context.\" };\n context.drawImage(target, 0, 0, width, height);\n const dataurl = canvas.toDataURL(\"image/png\");\n return { ok: dataurl.length > 100, dataurl, width, height, summary: `Grabbed the video frame at ${target.currentTime.toFixed(2)} seconds of ${width} by ${height} pixels${poster ? \" as the poster frame\" : \"\"}.` };\n } catch {\n return { ok: false, summary: \"The video frame draw was refused; cross origin videos need cors headers before frames can be read.\" };\n }\n}\n\n/** Reads the content of one canvas element: plain 2d canvases return their buffer directly and webgl canvases request the buffer through a preserved read; tainted canvases refuse honestly. */\nexport function canvasdata(selector: string): { ok: boolean; context: \"2d\" | \"webgl\"; dataurl?: string; width?: number; height?: number; preserved?: boolean; summary: string } {\n const target = document.querySelector(selector);\n if (!(target instanceof HTMLCanvasElement)) return { ok: false, context: \"2d\", summary: \"The reviewed canvas element is no longer available.\" };\n const width = target.width || 1;\n const height = target.height || 1;\n const kind: \"2d\" | \"webgl\" = target.getContext(\"2d\") ? \"2d\" : \"webgl\";\n try {\n let dataurl = \"\";\n let preserved = false;\n if (kind === \"2d\") {\n dataurl = target.toDataURL(\"image/png\");\n } else {\n dataurl = target.toDataURL(\"image/png\");\n if (dataurl.length <= 100) {\n const gl = (target.getContext(\"webgl\") ?? target.getContext(\"experimental-webgl\")) as WebGLRenderingContext | null;\n if (gl) {\n const pixels = new Uint8Array(width * height * 4);\n gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n const context = canvas.getContext(\"2d\");\n if (context) {\n const image = context.createImageData(width, height);\n for (let row = 0; row < height; row += 1) {\n const source = (height - 1 - row) * width * 4;\n const destination = row * width * 4;\n image.data.set(pixels.subarray(source, source + width * 4), destination);\n }\n context.putImageData(image, 0, 0);\n dataurl = canvas.toDataURL(\"image/png\");\n preserved = true;\n }\n }\n }\n }\n return { ok: dataurl.length > 100, context: kind, dataurl, width, height, preserved, summary: `Read the ${kind} canvas buffer of ${width} by ${height} pixels${kind === \"webgl\" ? preserved ? \" through a preserved readPixels pass\" : \" through the preserved drawing buffer\" : \"\"}.` };\n } catch {\n return { ok: false, context: kind, summary: \"The canvas read was refused; tainted canvas content needs cross origin resources with cors headers.\" };\n }\n}\n\n/** Probes the media streams of the page: every video and audio element with a srcObject reports its track kinds, labels, settings and live states; peer connection statistics stay outside the isolated world bridge. */\nexport function streamelements(selector?: string): Array<Record<string, unknown>> {\n const root = selector ? document.querySelector(selector) : document;\n if (!root) return [];\n const entries: Array<Record<string, unknown>> = [];\n for (const element of [...root.querySelectorAll(\"video, audio\")]) {\n const media = element instanceof HTMLMediaElement ? element : null;\n if (!media) continue;\n const stream = media.srcObject;\n if (!(stream instanceof MediaStream)) continue;\n entries.push({\n kind: \"webrtc\",\n label: stream.id,\n live: stream.active,\n tracks: stream.getTracks().map(track => ({\n kind: track.kind,\n label: track.label,\n state: track.readyState,\n ...(track.kind === \"video\" ? { width: track.getSettings().width, height: track.getSettings().height, framerate: track.getSettings().frameRate } : {}),\n })),\n });\n }\n return entries;\n}\n\n/** Reads the embedded video and audio sources of the page with their formats, durations, dimensions, codecs and track lists. */\nexport function mediaelements(): Array<Record<string, unknown>> {\n const entries: Array<Record<string, unknown>> = [];\n for (const element of [...document.querySelectorAll(\"video, audio\")]) {\n if (!(element instanceof HTMLMediaElement)) continue;\n const source = element.querySelector(\"source\");\n const url = element.currentSrc || element.src || (source instanceof HTMLSourceElement ? source.src : \"\") || \"\";\n if (!url) continue;\n const type = (source instanceof HTMLSourceElement ? source.type : \"\") || \"\";\n const codecs = type.includes(\"codecs=\") ? type.slice(type.indexOf(\"codecs=\") + \"codecs=\".length).replace(/[\"']/g, \"\") : \"\";\n entries.push({\n url,\n mime: type.split(\";\")[0] || \"\",\n duration: Number.isFinite(element.duration) ? element.duration : 0,\n width: element instanceof HTMLVideoElement ? element.videoWidth : 0,\n height: element instanceof HTMLVideoElement ? element.videoHeight : 0,\n codecs,\n tracks: [...element.textTracks].map(track => track.label || track.kind).filter(Boolean),\n });\n }\n return entries;\n}\n\n/** Collects the page assets: declared favicons and apple touch icons with their sizes, manifest declared icons and logo candidates from meta images and header imagery. */\nexport async function pageassets(): Promise<Array<Record<string, unknown>>> {\n const entries: Array<Record<string, unknown>> = [];\n for (const link of [...document.querySelectorAll(\"link[rel]\")]) {\n const rel = (link.getAttribute(\"rel\") ?? \"\").toLowerCase();\n const href = link.getAttribute(\"href\");\n if (!href || !(rel.includes(\"icon\") || rel.includes(\"apple-touch\"))) continue;\n const resolved = new URL(href, location.href).toString();\n entries.push({ kind: \"favicon\", url: resolved, bytes: 0, sizes: link.getAttribute(\"sizes\") ?? \"any\" });\n }\n const og = document.querySelector('meta[property=\"og:image\"]');\n if (og instanceof HTMLMetaElement && og.content) entries.push({ kind: \"logo\", url: new URL(og.content, location.href).toString(), bytes: 0, sizes: \"og\" });\n for (const image of [...document.querySelectorAll(\"header img, nav img, img[alt*=logo i], img[src*=logo i]\")]) {\n const url = image instanceof HTMLImageElement ? image.currentSrc || image.src : \"\";\n if (!url) continue;\n entries.push({ kind: \"logo\", url: new URL(url, location.href).toString(), bytes: 0, sizes: image instanceof HTMLImageElement ? `${image.naturalWidth}x${image.naturalHeight}` : \"\" });\n }\n const manifestlink = document.querySelector('link[rel=\"manifest\"]');\n if (manifestlink instanceof HTMLLinkElement && manifestlink.href) {\n try {\n const response = await fetch(manifestlink.href);\n const manifest = await response.json() as { icons?: Array<{ src?: string; sizes?: string }> };\n for (const icon of manifest.icons ?? []) {\n if (!icon.src) continue;\n entries.push({ kind: \"favicon\", url: new URL(icon.src, location.href).toString(), bytes: 0, sizes: icon.sizes ?? \"any\" });\n }\n } catch { /* a refused manifest fetch leaves the declared icons unreported */ }\n }\n return entries;\n}\n\n/** Detects every image of the page inside an optional selector scope: urls, alt text, natural dimensions, transfer sizes from the performance entries and mime types. */\nexport function pageimages(selector?: string): Array<Record<string, unknown>> {\n const root = selector ? document.querySelector(selector) : document;\n if (!root) return [];\n const transfers = new Map<string, number>();\n for (const entry of performance.getEntriesByType(\"resource\")) {\n const resource = entry as PerformanceResourceTiming;\n if (resource.transferSize > 0) transfers.set(resource.name, resource.transferSize);\n }\n const images: Array<Record<string, unknown>> = [];\n for (const element of [...root.querySelectorAll(\"img\")]) {\n if (!(element instanceof HTMLImageElement)) continue;\n const url = element.currentSrc || element.src;\n if (!url) continue;\n const resolved = new URL(url, location.href).toString();\n const type = element.getAttribute(\"type\") ?? \"\";\n images.push({\n url: resolved,\n alt: element.alt ?? \"\",\n width: element.naturalWidth || element.width,\n height: element.naturalHeight || element.height,\n bytes: transfers.get(resolved) ?? 0,\n mime: type || (element.src.startsWith(\"data:\") ? element.src.slice(5, element.src.indexOf(\";\")) : \"image/*\"),\n });\n }\n return images;\n}\nObject.assign(globalThis, { devthinkbridge: { capturesnapshot, previewtarget, performstep, readdialogs, measurepage, elementrect, preparecapture, scrollcapture, restorecapture, scrollcontainercapture, waitsettle, pdfsegment, pdfbreaks, videoframe, canvasdata, streamelements, mediaelements, pageassets, pageimages } });\n"],
5
+ "mappings": "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",
6
+ "names": ["receiver", "owntext", "events", "modifiers", "keyevent", "fieldlike", "modifiers", "receiver", "wait", "poll", "wrap", "owntext", "stepoptions", "window", "events", "wait", "poll", "events", "wait", "pollfor", "entry", "wait", "stepoptions", "text"]
7
7
  }