@guidelytech/guide-runtime 0.5.0 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/styles.ts","../src/host.ts"],"sourcesContent":["/** All runtime CSS, injected once into the Shadow DOM host. Tokens are CSS custom properties. */\nexport const STYLES = `\n:host{all:initial;position:static;display:block;contain:none}\n*,*::before,*::after{box-sizing:border-box}\n.g-scope [hidden]{display:none!important}\n.g-scope{\n --g-primary:#4f46e5;--g-bg:#ffffff;--g-text:#111827;--g-radius:12px;--g-font:Inter,system-ui,-apple-system,sans-serif;--g-z:2147483000;--g-overlay:.5;\n --g-muted:color-mix(in srgb,var(--g-text) 62%,transparent);--g-border:color-mix(in srgb,var(--g-text) 12%,transparent);\n --g-subtle:color-mix(in srgb,var(--g-text) 5%,transparent);--g-shadow:0 10px 40px rgba(0,0,0,.18),0 2px 8px rgba(0,0,0,.08);\n --g-primary-text:#ffffff;\n font-family:var(--g-font);font-size:14px;line-height:1.5;color:var(--g-text);-webkit-font-smoothing:antialiased;\n}\n.g-scope[data-theme=\"dark\"]{--g-shadow:0 10px 40px rgba(0,0,0,.5),0 2px 8px rgba(0,0,0,.3)}\n.g-live{position:fixed;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}\n.g-layer{position:fixed;inset:0;z-index:var(--g-z);pointer-events:none}\n.g-overlay{position:fixed;inset:0;background:rgba(0,0,0,var(--g-overlay));z-index:calc(var(--g-z) + 3);pointer-events:auto}\n.g-overlay.g-transparent{background:transparent}\n.g-spot-rect{position:fixed;background:rgba(0,0,0,var(--g-overlay));z-index:calc(var(--g-z) + 3);pointer-events:auto}\n.g-spot-ring{position:fixed;z-index:calc(var(--g-z) + 3);pointer-events:none;border-radius:6px;box-shadow:0 0 0 2px var(--g-primary),0 0 0 6px color-mix(in srgb,var(--g-primary) 30%,transparent)}\n.g-card{\n position:fixed;z-index:calc(var(--g-z) + 4);pointer-events:auto;background:var(--g-bg);color:var(--g-text);border-radius:var(--g-radius);\n box-shadow:var(--g-shadow);border:1px solid var(--g-border);width:min(360px,calc(100vw - 32px));max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);overflow:auto;outline:none;\n}\n.g-card.g-modal{left:50%;top:50%;transform:translate(-50%,-50%);width:min(480px,calc(100vw - 32px))}\n.g-card.g-tooltip,.g-card.g-popover,.g-card.g-spotlight-card,.g-card.g-hotspot-card{top:0;left:0;width:min(320px,calc(100vw - 32px))}\n.g-card.g-slideout{width:min(360px,calc(100vw - 32px));margin:16px}\n.g-pos-bottom-right{right:0;bottom:0}.g-pos-bottom-left{left:0;bottom:0}.g-pos-top-right{right:0;top:0}.g-pos-top-left{left:0;top:0}\n.g-pos-center{left:50%;top:50%;transform:translate(-50%,-50%)}\n.g-pos-top{top:0;left:0;right:0}.g-pos-bottom{bottom:0;left:0;right:0}\n.g-banner{position:fixed;left:0;right:0;z-index:calc(var(--g-z) + 1);pointer-events:auto;background:var(--g-primary);color:var(--g-primary-text);padding:10px 48px 10px 16px;display:flex;align-items:center;gap:12px;font-size:14px;box-shadow:0 2px 10px rgba(0,0,0,.15);max-width:100vw}\n.g-banner .g-body{flex:1;min-width:0}\n.g-banner .g-body a{color:inherit;text-decoration:underline}\n.g-banner .g-close{color:inherit;right:8px;top:50%;transform:translateY(-50%)}\n.g-banner .g-btn{background:rgba(255,255,255,.18);color:inherit;border-color:transparent;min-height:36px}\n.g-banner.g-pos-top{top:0}.g-banner.g-pos-bottom{bottom:0}\n.g-inner{padding:20px}\n.g-close{position:absolute;top:8px;right:8px;width:40px;height:40px;display:inline-flex;align-items:center;justify-content:center;border:0;background:transparent;color:var(--g-muted);border-radius:999px;cursor:pointer;font:inherit;font-size:20px;line-height:1}\n.g-close:hover,.g-close:focus-visible{background:var(--g-subtle);color:var(--g-text);outline:none}\n.g-close:focus-visible,.g-btn:focus-visible,.g-task:focus-visible,.g-choice:focus-visible,.g-scale button:focus-visible,.g-launcher:focus-visible,.g-input:focus-visible,.g-rc-item:focus-visible{outline:2px solid var(--g-primary);outline-offset:2px}\n.g-image{display:block;width:100%;max-height:220px;object-fit:cover;border-radius:var(--g-radius) var(--g-radius) 0 0}\n.g-title{margin:0 28px 6px 0;font-size:16px;font-weight:600;line-height:1.3}\n.g-body{font-size:14px;color:var(--g-text)}\n.g-body p{margin:0 0 8px}.g-body p:last-child{margin-bottom:0}\n.g-body ul,.g-body ol{margin:6px 0;padding-left:20px}\n.g-body a{color:var(--g-primary)}\n.g-body img{max-width:100%;height:auto;border-radius:6px}\n.g-body video,.g-body iframe{display:block;width:100%;max-width:100%;border:0;border-radius:6px;margin:8px 0;background:#000}\n.g-body video{height:auto;max-height:60vh}\n.g-body iframe{aspect-ratio:16/9;height:auto}\n.g-body .gd-pdf{margin:10px 0;border:1px solid var(--g-border);border-radius:10px;background:var(--g-subtle);overflow:hidden}\n.g-body a.gd-file{display:flex;align-items:center;gap:8px;padding:8px 10px;color:var(--g-text);font-size:13px;font-weight:500;text-decoration:none;min-height:40px;overflow-wrap:anywhere}\n.g-body a.gd-file::before{content:\"PDF\";flex:none;font-size:9px;font-weight:700;letter-spacing:.04em;line-height:1;color:#fff;background:#e5484d;border-radius:4px;padding:4px 5px}\n.g-body a.gd-file::after{content:\"⤢\";margin-left:auto;padding-left:8px;color:var(--g-muted);font-size:15px}\n.g-body a.gd-file:hover::after,.g-body a.gd-file:focus-visible::after{color:var(--g-primary)}\n.g-body a.gd-file:focus-visible{outline:2px solid var(--g-primary);outline-offset:-2px;border-radius:10px}\n.g-body > a.gd-file,.g-body p > a.gd-file{margin:10px 0;border:1px solid var(--g-border);border-radius:10px;background:var(--g-subtle)}\n.g-body > a.gd-file::after,.g-body p > a.gd-file::after,.g-body .gd-pdf:not([data-g-ready]) > a.gd-file::after{content:\"↗\"}\n.g-pdf-viewport{position:relative}\n.g-body .gd-pdf-pages{display:flex;gap:10px;overflow-x:auto;scroll-snap-type:x mandatory;overscroll-behavior-x:contain;scrollbar-width:none;padding:0 10px 10px;scroll-padding:0 10px}\n.g-body .gd-pdf-pages::-webkit-scrollbar{display:none}\n.g-body .gd-pdf-pages:focus-visible{outline:2px solid var(--g-primary);outline-offset:-2px}\n.g-body .gd-pdf-pages img{flex:0 0 100%;width:100%;height:auto;margin:0;scroll-snap-align:center;background:#fff;border-radius:4px;box-shadow:0 1px 3px rgba(0,0,0,.18);cursor:zoom-in}\n.g-pdf-viewport .gd-pdf-pages{padding:0;scroll-padding:0;margin:0 10px 10px}\n.g-pdf-count{position:absolute;right:18px;bottom:18px;padding:2px 8px;border-radius:999px;background:rgba(17,17,17,.72);color:#fff;font-size:11px;font-weight:500;pointer-events:none;font-variant-numeric:tabular-nums}\n.g-pdf-nav{position:absolute;top:calc(50% - 21px);width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;border:0;border-radius:999px;background:rgba(17,17,17,.6);color:#fff;font:inherit;font-size:20px;line-height:1;cursor:pointer;opacity:0;transition:opacity .15s}\n.g-pdf-prev{left:16px}.g-pdf-next{right:16px}\n.g-pdf-viewport:hover .g-pdf-nav,.g-pdf-nav:focus-visible{opacity:1}\n.g-pdf-nav:disabled,.g-pdf-single .g-pdf-nav,.g-pdf-single .g-pdf-count{display:none}\n.g-pdf-nav:focus-visible{outline:2px solid #fff;outline-offset:1px}\n@media (hover:none){.g-pdf-nav{display:none}}\n.g-pdf-reader{position:fixed;inset:0;z-index:calc(var(--g-z) + 10);display:flex;flex-direction:column;background:#0b0b0d;pointer-events:auto;color:#fff}\n.g-pdf-bar{display:flex;align-items:center;gap:10px;padding:8px 8px 8px 16px;min-height:56px}\n.g-pdf-title{flex:1;min-width:0;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.g-pdf-bar .g-btn{min-height:36px;color:#fff;background:rgba(255,255,255,.12);border-color:rgba(255,255,255,.18)}\n.g-pdf-close{position:static;color:#fff}\n.g-pdf-close:hover,.g-pdf-close:focus-visible{background:rgba(255,255,255,.14);color:#fff}\n.g-pdf-scroll{position:relative;flex:1;overflow-y:auto;overscroll-behavior:contain;padding:4px 16px 24px;display:flex;flex-direction:column;align-items:center;gap:12px;outline:none}\n.g-pdf-scroll img{display:block;width:100%;max-width:900px;height:auto;background:#fff;border-radius:2px;box-shadow:0 2px 12px rgba(0,0,0,.4)}\n.g-body code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px;background:var(--g-subtle);padding:1px 4px;border-radius:4px}\n.g-body pre{background:var(--g-subtle);padding:10px;border-radius:6px;overflow:auto}\n.g-body blockquote{margin:6px 0;padding-left:10px;border-left:3px solid var(--g-border);color:var(--g-muted)}\n.g-footer{display:flex;align-items:center;gap:8px;margin-top:14px;flex-wrap:wrap}\n.g-progress{font-size:12px;color:var(--g-muted);margin-right:auto}\n.g-btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:40px;padding:8px 14px;border-radius:calc(var(--g-radius) * .66);border:1px solid transparent;font:inherit;font-size:14px;font-weight:500;cursor:pointer;text-decoration:none;transition:background .15s,color .15s,border-color .15s}\n.g-btn-primary{background:var(--g-primary);color:var(--g-primary-text)}\n.g-btn-primary:hover{filter:brightness(1.08)}\n.g-btn-secondary{background:var(--g-subtle);color:var(--g-text);border-color:var(--g-border)}\n.g-btn-secondary:hover{background:color-mix(in srgb,var(--g-text) 10%,transparent)}\n.g-btn-ghost{background:transparent;color:var(--g-muted)}\n.g-btn-ghost:hover{background:var(--g-subtle);color:var(--g-text)}\n.g-btn-link{background:transparent;color:var(--g-primary);padding-left:4px;padding-right:4px}\n.g-btn-link:hover{text-decoration:underline}\n.g-btn:disabled{opacity:.5;cursor:not-allowed}\n.g-arrow{position:absolute;width:12px;height:12px;background:var(--g-bg);transform:rotate(45deg);border:1px solid var(--g-border);z-index:-1}\n.g-hotspot{position:fixed;z-index:calc(var(--g-z) + 1);pointer-events:auto;border-radius:999px;background:var(--g-primary);border:2px solid #fff;box-shadow:0 0 0 2px color-mix(in srgb,var(--g-primary) 40%,transparent);cursor:pointer;padding:0;margin:0}\n.g-hotspot::after{content:\"\";position:absolute;inset:-4px;border-radius:999px;border:2px solid var(--g-primary);opacity:0}\n.g-hotspot.g-pulse::after{animation:g-pulse 1.8s ease-out infinite}\n.g-hotspot-hit{position:absolute;inset:-14px}\n.g-custom{position:fixed;z-index:calc(var(--g-z) + 4);pointer-events:auto;left:50%;top:50%;transform:translate(-50%,-50%);max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);overflow:auto}\n/* animations */\n.g-scope[data-anim=\"fade\"] .g-card,.g-scope[data-anim=\"fade\"] .g-banner,.g-scope[data-anim=\"fade\"] .g-panel{animation:g-fade .18s ease-out}\n.g-scope[data-anim=\"slide\"] .g-card,.g-scope[data-anim=\"slide\"] .g-panel{animation:g-slide .22s ease-out}\n.g-scope[data-anim=\"none\"] *{animation:none!important;transition:none!important}\n@keyframes g-fade{from{opacity:0}to{opacity:1}}\n@keyframes g-slide{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}\n@keyframes g-pulse{0%{transform:scale(.6);opacity:.9}100%{transform:scale(2.2);opacity:0}}\n@media (prefers-reduced-motion:reduce){.g-scope *{animation:none!important;transition:none!important}}\n/* launcher + panel (checklist / resource center) */\n.g-launcher{position:fixed;z-index:calc(var(--g-z) + 1);pointer-events:auto;display:inline-flex;align-items:center;gap:8px;min-height:44px;padding:10px 16px;border-radius:999px;border:0;background:var(--g-primary);color:var(--g-primary-text);font:inherit;font-size:14px;font-weight:600;cursor:pointer;box-shadow:var(--g-shadow);margin:16px}\n.g-launcher .g-ring{width:22px;height:22px;border-radius:999px;background:conic-gradient(#fff var(--g-pct,0%),rgba(255,255,255,.3) 0);display:inline-flex;align-items:center;justify-content:center;font-size:10px;position:relative}\n.g-launcher .g-ring::after{content:\"\";position:absolute;inset:3px;border-radius:999px;background:var(--g-primary)}\n.g-launcher .g-count{position:relative;z-index:1}\n.g-panel{position:fixed;z-index:calc(var(--g-z) + 2);pointer-events:auto;width:min(380px,calc(100vw - 32px));max-height:min(620px,calc(100vh - 100px));display:flex;flex-direction:column;background:var(--g-bg);color:var(--g-text);border-radius:var(--g-radius);box-shadow:var(--g-shadow);border:1px solid var(--g-border);margin:16px;bottom:60px;overflow:hidden}\n.g-panel-head{padding:16px 48px 12px 20px;border-bottom:1px solid var(--g-border);position:relative}\n.g-panel-title{margin:0;font-size:16px;font-weight:600}\n.g-panel-sub{margin:4px 0 0;font-size:12px;color:var(--g-muted)}\n.g-panel-body{overflow:auto;padding:8px 0;flex:1}\n.g-help{display:flex;flex-direction:column;min-height:0;flex:1}\n.g-bar{height:6px;border-radius:999px;background:var(--g-subtle);overflow:hidden;margin-top:10px}\n.g-bar > span{display:block;height:100%;background:var(--g-primary);transition:width .3s}\n.g-task{display:flex;gap:12px;align-items:flex-start;width:100%;padding:12px 20px;border:0;background:transparent;text-align:left;font:inherit;color:inherit;cursor:pointer;min-height:44px}\n.g-task:hover{background:var(--g-subtle)}\n.g-task[disabled]{cursor:not-allowed;opacity:.55}\n.g-task .g-check{flex:none;width:22px;height:22px;border-radius:999px;border:2px solid var(--g-border);display:inline-flex;align-items:center;justify-content:center;font-size:13px;margin-top:1px;color:#fff}\n.g-task.g-done .g-check{background:var(--g-primary);border-color:var(--g-primary)}\n.g-task.g-done .g-task-title{text-decoration:line-through;color:var(--g-muted)}\n.g-task-title{font-weight:500}\n.g-task-desc{font-size:12px;color:var(--g-muted);margin-top:2px}\n.g-panel-foot{padding:10px 20px;border-top:1px solid var(--g-border);display:flex;justify-content:flex-end;gap:8px}\n.g-complete{padding:28px 20px;text-align:center}\n.g-complete .g-title{margin-right:0;font-size:18px}\n/* survey */\n.g-question{margin-bottom:16px}\n.g-q-title{font-weight:600;margin:0 0 4px}\n.g-q-desc{font-size:12px;color:var(--g-muted);margin:0 0 8px}\n.g-scale{display:flex;gap:4px;flex-wrap:wrap}\n.g-scale button{min-width:34px;height:40px;flex:1;padding:0 4px;border-radius:6px;border:1px solid var(--g-border);background:var(--g-subtle);color:var(--g-text);font:inherit;cursor:pointer}\n.g-scale button[aria-pressed=\"true\"],.g-scale button:hover{background:var(--g-primary);color:var(--g-primary-text);border-color:var(--g-primary)}\n.g-scale-labels{display:flex;justify-content:space-between;font-size:11px;color:var(--g-muted);margin-top:4px}\n.g-stars button,.g-thumbs button{font-size:22px;background:transparent;border:0;cursor:pointer;color:var(--g-muted);min-width:40px;height:40px;font:inherit}\n.g-stars button[aria-pressed=\"true\"],.g-stars button.g-on{color:#f59e0b}\n.g-thumbs button[aria-pressed=\"true\"]{color:var(--g-primary)}\n.g-choice{display:flex;align-items:center;gap:10px;padding:8px 10px;border:1px solid var(--g-border);border-radius:8px;margin-bottom:6px;cursor:pointer;min-height:40px;font:inherit;background:transparent;color:inherit;width:100%;text-align:left}\n.g-choice[aria-checked=\"true\"]{border-color:var(--g-primary);background:color-mix(in srgb,var(--g-primary) 8%,transparent)}\n.g-choice .g-dot{width:16px;height:16px;border-radius:999px;border:2px solid var(--g-border);flex:none}\n.g-choice.g-multi .g-dot{border-radius:4px}\n.g-choice[aria-checked=\"true\"] .g-dot{background:var(--g-primary);border-color:var(--g-primary)}\n.g-input{width:100%;min-height:40px;padding:8px 10px;border:1px solid var(--g-border);border-radius:8px;background:var(--g-bg);color:var(--g-text);font:inherit;resize:vertical}\n.g-error{color:#dc2626;font-size:12px;margin-top:4px}\n/* resource center */\n.g-rc-search{padding:12px 20px 4px}\n.g-rc-section{padding:8px 20px 4px;font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--g-muted);font-weight:600}\n.g-rc-section[data-depth]{text-transform:none;letter-spacing:0;font-size:12px}\n.g-rc-item{display:flex;align-items:flex-start;gap:10px;width:100%;padding:10px 20px;border:0;background:transparent;font:inherit;color:inherit;text-align:left;cursor:pointer;min-height:44px;text-decoration:none}\n.g-rc-item:hover{background:var(--g-subtle)}\n.g-rc-item .g-rc-title{font-weight:500}\n.g-rc-item .g-rc-sum{font-size:12px;color:var(--g-muted);margin-top:2px}\n.g-rc-item .g-rc-icon{flex:none;width:20px;text-align:center;color:var(--g-primary)}\n.g-rc-article{padding:16px 20px}\n.g-rc-back{margin-bottom:8px}\n.g-rc-empty{padding:24px 20px;color:var(--g-muted);text-align:center}\n.g-faq-a{padding:0 20px 12px 50px;font-size:13px;color:var(--g-muted)}\n.g-faq-a[hidden]{display:none}\n/* authoring */\n.g-auth-bar{position:fixed;top:0;left:0;right:0;z-index:calc(var(--g-z) + 10);pointer-events:auto;display:flex;align-items:center;gap:12px;padding:8px 16px;background:#111827;color:#fff;font:500 13px/1.4 var(--g-font);box-shadow:0 2px 10px rgba(0,0,0,.3)}\n.g-auth-bar .g-dot-live{width:8px;height:8px;border-radius:999px;background:#22c55e;box-shadow:0 0 0 3px rgba(34,197,94,.3)}\n.g-auth-bar .g-spacer{flex:1}\n.g-auth-bar .g-btn{min-height:32px;padding:4px 12px;font-size:13px}\n.g-auth-bar .g-btn-secondary{background:rgba(255,255,255,.12);color:#fff;border-color:transparent}\n.g-auth-outline{position:fixed;z-index:calc(var(--g-z) + 9);pointer-events:none;border:2px solid var(--g-primary);background:color-mix(in srgb,var(--g-primary) 12%,transparent);border-radius:4px;transition:all .06s linear}\n.g-auth-label{position:absolute;left:-2px;top:-24px;background:var(--g-primary);color:#fff;font:600 11px/1 var(--g-font);padding:5px 7px;border-radius:4px;white-space:nowrap;max-width:320px;overflow:hidden;text-overflow:ellipsis}\n.g-auth-outline.g-picked{border-style:dashed;border-color:#22c55e;background:rgba(34,197,94,.12)}\n.g-auth-outline.g-picked .g-auth-label{background:#16a34a}\n.g-highlight{position:fixed;z-index:calc(var(--g-z) + 8);pointer-events:none;border:2px dashed #f59e0b;background:rgba(245,158,11,.12);border-radius:4px}\n@media (max-width:480px){.g-card.g-modal,.g-panel{width:calc(100vw - 32px)}.g-inner{padding:16px}}\n`;\n","import type { Appearance, ProjectTheme } from \"@guidelytech/shared\";\nimport { STYLES } from \"./styles\";\n\nexport const HOST_ID = \"guidely-root\";\n\nexport interface HostHandle {\n host: HTMLElement;\n shadow: ShadowRoot;\n /** Polite live region for screen-reader announcements. */\n live: HTMLElement;\n announce(text: string): void;\n destroy(): void;\n}\n\nlet current: HostHandle | null = null;\n\n/** Default project theme used when the config has not loaded yet. */\nexport const DEFAULT_THEME: ProjectTheme = {\n primaryColor: \"#4f46e5\",\n backgroundColor: \"#ffffff\",\n textColor: \"#111827\",\n borderRadius: 12,\n fontFamily: \"Inter, system-ui, -apple-system, sans-serif\",\n};\n\n/** Returns (creating when needed) the single Shadow-DOM host appended to `document.body`. */\nexport function ensureHost(doc: Document = document): HostHandle {\n if (current && current.host.isConnected && current.host.ownerDocument === doc) return current;\n let host = doc.getElementById(HOST_ID) as HTMLElement | null;\n if (!host) {\n host = doc.createElement(\"div\");\n host.id = HOST_ID;\n host.setAttribute(\"data-guidely\", \"\");\n (doc.body || doc.documentElement).appendChild(host);\n }\n const shadow = host.shadowRoot ?? host.attachShadow({ mode: \"open\" });\n if (!shadow.querySelector(\"style[data-g-base]\")) {\n const style = doc.createElement(\"style\");\n style.setAttribute(\"data-g-base\", \"\");\n style.textContent = STYLES;\n shadow.appendChild(style);\n }\n let live = shadow.querySelector<HTMLElement>(\".g-live\");\n if (!live) {\n live = doc.createElement(\"div\");\n live.className = \"g-live\";\n live.setAttribute(\"aria-live\", \"polite\");\n live.setAttribute(\"aria-atomic\", \"true\");\n shadow.appendChild(live);\n }\n const liveEl = live;\n current = {\n host,\n shadow,\n live: liveEl,\n announce(text: string) {\n liveEl.textContent = \"\";\n setTimeout(() => {\n liveEl.textContent = text;\n }, 30);\n },\n destroy() {\n host?.remove();\n if (current?.host === host) current = null;\n },\n };\n return current;\n}\n\n/** Removes the host from the document (all overlays with it). */\nexport function destroyHost(): void {\n current?.destroy();\n const stray = typeof document !== \"undefined\" ? document.getElementById(HOST_ID) : null;\n stray?.remove();\n current = null;\n}\n\nexport type ResolvedThemeMode = \"light\" | \"dark\";\n\nfunction prefersDark(): boolean {\n try {\n return typeof window !== \"undefined\" && typeof window.matchMedia === \"function\" && window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n } catch {\n return false;\n }\n}\n\nexport function prefersReducedMotion(): boolean {\n try {\n return typeof window !== \"undefined\" && typeof window.matchMedia === \"function\" && window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n } catch {\n return false;\n }\n}\n\nexport interface ThemeVars {\n primary: string;\n bg: string;\n text: string;\n radius: number;\n font: string;\n z: number;\n overlay: number;\n mode: ResolvedThemeMode;\n animation: Appearance[\"animation\"];\n}\n\n/** Merges project theme + guide appearance into CSS custom property values. */\nexport function resolveTheme(theme: Partial<ProjectTheme> | null | undefined, appearance?: Partial<Appearance> | null): ThemeVars {\n const t = { ...DEFAULT_THEME, ...(theme || {}) };\n const a = appearance || {};\n const requested = a.theme ?? \"auto\";\n const mode: ResolvedThemeMode = requested === \"auto\" ? (prefersDark() ? \"dark\" : \"light\") : requested;\n const dark = mode === \"dark\";\n return {\n primary: a.primaryColor || t.primaryColor,\n bg: a.backgroundColor || (dark ? \"#1f2937\" : t.backgroundColor),\n text: a.textColor || (dark ? \"#f9fafb\" : t.textColor),\n radius: a.borderRadius ?? t.borderRadius,\n font: a.fontFamily || t.fontFamily,\n z: a.zIndex ?? 2147483000,\n overlay: a.overlayOpacity ?? 0.5,\n mode,\n animation: prefersReducedMotion() ? \"none\" : (a.animation ?? \"fade\"),\n };\n}\n\n/** Applies theme variables to a scope element. */\nexport function applyTheme(el: HTMLElement, vars: ThemeVars): void {\n el.style.setProperty(\"--g-primary\", vars.primary);\n el.style.setProperty(\"--g-bg\", vars.bg);\n el.style.setProperty(\"--g-text\", vars.text);\n el.style.setProperty(\"--g-radius\", `${vars.radius}px`);\n el.style.setProperty(\"--g-font\", vars.font);\n el.style.setProperty(\"--g-z\", String(vars.z));\n el.style.setProperty(\"--g-overlay\", String(vars.overlay));\n el.setAttribute(\"data-theme\", vars.mode);\n el.setAttribute(\"data-anim\", vars.animation);\n}\n\n/**\n * Creates a themed scope container inside the shadow root. Each guide/widget renders inside its\n * own scope so appearance settings never leak between guides.\n */\nexport function createScope(theme?: Partial<ProjectTheme> | null, appearance?: Partial<Appearance> | null, doc: Document = document): { el: HTMLElement; vars: ThemeVars; destroy(): void } {\n const handle = ensureHost(doc);\n const el = doc.createElement(\"div\");\n el.className = \"g-scope\";\n const vars = resolveTheme(theme, appearance);\n applyTheme(el, vars);\n handle.shadow.appendChild(el);\n let mq: MediaQueryList | null = null;\n const onChange = () => applyTheme(el, resolveTheme(theme, appearance));\n if ((appearance?.theme ?? \"auto\") === \"auto\" && typeof window !== \"undefined\" && typeof window.matchMedia === \"function\") {\n try {\n mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n mq.addEventListener?.(\"change\", onChange);\n } catch {\n mq = null;\n }\n }\n return {\n el,\n vars,\n destroy() {\n mq?.removeEventListener?.(\"change\", onChange);\n el.remove();\n },\n };\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,301 @@
1
+ import {
2
+ __publicField
3
+ } from "./chunk-7DOGZKWD.js";
4
+
5
+ // src/selectors.ts
6
+ import { matchUrlPattern } from "@guidelytech/shared/runtime";
7
+ function urlMatches(pattern, url) {
8
+ if (!pattern) return true;
9
+ if (matchUrlPattern(pattern, url)) return true;
10
+ try {
11
+ const u = new URL(url, "http://localhost");
12
+ if (!pattern.includes("?") && !pattern.includes("#")) return matchUrlPattern(pattern, u.pathname) || matchUrlPattern(pattern, u.origin + u.pathname);
13
+ } catch {
14
+ }
15
+ return false;
16
+ }
17
+ var TEXT_CANDIDATES = "button, a, [role='button'], [role='link'], [role='tab'], [role='menuitem'], h1, h2, h3, h4, h5, h6, label, summary";
18
+ var HOST_ID = "guidely-root";
19
+ function docOf(root) {
20
+ return root.nodeType === 9 ? root : root.ownerDocument;
21
+ }
22
+ function hasLayout(doc) {
23
+ const de = doc.documentElement;
24
+ if (!de) return false;
25
+ const r = de.getBoundingClientRect();
26
+ return r.width > 0 || r.height > 0;
27
+ }
28
+ function normalizeText(text) {
29
+ return (text || "").replace(/\s+/g, " ").trim();
30
+ }
31
+ function isVisible(el) {
32
+ if (!el.isConnected) return false;
33
+ const doc = el.ownerDocument;
34
+ const win = doc.defaultView;
35
+ let cur = el;
36
+ while (cur && cur !== doc.documentElement) {
37
+ if (cur.hidden) return false;
38
+ if (win) {
39
+ const cs = win.getComputedStyle(cur);
40
+ if (cs.display === "none" || cs.visibility === "hidden") return false;
41
+ }
42
+ cur = cur.parentElement ?? cur.getRootNode().host ?? null;
43
+ }
44
+ if (hasLayout(doc)) {
45
+ const r = el.getBoundingClientRect();
46
+ if (r.width === 0 && r.height === 0) return false;
47
+ }
48
+ return true;
49
+ }
50
+ function isGuidelyElement(el) {
51
+ if (!el) return false;
52
+ const root = el.getRootNode();
53
+ if (root instanceof ShadowRoot && root.host.id === HOST_ID) return true;
54
+ return el.id === HOST_ID || !!el.closest?.(`#${HOST_ID}`);
55
+ }
56
+ function safeQueryAll(root, selector) {
57
+ try {
58
+ return Array.from(root.querySelectorAll(selector));
59
+ } catch {
60
+ return [];
61
+ }
62
+ }
63
+ function escapeCss(value) {
64
+ const g = globalThis;
65
+ if (g.CSS && typeof g.CSS.escape === "function") return g.CSS.escape(value);
66
+ return value.replace(/["\\]/g, "\\$&");
67
+ }
68
+ function queryXPath(root, expr) {
69
+ const doc = docOf(root);
70
+ const d = doc;
71
+ if (typeof d.evaluate !== "function") return [];
72
+ try {
73
+ const result = d.evaluate(expr, root, null, 7, null);
74
+ const out = [];
75
+ for (let i = 0; i < result.snapshotLength; i++) {
76
+ const n = result.snapshotItem(i);
77
+ if (n && n.nodeType === 1) out.push(n);
78
+ }
79
+ return out;
80
+ } catch {
81
+ return [];
82
+ }
83
+ }
84
+ function queryText(root, text) {
85
+ const needle = normalizeText(text).toLowerCase();
86
+ if (!needle) return [];
87
+ const candidates = safeQueryAll(root, TEXT_CANDIDATES);
88
+ const exact = candidates.filter((c) => normalizeText(c.textContent).toLowerCase() === needle);
89
+ if (exact.length) return exact;
90
+ return candidates.filter((c) => normalizeText(c.textContent).toLowerCase().includes(needle));
91
+ }
92
+ function querySelectorStrategy(strategy, root) {
93
+ const value = strategy.value.trim();
94
+ if (!value) return [];
95
+ switch (strategy.kind) {
96
+ case "id": {
97
+ const id = value.startsWith("#") ? value.slice(1) : value;
98
+ return safeQueryAll(root, `#${escapeCss(id)}`);
99
+ }
100
+ case "guidely-id": {
101
+ const id = value.startsWith("#") ? value.slice(1) : value;
102
+ return safeQueryAll(root, attrSelector("data-guidely-id", id));
103
+ }
104
+ case "data-attr":
105
+ case "aria":
106
+ case "css":
107
+ return safeQueryAll(root, value.startsWith("[") || /^[a-z*#.[]/i.test(value) ? value : `[${value}]`);
108
+ case "text":
109
+ return queryText(root, value);
110
+ case "xpath":
111
+ return queryXPath(root, value);
112
+ default:
113
+ return [];
114
+ }
115
+ }
116
+ function resolveTarget(target, root = document) {
117
+ const selectors = Array.isArray(target) ? target : target.selectors;
118
+ for (const strategy of selectors) {
119
+ const matches = querySelectorStrategy(strategy, root).filter((el) => !isGuidelyElement(el) && isVisible(el));
120
+ if (matches.length === 1) return matches[0];
121
+ }
122
+ return null;
123
+ }
124
+ var TargetTimeoutError = class extends Error {
125
+ constructor(message = "Target element not found before timeout") {
126
+ super(message);
127
+ __publicField(this, "name", "TargetTimeoutError");
128
+ }
129
+ };
130
+ function waitForTarget(target, options = {}) {
131
+ const timeoutMs = options.timeoutMs ?? 5e3;
132
+ const root = options.root ?? document;
133
+ const pollMs = Math.min(250, Math.max(16, options.pollMs ?? 250));
134
+ return new Promise((resolve, reject) => {
135
+ const immediate = resolveTarget(target, root);
136
+ if (immediate) return resolve(immediate);
137
+ if (options.signal?.aborted) return reject(new DOMException("Aborted", "AbortError"));
138
+ let done = false;
139
+ let observer = null;
140
+ let timer = null;
141
+ let timeout = null;
142
+ const cleanup = () => {
143
+ done = true;
144
+ observer?.disconnect();
145
+ if (timer) clearInterval(timer);
146
+ if (timeout) clearTimeout(timeout);
147
+ options.signal?.removeEventListener("abort", onAbort);
148
+ };
149
+ const check = () => {
150
+ if (done) return;
151
+ const el = resolveTarget(target, root);
152
+ if (el) {
153
+ cleanup();
154
+ resolve(el);
155
+ }
156
+ };
157
+ const onAbort = () => {
158
+ cleanup();
159
+ reject(new DOMException("Aborted", "AbortError"));
160
+ };
161
+ options.signal?.addEventListener("abort", onAbort);
162
+ const observeRoot = root.nodeType === 9 ? root.documentElement : root;
163
+ if (typeof MutationObserver !== "undefined" && observeRoot) {
164
+ observer = new MutationObserver(check);
165
+ observer.observe(observeRoot, { childList: true, subtree: true, attributes: true, attributeFilter: ["class", "style", "hidden", "id", "data-tour", "data-guidely-id", "aria-label"] });
166
+ }
167
+ timer = setInterval(check, pollMs);
168
+ if (timeoutMs > 0) {
169
+ timeout = setTimeout(() => {
170
+ cleanup();
171
+ reject(new TargetTimeoutError());
172
+ }, timeoutMs);
173
+ }
174
+ });
175
+ }
176
+ var GENERATED_ID = /(\d{4,}|:r[0-9a-z]+:|^radix-|^headlessui-|^mui-|^ember\d|^react-|^\w*-\d+$|__|^[a-f0-9]{8,}$|^svelte-)/i;
177
+ var GENERATED_CLASS = /(^css-|^sc-|^jss\d|^svelte-|^emotion-|^chakra-|^Mui|^_|[0-9a-f]{6,}|^\w{1,2}$|^[a-z]+-\d+$|[:[\]/])/;
178
+ var PREFERRED_DATA_ATTRS = ["data-testid", "data-tour", "data-test", "data-test-id", "data-cy", "data-qa", "data-id", "data-name", "data-guidely"];
179
+ var IGNORED_DATA_ATTRS = /^data-(guidely-id|state|v-|reactid|react|radix|headlessui|svelte|hydrated|orientation|highlighted|focus|key|index|rbd|dnd|rk-|sveltekit)/i;
180
+ function isStableId(id) {
181
+ return !!id && /^[A-Za-z][\w-]*$/.test(id) && !GENERATED_ID.test(id);
182
+ }
183
+ function isStableClass(cls) {
184
+ return !!cls && !GENERATED_CLASS.test(cls) && cls.length <= 40;
185
+ }
186
+ function uniqueIn(doc, selector, el) {
187
+ const all = safeQueryAll(doc, selector);
188
+ return all.length === 1 && all[0] === el;
189
+ }
190
+ function attrSelector(name, value) {
191
+ return `[${name}='${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}']`;
192
+ }
193
+ function cssPath(el, doc) {
194
+ const segments = [];
195
+ let cur = el;
196
+ while (cur && cur.nodeType === 1 && cur !== doc.body && cur !== doc.documentElement) {
197
+ const tag = cur.tagName.toLowerCase();
198
+ if (isStableId(cur.id)) {
199
+ segments.unshift(`#${cur.id}`);
200
+ break;
201
+ }
202
+ let seg = tag;
203
+ const parent = cur.parentElement;
204
+ if (parent) {
205
+ const sameTag = Array.from(parent.children).filter((c) => c.tagName === cur.tagName);
206
+ if (sameTag.length > 1) {
207
+ const stableCls = Array.from(cur.classList).find((c) => isStableClass(c) && sameTag.filter((s) => s.classList.contains(c)).length === 1);
208
+ seg += stableCls ? `.${escapeCss(stableCls)}` : `:nth-of-type(${sameTag.indexOf(cur) + 1})`;
209
+ }
210
+ }
211
+ segments.unshift(seg);
212
+ const candidate = segments.join(" > ");
213
+ if (uniqueIn(doc, candidate, el)) return candidate;
214
+ cur = parent;
215
+ }
216
+ const full = segments.join(" > ");
217
+ return uniqueIn(doc, full, el) ? full : null;
218
+ }
219
+ function textSnapshotOf(el) {
220
+ const he = el;
221
+ const own = normalizeText(he.innerText ?? el.textContent);
222
+ const alt = normalizeText(el.getAttribute("aria-label") || el.getAttribute("title") || el.getAttribute("placeholder") || el.getAttribute("alt") || el.value);
223
+ return (own || alt).slice(0, 200);
224
+ }
225
+ function generateSelectors(el) {
226
+ const doc = el.ownerDocument;
227
+ const out = [];
228
+ const seen = /* @__PURE__ */ new Set();
229
+ const push = (s) => {
230
+ const k = `${s.kind}:${s.value}`;
231
+ if (!seen.has(k)) {
232
+ seen.add(k);
233
+ out.push(s);
234
+ }
235
+ };
236
+ const tag = el.tagName.toLowerCase();
237
+ const guidelyId = el.getAttribute("data-guidely-id");
238
+ if (guidelyId && uniqueIn(doc, attrSelector("data-guidely-id", guidelyId), el)) push({ kind: "guidely-id", value: guidelyId, label: `Guidely id ${guidelyId}` });
239
+ if (isStableId(el.id) && uniqueIn(doc, `#${escapeCss(el.id)}`, el)) push({ kind: "id", value: `#${el.id}`, label: `id ${el.id}` });
240
+ const dataAttrs = Array.from(el.attributes).filter((a) => a.name.startsWith("data-") && !IGNORED_DATA_ATTRS.test(a.name) && a.value && a.value.length <= 120 && !/\d{5,}/.test(a.value));
241
+ dataAttrs.sort((a, b) => {
242
+ const ia = PREFERRED_DATA_ATTRS.indexOf(a.name);
243
+ const ib = PREFERRED_DATA_ATTRS.indexOf(b.name);
244
+ return (ia === -1 ? 99 : ia) - (ib === -1 ? 99 : ib);
245
+ });
246
+ for (const a of dataAttrs) {
247
+ const sel = attrSelector(a.name, a.value);
248
+ if (uniqueIn(doc, sel, el)) push({ kind: "data-attr", value: sel, label: `${a.name}=${a.value}` });
249
+ else if (uniqueIn(doc, tag + sel, el)) push({ kind: "data-attr", value: tag + sel, label: `${a.name}=${a.value}` });
250
+ }
251
+ const aria = el.getAttribute("aria-label");
252
+ if (aria && aria.length <= 120) {
253
+ const sel = attrSelector("aria-label", aria);
254
+ if (uniqueIn(doc, sel, el)) push({ kind: "aria", value: sel, label: aria });
255
+ else if (uniqueIn(doc, tag + sel, el)) push({ kind: "aria", value: tag + sel, label: aria });
256
+ }
257
+ const name = el.getAttribute("name");
258
+ if (name && uniqueIn(doc, tag + attrSelector("name", name), el)) push({ kind: "css", value: tag + attrSelector("name", name), label: `${tag} name=${name}` });
259
+ const role = el.getAttribute("role");
260
+ if (role) {
261
+ const title = el.getAttribute("title") || el.getAttribute("aria-labelledby");
262
+ const sel = title ? `[role='${role}']${attrSelector(el.getAttribute("title") ? "title" : "aria-labelledby", title)}` : `[role='${role}']`;
263
+ if (uniqueIn(doc, sel, el)) push({ kind: "css", value: sel, label: `role ${role}` });
264
+ }
265
+ if (tag === "a") {
266
+ const href = el.getAttribute("href");
267
+ if (href && href.length <= 200 && uniqueIn(doc, `a${attrSelector("href", href)}`, el)) push({ kind: "css", value: `a${attrSelector("href", href)}`, label: `link ${href}` });
268
+ }
269
+ const path = cssPath(el, doc);
270
+ if (path) push({ kind: "css", value: path, label: "css path" });
271
+ if (/^(button|a|h[1-6]|label|summary)$/.test(tag) || role === "button" || role === "link" || role === "tab" || role === "menuitem") {
272
+ const text = normalizeText(el.innerText ?? el.textContent);
273
+ if (text && text.length <= 80) push({ kind: "text", value: text, label: `text "${text}"` });
274
+ }
275
+ return out.slice(0, 10);
276
+ }
277
+ function describeElement(el) {
278
+ const r = el.getBoundingClientRect();
279
+ return {
280
+ selectors: generateSelectors(el),
281
+ textSnapshot: textSnapshotOf(el),
282
+ rect: { x: r.x, y: r.y, width: r.width, height: r.height },
283
+ tag: el.tagName.toLowerCase()
284
+ };
285
+ }
286
+
287
+ export {
288
+ urlMatches,
289
+ normalizeText,
290
+ isVisible,
291
+ isGuidelyElement,
292
+ querySelectorStrategy,
293
+ resolveTarget,
294
+ TargetTimeoutError,
295
+ waitForTarget,
296
+ isStableId,
297
+ textSnapshotOf,
298
+ generateSelectors,
299
+ describeElement
300
+ };
301
+ //# sourceMappingURL=chunk-GUSKGNNR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/selectors.ts"],"sourcesContent":["import { matchUrlPattern } from \"@guidelytech/shared/runtime\";\nimport type { SelectorStrategy, StepTarget } from \"@guidelytech/shared\";\n\n/**\n * URL matching used for `step.url`, `urlPatterns` and `trigger.urlPattern`: a pattern matches the\n * full URL, the path+query+hash, or the bare path (so `/deals` also matches `/deals?x=1`).\n */\nexport function urlMatches(pattern: string | undefined | null, url: string): boolean {\n if (!pattern) return true;\n if (matchUrlPattern(pattern, url)) return true;\n try {\n const u = new URL(url, \"http://localhost\");\n if (!pattern.includes(\"?\") && !pattern.includes(\"#\")) return matchUrlPattern(pattern, u.pathname) || matchUrlPattern(pattern, u.origin + u.pathname);\n } catch {\n /* ignore */\n }\n return false;\n}\n\nexport type QueryRoot = Document | DocumentFragment | Element;\n\nconst TEXT_CANDIDATES =\n \"button, a, [role='button'], [role='link'], [role='tab'], [role='menuitem'], h1, h2, h3, h4, h5, h6, label, summary\";\n\nconst HOST_ID = \"guidely-root\";\n\nfunction docOf(root: QueryRoot): Document {\n return root.nodeType === 9 ? (root as Document) : (root.ownerDocument as Document);\n}\n\n/** True when the environment has a layout engine (real browsers). happy-dom/jsdom report zero sizes. */\nfunction hasLayout(doc: Document): boolean {\n const de = doc.documentElement;\n if (!de) return false;\n const r = de.getBoundingClientRect();\n return r.width > 0 || r.height > 0;\n}\n\n/** Normalises whitespace in a text snippet. */\nexport function normalizeText(text: string | null | undefined): string {\n return (text || \"\").replace(/\\s+/g, \" \").trim();\n}\n\n/** Is the element rendered (not hidden by `hidden`, `display:none`, `visibility:hidden`, or zero size)? */\nexport function isVisible(el: Element): boolean {\n if (!el.isConnected) return false;\n const doc = el.ownerDocument;\n const win = doc.defaultView;\n let cur: Element | null = el;\n while (cur && cur !== doc.documentElement) {\n if ((cur as HTMLElement).hidden) return false;\n if (win) {\n const cs = win.getComputedStyle(cur);\n if (cs.display === \"none\" || cs.visibility === \"hidden\") return false;\n }\n cur = cur.parentElement ?? ((cur.getRootNode() as ShadowRoot).host as Element | undefined) ?? null;\n }\n if (hasLayout(doc)) {\n const r = el.getBoundingClientRect();\n if (r.width === 0 && r.height === 0) return false;\n }\n return true;\n}\n\n/** Elements that belong to Guidely's own UI are never valid targets. */\nexport function isGuidelyElement(el: Element | null): boolean {\n if (!el) return false;\n const root = el.getRootNode();\n if (root instanceof ShadowRoot && root.host.id === HOST_ID) return true;\n return el.id === HOST_ID || !!el.closest?.(`#${HOST_ID}`);\n}\n\nfunction safeQueryAll(root: QueryRoot, selector: string): Element[] {\n try {\n return Array.from(root.querySelectorAll(selector));\n } catch {\n return [];\n }\n}\n\nfunction escapeCss(value: string): string {\n const g = globalThis as { CSS?: { escape?: (v: string) => string } };\n if (g.CSS && typeof g.CSS.escape === \"function\") return g.CSS.escape(value);\n return value.replace(/[\"\\\\]/g, \"\\\\$&\");\n}\n\nfunction queryXPath(root: QueryRoot, expr: string): Element[] {\n const doc = docOf(root);\n const d = doc as Document & { evaluate?: Document[\"evaluate\"] };\n if (typeof d.evaluate !== \"function\") return [];\n try {\n const result = d.evaluate(expr, root, null, 7 /* ORDERED_NODE_SNAPSHOT_TYPE */, null);\n const out: Element[] = [];\n for (let i = 0; i < result.snapshotLength; i++) {\n const n = result.snapshotItem(i);\n if (n && n.nodeType === 1) out.push(n as Element);\n }\n return out;\n } catch {\n return [];\n }\n}\n\nfunction queryText(root: QueryRoot, text: string): Element[] {\n const needle = normalizeText(text).toLowerCase();\n if (!needle) return [];\n const candidates = safeQueryAll(root, TEXT_CANDIDATES);\n const exact = candidates.filter((c) => normalizeText(c.textContent).toLowerCase() === needle);\n if (exact.length) return exact;\n return candidates.filter((c) => normalizeText(c.textContent).toLowerCase().includes(needle));\n}\n\n/** Resolves every element matching one strategy (visible or not). */\nexport function querySelectorStrategy(strategy: SelectorStrategy, root: QueryRoot): Element[] {\n const value = strategy.value.trim();\n if (!value) return [];\n switch (strategy.kind) {\n case \"id\": {\n const id = value.startsWith(\"#\") ? value.slice(1) : value;\n return safeQueryAll(root, `#${escapeCss(id)}`);\n }\n case \"guidely-id\": {\n const id = value.startsWith(\"#\") ? value.slice(1) : value;\n return safeQueryAll(root, attrSelector(\"data-guidely-id\", id));\n }\n case \"data-attr\":\n case \"aria\":\n case \"css\":\n return safeQueryAll(root, value.startsWith(\"[\") || /^[a-z*#.[]/i.test(value) ? value : `[${value}]`);\n case \"text\":\n return queryText(root, value);\n case \"xpath\":\n return queryXPath(root, value);\n default:\n return [];\n }\n}\n\n/**\n * Resolves a step target by trying each strategy in order. A strategy wins only when it\n * resolves to exactly one *visible* element; otherwise the next strategy is tried.\n */\nexport function resolveTarget(target: Pick<StepTarget, \"selectors\"> | SelectorStrategy[], root: QueryRoot = document): Element | null {\n const selectors = Array.isArray(target) ? target : target.selectors;\n for (const strategy of selectors) {\n const matches = querySelectorStrategy(strategy, root).filter((el) => !isGuidelyElement(el) && isVisible(el));\n if (matches.length === 1) return matches[0] as Element;\n }\n return null;\n}\n\nexport interface WaitForTargetOptions {\n /** Give up after this many milliseconds (default 5000). */\n timeoutMs?: number;\n /** Abort early. */\n signal?: AbortSignal;\n root?: QueryRoot;\n /** Polling fallback interval (default 250ms, which is also the maximum). */\n pollMs?: number;\n}\n\nexport class TargetTimeoutError extends Error {\n override name = \"TargetTimeoutError\";\n constructor(message = \"Target element not found before timeout\") {\n super(message);\n }\n}\n\n/**\n * Waits until `resolveTarget` finds an element. Uses a MutationObserver plus a polling fallback\n * (at most every 250ms) so visibility changes without DOM mutations are also detected.\n */\nexport function waitForTarget(target: Pick<StepTarget, \"selectors\"> | SelectorStrategy[], options: WaitForTargetOptions = {}): Promise<Element> {\n const timeoutMs = options.timeoutMs ?? 5000;\n const root = options.root ?? document;\n const pollMs = Math.min(250, Math.max(16, options.pollMs ?? 250));\n return new Promise<Element>((resolve, reject) => {\n const immediate = resolveTarget(target, root);\n if (immediate) return resolve(immediate);\n if (options.signal?.aborted) return reject(new DOMException(\"Aborted\", \"AbortError\"));\n let done = false;\n let observer: MutationObserver | null = null;\n let timer: ReturnType<typeof setInterval> | null = null;\n let timeout: ReturnType<typeof setTimeout> | null = null;\n const cleanup = () => {\n done = true;\n observer?.disconnect();\n if (timer) clearInterval(timer);\n if (timeout) clearTimeout(timeout);\n options.signal?.removeEventListener(\"abort\", onAbort);\n };\n const check = () => {\n if (done) return;\n const el = resolveTarget(target, root);\n if (el) {\n cleanup();\n resolve(el);\n }\n };\n const onAbort = () => {\n cleanup();\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n };\n options.signal?.addEventListener(\"abort\", onAbort);\n const observeRoot = root.nodeType === 9 ? (root as Document).documentElement : (root as Element);\n if (typeof MutationObserver !== \"undefined\" && observeRoot) {\n observer = new MutationObserver(check);\n observer.observe(observeRoot, { childList: true, subtree: true, attributes: true, attributeFilter: [\"class\", \"style\", \"hidden\", \"id\", \"data-tour\", \"data-guidely-id\", \"aria-label\"] });\n }\n timer = setInterval(check, pollMs);\n if (timeoutMs > 0) {\n timeout = setTimeout(() => {\n cleanup();\n reject(new TargetTimeoutError());\n }, timeoutMs);\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Selector generation (used by the element picker)\n// ---------------------------------------------------------------------------\n\nconst GENERATED_ID = /(\\d{4,}|:r[0-9a-z]+:|^radix-|^headlessui-|^mui-|^ember\\d|^react-|^\\w*-\\d+$|__|^[a-f0-9]{8,}$|^svelte-)/i;\nconst GENERATED_CLASS = /(^css-|^sc-|^jss\\d|^svelte-|^emotion-|^chakra-|^Mui|^_|[0-9a-f]{6,}|^\\w{1,2}$|^[a-z]+-\\d+$|[:[\\]/])/;\nconst PREFERRED_DATA_ATTRS = [\"data-testid\", \"data-tour\", \"data-test\", \"data-test-id\", \"data-cy\", \"data-qa\", \"data-id\", \"data-name\", \"data-guidely\"];\nconst IGNORED_DATA_ATTRS = /^data-(guidely-id|state|v-|reactid|react|radix|headlessui|svelte|hydrated|orientation|highlighted|focus|key|index|rbd|dnd|rk-|sveltekit)/i;\n\n/** Is this id stable enough to be used as a selector (not generated by a framework)? */\nexport function isStableId(id: string): boolean {\n return !!id && /^[A-Za-z][\\w-]*$/.test(id) && !GENERATED_ID.test(id);\n}\n\nfunction isStableClass(cls: string): boolean {\n return !!cls && !GENERATED_CLASS.test(cls) && cls.length <= 40;\n}\n\nfunction uniqueIn(doc: Document, selector: string, el: Element): boolean {\n const all = safeQueryAll(doc, selector);\n return all.length === 1 && all[0] === el;\n}\n\nfunction attrSelector(name: string, value: string): string {\n return `[${name}='${value.replace(/\\\\/g, \"\\\\\\\\\").replace(/'/g, \"\\\\'\")}']`;\n}\n\nfunction cssPath(el: Element, doc: Document): string | null {\n const segments: string[] = [];\n let cur: Element | null = el;\n while (cur && cur.nodeType === 1 && cur !== doc.body && cur !== doc.documentElement) {\n const tag = cur.tagName.toLowerCase();\n if (isStableId(cur.id)) {\n segments.unshift(`#${cur.id}`);\n break;\n }\n let seg = tag;\n const parent: Element | null = cur.parentElement;\n if (parent) {\n const sameTag = Array.from(parent.children).filter((c) => c.tagName === cur!.tagName);\n if (sameTag.length > 1) {\n const stableCls = Array.from(cur.classList).find((c) => isStableClass(c) && sameTag.filter((s) => s.classList.contains(c)).length === 1);\n seg += stableCls ? `.${escapeCss(stableCls)}` : `:nth-of-type(${sameTag.indexOf(cur) + 1})`;\n }\n }\n segments.unshift(seg);\n const candidate = segments.join(\" > \");\n if (uniqueIn(doc, candidate, el)) return candidate;\n cur = parent;\n }\n const full = segments.join(\" > \");\n return uniqueIn(doc, full, el) ? full : null;\n}\n\n/** Short human-readable text for an element, trimmed to 200 characters. */\nexport function textSnapshotOf(el: Element): string {\n const he = el as HTMLElement;\n const own = normalizeText(he.innerText ?? el.textContent);\n const alt = normalizeText(el.getAttribute(\"aria-label\") || el.getAttribute(\"title\") || el.getAttribute(\"placeholder\") || el.getAttribute(\"alt\") || (el as HTMLInputElement).value);\n return (own || alt).slice(0, 200);\n}\n\n/**\n * Generates an ordered list of selector strategies for an element, most robust first:\n * stable id → data-* attributes → aria-label → role/name → short unique CSS path → visible text.\n */\nexport function generateSelectors(el: Element): SelectorStrategy[] {\n const doc = el.ownerDocument;\n const out: SelectorStrategy[] = [];\n const seen = new Set<string>();\n const push = (s: SelectorStrategy) => {\n const k = `${s.kind}:${s.value}`;\n if (!seen.has(k)) {\n seen.add(k);\n out.push(s);\n }\n };\n const tag = el.tagName.toLowerCase();\n\n // A Guidely id is shared with the mobile apps, so it is the most portable target there is.\n const guidelyId = el.getAttribute(\"data-guidely-id\");\n if (guidelyId && uniqueIn(doc, attrSelector(\"data-guidely-id\", guidelyId), el)) push({ kind: \"guidely-id\", value: guidelyId, label: `Guidely id ${guidelyId}` });\n if (isStableId(el.id) && uniqueIn(doc, `#${escapeCss(el.id)}`, el)) push({ kind: \"id\", value: `#${el.id}`, label: `id ${el.id}` });\n\n const dataAttrs = Array.from(el.attributes).filter((a) => a.name.startsWith(\"data-\") && !IGNORED_DATA_ATTRS.test(a.name) && a.value && a.value.length <= 120 && !/\\d{5,}/.test(a.value));\n dataAttrs.sort((a, b) => {\n const ia = PREFERRED_DATA_ATTRS.indexOf(a.name);\n const ib = PREFERRED_DATA_ATTRS.indexOf(b.name);\n return (ia === -1 ? 99 : ia) - (ib === -1 ? 99 : ib);\n });\n for (const a of dataAttrs) {\n const sel = attrSelector(a.name, a.value);\n if (uniqueIn(doc, sel, el)) push({ kind: \"data-attr\", value: sel, label: `${a.name}=${a.value}` });\n else if (uniqueIn(doc, tag + sel, el)) push({ kind: \"data-attr\", value: tag + sel, label: `${a.name}=${a.value}` });\n }\n\n const aria = el.getAttribute(\"aria-label\");\n if (aria && aria.length <= 120) {\n const sel = attrSelector(\"aria-label\", aria);\n if (uniqueIn(doc, sel, el)) push({ kind: \"aria\", value: sel, label: aria });\n else if (uniqueIn(doc, tag + sel, el)) push({ kind: \"aria\", value: tag + sel, label: aria });\n }\n\n const name = el.getAttribute(\"name\");\n if (name && uniqueIn(doc, tag + attrSelector(\"name\", name), el)) push({ kind: \"css\", value: tag + attrSelector(\"name\", name), label: `${tag} name=${name}` });\n const role = el.getAttribute(\"role\");\n if (role) {\n const title = el.getAttribute(\"title\") || el.getAttribute(\"aria-labelledby\");\n const sel = title ? `[role='${role}']${attrSelector(el.getAttribute(\"title\") ? \"title\" : \"aria-labelledby\", title)}` : `[role='${role}']`;\n if (uniqueIn(doc, sel, el)) push({ kind: \"css\", value: sel, label: `role ${role}` });\n }\n if (tag === \"a\") {\n const href = el.getAttribute(\"href\");\n if (href && href.length <= 200 && uniqueIn(doc, `a${attrSelector(\"href\", href)}`, el)) push({ kind: \"css\", value: `a${attrSelector(\"href\", href)}`, label: `link ${href}` });\n }\n\n const path = cssPath(el, doc);\n if (path) push({ kind: \"css\", value: path, label: \"css path\" });\n\n if (/^(button|a|h[1-6]|label|summary)$/.test(tag) || role === \"button\" || role === \"link\" || role === \"tab\" || role === \"menuitem\") {\n const text = normalizeText((el as HTMLElement).innerText ?? el.textContent);\n if (text && text.length <= 80) push({ kind: \"text\", value: text, label: `text \"${text}\"` });\n }\n return out.slice(0, 10);\n}\n\nexport interface ElementDescription {\n selectors: SelectorStrategy[];\n textSnapshot: string;\n rect: { x: number; y: number; width: number; height: number };\n tag: string;\n}\n\n/** Everything the authoring picker needs for one element. */\nexport function describeElement(el: Element): ElementDescription {\n const r = el.getBoundingClientRect();\n return {\n selectors: generateSelectors(el),\n textSnapshot: textSnapshotOf(el),\n rect: { x: r.x, y: r.y, width: r.width, height: r.height },\n tag: el.tagName.toLowerCase(),\n };\n}\n"],"mappings":";;;;;AAAA,SAAS,uBAAuB;AAOzB,SAAS,WAAW,SAAoC,KAAsB;AACnF,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,gBAAgB,SAAS,GAAG,EAAG,QAAO;AAC1C,MAAI;AACF,UAAM,IAAI,IAAI,IAAI,KAAK,kBAAkB;AACzC,QAAI,CAAC,QAAQ,SAAS,GAAG,KAAK,CAAC,QAAQ,SAAS,GAAG,EAAG,QAAO,gBAAgB,SAAS,EAAE,QAAQ,KAAK,gBAAgB,SAAS,EAAE,SAAS,EAAE,QAAQ;AAAA,EACrJ,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAIA,IAAM,kBACJ;AAEF,IAAM,UAAU;AAEhB,SAAS,MAAM,MAA2B;AACxC,SAAO,KAAK,aAAa,IAAK,OAAqB,KAAK;AAC1D;AAGA,SAAS,UAAU,KAAwB;AACzC,QAAM,KAAK,IAAI;AACf,MAAI,CAAC,GAAI,QAAO;AAChB,QAAM,IAAI,GAAG,sBAAsB;AACnC,SAAO,EAAE,QAAQ,KAAK,EAAE,SAAS;AACnC;AAGO,SAAS,cAAc,MAAyC;AACrE,UAAQ,QAAQ,IAAI,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAChD;AAGO,SAAS,UAAU,IAAsB;AAC9C,MAAI,CAAC,GAAG,YAAa,QAAO;AAC5B,QAAM,MAAM,GAAG;AACf,QAAM,MAAM,IAAI;AAChB,MAAI,MAAsB;AAC1B,SAAO,OAAO,QAAQ,IAAI,iBAAiB;AACzC,QAAK,IAAoB,OAAQ,QAAO;AACxC,QAAI,KAAK;AACP,YAAM,KAAK,IAAI,iBAAiB,GAAG;AACnC,UAAI,GAAG,YAAY,UAAU,GAAG,eAAe,SAAU,QAAO;AAAA,IAClE;AACA,UAAM,IAAI,iBAAmB,IAAI,YAAY,EAAiB,QAAgC;AAAA,EAChG;AACA,MAAI,UAAU,GAAG,GAAG;AAClB,UAAM,IAAI,GAAG,sBAAsB;AACnC,QAAI,EAAE,UAAU,KAAK,EAAE,WAAW,EAAG,QAAO;AAAA,EAC9C;AACA,SAAO;AACT;AAGO,SAAS,iBAAiB,IAA6B;AAC5D,MAAI,CAAC,GAAI,QAAO;AAChB,QAAM,OAAO,GAAG,YAAY;AAC5B,MAAI,gBAAgB,cAAc,KAAK,KAAK,OAAO,QAAS,QAAO;AACnE,SAAO,GAAG,OAAO,WAAW,CAAC,CAAC,GAAG,UAAU,IAAI,OAAO,EAAE;AAC1D;AAEA,SAAS,aAAa,MAAiB,UAA6B;AAClE,MAAI;AACF,WAAO,MAAM,KAAK,KAAK,iBAAiB,QAAQ,CAAC;AAAA,EACnD,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,SAAS,UAAU,OAAuB;AACxC,QAAM,IAAI;AACV,MAAI,EAAE,OAAO,OAAO,EAAE,IAAI,WAAW,WAAY,QAAO,EAAE,IAAI,OAAO,KAAK;AAC1E,SAAO,MAAM,QAAQ,UAAU,MAAM;AACvC;AAEA,SAAS,WAAW,MAAiB,MAAyB;AAC5D,QAAM,MAAM,MAAM,IAAI;AACtB,QAAM,IAAI;AACV,MAAI,OAAO,EAAE,aAAa,WAAY,QAAO,CAAC;AAC9C,MAAI;AACF,UAAM,SAAS,EAAE,SAAS,MAAM,MAAM,MAAM,GAAoC,IAAI;AACpF,UAAM,MAAiB,CAAC;AACxB,aAAS,IAAI,GAAG,IAAI,OAAO,gBAAgB,KAAK;AAC9C,YAAM,IAAI,OAAO,aAAa,CAAC;AAC/B,UAAI,KAAK,EAAE,aAAa,EAAG,KAAI,KAAK,CAAY;AAAA,IAClD;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,SAAS,UAAU,MAAiB,MAAyB;AAC3D,QAAM,SAAS,cAAc,IAAI,EAAE,YAAY;AAC/C,MAAI,CAAC,OAAQ,QAAO,CAAC;AACrB,QAAM,aAAa,aAAa,MAAM,eAAe;AACrD,QAAM,QAAQ,WAAW,OAAO,CAAC,MAAM,cAAc,EAAE,WAAW,EAAE,YAAY,MAAM,MAAM;AAC5F,MAAI,MAAM,OAAQ,QAAO;AACzB,SAAO,WAAW,OAAO,CAAC,MAAM,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,MAAM,CAAC;AAC7F;AAGO,SAAS,sBAAsB,UAA4B,MAA4B;AAC5F,QAAM,QAAQ,SAAS,MAAM,KAAK;AAClC,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,UAAQ,SAAS,MAAM;AAAA,IACrB,KAAK,MAAM;AACT,YAAM,KAAK,MAAM,WAAW,GAAG,IAAI,MAAM,MAAM,CAAC,IAAI;AACpD,aAAO,aAAa,MAAM,IAAI,UAAU,EAAE,CAAC,EAAE;AAAA,IAC/C;AAAA,IACA,KAAK,cAAc;AACjB,YAAM,KAAK,MAAM,WAAW,GAAG,IAAI,MAAM,MAAM,CAAC,IAAI;AACpD,aAAO,aAAa,MAAM,aAAa,mBAAmB,EAAE,CAAC;AAAA,IAC/D;AAAA,IACA,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO,aAAa,MAAM,MAAM,WAAW,GAAG,KAAK,cAAc,KAAK,KAAK,IAAI,QAAQ,IAAI,KAAK,GAAG;AAAA,IACrG,KAAK;AACH,aAAO,UAAU,MAAM,KAAK;AAAA,IAC9B,KAAK;AACH,aAAO,WAAW,MAAM,KAAK;AAAA,IAC/B;AACE,aAAO,CAAC;AAAA,EACZ;AACF;AAMO,SAAS,cAAc,QAA4D,OAAkB,UAA0B;AACpI,QAAM,YAAY,MAAM,QAAQ,MAAM,IAAI,SAAS,OAAO;AAC1D,aAAW,YAAY,WAAW;AAChC,UAAM,UAAU,sBAAsB,UAAU,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,iBAAiB,EAAE,KAAK,UAAU,EAAE,CAAC;AAC3G,QAAI,QAAQ,WAAW,EAAG,QAAO,QAAQ,CAAC;AAAA,EAC5C;AACA,SAAO;AACT;AAYO,IAAM,qBAAN,cAAiC,MAAM;AAAA,EAE5C,YAAY,UAAU,2CAA2C;AAC/D,UAAM,OAAO;AAFf,wBAAS,QAAO;AAAA,EAGhB;AACF;AAMO,SAAS,cAAc,QAA4D,UAAgC,CAAC,GAAqB;AAC9I,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAM,SAAS,KAAK,IAAI,KAAK,KAAK,IAAI,IAAI,QAAQ,UAAU,GAAG,CAAC;AAChE,SAAO,IAAI,QAAiB,CAAC,SAAS,WAAW;AAC/C,UAAM,YAAY,cAAc,QAAQ,IAAI;AAC5C,QAAI,UAAW,QAAO,QAAQ,SAAS;AACvC,QAAI,QAAQ,QAAQ,QAAS,QAAO,OAAO,IAAI,aAAa,WAAW,YAAY,CAAC;AACpF,QAAI,OAAO;AACX,QAAI,WAAoC;AACxC,QAAI,QAA+C;AACnD,QAAI,UAAgD;AACpD,UAAM,UAAU,MAAM;AACpB,aAAO;AACP,gBAAU,WAAW;AACrB,UAAI,MAAO,eAAc,KAAK;AAC9B,UAAI,QAAS,cAAa,OAAO;AACjC,cAAQ,QAAQ,oBAAoB,SAAS,OAAO;AAAA,IACtD;AACA,UAAM,QAAQ,MAAM;AAClB,UAAI,KAAM;AACV,YAAM,KAAK,cAAc,QAAQ,IAAI;AACrC,UAAI,IAAI;AACN,gBAAQ;AACR,gBAAQ,EAAE;AAAA,MACZ;AAAA,IACF;AACA,UAAM,UAAU,MAAM;AACpB,cAAQ;AACR,aAAO,IAAI,aAAa,WAAW,YAAY,CAAC;AAAA,IAClD;AACA,YAAQ,QAAQ,iBAAiB,SAAS,OAAO;AACjD,UAAM,cAAc,KAAK,aAAa,IAAK,KAAkB,kBAAmB;AAChF,QAAI,OAAO,qBAAqB,eAAe,aAAa;AAC1D,iBAAW,IAAI,iBAAiB,KAAK;AACrC,eAAS,QAAQ,aAAa,EAAE,WAAW,MAAM,SAAS,MAAM,YAAY,MAAM,iBAAiB,CAAC,SAAS,SAAS,UAAU,MAAM,aAAa,mBAAmB,YAAY,EAAE,CAAC;AAAA,IACvL;AACA,YAAQ,YAAY,OAAO,MAAM;AACjC,QAAI,YAAY,GAAG;AACjB,gBAAU,WAAW,MAAM;AACzB,gBAAQ;AACR,eAAO,IAAI,mBAAmB,CAAC;AAAA,MACjC,GAAG,SAAS;AAAA,IACd;AAAA,EACF,CAAC;AACH;AAMA,IAAM,eAAe;AACrB,IAAM,kBAAkB;AACxB,IAAM,uBAAuB,CAAC,eAAe,aAAa,aAAa,gBAAgB,WAAW,WAAW,WAAW,aAAa,cAAc;AACnJ,IAAM,qBAAqB;AAGpB,SAAS,WAAW,IAAqB;AAC9C,SAAO,CAAC,CAAC,MAAM,mBAAmB,KAAK,EAAE,KAAK,CAAC,aAAa,KAAK,EAAE;AACrE;AAEA,SAAS,cAAc,KAAsB;AAC3C,SAAO,CAAC,CAAC,OAAO,CAAC,gBAAgB,KAAK,GAAG,KAAK,IAAI,UAAU;AAC9D;AAEA,SAAS,SAAS,KAAe,UAAkB,IAAsB;AACvE,QAAM,MAAM,aAAa,KAAK,QAAQ;AACtC,SAAO,IAAI,WAAW,KAAK,IAAI,CAAC,MAAM;AACxC;AAEA,SAAS,aAAa,MAAc,OAAuB;AACzD,SAAO,IAAI,IAAI,KAAK,MAAM,QAAQ,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAK,CAAC;AACvE;AAEA,SAAS,QAAQ,IAAa,KAA8B;AAC1D,QAAM,WAAqB,CAAC;AAC5B,MAAI,MAAsB;AAC1B,SAAO,OAAO,IAAI,aAAa,KAAK,QAAQ,IAAI,QAAQ,QAAQ,IAAI,iBAAiB;AACnF,UAAM,MAAM,IAAI,QAAQ,YAAY;AACpC,QAAI,WAAW,IAAI,EAAE,GAAG;AACtB,eAAS,QAAQ,IAAI,IAAI,EAAE,EAAE;AAC7B;AAAA,IACF;AACA,QAAI,MAAM;AACV,UAAM,SAAyB,IAAI;AACnC,QAAI,QAAQ;AACV,YAAM,UAAU,MAAM,KAAK,OAAO,QAAQ,EAAE,OAAO,CAAC,MAAM,EAAE,YAAY,IAAK,OAAO;AACpF,UAAI,QAAQ,SAAS,GAAG;AACtB,cAAM,YAAY,MAAM,KAAK,IAAI,SAAS,EAAE,KAAK,CAAC,MAAM,cAAc,CAAC,KAAK,QAAQ,OAAO,CAAC,MAAM,EAAE,UAAU,SAAS,CAAC,CAAC,EAAE,WAAW,CAAC;AACvI,eAAO,YAAY,IAAI,UAAU,SAAS,CAAC,KAAK,gBAAgB,QAAQ,QAAQ,GAAG,IAAI,CAAC;AAAA,MAC1F;AAAA,IACF;AACA,aAAS,QAAQ,GAAG;AACpB,UAAM,YAAY,SAAS,KAAK,KAAK;AACrC,QAAI,SAAS,KAAK,WAAW,EAAE,EAAG,QAAO;AACzC,UAAM;AAAA,EACR;AACA,QAAM,OAAO,SAAS,KAAK,KAAK;AAChC,SAAO,SAAS,KAAK,MAAM,EAAE,IAAI,OAAO;AAC1C;AAGO,SAAS,eAAe,IAAqB;AAClD,QAAM,KAAK;AACX,QAAM,MAAM,cAAc,GAAG,aAAa,GAAG,WAAW;AACxD,QAAM,MAAM,cAAc,GAAG,aAAa,YAAY,KAAK,GAAG,aAAa,OAAO,KAAK,GAAG,aAAa,aAAa,KAAK,GAAG,aAAa,KAAK,KAAM,GAAwB,KAAK;AACjL,UAAQ,OAAO,KAAK,MAAM,GAAG,GAAG;AAClC;AAMO,SAAS,kBAAkB,IAAiC;AACjE,QAAM,MAAM,GAAG;AACf,QAAM,MAA0B,CAAC;AACjC,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,OAAO,CAAC,MAAwB;AACpC,UAAM,IAAI,GAAG,EAAE,IAAI,IAAI,EAAE,KAAK;AAC9B,QAAI,CAAC,KAAK,IAAI,CAAC,GAAG;AAChB,WAAK,IAAI,CAAC;AACV,UAAI,KAAK,CAAC;AAAA,IACZ;AAAA,EACF;AACA,QAAM,MAAM,GAAG,QAAQ,YAAY;AAGnC,QAAM,YAAY,GAAG,aAAa,iBAAiB;AACnD,MAAI,aAAa,SAAS,KAAK,aAAa,mBAAmB,SAAS,GAAG,EAAE,EAAG,MAAK,EAAE,MAAM,cAAc,OAAO,WAAW,OAAO,cAAc,SAAS,GAAG,CAAC;AAC/J,MAAI,WAAW,GAAG,EAAE,KAAK,SAAS,KAAK,IAAI,UAAU,GAAG,EAAE,CAAC,IAAI,EAAE,EAAG,MAAK,EAAE,MAAM,MAAM,OAAO,IAAI,GAAG,EAAE,IAAI,OAAO,MAAM,GAAG,EAAE,GAAG,CAAC;AAEjI,QAAM,YAAY,MAAM,KAAK,GAAG,UAAU,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,WAAW,OAAO,KAAK,CAAC,mBAAmB,KAAK,EAAE,IAAI,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,OAAO,CAAC,SAAS,KAAK,EAAE,KAAK,CAAC;AACvL,YAAU,KAAK,CAAC,GAAG,MAAM;AACvB,UAAM,KAAK,qBAAqB,QAAQ,EAAE,IAAI;AAC9C,UAAM,KAAK,qBAAqB,QAAQ,EAAE,IAAI;AAC9C,YAAQ,OAAO,KAAK,KAAK,OAAO,OAAO,KAAK,KAAK;AAAA,EACnD,CAAC;AACD,aAAW,KAAK,WAAW;AACzB,UAAM,MAAM,aAAa,EAAE,MAAM,EAAE,KAAK;AACxC,QAAI,SAAS,KAAK,KAAK,EAAE,EAAG,MAAK,EAAE,MAAM,aAAa,OAAO,KAAK,OAAO,GAAG,EAAE,IAAI,IAAI,EAAE,KAAK,GAAG,CAAC;AAAA,aACxF,SAAS,KAAK,MAAM,KAAK,EAAE,EAAG,MAAK,EAAE,MAAM,aAAa,OAAO,MAAM,KAAK,OAAO,GAAG,EAAE,IAAI,IAAI,EAAE,KAAK,GAAG,CAAC;AAAA,EACpH;AAEA,QAAM,OAAO,GAAG,aAAa,YAAY;AACzC,MAAI,QAAQ,KAAK,UAAU,KAAK;AAC9B,UAAM,MAAM,aAAa,cAAc,IAAI;AAC3C,QAAI,SAAS,KAAK,KAAK,EAAE,EAAG,MAAK,EAAE,MAAM,QAAQ,OAAO,KAAK,OAAO,KAAK,CAAC;AAAA,aACjE,SAAS,KAAK,MAAM,KAAK,EAAE,EAAG,MAAK,EAAE,MAAM,QAAQ,OAAO,MAAM,KAAK,OAAO,KAAK,CAAC;AAAA,EAC7F;AAEA,QAAM,OAAO,GAAG,aAAa,MAAM;AACnC,MAAI,QAAQ,SAAS,KAAK,MAAM,aAAa,QAAQ,IAAI,GAAG,EAAE,EAAG,MAAK,EAAE,MAAM,OAAO,OAAO,MAAM,aAAa,QAAQ,IAAI,GAAG,OAAO,GAAG,GAAG,SAAS,IAAI,GAAG,CAAC;AAC5J,QAAM,OAAO,GAAG,aAAa,MAAM;AACnC,MAAI,MAAM;AACR,UAAM,QAAQ,GAAG,aAAa,OAAO,KAAK,GAAG,aAAa,iBAAiB;AAC3E,UAAM,MAAM,QAAQ,UAAU,IAAI,KAAK,aAAa,GAAG,aAAa,OAAO,IAAI,UAAU,mBAAmB,KAAK,CAAC,KAAK,UAAU,IAAI;AACrI,QAAI,SAAS,KAAK,KAAK,EAAE,EAAG,MAAK,EAAE,MAAM,OAAO,OAAO,KAAK,OAAO,QAAQ,IAAI,GAAG,CAAC;AAAA,EACrF;AACA,MAAI,QAAQ,KAAK;AACf,UAAM,OAAO,GAAG,aAAa,MAAM;AACnC,QAAI,QAAQ,KAAK,UAAU,OAAO,SAAS,KAAK,IAAI,aAAa,QAAQ,IAAI,CAAC,IAAI,EAAE,EAAG,MAAK,EAAE,MAAM,OAAO,OAAO,IAAI,aAAa,QAAQ,IAAI,CAAC,IAAI,OAAO,QAAQ,IAAI,GAAG,CAAC;AAAA,EAC7K;AAEA,QAAM,OAAO,QAAQ,IAAI,GAAG;AAC5B,MAAI,KAAM,MAAK,EAAE,MAAM,OAAO,OAAO,MAAM,OAAO,WAAW,CAAC;AAE9D,MAAI,oCAAoC,KAAK,GAAG,KAAK,SAAS,YAAY,SAAS,UAAU,SAAS,SAAS,SAAS,YAAY;AAClI,UAAM,OAAO,cAAe,GAAmB,aAAa,GAAG,WAAW;AAC1E,QAAI,QAAQ,KAAK,UAAU,GAAI,MAAK,EAAE,MAAM,QAAQ,OAAO,MAAM,OAAO,SAAS,IAAI,IAAI,CAAC;AAAA,EAC5F;AACA,SAAO,IAAI,MAAM,GAAG,EAAE;AACxB;AAUO,SAAS,gBAAgB,IAAiC;AAC/D,QAAM,IAAI,GAAG,sBAAsB;AACnC,SAAO;AAAA,IACL,WAAW,kBAAkB,EAAE;AAAA,IAC/B,cAAc,eAAe,EAAE;AAAA,IAC/B,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,OAAO,EAAE,OAAO,QAAQ,EAAE,OAAO;AAAA,IACzD,KAAK,GAAG,QAAQ,YAAY;AAAA,EAC9B;AACF;","names":[]}