{"id":327,"date":"2026-10-14T08:27:11","date_gmt":"2026-10-14T08:27:11","guid":{"rendered":"https:\/\/ongroundmedia.com\/?page_id=327"},"modified":"2026-10-14T08:28:33","modified_gmt":"2026-10-14T08:28:33","slug":"e-commerce-and-specialized-seo-tools","status":"publish","type":"page","link":"https:\/\/ongroundmedia.com\/?page_id=327","title":{"rendered":"E-commerce and Specialized SEO Tools"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"327\" class=\"elementor elementor-327\">\n\t\t\t\t<div class=\"elementor-element elementor-element-e6158ef e-con e-atomic-element e-flexbox-base e-default-div e-27e7412 \" data-id=\"e6158ef\" data-element_type=\"e-flexbox\" data-e-type=\"e-flexbox\" data-interaction-id=\"e6158ef\">\n    \t\t<div class=\"elementor-element elementor-element-4171757 elementor-widget elementor-widget-html\" data-id=\"4171757\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!doctype html><html><head><meta charset=utf8><meta name=viewport content=\"width=device-width,initial-scale=1,viewport-fit=cover\"><style>:root{color-scheme:light;box-sizing:border-box;padding-top:env(safe-area-inset-top,0px);padding-bottom:env(safe-area-inset-bottom,0px)}html{scroll-padding-top:env(safe-area-inset-top,0px)}body{margin:0;padding:0;font:14px -apple-system,BlinkMacSystemFont,sans-serif;background:#fff;color:#000}img{max-width:100%}[hidden]:not([hidden=until-found i]){display:none!important}<\/style><\/head><body>\r\n<title>Onground Media SEO Toolkit<\/title>\r\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\r\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\r\n<link rel=\"stylesheet\" href=\"https:\/\/fonts.googleapis.com\/css2?family=Bricolage+Grotesque:opsz,wght@12..96,600;12..96,700;12..96,800&family=Figtree:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap\">\r\n<style>\r\n\/* Layout: navy hero band, then a two-pane workbench. Tool rail on the left, the active tool on the right (inputs, then results). *\/\r\n:root{\r\n  --indigo:#4F46E5; --navy:#0F172A; --orange:#FF6B35; --emerald:#10B981;\r\n  --bg:#F8FAFC; --surface:#FFFFFF; --surface-2:#F1F5F9; --text:#1E293B; --muted:#64748B; --border:#E2E8F0;\r\n  --link:#4F46E5; --soft:#EEF2FF; --on-indigo:#FFFFFF; --on-orange:#0F172A;\r\n  --ok:#047857; --ok-bg:#D1FAE5; --warn:#B45309; --warn-bg:#FEF3C7; --bad:#B91C1C; --bad-bg:#FEE2E2;\r\n  --lvl-mid:#D97706; --lvl-adv:#DC2626;\r\n  --hero:#0F172A; --hero-fg:#FFFFFF; --hero-muted:#CBD5E1; --hero-line:rgba(255,255,255,.18);\r\n  --shadow:0 1px 2px rgba(15,23,42,.06),0 6px 20px rgba(15,23,42,.05);\r\n  --f-display:'Bricolage Grotesque','Segoe UI',system-ui,sans-serif;\r\n  --f-body:'Figtree','Segoe UI',system-ui,-apple-system,sans-serif;\r\n  --f-mono:'JetBrains Mono',ui-monospace,'SF Mono',Menlo,Consolas,monospace;\r\n}\r\n@media (prefers-color-scheme: dark){\r\n  :root:not([data-theme=\"light\"]){\r\n    --bg:#0B1120; --surface:#121B31; --surface-2:#18233D; --text:#E2E8F0; --muted:#94A3B8; --border:#26334F;\r\n    --link:#A5B4FC; --soft:#1E2447;\r\n    --ok:#34D399; --ok-bg:#0F2E27; --warn:#FBBF24; --warn-bg:#33270B; --bad:#F87171; --bad-bg:#3A1518;\r\n    --hero:#070D1C; --shadow:0 1px 2px rgba(0,0,0,.3);\r\n    color-scheme:dark;\r\n  }\r\n}\r\n:root[data-theme=\"dark\"]{\r\n  --bg:#0B1120; --surface:#121B31; --surface-2:#18233D; --text:#E2E8F0; --muted:#94A3B8; --border:#26334F;\r\n  --link:#A5B4FC; --soft:#1E2447;\r\n  --ok:#34D399; --ok-bg:#0F2E27; --warn:#FBBF24; --warn-bg:#33270B; --bad:#F87171; --bad-bg:#3A1518;\r\n  --hero:#070D1C; --shadow:0 1px 2px rgba(0,0,0,.3);\r\n  color-scheme:dark;\r\n}\r\n*{box-sizing:border-box}\r\nbody{background:var(--bg);color:var(--text);font-family:var(--f-body);font-size:15px;line-height:1.55;-webkit-text-size-adjust:100%}\r\na{color:var(--link)}\r\nbutton,input,select,textarea{font:inherit;color:inherit}\r\n:focus-visible{outline:2px solid var(--orange);outline-offset:2px}\r\n.wrap{max-width:1280px;margin-inline:auto;padding-inline:16px}\r\n\r\n\/* header *\/\r\n.top{background:var(--surface);border-bottom:1px solid var(--border);position:sticky;top:env(safe-area-inset-top,0px);z-index:30}\r\n.top-in{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-block:10px}\r\n.brand{display:flex;align-items:center;gap:12px;text-decoration:none;color:var(--text);min-width:0}\r\n.logo-tile{width:46px;height:46px;border-radius:12px;background:#fff;border:1px solid var(--border);display:grid;place-items:center;flex:none}\r\n.logo-tile img{width:34px;height:34px;display:block}\r\n.brand-text{display:grid;line-height:1.15;min-width:0}\r\n.brand-text b{font-family:var(--f-display);font-size:1.15rem;font-weight:700;letter-spacing:-.01em}\r\n.brand-text small{color:var(--muted);font-size:.78rem;letter-spacing:.08em;text-transform:uppercase;font-weight:600}\r\n.icon-btn{display:inline-flex;align-items:center;gap:8px;border:1px solid var(--border);background:var(--surface);border-radius:10px;padding:8px 12px;cursor:pointer;font-weight:600;font-size:.88rem}\r\n.icon-btn:hover{background:var(--surface-2)}\r\n.icon-btn svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}\r\n\r\n\/* hero *\/\r\n.hero{background:var(--hero);color:var(--hero-fg)}\r\n.hero-in{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:32px;align-items:center;padding-block:36px 40px}\r\n.eyebrow{margin:0 0 10px;color:var(--orange);font-weight:700;font-size:.8rem;letter-spacing:.12em;text-transform:uppercase}\r\n.hero h1{margin:0 0 12px;font-family:var(--f-display);font-weight:700;font-size:clamp(1.8rem,1rem + 3vw,3rem);line-height:1.08;letter-spacing:-.025em;text-wrap:balance;max-width:20ch}\r\n.lead{margin:0 0 20px;color:var(--hero-muted);max-width:60ch;font-size:1.02rem}\r\n.search{position:relative;max-width:520px}\r\n.search svg{position:absolute;left:14px;top:50%;translate:0 -50%;width:18px;height:18px;fill:none;stroke:var(--hero-muted);stroke-width:2;stroke-linecap:round}\r\n.search input{width:100%;background:rgba(255,255,255,.08);border:1px solid var(--hero-line);border-radius:12px;padding:13px 14px 13px 42px;color:var(--hero-fg);font-size:1rem}\r\n.search input::placeholder{color:#94A3B8}\r\n.search input:focus-visible{outline-color:var(--orange)}\r\n.chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}\r\n.chip{border:1px solid var(--hero-line);background:transparent;color:var(--hero-fg);border-radius:999px;padding:6px 14px;font-size:.86rem;font-weight:600;cursor:pointer}\r\n.chip:hover{background:rgba(255,255,255,.1)}\r\n.chip[aria-pressed=\"true\"]{background:var(--orange);border-color:var(--orange);color:var(--on-orange)}\r\n.hero-art{width:min(300px,28vw);height:auto}\r\n\r\n\/* shell *\/\r\n.shell{display:grid;grid-template-columns:300px minmax(0,1fr);gap:24px;padding-block:24px 56px;align-items:start}\r\n.rail{position:sticky;top:calc(env(safe-area-inset-top,0px) + 76px);max-height:calc(100vh - 96px);overflow:auto;min-width:0}\r\n.rail-group{margin-bottom:18px}\r\n.rail-label{margin:0 0 6px;padding-inline:10px;font-size:.72rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}\r\n.rail-items{display:grid;gap:4px}\r\n.rail-item{display:grid;grid-template-columns:36px minmax(0,1fr) auto;gap:10px;align-items:center;padding:8px 10px;border-radius:12px;text-decoration:none;color:var(--text);border:1px solid transparent}\r\n.rail-item:hover{background:var(--surface-2)}\r\n.rail-item[aria-current=\"page\"]{background:var(--soft);border-color:var(--border)}\r\n.ico{width:36px;height:36px;border-radius:10px;display:grid;place-items:center;background:var(--surface-2);color:var(--link)}\r\n.rail-item[aria-current=\"page\"] .ico{background:var(--indigo);color:#fff}\r\n.ico svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}\r\n.rail-name{display:grid;min-width:0;line-height:1.25}\r\n.rail-name b{font-weight:650;font-size:.92rem}\r\n.rail-name span{color:var(--muted);font-size:.8rem}\r\n.dot{width:9px;height:9px;border-radius:50%;background:var(--lvl-mid)}\r\n.dot.adv{background:var(--lvl-adv)}\r\n.legend{margin:6px 0 0;padding:12px;border:1px dashed var(--border);border-radius:12px;color:var(--muted);font-size:.82rem;display:grid;gap:6px}\r\n.legend div{display:flex;gap:8px;align-items:center}\r\n.no-match{padding:12px 10px;color:var(--muted);font-size:.9rem}\r\n\r\n\/* stage *\/\r\n.stage{min-width:0}\r\n.stage-head{display:flex;gap:14px;align-items:flex-start;margin-bottom:18px}\r\n.stage-head .ico{width:48px;height:48px;border-radius:14px;background:var(--indigo);color:#fff;flex:none}\r\n.stage-head .ico svg{width:26px;height:26px}\r\n.stage-head h2{margin:0;font-family:var(--f-display);font-size:clamp(1.4rem,1rem + 1.6vw,2rem);letter-spacing:-.02em;line-height:1.15;display:flex;flex-wrap:wrap;gap:8px 12px;align-items:center}\r\n.stage-head p{margin:4px 0 0;color:var(--muted);max-width:70ch}\r\n.pill{display:inline-flex;align-items:center;gap:6px;font-family:var(--f-body);font-size:.74rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;border-radius:999px;padding:3px 10px;border:1px solid var(--border);color:var(--muted);background:var(--surface)}\r\n.pill i{width:8px;height:8px;border-radius:50%;background:var(--lvl-mid)}\r\n.pill.adv i{background:var(--lvl-adv)}\r\n.split{display:grid;gap:20px;align-items:start}\r\n@media (min-width:1180px){.split{grid-template-columns:minmax(0,5fr) minmax(0,7fr)}.split.stack{grid-template-columns:minmax(0,1fr)}}\r\n.panel{background:var(--surface);border:1px solid var(--border);border-radius:16px;padding:20px;box-shadow:var(--shadow);min-width:0}\r\n.sample-note{margin:0 0 14px;font-size:.82rem;color:var(--muted);background:var(--surface-2);border-radius:8px;padding:8px 10px}\r\n.grid2{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:14px}\r\n.field{display:grid;gap:5px;min-width:0;align-content:start}\r\n.field.span{grid-column:1\/-1}\r\nlabel{font-weight:650;font-size:.85rem}\r\n.hint{color:var(--muted);font-size:.78rem}\r\ninput[type=text],input[type=number],input[type=search],select,textarea{width:100%;background:var(--bg);border:1px solid var(--border);border-radius:10px;padding:10px 12px;min-width:0}\r\ntextarea{resize:vertical;line-height:1.45}\r\ntextarea.mono,.mono{font-family:var(--f-mono);font-size:.8rem}\r\ninput:focus-visible,select:focus-visible,textarea:focus-visible{outline:2px solid var(--indigo);outline-offset:0;border-color:var(--indigo)}\r\n.actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:18px}\r\n.btn{border:0;border-radius:10px;padding:11px 20px;font-weight:700;cursor:pointer;font-size:.95rem}\r\n.btn-cta{background:var(--orange);color:var(--on-orange)}\r\n.btn-cta:hover{filter:brightness(.95)}\r\n.btn-primary{background:var(--indigo);color:var(--on-indigo)}\r\n.btn-primary:hover{filter:brightness(1.1)}\r\n.btn-ghost{background:var(--surface);color:var(--text);border:1px solid var(--border)}\r\n.btn-ghost:hover{background:var(--surface-2)}\r\n.btn-sm{padding:6px 12px;font-size:.82rem;border-radius:8px}\r\n\r\n\/* results *\/\r\n.out-head{display:flex;flex-wrap:wrap;justify-content:space-between;gap:8px 16px;align-items:center;margin-bottom:6px}\r\n.out-head h3{margin:0;font-family:var(--f-display);font-size:1.15rem;letter-spacing:-.01em}\r\n.out-sub{margin:0 0 6px;color:var(--muted);font-size:.85rem}\r\n.res{display:grid;gap:8px;padding:14px 0;border-top:1px solid var(--border)}\r\n.res:first-of-type{border-top:0}\r\n.res-text{margin:0;overflow-wrap:anywhere;white-space:pre-line}\r\n.res-meta{display:flex;flex-wrap:wrap;gap:8px 12px;align-items:center}\r\n.meter-wrap{display:flex;align-items:center;gap:8px;flex:1 1 160px;min-width:120px}\r\n.meter{flex:1;height:6px;background:var(--surface-2);border-radius:999px;overflow:hidden}\r\n.meter span{display:block;height:100%;border-radius:999px;background:var(--emerald)}\r\n.meter span.warn{background:#F59E0B}.meter span.bad{background:var(--lvl-adv)}\r\n.count{font-family:var(--f-mono);font-size:.78rem;color:var(--muted);white-space:nowrap;font-variant-numeric:tabular-nums}\r\n.count.over{color:var(--bad);font-weight:600}\r\n.copy{border:1px solid var(--border);background:var(--surface);color:var(--link);border-radius:8px;padding:4px 12px;font-size:.8rem;font-weight:700;cursor:pointer}\r\n.copy:hover{background:var(--soft)}\r\n.tag{display:inline-flex;align-items:center;border-radius:999px;padding:2px 10px;font-size:.74rem;font-weight:700;background:var(--surface-2);color:var(--muted)}\r\n.tag.ok{background:var(--ok-bg);color:var(--ok)}.tag.warn{background:var(--warn-bg);color:var(--warn)}.tag.bad{background:var(--bad-bg);color:var(--bad)}.tag.info{background:var(--soft);color:var(--link)}\r\n.block{padding:14px 0;border-top:1px solid var(--border)}\r\n.block:first-of-type{border-top:0}\r\n.block h4{margin:0 0 6px;font-size:.78rem;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);display:flex;justify-content:space-between;gap:10px;align-items:center}\r\n.block h4 .copy{text-transform:none;letter-spacing:0}\r\n.block p,.block ul{margin:0 0 8px}\r\n.block ul{padding-left:20px}\r\n.block li{margin-bottom:4px}\r\n.prose{white-space:pre-line;overflow-wrap:anywhere}\r\npre.code{margin:0;background:var(--surface-2);border-radius:10px;padding:12px;font-family:var(--f-mono);font-size:.78rem;line-height:1.55;overflow:auto;max-height:320px;white-space:pre-wrap;overflow-wrap:anywhere}\r\n.tips{margin-top:12px;background:var(--soft);border-radius:12px;padding:12px 14px;font-size:.88rem}\r\n.tips b{display:block;margin-bottom:2px}\r\n.empty{color:var(--muted);margin:0;padding:8px 0}\r\n.note{color:var(--muted);font-size:.82rem;margin:10px 0 0}\r\n.kgroup{padding:12px 0;border-top:1px solid var(--border)}\r\n.kgroup:first-of-type{border-top:0}\r\n.kgroup h4{margin:0 0 8px;font-size:.85rem;display:flex;justify-content:space-between;gap:8px;align-items:center}\r\n.kchips{display:flex;flex-wrap:wrap;gap:6px}\r\n.kchip{border:1px solid var(--border);background:var(--surface);border-radius:999px;padding:4px 12px;font-size:.84rem;cursor:pointer}\r\n.kchip:hover{border-color:var(--indigo)}\r\n.kchip[aria-pressed=\"true\"]{background:var(--indigo);border-color:var(--indigo);color:#fff}\r\n.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(110px,1fr));gap:10px;margin:12px 0}\r\n.stat{background:var(--surface-2);border-radius:12px;padding:10px 12px}\r\n.stat b{display:block;font-family:var(--f-display);font-size:1.5rem;line-height:1.1;font-variant-numeric:tabular-nums}\r\n.stat span{font-size:.78rem;color:var(--muted)}\r\n.stat.bad b{color:var(--bad)}.stat.warn b{color:var(--warn)}.stat.ok b{color:var(--ok)}\r\n.seg{display:inline-flex;border:1px solid var(--border);border-radius:10px;overflow:hidden}\r\n.seg button{border:0;background:var(--surface);padding:6px 14px;font-weight:600;font-size:.83rem;cursor:pointer;text-transform:none;letter-spacing:0}\r\n.seg button+button{border-left:1px solid var(--border)}\r\n.seg button[aria-pressed=\"true\"]{background:var(--indigo);color:#fff}\r\n.tbl-wrap{overflow-x:auto;border:1px solid var(--border);border-radius:10px;margin-top:10px}\r\ntable{border-collapse:collapse;width:100%;font-size:.84rem}\r\nth,td{text-align:left;padding:8px 12px;border-bottom:1px solid var(--border);vertical-align:top}\r\nth{background:var(--surface-2);font-size:.74rem;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);white-space:nowrap}\r\ntr:last-child td{border-bottom:0}\r\ntd.mono{font-family:var(--f-mono);font-size:.78rem}\r\n.cov{display:grid;grid-template-columns:190px minmax(0,1fr) 48px;gap:10px;align-items:center;font-size:.84rem;margin:5px 0}\r\n.cov .meter{height:8px}\r\n.cov span:last-child{text-align:right;font-family:var(--f-mono);font-size:.78rem;color:var(--muted)}\r\n.score{display:flex;flex-wrap:wrap;gap:20px;align-items:center;margin-bottom:8px}\r\n.ring{width:130px;height:130px;flex:none}\r\n.ring text{font-family:var(--f-display);fill:var(--text)}\r\n.check{display:grid;grid-template-columns:auto minmax(0,1fr);gap:4px 12px;padding:12px 0;border-top:1px solid var(--border)}\r\n.check .tag{align-self:start;min-width:64px;justify-content:center}\r\n.check b{font-weight:650}\r\n.check .count{white-space:normal}\r\n.check p{margin:2px 0 0;color:var(--muted);font-size:.86rem;grid-column:2}\r\n.faq-item{border-top:1px solid var(--border);padding:12px 0;display:grid;gap:6px}\r\n.qrow{display:flex;gap:8px;align-items:center;justify-content:space-between;padding:7px 0;border-top:1px solid var(--border)}\r\n.qrow:first-of-type{border-top:0}\r\n.qrow span{min-width:0;overflow-wrap:anywhere}\r\n.qrow div{display:flex;gap:6px;flex:none;flex-wrap:wrap;justify-content:flex-end}\r\nfooter{border-top:1px solid var(--border);color:var(--muted);font-size:.85rem}\r\nfooter .wrap{padding-block:20px 28px;display:flex;flex-wrap:wrap;justify-content:space-between;gap:8px 24px}\r\n#toast{position:fixed;left:50%;translate:-50% 20px;bottom:calc(20px + env(safe-area-inset-bottom,0px));background:var(--navy);color:#fff;padding:10px 18px;border-radius:10px;font-size:.88rem;font-weight:600;opacity:0;pointer-events:none;transition:opacity .2s,translate .2s;z-index:50;max-width:calc(100vw - 32px);box-shadow:0 8px 24px rgba(0,0,0,.25)}\r\n#toast.show{opacity:1;translate:-50% 0}\r\n\r\n@media (max-width:900px){\r\n  .hero-art{display:none}\r\n  .hero-in{grid-template-columns:minmax(0,1fr)}\r\n  .shell{grid-template-columns:minmax(0,1fr);gap:16px;padding-block:16px 40px}\r\n  .rail{position:static;max-height:none;overflow-x:auto;overflow-y:hidden;padding-bottom:6px}\r\n  .rail-list{display:flex;gap:8px;width:max-content}\r\n  .rail-group,.rail-items{display:contents}\r\n  .rail-label,.legend,.rail-name span{display:none}\r\n  .rail-item{grid-template-columns:auto auto auto;border:1px solid var(--border);background:var(--surface);white-space:nowrap;padding:6px 12px 6px 8px}\r\n  .rail-item .ico{width:28px;height:28px}\r\n  .rail-item .ico svg{width:16px;height:16px}\r\n}\r\n@media (max-width:520px){\r\n  .brand-text small{display:none}\r\n  .icon-btn span{display:none}\r\n  .cov{grid-template-columns:110px minmax(0,1fr) 42px}\r\n  .panel{padding:16px}\r\n}\r\n@media (prefers-reduced-motion:reduce){*{transition:none!important;scroll-behavior:auto!important}}\r\n<\/style>\r\n\r\n<header class=\"top\">\r\n  <div class=\"wrap top-in\">\r\n    <a class=\"brand\" href=\"#\" id=\"home\" aria-label=\"Onground Media SEO Toolkit home\">\r\n      <span class=\"logo-tile\"><img decoding=\"async\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKAAAACgCAYAAACLz2ctAABTLUlEQVR42u19eZxcZZX2c857b1X1ms6eQDYgbCFsgiwCk4CKy6jj1lHHBVEWHVAGHR1x6\/S44IILoCO4fuJKWhkBBcQlBBBkCQghCQkh+55O0mt1173ve873x3tv9e1Kd6cTtoB9fr+CdFd1Vd17n3vW55wDjMiIjMiIjMiIjMiIjMiIjMiIjMiIjMiIjMiIjMiIjMiIjMiIjMiIjMiIjMiIjMiIjMiIjMiIjMiIjMiIjMiIjMiIjMiIjMiIjMiLTejFfgAKEBTAfBCOAd21dA7NxSLgGChaKl7cCNy1FDQXc4BjJmhLSwsaZ0ExH0r+XUbkeZCmJvD8F+s5VwVpUxPrAhhtAj+r792E8vuqvvhvzgMNdNoIo+h\/zQ74k6wAoQmEZSBugdMKBd6kwu+75bLxvG3VZNe57aA6thOMc3U5xHUUFfNiIxYVEmah6obIcKGkRN0i2l6C2RLXTNxRnHz0lqP+7ZpWqPOfmP3sRjBmNSmam5UwoiX35bq1NIIbAVALXPaaLf74u6bHpU4+7Tu3rqEDFnSNYMyCUjOk7xmDlbd9s75u051H1bavPV2izqNNgCNVeg8XKU0I2IXVYeBh4mJAIoDUvyMHAIf+AQNnHbpjgTJFhmmzIV5eUvNUKRi9rL3usAd6pr\/zqRNe8\/5uZD5em8Aty0Dz+p3QEcmeHywDoQXS72ZVpc1ffPc0bFwxp7pYOrsUl97YUTX5Y4f\/5O4b6EA8gL47hvCESm7Sda88gXetfW2BSieTxEeqkUOqjA0hJQAWsDHKkFAWSKBgBTjur+sJcCAQFAxD0IBBCpADDABlgKrQY2t6lfOrJNAne6n6wdLo4\/988Ad\/tYSIbPm7NsLMnwVt7neD\/JMBTkGYN5CiYNz7wyvrpt+z4KSwa+e5Bdd7CqHn+Hpjx8EJ2sMctk89+WVHfPMvj9IBAzwA6UE8rBpOv\/qUf6HizrcU0H2qkd7jCkGcgwrgLJwKRI0jKAiOFEqBj0UIYEAZjglKggDW34sEgAiAeqXoUamOGEKkCiiLgEWI2TCCAGACKEQxzhedKTxWMjV\/7w6n\/2bG5XfdB4nKQNzzArx0zWrqDqEFShnz0KTK\/37Bq4+s79l2TiFuPzOM2o5jZ2dVkQJiAHKIteRCS+iqGbNh2dkfPPnUj3xl5wsJQNImEJqR+FaMZVc1HjFR\/vHufLzzNYGTU\/NVDrA9kFIMqNdxapQSJJECYNIBPVpRBmBgYEEEKBEEBALAqgDEa0QCBAwihRFNzjIUgIqEqiowgTMIAAR5dMWjYheM+VuP5u4s1h\/\/i8Mu\/vl6QMsX56UGxKYm8DHLQHv6cgYLmy4bN\/nJ28+YJB1nBb29p7CT46qMGwVXBKwFBBCCcwGRDQ0ZEcm5KtPFE++o\/f3TrwfRCxOEaBOYmyEeOgE2XPOa46t6ll8Yxp3\/Xh\/0jkYUwVmBkjiwEis8hIggUCS\/SDQbQZUANQAIRAqFglRBEIATgBLBkQGBQCog7fu9EkAqHtJKUBgIGbDGUBWoshKpMlTAFCAIgLCADjdqiw3G\/mRH9WE\/O+riW54E7B7a\/KUkP2laWDju6flTZsiWkwLpemPU03t6vbpDc64EIIaSQxzDMUIAIGYQkSNl8ZfKkuMwb3aHY68Yc9Omr2gjzPMKwNRnoBY4cIhN3557xqieNR8PSjtfm88Vq1CyEMtWFSxsiVmJU5CogtgAKqm+6e\/caf+MDJGgnGbKeMRE\/Q9ZBzwDDPEGOnkP9h9HAERVGKqkYtgECAsoRlVdYsa1dI972bcmfeDGJYCDLoBBI+TFnF9cuHBhgFt\/1XCMrDvabl\/1eip2vKra2cPqjYyGRkDcA4khzoSqRglkSYWIwSBVMJFXAlCoQtkSusI6XT1uzNnH37D27ucNgAoQFoBpHhxAaP3Bq0+R1tWfqXU7X1vF7TnEghLYCQIOxZKBDAiMLHgGBk4ZZqBBjmzv75G9YXQPwGZFQKIwGqg1yIWIbE1nlBv3692jjv\/atAtbVgHAgsZGM6+l5UUTNae3NqnS0vf+S9OE4qpLhTpHT4gjgrMAGM4aUYgGxpKSspSVgADei\/Huc+Z9nUADEO0Ox29fctzpJ8\/50s0bVEHPOQCz5nb5D9950JTOFR\/Kd627PKS2WkQCAM6yYUtMDEGoDgTvs6Ug2Bfw9L1GhwTfcAC4dydWoWBYghI5CQQG+QDt8bhtpdpD\/qf9tff96IgjqKRN4BdTtUUTJ7vt8nMPi9Y9du0o1\/ZaKpUch1AybCT2hoFJvL+hIbxXHVcmHbLWT9gQ76o95MExv3r6LCKKFCB+Tg+kEYaaIUohdnzzxPcetPW+v9VGaz4X2vZaVyInpqBKeWOEKe8ccuKS248GBc3zGiXt5bOVDVQVIRwRYGIm7Y2cq+XdEyfET3734N9NvW3dT998JjV7U6xNTfxiAGDqsTR8685VE3679fXbao6dX6yaqCYXBmxF2QgsK5QYcAawOZCaIcsaDChyBnEufIiII\/VKUp+TE+LLZd7XW\/Hddxzd\/sUJN43rXn5DvWya0dNTdN1ManNsvNuqILUgEigDUWAQmWAPIFTGS0Q0IEBUtZ\/W3F+QDQf4ERhxkIOAwD7eIebAWBVFaberNpvOGbPr\/j9v\/c5pTT9ZqAVqbhZdAPOiSfOpj+qm\/XJxc\/HQuW\/aGUxfBeQYgCJIFAUrJNcLZyJUJiT6XSMBhAsoAXcCCjT6C\/qsA1CbwEQ+CtzyrbPeMXXnXxfWy+a3oNQrYp0YFlMgR4HGMFQCUVqtSHW2V+ZK6PfwTkXm8TxousHMfyoBLAL1J56EwRIgcAQjjhzDSKRSW9yWn+iWzH\/DE1NvfeR7px5O8+BeLCAkgipAT8zS3EHfuPH2p+a+7dXtQdUWBlEgJKwMsCLOOcSB9CkJIu9vJMpAAIWBaStR18bCpJUAMH+W17LPejGfmiGqajZ85eQv1LU\/+Ysqt2MiYnUwYCLinFgYURhhkDCAAMIBoAxyQC4W5Kwb0C70exwApphVYMopHQGpgKGgNGoGGEqKYrcbh42vOjLecMf66858Lc2D0+fg5n9OpBE8exmi9U2XjznsLzf9V87FY2AVpGmYYRDEBoFjn87K5vaS1AEBCia4sHb9jsPeuwkA5jc\/ywDUpiamZsjiay85qOPKI389RdZ8tkrb2CqLYzaOAigzQAwl05cUJoUywZoQDgbPJwmF+vmafSYj\/f1gZr7PWWcIGMIMZwhiHEAxmAVQA6EANmASCo3rDFx1tPPQ0d1Lf7ftujMuIbA0HeCsm4VzEFAL3OpL33J8\/eMtt47Htkvy6M2rGrADKVsoC4wzCJzpf+4S6FFSmwIZwIRL33zFxZ1JkKPeijwb4FsAQ\/Oa3bYb3jPTbPrzb+t13XGIYqeqHEDZARBmkBoQubKZJU0vvIPAeIB6tZHUZR1AmpRKFKwEkooAlwAh784SSbnC4V1p6nsxpakCzWhRyeQQk9eS+ko6kc9hKwaNqhmAEODI+LsfDhDxuS81Xg+SQCBgZgNbcrUc5\/NuxXfWXXdq7fQPPfjV+XCs\/jwcMBGy9\/1AtIjs+o+98jV1Gx74ySjZObnLlVwQwhSUAQuQU2ig0CAGbACSACAByMElZ5T9j0AYwOTyf4E4oBGMpKryjAG4sAkBzYPd9M03vKx6\/V0ttbTtUBfFDoDx4EgUtVh\/d5TdPerDgwIBEvAkl9YXJTSjaXxK0wBJJYOhrBBWXx1JAFq2zwloy7cj+5+Vkopx8rkpW0aT5HXyS\/\/+mYQ3a0ViK\/1+pDBpvTn1fwCAJPme\/ioIKUgDo86q6d0p4wvhV7b97ysm0CX3fVwPIBAmPryAjK5537Efr9vwyBcaoo4qF8HVBGTUKWIjIGIYBUgouY3Flz+JlVTIsoCYkI9IATVtyNmufO1iAP14ws8IgEmaxW745tx\/re1e+oNa7pgcl6wzDFMZiGbN2t6iVE0iYlICCcOoV+8gwLGAkufKABCAxaXRCpQMlOK+MlySs8v6jz4p58t3Phfgf4ImtWJ1UKZyrlArXc9h+KJKCZBVocpeK6ojZ5WpZ7uMrqGPbfzuyw39x0P\/qcc4k9yBLwgIFSDM8dfz4asuGnfIY3ddV9+5+m2BFIFIxRhnIAaqIVxg4XIWgQChC8CiEOMQkRNDzGEMCZVZVSCBKpMhl69e0zl17mrgUTQugGT0xDMAXwvcjq+f\/Mba3tW\/zKO71sXWBeqMJNaPMp+wLwAUJigZGPFaxFMD+gCk1JcrVCpfNlUBiD3DhVVhVPpUoC8CJ9knkBDgAk6y\/t7cMgSarQckUXm5bKwVSnCAEl\/\/YyMwAEcKAcFIABYAFMOFqmAIV00wWzHjKwdd8uAV3pV5\/rmG2gROSSHLL5szd9KuJ7\/bEO2e5XpVVIk4iIgFEM3BIUSgvf4GpQCOCQwLERUDsDAhcAxIToSVhKwExpj2\/MQbGm7ccJ5+XjlbJ+dnAr7N177t5PrutT8pyK5a50ougDPJxe7TGrTvyWQWghF\/0RyRN7PsNYojhtMAJKGq5sRp3sUcOjEEk1PiQDgMhU2OGDk2yLNBngxyxAiZYYgRgJhAobUuFOsYsSjH6thBCBDyd7o\/PTQg4IZbKQEJmBXEAhjrta2GMM4QWbD2tMr4aNWntn\/r5RfSPLiFTc+OX76vxQIC68YLXnbJjG0rbmno3TnLxZEjI6yBI9UAgIGwBZsiyLnEPVeoWjVOJaQ8d2D0Y51Vo+buyk28AbX1ntXmjMACket9BKrAsv5KL9gvH6EZbtM17zqqevfDv81R71jrIMQwjhkmCR5Sd0bTkGdfksNlJcCIOfQ+pFqoijeQRKocGWZDjBAI80AUosdKuwurOmKTa1Mb7Q5ISqT+blOiHBGPAlODVdQZ0ob6fBQCvWBnAatwyo4AqDgmExPYM20IfVo7jWv6kg06gObLqvMABOdZOiSAiaGcB3m7T04dwrhNGnjNdzdcd8bOqR\/6200LGmGea9Z1quOpBW5V01smVK958JrJbevegagHwiQckFE4hA6AKwDkEFAMKCABQI5AcJIDs+ZHUZFH37gzN\/OjM3\/+p+3XP\/zn+9547ftWjXbF+QXpDeM4cOywdKDvsU8AbEryfMu\/d96MqtZ7bxplt06LXCTExKIMoRCMGJnYMzFf++bWpLGEqIIFCFSVnRMYGISWkMujK66LnBQ2Iqh6rLoq\/1eXk6Xd4ejN8bhjd+0a\/7qeFjT2Ns+FA4e+PC6WH7711kIht7igPZ01Vdsen8jRxsOdRGcz9ZwcUHx4VYhaIILaIiyJg4ADJiImQCTLdYAkgNujvpwBohL7yFBCEJUAFigrVGKADEACA5A4aIj2sLa0+n\/X\/\/otK6e98\/+eSHOqz63JJXnyP087Z\/Sa+783xu06osQqgQmIhDlNVIoByPT65IIAMQDHjMCpCxybjvy40pZRUz9\/1A8f\/gaI3MI5CM45+eT4YtAX1n7gyEfGlDq\/32N5dKupfQrYXk5A90sVDjs0nw\/aetjHq3jt7bdN4M3\/YnvaXQA1jgwcBcihBMfGmxvtrwH3pcxF8KkXK6Qhk4DVIDAouVqUwvoHJVfz2x6q+suu6hPXzL7w\/+3CM1IWhAX33Vj18qXfn1HfvXNO3nW+PZTdZ+VybTnEDhA4gFk9UbDfcXnWDe2pW\/qOAgoCSd6nlqg3McGcmHebkLQNoOJQmze7zGGLxnz4iVfPn0\/uuWhdXDgHwdmLYKFKGy887ktjSps\/VqXteWvhVK0BARQHyQ1kQeztUeh8IOWUlJ2TwASmzYzd0DrmyPMO\/\/49CwFFUxO42RNPUi9dVl7x7lk9xd1vNWe8\/Guz5zVHA9UX9sH0smyef\/S1k3XdpaW414XGmrJjnnBwJFtWG4Kxool\/RZByugUJh0yFoQ7CeTAKIXps1Q7NNdzeVZjyy0X\/cvfCebMp6mdKFiS+7FLf49sXd\/TPGKbKaf580Hw0Acc0E5ZW0ukDbLn+zFO5tOaCOtf5hqqgNAlRD8SKA8gQJUGJZAGYfGQShacRi5Iv2hvLYM0BiLwa8YVUANYHOewjKyI4qRlj2guz54+54O5mbfocU3Pzs6IFk9weCNB7P3L2YYe1L79qkrS9GZEFrApIWEwAMRZEmqi6PFQJjBhMCgELszLCELuChrvWTj7iP0762t3L1WfHpNJF7tPiDAyizGn44CPZ\/NUT3tvQtfKGfNwtwoYMKYH6OHM+G+d8MVj7aBX+eenTDwwIAqgGYHIAWYA9tUmsiGHDXFVA0Vati4KGX7SPOvqHMy76w5ryeyR9GM8Wxanc63AMqC8KJWz+zfnTzeaHL6yOt55Xm2ufolEJsUCMMpPzie8+9nVycBr2JdHZJkny1GdMTkqqNVUSBnfofUVjFRxrr5lkOxtOfdWED9x8z7NhitOgERxg7SUnv3ts24Yv1brW6ZCSEzXMjn3VN1A4dj6v53w0q2CoOkDJMZzpqqqVzrEzvnL9xUuam2dTtDd\/takJPL958PiNhgc+yM7vvOaYYNfS+6riHXUmjn2ulgBKAUhUTvyylo1PkgTuA2D2OmhShGAF4KCOQjUhcexCSPWk\/11HL\/vykR9v2ZR+j5ZjQI3z9rzTnhMfCX20+jU\/eceM8V3LPxH27rgoR12BlEqO4QyMQMDeK4cCHJU1IYkB1EBN3JcQHyjihwJSgJjk74WF8wXezhPvL73lK6+cOnVe7wDafPg3VqNnJT3c9LFxM7f88apRvZvPg+uEdUaYhMXEPjtlGRYCowR2AAL\/rUUCJZsTLjizU2u2dDdM\/9D06\/5xC0Ehz8LNsTcAkjaB7q\/\/Rv7Itm\/9fgxvPyeKITlYltTSJ+AieAZE\/zcUb27LN33qPxFAJomUHeBLw4xCNdrj+nu6+eAvHPypR\/4E6Ava\/tivhQCEtu\/+67nc\/ug36qp2zobtFbGGWANSxBAiCCUVEFKfC3M5qImGBCDId5A6kyrOAEAgKFRxW+7Y88Z9+O4bdEGjoXn7xqouaz0wtp5\/wlvqdUdTFXYeH7uiCAGkzIHzhAphwKn\/bE4yaUoWRCSsYBRq0GrG\/mHDpCM++bIr71j2bAZINJyD2PalEz8yoXfZNVIqOWI2BGQqBLpHRpGRNA9lQZdJSDtDAAIYR1C1jgsw3eHYYlQ99Qub5z78zdmzKTqQWMSqoJZ54HktcE\/84INjZth7P2fstssKURehVwVw7DvsGI58+BFI4hNS\/9PcL0pOokwjnhvsq+YAKwmMoWI4ZfW6sWecdfR7frE1W+UbVh0XkAe+fMnYQ9f9\/stj2ndcxKYXPTl25Mjk1EFVIAQEcQ4kChfEEC14Re6sUuyE8wWzO6jppobR87\/9nZXfbCaS609CePFixOecfPx7eqCfiHO1PQHnDItlVQcRgYhAVa0xJgDw5QceeOC3jY2NpmWA1oRgL6G6bPj2uw6v3fbXT0NKIiA2op4ur6nXB8Ak9jhjZrlcL+3fi6tQsLA\/AbDW5INgNyat7K465uKpl955F0AoVwSaD4zifHLhnf9eP9oF8OXrfvi6+2rtgz8cE+6oR6nKKdQw9ya20iTnx5XvzIHyhP6MMQgEYwVgBowCAnaAq67adNi41r9cSET\/o00+fh7SWjWCieAAo9v\/4\/h5VU8taK4NO47qyZUUgOYcG+MYcJ7N7XkYDiAGIUTAETQWYQGhKm+2h\/UPbx196MePv\/r+u\/FdQlbztUk8VSQ4DhJDOUqifO7jAIrHgnNu2pBFh6HVIyvvXv7xau6YlFSpSJTKqYjy6wTwXR9p1T\/pTNHkuUzzBSnAjmAcrMkXgm6e+DdMOfvVUz\/yx7u0UY0iGwgcWELz4DzbW3j6BX9oaa2a8cbW3EGtqKsySurIGbBjsEimejx06ZHUQSEAuyT6rAGkCnFgKI5iWy\/FS9p+Ne8waoY0DTKMSZt8gZFa4JZd+6mxW86f8P\/qOpffWKutR8U9kWMEyAmxcRZKJdhQ\/GwIETA7UBBDSZRUHRvmUk29bm2Y9u2n\/uV95xx\/9f13J0OFiJohjY3+Mx1Jr0EgJqZYXCSRLUkcx+KcE\/HosyIizjm3zwBMkb7lS6edPaq04f02KokoGT+YgqGiHnBaYcUTIKpS8vB3g6Z+XyIxWYcqBF1u\/B92jZ\/3pjHn\/Wy9LvDm\/kAfAETk0za6AObIDz10d9foV567LTdmKdeogbKQ5JOIV3yPcdbkDgBEIwGMyyXTHJIGelVhLTHlG4KoemJdd8\/m2T591LRHkFHuu+EA2684+Z2Tnrzh75PyHeeR6dViDDEwJq9CJuUgKcHAgYISNHQAATFYHDMhX23a66Yt23nwCa+d\/L3Vl595wdc7FzRWXhePwLxWa2iExfSwIGSlPPv4U1nVJzrDMOSqqirsEwCThLPedttt+XDXpi\/WuF15iECpAIIBi+07mQmlaW99GNyX5gMpXJgPTBtP\/vm6MR9457QLv7VLm9KWzRePpNT6Q8772aOdtSe+eRdGrUZ1zDCRkFYBmoNSwpZWf8Mm5J0+Yrd6Fg8hQsyKiFRc0KUcxsxxrXa4ST9um3DWKQedf\/ctChBRX05wge+pVWqB29B0znFbLzv81rr2tb8abbfPdHGPC4lQMMSkDiBfgbEhwQW+FY3YwzFW40Iwl8I6t230EVeunv7GuQdfefefFI4Vgw9isqjX2NRAKW1NkD2S8tZaNDQ0DHke9\/QBk6hv+39\/8lWjou2vEKiQAVu1CMg335RzrUj9waxjTX1TIwmwZGAgYFXEHDjOB2Y3xt7x2Ok3XHj22Wf3LvB38Ity2hTNg9MmBPS+llXLrj7j3QXjbqsO2kYjihSsJJqDsRYSCsQAKiEMQl8b1lK5KydWqIPRKqMM5NCjYx4p5ad8YexHF\/8OeBLAj\/dMKLfA3XbbbfmX3dP0vlzbqitHy+6xKHUrSJQMDMh37FkiBJom\/CXDwSSnMCbM581OrXmytX7Gp4765uKbgUczEfTgEqNIeYQgCnxpkQFVRgqHVCmVSqXha0BVP1rrtttW5oOo89MBRSlLDkYtyNmKTqFErSU\/92lCSiMQMCmcp5tKGLDZickP47Wff+fZZ5\/dq00+ssSLWKgZVhfAzLrsb38v1p52fm84zsHEECtKUCgHMEmpwOf8LOAiEAGOArUSupACKgR5LmHyqp1Vx11Q9V+bTh99+YO\/a4LjtJWzbG4JSmDd3HzynJMWXnrXGLfh+6N161hxXc4ZIYFhEgOCgEgQkCQMUwaxgRBUBAoTmq7CuJ7NNYdcteHY151+1LcfvFnhuKkpTTsNLWPqqoikBKj6FgvxWPClVyrT7tra2vbBBM\/zzuxJi98\/p4qLr7BUUCgxC8CiCQk0C1gqmxbVPuSL+uc8GVjhFEKc4664Zr2bcMo7x5x8cXui+V4S81NoHpw2woy\/6LabuwvTPieFaiJWIVWI8YRXFiBwFqwR1CiswhklCqryphSM2tEdTv3cyslvOmXcJQ\/+iMinoZoBSVs5U3P7dNMZ07Z\/YvKPR3U8ddcE2XwaFXcIJFIyaiTvTayQd484bStAUiwQcgHypFVjaVMw+W87J5xwxsHXPPGJEy\/\/aftFJyEkgJqbQY2NMMAej372ddSoUeVpY9kSa5b5ZIxBGIY6LBNMANACgSpVfWL6pQXZjR6t1ZzGVObuqELIz9dLPztbei\/XgzUpvDLg1GhoFBHVx8Xqwy6cePGNTw9Hxb\/opAWyoBFm3CWPXrnz6+NOHVMd\/ZstBUJkWcGgJHDTgCQGUCjkTalUI6Vw0g\/iI0\/6wrg33rAJWNHHVGmGJP9Oom812z\/7sv+o61n9mSrZMRE9Vh2xMoiFGAof\/JApgspXJAcXOECtIwsOkDddwaRdxTEzPjvly3ddD\/J9iQLo9xf3jTVoaemLuDCIb5\/m+0Q04XzumSUSEdBemCdlAN6YgGLdDy48huPOVyG2YIrI+yvldLJPq3CWC5dEeinxVCjJCQEqBMApF6q4GIz72sRPP3xn0mll8RITAlRnQQGHYvXhn68tujODfHG0jaAhQE6MEOXAoXJg8timY+7EmJlXTfrwn\/8ELEUm8S6qIJ3fV8jfcuXL52674pDPTdTd58B2Q8QJQuZ0qBfEE3VZFcYZAIrYMGISDWElDALT7mrQ7Ubf1FN7TNPMK\/\/wRNOVxPObwO+++\/Sp63fvviCuGu3CMC+d3e0cMCjH0FGjRumO3d3UG9k8i21ZsmTJI6tXr+YkwVmenaMqZawSEZhpr3N1Bg1Cqtc88O4a6q2CsIToZTZpiyHBU3i1bG7L7Gf1VHdNasDMHnyWjYSBcGdv\/tH2o1\/7VW1awZgP91Id\/52mZ2jevY8Xrznmqzm35muBs86BEORzBjQGPVz1UHeh7upJl\/7jF8DqvniNIGhOolvPgNIV3zjh+IldWy6vaX\/ivIAixL2xMgFiAhYyCCWCUYGaAKzd\/lIEBrHmIGpdFVtDVGvachMebKud\/tVDmhfdBKyFNoHn3jWHqXmRfdXJOkO46rNRbxFRbxG5gLzPqMCO1jZYZRAZxBI9DeCRnp4eSsDHlZmP1O\/r3+46DA2Y\/I1befUV48Mnf\/h+NRZOCAG7cq5PEPihZerzW2lHmWfApJWQxNF2vq9DKI9uyrn2qkmfPeT8q9t0AQzRS3ySaKNPGG9zJ\/9gfNT6npowOo6J0C31T5fCg67bcu4D18ye7QfztCREAZAHXmMLhFrgHv7iWZMP71n1Yd6x4rLanKvXOAacukBhlEOQBv48I4AYB8eCwALiCJbZBVJiDsn0YtLG1sKM7\/R84L5vH3EElbJDNBsxgQCg1VbFAQWxQad3nizIebsHVQMVUValnMmVBs6LppS0DGu8f+5z7z5gyzzfO1O74sa316Njsuu1oobYKWA8NyeZgBQCKPlEdDKvpW\/QY9kTTJxDcfl8YNryB\/966meX3L5gGRnMe+mPsSWCaiOYWn7atv7qOdcG0dprLLp\/2Dr68CtnXHzPFoD60hwtcBnmjQMZbPrcke+u736yqVbbDkdJYG3oYg45j9gwefo0Q6BCUCYQExgOlowoGeRYTUS1KJnRv+yecvZnpl7+07X4SuYzk4kEaATQAhjTQQIEkCCJKL27qsl0h5CgTEoi\/Uf5bd68QZlDiFhQUoJL3cY9STl7AWBji\/c1aqXjbaQlBGzUiQCG+1gtIknjd9\/7Krg8qiXNviQOsBoQx5Zbq2acMh9E2tjUpITmf441By0+DttQPfOmHSa3ZOqlf34AuMcPrZzntVyZadPs6UBrrjxh7sTixsvzvWvexOoQSeACitlIryFGeSAzcep5u3KyyyiJKQRGuQrtvbl7duQnf\/Pwryz9HfSnnjuZaNbKL+nzebsJLg9CDYh8P7ZkeCpEPppWkn7Xrq6uAd3d3SAiiAg4mRS2r42WQepHLrv+gsn0yP8dD2H47kZ\/Q\/hbmsEU+QPmBHRpDrAcc0lf+VPhUJUPelzVr0dd8OMVvlzU\/E+z2qBctrrwR7sAPJAJMFwmn+cAuFVfmjO7PtryX\/Uda96TlzaDkqjlUI0Rw+oA8fwETTmXnM60ZjUqQhAjtXVmt9Q9YYMxV2\/80uM\/PZkozphbN8hN4qsVPQUYY0Acly0Yo69twoGgxHDSH1njxo1DV1dXOUjuC0i0nz+4t2Y0hje\/qHn60XPzJh4HSYYiJ8GGiEBFktKm9\/VUM7XdpMyU\/izKCsOmV03n7lHTfqIAYdY\/54IXRTKmrtk3YmfLZ23faBzTNf\/QT0xue+Se8W7tefniLoNInWMmYmJP6vWgExMgDqsRBwWwQgOxzkAI+WrTGYzr3GSmXb3k7O+cNenzS354K5FbOGdOMN+TB\/oYEZWjnRJWwezZszWfz+8BlHIdP2G2iPTH8fbt25XZlH9fxkrmb4bTCRmgxWvcqp4dbwzRDUHKHvCjJ\/oGjirYMxnL2i+dKJCUuX3lg8kh5EDyVbfO+OyDjzyX3V0vCk3YDC2fgxa4265emX9Fa+N5VTv++t857jgUEgPdcDYM2QkME4OgviOwTN83YBVAxQnYcN6YXqqLOnPjf9Uz5sSvT7\/010uBt4AJaFZI86JFwz7fU6ZMoXXr1qU5u35BRP+otr9p7e7uLgPPN++7PV6TgHFoH5AA1fX3VbV\/+Q0vg4vBmnh6lFDLkw61cmKRuS8DnrxQU+IpEcgJS5xHZ6Hh94odVNmI\/E+lAZNOQq8BA2z70tnn5je\/pnkUdp4G6UQpVheoYYYaFgWJgMn2JfXhfT+GEzgQ5wJTkhr0cu3NdtJpV0649HcPACs8axyzzCM7eXRvT1G7uoFuANY6BmrQGwQysWYiisXtIYDuxx57rC1LGFBVynL4Kk2oqiKO+2P64IMPpo0bNwLQBLzBgBpPVfeehtn+2+8cWUN2cpIeJs5UWPx9mBkTJZLou+S3aSowmVBDBuzicBlNePWthKc01bD\/dMCbl5JDoWubTn\/FpPY1n9dND5xbqClRZEuSEyDk0Hh7EpdZRn4wGEEcYEh94cmELJpHkWrv7Bh92FUHf\/rBP0F+C20Cz78LTC2wrzjZzOwsln6rQXWNI1KNSySWCQQUSLSra4sDqEBEvwTwye3btxMARFFEaVVj8MieYCpGau7cuZPSSogHod1DA\/q\/M3tPRPeufuz0sXAFcRBKQqFU61JCu\/JOcOKiZkexqvZNLVVRcIguyd858dLvdf2zmd9yE1ASYKz53sUz6jYv\/lDQ+dRH8kFrtToAnYEEXM02tAAikDAEJqke+ZyqCAQsQN6w5QK6g+p\/dNGoa6Y0P\/lTEMlAS3E6XHW+qDSzmkzeSAxLOXDgkNcITg1EQoShARGNH\/im0WQnyh5pJT8doiK\/EoahZv28gbRf8rzsBYCEWtd1qrHWT+xLVJkmWKPyuDJkym7pqFzto+YTQxUcawFdY6cvUmz7pzK\/CzK5vb99\/UMTjmhddF7Nypb\/rKLoICsxemFcjtUQOb\/vxnndRyJQCJQNWEVIBGzAUa4BHYWxjxXzE66+4\/Qv\/+r8s8\/uxf+U83mKihvbGiehSi+KPaFhUYUhRwQLb0KdWqcqQRAEJQDo6uoiAMjlcuqcU+ccaWZkeGVEWylhGGaA5qfxDYI12ksaRqj94vFHIXJgISq3M6CPbJDdfOAbkpLm7IQdQ1CQqBATlzi\/Kj7ohIWEB5V+89LfKlkmDLTA\/WThwsK5t13yttqNv\/lsvXYeBY3gYhUOqyh0OUMoAUbhuORnIro02CNRJUVIBlRAT27Uko7C1O8+dsoXfv6a17ymGzgb2ggzD42gQXaO5KIuFIVZTDWTizSPiMgwilwLkhiB2mQ02ICAoD1TJtpPG1aa6J6eniQ69nMfnbMJIaH\/3zB74kBLS8vAAFz5rbcdMsHaQ3wVJiBS6xvLy4DLThhNv5vzJTgqAIgAtRBWNWRQoqoHD7v4B+2KpOf6pQy8ZWmezeDpT53+qjE3vaepnjvPZNsLxJEIgQzAzsZAkCubWgOFKMECDhxQQMrIBegxo5a05iZfvfyM\/\/fr17zmhG7gNVngCdCiF110UfiXv\/zliKeffnppf41UQ9TTDZUICkEpcZ\/Ylfy4APHFBBFhAKitrdW+IEQAuHLAQcl08j5NiMTXywA+l0sACKg6MPOAqRzmoQewBT1rVhwjUTQW4pIJppSQDPu+QGpm08m+lDjKUCnvYxMBcZBDUcMHFErZMawvtQCjpVzBIKz71Bknjel48gLu+MfF1Sj5Nk12PiMFAzEOCgsjNjPfjZwhYygfGMtVaDW1D0TV437Rfcr7f3rE6y\/rAE6o0HgtCIIAp59++rn33LPoI+rnpb0uq83iOFZjAGujcvCoKiBECTdz4HnXIkKqCufEk0gyCeXszGfn9tSAaeTMzLCZwfLMXP59Gr02NjYOqAWDup7eabUQA4UaOBJJzpMoyHDfdKuUcpVkxqECAwtVB1GoMcw9NtdTPXHKPYTVCTXpJQa+TAVj6WdfdfjErnUfovaVH67ljirXE8GBxBCzUg6WCTAEodiPJ3ZQiAoITIVa0+1qJaDqv7bmG36x9UuLf3EyUQw8ioVNc4L5dwHUssgBLTqnqSnYddOCfw2C3Pltbbv+LQHFnwaIVNVa6wAS55wyl5d++nKZcxIPQE5hZvWNbEnWh4hEvPllJoiIighVasCdO3c6IhJVFWstpdov1YREJCICa60OaYJHFWV6zmf+NOWZJuxqJPFWog37ppsIUTK51KXjcpXBZLmwo3PySeuAu4H50AOlr\/fZCDDKTJWHb6me+rMrLslt\/ccnG8KucdZGiMQ4jkM2bNnmvFUIEiKRAYtoTpVhKK+m1wUohWNu7xh3yDXTmv52B2Q18GUqA+\/s5kXOVzwZJ5928rk7\/u+mj0c9pXPD0Dd7EzEFQWAyhX5KNGBYKpWqgyDgyim0CSDYazKXyx6bcy5wzrFmpn6JeGPnnEv4fQbG9EcuEYVxHLOqcmpm2a\/HTD+bkzTPkHmYoFpkNExSafNdDH7YDiUT6dOxtuWKh9d+mib\/xN8pMAyl3O6pF3xzNy78Fl7MWyIHCjBABps\/fvJ7zI8u\/8\/RbvtJoesESrCBgQHEICTAKUwUwAWkwpEYC0Iux5yvRofUdMTVDb9sDxpuOuxLf\/8TZD0UoLua5pgEeBYAgiDAEUcc9iaovahnd+trCWSIvFYTEcrn80ZEQwD9+fBA5JxbparVzNlV8WWt5+I4rp4+ffq6p556CosWLUqfL8ZxvCb2mWbJJI7VWgtmdmEYmqqqqt0AsGzZMgUAY0xbd3f3RmYuiggzs4pXk6yqREQuCIJCXV1d65AADEga0lU2qur3dlSEStRXnetbx8TZghMpnIOQ20rEmt0D8aJOJKd+3kdm\/9vo0u5L8m1rXp3TIiQqOgFYAw4AhoFLSLlQK1asGlPFbJDLoZ3qliI\/9mfxuJk3j\/+vPzyZLre+q2mOmdu8CIsS4DU1NRVafv2zd9XV1ry3o6t4toNBiQIwRIhssrWWREQhItzY2MjJqAsFgPHjx6\/M5XJzRYSiKCo7ZDU1NdTZ2QlmVmstz5gxo3jvvfcCfjYcVPXRQqFwem1trRSLRQWAuro6pH8ThqEAwFvf+tbu5uZmwA9uw8yZM3+5evXq31trbV1dHbq7uzX9POccGWPUOUfnn39+x2WXXeZ5DQOF393vmHx7NVpf69RPZk32TvWLfCnTBEfKcKxQIwjUTwEVNc6EsWmn8T9q+EHrBdqkL8oEdHaaFEBYesW5ZxV2bvj4qGj7G8aizSB2Cg5UiFiRrJ1gKKsnuWiYN5RXdJdI47D2952F0b\/Sk151x\/R3f293asp3jz6JL\/7+YkkvyAc\/+M6J99\/\/+PlEPM86d6IxDBHR2KkIGSaNKUjH0qmKMYatlftOPPHEf0kAWKkJh1mmznCXnt+\/63fKAwRSi94YhgM\/0VM1qfdKsp8Z\/ZOAyfulw0Kdv0dhAORJdwLAizEB3UcSJbf8q+cfNG71Qx+v2vb4xTXaVWPjXsRiHYdkmISU2fu9PjQ0CENCroAO1LRKvv4mG5ifT\/j2inuAVgBP+Vrt9jk0r2WRBRY7ADjrrLMOad3e+q4HH1r+AQCHQWKQQiNLQhQYQ9aE0gsihQNXEAVIB3HqeXj3Wb8E8XCXn+kAYBru32nFe\/SZYFuK6kCAE0dk+pbHpPVeLs+\/SkavkZQ3CEmSyTciADFMEGx\/sVneBY0w72iBoxa4lbddXV\/43dcvrFv+fx9pcNF02F4A4pjUKMNoOqqxZMG5kBGw6ZGcdFLDoy6s\/1FUO+WOGV\/6S\/9BmgsgPnJeBFXlt7\/97actX7784h07drxOVMfHpRIM1JE6ggobhvHF\/XIbWAWuCCJWK9MaSd1VBiuzVVY4Kv6vlf0cA\/274ndKRPt9sdMUTmDY5NO9SkrURzzoVwXJNJ8nm4XIAY4B48T7TMghFi6+KAOMIIdVHz35\/WNv\/MonGnpbZ8E6ODbOBcomMEYdhK1T49QgHxDqqtDhzJZerm2xhVEtf5l63KPv+8TPu4HlUIDR6KfPJ\/0eDEBnzpz59lmzZl3GzC8nonxCf3IkjsBs\/HIdkzigSeMXmQEqWgQi0paWFslqpNNPP\/2wUqn0dWttIc3vJQDJaiBK0jhaEdFSpq6rAMinZ7zbZowBeek3+SrN9aX\/T\/6+X6rHGJPNKVISrKC3t1fHjRvXFPj0Y9+Ml3KjW1ZnJtGHwDenk3IZiEAAhYNTQq\/JHfCJ5\/6JZMY\/Pnr6meM7N10xdseTr89LD2xMQprziTU4gbUmMMRgQo\/NR0Ue+5CtGd8SHXfcb6a9\/2eb\/Dl4vDxIM+H9DSTz4jg+k5lFVR0RsXPO9MvLDUGdS7l1CRjiSjPY09MzurOz8y3Z6kNFd9qgWm2g6kVKtc8uGKoosZVJp4NVQQb6XGaGc77qsnXr1usD5xeklY+dy9PfE9ObjDdNC80+TeMbVlgBVr9fyAnDBUYPdK2XdOW5pRecccyo4sZP1m1\/6r31bjchsiomEJsziCXmOnZkKEQv16MzFyxBofqvvfn8Lz\/6zZWLW4gc8A8\/NngZqHHAnovKdEPQq6rOWqvMHGQrDcPtoU0vbC6XK1b4YzDGOGNMl6pWqU\/OUWU5LAu+7O+GAk\/6NyICY0w5N6iqZe1WCcIUvFktmIJZRJSZSUS0p6fHBQL0ghlwySSntKCcGSjZj5FACiWX\/JMA5xCQqpKCo7hwAJtbpWbIo59uPHjC+sc+XL9r+aW1QccoiQQAYiFiFmcKnAPCPHY4WROHY+5Bw0G\/\/NsZl989b947ewABvkVZ3244kX5ql0YBMETksmAbTBMNGk76i9hd+fve3l4DT68zlFKYMpWJ7N9nPzer5Qb4nH5ArDC1A7KoK\/3H7OuS3yfuI8mECRMkCMJcN3oAw6yq4reaUbJCITHJfaVgKq9OpWx0LAJSh5xEow844CEZNm4CbHr\/8RfUrbh3fp22HQyNIY4ikORAJuQwh1bKd2th1J8LdeNvWDHpiIVnXfHr3cA64Or7+ybzN\/uejmHG+eWIsVQq1QVBsIfG25c1Zp514qCquyo1YBiGKJVKexT\/h9r6Xvk99haEDATiwcBd+b0HnBBLJIG1rhvEEHXlnqhy3EvZBvQ+wFHWs01nIDsB1I4HGJglL6gprkwkLz3vhFeO6919WUPbhjfmbCdEepSriZhyuU4dGxcR\/EVz5q+ttaN\/f+z3li8H1gF4GApwS+PwTOxQMmvWrDCKovrk4gw5LGCg5yovXhzHWytfY60VZtahOHzDAfi+rFTbn\/fPatddu3YhIKU2MIOTonF53gv1IZ\/SxhMCWBgQgrJAmABmGLWACBzR2Bc6DZMlDDz+sXOPOmjjqo\/Vta1+Xw7FPGAAk0d7obpYYnd3TOYuHj\/lzinXLv0HxALYXE5Gl01syzP\/TgcddFDVpk2bJif+0zPOkRpjNlf+Lp\/PaxRFOhwQDecr7HWbVcU2+YFSPXu7VESkQcFQG5QgNglAMlyw8tZLrdhTWp7W5ZL\/GjIssMTTAAKa9XlHYVMmrbLgK9ePOmXJVy+btPrBy\/LOjoFxaAtzrZEGfyvJ6L8FY2b+\/qDrFi6HOgA7fcI9MbHUDEXLsza\/hgBoV1fXeBEZN5i\/NZS2q\/AljXj68arKJ6Mo2sP5318tNRwtOJRpH64EQYCAItOBUKAMUhdAVJJNR5oxxcnoLdGkDOervUYVrAJLBhAHwzRe1eWI\/OyT56senA7QBoBVbzn8LRP+\/oVv1YXF6e1OtTuoWxTla3+7c8xBt8\/+33tXAe0A1vZpugR0z8W4uMbGRmppaUEYhscAyA1SjtqH3K1SVVXVtrlz56669tpr0dTUpEl9Nu1so4EAsa8AGa4fOFQ\/yEAtnuWZCwQAAmsV3Ka6VhwDqn4bGPbcZZG9nTmd\/ZcMpvRUQSE4gNSN2fz9yyYlKul5K8cRoI++a9Ypa+Yd+rtq6vpxSXtWbLPVFz7dcMwpb71p86sm\/\/qpa2f\/76JVCkfaCJOdKp8A9zm5UdJKxdatW49JKhW6LymXQQC06ZprrtkBAM3N\/UedDASSZ8Hi76umHoZPm2pAICgW6teWijtdHjDpWLc0sPA9R9kAxEfG7McAJm9GMGQA5zSv0ZhdKx8\/FsD6lmXNzwsAFyxYkDty0Y3vqunaOJtV\/9hz0JGfPOird66E7gSwEfgZlSPYtDn8+XRJk1TIEZkc2JAXaLAJBQA0CAJEUbSZiEro2wBIQ4HkmQJwMKA9k\/dO84YTJkzWIDro4FX69KY2puJYkb6jqQxAkOkTASTZdpks6VIQBK7KxKamd8eZAP7wfF3haVuWFkp1E+45\/rs3\/dR\/ueVl89oCYN4zjGCfof8nTU1NfOONNx7yLEaSKypqc3uNoPcHKAOlUp5dECYa8Kiv3bGq+I7JGyAYq6LKSJZ5U1\/tUcWvHiXipLTphxFRev9pMiIh7kU+7HgFwJjXIs\/LRT\/tsuYOAB1pBPwCabpBA5B77rlnvDHm6DiO90jBDJYAHqiUlVQPYIx5aLAPTMtj+wOk\/QXm3oKRvue1orQHjWN1TMSui+lJhCEglEwkMX4IkfRNvfc14L6REZ6S7wdh+V0UIDgButtevvg\/zzo5mwh+ri90ui0149MdCEIAaP369a8UkfFJ+p\/3JzBIKhvsnNsWhuHDA7jn6Wt0b8FBZcViqJ8HcQWecR4wLZAYY0oMKFx99cOqBpRMACzPectOQKBky7dysgUpDWpS2pAhC7gG6q2a0r15LoDnixeoByj9X4lIC4XCOUkJS\/a3+pFOFxCRlY899tiG1LxnXxeGIVVOtBoO0LJ\/M9jvBnoMBdLhvJ6IYlXtZgDoDfjerlhjZmLDnlDg1SX2YGj4Ulz\/3W8EP0MwFgIkRnWpfQ7I4J9xLkzW\/zv88MPHxXF8TlI\/peHkAffiZ92D7AbEjJRKJXbO8XACmoGAMVzwDfc77\/nZe5yiuFQqdTEAbK45epkFbUHgO5DTdVKqiekFZd5EwHBl\/49TGpc6hJYYMdRo\/Mo1V7zpNG+Gm\/ifEIDJjEc6W0QOSZt1KpO8aZqksqJQyUZRVeOcs7W1tbcP9oFxHENE4JzLcgA1yR+m5rnfo\/L57KPydQmJQPfmGw6V+vEzZrwlVUXc3d3dywrQmV+\/tVOCmmUwBs47fskS0b75u5Rw8DXjfWh57TkAERhVHw1TqSq3feXbCVA8T+mYA838JhftHGOMVprL4Tr\/CRjTv90QhuGTqf80mJ9oraWkzZKyDxEh51y\/h4hQ8nryvb\/S7znnXPn59P9psKN74S4Odnx+rwgBQFFV48BPMFAnwbg\/San3tSBLmvSFphY4Sw7vtxMkm65JeWMK5qgXVdj1pruv+MhXceW1rSnj6J9I++nkyZOnOefeFAQBpeMw9hOEGgQB4jh+aPHixa2Z\/F+\/XOOUKVNWicibrbWBqgozU3ZLkbUWRKTOufLItMp\/A9jj57TKQkSaz+fNunXr\/kdEToBv4eRKn3ZvgQ8zp9WgtgsvvLAnSMfndoydcmthw+b5dUR1YFJVyczFTAipnHAAs35JmcCajidXRiQyqlA8fMaWO84j4CqdBwPgn2VGNAGQmpqatxljDkpmDnBlL8beEtEZBjGLiObz+QWD5P8UAP785z+3A7j9OVXrqnz88cd\/KYoiJD3DA\/qPQ9GyMmzqto9+9KPdTM1+FPnMq\/+0SpSWwpDGvmCUegg+z6EEVk78Qeq\/rEb9KA8VTSYnMLinqGOibReuvKJxPFr89p9\/FvCdcsop9cz8PlSsychGwZX+X\/biZUApqkrOuc2FQuG+wcxv5rPNc\/QIAZhjjz321FKpdGRyDDRYkDJYwJJQ+NMgdzMR+aippREMIu3gmttFDBEyb1heA+L9PdmLGREliIaMUqw1KB5Rt+6hywik6TD0fwbzu3HjxreKyAmJGePhRIwDPUREExLqg4sXL96Svv8Qfqd7jh4CwHV3d79CVXNJTwvtb4UlefyjfHIaF3hc9R56yi86qKrDMBgKKW9FT4IkgZ+YPxjq07QMA3CGCL1W6qJdl6+4+NRTKLOU5SWs\/XTKlClV1dXVH0rIoTKcnNogaY40+SyTJk360SDm9\/kSSfzDM9M+kIEqN8M5trQalM\/nV5YBSOQnuR9x1S1Pa0C\/IfYdWNQ3YKmvN2QIFetX1yjYWTgoOSHUSFd13a61X73l+uurW5b1VS1eotpPcrncZUEQnJqYGrM3szRQpSD5vxAROef+PmrUqD8jJWC+MMeFww47bKZz7qwoisq\/q0x4703DO+fUGMNxHEfW2rX9zcMyECDoMqNu6LKjhAgsRvvG8Ap79CRakdGXI\/Sr6AkklMDQgR2BJGSUxE3m9rnH\/O2qy+a1wGE+zEsUfG7atGmzROTTIqL7W6jPkErTxPUNd9xxRynxxV4wzQ7gPUEQjE0GJdFA\/SB7O960q84Y05rP57f0B2CyXurvk97yYDeNWmxyOVJRp+mwomRBIQPgBGxl4CXPpQlrx566z8I+aVTqkQnR9s+s\/MjcOdQMq40vKRCmyQIjIl82xtQ555SIeJDlfXssgcm+Lmk6SqdMbSsWi3fsJfh4zoOqWbNmTTLGnJfeHOljqHzfgHY8oaOp6rolS5bs6gdAAhSN4Hnf+laPqTHfVq2GcSAXA5aAmCxUTflGTOfIaPmLpCvT+zSjskBIySlQ40o1te2bf\/iPS153xEvMHzQA3MyZMy\/M5XL\/lkaulZuC9lZrrbxQiZ90\/datW9clnyEvkGbXUql0vqrOsNZKZVC1t1ryAMlyxHF8T9Jcb\/qDYIHXguumnvSH7jhc6dfUeY6M44SEKtyHNVWIpB+GMkGBxfjGJTgoK5jAUopkcnHbzIO3PvrbBy5581hqhrwENKEBYA899NCTiehryVTQcvq0ctlL5UWSAQK6ZPoBOec6SqXSz7O5vhfCrTjiiCMOcc5d5pzTlPI\/UOvnMIgKmiSupaGh4Q7Aj+3l\/gj1WvDkr7a0F8Pc1ZrLEwEIHPl1NaSAOPRVDqlvZoykSpDgd3j5XmEWv7yaAUZPhxvnWmfP2PnQD7\/xjW9UUQvcghcvCBmAmzFjxnQi+gGAusTv22OGyt7SLhVaQpIy2C9Xr1791ACVj+c1+Ijj+FNBEExMg6LhaL3Bnktm0GzbtWvXCgBoaWnRPc1gogU3H\/fKX+7I1azgfI7hQjGW\/D4IqvwA7ceiVvV7L0Di\/UJLIDGwIFgDA2vdBLftzRc88o2fPXJ+4\/h5LXAvQk3IAGTmzJnjAbSo6gnOJ\/14bz7RwEyRvryfiLC1tkNVr3kBjy8AYKdNm\/Z2IrowqeaY\/dB62cqOAIC19sH169dvSf1L3jMKg7Y0gk9s\/mlbV23DZ7tNvQoCkGh5LFvCDCw\/qPJndRDVsqYk5zk0EREsw7hesfU9rW87fNftNz\/1ntNmUguczvFbm14kZlcOOuigsc65G40xL1dVJyJmsOx\/9jHAhSm\/Dp6kScaYb69bt275C6T9TAK+lzHzd4ZLyxpOVSSZWfPLlDgxaJZ+XgucAnzoj5\/6bYdW38I5ZaeBI989N8iH93krJH6QueVUNzqwWLAD2DJUTBBFsa1F1+mTup++bc1\/v+lEWgSrTeADPDgJALgjjzzyoOrq6t8w89nWWqeqZl8u1EA\/E5EQkbHWLsnlcldh\/yafPivHd8YZZ0xj5t8CmJiklHio4GIYiWhRVWOt3VZdXX13Nqof\/GI3+ahlVO3EL3ZT0E1hjhQFhXryKUn6SGrDgGdLI\/DRipAvyyW0M1ZFIAJ2hEAs2JmgFBVcrbYfPn71fbc\/\/e5jL6BmI9QM0TkIFAdUwppTzTB58uSXFYvFPzjn5oqIIyKTHWm2D6WosuZTVRURdc7BOffFFStWdL4AAAwA2FNOOWXKli1bFqjqDM9Iob26FUMda6r5ACAMw5uffPLJrdljGxSA1AzRJnDNzx5+eGv1wV8PmDhAJI4JSuKTfX59NwCFsEIASDI1IXBA6Pq445wgSoyfq01EQMDGRiI1xZ0Tp3et\/8H6dx3+s0WfueAQWgRLgB4gAUqaAnHTp09\/Zy6Xu9UYc4JzzomIyZ7sytzY3qofGZMsxhhDRL\/asGHDgufZ9KYkBjtlypSX79y58xZr7anqFwDzcCo4Q7SSIiXjikixurr6u8kxc79IZ1CZ79dSb53+im+2utr7ADFCKqJAzH7dlCbrHEgBIYGxLtnQk7ClhbDHhylg1JtlGGEnqiZql6k9G99z4vK\/3Ln+HSdd2vSE5hJXgBY0wrwAGrE8f+T1r3\/99GnTpn1PVX9FRAcl4DBZ0FX2YAyl9bI\/p6aXiNaPHTv2UwMkuJ\/rY9Tk5noXgFviOD4xGSFnhqPJK7ekZ39O77OkpPiLJUuWLEmzB9mDHBrdycrVVY3HnjShtOHeuqgtHyXvGjqGDQAj3ryqn23uV7umf08AspvX09+pr6ikmRzxGtkFIIOgBrtN3V2bq8d\/YfYvlv0V6nfpLmiEaUzbLp87bVA+QUEQ4IQTTnhHa2vr\/wA4QtLluAm\/rxJsA5WjhooQ02QWM0s+n3\/rihUrbs1oXK3QwPpcHONxxx1Xs3v37s8bYz6ZAMgRkdnXBvrBTC8RqYjENTU1Z65YseLhNHE\/bAACfRPkn373sRdM27XuBywdYg0oZ0GWGQ6MfJyEuwZJ07r2ZVAJIO77wrHxGjO0qd8YIg4Yji3AsQQOGgbGdGnBFoOaO9vqp\/ww\/vHiP8wmitI4J53rgua+DWzP8IKUqfPMjKOPPvqNnZ2dlwM4O9FULtV6Q9U9h2IHVxJSEzNnAFy7cePGj6ovNQkAnTNnzri5c+fuam5ulgptpdi\/tQzpwyWfbWbMmPEOa+3HjDEnAdCkVLZfraMDHaeIOGY2RPS\/69evvyRhhkvlFxvemzaBqZlk8xumXztZtl8KV7RKCMjBl+jIgOAgxoGEM43tUtZ6VN4x7M8z+anTgIaAhp5xwzHUWAjYGQkMG0YPGZQKuYd35mpv7ppy+oITvvrblalWRJoZakyOJWF4z28GmvdcSVB53P3YJVddddW466677t9KpdL7iOhfsnexqvJQYBtMQwxBSnDMbKy19znnXr1ly5beFCCnn376hI0bN\/4xiqLtBx988DcXL1785+QGyHoztJcqSfb58kVfsGBB7Wc+85m3isgFURSdlTkPZqBj25dpXpV0smTQ+S4iOm3Dhg1PD+TbDh+AyR106\/UXFU67c+Efx3fvONNRmxUgCGMGJIQahyhnkbPsG9sBlCcYZRKN5HJ+pmXYCwcgEIAlscWUMHBgfDUPKqzCCA2pyWMHF3ZTztydC2pbNkr90vWnfmD16y+7vGN\/fHZjDGbNmjVFRA5X1dcXi8W3quqhGeZuvwTscKZODbSnrfLfSY8wG2Naa2pqzlmyZMmSxsZG09LSoh\/5yEfCm2+++YY4jucl86ChqvflcrlfF4vFv7397W9fde2113YMW\/UR4X3ve1\/D0qVLD9+5c+eroij6d2aenSmPlbXeYK0Cw5mmMIBJdkRkqqurP7FixYqrBgus9knHpiPXll923oxJT917awNvmt2FXqmKiE0UQI2ilE8BmPH30L8flsRACXBGoCQw6gMWISAOACNAEPnEgGVfazFqBLFTzsEgZCCuQzdy3d25cFNYEz4MdQ86za3dFfMWqRvf\/v\/Wl3p+t6HLAkXkcg0sIvn2np6qSWPG1IdhePDOHTuP6+zuPEtVDw+CYHK6qiDN2A\/k5w0GwKG03QCATKlacRiG716zZs1vMiB3EyZMaCKi+YmGBDObTMBSVNUNIvLI+PHj\/z5hwoQ1Tz\/9dKu1tlhTU1NKSme5IAiqJk2aNG737t2HdHR0nEFEJwGYJiL5NOGdfDfOrFXd68013LRLklDnKIoWjR8\/\/l8ff\/zxnsFch33+lKYmcHMzZNkFrzxi2vbH7qyJW6f3giRvAyYVKFxifvsW6mhGC3r\/KekdgYEDwfhdQEkHnvHPk4OqScy2A6kHsdOEDKaOyIApb\/wyRaeIYoO2oFCytQ29X3y8q\/j77YE1BhAOGMbkRTUvVgoMhMRUXsKcgMSpKrGnMidbInnYlKOhGnGy14iIxFprmPmDGzdu\/HGSf0OSBnmLtfbGBPyc1JU1YccoERnn\/HLoMAxhrYVzLjLGxGEYWiLSOI6DKIpCZs7ncjlk69Ii4owxJCI81Fya4R7vIK+RhIq2UUReuXnz5pVDpZX2y8tMg5JV5x170qj2jXeOs8Ux0kOOIAYcl7dsOuOjYhZGHDCIHALXtwJW1e8eLi\/HIQaLT14LO\/glsH5giGSmtBIMxLtEKkxqVJMVRmCTY9od1OHyx2L8ob0WNaGB03S1WFlDlaPKpLmGsoX2fY1oh3LEy04bszKzGGOMiHxy7dq1X89qvqOPPvrEjo6OOwGMc34FGA+wxiHbRI7kZqHKz0ojbGbOLrNJj7MfS2ewjeZ7G8s2SPebJotoSETesXXr1pbKqHdAxsM+h40Ji2XmT59YvHXS7H\/vMg27OYyMknUKAyghThaKCgGRMTAugHGMTLOdr5BAQAmhgSAQdgALDAHMAr\/pWct9ypSW9hxgxJABmEEGzIYDEIlqHDktxiKxQKySiC8FaVpxUFVOIk6TBBc0wDSC\/RpLUakhMtMKBIBxzl2dgC89927y5MnTOjs7f2mMGZdWHwYy7wmA0qqMScxp9rjKkka6yXFyZg3rkATZIWhiwxl6JIlL+bXhgG+\/AViuFzeqOfa6e\/64dez0t3UURq\/jUIxT56LQgB2DBTAKGHEALFQZogaqPHDslirCZEtdqiq1H+3LP3yBKHMnp2pVlAggJmL\/ACeAI8q0cg00DmM4o8b2VvMd4H00MY2mt7f3unXr1l2eTYm84Q1vGBeG4c9F5Kg4jt1A0fYQkSZVHBclSj3VeAMSHwYD00CvHYrhUvH6NHn9o\/r6+s8Pt5rzjAr\/lFCpDv\/xgwvXTDvtDTtzY1aFVcYIWWeUQJZBMWBUIGyh7MAuB07OMfWpwn4+gYp4fqFQ0o9czlYnV65vHIj4+p+PupP2FcMGhgPQAOWxwU7mMArqQ4KxsgqQRtLGGGVmttZ+ddu2bR\/OnHc3a9as3NKlS38A4Kw0J7i3oUF7Y58MBZiB\/nawRTODfc5ALB+\/yZ2Mc+4PGzdu\/I9ly5ZFw81XPmPmSQrCE675wxOrxp907pb8hLsKOWNATkSNKoewxoCF\/VZNlHxQkTHF5QPLZq5U+z1S6n85S1NWAemfkDfTxCAyUFE4kXKgkTWLlXXbSp9vuDTzgcx15rUuWZfFhULhs62trZ\/KViFmzpyZ3759+\/WlUunNURS5xFTutZa8N7ANp3w2mDbMHtdgde0BwGkBBM65P9fX17+ffLGAh5ssf1aoT6lPeNoP\/7RmyamXv2FTYerVUTCWOVCyoYiSAVEeEAMNBMoJkPqlUrXcgDeAVS4D1P+sfWY5+8pEK2oy4V+fQTZ\/qAs7EK+vQjM455xR1d01NTXnPf3001\/Kgq+xsbFq9+7dPyOi9ydEVlOpkZ5pNWKg6HygG2hvvt1eyohCRIGq3tzQ0PDOlStXtu4rkeJZLXandWPAYPW\/n\/LeccW1X6+TbROtU0dxjlmU4tDBiMCI9sfPHml92ktuSkFqYI1NNrcbKARMip3hKFz6WIzbOmtQExo\/F2QftxMNV8NUaJT0opgoip7I5\/MXb968+b5M5cKdcsop9Vu3bv15b2\/vG5MJA2ZfKw\/DWSLzTG62ocxymkVg9lki59w1RHTFli1bivvD4nlWyZ\/U7K+1wvGhv7z\/Z+tGH\/WaLbmD\/x5wlTFaImsiAdj7dANATPvt\/9rzIRmrTMlSHUoVofRZbtKBUyjD9eeGAtoQDrwQEQVBYGpra383e\/bsVyfgK6daDj300FFbtmz5P+fcG1OnfV96K4ZjhocyvcMJoFItPoQfmNK0SESu2Lp162UJ+Aj7UY561tnHyT5DWQCYY3+y8LF\/nHX93B005eNdNePaw5qAc4hVIeIozf5ReaVNuuOR4BvgKUEcid9L4ucTEgSc0BAVKig3RGWneWU15TOdbbwXAEiafBWRXSLygZUrV7590aJFWzNMFhk9evSxbW1ti6y15yTbjkxKYt3Xkb37A7ZncqyZ8qEAMNbatar6ui1btnwlo9336yQ\/Z\/T3efC9v6+\/7PWlCbes\/ObqSa84dUthxoJiroF87VFVQAJiqHoKv2P2HEMlnyFMaFoOfkKXcQA7SqJoKgclLMiMEPEa0an2bxXYC7VokOlUe1zIFDTJ4EhnjOEgCNhae1MQBKdt3rz5JwlxoLzT8ZhjjnkjMz8I4PgoimLnHFdOytpbOmiQyanD0tz7AtpyITdZKp2QMVxS3eBCofCzgw8++MytW7fekQk29vsOf85JngpQSyN4XgscVGnt+eeeXdvx1KdHaccrg7gdiJxCIY4MKwJiJxAInOnTXkaBoDwKP8n\/ASA1cMaBRQHKQdmCIGjNjcUlj\/Xi9o48anLBHmdnqBzXUIX3FHhJU41J1iY8PmHChP95\/PHH\/y9DXhD0reXSiRMnzojj+L9F5P3GmEIQBAAgzjliZhps1dW++qZDUcSGyCUOFrRocpMZYwyMMWuMMf+9bt2636THj2dhVs3zxjLWJjD7WYS4XjU887zT3jG2d9Olo3raTy1EncmhGAciEhUmkSQq9nOFlfyuknI5TvxCE8cCowSlEMIxSIGd+XG4dElPAkAD0eFdqKGvsWoCipQ8sjGKop+o6lW7du3qyFiUQf2ghoaGs8Iw\/FwQBK+01qajOxylC5qfpah9fxZiZ86NEpGoqkk2M3U4535+1FFHNd9\/\/\/3bsXca2IEJwPTzFqTaMAHiWe865Q0Te7d8uFq7Ti9IsRY2BmIVKFQkrUkxabLFU8kvSFR42r9jJHx9hmUFQbErPwYffSLCbZ1VqA4YkqHMD8ZWGeCiqYhost\/NZF63mpl\/MG3atJ888MAD25I\/2RtrOXVPhZkxderU13Z2dl4hIqcFQZBLxuK6tF8irdb0X+wyMAO7UsNl67tDmeTK6D2tMafHGoZhu6reLiJf3LZt29JhHucBD8CyWUYjuLxCy4R46uNvOiZc+dAHq13P22pRnFaFImADoOgACh0ASOCHzqg6Apz3+YwHoDr\/byZgd74BlzwR4w\/tBVQHDCeDm7jMnOS0firJRTIZRowDcF+pVPr+mDFjbl29enX7fl6Qfj5TbW3tmVVVVR82xvyriIzK9JW4tGKYJREMZnIHY7FUblvK9CCnpIFUq5tkmSJUtdVa++vJkyd\/54knnliRvAdnAq5nVyPhBZTUP2xsgSRxMO6+4v3jJ6+993UNXTvPDAln5cUeVZBugJ0nQVuAYMSRz\/g4FmIH3x1lAMOK9nwDfegfEW7rqEoAKGVGStampsNyUhpWNpmclNAei+P4nvr6+pvXrl37lwxAnqkmKJtqIsL06dOP7OjoaBSRublc7jQiqkkBlC65SfpRkKn5Zu6l\/oFMMplVs\/5cuk09BVy61is5ph5mvp+Zb3\/5y1\/+21tvvXVNRZD6nHXoHTC9t2lDel\/DEeFhlbD24tNfmd+57vSC7Tw6UHtiTsz0WidhGUtsAZu2iVqAgN3hKL3w0RJu6yqgLh+gj\/ZH5X1q2aiXmdO7f1MURY\/W1NQ8ksvl7lq1atWiDEH1uTBBe1zgadOmzSoWi68hopNF5OW5XO7QOI7NYCYXfbSyyqiWBvIJM\/\/eEATBA4VCYXE+n\/\/jk08++WjmPZ9z4B1wABxAKyb0g76vetFF14X\/xQtmB21bjhvbu\/uwwOkUa+xkI3owhMdaW6wjlaqefH1w6eJ23Npm0FBdAHEApwrD7FS1W0Q6mXmbc259Pp\/f6JxbG4bhkhNPPPH+W265pXNvIHkOhDOJ3DIKFi5cGFx++eWnPPXUUy+vra09hJmnish0EZlsjKlT1eo0Gk+1c7pmIQFb0Vrbxcw7Aaytra1dXywW11ZVVT165pln3vvzn\/+8uwIL\/ZqznpegAAewlMEIAGUzvadv37TwL0HjXS2FeOvScT2dbQcHJGO\/eM\/quj9vj4KcMTbMV0cml+s69thjO8aPH79x4cKFOy666KKoubnZDnJOnvcLsTcwpjJnzpxg2bJlhXPOOWfcQw89dHB7e\/sYEanp6ekJmJlyuZwwc09DQ0PbqaeeunnZsmVb4zguLl++PBogMHmhj\/VFN6+ZtAlUXoLY4mcz6DM7\/qxP9ZxtT38Wvt\/+tmQOBO4D8VhfvJJU8agpGW60oBGmcYB9F01+b10l6F5sQug\/kGzQ\/R4VxzsiIzIiIzIiIzIiIzIiIzIiIzIiIzIiIzIiIzIiIzIiIzIiIzIiIzIiIzIiIzIiIzIiIzIiIzIiIzIiIzIiIzIiIzIiIzIiIzIiI\/KsyP8HYtv0ssu3KeUAAAAASUVORK5CYII=\" alt=\"Onground Media logo\" width=\"34\" height=\"34\"><\/span>\r\n      <span class=\"brand-text\"><b>Onground Media<\/b><small>SEO Toolkit<\/small><\/span>\r\n    <\/a>\r\n    <button class=\"icon-btn\" id=\"themeBtn\" type=\"button\" aria-label=\"Switch between light and dark theme\">\r\n      <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z\"\/><\/svg><span>Theme<\/span>\r\n    <\/button>\r\n  <\/div>\r\n<\/header>\r\n\r\n<section class=\"hero\">\r\n  <div class=\"wrap hero-in\">\r\n    <div>\r\n      <p class=\"eyebrow\">E-commerce and specialized SEO<\/p>\r\n      <h1>Tools for listings, feeds, app stores and AI search<\/h1>\r\n      <p class=\"lead\">Eight working tools for digital marketers. Pick one, fill in your product or page, and copy the result. Everything runs in your browser and nothing you type is sent anywhere.<\/p>\r\n      <div class=\"search\">\r\n        <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><circle cx=\"11\" cy=\"11\" r=\"7\"\/><path d=\"m20 20-3.5-3.5\"\/><\/svg>\r\n        <input id=\"toolSearch\" type=\"search\" placeholder=\"Find a tool: title, feed, ASO, voice, AI search\" aria-label=\"Search tools\" autocomplete=\"off\">\r\n      <\/div>\r\n      <div class=\"chips\" id=\"groupChips\" role=\"group\" aria-label=\"Filter tools by group\"><\/div>\r\n    <\/div>\r\n    <svg class=\"hero-art\" viewBox=\"0 0 300 190\" aria-hidden=\"true\">\r\n      <rect x=\"18\" y=\"124\" width=\"34\" height=\"46\" rx=\"6\" fill=\"#4F46E5\" opacity=\".9\"\/>\r\n      <rect x=\"68\" y=\"98\" width=\"34\" height=\"72\" rx=\"6\" fill=\"#4F46E5\" opacity=\".75\"\/>\r\n      <rect x=\"118\" y=\"72\" width=\"34\" height=\"98\" rx=\"6\" fill=\"#4F46E5\" opacity=\".6\"\/>\r\n      <rect x=\"168\" y=\"46\" width=\"34\" height=\"124\" rx=\"6\" fill=\"#4F46E5\" opacity=\".45\"\/>\r\n      <polyline points=\"14,118 78,84 128,92 196,40 262,16\" fill=\"none\" stroke=\"#FF6B35\" stroke-width=\"7\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/>\r\n      <polygon points=\"282,8 250,10 266,34\" fill=\"#FF6B35\"\/>\r\n    <\/svg>\r\n  <\/div>\r\n<\/section>\r\n\r\n<main class=\"wrap shell\">\r\n  <nav class=\"rail\" aria-label=\"SEO tools\">\r\n    <div class=\"rail-list\" id=\"toolList\"><\/div>\r\n    <div class=\"legend\" aria-label=\"Level guide\">\r\n      <div><span class=\"dot\"><\/span> Intermediate: fill in a few fields and go<\/div>\r\n      <div><span class=\"dot adv\"><\/span> Advanced: checks real feed or content data<\/div>\r\n    <\/div>\r\n  <\/nav>\r\n  <section class=\"stage\" id=\"stage\" aria-live=\"polite\"><\/section>\r\n<\/main>\r\n\r\n<footer>\r\n  <div class=\"wrap\">\r\n    <span>Onground Media SEO Toolkit<\/span>\r\n    <span>Drafts are starting points. Review every title, description and feed before you publish.<\/span>\r\n  <\/div>\r\n<\/footer>\r\n<div id=\"toast\" role=\"status\"><\/div>\r\n\r\n<script>\r\n(function(){\r\n'use strict';\r\n\/* ---------- helpers ---------- *\/\r\nconst $=(s,r=document)=>r.querySelector(s), $$=(s,r=document)=>[...r.querySelectorAll(s)];\r\nconst esc=s=>String(s==null?'':s).replace(\/[&<>\"']\/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[c]));\r\nconst list=s=>String(s||'').split(\/[,\\n;|]+\/).map(x=>x.trim()).filter(Boolean);\r\nconst cap=s=>String(s||'').replace(\/(^|[\\s(\\-\u2013\/])(\\p{L})\/gu,(m,a,b)=>a+b.toUpperCase());\r\nconst up1=s=>s?s.charAt(0).toUpperCase()+s.slice(1):s;\r\nconst words=s=>(String(s).trim().match(\/\\S+\/g)||[]).length;\r\nconst pick=a=>a[Math.floor(Math.random()*a.length)];\r\nconst shuffle=a=>{a=a.slice();for(let i=a.length-1;i>0;i--){const j=Math.floor(Math.random()*(i+1));[a[i],a[j]]=[a[j],a[i]]}return a};\r\nconst uniq=a=>[...new Set(a)];\r\nconst trimTo=(s,n)=>{if(s.length<=n)return s;let c=s.slice(0,n+1);const i=c.lastIndexOf(' ');c=c.slice(0,i>0?i:n).replace(\/[\\s,\\-\u2013|:&]+$\/,'');return c};\r\nconst joinList=a=>a.length<2?(a[0]||''):a.length===2?a.join(' and '):a.slice(0,-1).join(', ')+' and '+a[a.length-1];\r\nconst clean=s=>s.replace(\/\\s+\/g,' ').replace(\/[\\s\u2013|,:&-]+$\/,'').trim();\r\nconst empty=m=>`<p class=\"empty\">${esc(m)}<\/p>`;\r\nconst YEAR=new Date().getFullYear();\r\n\r\nlet tt;\r\nfunction toast(m){const t=$('#toast');t.textContent=m;t.classList.add('show');clearTimeout(tt);tt=setTimeout(()=>t.classList.remove('show'),2000)}\r\nasync function copyText(text){\r\n  try{await navigator.clipboard.writeText(text);return true}catch(e){}\r\n  try{const ta=document.createElement('textarea');ta.value=text;ta.style.cssText='position:fixed;opacity:0;top:0;left:0';document.body.appendChild(ta);ta.select();const ok=document.execCommand('copy');ta.remove();return ok}catch(e){return false}\r\n}\r\ndocument.addEventListener('click',async e=>{\r\n  const b=e.target.closest('[data-copy],[data-from]');if(!b)return;\r\n  let text=b.dataset.copy;\r\n  if(text===undefined){const n=$(b.dataset.from);text=n?(n.matches('textarea,input')?n.value:n.innerText):''}\r\n  toast(await copyText(text)?'Copied to clipboard':'Copy was blocked. Select the text and press Ctrl+C');\r\n});\r\n\r\nconst ICON={\r\n  tag:'<path d=\"M20.6 13.4 13.4 20.6a2 2 0 0 1-2.8 0L3 13V3h10l7.6 7.6a2 2 0 0 1 0 2.8z\"\/><circle cx=\"7.5\" cy=\"7.5\" r=\"1.4\"\/>',\r\n  doc:'<path d=\"M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z\"\/><path d=\"M14 3v5h5M9 13h6M9 17h6\"\/>',\r\n  grid:'<rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" rx=\"1.5\"\/><rect x=\"14\" y=\"3\" width=\"7\" height=\"7\" rx=\"1.5\"\/><rect x=\"3\" y=\"14\" width=\"7\" height=\"7\" rx=\"1.5\"\/><rect x=\"14\" y=\"14\" width=\"7\" height=\"7\" rx=\"1.5\"\/>',\r\n  cart:'<circle cx=\"9\" cy=\"20\" r=\"1.5\"\/><circle cx=\"18\" cy=\"20\" r=\"1.5\"\/><path d=\"M2 3h3l2.7 12.4a2 2 0 0 0 2 1.6h7.7a2 2 0 0 0 2-1.5L21 8H6\"\/>',\r\n  shield:'<path d=\"M12 3 4 6v6c0 4.5 3.3 8 8 9 4.7-1 8-4.5 8-9V6z\"\/><path d=\"m9 12 2 2 4-4\"\/>',\r\n  phone:'<rect x=\"7\" y=\"2\" width=\"10\" height=\"20\" rx=\"2.5\"\/><path d=\"M11 18h2\"\/>',\r\n  mic:'<rect x=\"9\" y=\"2\" width=\"6\" height=\"12\" rx=\"3\"\/><path d=\"M5 11a7 7 0 0 0 14 0M12 18v4\"\/>',\r\n  spark:'<path d=\"M12 3l1.8 5.2L19 10l-5.2 1.8L12 17l-1.8-5.2L5 10l5.2-1.8z\"\/><path d=\"M19 16l.8 2.2L22 19l-2.2.8L19 22l-.8-2.2L16 19l2.2-.8z\"\/>'\r\n};\r\nconst svg=n=>`<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">${ICON[n]}<\/svg>`;\r\n\r\n\/* form + result helpers *\/\r\nconst F=(t,name,label,o={})=>{\r\n  const id=`${t}-${name}`,hint=o.hint?`<small class=\"hint\">${o.hint}<\/small>`:'';\r\n  let ctl;\r\n  if(o.options)ctl=`<select id=\"${id}\">${o.options.map(([v,l])=>`<option value=\"${esc(v)}\"${v===o.value?' selected':''}>${esc(l)}<\/option>`).join('')}<\/select>`;\r\n  else if(o.rows)ctl=`<textarea id=\"${id}\" rows=\"${o.rows}\" placeholder=\"${esc(o.ph||'')}\"${o.mono?' class=\"mono\"':''}>${esc(o.value||'')}<\/textarea>`;\r\n  else ctl=`<input id=\"${id}\" type=\"${o.type||'text'}\" value=\"${esc(o.value||'')}\" placeholder=\"${esc(o.ph||'')}\" autocomplete=\"off\">`;\r\n  return `<div class=\"field${o.span?' span':''}\"><label for=\"${id}\">${label}<\/label>${ctl}${hint}<\/div>`;\r\n};\r\nconst shell=(t,form,btn,cls='',note=true)=>`<div class=\"split ${cls}\"><form class=\"panel in\" id=\"${t}-form\" novalidate>${note?'<p class=\"sample-note\">Example data is loaded so you can see the result. Replace it with your own.<\/p>':''}${form}<div class=\"actions\"><button class=\"btn btn-cta\" type=\"submit\">${btn}<\/button><\/div><\/form><div class=\"panel out\" id=\"${t}-out\" aria-live=\"polite\"><\/div><\/div>`;\r\nconst wire=(root,t,run)=>{root.querySelector(`#${t}-form`).addEventListener('submit',e=>{e.preventDefault();run()});run()};\r\nconst val=(root,t,n)=>root.querySelector(`#${t}-${n}`).value.trim();\r\nconst outEl=(root,t)=>root.querySelector(`#${t}-out`);\r\nconst meter=(len,limit)=>{const pct=Math.min(100,len\/limit*100),c=len>limit?'bad':len>limit*.92?'warn':'';return `<div class=\"meter\"><span class=\"${c}\" style=\"width:${pct.toFixed(1)}%\"><\/span><\/div>`};\r\nconst resRow=(text,o={})=>`<div class=\"res\"><p class=\"res-text\">${esc(text)}<\/p><div class=\"res-meta\">${o.limit?`<div class=\"meter-wrap\">${meter(text.length,o.limit)}<span class=\"count${text.length>o.limit?' over':''}\">${text.length} \/ ${o.limit}<\/span><\/div>`:`<span class=\"count\">${words(text)} words<\/span>`}${(o.chips||[]).join('')}<button type=\"button\" class=\"copy\" data-copy=\"${esc(text)}\">Copy<\/button><\/div><\/div>`;\r\nconst tag=(t,c='')=>`<span class=\"tag ${c}\">${esc(t)}<\/span>`;\r\nconst block=(title,body,copy)=>`<div class=\"block\"><h4><span>${esc(title)}<\/span>${copy!==undefined?`<button type=\"button\" class=\"copy\" data-copy=\"${esc(copy)}\">Copy<\/button>`:''}<\/h4>${body}<\/div>`;\r\n\r\n\/* ================= 1. PRODUCT TITLE ================= *\/\r\nconst MK={\r\n  google:[150,'Google Shopping','Put the product type and brand in the first 70 characters. Google can cut off the rest in Shopping results.'],\r\n  amazon:[200,'Amazon','Skip promotional phrases such as \"best seller\" or \"free shipping\", and avoid all-caps words. Follow your category style guide.'],\r\n  flipkart:[100,'Flipkart','Keep it factual and match brand, model and key attributes to your catalog data. Treat 100 characters as a guideline and check your seller dashboard for category rules.'],\r\n  store:[70,'Your store page title','Page titles near 60 to 70 characters are less likely to be cut off in search results.'],\r\n  etsy:[140,'Etsy','Lead with what the item is. Shoppers scan the first few words.']\r\n};\r\nconst J=(...p)=>p.filter(Boolean).join(' ');\r\nconst TITLE_PATTERNS=[\r\n  (d,k,v)=>J(d.brand,d.product)+(k?' \u2013 '+d.feats.slice(0,k).join(', '):'')+(v&&d.variant?` (${d.variant})`:''),\r\n  (d,k,v)=>(d.kw?cap(d.kw)+' | ':'')+J(d.brand,d.product)+(v&&d.variant?' '+d.variant:'')+(k?' | '+d.feats.slice(0,k).join(' | '):''),\r\n  (d,k,v)=>J(d.brand,d.product)+(d.aud?` for ${d.aud}`:'')+(k?' \u2013 '+d.feats.slice(0,k).join(', '):'')+(v&&d.variant?`, ${d.variant}`:''),\r\n  (d,k,v)=>d.product+(d.brand?' by '+d.brand:'')+(k?' | '+d.feats.slice(0,k).join(' | '):'')+(v&&d.variant?' | '+d.variant:''),\r\n  (d,k,v)=>(d.kw?cap(d.kw)+': ':'')+J(d.brand,d.product)+(k?' with '+d.feats.slice(0,k).join(' & '):'')+(v&&d.variant?' \u2013 '+d.variant:''),\r\n  (d,k,v)=>J(k?d.feats[0]:'',d.product)+(d.aud?` for ${d.aud}`:'')+(d.brand?` | ${d.brand}`:'')+(v&&d.variant?` (${d.variant})`:''),\r\n  (d,k,v)=>`Buy ${d.product} Online \u2013 `+J(d.brand,k?d.feats.slice(0,k).join(', '):'',v?d.variant:''),\r\n  (d,k,v)=>J(d.brand,d.kw?cap(d.kw):d.product)+(k?' \u2013 '+d.feats.slice(0,Math.min(k,2)).join(', '):'')+(v&&d.variant?' \u2013 '+d.variant:'')\r\n];\r\nfunction toolTitle(root){\r\n  const t='pt';\r\n  root.innerHTML=shell(t,`<div class=\"grid2\">`+\r\n    F(t,'brand','Brand',{value:'Aroma Roots'})+\r\n    F(t,'product','Product',{value:'Cold Pressed Coconut Oil'})+\r\n    F(t,'kw','Main keyword',{value:'coconut oil for hair',hint:'What shoppers type into search'})+\r\n    F(t,'aud','Who it is for (optional)',{value:'Men & Women'})+\r\n    F(t,'feat','Key features',{span:1,value:'100% Pure, Chemical Free, Glass Bottle',hint:'Separate with commas, most important first'})+\r\n    F(t,'variant','Size, color or pack',{span:1,value:'500 ml, Pack of 2'})+\r\n    F(t,'mk','Where will it be listed?',{span:1,value:'amazon',options:Object.entries(MK).map(([k,v])=>[k,`${v[1]} (${v[0]} characters)`])})+\r\n    `<\/div>`,'Generate titles');\r\n  wire(root,t,()=>{\r\n    const d={brand:val(root,t,'brand'),product:val(root,t,'product'),kw:val(root,t,'kw'),aud:val(root,t,'aud'),feats:list(val(root,t,'feat')),variant:val(root,t,'variant')};\r\n    const [limit,name,tip]=MK[val(root,t,'mk')],o=outEl(root,t);\r\n    if(!d.product){o.innerHTML=empty('Enter a product name to generate titles.');return}\r\n    const seen=new Set(),rows=[];\r\n    for(const p of TITLE_PATTERNS){\r\n      let s=null;\r\n      outer:for(let k=d.feats.length;k>=0;k--){for(const v of [true,false]){const c=clean(p(d,k,v));if(c.length<=limit){s=c;break outer}}}\r\n      if(!s)s=trimTo(clean(p(d,0,false)),limit);\r\n      if(!seen.has(s.toLowerCase())){seen.add(s.toLowerCase());rows.push(s)}\r\n    }\r\n    o.innerHTML=`<div class=\"out-head\"><h3>${rows.length} titles for ${esc(name)}<\/h3>${tag('Limit '+limit,'info')}<\/div><p class=\"out-sub\">Longer features are dropped first so every title fits the limit.<\/p>`+\r\n      rows.map(s=>{\r\n        const ok=d.kw&&d.kw.toLowerCase().split(\/\\s+\/).every(w=>s.toLowerCase().includes(w));\r\n        return resRow(s,{limit,chips:[d.kw?(ok?tag('Keyword included','ok'):tag('Keyword missing','warn')):'']});\r\n      }).join('')+`<div class=\"tips\"><b>Tip for ${esc(name)}<\/b>${esc(tip)}<\/div>`;\r\n  });\r\n}\r\n\r\n\/* ================= 2. PRODUCT DESCRIPTION ================= *\/\r\nconst CONN=['a detail you notice from the first use','chosen to make everyday use easier','there so you can buy with confidence','one less thing to worry about','built into every unit','a small thing that makes a real difference'];\r\nfunction toolDesc(root){\r\n  const t='pd';\r\n  root.innerHTML=shell(t,`<div class=\"grid2\">`+\r\n    F(t,'brand','Brand',{value:'Aroma Roots'})+\r\n    F(t,'product','Product',{value:'Cold Pressed Coconut Oil'})+\r\n    F(t,'kw','Main keyword',{value:'coconut oil for hair'})+\r\n    F(t,'aud','Who it is for',{value:'people who want softer, healthier hair'})+\r\n    F(t,'feat','Key features',{span:1,rows:2,value:'100% pure, cold pressed, no added chemicals, glass bottle',hint:'Separate with commas'})+\r\n    F(t,'benefit','Main benefit',{span:1,value:'smooth, nourished hair'})+\r\n    F(t,'offer','Offer or promise (optional)',{span:1,value:'get free delivery on orders above \u20b9499'})+\r\n    F(t,'tone','Tone',{value:'friendly',options:[['friendly','Friendly'],['professional','Professional'],['luxury','Luxury'],['punchy','Short and punchy']]})+\r\n    F(t,'len','Length',{value:'medium',options:[['short','Short'],['medium','Medium'],['long','Long']]})+\r\n    `<\/div>`,'Write description');\r\n  wire(root,t,()=>{\r\n    const brand=val(root,t,'brand'),p=val(root,t,'product'),kw=val(root,t,'kw'),aud=val(root,t,'aud'),benefit=val(root,t,'benefit'),offer=val(root,t,'offer'),tone=val(root,t,'tone'),len=val(root,t,'len');\r\n    const feats=list(val(root,t,'feat')),f1=feats[0]||'',f2=feats[1]||'',o=outEl(root,t);\r\n    if(!p){o.innerHTML=empty('Enter a product name to write a description.');return}\r\n    const bb=brand?` from ${brand}`:'',kwx=kw||p;\r\n    const OPEN={\r\n      friendly:[`Say hello to the ${p}${bb}. It is made for people who want ${benefit||'something that just works'} without the fuss.`,`Looking for ${kwx} you can count on? The ${p}${bb} is ready when you are.`,`The ${p}${bb} brings ${f1||'quality'} to your day and keeps things simple.`],\r\n      professional:[`The ${p}${bb} is built for ${aud||'customers'} who expect dependable quality.`,`${up1(kwx)}, done properly: the ${p}${bb} combines ${f1||'careful design'} with ${f2||'consistent results'}.`,`Designed with ${f1||'attention to detail'} in mind, the ${p}${bb} delivers consistent results.`],\r\n      luxury:[`Elevate your routine with the ${p}${bb}, made with ${f1||'exceptional care'}.`,`A refined choice for ${aud||'those who appreciate the finer details'}: the ${p}${bb}.`,`Every detail of the ${p}${bb} has been considered, from ${f1||'the materials'} to the finish.`],\r\n      punchy:[`${up1(p)}. ${up1(f1||'Built right')}. ${aud?`Made for ${aud}.`:'Ready to use.'}`,`Skip the guesswork. The ${p}${bb} gets it done.`,`Better ${kwx}. Fewer compromises.`]\r\n    }[tone];\r\n    const BODY=[`It features ${joinList(feats)||'thoughtful design'}, so you get ${benefit||'a better experience every time'}.`,`What you get: ${joinList(feats)||'a well-made product'}.`,`With ${joinList(feats)||'quality materials'}, it is a practical choice for ${aud||'everyday use'}.`];\r\n    const CLOSE={friendly:[`Add the ${p} to your cart today${offer?` and ${offer}`:''}.`,`Ready to try it? ${offer?up1(offer)+'.':'Add it to your cart.'}`],professional:[`Order the ${p} today${offer?` and ${offer}`:''}.`],luxury:[`Treat yourself to the ${p}${offer?`, and ${offer}`:''}.`],punchy:[`Order now${offer?`, and ${offer}`:''}.`]}[tone];\r\n    const opener=pick(OPEN),body=pick(BODY),close=pick(CLOSE);\r\n    const conns=shuffle(CONN),n=len==='short'?0:len==='medium'?3:5;\r\n    const bullets=feats.slice(0,n).map((f,i)=>`\u2022 ${up1(f)}: ${conns[i%conns.length]}.`).join('\\n');\r\n    const audLine=aud&&len==='long'?`\\n\\nWho it suits: ${aud}. If you have been searching for ${kwx}, this is a straightforward place to start.`:'';\r\n    const full=len==='short'?`${opener} ${body}\\n\\n${close}`:`${opener} ${body}${audLine}\\n\\n${bullets}\\n\\n${close}`;\r\n    const short=trimTo(`${opener} ${body}`,320);\r\n    const meta=trimTo(`${up1(kwx)}: ${p}${bb}. ${joinList(feats.slice(0,2))}${offer?`. ${up1(offer)}`:''}`,154).replace(\/[\\s,.:;-]+$\/,'')+'.';\r\n    const kwOk=kw&&full.toLowerCase().includes(kw.toLowerCase());\r\n    o.innerHTML=`<div class=\"out-head\"><h3>Description<\/h3><button type=\"button\" class=\"btn btn-ghost btn-sm\" id=\"pd-again\">Write another version<\/button><\/div>`+\r\n      `<div class=\"res\"><p class=\"res-text\">${esc(full)}<\/p><div class=\"res-meta\"><span class=\"count\">${words(full)} words<\/span>${kw?(kwOk?tag('Keyword included','ok'):tag('Keyword missing','warn')):''}<button type=\"button\" class=\"copy\" data-copy=\"${esc(full)}\">Copy<\/button><\/div><\/div>`+\r\n      block('Short version for listing cards',`<p>${esc(short)}<\/p>`,short)+\r\n      block('Meta description',`<p>${esc(meta)}<\/p><div class=\"meter-wrap\">${meter(meta.length,155)}<span class=\"count\">${meta.length} \/ 155<\/span><\/div>`,meta)+\r\n      `<p class=\"note\">Each click writes a new combination of opening, body and closing lines.<\/p>`;\r\n    o.querySelector('#pd-again').addEventListener('click',()=>root.querySelector(`#${t}-form`).requestSubmit());\r\n  });\r\n}\r\n\r\n\/* ================= 3. CATEGORY PAGE CONTENT ================= *\/\r\nfunction toolCategory(root){\r\n  const t='cp';\r\n  root.innerHTML=shell(t,`<div class=\"grid2\">`+\r\n    F(t,'cat','Category name',{value:'Hair Oils'})+\r\n    F(t,'store','Store name',{value:'Aroma Roots'})+\r\n    F(t,'kw','Main keyword',{value:'hair oil online',hint:'Used in the first sentence'})+\r\n    F(t,'loc','Delivery area (optional)',{value:'across India'})+\r\n    F(t,'sub','Popular products or subcategories',{span:1,value:'coconut oil, argan oil, onion hair oil, castor oil',hint:'Separate with commas'})+\r\n    F(t,'factors','What buyers should compare',{span:1,value:'ingredients, bottle size, hair type',hint:'Becomes the buying guide'})+\r\n    F(t,'usp','Store promises (optional)',{span:1,value:'free delivery above \u20b9499, easy 7-day returns',hint:'Only add what is true for your store'})+\r\n    `<\/div>`,'Write category content');\r\n  wire(root,t,()=>{\r\n    const cat=val(root,t,'cat'),store=val(root,t,'store'),kw=val(root,t,'kw')||cat,loc=val(root,t,'loc'),sub=list(val(root,t,'sub')),fac=list(val(root,t,'factors')),usp=list(val(root,t,'usp')),o=outEl(root,t);\r\n    if(!cat){o.innerHTML=empty('Enter a category name to write the page content.');return}\r\n    const cl=cat.toLowerCase(),f=fac.length?fac:['price','brand','customer reviews'],at=store?` at ${store}`:'';\r\n    const metaTitle=trimTo(`${cat}${store?` | ${store}`:''} \u2013 Shop ${up1(kw)}`,60);\r\n    const metaDesc=trimTo(`Shop ${cl}${at}. ${sub.length?`Browse ${joinList(sub.slice(0,3))} and more.`:'Compare options and choose with confidence.'}${usp.length?' '+up1(usp[0])+'.':''}`,155);\r\n    const h1=cat;\r\n    const p1=`Looking for ${kw}? ${store||'Our store'} brings together a carefully chosen range of ${cl}${loc?`, delivered ${loc}`:''}, so you can compare options in one place instead of searching across many sites.`;\r\n    const p2=(sub.length?`Popular picks in this category include ${joinList(sub)}. `:'')+`Use the filters on this page to narrow the range by ${joinList(f.slice(0,3))}.`;\r\n    const p3=usp.length?`When you shop${at}, you get ${joinList(usp)}.`:'';\r\n    const intro=[p1,p2,p3].filter(Boolean).join('\\n\\n');\r\n    const guideH=`How to choose the right ${cl}`;\r\n    const guide=f.slice(0,5).map(x=>`${up1(x)}: check this first, because it decides how well the product fits what you need.`);\r\n    const faqs=[[`How do I choose the right ${cl}?`,`Start with ${joinList(f.slice(0,3))}. Compare two or three products side by side, then read recent reviews before you decide.`],[`What can I buy in ${cl}${at}?`,sub.length?`You can browse ${joinList(sub)} and more. Use the filters to narrow by ${f[0]}.`:`Use the filters on this page to browse by ${joinList(f.slice(0,3))}.`]];\r\n    if(usp.length)faqs.push([`What does ${store||'the store'} offer when I order ${cl}?`,`${up1(joinList(usp))}.`]);\r\n    const htmlOut=`<h1>${h1}<\/h1>\\n${[p1,p2,p3].filter(Boolean).map(x=>`<p>${x}<\/p>`).join('\\n')}\\n<h2>${guideH}<\/h2>\\n<ul>\\n${guide.map(x=>`  <li>${x}<\/li>`).join('\\n')}\\n<\/ul>\\n<h2>Frequently asked questions<\/h2>\\n${faqs.map(([q,a])=>`<h3>${q}<\/h3>\\n<p>${a}<\/p>`).join('\\n')}`;\r\n    const wc=words(intro),first100=intro.split(\/\\s+\/).slice(0,100).join(' ').toLowerCase().includes(kw.toLowerCase());\r\n    o.innerHTML=`<div class=\"out-head\"><h3>Category page content<\/h3><button type=\"button\" class=\"btn btn-primary btn-sm\" data-from=\"#cp-html\">Copy all as HTML<\/button><\/div>`+\r\n      `<div class=\"res-meta\" style=\"margin-bottom:6px\">${tag(wc+' words in intro','info')}${first100?tag('Keyword in first 100 words','ok'):tag('Keyword not in first 100 words','warn')}${tag(faqs.length+' FAQ answers','info')}<\/div>`+\r\n      block('Meta title',`<p>${esc(metaTitle)}<\/p><div class=\"meter-wrap\">${meter(metaTitle.length,60)}<span class=\"count\">${metaTitle.length} \/ 60<\/span><\/div>`,metaTitle)+\r\n      block('Meta description',`<p>${esc(metaDesc)}<\/p><div class=\"meter-wrap\">${meter(metaDesc.length,155)}<span class=\"count\">${metaDesc.length} \/ 155<\/span><\/div>`,metaDesc)+\r\n      block('H1',`<p><b>${esc(h1)}<\/b><\/p>`,h1)+\r\n      block('Intro text',`<p class=\"prose\">${esc(intro)}<\/p>`,intro)+\r\n      block(guideH,`<ul>${guide.map(x=>`<li>${esc(x)}<\/li>`).join('')}<\/ul>`,guideH+'\\n'+guide.map(x=>'- '+x).join('\\n'))+\r\n      block('FAQ',faqs.map(([q,a])=>`<p><b>${esc(q)}<\/b><br>${esc(a)}<\/p>`).join(''),faqs.map(([q,a])=>q+'\\n'+a).join('\\n\\n'))+\r\n      block('HTML for your page',`<pre class=\"code\" id=\"cp-html\">${esc(htmlOut)}<\/pre>`);\r\n  });\r\n}\r\n\r\n\/* ================= 4. MARKETPLACE KEYWORDS ================= *\/\r\nconst STOP=new Set('a an and the for of with in on to by at or from is are be it as your you this that'.split(' '));\r\nfunction toolKeywords(root){\r\n  const t='mk';\r\n  root.innerHTML=shell(t,`<div class=\"grid2\">`+\r\n    F(t,'seed','Product keyword',{span:1,value:'coconut oil',hint:'The plain name of the product'})+\r\n    F(t,'mk','Marketplace',{value:'amazon-in',options:[['amazon-in','Amazon.in'],['amazon-com','Amazon.com'],['flipkart','Flipkart']]})+\r\n    F(t,'aud','Audiences (optional)',{value:'men, women, kids',hint:'Leave empty for defaults'})+\r\n    F(t,'attr','Attributes (optional)',{value:'cold pressed, organic, pure',hint:'Material, type, color, size'})+\r\n    F(t,'price','Price points',{value:'299, 499, 999',hint:'Numbers only'})+\r\n    `<\/div>`,'Find keywords');\r\n  let sel=new Set(),all=[],mkt='amazon-in';\r\n  const o=outEl(root,t),enc=new TextEncoder();\r\n  function terms(){\r\n    const src=sel.size?[...sel]:all.flatMap(g=>g.items);\r\n    const seen=new Set(),ws=[];\r\n    src.join(' ').toLowerCase().split(\/[^\\p{L}\\p{N}]+\/u).forEach(w=>{if(w&&!STOP.has(w)&&!seen.has(w)){seen.add(w);ws.push(w)}});\r\n    const fl=mkt==='flipkart';let txt='';\r\n    for(const w of ws){const next=fl?(txt?txt+', '+w:w):(txt?txt+' '+w:w);if(!fl&&enc.encode(next).length>249)break;txt=next}\r\n    return {txt,bytes:enc.encode(txt).length,n:txt?txt.split(fl?', ':' ').length:0,fl};\r\n  }\r\n  function paintTerms(){\r\n    const r=terms(),box=o.querySelector('#mk-terms');if(!box)return;\r\n    box.innerHTML=`<h4><span>${r.fl?'Search tags for your Flipkart listing':'Backend search terms (Amazon)'}<\/span><button type=\"button\" class=\"copy\" data-copy=\"${esc(r.txt)}\">Copy<\/button><\/h4><p class=\"mono prose\">${esc(r.txt)||'Select keywords above.'}<\/p>`+(r.fl?`<span class=\"count\">${r.n} unique words<\/span>`:`<div class=\"meter-wrap\">${meter(r.bytes,250)}<span class=\"count\">${r.bytes} \/ 250 bytes<\/span><\/div>`)+`<p class=\"note\">${sel.size?`Built from your ${sel.size} selected keywords.`:'Built from every keyword shown. Select the ones you want to narrow it down.'} Duplicate words and filler words are removed.${r.fl?'':' Do not repeat words that are already in your title.'}<\/p>`;\r\n  }\r\n  wire(root,t,()=>{\r\n    const k=val(root,t,'seed').toLowerCase();mkt=val(root,t,'mk');sel=new Set();\r\n    if(!k){o.innerHTML=empty('Enter a product keyword to find ideas.');return}\r\n    const india=mkt!=='amazon-com',cur=india?'\u20b9':'$';\r\n    const auds=list(val(root,t,'aud')),attrs=list(val(root,t,'attr')).map(x=>x.toLowerCase()),prices=list(val(root,t,'price')).filter(x=>\/^\\d+$\/.test(x));\r\n    const A=auds.length?auds:['men','women','kids','home use','gifting'];\r\n    all=[\r\n      {name:'Buying intent',items:[`best ${k}`,`buy ${k} online`,`${k} price`,`top rated ${k}`,`original ${k}`,`${k} combo`,`${k} deals`,`${k} with offers`,`premium ${k}`,`cheap ${k}`]},\r\n      {name:'Audience and use',items:A.map(a=>`${k} for ${a}`).concat([`${k} for daily use`])},\r\n      {name:'Price',items:prices.map(p=>`${k} under ${cur}${p}`).concat([`budget ${k}`])},\r\n      {name:'Attributes',items:attrs.flatMap(a=>[`${a} ${k}`,`${k} ${a}`])},\r\n      {name:'Long-tail and questions',items:[`which ${k} is best`,`best ${k} ${YEAR}`,`${k} pack of 2`,`${k} pack of 3`,`${k} with free delivery`,`${k} for ${A[0]} ${attrs[0]||'daily use'}`].concat(india?[`${k} cash on delivery`]:[`${k} prime eligible`])},\r\n      {name:'Occasions',items:india?[`${k} gift for diwali`,`${k} gift set`,`${k} for festival`,`${k} for wedding gift`]:[`${k} gift set`,`${k} christmas gift`,`${k} black friday deal`,`${k} birthday gift`]}\r\n    ].map(g=>({name:g.name,items:uniq(g.items.filter(Boolean))})).filter(g=>g.items.length);\r\n    const total=all.reduce((a,g)=>a+g.items.length,0);\r\n    o.innerHTML=`<div class=\"out-head\"><h3>${total} keyword ideas<\/h3><button type=\"button\" class=\"btn btn-ghost btn-sm\" data-copy=\"${esc(all.flatMap(g=>g.items).join('\\n'))}\">Copy all<\/button><\/div><p class=\"out-sub\">Click keywords to select them. Your selection feeds the box at the bottom.<\/p>`+\r\n      all.map(g=>`<div class=\"kgroup\"><h4><span>${esc(g.name)}<\/span><span class=\"count\">${g.items.length}<\/span><\/h4><div class=\"kchips\">${g.items.map(i=>`<button type=\"button\" class=\"kchip\" aria-pressed=\"false\" data-k=\"${esc(i)}\">${esc(i)}<\/button>`).join('')}<\/div><\/div>`).join('')+\r\n      `<div class=\"block\" id=\"mk-terms\"><\/div><div class=\"tips\"><b>Check demand before you use these<\/b>These ideas come from common shopper phrasing patterns, not live search data. Type your best picks into the ${mkt==='flipkart'?'Flipkart':'Amazon'} search bar and keep the ones that show up as suggestions.<\/div>`;\r\n    paintTerms();\r\n  });\r\n  o.addEventListener('click',e=>{const b=e.target.closest('.kchip');if(!b)return;const k=b.dataset.k;if(sel.has(k)){sel.delete(k);b.setAttribute('aria-pressed','false')}else{sel.add(k);b.setAttribute('aria-pressed','true')}paintTerms()});\r\n}\r\n\r\n\/* ================= 5. MERCHANT FEED CHECKER ================= *\/\r\nfunction parseTable(text){\r\n  text=text.replace(\/^\\uFEFF\/,'');\r\n  const first=text.split(\/\\r?\\n\/)[0]||'',tabs=(first.match(\/\\t\/g)||[]).length,commas=(first.match(\/,\/g)||[]).length,delim=tabs>0&&tabs>=commas?'\\t':',';\r\n  const rows=[];let row=[],cur='',q=false;\r\n  for(let i=0;i<text.length;i++){const c=text[i];\r\n    if(q){if(c==='\"'){if(text[i+1]==='\"'){cur+='\"';i++}else q=false}else cur+=c}\r\n    else if(c==='\"'&&cur===''){q=true}\r\n    else if(c===delim){row.push(cur);cur=''}\r\n    else if(c==='\\n'||c==='\\r'){if(c==='\\r'&&text[i+1]==='\\n')i++;row.push(cur);cur='';rows.push(row);row=[]}\r\n    else cur+=c}\r\n  if(cur!==''||row.length){row.push(cur);rows.push(row)}\r\n  return rows.filter(r=>r.some(x=>x.trim()!==''));\r\n}\r\nfunction gtinOk(g){if(!\/^\\d+$\/.test(g)||![8,12,13,14].includes(g.length))return false;const d=g.split('').map(Number),c=d.pop();let s=0;d.reverse().forEach((x,i)=>{s+=x*(i%2===0?3:1)});return (10-s%10)%10===c}\r\nconst PRICE_RE=\/^\\d+(\\.\\d{1,2})?\\s[A-Z]{3}$\/;\r\nfunction checkFeed(text){\r\n  const rows=parseTable(text);\r\n  if(rows.length<2)return {err:'The feed needs a header row and at least one product row.'};\r\n  const head=rows[0].map(h=>h.trim().toLowerCase().replace(\/^g:\/,'').replace(\/[\\s-]+\/g,'_').replace(\/^item_id$\/,'id').replace(\/^product_id$\/,'id'));\r\n  const products=rows.slice(1).map(r=>{const o={};head.forEach((h,i)=>o[h]=(r[i]||'').trim());return o});\r\n  const issues=[],ids=new Map(),bad=new Set();\r\n  const add=(i,p,field,sev,msg)=>{issues.push({row:i+2,id:p.id||'(no id)',field,sev,msg});if(sev==='error')bad.add(i)};\r\n  const REQ=['id','title','description','link','image_link','price','availability'];\r\n  products.forEach((p,i)=>{\r\n    REQ.forEach(f=>{if(!p[f])add(i,p,f,'error',`Missing ${f}. Google requires it for every product.`)});\r\n    if(p.id){if(p.id.length>50)add(i,p,'id','error','ID is longer than 50 characters.');if(ids.has(p.id))add(i,p,'id','error',`Duplicate ID. Row ${ids.get(p.id)} uses the same ID.`);else ids.set(p.id,i+2)}\r\n    if(p.title){\r\n      if(p.title.length>150)add(i,p,'title','warning',`Title is ${p.title.length} characters. Google reads up to 150.`);\r\n      if(p.title.length<20)add(i,p,'title','warning','Title is very short. Add brand, product type and a key attribute.');\r\n      const letters=p.title.replace(\/[^A-Za-z]\/g,'');if(letters.length>8&&letters===letters.toUpperCase())add(i,p,'title','warning','Title is all capitals. Google treats excessive capitalization as a quality problem.');\r\n      if(\/free shipping|\\bsale\\b|% ?off|best price|discount|buy now|limited offer\/i.test(p.title))add(i,p,'title','warning','Title contains promotional text. Move offers to a promotion or the description.');\r\n      if(\/[!]{2,}\/.test(p.title))add(i,p,'title','warning','Title has repeated exclamation marks.');\r\n    }\r\n    if(p.description){if(p.description.length>5000)add(i,p,'description','warning','Description is over 5,000 characters.');else if(p.description.length<40)add(i,p,'description','warning','Description is very short. Add materials, size, use and key benefits.')}\r\n    ['link','image_link'].forEach(f=>{if(p[f]){if(!\/^https?:\\\/\\\/\\S+$\/i.test(p[f]))add(i,p,f,'error',`${f==='link'?'Product URL':'Image URL'} must start with http:\/\/ or https:\/\/ and contain no spaces.`);else if(f==='image_link'){const path=p[f].split(\/[?#]\/)[0];if(\/\\.[a-z0-9]{2,5}$\/i.test(path)&&!\/\\.(jpe?g|png|gif|bmp|tiff?|webp)$\/i.test(path))add(i,p,f,'warning','Image file type may not be supported. Use JPEG, PNG, GIF, BMP, TIFF or WebP.');if(\/^http:\\\/\\\/\/i.test(p[f]))add(i,p,f,'warning','Image uses http. Use https where you can.')}}});\r\n    if(p.price&&!PRICE_RE.test(p.price))add(i,p,'price','error','Use a number, a space and the currency code, for example 499.00 INR. No commas or symbols.');\r\n    else if(p.price&&parseFloat(p.price)<=0)add(i,p,'price','error','Price must be greater than zero.');\r\n    if(p.sale_price){if(!PRICE_RE.test(p.sale_price))add(i,p,'sale_price','error','Use a number, a space and the currency code, for example 399.00 INR.');else if(PRICE_RE.test(p.price||'')&&parseFloat(p.sale_price)>=parseFloat(p.price))add(i,p,'sale_price','error','Sale price must be lower than the price.')}\r\n    if(p.availability){const a=p.availability.toLowerCase();if(!['in_stock','out_of_stock','preorder','backorder'].includes(a)){if(['in stock','out of stock'].includes(a))add(i,p,'availability','warning','Use in_stock or out_of_stock with an underscore.');else add(i,p,'availability','error','Use in_stock, out_of_stock, preorder or backorder.')}}\r\n    if(p.condition&&!['new','refurbished','used'].includes(p.condition.toLowerCase()))add(i,p,'condition','error','Use new, refurbished or used.');\r\n    if(!p.brand)add(i,p,'brand','error','Missing brand. Required for every product except books, movies and music.');\r\n    if(p.gtin){if(!gtinOk(p.gtin))add(i,p,'gtin','error','GTIN is not valid. It must be 8, 12, 13 or 14 digits with a correct check digit.')}\r\n    else if(!p.mpn&&(p.identifier_exists||'').toLowerCase()!=='no')add(i,p,'gtin','warning','No GTIN or MPN. Add one, or set identifier_exists to no if the product has none.');\r\n    if(!p.google_product_category)add(i,p,'google_product_category','warning','Missing google_product_category. Adding it improves matching.');\r\n    if(\/apparel|clothing|shoes\/i.test(p.google_product_category||'')){['color','size','gender','age_group'].forEach(f=>{if(!p[f])add(i,p,f,'error',`${f} is required for apparel.`)})}\r\n    if(p.gender&&!['male','female','unisex'].includes(p.gender.toLowerCase()))add(i,p,'gender','error','Use male, female or unisex.');\r\n    if(p.age_group&&!['newborn','infant','toddler','kids','adult'].includes(p.age_group.toLowerCase()))add(i,p,'age_group','error','Use newborn, infant, toddler, kids or adult.');\r\n  });\r\n  const cols=['id','title','description','link','image_link','price','availability','brand','gtin','mpn','condition','google_product_category','color','size'];\r\n  const cov=cols.filter(c=>head.includes(c)||REQ.includes(c)).map(c=>({c,req:REQ.includes(c)||c==='brand',pct:Math.round(products.filter(p=>p[c]).length\/products.length*100)}));\r\n  issues.sort((a,b)=>a.row-b.row||(a.sev==='error'?-1:1));\r\n  return {n:products.length,issues,errors:issues.filter(x=>x.sev==='error').length,warnings:issues.filter(x=>x.sev==='warning').length,clean:products.length-bad.size,cov};\r\n}\r\nfunction sampleFeed(){\r\n  const H=['id','title','description','link','image_link','price','sale_price','availability','condition','brand','gtin','mpn','google_product_category','color','size','gender','age_group'];\r\n  const R=[\r\n    ['OG-1001','Aroma Roots Cold Pressed Coconut Oil 500 ml \u2013 100% Pure, Glass Bottle','Cold pressed coconut oil in a 500 ml glass bottle. No added chemicals. Suitable for hair and skin.','https:\/\/example-store.in\/p\/coconut-oil-500','https:\/\/example-store.in\/img\/coconut-500.jpg','449.00 INR','399.00 INR','in_stock','new','Aroma Roots','8901234567890','','Health & Beauty > Personal Care > Hair Care','','500 ml','',''],\r\n    ['OG-1002','BEST SALE!!! COCONUT OIL FREE SHIPPING 50% OFF','Coconut oil.','https:\/\/example-store.in\/p\/coconut-oil-250','http:\/\/example-store.in\/img\/coconut-250.jpg','249','','in stock','new','Aroma Roots','8901234567891','','Health & Beauty > Personal Care > Hair Care','','250 ml','',''],\r\n    ['OG-1003','Aroma Roots Argan Hair Oil 100 ml with Vitamin E','','www.example-store.in\/p\/argan-100','https:\/\/example-store.in\/img\/argan-100.jpg','1,299.00 INR','','available','new','Aroma Roots','','ARG-100','Health & Beauty > Personal Care > Hair Care','','100 ml','',''],\r\n    ['OG-1001','Aroma Roots Onion Hair Oil 200 ml \u2013 Redensyl and Castor, Glass Bottle','Onion hair oil in a 200 ml glass bottle, blended with castor oil for regular scalp massage.','https:\/\/example-store.in\/p\/onion-200','https:\/\/example-store.in\/img\/onion-200.webp','599.00 INR','649.00 INR','in_stock','new','Aroma Roots','','','Health & Beauty > Personal Care > Hair Care','','200 ml','',''],\r\n    ['OG-1005','Aroma Roots Cotton Kurta for Men','Soft cotton kurta with a straight cut, made for daily wear and festive occasions.','https:\/\/example-store.in\/p\/kurta-m','https:\/\/example-store.in\/img\/kurta-m.png','1499.00 INR','','in_stock','new','','','','Apparel & Accessories > Clothing > Shirts','','','',''],\r\n    ['OG-1006','Aroma Roots Neem Wood Comb \u2013 Anti-Static, Handmade, Pack of 2','Handmade neem wood comb that is gentle on the scalp. Pack of 2 in a cotton pouch.','https:\/\/example-store.in\/p\/neem-comb','https:\/\/example-store.in\/img\/neem-comb.jpg','299.00 INR','','preorder','new','Aroma Roots','','NC-02','Health & Beauty > Personal Care > Hair Care','Brown','Standard','unisex','adult']\r\n  ];\r\n  return [H,...R].map(r=>r.join('\\t')).join('\\n');\r\n}\r\nfunction toolFeed(root){\r\n  root.innerHTML=`<div class=\"split stack\"><div class=\"panel\"><p class=\"sample-note\">A sample feed with deliberate mistakes is loaded so you can see what the checker finds. Replace it with your own feed.<\/p>\r\n    <div class=\"field\"><label for=\"fc-feed\">Paste your product feed<\/label><textarea id=\"fc-feed\" class=\"mono\" rows=\"9\" spellcheck=\"false\" placeholder=\"id, title, description, link, image_link, price, availability\"><\/textarea><small class=\"hint\">Works with tab-separated or comma-separated text, including a Google Sheets export. Header names like g:price are accepted.<\/small><\/div>\r\n    <div class=\"actions\"><button class=\"btn btn-cta\" type=\"button\" id=\"fc-run\">Check feed<\/button>\r\n    <label class=\"btn btn-ghost\" for=\"fc-file\" style=\"display:inline-block;cursor:pointer\">Upload .csv or .tsv<\/label><input id=\"fc-file\" type=\"file\" accept=\".csv,.tsv,.txt,text\/csv,text\/plain\" hidden>\r\n    <button class=\"btn btn-ghost\" type=\"button\" id=\"fc-sample\">Load sample feed<\/button><\/div>\r\n    <p class=\"note\">Your feed stays in this browser tab. The checks follow Google Merchant Center product data rules. Final approval always comes from Merchant Center, so use this before you upload.<\/p><\/div>\r\n    <div class=\"panel out\" id=\"fc-out\" aria-live=\"polite\"><\/div><\/div>`;\r\n  const ta=root.querySelector('#fc-feed'),o=root.querySelector('#fc-out');\r\n  ta.value=sampleFeed();\r\n  let filter='all',res=null;\r\n  function paint(){\r\n    if(!res)return;\r\n    if(res.err){o.innerHTML=`<p class=\"empty\">${esc(res.err)}<\/p>`;return}\r\n    const pct=Math.round(res.clean\/res.n*100),shown=res.issues.filter(x=>filter==='all'||x.sev===(filter==='errors'?'error':'warning'));\r\n    const report=res.issues.map(x=>`Row ${x.row} | ${x.id} | ${x.field} | ${x.sev.toUpperCase()} | ${x.msg}`).join('\\n');\r\n    o.innerHTML=`<div class=\"out-head\"><h3>Feed report<\/h3><button type=\"button\" class=\"btn btn-ghost btn-sm\" data-copy=\"${esc(report)}\">Copy full report<\/button><\/div>\r\n    <div class=\"stats\"><div class=\"stat ${pct===100?'ok':pct>=70?'warn':'bad'}\"><b>${pct}%<\/b><span>products with no errors<\/span><\/div><div class=\"stat\"><b>${res.n}<\/b><span>products checked<\/span><\/div><div class=\"stat ${res.errors?'bad':'ok'}\"><b>${res.errors}<\/b><span>errors to fix<\/span><\/div><div class=\"stat ${res.warnings?'warn':'ok'}\"><b>${res.warnings}<\/b><span>warnings<\/span><\/div><\/div>\r\n    <div class=\"block\"><h4><span>Attribute coverage<\/span><span class=\"count\">share of products with a value<\/span><\/h4>${res.cov.map(c=>`<div class=\"cov\"><span>${esc(c.c)}${c.req?' *':''}<\/span><div class=\"meter\"><span class=\"${c.pct===100?'':c.req?'bad':'warn'}\" style=\"width:${c.pct}%\"><\/span><\/div><span>${c.pct}%<\/span><\/div>`).join('')}<p class=\"note\">* required by Google<\/p><\/div>\r\n    <div class=\"block\"><h4><span>Issues<\/span><span class=\"seg\" role=\"group\" aria-label=\"Filter issues\"><button type=\"button\" data-f=\"all\" aria-pressed=\"${filter==='all'}\">All ${res.issues.length}<\/button><button type=\"button\" data-f=\"errors\" aria-pressed=\"${filter==='errors'}\">Errors ${res.errors}<\/button><button type=\"button\" data-f=\"warnings\" aria-pressed=\"${filter==='warnings'}\">Warnings ${res.warnings}<\/button><\/span><\/h4>\r\n    ${shown.length?`<div class=\"tbl-wrap\"><table><thead><tr><th>Row<\/th><th>Product ID<\/th><th>Field<\/th><th>Level<\/th><th>What to fix<\/th><\/tr><\/thead><tbody>${shown.slice(0,400).map(x=>`<tr><td class=\"mono\">${x.row}<\/td><td class=\"mono\">${esc(x.id)}<\/td><td class=\"mono\">${esc(x.field)}<\/td><td>${tag(x.sev==='error'?'Error':'Warning',x.sev==='error'?'bad':'warn')}<\/td><td>${esc(x.msg)}<\/td><\/tr>`).join('')}<\/tbody><\/table><\/div>${shown.length>400?`<p class=\"note\">Showing the first 400 of ${shown.length}. Copy the full report for the rest.<\/p>`:''}`:empty(res.issues.length?'No issues at this level.':'No issues found. Your feed passes every check here.')}<\/div>`;\r\n  }\r\n  const run=()=>{res=checkFeed(ta.value);filter='all';paint()};\r\n  root.querySelector('#fc-run').addEventListener('click',run);\r\n  root.querySelector('#fc-sample').addEventListener('click',()=>{ta.value=sampleFeed();run()});\r\n  root.querySelector('#fc-file').addEventListener('change',e=>{const f=e.target.files[0];if(!f)return;const r=new FileReader();r.onload=()=>{ta.value=String(r.result);run()};r.readAsText(f)});\r\n  o.addEventListener('click',e=>{const b=e.target.closest('[data-f]');if(b){filter=b.dataset.f;paint()}});\r\n  run();\r\n}\r\n\r\n\/* ================= 6. ASO KEYWORDS ================= *\/\r\nconst CAT={\r\n  'Health & Fitness':{n:['fitness','workout','health','exercise'],v:['track','train','burn']},\r\n  'Finance':{n:['budget','expense','money','savings'],v:['track','save','manage']},\r\n  'Education':{n:['learning','study','quiz','courses'],v:['learn','study','practice']},\r\n  'Productivity':{n:['planner','to do list','notes','tasks'],v:['plan','organize','remind']},\r\n  'Photo & Video':{n:['photo editor','filters','video editor','collage'],v:['edit','create','share']},\r\n  'Shopping':{n:['deals','coupons','shopping','discounts'],v:['shop','save','compare']},\r\n  'Food & Drink':{n:['recipes','meal plan','grocery','delivery'],v:['cook','order','plan']},\r\n  'Travel':{n:['trip planner','flights','hotels','maps'],v:['plan','book','explore']},\r\n  'Social':{n:['chat','friends','messenger','community'],v:['chat','connect','share']},\r\n  'Games':{n:['puzzle','offline games','multiplayer','arcade'],v:['play','win','challenge']},\r\n  'Business':{n:['invoice','billing','crm','accounting'],v:['bill','manage','grow']},\r\n  'Utilities':{n:['scanner','pdf','qr code','cleaner'],v:['scan','convert','clean']}\r\n};\r\nconst STOP2=new Set('a an and the for of with in on to by at or from is are be it as your you app apps free'.split(' '));\r\nfunction toolASO(root){\r\n  const t='as';\r\n  root.innerHTML=shell(t,`<div class=\"grid2\">`+\r\n    F(t,'name','App name',{value:'FitTrack'})+\r\n    F(t,'cat','Category',{value:'Health & Fitness',options:Object.keys(CAT).map(c=>[c,c])})+\r\n    F(t,'feat','Main features',{span:1,value:'step counter, calorie tracker, workout plans',hint:'Separate with commas'})+\r\n    F(t,'aud','Who uses it',{value:'beginners, busy professionals'})+\r\n    F(t,'extra','Other keywords (optional)',{value:'weight loss, home workout'})+\r\n    F(t,'store','Store',{value:'both',options:[['both','App Store and Google Play'],['ios','App Store only'],['play','Google Play only']]})+\r\n    `<\/div>`,'Generate ASO keywords');\r\n  wire(root,t,()=>{\r\n    const name=val(root,t,'name'),cat=CAT[val(root,t,'cat')],feats=list(val(root,t,'feat')).map(x=>x.toLowerCase()),aud=list(val(root,t,'aud')).map(x=>x.toLowerCase()),extra=list(val(root,t,'extra')).map(x=>x.toLowerCase()),store=val(root,t,'store'),o=outEl(root,t);\r\n    if(!name){o.innerHTML=empty('Enter your app name to generate keywords.');return}\r\n    const core=uniq([...feats,...extra,...cat.n]),a0=aud[0]||'everyone',verb=cat.v[0];\r\n    const tset=[];\r\n    core.slice(0,8).forEach(k=>{const s=name+': '+cap(k);if(s.length<=30&&tset.length<4)tset.push(s)});\r\n    if(!tset.length)tset.push(trimTo(name,30));\r\n    const subs=[];\r\n    [[core[0],core[1]],[core[1],core[2]],[core[0],core[2]]].filter(p=>p[0]&&p[1]).forEach(([a,b])=>{const s=`${cap(a)} & ${cap(b)}`;if(s.length<=30)subs.push(s)});\r\n    core.slice(0,4).forEach(k=>{const s=`${cap(verb)} ${k} for ${a0}`;if(s.length<=30)subs.push(s);const s2=`${cap(k)} for ${cap(a0)}`;if(s2.length<=30)subs.push(s2)});\r\n    const subset=uniq(subs).slice(0,4);\r\n    const shorts=[trimTo(`${cap(verb)} ${feats[0]||cat.n[0]}${feats[1]?`, ${feats[1]}`:''} and more${aud[0]?` for ${aud[0]}`:''}. Free to download.`,80),trimTo(`The simple ${cat.n[0]} app for ${a0}: ${feats.slice(0,2).join(' and ')||cat.n[1]}.`,80),trimTo(`${name} helps you ${cat.v[1]||verb} ${feats[0]||cat.n[0]} every day.`,80)];\r\n    const used=new Set(((tset[0]||name)+' '+(subset[0]||'')).toLowerCase().split(\/[^\\p{L}\\p{N}]+\/u));\r\n    const pool=[...core,...aud.map(a=>`${cat.n[0]} for ${a}`),`offline ${cat.n[0]}`,`simple ${cat.n[0]}`,`${cat.n[0]} tracker`,`${cat.n[0]} ${YEAR}`,...cat.v];\r\n    const kwWords=uniq(pool.join(' ').toLowerCase().split(\/[^\\p{L}\\p{N}]+\/u).filter(w=>w&&!STOP2.has(w)&&!used.has(w)&&w.length>2)).sort((a,b)=>a.length-b.length);\r\n    let field='';for(const w of kwWords){const n=field?field+','+w:w;if(n.length>100)break;field=n}\r\n    const groups=[\r\n      ['Core keywords',core],\r\n      ['Action keywords',cat.v.flatMap(v=>core.slice(0,3).map(k=>`${v} ${k}`))],\r\n      ['Audience long-tail',aud.flatMap(a=>[`${cat.n[0]} app for ${a}`,`${core[0]} for ${a}`])],\r\n      ['Modifiers',[`offline ${cat.n[0]}`,`simple ${cat.n[0]}`,`${cat.n[0]} tracker`,`free ${cat.n[0]}`,`${cat.n[0]} ${YEAR}`]]\r\n    ];\r\n    const ios=store!=='play',play=store!=='ios';\r\n    o.innerHTML=`<div class=\"out-head\"><h3>ASO draft for ${esc(name)}<\/h3><\/div>`+\r\n      block(ios&&play?'App name ideas (30 characters, both stores)':'App name ideas (30 characters)',tset.map(s=>resRow(s,{limit:30})).join(''))+\r\n      (ios&&subset.length?block('App Store subtitle ideas (30 characters)',subset.map(s=>resRow(s,{limit:30})).join('')):'')+\r\n      (ios?block('App Store keyword field (100 characters)',`<p class=\"mono prose\">${esc(field)}<\/p><div class=\"meter-wrap\">${meter(field.length,100)}<span class=\"count\">${field.length} \/ 100<\/span><\/div><p class=\"note\">Comma-separated with no spaces. Words already in the name and subtitle are left out because Apple indexes them anyway.<\/p>`,field):'')+\r\n      (play?block('Google Play short description ideas (80 characters)',shorts.map(s=>resRow(s,{limit:80})).join('')):'')+\r\n      groups.map(([n,items])=>`<div class=\"kgroup\"><h4><span>${esc(n)}<\/span><button type=\"button\" class=\"copy\" data-copy=\"${esc(uniq(items).join('\\n'))}\">Copy<\/button><\/h4><div class=\"kchips\">${uniq(items).map(i=>`<span class=\"tag info\">${esc(i)}<\/span>`).join('')}<\/div><\/div>`).join('')+\r\n      `<div class=\"tips\"><b>Before you submit<\/b>${play?'On Google Play, repeat your main keyword naturally in the long description, about 3 to 5 times. ':''}Check the store search suggestions for each keyword and replace any that do not show up.<\/div>`;\r\n  });\r\n}\r\n\r\n\/* ================= 7. VOICE SEARCH QUESTIONS ================= *\/\r\nfunction toolVoice(root){\r\n  const t='vq';\r\n  root.innerHTML=`<div class=\"split\">`+\r\n    `<form class=\"panel in\" id=\"vq-form\" novalidate><p class=\"sample-note\">Example topic loaded. Replace it with your own.<\/p><div class=\"grid2\">`+\r\n    F(t,'topic','Topic or service',{span:1,value:'hair oil',hint:'A noun phrase works best'})+\r\n    F(t,'biz','Business type',{value:'store',options:[['store','Online store'],['local','Local business'],['service','Service provider'],['blog','Blog or publisher']]})+\r\n    F(t,'city','City or area (optional)',{value:'Jaipur'})+\r\n    `<div class=\"field span\"><label id=\"vq-types-l\">Question types<\/label><div class=\"kchips\" id=\"vq-types\" role=\"group\" aria-labelledby=\"vq-types-l\">${['what','how','why','when','where','who','yes\/no','near me'].map(x=>`<button type=\"button\" class=\"kchip\" aria-pressed=\"true\" data-type=\"${x}\">${x}<\/button>`).join('')}<\/div><\/div>`+\r\n    `<\/div><div class=\"actions\"><button class=\"btn btn-cta\" type=\"submit\">Generate questions<\/button><\/div><\/form>`+\r\n    `<div class=\"panel out\" aria-live=\"polite\"><div id=\"vq-list\"><\/div><div id=\"vq-faq\"><\/div><\/div><\/div>`;\r\n  const types=new Set(['what','how','why','when','where','who','yes\/no','near me']);\r\n  root.querySelector('#vq-types').addEventListener('click',e=>{const b=e.target.closest('[data-type]');if(!b)return;const k=b.dataset.type;if(types.has(k)){types.delete(k);b.setAttribute('aria-pressed','false')}else{types.add(k);b.setAttribute('aria-pressed','true')}});\r\n  const faq=[],listEl=root.querySelector('#vq-list'),faqEl=root.querySelector('#vq-faq');\r\n  const mk=(topic,city,biz)=>{\r\n    const x=topic,c=city?` in ${city}`:'',buy=biz==='service'?'hire':'buy';\r\n    return {\r\n      'what':[`What is ${x}?`,`What are the benefits of ${x}?`,`What is the best ${x}${c}?`,`What should I look for in ${x}?`,`What does ${x} cost${c}?`],\r\n      'how':[`How does ${x} work?`,`How do I choose the right ${x}?`,`How much does ${x} cost${c}?`,`How long does ${x} take to work?`,`How do I get started with ${x}?`],\r\n      'why':[`Why is ${x} important?`,`Why should I use ${x}?`,`Why is ${x} so expensive?`],\r\n      'when':[`When should I use ${x}?`,`When is the best time to ${buy} ${x}?`,`When will my ${x} order arrive?`],\r\n      'where':[`Where can I ${buy} ${x}${c}?`,`Where to find the best ${x}${c}?`,`Where can I get ${x} online?`],\r\n      'who':[`Who sells the best ${x}${c}?`,`Who should use ${x}?`,`Who offers ${x}${c}?`],\r\n      'yes\/no':[`Is ${x} worth it?`,`Is ${x} safe to use every day?`,`Can I ${buy} ${x} online?`,`Does ${x} really work?`,`Do I need ${x}?`],\r\n      'near me':[`Best ${x} near me`,`${cap(x)} shop near me open now`,`Where is the nearest place to ${buy} ${x}?`].concat(city?[`Best ${x} in ${city}`,`${cap(x)} delivery in ${city}`]:[])\r\n    };\r\n  };\r\n  const schema=()=>'<script type=\"application\/ld+json\">\\n'+JSON.stringify({'@context':'https:\/\/schema.org','@type':'FAQPage',mainEntity:faq.map(f=>({'@type':'Question',name:f.q,acceptedAnswer:{'@type':'Answer',text:f.a||'Add your answer here.'}}))},null,2)+'\\n<\\\/script>';\r\n  function paintFaq(){\r\n    faqEl.innerHTML=faq.length?`<div class=\"block\"><h4><span>FAQ builder (${faq.length})<\/span><button type=\"button\" class=\"copy\" data-from=\"#vq-json\">Copy schema<\/button><\/h4><p class=\"out-sub\">Write a short, direct answer under each question. Voice assistants tend to read answers of about 20 to 40 words.<\/p>`+faq.map((f,i)=>`<div class=\"faq-item\"><b>${esc(f.q)}<\/b><textarea rows=\"2\" data-i=\"${i}\" placeholder=\"Write your answer here\" aria-label=\"Answer for ${esc(f.q)}\">${esc(f.a)}<\/textarea><div class=\"res-meta\"><span class=\"count\" data-wc=\"${i}\">${words(f.a)} words<\/span><button type=\"button\" class=\"copy\" data-rm=\"${i}\">Remove<\/button><\/div><\/div>`).join('')+`<h4 style=\"margin-top:12px\"><span>FAQPage JSON-LD<\/span><\/h4><pre class=\"code\" id=\"vq-json\">${esc(schema())}<\/pre><\/div>`:'';\r\n  }\r\n  function run(){\r\n    const topic=val(root,t,'topic'),city=val(root,t,'city'),biz=val(root,t,'biz');\r\n    if(!topic){listEl.innerHTML=empty('Enter a topic to generate questions.');return}\r\n    const all=mk(topic.toLowerCase(),city,biz),keys=Object.keys(all).filter(k=>types.has(k)&&!(k==='near me'&&biz==='blog'));\r\n    if(!keys.length){listEl.innerHTML=empty('Select at least one question type.');return}\r\n    const every=keys.flatMap(k=>all[k]);\r\n    listEl.innerHTML=`<div class=\"out-head\"><h3>${every.length} spoken questions<\/h3><button type=\"button\" class=\"btn btn-ghost btn-sm\" data-copy=\"${esc(every.join('\\n'))}\">Copy all<\/button><\/div><p class=\"out-sub\">Phrased the way people speak to a phone or smart speaker. Add the best ones to the FAQ builder.<\/p>`+\r\n      keys.map(k=>`<div class=\"kgroup\"><h4><span>${esc(up1(k))}<\/span><span class=\"count\">${all[k].length}<\/span><\/h4>${all[k].map(q=>`<div class=\"qrow\"><span>${esc(q)}<\/span><div><button type=\"button\" class=\"copy\" data-copy=\"${esc(q)}\">Copy<\/button><button type=\"button\" class=\"copy\" data-add=\"${esc(q)}\">Add to FAQ<\/button><\/div><\/div>`).join('')}<\/div>`).join('');\r\n  }\r\n  root.querySelector('#vq-form').addEventListener('submit',e=>{e.preventDefault();run()});\r\n  root.addEventListener('click',e=>{\r\n    const a=e.target.closest('[data-add]');if(a){const q=a.dataset.add;if(!faq.some(f=>f.q===q)){faq.push({q,a:''});paintFaq();toast('Added to FAQ builder')}else toast('Already in the FAQ builder');return}\r\n    const r=e.target.closest('[data-rm]');if(r){faq.splice(+r.dataset.rm,1);paintFaq()}\r\n  });\r\n  root.addEventListener('input',e=>{const ta=e.target.closest('textarea[data-i]');if(!ta)return;const i=+ta.dataset.i;faq[i].a=ta.value;const wc=faqEl.querySelector(`[data-wc=\"${i}\"]`);if(wc)wc.textContent=words(ta.value)+' words';const pre=faqEl.querySelector('#vq-json');if(pre)pre.textContent=schema()});\r\n  run();\r\n  faq.push({q:'What is the best hair oil in Jaipur?',a:''});paintFaq();\r\n}\r\n\r\n\/* ================= 8. AI SEARCH (GEO) CHECKER ================= *\/\r\nconst GEO_SAMPLE=`# What is a product feed?\r\n\r\nA product feed is a file that lists every product you sell, with details like title, price, image and availability. Shopping platforms such as Google Merchant Center read it to show your products to buyers.\r\n\r\n## Why does a product feed matter?\r\n\r\nWithout a feed, your products cannot appear in Google Shopping ads or free listings. According to Google, accurate and complete product data helps shoppers find the right item. Fixing missing GTINs and titles is usually the fastest way to recover disapproved products.\r\n\r\n## How do you build a feed?\r\n\r\nMost stores follow these steps:\r\n\r\n- Export products from your store platform as a CSV file\r\n- Match each column to a Google attribute such as id, title and price\r\n- Upload the file to Merchant Center and schedule a daily fetch\r\n- Fix every error shown in the Diagnostics tab\r\n\r\n## What mistakes cause disapprovals?\r\n\r\nThe most common mistakes are missing identifiers, prices without a currency code, and titles written in all capitals. A review of 300 feeds found that 6 in 10 had at least one price formatting error, so it pays to check this first.\r\n\r\n## FAQ\r\n\r\nCan I use a spreadsheet? Yes. Google Sheets works well for small catalogs of a few hundred products. Larger stores should use an automatic file export or an API connection.`;\r\nfunction analyzeGeo(raw,kw){\r\n  const text=raw.replace(\/\\r\/g,'').replace(\/^(#{1,6}\\s.*)$\/gm,'\\n$1\\n'),blocks=text.split(\/\\n\\s*\\n\/).map(b=>b.trim()).filter(Boolean);\r\n  const heads=[],paras=[];let lists=0,tables=0;\r\n  blocks.forEach((b,i)=>{\r\n    const lines=b.split('\\n'),li=lines.filter(l=>\/^\\s*([-*\u2022]|\\d+[.)])\\s+\/.test(l)).length;\r\n    if(lines.filter(l=>(l.match(\/\\|\/g)||[]).length>=2).length>=2){tables++;return}\r\n    if(\/^#{1,6}\\s+\/.test(b)){heads.push(b.replace(\/^#{1,6}\\s+\/,'').trim());return}\r\n    if(li>=2&&li>=lines.length-1){lists++;return}\r\n    if(lines.length===1&&b.length<=90&&!\/[.!;,]$\/.test(b)&&words(b)>=2&&words(b)<=14&&i<blocks.length-1){heads.push(b);return}\r\n    paras.push(b);\r\n  });\r\n  const wc=words(raw),ptext=paras.join(' '),sents=ptext.split(\/(?<=[.!?])\\s+(?=[A-Z0-9\"\u201c(])\/).filter(s=>words(s)>2);\r\n  const avgSent=sents.length?sents.reduce((a,s)=>a+words(s),0)\/sents.length:0;\r\n  const pw=paras.map(words),avgPara=pw.length?pw.reduce((a,b)=>a+b,0)\/pw.length:0,maxPara=Math.max(0,...pw);\r\n  const nums=(raw.match(\/\\b\\d[\\d,.]*%?\/g)||[]).length,numRate=wc?nums\/wc*100:0;\r\n  const src=(raw.match(\/according to|source:|sources:|\\bstudy\\b|\\bstudies\\b|research|survey|report(ed)? by|data from|https?:\\\/\\\/|\\(\\s*(19|20)\\d\\d\\s*\\)|\\[\\d+\\]|\\b20\\d\\d (review|report|survey|study)\/gi)||[]).length;\r\n  const fresh=new RegExp('\\\\b('+[YEAR,YEAR-1].join('|')+')\\\\b').test(raw)||\/last (updated|reviewed)|updated:\/i.test(raw);\r\n  const expert=\/\\b(we tested|i tested|our team|in our experience|years of experience|reviewed by|written by|by [A-Z][a-z]+ [A-Z][a-z]+|certified|hands-on)\\b\/i.test(raw);\r\n  const quotable=sents.filter(s=>{const n=words(s);return n>=12&&n<=30&&(\/\\d\/.test(s)||\/\\b(is|are|means|refers to|helps|allows)\\b\/i.test(s))});\r\n  const qHeads=heads.filter(h=>\/\\?$\/.test(h)).length,hasFaq=qHeads>=2||\/\\bfaq\\b|frequently asked\/i.test(raw);\r\n  const fp=words(paras[0]||'');\r\n  const K=kw.toLowerCase(),first100=raw.split(\/\\s+\/).slice(0,100).join(' ').toLowerCase(),kwHead=K&&heads.some(h=>h.toLowerCase().includes(K)),kwTop=K&&first100.includes(K);\r\n  const C=[];const add=(label,max,pts,tip,detail)=>C.push({label,max,pts,tip,detail,status:pts>=max?'ok':pts>0?'warn':'bad'});\r\n  add('Answer-first opening',10,fp>=12&&fp<=70?10:fp>0&&fp<=110?5:0,'Open with a 2 to 3 sentence answer that stands alone. AI answers lift from the first clear statement.',`First paragraph: ${fp} words`);\r\n  add('Clear section headings',10,heads.length>=Math.max(2,Math.floor(wc\/250))?10:heads.length>=1?5:0,'Add a heading for each main idea, roughly one per 200 to 250 words.',`${heads.length} headings found`);\r\n  add('Question-style headings',10,qHeads>=2?10:qHeads===1?5:0,'Phrase some headings as the questions people ask, such as \"How do you build a feed?\".',`${qHeads} question headings`);\r\n  add('Short paragraphs',10,paras.length&&avgPara<=80&&maxPara<=150?10:avgPara<=120?5:0,'Keep paragraphs to 2 to 4 sentences so each one can be quoted by itself.',`Average ${Math.round(avgPara)} words, longest ${maxPara}`);\r\n  add('Readable sentences',10,avgSent&&avgSent<=22?10:avgSent<=28?5:0,'Aim for an average sentence under 22 words. Split long sentences at \"and\" or \"which\".',`Average ${avgSent.toFixed(1)} words`);\r\n  add('Lists or tables',10,(lists+tables)>=1?10:0,'Turn steps, comparisons or specs into a bulleted list or a table. They are easy to extract.',`${lists} lists, ${tables} tables`);\r\n  add('Facts and numbers',10,numRate>=1.5?10:numRate>=.5?5:0,'Add specific figures, dates, sizes or prices. Concrete facts get cited more than general claims.',`${nums} numbers, ${numRate.toFixed(1)} per 100 words`);\r\n  add('Sources and attribution',10,src>=2?10:src===1?5:0,'Name where facts come from: \"according to...\", a study, a report or a link.',`${src} source signals`);\r\n  add('Quotable sentences',10,quotable.length>=3?10:quotable.length>=1?5:0,'Write a few self-contained sentences of 12 to 30 words that state a fact or a definition.',`${quotable.length} found`);\r\n  add('Fresh signal',5,fresh?5:0,'Mention the current year or a \"last updated\" date so the page reads as current.',fresh?'Date found':'No recent date');\r\n  add('Experience and authorship',5,expert?5:0,'Show who wrote it and why they know. Add a byline, \"we tested\" or years of experience.',expert?'Signal found':'None found');\r\n  add('FAQ block',5,hasFaq?5:0,'End with a short FAQ of 2 to 5 real questions with direct answers.',hasFaq?'FAQ found':'None found');\r\n  if(K)add('Target topic placement',10,kwTop&&kwHead?10:(kwTop||kwHead)?5:0,'Use your topic phrase in the first 100 words and in at least one heading.',`${kwTop?'In first 100 words':'Not in first 100 words'}, ${kwHead?'in a heading':'not in a heading'}`);\r\n  const max=C.reduce((a,c)=>a+c.max,0),pts=C.reduce((a,c)=>a+c.pts,0);\r\n  return {score:Math.round(pts\/max*100),C,wc,heads:heads.length,avgSent,numRate,quotable:quotable.slice(0,5)};\r\n}\r\nfunction toolGeo(root){\r\n  const t='gc';\r\n  root.innerHTML=`<div class=\"split stack\"><form class=\"panel in\" id=\"gc-form\" novalidate><p class=\"sample-note\">A sample article is loaded. Replace it with your own page copy.<\/p>\r\n    <div class=\"field\"><label for=\"gc-text\">Paste your page content<\/label><textarea id=\"gc-text\" rows=\"12\" placeholder=\"Paste the article or page text here\"><\/textarea><small class=\"hint\">Use # for headings, or put each heading on its own short line. Lists can start with - or numbers.<\/small><\/div>\r\n    <div class=\"grid2\" style=\"margin-top:14px\">${F(t,'kw','Topic or question this page should answer (optional)',{value:'product feed'})}<\/div>\r\n    <div class=\"actions\"><button class=\"btn btn-cta\" type=\"submit\">Check content<\/button><button class=\"btn btn-ghost\" type=\"button\" id=\"gc-sample\">Load sample<\/button><\/div><\/form>\r\n    <div class=\"panel out\" id=\"gc-out\" aria-live=\"polite\"><\/div><\/div>`;\r\n  const ta=root.querySelector('#gc-text'),o=root.querySelector('#gc-out');ta.value=GEO_SAMPLE;\r\n  function run(){\r\n    const raw=ta.value.trim();if(words(raw)<30){o.innerHTML=empty('Paste at least 30 words of content to check.');return}\r\n    const r=analyzeGeo(raw,val(root,t,'kw')),col=r.score>=80?'var(--emerald)':r.score>=60?'#F59E0B':'var(--lvl-adv)',C=2*Math.PI*52;\r\n    const verdict=r.score>=80?'Ready to be cited':r.score>=60?'Close. A few fixes will help':'Needs more structure';\r\n    const fix=r.C.filter(c=>c.pts<c.max).sort((a,b)=>(b.max-b.pts)-(a.max-a.pts)).slice(0,3);\r\n    o.innerHTML=`<div class=\"out-head\"><h3>AI answer readiness<\/h3><\/div>\r\n    <div class=\"score\"><svg class=\"ring\" viewBox=\"0 0 130 130\" role=\"img\" aria-label=\"Score ${r.score} out of 100\"><circle cx=\"65\" cy=\"65\" r=\"52\" fill=\"none\" stroke=\"var(--surface-2)\" stroke-width=\"12\"\/><circle cx=\"65\" cy=\"65\" r=\"52\" fill=\"none\" stroke=\"${col}\" stroke-width=\"12\" stroke-linecap=\"round\" stroke-dasharray=\"${(C*r.score\/100).toFixed(1)} ${C.toFixed(1)}\" transform=\"rotate(-90 65 65)\"\/><text x=\"65\" y=\"74\" text-anchor=\"middle\" font-size=\"32\" font-weight=\"700\">${r.score}<\/text><\/svg>\r\n    <div><h3 style=\"margin:0 0 4px;font-family:var(--f-display);font-size:1.3rem\">${verdict}<\/h3><p class=\"out-sub\" style=\"margin:0\">This is a structure and clarity check, not a promise of being cited. AI answer engines also weigh how trusted your site is.<\/p><\/div><\/div>\r\n    <div class=\"stats\"><div class=\"stat\"><b>${r.wc}<\/b><span>words<\/span><\/div><div class=\"stat\"><b>${r.heads}<\/b><span>headings<\/span><\/div><div class=\"stat\"><b>${r.avgSent.toFixed(0)}<\/b><span>avg words per sentence<\/span><\/div><div class=\"stat\"><b>${r.numRate.toFixed(1)}<\/b><span>numbers per 100 words<\/span><\/div><\/div>\r\n    ${fix.length?`<div class=\"tips\"><b>Fix these first<\/b>${fix.map(c=>esc(c.label)).join(', ')}.<\/div>`:''}\r\n    <div class=\"block\" style=\"margin-top:12px\"><h4><span>Checklist<\/span><\/h4>${r.C.map(c=>`<div class=\"check\">${tag(c.status==='ok'?'Pass':c.status==='warn'?'Improve':'Fix',c.status==='ok'?'ok':c.status==='warn'?'warn':'bad')}<div><b>${esc(c.label)}<\/b> <span class=\"count\">${c.pts}\/${c.max} \u00b7 ${esc(c.detail)}<\/span><\/div>${c.status!=='ok'?`<p>${esc(c.tip)}<\/p>`:''}<\/div>`).join('')}<\/div>\r\n    ${r.quotable.length?`<div class=\"block\"><h4><span>Sentences an AI answer could quote<\/span><\/h4>${r.quotable.map(s=>resRow(s)).join('')}<\/div>`:''}`;\r\n  }\r\n  root.querySelector('#gc-form').addEventListener('submit',e=>{e.preventDefault();run()});\r\n  root.querySelector('#gc-sample').addEventListener('click',()=>{ta.value=GEO_SAMPLE;run()});\r\n  run();\r\n}\r\n\r\n\/* ================= registry, rail, routing ================= *\/\r\nconst GROUPS=['Marketplace and listings','Feeds and apps','Next-gen search'];\r\nconst TOOLS=[\r\n  {id:'product-title',g:0,lvl:'mid',icon:'tag',title:'Product Title Generator',short:'SEO titles for listings',desc:'Get title formats that fit the character limit of Google Shopping, Amazon, Flipkart, your own store or Etsy.',kw:'amazon flipkart google shopping etsy title listing',mount:toolTitle},\r\n  {id:'product-description',g:0,lvl:'mid',icon:'doc',title:'Product Description Generator',short:'Unique descriptions',desc:'Write a full description, a short card version and a meta description from your features, in the tone you pick.',kw:'copywriting ecommerce description meta',mount:toolDesc},\r\n  {id:'category-content',g:0,lvl:'mid',icon:'grid',title:'Category Page Content Generator',short:'Intro text for categories',desc:'Create the intro, buying guide, FAQ and meta tags for a category page, plus HTML you can paste in.',kw:'category page collection intro faq html',mount:toolCategory},\r\n  {id:'marketplace-keywords',g:0,lvl:'mid',icon:'cart',title:'Amazon \/ Flipkart Keyword Helper',short:'Marketplace keyword ideas',desc:'Find shopper search phrases, pick the best, and build backend search terms within Amazon\\u2019s 250-byte limit.',kw:'amazon flipkart backend search terms keywords',mount:toolKeywords},\r\n  {id:'feed-checker',g:1,lvl:'adv',icon:'shield',title:'Google Merchant Feed Checker',short:'Validates product feed',desc:'Paste or upload a product feed and see every error and warning by row, with attribute coverage.',kw:'google merchant center shopping feed validate gtin price disapproved',mount:toolFeed},\r\n  {id:'aso-keywords',g:1,lvl:'mid',icon:'phone',title:'App Store Keyword Generator (ASO)',short:'Play Store and App Store ideas',desc:'Draft app names, subtitles, short descriptions and the 100-character iOS keyword field.',kw:'aso app store play store mobile app keywords subtitle',mount:toolASO},\r\n  {id:'voice-questions',g:2,lvl:'mid',icon:'mic',title:'Voice Search Question Generator',short:'Natural-language queries',desc:'Turn a topic into the spoken questions people ask, then build FAQ schema from the ones you answer.',kw:'voice search questions faq schema alexa siri near me',mount:toolVoice},\r\n  {id:'geo-checker',g:2,lvl:'adv',icon:'spark',title:'AI Search (GEO) Content Checker',short:'Is it easy for AI to cite?',desc:'Score your content on what AI answer engines look for: direct answers, structure, facts, sources and quotable lines.',kw:'geo generative engine optimization ai overviews chatgpt perplexity citation',mount:toolGeo}\r\n];\r\nconst rail=$('#toolList'),stage=$('#stage');\r\nlet groupFilter=-1,query='';\r\nfunction currentId(){const h=location.hash.slice(1);return TOOLS.some(t=>t.id===h)?h:TOOLS[0].id}\r\nfunction paintRail(){\r\n  const cur=currentId();\r\n  const vis=TOOLS.filter(t=>(groupFilter<0||t.g===groupFilter)&&(!query||(t.title+' '+t.short+' '+t.desc+' '+t.kw).toLowerCase().includes(query)));\r\n  rail.innerHTML=GROUPS.map((g,gi)=>{const items=vis.filter(t=>t.g===gi);if(!items.length)return '';return `<div class=\"rail-group\"><p class=\"rail-label\">${esc(g)}<\/p><div class=\"rail-items\">${items.map(t=>`<a class=\"rail-item\" href=\"#${t.id}\"${t.id===cur?' aria-current=\"page\"':''}><span class=\"ico\">${svg(t.icon)}<\/span><span class=\"rail-name\"><b>${esc(t.title)}<\/b><span>${esc(t.short)}<\/span><\/span><span class=\"dot${t.lvl==='adv'?' adv':''}\" title=\"${t.lvl==='adv'?'Advanced':'Intermediate'}\"><\/span><\/a>`).join('')}<\/div><\/div>`}).join('')||'<p class=\"no-match\">No tool matches that search. Try \"title\", \"feed\" or \"voice\".<\/p>';\r\n}\r\nconst mounted={};\r\nfunction show(){\r\n  const id=currentId(),tool=TOOLS.find(t=>t.id===id);\r\n  TOOLS.forEach(t=>{if(mounted[t.id])mounted[t.id].hidden=t.id!==id});\r\n  if(!mounted[id]){\r\n    const w=document.createElement('div');\r\n    w.innerHTML=`<div class=\"stage-head\"><span class=\"ico\">${svg(tool.icon)}<\/span><div><h2>${esc(tool.title)} <span class=\"pill${tool.lvl==='adv'?' adv':''}\"><i><\/i>${tool.lvl==='adv'?'Advanced':'Intermediate'}<\/span><\/h2><p>${esc(tool.desc)}<\/p><\/div><\/div><div class=\"body\"><\/div>`;\r\n    stage.appendChild(w);mounted[id]=w;\r\n    try{tool.mount(w.querySelector('.body'))}catch(err){w.querySelector('.body').innerHTML='<p class=\"empty\">This tool failed to load. Reload the page and try again.<\/p>';console.error(err)}\r\n  }\r\n  paintRail();\r\n}\r\nwindow.addEventListener('hashchange',()=>{show();if(innerWidth<=900){const r=stage.getBoundingClientRect();window.scrollTo({top:scrollY+r.top-70,behavior:'smooth'})}});\r\n$('#home').addEventListener('click',e=>{e.preventDefault();location.hash=TOOLS[0].id});\r\n$('#toolSearch').addEventListener('input',e=>{query=e.target.value.trim().toLowerCase();paintRail()});\r\nconst chips=$('#groupChips');\r\nchips.innerHTML=['All tools',...GROUPS].map((g,i)=>`<button type=\"button\" class=\"chip\" data-g=\"${i-1}\" aria-pressed=\"${i===0}\">${esc(g)}<\/button>`).join('');\r\nchips.addEventListener('click',e=>{const b=e.target.closest('.chip');if(!b)return;groupFilter=+b.dataset.g;$$('.chip',chips).forEach(c=>c.setAttribute('aria-pressed',String(c===b)));paintRail()});\r\n\r\n\/* theme *\/\r\nconst docEl=document.documentElement;\r\n$('#themeBtn').addEventListener('click',()=>{\r\n  const dark=docEl.dataset.theme==='dark'||(!docEl.dataset.theme&&matchMedia('(prefers-color-scheme: dark)').matches);\r\n  docEl.dataset.theme=dark?'light':'dark';\r\n  try{localStorage.setItem('og-theme',docEl.dataset.theme)}catch(e){}\r\n});\r\ntry{const s=localStorage.getItem('og-theme');if(s&&!docEl.dataset.theme)docEl.dataset.theme=s}catch(e){}\r\n\r\nshow();\r\n})();\r\n<\/script>\r\n\r\n<\/body><\/html>\t\t\t\t<\/div>\n\t\t\n<\/div>\n\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Onground Media SEO Toolkit Onground MediaSEO Toolkit Theme E-commerce and specialized SEO Tools for listings, feeds, app stores and AI [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"site-sidebar-layout":"no-sidebar","site-content-layout":"","ast-site-content-layout":"full-width-container","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"disabled","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"default","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-327","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/ongroundmedia.com\/index.php?rest_route=\/wp\/v2\/pages\/327","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ongroundmedia.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ongroundmedia.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ongroundmedia.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ongroundmedia.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=327"}],"version-history":[{"count":4,"href":"https:\/\/ongroundmedia.com\/index.php?rest_route=\/wp\/v2\/pages\/327\/revisions"}],"predecessor-version":[{"id":331,"href":"https:\/\/ongroundmedia.com\/index.php?rest_route=\/wp\/v2\/pages\/327\/revisions\/331"}],"wp:attachment":[{"href":"https:\/\/ongroundmedia.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=327"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}