/* ═══════════════════════════════════════════════════════════════════
   MigWizard.jsx — guided new-migration flow (Source → Destination →
   Verify → Run). v1.0.0 — ported from the Claude Design v2 package
   (_CLAUDE-DESIGN/_2026-06-12-v2-SaaS-Redesign/migrations-wizard.jsx)
   — port, not redesign. Reuses WizardShell + ModeSelectorGroup +
   WToggle + NoticeCard (bare globals from the Wizard foundation).
   Surfaces the OBJECT-SAFETY ceremony in UI form: impact preview,
   redirect detection, dry-run, pre-commit backup gate, tiered confirm
   (type-the-domain + acknowledge). NO WRITE PATH EXISTS in this
   increment — every action resolves to a toast on sample data; the
   full RESTRUCTURE ceremony + site-portability declarations are
   REQUIRED before the real migrations API ships (HANDOFF-V2 §3).
   Bare-global design refs (CONNECT_METHODS, SOURCE_STACK, PREFLIGHT,
   ACTIVE, HostBreadcrumb, PreflightRow, Seg) rewritten to the app
   namespaces — the only port delta.
   Load order: FOURTH of the five Mig modules.
   Registers: window.WPSB.MigWizard = { NewMigrationWizard }.
   ═══════════════════════════════════════════════════════════════════ */
(function () {
const { useState: useStateMw } = React;
const tx = (k, v, f) => (window.WPSB && window.WPSB.t) ? window.WPSB.t(k, v, f) : (f != null ? f : k);
const { HostBreadcrumb, PreflightRow } = window.WPSB.MigCharts;
const { ACTIVE, CONNECT_METHODS, SOURCE_STACK, PREFLIGHT } = window.WPSB.MigData;
const Seg = window.WPSB.SeoTracker.Seg;

/* small labeled field shell (visual) */
function Field({ label, children, hint }) {
  return React.createElement('label', { style: { display: 'flex', flexDirection: 'column', gap: 6 } },
    React.createElement('span', { style: { fontWeight: 'var(--fw-label)', fontSize: '.8rem', color: 'var(--text)' } }, label),
    children,
    hint && React.createElement('span', { style: { fontSize: '.74rem', color: 'var(--muted)' } }, hint));
}
const INPUT_STYLE = { width: '100%', padding: '9px 12px', borderRadius: 'var(--r-sm)', border: '1px solid var(--border-2)',
  background: 'var(--surface)', color: 'var(--text)', font: 'inherit', fontSize: '.86rem' };

function StepHead({ icon, title, body }) {
  return React.createElement('div', { style: { display: 'flex', gap: 'var(--sp-4)', marginBottom: 'var(--sp-5)' } },
    React.createElement('span', { style: { width: 40, height: 40, borderRadius: 'var(--r)', flex: 'none', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--beam-dim)', color: 'var(--beam)', border: '1px solid color-mix(in oklch, var(--beam) 26%, transparent)' } },
      React.createElement(WIcon, { name: icon, size: 21 })),
    React.createElement('div', null,
      React.createElement('h2', { style: { margin: 0, fontWeight: 'var(--fw-label)', fontSize: '1.05rem', color: 'var(--text)' } }, title),
      React.createElement('p', { style: { margin: '4px 0 0', fontSize: '.86rem', color: 'var(--text-2)', lineHeight: 1.45, maxWidth: 520 } }, body)));
}

/* STEP 1 — Source */
function SourceStep({ method, setMethod }) {
  return React.createElement('div', null,
    React.createElement(StepHead, { icon: 'server', title: tx('page.migration.wizard.source.head_title', null, 'Where are we migrating from?'), body: tx('page.migration.wizard.source.head_body', null, 'Connect the source site. The WPSiteBeam plugin is the fastest, most reliable path when it’s installed.') }),
    React.createElement('div', { className: 'wiz-eyebrow', style: { marginBottom: 'var(--sp-3)' } }, tx('page.migration.wizard.source.connection_method', null, 'Connection method')),
    React.createElement(window.ModeSelectorGroup, { legend: tx('page.migration.wizard.source.connection_method', null, 'Connection method'), options: CONNECT_METHODS, selected: method, onSelect: setMethod }),
    // connected source preview
    React.createElement('div', { className: 'wiz-card', style: { marginTop: 'var(--sp-5)', background: 'var(--surface-2)', border: '1px solid var(--border)', borderRadius: 'var(--r-lg)', padding: 'var(--sp-5)' } },
      React.createElement('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10, flexWrap: 'wrap', marginBottom: 'var(--sp-4)' } },
        React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 10 } },
          React.createElement('span', { style: { width: 30, height: 30, borderRadius: 'var(--r-sm)', flex: 'none', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--surface-3)', color: 'var(--muted)', border: '1px solid var(--border)' } }, React.createElement(WIcon, { name: 'globe', size: 15 })),
          React.createElement('span', { style: { fontFamily: 'var(--font-mono)', fontSize: '.86rem', color: 'var(--text)' } }, 'maplewood.co'),
          React.createElement('span', { style: { fontFamily: 'var(--font-mono)', fontSize: '.6rem', color: 'var(--muted)' } }, '· SiteGround')),
        React.createElement('span', { className: 'wiz-tag wiz-tag-new' }, React.createElement(WIcon, { name: 'check', size: 11, stroke: 3 }), tx('page.migration.wizard.source.connected', null, 'Connected'))),
      React.createElement('div', { style: { display: 'flex', gap: 'var(--sp-5)', flexWrap: 'wrap' } },
        SOURCE_STACK.map((s, i) => React.createElement('div', { key: i, style: { display: 'flex', flexDirection: 'column', gap: 2 } },
          React.createElement('span', { className: 'wiz-eyebrow', style: { fontSize: '.52rem' } }, s.label),
          React.createElement('span', { style: { fontFamily: 'var(--font-mono)', fontSize: '.82rem', color: 'var(--text)', fontWeight: 'var(--fw-mono)' } }, s.value))))));
}

/* STEP 2 — Destination */
const REDIRECT_OPTS = [
  { key: 'theirs', label: tx('page.migration.wizard.redirect.theirs_label', null, 'Write to their redirect plugin'), qualifier: tx('page.migration.wizard.redirect.theirs_qualifier', null, 'detected: Redirection'), detail: tx('page.migration.wizard.redirect.theirs_detail', null, 'We’ll add the migration redirects to the plugin already on the destination.') },
  { key: 'install', label: tx('page.migration.wizard.redirect.install_label', null, 'Install Redirect Manager'), qualifier: tx('page.migration.wizard.redirect.install_qualifier', null, 'recommended'), detail: tx('page.migration.wizard.redirect.install_detail', null, 'Add WPSiteBeam’s redirect manager so you can edit rules from here.') },
  { key: 'courier', label: tx('page.migration.wizard.redirect.courier_label', null, 'Minimal courier fallback'), qualifier: tx('page.migration.wizard.redirect.courier_qualifier', null, 'no plugin'), detail: tx('page.migration.wizard.redirect.courier_detail', null, 'A lightweight must-use redirect file — nothing installed in the admin.') },
];
function DestinationStep({ env, setEnv, redirect, setRedirect }) {
  return React.createElement('div', null,
    React.createElement(StepHead, { icon: 'database', title: tx('page.migration.wizard.dest.head_title', null, 'Where are we migrating to?'), body: tx('page.migration.wizard.dest.head_body', null, 'Pick the destination host and environment. Production targets get the full object-safety ceremony.') }),
    React.createElement('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px,1fr))', gap: 'var(--sp-4)', marginBottom: 'var(--sp-5)' } },
      React.createElement(Field, { label: tx('page.migration.wizard.dest.host_label', null, 'Destination host'), hint: tx('page.migration.wizard.dest.host_hint', null, 'Auto-detected from the destination connection · change if needed') },
        React.createElement('div', { style: { ...INPUT_STYLE, display: 'flex', alignItems: 'center', justifyContent: 'space-between', cursor: 'pointer' } },
          React.createElement('span', { style: { display: 'inline-flex', alignItems: 'center', gap: 8 } }, React.createElement(WIcon, { name: 'server', size: 15, style: { color: 'var(--muted)' } }), 'WP Engine'),
          React.createElement(WIcon, { name: 'chevron-down', size: 15, style: { color: 'var(--muted)' } }))),
      React.createElement(Field, { label: tx('page.migration.wizard.dest.domain_label', null, 'Destination domain') },
        React.createElement('div', { style: { ...INPUT_STYLE, color: 'var(--text)', fontFamily: 'var(--font-mono)' } }, 'maplewood.co'))),
    React.createElement('div', { style: { marginBottom: 'var(--sp-5)' } },
      React.createElement('div', { style: { fontWeight: 'var(--fw-label)', fontSize: '.8rem', color: 'var(--text)', marginBottom: 6 } }, tx('page.migration.wizard.dest.environment', null, 'Environment')),
      React.createElement(Seg, { options: [{ key: 'staging', label: tx('page.migration.wizard.dest.env_staging', null, 'Staging') }, { key: 'production', label: tx('page.migration.wizard.dest.env_production', null, 'Production') }], value: env, onChange: setEnv })),
    // impact preview
    env === 'production'
      ? React.createElement(window.NoticeCard, { accent: 'var(--warn)', icon: 'alert-triangle', title: tx('page.migration.wizard.dest.impact_prod_title', null, 'Production destination — impact preview'),
          body: tx('page.migration.wizard.dest.impact_prod_body', null, 'The existing site and database at maplewood.co (WP Engine) will be backed up, then overwritten. A restore point is created before anything is committed.'), tag: tx('page.migration.wizard.dest.impact_prod_tag', null, 'Destructive') })
      : React.createElement(window.NoticeCard, { accent: 'var(--beam)', icon: 'shield-check', title: tx('page.migration.wizard.dest.impact_staging_title', null, 'Staging destination'),
          body: tx('page.migration.wizard.dest.impact_staging_body', null, 'Changes land on the staging environment only. Nothing on the live site is touched until you promote.'), tag: tx('page.migration.wizard.dest.impact_staging_tag', null, 'Safe') }),
    // redirect-system detection
    React.createElement('div', { style: { marginTop: 'var(--sp-5)' } },
      React.createElement('div', { className: 'wiz-eyebrow', style: { marginBottom: 'var(--sp-3)' } }, tx('page.migration.wizard.dest.redirects_eyebrow', null, 'Redirects · existing system detected')),
      React.createElement(window.ModeSelectorGroup, { legend: tx('page.migration.wizard.dest.redirect_handling', null, 'Redirect handling'), options: REDIRECT_OPTS, selected: redirect, onSelect: setRedirect })));
}

/* STEP 3 — Verify */
function VerifyStep({ dryRun, setDryRun }) {
  const passed = PREFLIGHT.filter(p => p.v === 'pass').length;
  const warns = PREFLIGHT.filter(p => p.v === 'warn').length;
  return React.createElement('div', null,
    React.createElement(StepHead, { icon: 'shield-check', title: tx('page.migration.wizard.verify.head_title', null, 'Verify before we commit'), body: tx('page.migration.wizard.verify.head_body', null, 'Run the pre-flight checks, optionally do a dry run, and confirm the backup gate. Nothing is written to the destination yet.') }),
    // dry-run toggle
    React.createElement('div', { className: 'wiz-card', style: { background: 'var(--surface-2)', border: '1px solid var(--border)', borderRadius: 'var(--r-lg)', padding: 'var(--sp-4) var(--sp-5)', display: 'flex', alignItems: 'center', gap: 'var(--sp-4)', marginBottom: 'var(--sp-5)' } },
      React.createElement('span', { style: { width: 38, height: 38, borderRadius: 'var(--r)', flex: 'none', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--beam-dim)', color: 'var(--beam)' } }, React.createElement(WIcon, { name: 'play', size: 18 })),
      React.createElement('div', { style: { flex: 1, minWidth: 0 } },
        React.createElement('div', { style: { fontWeight: 'var(--fw-label)', fontSize: '.9rem', color: 'var(--text)' } }, tx('page.migration.wizard.verify.dryrun_title', null, 'Run a dry run first')),
        React.createElement('div', { style: { fontSize: '.82rem', color: 'var(--text-2)', marginTop: 2 } }, tx('page.migration.wizard.verify.dryrun_body', null, 'Simulate the full migration end-to-end without committing a single change.'))),
      React.createElement(window.WToggle, { checked: dryRun, onChange: setDryRun, label: tx('page.migration.wizard.verify.dryrun_title', null, 'Run a dry run first') })),
    // preflight checks
    React.createElement('div', { className: 'wiz-card', style: { background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 'var(--r-lg)', padding: 'var(--sp-5)', marginBottom: 'var(--sp-5)' } },
      React.createElement('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10, marginBottom: 'var(--sp-2)' } },
        React.createElement('span', { style: { fontWeight: 'var(--fw-label)', fontSize: '.95rem', color: 'var(--text)' } }, tx('page.migration.wizard.verify.preflight_title', null, 'Pre-flight checks')),
        React.createElement('span', { style: { fontFamily: 'var(--font-mono)', fontSize: '.72rem', color: 'var(--muted)' } }, tx('page.migration.wizard.verify.preflight_summary', { passed: passed, warns: warns }, '{passed} passed · {warns} warnings'))),
      PREFLIGHT.map((p, i) => React.createElement(PreflightRow, { key: i, v: p.v, label: p.label, detail: p.detail }))),
    // backup gate (required)
    React.createElement('div', { className: 'wiz-card', style: { background: 'color-mix(in oklch, var(--green) 8%, var(--surface))', border: '1px solid color-mix(in oklch, var(--green) 32%, transparent)', borderRadius: 'var(--r-lg)', padding: 'var(--sp-5)', display: 'flex', alignItems: 'center', gap: 'var(--sp-4)' } },
      React.createElement('span', { style: { width: 40, height: 40, borderRadius: 'var(--r)', flex: 'none', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'color-mix(in oklch, var(--green) 16%, transparent)', color: 'var(--green)', border: '1px solid color-mix(in oklch, var(--green) 30%, transparent)' } }, React.createElement(WIcon, { name: 'shield-check', size: 21 })),
      React.createElement('div', { style: { flex: 1, minWidth: 0 } },
        React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' } },
          React.createElement('span', { style: { fontWeight: 'var(--fw-label)', fontSize: '.9rem', color: 'var(--text)' } }, tx('page.migration.wizard.verify.backup_title', null, 'Create restore points on both sides before committing')),
          React.createElement('span', { style: { display: 'inline-flex', alignItems: 'center', gap: 5, fontFamily: 'var(--font-mono)', fontSize: '.6rem', letterSpacing: '.06em', textTransform: 'uppercase',
            color: 'var(--green)', background: 'color-mix(in oklch, var(--green) 13%, transparent)', border: '1px solid color-mix(in oklch, var(--green) 32%, transparent)', borderRadius: 999, padding: '3px 8px' } },
            React.createElement(WIcon, { name: 'lock', size: 10 }), tx('page.migration.wizard.verify.backup_required', null, 'Required'))),
        React.createElement('div', { style: { fontSize: '.82rem', color: 'var(--text-2)', marginTop: 3 } }, tx('page.migration.wizard.verify.backup_body', null, 'On for production migrations — this is what makes the rollback dual-sided.'))),
      React.createElement('span', { style: { display: 'inline-flex', alignItems: 'center', gap: 7, flex: 'none', fontFamily: 'var(--font-mono)', fontSize: '.64rem', letterSpacing: '.05em', textTransform: 'uppercase',
        color: 'var(--green)', background: 'color-mix(in oklch, var(--green) 14%, transparent)', border: '1px solid color-mix(in oklch, var(--green) 34%, transparent)', borderRadius: 999, padding: '7px 12px' } },
        React.createElement(WIcon, { name: 'check', size: 13, stroke: 3 }), tx('page.migration.wizard.verify.backup_always_on', null, 'Always on'))),
    // estimate
    React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 'var(--sp-4)', marginTop: 'var(--sp-4)', fontFamily: 'var(--font-mono)', fontSize: '.78rem', color: 'var(--muted)' } },
      React.createElement('span', { style: { display: 'inline-flex', alignItems: 'center', gap: 6 } }, React.createElement(WIcon, { name: 'clock', size: 14 }), tx('page.migration.wizard.verify.est_time', null, 'Est. ~18 min')),
      React.createElement('span', { style: { display: 'inline-flex', alignItems: 'center', gap: 6 } }, React.createElement(WIcon, { name: 'arrow-up-right', size: 14 }), tx('page.migration.wizard.verify.est_transfer', null, '10.5 GB to transfer'))));
}

/* STEP 4 — Run (tiered confirm) */
function RunStep({ confirm, setConfirm, ack, setAck }) {
  const domain = 'maplewood.co';
  const ready = confirm.trim() === domain && ack;
  return React.createElement('div', null,
    React.createElement(StepHead, { icon: 'rocket', title: tx('page.migration.wizard.run.head_title', null, 'Confirm & run'), body: tx('page.migration.wizard.run.head_body', null, 'Final review. Because this targets production, type the destination domain and acknowledge the overwrite to arm the migration.') }),
    // summary
    React.createElement('div', { className: 'wiz-card', style: { background: 'var(--surface-2)', border: '1px solid var(--border)', borderRadius: 'var(--r-lg)', padding: 'var(--sp-5)', marginBottom: 'var(--sp-5)' } },
      React.createElement(HostBreadcrumb, { source: ACTIVE.source, dest: ACTIVE.dest }),
      React.createElement('div', { style: { display: 'flex', gap: 'var(--sp-3)', flexWrap: 'wrap', marginTop: 'var(--sp-4)', paddingTop: 'var(--sp-4)', borderTop: '1px solid var(--border)' } },
        [['shield-check', tx('page.migration.wizard.run.chip_backup', null, 'Dual-side backup')], ['play', tx('page.migration.wizard.run.chip_dryrun', null, 'Dry run enabled')], ['git-branch', tx('page.migration.wizard.run.chip_redirects', null, 'Redirects: write to theirs')]].map((c, i) =>
          React.createElement('span', { key: i, style: { display: 'inline-flex', alignItems: 'center', gap: 6, fontFamily: 'var(--font-mono)', fontSize: '.7rem', color: 'var(--text-2)', background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 999, padding: '5px 11px' } },
            React.createElement(WIcon, { name: c[0], size: 13, style: { color: 'var(--green)' } }), c[1])))),
    // tiered confirm
    React.createElement('div', { style: { marginBottom: 'var(--sp-4)' } },
      React.createElement(Field, { label: tx('page.migration.wizard.run.confirm_label', null, 'Type the destination domain to confirm'), hint: tx('page.migration.wizard.run.confirm_hint', null, 'This guards against accidental production overwrites.') },
        React.createElement('input', { type: 'text', value: confirm, onChange: (e) => setConfirm(e.target.value), placeholder: domain, spellCheck: false, autoComplete: 'off',
          style: { ...INPUT_STYLE, fontFamily: 'var(--font-mono)', borderColor: confirm && confirm.trim() === domain ? 'color-mix(in oklch, var(--green) 55%, transparent)' : 'var(--border-2)' } }))),
    React.createElement('label', { style: { display: 'flex', alignItems: 'flex-start', gap: 10, cursor: 'pointer', marginBottom: 'var(--sp-5)' } },
      React.createElement('input', { type: 'checkbox', checked: ack, onChange: (e) => setAck(e.target.checked), style: { width: 18, height: 18, marginTop: 1, accentColor: 'var(--beam)', flex: 'none' } }),
      React.createElement('span', { style: { fontSize: '.86rem', color: 'var(--text-2)', lineHeight: 1.45 } }, tx('page.migration.wizard.run.ack', null, 'I understand the destination site and database will be overwritten. A restore point is taken first, and rollback stays available on both sides.'))),
    React.createElement(window.NoticeCard, { accent: ready ? 'var(--green)' : 'var(--beam)', icon: ready ? 'shield-check' : 'rotate-ccw',
      title: ready ? tx('page.migration.wizard.run.notice_armed_title', null, 'Armed — rollback is ready') : tx('page.migration.wizard.run.notice_pending_title', null, 'Dual-side rollback will be armed'),
      body: ready ? tx('page.migration.wizard.run.notice_armed_body', null, 'Press “Start migration” below. You can pause, abort, or roll back both sides at any point.') : tx('page.migration.wizard.run.notice_pending_body', null, 'Once confirmed, you can revert both source and destination in one click if anything goes wrong.') }));
}

/* ── the flow ─────────────────────────────────────────────────────── */
function NewMigrationWizard({ stepVariant = 'vertical', onExit, onToast }) {
  const STEPS = [
    { key: 'source', title: tx('page.migration.wizard.step.source_title', null, 'Source'), subtitle: tx('page.migration.wizard.step.source_subtitle', null, 'From') },
    { key: 'dest', title: tx('page.migration.wizard.step.dest_title', null, 'Destination'), subtitle: tx('page.migration.wizard.step.dest_subtitle', null, 'To') },
    { key: 'verify', title: tx('page.migration.wizard.step.verify_title', null, 'Verify'), subtitle: tx('page.migration.wizard.step.verify_subtitle', null, 'Pre-flight') },
    { key: 'run', title: tx('page.migration.wizard.step.run_title', null, 'Run'), subtitle: tx('page.migration.wizard.step.run_subtitle', null, 'Confirm') },
  ];
  const [cur, setCur] = useStateMw(0);
  const [maxReached, setMax] = useStateMw(0);
  const [method, setMethod] = useStateMw('plugin');
  const [env, setEnv] = useStateMw('production');
  const [redirect, setRedirect] = useStateMw('theirs');
  const [dryRun, setDryRun] = useStateMw(true);
  const [confirm, setConfirm] = useStateMw('');
  const [ack, setAck] = useStateMw(false);

  const go = (n) => { const c = Math.max(0, Math.min(STEPS.length - 1, n)); setCur(c); setMax(m => Math.max(m, c)); };
  const ready = confirm.trim() === 'maplewood.co' && ack;
  const launch = () => {
    if (!ready) { onToast({ kind: 'upsell', text: tx('page.migration.wizard.toast.need_confirm', null, 'Type the destination domain and acknowledge the overwrite to continue.') }); return; }
    onToast({ kind: 'success', text: tx('page.migration.wizard.toast.started', null, 'Migration started — maplewood.co → WP Engine. Live log is streaming.') });
    onExit && onExit();
  };

  let body;
  if (cur === 0) body = React.createElement(SourceStep, { method, setMethod });
  else if (cur === 1) body = React.createElement(DestinationStep, { env, setEnv, redirect, setRedirect });
  else if (cur === 2) body = React.createElement(VerifyStep, { dryRun, setDryRun });
  else body = React.createElement(RunStep, { confirm, setConfirm, ack, setAck });

  return React.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: 'var(--sp-4)' } },
    React.createElement('button', { type: 'button', className: 'wiz-btn wiz-btn-ghost wiz-focusable', onClick: onExit,
      style: { alignSelf: 'flex-start', fontSize: '.74rem', padding: '6px 10px' } },
      React.createElement(WIcon, { name: 'chevron-left', size: 15 }), tx('page.migration.wizard.back_to_migrations', null, 'Back to migrations')),
    React.createElement(window.WizardShell, {
      eyebrow: tx('page.migration.wizard.shell.eyebrow', null, 'Migrations · New migration'), title: tx('page.migration.wizard.shell.title', null, 'Migrate a site'), subtitle: tx('page.migration.wizard.shell.subtitle', null, 'Four guided steps with snapshots, a dry run, and dual-side rollback before anything goes live.'),
      steps: STEPS, current: cur, maxReached, stepVariant, onStepClick: go,
      footer: {
        onBack: () => go(cur - 1), onNext: () => go(cur + 1), onFinish: launch,
        canBack: cur > 0, canSkip: false, isLast: cur === STEPS.length - 1,
        nextLabel: cur === 2 ? tx('page.migration.wizard.footer.next_review', null, 'Looks good — review') : tx('page.migration.wizard.footer.next_continue', null, 'Continue'), finishLabel: tx('page.migration.wizard.footer.finish', null, 'Start migration'),
      },
    }, body));
}

window.WPSB = window.WPSB || {};
window.WPSB.MigWizard = { NewMigrationWizard };
console.log('[WPSB] MigWizard v1.0.0 loaded');
})();
