{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "email-campaign-composer",
  "title": "Email Campaign Composer",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/email-campaign-composer/email-campaign-composer.component.ts",
      "content": "// High-craft marketing email broadcast designer, audience segment selector, AI subject line\n// optimizer, A/B testing split, live multi-device newsletter preview, and deliverability\n// scorecard. Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, DestroyRef, Input, computed, inject, signal } from '@angular/core'\nimport {\n  ArrowRight,\n  Calendar,\n  Check,\n  CheckCircle2,\n  Eye,\n  Flame,\n  Inbox,\n  Lock,\n  LucideAngularModule,\n  Mail,\n  Monitor,\n  Send,\n  ShieldCheck,\n  Smartphone,\n  Sparkles,\n  Split,\n  Terminal,\n  UserCheck,\n  Users,\n  Zap,\n} from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiBadgeComponent } from '@/ui/badge/badge.component'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport {\n  UiCardComponent,\n  UiCardContentComponent,\n  UiCardDescriptionComponent,\n  UiCardHeaderComponent,\n  UiCardTitleComponent,\n} from '@/ui/card/card.component'\nimport {\n  UiDialogComponent,\n  UiDialogContentComponent,\n  UiDialogDescriptionComponent,\n  UiDialogFooterComponent,\n  UiDialogHeaderComponent,\n  UiDialogTitleComponent,\n} from '@/ui/dialog/dialog.component'\nimport { UiInputComponent } from '@/ui/input/input.component'\nimport {\n  UiSelectComponent,\n  UiSelectContentComponent,\n  UiSelectItemComponent,\n  UiSelectTriggerComponent,\n  UiSelectValueComponent,\n} from '@/ui/select/select.component'\nimport { UiSeparatorComponent } from '@/ui/separator/separator.component'\nimport { UiSwitchComponent } from '@/ui/switch/switch.component'\n\nexport type CampaignViewport = 'desktop' | 'mobile'\nexport type CampaignClient = 'all' | 'gmail' | 'apple' | 'outlook'\nexport type ScheduleTiming = 'optimal' | 'immediate'\n\ninterface AudienceSegment {\n  id: string\n  label: string\n  count: number\n  formattedCount: string\n  openRate: string\n  clickRate: string\n  deliverability: string\n}\n\nconst AUDIENCE_OPTIONS: AudienceSegment[] = [\n  {\n    id: 'active-devs',\n    label: 'All Active Developers (42,500 subscribers)',\n    count: 42500,\n    formattedCount: '42.5k',\n    openRate: '38.4%',\n    clickRate: '12.2%',\n    deliverability: '99.9%',\n  },\n  {\n    id: 'tech-leads',\n    label: 'Enterprise Tech Leads (8,200 subscribers)',\n    count: 8200,\n    formattedCount: '8.2k',\n    openRate: '46.1%',\n    clickRate: '18.5%',\n    deliverability: '99.8%',\n  },\n  {\n    id: 'free-users',\n    label: 'Free Plan Users (28,000 subscribers)',\n    count: 28000,\n    formattedCount: '28.0k',\n    openRate: '31.2%',\n    clickRate: '8.9%',\n    deliverability: '99.7%',\n  },\n]\n\nconst AI_SUGGESTIONS = [\n  { text: '🚀 Introducing UIPKGE 2.0: The unbundled UI registry', score: 94, tag: 'High Open Rate Impact' },\n  { text: 'Ship polished UIs 10x faster with UIPKGE 2.0 ⚡', score: 92, tag: 'Strong Action Verb' },\n  { text: 'Zero npm dependencies: How UIPKGE 2.0 changes frontend dev', score: 89, tag: 'Curiosity Spike' },\n]\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-email-campaign-composer, [ui-email-campaign-composer]',\n  standalone: true,\n  // React renders the root <div> itself: the host stays out of layout and `class` goes to the root.\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [\n    LucideAngularModule,\n    UiBadgeComponent,\n    UiButtonComponent,\n    UiCardComponent,\n    UiCardContentComponent,\n    UiCardDescriptionComponent,\n    UiCardHeaderComponent,\n    UiCardTitleComponent,\n    UiDialogComponent,\n    UiDialogContentComponent,\n    UiDialogDescriptionComponent,\n    UiDialogFooterComponent,\n    UiDialogHeaderComponent,\n    UiDialogTitleComponent,\n    UiInputComponent,\n    UiSelectComponent,\n    UiSelectContentComponent,\n    UiSelectItemComponent,\n    UiSelectTriggerComponent,\n    UiSelectValueComponent,\n    UiSeparatorComponent,\n    UiSwitchComponent,\n  ],\n  template: `\n    <div data-slot=\"email-campaign-composer\" [class]=\"rootClass\">\n      <!-- Top Header Bar -->\n      <div ui-card class=\"border-border bg-card shadow-xs\">\n        <div ui-card-header class=\"pb-4\">\n          <div class=\"flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between\">\n            <div class=\"space-y-1.5\">\n              <div class=\"flex flex-wrap items-center gap-2.5\">\n                <div class=\"bg-primary/10 text-primary flex size-8 items-center justify-center rounded-lg shadow-xs\">\n                  <lucide-icon [img]=\"Mail\" class=\"size-4\" />\n                </div>\n                <h2 class=\"text-foreground text-lg font-semibold tracking-tight sm:text-xl\">{{ campaignName }}</h2>\n                <span\n                  ui-badge\n                  variant=\"outline\"\n                  class=\"border-info/30 bg-info/10 text-info gap-1.5 px-2.5 py-0.5 text-xs font-medium\"\n                >\n                  <span class=\"bg-info size-1.5 rounded-full\"></span>\n                  <span>Draft Saved · {{ currentAudience().formattedCount }} Recipients</span>\n                </span>\n              </div>\n              <p class=\"text-muted-foreground text-xs\">\n                Configure campaign targeting, optimize open rates with AI scoring, and preview live multi-device inbox\n                rendering.\n              </p>\n            </div>\n\n            <div class=\"flex flex-wrap items-center gap-2.5\">\n              <button\n                ui-button\n                variant=\"outline\"\n                size=\"sm\"\n                class=\"gap-1.5 text-xs font-medium\"\n                (click)=\"isTestModalOpen.set(true)\"\n              >\n                <lucide-icon [img]=\"Mail\" class=\"text-muted-foreground size-3.5\" />\n                <span>Send Test Proof</span>\n              </button>\n\n              <button\n                ui-button\n                size=\"sm\"\n                class=\"gap-1.5 text-xs font-medium shadow-xs\"\n                (click)=\"isScheduleModalOpen.set(true)\"\n              >\n                <lucide-icon [img]=\"Send\" class=\"size-3.5 fill-current\" />\n                <span>Schedule Broadcast</span>\n              </button>\n            </div>\n          </div>\n        </div>\n      </div>\n\n      <!-- 2-Column Campaign Studio Grid -->\n      <div class=\"grid grid-cols-1 items-start gap-6 lg:grid-cols-12\">\n        <!-- LEFT PANEL: Campaign Setup & Audience -->\n        <div class=\"space-y-5 lg:col-span-5\">\n          <div ui-card class=\"border-border bg-card shadow-xs\">\n            <div ui-card-header class=\"pb-3\">\n              <div class=\"flex flex-wrap items-center justify-between\">\n                <div class=\"flex items-center gap-2\">\n                  <div class=\"bg-primary/10 text-primary flex size-7 items-center justify-center rounded-md\">\n                    <lucide-icon [img]=\"Users\" class=\"size-3.5\" />\n                  </div>\n                  <h3 ui-card-title class=\"text-sm font-semibold tracking-tight\">Audience Segment</h3>\n                </div>\n                <span ui-badge variant=\"secondary\" class=\"h-5 gap-1 px-2 text-xs font-normal\">\n                  <lucide-icon [img]=\"UserCheck\" class=\"text-success size-3\" />\n                  Verified List\n                </span>\n              </div>\n              <p ui-card-description class=\"text-xs\">\n                Select subscriber segment to calculate deliverability pacing and personalization tags.\n              </p>\n            </div>\n            <div ui-card-content class=\"space-y-3.5 pt-0\">\n              <div class=\"space-y-1.5\">\n                <label class=\"text-foreground text-xs font-medium\">Target Segment</label>\n                <ui-select [value]=\"selectedAudience()\" (valueChange)=\"selectedAudience.set($event)\">\n                  <button\n                    ui-select-trigger\n                    class=\"h-9 w-full text-xs font-medium [&>span]:truncate [&>svg]:shrink-0\"\n                    aria-label=\"Select Audience Segment\"\n                  >\n                    <ui-select-value placeholder=\"Select audience segment\" />\n                  </button>\n                  <ui-select-content>\n                    @for (aud of audienceOptions; track aud.id) {\n                      <ui-select-item [value]=\"aud.id\">\n                        <span>{{ aud.label }}</span>\n                      </ui-select-item>\n                    }\n                  </ui-select-content>\n                </ui-select>\n              </div>\n\n              <div class=\"grid grid-cols-3 gap-2 pt-1\">\n                <div class=\"border-border bg-muted/40 rounded-lg border p-2.5 text-center\">\n                  <div class=\"text-muted-foreground text-xs font-medium\">Recipients</div>\n                  <div class=\"text-foreground mt-0.5 text-sm font-bold tracking-tight\">\n                    {{ currentAudience().formattedCount }}\n                  </div>\n                </div>\n                <div class=\"border-border bg-muted/40 rounded-lg border p-2.5 text-center\">\n                  <div class=\"text-muted-foreground text-xs font-medium\">Avg Open Rate</div>\n                  <div class=\"text-success mt-0.5 text-sm font-bold tracking-tight\">\n                    {{ currentAudience().openRate }}\n                  </div>\n                </div>\n                <div class=\"border-border bg-muted/40 rounded-lg border p-2.5 text-center\">\n                  <div class=\"text-muted-foreground text-xs font-medium\">Avg CTR</div>\n                  <div class=\"text-info mt-0.5 text-sm font-bold tracking-tight\">\n                    {{ currentAudience().clickRate }}\n                  </div>\n                </div>\n              </div>\n            </div>\n          </div>\n\n          <!-- Subject Line & AI Optimizer Card -->\n          <div ui-card class=\"border-border bg-card shadow-xs\">\n            <div ui-card-header class=\"pb-3\">\n              <div class=\"flex flex-wrap items-center justify-between\">\n                <div class=\"flex items-center gap-2\">\n                  <div class=\"bg-primary/10 text-primary flex size-7 items-center justify-center rounded-md\">\n                    <lucide-icon [img]=\"Sparkles\" class=\"size-3.5\" />\n                  </div>\n                  <h3 ui-card-title class=\"text-sm font-semibold tracking-tight\">Subject Line & AI Scorer</h3>\n                </div>\n                <span\n                  ui-badge\n                  variant=\"outline\"\n                  class=\"border-success/30 bg-success/10 text-success gap-1 px-2 text-xs font-medium\"\n                >\n                  <lucide-icon [img]=\"Sparkles\" class=\"text-success size-3\" />\n                  <span>94 / 100 · High Open Rate Impact</span>\n                </span>\n              </div>\n              <p ui-card-description class=\"text-xs\">\n                AI predictive heuristic analyzing urgency, sentiment, character count, and spam filter risk.\n              </p>\n            </div>\n\n            <div ui-card-content class=\"space-y-4 pt-0\">\n              <div class=\"border-border bg-muted/30 flex flex-wrap items-center justify-between rounded-lg border p-3\">\n                <div class=\"space-y-0.5\">\n                  <div class=\"text-foreground flex items-center gap-1.5 text-xs font-medium\">\n                    <lucide-icon [img]=\"Split\" class=\"text-primary size-3.5\" />\n                    <span>A/B Subject Variant Testing</span>\n                  </div>\n                  <p class=\"text-muted-foreground text-xs\">Test 2 subject lines with 50/50 subscriber split</p>\n                </div>\n                <button\n                  ui-switch\n                  id=\"ng-ab-toggle\"\n                  [checked]=\"isAbTestEnabled()\"\n                  (checkedChange)=\"isAbTestEnabled.set($event)\"\n                ></button>\n              </div>\n\n              <div class=\"space-y-1.5\">\n                <div class=\"flex flex-wrap items-center justify-between text-xs\">\n                  <label class=\"text-foreground font-medium\">\n                    Subject Line {{ isAbTestEnabled() ? '(Variant A · 50%)' : '' }}\n                  </label>\n                  <div class=\"flex items-center gap-1.5\">\n                    <span class=\"text-muted-foreground font-mono text-xs\">{{ subjectA().length }}/60 chars</span>\n                    <span\n                      ui-badge\n                      variant=\"outline\"\n                      class=\"text-muted-foreground h-4.5 gap-1 px-1.5 text-xs font-normal\"\n                    >\n                      <lucide-icon [img]=\"Flame\" class=\"text-warning size-2.5\" />\n                      <span>{{ emojiCount() }} emoji</span>\n                    </span>\n                  </div>\n                </div>\n                <ui-input\n                  [value]=\"subjectA()\"\n                  (valueChange)=\"subjectA.set($event)\"\n                  class=\"text-xs\"\n                  placeholder=\"Enter campaign subject line...\"\n                />\n              </div>\n\n              @if (isAbTestEnabled()) {\n                <div class=\"space-y-1.5\">\n                  <div class=\"flex flex-wrap items-center justify-between text-xs\">\n                    <label class=\"text-foreground font-medium\">Subject Line (Variant B · 50%)</label>\n                    <span class=\"text-muted-foreground font-mono text-xs\">{{ subjectB().length }}/60 chars</span>\n                  </div>\n                  <ui-input\n                    [value]=\"subjectB()\"\n                    (valueChange)=\"subjectB.set($event)\"\n                    class=\"text-xs\"\n                    placeholder=\"Enter alternate subject line B...\"\n                  />\n                  <div class=\"flex items-center gap-1 pt-1\">\n                    <button\n                      type=\"button\"\n                      ui-button\n                      size=\"xs\"\n                      [variant]=\"activePreviewVariant() === 'A' ? 'default' : 'outline'\"\n                      class=\"text-xs font-medium\"\n                      (click)=\"activePreviewVariant.set('A')\"\n                    >\n                      Preview Variant A\n                    </button>\n                    <button\n                      type=\"button\"\n                      ui-button\n                      size=\"xs\"\n                      [variant]=\"activePreviewVariant() === 'B' ? 'default' : 'outline'\"\n                      class=\"text-xs font-medium\"\n                      (click)=\"activePreviewVariant.set('B')\"\n                    >\n                      Preview Variant B\n                    </button>\n                  </div>\n                </div>\n              }\n\n              <div class=\"border-border bg-muted/20 space-y-2 rounded-lg border p-3 text-xs\">\n                <div class=\"flex flex-wrap items-center justify-between\">\n                  <span class=\"text-muted-foreground flex items-center gap-1.5\">\n                    <lucide-icon [img]=\"Check\" class=\"text-success size-3\" />\n                    Sentiment Tone\n                  </span>\n                  <span class=\"text-foreground font-medium\">Positive (98%)</span>\n                </div>\n                <div class=\"flex flex-wrap items-center justify-between\">\n                  <span class=\"text-muted-foreground flex items-center gap-1.5\">\n                    <lucide-icon [img]=\"Check\" class=\"text-success size-3\" />\n                    Urgency & Relevance\n                  </span>\n                  <span class=\"text-foreground font-medium\">High (91%)</span>\n                </div>\n                <div class=\"flex flex-wrap items-center justify-between\">\n                  <span class=\"text-muted-foreground flex items-center gap-1.5\">\n                    <lucide-icon [img]=\"Check\" class=\"text-success size-3\" />\n                    Spam Keyword Risk\n                  </span>\n                  <span class=\"text-success font-medium\">Very Low (0.1%)</span>\n                </div>\n              </div>\n\n              <div class=\"space-y-2\">\n                <span class=\"text-muted-foreground flex items-center gap-1 text-xs font-medium\">\n                  <lucide-icon [img]=\"Sparkles\" class=\"text-primary size-3\" />\n                  AI Optimization Suggestions (Click to apply):\n                </span>\n                <div class=\"space-y-1.5\">\n                  @for (suggestion of aiSuggestions; track suggestion.text) {\n                    <button\n                      type=\"button\"\n                      class=\"border-border hover:border-primary/40 hover:bg-muted/50 focus-visible:ring-ring flex w-full items-center justify-between rounded-md border p-2 text-left text-xs transition-colors outline-none focus-visible:ring-2\"\n                      (click)=\"applyAiSubject(suggestion.text)\"\n                    >\n                      <span class=\"text-foreground truncate font-medium\">{{ suggestion.text }}</span>\n                      <span ui-badge variant=\"secondary\" class=\"text-success ml-2 shrink-0 font-mono text-xs\">\n                        {{ suggestion.score }}/100\n                      </span>\n                    </button>\n                  }\n                </div>\n              </div>\n\n              <div ui-separator></div>\n\n              <div class=\"space-y-1.5\">\n                <div class=\"flex flex-wrap items-center justify-between text-xs\">\n                  <label class=\"text-foreground font-medium\">Preview Text / Preheader</label>\n                  <span class=\"text-muted-foreground font-mono text-xs\">{{ previewText().length }}/90 chars</span>\n                </div>\n                <ui-input\n                  [value]=\"previewText()\"\n                  (valueChange)=\"previewText.set($event)\"\n                  class=\"text-xs\"\n                  placeholder=\"Secondary snippet displayed in subscriber inbox lists...\"\n                />\n              </div>\n\n              <div ui-separator></div>\n\n              <div class=\"space-y-3\">\n                <label class=\"text-foreground text-xs font-medium\">Sender Identity</label>\n                <div class=\"grid grid-cols-1 gap-2.5 sm:grid-cols-2\">\n                  <div class=\"space-y-1\">\n                    <span class=\"text-muted-foreground text-xs\">Sender Display Name</span>\n                    <ui-input [value]=\"senderName\" class=\"text-xs\" placeholder=\"UIPKGE Team\" />\n                  </div>\n                  <div class=\"space-y-1\">\n                    <span class=\"text-muted-foreground text-xs\">From Address</span>\n                    <ui-input [value]=\"senderEmail\" class=\"text-xs\" placeholder=\"updates@uipkge.dev\" />\n                  </div>\n                </div>\n                <div\n                  class=\"border-success/20 bg-success/5 text-success flex flex-wrap items-center justify-between rounded-md border px-2.5 py-1.5 text-xs\"\n                >\n                  <div class=\"flex items-center gap-1.5\">\n                    <lucide-icon [img]=\"ShieldCheck\" class=\"size-3.5 shrink-0\" />\n                    <span>Domain verified: <strong>mail.uipkge.dev</strong> (SPF & DKIM valid)</span>\n                  </div>\n                  <span ui-badge variant=\"outline\" class=\"border-success/30 text-success h-4.5 px-1.5 text-xs\">\n                    TLS 1.3\n                  </span>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n\n        <!-- RIGHT PANEL: Live Multi-Device Email Preview -->\n        <div class=\"space-y-5 lg:col-span-7\">\n          <div ui-card class=\"border-border bg-card overflow-hidden shadow-xs\">\n            <div ui-card-header class=\"border-border bg-muted/20 border-b pb-3\">\n              <div class=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n                <div class=\"flex items-center gap-2\">\n                  <lucide-icon [img]=\"Eye\" class=\"text-primary size-4\" />\n                  <h3 ui-card-title class=\"text-sm font-semibold tracking-tight\">Live Newsletter Preview</h3>\n                  @if (isAbTestEnabled()) {\n                    <span ui-badge variant=\"secondary\" class=\"text-xs font-normal\">\n                      Showing Variant {{ activePreviewVariant() }}\n                    </span>\n                  }\n                </div>\n\n                <div class=\"bg-muted border-border inline-flex items-center rounded-lg border p-1 shadow-xs\">\n                  <button\n                    type=\"button\"\n                    ui-button\n                    size=\"xs\"\n                    [variant]=\"viewport() === 'desktop' ? 'default' : 'ghost'\"\n                    class=\"gap-1.5 text-xs font-medium\"\n                    (click)=\"viewport.set('desktop')\"\n                  >\n                    <lucide-icon [img]=\"Monitor\" class=\"size-3.5\" />\n                    <span>Desktop 600px</span>\n                  </button>\n                  <button\n                    type=\"button\"\n                    ui-button\n                    size=\"xs\"\n                    [variant]=\"viewport() === 'mobile' ? 'default' : 'ghost'\"\n                    class=\"gap-1.5 text-xs font-medium\"\n                    (click)=\"viewport.set('mobile')\"\n                  >\n                    <lucide-icon [img]=\"Smartphone\" class=\"size-3.5\" />\n                    <span>Mobile 375px</span>\n                  </button>\n                </div>\n              </div>\n            </div>\n\n            <div ui-card-content class=\"bg-muted/30 flex min-h-[580px] flex-col items-center justify-start p-4 sm:p-6\">\n              <div [class]=\"previewCanvasClass\">\n                <div class=\"border-border bg-card overflow-hidden rounded-xl border shadow-sm\">\n                  <div\n                    class=\"border-border bg-muted/60 flex flex-wrap items-center justify-between border-b px-4 py-2.5\"\n                  >\n                    <div class=\"flex items-center gap-1.5\">\n                      <div class=\"bg-destructive/80 size-2.5 rounded-full\"></div>\n                      <div class=\"bg-warning/80 size-2.5 rounded-full\"></div>\n                      <div class=\"bg-success/80 size-2.5 rounded-full\"></div>\n                    </div>\n                    <div class=\"text-muted-foreground flex items-center gap-1.5 font-mono text-xs\">\n                      <lucide-icon [img]=\"Inbox\" class=\"size-3\" />\n                      <span>UIPKGE Preview · {{ viewport() === 'desktop' ? '600px' : '375px' }}</span>\n                    </div>\n                    <span\n                      ui-badge\n                      variant=\"outline\"\n                      class=\"border-border text-muted-foreground h-4.5 gap-1 px-1.5 text-xs font-normal\"\n                    >\n                      <lucide-icon [img]=\"Lock\" class=\"text-success size-2.5\" />\n                      TLS 1.3\n                    </span>\n                  </div>\n\n                  <div class=\"border-border bg-card/70 space-y-2 border-b p-4 text-xs\">\n                    <div class=\"flex flex-wrap items-center justify-between\">\n                      <div class=\"flex items-center gap-2\">\n                        <div\n                          class=\"bg-primary text-primary-foreground flex size-7 items-center justify-center rounded-full font-bold\"\n                        >\n                          U\n                        </div>\n                        <div>\n                          <div class=\"flex items-center gap-1.5\">\n                            <span class=\"text-foreground font-semibold\">{{ senderName }}</span>\n                            <span class=\"text-muted-foreground\">&lt;{{ senderEmail }}&gt;</span>\n                          </div>\n                          <div class=\"text-muted-foreground text-xs\">To: alex.developer@enterprise.com</div>\n                        </div>\n                      </div>\n                      <span class=\"text-muted-foreground text-xs\">Aug 21, 2026</span>\n                    </div>\n\n                    <div class=\"space-y-0.5 pt-1\">\n                      <div class=\"text-foreground text-sm font-semibold tracking-tight\">\n                        {{ currentActiveSubject() }}\n                      </div>\n                      <div class=\"text-muted-foreground line-clamp-1 text-xs\">{{ previewText() }}</div>\n                    </div>\n                  </div>\n\n                  <div class=\"bg-card space-y-5 p-5 sm:p-7\">\n                    <div class=\"border-border flex flex-wrap items-center justify-between border-b pb-3.5\">\n                      <div class=\"flex items-center gap-2\">\n                        <div\n                          class=\"bg-primary text-primary-foreground flex size-6 items-center justify-center rounded-md\"\n                        >\n                          <lucide-icon [img]=\"Zap\" class=\"size-3.5 fill-current\" />\n                        </div>\n                        <span class=\"text-foreground text-sm font-bold tracking-tight\">UIPKGE</span>\n                      </div>\n                      <span ui-badge variant=\"secondary\" class=\"text-xs font-medium\">Changelog #24 · Release 2.0</span>\n                    </div>\n\n                    <div class=\"space-y-2.5\">\n                      <span\n                        ui-badge\n                        variant=\"outline\"\n                        class=\"text-primary border-primary/30 text-xs font-semibold tracking-wider uppercase\"\n                      >\n                        Major Product Release\n                      </span>\n                      <h3 class=\"text-foreground text-xl leading-tight font-bold tracking-tight sm:text-2xl\">\n                        Ship polished UIs in minutes\n                      </h3>\n                      <p class=\"text-muted-foreground text-xs leading-relaxed sm:text-sm\">\n                        We completely rebuilt the registry engine. 370+ production components with zero npm\n                        dependencies, 100% code ownership, and full native support for Vue 3 and React with modern OKLCH\n                        tokens.\n                      </p>\n                    </div>\n\n                    <div class=\"border-border bg-muted/40 overflow-hidden rounded-lg border\">\n                      <div\n                        class=\"border-border bg-muted/60 flex flex-wrap items-center justify-between border-b px-3.5 py-2\"\n                      >\n                        <div class=\"text-muted-foreground flex items-center gap-1.5 font-mono text-xs\">\n                          <lucide-icon [img]=\"Terminal\" class=\"text-primary size-3\" />\n                          <span>components/ui/button.tsx</span>\n                        </div>\n                        <span class=\"text-success font-mono text-xs font-medium\">TypeScript</span>\n                      </div>\n                      <div class=\"space-y-3 p-3.5\">\n                        <div\n                          class=\"border-border bg-background text-muted-foreground rounded-md border p-2.5 font-mono text-xs\"\n                        >\n                          <span class=\"text-primary font-semibold\">$</span> npx shadcn add @uipkge/button\n                        </div>\n\n                        <div\n                          class=\"bg-card border-border flex flex-wrap items-center justify-center gap-2 rounded-md border p-3\"\n                        >\n                          <button ui-button size=\"xs\" variant=\"default\">Primary</button>\n                          <button ui-button size=\"xs\" variant=\"secondary\">Secondary</button>\n                          <button ui-button size=\"xs\" variant=\"outline\">Outline</button>\n                          <button ui-button size=\"xs\" variant=\"destructive\">Destructive</button>\n                        </div>\n\n                        <div class=\"flex flex-wrap items-center justify-center gap-1.5 pt-1\">\n                          <span ui-badge variant=\"secondary\" class=\"text-xs font-normal\">⚡ Zero npm dependencies</span>\n                          <span ui-badge variant=\"secondary\" class=\"text-xs font-normal\">🎨 OKLCH Dark Mode</span>\n                          <span ui-badge variant=\"secondary\" class=\"text-xs font-normal\">🧩 Vue 3 + React Parity</span>\n                        </div>\n                      </div>\n                    </div>\n\n                    <div class=\"flex flex-col items-center justify-center space-y-2 pt-1 text-center\">\n                      <button ui-button size=\"lg\" class=\"w-full px-8 font-semibold shadow-xs sm:w-auto\">\n                        <span>Explore Components</span>\n                        <lucide-icon [img]=\"ArrowRight\" class=\"ml-1 size-4\" />\n                      </button>\n                      <p class=\"text-muted-foreground text-xs\">\n                        Free & Open Source · MIT License · 370+ Primitives & Blocks\n                      </p>\n                    </div>\n\n                    <div ui-separator></div>\n\n                    <div class=\"text-muted-foreground space-y-2.5 pt-1 text-center text-xs\">\n                      <div class=\"flex flex-wrap items-center justify-center gap-3 font-medium\">\n                        <span class=\"hover:text-foreground cursor-pointer transition-colors\">Documentation</span>\n                        <span>·</span>\n                        <span class=\"hover:text-foreground cursor-pointer transition-colors\">GitHub</span>\n                        <span>·</span>\n                        <span class=\"hover:text-foreground cursor-pointer transition-colors\">Discord</span>\n                        <span>·</span>\n                        <span class=\"hover:text-foreground cursor-pointer transition-colors\">Preferences</span>\n                      </div>\n                      <p class=\"text-xs\">UIPKGE Inc. · 548 Market St, Suite 29314, San Francisco, CA 94104</p>\n                      <p class=\"text-xs\">\n                        You received this email because you subscribed to UIPKGE updates.\n                        <span class=\"hover:text-foreground cursor-pointer underline\">\n                          Unsubscribe anytime (RFC 8058)</span\n                        >.\n                      </p>\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </div>\n\n          <!-- Deliverability & Inbox Placement Card -->\n          <div ui-card class=\"border-border bg-card shadow-xs\">\n            <div ui-card-header class=\"pb-3\">\n              <div class=\"flex flex-wrap items-center justify-between\">\n                <div class=\"flex items-center gap-2\">\n                  <div class=\"bg-success/10 text-success flex size-7 items-center justify-center rounded-md\">\n                    <lucide-icon [img]=\"ShieldCheck\" class=\"size-4\" />\n                  </div>\n                  <h3 ui-card-title class=\"text-sm font-semibold tracking-tight\">\n                    Deliverability & Inbox Placement Scorecard\n                  </h3>\n                </div>\n                <span ui-badge variant=\"outline\" class=\"border-success/30 text-success h-5 px-2 text-xs\">\n                  99.8% Inbox Probability\n                </span>\n              </div>\n              <p ui-card-description class=\"text-xs\">\n                Heuristic spam risk evaluation, DNS authentication compliance, and subscriber engagement telemetry.\n              </p>\n            </div>\n\n            <div ui-card-content class=\"space-y-4 pt-0\">\n              <div class=\"grid grid-cols-1 gap-3 sm:grid-cols-3\">\n                <div class=\"border-border bg-muted/30 rounded-lg border p-3\">\n                  <div class=\"flex flex-wrap items-center justify-between text-xs\">\n                    <span class=\"text-muted-foreground\">Spam Score</span>\n                    <span ui-badge variant=\"success\" class=\"h-4.5 px-1 text-xs\">Optimal</span>\n                  </div>\n                  <div class=\"mt-1 flex items-baseline gap-1\">\n                    <span class=\"text-success text-xl font-bold tracking-tight\">0.2</span>\n                    <span class=\"text-muted-foreground text-xs\">/ 10.0</span>\n                  </div>\n                  <div class=\"bg-muted mt-2 h-1.5 w-full overflow-hidden rounded-full\">\n                    <div class=\"bg-success h-full w-[98%] rounded-full\"></div>\n                  </div>\n                </div>\n\n                <div class=\"border-border bg-muted/30 rounded-lg border p-3\">\n                  <div class=\"flex flex-wrap items-center justify-between text-xs\">\n                    <span class=\"text-muted-foreground\">Auth Headers</span>\n                    <span ui-badge variant=\"success\" class=\"h-4.5 px-1 text-xs\">100% Pass</span>\n                  </div>\n                  <div class=\"mt-1 space-y-0.5 text-xs\">\n                    <div class=\"flex justify-between\">\n                      <span class=\"text-muted-foreground\">SPF / DKIM</span>\n                      <span class=\"text-foreground font-medium\">Valid (2048-bit)</span>\n                    </div>\n                    <div class=\"flex justify-between\">\n                      <span class=\"text-muted-foreground\">DMARC</span>\n                      <span class=\"text-foreground font-medium\">p=reject</span>\n                    </div>\n                  </div>\n                </div>\n\n                <div class=\"border-border bg-muted/30 rounded-lg border p-3\">\n                  <div class=\"flex flex-wrap items-center justify-between text-xs\">\n                    <span class=\"text-muted-foreground\">Reading Time</span>\n                    <span class=\"text-foreground font-mono font-medium\">185 words</span>\n                  </div>\n                  <div class=\"mt-1 flex items-baseline gap-1\">\n                    <span class=\"text-foreground text-xl font-bold tracking-tight\">45</span>\n                    <span class=\"text-muted-foreground text-xs\">seconds</span>\n                  </div>\n                  <div class=\"text-muted-foreground mt-1 text-xs\">Payload size: 14.2 KB (Safe)</div>\n                </div>\n              </div>\n\n              <div class=\"grid grid-cols-1 gap-2 text-xs sm:grid-cols-2\">\n                <div\n                  class=\"border-border/80 bg-muted/20 flex flex-wrap items-center justify-between rounded-md border px-3 py-2\"\n                >\n                  <span class=\"text-muted-foreground flex items-center gap-1.5\">\n                    <lucide-icon [img]=\"Check\" class=\"text-success size-3.5\" />\n                    Primary Tab Placement\n                  </span>\n                  <span class=\"text-foreground font-medium\">99.8% (Gmail / Apple)</span>\n                </div>\n                <div\n                  class=\"border-border/80 bg-muted/20 flex flex-wrap items-center justify-between rounded-md border px-3 py-2\"\n                >\n                  <span class=\"text-muted-foreground flex items-center gap-1.5\">\n                    <lucide-icon [img]=\"Check\" class=\"text-success size-3.5\" />\n                    RFC 8058 One-Click\n                  </span>\n                  <span class=\"text-foreground font-medium\">Compliant</span>\n                </div>\n                <div\n                  class=\"border-border/80 bg-muted/20 flex flex-wrap items-center justify-between rounded-md border px-3 py-2\"\n                >\n                  <span class=\"text-muted-foreground flex items-center gap-1.5\">\n                    <lucide-icon [img]=\"Check\" class=\"text-success size-3.5\" />\n                    Dark Mode Contrast\n                  </span>\n                  <span class=\"text-foreground font-medium\">100% WCAG AAA</span>\n                </div>\n                <div\n                  class=\"border-border/80 bg-muted/20 flex flex-wrap items-center justify-between rounded-md border px-3 py-2\"\n                >\n                  <span class=\"text-muted-foreground flex items-center gap-1.5\">\n                    <lucide-icon [img]=\"Check\" class=\"text-success size-3.5\" />\n                    HTTPS Asset Links\n                  </span>\n                  <span class=\"text-foreground font-medium\">6 Valid Links</span>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n\n      <!-- Send Test Proof Dialog -->\n      <ui-dialog [open]=\"isTestModalOpen()\" (openChange)=\"isTestModalOpen.set($event)\">\n        <ui-dialog-content class=\"sm:max-w-md\">\n          <div ui-dialog-header>\n            <h2 ui-dialog-title class=\"flex items-center gap-2 text-base\">\n              <lucide-icon [img]=\"Mail\" class=\"text-primary size-4\" />\n              Dispatch Test Proof\n            </h2>\n            <p ui-dialog-description class=\"text-xs\">\n              Send a full fidelity rendering test to inspect subject line, preheader, and layout across email clients.\n            </p>\n          </div>\n\n          <div class=\"space-y-4 py-2\">\n            <div class=\"space-y-1.5\">\n              <label class=\"text-muted-foreground text-xs font-medium\">Proof Recipient Address</label>\n              <ui-input\n                [value]=\"testTargetEmail()\"\n                (valueChange)=\"testTargetEmail.set($event)\"\n                type=\"email\"\n                placeholder=\"alex.developer@company.com\"\n                class=\"text-xs\"\n                [disabled]=\"isSendingTest()\"\n              />\n            </div>\n\n            <div class=\"space-y-1.5\">\n              <label class=\"text-muted-foreground text-xs font-medium\">Email Client Engine Simulation</label>\n              <div class=\"grid grid-cols-2 gap-2\">\n                <button\n                  type=\"button\"\n                  ui-button\n                  size=\"xs\"\n                  [variant]=\"selectedClient() === 'all' ? 'default' : 'outline'\"\n                  class=\"justify-start text-xs font-medium\"\n                  (click)=\"selectedClient.set('all')\"\n                >\n                  🌐 All Clients (Auto)\n                </button>\n                <button\n                  type=\"button\"\n                  ui-button\n                  size=\"xs\"\n                  [variant]=\"selectedClient() === 'gmail' ? 'default' : 'outline'\"\n                  class=\"justify-start text-xs font-medium\"\n                  (click)=\"selectedClient.set('gmail')\"\n                >\n                  ✉️ Gmail (Web/App)\n                </button>\n                <button\n                  type=\"button\"\n                  ui-button\n                  size=\"xs\"\n                  [variant]=\"selectedClient() === 'apple' ? 'default' : 'outline'\"\n                  class=\"justify-start text-xs font-medium\"\n                  (click)=\"selectedClient.set('apple')\"\n                >\n                  🍏 Apple Mail (iOS)\n                </button>\n                <button\n                  type=\"button\"\n                  ui-button\n                  size=\"xs\"\n                  [variant]=\"selectedClient() === 'outlook' ? 'default' : 'outline'\"\n                  class=\"justify-start text-xs font-medium\"\n                  (click)=\"selectedClient.set('outlook')\"\n                >\n                  💼 Outlook 365\n                </button>\n              </div>\n            </div>\n\n            @if (testSentSuccess()) {\n              <div\n                class=\"border-success/30 bg-success/10 text-success flex items-center gap-2 rounded-md border p-2.5 text-xs font-medium\"\n              >\n                <lucide-icon [img]=\"CheckCircle2\" class=\"size-4 shrink-0\" />\n                <span>Test proof dispatched to {{ testTargetEmail() }}!</span>\n              </div>\n            }\n          </div>\n\n          <div ui-dialog-footer class=\"gap-2 sm:gap-0\">\n            <button\n              ui-button\n              variant=\"outline\"\n              size=\"sm\"\n              [disabled]=\"isSendingTest()\"\n              (click)=\"isTestModalOpen.set(false)\"\n            >\n              Cancel\n            </button>\n            <button ui-button size=\"sm\" class=\"gap-1.5\" [disabled]=\"isSendingTest()\" (click)=\"handleSendTest()\">\n              <lucide-icon [img]=\"Send\" class=\"size-3.5\" />\n              <span>{{ isSendingTest() ? 'Dispatching...' : 'Send Test Proof' }}</span>\n            </button>\n          </div>\n        </ui-dialog-content>\n      </ui-dialog>\n\n      <!-- Schedule Broadcast Dialog -->\n      <ui-dialog [open]=\"isScheduleModalOpen()\" (openChange)=\"isScheduleModalOpen.set($event)\">\n        <ui-dialog-content class=\"sm:max-w-md\">\n          <div ui-dialog-header>\n            <h2 ui-dialog-title class=\"flex items-center gap-2 text-base\">\n              <lucide-icon [img]=\"Calendar\" class=\"text-primary size-4\" />\n              Schedule Email Broadcast\n            </h2>\n            <p ui-dialog-description class=\"text-xs\">\n              Queue this broadcast for {{ currentAudience().count.toLocaleString() }} verified subscribers with\n              deliverability rate limit guardrails.\n            </p>\n          </div>\n\n          <div class=\"space-y-4 py-2\">\n            <div class=\"border-border bg-muted/40 space-y-2 rounded-lg border p-3 text-xs\">\n              <div class=\"flex flex-wrap items-center justify-between\">\n                <span class=\"text-muted-foreground\">Audience Target</span>\n                <span class=\"text-foreground font-medium\">{{ currentAudience().label }}</span>\n              </div>\n              <div class=\"flex flex-wrap items-center justify-between\">\n                <span class=\"text-muted-foreground\">Estimated Reach</span>\n                <span class=\"text-foreground font-semibold\"\n                  >{{ currentAudience().count.toLocaleString() }} recipients</span\n                >\n              </div>\n              <div class=\"flex flex-wrap items-center justify-between\">\n                <span class=\"text-muted-foreground\">Spam Safety Score</span>\n                <span ui-badge variant=\"success\" class=\"h-4.5 px-1.5 text-xs font-normal\">0.2 / 10.0 (Safe)</span>\n              </div>\n            </div>\n\n            <div class=\"space-y-2\">\n              <label class=\"text-muted-foreground text-xs font-medium\">Broadcast Timing</label>\n              <div class=\"grid grid-cols-1 gap-2\">\n                <button type=\"button\" [class]=\"timingCardClass('optimal')\" (click)=\"scheduleTiming.set('optimal')\">\n                  <div class=\"space-y-0.5\">\n                    <div class=\"text-foreground font-medium\">✨ AI Optimal Send Time (Recommended)</div>\n                    <div class=\"text-muted-foreground text-xs\">\n                      Tuesday, Aug 25 @ 9:00 AM EDT (+18% projected opens)\n                    </div>\n                  </div>\n                  <div [class]=\"timingRadioClass('optimal')\">\n                    @if (scheduleTiming() === 'optimal') {\n                      <div class=\"size-1.5 rounded-full bg-white\"></div>\n                    }\n                  </div>\n                </button>\n\n                <button type=\"button\" [class]=\"timingCardClass('immediate')\" (click)=\"scheduleTiming.set('immediate')\">\n                  <div class=\"space-y-0.5\">\n                    <div class=\"text-foreground font-medium\">⚡ Send Immediately</div>\n                    <div class=\"text-muted-foreground text-xs\">\n                      Dispatch immediately with warm-up concurrency pacing\n                    </div>\n                  </div>\n                  <div [class]=\"timingRadioClass('immediate')\">\n                    @if (scheduleTiming() === 'immediate') {\n                      <div class=\"size-1.5 rounded-full bg-white\"></div>\n                    }\n                  </div>\n                </button>\n              </div>\n            </div>\n\n            @if (scheduleSuccess()) {\n              <div\n                class=\"border-success/30 bg-success/10 text-success flex items-center gap-2 rounded-md border p-2.5 text-xs font-medium\"\n              >\n                <lucide-icon [img]=\"CheckCircle2\" class=\"size-4 shrink-0\" />\n                <span>Broadcast successfully queued for dispatch!</span>\n              </div>\n            }\n          </div>\n\n          <div ui-dialog-footer class=\"gap-2 sm:gap-0\">\n            <button\n              ui-button\n              variant=\"outline\"\n              size=\"sm\"\n              [disabled]=\"isScheduling()\"\n              (click)=\"isScheduleModalOpen.set(false)\"\n            >\n              Cancel\n            </button>\n            <button ui-button size=\"sm\" class=\"gap-1.5\" [disabled]=\"isScheduling()\" (click)=\"handleScheduleBroadcast()\">\n              <lucide-icon [img]=\"Send\" class=\"size-3.5\" />\n              <span>{{ isScheduling() ? 'Scheduling...' : 'Confirm & Schedule' }}</span>\n            </button>\n          </div>\n        </ui-dialog-content>\n      </ui-dialog>\n    </div>\n  `,\n})\nexport class UiEmailCampaignComposerComponent {\n  protected readonly ArrowRight = ArrowRight\n  protected readonly Calendar = Calendar\n  protected readonly Check = Check\n  protected readonly CheckCircle2 = CheckCircle2\n  protected readonly Eye = Eye\n  protected readonly Flame = Flame\n  protected readonly Inbox = Inbox\n  protected readonly Lock = Lock\n  protected readonly Mail = Mail\n  protected readonly Monitor = Monitor\n  protected readonly Send = Send\n  protected readonly ShieldCheck = ShieldCheck\n  protected readonly Smartphone = Smartphone\n  protected readonly Sparkles = Sparkles\n  protected readonly Split = Split\n  protected readonly Terminal = Terminal\n  protected readonly UserCheck = UserCheck\n  protected readonly Users = Users\n  protected readonly Zap = Zap\n\n  protected readonly audienceOptions = AUDIENCE_OPTIONS\n  protected readonly aiSuggestions = AI_SUGGESTIONS\n  protected readonly campaignName = 'Product Launch: UIPKGE 2.0 Global Release'\n  protected readonly senderName = 'UIPKGE Team'\n  protected readonly senderEmail = 'updates@uipkge.dev'\n\n  @Input('class') className?: string\n\n  readonly selectedAudience = signal('active-devs')\n  readonly subjectA = signal('🚀 Introducing UIPKGE 2.0: The unbundled UI registry')\n  readonly subjectB = signal('Ship polished UIs 10x faster with UIPKGE 2.0 ⚡')\n  readonly previewText = signal('370+ production components with zero npm dependencies. Native Vue 3 & React code.')\n  readonly isAbTestEnabled = signal(false)\n  readonly activePreviewVariant = signal<'A' | 'B'>('A')\n  readonly viewport = signal<CampaignViewport>('desktop')\n\n  readonly isTestModalOpen = signal(false)\n  readonly testTargetEmail = signal('alex.developer@company.com')\n  readonly selectedClient = signal<CampaignClient>('all')\n  readonly isSendingTest = signal(false)\n  readonly testSentSuccess = signal(false)\n\n  readonly isScheduleModalOpen = signal(false)\n  readonly scheduleTiming = signal<ScheduleTiming>('optimal')\n  readonly isScheduling = signal(false)\n  readonly scheduleSuccess = signal(false)\n\n  private timers: ReturnType<typeof setTimeout>[] = []\n\n  constructor() {\n    inject(DestroyRef).onDestroy(() => this.timers.forEach((t) => clearTimeout(t)))\n  }\n\n  readonly currentAudience = computed(\n    () => AUDIENCE_OPTIONS.find((item) => item.id === this.selectedAudience()) ?? AUDIENCE_OPTIONS[0]!,\n  )\n\n  readonly currentActiveSubject = computed(() => {\n    if (this.isAbTestEnabled() && this.activePreviewVariant() === 'B') return this.subjectB()\n    return this.subjectA()\n  })\n\n  readonly emojiCount = computed(() => {\n    const matches = this.currentActiveSubject().match(/\\p{Extended_Pictographic}/gu)\n    return matches ? matches.length : 0\n  })\n\n  get rootClass(): string {\n    return cn('w-full space-y-6', this.className)\n  }\n\n  get previewCanvasClass(): string {\n    return cn(\n      'w-full transition-[max-width] duration-300 ease-in-out',\n      this.viewport() === 'desktop' ? 'max-w-[580px]' : 'max-w-[360px]',\n    )\n  }\n\n  timingCardClass(kind: ScheduleTiming): string {\n    return cn(\n      'border-border hover:border-primary/50 focus-visible:ring-ring flex flex-wrap items-center justify-between rounded-lg border p-3 text-left text-xs transition-colors outline-none focus-visible:ring-2',\n      this.scheduleTiming() === kind ? 'border-primary bg-primary/5' : 'bg-card',\n    )\n  }\n\n  timingRadioClass(kind: ScheduleTiming): string {\n    return cn(\n      'flex size-4 items-center justify-center rounded-full border',\n      this.scheduleTiming() === kind ? 'border-primary bg-primary text-primary-foreground' : 'border-border',\n    )\n  }\n\n  applyAiSubject(text: string): void {\n    if (this.isAbTestEnabled() && this.activePreviewVariant() === 'B') this.subjectB.set(text)\n    else this.subjectA.set(text)\n  }\n\n  handleSendTest(): void {\n    if (!this.testTargetEmail()) return\n    this.isSendingTest.set(true)\n    this.testSentSuccess.set(false)\n    this.timers.push(\n      setTimeout(() => {\n        this.isSendingTest.set(false)\n        this.testSentSuccess.set(true)\n        this.timers.push(\n          setTimeout(() => {\n            this.testSentSuccess.set(false)\n            this.isTestModalOpen.set(false)\n          }, 1800),\n        )\n      }, 800),\n    )\n  }\n\n  handleScheduleBroadcast(): void {\n    this.isScheduling.set(true)\n    this.scheduleSuccess.set(false)\n    this.timers.push(\n      setTimeout(() => {\n        this.isScheduling.set(false)\n        this.scheduleSuccess.set(true)\n        this.timers.push(\n          setTimeout(() => {\n            this.scheduleSuccess.set(false)\n            this.isScheduleModalOpen.set(false)\n          }, 1800),\n        )\n      }, 900),\n    )\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/email-campaign-composer/email-campaign-composer.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/email-campaign-composer/index.ts",
      "content": "export {\n  UiEmailCampaignComposerComponent,\n  type CampaignClient,\n  type CampaignViewport,\n  type ScheduleTiming,\n} from './email-campaign-composer.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/email-campaign-composer/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/angular/badge.json",
    "https://uipkge.dev/r/angular/button.json",
    "https://uipkge.dev/r/angular/card.json",
    "https://uipkge.dev/r/angular/dialog.json",
    "https://uipkge.dev/r/angular/input.json",
    "https://uipkge.dev/r/angular/select.json",
    "https://uipkge.dev/r/angular/separator.json",
    "https://uipkge.dev/r/angular/switch.json"
  ],
  "description": "High-craft marketing email broadcast designer, audience segment selector, AI subject line optimizer, A/B testing split, live multi-device newsletter preview, and deliverability scorecard.",
  "categories": [
    "marketing",
    "app",
    "dashboard"
  ]
}