@aglyn/plugins-ai 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/package.json +17 -17
  2. package/src/lib/components/ai-site-start-card.component.d.ts +1 -1
  3. package/src/lib/components/ai-site-start-card.component.js +40 -13
  4. package/src/lib/components/ai-site-start-card.component.js.map +1 -1
  5. package/src/lib/components/ai-site-start-steps.component.d.ts +17 -1
  6. package/src/lib/components/ai-site-start-steps.component.js +30 -7
  7. package/src/lib/components/ai-site-start-steps.component.js.map +1 -1
  8. package/src/lib/components/assist-panel.component.js +8 -12
  9. package/src/lib/components/assist-panel.component.js.map +1 -1
  10. package/src/lib/jobs/ai-job-drafts.d.ts +3 -0
  11. package/src/lib/jobs/ai-job-drafts.js +5 -0
  12. package/src/lib/jobs/ai-job-drafts.js.map +1 -1
  13. package/src/lib/jobs/ai-job-layout-language.d.ts +10 -0
  14. package/src/lib/jobs/ai-job-layout-language.js +38 -2
  15. package/src/lib/jobs/ai-job-layout-language.js.map +1 -1
  16. package/src/lib/jobs/ai-job-layout-step.js +3 -3
  17. package/src/lib/jobs/ai-job-layout-step.js.map +1 -1
  18. package/src/lib/jobs/ai-site-import-compile.js +15 -7
  19. package/src/lib/jobs/ai-site-import-compile.js.map +1 -1
  20. package/src/lib/layout-language/ai-layout-compiler.js +39 -1
  21. package/src/lib/layout-language/ai-layout-compiler.js.map +1 -1
  22. package/src/lib/layout-language/ai-layout-frame.d.ts +6 -0
  23. package/src/lib/layout-language/ai-layout-frame.js +85 -30
  24. package/src/lib/layout-language/ai-layout-frame.js.map +1 -1
  25. package/src/lib/layout-language/ai-layout-language.d.ts +5 -0
  26. package/src/lib/layout-language/ai-layout-language.js.map +1 -1
  27. package/src/lib/model/ai-site-import-fidelity.d.ts +175 -0
  28. package/src/lib/model/ai-site-import-fidelity.js +941 -0
  29. package/src/lib/model/ai-site-import-fidelity.js.map +1 -0
  30. package/src/lib/model/ai-site-start.d.ts +27 -0
  31. package/src/lib/model/ai-site-start.js +41 -0
  32. package/src/lib/model/ai-site-start.js.map +1 -1
  33. package/src/lib/model/assist-page-change.d.ts +26 -6
  34. package/src/lib/model/assist-page-change.js +32 -10
  35. package/src/lib/model/assist-page-change.js.map +1 -1
  36. package/src/lib/runtime/ai-node-tree.js +18 -2
  37. package/src/lib/runtime/ai-node-tree.js.map +1 -1
  38. package/src/lib/server/assist-chat.d.ts +5 -0
  39. package/src/lib/server/assist-chat.js +11 -2
  40. package/src/lib/server/assist-chat.js.map +1 -1
  41. package/src/lib/server/assist-page-change.d.ts +12 -0
  42. package/src/lib/server/assist-page-change.js +23 -1
  43. package/src/lib/server/assist-page-change.js.map +1 -1
  44. package/src/lib/site-import/fixtures/site-import-fidelity-replay.d.ts +62 -0
  45. package/src/lib/site-import/fixtures/site-import-fidelity-replay.js +374 -0
  46. package/src/lib/site-import/fixtures/site-import-fidelity-replay.js.map +1 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/ai-site-start-steps.component.tsx"],"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'use client'\n\nimport { pluginDocsHelp } from '@aglyn/aglyn/app-utils/docs-help'\nimport {\n mdiBookOpenPageVariant,\n mdiBriefcaseOutline,\n mdiCalendarHeart,\n mdiCheck,\n mdiChevronDown,\n mdiCreation,\n mdiHandHeart,\n mdiScaleBalance,\n mdiShopping,\n mdiSilverwareForkKnife,\n mdiViewGridOutline,\n mdiWrench,\n} from '@aglyn/shared-data-mdi'\nimport { HelpTip, MdiIcon } from '@aglyn/shared-ui-jsx'\nimport { OptionCardGrid } from '@aglyn/shared-ui-jsx/components/option-card-grid.component'\nimport { BlockedControl } from '@aglyn/shared-ui-jsx/components/blocked-control.component'\nimport { PrerequisiteNotice } from '@aglyn/shared-ui-jsx/components/prerequisite-notice.component'\nimport { OpeningHoursPicker } from '@aglyn/shared-ui-jsx/components/weekly-hours-picker.component'\nimport {\n Accordion,\n AccordionDetails,\n AccordionSummary,\n Box,\n Divider,\n FormHelperText,\n LinearProgress,\n List,\n ListItemButton,\n MenuItem,\n Stack,\n Step,\n StepButton,\n StepLabel,\n Stepper,\n TextField,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport { Fragment, useId, useState, type ReactNode, type Ref } from 'react'\nimport { aiSiteHoursSentence, aiSiteServiceAreas, aiSiteSocialLinks } from '../model/ai-site-details'\nimport { AI_SITE_FREE_PAGES_NOTE, AI_SITE_SUBMISSION_CHOICES, type AiSiteSubmissions } from '../model/ai-site-job'\nimport { AI_SITE_KINDS } from '../model/ai-site-kinds'\nimport {\n AI_SITE_INSPIRATION_LIMITS,\n AI_SITE_INSPIRATION_MAX,\n AI_SITE_INSPIRATION_PAID_NOTE,\n aiSiteInspirationHost,\n} from '../model/ai-site-inspiration'\nimport { SITE_STYLE_AUTO } from '@aglyn/aglyn/app-utils/site-styles'\nimport {\n AI_SITE_START_TYPES,\n aiSiteStartInspirationTyped,\n aiSiteStartKind,\n aiSiteStartStyleAnswer,\n type AiSiteStartAnswers,\n type AiSiteStartExtraKey,\n} from '../model/ai-site-start'\nimport {\n AI_SITE_START_MORE_FIELDS,\n AI_SITE_START_STEP_LABELS,\n AI_SITE_START_STEPS,\n aiSiteStartStepIndex,\n type AiSiteStartField,\n type AiSiteStartFieldError,\n type AiSiteStartStep,\n} from '../model/ai-site-start-steps'\nimport type { AiSiteStartTracker } from './ai-site-start-tracking'\nimport { aiSiteStylePreview } from './ai-site-style-previews'\n\n/**\n * The guided start's question steps (AGL-3898), one decision each. Each step\n * draws its own answers and writes them through `answer`, exactly the patch\n * the single form wrote, so the answers object is the same whichever way it\n * was filled in. The dialog around them (`ai-site-start-card.component.tsx`)\n * owns the step, Back and Next, validation and the job.\n */\n\n/** Each part of the guided start links its own section of the Start with AI guide (AGL-3660). */\nexport const START_STEP_HELP = {\n kind: pluginDocsHelp('aiStart', {\n anchor: '#your-business',\n excerpt:\n 'What kind of site it is picks its style and pages; who it is for is who every page and the contact form are written for.',\n }),\n audience: pluginDocsHelp('aiStart', {\n anchor: '#audience',\n excerpt: 'Who the site is for is who every page, every search listing and the contact form are written for. Optional.',\n }),\n review: pluginDocsHelp('aiStart', {\n anchor: '#review',\n excerpt: 'Every answer, each with Edit to change it. Plan my site creates the site, plans it, writes the pages and publishes it.',\n }),\n style: pluginDocsHelp('aiSiteLooks', {\n anchor: '#choose-a-style',\n excerpt:\n 'The style decides the look — theme, colors, fonts, buttons — and which pages the site usually has. Every site gets its own variation.',\n }),\n details: pluginDocsHelp('aiStart', {\n anchor: '#details',\n excerpt:\n 'Your phone number and email, which your pages show, where contact form messages go, how many pages to write, and on paid plans whether to draft a welcome email. All can be changed later.',\n }),\n}\n\n/** The icon on each kind-of-site card: the icon of the style that answer picks. */\nconst START_TYPE_ICONS: Readonly<Record<string, string>> = {\n 'a local service business': mdiBriefcaseOutline.path,\n 'a restaurant or cafe': mdiSilverwareForkKnife.path,\n 'a professional practice': mdiScaleBalance.path,\n 'a trades business': mdiWrench.path,\n 'a shop': mdiShopping.path,\n 'a nonprofit': mdiHandHeart.path,\n 'a personal portfolio': mdiViewGridOutline.path,\n 'an event': mdiCalendarHeart.path,\n}\n\n/** \"a restaurant or cafe\" as a card title: \"Restaurant or cafe\". The answer itself keeps its words. */\nexport function startTypeTitle(type: string): string {\n const words = type.replace(/^(a|an)\\s+/i, '')\n return words.charAt(0).toUpperCase() + words.slice(1)\n}\n\n/** The id the style grid gives \"Pick for me\", which is no kind: the answers' `kind: null`. */\nexport const AI_SITE_STYLE_AUTO = SITE_STYLE_AUTO\n\n/**\n * The 21 style cards, each with its example home page (AGL-3898), as the\n * Style step and the starter site's style choice (AGL-4049) both draw them.\n */\nexport function aiSiteStyleCards(): Array<{\n id: string\n title: string\n description: string\n image?: NonNullable<ReturnType<typeof aiSiteStylePreview>>\n}> {\n return AI_SITE_KINDS.map((kind) => {\n const image = aiSiteStylePreview(kind.id)\n return { id: kind.id, title: kind.label, description: kind.blurb, ...(image ? { image } : {}) }\n })\n}\n\n/**\n * The progress through the steps: labeled steps on a wide screen, a bar and\n * \"Step 3 of 6\" on a phone. On a wide screen a step already answered is a\n * button back to it (`onStep`), because a checked step reads as a link: the\n * guided start's dead clicks were people clicking it to go back.\n */\nexport function StartProgress({\n step,\n compact,\n onStep,\n}: {\n step: AiSiteStartStep\n compact: boolean\n onStep?: (step: AiSiteStartStep) => void\n}) {\n const index = aiSiteStartStepIndex(step)\n const count = AI_SITE_START_STEPS.length\n const name = `Step ${index + 1} of ${count}`\n if (compact) {\n return (\n <Stack spacing={1} data-start-area=\"progress\" role=\"group\" aria-label={name}>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {`${name}: ${AI_SITE_START_STEP_LABELS[step]}`}\n </Typography>\n <LinearProgress variant=\"determinate\" value={((index + 1) / count) * 100} aria-hidden />\n </Stack>\n )\n }\n return (\n <Stepper activeStep={index} alternativeLabel aria-label={name} data-start-area=\"progress\">\n {AI_SITE_START_STEPS.map((id, at) => (\n <Step key={id}>\n {onStep && at < index ? (\n <StepButton onClick={() => onStep(id)} aria-label={`Back to ${AI_SITE_START_STEP_LABELS[id].toLowerCase()}`}>\n {AI_SITE_START_STEP_LABELS[id]}\n </StepButton>\n ) : (\n <StepLabel>{AI_SITE_START_STEP_LABELS[id]}</StepLabel>\n )}\n </Step>\n ))}\n </Stepper>\n )\n}\n\ninterface StepProps {\n answers: AiSiteStartAnswers\n answer: (patch: Partial<AiSiteStartAnswers>) => void\n tracker: AiSiteStartTracker\n /** Each field's reason not to go forward, once the person has tried to. */\n errors: Partial<Record<AiSiteStartField, AiSiteStartFieldError>>\n /** Where each field's input is, so a refused Next can put the cursor in it. */\n fieldRef: (field: AiSiteStartField) => Ref<HTMLInputElement>\n}\n\n/** A text answer's tracking: each change, and leaving the field, which ends one edit. */\nconst typed = (tracker: AiSiteStartTracker, field: AiSiteStartField) => ({\n onBlur: () => tracker.fieldLeft(field),\n})\n\n/** Step: what kind of site it is — the one required answer — typed, or picked from cards. */\nexport function KindStep({ answers, answer, tracker, errors, fieldRef }: StepProps) {\n const picked = AI_SITE_START_TYPES.includes(answers.siteType) ? answers.siteType : null\n return (\n <Stack spacing={3}>\n <Box data-start-area=\"field-siteType\">\n <TextField\n fullWidth\n required\n inputRef={fieldRef('siteType')}\n label=\"What kind of site are you creating?\"\n placeholder=\"a neighborhood dog groomer that takes bookings\"\n value={answers.siteType}\n onChange={(event) => {\n answer({ siteType: event.target.value })\n tracker.fieldChanged('siteType')\n }}\n {...typed(tracker, 'siteType')}\n error={Boolean(errors.siteType)}\n helperText={errors.siteType?.message ?? 'A few words is enough, or pick one below.'}\n />\n </Box>\n <Stack spacing={1.5}>\n <Typography variant=\"overline\" color=\"text.secondary\" component=\"h2\">\n {'Or pick the closest'}\n </Typography>\n <OptionCardGrid\n label=\"Kind of site\"\n data-start-area=\"kind-cards\"\n columns={{ xs: 2, sm: 2, md: 4 }}\n options={AI_SITE_START_TYPES.map((type) => ({\n id: type,\n title: startTypeTitle(type),\n icon: START_TYPE_ICONS[type] ?? mdiBookOpenPageVariant.path,\n }))}\n value={picked}\n onChange={(type) => {\n answer({ siteType: type })\n tracker.fieldPicked('siteType')\n }}\n />\n </Stack>\n </Stack>\n )\n}\n\n/** Step: who the site is for. Optional. */\nexport function AudienceStep({ answers, answer, tracker, errors, fieldRef }: StepProps) {\n return (\n <Box data-start-area=\"field-audience\">\n <TextField\n fullWidth\n inputRef={fieldRef('audience')}\n label=\"Who is it for?\"\n placeholder=\"local dog owners who want a regular groom booked online\"\n value={answers.audience}\n onChange={(event) => {\n answer({ audience: event.target.value })\n tracker.fieldChanged('audience')\n }}\n {...typed(tracker, 'audience')}\n error={Boolean(errors.audience)}\n helperText={errors.audience?.message ?? 'Optional. It narrows who the pages are written for.'}\n />\n </Box>\n )\n}\n\n/**\n * Step: the style, from cards that show it. Nothing is chosen until a card is\n * clicked (AGL-4049), and the step does not go forward before one is. \"Pick\n * for me\" is a card too: it leaves the kind unset, so the kind the first\n * answer suggests is the one used, and the card says which.\n */\nexport function StyleStep({\n answers,\n answer,\n tracker,\n errors,\n fieldRef,\n inspiration,\n}: StepProps & { inspiration?: AiSiteStartInspirationOffer | null }) {\n const suggested = aiSiteStartKind({ ...answers, kind: null })\n const cards = (\n <OptionCardGrid\n label=\"Style of site\"\n data-start-area=\"style-cards\"\n columns={{ xs: 2, sm: 2, md: 3 }}\n options={[\n {\n id: AI_SITE_STYLE_AUTO,\n title: 'Pick for me',\n description: `From your answer: ${suggested.label}`,\n icon: mdiCreation.path,\n },\n ...aiSiteStyleCards(),\n ]}\n value={answers.style}\n onChange={(id) => {\n answer(aiSiteStartStyleAnswer(id))\n tracker.fieldPicked('style')\n }}\n />\n )\n const chosen = (\n <Stack spacing={1} data-start-area=\"field-style\">\n {cards}\n {errors.style ? (\n <FormHelperText error role=\"alert\">\n {errors.style.message}\n </FormHelperText>\n ) : null}\n </Stack>\n )\n if (!inspiration) return chosen\n return (\n <Stack spacing={4}>\n {chosen}\n <InspirationFields answers={answers} answer={answer} tracker={tracker} errors={errors} fieldRef={fieldRef} offer={inspiration} />\n </Stack>\n )\n}\n\n/**\n * What the guided start offers of Sites I like (AGL-3975), while\n * `release_ai_site_inspiration` is on: how many sites the workspace may name,\n * and where it upgrades for more.\n */\nexport interface AiSiteStartInspirationOffer {\n limit: number\n upgradeHref: string | null\n}\n\n/** Why a Free workspace's second and third site fields are locked. */\nexport const AI_SITE_INSPIRATION_LOCKED_REASON = `A Free workspace names ${AI_SITE_INSPIRATION_LIMITS.free} site you like. Paid plans name up to ${AI_SITE_INSPIRATION_MAX}.`\n\n/**\n * Sites I like (AGL-3975): up to three addresses under the style cards. A\n * Free workspace's fields past its one are shown disabled with the reason\n * and an upgrade link, never hidden, so the person sees what a paid plan adds.\n */\nfunction InspirationFields({\n answers,\n answer,\n tracker,\n errors,\n fieldRef,\n offer,\n}: StepProps & { offer: AiSiteStartInspirationOffer }) {\n const values = answers.inspiration ?? []\n const change = (index: number, value: string) => {\n const next = Array.from({ length: offer.limit }, (_, at) => values[at] ?? '')\n next[index] = value\n answer({ inspiration: next })\n tracker.fieldChanged('inspiration')\n }\n return (\n <Stack spacing={1.5} data-start-area=\"field-inspiration\">\n <Typography variant=\"overline\" color=\"text.secondary\" component=\"h2\">\n {'Sites you like (optional)'}\n </Typography>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {\n 'We take only how they are laid out and styled: the order of sections, colors, type, buttons and motion. Never their words, photos or logos, so your site stays your own.'\n }\n </Typography>\n {Array.from({ length: AI_SITE_INSPIRATION_MAX }, (_, index) => {\n const locked = index >= offer.limit\n const field = (\n <TextField\n fullWidth\n type=\"url\"\n inputMode=\"url\"\n label={`Site ${index + 1}`}\n placeholder=\"https://example.com\"\n value={locked ? '' : (values[index] ?? '')}\n onChange={(event) => change(index, event.target.value)}\n onBlur={() => tracker.fieldLeft('inspiration')}\n {...(index === 0 ? { inputRef: fieldRef('inspiration') } : {})}\n error={index === 0 && Boolean(errors.inspiration)}\n {...(index === 0 && errors.inspiration ? { helperText: errors.inspiration.message } : {})}\n />\n )\n return locked ? (\n <BlockedControl key={index} blocked reason={AI_SITE_INSPIRATION_LOCKED_REASON} fullWidth>\n {field}\n </BlockedControl>\n ) : (\n <Box key={index}>{field}</Box>\n )\n })}\n {offer.limit < AI_SITE_INSPIRATION_MAX && (\n <PrerequisiteNotice {...(offer.upgradeHref ? { href: offer.upgradeHref } : {})} actionLabel=\"Upgrade\">\n {AI_SITE_INSPIRATION_PAID_NOTE}\n </PrerequisiteNotice>\n )}\n </Stack>\n )\n}\n\n/** Step: where leads go, how many pages, and on a paid plan the welcome email. */\nexport function DetailsStep({\n answers,\n answer,\n tracker,\n errors,\n fieldRef,\n freeTaste,\n band,\n}: StepProps & { freeTaste: boolean; band: { min: number; max: number } }) {\n return (\n <Stack spacing={3}>\n {/*\n How a customer reaches the business (AGL-3979), first: given, the\n pages show them as links — the contact page, the footer, the buttons\n that ask a visitor to call or write — and the site's search listing\n and AI-agent details carry them. Optional, and never a placeholder.\n */}\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>\n <Box data-start-area=\"field-phone\" sx={{ flex: 1 }}>\n <TextField\n fullWidth\n type=\"tel\"\n inputRef={fieldRef('phone')}\n label=\"Business phone\"\n placeholder=\"(512) 555-0142\"\n autoComplete=\"tel\"\n value={answers.phone}\n onChange={(event) => {\n answer({ phone: event.target.value })\n tracker.fieldChanged('phone')\n }}\n {...typed(tracker, 'phone')}\n error={Boolean(errors.phone)}\n helperText={errors.phone?.message ?? 'Optional. Shown on your site so customers can call.'}\n slotProps={{ htmlInput: { inputMode: 'tel' } }}\n />\n </Box>\n <Box data-start-area=\"field-email\" sx={{ flex: 1 }}>\n <TextField\n fullWidth\n type=\"email\"\n inputRef={fieldRef('email')}\n label=\"Business email\"\n placeholder=\"hello@yourbusiness.com\"\n autoComplete=\"email\"\n value={answers.email}\n onChange={(event) => {\n answer({ email: event.target.value })\n tracker.fieldChanged('email')\n }}\n {...typed(tracker, 'email')}\n error={Boolean(errors.email)}\n helperText={errors.email?.message ?? 'Optional. Shown on your site so customers can write.'}\n />\n </Box>\n </Stack>\n {/*\n The one setting a new site owner has to make, asked where they are\n already answering: a contact form nobody routed files its messages\n somewhere the person has not looked.\n */}\n <Box data-start-area=\"field-submissions\">\n <TextField\n select\n fullWidth\n inputRef={fieldRef('submissions')}\n label=\"Where do form submissions go?\"\n value={answers.submissions}\n onChange={(event) => {\n answer({ submissions: event.target.value as AiSiteSubmissions })\n tracker.fieldPicked('submissions')\n }}\n error={Boolean(errors.submissions)}\n helperText={errors.submissions?.message ?? 'You can change this on the form itself afterwards.'}\n >\n {AI_SITE_SUBMISSION_CHOICES.map((option) => (\n <MenuItem key={option.id} value={option.id}>\n {`${option.label} — ${option.blurb}`}\n </MenuItem>\n ))}\n </TextField>\n </Box>\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>\n <Box data-start-area=\"field-pages\" sx={{ flex: 1 }}>\n <TextField\n select\n fullWidth\n inputRef={fieldRef('pages')}\n label=\"Pages\"\n value={answers.pages}\n onChange={(event) => {\n answer({ pages: Number(event.target.value) })\n tracker.fieldPicked('pages')\n }}\n error={Boolean(errors.pages)}\n helperText={errors.pages?.message ?? (freeTaste ? AI_SITE_FREE_PAGES_NOTE : undefined)}\n >\n {Array.from({ length: band.max - band.min + 1 }, (_, index) => band.min + index).map((count) => (\n <MenuItem key={count} value={count}>\n {count}\n </MenuItem>\n ))}\n </TextField>\n </Box>\n {!freeTaste && (\n <Box data-start-area=\"field-welcomeEmail\" sx={{ flex: 1 }}>\n <TextField\n select\n fullWidth\n label=\"Welcome email\"\n value={answers.welcomeEmail ? 'yes' : 'no'}\n onChange={(event) => {\n answer({ welcomeEmail: event.target.value === 'yes' })\n tracker.fieldPicked('welcomeEmail')\n }}\n >\n <MenuItem value=\"yes\">{'Draft one'}</MenuItem>\n <MenuItem value=\"no\">{'No'}</MenuItem>\n </TextField>\n </Box>\n )}\n </Stack>\n </Stack>\n )\n}\n\n/**\n * The brand colors \"More details\" offers on the Style step (AGL-3979), by\n * name: picking one makes it the site's primary color, held to contrast by\n * the look like any brand color; none leaves the style to choose. Picked,\n * never typed: a color code is not something a site owner should need.\n */\nexport const AI_SITE_START_BRAND_COLORS: ReadonlyArray<{ label: string; hex: string }> = [\n { label: 'Red', hex: '#c62828' },\n { label: 'Orange', hex: '#e65100' },\n { label: 'Gold', hex: '#b28704' },\n { label: 'Green', hex: '#2e7d32' },\n { label: 'Teal', hex: '#00796b' },\n { label: 'Blue', hex: '#1565c0' },\n { label: 'Navy', hex: '#1a237e' },\n { label: 'Purple', hex: '#6a1b9a' },\n { label: 'Pink', hex: '#ad1457' },\n { label: 'Brown', hex: '#5d4037' },\n { label: 'Charcoal', hex: '#37474f' },\n]\n\n/** The price ranges offered, as a search listing writes them. */\nconst PRICE_RANGES: ReadonlyArray<{ value: string; label: string }> = [\n { value: '$', label: '$ — budget' },\n { value: '$$', label: '$$ — moderate' },\n { value: '$$$', label: '$$$ — premium' },\n { value: '$$$$', label: '$$$$ — luxury' },\n]\n\n/** What each step's \"More details\" says it holds, under its title. */\nconst MORE_SUMMARY: Readonly<Partial<Record<AiSiteStartStep, string>>> = {\n kind: 'Optional: a tagline and the year you started',\n audience: 'Optional: areas you serve, price range and languages',\n style: 'Optional: your brand color',\n details: 'Optional: address, opening hours and social profiles',\n}\n\n/** A typed extra's field. */\nfunction ExtraText({\n field,\n answers,\n answer,\n tracker,\n errors,\n fieldRef,\n label,\n placeholder,\n helper,\n autoComplete = 'off',\n multiline = false,\n inputMode,\n}: StepProps & {\n field: AiSiteStartExtraKey\n label: string\n placeholder?: string\n helper?: string\n autoComplete?: string\n multiline?: boolean\n inputMode?: 'numeric' | 'url'\n}) {\n const error = errors[field]\n return (\n <Box data-start-area={`field-${field}`} sx={{ flex: 1, minWidth: 0 }}>\n <TextField\n fullWidth\n inputRef={fieldRef(field)}\n label={label}\n placeholder={placeholder}\n autoComplete={autoComplete}\n multiline={multiline}\n minRows={multiline ? 2 : undefined}\n value={answers[field]}\n onChange={(event) => {\n answer({ [field]: event.target.value })\n tracker.fieldChanged(field)\n }}\n {...typed(tracker, field)}\n error={Boolean(error)}\n helperText={error?.message ?? helper}\n slotProps={inputMode ? { htmlInput: { inputMode } } : undefined}\n />\n </Box>\n )\n}\n\n/** The price range, picked from how search results show one. */\nfunction PriceRangeField({ answers, answer, tracker, errors, fieldRef }: StepProps) {\n const own = answers.priceRange && !PRICE_RANGES.some((option) => option.value === answers.priceRange)\n const options = own ? [...PRICE_RANGES, { value: answers.priceRange, label: answers.priceRange }] : PRICE_RANGES\n return (\n <Box data-start-area=\"field-priceRange\" sx={{ flex: 1, minWidth: 0 }}>\n <TextField\n select\n fullWidth\n inputRef={fieldRef('priceRange')}\n label=\"Price range\"\n value={answers.priceRange}\n onChange={(event) => {\n answer({ priceRange: event.target.value })\n tracker.fieldPicked('priceRange')\n }}\n error={Boolean(errors.priceRange)}\n helperText={errors.priceRange?.message ?? 'How your prices compare, as search results show it.'}\n >\n <MenuItem value=\"\">{'Not said'}</MenuItem>\n {options.map((option) => (\n <MenuItem key={option.value} value={option.value}>\n {option.label}\n </MenuItem>\n ))}\n </TextField>\n </Box>\n )\n}\n\n/** The brand color, picked from named swatches. */\nfunction BrandField({ answers, answer, tracker }: StepProps) {\n const labelId = useId()\n return (\n <Stack spacing={1} data-start-area=\"field-brand\">\n <Typography variant=\"body2\" color=\"text.secondary\" id={labelId}>\n {'Brand color'}\n </Typography>\n <Stack direction=\"row\" role=\"radiogroup\" aria-labelledby={labelId} sx={{ flexWrap: 'wrap', gap: 1 }}>\n {[{ label: 'Let the style choose', hex: '' }, ...AI_SITE_START_BRAND_COLORS].map((color) => {\n const picked = (answers.brand || '') === color.hex\n return (\n <Tooltip key={color.label} title={color.label}>\n <Box\n component=\"button\"\n type=\"button\"\n role=\"radio\"\n aria-checked={picked}\n aria-label={color.label}\n onClick={() => {\n answer({ brand: color.hex })\n tracker.fieldPicked('brand')\n }}\n sx={{\n width: 36,\n height: 36,\n p: 0,\n borderRadius: '50%',\n border: 2,\n borderColor: picked ? 'text.primary' : 'divider',\n bgcolor: color.hex || 'background.paper',\n color: color.hex ? 'common.white' : 'text.secondary',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n }}\n >\n {picked ? <MdiIcon path={mdiCheck.path} fontSize=\"small\" /> : null}\n </Box>\n </Tooltip>\n )\n })}\n </Stack>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'Picked, it is your site’s main color, kept readable everywhere it is used.'}\n </Typography>\n </Stack>\n )\n}\n\n/** The opening hours, picked a day at a time: the same editor as Setup → SEO. */\nfunction HoursField({ answers, answer, tracker, errors }: StepProps) {\n return (\n <Box data-start-area=\"field-hours\">\n <OpeningHoursPicker\n label=\"Opening hours\"\n value={answers.hours}\n onChange={(hours) => {\n answer({ hours })\n tracker.fieldPicked('hours')\n }}\n helperText={errors.hours?.message ?? 'Leave every day closed if you work by appointment.'}\n />\n </Box>\n )\n}\n\n/** One extra's field, as \"More details\" draws it. */\nfunction ExtraField({ field, ...props }: StepProps & { field: AiSiteStartExtraKey }) {\n switch (field) {\n case 'tagline':\n return <ExtraText {...props} field={field} label=\"Tagline\" placeholder=\"Calm, gentle grooming your dog will love\" helper=\"A short line about the business, in your words.\" />\n case 'founded':\n return <ExtraText {...props} field={field} label=\"Year founded\" placeholder=\"2015\" inputMode=\"numeric\" />\n case 'serviceArea':\n return <ExtraText {...props} field={field} label=\"Areas you serve\" placeholder={'Austin\\nRound Rock'} helper=\"Cities, towns or neighborhoods, one a line.\" multiline />\n case 'priceRange':\n return <PriceRangeField {...props} />\n case 'languages':\n return <ExtraText {...props} field={field} label=\"Languages you serve customers in\" placeholder=\"English, Spanish\" />\n case 'brand':\n return <BrandField {...props} />\n case 'street':\n return <ExtraText {...props} field={field} label=\"Street address\" placeholder=\"214 Main Street\" autoComplete=\"street-address\" />\n case 'city':\n return <ExtraText {...props} field={field} label=\"City or town\" placeholder=\"Austin\" autoComplete=\"address-level2\" />\n case 'region':\n return <ExtraText {...props} field={field} label=\"State or region\" placeholder=\"TX\" autoComplete=\"address-level1\" />\n case 'postalCode':\n return <ExtraText {...props} field={field} label=\"ZIP or postal code\" placeholder=\"78701\" autoComplete=\"postal-code\" />\n case 'country':\n return <ExtraText {...props} field={field} label=\"Country\" placeholder=\"United States\" autoComplete=\"country-name\" />\n case 'hours':\n return <HoursField {...props} />\n case 'social':\n return (\n <ExtraText\n {...props}\n field={field}\n label=\"Social profiles\"\n placeholder=\"instagram.com/yourbusiness\"\n helper=\"One link a line. Your site links them, and its search listing names them as yours.\"\n multiline\n inputMode=\"url\"\n />\n )\n default:\n return null\n }\n}\n\n/** Fields \"More details\" draws side by side. */\nconst PAIRS: ReadonlyArray<readonly [AiSiteStartExtraKey, AiSiteStartExtraKey]> = [\n ['tagline', 'founded'],\n ['priceRange', 'languages'],\n ['city', 'region'],\n ['postalCode', 'country'],\n]\n\n/**\n * A step's \"More details\" (AGL-3979): a collapsed section of optional extras\n * that fit the step, so a person who wants the site to say more can, and one\n * who does not never has to open it. Open from the start where something in\n * it is already filled in (a start reopened on its answers), and opened by a\n * Next refused on one of its fields.\n */\nexport function MoreDetails({ step, ...props }: StepProps & { step: AiSiteStartStep }) {\n const fields = AI_SITE_START_MORE_FIELDS[step]\n const { answers, errors, tracker } = props\n const [open, setOpen] = useState(() => fields.some((field) => (answers[field] ?? '').trim() !== ''))\n if (!fields.length) return null\n const expanded = open || fields.some((field) => errors[field])\n const rows: Array<readonly AiSiteStartExtraKey[]> = []\n for (const field of fields) {\n if (rows.some((row) => row.includes(field))) continue\n const pair = PAIRS.find((entry) => entry[0] === field && fields.includes(entry[1]))\n rows.push(pair ?? [field])\n }\n return (\n <Accordion\n disableGutters\n variant=\"outlined\"\n // The same outlined, rounded section as the build page's plan.\n sx={{ borderRadius: 2, '&::before': { display: 'none' } }}\n expanded={expanded}\n onChange={(_, next) => {\n setOpen(next)\n if (next) tracker.moreDetails()\n }}\n data-start-area=\"more-details\"\n >\n <AccordionSummary expandIcon={<MdiIcon path={mdiChevronDown.path} />}>\n <Stack spacing={0.25}>\n <Typography variant=\"subtitle2\" component=\"span\">\n {'More details'}\n </Typography>\n <Typography variant=\"body2\" color=\"text.secondary\" component=\"span\">\n {MORE_SUMMARY[step]}\n </Typography>\n </Stack>\n </AccordionSummary>\n <AccordionDetails>\n <Stack spacing={2.5}>\n {rows.map((row) =>\n row.length > 1 ? (\n <Stack key={row.join('-')} direction={{ xs: 'column', sm: 'row' }} spacing={2}>\n {row.map((field) => (\n <ExtraField key={field} field={field} {...props} />\n ))}\n </Stack>\n ) : (\n <ExtraField key={row[0]} field={row[0]} {...props} />\n ),\n )}\n </Stack>\n </AccordionDetails>\n </Accordion>\n )\n}\n\n/** The extras on the review, each as a person reads it, with the step that asks it. */\nexport function aiSiteStartExtraRows(answers: AiSiteStartAnswers): Array<{ label: string; value: string; step: AiSiteStartStep }> {\n const rows: Array<{ label: string; value: string; step: AiSiteStartStep }> = []\n const add = (label: string, value: string, step: AiSiteStartStep) => {\n if (value.trim()) rows.push({ label, value: value.trim(), step })\n }\n add('Phone', answers.phone, 'details')\n add('Email', answers.email, 'details')\n add('Tagline', answers.tagline, 'kind')\n add('Year founded', answers.founded, 'kind')\n add('Areas you serve', aiSiteServiceAreas(answers.serviceArea).join(', '), 'audience')\n add('Price range', answers.priceRange, 'audience')\n add('Languages', answers.languages, 'audience')\n const brand = AI_SITE_START_BRAND_COLORS.find((color) => color.hex === answers.brand)\n add('Brand color', brand?.label ?? answers.brand, 'style')\n const regional = [answers.region, answers.postalCode].map((part) => part.trim()).filter(Boolean).join(' ')\n const address = [answers.street, answers.city, regional, answers.country]\n .map((part) => part.trim())\n .filter(Boolean)\n .join(', ')\n add('Address', address, 'details')\n add('Opening hours', aiSiteHoursSentence(answers.hours), 'details')\n const links = aiSiteSocialLinks(answers.social) ?? []\n add('Social profiles', links.map((link) => link.replace(/^https:\\/\\//, '')).join(', '), 'details')\n return rows\n}\n\n/**\n * One answer on the review, as one button back to the step that asks it. The\n * whole row is the target, not only \"Edit\" at its end: people clicked the\n * answer itself to change it, and nothing happened.\n */\nfunction ReviewRow({ label, value, step, onEdit }: { label: string; value: ReactNode; step: AiSiteStartStep; onEdit: (step: AiSiteStartStep) => void }) {\n const valueId = useId()\n return (\n <ListItemButton\n onClick={() => onEdit(step)}\n aria-label={`Edit ${label.toLowerCase()}`}\n aria-describedby={valueId}\n sx={{ alignItems: 'flex-start', gap: 2, py: 1.5, px: 1, mx: -1, borderRadius: 1 }}\n >\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Typography variant=\"body2\" color=\"text.secondary\" component=\"span\" sx={{ display: 'block' }}>\n {label}\n </Typography>\n <Typography id={valueId} variant=\"body1\" component=\"span\" sx={{ display: 'block', overflowWrap: 'anywhere' }}>\n {value}\n </Typography>\n </Box>\n <Typography variant=\"button\" color=\"primary\" component=\"span\" aria-hidden sx={{ fontSize: '0.8125rem', pt: 0.25 }}>\n {'Edit'}\n </Typography>\n </ListItemButton>\n )\n}\n\n/** Step: every answer, each with Edit, before \"Plan my site\". */\nexport function ReviewStep({\n answers,\n freeTaste,\n onEdit,\n children,\n inspiration = false,\n}: {\n answers: AiSiteStartAnswers\n freeTaste: boolean\n onEdit: (step: AiSiteStartStep) => void\n children?: ReactNode\n /** Whether the start asks for the sites the person likes (AGL-3975). */\n inspiration?: boolean\n}) {\n const liked = aiSiteStartInspirationTyped(answers)\n const kind = aiSiteStartKind(answers)\n const submissions = AI_SITE_SUBMISSION_CHOICES.find((option) => option.id === answers.submissions)\n const rows: Array<{ label: string; value: ReactNode; step: AiSiteStartStep }> = [\n { label: 'Kind of site', value: answers.siteType.trim(), step: 'kind' },\n { label: 'Who it is for', value: answers.audience.trim() || 'Anyone (not said)', step: 'audience' },\n {\n label: 'Style',\n value: answers.style === null ? 'Not chosen yet' : answers.kind ? kind.label : `${kind.label}, picked for you`,\n step: 'style',\n },\n ...(inspiration\n ? [{ label: 'Sites you like', value: liked.length ? liked.map(aiSiteInspirationHost).join(', ') : 'None', step: 'style' as const }]\n : []),\n { label: 'Form submissions', value: submissions?.label ?? answers.submissions, step: 'details' },\n { label: 'Pages', value: String(answers.pages), step: 'details' },\n ...(freeTaste ? [] : [{ label: 'Welcome email', value: answers.welcomeEmail ? 'Draft one' : 'No', step: 'details' as const }]),\n // Everything \"More details\" and the contact fields were given (AGL-3979), each with Edit.\n ...aiSiteStartExtraRows(answers),\n ]\n return (\n <Stack spacing={3}>\n <List disablePadding data-start-area=\"review\" aria-label=\"Your answers\">\n {rows.map((row, index) => (\n <Fragment key={row.label}>\n {index > 0 && <Divider component=\"li\" aria-hidden />}\n <li>\n <ReviewRow {...row} onEdit={onEdit} />\n </li>\n </Fragment>\n ))}\n </List>\n {children}\n </Stack>\n )\n}\n\n/** A step's help beside its heading. */\nexport function StepHelp({ step }: { step: AiSiteStartStep }) {\n const help = step === 'choose' ? null : START_STEP_HELP[step]\n return help ? <HelpTip sx={{ float: 'right' }} {...help} /> : null\n}\n"],"names":["pluginDocsHelp","mdiBookOpenPageVariant","mdiBriefcaseOutline","mdiCalendarHeart","mdiCheck","mdiChevronDown","mdiCreation","mdiHandHeart","mdiScaleBalance","mdiShopping","mdiSilverwareForkKnife","mdiViewGridOutline","mdiWrench","HelpTip","MdiIcon","OptionCardGrid","BlockedControl","PrerequisiteNotice","OpeningHoursPicker","Accordion","AccordionDetails","AccordionSummary","Box","Divider","FormHelperText","LinearProgress","List","ListItemButton","MenuItem","Stack","Step","StepButton","StepLabel","Stepper","TextField","Tooltip","Typography","Fragment","useId","useState","aiSiteHoursSentence","aiSiteServiceAreas","aiSiteSocialLinks","AI_SITE_FREE_PAGES_NOTE","AI_SITE_SUBMISSION_CHOICES","AI_SITE_KINDS","AI_SITE_INSPIRATION_LIMITS","AI_SITE_INSPIRATION_MAX","AI_SITE_INSPIRATION_PAID_NOTE","aiSiteInspirationHost","SITE_STYLE_AUTO","AI_SITE_START_TYPES","aiSiteStartInspirationTyped","aiSiteStartKind","aiSiteStartStyleAnswer","AI_SITE_START_MORE_FIELDS","AI_SITE_START_STEP_LABELS","AI_SITE_START_STEPS","aiSiteStartStepIndex","aiSiteStylePreview","START_STEP_HELP","kind","anchor","excerpt","audience","review","style","details","START_TYPE_ICONS","path","startTypeTitle","type","words","replace","charAt","toUpperCase","slice","AI_SITE_STYLE_AUTO","aiSiteStyleCards","map","image","id","title","label","description","blurb","StartProgress","step","compact","onStep","index","count","length","name","spacing","data-start-area","role","aria-label","variant","color","value","aria-hidden","activeStep","alternativeLabel","at","onClick","toLowerCase","typed","tracker","field","onBlur","fieldLeft","KindStep","answers","answer","errors","fieldRef","picked","includes","siteType","fullWidth","required","inputRef","placeholder","onChange","event","target","fieldChanged","error","Boolean","helperText","message","component","columns","xs","sm","md","options","icon","fieldPicked","AudienceStep","StyleStep","inspiration","suggested","cards","chosen","InspirationFields","offer","AI_SITE_INSPIRATION_LOCKED_REASON","free","values","change","next","Array","from","limit","_","locked","inputMode","blocked","reason","upgradeHref","href","actionLabel","DetailsStep","freeTaste","band","direction","sx","flex","autoComplete","phone","slotProps","htmlInput","email","select","submissions","option","pages","Number","undefined","max","min","welcomeEmail","AI_SITE_START_BRAND_COLORS","hex","PRICE_RANGES","MORE_SUMMARY","ExtraText","helper","multiline","minWidth","minRows","PriceRangeField","own","priceRange","some","BrandField","labelId","aria-labelledby","flexWrap","gap","brand","aria-checked","width","height","p","borderRadius","border","borderColor","bgcolor","display","alignItems","justifyContent","cursor","fontSize","HoursField","hours","ExtraField","props","PAIRS","MoreDetails","fields","open","setOpen","trim","expanded","rows","row","pair","find","entry","push","disableGutters","moreDetails","expandIcon","join","aiSiteStartExtraRows","add","tagline","founded","serviceArea","languages","regional","region","postalCode","part","filter","address","street","city","country","links","social","link","ReviewRow","onEdit","valueId","aria-describedby","py","px","mx","overflowWrap","pt","ReviewStep","children","liked","String","disablePadding","li","StepHelp","help","float"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/ai-site-start-steps.component.tsx"],"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'use client'\n\nimport { pluginDocsHelp } from '@aglyn/aglyn/app-utils/docs-help'\nimport {\n mdiBookOpenPageVariant,\n mdiBriefcaseOutline,\n mdiCalendarHeart,\n mdiCheck,\n mdiChevronDown,\n mdiCreation,\n mdiHandHeart,\n mdiScaleBalance,\n mdiShopping,\n mdiSilverwareForkKnife,\n mdiViewGridOutline,\n mdiWrench,\n} from '@aglyn/shared-data-mdi'\nimport { HelpTip, MdiIcon } from '@aglyn/shared-ui-jsx'\nimport { OptionCardGrid } from '@aglyn/shared-ui-jsx/components/option-card-grid.component'\nimport { BlockedControl } from '@aglyn/shared-ui-jsx/components/blocked-control.component'\nimport { PrerequisiteNotice } from '@aglyn/shared-ui-jsx/components/prerequisite-notice.component'\nimport { OpeningHoursPicker } from '@aglyn/shared-ui-jsx/components/weekly-hours-picker.component'\nimport {\n Accordion,\n AccordionDetails,\n AccordionSummary,\n Box,\n Divider,\n FormHelperText,\n LinearProgress,\n List,\n ListItemButton,\n MenuItem,\n Stack,\n Step,\n StepButton,\n StepLabel,\n Stepper,\n TextField,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport { Fragment, useId, useState, type ReactNode, type Ref } from 'react'\nimport { aiSiteHoursSentence, aiSiteServiceAreas, aiSiteSocialLinks } from '../model/ai-site-details'\nimport { AI_SITE_FREE_PAGES_NOTE, AI_SITE_SUBMISSION_CHOICES, type AiSiteSubmissions } from '../model/ai-site-job'\nimport { AI_SITE_KINDS } from '../model/ai-site-kinds'\nimport {\n AI_SITE_INSPIRATION_LIMITS,\n AI_SITE_INSPIRATION_MAX,\n AI_SITE_INSPIRATION_PAID_NOTE,\n aiSiteInspirationHost,\n} from '../model/ai-site-inspiration'\nimport { SITE_STYLE_AUTO } from '@aglyn/aglyn/app-utils/site-styles'\nimport {\n AI_SITE_START_TYPES,\n aiSiteStartInspirationTyped,\n aiSiteStartKind,\n aiSiteStartStyleAnswer,\n type AiSiteStartAnswers,\n type AiSiteStartExtraKey,\n} from '../model/ai-site-start'\nimport {\n AI_SITE_START_MORE_FIELDS,\n AI_SITE_START_STEP_LABELS,\n AI_SITE_START_STEPS,\n aiSiteStartStepIndex,\n type AiSiteStartField,\n type AiSiteStartFieldError,\n type AiSiteStartStep,\n} from '../model/ai-site-start-steps'\nimport type { AiSiteStartTracker } from './ai-site-start-tracking'\nimport { aiSiteStylePreview } from './ai-site-style-previews'\n\n/**\n * The guided start's question steps (AGL-3898), one decision each. Each step\n * draws its own answers and writes them through `answer`, exactly the patch\n * the single form wrote, so the answers object is the same whichever way it\n * was filled in. The dialog around them (`ai-site-start-card.component.tsx`)\n * owns the step, Back and Next, validation and the job.\n */\n\n/** Each part of the guided start links its own section of the Start with AI guide (AGL-3660). */\nexport const START_STEP_HELP = {\n kind: pluginDocsHelp('aiStart', {\n anchor: '#your-business',\n excerpt:\n 'What kind of site it is picks its style and pages; who it is for is who every page and the contact form are written for.',\n }),\n audience: pluginDocsHelp('aiStart', {\n anchor: '#audience',\n excerpt: 'Who the site is for is who every page, every search listing and the contact form are written for. Optional.',\n }),\n review: pluginDocsHelp('aiStart', {\n anchor: '#review',\n excerpt: 'Every answer, each with Edit to change it. Plan my site creates the site, plans it, writes the pages and publishes it.',\n }),\n style: pluginDocsHelp('aiSiteLooks', {\n anchor: '#choose-a-style',\n excerpt:\n 'The style decides the look — theme, colors, fonts, buttons — and which pages the site usually has. Every site gets its own variation.',\n }),\n details: pluginDocsHelp('aiStart', {\n anchor: '#details',\n excerpt:\n 'Your phone number and email, which your pages show, where contact form messages go, how many pages to write, and on paid plans whether to draft a welcome email. All can be changed later.',\n }),\n}\n\n/** The icon on each kind-of-site card: the icon of the style that answer picks. */\nconst START_TYPE_ICONS: Readonly<Record<string, string>> = {\n 'a local service business': mdiBriefcaseOutline.path,\n 'a restaurant or cafe': mdiSilverwareForkKnife.path,\n 'a professional practice': mdiScaleBalance.path,\n 'a trades business': mdiWrench.path,\n 'a shop': mdiShopping.path,\n 'a nonprofit': mdiHandHeart.path,\n 'a personal portfolio': mdiViewGridOutline.path,\n 'an event': mdiCalendarHeart.path,\n}\n\n/** \"a restaurant or cafe\" as a card title: \"Restaurant or cafe\". The answer itself keeps its words. */\nexport function startTypeTitle(type: string): string {\n const words = type.replace(/^(a|an)\\s+/i, '')\n return words.charAt(0).toUpperCase() + words.slice(1)\n}\n\n/** The id the style grid gives \"Pick for me\", which is no kind: the answers' `kind: null`. */\nexport const AI_SITE_STYLE_AUTO = SITE_STYLE_AUTO\n\n/**\n * The 21 style cards, each with its example home page (AGL-3898), as the\n * Style step and the starter site's style choice (AGL-4049) both draw them.\n */\nexport function aiSiteStyleCards(): Array<{\n id: string\n title: string\n description: string\n image?: NonNullable<ReturnType<typeof aiSiteStylePreview>>\n}> {\n return AI_SITE_KINDS.map((kind) => {\n const image = aiSiteStylePreview(kind.id)\n return { id: kind.id, title: kind.label, description: kind.blurb, ...(image ? { image } : {}) }\n })\n}\n\n/**\n * The progress through the steps: labeled steps on a wide screen, a bar and\n * \"Step 3 of 6\" on a phone. On a wide screen a step already answered is a\n * button back to it (`onStep`), because a checked step reads as a link: the\n * guided start's dead clicks were people clicking it to go back.\n */\nexport function StartProgress({\n step,\n compact,\n onStep,\n}: {\n step: AiSiteStartStep\n compact: boolean\n onStep?: (step: AiSiteStartStep) => void\n}) {\n const index = aiSiteStartStepIndex(step)\n const count = AI_SITE_START_STEPS.length\n const name = `Step ${index + 1} of ${count}`\n if (compact) {\n return (\n <Stack spacing={1} data-start-area=\"progress\" role=\"group\" aria-label={name}>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {`${name}: ${AI_SITE_START_STEP_LABELS[step]}`}\n </Typography>\n <LinearProgress variant=\"determinate\" value={((index + 1) / count) * 100} aria-hidden />\n </Stack>\n )\n }\n return (\n <Stepper activeStep={index} alternativeLabel aria-label={name} data-start-area=\"progress\">\n {AI_SITE_START_STEPS.map((id, at) => (\n <Step key={id}>\n {onStep && at < index ? (\n <StepButton onClick={() => onStep(id)} aria-label={`Back to ${AI_SITE_START_STEP_LABELS[id].toLowerCase()}`}>\n {AI_SITE_START_STEP_LABELS[id]}\n </StepButton>\n ) : (\n <StepLabel>{AI_SITE_START_STEP_LABELS[id]}</StepLabel>\n )}\n </Step>\n ))}\n </Stepper>\n )\n}\n\ninterface StepProps {\n answers: AiSiteStartAnswers\n answer: (patch: Partial<AiSiteStartAnswers>) => void\n tracker: AiSiteStartTracker\n /** Each field's reason not to go forward, once the person has tried to. */\n errors: Partial<Record<AiSiteStartField, AiSiteStartFieldError>>\n /** Where each field's input is, so a refused Next can put the cursor in it. */\n fieldRef: (field: AiSiteStartField) => Ref<HTMLInputElement>\n}\n\n/** A text answer's tracking: each change, and leaving the field, which ends one edit. */\nconst typed = (tracker: AiSiteStartTracker, field: AiSiteStartField) => ({\n onBlur: () => tracker.fieldLeft(field),\n})\n\n/** Step: what kind of site it is — the one required answer — typed, or picked from cards. */\nexport function KindStep({ answers, answer, tracker, errors, fieldRef }: StepProps) {\n const picked = AI_SITE_START_TYPES.includes(answers.siteType) ? answers.siteType : null\n return (\n <Stack spacing={3}>\n <Box data-start-area=\"field-siteType\">\n <TextField\n fullWidth\n required\n inputRef={fieldRef('siteType')}\n label=\"What kind of site are you creating?\"\n placeholder=\"a neighborhood dog groomer that takes bookings\"\n value={answers.siteType}\n onChange={(event) => {\n answer({ siteType: event.target.value })\n tracker.fieldChanged('siteType')\n }}\n {...typed(tracker, 'siteType')}\n error={Boolean(errors.siteType)}\n helperText={errors.siteType?.message ?? 'A few words is enough, or pick one below.'}\n />\n </Box>\n <Stack spacing={1.5}>\n <Typography variant=\"overline\" color=\"text.secondary\" component=\"h2\">\n {'Or pick the closest'}\n </Typography>\n <OptionCardGrid\n label=\"Kind of site\"\n data-start-area=\"kind-cards\"\n columns={{ xs: 2, sm: 2, md: 4 }}\n options={AI_SITE_START_TYPES.map((type) => ({\n id: type,\n title: startTypeTitle(type),\n icon: START_TYPE_ICONS[type] ?? mdiBookOpenPageVariant.path,\n }))}\n value={picked}\n onChange={(type) => {\n answer({ siteType: type })\n tracker.fieldPicked('siteType')\n }}\n />\n </Stack>\n </Stack>\n )\n}\n\n/** Step: who the site is for. Optional. */\nexport function AudienceStep({ answers, answer, tracker, errors, fieldRef }: StepProps) {\n return (\n <Box data-start-area=\"field-audience\">\n <TextField\n fullWidth\n inputRef={fieldRef('audience')}\n label=\"Who is it for?\"\n placeholder=\"local dog owners who want a regular groom booked online\"\n value={answers.audience}\n onChange={(event) => {\n answer({ audience: event.target.value })\n tracker.fieldChanged('audience')\n }}\n {...typed(tracker, 'audience')}\n error={Boolean(errors.audience)}\n helperText={errors.audience?.message ?? 'Optional. It narrows who the pages are written for.'}\n />\n </Box>\n )\n}\n\n/**\n * Step: the style, from cards that show it. Nothing is chosen until a card is\n * clicked (AGL-4049), and the step does not go forward before one is. \"Pick\n * for me\" is a card too: it leaves the kind unset, so the kind the first\n * answer suggests is the one used, and the card says which.\n *\n * Questions filled in from an AI starter arrive with its style chosen, and\n * `starterStyle` names that card: it says which starter it came from, and\n * that it is the person's to change.\n */\nexport function StyleStep({\n answers,\n answer,\n tracker,\n errors,\n fieldRef,\n inspiration,\n starterStyle = null,\n}: StepProps & {\n inspiration?: AiSiteStartInspirationOffer | null\n starterStyle?: { id: string; name: string } | null\n}) {\n const suggested = aiSiteStartKind({ ...answers, kind: null })\n const cards = (\n <OptionCardGrid\n label=\"Style of site\"\n data-start-area=\"style-cards\"\n columns={{ xs: 2, sm: 2, md: 3 }}\n options={[\n {\n id: AI_SITE_STYLE_AUTO,\n title: 'Pick for me',\n description: `From your answer: ${suggested.label}`,\n icon: mdiCreation.path,\n },\n ...aiSiteStyleCards().map((card) =>\n card.id === starterStyle?.id\n ? { ...card, description: `From ${starterStyle.name}. Change it if you like.` }\n : card,\n ),\n ]}\n value={answers.style}\n onChange={(id) => {\n answer(aiSiteStartStyleAnswer(id))\n tracker.fieldPicked('style')\n }}\n />\n )\n const chosen = (\n <Stack spacing={1} data-start-area=\"field-style\">\n {cards}\n {errors.style ? (\n <FormHelperText error role=\"alert\">\n {errors.style.message}\n </FormHelperText>\n ) : null}\n </Stack>\n )\n if (!inspiration) return chosen\n return (\n <Stack spacing={4}>\n {chosen}\n <InspirationFields answers={answers} answer={answer} tracker={tracker} errors={errors} fieldRef={fieldRef} offer={inspiration} />\n </Stack>\n )\n}\n\n/**\n * What the guided start offers of Sites I like (AGL-3975), while\n * `release_ai_site_inspiration` is on: how many sites the workspace may name,\n * and where it upgrades for more.\n */\nexport interface AiSiteStartInspirationOffer {\n limit: number\n upgradeHref: string | null\n}\n\n/** Why a Free workspace's second and third site fields are locked. */\nexport const AI_SITE_INSPIRATION_LOCKED_REASON = `A Free workspace names ${AI_SITE_INSPIRATION_LIMITS.free} site you like. Paid plans name up to ${AI_SITE_INSPIRATION_MAX}.`\n\n/**\n * Sites I like (AGL-3975): up to three addresses under the style cards. A\n * Free workspace's fields past its one are shown disabled with the reason\n * and an upgrade link, never hidden, so the person sees what a paid plan adds.\n */\nfunction InspirationFields({\n answers,\n answer,\n tracker,\n errors,\n fieldRef,\n offer,\n}: StepProps & { offer: AiSiteStartInspirationOffer }) {\n const values = answers.inspiration ?? []\n const change = (index: number, value: string) => {\n const next = Array.from({ length: offer.limit }, (_, at) => values[at] ?? '')\n next[index] = value\n answer({ inspiration: next })\n tracker.fieldChanged('inspiration')\n }\n return (\n <Stack spacing={1.5} data-start-area=\"field-inspiration\">\n <Typography variant=\"overline\" color=\"text.secondary\" component=\"h2\">\n {'Sites you like (optional)'}\n </Typography>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {\n 'We take only how they are laid out and styled: the order of sections, colors, type, buttons and motion. Never their words, photos or logos, so your site stays your own.'\n }\n </Typography>\n {Array.from({ length: AI_SITE_INSPIRATION_MAX }, (_, index) => {\n const locked = index >= offer.limit\n const field = (\n <TextField\n fullWidth\n type=\"url\"\n inputMode=\"url\"\n label={`Site ${index + 1}`}\n placeholder=\"https://example.com\"\n value={locked ? '' : (values[index] ?? '')}\n onChange={(event) => change(index, event.target.value)}\n onBlur={() => tracker.fieldLeft('inspiration')}\n {...(index === 0 ? { inputRef: fieldRef('inspiration') } : {})}\n error={index === 0 && Boolean(errors.inspiration)}\n {...(index === 0 && errors.inspiration ? { helperText: errors.inspiration.message } : {})}\n />\n )\n return locked ? (\n <BlockedControl key={index} blocked reason={AI_SITE_INSPIRATION_LOCKED_REASON} fullWidth>\n {field}\n </BlockedControl>\n ) : (\n <Box key={index}>{field}</Box>\n )\n })}\n {offer.limit < AI_SITE_INSPIRATION_MAX && (\n <PrerequisiteNotice {...(offer.upgradeHref ? { href: offer.upgradeHref } : {})} actionLabel=\"Upgrade\">\n {AI_SITE_INSPIRATION_PAID_NOTE}\n </PrerequisiteNotice>\n )}\n </Stack>\n )\n}\n\n/** Step: where leads go, how many pages, and on a paid plan the welcome email. */\nexport function DetailsStep({\n answers,\n answer,\n tracker,\n errors,\n fieldRef,\n freeTaste,\n band,\n}: StepProps & { freeTaste: boolean; band: { min: number; max: number } }) {\n return (\n <Stack spacing={3}>\n {/*\n How a customer reaches the business (AGL-3979), first: given, the\n pages show them as links — the contact page, the footer, the buttons\n that ask a visitor to call or write — and the site's search listing\n and AI-agent details carry them. Optional, and never a placeholder.\n */}\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>\n <Box data-start-area=\"field-phone\" sx={{ flex: 1 }}>\n <TextField\n fullWidth\n type=\"tel\"\n inputRef={fieldRef('phone')}\n label=\"Business phone\"\n placeholder=\"(512) 555-0142\"\n autoComplete=\"tel\"\n value={answers.phone}\n onChange={(event) => {\n answer({ phone: event.target.value })\n tracker.fieldChanged('phone')\n }}\n {...typed(tracker, 'phone')}\n error={Boolean(errors.phone)}\n helperText={errors.phone?.message ?? 'Optional. Shown on your site so customers can call.'}\n slotProps={{ htmlInput: { inputMode: 'tel' } }}\n />\n </Box>\n <Box data-start-area=\"field-email\" sx={{ flex: 1 }}>\n <TextField\n fullWidth\n type=\"email\"\n inputRef={fieldRef('email')}\n label=\"Business email\"\n placeholder=\"hello@yourbusiness.com\"\n autoComplete=\"email\"\n value={answers.email}\n onChange={(event) => {\n answer({ email: event.target.value })\n tracker.fieldChanged('email')\n }}\n {...typed(tracker, 'email')}\n error={Boolean(errors.email)}\n helperText={errors.email?.message ?? 'Optional. Shown on your site so customers can write.'}\n />\n </Box>\n </Stack>\n {/*\n The one setting a new site owner has to make, asked where they are\n already answering: a contact form nobody routed files its messages\n somewhere the person has not looked.\n */}\n <Box data-start-area=\"field-submissions\">\n <TextField\n select\n fullWidth\n inputRef={fieldRef('submissions')}\n label=\"Where do form submissions go?\"\n value={answers.submissions}\n onChange={(event) => {\n answer({ submissions: event.target.value as AiSiteSubmissions })\n tracker.fieldPicked('submissions')\n }}\n error={Boolean(errors.submissions)}\n helperText={errors.submissions?.message ?? 'You can change this on the form itself afterwards.'}\n >\n {AI_SITE_SUBMISSION_CHOICES.map((option) => (\n <MenuItem key={option.id} value={option.id}>\n {`${option.label} — ${option.blurb}`}\n </MenuItem>\n ))}\n </TextField>\n </Box>\n <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2}>\n <Box data-start-area=\"field-pages\" sx={{ flex: 1 }}>\n <TextField\n select\n fullWidth\n inputRef={fieldRef('pages')}\n label=\"Pages\"\n value={answers.pages}\n onChange={(event) => {\n answer({ pages: Number(event.target.value) })\n tracker.fieldPicked('pages')\n }}\n error={Boolean(errors.pages)}\n helperText={errors.pages?.message ?? (freeTaste ? AI_SITE_FREE_PAGES_NOTE : undefined)}\n >\n {Array.from({ length: band.max - band.min + 1 }, (_, index) => band.min + index).map((count) => (\n <MenuItem key={count} value={count}>\n {count}\n </MenuItem>\n ))}\n </TextField>\n </Box>\n {!freeTaste && (\n <Box data-start-area=\"field-welcomeEmail\" sx={{ flex: 1 }}>\n <TextField\n select\n fullWidth\n label=\"Welcome email\"\n value={answers.welcomeEmail ? 'yes' : 'no'}\n onChange={(event) => {\n answer({ welcomeEmail: event.target.value === 'yes' })\n tracker.fieldPicked('welcomeEmail')\n }}\n >\n <MenuItem value=\"yes\">{'Draft one'}</MenuItem>\n <MenuItem value=\"no\">{'No'}</MenuItem>\n </TextField>\n </Box>\n )}\n </Stack>\n </Stack>\n )\n}\n\n/**\n * The brand colors \"More details\" offers on the Style step (AGL-3979), by\n * name: picking one makes it the site's primary color, held to contrast by\n * the look like any brand color; none leaves the style to choose. Picked,\n * never typed: a color code is not something a site owner should need.\n */\nexport const AI_SITE_START_BRAND_COLORS: ReadonlyArray<{ label: string; hex: string }> = [\n { label: 'Red', hex: '#c62828' },\n { label: 'Orange', hex: '#e65100' },\n { label: 'Gold', hex: '#b28704' },\n { label: 'Green', hex: '#2e7d32' },\n { label: 'Teal', hex: '#00796b' },\n { label: 'Blue', hex: '#1565c0' },\n { label: 'Navy', hex: '#1a237e' },\n { label: 'Purple', hex: '#6a1b9a' },\n { label: 'Pink', hex: '#ad1457' },\n { label: 'Brown', hex: '#5d4037' },\n { label: 'Charcoal', hex: '#37474f' },\n]\n\n/** The price ranges offered, as a search listing writes them. */\nconst PRICE_RANGES: ReadonlyArray<{ value: string; label: string }> = [\n { value: '$', label: '$ — budget' },\n { value: '$$', label: '$$ — moderate' },\n { value: '$$$', label: '$$$ — premium' },\n { value: '$$$$', label: '$$$$ — luxury' },\n]\n\n/** What each step's \"More details\" says it holds, under its title. */\nconst MORE_SUMMARY: Readonly<Partial<Record<AiSiteStartStep, string>>> = {\n kind: 'Optional: a tagline and the year you started',\n audience: 'Optional: areas you serve, price range and languages',\n style: 'Optional: your brand color',\n details: 'Optional: address, opening hours and social profiles',\n}\n\n/** A typed extra's field. */\nfunction ExtraText({\n field,\n answers,\n answer,\n tracker,\n errors,\n fieldRef,\n label,\n placeholder,\n helper,\n autoComplete = 'off',\n multiline = false,\n inputMode,\n}: StepProps & {\n field: AiSiteStartExtraKey\n label: string\n placeholder?: string\n helper?: string\n autoComplete?: string\n multiline?: boolean\n inputMode?: 'numeric' | 'url'\n}) {\n const error = errors[field]\n return (\n <Box data-start-area={`field-${field}`} sx={{ flex: 1, minWidth: 0 }}>\n <TextField\n fullWidth\n inputRef={fieldRef(field)}\n label={label}\n placeholder={placeholder}\n autoComplete={autoComplete}\n multiline={multiline}\n minRows={multiline ? 2 : undefined}\n value={answers[field]}\n onChange={(event) => {\n answer({ [field]: event.target.value })\n tracker.fieldChanged(field)\n }}\n {...typed(tracker, field)}\n error={Boolean(error)}\n helperText={error?.message ?? helper}\n slotProps={inputMode ? { htmlInput: { inputMode } } : undefined}\n />\n </Box>\n )\n}\n\n/** The price range, picked from how search results show one. */\nfunction PriceRangeField({ answers, answer, tracker, errors, fieldRef }: StepProps) {\n const own = answers.priceRange && !PRICE_RANGES.some((option) => option.value === answers.priceRange)\n const options = own ? [...PRICE_RANGES, { value: answers.priceRange, label: answers.priceRange }] : PRICE_RANGES\n return (\n <Box data-start-area=\"field-priceRange\" sx={{ flex: 1, minWidth: 0 }}>\n <TextField\n select\n fullWidth\n inputRef={fieldRef('priceRange')}\n label=\"Price range\"\n value={answers.priceRange}\n onChange={(event) => {\n answer({ priceRange: event.target.value })\n tracker.fieldPicked('priceRange')\n }}\n error={Boolean(errors.priceRange)}\n helperText={errors.priceRange?.message ?? 'How your prices compare, as search results show it.'}\n >\n <MenuItem value=\"\">{'Not said'}</MenuItem>\n {options.map((option) => (\n <MenuItem key={option.value} value={option.value}>\n {option.label}\n </MenuItem>\n ))}\n </TextField>\n </Box>\n )\n}\n\n/**\n * What a brand color the swatches do not name is called (AGL-4049): one an AI\n * starter brought, or a start reopened on its own. Shown as its swatch and by\n * this name, never as a color code.\n */\nexport const AI_SITE_START_OWN_BRAND_LABEL = 'Chosen color'\n\n/** A brand color's name: a swatch's, else {@link AI_SITE_START_OWN_BRAND_LABEL} for a color code, else as given. */\nexport function aiSiteStartBrandLabel(brand: string): string {\n const swatch = AI_SITE_START_BRAND_COLORS.find((color) => color.hex === brand)\n if (swatch) return swatch.label\n return /^#[0-9a-f]{6}$/i.test(brand) ? AI_SITE_START_OWN_BRAND_LABEL : brand\n}\n\n/** The brand color, picked from named swatches, with a color the swatches do not name kept as one more. */\nfunction BrandField({ answers, answer, tracker }: StepProps) {\n const labelId = useId()\n const own = aiSiteStartBrandLabel(answers.brand) === AI_SITE_START_OWN_BRAND_LABEL ? answers.brand : null\n const swatches = own\n ? [...AI_SITE_START_BRAND_COLORS, { label: AI_SITE_START_OWN_BRAND_LABEL, hex: own }]\n : AI_SITE_START_BRAND_COLORS\n return (\n <Stack spacing={1} data-start-area=\"field-brand\">\n <Typography variant=\"body2\" color=\"text.secondary\" id={labelId}>\n {'Brand color'}\n </Typography>\n <Stack direction=\"row\" role=\"radiogroup\" aria-labelledby={labelId} sx={{ flexWrap: 'wrap', gap: 1 }}>\n {[{ label: 'Let the style choose', hex: '' }, ...swatches].map((color) => {\n const picked = (answers.brand || '') === color.hex\n return (\n <Tooltip key={color.label} title={color.label}>\n <Box\n component=\"button\"\n type=\"button\"\n role=\"radio\"\n aria-checked={picked}\n aria-label={color.label}\n onClick={() => {\n answer({ brand: color.hex })\n tracker.fieldPicked('brand')\n }}\n sx={{\n width: 36,\n height: 36,\n p: 0,\n borderRadius: '50%',\n border: 2,\n borderColor: picked ? 'text.primary' : 'divider',\n bgcolor: color.hex || 'background.paper',\n color: color.hex ? 'common.white' : 'text.secondary',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n }}\n >\n {picked ? <MdiIcon path={mdiCheck.path} fontSize=\"small\" /> : null}\n </Box>\n </Tooltip>\n )\n })}\n </Stack>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'Picked, it is your site’s main color, kept readable everywhere it is used.'}\n </Typography>\n </Stack>\n )\n}\n\n/** The opening hours, picked a day at a time: the same editor as Setup → SEO. */\nfunction HoursField({ answers, answer, tracker, errors }: StepProps) {\n return (\n <Box data-start-area=\"field-hours\">\n <OpeningHoursPicker\n label=\"Opening hours\"\n value={answers.hours}\n onChange={(hours) => {\n answer({ hours })\n tracker.fieldPicked('hours')\n }}\n helperText={errors.hours?.message ?? 'Leave every day closed if you work by appointment.'}\n />\n </Box>\n )\n}\n\n/** One extra's field, as \"More details\" draws it. */\nfunction ExtraField({ field, ...props }: StepProps & { field: AiSiteStartExtraKey }) {\n switch (field) {\n case 'tagline':\n return <ExtraText {...props} field={field} label=\"Tagline\" placeholder=\"Calm, gentle grooming your dog will love\" helper=\"A short line about the business, in your words.\" />\n case 'founded':\n return <ExtraText {...props} field={field} label=\"Year founded\" placeholder=\"2015\" inputMode=\"numeric\" />\n case 'serviceArea':\n return <ExtraText {...props} field={field} label=\"Areas you serve\" placeholder={'Austin\\nRound Rock'} helper=\"Cities, towns or neighborhoods, one a line.\" multiline />\n case 'priceRange':\n return <PriceRangeField {...props} />\n case 'languages':\n return <ExtraText {...props} field={field} label=\"Languages you serve customers in\" placeholder=\"English, Spanish\" />\n case 'brand':\n return <BrandField {...props} />\n case 'street':\n return <ExtraText {...props} field={field} label=\"Street address\" placeholder=\"214 Main Street\" autoComplete=\"street-address\" />\n case 'city':\n return <ExtraText {...props} field={field} label=\"City or town\" placeholder=\"Austin\" autoComplete=\"address-level2\" />\n case 'region':\n return <ExtraText {...props} field={field} label=\"State or region\" placeholder=\"TX\" autoComplete=\"address-level1\" />\n case 'postalCode':\n return <ExtraText {...props} field={field} label=\"ZIP or postal code\" placeholder=\"78701\" autoComplete=\"postal-code\" />\n case 'country':\n return <ExtraText {...props} field={field} label=\"Country\" placeholder=\"United States\" autoComplete=\"country-name\" />\n case 'hours':\n return <HoursField {...props} />\n case 'social':\n return (\n <ExtraText\n {...props}\n field={field}\n label=\"Social profiles\"\n placeholder=\"instagram.com/yourbusiness\"\n helper=\"One link a line. Your site links them, and its search listing names them as yours.\"\n multiline\n inputMode=\"url\"\n />\n )\n default:\n return null\n }\n}\n\n/** Fields \"More details\" draws side by side. */\nconst PAIRS: ReadonlyArray<readonly [AiSiteStartExtraKey, AiSiteStartExtraKey]> = [\n ['tagline', 'founded'],\n ['priceRange', 'languages'],\n ['city', 'region'],\n ['postalCode', 'country'],\n]\n\n/**\n * A step's \"More details\" (AGL-3979): a collapsed section of optional extras\n * that fit the step, so a person who wants the site to say more can, and one\n * who does not never has to open it. Open from the start where something in\n * it is already filled in (a start reopened on its answers), and opened by a\n * Next refused on one of its fields.\n */\nexport function MoreDetails({ step, ...props }: StepProps & { step: AiSiteStartStep }) {\n const fields = AI_SITE_START_MORE_FIELDS[step]\n const { answers, errors, tracker } = props\n const [open, setOpen] = useState(() => fields.some((field) => (answers[field] ?? '').trim() !== ''))\n if (!fields.length) return null\n const expanded = open || fields.some((field) => errors[field])\n const rows: Array<readonly AiSiteStartExtraKey[]> = []\n for (const field of fields) {\n if (rows.some((row) => row.includes(field))) continue\n const pair = PAIRS.find((entry) => entry[0] === field && fields.includes(entry[1]))\n rows.push(pair ?? [field])\n }\n return (\n <Accordion\n disableGutters\n variant=\"outlined\"\n // The same outlined, rounded section as the build page's plan.\n sx={{ borderRadius: 2, '&::before': { display: 'none' } }}\n expanded={expanded}\n onChange={(_, next) => {\n setOpen(next)\n if (next) tracker.moreDetails()\n }}\n data-start-area=\"more-details\"\n >\n <AccordionSummary expandIcon={<MdiIcon path={mdiChevronDown.path} />}>\n <Stack spacing={0.25}>\n <Typography variant=\"subtitle2\" component=\"span\">\n {'More details'}\n </Typography>\n <Typography variant=\"body2\" color=\"text.secondary\" component=\"span\">\n {MORE_SUMMARY[step]}\n </Typography>\n </Stack>\n </AccordionSummary>\n <AccordionDetails>\n <Stack spacing={2.5}>\n {rows.map((row) =>\n row.length > 1 ? (\n <Stack key={row.join('-')} direction={{ xs: 'column', sm: 'row' }} spacing={2}>\n {row.map((field) => (\n <ExtraField key={field} field={field} {...props} />\n ))}\n </Stack>\n ) : (\n <ExtraField key={row[0]} field={row[0]} {...props} />\n ),\n )}\n </Stack>\n </AccordionDetails>\n </Accordion>\n )\n}\n\n/** The extras on the review, each as a person reads it, with the step that asks it. */\nexport function aiSiteStartExtraRows(answers: AiSiteStartAnswers): Array<{ label: string; value: string; step: AiSiteStartStep }> {\n const rows: Array<{ label: string; value: string; step: AiSiteStartStep }> = []\n const add = (label: string, value: string, step: AiSiteStartStep) => {\n if (value.trim()) rows.push({ label, value: value.trim(), step })\n }\n add('Phone', answers.phone, 'details')\n add('Email', answers.email, 'details')\n add('Tagline', answers.tagline, 'kind')\n add('Year founded', answers.founded, 'kind')\n add('Areas you serve', aiSiteServiceAreas(answers.serviceArea).join(', '), 'audience')\n add('Price range', answers.priceRange, 'audience')\n add('Languages', answers.languages, 'audience')\n add('Brand color', answers.brand ? aiSiteStartBrandLabel(answers.brand) : '', 'style')\n const regional = [answers.region, answers.postalCode].map((part) => part.trim()).filter(Boolean).join(' ')\n const address = [answers.street, answers.city, regional, answers.country]\n .map((part) => part.trim())\n .filter(Boolean)\n .join(', ')\n add('Address', address, 'details')\n add('Opening hours', aiSiteHoursSentence(answers.hours), 'details')\n const links = aiSiteSocialLinks(answers.social) ?? []\n add('Social profiles', links.map((link) => link.replace(/^https:\\/\\//, '')).join(', '), 'details')\n return rows\n}\n\n/**\n * One answer on the review, as one button back to the step that asks it. The\n * whole row is the target, not only \"Edit\" at its end: people clicked the\n * answer itself to change it, and nothing happened.\n */\nfunction ReviewRow({ label, value, step, onEdit }: { label: string; value: ReactNode; step: AiSiteStartStep; onEdit: (step: AiSiteStartStep) => void }) {\n const valueId = useId()\n return (\n <ListItemButton\n onClick={() => onEdit(step)}\n aria-label={`Edit ${label.toLowerCase()}`}\n aria-describedby={valueId}\n sx={{ alignItems: 'flex-start', gap: 2, py: 1.5, px: 1, mx: -1, borderRadius: 1 }}\n >\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Typography variant=\"body2\" color=\"text.secondary\" component=\"span\" sx={{ display: 'block' }}>\n {label}\n </Typography>\n <Typography id={valueId} variant=\"body1\" component=\"span\" sx={{ display: 'block', overflowWrap: 'anywhere' }}>\n {value}\n </Typography>\n </Box>\n <Typography variant=\"button\" color=\"primary\" component=\"span\" aria-hidden sx={{ fontSize: '0.8125rem', pt: 0.25 }}>\n {'Edit'}\n </Typography>\n </ListItemButton>\n )\n}\n\n/** Step: every answer, each with Edit, before \"Plan my site\". */\nexport function ReviewStep({\n answers,\n freeTaste,\n onEdit,\n children,\n inspiration = false,\n}: {\n answers: AiSiteStartAnswers\n freeTaste: boolean\n onEdit: (step: AiSiteStartStep) => void\n children?: ReactNode\n /** Whether the start asks for the sites the person likes (AGL-3975). */\n inspiration?: boolean\n}) {\n const liked = aiSiteStartInspirationTyped(answers)\n const kind = aiSiteStartKind(answers)\n const submissions = AI_SITE_SUBMISSION_CHOICES.find((option) => option.id === answers.submissions)\n const rows: Array<{ label: string; value: ReactNode; step: AiSiteStartStep }> = [\n { label: 'Kind of site', value: answers.siteType.trim(), step: 'kind' },\n { label: 'Who it is for', value: answers.audience.trim() || 'Anyone (not said)', step: 'audience' },\n {\n label: 'Style',\n value: answers.style === null ? 'Not chosen yet' : answers.kind ? kind.label : `${kind.label}, picked for you`,\n step: 'style',\n },\n ...(inspiration\n ? [{ label: 'Sites you like', value: liked.length ? liked.map(aiSiteInspirationHost).join(', ') : 'None', step: 'style' as const }]\n : []),\n { label: 'Form submissions', value: submissions?.label ?? answers.submissions, step: 'details' },\n { label: 'Pages', value: String(answers.pages), step: 'details' },\n ...(freeTaste ? [] : [{ label: 'Welcome email', value: answers.welcomeEmail ? 'Draft one' : 'No', step: 'details' as const }]),\n // Everything \"More details\" and the contact fields were given (AGL-3979), each with Edit.\n ...aiSiteStartExtraRows(answers),\n ]\n return (\n <Stack spacing={3}>\n <List disablePadding data-start-area=\"review\" aria-label=\"Your answers\">\n {rows.map((row, index) => (\n <Fragment key={row.label}>\n {index > 0 && <Divider component=\"li\" aria-hidden />}\n <li>\n <ReviewRow {...row} onEdit={onEdit} />\n </li>\n </Fragment>\n ))}\n </List>\n {children}\n </Stack>\n )\n}\n\n/** A step's help beside its heading. */\nexport function StepHelp({ step }: { step: AiSiteStartStep }) {\n const help = step === 'choose' ? null : START_STEP_HELP[step]\n return help ? <HelpTip sx={{ float: 'right' }} {...help} /> : null\n}\n"],"names":["pluginDocsHelp","mdiBookOpenPageVariant","mdiBriefcaseOutline","mdiCalendarHeart","mdiCheck","mdiChevronDown","mdiCreation","mdiHandHeart","mdiScaleBalance","mdiShopping","mdiSilverwareForkKnife","mdiViewGridOutline","mdiWrench","HelpTip","MdiIcon","OptionCardGrid","BlockedControl","PrerequisiteNotice","OpeningHoursPicker","Accordion","AccordionDetails","AccordionSummary","Box","Divider","FormHelperText","LinearProgress","List","ListItemButton","MenuItem","Stack","Step","StepButton","StepLabel","Stepper","TextField","Tooltip","Typography","Fragment","useId","useState","aiSiteHoursSentence","aiSiteServiceAreas","aiSiteSocialLinks","AI_SITE_FREE_PAGES_NOTE","AI_SITE_SUBMISSION_CHOICES","AI_SITE_KINDS","AI_SITE_INSPIRATION_LIMITS","AI_SITE_INSPIRATION_MAX","AI_SITE_INSPIRATION_PAID_NOTE","aiSiteInspirationHost","SITE_STYLE_AUTO","AI_SITE_START_TYPES","aiSiteStartInspirationTyped","aiSiteStartKind","aiSiteStartStyleAnswer","AI_SITE_START_MORE_FIELDS","AI_SITE_START_STEP_LABELS","AI_SITE_START_STEPS","aiSiteStartStepIndex","aiSiteStylePreview","START_STEP_HELP","kind","anchor","excerpt","audience","review","style","details","START_TYPE_ICONS","path","startTypeTitle","type","words","replace","charAt","toUpperCase","slice","AI_SITE_STYLE_AUTO","aiSiteStyleCards","map","image","id","title","label","description","blurb","StartProgress","step","compact","onStep","index","count","length","name","spacing","data-start-area","role","aria-label","variant","color","value","aria-hidden","activeStep","alternativeLabel","at","onClick","toLowerCase","typed","tracker","field","onBlur","fieldLeft","KindStep","answers","answer","errors","fieldRef","picked","includes","siteType","fullWidth","required","inputRef","placeholder","onChange","event","target","fieldChanged","error","Boolean","helperText","message","component","columns","xs","sm","md","options","icon","fieldPicked","AudienceStep","StyleStep","inspiration","starterStyle","suggested","cards","card","chosen","InspirationFields","offer","AI_SITE_INSPIRATION_LOCKED_REASON","free","values","change","next","Array","from","limit","_","locked","inputMode","blocked","reason","upgradeHref","href","actionLabel","DetailsStep","freeTaste","band","direction","sx","flex","autoComplete","phone","slotProps","htmlInput","email","select","submissions","option","pages","Number","undefined","max","min","welcomeEmail","AI_SITE_START_BRAND_COLORS","hex","PRICE_RANGES","MORE_SUMMARY","ExtraText","helper","multiline","minWidth","minRows","PriceRangeField","own","priceRange","some","AI_SITE_START_OWN_BRAND_LABEL","aiSiteStartBrandLabel","brand","swatch","find","test","BrandField","labelId","swatches","aria-labelledby","flexWrap","gap","aria-checked","width","height","p","borderRadius","border","borderColor","bgcolor","display","alignItems","justifyContent","cursor","fontSize","HoursField","hours","ExtraField","props","PAIRS","MoreDetails","fields","open","setOpen","trim","expanded","rows","row","pair","entry","push","disableGutters","moreDetails","expandIcon","join","aiSiteStartExtraRows","add","tagline","founded","serviceArea","languages","regional","region","postalCode","part","filter","address","street","city","country","links","social","link","ReviewRow","onEdit","valueId","aria-describedby","py","px","mx","overflowWrap","pt","ReviewStep","children","liked","String","disablePadding","li","StepHelp","help","float"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;AAEA,SAASA,cAAc,QAAQ,mCAAkC;AACjE,SACEC,sBAAsB,EACtBC,mBAAmB,EACnBC,gBAAgB,EAChBC,QAAQ,EACRC,cAAc,EACdC,WAAW,EACXC,YAAY,EACZC,eAAe,EACfC,WAAW,EACXC,sBAAsB,EACtBC,kBAAkB,EAClBC,SAAS,QACJ,yBAAwB;AAC/B,SAASC,OAAO,EAAEC,OAAO,QAAQ,uBAAsB;AACvD,SAASC,cAAc,QAAQ,6DAA4D;AAC3F,SAASC,cAAc,QAAQ,4DAA2D;AAC1F,SAASC,kBAAkB,QAAQ,gEAA+D;AAClG,SAASC,kBAAkB,QAAQ,gEAA+D;AAClG,SACEC,SAAS,EACTC,gBAAgB,EAChBC,gBAAgB,EAChBC,GAAG,EACHC,OAAO,EACPC,cAAc,EACdC,cAAc,EACdC,IAAI,EACJC,cAAc,EACdC,QAAQ,EACRC,KAAK,EACLC,IAAI,EACJC,UAAU,EACVC,SAAS,EACTC,OAAO,EACPC,SAAS,EACTC,OAAO,EACPC,UAAU,QACL,gBAAe;AACtB,SAASC,QAAQ,EAAEC,KAAK,EAAEC,QAAQ,QAAkC,QAAO;AAC3E,SAASC,mBAAmB,EAAEC,kBAAkB,EAAEC,iBAAiB,QAAQ,8BAA0B;AACrG,SAASC,uBAAuB,EAAEC,0BAA0B,QAAgC,0BAAsB;AAClH,SAASC,aAAa,QAAQ,4BAAwB;AACtD,SACEC,0BAA0B,EAC1BC,uBAAuB,EACvBC,6BAA6B,EAC7BC,qBAAqB,QAChB,kCAA8B;AACrC,SAASC,eAAe,QAAQ,qCAAoC;AACpE,SACEC,mBAAmB,EACnBC,2BAA2B,EAC3BC,eAAe,EACfC,sBAAsB,QAGjB,4BAAwB;AAC/B,SACEC,yBAAyB,EACzBC,yBAAyB,EACzBC,mBAAmB,EACnBC,oBAAoB,QAIf,kCAA8B;AAErC,SAASC,kBAAkB,QAAQ,8BAA0B;AAE7D;;;;;;CAMC,GAED,+FAA+F,GAC/F,OAAO,MAAMC,kBAAkB;IAC7BC,MAAM7D,eAAe,WAAW;QAC9B8D,QAAQ;QACRC,SACE;IACJ;IACAC,UAAUhE,eAAe,WAAW;QAClC8D,QAAQ;QACRC,SAAS;IACX;IACAE,QAAQjE,eAAe,WAAW;QAChC8D,QAAQ;QACRC,SAAS;IACX;IACAG,OAAOlE,eAAe,eAAe;QACnC8D,QAAQ;QACRC,SACE;IACJ;IACAI,SAASnE,eAAe,WAAW;QACjC8D,QAAQ;QACRC,SACE;IACJ;AACF,EAAC;AAED,iFAAiF,GACjF,MAAMK,mBAAqD;IACzD,4BAA4BlE,oBAAoBmE,IAAI;IACpD,wBAAwB3D,uBAAuB2D,IAAI;IACnD,2BAA2B7D,gBAAgB6D,IAAI;IAC/C,qBAAqBzD,UAAUyD,IAAI;IACnC,UAAU5D,YAAY4D,IAAI;IAC1B,eAAe9D,aAAa8D,IAAI;IAChC,wBAAwB1D,mBAAmB0D,IAAI;IAC/C,YAAYlE,iBAAiBkE,IAAI;AACnC;AAEA,qGAAqG,GACrG,OAAO,SAASC,eAAeC,IAAY;IACzC,MAAMC,QAAQD,KAAKE,OAAO,CAAC,eAAe;IAC1C,OAAOD,MAAME,MAAM,CAAC,GAAGC,WAAW,KAAKH,MAAMI,KAAK,CAAC;AACrD;AAEA,4FAA4F,GAC5F,OAAO,MAAMC,qBAAqB3B,gBAAe;AAEjD;;;CAGC,GACD,OAAO,SAAS4B;IAMd,OAAOjC,cAAckC,GAAG,CAAC,CAAClB;QACxB,MAAMmB,QAAQrB,mBAAmBE,KAAKoB,EAAE;QACxC,OAAO;YAAEA,IAAIpB,KAAKoB,EAAE;YAAEC,OAAOrB,KAAKsB,KAAK;YAAEC,aAAavB,KAAKwB,KAAK;WAAML,QAAQ;YAAEA;QAAM,IAAI,CAAC;IAC7F;AACF;AAEA;;;;;CAKC,GACD,OAAO,SAASM,cAAc,EAC5BC,IAAI,EACJC,OAAO,EACPC,MAAM,EAKP;IACC,MAAMC,QAAQhC,qBAAqB6B;IACnC,MAAMI,QAAQlC,oBAAoBmC,MAAM;IACxC,MAAMC,OAAO,CAAC,KAAK,EAAEH,QAAQ,EAAE,IAAI,EAAEC,OAAO;IAC5C,IAAIH,SAAS;QACX,qBACE,MAAC3D;YAAMiE,SAAS;YAAGC,mBAAgB;YAAWC,MAAK;YAAQC,cAAYJ;;8BACrE,KAACzD;oBAAW8D,SAAQ;oBAAUC,OAAM;8BACjC,GAAGN,KAAK,EAAE,EAAErC,yBAAyB,CAAC+B,KAAK,EAAE;;8BAEhD,KAAC9D;oBAAeyE,SAAQ;oBAAcE,OAAO,AAAEV,CAAAA,QAAQ,CAAA,IAAKC,QAAS;oBAAKU,aAAW;;;;IAG3F;IACA,qBACE,KAACpE;QAAQqE,YAAYZ;QAAOa,gBAAgB;QAACN,cAAYJ;QAAME,mBAAgB;kBAC5EtC,oBAAoBsB,GAAG,CAAC,CAACE,IAAIuB,mBAC5B,KAAC1E;0BACE2D,UAAUe,KAAKd,sBACd,KAAC3D;oBAAW0E,SAAS,IAAMhB,OAAOR;oBAAKgB,cAAY,CAAC,QAAQ,EAAEzC,yBAAyB,CAACyB,GAAG,CAACyB,WAAW,IAAI;8BACxGlD,yBAAyB,CAACyB,GAAG;mCAGhC,KAACjD;8BAAWwB,yBAAyB,CAACyB,GAAG;;eANlCA;;AAYnB;AAYA,uFAAuF,GACvF,MAAM0B,QAAQ,CAACC,SAA6BC,QAA6B,CAAA;QACvEC,QAAQ,IAAMF,QAAQG,SAAS,CAACF;IAClC,CAAA;AAEA,2FAA2F,GAC3F,OAAO,SAASG,SAAS,EAAEC,OAAO,EAAEC,MAAM,EAAEN,OAAO,EAAEO,MAAM,EAAEC,QAAQ,EAAa;;QAkB5DD;IAjBpB,MAAME,SAASlE,oBAAoBmE,QAAQ,CAACL,QAAQM,QAAQ,IAAIN,QAAQM,QAAQ,GAAG;IACnF,qBACE,MAAC1F;QAAMiE,SAAS;;0BACd,KAACxE;gBAAIyE,mBAAgB;0BACnB,cAAA,KAAC7D;oBACCsF,SAAS;oBACTC,QAAQ;oBACRC,UAAUN,SAAS;oBACnBjC,OAAM;oBACNwC,aAAY;oBACZvB,OAAOa,QAAQM,QAAQ;oBACvBK,UAAU,CAACC;wBACTX,OAAO;4BAAEK,UAAUM,MAAMC,MAAM,CAAC1B,KAAK;wBAAC;wBACtCQ,QAAQmB,YAAY,CAAC;oBACvB;mBACIpB,MAAMC,SAAS;oBACnBoB,OAAOC,QAAQd,OAAOI,QAAQ;oBAC9BW,UAAU,WAAEf,mBAAAA,OAAOI,QAAQ,qBAAfJ,iBAAiBgB,OAAO,mBAAI;;;0BAG5C,MAACtG;gBAAMiE,SAAS;;kCACd,KAAC1D;wBAAW8D,SAAQ;wBAAWC,OAAM;wBAAiBiC,WAAU;kCAC7D;;kCAEH,KAACrH;wBACCoE,OAAM;wBACNY,mBAAgB;wBAChBsC,SAAS;4BAAEC,IAAI;4BAAGC,IAAI;4BAAGC,IAAI;wBAAE;wBAC/BC,SAAStF,oBAAoB4B,GAAG,CAAC,CAACR;gCAG1BH;mCAHoC;gCAC1Ca,IAAIV;gCACJW,OAAOZ,eAAeC;gCACtBmE,IAAI,GAAEtE,yBAAAA,gBAAgB,CAACG,KAAK,YAAtBH,yBAA0BnE,uBAAuBoE,IAAI;4BAC7D;;wBACA+B,OAAOiB;wBACPO,UAAU,CAACrD;4BACT2C,OAAO;gCAAEK,UAAUhD;4BAAK;4BACxBqC,QAAQ+B,WAAW,CAAC;wBACtB;;;;;;AAKV;AAEA,yCAAyC,GACzC,OAAO,SAASC,aAAa,EAAE3B,OAAO,EAAEC,MAAM,EAAEN,OAAO,EAAEO,MAAM,EAAEC,QAAQ,EAAa;;QAelED;IAdlB,qBACE,KAAC7F;QAAIyE,mBAAgB;kBACnB,cAAA,KAAC7D;YACCsF,SAAS;YACTE,UAAUN,SAAS;YACnBjC,OAAM;YACNwC,aAAY;YACZvB,OAAOa,QAAQjD,QAAQ;YACvB4D,UAAU,CAACC;gBACTX,OAAO;oBAAElD,UAAU6D,MAAMC,MAAM,CAAC1B,KAAK;gBAAC;gBACtCQ,QAAQmB,YAAY,CAAC;YACvB;WACIpB,MAAMC,SAAS;YACnBoB,OAAOC,QAAQd,OAAOnD,QAAQ;YAC9BkE,UAAU,WAAEf,mBAAAA,OAAOnD,QAAQ,qBAAfmD,iBAAiBgB,OAAO,mBAAI;;;AAIhD;AAEA;;;;;;;;;CASC,GACD,OAAO,SAASU,UAAU,EACxB5B,OAAO,EACPC,MAAM,EACNN,OAAO,EACPO,MAAM,EACNC,QAAQ,EACR0B,WAAW,EACXC,eAAe,IAAI,EAIpB;IACC,MAAMC,YAAY3F,gBAAgB,aAAK4D;QAASpD,MAAM;;IACtD,MAAMoF,sBACJ,KAAClI;QACCoE,OAAM;QACNY,mBAAgB;QAChBsC,SAAS;YAAEC,IAAI;YAAGC,IAAI;YAAGC,IAAI;QAAE;QAC/BC,SAAS;YACP;gBACExD,IAAIJ;gBACJK,OAAO;gBACPE,aAAa,CAAC,kBAAkB,EAAE4D,UAAU7D,KAAK,EAAE;gBACnDuD,MAAMpI,YAAY+D,IAAI;YACxB;eACGS,mBAAmBC,GAAG,CAAC,CAACmE,OACzBA,KAAKjE,EAAE,MAAK8D,gCAAAA,aAAc9D,EAAE,IACxB,aAAKiE;oBAAM9D,aAAa,CAAC,KAAK,EAAE2D,aAAalD,IAAI,CAAC,wBAAwB,CAAC;qBAC3EqD;SAEP;QACD9C,OAAOa,QAAQ/C,KAAK;QACpB0D,UAAU,CAAC3C;YACTiC,OAAO5D,uBAAuB2B;YAC9B2B,QAAQ+B,WAAW,CAAC;QACtB;;IAGJ,MAAMQ,uBACJ,MAACtH;QAAMiE,SAAS;QAAGC,mBAAgB;;YAChCkD;YACA9B,OAAOjD,KAAK,iBACX,KAAC1C;gBAAewG,KAAK;gBAAChC,MAAK;0BACxBmB,OAAOjD,KAAK,CAACiE,OAAO;iBAErB;;;IAGR,IAAI,CAACW,aAAa,OAAOK;IACzB,qBACE,MAACtH;QAAMiE,SAAS;;YACbqD;0BACD,KAACC;gBAAkBnC,SAASA;gBAASC,QAAQA;gBAAQN,SAASA;gBAASO,QAAQA;gBAAQC,UAAUA;gBAAUiC,OAAOP;;;;AAGxH;AAYA,oEAAoE,GACpE,OAAO,MAAMQ,oCAAoC,CAAC,uBAAuB,EAAExG,2BAA2ByG,IAAI,CAAC,sCAAsC,EAAExG,wBAAwB,CAAC,CAAC,CAAA;AAE7K;;;;CAIC,GACD,SAASqG,kBAAkB,EACzBnC,OAAO,EACPC,MAAM,EACNN,OAAO,EACPO,MAAM,EACNC,QAAQ,EACRiC,KAAK,EAC8C;QACpCpC;IAAf,MAAMuC,UAASvC,uBAAAA,QAAQ6B,WAAW,YAAnB7B,uBAAuB,EAAE;IACxC,MAAMwC,SAAS,CAAC/D,OAAeU;QAC7B,MAAMsD,OAAOC,MAAMC,IAAI,CAAC;YAAEhE,QAAQyD,MAAMQ,KAAK;QAAC,GAAG,CAACC,GAAGtD;gBAAOgD;oBAAAA,aAAAA,MAAM,CAAChD,GAAG,YAAVgD,aAAc;;QAC1EE,IAAI,CAAChE,MAAM,GAAGU;QACdc,OAAO;YAAE4B,aAAaY;QAAK;QAC3B9C,QAAQmB,YAAY,CAAC;IACvB;IACA,qBACE,MAAClG;QAAMiE,SAAS;QAAKC,mBAAgB;;0BACnC,KAAC3D;gBAAW8D,SAAQ;gBAAWC,OAAM;gBAAiBiC,WAAU;0BAC7D;;0BAEH,KAAChG;gBAAW8D,SAAQ;gBAAQC,OAAM;0BAE9B;;YAGHwD,MAAMC,IAAI,CAAC;gBAAEhE,QAAQ7C;YAAwB,GAAG,CAAC+G,GAAGpE;oBASzB8D;gBAR1B,MAAMO,SAASrE,SAAS2D,MAAMQ,KAAK;gBACnC,MAAMhD,sBACJ,KAAC3E;oBACCsF,SAAS;oBACTjD,MAAK;oBACLyF,WAAU;oBACV7E,OAAO,CAAC,KAAK,EAAEO,QAAQ,GAAG;oBAC1BiC,aAAY;oBACZvB,OAAO2D,SAAS,MAAMP,gBAAAA,MAAM,CAAC9D,MAAM,YAAb8D,gBAAiB;oBACvC5B,UAAU,CAACC,QAAU4B,OAAO/D,OAAOmC,MAAMC,MAAM,CAAC1B,KAAK;oBACrDU,QAAQ,IAAMF,QAAQG,SAAS,CAAC;mBAC3BrB,UAAU,IAAI;oBAAEgC,UAAUN,SAAS;gBAAe,IAAI,CAAC;oBAC5DY,OAAOtC,UAAU,KAAKuC,QAAQd,OAAO2B,WAAW;mBAC3CpD,UAAU,KAAKyB,OAAO2B,WAAW,GAAG;oBAAEZ,YAAYf,OAAO2B,WAAW,CAACX,OAAO;gBAAC,IAAI,CAAC;gBAG3F,OAAO4B,uBACL,KAAC/I;oBAA2BiJ,OAAO;oBAACC,QAAQZ;oBAAmC9B,SAAS;8BACrFX;mBADkBnB,uBAIrB,KAACpE;8BAAiBuF;mBAARnB;YAEd;YACC2D,MAAMQ,KAAK,GAAG9G,yCACb,KAAC9B,iCAAwBoI,MAAMc,WAAW,GAAG;gBAAEC,MAAMf,MAAMc,WAAW;YAAC,IAAI,CAAC;gBAAIE,aAAY;0BACzFrH;;;;AAKX;AAEA,gFAAgF,GAChF,OAAO,SAASsH,YAAY,EAC1BrD,OAAO,EACPC,MAAM,EACNN,OAAO,EACPO,MAAM,EACNC,QAAQ,EACRmD,SAAS,EACTC,IAAI,EACmE;;QAyBjDrD,eAmBAA,eAqBFA,qBAsBEA;IAtFtB,qBACE,MAACtF;QAAMiE,SAAS;;0BAOd,MAACjE;gBAAM4I,WAAW;oBAAEnC,IAAI;oBAAUC,IAAI;gBAAM;gBAAGzC,SAAS;;kCACtD,KAACxE;wBAAIyE,mBAAgB;wBAAc2E,IAAI;4BAAEC,MAAM;wBAAE;kCAC/C,cAAA,KAACzI;4BACCsF,SAAS;4BACTjD,MAAK;4BACLmD,UAAUN,SAAS;4BACnBjC,OAAM;4BACNwC,aAAY;4BACZiD,cAAa;4BACbxE,OAAOa,QAAQ4D,KAAK;4BACpBjD,UAAU,CAACC;gCACTX,OAAO;oCAAE2D,OAAOhD,MAAMC,MAAM,CAAC1B,KAAK;gCAAC;gCACnCQ,QAAQmB,YAAY,CAAC;4BACvB;2BACIpB,MAAMC,SAAS;4BACnBoB,OAAOC,QAAQd,OAAO0D,KAAK;4BAC3B3C,UAAU,WAAEf,gBAAAA,OAAO0D,KAAK,qBAAZ1D,cAAcgB,OAAO,mBAAI;4BACrC2C,WAAW;gCAAEC,WAAW;oCAAEf,WAAW;gCAAM;4BAAE;;;kCAGjD,KAAC1I;wBAAIyE,mBAAgB;wBAAc2E,IAAI;4BAAEC,MAAM;wBAAE;kCAC/C,cAAA,KAACzI;4BACCsF,SAAS;4BACTjD,MAAK;4BACLmD,UAAUN,SAAS;4BACnBjC,OAAM;4BACNwC,aAAY;4BACZiD,cAAa;4BACbxE,OAAOa,QAAQ+D,KAAK;4BACpBpD,UAAU,CAACC;gCACTX,OAAO;oCAAE8D,OAAOnD,MAAMC,MAAM,CAAC1B,KAAK;gCAAC;gCACnCQ,QAAQmB,YAAY,CAAC;4BACvB;2BACIpB,MAAMC,SAAS;4BACnBoB,OAAOC,QAAQd,OAAO6D,KAAK;4BAC3B9C,UAAU,YAAEf,gBAAAA,OAAO6D,KAAK,qBAAZ7D,cAAcgB,OAAO,oBAAI;;;;;0BAS3C,KAAC7G;gBAAIyE,mBAAgB;0BACnB,cAAA,KAAC7D;oBACC+I,MAAM;oBACNzD,SAAS;oBACTE,UAAUN,SAAS;oBACnBjC,OAAM;oBACNiB,OAAOa,QAAQiE,WAAW;oBAC1BtD,UAAU,CAACC;wBACTX,OAAO;4BAAEgE,aAAarD,MAAMC,MAAM,CAAC1B,KAAK;wBAAsB;wBAC9DQ,QAAQ+B,WAAW,CAAC;oBACtB;oBACAX,OAAOC,QAAQd,OAAO+D,WAAW;oBACjChD,UAAU,YAAEf,sBAAAA,OAAO+D,WAAW,qBAAlB/D,oBAAoBgB,OAAO,oBAAI;8BAE1CvF,2BAA2BmC,GAAG,CAAC,CAACoG,uBAC/B,KAACvJ;4BAAyBwE,OAAO+E,OAAOlG,EAAE;sCACvC,GAAGkG,OAAOhG,KAAK,CAAC,GAAG,EAAEgG,OAAO9F,KAAK,EAAE;2BADvB8F,OAAOlG,EAAE;;;0BAM9B,MAACpD;gBAAM4I,WAAW;oBAAEnC,IAAI;oBAAUC,IAAI;gBAAM;gBAAGzC,SAAS;;kCACtD,KAACxE;wBAAIyE,mBAAgB;wBAAc2E,IAAI;4BAAEC,MAAM;wBAAE;kCAC/C,cAAA,KAACzI;4BACC+I,MAAM;4BACNzD,SAAS;4BACTE,UAAUN,SAAS;4BACnBjC,OAAM;4BACNiB,OAAOa,QAAQmE,KAAK;4BACpBxD,UAAU,CAACC;gCACTX,OAAO;oCAAEkE,OAAOC,OAAOxD,MAAMC,MAAM,CAAC1B,KAAK;gCAAE;gCAC3CQ,QAAQ+B,WAAW,CAAC;4BACtB;4BACAX,OAAOC,QAAQd,OAAOiE,KAAK;4BAC3BlD,UAAU,YAAEf,gBAAAA,OAAOiE,KAAK,qBAAZjE,cAAcgB,OAAO,oBAAKoC,YAAY5H,0BAA0B2I;sCAE3E3B,MAAMC,IAAI,CAAC;gCAAEhE,QAAQ4E,KAAKe,GAAG,GAAGf,KAAKgB,GAAG,GAAG;4BAAE,GAAG,CAAC1B,GAAGpE,QAAU8E,KAAKgB,GAAG,GAAG9F,OAAOX,GAAG,CAAC,CAACY,sBACpF,KAAC/D;oCAAqBwE,OAAOT;8CAC1BA;mCADYA;;;oBAMpB,CAAC4E,2BACA,KAACjJ;wBAAIyE,mBAAgB;wBAAqB2E,IAAI;4BAAEC,MAAM;wBAAE;kCACtD,cAAA,MAACzI;4BACC+I,MAAM;4BACNzD,SAAS;4BACTrC,OAAM;4BACNiB,OAAOa,QAAQwE,YAAY,GAAG,QAAQ;4BACtC7D,UAAU,CAACC;gCACTX,OAAO;oCAAEuE,cAAc5D,MAAMC,MAAM,CAAC1B,KAAK,KAAK;gCAAM;gCACpDQ,QAAQ+B,WAAW,CAAC;4BACtB;;8CAEA,KAAC/G;oCAASwE,OAAM;8CAAO;;8CACvB,KAACxE;oCAASwE,OAAM;8CAAM;;;;;;;;;AAOpC;AAEA;;;;;CAKC,GACD,OAAO,MAAMsF,6BAA4E;IACvF;QAAEvG,OAAO;QAAOwG,KAAK;IAAU;IAC/B;QAAExG,OAAO;QAAUwG,KAAK;IAAU;IAClC;QAAExG,OAAO;QAAQwG,KAAK;IAAU;IAChC;QAAExG,OAAO;QAASwG,KAAK;IAAU;IACjC;QAAExG,OAAO;QAAQwG,KAAK;IAAU;IAChC;QAAExG,OAAO;QAAQwG,KAAK;IAAU;IAChC;QAAExG,OAAO;QAAQwG,KAAK;IAAU;IAChC;QAAExG,OAAO;QAAUwG,KAAK;IAAU;IAClC;QAAExG,OAAO;QAAQwG,KAAK;IAAU;IAChC;QAAExG,OAAO;QAASwG,KAAK;IAAU;IACjC;QAAExG,OAAO;QAAYwG,KAAK;IAAU;CACrC,CAAA;AAED,+DAA+D,GAC/D,MAAMC,eAAgE;IACpE;QAAExF,OAAO;QAAKjB,OAAO;IAAa;IAClC;QAAEiB,OAAO;QAAMjB,OAAO;IAAgB;IACtC;QAAEiB,OAAO;QAAOjB,OAAO;IAAgB;IACvC;QAAEiB,OAAO;QAAQjB,OAAO;IAAgB;CACzC;AAED,oEAAoE,GACpE,MAAM0G,eAAmE;IACvEhI,MAAM;IACNG,UAAU;IACVE,OAAO;IACPC,SAAS;AACX;AAEA,2BAA2B,GAC3B,SAAS2H,UAAU,EACjBjF,KAAK,EACLI,OAAO,EACPC,MAAM,EACNN,OAAO,EACPO,MAAM,EACNC,QAAQ,EACRjC,KAAK,EACLwC,WAAW,EACXoE,MAAM,EACNnB,eAAe,KAAK,EACpBoB,YAAY,KAAK,EACjBhC,SAAS,EASV;;IACC,MAAMhC,QAAQb,MAAM,CAACN,MAAM;IAC3B,qBACE,KAACvF;QAAIyE,mBAAiB,CAAC,MAAM,EAAEc,OAAO;QAAE6D,IAAI;YAAEC,MAAM;YAAGsB,UAAU;QAAE;kBACjE,cAAA,KAAC/J;YACCsF,SAAS;YACTE,UAAUN,SAASP;YACnB1B,OAAOA;YACPwC,aAAaA;YACbiD,cAAcA;YACdoB,WAAWA;YACXE,SAASF,YAAY,IAAIV;YACzBlF,OAAOa,OAAO,CAACJ,MAAM;YACrBe,UAAU,CAACC;gBACTX,OAAO;oBAAE,CAACL,MAAM,EAAEgB,MAAMC,MAAM,CAAC1B,KAAK;gBAAC;gBACrCQ,QAAQmB,YAAY,CAAClB;YACvB;WACIF,MAAMC,SAASC;YACnBmB,OAAOC,QAAQD;YACfE,UAAU,UAAEF,yBAAAA,MAAOG,OAAO,mBAAI4D;YAC9BjB,WAAWd,YAAY;gBAAEe,WAAW;oBAAEf;gBAAU;YAAE,IAAIsB;;;AAI9D;AAEA,8DAA8D,GAC9D,SAASa,gBAAgB,EAAElF,OAAO,EAAEC,MAAM,EAAEN,OAAO,EAAEO,MAAM,EAAEC,QAAQ,EAAa;;QAgB9DD;IAflB,MAAMiF,MAAMnF,QAAQoF,UAAU,IAAI,CAACT,aAAaU,IAAI,CAAC,CAACnB,SAAWA,OAAO/E,KAAK,KAAKa,QAAQoF,UAAU;IACpG,MAAM5D,UAAU2D,MAAM;WAAIR;QAAc;YAAExF,OAAOa,QAAQoF,UAAU;YAAElH,OAAO8B,QAAQoF,UAAU;QAAC;KAAE,GAAGT;IACpG,qBACE,KAACtK;QAAIyE,mBAAgB;QAAmB2E,IAAI;YAAEC,MAAM;YAAGsB,UAAU;QAAE;kBACjE,cAAA,MAAC/J;YACC+I,MAAM;YACNzD,SAAS;YACTE,UAAUN,SAAS;YACnBjC,OAAM;YACNiB,OAAOa,QAAQoF,UAAU;YACzBzE,UAAU,CAACC;gBACTX,OAAO;oBAAEmF,YAAYxE,MAAMC,MAAM,CAAC1B,KAAK;gBAAC;gBACxCQ,QAAQ+B,WAAW,CAAC;YACtB;YACAX,OAAOC,QAAQd,OAAOkF,UAAU;YAChCnE,UAAU,WAAEf,qBAAAA,OAAOkF,UAAU,qBAAjBlF,mBAAmBgB,OAAO,mBAAI;;8BAE1C,KAACvG;oBAASwE,OAAM;8BAAI;;gBACnBqC,QAAQ1D,GAAG,CAAC,CAACoG,uBACZ,KAACvJ;wBAA4BwE,OAAO+E,OAAO/E,KAAK;kCAC7C+E,OAAOhG,KAAK;uBADAgG,OAAO/E,KAAK;;;;AAOrC;AAEA;;;;CAIC,GACD,OAAO,MAAMmG,gCAAgC,eAAc;AAE3D,kHAAkH,GAClH,OAAO,SAASC,sBAAsBC,KAAa;IACjD,MAAMC,SAAShB,2BAA2BiB,IAAI,CAAC,CAACxG,QAAUA,MAAMwF,GAAG,KAAKc;IACxE,IAAIC,QAAQ,OAAOA,OAAOvH,KAAK;IAC/B,OAAO,kBAAkByH,IAAI,CAACH,SAASF,gCAAgCE;AACzE;AAEA,yGAAyG,GACzG,SAASI,WAAW,EAAE5F,OAAO,EAAEC,MAAM,EAAEN,OAAO,EAAa;IACzD,MAAMkG,UAAUxK;IAChB,MAAM8J,MAAMI,sBAAsBvF,QAAQwF,KAAK,MAAMF,gCAAgCtF,QAAQwF,KAAK,GAAG;IACrG,MAAMM,WAAWX,MACb;WAAIV;QAA4B;YAAEvG,OAAOoH;YAA+BZ,KAAKS;QAAI;KAAE,GACnFV;IACJ,qBACE,MAAC7J;QAAMiE,SAAS;QAAGC,mBAAgB;;0BACjC,KAAC3D;gBAAW8D,SAAQ;gBAAQC,OAAM;gBAAiBlB,IAAI6H;0BACpD;;0BAEH,KAACjL;gBAAM4I,WAAU;gBAAMzE,MAAK;gBAAagH,mBAAiBF;gBAASpC,IAAI;oBAAEuC,UAAU;oBAAQC,KAAK;gBAAE;0BAC/F;oBAAC;wBAAE/H,OAAO;wBAAwBwG,KAAK;oBAAG;uBAAMoB;iBAAS,CAAChI,GAAG,CAAC,CAACoB;oBAC9D,MAAMkB,SAAS,AAACJ,CAAAA,QAAQwF,KAAK,IAAI,EAAC,MAAOtG,MAAMwF,GAAG;oBAClD,qBACE,KAACxJ;wBAA0B+C,OAAOiB,MAAMhB,KAAK;kCAC3C,cAAA,KAAC7D;4BACC8G,WAAU;4BACV7D,MAAK;4BACLyB,MAAK;4BACLmH,gBAAc9F;4BACdpB,cAAYE,MAAMhB,KAAK;4BACvBsB,SAAS;gCACPS,OAAO;oCAAEuF,OAAOtG,MAAMwF,GAAG;gCAAC;gCAC1B/E,QAAQ+B,WAAW,CAAC;4BACtB;4BACA+B,IAAI;gCACF0C,OAAO;gCACPC,QAAQ;gCACRC,GAAG;gCACHC,cAAc;gCACdC,QAAQ;gCACRC,aAAapG,SAAS,iBAAiB;gCACvCqG,SAASvH,MAAMwF,GAAG,IAAI;gCACtBxF,OAAOA,MAAMwF,GAAG,GAAG,iBAAiB;gCACpCgC,SAAS;gCACTC,YAAY;gCACZC,gBAAgB;gCAChBC,QAAQ;4BACV;sCAECzG,uBAAS,KAACvG;gCAAQuD,MAAMjE,SAASiE,IAAI;gCAAE0J,UAAS;iCAAa;;uBA1BpD5H,MAAMhB,KAAK;gBA8B7B;;0BAEF,KAAC/C;gBAAW8D,SAAQ;gBAAUC,OAAM;0BACjC;;;;AAIT;AAEA,+EAA+E,GAC/E,SAAS6H,WAAW,EAAE/G,OAAO,EAAEC,MAAM,EAAEN,OAAO,EAAEO,MAAM,EAAa;;QAU/CA;IATlB,qBACE,KAAC7F;QAAIyE,mBAAgB;kBACnB,cAAA,KAAC7E;YACCiE,OAAM;YACNiB,OAAOa,QAAQgH,KAAK;YACpBrG,UAAU,CAACqG;gBACT/G,OAAO;oBAAE+G;gBAAM;gBACfrH,QAAQ+B,WAAW,CAAC;YACtB;YACAT,UAAU,WAAEf,gBAAAA,OAAO8G,KAAK,qBAAZ9G,cAAcgB,OAAO,mBAAI;;;AAI7C;AAEA,mDAAmD,GACnD,SAAS+F,WAAW,EAA+D;QAA/D,EAAErH,KAAK,EAAwD,OAAnDsH;;;IAC9B,OAAQtH;QACN,KAAK;YACH,qBAAO,KAACiF,wBAAcqC;gBAAOtH,OAAOA;gBAAO1B,OAAM;gBAAUwC,aAAY;gBAA2CoE,QAAO;;QAC3H,KAAK;YACH,qBAAO,KAACD,wBAAcqC;gBAAOtH,OAAOA;gBAAO1B,OAAM;gBAAewC,aAAY;gBAAOqC,WAAU;;QAC/F,KAAK;YACH,qBAAO,KAAC8B,wBAAcqC;gBAAOtH,OAAOA;gBAAO1B,OAAM;gBAAkBwC,aAAa;gBAAsBoE,QAAO;gBAA8CC,SAAS;;QACtK,KAAK;YACH,qBAAO,KAACG,8BAAoBgC;QAC9B,KAAK;YACH,qBAAO,KAACrC,wBAAcqC;gBAAOtH,OAAOA;gBAAO1B,OAAM;gBAAmCwC,aAAY;;QAClG,KAAK;YACH,qBAAO,KAACkF,yBAAesB;QACzB,KAAK;YACH,qBAAO,KAACrC,wBAAcqC;gBAAOtH,OAAOA;gBAAO1B,OAAM;gBAAiBwC,aAAY;gBAAkBiD,cAAa;;QAC/G,KAAK;YACH,qBAAO,KAACkB,wBAAcqC;gBAAOtH,OAAOA;gBAAO1B,OAAM;gBAAewC,aAAY;gBAASiD,cAAa;;QACpG,KAAK;YACH,qBAAO,KAACkB,wBAAcqC;gBAAOtH,OAAOA;gBAAO1B,OAAM;gBAAkBwC,aAAY;gBAAKiD,cAAa;;QACnG,KAAK;YACH,qBAAO,KAACkB,wBAAcqC;gBAAOtH,OAAOA;gBAAO1B,OAAM;gBAAqBwC,aAAY;gBAAQiD,cAAa;;QACzG,KAAK;YACH,qBAAO,KAACkB,wBAAcqC;gBAAOtH,OAAOA;gBAAO1B,OAAM;gBAAUwC,aAAY;gBAAgBiD,cAAa;;QACtG,KAAK;YACH,qBAAO,KAACoD,yBAAeG;QACzB,KAAK;YACH,qBACE,KAACrC,wBACKqC;gBACJtH,OAAOA;gBACP1B,OAAM;gBACNwC,aAAY;gBACZoE,QAAO;gBACPC,SAAS;gBACThC,WAAU;;QAGhB;YACE,OAAO;IACX;AACF;AAEA,8CAA8C,GAC9C,MAAMoE,QAA4E;IAChF;QAAC;QAAW;KAAU;IACtB;QAAC;QAAc;KAAY;IAC3B;QAAC;QAAQ;KAAS;IAClB;QAAC;QAAc;KAAU;CAC1B;AAED;;;;;;CAMC,GACD,OAAO,SAASC,YAAY,EAAyD;QAAzD,EAAE9I,IAAI,EAAmD,OAA9C4I;;;IACrC,MAAMG,SAAS/K,yBAAyB,CAACgC,KAAK;IAC9C,MAAM,EAAE0B,OAAO,EAAEE,MAAM,EAAEP,OAAO,EAAE,GAAGuH;IACrC,MAAM,CAACI,MAAMC,QAAQ,GAAGjM,SAAS,IAAM+L,OAAOhC,IAAI,CAAC,CAACzF;gBAAWI;mBAAD,EAACA,iBAAAA,OAAO,CAACJ,MAAM,YAAdI,iBAAkB,IAAIwH,IAAI,OAAO;;IAChG,IAAI,CAACH,OAAO1I,MAAM,EAAE,OAAO;IAC3B,MAAM8I,WAAWH,QAAQD,OAAOhC,IAAI,CAAC,CAACzF,QAAUM,MAAM,CAACN,MAAM;IAC7D,MAAM8H,OAA8C,EAAE;IACtD,KAAK,MAAM9H,SAASyH,OAAQ;QAC1B,IAAIK,KAAKrC,IAAI,CAAC,CAACsC,MAAQA,IAAItH,QAAQ,CAACT,SAAS;QAC7C,MAAMgI,OAAOT,MAAMzB,IAAI,CAAC,CAACmC,QAAUA,KAAK,CAAC,EAAE,KAAKjI,SAASyH,OAAOhH,QAAQ,CAACwH,KAAK,CAAC,EAAE;QACjFH,KAAKI,IAAI,CAACF,eAAAA,OAAQ;YAAChI;SAAM;IAC3B;IACA,qBACE,MAAC1F;QACC6N,cAAc;QACd9I,SAAQ;QACR,+DAA+D;QAC/DwE,IAAI;YAAE6C,cAAc;YAAG,aAAa;gBAAEI,SAAS;YAAO;QAAE;QACxDe,UAAUA;QACV9G,UAAU,CAACkC,GAAGJ;YACZ8E,QAAQ9E;YACR,IAAIA,MAAM9C,QAAQqI,WAAW;QAC/B;QACAlJ,mBAAgB;;0BAEhB,KAAC1E;gBAAiB6N,0BAAY,KAACpO;oBAAQuD,MAAMhE,eAAegE,IAAI;;0BAC9D,cAAA,MAACxC;oBAAMiE,SAAS;;sCACd,KAAC1D;4BAAW8D,SAAQ;4BAAYkC,WAAU;sCACvC;;sCAEH,KAAChG;4BAAW8D,SAAQ;4BAAQC,OAAM;4BAAiBiC,WAAU;sCAC1DyD,YAAY,CAACtG,KAAK;;;;;0BAIzB,KAACnE;0BACC,cAAA,KAACS;oBAAMiE,SAAS;8BACb6I,KAAK5J,GAAG,CAAC,CAAC6J,MACTA,IAAIhJ,MAAM,GAAG,kBACX,KAAC/D;4BAA0B4I,WAAW;gCAAEnC,IAAI;gCAAUC,IAAI;4BAAM;4BAAGzC,SAAS;sCACzE8I,IAAI7J,GAAG,CAAC,CAAC8B,sBACR,KAACqH;oCAAuBrH,OAAOA;mCAAWsH,QAAzBtH;2BAFT+H,IAAIO,IAAI,CAAC,sBAMrB,KAACjB;4BAAwBrH,OAAO+H,GAAG,CAAC,EAAE;2BAAMT,QAA3BS,GAAG,CAAC,EAAE;;;;;AAOrC;AAEA,qFAAqF,GACrF,OAAO,SAASQ,qBAAqBnI,OAA2B;QAoBhDvE;IAnBd,MAAMiM,OAAuE,EAAE;IAC/E,MAAMU,MAAM,CAAClK,OAAeiB,OAAeb;QACzC,IAAIa,MAAMqI,IAAI,IAAIE,KAAKI,IAAI,CAAC;YAAE5J;YAAOiB,OAAOA,MAAMqI,IAAI;YAAIlJ;QAAK;IACjE;IACA8J,IAAI,SAASpI,QAAQ4D,KAAK,EAAE;IAC5BwE,IAAI,SAASpI,QAAQ+D,KAAK,EAAE;IAC5BqE,IAAI,WAAWpI,QAAQqI,OAAO,EAAE;IAChCD,IAAI,gBAAgBpI,QAAQsI,OAAO,EAAE;IACrCF,IAAI,mBAAmB5M,mBAAmBwE,QAAQuI,WAAW,EAAEL,IAAI,CAAC,OAAO;IAC3EE,IAAI,eAAepI,QAAQoF,UAAU,EAAE;IACvCgD,IAAI,aAAapI,QAAQwI,SAAS,EAAE;IACpCJ,IAAI,eAAepI,QAAQwF,KAAK,GAAGD,sBAAsBvF,QAAQwF,KAAK,IAAI,IAAI;IAC9E,MAAMiD,WAAW;QAACzI,QAAQ0I,MAAM;QAAE1I,QAAQ2I,UAAU;KAAC,CAAC7K,GAAG,CAAC,CAAC8K,OAASA,KAAKpB,IAAI,IAAIqB,MAAM,CAAC7H,SAASkH,IAAI,CAAC;IACtG,MAAMY,UAAU;QAAC9I,QAAQ+I,MAAM;QAAE/I,QAAQgJ,IAAI;QAAEP;QAAUzI,QAAQiJ,OAAO;KAAC,CACtEnL,GAAG,CAAC,CAAC8K,OAASA,KAAKpB,IAAI,IACvBqB,MAAM,CAAC7H,SACPkH,IAAI,CAAC;IACRE,IAAI,WAAWU,SAAS;IACxBV,IAAI,iBAAiB7M,oBAAoByE,QAAQgH,KAAK,GAAG;IACzD,MAAMkC,SAAQzN,qBAAAA,kBAAkBuE,QAAQmJ,MAAM,aAAhC1N,qBAAqC,EAAE;IACrD2M,IAAI,mBAAmBc,MAAMpL,GAAG,CAAC,CAACsL,OAASA,KAAK5L,OAAO,CAAC,eAAe,KAAK0K,IAAI,CAAC,OAAO;IACxF,OAAOR;AACT;AAEA;;;;CAIC,GACD,SAAS2B,UAAU,EAAEnL,KAAK,EAAEiB,KAAK,EAAEb,IAAI,EAAEgL,MAAM,EAAuG;IACpJ,MAAMC,UAAUlO;IAChB,qBACE,MAACX;QACC8E,SAAS,IAAM8J,OAAOhL;QACtBU,cAAY,CAAC,KAAK,EAAEd,MAAMuB,WAAW,IAAI;QACzC+J,oBAAkBD;QAClB9F,IAAI;YAAEkD,YAAY;YAAcV,KAAK;YAAGwD,IAAI;YAAKC,IAAI;YAAGC,IAAI,CAAC;YAAGrD,cAAc;QAAE;;0BAEhF,MAACjM;gBAAIoJ,IAAI;oBAAEC,MAAM;oBAAGsB,UAAU;gBAAE;;kCAC9B,KAAC7J;wBAAW8D,SAAQ;wBAAQC,OAAM;wBAAiBiC,WAAU;wBAAOsC,IAAI;4BAAEiD,SAAS;wBAAQ;kCACxFxI;;kCAEH,KAAC/C;wBAAW6C,IAAIuL;wBAAStK,SAAQ;wBAAQkC,WAAU;wBAAOsC,IAAI;4BAAEiD,SAAS;4BAASkD,cAAc;wBAAW;kCACxGzK;;;;0BAGL,KAAChE;gBAAW8D,SAAQ;gBAASC,OAAM;gBAAUiC,WAAU;gBAAO/B,aAAW;gBAACqE,IAAI;oBAAEqD,UAAU;oBAAa+C,IAAI;gBAAK;0BAC7G;;;;AAIT;AAEA,+DAA+D,GAC/D,OAAO,SAASC,WAAW,EACzB9J,OAAO,EACPsD,SAAS,EACTgG,MAAM,EACNS,QAAQ,EACRlI,cAAc,KAAK,EAQpB;;IACC,MAAMmI,QAAQ7N,4BAA4B6D;IAC1C,MAAMpD,OAAOR,gBAAgB4D;IAC7B,MAAMiE,cAActI,2BAA2B+J,IAAI,CAAC,CAACxB,SAAWA,OAAOlG,EAAE,KAAKgC,QAAQiE,WAAW;IACjG,MAAMyD,OAA0E;QAC9E;YAAExJ,OAAO;YAAgBiB,OAAOa,QAAQM,QAAQ,CAACkH,IAAI;YAAIlJ,MAAM;QAAO;QACtE;YAAEJ,OAAO;YAAiBiB,OAAOa,QAAQjD,QAAQ,CAACyK,IAAI,MAAM;YAAqBlJ,MAAM;QAAW;QAClG;YACEJ,OAAO;YACPiB,OAAOa,QAAQ/C,KAAK,KAAK,OAAO,mBAAmB+C,QAAQpD,IAAI,GAAGA,KAAKsB,KAAK,GAAG,GAAGtB,KAAKsB,KAAK,CAAC,gBAAgB,CAAC;YAC9GI,MAAM;QACR;WACIuD,cACA;YAAC;gBAAE3D,OAAO;gBAAkBiB,OAAO6K,MAAMrL,MAAM,GAAGqL,MAAMlM,GAAG,CAAC9B,uBAAuBkM,IAAI,CAAC,QAAQ;gBAAQ5J,MAAM;YAAiB;SAAE,GACjI,EAAE;QACN;YAAEJ,OAAO;YAAoBiB,KAAK,UAAE8E,+BAAAA,YAAa/F,KAAK,mBAAI8B,QAAQiE,WAAW;YAAE3F,MAAM;QAAU;QAC/F;YAAEJ,OAAO;YAASiB,OAAO8K,OAAOjK,QAAQmE,KAAK;YAAG7F,MAAM;QAAU;WAC5DgF,YAAY,EAAE,GAAG;YAAC;gBAAEpF,OAAO;gBAAiBiB,OAAOa,QAAQwE,YAAY,GAAG,cAAc;gBAAMlG,MAAM;YAAmB;SAAE;QAC7H,0FAA0F;WACvF6J,qBAAqBnI;KACzB;IACD,qBACE,MAACpF;QAAMiE,SAAS;;0BACd,KAACpE;gBAAKyP,cAAc;gBAACpL,mBAAgB;gBAASE,cAAW;0BACtD0I,KAAK5J,GAAG,CAAC,CAAC6J,KAAKlJ,sBACd,MAACrD;;4BACEqD,QAAQ,mBAAK,KAACnE;gCAAQ6G,WAAU;gCAAK/B,aAAW;;0CACjD,KAAC+K;0CACC,cAAA,KAACd,wBAAc1B;oCAAK2B,QAAQA;;;;uBAHjB3B,IAAIzJ,KAAK;;YAQ3B6L;;;AAGP;AAEA,sCAAsC,GACtC,OAAO,SAASK,SAAS,EAAE9L,IAAI,EAA6B;IAC1D,MAAM+L,OAAO/L,SAAS,WAAW,OAAO3B,eAAe,CAAC2B,KAAK;IAC7D,OAAO+L,qBAAO,KAACzQ;QAAQ6J,IAAI;YAAE6G,OAAO;QAAQ;OAAOD,SAAW;AAChE"}
@@ -36,7 +36,7 @@ import { AssistBuildCard } from "./assist-build-card.component.js";
36
36
  import { isAssistBuildProposal } from "../model/assist-build.js";
37
37
  import { assistBuildDraftLinks, isAssistFollowUpDue, isLiveAssistFollowUp } from "../model/assist-follow-up.js";
38
38
  import { cancelAiJobRequest, startAssistBuildRequest, startAssistPageChangeRequest } from "./ai-job-requests.js";
39
- import { assistPageChangeDraftVersion, assistPageChangeHistoryNote, isAssistPageChangeProposal } from "../model/assist-page-change.js";
39
+ import { assistPageChangeDraftVersion, assistThreadOutcomes, isAssistPageChangeProposal } from "../model/assist-page-change.js";
40
40
  import { AssistPageChangeCard } from "./assist-page-change-card.component.js";
41
41
  import { aiInsightSurfaceForPath } from "../model/ai-insight.js";
42
42
  import { AssistJobsDrawer } from "./assist-jobs-drawer.component.js";
@@ -50,15 +50,6 @@ import { followAiJobsForUsageMeter, refreshAiUsageMeterFree } from "./ai-usage-m
50
50
  import { readAiUsageMeter, usePublishAiUsageMeter } from "./use-ai-usage-meter.js";
51
51
  import { pluginDocsHelp } from "@aglyn/aglyn/app-utils/docs-help";
52
52
  import { HelpTip } from "@aglyn/shared-ui-jsx";
53
- /**
54
- * A turn as the next question's history carries it (AGL-4116): its words, and
55
- * what became of the change it made, which the words alone never say.
56
- */ function assistHistoryText(message) {
57
- var _assistPageChangeHistoryNote;
58
- var _message_editOutcome;
59
- const note = (_assistPageChangeHistoryNote = assistPageChangeHistoryNote(message)) != null ? _assistPageChangeHistoryNote : message.edit && ((_message_editOutcome = message.editOutcome) == null ? void 0 : _message_editOutcome.kind) === 'applied' ? `(Applied to the open canvas as an unsaved change: ${message.edit.summary})` : null;
60
- return note ? `${message.text}\n\n${note}` : message.text;
61
- }
62
53
  /** The key a follow-up waiting for its canvas is kept under, per org (AGL-3616). */ const followUpKey = (orgId)=>`aglyn-assist-follow-up:${orgId}`;
63
54
  function loadFollowUp(orgId) {
64
55
  if (!orgId || typeof sessionStorage === 'undefined') return null;
@@ -724,8 +715,10 @@ export function AssistPanelComponent(props) {
724
715
  // lands in the thread it was asked in.
725
716
  const history = messages.slice(-HISTORY_TURNS_SENT).map((message)=>({
726
717
  role: message.role,
727
- text: assistHistoryText(message)
718
+ text: message.text
728
719
  }));
720
+ // What this thread's changes came to, which its words never say (AGL-4116).
721
+ const outcomes = assistThreadOutcomes(messages);
729
722
  const askedIn = threadKey;
730
723
  updateThread(askedIn, (prior)=>[
731
724
  ...prior,
@@ -778,7 +771,10 @@ export function AssistPanelComponent(props) {
778
771
  body: JSON.stringify(_extends({
779
772
  orgId: scopedOrgId,
780
773
  question,
781
- history,
774
+ history
775
+ }, outcomes.length ? {
776
+ outcomes
777
+ } : {}, {
782
778
  // Page context rides along; the server drops it for free orgs
783
779
  // (level 2 is Pro+). Sending it is not a grant — the capability
784
780
  // decision is server-side.