@webx-ui/module-audit 0.5.1 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AuditHostsPage-YFRORYHZ.js → AuditHostsPage-CSAlf3jK.js} +3 -3
- package/dist/{AuditHostsPage-YFRORYHZ.js.map → AuditHostsPage-CSAlf3jK.js.map} +1 -1
- package/dist/AuditIssuesPage-DtEJ9Sgq.js +718 -0
- package/dist/AuditIssuesPage-DtEJ9Sgq.js.map +1 -0
- package/dist/{AuditLayout.vue_vue_type_script_setup_true_lang-C8H5jlTe.js → AuditLayout.vue_vue_type_script_setup_true_lang-C39k6JNr.js} +2 -2
- package/dist/{AuditLayout.vue_vue_type_script_setup_true_lang-C8H5jlTe.js.map → AuditLayout.vue_vue_type_script_setup_true_lang-C39k6JNr.js.map} +1 -1
- package/dist/{AuditOverviewPage-gVpdBOAY.js → AuditOverviewPage-B5mexNDW.js} +3 -3
- package/dist/{AuditOverviewPage-gVpdBOAY.js.map → AuditOverviewPage-B5mexNDW.js.map} +1 -1
- package/dist/{AuditPagesPage-DNgZo-K-.js → AuditPagesPage-C1Akv4Ql.js} +3 -3
- package/dist/{AuditPagesPage-DNgZo-K-.js.map → AuditPagesPage-C1Akv4Ql.js.map} +1 -1
- package/dist/{AuditRunsPage-BbWsuATw.js → AuditRunsPage-SlBisvcG.js} +3 -3
- package/dist/{AuditRunsPage-BbWsuATw.js.map → AuditRunsPage-SlBisvcG.js.map} +1 -1
- package/dist/{AuditSettingsPage-HwfdLU_s.js → AuditSettingsPage-ADutjdIO.js} +3 -3
- package/dist/{AuditSettingsPage-HwfdLU_s.js.map → AuditSettingsPage-ADutjdIO.js.map} +1 -1
- package/dist/{index-BFYHJYU_.js → index-_DgRf2O6.js} +8 -8
- package/dist/{index-BFYHJYU_.js.map → index-_DgRf2O6.js.map} +1 -1
- package/dist/index.js +1 -1
- package/dist/style.css +1 -1
- package/package.json +4 -4
- package/dist/AuditIssuesPage-BjTPgAnD.js +0 -693
- package/dist/AuditIssuesPage-BjTPgAnD.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-BFYHJYU_.js","sources":["../src/module.ts","../src/api.ts","../src/messages.ts","../src/addresses.ts","../src/AuditAddress.vue","../src/i18n.ts","../src/AuditLinkAttrs.vue","../src/AuditStatus.vue","../src/AuditDetails.vue","../src/headings.ts","../src/AuditHeadings.vue","../src/resources.ts","../src/AuditPageCard.vue","../src/AuditHideDialog.vue","../src/fields.ts","../src/index.ts"],"sourcesContent":["import type { AdminModule } from '@webx-ui/module-admin'\n\nexport interface AuditOptions {\n /** Where the section lives inside the panel. */\n path?: string\n /**\n * @deprecated The audit's settings are a view of the section itself (`<path>/settings`); the\n * option is read by nothing and stays only so that a panel which passed it still compiles.\n */\n settingsPath?: string\n}\n\n/**\n * «System → Audit» as a section of the panel: the overview of the last run, its findings, the\n * pages the last full run crawled, the hosts the site points at, the history of runs with two of\n * them compared, and the section's settings.\n *\n * The id matches the module the server reports, which is what makes the entry appear in the\n * navigation: the section shows up when both halves are installed.\n */\nexport function audit(options: AuditOptions = {}): AdminModule {\n const path = options.path ?? '/audit'\n const props = { base: path }\n\n return {\n id: 'audit',\n path,\n routes: [\n { path, name: 'webx.audit', component: () => import('./AuditOverviewPage.vue'), props },\n {\n path: `${path}/issues`,\n name: 'webx.audit.issues',\n component: () => import('./AuditIssuesPage.vue'),\n props,\n },\n {\n path: `${path}/pages`,\n name: 'webx.audit.pages',\n component: () => import('./AuditPagesPage.vue'),\n props,\n },\n {\n path: `${path}/hosts`,\n name: 'webx.audit.hosts',\n component: () => import('./AuditHostsPage.vue'),\n props,\n },\n {\n path: `${path}/runs`,\n name: 'webx.audit.runs',\n component: () => import('./AuditRunsPage.vue'),\n props,\n },\n {\n path: `${path}/settings`,\n name: 'webx.audit.settings',\n component: () => import('./AuditSettingsPage.vue'),\n props,\n },\n ],\n }\n}\n","import type { AdminContext } from '@webx-ui/module-admin'\nimport type {\n AuditCheckRow,\n AuditComparison,\n AuditComparisonKind,\n AuditFixOffer,\n AuditFixResult,\n AuditHosts,\n AuditHostClass,\n AuditIgnoreRule,\n AuditIssue,\n AuditIssueQuery,\n AuditLatest,\n AuditLinkRow,\n AuditPage,\n AuditPageCard,\n AuditPageQuery,\n AuditPageRow,\n AuditResourceRow,\n AuditResourceTab,\n AuditRun,\n AuditScope,\n} from './types'\n\nexport interface AuditApi {\n /** The run that is going, the last one that finished, and whether the queue can take one. */\n latest(): Promise<AuditLatest>\n run(id: number): Promise<AuditRun>\n /** Every run, newest first — the history. */\n runs(query?: { page?: number; per_page?: number }): Promise<AuditPage<AuditRun>>\n /**\n * Queues a run; refused with 409 on a `sync` queue or while another one is going. A `urls` run\n * is a recheck of the addresses given.\n */\n start(scope: AuditScope, urls?: string[]): Promise<AuditRun>\n cancel(id: number): Promise<AuditRun>\n /** Deletes every run with all it found; refused with 409 while a run is going. */\n clear(): Promise<number>\n /** The checks of a run that found something, worst first. */\n checks(run: number, query?: AuditIssueQuery): Promise<AuditCheckRow[]>\n /** The findings of a run — of one check when `check` is given. */\n issues(run: number, query?: AuditIssueQuery): Promise<AuditPage<AuditIssue>>\n /** The crawled pages of a run under the screen's filters. */\n pages(run: number, query?: AuditPageQuery): Promise<AuditPage<AuditPageRow>>\n /** Where the browser downloads the same list as CSV, under the panel's session. */\n pagesFile(run: number, query: AuditPageQuery, columns: string[]): string\n page(run: number, id: number): Promise<AuditPageCard>\n /** The links of a page: `out` — what it points at, `in` — what points at it. */\n links(\n run: number,\n id: number,\n query?: { direction?: 'in' | 'out'; kind?: string; page?: number; per_page?: number },\n ): Promise<AuditPage<AuditLinkRow>>\n /** What a page loads, a tab of the card at a time. */\n resources(\n run: number,\n id: number,\n query: { tab: AuditResourceTab; page?: number; per_page?: number },\n ): Promise<AuditPage<AuditResourceRow>>\n /** The fixes that can close a finding now, each with what it would change. */\n fixes(run: number, issue: number): Promise<AuditFixOffer[]>\n /** Presses a fix — or, with `dryRun`, only asks again what it would change. */\n fix(run: number, issue: number, fix: string, dryRun?: boolean): Promise<AuditFixResult>\n /** Where the browser downloads one page of a run — its snapshot, findings and links. */\n pageFile(run: number, id: number): string\n /** Two runs by fingerprint; without `from`, `to` against the run it was analysed against. */\n compare(to: number, from?: number | null): Promise<AuditComparison>\n /** The findings of one kind of a comparison, of one check when given. */\n compareIssues(query: {\n to: number\n from?: number | null\n kind: AuditComparisonKind\n check?: string\n page?: number\n per_page?: number\n }): Promise<AuditPage<AuditIssue>>\n /** Every host the site points at, by class — stands first; with `host`, where it stands. */\n hosts(query?: {\n class?: AuditHostClass | null\n search?: string\n host?: string\n }): Promise<AuditHosts>\n /** The hiding rules. */\n ignores(): Promise<AuditIgnoreRule[]>\n /** Hides what a rule matches, with the reason. */\n hide(rule: { check: string; pattern: string; reason: string }): Promise<AuditIgnoreRule>\n /** How many findings of the last run a rule would hide — nothing is hidden. */\n hidePreview(rule: { check: string; pattern: string }): Promise<number>\n /** Removes a rule: its findings count again. */\n unhide(id: number): Promise<void>\n /** The section's settings, keyed as the screen names them. */\n settings(): Promise<Record<string, unknown>>\n saveSettings(values: Record<string, unknown>): Promise<Record<string, unknown>>\n}\n\n/** The query of the pages screen as the API reads it: `f[field]=op:value` for each filter. */\nexport function pageParams(query: AuditPageQuery): Record<string, string | number | undefined> {\n const params: Record<string, string | number | undefined> = {\n search: query.search || undefined,\n status: query.status || undefined,\n indexable:\n query.indexable === null || query.indexable === undefined\n ? undefined\n : query.indexable\n ? 1\n : 0,\n check: query.check || undefined,\n sort: query.sort || undefined,\n page: query.page,\n per_page: query.per_page,\n }\n\n for (const filter of query.filters ?? []) {\n params[`f[${filter.field}]`] =\n filter.value === undefined || filter.value === '' ? filter.op : `${filter.op}:${filter.value}`\n }\n\n return params\n}\n\n/** Everything under `/audit`, below the panel's API path. */\nexport function createAuditApi(admin: AdminContext): AuditApi {\n const base = `${admin.apiPath}/audit`\n const data = <T>(body: { data: T }): T => body.data\n\n /* `undefined` drops a parameter; `null` and `''` would be sent as words. */\n const filters = (query: AuditIssueQuery) => ({\n check: query.check || undefined,\n severity: query.severity || undefined,\n group: query.group || undefined,\n state: query.state || undefined,\n page: query.page,\n per_page: query.per_page,\n })\n\n return {\n latest: () => admin.http.get<{ data: AuditLatest }>(`${base}/runs/latest`).then(data),\n\n run: (id) => admin.http.get<{ data: AuditRun }>(`${base}/runs/${id}`).then(data),\n\n runs: (query = {}) =>\n admin.http\n .get<{\n data: AuditRun[]\n meta: Omit<AuditPage<AuditRun>, 'data'>\n }>(`${base}/runs`, { query })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n start: (scope, urls) =>\n admin.http\n .post<{ data: AuditRun }>(`${base}/runs`, scope === 'urls' ? { scope, urls } : { scope })\n .then(data),\n\n cancel: (id) => admin.http.post<{ data: AuditRun }>(`${base}/runs/${id}/cancel`, {}).then(data),\n\n clear: () =>\n admin.http.delete<{ data: { runs: number } }>(`${base}/runs`).then((body) => body.data.runs),\n\n checks: (run, query = {}) =>\n admin.http\n .get<{ data: AuditCheckRow[] }>(`${base}/runs/${run}/checks`, { query: filters(query) })\n .then(data),\n\n issues: (run, query = {}) =>\n admin.http\n .get<{\n data: AuditIssue[]\n meta: Omit<AuditPage<AuditIssue>, 'data'>\n }>(`${base}/runs/${run}/issues`, { query: filters(query) })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n pages: (run, query = {}) =>\n admin.http\n .get<{\n data: AuditPageRow[]\n meta: Omit<AuditPage<AuditPageRow>, 'data'>\n }>(`${base}/runs/${run}/pages`, { query: pageParams(query) })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n pagesFile: (run, query, columns) => {\n const params = new URLSearchParams()\n\n for (const [key, value] of Object.entries({\n ...pageParams(query),\n page: undefined,\n per_page: undefined,\n })) {\n if (value !== undefined) params.set(key, String(value))\n }\n\n params.set('columns', columns.join(','))\n\n return `${base}/runs/${run}/pages/export?${params.toString()}`\n },\n\n page: (run, id) =>\n admin.http.get<{ data: AuditPageCard }>(`${base}/runs/${run}/pages/${id}`).then(data),\n\n links: (run, id, query = {}) =>\n admin.http\n .get<{\n data: AuditLinkRow[]\n meta: Omit<AuditPage<AuditLinkRow>, 'data'>\n }>(`${base}/runs/${run}/pages/${id}/links`, { query })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n resources: (run, id, query) =>\n admin.http\n .get<{\n data: AuditResourceRow[]\n meta: Omit<AuditPage<AuditResourceRow>, 'data'>\n }>(`${base}/runs/${run}/pages/${id}/resources`, { query })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n fixes: (run, issue) =>\n admin.http\n .get<{ data: AuditFixOffer[] }>(`${base}/runs/${run}/issues/${issue}/fixes`)\n .then(data),\n\n fix: (run, issue, fix, dryRun = false) =>\n admin.http\n .post<{\n data: AuditFixResult\n }>(`${base}/runs/${run}/issues/${issue}/fixes/${encodeURIComponent(fix)}`, {\n dry_run: dryRun,\n })\n .then(data),\n\n pageFile: (run, id) => `${base}/runs/${run}/pages/${id}/export`,\n\n compare: (to, from) =>\n admin.http\n .get<{\n data: AuditComparison\n }>(`${base}/runs/compare`, { query: { to, from: from ?? undefined } })\n .then(data),\n\n compareIssues: (query) =>\n admin.http\n .get<{\n data: AuditIssue[]\n meta: Omit<AuditPage<AuditIssue>, 'data'>\n }>(`${base}/runs/compare/issues`, {\n query: { ...query, from: query.from ?? undefined, check: query.check || undefined },\n })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n hosts: (query = {}) =>\n admin.http\n .get<{ data: AuditHosts }>(`${base}/hosts`, {\n query: {\n class: query.class || undefined,\n search: query.search || undefined,\n host: query.host || undefined,\n },\n })\n .then(data),\n\n ignores: () => admin.http.get<{ data: AuditIgnoreRule[] }>(`${base}/ignores`).then(data),\n\n hide: (rule) => admin.http.post<{ data: AuditIgnoreRule }>(`${base}/ignores`, rule).then(data),\n\n hidePreview: (rule) =>\n admin.http\n .post<{ data: { hidden: number } }>(`${base}/ignores`, { ...rule, dry_run: true })\n .then((body) => body.data.hidden),\n\n unhide: (id) => admin.http.delete(`${base}/ignores/${id}`).then(() => undefined),\n\n settings: () =>\n admin.http\n .get<{ data: { values: Record<string, unknown> } }>(`${base}/settings`)\n .then((body) => body.data.values),\n\n saveSettings: (values) =>\n admin.http\n .put<{ data: { values: Record<string, unknown> } }>(`${base}/settings`, { values })\n .then((body) => body.data.values),\n }\n}\n","import type { Messages } from '@webx-ui/module-admin'\n\n/**\n * What this package says, in English — the same keys `webx-ui/module-audit` ships as\n * `lang/en/*.php`, so a key never reaches the screen while the dictionary is on its way. The\n * server's dictionary wins; the check texts and the details arrive translated from the server and\n * are not repeated here.\n */\nexport const auditMessages: Record<string, Messages> = {\n module: {\n title: 'Audit',\n },\n\n page: {\n overview: 'Overview',\n issues: 'Findings',\n settings: 'Settings',\n run: 'Run the audit',\n scope: 'Scope',\n 'scope-full': 'Full',\n 'scope-full-help': 'Everything the audit can check.',\n 'scope-quick': 'Quick',\n 'scope-quick-help': 'The config, the host and the database — takes seconds.',\n start: 'Start',\n started: 'The audit has started.',\n cancel: 'Cancel the run',\n never: 'No audit has been run yet.',\n 'never-help':\n 'Run the first one to see how the site looks to a visitor and to a search engine.',\n health: 'Health',\n errors: 'Errors',\n warnings: 'Warnings',\n notices: 'Notices',\n new: 'New',\n fixed: 'Fixed',\n 'health-pages': 'Pages without errors: :clean of :pages',\n 'health-site': 'Errors of the whole site: :count',\n 'health-warnings': 'Checks with warnings: :count',\n 'health-help':\n 'The share of pages without errors, minus 10 points for each error of the whole site and 2 for each check with warnings — the warnings take 20 at most.',\n 'last-run': 'Last run',\n 'base-url': 'Address',\n 'status-queued': 'Waiting in the queue',\n 'status-running': 'Running',\n 'status-done': 'Done',\n 'status-failed': 'Failed',\n 'status-cancelled': 'Cancelled',\n 'stage-probes': 'Config and host',\n 'stage-database': 'Database',\n 'stage-crawl': 'Pages',\n 'stage-analyse': 'Analysis',\n 'last-failed': 'The last run did not finish: :error',\n 'by-group': 'By group',\n 'group-config': 'Configuration',\n 'group-host': 'Host and addresses',\n 'group-hosts': 'Outgoing addresses',\n 'group-other': 'Other',\n sources: 'Content searched',\n 'sources-missing': 'Installed, but not searched:',\n 'sources-help':\n 'Besides crawling the site, the audit reads the text modules keep in the database — drafts, hidden records and fields the template never prints — and looks there for absolute addresses, such as links to a development stand. Green: modules that hand their text over. Orange: modules installed here that do not yet. Their published pages are still crawled, but their drafts and hidden fields are not searched, and a fix button cannot reach them.',\n 'sources-help-label': 'What this means',\n 'sync-queue':\n 'The queue runs jobs inside the request (sync), so the panel cannot start a run. Run php artisan webx:audit:run from the terminal or cron.',\n 'already-running': 'An audit is already running.',\n check: 'Check',\n count: 'Found',\n severity: 'Severity',\n 'severity-error': 'Error',\n 'severity-warning': 'Warning',\n 'severity-notice': 'Notice',\n 'any-severity': 'Any severity',\n 'any-group': 'Any group',\n 'any-state': 'New and persisting',\n 'state-new': 'New',\n 'state-persisting': 'Persisting',\n address: 'Address',\n empty: 'Nothing found.',\n clean: 'The last run found nothing.',\n found: 'What was found',\n why: 'Why it matters',\n fix: 'How to fix it',\n explain: 'What this check means',\n 'open-editor': 'Open in the editor',\n 'fix-button': 'Fix',\n 'fix-apply': 'Apply',\n 'fix-applied': 'Done. Run the audit again to see the finding go.',\n 'fix-none': 'Nothing left to change: no fix can close this finding now.',\n 'fix-pressed': 'Fixed — waiting for the next run',\n 'fix-changes': 'Changes',\n 'fix-before': 'Now',\n 'fix-after': 'After',\n yes: 'Yes',\n no: 'No',\n missing: 'Missing',\n pages: 'Pages',\n 'pages-progress': 'Pages crawled: :crawled of at most :limit',\n 'resources-progress':\n 'Pictures, styles, scripts and external links checked: :checked of :total',\n 'pages-none': 'No full run has crawled the site yet. Start a full audit to see every page.',\n 'pages-run': 'Full run of :date',\n 'group-indexing': 'Indexing',\n 'group-redirects': 'Redirects',\n 'group-page': 'Page',\n 'group-content': 'Content and speed',\n 'group-links': 'Links',\n 'group-images': 'Pictures',\n 'group-a11y': 'Accessibility',\n 'group-structure': 'Structure',\n columns: 'Columns',\n export: 'Export CSV',\n 'search-url': 'Search by address',\n 'any-status': 'Any answer',\n 'status-none': 'No answer',\n 'any-indexable': 'Indexable or not',\n 'indexable-yes': 'Indexable',\n 'indexable-no': 'Not indexable',\n 'any-check': 'With any findings or none',\n 'add-filter': 'Add a filter',\n 'remove-filter': 'Remove the filter',\n 'op-contains': 'contains',\n 'op-eq': 'is',\n 'op-empty': 'is empty',\n 'op-filled': 'is not empty',\n 'op-gt': 'more than',\n 'op-lt': 'less than',\n 'op-yes': 'yes',\n 'op-no': 'no',\n value: 'Value',\n 'field-url': 'Address',\n 'field-status': 'Code',\n 'field-final_status': 'Final code',\n 'field-redirect_to': 'Redirects to',\n 'field-source': 'Found through',\n 'field-depth': 'Depth',\n 'field-indexable': 'Indexable',\n 'field-issues': 'Findings',\n 'field-title': 'Title',\n 'field-description': 'Description',\n 'field-h1': 'H1',\n 'field-canonical': 'Canonical',\n 'field-robots_meta': 'Meta robots',\n 'field-x_robots_tag': 'X-Robots-Tag',\n 'field-lang': 'Language',\n 'field-content_type': 'Content type',\n 'field-bytes': 'Size, bytes',\n 'field-ttfb_ms': 'First byte, ms',\n 'field-total_ms': 'Answer, ms',\n 'field-compression': 'Compression',\n 'field-word_count': 'Words',\n 'field-links_in': 'Links in',\n 'field-links_out_internal': 'Internal links out',\n 'field-links_out_external': 'External links out',\n 'field-images': 'Pictures',\n 'field-images_without_alt': 'Pictures without alt',\n 'field-in_sitemap': 'In the sitemap',\n 'field-in_registry': 'In the registry',\n 'field-blocked_by_robots': 'Closed in robots.txt',\n 'source-home': 'Home page',\n 'source-sitemap': 'Sitemap',\n 'source-registry': 'Address registry',\n 'source-link': 'Link',\n 'card-overview': 'Overview',\n 'card-issues': 'Problems',\n 'card-incoming': 'Incoming',\n 'card-outgoing': 'Outgoing',\n 'card-images': 'Pictures',\n 'card-css': 'CSS',\n 'card-js': 'JS',\n 'card-microdata': 'Structured data',\n 'card-headings': 'Headings',\n 'no-headings': 'The page has no headings.',\n 'headings-recheck': 'The list of headings appears once the page is checked again.',\n 'heading-empty': 'Empty heading',\n 'headings-hints': 'Not the usual order',\n 'headings-fine':\n 'The headings go in the usual order: one H1 first, each level one step below the one above.',\n 'headings-no-h1':\n 'There is no H1. A page needs one main heading — search engines and screen readers start from it.',\n 'headings-many-h1': 'More than one H1 — keep one, make the rest H2. H1 headings: :count',\n 'headings-h1-not-first':\n 'The page starts with :level, not H1: the main heading should come before the rest.',\n 'headings-skipped':\n 'Levels are skipped — go down one step at a time: after H2 comes H3, not H4. Places: :count',\n 'headings-empty':\n 'Headings with no text — fill them in or make them ordinary text. Empty: :count',\n 'heading-missing': ':level is missing after :after',\n 'headings-summary-ok': 'In order, headings: :count',\n 'headings-summary-bad': 'Out of order, headings: :count',\n 'headings-open': 'Open the map',\n response: 'Response',\n headers: 'Headers',\n markup: 'Markup',\n 'open-page': 'Open the page',\n 'no-issues': 'No problems on this page.',\n 'no-links': 'No links.',\n kind: 'Kind',\n anchor: 'Anchor',\n host: 'Host',\n size: 'Size',\n cache: 'Cache',\n alt: 'Alt',\n 'not-checked': 'Not checked',\n 'no-resources': 'Nothing of this kind on the page.',\n 'no-json-ld': 'The page has no structured data.',\n 'jsonld-block': 'Block :number',\n 'jsonld-error': 'Does not parse:',\n 'jsonld-required': 'Required fields missing:',\n 'jsonld-recommended': 'Recommended fields missing:',\n 'jsonld-complete': 'Every field search engines ask for is there.',\n 'host-own': 'Own',\n 'host-own_mirror': 'Other mirror',\n 'host-dev': 'Stand',\n 'host-external': 'External',\n error: 'Error',\n 'source-list': 'Recheck list',\n hosts: 'Outgoing',\n runs: 'Runs',\n 'scope-urls': 'Recheck',\n 'urls-foreign': 'None of these addresses is on the audited site.',\n 'state-hidden': 'Hidden',\n hide: 'Hide',\n 'hide-title': 'Hide this finding',\n 'hide-help':\n 'Hidden findings stop counting, in this run and in every later one. Nothing is deleted: the hidden list shows them again.',\n 'hide-pattern': 'Addresses',\n 'hide-pattern-help':\n 'This address, or a mask of them: * is a stretch without a slash, ** one with slashes (/search/**). Empty hides every finding of the check.',\n 'hide-reason': 'Why it is all right',\n 'hide-count': 'Findings of the last run it would hide: :count',\n 'hidden-done': 'Hidden.',\n 'hidden-reason': 'Hidden: :reason',\n 'hidden-by': 'Hidden by :who: :reason',\n unhide: 'Show again',\n unhidden: 'Shown again.',\n recheck: 'Recheck',\n 'recheck-running': 'Rechecking the page…',\n 'recheck-fixed': 'Fixed since the last full run: :count',\n 'recheck-new': 'New since the last full run: :count',\n 'recheck-compare': 'Compare the runs',\n 'export-page': 'Export',\n 'runs-empty': 'No runs yet.',\n 'run-id': 'Run',\n status: 'Status',\n 'started-at': 'Started',\n 'started-by': 'Started by',\n 'by-schedule': 'Schedule',\n 'by-mcp': 'Agent',\n 'by-console': 'Console',\n 'by-person': 'Administrator',\n compare: 'Compare',\n 'compare-help':\n 'Pick two runs: what the later one found that the earlier did not, what both found, and what is gone.',\n clear: 'Clear audit data',\n 'clear-title': 'Clear all audit data?',\n 'clear-text':\n 'Every run is deleted with everything it found: findings, crawled pages, snapshots, links and the history to compare against. This cannot be undone. Hiding rules and settings stay.',\n 'clear-confirm': 'Delete everything',\n 'clear-cancel': 'Keep',\n cleared: 'Audit data cleared.',\n 'clear-running': 'An audit is running: cancel it or wait for it to finish, then clear.',\n 'compare-from': 'Earlier run',\n 'compare-to': 'Later run',\n 'compare-none': 'Both runs found the same.',\n 'compare-scopes':\n 'The runs differ in scope: only the checks the later run ran can count as fixed.',\n 'kind-new': 'New',\n 'kind-persisting': 'Persisting',\n 'kind-fixed': 'Fixed',\n 'hosts-empty': 'No run has seen a link or an address in the database yet.',\n 'search-host': 'Search by host',\n 'any-class': 'Any class',\n links: 'Links',\n fields: 'Fields in the database',\n broken: 'Broken',\n 'first-seen': 'First seen',\n 'host-pages': 'On pages',\n 'host-fields': 'In the database',\n record: 'Record',\n field: 'Field',\n unpublished: 'Not published',\n save: 'Save',\n saved: 'Saved.',\n dismiss: 'Cancel',\n 'view-full': 'View full size',\n 'view-pages': 'By page',\n 'view-links': 'By link',\n 'leads-to': 'Leads to',\n 'change-slash': 'Slash only',\n 'change-www': 'www',\n 'change-https': 'http → https',\n 'link-pages': 'Pages: :count',\n 'link-show-all': 'Show all',\n 'link-collapse': 'Collapse',\n 'attrs-opener':\n 'Opens in a new tab without noopener. Current browsers add it themselves; older ones let the opened page control this one.',\n 'section-answer': 'Server answer',\n 'section-crawl': 'Crawl',\n 'section-head': 'Markup',\n 'section-sharing': 'Preview and structured data',\n 'code-none':\n 'No answer — the server did not respond in time or the connection failed (DNS, certificate, refused). Open the address in a browser.',\n 'code-200': '200 OK — the page opens normally.',\n 'code-201': '201 Created — the server created something; a link should not lead here.',\n 'code-204': '204 No Content — answered, but with an empty page.',\n 'code-206': '206 Partial Content — a part of the file was sent, as video and downloads do.',\n 'code-301':\n '301 Moved Permanently — the address has moved for good. Update the link to where it leads.',\n 'code-302':\n '302 Found — a temporary redirect. The target may change again; search engines keep the old address.',\n 'code-303':\n '303 See Other — sent elsewhere after a form or an action; a link should point at the result.',\n 'code-304': \"304 Not Modified — the browser's copy is still current.\",\n 'code-307': '307 Temporary Redirect — like 302: temporary, the old address stays the main one.',\n 'code-308': '308 Permanent Redirect — like 301: moved for good. Update the link.',\n 'code-400':\n '400 Bad Request — the server did not understand the request; often a broken address.',\n 'code-401': '401 Unauthorized — sign-in needed. Visitors without an account cannot open it.',\n 'code-403':\n '403 Forbidden — the server refused. Many sites answer robots this way: if it opens in a browser, the link is fine.',\n 'code-404': '404 Not Found — the page is gone. Fix or remove the link.',\n 'code-405':\n '405 Method Not Allowed — the address exists but does not answer this kind of request.',\n 'code-406':\n '406 Not Acceptable — the server would not answer in a form the robot asked for; check in a browser.',\n 'code-408': '408 Request Timeout — the server gave up waiting. Usually passes; recheck later.',\n 'code-410': '410 Gone — removed on purpose and not coming back. Remove the link.',\n 'code-415': '415 Unsupported Media Type — the server refused the format of the request.',\n 'code-429':\n '429 Too Many Requests — the server asked the robot to slow down. Not a broken page.',\n 'code-451': \"451 Unavailable For Legal Reasons — blocked by law in the server's region.\",\n 'code-500':\n '500 Internal Server Error — the site behind the link broke. Recheck later; if it stays, the link is dead.',\n 'code-502': '502 Bad Gateway — the server behind a proxy did not answer. Usually temporary.',\n 'code-503': '503 Service Unavailable — overloaded or under maintenance. Usually temporary.',\n 'code-504':\n '504 Gateway Timeout — the server behind a proxy answered too slowly. Usually temporary.',\n 'code-1xx': 'An interim answer — the request is still being handled.',\n 'code-2xx': 'A success — the address answered.',\n 'code-3xx':\n 'A redirect — the address sends elsewhere. Better to link straight to where it leads.',\n 'code-4xx':\n 'A client error — the address cannot be opened as it is: missing, closed or refused.',\n 'code-5xx': 'A server error — the site behind the link failed. Often temporary; recheck later.',\n },\n}\n","import type { BadgeType } from '@webx-ui/core'\n\n/** What tells a redirect's target from its source when the rest of the address is the same. */\nexport type AddressDifference = 'slash' | 'www' | 'https'\n\n/**\n * The small differences between where a link points and where it lands: a trailing slash, `www.`,\n * `http` → `https`. Empty when the addresses differ in anything else (the page really moved) or\n * either is not an address — then there is nothing small to name.\n */\nexport function differences(from: string, to: string): AddressDifference[] {\n let source: URL\n let target: URL\n\n try {\n source = new URL(from)\n target = new URL(to, from)\n } catch {\n return []\n }\n\n const found: AddressDifference[] = []\n\n if (source.protocol === 'http:' && target.protocol === 'https:') found.push('https')\n else if (source.protocol !== target.protocol) return []\n\n const bare = (host: string) => host.replace(/^www\\./, '')\n\n if (source.host !== target.host) {\n if (bare(source.host) !== bare(target.host)) return []\n found.push('www')\n }\n\n const trimmed = (path: string) => path.replace(/\\/+$/, '')\n\n if (source.pathname !== target.pathname) {\n if (trimmed(source.pathname) !== trimmed(target.pathname)) return []\n found.push('slash')\n }\n\n if (source.search !== target.search || source.hash !== target.hash) return []\n\n return found\n}\n\n/** How many characters stay at the end of a shortened address: where a slug or a slash differs. */\nconst TAIL = 14\n\n/**\n * An address cut in two for an ellipsis in the middle: the head gives way, the tail stays —\n * the end of an address is what tells two of them apart.\n */\nexport function splitMiddle(text: string): [string, string] {\n if (text.length <= TAIL * 2) return [text, '']\n\n return [text.slice(0, -TAIL), text.slice(-TAIL)]\n}\n\n/** The colour of an answer's code. */\nexport function statusType(value: unknown): BadgeType {\n const code = Number(value)\n\n if (code >= 500 || code === 0) return 'danger'\n if (code >= 400) return 'warning'\n // A permanent redirect only asks for the link to be updated; a temporary one may move again.\n if (code === 301 || code === 308) return 'info'\n if (code >= 300) return 'warning'\n\n return 'success'\n}\n\n/** The codes with a line of their own in the dictionary; the rest are explained by their class. */\nconst EXPLAINED = [\n 200, 201, 204, 206, 301, 302, 303, 304, 307, 308, 400, 401, 403, 404, 405, 406, 408, 410, 415,\n 429, 451, 500, 502, 503, 504,\n]\n\n/** The dictionary key of what an answer means: `code-404`, `code-5xx`, or `code-none`. */\nexport function statusKey(code: number | null | undefined): string {\n if (!code) return 'code-none'\n if (EXPLAINED.includes(code)) return `code-${code}`\n if (code >= 100 && code < 600) return `code-${Math.floor(code / 100)}xx`\n\n return 'code-none'\n}\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { WxLink, WxTooltip, type LinkType } from '@webx-ui/core'\nimport { splitMiddle } from './addresses'\n\n/**\n * An address on one line, opened in a new tab: a long one loses its middle rather than wrapping,\n * since the start names the site and the end tells two addresses apart. The whole of it is in the\n * panel's tooltip.\n */\nconst props = defineProps<{ href: string; type?: LinkType; strong?: boolean }>()\n\nconst parts = computed(() => splitMiddle(props.href))\n</script>\n\n<template>\n <wx-tooltip :max-width=\"560\">\n <wx-link\n :href=\"props.href\"\n target=\"_blank\"\n :type=\"props.type\"\n :weight=\"props.strong ? 'medium' : undefined\"\n class=\"wx-audit-address\"\n ><span class=\"wx-audit-address__head\">{{ parts[0] }}</span\n ><span v-if=\"parts[1]\" class=\"wx-audit-address__tail\">{{ parts[1] }}</span></wx-link\n >\n <template #content>\n <span class=\"wx-audit-address__full\">{{ props.href }}</span>\n </template>\n </wx-tooltip>\n</template>\n\n<style scoped>\n.wx-audit-address {\n display: flex;\n gap: 0;\n min-width: 0;\n max-width: 100%;\n white-space: nowrap;\n}\n\n.wx-audit-address__head {\n overflow: hidden;\n text-overflow: ellipsis;\n min-width: 0;\n}\n\n.wx-audit-address__tail {\n flex-shrink: 0;\n}\n\n/* The tip is teleported out of this component, and an address has no spaces to wrap at. */\n:global(.wx-audit-address__full) {\n overflow-wrap: anywhere;\n}\n</style>\n","import { useAdmin } from '@webx-ui/module-admin'\nimport { auditMessages } from './messages'\n\nconst seeded = new WeakSet<object>()\n\n/** Puts this package's English under the panel's dictionary, once per panel. */\nexport function useAuditMessages(): void {\n try {\n const { i18n } = useAdmin()\n\n if (!seeded.has(i18n)) {\n i18n.defaults('webx-audit', auditMessages)\n seeded.add(i18n)\n }\n } catch {\n // Outside a panel there is no dictionary to seed, and `useTranslate` falls back on its own.\n }\n}\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useTranslate } from '@webx-ui/module-admin'\nimport { WxBadge, WxTooltip } from '@webx-ui/core'\nimport { useAuditMessages } from './i18n'\n\n/**\n * A link's `target` and `rel`, as they are in the markup: `_blank`, `nofollow`, `noopener`… Nothing\n * when the link has neither — a plain link is the usual case, not an empty cell. `_blank` without\n * `noopener` or `noreferrer` is marked: current browsers add `noopener` themselves, older ones\n * hand the opened page control of this one.\n */\nconst props = defineProps<{ rel?: string | null; target?: string | null }>()\n\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\n\nconst rels = computed(() => (props.rel ?? '').split(/\\s+/).filter(Boolean))\n\nconst opener = computed(\n () =>\n props.target?.toLowerCase() === '_blank' &&\n !rels.value.some((rel) => rel === 'noopener' || rel === 'noreferrer'),\n)\n</script>\n\n<template>\n <span v-if=\"props.target || rels.length\" class=\"wx-audit-attrs\">\n <wx-tooltip v-if=\"props.target && opener\" :content=\"t('page.attrs-opener')\" :max-width=\"320\">\n <wx-badge type=\"warning\" variant=\"outline\" size=\"sm\">{{ props.target }}</wx-badge>\n </wx-tooltip>\n <wx-badge v-else-if=\"props.target\" variant=\"outline\" size=\"sm\">{{ props.target }}</wx-badge>\n <wx-badge v-for=\"value in rels\" :key=\"value\" variant=\"outline\" size=\"sm\">{{ value }}</wx-badge>\n </span>\n</template>\n\n<style scoped>\n.wx-audit-attrs {\n display: inline-flex;\n flex-wrap: wrap;\n gap: var(--wx-space-4);\n min-width: 0;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useTranslate } from '@webx-ui/module-admin'\nimport { WxBadge, WxTooltip, type BadgeSize } from '@webx-ui/core'\nimport { statusKey, statusType } from './addresses'\nimport { useAuditMessages } from './i18n'\n\n/**\n * An answer's code as a badge of its colour, and what it means in the tooltip: the name and what\n * to do about it. A code with no line of its own is explained by its class (4xx…); none at all, or\n * 0, is «no answer».\n */\nconst props = withDefaults(defineProps<{ code: number | null | undefined; size?: BadgeSize }>(), {\n size: 'sm',\n})\n\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\n\nconst label = computed(() => (props.code ? String(props.code) : t('page.status-none')))\n</script>\n\n<template>\n <wx-tooltip :content=\"t(`page.${statusKey(props.code)}`)\" :max-width=\"360\">\n <wx-badge :type=\"statusType(props.code ?? 0)\" :size=\"props.size\">{{ label }}</wx-badge>\n </wx-tooltip>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useRouter } from 'vue-router'\nimport { useTranslate } from '@webx-ui/module-admin'\nimport { WxBadge, WxButton, WxIcon, WxText } from '@webx-ui/core'\nimport AuditAddress from './AuditAddress.vue'\nimport AuditLinkAttrs from './AuditLinkAttrs.vue'\nimport { differences } from './addresses'\nimport AuditStatus from './AuditStatus.vue'\nimport { useAuditMessages } from './i18n'\nimport type { AuditDetails, AuditDetailsColumn } from './types'\n\n/**\n * The expansion of a finding, for every check alike (§4 of the spec): a summary line and, when\n * the check gave one, a table whose cells are drawn by their type — an address opens, a code is\n * coloured, a missing value is said in red, an editor link goes to the record in the panel, and\n * markup quoted from the page is shown as code.\n *\n * The columns have widths by their type, not by what they hold, so the tables of one check line\n * up under each other. A `location` address beside a `url` is where that address leads: the row\n * reads as from → to, and a difference of a slash, `www.` or `https` is named.\n */\nconst props = defineProps<{\n details: AuditDetails\n /** The count is shown elsewhere (the head of the finding) — the summary line would repeat it. */\n counted?: boolean\n}>()\n\nconst router = useRouter()\n\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\n\nconst columns = computed(() => props.details.table?.columns ?? [])\n\nconst redirects = computed(\n () =>\n columns.value.some((column) => column.key === 'url' && column.type === 'url') &&\n columns.value.some((column) => column.key === 'location' && column.type === 'url'),\n)\n\nfunction isSource(column: AuditDetailsColumn): boolean {\n return redirects.value && column.key === 'url'\n}\n\nfunction isTarget(column: AuditDetailsColumn): boolean {\n return redirects.value && column.key === 'location'\n}\n\nfunction cell(row: Record<string, unknown>, column: AuditDetailsColumn): unknown {\n return row[column.key]\n}\n\n/** Yes, no — or nothing, when the check could not tell (the other page was not crawled). */\nfunction yesNo(value: unknown): string {\n if (value === null || value === undefined) return ''\n\n return value ? t('page.yes') : t('page.no')\n}\n\nfunction text(value: unknown): string {\n return value === null || value === undefined ? '' : String(value)\n}\n\nfunction changes(row: Record<string, unknown>) {\n return differences(text(row.url), text(row.location))\n}\n</script>\n\n<template>\n <div class=\"wx-audit-details\">\n <wx-text v-if=\"props.details.summary && !props.counted\" size=\"sm\">{{\n props.details.summary\n }}</wx-text>\n\n <div\n v-if=\"props.details.table && props.details.table.rows.length\"\n class=\"wx-audit-details__scroll\"\n >\n <table class=\"wx-audit-details__table\">\n <colgroup>\n <col\n v-for=\"column in columns\"\n :key=\"column.key\"\n :class=\"[\n `wx-audit-details__col--${column.type}`,\n `wx-audit-details__col--${column.key}`,\n ]\"\n />\n </colgroup>\n <thead>\n <tr>\n <th v-for=\"column in columns\" :key=\"column.key\">\n {{ column.label }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr v-for=\"(row, index) in props.details.table.rows\" :key=\"index\">\n <td v-for=\"column in columns\" :key=\"column.key\">\n <span v-if=\"isTarget(column) && text(cell(row, column))\" class=\"wx-audit-details__to\">\n <wx-icon\n name=\"arrow-right\"\n size=\"1em\"\n class=\"wx-audit-details__arrow\"\n :label=\"t('page.leads-to')\"\n />\n <audit-address :href=\"text(cell(row, column))\" strong />\n <wx-badge\n v-for=\"change in changes(row)\"\n :key=\"change\"\n type=\"default\"\n size=\"sm\"\n class=\"wx-audit-details__change\"\n >{{ t(`page.change-${change}`) }}</wx-badge\n >\n </span>\n <audit-address\n v-else-if=\"column.type === 'url' && text(cell(row, column))\"\n :href=\"text(cell(row, column))\"\n :type=\"isSource(column) ? 'muted' : undefined\"\n />\n <audit-status\n v-else-if=\"column.type === 'status' && cell(row, column) !== null\"\n :code=\"Number(cell(row, column))\"\n />\n <audit-link-attrs\n v-else-if=\"column.type === 'attrs'\"\n :rel=\"text(row.rel)\"\n :target=\"text(row.target)\"\n />\n <template v-else-if=\"column.type === 'bool'\">\n {{ yesNo(cell(row, column)) }}\n </template>\n <wx-text\n v-else-if=\"column.type === 'missing' && !text(cell(row, column))\"\n size=\"sm\"\n tone=\"danger\"\n >{{ t('page.missing') }}</wx-text\n >\n <wx-button\n v-else-if=\"column.type === 'edit' && text(cell(row, column))\"\n size=\"sm\"\n variant=\"text\"\n icon=\"edit\"\n @click=\"router.push(text(cell(row, column)))\"\n >{{ t('page.open-editor') }}</wx-button\n >\n <code v-else-if=\"column.type === 'code'\" class=\"wx-audit-details__code\">{{\n text(cell(row, column))\n }}</code>\n <template v-else>{{ text(cell(row, column)) }}</template>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</template>\n\n<style scoped>\n.wx-audit-details {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n/* A wide table scrolls inside itself rather than pushing the panel sideways on a phone. */\n.wx-audit-details__scroll {\n overflow-x: auto;\n}\n\n/*\n * Fixed layout: a column's width comes from its type, never from its longest cell, so every\n * finding of a check draws the same grid.\n */\n.wx-audit-details__table {\n width: 100%;\n min-width: 560px;\n table-layout: fixed;\n border-collapse: collapse;\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-details__col--status {\n width: 72px;\n}\n\n.wx-audit-details__col--bool {\n width: 96px;\n}\n\n.wx-audit-details__col--attrs {\n width: 216px;\n}\n\n/* Columns whose values are short by nature — a kind, a size, a type — by their key. */\n.wx-audit-details__col--kind,\n.wx-audit-details__col--line {\n width: 72px;\n}\n\n.wx-audit-details__col--kb,\n.wx-audit-details__col--lang,\n.wx-audit-details__col--locale {\n width: 96px;\n}\n\n.wx-audit-details__col--type {\n width: 140px;\n}\n\n.wx-audit-details__col--edit {\n width: 160px;\n}\n\n.wx-audit-details__table th {\n color: var(--wx-text-muted);\n font-weight: normal;\n text-align: left;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.wx-audit-details__table th,\n.wx-audit-details__table td {\n padding: var(--wx-space-6) var(--wx-space-8);\n border-bottom: 1px solid var(--wx-border-muted);\n vertical-align: middle;\n overflow-wrap: anywhere;\n}\n\n.wx-audit-details__table tbody tr:last-child td {\n border-bottom: 0;\n}\n\n.wx-audit-details__to {\n display: flex;\n align-items: center;\n gap: var(--wx-space-6);\n min-width: 0;\n}\n\n.wx-audit-details__arrow {\n flex-shrink: 0;\n color: var(--wx-text-muted);\n}\n\n.wx-audit-details__change {\n flex-shrink: 0;\n}\n\n/* Quoted markup is one long line more often than not; it wraps anywhere rather than scrolling. */\n.wx-audit-details__code {\n font-family: var(--wx-font-family-mono);\n font-size: var(--wx-font-size-xs);\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n}\n</style>\n","/** One heading as the parser kept it: its level and its text. */\nexport type OutlineEntry = [number, string]\n\n/** A row of the drawn tree — a heading, or a level the page jumped over (`missing`). */\nexport interface OutlineRow {\n level: number\n text: string\n missing: boolean\n /** For a missing level: the level the page jumped from. */\n after?: number\n}\n\n/**\n * The tree to draw: every heading, and between two of them the levels skipped on the way down,\n * so a gap stands where the heading should have been.\n */\nexport function outlineRows(outline: OutlineEntry[]): OutlineRow[] {\n const out: OutlineRow[] = []\n let previous = 0\n\n for (const [level, text] of outline) {\n for (let gap = previous + 1; previous > 0 && gap < level; gap++) {\n out.push({ level: gap, text: '', missing: true, after: previous })\n }\n\n out.push({ level, text, missing: false })\n previous = level\n }\n\n return out\n}\n\n/**\n * What breaks the usual order — one H1, first; each level one step below the one above; text in\n * every heading — as sentences in the reader's language. Empty when the order is fine.\n */\nexport function outlineHints(\n outline: OutlineEntry[],\n t: (key: string, params?: Record<string, string | number>) => string,\n): string[] {\n if (!outline.length) return []\n\n const ones = outline.filter(([level]) => level === 1).length\n const jumps = outline.filter(\n ([level], index) => index > 0 && level > outline[index - 1][0] + 1,\n ).length\n const empty = outline.filter(([, text]) => text === '').length\n const out: string[] = []\n\n if (ones === 0) out.push(t('page.headings-no-h1'))\n if (ones > 1) out.push(t('page.headings-many-h1', { count: ones }))\n if (ones > 0 && outline[0][0] !== 1) {\n out.push(t('page.headings-h1-not-first', { level: `H${outline[0][0]}` }))\n }\n if (jumps > 0) out.push(t('page.headings-skipped', { count: jumps }))\n if (empty > 0) out.push(t('page.headings-empty', { count: empty }))\n\n return out\n}\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useTranslate } from '@webx-ui/module-admin'\nimport { WxAlert, WxBadge, WxText } from '@webx-ui/core'\nimport { outlineHints, outlineRows, type OutlineEntry } from './headings'\nimport { useAuditMessages } from './i18n'\n\n/**\n * The page's headings as a tree: each one indented by its level, in the order the page has them.\n * The indent is the level itself, not the nesting the page managed — so a level the page jumped\n * over is drawn where it should have been, as an empty dashed row, and the gap is seen rather\n * than read about. Above the tree, what departs from the usual order, in plain words.\n */\nconst props = defineProps<{\n /** `[level, text]` in document order; null on a run crawled before the outline was kept. */\n outline: OutlineEntry[] | null\n /** How many headings of each level — to tell «none» from «not kept». */\n counts: Record<string, number>\n}>()\n\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\n\nconst rows = computed(() => outlineRows(props.outline ?? []))\n\nconst hints = computed(() => outlineHints(props.outline ?? [], t))\n\nconst total = computed(() => Object.values(props.counts).reduce((sum, count) => sum + count, 0))\n</script>\n\n<template>\n <div class=\"wx-audit-headings\">\n <wx-text v-if=\"props.outline === null && total > 0\" tone=\"muted\">{{\n t('page.headings-recheck')\n }}</wx-text>\n <wx-text v-else-if=\"!rows.length\" tone=\"muted\">{{ t('page.no-headings') }}</wx-text>\n <template v-else>\n <wx-alert v-if=\"hints.length\" type=\"warning\" variant=\"soft\" :title=\"t('page.headings-hints')\">\n <ul class=\"wx-audit-headings__hints\">\n <li v-for=\"hint in hints\" :key=\"hint\">{{ hint }}</li>\n </ul>\n </wx-alert>\n <wx-alert v-else type=\"success\" variant=\"soft\" :title=\"t('page.headings-fine')\" />\n\n <ol class=\"wx-audit-headings__tree\">\n <li\n v-for=\"(row, index) in rows\"\n :key=\"index\"\n class=\"wx-audit-headings__row\"\n :class=\"{ 'is-missing': row.missing }\"\n >\n <span v-for=\"step in row.level - 1\" :key=\"step\" class=\"wx-audit-headings__guide\" />\n <template v-if=\"row.missing\">\n <span class=\"wx-audit-headings__gap\">H{{ row.level }}</span>\n <wx-text size=\"sm\" tone=\"warning\">{{\n t('page.heading-missing', { level: `H${row.level}`, after: `H${row.after}` })\n }}</wx-text>\n </template>\n <template v-else>\n <wx-badge :type=\"row.level === 1 ? 'primary' : 'info'\" size=\"sm\"\n >H{{ row.level }}</wx-badge\n >\n <span v-if=\"row.text\" class=\"wx-audit-headings__text\">{{ row.text }}</span>\n <wx-text v-else size=\"sm\" tone=\"danger\">{{ t('page.heading-empty') }}</wx-text>\n </template>\n </li>\n </ol>\n </template>\n </div>\n</template>\n\n<style scoped>\n.wx-audit-headings {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n}\n\n.wx-audit-headings__hints {\n margin: 0;\n padding-inline-start: var(--wx-space-18);\n}\n\n.wx-audit-headings__tree {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.wx-audit-headings__row {\n display: flex;\n align-items: center;\n gap: var(--wx-space-8);\n min-height: 32px;\n}\n\n/* One step of depth: a thin line down, so the levels read as columns, like a file tree. */\n.wx-audit-headings__guide {\n align-self: stretch;\n flex: none;\n width: var(--wx-space-16);\n background: linear-gradient(var(--wx-border-default), var(--wx-border-default)) no-repeat\n calc(var(--wx-space-12) + 1px) 0 / 1px 100%;\n}\n\n/* The level that should have been here: the badge's outline, empty, in the warning colour. */\n.wx-audit-headings__gap {\n display: inline-flex;\n align-items: center;\n padding: 0 var(--wx-space-6);\n border: 1px dashed var(--wx-color-warning);\n border-radius: var(--wx-radius-sm);\n color: var(--wx-color-warning);\n font-size: var(--wx-font-size-xs);\n line-height: 18px;\n}\n\n.wx-audit-headings__text {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n</style>\n","import type { AuditResourceRow } from './types'\n\n/**\n * Whether the browser is worth asking for a picture of the page: the run reached it and it\n * answered. One past the run's limit or on the stand was never asked, and one that failed for the\n * run would fail here too — the card keeps the placeholder for those, with nothing to open.\n */\nexport function viewable(row: AuditResourceRow): boolean {\n return row.checked && row.status !== null && row.status < 400 && row.error === null\n}\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, ref, watch } from 'vue'\nimport { useRouter } from 'vue-router'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport {\n toast,\n WxAlert,\n WxBadge,\n WxButton,\n WxDrawer,\n WxIcon,\n WxImage,\n WxLink,\n WxSkeleton,\n WxTable,\n WxTabs,\n WxText,\n WxTooltip,\n type BadgeType,\n type TabItem,\n type TabValue,\n type TableColumn,\n type TableState,\n} from '@webx-ui/core'\nimport AuditDetails from './AuditDetails.vue'\nimport AuditHeadings from './AuditHeadings.vue'\nimport { outlineHints, type OutlineEntry } from './headings'\nimport { createAuditApi } from './api'\nimport { viewable } from './resources'\nimport AuditStatus from './AuditStatus.vue'\nimport { useAuditMessages } from './i18n'\nimport type {\n AuditLinkRow,\n AuditPage,\n AuditPageCard,\n AuditResourceRow,\n AuditResourceTab,\n AuditRun,\n AuditSeverity,\n} from './types'\n\n/**\n * One page of the snapshot, sliding in from the right (§8): what it answered and what its head\n * says, its findings, the links that lead in and out of it — with the answer of each own page\n * and the class of each host — what it loads (pictures, CSS, JS) with what each answered, and\n * its structured data with what the types lack.\n *\n * «Recheck» asks this one address again (a run of the `urls` scope) and says what of its findings\n * in the last full run are fixed; «Export» downloads the page — snapshot, findings and links.\n */\nconst props = defineProps<{\n run: number\n /** Where the section lives — the recheck's comparison opens on its runs. */\n base?: string\n /** The page to show; null keeps the card closed. */\n pageId: number | null\n /** Check ids and their titles in the reader's language, for the findings tab. */\n titles: Record<string, string>\n}>()\n\nconst emit = defineEmits<{ close: [] }>()\n\n/*\n * The card is wide: a page has long addresses, headers and hreflang lists. Its width is kept under\n * a key of its own, so one remembered from the narrow card of before does not keep it narrow.\n */\n\nconst context = useAdmin()\nconst api = createAuditApi(context)\nconst router = useRouter()\nuseAuditMessages()\n\nconst canRun = context.can('audit.run') || context.can('audit.manage')\nconst recheck = ref<AuditRun | null>(null)\nconst rechecking = ref(false)\nlet timer: ReturnType<typeof setTimeout> | undefined\n\nconst POLL_MS = 2000\n\n/* The page in its own words: the run it was crawled in, then one more, of just this address. */\nasync function startRecheck(): Promise<void> {\n if (!card.value) return\n\n rechecking.value = true\n recheck.value = null\n\n try {\n follow(await api.start('urls', [card.value.page.url]))\n } catch (error) {\n rechecking.value = false\n toast.danger(message(error))\n }\n}\n\nfunction follow(run: AuditRun): void {\n clearTimeout(timer)\n\n if (run.status === 'queued' || run.status === 'running') {\n timer = setTimeout(async () => {\n try {\n follow(await api.run(run.id))\n } catch (error) {\n rechecking.value = false\n toast.danger(message(error))\n }\n }, POLL_MS)\n\n return\n }\n\n rechecking.value = false\n recheck.value = run\n}\n\nfunction compareRecheck(): void {\n if (recheck.value && props.base) {\n void router.push({ path: `${props.base}/runs`, query: { to: String(recheck.value.id) } })\n }\n}\n\nonBeforeUnmount(() => clearTimeout(timer))\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\n\nconst card = ref<AuditPageCard | null>(null)\nconst failure = ref<string | null>(null)\nconst tab = ref<TabValue>('overview')\nconst links = ref<AuditPage<AuditLinkRow> | null>(null)\nconst linksLoading = ref(false)\nconst resources = ref<AuditPage<AuditResourceRow> | null>(null)\nconst resourcesLoading = ref(false)\n\nconst resourceTabs: AuditResourceTab[] = ['images', 'css', 'js']\n\nconst open = computed({\n get: () => props.pageId !== null,\n set: (value) => {\n if (!value) emit('close')\n },\n})\n\nconst tabs = computed<TabItem[]>(() => [\n { value: 'overview', label: t('page.card-overview') },\n { value: 'issues', label: t('page.card-issues'), badge: card.value?.counts.issues || undefined },\n {\n value: 'headings',\n label: t('page.card-headings'),\n badge: outline.value?.length || undefined,\n },\n { value: 'in', label: t('page.card-incoming'), badge: card.value?.counts.incoming || undefined },\n { value: 'out', label: t('page.card-outgoing'), badge: card.value?.counts.outgoing || undefined },\n { value: 'images', label: t('page.card-images'), badge: card.value?.counts.images || undefined },\n { value: 'css', label: t('page.card-css'), badge: card.value?.counts.css || undefined },\n { value: 'js', label: t('page.card-js'), badge: card.value?.counts.js || undefined },\n {\n value: 'microdata',\n label: t('page.card-microdata'),\n badge: card.value?.counts.microdata || undefined,\n },\n])\n\n/** Every heading in order; null on a run crawled before the parser kept them. */\nconst outline = computed(() => {\n const kept = card.value?.page.facts.outline\n\n return Array.isArray(kept) ? (kept as OutlineEntry[]) : null\n})\n\nconst resourceTab = computed<AuditResourceTab | null>(() =>\n resourceTabs.includes(tab.value as AuditResourceTab) ? (tab.value as AuditResourceTab) : null,\n)\n\nconst severities: Record<AuditSeverity, BadgeType> = {\n error: 'danger',\n warning: 'warning',\n notice: 'info',\n}\n\nconst hostTypes: Record<string, BadgeType> = {\n own: 'success',\n own_mirror: 'warning',\n dev: 'danger',\n external: 'info',\n}\n\nconst linkColumns = computed<TableColumn<AuditLinkRow>[]>(() => [\n { key: 'url', label: t('page.address'), minWidth: 220 },\n { key: 'status', label: t('page.field-status'), width: 80 },\n { key: 'kind', label: t('page.kind'), width: 90 },\n { key: 'anchor', label: t('page.anchor'), minWidth: 140 },\n { key: 'host_class', label: t('page.host'), width: 120 },\n])\n\n/** Pictures show their alt; stylesheets and scripts how they are cached and compressed. */\nconst resourceColumns = computed<TableColumn<AuditResourceRow>[]>(() => [\n { key: 'url', label: t('page.address'), minWidth: 220 },\n { key: 'status', label: t('page.field-status'), width: 80 },\n { key: 'bytes', label: t('page.size'), width: 110 },\n ...(resourceTab.value === 'images'\n ? [{ key: 'alt', label: t('page.alt'), minWidth: 120 }]\n : [\n { key: 'cache_control', label: t('page.cache'), minWidth: 120 },\n { key: 'compression', label: t('page.field-compression'), width: 100 },\n ]),\n])\n\n/*\n * The block indented, the way a person reads JSON. One the server cut at its length limit does not\n * parse, and is shown as the page printed it rather than not at all.\n */\nfunction pretty(source: string): string {\n try {\n return JSON.stringify(JSON.parse(source), null, 2)\n } catch {\n return source\n }\n}\n\nfunction size(row: AuditResourceRow): string {\n if (row.bytes === null) return ''\n\n const kb = row.bytes / 1024\n const text = kb >= 1024 ? `${(kb / 1024).toFixed(1)} MB` : `${Math.round(kb)} KB`\n\n return row.width && row.height ? `${text} · ${row.width}×${row.height}` : text\n}\n\n/*\n * A fact is a line, or a list: hreflang and Open Graph are key and value per row, the key set apart\n * so the eye does not run it into the value after it; JSON-LD is the types as tags.\n */\ntype Fact =\n | string\n | { pairs: [string, string][] }\n | { tags: string[]; error?: string | null }\n | { headings: number; hints: string[] }\n\n/** The numbers of the page, read at a glance before the details: one tile each. */\ninterface Tile {\n label: string\n value: string\n /** The answer's code is drawn as a badge of its colour. */\n status?: number | null\n danger?: boolean\n}\n\nfunction bytes(value: number): string {\n const kb = value / 1024\n\n return kb >= 1024 ? `${(kb / 1024).toFixed(1)} MB` : `${kb.toFixed(1)} KB`\n}\n\nconst tiles = computed<Tile[]>(() => {\n const page = card.value?.page\n\n if (!page) return []\n\n const all: (Tile | null)[] = [\n {\n label: t('page.field-status'),\n value: String(page.status ?? t('page.status-none')),\n status: page.status,\n },\n page.bytes === null ? null : { label: t('page.size'), value: bytes(page.bytes) },\n page.ttfb_ms === null ? null : { label: t('page.field-ttfb_ms'), value: String(page.ttfb_ms) },\n page.total_ms === null\n ? null\n : { label: t('page.field-total_ms'), value: String(page.total_ms) },\n page.word_count === null\n ? null\n : { label: t('page.field-word_count'), value: String(page.word_count) },\n { label: t('page.field-links_in'), value: String(page.links_in) },\n { label: t('page.field-links_out_internal'), value: String(page.links_out_internal) },\n { label: t('page.field-links_out_external'), value: String(page.links_out_external) },\n { label: t('page.field-images'), value: String(page.images) },\n page.images_without_alt\n ? {\n label: t('page.field-images_without_alt'),\n value: String(page.images_without_alt),\n danger: true,\n }\n : null,\n ]\n\n return all.filter((tile): tile is Tile => tile !== null)\n})\n\n/** The rest of what the page answered and says in its head, in sections a reader looks for. */\nconst sections = computed<{ title: string; facts: [string, Fact][] }[]>(() => {\n const page = card.value?.page\n\n if (!page) return []\n\n const groups: [string, [string, unknown][]][] = [\n [\n t('page.section-answer'),\n [\n [t('page.field-final_status'), page.redirect_to ? page.final_status : null],\n [t('page.field-redirect_to'), page.redirect_to],\n [t('page.error'), page.error],\n [t('page.field-content_type'), page.content_type],\n [t('page.field-compression'), page.compression],\n ],\n ],\n [\n t('page.section-crawl'),\n [\n [t('page.field-source'), t(`page.source-${page.source}`)],\n [t('page.field-depth'), page.depth],\n [t('page.field-indexable'), page.indexable ? t('page.yes') : t('page.no')],\n [t('page.field-blocked_by_robots'), page.blocked_by_robots ? t('page.yes') : null],\n ],\n ],\n [\n t('page.section-head'),\n [\n [t('page.field-title'), page.title],\n [t('page.field-description'), page.description],\n [t('page.field-h1'), page.h1.join(' · ') || null],\n [\n t('page.card-headings'),\n outline.value?.length\n ? { headings: outline.value.length, hints: outlineHints(outline.value, t) }\n : null,\n ],\n [t('page.field-canonical'), page.canonical],\n [t('page.field-robots_meta'), page.robots_meta],\n [t('page.field-x_robots_tag'), page.x_robots_tag],\n [t('page.field-lang'), page.lang],\n [\n 'hreflang',\n page.hreflang.length\n ? { pairs: page.hreflang.map((alternate) => [alternate.lang, alternate.url]) }\n : null,\n ],\n ],\n ],\n [\n t('page.section-sharing'),\n [\n [\n 'Open Graph',\n Object.keys(page.og).length\n ? {\n pairs: Object.entries(page.og).map(([key, value]) => [`og:${key}`, String(value)]),\n }\n : null,\n ],\n [\n 'Twitter',\n Object.keys(page.twitter).length\n ? {\n pairs: Object.entries(page.twitter).map(([key, value]) => [\n `twitter:${key}`,\n String(value),\n ]),\n }\n : null,\n ],\n [\n 'JSON-LD',\n page.json_ld.length\n ? {\n tags: page.json_ld.flatMap((block) => block.types),\n error: page.json_ld.find((block) => block.error)?.error ?? null,\n }\n : null,\n ],\n ],\n ],\n ]\n\n return groups\n .map(([title, rows]) => ({\n title,\n facts: rows\n .filter(([, value]) => value !== null && value !== undefined && value !== '')\n .map(\n ([label, value]) =>\n [label, typeof value === 'object' ? (value as Fact) : String(value)] as [string, Fact],\n ),\n }))\n .filter((section) => section.facts.length)\n})\n\nasync function load(id: number): Promise<void> {\n clearTimeout(timer)\n rechecking.value = false\n recheck.value = null\n card.value = null\n failure.value = null\n links.value = null\n resources.value = null\n tab.value = 'overview'\n\n try {\n card.value = await api.page(props.run, id)\n } catch (error) {\n failure.value = message(error)\n }\n}\n\nasync function loadLinks(state: TableState): Promise<void> {\n if (props.pageId === null || (tab.value !== 'in' && tab.value !== 'out')) return\n\n linksLoading.value = true\n\n try {\n links.value = await api.links(props.run, props.pageId, {\n direction: tab.value,\n page: state.page,\n per_page: state.perPage,\n })\n } catch (error) {\n failure.value = message(error)\n } finally {\n linksLoading.value = false\n }\n}\n\nasync function loadResources(state: TableState): Promise<void> {\n const current = resourceTab.value\n\n if (props.pageId === null || current === null) return\n\n resourcesLoading.value = true\n\n try {\n resources.value = await api.resources(props.run, props.pageId, {\n tab: current,\n page: state.page,\n per_page: state.perPage,\n })\n } catch (error) {\n failure.value = message(error)\n } finally {\n resourcesLoading.value = false\n }\n}\n\nwatch(\n () => props.pageId,\n (id) => {\n if (id !== null) void load(id)\n },\n { immediate: true },\n)\n\nwatch(tab, () => {\n links.value = null\n resources.value = null\n})\n</script>\n\n<template>\n <wx-drawer\n v-model:open=\"open\"\n size=\"min(1100px, 75vw)\"\n :min-size=\"480\"\n resizable\n persist=\"webx-audit.page-card-wide\"\n >\n <template #title>\n <span class=\"wx-audit-card__title\">\n <audit-status v-if=\"card\" :code=\"card.page.status\" />\n <span class=\"wx-audit-card__url\">{{ card?.page.url ?? '' }}</span>\n </span>\n </template>\n\n <template #extra>\n <span v-if=\"card\" class=\"wx-audit-card__extra\">\n <wx-button\n v-if=\"canRun\"\n size=\"sm\"\n icon=\"refresh\"\n :loading=\"rechecking\"\n @click=\"startRecheck\"\n >{{ t('page.recheck') }}</wx-button\n >\n <wx-button\n size=\"sm\"\n variant=\"text\"\n icon=\"download\"\n :href=\"api.pageFile(props.run, card.page.id)\"\n >{{ t('page.export-page') }}</wx-button\n >\n <wx-link :href=\"card.page.url\" target=\"_blank\">{{ t('page.open-page') }}</wx-link>\n </span>\n </template>\n\n <wx-text v-if=\"failure\" tone=\"danger\">{{ failure }}</wx-text>\n <wx-skeleton v-else-if=\"!card\" :rows=\"6\" />\n\n <div v-else class=\"wx-audit-card\">\n <wx-alert v-if=\"rechecking\" type=\"info\" :description=\"t('page.recheck-running')\" />\n <wx-alert\n v-else-if=\"recheck && recheck.status === 'done' && recheck.counts\"\n :type=\"recheck.counts.new > 0 ? 'warning' : 'success'\"\n >\n <div class=\"wx-audit-card__recheck\">\n <span>{{ t('page.recheck-fixed', { count: recheck.counts.fixed }) }}</span>\n <span>{{ t('page.recheck-new', { count: recheck.counts.new }) }}</span>\n <wx-button v-if=\"props.base\" size=\"sm\" variant=\"text\" @click=\"compareRecheck\">{{\n t('page.recheck-compare')\n }}</wx-button>\n </div>\n </wx-alert>\n <wx-alert\n v-else-if=\"recheck\"\n type=\"danger\"\n :description=\"recheck.error ?? t(`page.status-${recheck.status}`)\"\n />\n <wx-text v-if=\"card.page.title\" weight=\"semibold\">{{ card.page.title }}</wx-text>\n\n <wx-tabs v-model=\"tab\" :items=\"tabs\">\n <div v-if=\"tab === 'overview'\" class=\"wx-audit-card__overview\">\n <div class=\"wx-audit-card__tiles\">\n <div v-for=\"tile in tiles\" :key=\"tile.label\" class=\"wx-audit-card__tile\">\n <wx-text size=\"sm\" tone=\"muted\">{{ tile.label }}</wx-text>\n <audit-status v-if=\"tile.status !== undefined\" :code=\"tile.status\" size=\"md\" />\n <wx-text\n v-else\n weight=\"semibold\"\n :tone=\"tile.danger ? 'danger' : undefined\"\n class=\"wx-audit-card__number\"\n >{{ tile.value }}</wx-text\n >\n </div>\n </div>\n\n <section v-for=\"section in sections\" :key=\"section.title\" class=\"wx-audit-card__box\">\n <div class=\"wx-audit-card__box-head\">{{ section.title }}</div>\n <dl class=\"wx-audit-card__facts\">\n <template v-for=\"[label, value] in section.facts\" :key=\"label\">\n <dt>{{ label }}</dt>\n <dd v-if=\"typeof value === 'string'\">{{ value }}</dd>\n <dd v-else-if=\"'pairs' in value\" class=\"wx-audit-card__pairs\">\n <template v-for=\"([key, text], index) in value.pairs\" :key=\"index\">\n <code class=\"wx-audit-card__key\">{{ key }}</code>\n <span>{{ text }}</span>\n </template>\n </dd>\n <dd v-else-if=\"'headings' in value\" class=\"wx-audit-card__heading-fact\">\n <span>\n <wx-text :tone=\"value.hints.length ? 'warning' : 'success'\">{{\n value.hints.length\n ? t('page.headings-summary-bad', { count: value.headings })\n : t('page.headings-summary-ok', { count: value.headings })\n }}</wx-text>\n <wx-link\n as=\"button\"\n class=\"wx-audit-card__heading-open\"\n @click=\"tab = 'headings'\"\n >{{ t('page.headings-open') }}</wx-link\n >\n </span>\n <ul v-if=\"value.hints.length\" class=\"wx-audit-card__heading-hints\">\n <li v-for=\"hint in value.hints\" :key=\"hint\">{{ hint }}</li>\n </ul>\n </dd>\n <dd v-else class=\"wx-audit-card__tags\">\n <wx-badge v-for=\"(tag, index) in value.tags\" :key=\"index\" type=\"info\" size=\"sm\">{{\n tag\n }}</wx-badge>\n <wx-text v-if=\"value.error\" size=\"sm\" tone=\"danger\">{{ value.error }}</wx-text>\n </dd>\n </template>\n </dl>\n </section>\n\n <section v-if=\"Object.keys(card.page.headers).length\" class=\"wx-audit-card__box\">\n <div class=\"wx-audit-card__box-head\">{{ t('page.headers') }}</div>\n <dl class=\"wx-audit-card__facts\">\n <template v-for=\"(value, name) in card.page.headers\" :key=\"name\">\n <dt class=\"wx-audit-card__code\">{{ name }}</dt>\n <dd class=\"wx-audit-card__code\">{{ value }}</dd>\n </template>\n </dl>\n </section>\n </div>\n\n <div v-else-if=\"tab === 'headings'\" class=\"wx-audit-card__box wx-audit-card__headings\">\n <audit-headings :outline=\"outline\" :counts=\"card.page.headings\" />\n </div>\n\n <div v-else-if=\"tab === 'issues'\" class=\"wx-audit-card__issues\">\n <wx-text v-if=\"!card.issues.length\" tone=\"muted\">{{ t('page.no-issues') }}</wx-text>\n <div v-for=\"issue in card.issues\" :key=\"issue.id\" class=\"wx-audit-card__box\">\n <div class=\"wx-audit-card__box-head wx-audit-card__issue-head\">\n <wx-badge :type=\"severities[issue.severity]\" dot>{{\n t(`page.severity-${issue.severity}`)\n }}</wx-badge>\n <wx-text size=\"sm\" weight=\"semibold\">{{\n props.titles[issue.check] ?? issue.check\n }}</wx-text>\n <wx-badge v-if=\"issue.state === 'new'\" type=\"primary\" size=\"sm\">{{\n t('page.state-new')\n }}</wx-badge>\n <wx-tooltip\n v-if=\"issue.details.count != null && issue.details.table\"\n :content=\"issue.details.summary ?? undefined\"\n :disabled=\"!issue.details.summary\"\n >\n <wx-badge round size=\"sm\">{{ issue.details.count }}</wx-badge>\n </wx-tooltip>\n </div>\n <div class=\"wx-audit-card__box-body\">\n <audit-details\n :details=\"issue.details\"\n :counted=\"issue.details.count != null && !!issue.details.table\"\n />\n </div>\n </div>\n </div>\n\n <wx-table\n v-else-if=\"resourceTab\"\n :key=\"`resources-${String(tab)}`\"\n :data=\"resources\"\n :columns=\"resourceColumns\"\n row-key=\"id\"\n flush\n :loading=\"resourcesLoading\"\n :per-page-options=\"[]\"\n :empty-text=\"t('page.no-resources')\"\n @state-change=\"loadResources\"\n >\n <template #cell-url=\"{ row }\">\n <span v-if=\"resourceTab === 'images'\" class=\"wx-audit-card__picture\">\n <!-- Only a picture that answered is fetched: the stand's and a broken one keep the\n placeholder rather than a request the browser is sure to lose. -->\n <wx-image\n :src=\"viewable(row) ? row.url : undefined\"\n :alt=\"row.alt ?? ''\"\n :width=\"48\"\n :height=\"48\"\n fit=\"cover\"\n radius=\"var(--wx-radius-sm)\"\n preview\n :preview-label=\"t('page.view-full')\"\n class=\"wx-audit-card__thumb\"\n :class=\"{ 'is-unviewable': !viewable(row) }\"\n >\n <template v-if=\"!viewable(row)\" #placeholder>\n <wx-icon name=\"image\" />\n </template>\n </wx-image>\n <span class=\"wx-audit-card__url\">{{ row.url }}</span>\n </span>\n <span v-else class=\"wx-audit-card__url\">{{ row.url }}</span>\n <wx-text v-if=\"row.location\" size=\"sm\" tone=\"muted\" class=\"wx-audit-card__url\">\n → {{ row.location }}</wx-text\n >\n <wx-text v-if=\"row.error\" size=\"sm\" tone=\"danger\">{{ row.error }}</wx-text>\n </template>\n <template #cell-status=\"{ row }\">\n <audit-status v-if=\"row.status !== null || row.checked\" :code=\"row.status\" />\n <wx-text v-else size=\"sm\" tone=\"muted\">{{ t('page.not-checked') }}</wx-text>\n </template>\n <template #cell-bytes=\"{ row }\">{{ size(row) }}</template>\n <template #cell-alt=\"{ row }\">\n <wx-text v-if=\"row.alt === null && row.kind === 'img'\" size=\"sm\" tone=\"danger\">{{\n t('page.missing')\n }}</wx-text>\n <template v-else>{{ row.alt ?? '' }}</template>\n </template>\n </wx-table>\n\n <div v-else-if=\"tab === 'microdata'\" class=\"wx-audit-card__issues\">\n <wx-text v-if=\"!card.page.json_ld.length\" tone=\"muted\">{{\n t('page.no-json-ld')\n }}</wx-text>\n <div\n v-for=\"(block, index) in card.page.json_ld\"\n :key=\"index\"\n class=\"wx-audit-card__issue\"\n >\n <div class=\"wx-audit-card__issue-head\">\n <wx-text size=\"sm\" weight=\"semibold\">{{\n t('page.jsonld-block', { number: index + 1 })\n }}</wx-text>\n <wx-badge v-for=\"type in block.types\" :key=\"type\" size=\"sm\">{{ type }}</wx-badge>\n </div>\n <wx-text v-if=\"block.error\" size=\"sm\" tone=\"danger\"\n >{{ t('page.jsonld-error') }} {{ block.error }}</wx-text\n >\n <template v-for=\"(item, position) in block.items ?? []\" :key=\"position\">\n <wx-text v-if=\"item.missing.length\" size=\"sm\" tone=\"danger\"\n >{{ item.type }} — {{ t('page.jsonld-required') }}\n {{ item.missing.join(', ') }}</wx-text\n >\n <wx-text v-if=\"item.recommended.length\" size=\"sm\" tone=\"muted\"\n >{{ item.type }} — {{ t('page.jsonld-recommended') }}\n {{ item.recommended.join(', ') }}</wx-text\n >\n <wx-text\n v-if=\"!item.missing.length && !item.recommended.length\"\n size=\"sm\"\n tone=\"success\"\n >{{ item.type }} — {{ t('page.jsonld-complete') }}</wx-text\n >\n </template>\n <pre v-if=\"block.source\" class=\"wx-audit-card__source\">{{ pretty(block.source) }}</pre>\n </div>\n </div>\n\n <wx-table\n v-else\n :key=\"String(tab)\"\n :data=\"links\"\n :columns=\"linkColumns\"\n row-key=\"id\"\n flush\n :loading=\"linksLoading\"\n :per-page-options=\"[]\"\n :empty-text=\"t('page.no-links')\"\n @state-change=\"loadLinks\"\n >\n <template #cell-url=\"{ row }\">\n <span class=\"wx-audit-card__url\">{{ row.url ?? '—' }}</span>\n </template>\n <template #cell-status=\"{ row }\">\n <audit-status v-if=\"row.status !== null\" :code=\"row.status\" />\n </template>\n <template #cell-host_class=\"{ row }\">\n <wx-badge v-if=\"row.host_class\" :type=\"hostTypes[row.host_class] ?? 'info'\" size=\"sm\">{{\n t(`page.host-${row.host_class}`)\n }}</wx-badge>\n </template>\n </wx-table>\n </wx-tabs>\n </div>\n </wx-drawer>\n</template>\n\n<style scoped>\n.wx-audit-card {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n min-width: 0;\n /* The card decides its layout by its own width, not the window's. */\n container-type: inline-size;\n}\n\n.wx-audit-card__title {\n display: inline-flex;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-audit-card__url {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n\n.wx-audit-card__overview {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n margin-top: var(--wx-space-12);\n min-width: 0;\n}\n\n/* The numbers first: what a reader compares between pages, at a glance. */\n.wx-audit-card__tiles {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));\n gap: var(--wx-space-8);\n}\n\n.wx-audit-card__tile {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n /* A label on two lines must not lift its number above its neighbours' — the numbers sit on one line. */\n justify-content: space-between;\n gap: var(--wx-space-4);\n min-width: 0;\n padding: var(--wx-space-8) var(--wx-space-12);\n border: 1px solid var(--wx-border-default);\n border-radius: var(--wx-radius-md);\n background: var(--wx-bg-surface);\n}\n\n.wx-audit-card__number {\n font-size: var(--wx-font-size-lg);\n}\n\n/* A section, or a finding: an edge of its own, a tinted head, the content under it. */\n.wx-audit-card__box {\n min-width: 0;\n border: 1px solid var(--wx-border-default);\n border-radius: var(--wx-radius-md);\n background: var(--wx-bg-surface);\n overflow: hidden;\n}\n\n.wx-audit-card__heading-fact {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-4);\n}\n\n.wx-audit-card__heading-open {\n margin-inline-start: var(--wx-space-8);\n}\n\n.wx-audit-card__heading-hints {\n margin: 0;\n padding-inline-start: var(--wx-space-18);\n color: var(--wx-text-muted);\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-card__headings {\n padding: var(--wx-space-12) var(--wx-space-16);\n}\n\n.wx-audit-card__box-head {\n padding: var(--wx-space-8) var(--wx-space-12);\n border-bottom: 1px solid var(--wx-border-muted);\n background: var(--wx-bg-subtle);\n font-size: var(--wx-font-size-sm);\n font-weight: var(--wx-font-weight-semibold);\n}\n\n.wx-audit-card__box-body {\n padding: var(--wx-space-8) var(--wx-space-12);\n}\n\n/* One label column for every section, so the values start on one line down the card. */\n.wx-audit-card__facts {\n display: grid;\n grid-template-columns: 200px minmax(0, 1fr);\n gap: var(--wx-space-8) var(--wx-space-16);\n margin: 0;\n padding: var(--wx-space-12);\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-card__facts dt {\n color: var(--wx-text-muted);\n}\n\n.wx-audit-card__facts dd {\n margin: 0;\n overflow-wrap: anywhere;\n white-space: pre-line;\n}\n\n/* Key and value in two columns of their own: the keys start on one line, so do the values. */\n.wx-audit-card__pairs {\n display: grid;\n grid-template-columns: max-content minmax(0, 1fr);\n gap: var(--wx-space-6) var(--wx-space-12);\n align-items: baseline;\n}\n\n.wx-audit-card__key {\n color: var(--wx-text-muted);\n font-family: var(--wx-font-family-mono);\n font-size: var(--wx-font-size-xs);\n}\n\n.wx-audit-card__tags {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-6);\n}\n\n.wx-audit-card__code {\n font-family: var(--wx-font-family-mono);\n}\n\n.wx-audit-card__issues {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-16);\n margin-top: var(--wx-space-12);\n}\n\n.wx-audit-card__issue {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-6);\n min-width: 0;\n}\n\n/* A picture is recognised by sight faster than by its hashed file name. */\n.wx-audit-card__picture {\n display: flex;\n align-items: center;\n gap: var(--wx-space-12);\n min-width: 0;\n}\n\n.wx-audit-card__thumb {\n flex: none;\n}\n\n/* The same box as a picture that would not load, with the same mark — nothing here to open. */\n.wx-audit-card__thumb.is-unviewable :deep(.wx-image__placeholder .wx-icon) {\n width: 32px;\n height: 32px;\n}\n\n.wx-audit-card__source {\n max-height: 480px;\n margin: 0;\n padding: var(--wx-space-8);\n overflow: auto;\n border-radius: var(--wx-radius-sm);\n background: var(--wx-bg-muted);\n font-family: var(--wx-font-family-mono);\n font-size: var(--wx-font-size-xs);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n\n.wx-audit-card__issue-head {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-8);\n}\n\n/* A narrow card: the label goes above its value instead of beside it. */\n@container (max-width: 560px) {\n .wx-audit-card__facts {\n grid-template-columns: minmax(0, 1fr);\n row-gap: var(--wx-space-2);\n }\n\n .wx-audit-card__facts dd + dt {\n margin-top: var(--wx-space-8);\n }\n}\n\n.wx-audit-card__extra {\n display: inline-flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-8);\n}\n\n.wx-audit-card__recheck {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-4) var(--wx-space-12);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { WxButton, WxDialog, WxFormItem, WxInput, WxText, WxTextarea, toast } from '@webx-ui/core'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditIgnoreRule, AuditIssue } from './types'\n\n/**\n * «Hide» on a finding (decision 9): which addresses — this one, a mask of them, or the whole\n * check — and why. While the mask is typed the dialog says how many findings of the last run it\n * would hide; nothing is hidden until the button is pressed, and nothing is ever deleted.\n */\nconst props = defineProps<{ issue: AuditIssue; title: string }>()\nconst emit = defineEmits<{ hidden: [rule: AuditIgnoreRule] }>()\nconst open = defineModel<boolean>('open', { default: false })\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\n\nconst pattern = ref('')\nconst reason = ref('')\nconst count = ref<number | null>(null)\nconst saving = ref(false)\nlet timer: ReturnType<typeof setTimeout> | undefined\n\n/* The path, not the whole address: a mask of the path hides it on every mirror a run opened. */\nfunction pathOf(url: string | null): string {\n if (!url) return ''\n\n try {\n const parsed = new URL(url)\n\n return parsed.pathname + parsed.search\n } catch {\n return url\n }\n}\n\nconst ready = computed(() => reason.value.trim() !== '')\n\nfunction preview(): void {\n clearTimeout(timer)\n timer = setTimeout(async () => {\n try {\n count.value = await api.hidePreview({ check: props.issue.check, pattern: pattern.value })\n } catch {\n count.value = null\n }\n }, 300)\n}\n\nasync function hide(): Promise<void> {\n saving.value = true\n\n try {\n const rule = await api.hide({\n check: props.issue.check,\n pattern: pattern.value,\n reason: reason.value,\n })\n\n toast.success(t('page.hidden-done'))\n emit('hidden', rule)\n open.value = false\n } catch (error) {\n toast.danger(message(error))\n } finally {\n saving.value = false\n }\n}\n\nwatch(\n [open, () => props.issue.id],\n ([now]) => {\n if (!now) return\n\n pattern.value = pathOf(props.issue.url)\n reason.value = ''\n count.value = null\n preview()\n },\n { immediate: true },\n)\n\nwatch(pattern, () => {\n if (open.value) preview()\n})\n</script>\n\n<template>\n <wx-dialog v-model:open=\"open\" :title=\"t('page.hide-title')\" :width=\"560\">\n <div class=\"wx-audit-hide\">\n <wx-text weight=\"semibold\">{{ props.title }}</wx-text>\n <wx-text size=\"sm\" tone=\"muted\">{{ t('page.hide-help') }}</wx-text>\n\n <wx-form-item :label=\"t('page.hide-pattern')\" :help=\"t('page.hide-pattern-help')\">\n <wx-input v-model=\"pattern\" placeholder=\"/search/**\" />\n </wx-form-item>\n\n <wx-form-item :label=\"t('page.hide-reason')\" required>\n <wx-textarea v-model=\"reason\" :rows=\"3\" />\n </wx-form-item>\n\n <wx-text v-if=\"count !== null\" size=\"sm\" tone=\"muted\">{{\n t('page.hide-count', { count })\n }}</wx-text>\n </div>\n\n <template #footer>\n <wx-button @click=\"open = false\">{{ t('page.dismiss') }}</wx-button>\n <wx-button type=\"primary\" :loading=\"saving\" :disabled=\"!ready\" @click=\"hide\">{{\n t('page.hide')\n }}</wx-button>\n </template>\n </wx-dialog>\n</template>\n\n<style scoped>\n.wx-audit-hide {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n min-width: 0;\n}\n</style>\n","import type { AuditFieldType, AuditFilterOp, AuditPageField } from './types'\n\n/**\n * The fields of the snapshot, as `PageColumns` lists them on the server: what the pages screen\n * can show, filter on, sort by and export. Kept in the same order, so the column picker reads\n * like the page's card — address and answer first, markup, then speed and links.\n */\nexport const PAGE_FIELDS: Record<AuditPageField, AuditFieldType> = {\n url: 'url',\n status: 'status',\n final_status: 'status',\n redirect_to: 'url',\n source: 'source',\n depth: 'number',\n indexable: 'bool',\n issues: 'number',\n title: 'text',\n description: 'text',\n h1: 'text',\n canonical: 'url',\n robots_meta: 'text',\n x_robots_tag: 'text',\n lang: 'text',\n content_type: 'text',\n bytes: 'number',\n ttfb_ms: 'number',\n total_ms: 'number',\n compression: 'text',\n word_count: 'number',\n links_in: 'number',\n links_out_internal: 'number',\n links_out_external: 'number',\n images: 'number',\n images_without_alt: 'number',\n in_sitemap: 'bool',\n in_registry: 'bool',\n blocked_by_robots: 'bool',\n}\n\nexport const DEFAULT_COLUMNS: AuditPageField[] = [\n 'url',\n 'status',\n 'indexable',\n 'title',\n 'word_count',\n 'links_in',\n 'issues',\n]\n\n/** `h1` is read out of a JSON list: shown and exported, not filtered or sorted on. */\nexport const COMPUTED_FIELDS: AuditPageField[] = ['h1']\n\n/** What can be asked of a field of each type. */\nexport const OPERATIONS: Record<AuditFieldType, AuditFilterOp[]> = {\n url: ['contains', 'eq', 'empty', 'filled'],\n text: ['contains', 'eq', 'empty', 'filled'],\n number: ['gt', 'lt', 'eq', 'empty'],\n status: ['eq', 'gt', 'lt', 'empty'],\n bool: ['yes', 'no'],\n source: ['eq'],\n}\n\n/** The operations that need a value typed beside them. */\nexport const WITH_VALUE: AuditFilterOp[] = ['contains', 'eq', 'gt', 'lt']\n\nexport const SOURCES = ['home', 'sitemap', 'registry', 'link'] as const\n","import { defineAsyncComponent } from 'vue'\nexport { audit, type AuditOptions } from './module'\nexport { createAuditApi, pageParams, type AuditApi } from './api'\nexport { auditMessages } from './messages'\nexport const WxAuditOverviewPage = defineAsyncComponent(() => import('./AuditOverviewPage.vue'))\nexport const WxAuditIssuesPage = defineAsyncComponent(() => import('./AuditIssuesPage.vue'))\nexport { default as WxAuditDetails } from './AuditDetails.vue'\nexport const WxAuditPagesPage = defineAsyncComponent(() => import('./AuditPagesPage.vue'))\nexport { default as WxAuditPageCard } from './AuditPageCard.vue'\nexport const WxAuditHostsPage = defineAsyncComponent(() => import('./AuditHostsPage.vue'))\nexport const WxAuditRunsPage = defineAsyncComponent(() => import('./AuditRunsPage.vue'))\nexport const WxAuditSettingsPage = defineAsyncComponent(() => import('./AuditSettingsPage.vue'))\nexport { default as WxAuditHideDialog } from './AuditHideDialog.vue'\nexport { PAGE_FIELDS, DEFAULT_COLUMNS } from './fields'\nexport type {\n AuditCellType,\n AuditCheckRow,\n AuditComparison,\n AuditComparisonKind,\n AuditComparisonRow,\n AuditCounts,\n AuditDetails,\n AuditDetailsColumn,\n AuditFieldFilter,\n AuditFieldType,\n AuditFilterOp,\n AuditFixChange,\n AuditFixOffer,\n AuditFixResult,\n AuditHostClass,\n AuditHostField,\n AuditHostPage,\n AuditHostRow,\n AuditHosts,\n AuditIgnoreRule,\n AuditIssue,\n AuditIssueQuery,\n AuditJsonLdBlock,\n AuditLatest,\n AuditLinkRow,\n AuditPage,\n AuditPageCard,\n AuditPageField,\n AuditPageQuery,\n AuditPageRow,\n AuditPageSource,\n AuditResourceRow,\n AuditResourceTab,\n AuditRun,\n AuditRunStatus,\n AuditScope,\n AuditSeverity,\n AuditStage,\n} from './types'\n"],"names":["audit","options","path","props","pageParams","query","params","filter","createAuditApi","admin","base","data","body","filters","id","scope","urls","run","columns","key","value","issue","fix","dryRun","to","from","rule","values","auditMessages","differences","source","target","found","bare","host","trimmed","TAIL","splitMiddle","text","statusType","code","EXPLAINED","statusKey","__props","parts","computed","_createBlock","_unref","WxTooltip","_createElementVNode","_hoisted_3","_toDisplayString","_createVNode","WxLink","_hoisted_1","_createElementBlock","_hoisted_2","seeded","useAuditMessages","i18n","useAdmin","t","useTranslate","rels","opener","rel","_openBlock","WxBadge","_createTextVNode","_Fragment","_renderList","label","router","useRouter","redirects","column","isSource","isTarget","cell","row","yesNo","changes","WxText","_normalizeClass","index","_hoisted_4","WxIcon","AuditAddress","change","AuditStatus","AuditLinkAttrs","WxButton","$event","_hoisted_5","outlineRows","outline","out","previous","level","gap","outlineHints","ones","jumps","empty","rows","hints","total","sum","count","WxAlert","hint","step","viewable","POLL_MS","emit","__emit","context","api","canRun","recheck","ref","rechecking","timer","startRecheck","card","follow","error","toast","message","compareRecheck","onBeforeUnmount","useErrorText","failure","tab","links","linksLoading","resources","resourcesLoading","resourceTabs","open","tabs","kept","resourceTab","severities","hostTypes","linkColumns","resourceColumns","pretty","size","kb","bytes","tiles","page","tile","sections","alternate","block","title","section","load","loadLinks","state","loadResources","current","watch","WxDrawer","WxTabs","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","tag","_hoisted_16","_hoisted_17","_hoisted_18","name","_hoisted_19","_hoisted_20","_hoisted_21","AuditHeadings","_hoisted_22","_hoisted_23","_hoisted_24","AuditDetails","WxTable","_withCtx","_hoisted_25","WxImage","_hoisted_26","_hoisted_27","_hoisted_28","_hoisted_29","type","item","position","_hoisted_30","_hoisted_31","WxSkeleton","_useModel","pattern","reason","saving","pathOf","url","parsed","ready","preview","hide","now","WxDialog","WxFormItem","WxInput","WxTextarea","PAGE_FIELDS","DEFAULT_COLUMNS","COMPUTED_FIELDS","OPERATIONS","WITH_VALUE","SOURCES","WxAuditOverviewPage","defineAsyncComponent","WxAuditIssuesPage","WxAuditPagesPage","WxAuditHostsPage","WxAuditRunsPage","WxAuditSettingsPage"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-_DgRf2O6.js","sources":["../src/module.ts","../src/api.ts","../src/messages.ts","../src/addresses.ts","../src/AuditAddress.vue","../src/i18n.ts","../src/AuditLinkAttrs.vue","../src/AuditStatus.vue","../src/AuditDetails.vue","../src/headings.ts","../src/AuditHeadings.vue","../src/resources.ts","../src/AuditPageCard.vue","../src/AuditHideDialog.vue","../src/fields.ts","../src/index.ts"],"sourcesContent":["import type { AdminModule } from '@webx-ui/module-admin'\n\nexport interface AuditOptions {\n /** Where the section lives inside the panel. */\n path?: string\n /**\n * @deprecated The audit's settings are a view of the section itself (`<path>/settings`); the\n * option is read by nothing and stays only so that a panel which passed it still compiles.\n */\n settingsPath?: string\n}\n\n/**\n * «System → Audit» as a section of the panel: the overview of the last run, its findings, the\n * pages the last full run crawled, the hosts the site points at, the history of runs with two of\n * them compared, and the section's settings.\n *\n * The id matches the module the server reports, which is what makes the entry appear in the\n * navigation: the section shows up when both halves are installed.\n */\nexport function audit(options: AuditOptions = {}): AdminModule {\n const path = options.path ?? '/audit'\n const props = { base: path }\n\n return {\n id: 'audit',\n path,\n routes: [\n { path, name: 'webx.audit', component: () => import('./AuditOverviewPage.vue'), props },\n {\n path: `${path}/issues`,\n name: 'webx.audit.issues',\n component: () => import('./AuditIssuesPage.vue'),\n props,\n },\n {\n path: `${path}/pages`,\n name: 'webx.audit.pages',\n component: () => import('./AuditPagesPage.vue'),\n props,\n },\n {\n path: `${path}/hosts`,\n name: 'webx.audit.hosts',\n component: () => import('./AuditHostsPage.vue'),\n props,\n },\n {\n path: `${path}/runs`,\n name: 'webx.audit.runs',\n component: () => import('./AuditRunsPage.vue'),\n props,\n },\n {\n path: `${path}/settings`,\n name: 'webx.audit.settings',\n component: () => import('./AuditSettingsPage.vue'),\n props,\n },\n ],\n }\n}\n","import type { AdminContext } from '@webx-ui/module-admin'\nimport type {\n AuditCheckRow,\n AuditComparison,\n AuditComparisonKind,\n AuditFixOffer,\n AuditFixResult,\n AuditHosts,\n AuditHostClass,\n AuditIgnoreRule,\n AuditIssue,\n AuditIssueQuery,\n AuditLatest,\n AuditLinkRow,\n AuditPage,\n AuditPageCard,\n AuditPageQuery,\n AuditPageRow,\n AuditResourceRow,\n AuditResourceTab,\n AuditRun,\n AuditScope,\n} from './types'\n\nexport interface AuditApi {\n /** The run that is going, the last one that finished, and whether the queue can take one. */\n latest(): Promise<AuditLatest>\n run(id: number): Promise<AuditRun>\n /** Every run, newest first — the history. */\n runs(query?: { page?: number; per_page?: number }): Promise<AuditPage<AuditRun>>\n /**\n * Queues a run; refused with 409 on a `sync` queue or while another one is going. A `urls` run\n * is a recheck of the addresses given.\n */\n start(scope: AuditScope, urls?: string[]): Promise<AuditRun>\n cancel(id: number): Promise<AuditRun>\n /** Deletes every run with all it found; refused with 409 while a run is going. */\n clear(): Promise<number>\n /** The checks of a run that found something, worst first. */\n checks(run: number, query?: AuditIssueQuery): Promise<AuditCheckRow[]>\n /** The findings of a run — of one check when `check` is given. */\n issues(run: number, query?: AuditIssueQuery): Promise<AuditPage<AuditIssue>>\n /** The crawled pages of a run under the screen's filters. */\n pages(run: number, query?: AuditPageQuery): Promise<AuditPage<AuditPageRow>>\n /** Where the browser downloads the same list as CSV, under the panel's session. */\n pagesFile(run: number, query: AuditPageQuery, columns: string[]): string\n page(run: number, id: number): Promise<AuditPageCard>\n /** The links of a page: `out` — what it points at, `in` — what points at it. */\n links(\n run: number,\n id: number,\n query?: { direction?: 'in' | 'out'; kind?: string; page?: number; per_page?: number },\n ): Promise<AuditPage<AuditLinkRow>>\n /** What a page loads, a tab of the card at a time. */\n resources(\n run: number,\n id: number,\n query: { tab: AuditResourceTab; page?: number; per_page?: number },\n ): Promise<AuditPage<AuditResourceRow>>\n /** The fixes that can close a finding now, each with what it would change. */\n fixes(run: number, issue: number): Promise<AuditFixOffer[]>\n /** Presses a fix — or, with `dryRun`, only asks again what it would change. */\n fix(run: number, issue: number, fix: string, dryRun?: boolean): Promise<AuditFixResult>\n /** Where the browser downloads one page of a run — its snapshot, findings and links. */\n pageFile(run: number, id: number): string\n /** Two runs by fingerprint; without `from`, `to` against the run it was analysed against. */\n compare(to: number, from?: number | null): Promise<AuditComparison>\n /** The findings of one kind of a comparison, of one check when given. */\n compareIssues(query: {\n to: number\n from?: number | null\n kind: AuditComparisonKind\n check?: string\n page?: number\n per_page?: number\n }): Promise<AuditPage<AuditIssue>>\n /** Every host the site points at, by class — stands first; with `host`, where it stands. */\n hosts(query?: {\n class?: AuditHostClass | null\n search?: string\n host?: string\n }): Promise<AuditHosts>\n /** The hiding rules. */\n ignores(): Promise<AuditIgnoreRule[]>\n /** Hides what a rule matches, with the reason. */\n hide(rule: { check: string; pattern: string; reason: string }): Promise<AuditIgnoreRule>\n /** How many findings of the last run a rule would hide — nothing is hidden. */\n hidePreview(rule: { check: string; pattern: string }): Promise<number>\n /** Removes a rule: its findings count again. */\n unhide(id: number): Promise<void>\n /** The section's settings, keyed as the screen names them. */\n settings(): Promise<Record<string, unknown>>\n saveSettings(values: Record<string, unknown>): Promise<Record<string, unknown>>\n}\n\n/** The query of the pages screen as the API reads it: `f[field]=op:value` for each filter. */\nexport function pageParams(query: AuditPageQuery): Record<string, string | number | undefined> {\n const params: Record<string, string | number | undefined> = {\n search: query.search || undefined,\n status: query.status || undefined,\n indexable:\n query.indexable === null || query.indexable === undefined\n ? undefined\n : query.indexable\n ? 1\n : 0,\n check: query.check || undefined,\n sort: query.sort || undefined,\n page: query.page,\n per_page: query.per_page,\n }\n\n for (const filter of query.filters ?? []) {\n params[`f[${filter.field}]`] =\n filter.value === undefined || filter.value === '' ? filter.op : `${filter.op}:${filter.value}`\n }\n\n return params\n}\n\n/** Everything under `/audit`, below the panel's API path. */\nexport function createAuditApi(admin: AdminContext): AuditApi {\n const base = `${admin.apiPath}/audit`\n const data = <T>(body: { data: T }): T => body.data\n\n /* `undefined` drops a parameter; `null` and `''` would be sent as words. */\n const filters = (query: AuditIssueQuery) => ({\n check: query.check || undefined,\n severity: query.severity || undefined,\n group: query.group || undefined,\n state: query.state || undefined,\n page: query.page,\n per_page: query.per_page,\n })\n\n return {\n latest: () => admin.http.get<{ data: AuditLatest }>(`${base}/runs/latest`).then(data),\n\n run: (id) => admin.http.get<{ data: AuditRun }>(`${base}/runs/${id}`).then(data),\n\n runs: (query = {}) =>\n admin.http\n .get<{\n data: AuditRun[]\n meta: Omit<AuditPage<AuditRun>, 'data'>\n }>(`${base}/runs`, { query })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n start: (scope, urls) =>\n admin.http\n .post<{ data: AuditRun }>(`${base}/runs`, scope === 'urls' ? { scope, urls } : { scope })\n .then(data),\n\n cancel: (id) => admin.http.post<{ data: AuditRun }>(`${base}/runs/${id}/cancel`, {}).then(data),\n\n clear: () =>\n admin.http.delete<{ data: { runs: number } }>(`${base}/runs`).then((body) => body.data.runs),\n\n checks: (run, query = {}) =>\n admin.http\n .get<{ data: AuditCheckRow[] }>(`${base}/runs/${run}/checks`, { query: filters(query) })\n .then(data),\n\n issues: (run, query = {}) =>\n admin.http\n .get<{\n data: AuditIssue[]\n meta: Omit<AuditPage<AuditIssue>, 'data'>\n }>(`${base}/runs/${run}/issues`, { query: filters(query) })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n pages: (run, query = {}) =>\n admin.http\n .get<{\n data: AuditPageRow[]\n meta: Omit<AuditPage<AuditPageRow>, 'data'>\n }>(`${base}/runs/${run}/pages`, { query: pageParams(query) })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n pagesFile: (run, query, columns) => {\n const params = new URLSearchParams()\n\n for (const [key, value] of Object.entries({\n ...pageParams(query),\n page: undefined,\n per_page: undefined,\n })) {\n if (value !== undefined) params.set(key, String(value))\n }\n\n params.set('columns', columns.join(','))\n\n return `${base}/runs/${run}/pages/export?${params.toString()}`\n },\n\n page: (run, id) =>\n admin.http.get<{ data: AuditPageCard }>(`${base}/runs/${run}/pages/${id}`).then(data),\n\n links: (run, id, query = {}) =>\n admin.http\n .get<{\n data: AuditLinkRow[]\n meta: Omit<AuditPage<AuditLinkRow>, 'data'>\n }>(`${base}/runs/${run}/pages/${id}/links`, { query })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n resources: (run, id, query) =>\n admin.http\n .get<{\n data: AuditResourceRow[]\n meta: Omit<AuditPage<AuditResourceRow>, 'data'>\n }>(`${base}/runs/${run}/pages/${id}/resources`, { query })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n fixes: (run, issue) =>\n admin.http\n .get<{ data: AuditFixOffer[] }>(`${base}/runs/${run}/issues/${issue}/fixes`)\n .then(data),\n\n fix: (run, issue, fix, dryRun = false) =>\n admin.http\n .post<{\n data: AuditFixResult\n }>(`${base}/runs/${run}/issues/${issue}/fixes/${encodeURIComponent(fix)}`, {\n dry_run: dryRun,\n })\n .then(data),\n\n pageFile: (run, id) => `${base}/runs/${run}/pages/${id}/export`,\n\n compare: (to, from) =>\n admin.http\n .get<{\n data: AuditComparison\n }>(`${base}/runs/compare`, { query: { to, from: from ?? undefined } })\n .then(data),\n\n compareIssues: (query) =>\n admin.http\n .get<{\n data: AuditIssue[]\n meta: Omit<AuditPage<AuditIssue>, 'data'>\n }>(`${base}/runs/compare/issues`, {\n query: { ...query, from: query.from ?? undefined, check: query.check || undefined },\n })\n .then((body) => ({ ...body.meta, data: body.data })),\n\n hosts: (query = {}) =>\n admin.http\n .get<{ data: AuditHosts }>(`${base}/hosts`, {\n query: {\n class: query.class || undefined,\n search: query.search || undefined,\n host: query.host || undefined,\n },\n })\n .then(data),\n\n ignores: () => admin.http.get<{ data: AuditIgnoreRule[] }>(`${base}/ignores`).then(data),\n\n hide: (rule) => admin.http.post<{ data: AuditIgnoreRule }>(`${base}/ignores`, rule).then(data),\n\n hidePreview: (rule) =>\n admin.http\n .post<{ data: { hidden: number } }>(`${base}/ignores`, { ...rule, dry_run: true })\n .then((body) => body.data.hidden),\n\n unhide: (id) => admin.http.delete(`${base}/ignores/${id}`).then(() => undefined),\n\n settings: () =>\n admin.http\n .get<{ data: { values: Record<string, unknown> } }>(`${base}/settings`)\n .then((body) => body.data.values),\n\n saveSettings: (values) =>\n admin.http\n .put<{ data: { values: Record<string, unknown> } }>(`${base}/settings`, { values })\n .then((body) => body.data.values),\n }\n}\n","import type { Messages } from '@webx-ui/module-admin'\n\n/**\n * What this package says, in English — the same keys `webx-ui/module-audit` ships as\n * `lang/en/*.php`, so a key never reaches the screen while the dictionary is on its way. The\n * server's dictionary wins; the check texts and the details arrive translated from the server and\n * are not repeated here.\n */\nexport const auditMessages: Record<string, Messages> = {\n module: {\n title: 'Audit',\n },\n\n page: {\n overview: 'Overview',\n issues: 'Findings',\n settings: 'Settings',\n run: 'Run the audit',\n scope: 'Scope',\n 'scope-full': 'Full',\n 'scope-full-help': 'Everything the audit can check.',\n 'scope-quick': 'Quick',\n 'scope-quick-help': 'The config, the host and the database — takes seconds.',\n start: 'Start',\n started: 'The audit has started.',\n cancel: 'Cancel the run',\n never: 'No audit has been run yet.',\n 'never-help':\n 'Run the first one to see how the site looks to a visitor and to a search engine.',\n health: 'Health',\n errors: 'Errors',\n warnings: 'Warnings',\n notices: 'Notices',\n new: 'New',\n fixed: 'Fixed',\n 'health-pages': 'Pages without errors: :clean of :pages',\n 'health-site': 'Errors of the whole site: :count',\n 'health-warnings': 'Checks with warnings: :count',\n 'health-help':\n 'The share of pages without errors, minus 10 points for each error of the whole site and 2 for each check with warnings — the warnings take 20 at most.',\n 'last-run': 'Last run',\n 'base-url': 'Address',\n 'status-queued': 'Waiting in the queue',\n 'status-running': 'Running',\n 'status-done': 'Done',\n 'status-failed': 'Failed',\n 'status-cancelled': 'Cancelled',\n 'stage-probes': 'Config and host',\n 'stage-database': 'Database',\n 'stage-crawl': 'Pages',\n 'stage-analyse': 'Analysis',\n 'last-failed': 'The last run did not finish: :error',\n 'by-group': 'By group',\n 'group-config': 'Configuration',\n 'group-host': 'Host and addresses',\n 'group-hosts': 'Outgoing addresses',\n 'group-other': 'Other',\n sources: 'Content searched',\n 'sources-missing': 'Installed, but not searched:',\n 'sources-help':\n 'Besides crawling the site, the audit reads the text modules keep in the database — drafts, hidden records and fields the template never prints — and looks there for absolute addresses, such as links to a development stand. Green: modules that hand their text over. Orange: modules installed here that do not yet. Their published pages are still crawled, but their drafts and hidden fields are not searched, and a fix button cannot reach them.',\n 'sources-help-label': 'What this means',\n 'sync-queue':\n 'The queue runs jobs inside the request (sync), so the panel cannot start a run. Run php artisan webx:audit:run from the terminal or cron.',\n 'already-running': 'An audit is already running.',\n check: 'Check',\n count: 'Found',\n severity: 'Severity',\n 'severity-error': 'Error',\n 'severity-warning': 'Warning',\n 'severity-notice': 'Notice',\n 'any-severity': 'Any severity',\n 'any-group': 'Any group',\n 'any-state': 'New and persisting',\n 'state-new': 'New',\n 'state-persisting': 'Persisting',\n address: 'Address',\n empty: 'Nothing found.',\n clean: 'The last run found nothing.',\n found: 'What was found',\n why: 'Why it matters',\n fix: 'How to fix it',\n explain: 'What this check means',\n 'open-editor': 'Open in the editor',\n 'fix-button': 'Fix',\n 'fix-apply': 'Apply',\n 'fix-applied': 'Done. Run the audit again to see the finding go.',\n 'fix-none': 'Nothing left to change: no fix can close this finding now.',\n 'fix-pressed': 'Fixed — waiting for the next run',\n 'fix-changes': 'Changes',\n 'fix-before': 'Now',\n 'fix-after': 'After',\n yes: 'Yes',\n no: 'No',\n missing: 'Missing',\n pages: 'Pages',\n 'pages-progress': 'Pages crawled: :crawled of at most :limit',\n 'resources-progress':\n 'Pictures, styles, scripts and external links checked: :checked of :total',\n 'pages-none': 'No full run has crawled the site yet. Start a full audit to see every page.',\n 'pages-run': 'Full run of :date',\n 'group-indexing': 'Indexing',\n 'group-redirects': 'Redirects',\n 'group-page': 'Page',\n 'group-content': 'Content and speed',\n 'group-links': 'Links',\n 'group-images': 'Pictures',\n 'group-a11y': 'Accessibility',\n 'group-structure': 'Structure',\n columns: 'Columns',\n export: 'Export CSV',\n 'search-url': 'Search by address',\n 'any-status': 'Any answer',\n 'status-none': 'No answer',\n 'any-indexable': 'Indexable or not',\n 'indexable-yes': 'Indexable',\n 'indexable-no': 'Not indexable',\n 'any-check': 'With any findings or none',\n 'add-filter': 'Add a filter',\n 'remove-filter': 'Remove the filter',\n 'op-contains': 'contains',\n 'op-eq': 'is',\n 'op-empty': 'is empty',\n 'op-filled': 'is not empty',\n 'op-gt': 'more than',\n 'op-lt': 'less than',\n 'op-yes': 'yes',\n 'op-no': 'no',\n value: 'Value',\n 'field-url': 'Address',\n 'field-status': 'Code',\n 'field-final_status': 'Final code',\n 'field-redirect_to': 'Redirects to',\n 'field-source': 'Found through',\n 'field-depth': 'Depth',\n 'field-indexable': 'Indexable',\n 'field-issues': 'Findings',\n 'field-title': 'Title',\n 'field-description': 'Description',\n 'field-h1': 'H1',\n 'field-canonical': 'Canonical',\n 'field-robots_meta': 'Meta robots',\n 'field-x_robots_tag': 'X-Robots-Tag',\n 'field-lang': 'Language',\n 'field-content_type': 'Content type',\n 'field-bytes': 'Size, bytes',\n 'field-ttfb_ms': 'First byte, ms',\n 'field-total_ms': 'Answer, ms',\n 'field-compression': 'Compression',\n 'field-word_count': 'Words',\n 'field-links_in': 'Links in',\n 'field-links_out_internal': 'Internal links out',\n 'field-links_out_external': 'External links out',\n 'field-images': 'Pictures',\n 'field-images_without_alt': 'Pictures without alt',\n 'field-in_sitemap': 'In the sitemap',\n 'field-in_registry': 'In the registry',\n 'field-blocked_by_robots': 'Closed in robots.txt',\n 'source-home': 'Home page',\n 'source-sitemap': 'Sitemap',\n 'source-registry': 'Address registry',\n 'source-link': 'Link',\n 'card-overview': 'Overview',\n 'card-issues': 'Problems',\n 'card-incoming': 'Incoming',\n 'card-outgoing': 'Outgoing',\n 'card-images': 'Pictures',\n 'card-css': 'CSS',\n 'card-js': 'JS',\n 'card-microdata': 'Structured data',\n 'card-headings': 'Headings',\n 'no-headings': 'The page has no headings.',\n 'headings-recheck': 'The list of headings appears once the page is checked again.',\n 'heading-empty': 'Empty heading',\n 'headings-hints': 'Not the usual order',\n 'headings-fine':\n 'The headings go in the usual order: one H1 first, each level one step below the one above.',\n 'headings-no-h1':\n 'There is no H1. A page needs one main heading — search engines and screen readers start from it.',\n 'headings-many-h1': 'More than one H1 — keep one, make the rest H2. H1 headings: :count',\n 'headings-h1-not-first':\n 'The page starts with :level, not H1: the main heading should come before the rest.',\n 'headings-skipped':\n 'Levels are skipped — go down one step at a time: after H2 comes H3, not H4. Places: :count',\n 'headings-empty':\n 'Headings with no text — fill them in or make them ordinary text. Empty: :count',\n 'heading-missing': ':level is missing after :after',\n 'headings-summary-ok': 'In order, headings: :count',\n 'headings-summary-bad': 'Out of order, headings: :count',\n 'headings-open': 'Open the map',\n response: 'Response',\n headers: 'Headers',\n markup: 'Markup',\n 'open-page': 'Open the page',\n 'no-issues': 'No problems on this page.',\n 'no-links': 'No links.',\n kind: 'Kind',\n anchor: 'Anchor',\n host: 'Host',\n size: 'Size',\n cache: 'Cache',\n alt: 'Alt',\n 'not-checked': 'Not checked',\n 'no-resources': 'Nothing of this kind on the page.',\n 'no-json-ld': 'The page has no structured data.',\n 'jsonld-block': 'Block :number',\n 'jsonld-error': 'Does not parse:',\n 'jsonld-required': 'Required fields missing:',\n 'jsonld-recommended': 'Recommended fields missing:',\n 'jsonld-complete': 'Every field search engines ask for is there.',\n 'host-own': 'Own',\n 'host-own_mirror': 'Other mirror',\n 'host-dev': 'Stand',\n 'host-external': 'External',\n error: 'Error',\n 'source-list': 'Recheck list',\n hosts: 'Outgoing',\n runs: 'Runs',\n 'scope-urls': 'Recheck',\n 'urls-foreign': 'None of these addresses is on the audited site.',\n 'state-hidden': 'Hidden',\n hide: 'Hide',\n 'hide-title': 'Hide this finding',\n 'hide-help':\n 'Hidden findings stop counting, in this run and in every later one. Nothing is deleted: the hidden list shows them again.',\n 'hide-pattern': 'Addresses',\n 'hide-pattern-help':\n 'This address, or a mask of them: * is a stretch without a slash, ** one with slashes (/search/**). Empty hides every finding of the check.',\n 'hide-reason': 'Why it is all right',\n 'hide-count': 'Findings of the last run it would hide: :count',\n 'hidden-done': 'Hidden.',\n 'hidden-reason': 'Hidden: :reason',\n 'hidden-by': 'Hidden by :who: :reason',\n unhide: 'Show again',\n unhidden: 'Shown again.',\n recheck: 'Recheck',\n 'recheck-running': 'Rechecking the page…',\n 'recheck-fixed': 'Fixed since the last full run: :count',\n 'recheck-new': 'New since the last full run: :count',\n 'recheck-compare': 'Compare the runs',\n 'export-page': 'Export',\n 'runs-empty': 'No runs yet.',\n 'run-id': 'Run',\n status: 'Status',\n 'started-at': 'Started',\n 'started-by': 'Started by',\n 'by-schedule': 'Schedule',\n 'by-mcp': 'Agent',\n 'by-console': 'Console',\n 'by-person': 'Administrator',\n compare: 'Compare',\n 'compare-help':\n 'Pick two runs: what the later one found that the earlier did not, what both found, and what is gone.',\n clear: 'Clear audit data',\n 'clear-title': 'Clear all audit data?',\n 'clear-text':\n 'Every run is deleted with everything it found: findings, crawled pages, snapshots, links and the history to compare against. This cannot be undone. Hiding rules and settings stay.',\n 'clear-confirm': 'Delete everything',\n 'clear-cancel': 'Keep',\n cleared: 'Audit data cleared.',\n 'clear-running': 'An audit is running: cancel it or wait for it to finish, then clear.',\n 'compare-from': 'Earlier run',\n 'compare-to': 'Later run',\n 'compare-none': 'Both runs found the same.',\n 'compare-scopes':\n 'The runs differ in scope: only the checks the later run ran can count as fixed.',\n 'kind-new': 'New',\n 'kind-persisting': 'Persisting',\n 'kind-fixed': 'Fixed',\n 'hosts-empty': 'No run has seen a link or an address in the database yet.',\n 'search-host': 'Search by host',\n 'any-class': 'Any class',\n links: 'Links',\n fields: 'Fields in the database',\n broken: 'Broken',\n 'first-seen': 'First seen',\n 'host-pages': 'On pages',\n 'host-fields': 'In the database',\n record: 'Record',\n field: 'Field',\n unpublished: 'Not published',\n save: 'Save',\n saved: 'Saved.',\n dismiss: 'Cancel',\n 'view-full': 'View full size',\n 'view-pages': 'By page',\n 'view-links': 'By link',\n 'leads-to': 'Leads to',\n 'change-slash': 'Slash only',\n 'change-www': 'www',\n 'change-https': 'http → https',\n 'link-pages': 'Pages: :count',\n 'link-show-all': 'Show all',\n 'link-collapse': 'Collapse',\n 'attrs-opener':\n 'Opens in a new tab without noopener. Current browsers add it themselves; older ones let the opened page control this one.',\n 'section-answer': 'Server answer',\n 'section-crawl': 'Crawl',\n 'section-head': 'Markup',\n 'section-sharing': 'Preview and structured data',\n 'code-none':\n 'No answer — the server did not respond in time or the connection failed (DNS, certificate, refused). Open the address in a browser.',\n 'code-200': '200 OK — the page opens normally.',\n 'code-201': '201 Created — the server created something; a link should not lead here.',\n 'code-204': '204 No Content — answered, but with an empty page.',\n 'code-206': '206 Partial Content — a part of the file was sent, as video and downloads do.',\n 'code-301':\n '301 Moved Permanently — the address has moved for good. Update the link to where it leads.',\n 'code-302':\n '302 Found — a temporary redirect. The target may change again; search engines keep the old address.',\n 'code-303':\n '303 See Other — sent elsewhere after a form or an action; a link should point at the result.',\n 'code-304': \"304 Not Modified — the browser's copy is still current.\",\n 'code-307': '307 Temporary Redirect — like 302: temporary, the old address stays the main one.',\n 'code-308': '308 Permanent Redirect — like 301: moved for good. Update the link.',\n 'code-400':\n '400 Bad Request — the server did not understand the request; often a broken address.',\n 'code-401': '401 Unauthorized — sign-in needed. Visitors without an account cannot open it.',\n 'code-403':\n '403 Forbidden — the server refused. Many sites answer robots this way: if it opens in a browser, the link is fine.',\n 'code-404': '404 Not Found — the page is gone. Fix or remove the link.',\n 'code-405':\n '405 Method Not Allowed — the address exists but does not answer this kind of request.',\n 'code-406':\n '406 Not Acceptable — the server would not answer in a form the robot asked for; check in a browser.',\n 'code-408': '408 Request Timeout — the server gave up waiting. Usually passes; recheck later.',\n 'code-410': '410 Gone — removed on purpose and not coming back. Remove the link.',\n 'code-415': '415 Unsupported Media Type — the server refused the format of the request.',\n 'code-429':\n '429 Too Many Requests — the server asked the robot to slow down. Not a broken page.',\n 'code-451': \"451 Unavailable For Legal Reasons — blocked by law in the server's region.\",\n 'code-500':\n '500 Internal Server Error — the site behind the link broke. Recheck later; if it stays, the link is dead.',\n 'code-502': '502 Bad Gateway — the server behind a proxy did not answer. Usually temporary.',\n 'code-503': '503 Service Unavailable — overloaded or under maintenance. Usually temporary.',\n 'code-504':\n '504 Gateway Timeout — the server behind a proxy answered too slowly. Usually temporary.',\n 'code-1xx': 'An interim answer — the request is still being handled.',\n 'code-2xx': 'A success — the address answered.',\n 'code-3xx':\n 'A redirect — the address sends elsewhere. Better to link straight to where it leads.',\n 'code-4xx':\n 'A client error — the address cannot be opened as it is: missing, closed or refused.',\n 'code-5xx': 'A server error — the site behind the link failed. Often temporary; recheck later.',\n },\n}\n","import type { BadgeType } from '@webx-ui/core'\n\n/** What tells a redirect's target from its source when the rest of the address is the same. */\nexport type AddressDifference = 'slash' | 'www' | 'https'\n\n/**\n * The small differences between where a link points and where it lands: a trailing slash, `www.`,\n * `http` → `https`. Empty when the addresses differ in anything else (the page really moved) or\n * either is not an address — then there is nothing small to name.\n */\nexport function differences(from: string, to: string): AddressDifference[] {\n let source: URL\n let target: URL\n\n try {\n source = new URL(from)\n target = new URL(to, from)\n } catch {\n return []\n }\n\n const found: AddressDifference[] = []\n\n if (source.protocol === 'http:' && target.protocol === 'https:') found.push('https')\n else if (source.protocol !== target.protocol) return []\n\n const bare = (host: string) => host.replace(/^www\\./, '')\n\n if (source.host !== target.host) {\n if (bare(source.host) !== bare(target.host)) return []\n found.push('www')\n }\n\n const trimmed = (path: string) => path.replace(/\\/+$/, '')\n\n if (source.pathname !== target.pathname) {\n if (trimmed(source.pathname) !== trimmed(target.pathname)) return []\n found.push('slash')\n }\n\n if (source.search !== target.search || source.hash !== target.hash) return []\n\n return found\n}\n\n/** How many characters stay at the end of a shortened address: where a slug or a slash differs. */\nconst TAIL = 14\n\n/**\n * An address cut in two for an ellipsis in the middle: the head gives way, the tail stays —\n * the end of an address is what tells two of them apart.\n */\nexport function splitMiddle(text: string): [string, string] {\n if (text.length <= TAIL * 2) return [text, '']\n\n return [text.slice(0, -TAIL), text.slice(-TAIL)]\n}\n\n/** The colour of an answer's code. */\nexport function statusType(value: unknown): BadgeType {\n const code = Number(value)\n\n if (code >= 500 || code === 0) return 'danger'\n if (code >= 400) return 'warning'\n // A permanent redirect only asks for the link to be updated; a temporary one may move again.\n if (code === 301 || code === 308) return 'info'\n if (code >= 300) return 'warning'\n\n return 'success'\n}\n\n/** The codes with a line of their own in the dictionary; the rest are explained by their class. */\nconst EXPLAINED = [\n 200, 201, 204, 206, 301, 302, 303, 304, 307, 308, 400, 401, 403, 404, 405, 406, 408, 410, 415,\n 429, 451, 500, 502, 503, 504,\n]\n\n/** The dictionary key of what an answer means: `code-404`, `code-5xx`, or `code-none`. */\nexport function statusKey(code: number | null | undefined): string {\n if (!code) return 'code-none'\n if (EXPLAINED.includes(code)) return `code-${code}`\n if (code >= 100 && code < 600) return `code-${Math.floor(code / 100)}xx`\n\n return 'code-none'\n}\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { WxLink, WxTooltip, type LinkType } from '@webx-ui/core'\nimport { splitMiddle } from './addresses'\n\n/**\n * An address on one line, opened in a new tab: a long one loses its middle rather than wrapping,\n * since the start names the site and the end tells two addresses apart. The whole of it is in the\n * panel's tooltip.\n */\nconst props = defineProps<{ href: string; type?: LinkType; strong?: boolean }>()\n\nconst parts = computed(() => splitMiddle(props.href))\n</script>\n\n<template>\n <wx-tooltip :max-width=\"560\">\n <wx-link\n :href=\"props.href\"\n target=\"_blank\"\n :type=\"props.type\"\n :weight=\"props.strong ? 'medium' : undefined\"\n class=\"wx-audit-address\"\n ><span class=\"wx-audit-address__head\">{{ parts[0] }}</span\n ><span v-if=\"parts[1]\" class=\"wx-audit-address__tail\">{{ parts[1] }}</span></wx-link\n >\n <template #content>\n <span class=\"wx-audit-address__full\">{{ props.href }}</span>\n </template>\n </wx-tooltip>\n</template>\n\n<style scoped>\n.wx-audit-address {\n display: flex;\n gap: 0;\n min-width: 0;\n max-width: 100%;\n white-space: nowrap;\n}\n\n.wx-audit-address__head {\n overflow: hidden;\n text-overflow: ellipsis;\n min-width: 0;\n}\n\n.wx-audit-address__tail {\n flex-shrink: 0;\n}\n\n/* The tip is teleported out of this component, and an address has no spaces to wrap at. */\n:global(.wx-audit-address__full) {\n overflow-wrap: anywhere;\n}\n</style>\n","import { useAdmin } from '@webx-ui/module-admin'\nimport { auditMessages } from './messages'\n\nconst seeded = new WeakSet<object>()\n\n/** Puts this package's English under the panel's dictionary, once per panel. */\nexport function useAuditMessages(): void {\n try {\n const { i18n } = useAdmin()\n\n if (!seeded.has(i18n)) {\n i18n.defaults('webx-audit', auditMessages)\n seeded.add(i18n)\n }\n } catch {\n // Outside a panel there is no dictionary to seed, and `useTranslate` falls back on its own.\n }\n}\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useTranslate } from '@webx-ui/module-admin'\nimport { WxBadge, WxTooltip } from '@webx-ui/core'\nimport { useAuditMessages } from './i18n'\n\n/**\n * A link's `target` and `rel`, as they are in the markup: `_blank`, `nofollow`, `noopener`… Nothing\n * when the link has neither — a plain link is the usual case, not an empty cell. `_blank` without\n * `noopener` or `noreferrer` is marked: current browsers add `noopener` themselves, older ones\n * hand the opened page control of this one.\n */\nconst props = defineProps<{ rel?: string | null; target?: string | null }>()\n\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\n\nconst rels = computed(() => (props.rel ?? '').split(/\\s+/).filter(Boolean))\n\nconst opener = computed(\n () =>\n props.target?.toLowerCase() === '_blank' &&\n !rels.value.some((rel) => rel === 'noopener' || rel === 'noreferrer'),\n)\n</script>\n\n<template>\n <span v-if=\"props.target || rels.length\" class=\"wx-audit-attrs\">\n <wx-tooltip v-if=\"props.target && opener\" :content=\"t('page.attrs-opener')\" :max-width=\"320\">\n <wx-badge type=\"warning\" variant=\"outline\" size=\"sm\">{{ props.target }}</wx-badge>\n </wx-tooltip>\n <wx-badge v-else-if=\"props.target\" variant=\"outline\" size=\"sm\">{{ props.target }}</wx-badge>\n <wx-badge v-for=\"value in rels\" :key=\"value\" variant=\"outline\" size=\"sm\">{{ value }}</wx-badge>\n </span>\n</template>\n\n<style scoped>\n.wx-audit-attrs {\n display: inline-flex;\n flex-wrap: wrap;\n gap: var(--wx-space-4);\n min-width: 0;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useTranslate } from '@webx-ui/module-admin'\nimport { WxBadge, WxTooltip, type BadgeSize } from '@webx-ui/core'\nimport { statusKey, statusType } from './addresses'\nimport { useAuditMessages } from './i18n'\n\n/**\n * An answer's code as a badge of its colour, and what it means in the tooltip: the name and what\n * to do about it. A code with no line of its own is explained by its class (4xx…); none at all, or\n * 0, is «no answer».\n */\nconst props = withDefaults(defineProps<{ code: number | null | undefined; size?: BadgeSize }>(), {\n size: 'sm',\n})\n\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\n\nconst label = computed(() => (props.code ? String(props.code) : t('page.status-none')))\n</script>\n\n<template>\n <wx-tooltip :content=\"t(`page.${statusKey(props.code)}`)\" :max-width=\"360\">\n <wx-badge :type=\"statusType(props.code ?? 0)\" :size=\"props.size\">{{ label }}</wx-badge>\n </wx-tooltip>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useRouter } from 'vue-router'\nimport { useTranslate } from '@webx-ui/module-admin'\nimport { WxBadge, WxButton, WxIcon, WxText } from '@webx-ui/core'\nimport AuditAddress from './AuditAddress.vue'\nimport AuditLinkAttrs from './AuditLinkAttrs.vue'\nimport { differences } from './addresses'\nimport AuditStatus from './AuditStatus.vue'\nimport { useAuditMessages } from './i18n'\nimport type { AuditDetails, AuditDetailsColumn } from './types'\n\n/**\n * The expansion of a finding, for every check alike (§4 of the spec): a summary line and, when\n * the check gave one, a table whose cells are drawn by their type — an address opens, a code is\n * coloured, a missing value is said in red, an editor link goes to the record in the panel, and\n * markup quoted from the page is shown as code.\n *\n * The columns have widths by their type, not by what they hold, so the tables of one check line\n * up under each other. A `location` address beside a `url` is where that address leads: the row\n * reads as from → to, and a difference of a slash, `www.` or `https` is named.\n */\nconst props = defineProps<{\n details: AuditDetails\n /** The count is shown elsewhere (the head of the finding) — the summary line would repeat it. */\n counted?: boolean\n}>()\n\nconst router = useRouter()\n\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\n\nconst columns = computed(() => props.details.table?.columns ?? [])\n\nconst redirects = computed(\n () =>\n columns.value.some((column) => column.key === 'url' && column.type === 'url') &&\n columns.value.some((column) => column.key === 'location' && column.type === 'url'),\n)\n\nfunction isSource(column: AuditDetailsColumn): boolean {\n return redirects.value && column.key === 'url'\n}\n\nfunction isTarget(column: AuditDetailsColumn): boolean {\n return redirects.value && column.key === 'location'\n}\n\nfunction cell(row: Record<string, unknown>, column: AuditDetailsColumn): unknown {\n return row[column.key]\n}\n\n/** Yes, no — or nothing, when the check could not tell (the other page was not crawled). */\nfunction yesNo(value: unknown): string {\n if (value === null || value === undefined) return ''\n\n return value ? t('page.yes') : t('page.no')\n}\n\nfunction text(value: unknown): string {\n return value === null || value === undefined ? '' : String(value)\n}\n\nfunction changes(row: Record<string, unknown>) {\n return differences(text(row.url), text(row.location))\n}\n</script>\n\n<template>\n <div class=\"wx-audit-details\">\n <wx-text v-if=\"props.details.summary && !props.counted\" size=\"sm\">{{\n props.details.summary\n }}</wx-text>\n\n <div\n v-if=\"props.details.table && props.details.table.rows.length\"\n class=\"wx-audit-details__scroll\"\n >\n <table class=\"wx-audit-details__table\">\n <colgroup>\n <col\n v-for=\"column in columns\"\n :key=\"column.key\"\n :class=\"[\n `wx-audit-details__col--${column.type}`,\n `wx-audit-details__col--${column.key}`,\n ]\"\n />\n </colgroup>\n <thead>\n <tr>\n <th v-for=\"column in columns\" :key=\"column.key\">\n {{ column.label }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr v-for=\"(row, index) in props.details.table.rows\" :key=\"index\">\n <td v-for=\"column in columns\" :key=\"column.key\">\n <span v-if=\"isTarget(column) && text(cell(row, column))\" class=\"wx-audit-details__to\">\n <wx-icon\n name=\"arrow-right\"\n size=\"1em\"\n class=\"wx-audit-details__arrow\"\n :label=\"t('page.leads-to')\"\n />\n <audit-address :href=\"text(cell(row, column))\" strong />\n <wx-badge\n v-for=\"change in changes(row)\"\n :key=\"change\"\n type=\"default\"\n size=\"sm\"\n class=\"wx-audit-details__change\"\n >{{ t(`page.change-${change}`) }}</wx-badge\n >\n </span>\n <audit-address\n v-else-if=\"column.type === 'url' && text(cell(row, column))\"\n :href=\"text(cell(row, column))\"\n :type=\"isSource(column) ? 'muted' : undefined\"\n />\n <audit-status\n v-else-if=\"column.type === 'status' && cell(row, column) !== null\"\n :code=\"Number(cell(row, column))\"\n />\n <audit-link-attrs\n v-else-if=\"column.type === 'attrs'\"\n :rel=\"text(row.rel)\"\n :target=\"text(row.target)\"\n />\n <template v-else-if=\"column.type === 'bool'\">\n {{ yesNo(cell(row, column)) }}\n </template>\n <wx-text\n v-else-if=\"column.type === 'missing' && !text(cell(row, column))\"\n size=\"sm\"\n tone=\"danger\"\n >{{ t('page.missing') }}</wx-text\n >\n <wx-button\n v-else-if=\"column.type === 'edit' && text(cell(row, column))\"\n size=\"sm\"\n variant=\"text\"\n icon=\"edit\"\n @click=\"router.push(text(cell(row, column)))\"\n >{{ t('page.open-editor') }}</wx-button\n >\n <code v-else-if=\"column.type === 'code'\" class=\"wx-audit-details__code\">{{\n text(cell(row, column))\n }}</code>\n <template v-else>{{ text(cell(row, column)) }}</template>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</template>\n\n<style scoped>\n.wx-audit-details {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n/* A wide table scrolls inside itself rather than pushing the panel sideways on a phone. */\n.wx-audit-details__scroll {\n overflow-x: auto;\n}\n\n/*\n * Fixed layout: a column's width comes from its type, never from its longest cell, so every\n * finding of a check draws the same grid.\n */\n.wx-audit-details__table {\n width: 100%;\n min-width: 560px;\n table-layout: fixed;\n border-collapse: collapse;\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-details__col--status {\n width: 72px;\n}\n\n.wx-audit-details__col--bool {\n width: 96px;\n}\n\n.wx-audit-details__col--attrs {\n width: 216px;\n}\n\n/* Columns whose values are short by nature — a kind, a size, a type — by their key. */\n.wx-audit-details__col--kind,\n.wx-audit-details__col--line {\n width: 72px;\n}\n\n.wx-audit-details__col--kb,\n.wx-audit-details__col--lang,\n.wx-audit-details__col--locale {\n width: 96px;\n}\n\n.wx-audit-details__col--type {\n width: 140px;\n}\n\n.wx-audit-details__col--edit {\n width: 160px;\n}\n\n.wx-audit-details__table th {\n color: var(--wx-text-muted);\n font-weight: normal;\n text-align: left;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.wx-audit-details__table th,\n.wx-audit-details__table td {\n padding: var(--wx-space-6) var(--wx-space-8);\n border-bottom: 1px solid var(--wx-border-muted);\n vertical-align: middle;\n overflow-wrap: anywhere;\n}\n\n.wx-audit-details__table tbody tr:last-child td {\n border-bottom: 0;\n}\n\n.wx-audit-details__to {\n display: flex;\n align-items: center;\n gap: var(--wx-space-6);\n min-width: 0;\n}\n\n.wx-audit-details__arrow {\n flex-shrink: 0;\n color: var(--wx-text-muted);\n}\n\n.wx-audit-details__change {\n flex-shrink: 0;\n}\n\n/* Quoted markup is one long line more often than not; it wraps anywhere rather than scrolling. */\n.wx-audit-details__code {\n font-family: var(--wx-font-family-mono);\n font-size: var(--wx-font-size-xs);\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n}\n</style>\n","/** One heading as the parser kept it: its level and its text. */\nexport type OutlineEntry = [number, string]\n\n/** A row of the drawn tree — a heading, or a level the page jumped over (`missing`). */\nexport interface OutlineRow {\n level: number\n text: string\n missing: boolean\n /** For a missing level: the level the page jumped from. */\n after?: number\n}\n\n/**\n * The tree to draw: every heading, and between two of them the levels skipped on the way down,\n * so a gap stands where the heading should have been.\n */\nexport function outlineRows(outline: OutlineEntry[]): OutlineRow[] {\n const out: OutlineRow[] = []\n let previous = 0\n\n for (const [level, text] of outline) {\n for (let gap = previous + 1; previous > 0 && gap < level; gap++) {\n out.push({ level: gap, text: '', missing: true, after: previous })\n }\n\n out.push({ level, text, missing: false })\n previous = level\n }\n\n return out\n}\n\n/**\n * What breaks the usual order — one H1, first; each level one step below the one above; text in\n * every heading — as sentences in the reader's language. Empty when the order is fine.\n */\nexport function outlineHints(\n outline: OutlineEntry[],\n t: (key: string, params?: Record<string, string | number>) => string,\n): string[] {\n if (!outline.length) return []\n\n const ones = outline.filter(([level]) => level === 1).length\n const jumps = outline.filter(\n ([level], index) => index > 0 && level > outline[index - 1][0] + 1,\n ).length\n const empty = outline.filter(([, text]) => text === '').length\n const out: string[] = []\n\n if (ones === 0) out.push(t('page.headings-no-h1'))\n if (ones > 1) out.push(t('page.headings-many-h1', { count: ones }))\n if (ones > 0 && outline[0][0] !== 1) {\n out.push(t('page.headings-h1-not-first', { level: `H${outline[0][0]}` }))\n }\n if (jumps > 0) out.push(t('page.headings-skipped', { count: jumps }))\n if (empty > 0) out.push(t('page.headings-empty', { count: empty }))\n\n return out\n}\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useTranslate } from '@webx-ui/module-admin'\nimport { WxAlert, WxBadge, WxText } from '@webx-ui/core'\nimport { outlineHints, outlineRows, type OutlineEntry } from './headings'\nimport { useAuditMessages } from './i18n'\n\n/**\n * The page's headings as a tree: each one indented by its level, in the order the page has them.\n * The indent is the level itself, not the nesting the page managed — so a level the page jumped\n * over is drawn where it should have been, as an empty dashed row, and the gap is seen rather\n * than read about. Above the tree, what departs from the usual order, in plain words.\n */\nconst props = defineProps<{\n /** `[level, text]` in document order; null on a run crawled before the outline was kept. */\n outline: OutlineEntry[] | null\n /** How many headings of each level — to tell «none» from «not kept». */\n counts: Record<string, number>\n}>()\n\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\n\nconst rows = computed(() => outlineRows(props.outline ?? []))\n\nconst hints = computed(() => outlineHints(props.outline ?? [], t))\n\nconst total = computed(() => Object.values(props.counts).reduce((sum, count) => sum + count, 0))\n</script>\n\n<template>\n <div class=\"wx-audit-headings\">\n <wx-text v-if=\"props.outline === null && total > 0\" tone=\"muted\">{{\n t('page.headings-recheck')\n }}</wx-text>\n <wx-text v-else-if=\"!rows.length\" tone=\"muted\">{{ t('page.no-headings') }}</wx-text>\n <template v-else>\n <wx-alert v-if=\"hints.length\" type=\"warning\" variant=\"soft\" :title=\"t('page.headings-hints')\">\n <ul class=\"wx-audit-headings__hints\">\n <li v-for=\"hint in hints\" :key=\"hint\">{{ hint }}</li>\n </ul>\n </wx-alert>\n <wx-alert v-else type=\"success\" variant=\"soft\" :title=\"t('page.headings-fine')\" />\n\n <ol class=\"wx-audit-headings__tree\">\n <li\n v-for=\"(row, index) in rows\"\n :key=\"index\"\n class=\"wx-audit-headings__row\"\n :class=\"{ 'is-missing': row.missing }\"\n >\n <span v-for=\"step in row.level - 1\" :key=\"step\" class=\"wx-audit-headings__guide\" />\n <template v-if=\"row.missing\">\n <span class=\"wx-audit-headings__gap\">H{{ row.level }}</span>\n <wx-text size=\"sm\" tone=\"warning\">{{\n t('page.heading-missing', { level: `H${row.level}`, after: `H${row.after}` })\n }}</wx-text>\n </template>\n <template v-else>\n <wx-badge :type=\"row.level === 1 ? 'primary' : 'info'\" size=\"sm\"\n >H{{ row.level }}</wx-badge\n >\n <span v-if=\"row.text\" class=\"wx-audit-headings__text\">{{ row.text }}</span>\n <wx-text v-else size=\"sm\" tone=\"danger\">{{ t('page.heading-empty') }}</wx-text>\n </template>\n </li>\n </ol>\n </template>\n </div>\n</template>\n\n<style scoped>\n.wx-audit-headings {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n}\n\n.wx-audit-headings__hints {\n margin: 0;\n padding-inline-start: var(--wx-space-18);\n}\n\n.wx-audit-headings__tree {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.wx-audit-headings__row {\n display: flex;\n align-items: center;\n gap: var(--wx-space-8);\n min-height: 32px;\n}\n\n/* One step of depth: a thin line down, so the levels read as columns, like a file tree. */\n.wx-audit-headings__guide {\n align-self: stretch;\n flex: none;\n width: var(--wx-space-16);\n background: linear-gradient(var(--wx-border-default), var(--wx-border-default)) no-repeat\n calc(var(--wx-space-12) + 1px) 0 / 1px 100%;\n}\n\n/* The level that should have been here: the badge's outline, empty, in the warning colour. */\n.wx-audit-headings__gap {\n display: inline-flex;\n align-items: center;\n padding: 0 var(--wx-space-6);\n border: 1px dashed var(--wx-color-warning);\n border-radius: var(--wx-radius-sm);\n color: var(--wx-color-warning);\n font-size: var(--wx-font-size-xs);\n line-height: 18px;\n}\n\n.wx-audit-headings__text {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n</style>\n","import type { AuditResourceRow } from './types'\n\n/**\n * Whether the browser is worth asking for a picture of the page: the run reached it and it\n * answered. One past the run's limit or on the stand was never asked, and one that failed for the\n * run would fail here too — the card keeps the placeholder for those, with nothing to open.\n */\nexport function viewable(row: AuditResourceRow): boolean {\n return row.checked && row.status !== null && row.status < 400 && row.error === null\n}\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, ref, watch } from 'vue'\nimport { useRouter } from 'vue-router'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport {\n toast,\n WxAlert,\n WxBadge,\n WxButton,\n WxDrawer,\n WxIcon,\n WxImage,\n WxLink,\n WxSkeleton,\n WxTable,\n WxTabs,\n WxText,\n WxTooltip,\n type BadgeType,\n type TabItem,\n type TabValue,\n type TableColumn,\n type TableState,\n} from '@webx-ui/core'\nimport AuditDetails from './AuditDetails.vue'\nimport AuditHeadings from './AuditHeadings.vue'\nimport { outlineHints, type OutlineEntry } from './headings'\nimport { createAuditApi } from './api'\nimport { viewable } from './resources'\nimport AuditStatus from './AuditStatus.vue'\nimport { useAuditMessages } from './i18n'\nimport type {\n AuditLinkRow,\n AuditPage,\n AuditPageCard,\n AuditResourceRow,\n AuditResourceTab,\n AuditRun,\n AuditSeverity,\n} from './types'\n\n/**\n * One page of the snapshot, sliding in from the right (§8): what it answered and what its head\n * says, its findings, the links that lead in and out of it — with the answer of each own page\n * and the class of each host — what it loads (pictures, CSS, JS) with what each answered, and\n * its structured data with what the types lack.\n *\n * «Recheck» asks this one address again (a run of the `urls` scope) and says what of its findings\n * in the last full run are fixed; «Export» downloads the page — snapshot, findings and links.\n */\nconst props = defineProps<{\n run: number\n /** Where the section lives — the recheck's comparison opens on its runs. */\n base?: string\n /** The page to show; null keeps the card closed. */\n pageId: number | null\n /** Check ids and their titles in the reader's language, for the findings tab. */\n titles: Record<string, string>\n}>()\n\nconst emit = defineEmits<{ close: [] }>()\n\n/*\n * The card is wide: a page has long addresses, headers and hreflang lists. Its width is kept under\n * a key of its own, so one remembered from the narrow card of before does not keep it narrow.\n */\n\nconst context = useAdmin()\nconst api = createAuditApi(context)\nconst router = useRouter()\nuseAuditMessages()\n\nconst canRun = context.can('audit.run') || context.can('audit.manage')\nconst recheck = ref<AuditRun | null>(null)\nconst rechecking = ref(false)\nlet timer: ReturnType<typeof setTimeout> | undefined\n\nconst POLL_MS = 2000\n\n/* The page in its own words: the run it was crawled in, then one more, of just this address. */\nasync function startRecheck(): Promise<void> {\n if (!card.value) return\n\n rechecking.value = true\n recheck.value = null\n\n try {\n follow(await api.start('urls', [card.value.page.url]))\n } catch (error) {\n rechecking.value = false\n toast.danger(message(error))\n }\n}\n\nfunction follow(run: AuditRun): void {\n clearTimeout(timer)\n\n if (run.status === 'queued' || run.status === 'running') {\n timer = setTimeout(async () => {\n try {\n follow(await api.run(run.id))\n } catch (error) {\n rechecking.value = false\n toast.danger(message(error))\n }\n }, POLL_MS)\n\n return\n }\n\n rechecking.value = false\n recheck.value = run\n}\n\nfunction compareRecheck(): void {\n if (recheck.value && props.base) {\n void router.push({ path: `${props.base}/runs`, query: { to: String(recheck.value.id) } })\n }\n}\n\nonBeforeUnmount(() => clearTimeout(timer))\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\n\nconst card = ref<AuditPageCard | null>(null)\nconst failure = ref<string | null>(null)\nconst tab = ref<TabValue>('overview')\nconst links = ref<AuditPage<AuditLinkRow> | null>(null)\nconst linksLoading = ref(false)\nconst resources = ref<AuditPage<AuditResourceRow> | null>(null)\nconst resourcesLoading = ref(false)\n\nconst resourceTabs: AuditResourceTab[] = ['images', 'css', 'js']\n\nconst open = computed({\n get: () => props.pageId !== null,\n set: (value) => {\n if (!value) emit('close')\n },\n})\n\nconst tabs = computed<TabItem[]>(() => [\n { value: 'overview', label: t('page.card-overview') },\n { value: 'issues', label: t('page.card-issues'), badge: card.value?.counts.issues || undefined },\n {\n value: 'headings',\n label: t('page.card-headings'),\n badge: outline.value?.length || undefined,\n },\n { value: 'in', label: t('page.card-incoming'), badge: card.value?.counts.incoming || undefined },\n { value: 'out', label: t('page.card-outgoing'), badge: card.value?.counts.outgoing || undefined },\n { value: 'images', label: t('page.card-images'), badge: card.value?.counts.images || undefined },\n { value: 'css', label: t('page.card-css'), badge: card.value?.counts.css || undefined },\n { value: 'js', label: t('page.card-js'), badge: card.value?.counts.js || undefined },\n {\n value: 'microdata',\n label: t('page.card-microdata'),\n badge: card.value?.counts.microdata || undefined,\n },\n])\n\n/** Every heading in order; null on a run crawled before the parser kept them. */\nconst outline = computed(() => {\n const kept = card.value?.page.facts.outline\n\n return Array.isArray(kept) ? (kept as OutlineEntry[]) : null\n})\n\nconst resourceTab = computed<AuditResourceTab | null>(() =>\n resourceTabs.includes(tab.value as AuditResourceTab) ? (tab.value as AuditResourceTab) : null,\n)\n\nconst severities: Record<AuditSeverity, BadgeType> = {\n error: 'danger',\n warning: 'warning',\n notice: 'info',\n}\n\nconst hostTypes: Record<string, BadgeType> = {\n own: 'success',\n own_mirror: 'warning',\n dev: 'danger',\n external: 'info',\n}\n\nconst linkColumns = computed<TableColumn<AuditLinkRow>[]>(() => [\n { key: 'url', label: t('page.address'), minWidth: 220 },\n { key: 'status', label: t('page.field-status'), width: 80 },\n { key: 'kind', label: t('page.kind'), width: 90 },\n { key: 'anchor', label: t('page.anchor'), minWidth: 140 },\n { key: 'host_class', label: t('page.host'), width: 120 },\n])\n\n/** Pictures show their alt; stylesheets and scripts how they are cached and compressed. */\nconst resourceColumns = computed<TableColumn<AuditResourceRow>[]>(() => [\n { key: 'url', label: t('page.address'), minWidth: 220 },\n { key: 'status', label: t('page.field-status'), width: 80 },\n { key: 'bytes', label: t('page.size'), width: 110 },\n ...(resourceTab.value === 'images'\n ? [{ key: 'alt', label: t('page.alt'), minWidth: 120 }]\n : [\n { key: 'cache_control', label: t('page.cache'), minWidth: 120 },\n { key: 'compression', label: t('page.field-compression'), width: 100 },\n ]),\n])\n\n/*\n * The block indented, the way a person reads JSON. One the server cut at its length limit does not\n * parse, and is shown as the page printed it rather than not at all.\n */\nfunction pretty(source: string): string {\n try {\n return JSON.stringify(JSON.parse(source), null, 2)\n } catch {\n return source\n }\n}\n\nfunction size(row: AuditResourceRow): string {\n if (row.bytes === null) return ''\n\n const kb = row.bytes / 1024\n const text = kb >= 1024 ? `${(kb / 1024).toFixed(1)} MB` : `${Math.round(kb)} KB`\n\n return row.width && row.height ? `${text} · ${row.width}×${row.height}` : text\n}\n\n/*\n * A fact is a line, or a list: hreflang and Open Graph are key and value per row, the key set apart\n * so the eye does not run it into the value after it; JSON-LD is the types as tags.\n */\ntype Fact =\n | string\n | { pairs: [string, string][] }\n | { tags: string[]; error?: string | null }\n | { headings: number; hints: string[] }\n\n/** The numbers of the page, read at a glance before the details: one tile each. */\ninterface Tile {\n label: string\n value: string\n /** The answer's code is drawn as a badge of its colour. */\n status?: number | null\n danger?: boolean\n}\n\nfunction bytes(value: number): string {\n const kb = value / 1024\n\n return kb >= 1024 ? `${(kb / 1024).toFixed(1)} MB` : `${kb.toFixed(1)} KB`\n}\n\nconst tiles = computed<Tile[]>(() => {\n const page = card.value?.page\n\n if (!page) return []\n\n const all: (Tile | null)[] = [\n {\n label: t('page.field-status'),\n value: String(page.status ?? t('page.status-none')),\n status: page.status,\n },\n page.bytes === null ? null : { label: t('page.size'), value: bytes(page.bytes) },\n page.ttfb_ms === null ? null : { label: t('page.field-ttfb_ms'), value: String(page.ttfb_ms) },\n page.total_ms === null\n ? null\n : { label: t('page.field-total_ms'), value: String(page.total_ms) },\n page.word_count === null\n ? null\n : { label: t('page.field-word_count'), value: String(page.word_count) },\n { label: t('page.field-links_in'), value: String(page.links_in) },\n { label: t('page.field-links_out_internal'), value: String(page.links_out_internal) },\n { label: t('page.field-links_out_external'), value: String(page.links_out_external) },\n { label: t('page.field-images'), value: String(page.images) },\n page.images_without_alt\n ? {\n label: t('page.field-images_without_alt'),\n value: String(page.images_without_alt),\n danger: true,\n }\n : null,\n ]\n\n return all.filter((tile): tile is Tile => tile !== null)\n})\n\n/** The rest of what the page answered and says in its head, in sections a reader looks for. */\nconst sections = computed<{ title: string; facts: [string, Fact][] }[]>(() => {\n const page = card.value?.page\n\n if (!page) return []\n\n const groups: [string, [string, unknown][]][] = [\n [\n t('page.section-answer'),\n [\n [t('page.field-final_status'), page.redirect_to ? page.final_status : null],\n [t('page.field-redirect_to'), page.redirect_to],\n [t('page.error'), page.error],\n [t('page.field-content_type'), page.content_type],\n [t('page.field-compression'), page.compression],\n ],\n ],\n [\n t('page.section-crawl'),\n [\n [t('page.field-source'), t(`page.source-${page.source}`)],\n [t('page.field-depth'), page.depth],\n [t('page.field-indexable'), page.indexable ? t('page.yes') : t('page.no')],\n [t('page.field-blocked_by_robots'), page.blocked_by_robots ? t('page.yes') : null],\n ],\n ],\n [\n t('page.section-head'),\n [\n [t('page.field-title'), page.title],\n [t('page.field-description'), page.description],\n [t('page.field-h1'), page.h1.join(' · ') || null],\n [\n t('page.card-headings'),\n outline.value?.length\n ? { headings: outline.value.length, hints: outlineHints(outline.value, t) }\n : null,\n ],\n [t('page.field-canonical'), page.canonical],\n [t('page.field-robots_meta'), page.robots_meta],\n [t('page.field-x_robots_tag'), page.x_robots_tag],\n [t('page.field-lang'), page.lang],\n [\n 'hreflang',\n page.hreflang.length\n ? { pairs: page.hreflang.map((alternate) => [alternate.lang, alternate.url]) }\n : null,\n ],\n ],\n ],\n [\n t('page.section-sharing'),\n [\n [\n 'Open Graph',\n Object.keys(page.og).length\n ? {\n pairs: Object.entries(page.og).map(([key, value]) => [`og:${key}`, String(value)]),\n }\n : null,\n ],\n [\n 'Twitter',\n Object.keys(page.twitter).length\n ? {\n pairs: Object.entries(page.twitter).map(([key, value]) => [\n `twitter:${key}`,\n String(value),\n ]),\n }\n : null,\n ],\n [\n 'JSON-LD',\n page.json_ld.length\n ? {\n tags: page.json_ld.flatMap((block) => block.types),\n error: page.json_ld.find((block) => block.error)?.error ?? null,\n }\n : null,\n ],\n ],\n ],\n ]\n\n return groups\n .map(([title, rows]) => ({\n title,\n facts: rows\n .filter(([, value]) => value !== null && value !== undefined && value !== '')\n .map(\n ([label, value]) =>\n [label, typeof value === 'object' ? (value as Fact) : String(value)] as [string, Fact],\n ),\n }))\n .filter((section) => section.facts.length)\n})\n\nasync function load(id: number): Promise<void> {\n clearTimeout(timer)\n rechecking.value = false\n recheck.value = null\n card.value = null\n failure.value = null\n links.value = null\n resources.value = null\n tab.value = 'overview'\n\n try {\n card.value = await api.page(props.run, id)\n } catch (error) {\n failure.value = message(error)\n }\n}\n\nasync function loadLinks(state: TableState): Promise<void> {\n if (props.pageId === null || (tab.value !== 'in' && tab.value !== 'out')) return\n\n linksLoading.value = true\n\n try {\n links.value = await api.links(props.run, props.pageId, {\n direction: tab.value,\n page: state.page,\n per_page: state.perPage,\n })\n } catch (error) {\n failure.value = message(error)\n } finally {\n linksLoading.value = false\n }\n}\n\nasync function loadResources(state: TableState): Promise<void> {\n const current = resourceTab.value\n\n if (props.pageId === null || current === null) return\n\n resourcesLoading.value = true\n\n try {\n resources.value = await api.resources(props.run, props.pageId, {\n tab: current,\n page: state.page,\n per_page: state.perPage,\n })\n } catch (error) {\n failure.value = message(error)\n } finally {\n resourcesLoading.value = false\n }\n}\n\nwatch(\n () => props.pageId,\n (id) => {\n if (id !== null) void load(id)\n },\n { immediate: true },\n)\n\nwatch(tab, () => {\n links.value = null\n resources.value = null\n})\n</script>\n\n<template>\n <wx-drawer\n v-model:open=\"open\"\n size=\"min(1100px, 75vw)\"\n :min-size=\"480\"\n resizable\n persist=\"webx-audit.page-card-wide\"\n >\n <template #title>\n <span class=\"wx-audit-card__title\">\n <audit-status v-if=\"card\" :code=\"card.page.status\" />\n <span class=\"wx-audit-card__url\">{{ card?.page.url ?? '' }}</span>\n </span>\n </template>\n\n <template #extra>\n <span v-if=\"card\" class=\"wx-audit-card__extra\">\n <wx-button\n v-if=\"canRun\"\n size=\"sm\"\n icon=\"refresh\"\n :loading=\"rechecking\"\n @click=\"startRecheck\"\n >{{ t('page.recheck') }}</wx-button\n >\n <wx-button\n size=\"sm\"\n variant=\"text\"\n icon=\"download\"\n :href=\"api.pageFile(props.run, card.page.id)\"\n >{{ t('page.export-page') }}</wx-button\n >\n <wx-link :href=\"card.page.url\" target=\"_blank\">{{ t('page.open-page') }}</wx-link>\n </span>\n </template>\n\n <wx-text v-if=\"failure\" tone=\"danger\">{{ failure }}</wx-text>\n <wx-skeleton v-else-if=\"!card\" :rows=\"6\" />\n\n <div v-else class=\"wx-audit-card\">\n <wx-alert v-if=\"rechecking\" type=\"info\" :description=\"t('page.recheck-running')\" />\n <wx-alert\n v-else-if=\"recheck && recheck.status === 'done' && recheck.counts\"\n :type=\"recheck.counts.new > 0 ? 'warning' : 'success'\"\n >\n <div class=\"wx-audit-card__recheck\">\n <span>{{ t('page.recheck-fixed', { count: recheck.counts.fixed }) }}</span>\n <span>{{ t('page.recheck-new', { count: recheck.counts.new }) }}</span>\n <wx-button v-if=\"props.base\" size=\"sm\" variant=\"text\" @click=\"compareRecheck\">{{\n t('page.recheck-compare')\n }}</wx-button>\n </div>\n </wx-alert>\n <wx-alert\n v-else-if=\"recheck\"\n type=\"danger\"\n :description=\"recheck.error ?? t(`page.status-${recheck.status}`)\"\n />\n <wx-text v-if=\"card.page.title\" weight=\"semibold\">{{ card.page.title }}</wx-text>\n\n <wx-tabs v-model=\"tab\" :items=\"tabs\">\n <div v-if=\"tab === 'overview'\" class=\"wx-audit-card__overview\">\n <div class=\"wx-audit-card__tiles\">\n <div v-for=\"tile in tiles\" :key=\"tile.label\" class=\"wx-audit-card__tile\">\n <wx-text size=\"sm\" tone=\"muted\">{{ tile.label }}</wx-text>\n <audit-status v-if=\"tile.status !== undefined\" :code=\"tile.status\" size=\"md\" />\n <wx-text\n v-else\n weight=\"semibold\"\n :tone=\"tile.danger ? 'danger' : undefined\"\n class=\"wx-audit-card__number\"\n >{{ tile.value }}</wx-text\n >\n </div>\n </div>\n\n <section v-for=\"section in sections\" :key=\"section.title\" class=\"wx-audit-card__box\">\n <div class=\"wx-audit-card__box-head\">{{ section.title }}</div>\n <dl class=\"wx-audit-card__facts\">\n <template v-for=\"[label, value] in section.facts\" :key=\"label\">\n <dt>{{ label }}</dt>\n <dd v-if=\"typeof value === 'string'\">{{ value }}</dd>\n <dd v-else-if=\"'pairs' in value\" class=\"wx-audit-card__pairs\">\n <template v-for=\"([key, text], index) in value.pairs\" :key=\"index\">\n <code class=\"wx-audit-card__key\">{{ key }}</code>\n <span>{{ text }}</span>\n </template>\n </dd>\n <dd v-else-if=\"'headings' in value\" class=\"wx-audit-card__heading-fact\">\n <span>\n <wx-text :tone=\"value.hints.length ? 'warning' : 'success'\">{{\n value.hints.length\n ? t('page.headings-summary-bad', { count: value.headings })\n : t('page.headings-summary-ok', { count: value.headings })\n }}</wx-text>\n <wx-link\n as=\"button\"\n class=\"wx-audit-card__heading-open\"\n @click=\"tab = 'headings'\"\n >{{ t('page.headings-open') }}</wx-link\n >\n </span>\n <ul v-if=\"value.hints.length\" class=\"wx-audit-card__heading-hints\">\n <li v-for=\"hint in value.hints\" :key=\"hint\">{{ hint }}</li>\n </ul>\n </dd>\n <dd v-else class=\"wx-audit-card__tags\">\n <wx-badge v-for=\"(tag, index) in value.tags\" :key=\"index\" type=\"info\" size=\"sm\">{{\n tag\n }}</wx-badge>\n <wx-text v-if=\"value.error\" size=\"sm\" tone=\"danger\">{{ value.error }}</wx-text>\n </dd>\n </template>\n </dl>\n </section>\n\n <section v-if=\"Object.keys(card.page.headers).length\" class=\"wx-audit-card__box\">\n <div class=\"wx-audit-card__box-head\">{{ t('page.headers') }}</div>\n <dl class=\"wx-audit-card__facts\">\n <template v-for=\"(value, name) in card.page.headers\" :key=\"name\">\n <dt class=\"wx-audit-card__code\">{{ name }}</dt>\n <dd class=\"wx-audit-card__code\">{{ value }}</dd>\n </template>\n </dl>\n </section>\n </div>\n\n <div v-else-if=\"tab === 'headings'\" class=\"wx-audit-card__box wx-audit-card__headings\">\n <audit-headings :outline=\"outline\" :counts=\"card.page.headings\" />\n </div>\n\n <div v-else-if=\"tab === 'issues'\" class=\"wx-audit-card__issues\">\n <wx-text v-if=\"!card.issues.length\" tone=\"muted\">{{ t('page.no-issues') }}</wx-text>\n <div v-for=\"issue in card.issues\" :key=\"issue.id\" class=\"wx-audit-card__box\">\n <div class=\"wx-audit-card__box-head wx-audit-card__issue-head\">\n <wx-badge :type=\"severities[issue.severity]\" dot>{{\n t(`page.severity-${issue.severity}`)\n }}</wx-badge>\n <wx-text size=\"sm\" weight=\"semibold\">{{\n props.titles[issue.check] ?? issue.check\n }}</wx-text>\n <wx-badge v-if=\"issue.state === 'new'\" type=\"primary\" size=\"sm\">{{\n t('page.state-new')\n }}</wx-badge>\n <wx-tooltip\n v-if=\"issue.details.count != null && issue.details.table\"\n :content=\"issue.details.summary ?? undefined\"\n :disabled=\"!issue.details.summary\"\n >\n <wx-badge round size=\"sm\">{{ issue.details.count }}</wx-badge>\n </wx-tooltip>\n </div>\n <div class=\"wx-audit-card__box-body\">\n <audit-details\n :details=\"issue.details\"\n :counted=\"issue.details.count != null && !!issue.details.table\"\n />\n </div>\n </div>\n </div>\n\n <wx-table\n v-else-if=\"resourceTab\"\n :key=\"`resources-${String(tab)}`\"\n :data=\"resources\"\n :columns=\"resourceColumns\"\n row-key=\"id\"\n flush\n :loading=\"resourcesLoading\"\n :per-page-options=\"[]\"\n :empty-text=\"t('page.no-resources')\"\n @state-change=\"loadResources\"\n >\n <template #cell-url=\"{ row }\">\n <span v-if=\"resourceTab === 'images'\" class=\"wx-audit-card__picture\">\n <!-- Only a picture that answered is fetched: the stand's and a broken one keep the\n placeholder rather than a request the browser is sure to lose. -->\n <wx-image\n :src=\"viewable(row) ? row.url : undefined\"\n :alt=\"row.alt ?? ''\"\n :width=\"48\"\n :height=\"48\"\n fit=\"cover\"\n radius=\"var(--wx-radius-sm)\"\n preview\n :preview-label=\"t('page.view-full')\"\n class=\"wx-audit-card__thumb\"\n :class=\"{ 'is-unviewable': !viewable(row) }\"\n >\n <template v-if=\"!viewable(row)\" #placeholder>\n <wx-icon name=\"image\" />\n </template>\n </wx-image>\n <span class=\"wx-audit-card__url\">{{ row.url }}</span>\n </span>\n <span v-else class=\"wx-audit-card__url\">{{ row.url }}</span>\n <wx-text v-if=\"row.location\" size=\"sm\" tone=\"muted\" class=\"wx-audit-card__url\">\n → {{ row.location }}</wx-text\n >\n <wx-text v-if=\"row.error\" size=\"sm\" tone=\"danger\">{{ row.error }}</wx-text>\n </template>\n <template #cell-status=\"{ row }\">\n <audit-status v-if=\"row.status !== null || row.checked\" :code=\"row.status\" />\n <wx-text v-else size=\"sm\" tone=\"muted\">{{ t('page.not-checked') }}</wx-text>\n </template>\n <template #cell-bytes=\"{ row }\">{{ size(row) }}</template>\n <template #cell-alt=\"{ row }\">\n <wx-text v-if=\"row.alt === null && row.kind === 'img'\" size=\"sm\" tone=\"danger\">{{\n t('page.missing')\n }}</wx-text>\n <template v-else>{{ row.alt ?? '' }}</template>\n </template>\n </wx-table>\n\n <div v-else-if=\"tab === 'microdata'\" class=\"wx-audit-card__issues\">\n <wx-text v-if=\"!card.page.json_ld.length\" tone=\"muted\">{{\n t('page.no-json-ld')\n }}</wx-text>\n <div\n v-for=\"(block, index) in card.page.json_ld\"\n :key=\"index\"\n class=\"wx-audit-card__issue\"\n >\n <div class=\"wx-audit-card__issue-head\">\n <wx-text size=\"sm\" weight=\"semibold\">{{\n t('page.jsonld-block', { number: index + 1 })\n }}</wx-text>\n <wx-badge v-for=\"type in block.types\" :key=\"type\" size=\"sm\">{{ type }}</wx-badge>\n </div>\n <wx-text v-if=\"block.error\" size=\"sm\" tone=\"danger\"\n >{{ t('page.jsonld-error') }} {{ block.error }}</wx-text\n >\n <template v-for=\"(item, position) in block.items ?? []\" :key=\"position\">\n <wx-text v-if=\"item.missing.length\" size=\"sm\" tone=\"danger\"\n >{{ item.type }} — {{ t('page.jsonld-required') }}\n {{ item.missing.join(', ') }}</wx-text\n >\n <wx-text v-if=\"item.recommended.length\" size=\"sm\" tone=\"muted\"\n >{{ item.type }} — {{ t('page.jsonld-recommended') }}\n {{ item.recommended.join(', ') }}</wx-text\n >\n <wx-text\n v-if=\"!item.missing.length && !item.recommended.length\"\n size=\"sm\"\n tone=\"success\"\n >{{ item.type }} — {{ t('page.jsonld-complete') }}</wx-text\n >\n </template>\n <pre v-if=\"block.source\" class=\"wx-audit-card__source\">{{ pretty(block.source) }}</pre>\n </div>\n </div>\n\n <wx-table\n v-else\n :key=\"String(tab)\"\n :data=\"links\"\n :columns=\"linkColumns\"\n row-key=\"id\"\n flush\n :loading=\"linksLoading\"\n :per-page-options=\"[]\"\n :empty-text=\"t('page.no-links')\"\n @state-change=\"loadLinks\"\n >\n <template #cell-url=\"{ row }\">\n <span class=\"wx-audit-card__url\">{{ row.url ?? '—' }}</span>\n </template>\n <template #cell-status=\"{ row }\">\n <audit-status v-if=\"row.status !== null\" :code=\"row.status\" />\n </template>\n <template #cell-host_class=\"{ row }\">\n <wx-badge v-if=\"row.host_class\" :type=\"hostTypes[row.host_class] ?? 'info'\" size=\"sm\">{{\n t(`page.host-${row.host_class}`)\n }}</wx-badge>\n </template>\n </wx-table>\n </wx-tabs>\n </div>\n </wx-drawer>\n</template>\n\n<style scoped>\n.wx-audit-card {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n min-width: 0;\n /* The card decides its layout by its own width, not the window's. */\n container-type: inline-size;\n}\n\n.wx-audit-card__title {\n display: inline-flex;\n align-items: center;\n gap: var(--wx-space-8);\n min-width: 0;\n}\n\n.wx-audit-card__url {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n\n.wx-audit-card__overview {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n margin-top: var(--wx-space-12);\n min-width: 0;\n}\n\n/* The numbers first: what a reader compares between pages, at a glance. */\n.wx-audit-card__tiles {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));\n gap: var(--wx-space-8);\n}\n\n.wx-audit-card__tile {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n /* A label on two lines must not lift its number above its neighbours' — the numbers sit on one line. */\n justify-content: space-between;\n gap: var(--wx-space-4);\n min-width: 0;\n padding: var(--wx-space-8) var(--wx-space-12);\n border: 1px solid var(--wx-border-default);\n border-radius: var(--wx-radius-md);\n background: var(--wx-bg-surface);\n}\n\n.wx-audit-card__number {\n font-size: var(--wx-font-size-lg);\n}\n\n/* A section, or a finding: an edge of its own, a tinted head, the content under it. */\n.wx-audit-card__box {\n min-width: 0;\n border: 1px solid var(--wx-border-default);\n border-radius: var(--wx-radius-md);\n background: var(--wx-bg-surface);\n overflow: hidden;\n}\n\n.wx-audit-card__heading-fact {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-4);\n}\n\n.wx-audit-card__heading-open {\n margin-inline-start: var(--wx-space-8);\n}\n\n.wx-audit-card__heading-hints {\n margin: 0;\n padding-inline-start: var(--wx-space-18);\n color: var(--wx-text-muted);\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-card__headings {\n padding: var(--wx-space-12) var(--wx-space-16);\n}\n\n.wx-audit-card__box-head {\n padding: var(--wx-space-8) var(--wx-space-12);\n border-bottom: 1px solid var(--wx-border-muted);\n background: var(--wx-bg-subtle);\n font-size: var(--wx-font-size-sm);\n font-weight: var(--wx-font-weight-semibold);\n}\n\n.wx-audit-card__box-body {\n padding: var(--wx-space-8) var(--wx-space-12);\n}\n\n/* One label column for every section, so the values start on one line down the card. */\n.wx-audit-card__facts {\n display: grid;\n grid-template-columns: 200px minmax(0, 1fr);\n gap: var(--wx-space-8) var(--wx-space-16);\n margin: 0;\n padding: var(--wx-space-12);\n font-size: var(--wx-font-size-sm);\n}\n\n.wx-audit-card__facts dt {\n color: var(--wx-text-muted);\n}\n\n.wx-audit-card__facts dd {\n margin: 0;\n overflow-wrap: anywhere;\n white-space: pre-line;\n}\n\n/* Key and value in two columns of their own: the keys start on one line, so do the values. */\n.wx-audit-card__pairs {\n display: grid;\n grid-template-columns: max-content minmax(0, 1fr);\n gap: var(--wx-space-6) var(--wx-space-12);\n align-items: baseline;\n}\n\n.wx-audit-card__key {\n color: var(--wx-text-muted);\n font-family: var(--wx-font-family-mono);\n font-size: var(--wx-font-size-xs);\n}\n\n.wx-audit-card__tags {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-6);\n}\n\n.wx-audit-card__code {\n font-family: var(--wx-font-family-mono);\n}\n\n.wx-audit-card__issues {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-16);\n margin-top: var(--wx-space-12);\n}\n\n.wx-audit-card__issue {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-6);\n min-width: 0;\n}\n\n/* A picture is recognised by sight faster than by its hashed file name. */\n.wx-audit-card__picture {\n display: flex;\n align-items: center;\n gap: var(--wx-space-12);\n min-width: 0;\n}\n\n.wx-audit-card__thumb {\n flex: none;\n}\n\n/* The same box as a picture that would not load, with the same mark — nothing here to open. */\n.wx-audit-card__thumb.is-unviewable :deep(.wx-image__placeholder .wx-icon) {\n width: 32px;\n height: 32px;\n}\n\n.wx-audit-card__source {\n max-height: 480px;\n margin: 0;\n padding: var(--wx-space-8);\n overflow: auto;\n border-radius: var(--wx-radius-sm);\n background: var(--wx-bg-muted);\n font-family: var(--wx-font-family-mono);\n font-size: var(--wx-font-size-xs);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n\n.wx-audit-card__issue-head {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-8);\n}\n\n/* A narrow card: the label goes above its value instead of beside it. */\n@container (max-width: 560px) {\n .wx-audit-card__facts {\n grid-template-columns: minmax(0, 1fr);\n row-gap: var(--wx-space-2);\n }\n\n .wx-audit-card__facts dd + dt {\n margin-top: var(--wx-space-8);\n }\n}\n\n.wx-audit-card__extra {\n display: inline-flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-8);\n}\n\n.wx-audit-card__recheck {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--wx-space-4) var(--wx-space-12);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport { WxButton, WxDialog, WxFormItem, WxInput, WxText, WxTextarea, toast } from '@webx-ui/core'\nimport { createAuditApi } from './api'\nimport { useAuditMessages } from './i18n'\nimport type { AuditIgnoreRule, AuditIssue } from './types'\n\n/**\n * «Hide» on a finding (decision 9): which addresses — this one, a mask of them, or the whole\n * check — and why. While the mask is typed the dialog says how many findings of the last run it\n * would hide; nothing is hidden until the button is pressed, and nothing is ever deleted.\n */\nconst props = defineProps<{ issue: AuditIssue; title: string }>()\nconst emit = defineEmits<{ hidden: [rule: AuditIgnoreRule] }>()\nconst open = defineModel<boolean>('open', { default: false })\n\nconst api = createAuditApi(useAdmin())\nuseAuditMessages()\n\nconst t = useTranslate('webx-audit')\nconst message = useErrorText()\n\nconst pattern = ref('')\nconst reason = ref('')\nconst count = ref<number | null>(null)\nconst saving = ref(false)\nlet timer: ReturnType<typeof setTimeout> | undefined\n\n/* The path, not the whole address: a mask of the path hides it on every mirror a run opened. */\nfunction pathOf(url: string | null): string {\n if (!url) return ''\n\n try {\n const parsed = new URL(url)\n\n return parsed.pathname + parsed.search\n } catch {\n return url\n }\n}\n\nconst ready = computed(() => reason.value.trim() !== '')\n\nfunction preview(): void {\n clearTimeout(timer)\n timer = setTimeout(async () => {\n try {\n count.value = await api.hidePreview({ check: props.issue.check, pattern: pattern.value })\n } catch {\n count.value = null\n }\n }, 300)\n}\n\nasync function hide(): Promise<void> {\n saving.value = true\n\n try {\n const rule = await api.hide({\n check: props.issue.check,\n pattern: pattern.value,\n reason: reason.value,\n })\n\n toast.success(t('page.hidden-done'))\n emit('hidden', rule)\n open.value = false\n } catch (error) {\n toast.danger(message(error))\n } finally {\n saving.value = false\n }\n}\n\nwatch(\n [open, () => props.issue.id],\n ([now]) => {\n if (!now) return\n\n pattern.value = pathOf(props.issue.url)\n reason.value = ''\n count.value = null\n preview()\n },\n { immediate: true },\n)\n\nwatch(pattern, () => {\n if (open.value) preview()\n})\n</script>\n\n<template>\n <wx-dialog v-model:open=\"open\" :title=\"t('page.hide-title')\" :width=\"560\">\n <div class=\"wx-audit-hide\">\n <wx-text weight=\"semibold\">{{ props.title }}</wx-text>\n <wx-text size=\"sm\" tone=\"muted\">{{ t('page.hide-help') }}</wx-text>\n\n <wx-form-item :label=\"t('page.hide-pattern')\" :help=\"t('page.hide-pattern-help')\">\n <wx-input v-model=\"pattern\" placeholder=\"/search/**\" />\n </wx-form-item>\n\n <wx-form-item :label=\"t('page.hide-reason')\" required>\n <wx-textarea v-model=\"reason\" :rows=\"3\" />\n </wx-form-item>\n\n <wx-text v-if=\"count !== null\" size=\"sm\" tone=\"muted\">{{\n t('page.hide-count', { count })\n }}</wx-text>\n </div>\n\n <template #footer>\n <wx-button @click=\"open = false\">{{ t('page.dismiss') }}</wx-button>\n <wx-button type=\"primary\" :loading=\"saving\" :disabled=\"!ready\" @click=\"hide\">{{\n t('page.hide')\n }}</wx-button>\n </template>\n </wx-dialog>\n</template>\n\n<style scoped>\n.wx-audit-hide {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-12);\n min-width: 0;\n}\n</style>\n","import type { AuditFieldType, AuditFilterOp, AuditPageField } from './types'\n\n/**\n * The fields of the snapshot, as `PageColumns` lists them on the server: what the pages screen\n * can show, filter on, sort by and export. Kept in the same order, so the column picker reads\n * like the page's card — address and answer first, markup, then speed and links.\n */\nexport const PAGE_FIELDS: Record<AuditPageField, AuditFieldType> = {\n url: 'url',\n status: 'status',\n final_status: 'status',\n redirect_to: 'url',\n source: 'source',\n depth: 'number',\n indexable: 'bool',\n issues: 'number',\n title: 'text',\n description: 'text',\n h1: 'text',\n canonical: 'url',\n robots_meta: 'text',\n x_robots_tag: 'text',\n lang: 'text',\n content_type: 'text',\n bytes: 'number',\n ttfb_ms: 'number',\n total_ms: 'number',\n compression: 'text',\n word_count: 'number',\n links_in: 'number',\n links_out_internal: 'number',\n links_out_external: 'number',\n images: 'number',\n images_without_alt: 'number',\n in_sitemap: 'bool',\n in_registry: 'bool',\n blocked_by_robots: 'bool',\n}\n\nexport const DEFAULT_COLUMNS: AuditPageField[] = [\n 'url',\n 'status',\n 'indexable',\n 'title',\n 'word_count',\n 'links_in',\n 'issues',\n]\n\n/** `h1` is read out of a JSON list: shown and exported, not filtered or sorted on. */\nexport const COMPUTED_FIELDS: AuditPageField[] = ['h1']\n\n/** What can be asked of a field of each type. */\nexport const OPERATIONS: Record<AuditFieldType, AuditFilterOp[]> = {\n url: ['contains', 'eq', 'empty', 'filled'],\n text: ['contains', 'eq', 'empty', 'filled'],\n number: ['gt', 'lt', 'eq', 'empty'],\n status: ['eq', 'gt', 'lt', 'empty'],\n bool: ['yes', 'no'],\n source: ['eq'],\n}\n\n/** The operations that need a value typed beside them. */\nexport const WITH_VALUE: AuditFilterOp[] = ['contains', 'eq', 'gt', 'lt']\n\nexport const SOURCES = ['home', 'sitemap', 'registry', 'link'] as const\n","import { defineAsyncComponent } from 'vue'\nexport { audit, type AuditOptions } from './module'\nexport { createAuditApi, pageParams, type AuditApi } from './api'\nexport { auditMessages } from './messages'\nexport const WxAuditOverviewPage = defineAsyncComponent(() => import('./AuditOverviewPage.vue'))\nexport const WxAuditIssuesPage = defineAsyncComponent(() => import('./AuditIssuesPage.vue'))\nexport { default as WxAuditDetails } from './AuditDetails.vue'\nexport const WxAuditPagesPage = defineAsyncComponent(() => import('./AuditPagesPage.vue'))\nexport { default as WxAuditPageCard } from './AuditPageCard.vue'\nexport const WxAuditHostsPage = defineAsyncComponent(() => import('./AuditHostsPage.vue'))\nexport const WxAuditRunsPage = defineAsyncComponent(() => import('./AuditRunsPage.vue'))\nexport const WxAuditSettingsPage = defineAsyncComponent(() => import('./AuditSettingsPage.vue'))\nexport { default as WxAuditHideDialog } from './AuditHideDialog.vue'\nexport { PAGE_FIELDS, DEFAULT_COLUMNS } from './fields'\nexport type {\n AuditCellType,\n AuditCheckRow,\n AuditComparison,\n AuditComparisonKind,\n AuditComparisonRow,\n AuditCounts,\n AuditDetails,\n AuditDetailsColumn,\n AuditFieldFilter,\n AuditFieldType,\n AuditFilterOp,\n AuditFixChange,\n AuditFixOffer,\n AuditFixResult,\n AuditHostClass,\n AuditHostField,\n AuditHostPage,\n AuditHostRow,\n AuditHosts,\n AuditIgnoreRule,\n AuditIssue,\n AuditIssueQuery,\n AuditJsonLdBlock,\n AuditLatest,\n AuditLinkRow,\n AuditPage,\n AuditPageCard,\n AuditPageField,\n AuditPageQuery,\n AuditPageRow,\n AuditPageSource,\n AuditResourceRow,\n AuditResourceTab,\n AuditRun,\n AuditRunStatus,\n AuditScope,\n AuditSeverity,\n AuditStage,\n} from './types'\n"],"names":["audit","options","path","props","pageParams","query","params","filter","createAuditApi","admin","base","data","body","filters","id","scope","urls","run","columns","key","value","issue","fix","dryRun","to","from","rule","values","auditMessages","differences","source","target","found","bare","host","trimmed","TAIL","splitMiddle","text","statusType","code","EXPLAINED","statusKey","__props","parts","computed","_createBlock","_unref","WxTooltip","_createElementVNode","_hoisted_3","_toDisplayString","_createVNode","WxLink","_hoisted_1","_createElementBlock","_hoisted_2","seeded","useAuditMessages","i18n","useAdmin","t","useTranslate","rels","opener","rel","_openBlock","WxBadge","_createTextVNode","_Fragment","_renderList","label","router","useRouter","redirects","column","isSource","isTarget","cell","row","yesNo","changes","WxText","_normalizeClass","index","_hoisted_4","WxIcon","AuditAddress","change","AuditStatus","AuditLinkAttrs","WxButton","$event","_hoisted_5","outlineRows","outline","out","previous","level","gap","outlineHints","ones","jumps","empty","rows","hints","total","sum","count","WxAlert","hint","step","viewable","POLL_MS","emit","__emit","context","api","canRun","recheck","ref","rechecking","timer","startRecheck","card","follow","error","toast","message","compareRecheck","onBeforeUnmount","useErrorText","failure","tab","links","linksLoading","resources","resourcesLoading","resourceTabs","open","tabs","kept","resourceTab","severities","hostTypes","linkColumns","resourceColumns","pretty","size","kb","bytes","tiles","page","tile","sections","alternate","block","title","section","load","loadLinks","state","loadResources","current","watch","WxDrawer","WxTabs","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","tag","_hoisted_16","_hoisted_17","_hoisted_18","name","_hoisted_19","_hoisted_20","_hoisted_21","AuditHeadings","_hoisted_22","_hoisted_23","_hoisted_24","AuditDetails","WxTable","_withCtx","_hoisted_25","WxImage","_hoisted_26","_hoisted_27","_hoisted_28","_hoisted_29","type","item","position","_hoisted_30","_hoisted_31","WxSkeleton","_useModel","pattern","reason","saving","pathOf","url","parsed","ready","preview","hide","now","WxDialog","WxFormItem","WxInput","WxTextarea","PAGE_FIELDS","DEFAULT_COLUMNS","COMPUTED_FIELDS","OPERATIONS","WITH_VALUE","SOURCES","WxAuditOverviewPage","defineAsyncComponent","WxAuditIssuesPage","WxAuditPagesPage","WxAuditHostsPage","WxAuditRunsPage","WxAuditSettingsPage"],"mappings":"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"}
|