@aglyn/plugins-ai 1.0.0-beta.291 → 1.0.0-beta.293
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/package.json +17 -17
- package/src/lib/components/ai-site-import-job.component.js +5 -4
- package/src/lib/components/ai-site-import-job.component.js.map +1 -1
- package/src/lib/components/ai-site-import-start.component.js +3 -3
- package/src/lib/components/ai-site-import-start.component.js.map +1 -1
- package/src/lib/components/ai-site-start-card.component.d.ts +1 -1
- package/src/lib/components/ai-site-start-card.component.js +129 -29
- package/src/lib/components/ai-site-start-card.component.js.map +1 -1
- package/src/lib/components/ai-site-start-steps.component.d.ts +15 -3
- package/src/lib/components/ai-site-start-steps.component.js +42 -25
- package/src/lib/components/ai-site-start-steps.component.js.map +1 -1
- package/src/lib/components/ai-site-style-previews.d.ts +17 -0
- package/src/lib/components/ai-site-style-previews.js +26 -95
- package/src/lib/components/ai-site-style-previews.js.map +1 -1
- package/src/lib/declarations.server.js +22 -0
- package/src/lib/declarations.server.js.map +1 -1
- package/src/lib/jobs/ai-job-import-step.d.ts +21 -2
- package/src/lib/jobs/ai-job-import-step.js +179 -49
- package/src/lib/jobs/ai-job-import-step.js.map +1 -1
- package/src/lib/jobs/ai-job-layout-language.d.ts +27 -3
- package/src/lib/jobs/ai-job-layout-language.js +156 -113
- package/src/lib/jobs/ai-job-layout-language.js.map +1 -1
- package/src/lib/jobs/ai-job-layout-step.js +56 -17
- package/src/lib/jobs/ai-job-layout-step.js.map +1 -1
- package/src/lib/jobs/ai-job-page-language.d.ts +25 -15
- package/src/lib/jobs/ai-job-page-language.js +120 -66
- package/src/lib/jobs/ai-job-page-language.js.map +1 -1
- package/src/lib/jobs/ai-job-page-step.js +27 -7
- package/src/lib/jobs/ai-job-page-step.js.map +1 -1
- package/src/lib/jobs/ai-job-site-datasets.d.ts +12 -4
- package/src/lib/jobs/ai-job-site-datasets.js +36 -16
- package/src/lib/jobs/ai-job-site-datasets.js.map +1 -1
- package/src/lib/jobs/ai-jobs.js +6 -2
- package/src/lib/jobs/ai-jobs.js.map +1 -1
- package/src/lib/jobs/ai-layout-stock-photos.d.ts +50 -1
- package/src/lib/jobs/ai-layout-stock-photos.js +586 -35
- package/src/lib/jobs/ai-layout-stock-photos.js.map +1 -1
- package/src/lib/jobs/ai-site-import-compile.d.ts +147 -0
- package/src/lib/jobs/ai-site-import-compile.js +1143 -0
- package/src/lib/jobs/ai-site-import-compile.js.map +1 -0
- package/src/lib/jobs/ai-site-import-document.d.ts +9 -36
- package/src/lib/jobs/ai-site-import-document.js +23 -489
- package/src/lib/jobs/ai-site-import-document.js.map +1 -1
- package/src/lib/jobs/ai-site-import-look.d.ts +54 -7
- package/src/lib/jobs/ai-site-import-look.js +163 -52
- package/src/lib/jobs/ai-site-import-look.js.map +1 -1
- package/src/lib/jobs/ai-site-import-publish.d.ts +7 -1
- package/src/lib/jobs/ai-site-import-publish.js +19 -5
- package/src/lib/jobs/ai-site-import-publish.js.map +1 -1
- package/src/lib/jobs/ai-site-late-photos.js +4 -2
- package/src/lib/jobs/ai-site-late-photos.js.map +1 -1
- package/src/lib/jobs/ai-site-publish.d.ts +10 -1
- package/src/lib/jobs/ai-site-publish.js +8 -3
- package/src/lib/jobs/ai-site-publish.js.map +1 -1
- package/src/lib/jobs/fixtures/ai-stock-photo-agl4092-1029-recordings.d.ts +23 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-agl4092-1029-recordings.js +677 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-agl4092-1029-recordings.js.map +1 -0
- package/src/lib/layout-language/ai-layout-compiler.d.ts +26 -0
- package/src/lib/layout-language/ai-layout-compiler.js +677 -33
- package/src/lib/layout-language/ai-layout-compiler.js.map +1 -1
- package/src/lib/layout-language/ai-layout-frame-hollows.js +5 -1
- package/src/lib/layout-language/ai-layout-frame-hollows.js.map +1 -1
- package/src/lib/layout-language/ai-layout-frame-source.d.ts +196 -0
- package/src/lib/layout-language/ai-layout-frame-source.js +726 -0
- package/src/lib/layout-language/ai-layout-frame-source.js.map +1 -0
- package/src/lib/layout-language/ai-layout-frame.d.ts +22 -0
- package/src/lib/layout-language/ai-layout-frame.js +121 -29
- package/src/lib/layout-language/ai-layout-frame.js.map +1 -1
- package/src/lib/layout-language/ai-layout-language.d.ts +103 -37
- package/src/lib/layout-language/ai-layout-language.js +85 -120
- package/src/lib/layout-language/ai-layout-language.js.map +1 -1
- package/src/lib/model/ai-credit-estimate.d.ts +11 -7
- package/src/lib/model/ai-credit-estimate.js +11 -7
- package/src/lib/model/ai-credit-estimate.js.map +1 -1
- package/src/lib/model/ai-site-import.d.ts +307 -13
- package/src/lib/model/ai-site-import.js +227 -19
- package/src/lib/model/ai-site-import.js.map +1 -1
- package/src/lib/model/ai-site-look.d.ts +65 -1
- package/src/lib/model/ai-site-look.js +141 -23
- package/src/lib/model/ai-site-look.js.map +1 -1
- package/src/lib/model/ai-site-photos.d.ts +2 -0
- package/src/lib/model/ai-site-photos.js.map +1 -1
- package/src/lib/model/ai-site-start-steps.d.ts +4 -3
- package/src/lib/model/ai-site-start-steps.js +11 -3
- package/src/lib/model/ai-site-start-steps.js.map +1 -1
- package/src/lib/model/ai-site-start.d.ts +23 -2
- package/src/lib/model/ai-site-start.js +25 -3
- package/src/lib/model/ai-site-start.js.map +1 -1
- package/src/lib/providers/routing.d.ts +11 -0
- package/src/lib/providers/routing.js +23 -0
- package/src/lib/providers/routing.js.map +1 -1
- package/src/lib/runtime/ai-doctrine-validators.d.ts +4 -2
- package/src/lib/runtime/ai-doctrine-validators.js +7 -2
- package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
- package/src/lib/runtime/ai-icon-library.d.ts +4 -0
- package/src/lib/runtime/ai-icon-library.js +4 -0
- package/src/lib/runtime/ai-icon-library.js.map +1 -1
- package/src/lib/runtime/ai-node-tree.js +5 -1
- package/src/lib/runtime/ai-node-tree.js.map +1 -1
- package/src/lib/runtime/ai-palette.d.ts +2 -0
- package/src/lib/runtime/ai-palette.generated.js +19 -3
- package/src/lib/runtime/ai-palette.generated.js.map +1 -1
- package/src/lib/runtime/ai-palette.js +2 -1
- package/src/lib/runtime/ai-palette.js.map +1 -1
- package/src/lib/site-import/fixtures/site-layout-recordings.d.ts +50 -0
- package/src/lib/site-import/fixtures/site-layout-recordings.js +86 -0
- package/src/lib/site-import/fixtures/site-layout-recordings.js.map +1 -0
- package/src/lib/site-import/site-import-crawl.d.ts +18 -1
- package/src/lib/site-import/site-import-crawl.js +70 -10
- package/src/lib/site-import/site-import-crawl.js.map +1 -1
- package/src/lib/site-import/site-import-css.d.ts +110 -0
- package/src/lib/site-import/site-import-css.js +826 -0
- package/src/lib/site-import/site-import-css.js.map +1 -0
- package/src/lib/site-import/site-import-html.d.ts +116 -1
- package/src/lib/site-import/site-import-html.js +538 -46
- package/src/lib/site-import/site-import-html.js.map +1 -1
- package/src/lib/site-import/site-import-layout.d.ts +79 -0
- package/src/lib/site-import/site-import-layout.js +1608 -0
- package/src/lib/site-import/site-import-layout.js.map +1 -0
- package/src/lib/site-import/site-import-nav.d.ts +40 -0
- package/src/lib/site-import/site-import-nav.js +437 -0
- package/src/lib/site-import/site-import-nav.js.map +1 -0
- package/src/lib/site-import/site-import-page.d.ts +8 -1
- package/src/lib/site-import/site-import-page.js +24 -2
- package/src/lib/site-import/site-import-page.js.map +1 -1
- package/src/lib/assets/site-styles/beauty.webp +0 -0
- package/src/lib/assets/site-styles/blog.webp +0 -0
- package/src/lib/assets/site-styles/business.webp +0 -0
- package/src/lib/assets/site-styles/coming-soon.webp +0 -0
- package/src/lib/assets/site-styles/education.webp +0 -0
- package/src/lib/assets/site-styles/events.webp +0 -0
- package/src/lib/assets/site-styles/fitness.webp +0 -0
- package/src/lib/assets/site-styles/landing.webp +0 -0
- package/src/lib/assets/site-styles/music.webp +0 -0
- package/src/lib/assets/site-styles/nonprofit.webp +0 -0
- package/src/lib/assets/site-styles/personal.webp +0 -0
- package/src/lib/assets/site-styles/photography.webp +0 -0
- package/src/lib/assets/site-styles/portfolio.webp +0 -0
- package/src/lib/assets/site-styles/professional.webp +0 -0
- package/src/lib/assets/site-styles/realestate.webp +0 -0
- package/src/lib/assets/site-styles/restaurant.webp +0 -0
- package/src/lib/assets/site-styles/store.webp +0 -0
- package/src/lib/assets/site-styles/studio.webp +0 -0
- package/src/lib/assets/site-styles/trades.webp +0 -0
- package/src/lib/assets/site-styles/wellness.webp +0 -0
- package/src/lib/assets/site-styles/yoga.webp +0 -0
- package/src/lib/site-import/site-import-review.d.ts +0 -40
- package/src/lib/site-import/site-import-review.js +0 -149
- package/src/lib/site-import/site-import-review.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/site-import/site-import-html.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*==========================================\n * WHAT A CRAWLED PAGE SAYS (AGL-3974, parent AGL-3973).\n *\n * \"Bring my site\" reads a person's existing pages for their words, their\n * structure and their pictures. No server HTML parser is a dependency of any\n * lib, and a page's text in order is a small question, so this is a\n * tokenizer: tags and text runs, with the few elements that matter tracked\n * and everything else read through.\n *\n * What never survives, before a single tag is walked:\n * - scripts, styles, iframes, embeds, objects, SVG, canvas, media players,\n * templates and comments, content and all;\n * - any form with a card, bank or payment field, whole;\n * - and a page with a password field is not read at all: it is refused and\n * reported (`loginForm`), because a sign-in page is exactly what a\n * phishing clone wants and nothing a site import needs.\n *\n * The output is DATA. Text from a page reaches a model only fenced as\n * untrusted (`fenceUntrustedText`), never as instructions.\n *\n * What a page is made of is kept as the page shows it (AGL-4083): words that\n * sit in tags side by side stay apart (\"Sign in\" and \"Start free\", never\n * \"Sign inStart free\"); a link is a block of its own, `mailto:` and `tel:`\n * ones too, so an address or a phone number survives; a menu entry is named\n * by its first line, not by its mega-menu description; a `<picture>`'s\n * source stands in for an `<img>` with no address; and the head's share card,\n * icons, site name and Organization structured data come along for the\n * header, the footer and the site's own facts.\n *=========================================*/\n\n/** One run of a page's content, in the order the page draws it. */\nexport type SiteImportBlock =\n | { kind: 'heading'; level: 1 | 2 | 3 | 4 | 5 | 6; text: string; region: SiteImportRegion }\n | { kind: 'paragraph' | 'list-item' | 'quote'; text: string; region: SiteImportRegion }\n | { kind: 'image'; url: string; alt: string; region: SiteImportRegion }\n /**\n * A link the page shows outside its menus (AGL-4083): `href` is an absolute\n * http(s) address, a `mailto:` or a `tel:`. `inline` when its words are\n * already in the block before it (a link inside a sentence); a link on its\n * own (a button, an email address in a card) is only this block.\n */\n | { kind: 'link'; text: string; href: string; region: SiteImportRegion; inline?: true }\n\n/** Where on the page a block sat: the header and footer carry business details. */\nexport type SiteImportRegion = 'header' | 'main' | 'footer'\n\nexport interface SiteImportImage {\n /** Absolute https (or http) address. */\n url: string\n alt: string\n /** On the site's own origin; otherwise a CDN or a third party. The importer decides. */\n sameSite: boolean\n /** Where on the page it sat, its menus included (AGL-4083): a header's picture is often the logo. */\n region: SiteImportRegion\n}\n\n/** A `<link rel=\"icon\">` or `apple-touch-icon` of the page's head (AGL-4083). */\nexport interface SiteImportIcon {\n url: string\n rel: 'icon' | 'apple-touch-icon'\n /** The larger side its `sizes` names, or `null` for none or `any`. */\n size: number | null\n /** Its declared type, as written. */\n type: string | null\n}\n\n/**\n * The link to the home page in a page's header (AGL-4083): what its brand is\n * drawn with. `logo` is the first picture inside it; `text` its words, which\n * are the site's name when the header prints one.\n */\nexport interface SiteImportBrandMark {\n logo: { url: string; alt: string } | null\n text: string\n region: SiteImportRegion\n}\n\n/**\n * The page's Organization (or LocalBusiness) structured data (AGL-4083), as\n * written: the site's own statement of its name, address, phone, email and\n * profiles. Every field is the empty string, or an empty list, when absent.\n */\nexport interface SiteImportOrganization {\n name: string\n description: string\n url: string\n logo: string\n telephone: string\n email: string\n /** One line: street, town, region and postal code, country. */\n address: string\n sameAs: string[]\n}\n\nexport interface SiteImportNavLink {\n text: string\n url: string\n}\n\n/** A form that was kept: what it asks, never what was typed. */\nexport interface SiteImportForm {\n fields: { type: string; name: string }[]\n}\n\nexport interface SiteImportExtract {\n title: string\n description: string\n lang: string | null\n canonical: string | null\n /** The share card, `og:image` (or `twitter:image`), as an absolute address (AGL-4083). */\n ogImage: string | null\n /** The site's own name, `og:site_name` (or `application-name`); empty when absent. */\n siteName: string\n icons: SiteImportIcon[]\n brand: SiteImportBrandMark | null\n organization: SiteImportOrganization | null\n blocks: SiteImportBlock[]\n images: SiteImportImage[]\n navLinks: SiteImportNavLink[]\n /** Same-site page addresses, fragment-free, in first-seen order. */\n links: string[]\n forms: { kept: SiteImportForm[]; removed: number }\n /** True when the page has a password field; nothing else is extracted. */\n loginForm: boolean\n}\n\n/** Ceilings that keep one odd page from becoming the whole inventory. */\nexport const SITE_IMPORT_PAGE_LIMITS = {\n /** A pricing page's plan table runs past 400 (AGL-4083); a wave's read keeps fewer, under its own budget. */\n blocks: 2_000,\n /** A legal page's paragraph runs past 2,000 characters. */\n blockChars: 10_000,\n images: 100,\n links: 300,\n /** A mega-menu's entries and the footer's columns together. */\n navLinks: 150,\n forms: 10,\n fieldsPerForm: 30,\n icons: 12,\n} as const\n\n/** Elements removed with everything inside them. */\nconst REMOVED_WITH_CONTENT = [\n 'script',\n 'style',\n 'noscript',\n 'template',\n 'iframe',\n 'frame',\n 'frameset',\n 'object',\n 'applet',\n 'svg',\n 'math',\n 'canvas',\n 'video',\n 'audio',\n]\n\n/** Form controls, removed with their content once the forms are summarized. */\nconst FORM_CONTROLS = ['textarea', 'select', 'button']\n\n/** Void elements removed wherever they appear. */\nconst REMOVED_VOID = /<(?:embed|param|source|track|link|base)\\b(?:[^>\"']|\"[^\"]*\"|'[^']*')*>/gi\n\nconst PASSWORD_INPUT = /<input\\b(?:[^>\"']|\"[^\"]*\"|'[^']*')*\\btype\\s*=\\s*[\"']?password\\b/i\n\n/**\n * A field that takes money or a bank detail: an autocomplete hint for a\n * card, or a name or id that says card, CVC, IBAN, routing or payment.\n */\nconst PAYMENT_FIELD =\n /<(?:input|select)\\b(?:[^>\"']|\"[^\"]*\"|'[^']*')*?(?:\\bautocomplete\\s*=\\s*[\"']?\\s*cc-|\\b(?:name|id|data-stripe|data-braintree-name)\\s*=\\s*[\"']?[^\"'\\s>]*(?:card|cc[-_]?(?:num|number|exp|csc|cvv|cvc)|cvv|cvc|csc|iban|routing|account[-_]?number|payment|billing[-_]?card))/i\n\nconst BLOCK_TAGS: Record<string, 'paragraph' | 'list-item' | 'quote'> = {\n p: 'paragraph',\n li: 'list-item',\n dt: 'paragraph',\n dd: 'paragraph',\n td: 'paragraph',\n th: 'paragraph',\n address: 'paragraph',\n pre: 'paragraph',\n figcaption: 'paragraph',\n caption: 'paragraph',\n label: 'paragraph',\n blockquote: 'quote',\n}\n\n/** Tags that end a run of loose text without being a block themselves. */\nconst BREAK_TAGS = new Set([\n 'div',\n 'section',\n 'article',\n 'main',\n 'aside',\n 'header',\n 'footer',\n 'nav',\n 'ul',\n 'ol',\n 'dl',\n 'table',\n 'tr',\n 'tbody',\n 'thead',\n 'figure',\n 'form',\n 'hr',\n 'br',\n 'body',\n])\n\n/**\n * Tags a browser lays out apart from the words beside them (AGL-4083): two\n * links, or a link and a picture, side by side are two runs of words, never\n * one (\"Sign in\" and \"Start free\", not \"Sign inStart free\"). Every other tag\n * inside a block styles words where they are (a `<span>` or a `<strong>`\n * mid-sentence) and adds no space; block-level tags already end their block.\n */\nconst RUN_BOUNDARY = new Set(['a', 'img', 'button', 'input', 'select', 'textarea', 'picture', 'video', 'audio', 'iframe', 'object', 'embed', 'canvas', 'svg', 'meter', 'progress', 'output'])\n\n/** Where one run of words ends and the next begins, resolved when a block is written. */\nconst RUN_BREAK = '\\u0001'\n\n/**\n * The runs of a block joined as a reader sees them: a space between two\n * runs, except before closing punctuation or after an opening one, where\n * the page wrote none (\"<span>Austin</span>, Texas\" is \"Austin, Texas\").\n */\nconst RUN_BREAKS = new RegExp(`[\\\\s${RUN_BREAK}]*${RUN_BREAK}[\\\\s${RUN_BREAK}]*`, 'g')\n\nfunction joinRuns(text: string): string {\n if (!text.includes(RUN_BREAK)) return text\n return text.replace(RUN_BREAKS, (match: string, offset: number, whole: string) => {\n if (/\\s/.test(match)) return ' '\n const before = whole[offset - 1] ?? ''\n const after = whole[offset + match.length] ?? ''\n if (!before || !after) return ''\n if (/[.,;:!?%)\\]}\\u2019\\u201d\\u00bb]/.test(after) || /[([{\\u2018\\u201c\\u00ab]/.test(before)) return ''\n // A straight quote opens after a space or a bracket, and closes before one.\n if (/[\"']/.test(before) && /^$|[\\s([{]/.test(whole[offset - 2] ?? '')) return ''\n if (/[\"']/.test(after) && /^$|[\\s.,;:!?)\\]}]/.test(whole[offset + match.length + 1] ?? '')) return ''\n return ' '\n })\n}\n\nconst NAMED_ENTITIES: Record<string, string> = {\n amp: '&',\n lt: '<',\n gt: '>',\n quot: '\"',\n apos: \"'\",\n nbsp: ' ',\n rsquo: '’',\n lsquo: '‘',\n rdquo: '”',\n ldquo: '“',\n mdash: '—',\n ndash: '–',\n hellip: '…',\n copy: '©',\n reg: '®',\n trade: '™',\n middot: '·',\n bull: '•',\n eacute: 'é',\n egrave: 'è',\n aacute: 'á',\n ntilde: 'ñ',\n uuml: 'ü',\n ouml: 'ö',\n auml: 'ä',\n deg: '°',\n times: '×',\n}\n\n/** Character references to characters; an unknown name stays as written. */\nexport function decodeHtmlEntities(text: string): string {\n return text.replace(/&(#x[0-9a-f]+|#\\d+|[a-z][a-z0-9]*);/gi, (whole, body: string) => {\n if (body[0] === '#') {\n const code =\n body[1] === 'x' || body[1] === 'X' ? parseInt(body.slice(2), 16) : parseInt(body.slice(1), 10)\n if (!Number.isFinite(code) || code <= 0 || code > 0x10ffff) return ''\n if (code < 32 && code !== 9 && code !== 10 && code !== 13) return ''\n return String.fromCodePoint(code)\n }\n const named = NAMED_ENTITIES[body.toLowerCase()]\n return named ?? whole\n })\n}\n\nconst ATTRIBUTE = /([^\\s=/>\"']+)(?:\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s>\"']+)))?/g\n\n/** A tag's attributes, names lowercased, values decoded. */\nexport function parseAttributes(source: string): Record<string, string> {\n const attributes: Record<string, string> = {}\n for (const match of source.matchAll(ATTRIBUTE)) {\n const name = match[1].toLowerCase()\n if (name in attributes) continue\n attributes[name] = decodeHtmlEntities(match[2] ?? match[3] ?? match[4] ?? '')\n }\n return attributes\n}\n\nconst TAG = /<(\\/?)([a-zA-Z][\\w:-]*)((?:[^>\"']|\"[^\"]*\"|'[^']*')*)>/g\n\n/** Every `<meta>` tag's attributes. */\nfunction metaTags(html: string): Record<string, string>[] {\n const out: Record<string, string>[] = []\n for (const match of html.matchAll(/<meta\\b((?:[^>\"']|\"[^\"]*\"|'[^']*')*)>/gi)) {\n out.push(parseAttributes(match[1]))\n }\n return out\n}\n\n/** The `content` of every `<meta name=\"…\">` with this name. */\nexport function readMetaValues(html: string, name: string): string[] {\n const wanted = name.toLowerCase()\n return metaTags(html)\n .filter((attributes) => (attributes['name'] ?? '').toLowerCase() === wanted)\n .map((attributes) => (attributes['content'] ?? '').trim())\n .filter(Boolean)\n}\n\nfunction collapse(text: string): string {\n return joinRuns(text).replace(/\\s+/g, ' ').trim()\n}\n\nfunction clip(text: string, max: number): string {\n return text.length > max ? `${text.slice(0, max - 1).trimEnd()}…` : text\n}\n\nfunction removeElements(html: string, tags: readonly string[]): string {\n let out = html\n for (const tag of tags) {\n const paired = new RegExp(`<${tag}\\\\b(?:[^>\"']|\"[^\"]*\"|'[^']*')*>[\\\\s\\\\S]*?<\\\\/${tag}\\\\s*>`, 'gi')\n out = out.replace(paired, ' ')\n // One left open runs to the end of the document, as a browser reads it.\n const unclosed = new RegExp(`<${tag}\\\\b(?:[^>\"']|\"[^\"]*\"|'[^']*')*>[\\\\s\\\\S]*$`, 'i')\n out = out.replace(unclosed, ' ')\n }\n return out\n}\n\n/** Forms with a payment field go whole; the rest are summarized, then go. */\nfunction takeForms(html: string): { html: string; kept: SiteImportForm[]; removed: number } {\n const kept: SiteImportForm[] = []\n let removed = 0\n const out = html.replace(/<form\\b(?:[^>\"']|\"[^\"]*\"|'[^']*')*>[\\s\\S]*?(?:<\\/form\\s*>|$)/gi, (form) => {\n if (PAYMENT_FIELD.test(form)) {\n removed += 1\n return ' '\n }\n if (kept.length < SITE_IMPORT_PAGE_LIMITS.forms) {\n const fields: SiteImportForm['fields'] = []\n for (const match of form.matchAll(/<(input|textarea|select)\\b((?:[^>\"']|\"[^\"]*\"|'[^']*')*)>/gi)) {\n const attributes = parseAttributes(match[2])\n const type = match[1].toLowerCase() === 'input' ? (attributes['type'] || 'text').toLowerCase() : match[1].toLowerCase()\n if (type === 'hidden' || type === 'submit' || type === 'button' || type === 'image') continue\n // A field no visitor sees is a trap for bots or a widget's shadow, not a question (AGL-4083).\n if ((attributes['aria-hidden'] ?? '').toLowerCase() === 'true' || attributes['tabindex'] === '-1') continue\n fields.push({ type, name: clip(attributes['name'] || attributes['id'] || '', 80) })\n if (fields.length >= SITE_IMPORT_PAGE_LIMITS.fieldsPerForm) break\n }\n kept.push({ fields })\n }\n return ' '\n })\n return { html: out, kept, removed }\n}\n\n/** `raw` against the page, as an absolute http(s) address without a fragment. */\nexport function resolveSiteUrl(raw: string | undefined, base: string): URL | null {\n const value = String(raw ?? '').trim()\n if (!value || /^(?:javascript|data|mailto|tel|sms|blob|about):/i.test(value)) return null\n try {\n const url = new URL(value, base)\n if (url.protocol !== 'https:' && url.protocol !== 'http:') return null\n url.hash = ''\n return url\n } catch {\n return null\n }\n}\n\n/** The first address a `srcset` offers. */\nfunction firstSrcset(srcset: string | undefined): string | undefined {\n const first = String(srcset ?? '').split(',')[0]?.trim().split(/\\s+/)[0]\n return first || undefined\n}\n\n/**\n * Where a link a page shows goes (AGL-4083): an absolute http(s) address\n * without its fragment, a `mailto:` with an address in it, or a `tel:` with\n * a number in it; `null` for anything else (a script, a jump on the page).\n */\nexport function resolveSiteLink(raw: string | undefined, base: string): string | null {\n const value = String(raw ?? '').trim()\n const mail = /^mailto:([^?\\s<>\"']+@[^?\\s<>\"']+)/i.exec(value)\n if (mail) return `mailto:${decodeURIComponent(mail[1]).toLowerCase()}`\n const phone = /^tel:([+\\d][\\d\\s().-]{2,30})$/i.exec(value)\n if (phone) return `tel:${phone[1].replace(/[\\s().-]/g, '')}`\n if (value.startsWith('#')) return null\n return resolveSiteUrl(value, base)?.toString() ?? null\n}\n\n/**\n * A `<picture>` whose `<img>` has no address of its own (a placeholder, or\n * none at all) is read from its first `<source>` (AGL-4083); a `<picture>`\n * whose `<img>` has one keeps it. The sources go with the void elements.\n */\nfunction readPictures(html: string): string {\n return html.replace(/<picture\\b(?:[^>\"']|\"[^\"]*\"|'[^']*')*>([\\s\\S]*?)<\\/picture\\s*>/gi, (whole, inner: string) => {\n const img = /<img\\b((?:[^>\"']|\"[^\"]*\"|'[^']*')*)>/i.exec(inner)\n const attributes = img ? parseAttributes(img[1]) : {}\n const own = attributes['src'] || attributes['data-src'] || firstSrcset(attributes['srcset'] || attributes['data-srcset'])\n if (own && !/^data:/i.test(own.trim())) return whole\n let source: string | undefined\n for (const match of inner.matchAll(/<source\\b((?:[^>\"']|\"[^\"]*\"|'[^']*')*)>/gi)) {\n const sourceAttributes = parseAttributes(match[1])\n source = firstSrcset(sourceAttributes['srcset'] || sourceAttributes['data-srcset'])\n if (source) break\n }\n if (!source) return whole\n const quote = (value: string) => value.replace(/&/g, '&').replace(/\"/g, '"').replace(/</g, '<')\n return ` <img src=\"${quote(source)}\" alt=\"${quote(attributes['alt'] ?? '')}\"> `\n })\n}\n\n/** The head's icons, the largest first within each kind. */\nfunction readIcons(html: string, pageUrl: string): SiteImportIcon[] {\n const icons: SiteImportIcon[] = []\n for (const match of html.matchAll(/<link\\b((?:[^>\"']|\"[^\"]*\"|'[^']*')*)>/gi)) {\n const attributes = parseAttributes(match[1])\n const rels = (attributes['rel'] ?? '').toLowerCase().split(/\\s+/)\n const rel = rels.includes('apple-touch-icon') || rels.includes('apple-touch-icon-precomposed')\n ? 'apple-touch-icon'\n : rels.includes('icon')\n ? 'icon'\n : null\n if (!rel) continue\n const url = resolveSiteUrl(attributes['href'], pageUrl)\n if (!url) continue\n const sizes: string[] = [...((attributes['sizes'] ?? '').match(/(\\d+)\\s*x\\s*(\\d+)/gi) ?? [])]\n const size = sizes.reduce<number>((most, entry) => Math.max(most, ...entry.split(/x/i).map((side) => Number(side) || 0)), 0)\n icons.push({ url: url.toString(), rel, size: size || null, type: attributes['type']?.trim() || null })\n if (icons.length >= SITE_IMPORT_PAGE_LIMITS.icons) break\n }\n return icons.sort((a, b) => (a.rel === b.rel ? (b.size ?? 0) - (a.size ?? 0) : a.rel === 'apple-touch-icon' ? -1 : 1))\n}\n\nconst ORGANIZATION_TYPE = /(?:^|\\b)(?:Organization|Corporation|LocalBusiness|NGO|EducationalOrganization|MedicalOrganization|SportsOrganization|Store|Restaurant|ProfessionalService|HomeAndConstructionBusiness|HealthAndBeautyBusiness|FoodEstablishment|AutomotiveBusiness|LegalService|FinancialService|Dentist|Physician|LodgingBusiness|EntertainmentBusiness)$/\n\n/**\n * The first Organization (or kind of local business) the page's structured\n * data describes, read before scripts are thrown away. Malformed data, or\n * none, is `null`; nothing in it is ever run.\n */\nfunction readOrganization(html: string): SiteImportOrganization | null {\n const nodes: Record<string, unknown>[] = []\n const visit = (value: unknown, depth: number) => {\n if (depth > 4 || nodes.length > 50 || !value || typeof value !== 'object') return\n if (Array.isArray(value)) {\n for (const entry of value) visit(entry, depth + 1)\n return\n }\n const node = value as Record<string, unknown>\n nodes.push(node)\n if (node['@graph']) visit(node['@graph'], depth + 1)\n }\n for (const match of html.matchAll(/<script\\b[^>]*\\btype\\s*=\\s*[\"']?application\\/ld\\+json[\"']?[^>]*>([\\s\\S]*?)<\\/script\\s*>/gi)) {\n try {\n visit(JSON.parse(match[1]), 0)\n } catch {\n // Structured data that does not parse says nothing.\n }\n }\n const typeOf = (node: Record<string, unknown>) => ([] as unknown[]).concat(node['@type'] ?? []).map(String)\n const node = nodes.find((entry) => typeOf(entry).some((type) => ORGANIZATION_TYPE.test(type)))\n if (!node) return null\n const text = (value: unknown, max = 300): string => (typeof value === 'string' ? clip(collapse(value), max) : '')\n const urlOf = (value: unknown): string => {\n const raw = typeof value === 'string' ? value : value && typeof value === 'object' ? (value as Record<string, unknown>)['url'] : ''\n return typeof raw === 'string' && /^https?:\\/\\//i.test(raw.trim()) ? raw.trim() : ''\n }\n const contact = ([] as unknown[]).concat(node['contactPoint'] ?? []).find((entry) => entry && typeof entry === 'object') as\n | Record<string, unknown>\n | undefined\n const address = (() => {\n const value = node['address']\n if (typeof value === 'string') return text(value)\n if (!value || typeof value !== 'object') return ''\n const parts = value as Record<string, unknown>\n const region = [text(parts['addressRegion']), text(parts['postalCode'])].filter(Boolean).join(' ')\n const country = parts['addressCountry']\n return [text(parts['streetAddress']), text(parts['addressLocality']), region, typeof country === 'string' ? text(country) : text((country as Record<string, unknown> | null)?.['name'])]\n .filter(Boolean)\n .join(', ')\n })()\n return {\n name: text(node['name']),\n description: text(node['description'], 1_000),\n url: urlOf(node['url']),\n logo: urlOf(node['logo']),\n telephone: text(node['telephone']) || text(contact?.['telephone']),\n email: (text(node['email']) || text(contact?.['email'])).replace(/^mailto:/i, ''),\n address,\n sameAs: ([] as unknown[])\n .concat(node['sameAs'] ?? [])\n .map((entry) => urlOf(entry))\n .filter(Boolean)\n .slice(0, 20),\n }\n}\n\n/**\n * The words, structure, pictures and links of one page.\n *\n * `isSameSite(url)` says whether an address is on the site being imported;\n * only those become `links`, and images are marked by it.\n */\nexport function extractSiteImportPage(\n html: string,\n pageUrl: string,\n isSameSite: (url: URL) => boolean,\n): SiteImportExtract {\n const empty: SiteImportExtract = {\n title: '',\n description: '',\n lang: null,\n canonical: null,\n ogImage: null,\n siteName: '',\n icons: [],\n brand: null,\n organization: null,\n blocks: [],\n images: [],\n navLinks: [],\n links: [],\n forms: { kept: [], removed: 0 },\n loginForm: false,\n }\n let source = String(html ?? '')\n .replace(/<!--[\\s\\S]*?(?:-->|$)/g, ' ')\n .replace(/<!\\[CDATA\\[[\\s\\S]*?\\]\\]>/g, ' ')\n if (PASSWORD_INPUT.test(source)) return { ...empty, loginForm: true }\n\n // Read before scripts go: the structured data is a script's body.\n const organization = readOrganization(source)\n const icons = readIcons(source, pageUrl)\n source = removeElements(readPictures(source), REMOVED_WITH_CONTENT).replace(REMOVED_VOID, ' ')\n // Forms next, so a field list is read before the controls go.\n const forms = takeForms(source)\n source = removeElements(forms.html, FORM_CONTROLS)\n\n const metas = metaTags(source)\n const metaContent = (key: string, attribute: 'name' | 'property') =>\n collapse(metas.find((m) => (m[attribute] ?? '').toLowerCase() === key)?.['content'] ?? '')\n const titleMatch = /<title\\b[^>]*>([\\s\\S]*?)<\\/title\\s*>/i.exec(source)\n const title = clip(\n collapse(decodeHtmlEntities(titleMatch?.[1] ?? '')) || metaContent('og:title', 'property'),\n 300,\n )\n const description = clip(\n metaContent('description', 'name') || metaContent('og:description', 'property'),\n 1_000,\n )\n const ogImage =\n resolveSiteUrl(metaContent('og:image', 'property') || metaContent('og:image:url', 'property') || metaContent('twitter:image', 'name'), pageUrl)?.toString() ??\n null\n const siteName = clip(metaContent('og:site_name', 'property') || metaContent('application-name', 'name'), 120)\n const htmlTag = /<html\\b((?:[^>\"']|\"[^\"]*\"|'[^']*')*)>/i.exec(source)\n const lang = htmlTag ? parseAttributes(htmlTag[1])['lang']?.trim() || null : null\n let canonical: string | null = null\n for (const match of String(html ?? '').matchAll(/<link\\b((?:[^>\"']|\"[^\"]*\"|'[^']*')*)>/gi)) {\n const attributes = parseAttributes(match[1])\n if ((attributes['rel'] ?? '').toLowerCase().split(/\\s+/).includes('canonical')) {\n canonical = resolveSiteUrl(attributes['href'], pageUrl)?.toString() ?? null\n break\n }\n }\n\n const bodyStart = source.search(/<body\\b/i)\n const body = bodyStart >= 0 ? source.slice(bodyStart) : source.replace(/<head\\b[\\s\\S]*?<\\/head\\s*>/i, ' ')\n const hasNav = /<nav\\b/i.test(body)\n\n const blocks: SiteImportBlock[] = []\n const images: SiteImportImage[] = []\n const imageSeen = new Set<string>()\n const navLinks: SiteImportNavLink[] = []\n const links: string[] = []\n const linkSeen = new Set<string>()\n let brand: SiteImportBrandMark | null = null\n\n let navDepth = 0\n let headerDepth = 0\n let footerDepth = 0\n let current: { kind: 'heading' | 'paragraph' | 'list-item' | 'quote'; level?: number; tag: string } | null = null\n let buffer = ''\n /** The link being read: its menu address (http(s) only), where it goes, its words and its first picture. */\n let anchor: {\n url: URL | null\n href: string | null\n text: string\n /** Its words split where a block-level tag inside it began, for a menu entry's first line. */\n lines: string[]\n image: { url: string; alt: string } | null\n /** Where in `buffer` its words begin. */\n start: number\n /** Its words ran across a block's end: some of them are in a block already. */\n crossed: boolean\n region: SiteImportRegion\n } | null = null\n /** The links read into the block being built, written after it. */\n let pending: Array<{ text: string; href: string; start: number; end: number; crossed: boolean; region: SiteImportRegion }> = []\n\n const region = (): SiteImportRegion =>\n footerDepth > 0 ? 'footer' : headerDepth > 0 ? 'header' : 'main'\n // A site without a <nav> keeps its menu in the header; its links are the nav.\n const inNav = () => navDepth > 0 || (!hasNav && headerDepth > 0)\n const room = () => blocks.length < SITE_IMPORT_PAGE_LIMITS.blocks\n\n const flush = () => {\n const raw = buffer\n const written = pending\n buffer = ''\n pending = []\n if (anchor && collapse(decodeHtmlEntities(raw.slice(anchor.start)))) anchor.crossed = true\n if (anchor) anchor.start = 0\n const kind = current?.kind ?? 'paragraph'\n const level = current?.level\n const loose = current === null\n current = null\n if (navDepth > 0) return\n const text = clip(collapse(decodeHtmlEntities(raw)), SITE_IMPORT_PAGE_LIMITS.blockChars)\n // Loose words that are only links (a row of buttons, an address in a\n // card) are those links, each a block of its own; words around a link\n // keep their block, and the link follows it.\n let rest = raw\n for (const link of [...written].sort((a, b) => b.start - a.start)) rest = `${rest.slice(0, link.start)}${rest.slice(link.end)}`\n const onlyLinks = loose && written.length > 0 && !collapse(decodeHtmlEntities(rest))\n if (text && !onlyLinks && room()) {\n const last = blocks[blocks.length - 1]\n if (!(last && last.kind !== 'image' && last.kind !== 'link' && last.text === text)) {\n if (kind === 'heading') {\n blocks.push({ kind, level: (level ?? 2) as 1 | 2 | 3 | 4 | 5 | 6, text, region: region() })\n } else {\n blocks.push({ kind, text, region: region() })\n }\n }\n }\n for (const link of written) {\n if (!room()) break\n const last = blocks[blocks.length - 1]\n if (last?.kind === 'link' && last.href === link.href && last.text === link.text) continue\n const inline = !onlyLinks || link.crossed\n blocks.push({ kind: 'link', text: link.text, href: link.href, region: link.region, ...(inline ? { inline: true as const } : {}) })\n }\n }\n\n /** A boundary between two runs of words: in the block, and in the link being read. */\n const boundary = (block: boolean) => {\n buffer += RUN_BREAK\n if (!anchor) return\n anchor.text += RUN_BREAK\n if (block && anchor.lines[anchor.lines.length - 1] !== '') anchor.lines.push('')\n }\n\n for (const match of body.matchAll(new RegExp(`${TAG.source}|([^<]+)|<`, 'g'))) {\n const text = match[4]\n if (text !== undefined || match[2] === undefined) {\n const run = text ?? '<'\n buffer += run\n if (anchor) {\n anchor.text += run\n anchor.lines[anchor.lines.length - 1] += run\n }\n continue\n }\n const closing = match[1] === '/'\n const tag = match[2].toLowerCase()\n const attributes = closing ? {} : parseAttributes(match[3] ?? '')\n\n if (tag === 'a') {\n if (closing) {\n if (anchor) {\n const label = clip(collapse(decodeHtmlEntities(anchor.text)), 300)\n const firstLine = clip(collapse(decodeHtmlEntities(anchor.lines.find((line) => collapse(decodeHtmlEntities(line))) ?? '')), 120)\n if (inNav() && anchor.url && firstLine && navLinks.length < SITE_IMPORT_PAGE_LIMITS.navLinks) {\n navLinks.push({ text: firstLine, url: anchor.url.toString() })\n }\n if (!brand && anchor.region !== 'footer' && (headerDepth > 0 || navDepth > 0) && anchor.url && isSameSite(anchor.url) && anchor.url.pathname === '/') {\n brand = { logo: anchor.image, text: label, region: anchor.region }\n }\n if (!inNav() && anchor.href && label) {\n pending.push({ text: label, href: anchor.href, start: anchor.start, end: buffer.length, crossed: anchor.crossed, region: anchor.region })\n }\n anchor = null\n }\n boundary(false)\n continue\n }\n boundary(false)\n const url = resolveSiteUrl(attributes['href'], pageUrl)\n anchor = {\n url,\n href: resolveSiteLink(attributes['href'], pageUrl),\n text: '',\n lines: [''],\n image: null,\n start: buffer.length,\n crossed: false,\n region: region(),\n }\n if (url && isSameSite(url) && links.length < SITE_IMPORT_PAGE_LIMITS.links) {\n const key = url.toString()\n if (!linkSeen.has(key)) {\n linkSeen.add(key)\n links.push(key)\n }\n }\n continue\n }\n\n if (tag === 'img' && !closing) {\n const url = resolveSiteUrl(\n attributes['src'] || attributes['data-src'] || firstSrcset(attributes['srcset'] || attributes['data-srcset']),\n pageUrl,\n )\n boundary(false)\n if (url && images.length < SITE_IMPORT_PAGE_LIMITS.images) {\n const key = url.toString()\n const alt = clip(collapse(attributes['alt'] ?? ''), 300)\n if (anchor && !anchor.image) anchor.image = { url: key, alt }\n if (!imageSeen.has(key)) {\n imageSeen.add(key)\n images.push({ url: key, alt, sameSite: isSameSite(url), region: region() })\n if (navDepth === 0) {\n flush()\n if (room()) blocks.push({ kind: 'image', url: key, alt, region: region() })\n }\n }\n }\n continue\n }\n\n if (tag === 'nav' || tag === 'header' || tag === 'footer') {\n flush()\n boundary(true)\n const step = closing ? -1 : 1\n if (tag === 'nav') navDepth = Math.max(0, navDepth + step)\n if (tag === 'header') headerDepth = Math.max(0, headerDepth + step)\n if (tag === 'footer') footerDepth = Math.max(0, footerDepth + step)\n continue\n }\n\n const heading = /^h([1-6])$/.exec(tag)\n if (heading || BLOCK_TAGS[tag]) {\n if (closing) {\n if (current?.tag === tag) flush()\n boundary(true)\n continue\n }\n flush()\n boundary(true)\n current = heading\n ? { kind: 'heading', level: Number(heading[1]), tag }\n : { kind: BLOCK_TAGS[tag], tag }\n continue\n }\n\n if (BREAK_TAGS.has(tag)) {\n if (tag === 'br' && current) {\n buffer += ' '\n if (anchor) anchor.text += ' '\n continue\n }\n flush()\n boundary(true)\n continue\n }\n\n if (RUN_BOUNDARY.has(tag)) boundary(false)\n }\n flush()\n\n return {\n title,\n description,\n lang,\n canonical,\n ogImage,\n siteName,\n icons,\n brand,\n organization,\n blocks,\n images,\n navLinks,\n links,\n forms: { kept: forms.kept, removed: forms.removed },\n loginForm: false,\n }\n}\n"],"names":["SITE_IMPORT_PAGE_LIMITS","blocks","blockChars","images","links","navLinks","forms","fieldsPerForm","icons","REMOVED_WITH_CONTENT","FORM_CONTROLS","REMOVED_VOID","PASSWORD_INPUT","PAYMENT_FIELD","BLOCK_TAGS","p","li","dt","dd","td","th","address","pre","figcaption","caption","label","blockquote","BREAK_TAGS","Set","RUN_BOUNDARY","RUN_BREAK","RUN_BREAKS","RegExp","joinRuns","text","includes","replace","match","offset","whole","test","before","after","length","NAMED_ENTITIES","amp","lt","gt","quot","apos","nbsp","rsquo","lsquo","rdquo","ldquo","mdash","ndash","hellip","copy","reg","trade","middot","bull","eacute","egrave","aacute","ntilde","uuml","ouml","auml","deg","times","decodeHtmlEntities","body","code","parseInt","slice","Number","isFinite","String","fromCodePoint","named","toLowerCase","ATTRIBUTE","parseAttributes","source","attributes","matchAll","name","TAG","metaTags","html","out","push","readMetaValues","wanted","filter","map","trim","Boolean","collapse","clip","max","trimEnd","removeElements","tags","tag","paired","unclosed","takeForms","kept","removed","form","fields","type","resolveSiteUrl","raw","base","value","url","URL","protocol","hash","firstSrcset","srcset","first","split","undefined","resolveSiteLink","mail","exec","decodeURIComponent","phone","startsWith","toString","readPictures","inner","img","own","sourceAttributes","quote","readIcons","pageUrl","rels","rel","sizes","size","reduce","most","entry","Math","side","sort","a","b","ORGANIZATION_TYPE","readOrganization","node","nodes","visit","depth","Array","isArray","JSON","parse","typeOf","concat","find","some","urlOf","contact","parts","region","join","country","description","logo","telephone","email","sameAs","extractSiteImportPage","isSameSite","empty","title","lang","canonical","ogImage","siteName","brand","organization","loginForm","metas","metaContent","key","attribute","m","titleMatch","htmlTag","bodyStart","search","hasNav","imageSeen","linkSeen","navDepth","headerDepth","footerDepth","current","buffer","anchor","pending","inNav","room","flush","written","start","crossed","kind","level","loose","rest","link","end","onlyLinks","last","href","inline","boundary","block","lines","run","closing","firstLine","line","pathname","image","has","add","alt","sameSite","step","heading"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/site-import/site-import-html.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*==========================================\n * WHAT A CRAWLED PAGE SAYS (AGL-3974, parent AGL-3973).\n *\n * \"Bring my site\" reads a person's existing pages for their words, their\n * structure and their pictures. No server HTML parser is a dependency of any\n * lib, and a page's text in order is a small question, so this is a\n * tokenizer: tags and text runs, with the few elements that matter tracked\n * and everything else read through.\n *\n * What never survives, before a single tag is walked:\n * - scripts, styles, iframes, embeds, objects, SVG, canvas, media players,\n * templates and comments, content and all;\n * - any form with a card, bank or payment field, whole;\n * - and a page with a password field is not read at all: it is refused and\n * reported (`loginForm`), because a sign-in page is exactly what a\n * phishing clone wants and nothing a site import needs.\n *\n * The output is DATA. Text from a page reaches a model only fenced as\n * untrusted (`fenceUntrustedText`), never as instructions.\n *\n * What a page is made of is kept as the page shows it (AGL-4083): words that\n * sit in tags side by side stay apart (\"Sign in\" and \"Start free\", never\n * \"Sign inStart free\"); a link is a block of its own, `mailto:` and `tel:`\n * ones too, so an address or a phone number survives; a menu entry is named\n * by its first line, not by its mega-menu description; a `<picture>`'s\n * source stands in for an `<img>` with no address; and the head's share card,\n * icons, site name and Organization structured data come along for the\n * header, the footer and the site's own facts.\n *=========================================*/\n\n/** One run of a page's content, in the order the page draws it. */\nexport type SiteImportBlock =\n | { kind: 'heading'; level: 1 | 2 | 3 | 4 | 5 | 6; text: string; region: SiteImportRegion }\n | { kind: 'paragraph' | 'list-item' | 'quote'; text: string; region: SiteImportRegion }\n | { kind: 'image'; url: string; alt: string; region: SiteImportRegion }\n /**\n * A link the page shows outside its menus (AGL-4083): `href` is an absolute\n * http(s) address, a `mailto:` or a `tel:`. `inline` when its words are\n * already in the block before it (a link inside a sentence); a link on its\n * own (a button, an email address in a card) is only this block.\n */\n | { kind: 'link'; text: string; href: string; region: SiteImportRegion; inline?: true }\n\n/** Where on the page a block sat: the header and footer carry business details. */\nexport type SiteImportRegion = 'header' | 'main' | 'footer'\n\nexport interface SiteImportImage {\n /** Absolute https (or http) address. */\n url: string\n alt: string\n /** On the site's own origin; otherwise a CDN or a third party. The importer decides. */\n sameSite: boolean\n /** Where on the page it sat, its menus included (AGL-4083): a header's picture is often the logo. */\n region: SiteImportRegion\n}\n\n/** A `<link rel=\"icon\">` or `apple-touch-icon` of the page's head (AGL-4083). */\nexport interface SiteImportIcon {\n url: string\n rel: 'icon' | 'apple-touch-icon'\n /** The larger side its `sizes` names, or `null` for none or `any`. */\n size: number | null\n /** Its declared type, as written. */\n type: string | null\n}\n\n/**\n * The link to the home page in a page's header (AGL-4083): what its brand is\n * drawn with. `logo` is the first picture inside it; `text` its words, which\n * are the site's name when the header prints one.\n */\nexport interface SiteImportBrandMark {\n logo: { url: string; alt: string } | null\n text: string\n region: SiteImportRegion\n}\n\n/**\n * The page's Organization (or LocalBusiness) structured data (AGL-4083), as\n * written: the site's own statement of its name, address, phone, email and\n * profiles. Every field is the empty string, or an empty list, when absent.\n */\nexport interface SiteImportOrganization {\n name: string\n description: string\n url: string\n logo: string\n telephone: string\n email: string\n /** One line: street, town, region and postal code, country. */\n address: string\n sameAs: string[]\n}\n\nexport interface SiteImportNavLink {\n text: string\n url: string\n}\n\n/** A form that was kept: what it asks, never what was typed. */\nexport interface SiteImportForm {\n fields: { type: string; name: string }[]\n}\n\nexport interface SiteImportExtract {\n title: string\n description: string\n lang: string | null\n canonical: string | null\n /** The share card, `og:image` (or `twitter:image`), as an absolute address (AGL-4083). */\n ogImage: string | null\n /** The site's own name, `og:site_name` (or `application-name`); empty when absent. */\n siteName: string\n icons: SiteImportIcon[]\n brand: SiteImportBrandMark | null\n organization: SiteImportOrganization | null\n blocks: SiteImportBlock[]\n images: SiteImportImage[]\n navLinks: SiteImportNavLink[]\n /** Same-site page addresses, fragment-free, in first-seen order. */\n links: string[]\n forms: { kept: SiteImportForm[]; removed: number }\n /** True when the page has a password field; nothing else is extracted. */\n loginForm: boolean\n /**\n * How the page is built (AGL-4106), when asked for: every element the\n * blocks sit in, so the layout reader sees the source's sections, rows,\n * cards and menus, not only its lines. Never stored: the crawl reads it\n * into a layout and drops it.\n */\n structure?: SiteImportStructure\n}\n\n/** The attributes of an element the layout reader reads; everything else is dropped. */\nexport interface SiteImportElementAttrs {\n class?: string\n id?: string\n style?: string\n role?: string\n /** `aria-label`. */\n label?: string\n /** An anchor's address as written. */\n href?: string\n /** `hidden`, or `aria-hidden=\"true\"`. */\n hidden?: true\n /** `data-section-theme` or `data-theme`: a site builder's name for a band's look. */\n theme?: string\n type?: string\n /** `aria-controls` / `aria-labelledby`: what a tab shows, and what names a panel. */\n controls?: string\n labelledby?: string\n}\n\n/** One element of the page, in a flat table: its parent and children by index. */\nexport interface SiteImportElement {\n id: number\n tag: string\n /** -1 for an element at the top of the body. */\n parent: number\n children: number[]\n region: SiteImportRegion\n /** Inside a `<nav>`, or a header with no `<nav>`. */\n nav: boolean\n attrs: SiteImportElementAttrs\n /** The blocks whose words sit directly in this element, by index into `blocks`. */\n blocks: number[]\n /** The icon this element is, by index into `structure.icons` (an inline `<svg>`). */\n icon?: number\n /** The form that sat here, by index into the page's kept forms. */\n form?: number\n /**\n * Its place in the page's order of content: a block's index, or the index\n * of the block that follows an icon, less a half. Set on elements that\n * hold a block or an icon directly.\n */\n order?: number\n}\n\n/**\n * An inline `<svg>` the page draws as an icon (AGL-4106): one path the\n * Besigner's icon element draws as it is, or the shapes of a small drawing,\n * cleaned to geometry, for a picture of it. Never its text.\n */\nexport interface SiteImportSvgIcon {\n viewBox: string\n /** The one `<path d>`, at most 4 KB. */\n path?: string\n /** A drawing of several shapes, at most 16 KB, its geometry and fills only. */\n svg?: string\n}\n\n/** A link on the page, menus included, as the structure keeps it for the menus' reader. */\nexport interface SiteImportAnchor {\n /** The `<a>` element. */\n element: number\n /** Where it goes: an absolute http(s) address, a `mailto:` or a `tel:`; `null` for none. */\n href: string | null\n /** Its first line: a menu entry's name. */\n label: string\n /** Its other lines: a mega-menu entry's description. */\n text: string\n region: SiteImportRegion\n nav: boolean\n /** The first icon inside it. */\n icon?: number\n /** The first picture inside it. */\n image?: string\n}\n\nexport interface SiteImportStructure {\n elements: SiteImportElement[]\n /** The element each block's words sit in, by block index. */\n blockElement: number[]\n icons: SiteImportSvgIcon[]\n anchors: SiteImportAnchor[]\n /**\n * Words a menu or a header holds outside its links, where they sit: a mega\n * menu's column heading (\"By team\"), the button that opens a menu. A menu's\n * words are never blocks, so these are how the menu reader sees them.\n */\n texts: Array<{ element: number; text: string }>\n /** The page's own `<style>` sheets, in order. */\n styles: string[]\n /** The stylesheets it links (absolute https), in order, Google Fonts' included. */\n stylesheets: string[]\n /** The `<main>` element, or -1 when the page has none. */\n main: number\n /** The `<body>`'s element, or -1. */\n body: number\n /** The `<html>` element's attributes. */\n root: SiteImportElementAttrs\n}\n\nexport interface SiteImportExtractOptions {\n /** Keep how the page is built (`structure`), for the layout reader (AGL-4106). */\n structure?: boolean\n}\n\n/** Ceilings that keep one odd page from becoming the whole inventory. */\nexport const SITE_IMPORT_PAGE_LIMITS = {\n /** A pricing page's plan table runs past 400 (AGL-4083); a wave's read keeps fewer, under its own budget. */\n blocks: 2_000,\n /** A legal page's paragraph runs past 2,000 characters. */\n blockChars: 10_000,\n images: 100,\n links: 300,\n /** A mega-menu's entries and the footer's columns together. */\n navLinks: 150,\n forms: 10,\n fieldsPerForm: 30,\n icons: 12,\n /** The structure's ceilings (AGL-4106): elements, inline icons, links and the page's own style sheets. */\n elements: 20_000,\n svgIcons: 200,\n anchors: 800,\n styleChars: 1_500_000,\n stylesheets: 4,\n} as const\n\n/** Elements removed with everything inside them. */\nconst REMOVED_WITH_CONTENT = [\n 'script',\n 'style',\n 'noscript',\n 'template',\n 'iframe',\n 'frame',\n 'frameset',\n 'object',\n 'applet',\n 'svg',\n 'math',\n 'canvas',\n 'video',\n 'audio',\n]\n\n/**\n * Form controls, removed with their content once the forms are summarized.\n * A `<button>` outside a form is not one (AGL-4106): its words are a line\n * (\"Watch the 40-second film\", a pricing tab's name) and a picture inside it\n * is still a picture. A form's own buttons go with the form.\n */\nconst FORM_CONTROLS = ['textarea', 'select']\n\n/** Void elements removed wherever they appear. */\nconst REMOVED_VOID = /<(?:embed|param|source|track|link|base)\\b(?:[^>\"']|\"[^\"]*\"|'[^']*')*>/gi\n\nconst PASSWORD_INPUT = /<input\\b(?:[^>\"']|\"[^\"]*\"|'[^']*')*\\btype\\s*=\\s*[\"']?password\\b/i\n\n/**\n * A field that takes money or a bank detail: an autocomplete hint for a\n * card, or a name or id that says card, CVC, IBAN, routing or payment.\n */\nconst PAYMENT_FIELD =\n /<(?:input|select)\\b(?:[^>\"']|\"[^\"]*\"|'[^']*')*?(?:\\bautocomplete\\s*=\\s*[\"']?\\s*cc-|\\b(?:name|id|data-stripe|data-braintree-name)\\s*=\\s*[\"']?[^\"'\\s>]*(?:card|cc[-_]?(?:num|number|exp|csc|cvv|cvc)|cvv|cvc|csc|iban|routing|account[-_]?number|payment|billing[-_]?card))/i\n\nconst BLOCK_TAGS: Record<string, 'paragraph' | 'list-item' | 'quote'> = {\n p: 'paragraph',\n li: 'list-item',\n dt: 'paragraph',\n dd: 'paragraph',\n td: 'paragraph',\n th: 'paragraph',\n address: 'paragraph',\n pre: 'paragraph',\n figcaption: 'paragraph',\n caption: 'paragraph',\n label: 'paragraph',\n /** A disclosure's question, a button's words (AGL-4106). */\n summary: 'paragraph',\n button: 'paragraph',\n blockquote: 'quote',\n}\n\n/** Tags that end a run of loose text without being a block themselves. */\nconst BREAK_TAGS = new Set([\n 'div',\n 'section',\n 'article',\n 'main',\n 'aside',\n 'header',\n 'footer',\n 'nav',\n 'ul',\n 'ol',\n 'dl',\n 'table',\n 'tr',\n 'tbody',\n 'thead',\n 'tfoot',\n 'details',\n 'figure',\n 'form',\n 'hr',\n 'br',\n 'body',\n])\n\n/**\n * Tags a browser lays out apart from the words beside them (AGL-4083): two\n * links, or a link and a picture, side by side are two runs of words, never\n * one (\"Sign in\" and \"Start free\", not \"Sign inStart free\"). Every other tag\n * inside a block styles words where they are (a `<span>` or a `<strong>`\n * mid-sentence) and adds no space; block-level tags already end their block.\n */\nconst RUN_BOUNDARY = new Set(['a', 'img', 'button', 'input', 'select', 'textarea', 'picture', 'video', 'audio', 'iframe', 'object', 'embed', 'canvas', 'svg', 'meter', 'progress', 'output'])\n\n/** Where one run of words ends and the next begins, resolved when a block is written. */\nconst RUN_BREAK = '\\u0001'\n\n/**\n * The runs of a block joined as a reader sees them: a space between two\n * runs, except before closing punctuation or after an opening one, where\n * the page wrote none (\"<span>Austin</span>, Texas\" is \"Austin, Texas\").\n */\nconst RUN_BREAKS = new RegExp(`[\\\\s${RUN_BREAK}]*${RUN_BREAK}[\\\\s${RUN_BREAK}]*`, 'g')\n\nfunction joinRuns(text: string): string {\n if (!text.includes(RUN_BREAK)) return text\n return text.replace(RUN_BREAKS, (match: string, offset: number, whole: string) => {\n if (/\\s/.test(match)) return ' '\n const before = whole[offset - 1] ?? ''\n const after = whole[offset + match.length] ?? ''\n if (!before || !after) return ''\n if (/[.,;:!?%)\\]}\\u2019\\u201d\\u00bb]/.test(after) || /[([{\\u2018\\u201c\\u00ab]/.test(before)) return ''\n // A straight quote opens after a space or a bracket, and closes before one.\n if (/[\"']/.test(before) && /^$|[\\s([{]/.test(whole[offset - 2] ?? '')) return ''\n if (/[\"']/.test(after) && /^$|[\\s.,;:!?)\\]}]/.test(whole[offset + match.length + 1] ?? '')) return ''\n return ' '\n })\n}\n\nconst NAMED_ENTITIES: Record<string, string> = {\n amp: '&',\n lt: '<',\n gt: '>',\n quot: '\"',\n apos: \"'\",\n nbsp: ' ',\n rsquo: '’',\n lsquo: '‘',\n rdquo: '”',\n ldquo: '“',\n mdash: '—',\n ndash: '–',\n hellip: '…',\n copy: '©',\n reg: '®',\n trade: '™',\n middot: '·',\n bull: '•',\n eacute: 'é',\n egrave: 'è',\n aacute: 'á',\n ntilde: 'ñ',\n uuml: 'ü',\n ouml: 'ö',\n auml: 'ä',\n deg: '°',\n times: '×',\n}\n\n/** Character references to characters; an unknown name stays as written. */\nexport function decodeHtmlEntities(text: string): string {\n return text.replace(/&(#x[0-9a-f]+|#\\d+|[a-z][a-z0-9]*);/gi, (whole, body: string) => {\n if (body[0] === '#') {\n const code =\n body[1] === 'x' || body[1] === 'X' ? parseInt(body.slice(2), 16) : parseInt(body.slice(1), 10)\n if (!Number.isFinite(code) || code <= 0 || code > 0x10ffff) return ''\n if (code < 32 && code !== 9 && code !== 10 && code !== 13) return ''\n return String.fromCodePoint(code)\n }\n const named = NAMED_ENTITIES[body.toLowerCase()]\n return named ?? whole\n })\n}\n\nconst ATTRIBUTE = /([^\\s=/>\"']+)(?:\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s>\"']+)))?/g\n\n/** A tag's attributes, names lowercased, values decoded. */\nexport function parseAttributes(source: string): Record<string, string> {\n const attributes: Record<string, string> = {}\n for (const match of source.matchAll(ATTRIBUTE)) {\n const name = match[1].toLowerCase()\n if (name in attributes) continue\n attributes[name] = decodeHtmlEntities(match[2] ?? match[3] ?? match[4] ?? '')\n }\n return attributes\n}\n\nconst TAG = /<(\\/?)([a-zA-Z][\\w:-]*)((?:[^>\"']|\"[^\"]*\"|'[^']*')*)>/g\n\n/** Every `<meta>` tag's attributes. */\nfunction metaTags(html: string): Record<string, string>[] {\n const out: Record<string, string>[] = []\n for (const match of html.matchAll(/<meta\\b((?:[^>\"']|\"[^\"]*\"|'[^']*')*)>/gi)) {\n out.push(parseAttributes(match[1]))\n }\n return out\n}\n\n/** The `content` of every `<meta name=\"…\">` with this name. */\nexport function readMetaValues(html: string, name: string): string[] {\n const wanted = name.toLowerCase()\n return metaTags(html)\n .filter((attributes) => (attributes['name'] ?? '').toLowerCase() === wanted)\n .map((attributes) => (attributes['content'] ?? '').trim())\n .filter(Boolean)\n}\n\nfunction collapse(text: string): string {\n return joinRuns(text).replace(/\\s+/g, ' ').trim()\n}\n\nfunction clip(text: string, max: number): string {\n return text.length > max ? `${text.slice(0, max - 1).trimEnd()}…` : text\n}\n\nfunction removeElements(html: string, tags: readonly string[]): string {\n let out = html\n for (const tag of tags) {\n const paired = new RegExp(`<${tag}\\\\b(?:[^>\"']|\"[^\"]*\"|'[^']*')*>[\\\\s\\\\S]*?<\\\\/${tag}\\\\s*>`, 'gi')\n out = out.replace(paired, ' ')\n // One left open runs to the end of the document, as a browser reads it.\n const unclosed = new RegExp(`<${tag}\\\\b(?:[^>\"']|\"[^\"]*\"|'[^']*')*>[\\\\s\\\\S]*$`, 'i')\n out = out.replace(unclosed, ' ')\n }\n return out\n}\n\n/** Forms with a payment field go whole; the rest are summarized, then go. */\nfunction takeForms(html: string): { html: string; kept: SiteImportForm[]; removed: number } {\n const kept: SiteImportForm[] = []\n let removed = 0\n const out = html.replace(/<form\\b(?:[^>\"']|\"[^\"]*\"|'[^']*')*>[\\s\\S]*?(?:<\\/form\\s*>|$)/gi, (form) => {\n if (PAYMENT_FIELD.test(form)) {\n removed += 1\n return ' '\n }\n if (kept.length < SITE_IMPORT_PAGE_LIMITS.forms) {\n const fields: SiteImportForm['fields'] = []\n for (const match of form.matchAll(/<(input|textarea|select)\\b((?:[^>\"']|\"[^\"]*\"|'[^']*')*)>/gi)) {\n const attributes = parseAttributes(match[2])\n const type = match[1].toLowerCase() === 'input' ? (attributes['type'] || 'text').toLowerCase() : match[1].toLowerCase()\n if (type === 'hidden' || type === 'submit' || type === 'button' || type === 'image') continue\n // A field no visitor sees is a trap for bots or a widget's shadow, not a question (AGL-4083).\n if ((attributes['aria-hidden'] ?? '').toLowerCase() === 'true' || attributes['tabindex'] === '-1') continue\n fields.push({ type, name: clip(attributes['name'] || attributes['id'] || '', 80) })\n if (fields.length >= SITE_IMPORT_PAGE_LIMITS.fieldsPerForm) break\n }\n kept.push({ fields })\n // Where the form sat, for the layout (AGL-4106): a marker, never words.\n return ` <aglyn-form data-form=\"${kept.length - 1}\"> `\n }\n return ' '\n })\n return { html: out, kept, removed }\n}\n\n/** `raw` against the page, as an absolute http(s) address without a fragment. */\nexport function resolveSiteUrl(raw: string | undefined, base: string): URL | null {\n const value = String(raw ?? '').trim()\n if (!value || /^(?:javascript|data|mailto|tel|sms|blob|about):/i.test(value)) return null\n try {\n const url = new URL(value, base)\n if (url.protocol !== 'https:' && url.protocol !== 'http:') return null\n url.hash = ''\n return url\n } catch {\n return null\n }\n}\n\n/** The first address a `srcset` offers. */\nfunction firstSrcset(srcset: string | undefined): string | undefined {\n const first = String(srcset ?? '').split(',')[0]?.trim().split(/\\s+/)[0]\n return first || undefined\n}\n\n/**\n * Where a link a page shows goes (AGL-4083): an absolute http(s) address\n * without its fragment, a `mailto:` with an address in it, or a `tel:` with\n * a number in it; `null` for anything else (a script, a jump on the page).\n */\nexport function resolveSiteLink(raw: string | undefined, base: string): string | null {\n const value = String(raw ?? '').trim()\n const mail = /^mailto:([^?\\s<>\"']+@[^?\\s<>\"']+)/i.exec(value)\n if (mail) return `mailto:${decodeURIComponent(mail[1]).toLowerCase()}`\n const phone = /^tel:([+\\d][\\d\\s().-]{2,30})$/i.exec(value)\n if (phone) return `tel:${phone[1].replace(/[\\s().-]/g, '')}`\n if (value.startsWith('#')) return null\n return resolveSiteUrl(value, base)?.toString() ?? null\n}\n\n/**\n * A `<picture>` whose `<img>` has no address of its own (a placeholder, or\n * none at all) is read from its first `<source>` (AGL-4083); a `<picture>`\n * whose `<img>` has one keeps it. The sources go with the void elements.\n */\nfunction readPictures(html: string): string {\n return html.replace(/<picture\\b(?:[^>\"']|\"[^\"]*\"|'[^']*')*>([\\s\\S]*?)<\\/picture\\s*>/gi, (whole, inner: string) => {\n const img = /<img\\b((?:[^>\"']|\"[^\"]*\"|'[^']*')*)>/i.exec(inner)\n const attributes = img ? parseAttributes(img[1]) : {}\n const own = attributes['src'] || attributes['data-src'] || firstSrcset(attributes['srcset'] || attributes['data-srcset'])\n if (own && !/^data:/i.test(own.trim())) return whole\n let source: string | undefined\n for (const match of inner.matchAll(/<source\\b((?:[^>\"']|\"[^\"]*\"|'[^']*')*)>/gi)) {\n const sourceAttributes = parseAttributes(match[1])\n source = firstSrcset(sourceAttributes['srcset'] || sourceAttributes['data-srcset'])\n if (source) break\n }\n if (!source) return whole\n const quote = (value: string) => value.replace(/&/g, '&').replace(/\"/g, '"').replace(/</g, '<')\n return ` <img src=\"${quote(source)}\" alt=\"${quote(attributes['alt'] ?? '')}\"> `\n })\n}\n\n/** The head's icons, the largest first within each kind. */\nfunction readIcons(html: string, pageUrl: string): SiteImportIcon[] {\n const icons: SiteImportIcon[] = []\n for (const match of html.matchAll(/<link\\b((?:[^>\"']|\"[^\"]*\"|'[^']*')*)>/gi)) {\n const attributes = parseAttributes(match[1])\n const rels = (attributes['rel'] ?? '').toLowerCase().split(/\\s+/)\n const rel = rels.includes('apple-touch-icon') || rels.includes('apple-touch-icon-precomposed')\n ? 'apple-touch-icon'\n : rels.includes('icon')\n ? 'icon'\n : null\n if (!rel) continue\n const url = resolveSiteUrl(attributes['href'], pageUrl)\n if (!url) continue\n const sizes: string[] = [...((attributes['sizes'] ?? '').match(/(\\d+)\\s*x\\s*(\\d+)/gi) ?? [])]\n const size = sizes.reduce<number>((most, entry) => Math.max(most, ...entry.split(/x/i).map((side) => Number(side) || 0)), 0)\n icons.push({ url: url.toString(), rel, size: size || null, type: attributes['type']?.trim() || null })\n if (icons.length >= SITE_IMPORT_PAGE_LIMITS.icons) break\n }\n return icons.sort((a, b) => (a.rel === b.rel ? (b.size ?? 0) - (a.size ?? 0) : a.rel === 'apple-touch-icon' ? -1 : 1))\n}\n\nconst ORGANIZATION_TYPE = /(?:^|\\b)(?:Organization|Corporation|LocalBusiness|NGO|EducationalOrganization|MedicalOrganization|SportsOrganization|Store|Restaurant|ProfessionalService|HomeAndConstructionBusiness|HealthAndBeautyBusiness|FoodEstablishment|AutomotiveBusiness|LegalService|FinancialService|Dentist|Physician|LodgingBusiness|EntertainmentBusiness)$/\n\n/**\n * The first Organization (or kind of local business) the page's structured\n * data describes, read before scripts are thrown away. Malformed data, or\n * none, is `null`; nothing in it is ever run.\n */\nfunction readOrganization(html: string): SiteImportOrganization | null {\n const nodes: Record<string, unknown>[] = []\n const visit = (value: unknown, depth: number) => {\n if (depth > 4 || nodes.length > 50 || !value || typeof value !== 'object') return\n if (Array.isArray(value)) {\n for (const entry of value) visit(entry, depth + 1)\n return\n }\n const node = value as Record<string, unknown>\n nodes.push(node)\n if (node['@graph']) visit(node['@graph'], depth + 1)\n }\n for (const match of html.matchAll(/<script\\b[^>]*\\btype\\s*=\\s*[\"']?application\\/ld\\+json[\"']?[^>]*>([\\s\\S]*?)<\\/script\\s*>/gi)) {\n try {\n visit(JSON.parse(match[1]), 0)\n } catch {\n // Structured data that does not parse says nothing.\n }\n }\n const typeOf = (node: Record<string, unknown>) => ([] as unknown[]).concat(node['@type'] ?? []).map(String)\n const node = nodes.find((entry) => typeOf(entry).some((type) => ORGANIZATION_TYPE.test(type)))\n if (!node) return null\n const text = (value: unknown, max = 300): string => (typeof value === 'string' ? clip(collapse(value), max) : '')\n const urlOf = (value: unknown): string => {\n const raw = typeof value === 'string' ? value : value && typeof value === 'object' ? (value as Record<string, unknown>)['url'] : ''\n return typeof raw === 'string' && /^https?:\\/\\//i.test(raw.trim()) ? raw.trim() : ''\n }\n const contact = ([] as unknown[]).concat(node['contactPoint'] ?? []).find((entry) => entry && typeof entry === 'object') as\n | Record<string, unknown>\n | undefined\n const address = (() => {\n const value = node['address']\n if (typeof value === 'string') return text(value)\n if (!value || typeof value !== 'object') return ''\n const parts = value as Record<string, unknown>\n const region = [text(parts['addressRegion']), text(parts['postalCode'])].filter(Boolean).join(' ')\n const country = parts['addressCountry']\n return [text(parts['streetAddress']), text(parts['addressLocality']), region, typeof country === 'string' ? text(country) : text((country as Record<string, unknown> | null)?.['name'])]\n .filter(Boolean)\n .join(', ')\n })()\n return {\n name: text(node['name']),\n description: text(node['description'], 1_000),\n url: urlOf(node['url']),\n logo: urlOf(node['logo']),\n telephone: text(node['telephone']) || text(contact?.['telephone']),\n email: (text(node['email']) || text(contact?.['email'])).replace(/^mailto:/i, ''),\n address,\n sameAs: ([] as unknown[])\n .concat(node['sameAs'] ?? [])\n .map((entry) => urlOf(entry))\n .filter(Boolean)\n .slice(0, 20),\n }\n}\n\n/*------------------------------------------\n * How the page is built (AGL-4106)\n *-----------------------------------------*/\n\nconst SVG_ELEMENT = /<svg\\b((?:[^>\"']|\"[^\"]*\"|'[^']*')*)>([\\s\\S]*?)<\\/svg\\s*>/gi\nconst SVG_SHAPE = /<(path|circle|rect|ellipse|line|polyline|polygon)\\b((?:[^>\"']|\"[^\"]*\"|'[^']*')*)>/gi\n/** What a drawing keeps of a shape: its geometry and paint, never a link, a script or a reference. */\nconst SVG_SHAPE_ATTRIBUTES = new Set([\n 'd',\n 'cx',\n 'cy',\n 'r',\n 'rx',\n 'ry',\n 'x',\n 'y',\n 'x1',\n 'y1',\n 'x2',\n 'y2',\n 'width',\n 'height',\n 'points',\n 'fill',\n 'fill-rule',\n 'clip-rule',\n 'fill-opacity',\n 'stroke',\n 'stroke-width',\n 'stroke-linecap',\n 'stroke-linejoin',\n 'opacity',\n 'transform',\n])\nconst SVG_SAFE_VALUE = /^[\\w\\s.,#%()+-]*$/\nconst SVG_PATH_DATA = /^[MmZzLlHhVvCcSsQqTtAa0-9eE.,\\s+-]+$/\nconst VIEW_BOX = /^-?[\\d.]+(?:[\\s,]+-?[\\d.]+){3}$/\n\n/** An `<svg>`'s drawing area: its `viewBox`, else its size, else the 24-unit square of an icon set. */\nfunction viewBoxOf(attributes: Record<string, string>): string {\n const written = (attributes['viewbox'] ?? '').trim().replace(/[\\s,]+/g, ' ')\n if (VIEW_BOX.test(written)) return written\n const width = parseFloat(attributes['width'] ?? '')\n const height = parseFloat(attributes['height'] ?? '')\n return width > 0 && height > 0 ? `0 0 ${width} ${height}` : '0 0 24 24'\n}\n\n/**\n * Every inline `<svg>` turned into a marker the walk reads as an icon at its\n * place, its drawing kept in `icons` once however often it repeats. A drawing\n * that embeds anything but shapes (a picture, text, a reference) is no icon\n * and goes, as every `<svg>` did before.\n */\nfunction readSvgIcons(html: string, icons: SiteImportSvgIcon[]): string {\n const seen = new Map<string, number>()\n return html.replace(SVG_ELEMENT, (whole: string, attributeSource: string, inner: string) => {\n if (/<(?:image|foreignobject|use|text|script)\\b/i.test(inner)) return ' '\n const shapes = [...inner.matchAll(SVG_SHAPE)]\n if (!shapes.length) return ' '\n const viewBox = viewBoxOf(parseAttributes(attributeSource))\n let icon: SiteImportSvgIcon | null = null\n if (shapes.length === 1 && shapes[0][1].toLowerCase() === 'path') {\n const d = (parseAttributes(shapes[0][2])['d'] ?? '').trim()\n if (d && d.length <= 4_096 && SVG_PATH_DATA.test(d)) icon = { viewBox, path: d }\n }\n if (!icon && whole.length <= 16_384 && shapes.length <= 64) {\n const drawn = shapes.map(([, tag, source]) => {\n const kept = Object.entries(parseAttributes(source))\n .filter(([name, value]) => SVG_SHAPE_ATTRIBUTES.has(name) && SVG_SAFE_VALUE.test(value) && !/url\\s*\\(/i.test(value))\n .map(([name, value]) => `${name}=\"${value}\"`)\n return `<${tag.toLowerCase()}${kept.length ? ` ${kept.join(' ')}` : ''}/>`\n })\n icon = { viewBox, svg: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"${viewBox}\">${drawn.join('')}</svg>` }\n }\n if (!icon) return ' '\n const key = `${icon.viewBox}|${icon.path ?? icon.svg}`\n let index = seen.get(key)\n if (index === undefined) {\n if (icons.length >= SITE_IMPORT_PAGE_LIMITS.svgIcons) return ' '\n index = icons.length\n icons.push(icon)\n seen.set(key, index)\n }\n return ` <aglyn-svg data-icon=\"${index}\"> `\n })\n}\n\n/** The page's own `<style>` sheets and the stylesheets it links, print ones left out. */\nfunction readStyleSheets(html: string, pageUrl: string): { styles: string[]; stylesheets: string[] } {\n const styles: string[] = []\n let chars = 0\n for (const match of html.matchAll(/<style\\b((?:[^>\"']|\"[^\"]*\"|'[^']*')*)>([\\s\\S]*?)<\\/style\\s*>/gi)) {\n const media = (parseAttributes(match[1])['media'] ?? '').toLowerCase()\n if (media && !/\\b(?:all|screen)\\b/.test(media)) continue\n const css = match[2] ?? ''\n if (!css.trim() || chars + css.length > SITE_IMPORT_PAGE_LIMITS.styleChars) continue\n chars += css.length\n styles.push(css)\n }\n const stylesheets: string[] = []\n for (const match of html.matchAll(/<link\\b((?:[^>\"']|\"[^\"]*\"|'[^']*')*)>/gi)) {\n const attributes = parseAttributes(match[1])\n if (!(attributes['rel'] ?? '').toLowerCase().split(/\\s+/).includes('stylesheet')) continue\n const media = (attributes['media'] ?? '').toLowerCase()\n if (media && !/\\b(?:all|screen)\\b/.test(media)) continue\n const url = resolveSiteUrl(attributes['href'], pageUrl)\n if (!url || url.protocol !== 'https:' || stylesheets.includes(url.toString())) continue\n stylesheets.push(url.toString())\n if (stylesheets.length >= SITE_IMPORT_PAGE_LIMITS.stylesheets) break\n }\n return { styles, stylesheets }\n}\n\n/** Elements with no content and no end tag. */\nconst VOID_TAGS = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr', 'aglyn-svg', 'aglyn-form'])\n\n/** Start tags that end an open `<p>`, as a browser reads them. */\nconst CLOSES_P = new Set([\n 'address',\n 'article',\n 'aside',\n 'blockquote',\n 'details',\n 'div',\n 'dl',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'header',\n 'hr',\n 'main',\n 'menu',\n 'nav',\n 'ol',\n 'p',\n 'pre',\n 'section',\n 'table',\n 'ul',\n])\n\n/** For each tag that ends an open one of its own kind: the kinds it ends, and the tags that wall the search off. */\nconst IMPLIED_END: Record<string, { ends: ReadonlySet<string>; walls: ReadonlySet<string> }> = {\n li: { ends: new Set(['li']), walls: new Set(['ul', 'ol', 'menu']) },\n dt: { ends: new Set(['dt', 'dd']), walls: new Set(['dl']) },\n dd: { ends: new Set(['dt', 'dd']), walls: new Set(['dl']) },\n tr: { ends: new Set(['tr', 'td', 'th']), walls: new Set(['table', 'tbody', 'thead', 'tfoot']) },\n td: { ends: new Set(['td', 'th']), walls: new Set(['tr', 'table']) },\n th: { ends: new Set(['td', 'th']), walls: new Set(['tr', 'table']) },\n option: { ends: new Set(['option']), walls: new Set(['select', 'datalist']) },\n tbody: { ends: new Set(['tbody', 'thead', 'tfoot', 'tr', 'td', 'th']), walls: new Set(['table']) },\n thead: { ends: new Set(['tbody', 'thead', 'tfoot', 'tr', 'td', 'th']), walls: new Set(['table']) },\n tfoot: { ends: new Set(['tbody', 'thead', 'tfoot', 'tr', 'td', 'th']), walls: new Set(['table']) },\n}\nconst P_WALLS = new Set(['button', 'table', 'td', 'th', 'caption', 'object', 'template', 'html', 'marquee', 'applet'])\n\n/** The attributes the layout reader reads. */\nfunction elementAttrs(attributes: Record<string, string>): SiteImportElementAttrs {\n const attrs: SiteImportElementAttrs = {}\n const text = (value: string | undefined, max: number) => {\n const clean = String(value ?? '').replace(/\\s+/g, ' ').trim()\n return clean ? clean.slice(0, max) : undefined\n }\n const put = <K extends keyof SiteImportElementAttrs>(key: K, value: SiteImportElementAttrs[K] | undefined) => {\n if (value !== undefined) attrs[key] = value\n }\n put('class', text(attributes['class'], 600))\n put('id', text(attributes['id'], 120))\n put('style', text(attributes['style'], 1_000))\n put('role', text(attributes['role'], 40)?.toLowerCase())\n put('label', text(attributes['aria-label'], 200))\n put('href', text(attributes['href'], 2_048))\n put('theme', text(attributes['data-section-theme'] ?? attributes['data-theme'], 40)?.toLowerCase())\n put('type', text(attributes['type'], 40)?.toLowerCase())\n put('controls', text(attributes['aria-controls'], 120))\n put('labelledby', text(attributes['aria-labelledby'], 120))\n if ('hidden' in attributes || (attributes['aria-hidden'] ?? '').toLowerCase() === 'true') attrs.hidden = true\n return attrs\n}\n\n/**\n * The words, structure, pictures and links of one page.\n *\n * `isSameSite(url)` says whether an address is on the site being imported;\n * only those become `links`, and images are marked by it.\n */\nexport function extractSiteImportPage(\n html: string,\n pageUrl: string,\n isSameSite: (url: URL) => boolean,\n options: SiteImportExtractOptions = {},\n): SiteImportExtract {\n const empty: SiteImportExtract = {\n title: '',\n description: '',\n lang: null,\n canonical: null,\n ogImage: null,\n siteName: '',\n icons: [],\n brand: null,\n organization: null,\n blocks: [],\n images: [],\n navLinks: [],\n links: [],\n forms: { kept: [], removed: 0 },\n loginForm: false,\n }\n let source = String(html ?? '')\n .replace(/<!--[\\s\\S]*?(?:-->|$)/g, ' ')\n .replace(/<!\\[CDATA\\[[\\s\\S]*?\\]\\]>/g, ' ')\n if (PASSWORD_INPUT.test(source)) return { ...empty, loginForm: true }\n\n // Read before scripts go: the structured data is a script's body.\n const organization = readOrganization(source)\n const icons = readIcons(source, pageUrl)\n const keep = options.structure === true\n const sheets = keep ? readStyleSheets(source, pageUrl) : { styles: [], stylesheets: [] }\n // An inline icon is a marker at its place (AGL-4106); its drawing is never words.\n const svgIcons: SiteImportSvgIcon[] = []\n source = readSvgIcons(source, svgIcons)\n source = removeElements(readPictures(source), REMOVED_WITH_CONTENT).replace(REMOVED_VOID, ' ')\n // Forms next, so a field list is read before the controls go.\n const forms = takeForms(source)\n source = removeElements(forms.html, FORM_CONTROLS)\n\n const metas = metaTags(source)\n const metaContent = (key: string, attribute: 'name' | 'property') =>\n collapse(metas.find((m) => (m[attribute] ?? '').toLowerCase() === key)?.['content'] ?? '')\n const titleMatch = /<title\\b[^>]*>([\\s\\S]*?)<\\/title\\s*>/i.exec(source)\n const title = clip(\n collapse(decodeHtmlEntities(titleMatch?.[1] ?? '')) || metaContent('og:title', 'property'),\n 300,\n )\n const description = clip(\n metaContent('description', 'name') || metaContent('og:description', 'property'),\n 1_000,\n )\n const ogImage =\n resolveSiteUrl(metaContent('og:image', 'property') || metaContent('og:image:url', 'property') || metaContent('twitter:image', 'name'), pageUrl)?.toString() ??\n null\n const siteName = clip(metaContent('og:site_name', 'property') || metaContent('application-name', 'name'), 120)\n const htmlTag = /<html\\b((?:[^>\"']|\"[^\"]*\"|'[^']*')*)>/i.exec(source)\n const lang = htmlTag ? parseAttributes(htmlTag[1])['lang']?.trim() || null : null\n let canonical: string | null = null\n for (const match of String(html ?? '').matchAll(/<link\\b((?:[^>\"']|\"[^\"]*\"|'[^']*')*)>/gi)) {\n const attributes = parseAttributes(match[1])\n if ((attributes['rel'] ?? '').toLowerCase().split(/\\s+/).includes('canonical')) {\n canonical = resolveSiteUrl(attributes['href'], pageUrl)?.toString() ?? null\n break\n }\n }\n\n const bodyStart = source.search(/<body\\b/i)\n const body = bodyStart >= 0 ? source.slice(bodyStart) : source.replace(/<head\\b[\\s\\S]*?<\\/head\\s*>/i, ' ')\n const hasNav = /<nav\\b/i.test(body)\n\n const blocks: SiteImportBlock[] = []\n const images: SiteImportImage[] = []\n const imageSeen = new Set<string>()\n const navLinks: SiteImportNavLink[] = []\n const links: string[] = []\n const linkSeen = new Set<string>()\n let brand: SiteImportBrandMark | null = null\n\n let navDepth = 0\n let headerDepth = 0\n let footerDepth = 0\n let current: { kind: 'heading' | 'paragraph' | 'list-item' | 'quote'; level?: number; tag: string; element: number } | null = null\n let buffer = ''\n /** The link being read: its menu address (http(s) only), where it goes, its words and its first picture. */\n let anchor: {\n url: URL | null\n href: string | null\n text: string\n /** Its words split where a block-level tag inside it began, for a menu entry's first line. */\n lines: string[]\n image: { url: string; alt: string } | null\n /** Where in `buffer` its words begin. */\n start: number\n /** Its words ran across a block's end: some of them are in a block already. */\n crossed: boolean\n region: SiteImportRegion\n /** Its element, and the first icon inside it (AGL-4106). */\n element: number\n icon?: number\n } | null = null\n /** The links read into the block being built, written after it. */\n let pending: Array<{ text: string; href: string; start: number; end: number; crossed: boolean; region: SiteImportRegion; element: number }> = []\n\n // How the page is built (AGL-4106): every element, in a flat table, and\n // the element each block's words sit in. Kept only when asked for.\n const elements: SiteImportElement[] = []\n const blockElement: number[] = []\n const anchors: SiteImportAnchor[] = []\n const texts: Array<{ element: number; text: string }> = []\n /** Where in `buffer` the words no link has taken begin: a menu's own words are read from here. */\n let ownFrom = 0\n /** A menu's or a header's own words, outside its links (AGL-4106), from `ownFrom` on. */\n const takeOwnWords = (element: number) => {\n if (!keep || element < 0 || !(navDepth > 0 || headerDepth > 0) || texts.length >= SITE_IMPORT_PAGE_LIMITS.anchors) return\n const words = clip(collapse(decodeHtmlEntities(buffer.slice(ownFrom))), 300)\n if (words) texts.push({ element, text: words })\n }\n /** The elements open where the walk is, innermost last. */\n const open: number[] = []\n let mainElement = -1\n let roleMain = -1\n let bodyElement = -1\n /** The element the loose words being read began in. */\n let looseElement = -1\n const top = () => (open.length ? (open[open.length - 1] as number) : -1)\n\n const region = (): SiteImportRegion =>\n footerDepth > 0 ? 'footer' : headerDepth > 0 ? 'header' : 'main'\n // A site without a <nav> keeps its menu in the header; its links are the nav.\n const inNav = () => navDepth > 0 || (!hasNav && headerDepth > 0)\n const room = () => blocks.length < SITE_IMPORT_PAGE_LIMITS.blocks\n\n /** A block, and where its words sit. */\n const push = (block: SiteImportBlock, element: number) => {\n blocks.push(block)\n if (!keep) return\n blockElement.push(element)\n const owner = elements[element]\n if (!owner) return\n owner.blocks.push(blocks.length - 1)\n if (owner.order === undefined) owner.order = blocks.length - 1\n }\n\n /** Pops the open elements down to the innermost `tags` one, unless a wall stands first. */\n const endOpen = (tags: ReadonlySet<string>, walls: ReadonlySet<string>) => {\n for (let at = open.length - 1; at >= 0; at -= 1) {\n const tag = elements[open[at] as number]?.tag ?? ''\n if (tags.has(tag)) {\n open.length = at\n return\n }\n if (walls.has(tag)) return\n }\n }\n const P_ONLY = new Set(['p'])\n /** An element opens: what it implies is closed first, then it is the innermost. */\n const openElement = (tag: string, attributes: Record<string, string>, selfClosing: boolean): number => {\n if (!keep) return -1\n if (CLOSES_P.has(tag)) endOpen(P_ONLY, P_WALLS)\n const implied = IMPLIED_END[tag]\n if (implied) endOpen(implied.ends, implied.walls)\n const isVoid = VOID_TAGS.has(tag)\n if (isVoid && tag !== 'img' && tag !== 'aglyn-svg' && tag !== 'aglyn-form') return -1\n if (elements.length >= SITE_IMPORT_PAGE_LIMITS.elements) return -1\n const id = elements.length\n const parent = top()\n elements.push({ id, tag, parent, children: [], region: region(), nav: inNav(), attrs: elementAttrs(attributes), blocks: [] })\n elements[parent]?.children.push(id)\n if (!isVoid && !selfClosing) open.push(id)\n if (tag === 'body' && bodyElement < 0) bodyElement = id\n if (tag === 'main' && mainElement < 0) mainElement = id\n if (roleMain < 0 && (attributes['role'] ?? '').toLowerCase() === 'main') roleMain = id\n return id\n }\n /** An element closes: it and everything still open inside it. */\n const closeElement = (tag: string) => {\n if (!keep) return\n for (let at = open.length - 1; at >= 0; at -= 1) {\n if (elements[open[at] as number]?.tag === tag) {\n open.length = at\n return\n }\n }\n }\n\n const flush = () => {\n const raw = buffer\n const written = pending\n const loose = current === null\n const element = current?.element ?? looseElement\n if (!anchor) takeOwnWords(element)\n ownFrom = 0\n buffer = ''\n pending = []\n looseElement = -1\n if (anchor && collapse(decodeHtmlEntities(raw.slice(anchor.start)))) anchor.crossed = true\n if (anchor) anchor.start = 0\n const kind = current?.kind ?? 'paragraph'\n const level = current?.level\n current = null\n const text = clip(collapse(decodeHtmlEntities(raw)), SITE_IMPORT_PAGE_LIMITS.blockChars)\n if (navDepth > 0) return\n // Loose words that are only links (a row of buttons, an address in a\n // card) are those links, each a block of its own; words around a link\n // keep their block, and the link follows it.\n let rest = raw\n for (const link of [...written].sort((a, b) => b.start - a.start)) rest = `${rest.slice(0, link.start)}${rest.slice(link.end)}`\n const onlyLinks = loose && written.length > 0 && !collapse(decodeHtmlEntities(rest))\n if (text && !onlyLinks && room()) {\n const last = blocks[blocks.length - 1]\n if (!(last && last.kind !== 'image' && last.kind !== 'link' && last.text === text)) {\n if (kind === 'heading') {\n push({ kind, level: (level ?? 2) as 1 | 2 | 3 | 4 | 5 | 6, text, region: region() }, element)\n } else {\n push({ kind, text, region: region() }, element)\n }\n }\n }\n for (const link of written) {\n if (!room()) break\n const last = blocks[blocks.length - 1]\n if (last?.kind === 'link' && last.href === link.href && last.text === link.text) continue\n const inline = !onlyLinks || link.crossed\n push({ kind: 'link', text: link.text, href: link.href, region: link.region, ...(inline ? { inline: true as const } : {}) }, link.element)\n }\n }\n\n /** A boundary between two runs of words: in the block, and in the link being read. */\n const boundary = (block: boolean) => {\n buffer += RUN_BREAK\n if (!anchor) return\n anchor.text += RUN_BREAK\n if (block && anchor.lines[anchor.lines.length - 1] !== '') anchor.lines.push('')\n }\n\n /** One tag of the page, read where the walk is. */\n const read = (closing: boolean, tag: string, attributes: Record<string, string>, element: number) => {\n if (tag === 'a') {\n if (closing) {\n if (anchor) {\n const label = clip(collapse(decodeHtmlEntities(anchor.text)), 300)\n const firstLine = clip(collapse(decodeHtmlEntities(anchor.lines.find((line) => collapse(decodeHtmlEntities(line))) ?? '')), 120)\n if (inNav() && anchor.url && firstLine && navLinks.length < SITE_IMPORT_PAGE_LIMITS.navLinks) {\n navLinks.push({ text: firstLine, url: anchor.url.toString() })\n }\n if (!brand && anchor.region !== 'footer' && (headerDepth > 0 || navDepth > 0) && anchor.url && isSameSite(anchor.url) && anchor.url.pathname === '/') {\n brand = { logo: anchor.image, text: label, region: anchor.region }\n }\n if (!inNav() && anchor.href && label) {\n pending.push({ text: label, href: anchor.href, start: anchor.start, end: buffer.length, crossed: anchor.crossed, region: anchor.region, element: anchor.element })\n }\n if (keep && anchor.element >= 0 && anchors.length < SITE_IMPORT_PAGE_LIMITS.anchors) {\n const lines = anchor.lines.map((line) => clip(collapse(decodeHtmlEntities(line)), 300)).filter(Boolean)\n anchors.push({\n element: anchor.element,\n href: anchor.href,\n label: firstLine,\n text: clip(lines.slice(1).join(' '), 300),\n region: anchor.region,\n nav: inNav(),\n ...(anchor.icon !== undefined ? { icon: anchor.icon } : {}),\n ...(anchor.image ? { image: anchor.image.url } : {}),\n })\n }\n anchor = null\n }\n boundary(false)\n ownFrom = buffer.length\n return\n }\n // Words before a link in a menu are its own: a column's heading.\n if (!anchor) takeOwnWords(current?.element ?? (looseElement >= 0 ? looseElement : top()))\n boundary(false)\n const url = resolveSiteUrl(attributes['href'], pageUrl)\n anchor = {\n url,\n href: resolveSiteLink(attributes['href'], pageUrl),\n text: '',\n lines: [''],\n image: null,\n start: buffer.length,\n crossed: false,\n region: region(),\n element,\n }\n if (url && isSameSite(url) && links.length < SITE_IMPORT_PAGE_LIMITS.links) {\n const key = url.toString()\n if (!linkSeen.has(key)) {\n linkSeen.add(key)\n links.push(key)\n }\n }\n return\n }\n\n if (tag === 'aglyn-svg') {\n // An icon at its place: never words (AGL-4106).\n const index = Number(attributes['data-icon'])\n if (keep && element >= 0 && Number.isInteger(index) && svgIcons[index]) {\n const own = elements[element] as SiteImportElement\n own.icon = index\n own.order = blocks.length - 0.5\n if (anchor && anchor.icon === undefined) anchor.icon = index\n }\n return\n }\n\n if (tag === 'aglyn-form') {\n const index = Number(attributes['data-form'])\n if (keep && element >= 0 && Number.isInteger(index)) {\n const own = elements[element] as SiteImportElement\n own.form = index\n own.order = blocks.length - 0.5\n }\n return\n }\n\n if (tag === 'img' && !closing) {\n const url = resolveSiteUrl(\n attributes['src'] || attributes['data-src'] || firstSrcset(attributes['srcset'] || attributes['data-srcset']),\n pageUrl,\n )\n boundary(false)\n if (url && images.length < SITE_IMPORT_PAGE_LIMITS.images) {\n const key = url.toString()\n const alt = clip(collapse(attributes['alt'] ?? ''), 300)\n if (anchor && !anchor.image) anchor.image = { url: key, alt }\n if (!imageSeen.has(key)) {\n imageSeen.add(key)\n images.push({ url: key, alt, sameSite: isSameSite(url), region: region() })\n if (navDepth === 0) {\n flush()\n if (room()) push({ kind: 'image', url: key, alt, region: region() }, element)\n }\n }\n }\n return\n }\n\n if (tag === 'nav' || tag === 'header' || tag === 'footer') {\n flush()\n boundary(true)\n const step = closing ? -1 : 1\n if (tag === 'nav') navDepth = Math.max(0, navDepth + step)\n if (tag === 'header') headerDepth = Math.max(0, headerDepth + step)\n if (tag === 'footer') footerDepth = Math.max(0, footerDepth + step)\n // The landmark is in its own region.\n const own = elements[element]\n if (own) {\n own.region = region()\n own.nav = inNav()\n }\n return\n }\n\n const heading = /^h([1-6])$/.exec(tag)\n if (heading || BLOCK_TAGS[tag]) {\n if (closing) {\n if (current?.tag === tag) flush()\n boundary(true)\n return\n }\n flush()\n boundary(true)\n current = heading\n ? { kind: 'heading', level: Number(heading[1]), tag, element }\n : { kind: BLOCK_TAGS[tag], tag, element }\n return\n }\n\n if (BREAK_TAGS.has(tag)) {\n if (tag === 'br' && current) {\n buffer += ' '\n if (anchor) anchor.text += ' '\n return\n }\n flush()\n boundary(true)\n return\n }\n\n if (RUN_BOUNDARY.has(tag)) boundary(false)\n }\n\n for (const match of body.matchAll(new RegExp(`${TAG.source}|([^<]+)|<`, 'g'))) {\n const text = match[4]\n if (text !== undefined || match[2] === undefined) {\n const run = text ?? '<'\n buffer += run\n if (keep && looseElement < 0 && current === null && run.trim()) looseElement = top()\n if (anchor) {\n anchor.text += run\n anchor.lines[anchor.lines.length - 1] += run\n }\n continue\n }\n const closing = match[1] === '/'\n const tag = match[2].toLowerCase()\n const attributes = closing ? {} : parseAttributes(match[3] ?? '')\n const element = closing ? -1 : openElement(tag, attributes, /\\/\\s*$/.test(match[3] ?? ''))\n read(closing, tag, attributes, element)\n if (closing) closeElement(tag)\n }\n flush()\n\n return {\n title,\n description,\n lang,\n canonical,\n ogImage,\n siteName,\n icons,\n brand,\n organization,\n blocks,\n images,\n navLinks,\n links,\n forms: { kept: forms.kept, removed: forms.removed },\n loginForm: false,\n ...(keep\n ? {\n structure: {\n elements,\n blockElement,\n icons: svgIcons,\n anchors,\n texts,\n styles: sheets.styles,\n stylesheets: sheets.stylesheets,\n main: mainElement >= 0 ? mainElement : roleMain,\n body: bodyElement,\n root: htmlTag ? elementAttrs(parseAttributes(htmlTag[1])) : {},\n },\n }\n : {}),\n }\n}\n"],"names":["SITE_IMPORT_PAGE_LIMITS","blocks","blockChars","images","links","navLinks","forms","fieldsPerForm","icons","elements","svgIcons","anchors","styleChars","stylesheets","REMOVED_WITH_CONTENT","FORM_CONTROLS","REMOVED_VOID","PASSWORD_INPUT","PAYMENT_FIELD","BLOCK_TAGS","p","li","dt","dd","td","th","address","pre","figcaption","caption","label","summary","button","blockquote","BREAK_TAGS","Set","RUN_BOUNDARY","RUN_BREAK","RUN_BREAKS","RegExp","joinRuns","text","includes","replace","match","offset","whole","test","before","after","length","NAMED_ENTITIES","amp","lt","gt","quot","apos","nbsp","rsquo","lsquo","rdquo","ldquo","mdash","ndash","hellip","copy","reg","trade","middot","bull","eacute","egrave","aacute","ntilde","uuml","ouml","auml","deg","times","decodeHtmlEntities","body","code","parseInt","slice","Number","isFinite","String","fromCodePoint","named","toLowerCase","ATTRIBUTE","parseAttributes","source","attributes","matchAll","name","TAG","metaTags","html","out","push","readMetaValues","wanted","filter","map","trim","Boolean","collapse","clip","max","trimEnd","removeElements","tags","tag","paired","unclosed","takeForms","kept","removed","form","fields","type","resolveSiteUrl","raw","base","value","url","URL","protocol","hash","firstSrcset","srcset","first","split","undefined","resolveSiteLink","mail","exec","decodeURIComponent","phone","startsWith","toString","readPictures","inner","img","own","sourceAttributes","quote","readIcons","pageUrl","rels","rel","sizes","size","reduce","most","entry","Math","side","sort","a","b","ORGANIZATION_TYPE","readOrganization","node","nodes","visit","depth","Array","isArray","JSON","parse","typeOf","concat","find","some","urlOf","contact","parts","region","join","country","description","logo","telephone","email","sameAs","SVG_ELEMENT","SVG_SHAPE","SVG_SHAPE_ATTRIBUTES","SVG_SAFE_VALUE","SVG_PATH_DATA","VIEW_BOX","viewBoxOf","written","width","parseFloat","height","readSvgIcons","seen","Map","attributeSource","icon","shapes","viewBox","d","path","drawn","Object","entries","has","svg","key","index","get","set","readStyleSheets","styles","chars","media","css","VOID_TAGS","CLOSES_P","IMPLIED_END","ends","walls","tr","option","tbody","thead","tfoot","P_WALLS","elementAttrs","attrs","clean","put","hidden","extractSiteImportPage","isSameSite","options","empty","title","lang","canonical","ogImage","siteName","brand","organization","loginForm","keep","structure","sheets","metas","metaContent","attribute","m","titleMatch","htmlTag","bodyStart","search","hasNav","imageSeen","linkSeen","navDepth","headerDepth","footerDepth","current","buffer","anchor","pending","blockElement","texts","ownFrom","takeOwnWords","element","words","open","mainElement","roleMain","bodyElement","looseElement","top","inNav","room","block","owner","order","endOpen","at","P_ONLY","openElement","selfClosing","implied","isVoid","id","parent","children","nav","closeElement","flush","loose","start","crossed","kind","level","rest","link","end","onlyLinks","last","href","inline","boundary","lines","read","closing","firstLine","line","pathname","image","add","isInteger","alt","sameSite","step","heading","run","main","root"],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import { type SiteImportBand, type SiteImportButtonStyle, type SiteImportGroupKind, type SiteImportLayout, type SiteImportLookFacts } from '../model/ai-site-import';
|
|
18
|
+
import { type SiteImportComputedStyle, type SiteImportStyles } from './site-import-css';
|
|
19
|
+
import { type SiteImportBlock, type SiteImportElement, type SiteImportExtract, type SiteImportStructure } from './site-import-html';
|
|
20
|
+
/** A page as the layout reader takes it: its blocks and how it is built. */
|
|
21
|
+
export type SiteImportLayoutSource = Pick<SiteImportExtract, 'blocks'> & {
|
|
22
|
+
structure: SiteImportStructure;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* The page's layout from its structure and its linked stylesheets' text,
|
|
26
|
+
* over its main-region lines. `null` for a page with no structure or no main
|
|
27
|
+
* content.
|
|
28
|
+
*/
|
|
29
|
+
export declare function siteImportLayout(page: SiteImportLayoutSource, stylesheets?: readonly string[]): SiteImportLayout | null;
|
|
30
|
+
/** A solid background's band: near white is the page, light or tinted is soft, a strong color is the brand's, dark is dark. */
|
|
31
|
+
export declare function siteImportBandOfColor(color: {
|
|
32
|
+
r: number;
|
|
33
|
+
g: number;
|
|
34
|
+
b: number;
|
|
35
|
+
a: number;
|
|
36
|
+
}): SiteImportBand;
|
|
37
|
+
/**
|
|
38
|
+
* How the source draws an `<a>` or `<button>` as a button, or `null` when it
|
|
39
|
+
* draws it as a link: a framework's button class, a role, or a fill or a
|
|
40
|
+
* border with room around the words.
|
|
41
|
+
*/
|
|
42
|
+
export declare function siteImportButtonStyleOf(element: SiteImportElement, style: SiteImportComputedStyle, under: string | null): SiteImportButtonStyle | null;
|
|
43
|
+
/** Families a Google Fonts stylesheet address loads: `family=Roboto+Flex:wght@400` is "Roboto Flex". */
|
|
44
|
+
export declare function siteImportGoogleFamilies(urls: readonly string[]): string[];
|
|
45
|
+
/** The look facts of a page read with its structure, through its linked stylesheets' text. */
|
|
46
|
+
export declare function siteImportLookOf(page: Pick<SiteImportLayoutSource, 'structure'>, stylesheets?: readonly string[]): SiteImportLookFacts | null;
|
|
47
|
+
/**
|
|
48
|
+
* The look facts of a page's markup and the stylesheets it links (AGL-4106),
|
|
49
|
+
* for the look pass, which reads the home page and its stylesheets itself.
|
|
50
|
+
*/
|
|
51
|
+
export declare function siteImportLookOfHtml(html: string, pageUrl: string, stylesheets?: readonly string[]): SiteImportLookFacts | null;
|
|
52
|
+
/**
|
|
53
|
+
* What the source's look is made of (AGL-4106): its fonts, its page's
|
|
54
|
+
* background and text, its filled buttons' fill, text and corners, its links'
|
|
55
|
+
* color and its header's background.
|
|
56
|
+
*/
|
|
57
|
+
export declare function siteImportLookFacts(structure: SiteImportStructure, styles: SiteImportStyles, fontFaces?: readonly string[]): SiteImportLookFacts;
|
|
58
|
+
/** What a layout holds, counted (AGL-4106): the reader's side of a fidelity score. */
|
|
59
|
+
export interface SiteImportLayoutCounts {
|
|
60
|
+
sections: number;
|
|
61
|
+
bands: SiteImportBand[];
|
|
62
|
+
/** Rows of two or more columns. */
|
|
63
|
+
rows: number;
|
|
64
|
+
/** Groups by kind, and the items in them. */
|
|
65
|
+
groups: Partial<Record<SiteImportGroupKind, number>>;
|
|
66
|
+
items: Partial<Record<SiteImportGroupKind, number>>;
|
|
67
|
+
tables: number;
|
|
68
|
+
tabs: number;
|
|
69
|
+
pictures: number;
|
|
70
|
+
/** Icons drawn: a group item's lead icon, each bullet's mark, and icons standing alone. */
|
|
71
|
+
icons: number;
|
|
72
|
+
/** Lines the source draws as buttons. */
|
|
73
|
+
buttons: number;
|
|
74
|
+
forms: number;
|
|
75
|
+
/** Lines placed, each once. */
|
|
76
|
+
lines: number;
|
|
77
|
+
}
|
|
78
|
+
/** Counts a layout's sections, bands, rows, groups, pictures, icons and buttons. */
|
|
79
|
+
export declare function siteImportLayoutCounts(layout: SiteImportLayout, blocks?: readonly SiteImportBlock[]): SiteImportLayoutCounts;
|