@siteping/widget 0.9.8 → 0.9.10
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.
- package/README.md +10 -0
- package/dist/{chunk-OTJZRTBK.js → chunk-HHREBLKP.js} +43 -10
- package/dist/chunk-HHREBLKP.js.map +1 -0
- package/dist/index.global.js +74 -41
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +35 -35
- package/dist/index.js.map +1 -1
- package/dist/{panel-HDPPIATU.js → panel-OQ6MGCXK.js} +2 -2
- package/dist/{panel-HDPPIATU.js.map → panel-OQ6MGCXK.js.map} +1 -1
- package/dist/react.js +35 -35
- package/dist/react.js.map +1 -1
- package/dist/types.d.ts +60 -0
- package/package.json +1 -1
- package/dist/chunk-OTJZRTBK.js.map +0 -1
package/dist/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../node_modules/.bun/@medv+finder@3.2.0/node_modules/@medv/finder/finder.js","../src/dom/fingerprint.ts","../src/dom/text-context.ts","../src/dom/xpath.ts","../src/dom/anchor.ts","../src/popup.ts","../src/screenshot.ts","../src/annotator.ts","../../core/src/errors.ts","../../core/src/types.ts","../src/api-client.ts","../src/diagnostics/console-buffer.ts","../src/diagnostics/network-buffer.ts","../src/events.ts","../src/fab.ts","../src/identity.ts","../src/dom/fuzzy.ts","../src/dom/resolver.ts","../src/markers.ts","../src/store-client.ts","../src/styles/animations.ts","../src/styles/base.ts","../src/tooltip.ts","../src/launcher.ts","../src/index.ts","../src/react.ts"],"names":["config","rootDocument","start","finder","input","options","defaults","name","value","findRootDocument","path","bottomUpSearch","optimized","sort","optimize","selector","rootNode","limit","fallback","stack","current","i","elapsedTime","level","maybe","id","attr","classNames","tagName","any","nth","index","dispensableNth","node","nthChild","findUniquePath","paths","combinations","candidate","unique","query","penalty","acc","css","elementId","parent","child","list","notEmpty","a","b","scope","newPath","newPathKey","same","STABLE_ATTRS","djb2","str","hash","generateFingerprint","element","childCount","siblingIdx","attrs","val","attrHash","scoreFingerprint","storedFingerprint","parts","storedChildren","storedSibIdx","storedAttrHash","storedChildCount","storedSibIndex","candidateFp","candChildren","candSibIdx","candAttrHash","score","childDiff","sibDiff","adjacentText","direction","prop","sibling","attempts","text","neighborText","prev","next","generateXPath","safeId","segments","tag","position","ANCHOR_KEY_ATTR","generateAnchor","cssSelector","xpath","textSnippet","textPrefix","textSuffix","fingerprint","neighbor","anchorKey","containsRect","el","rect","findAnchorElement","root","centerX","centerY","elementAtCenter","rectToPercentages","anchorBounds","Popup","colors","t","typeOptions","ICON_QUESTION","ICON_CHANGE","ICON_BUG","ICON_OTHER","typeRow","option","btn","icon","parseSvg","labelSpan","setText","bgColor","getTypeBgColor","getTypeColor","hint","uaData","isMac","e","btnRow","cancelBtn","rectBounds","resolve","popupH","popupW","top","left","aboveTop","focusableEls","first","last","reduceMotion","type","container","buttons","isActive","color","enabled","cachedHtml2Canvas","warnedAboutMissingDep","loadHtml2Canvas","mod","err","captureScreenshot","html2canvas","quality","maxWidth","canvas","ratio","targetW","targetH","scaled","ctx","Annotator","bus","enableScreenshot","dot","style","instruction","target","bounds","result","annotation","screenshotDataUrl","touch","clientX","clientY","source","evt","x","y","w","h","anchorElement","anchor","SitepingError","message","code","retryable","SitepingNetworkError","SitepingValidationError","SitepingAuthError","flattenAnnotation","ann","errorFromResponse","response","label","detail","networkErrorFromException","error","MAX_RETRIES","TIMEOUT_MS","RETRY_QUEUE_KEY","MAX_QUEUE_SIZE","resilientFetch","url","init","retries","attempt","controller","timeout","baseDelay","jitter","r","LOCK_NAME","withRetryLock","callback","queueForRetry","endpoint","payload","raw","parsed","queue","flushRetryQueue","toRetry","failed","entry","remaining","ApiClient","projectName","params","resolved","LEVELS","serializeArg","arg","seen","_key","formatArgs","args","out","ConsoleBuffer","maxEntries","original","buffer","wrapped","truncateUrl","urlString","NetworkBuffer","startedAt","t0","method","t1","proto","originalOpen","originalSend","meta","rest","body","info","onEnd","status","EventBus","event","listener","set","fn","ITEM_GAP","Fab","shadowRoot","isRight","ICON_CHAT","ICON_ANNOTATE","ICON_EYE","ICON_EYE_OFF","ICON_SITEPING","item","host","handleEscape","items","activeEl","currentIndex","nextIndex","count","displayText","ICON_CLOSE","svgStr","badge","STORAGE_KEY","getIdentity","identity","saveIdentity","editDistance","aLen","bLen","k","curr","j","prevDiag","tmp","similarity","maxLen","fuzzyIncludes","haystack","needle","minScore","nLen","best","capped","window","MAX_SCAN_CANDIDATES","TEXT_MATCH_THRESHOLD","textMatches","resolveAnchor","escaped","smartScan","candidates","bestElement","bestScore","scoreCandidate","totalWeight","candidateText","contextScore","contextParts","prevText","nextText","candidateNeighbor","resolveAnnotation","resolution","absoluteRect","toAnchorData","toRectData","MARKER_OFFSET","markerPosition","clusterMarker","cluster","elIdx","HIGHLIGHT_FADE","REPOSITION_DEBOUNCE","LOW_CONFIDENCE_THRESHOLD","CLUSTER_DISTANCE","FAN_SPACING","MarkerManager","tooltip","liveRegion","visible","mutations","hasRelevantMutation","m","validKeys","markerEl","cacheKey","cachedEl","anchorRect","pos","key","feedbacks","feedback","marker","allItems","used","itemI","itemJ","baseTop","baseLeft","isSolo","totalWidth","startLeft","topMarker","confidence","isResolved","number","typeColor","truncatedMessage","ariaLabel","getTypeLabel","activateMarker","feedbackId","highlight","StoreClient","store","record","toResponse","total","toAnnotationResponse","SPRING_LINEAR","EASE_OUT_EXPO","SPRING_OVERSHOOT","EASE_OUT_QUART","ANIMATION_CSS","buildStyles","cssVariables","STATS_CSS","SORT_CSS","BULK_CSS","EXPORT_CSS","SHORTCUTS_CSS","DETAIL_CSS","SHOW_DELAY","HIDE_DELAY","Tooltip","locale","children","typeBg","createT","typeLabel","header","date","formatRelativeDate","tooltipRect","gap","isAbove","arrowLeft","instance","normaliseDiagnosticsOptions","skippedInstance","noop","launch","log","reason","loadLocale","scopeAnnotationsByUrl","getScope","diagnosticsOpts","consoleBuffer","networkBuffer","buildThemeColors","publicBus","client","fb","isTestEnv","shadowMode","shadow","sheet","markers","fab","panelInstance","panelPromise","destroyed","loadPanel","prefetch","ric","pendingOpen","unsubToggle","open","p","annotator","submitting","unsubAnnotation","data","promptIdentity","clientId","diagnostics","initialScope","initialOptions","f","opts","previouslyFocused","backdrop","modal","titleId","title","nameInputId","emailInputId","nameLabel","nameInput","emailLabel","emailInput","closeModal","onKeydown","submitBtn","email","focusableSelectors","ke","active","initSiteping","useSiteping","configRef","useRef","setInstance","useState","useEffect","mounted","created","unsubSent","unsubOpen","unsubClose"],"mappings":"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A;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAAA,EA21BtF,UAAW,CAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA,IAAA,EAuStBwR,EAAa;AAAA,IAAA,EACbG,GAAS;AAAA,IAAA,EACTC,CAAQ;AAAA,IAAA,EACRC,CAAQ;AAAA,IAAA,EACRC,CAAU;AAAA,IAAA,EACVC,CAAa;AAAA,IAAA,EACbC,GAAU;AAAA,EAAA,CAEhB,CC5qCA,IAAMC,EAAAA,CAAa,GAAA,CACbC,GAAa,EAAA,CASNC,EAAAA,CAAN,KAAc,CASnB,WAAA,CACmBnS,CAAAA,CACAoS,EAAiB,IAAA,CAClC,CAFiB,IAAA,CAAA,MAAA,CAAApS,CAAAA,CACA,IAAA,CAAA,MAAA,CAAAoS,CAAAA,CAEjB,KAAK,IAAA,CAAO9S,CAAAA,CAAG,KAAA,CAAO,CACpB,KAAA,CAAO;AAAA;AAAA,iBAAA,EAEM,UAAW,CAAA;AAAA;AAAA;AAAA;AAAA,oBAAA,EAIR,IAAA,CAAK,OAAO,YAAY,CAAA;AAAA;AAAA;AAAA,0BAAA,EAGlB,IAAA,CAAK,OAAO,WAAW,CAAA;AAAA,+BAAA,EAClB,KAAK,MAAA,CAAO,MAAM,CAAA,YAAA,EAAe,IAAA,CAAK,OAAO,MAAM,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAAA,CAShF,CAAC,CAAA,CAED,IAAA,CAAK,KAAK,YAAA,CAAa,MAAA,CAAQ,SAAS,CAAA,CACxC,IAAA,CAAK,IAAA,CAAK,EAAA,CAAK,KAAK,SAAA,CAGpB,IAAA,CAAK,MAAQA,CAAAA,CAAG,KAAA,CAAO,CACrB,KAAA,CAAO;AAAA;AAAA;AAAA;AAAA,oBAAA,EAIS,IAAA,CAAK,OAAO,YAAY,CAAA;AAAA,0BAAA,EAClB,IAAA,CAAK,OAAO,WAAW,CAAA;AAAA;AAAA;AAAA,MAAA,CAI/C,CAAC,CAAA,CACD,IAAA,CAAK,IAAA,CAAK,WAAA,CAAY,IAAA,CAAK,KAAK,CAAA,CAEhC,IAAA,CAAK,IAAA,CAAK,gBAAA,CAAiB,YAAA,CAAc,IAAM,KAAK,UAAA,EAAY,CAAA,CAChE,IAAA,CAAK,IAAA,CAAK,gBAAA,CAAiB,YAAA,CAAc,IAAM,IAAA,CAAK,YAAA,EAAc,CAAA,CAClE,QAAA,CAAS,IAAA,CAAK,YAAY,IAAA,CAAK,IAAI,EACrC,CA7CmB,MAAA,CACA,MAAA,CAVX,IAAA,CACA,KAAA,CACA,SAAA,CAAkD,IAAA,CAClD,SAAA,CAAkD,IAAA,CAClD,iBAAA,CAAmC,IAAA,CAElC,SAAA,CAAY,YAAA,CAkDrB,IAAA,CAAKkQ,CAAAA,CAA4BJ,CAAAA,CAA2B,CACtD,IAAA,CAAK,iBAAA,GAAsBI,CAAAA,CAAS,EAAA,GACxC,IAAA,CAAK,UAAA,EAAW,CAChB,IAAA,CAAK,UAAA,EAAW,CAEhB,KAAK,SAAA,CAAY,UAAA,CAAW,IAAM,CAChC,IAAA,CAAK,iBAAA,CAAoBA,CAAAA,CAAS,EAAA,CAClC,IAAA,CAAK,MAAA,CAAOA,CAAQ,CAAA,CACpB,IAAA,CAAK,QAAA,CAASJ,CAAU,CAAA,CAGxB,IAAMnN,CAAAA,CACJ,OAAO,MAAA,CAAW,GAAA,EAAe,MAAA,CAAO,UAAA,CAAW,kCAAkC,CAAA,CAAE,OAAA,CACzF,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,WAAaA,CAAAA,CAAe,MAAA,CAAS,EAAA,CAErD,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,UAAA,CAAa,SAAA,CAC7B,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,OAAA,CAAU,GAAA,CAC1B,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,SAAA,CAAY,yBAC9B,CAAA,CAAGgQ,EAAU,CAAA,EACf,CAEA,YAAA,EAAqB,CACnB,IAAA,CAAK,UAAA,EAAW,CAChB,IAAA,CAAK,SAAA,CAAY,UAAA,CAAW,IAAM,IAAA,CAAK,IAAA,EAAK,CAAGC,EAAU,EAC3D,CAEA,IAAA,EAAa,CACX,IAAA,CAAK,UAAA,EAAW,CAChB,IAAA,CAAK,iBAAA,CAAoB,IAAA,CACzB,KAAK,IAAA,CAAK,KAAA,CAAM,OAAA,CAAU,GAAA,CAC1B,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,SAAA,CAAY,6BAAA,CAC5B,UAAA,CAAW,IAAM,CACV,IAAA,CAAK,iBAAA,GACR,KAAK,IAAA,CAAK,KAAA,CAAM,UAAA,CAAa,QAAA,EAEjC,CAAA,CAAG,GAAG,EACR,CAEQ,UAAA,EAAmB,CACrB,IAAA,CAAK,SAAA,GACP,YAAA,CAAa,IAAA,CAAK,SAAS,CAAA,CAC3B,IAAA,CAAK,SAAA,CAAY,IAAA,EAErB,CAEQ,UAAA,EAAmB,CACrB,IAAA,CAAK,SAAA,GACP,YAAA,CAAa,IAAA,CAAK,SAAS,CAAA,CAC3B,IAAA,CAAK,SAAA,CAAY,MAErB,CAEQ,MAAA,CAAO1C,GAAAA,CAAkC,CAE/C,IAAM6C,CAAAA,CAAW,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA,CAC9C,IAAA,IAAW3W,CAAAA,IAAS2W,CAAAA,CACd3W,CAAAA,GAAU,IAAA,CAAK,KAAA,EAAOA,CAAAA,CAAM,MAAA,EAAO,CAGzC,IAAM6U,CAAAA,CAAYvP,CAAAA,CAAawO,GAAAA,CAAS,IAAA,CAAM,IAAA,CAAK,MAAM,CAAA,CACnD8C,CAAAA,CAASvR,EAAeyO,GAAAA,CAAS,IAAA,CAAM,IAAA,CAAK,MAAM,CAAA,CAClDvP,CAAAA,CAAIsS,CAAAA,CAAQ,IAAA,CAAK,MAAM,CAAA,CACvBC,CAAAA,CAAY9B,CAAAA,CAAalB,GAAAA,CAAS,IAAA,CAAMvP,CAAC,CAAA,CAGzCwS,CAAAA,CAASnT,CAAAA,CAAG,KAAA,CAAO,CAAE,KAAA,CAAO,4DAA6D,CAAC,CAAA,CAE1F4L,CAAAA,CAAQ5L,CAAAA,CAAG,MAAA,CAAQ,CACvB,KAAA,CAAO;AAAA;AAAA;AAAA,cAAA,EAGGiR,CAAS,eAAe+B,CAAM,CAAA;AAAA;AAAA,MAAA,CAG1C,CAAC,CAAA,CACDzR,CAAAA,CAAQqK,CAAAA,CAAOsH,CAAS,EAExB,IAAME,CAAAA,CAAOpT,CAAAA,CAAG,MAAA,CAAQ,CAAE,KAAA,CAAO,CAAA,qBAAA,EAAwB,IAAA,CAAK,MAAA,CAAO,aAAa,CAAA,kBAAA,CAAqB,CAAC,CAAA,CACxGuB,CAAAA,CAAQ6R,EAAMC,CAAAA,CAAmBnD,GAAAA,CAAS,SAAA,CAAW,IAAA,CAAK,MAAM,CAAC,CAAA,CAEjEiD,CAAAA,CAAO,WAAA,CAAYvH,CAAK,CAAA,CACxBuH,CAAAA,CAAO,WAAA,CAAYC,CAAI,EAGvB,IAAMrJ,GAAAA,CAAO/J,CAAAA,CAAG,KAAA,CAAO,CACrB,KAAA,CAAO,CAAA,sCAAA,EAAyC,IAAA,CAAK,MAAA,CAAO,IAAI,CAAA,sFAAA,CAClE,CAAC,CAAA,CACDuB,CAAAA,CAAQwI,IAAMmG,GAAAA,CAAS,OAAO,CAAA,CAG9B,IAAA,CAAK,KAAK,YAAA,CAAaiD,CAAAA,CAAQ,IAAA,CAAK,KAAK,EACzC,IAAA,CAAK,IAAA,CAAK,YAAA,CAAapJ,GAAAA,CAAM,KAAK,KAAK,EACzC,CAEQ,QAAA,CAAS+F,EAA2B,CAC1C,IAAMwD,CAAAA,CAAc,IAAA,CAAK,KAAK,qBAAA,EAAsB,CAC9CC,CAAAA,CAAM,EAAA,CAERlR,EAAMyN,CAAAA,CAAW,GAAA,CAAMwD,CAAAA,CAAY,MAAA,CAASC,EAC5CjR,CAAAA,CAAOwN,CAAAA,CAAW,IAAA,CAAOA,CAAAA,CAAW,MAAQ,CAAA,CAAIwD,CAAAA,CAAY,KAAA,CAAQ,CAAA,CACpEE,EAAU,IAAA,CAGVnR,CAAAA,CAAM,CAAA,GACRA,CAAAA,CAAMyN,EAAW,MAAA,CAASyD,CAAAA,CAC1BC,CAAAA,CAAU,KAAA,CAAA,CAGZlR,EAAO,IAAA,CAAK,GAAA,CAAI,CAAA,CAAG,IAAA,CAAK,IAAIA,CAAAA,CAAM,MAAA,CAAO,UAAA,CAAagR,CAAAA,CAAY,MAAQ,CAAC,CAAC,CAAA,CAE5E,IAAA,CAAK,KAAK,KAAA,CAAM,GAAA,CAAM,CAAA,EAAGjR,CAAG,KAC5B,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,IAAA,CAAO,GAAGC,CAAI,CAAA,EAAA,CAAA,CAG9B,IAAMmR,CAAAA,CAAY,KAAK,GAAA,CAAI,EAAA,CAAI,IAAA,CAAK,GAAA,CAAI3D,EAAW,IAAA,CAAOA,CAAAA,CAAW,KAAA,CAAQ,CAAA,CAAIxN,EAAO,CAAA,CAAGgR,CAAAA,CAAY,KAAA,CAAQ,EAAE,CAAC,CAAA,CAE9GE,CAAAA,CAEF,IAAA,CAAK,KAAA,CAAM,MAAM,OAAA,CAAU;AAAA;AAAA;AAAA,mBAAA,EAGZ,IAAA,CAAK,OAAO,YAAY,CAAA;AAAA,+BAAA,EACZ,IAAA,CAAK,OAAO,WAAW,CAAA;AAAA,gCAAA,EACtB,IAAA,CAAK,OAAO,WAAW,CAAA;AAAA;AAAA;AAAA;AAAA,aAAA,EAI1CC,CAAS,CAAA;AAAA,MAAA,CAAA,CAIlB,IAAA,CAAK,KAAA,CAAM,KAAA,CAAM,OAAA,CAAU;AAAA;AAAA;AAAA,mBAAA,EAGZ,IAAA,CAAK,OAAO,YAAY,CAAA;AAAA,8BAAA,EACb,IAAA,CAAK,OAAO,WAAW,CAAA;AAAA,6BAAA,EACxB,IAAA,CAAK,OAAO,WAAW,CAAA;AAAA;AAAA;AAAA;AAAA,aAAA,EAIvCA,CAAS,CAAA;AAAA,MAAA,EAGtB,CAGA,QAAA,CAASlY,CAAAA,CAAqB,CAC5B,OAAO,IAAA,CAAK,IAAA,CAAK,QAAA,CAASA,CAAI,CAChC,CAEA,OAAA,EAAgB,CACd,KAAK,UAAA,EAAW,CAChB,IAAA,CAAK,UAAA,EAAW,CAChB,IAAA,CAAK,IAAA,CAAK,MAAA,GACZ,CACF,CAAA,CC1MA,IAAImY,CAAAA,CAAoC,KAkBxC,SAASC,EAAAA,CAA4B7Z,CAAAA,CAAoE,CACvG,OAAIA,CAAAA,GAAU,MAAA,EAAaA,CAAAA,GAAU,KAAA,CAC5B,CAAE,OAAA,CAAS,KAAA,CAAO,OAAA,CAAS,MAAO,iBAAA,CAAmB,EAAA,CAAI,iBAAA,CAAmB,EAAG,EAEpFA,CAAAA,GAAU,IAAA,CACL,CAAE,OAAA,CAAS,KAAM,OAAA,CAAS,IAAA,CAAM,iBAAA,CAAmB,EAAA,CAAI,iBAAA,CAAmB,EAAG,CAAA,CAE/E,CACL,QAASA,CAAAA,CAAM,OAAA,GAAY,KAAA,CAC3B,OAAA,CAASA,EAAM,OAAA,GAAY,KAAA,CAC3B,iBAAA,CAAmB,OAAOA,EAAM,iBAAA,EAAsB,QAAA,CAAWA,CAAAA,CAAM,iBAAA,CAAoB,EAAA,CAC3F,iBAAA,CAAmB,OAAOA,CAAAA,CAAM,mBAAsB,QAAA,CAAWA,CAAAA,CAAM,iBAAA,CAAoB,EAC7F,CACF,CAGA,SAAS8Z,EAAAA,EAAoC,CAC3C,IAAMC,CAAAA,CAAO,IAAM,CAAC,CAAA,CACpB,OAAO,CACL,OAAA,CAASA,EACT,IAAA,CAAMA,CAAAA,CACN,KAAA,CAAOA,CAAAA,CACP,QAASA,CAAAA,CACT,EAAA,CAAI,IAAMA,CAAAA,CACV,IAAKA,CACP,CACF,CAWO,SAASC,EAAAA,CAAOxa,CAAAA,CAA0C,CAE/D,IAAMya,EAAoCza,CAAAA,CAAO,KAAA,CAC7C,CAAA,GAAIsP,CAAAA,GAAoB,QAAQ,KAAA,CAAM,YAAA,CAAc,GAAGA,CAAI,EAC3D,IAAM,CAAC,CAAA,CAGX,GAAI8K,CAAAA,CACF,OAAAK,CAAAA,CAAI,yEAAoE,EACjEL,CAAAA,CAIT,GAAI,CAACpa,CAAAA,CAAO,UACV,GAAI,CAGF,GAAI,OAAO,QAAY,GAAA,CAGrB,OAAAA,CAAAA,CAAO,MAAA,GAFQ,YAEO,CAAA,CACfsa,EAAAA,EAEX,MAAQ,CAER,CAIF,GAAI,MAAA,CAAO,UAAA,CAAa,GAAA,CAAmB,CACzC,IAAMI,EAAS,QAAA,CACf,OACA1a,CAAAA,CAAO,MAAA,GAAS0a,CAAM,CAAA,CACfJ,IACT,CAGA,GAAI,CAACta,EAAO,KAAA,GAAU,CAACA,CAAAA,CAAO,QAAA,EAAY,OAAOA,CAAAA,CAAO,QAAA,EAAa,QAAA,CAAA,CACnE,OAAA,OAAA,CAAQ,KAAA,CACN,2HACF,CAAA,CACOsa,EAAAA,GAET,GAAI,CAACta,CAAAA,CAAO,WAAA,EAAe,OAAOA,CAAAA,CAAO,WAAA,EAAgB,QAAA,CACvD,OAAA,OAAA,CAAQ,MAAM,qFAAqF,CAAA,CAC5Fsa,EAAAA,EAAgB,CAGzB,IAAMd,CAAAA,CAASxZ,CAAAA,CAAO,MAAA,EAAU,KAI5BwZ,CAAAA,GAAW,IAAA,EACbmB,CAAAA,CAAWnB,CAAM,EAAE,KAAA,CAAM,IAAM,CAE/B,CAAC,EAEH,IAAMnS,CAAAA,CAAIsS,CAAAA,CAAQH,CAAM,CAAA,CAMlBoB,CAAAA,CAAwB5a,CAAAA,CAAO,qBAAA,EAAyB,KACxD6a,CAAAA,CAAW,IAAiB,CAChC,GAAI,CACF,IAAM1P,CAAAA,CAASnL,CAAAA,CAAO,YAAA,KACtB,GAAImL,CAAAA,CAAQ,OAAOA,CACrB,CAAA,MAAS3C,CAAAA,CAAG,CACViS,CAAAA,CAAI,kDAAmDjS,CAAC,EAC1D,CACA,OAAO,CAAE,GAAA,CAAK,MAAA,CAAO,QAAA,CAAS,QAAA,CAAU,WAAY,IAAK,CAC3D,CAAA,CAEAiS,CAAAA,CAAI,qBAAA,CAAuB,CACzB,WAAA,CAAaza,CAAAA,CAAO,YACpB,KAAA,CAAOA,CAAAA,CAAO,KAAA,EAAS,OAAA,CACvB,OAAAwZ,CAAAA,CACA,qBAAA,CAAAoB,CACF,CAAC,EAOD,IAAME,CAAAA,CAAkBT,EAAAA,CAA4Bra,CAAAA,CAAO,kBAAkB,CAAA,CACvE+a,CAAAA,CAAgBD,CAAAA,CAAgB,QAAU,IAAItL,EAAAA,CAAcsL,CAAAA,CAAgB,iBAAiB,EAAI,IAAA,CACjGE,CAAAA,CAAgBF,CAAAA,CAAgB,OAAA,CAAU,IAAI/K,EAAAA,CAAc+K,CAAAA,CAAgB,iBAAiB,CAAA,CAAI,IAAA,CAEjG1T,CAAAA,CAAS6T,GAAAA,CAAiBjb,CAAAA,CAAO,YAAaA,CAAAA,CAAO,KAAK,CAAA,CAC1D4K,CAAAA,CAAM,IAAIiG,CAAAA,CACVqK,CAAAA,CAAY,IAAIrK,EAGhBsK,CAAAA,CAAuBnb,CAAAA,CAAO,KAAA,CAChC,IAAIkY,EAAAA,CAAYlY,CAAAA,CAAO,KAAA,CAAOA,CAAAA,CAAO,WAAW,CAAA,CAChD,IAAI4O,EAAAA,CAAU5O,CAAAA,CAAO,SAAoBA,CAAAA,CAAO,WAAW,CAAA,CAG3DA,CAAAA,CAAO,QAAQ4K,CAAAA,CAAI,EAAA,CAAG,MAAA,CAAQ5K,CAAAA,CAAO,MAAM,CAAA,CAC3CA,CAAAA,CAAO,OAAA,EAAS4K,EAAI,EAAA,CAAG,OAAA,CAAS5K,CAAAA,CAAO,OAAO,EAC9CA,CAAAA,CAAO,cAAA,EAAgB4K,CAAAA,CAAI,EAAA,CAAG,gBAAiB5K,CAAAA,CAAO,cAAc,CAAA,CACpEA,CAAAA,CAAO,OAAA,EAAS4K,CAAAA,CAAI,EAAA,CAAG,gBAAA,CAAkB5K,EAAO,OAAO,CAAA,CACvDA,CAAAA,CAAO,iBAAA,EAAmB4K,EAAI,EAAA,CAAG,kBAAA,CAAoB5K,CAAAA,CAAO,iBAAiB,EAC7EA,CAAAA,CAAO,eAAA,EAAiB4K,CAAAA,CAAI,EAAA,CAAG,gBAAA,CAAkB5K,CAAAA,CAAO,eAAe,CAAA,CAG3E4K,EAAI,EAAA,CAAG,eAAA,CAAkBwQ,CAAAA,EAAOF,CAAAA,CAAU,KAAK,eAAA,CAAiBE,CAAE,CAAC,CAAA,CACnExQ,EAAI,EAAA,CAAG,kBAAA,CAAqBnJ,CAAAA,EAAOyZ,CAAAA,CAAU,IAAA,CAAK,kBAAA,CAAoBzZ,CAAE,CAAC,EACzEmJ,CAAAA,CAAI,EAAA,CAAG,MAAA,CAAQ,IAAMsQ,EAAU,IAAA,CAAK,YAAY,CAAC,CAAA,CACjDtQ,EAAI,EAAA,CAAG,OAAA,CAAS,IAAMsQ,CAAAA,CAAU,IAAA,CAAK,aAAa,CAAC,CAAA,CAGnDtQ,EAAI,EAAA,CAAG,MAAA,CAAQ,IAAM6P,CAAAA,CAAI,cAAc,CAAC,CAAA,CACxC7P,CAAAA,CAAI,EAAA,CAAG,QAAS,IAAM6P,CAAAA,CAAI,cAAc,CAAC,CAAA,CACzC7P,CAAAA,CAAI,EAAA,CAAG,eAAA,CAAkBwQ,GAAOX,CAAAA,CAAI,eAAA,CAAiBW,CAAAA,CAAG,EAAE,CAAC,CAAA,CAC3DxQ,CAAAA,CAAI,EAAA,CAAG,gBAAA,CAAmBZ,GAAQyQ,CAAAA,CAAI,iBAAA,CAAmBzQ,CAAAA,CAAI,OAAO,CAAC,CAAA,CACrEY,CAAAA,CAAI,EAAA,CAAG,mBAAoB,IAAM6P,CAAAA,CAAI,oBAAoB,CAAC,CAAA,CAC1D7P,CAAAA,CAAI,EAAA,CAAG,gBAAA,CAAkB,IAAM6P,CAAAA,CAAI,kBAAkB,CAAC,CAAA,CAGtD,IAAM7I,CAAAA,CAAO,QAAA,CAAS,aAAA,CAAc,iBAAiB,CAAA,CACrDA,CAAAA,CAAK,KAAA,CAAM,OAAA,CAAU,0BAA0B,UAAW,CAAA,CAAA,CAAA,CAG1D,IAAIyJ,CAAAA,CAAY,MAChB,GAAI,CAKE,OAAO,OAAA,CAAY,GAAA,EAAe,OAAA,CAAQ,GAAA,GAD/B,UAC2C,IAAM,MAAA,GAC9DA,CAAAA,CAAY,CAAA,CAAA,EAEhB,CAAA,KAAQ,CAER,CACA,IAAMC,CAAAA,CAAaD,CAAAA,CAAa,OAAoB,QAAA,CAC9CE,CAAAA,CAAS3J,CAAAA,CAAK,YAAA,CAAa,CAAE,IAAA,CAAM0J,CAAW,CAAC,EAIrD,GADmC,oBAAA,GAAwB,UAAA,CAAW,SAAA,CACtC,CAC9B,IAAME,CAAAA,CAAQ,IAAI,aAAA,CAClBA,EAAM,WAAA,CAAY3C,EAAAA,CAAYzR,CAAM,CAAC,CAAA,CACrCmU,CAAAA,CAAO,kBAAA,CAAqB,CAACC,CAAK,EACpC,CAAA,KAAO,CACL,IAAMzQ,EAAQ,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA,CAC5CA,EAAM,WAAA,CAAc8N,EAAAA,CAAYzR,CAAM,CAAA,CACrCmU,CAAAA,CAAuC,WAAA,CAAYxQ,CAAK,EAC3D,CAEA,QAAA,CAAS,IAAA,CAAK,WAAA,CAAY6G,CAAI,EAG9B,IAAMmE,CAAAA,CAAa,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA,CAC/CA,CAAAA,CAAW,YAAA,CAAa,MAAA,CAAQ,QAAQ,CAAA,CACxCA,CAAAA,CAAW,YAAA,CAAa,YAAa,QAAQ,CAAA,CAC7CA,CAAAA,CAAW,YAAA,CAAa,cAAe,MAAM,CAAA,CAC7CA,CAAAA,CAAW,KAAA,CAAM,QACf,+FAAA,CACF,QAAA,CAAS,IAAA,CAAK,WAAA,CAAYA,CAAU,CAAA,CAGpC,IAAMD,CAAAA,CAAU,IAAIyD,EAAAA,CAAQnS,CAAAA,CAAQoS,CAAM,CAAA,CACpCiC,EAAU,IAAI5F,EAAAA,CAAczO,CAAAA,CAAQ0O,CAAAA,CAASlL,EAAKvD,CAAAA,CAAG0O,CAAU,CAAA,CAG/D2F,CAAAA,CAAM,IAAIvK,EAAAA,CAAIoK,CAAAA,CAAQvb,CAAAA,CAAQ4K,EAAKvD,CAAC,CAAA,CAKtCsU,CAAAA,CAAkC,IAAA,CAClCC,CAAAA,CAA0C,IAAA,CAC1CC,CAAAA,CAAY,KAAA,CAChB,eAAeC,CAAAA,EAAuC,CACpD,OAAID,CAAAA,CAAkB,IAAA,CAClBF,CAAAA,GACCC,CAAAA,GACHA,CAAAA,CAAe,OAAO,qBAAY,CAAA,CAAE,IAAA,CAAM7R,CAAAA,EACpC8R,EAAkB,IAAA,EACtBF,CAAAA,CAAgB,IAAI5R,CAAAA,CAAI,MAAMwR,CAAAA,CAAQnU,CAAAA,CAAQwD,CAAAA,CAAKuQ,CAAAA,CAAQnb,CAAAA,CAAO,WAAA,CAAayb,CAAAA,CAASpU,CAAAA,CAAGmS,EAAQ,CACjG,QAAA,CAAAqB,CAAAA,CACA,qBAAA,CAAAD,CACF,CAAC,CAAA,CACMe,CAAAA,CACR,CAAA,CAAA,CAEIC,EACT,CAOA,GAAI,OAAO,MAAA,CAAW,GAAA,CAAa,CACjC,IAAMG,CAAAA,CAAW,IAAM,CAChBF,CAAAA,EAAgBC,CAAAA,GACvB,EACME,CAAAA,CAAO,MAAA,CAA8D,mBAAA,CACvE,OAAOA,GAAQ,UAAA,CAAYA,CAAAA,CAAID,CAAQ,CAAA,CACtC,UAAA,CAAWA,CAAAA,CAAU,GAAG,EAC/B,CAOA,IAAIE,CAAAA,CAAc,KAAA,CACZC,EAAAA,CAActR,CAAAA,CAAI,EAAA,CAAG,cAAA,CAAiBuR,CAAAA,EAAS,CAC/CR,CAAAA,GACAQ,CAAAA,EACFF,CAAAA,CAAc,IAAA,CACdH,CAAAA,EAAU,CACP,IAAA,CAAMM,CAAAA,EAAM,CACPA,CAAAA,EAAKH,CAAAA,EAAaG,CAAAA,CAAE,IAAA,GACxBH,CAAAA,CAAc,MAChB,CAAC,CAAA,CACA,MAAOjS,CAAAA,EAAQyQ,CAAAA,CAAI,4BAAA,CAA8BzQ,CAAG,CAAC,CAAA,EAExDiS,CAAAA,CAAc,KAAA,EAElB,CAAC,CAAA,CAEKI,EAAAA,CAAY,IAAI1R,EAAAA,CAAUvD,EAAQwD,CAAAA,CAAKvD,CAAAA,CAAGrH,CAAAA,CAAO,gBAAA,EAAoB,KAAK,CAAA,CAI5Esc,EAAAA,CAAa,KAAA,CACXC,EAAAA,CAAkB3R,CAAAA,CAAI,EAAA,CAAG,qBAAA,CAAuB,MAAO4R,GAAS,CACpE,GAAI,CAAAF,EAAAA,CACJ,CAAAA,EAAAA,CAAa,IAAA,CACb,GAAI,CACF,GAAM,CAAE,UAAA,CAAAlR,CAAAA,CAAY,IAAA,CAAA9B,CAAAA,CAAM,OAAA,CAAA4C,EAAAA,CAAS,iBAAA,CAAAb,EAAkB,CAAA,CAAImR,CAAAA,CAGrD/J,CAAAA,CAAWD,EAAAA,EAAY,CAC3B,GAAI,CAACC,CAAAA,CAAU,CAEb,GADAA,CAAAA,CAAW,MAAMgK,EAAAA,CAAelB,CAAAA,CAAQlU,CAAC,CAAA,CACrC,CAACoL,EAAU,OACfC,EAAAA,CAAaD,CAAQ,EACvB,CAGA,IAAMiK,EAAAA,CAAAA,CAAY,IAAM,CACtB,GAAI,CACF,OAAO,MAAA,CAAO,UAAA,EAChB,CAAA,KAAQ,CACN,OAAO,GAAG,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,EAAI,KAAK,MAAA,EAAO,CAAE,QAAA,CAAS,EAAE,EAAE,KAAA,CAAM,CAAC,CAAC,CAAA,CAC7D,CACF,CAAA,GAAG,CASGvZ,EAAAA,CAAQ0X,GAAS,CAInB8B,EAAAA,CAA0C,IAAA,CAAA,CAC1C5B,CAAAA,EAAiBC,KACnB2B,EAAAA,CAAc,CACZ,OAAA,CAAS5B,CAAAA,EAAe,YAAW,EAAK,EAAC,CACzC,OAAA,CAASC,CAAAA,EAAe,UAAA,EAAW,EAAK,EAC1C,CAAA,CAAA,CAGF,IAAM7M,EAAAA,CAA2B,CAC/B,YAAanO,CAAAA,CAAO,WAAA,CACpB,IAAA,CAAAsJ,CAAAA,CACA,QAAA4C,EAAAA,CACA,GAAA,CAAK/I,EAAAA,CAAM,GAAA,CACX,UAAA,CAAYA,EAAAA,CAAM,UAAA,CAClB,QAAA,CAAU,GAAG,MAAA,CAAO,UAAU,CAAA,CAAA,EAAI,MAAA,CAAO,WAAW,CAAA,CAAA,CACpD,SAAA,CAAW,SAAA,CAAU,SAAA,CACrB,WAAYsP,CAAAA,CAAS,IAAA,CACrB,WAAA,CAAaA,CAAAA,CAAS,KAAA,CACtB,WAAA,CAAa,CAACrH,CAAU,EACxB,QAAA,CAAAsR,EAAAA,CACA,iBAAA,CAAmBrR,EAAAA,EAAqB,KACxC,WAAA,CAAAsR,EACF,CAAA,CAEA,GAAI,CACF,IAAMhQ,CAAAA,CAAW,MAAMwO,CAAAA,CAAO,YAAA,CAAahN,EAAO,CAAA,CAClDvD,CAAAA,CAAI,KAAK,eAAA,CAAiB+B,CAAQ,CAAA,CAAA,CAI9B,CAACiO,GAAyBjO,CAAAA,CAAS,GAAA,GAAQxJ,EAAAA,CAAM,GAAA,GACnDsY,EAAQ,WAAA,CAAY9O,CAAAA,CAAU8O,CAAAA,CAAQ,KAAA,CAAQ,CAAC,CAAA,CAEjD1F,CAAAA,CAAW,WAAA,CAAc1O,EAAE,4BAA4B,CAAA,CAInDsU,CAAAA,EAAe,MAAMA,CAAAA,CAAc,OAAA,GACzC,CAAA,MAAS5O,EAAO,CACdnC,CAAAA,CAAI,IAAA,CAAK,gBAAA,CAAkBmC,CAAAA,YAAiB,KAAA,CAAQA,CAAAA,CAAQ,IAAI,MAAM,MAAA,CAAOA,CAAK,CAAC,CAAC,EACpFgJ,CAAAA,CAAW,WAAA,CAAc1O,CAAAA,CAAE,wBAAwB,EACrD,CACF,CAAA,OAAE,CACAiV,EAAAA,CAAa,MACf,CAAA,CACF,CAAC,CAAA,CAMKM,GAAe/B,CAAAA,EAAS,CACxBgC,EAAAA,CAAiBjC,CAAAA,CAAwB,CAAE,KAAA,CAAO,EAAA,CAAW,GAAA,CAAKgC,EAAAA,CAAa,GAAI,CAAA,CAAI,CAAE,KAAA,CAAO,EAAU,CAAA,CAChH,OAAAzB,CAAAA,CACG,YAAA,CAAanb,EAAO,WAAA,CAAa6c,EAAc,CAAA,CAC/C,IAAA,CAAK,CAAC,CAAE,SAAA,CAAAlG,CAAU,CAAA,GAAyC,CAE1D,IAAMX,CAAAA,CAAU4E,CAAAA,CAAwBjE,CAAAA,CAAU,MAAA,CAAQmG,CAAAA,EAAMA,CAAAA,CAAE,GAAA,GAAQF,GAAa,GAAG,CAAA,CAAIjG,CAAAA,CAC9F8E,CAAAA,CAAQ,OAAOzF,CAAO,EACxB,CAAC,CAAA,CACA,MAAOhM,CAAAA,EAAQ,CACdyQ,CAAAA,CAAI,iCAAA,CAAmCzQ,CAAG,EAC5C,CAAC,CAAA,CAGChK,EAAO,QAAA,EACTuO,EAAAA,CAAgBvO,CAAAA,CAAO,QAAQ,EAC5B,IAAA,CAAK,IAAMya,CAAAA,CAAI,qBAAqB,CAAC,CAAA,CACrC,KAAA,CAAM,IAAM,CAAC,CAAC,CAAA,CAGnBL,CAAAA,CAAW,CACT,QAAS,IAAM,CACbK,CAAAA,CAAI,mBAAmB,EACvBoB,CAAAA,CAAY,IAAA,CACZI,CAAAA,CAAc,KAAA,CACdM,IAAgB,CAChBL,EAAAA,EAAY,CACZR,CAAAA,CAAI,OAAA,EAAQ,CACZC,CAAAA,EAAe,OAAA,GACfU,EAAAA,CAAU,OAAA,EAAQ,CAClBZ,CAAAA,CAAQ,SAAQ,CAChB3F,CAAAA,CAAQ,OAAA,EAAQ,CAGhBiF,GAAe,OAAA,EAAQ,CACvBC,CAAAA,EAAe,OAAA,EAAQ,CACvBpQ,CAAAA,CAAI,SAAA,EAAU,CACdsQ,EAAU,SAAA,EAAU,CACpBnF,CAAAA,CAAW,MAAA,EAAO,CAClBnE,CAAAA,CAAK,MAAA,EAAO,CACZwI,EAAW,KACb,CAAA,CACA,IAAA,CAAM,IAAM,CAIVxP,CAAAA,CAAI,IAAA,CAAK,cAAA,CAAgB,IAAI,EAC/B,CAAA,CACA,KAAA,CAAO,IAAM,CACP+Q,CAAAA,CACFA,CAAAA,CAAc,KAAA,EAAM,CAGpBM,EAAc,MAElB,CAAA,CACA,OAAA,CAAS,IAAM,CAOb,GAAIN,CAAAA,EAAe,eAAA,CAAiB,CAClCA,CAAAA,CAAc,OAAA,EAAQ,CACtB,MACF,CAEA,IAAMxY,CAAAA,CAAQ0X,CAAAA,EAAS,CACjBkC,EAAOnC,CAAAA,CAAwB,CAAE,KAAA,CAAO,EAAA,CAAW,GAAA,CAAKzX,CAAAA,CAAM,GAAI,CAAA,CAAI,CAAE,KAAA,CAAO,EAAU,CAAA,CAC/FgY,CAAAA,CACG,aAAanb,CAAAA,CAAO,WAAA,CAAa+c,CAAI,CAAA,CACrC,KAAK,CAAC,CAAE,SAAA,CAAApG,CAAU,CAAA,GAAyC,CAC1D,IAAMX,EAAAA,CAAU4E,EAAwBjE,CAAAA,CAAU,MAAA,CAAQmG,EAAAA,EAAMA,EAAAA,CAAE,MAAQ3Z,CAAAA,CAAM,GAAG,CAAA,CAAIwT,CAAAA,CACvF8E,EAAQ,MAAA,CAAOzF,EAAO,EACxB,CAAC,CAAA,CACA,KAAA,CAAM,IAAM,CAAC,CAAC,EACnB,CAAA,CACA,EAAA,CAAI,CAAuClF,EAAUC,CAAAA,GAG5CmK,CAAAA,CAAU,EAAA,CAAGpK,CAAAA,CAAoBC,CAAuE,CAAA,CAEjH,GAAA,CAAK,CAAuCD,CAAAA,CAAUC,CAAAA,GAAyD,CAG7GmK,CAAAA,CAAU,GAAA,CAAIpK,EAAoBC,CAAuE,EAC3G,CACF,CAAA,CAEOqJ,CACT,CAOA,SAASqC,EAAAA,CAAerL,CAAAA,CAAwB/J,EAAwC,CACtF,OAAO,IAAI,OAAA,CAASuB,CAAAA,EAAY,CAE9B,IAAMoU,CAAAA,CAAqB5L,EAAW,aAAA,EAAiB,QAAA,CAAS,aAAA,CAE1D6L,CAAAA,CAAW,SAAS,aAAA,CAAc,KAAK,CAAA,CAC7CA,CAAAA,CAAS,MAAM,OAAA,CAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAAA,EAMb,UAAW,CAAA;AAAA;AAAA,IAAA,CAAA,CAIvB,IAAMC,EAAQ,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA,CAC1CA,CAAAA,CAAM,MAAM,OAAA,CAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAAA,CActB,IAAMC,CAAAA,CAAU,CAAA,kBAAA,EAAqB,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,CAC/CD,CAAAA,CAAM,YAAA,CAAa,MAAA,CAAQ,QAAQ,CAAA,CACnCA,CAAAA,CAAM,YAAA,CAAa,YAAA,CAAc,MAAM,CAAA,CACvCA,CAAAA,CAAM,YAAA,CAAa,iBAAA,CAAmBC,CAAO,CAAA,CAE7C,IAAMC,CAAAA,CAAQ,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA,CAC1CA,EAAM,SAAA,CAAY,mBAAA,CAClBA,CAAAA,CAAM,EAAA,CAAKD,CAAAA,CACXC,CAAAA,CAAM,WAAA,CAAc/V,CAAAA,CAAE,gBAAgB,CAAA,CACtC+V,CAAAA,CAAM,KAAA,CAAM,YAAA,CAAe,MAAA,CAE3B,IAAMC,CAAAA,CAAc,oBAAoB,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,CAC5CC,CAAAA,CAAe,CAAA,kBAAA,EAAqB,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,CAE9CC,CAAAA,CAAY,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA,CAChDA,CAAAA,CAAU,UAAY,gBAAA,CACtBA,CAAAA,CAAU,WAAA,CAAclW,CAAAA,CAAE,oBAAoB,CAAA,CAC9CkW,CAAAA,CAAU,YAAA,CAAa,KAAA,CAAOF,CAAW,CAAA,CACzC,IAAMG,CAAAA,CAAY,QAAA,CAAS,aAAA,CAAc,OAAO,EAChDA,CAAAA,CAAU,SAAA,CAAY,UAAA,CACtBA,CAAAA,CAAU,EAAA,CAAKH,CAAAA,CACfG,CAAAA,CAAU,IAAA,CAAO,MAAA,CACjBA,CAAAA,CAAU,WAAA,CAAcnW,CAAAA,CAAE,0BAA0B,CAAA,CACpDmW,CAAAA,CAAU,KAAA,CAAM,aAAe,MAAA,CAE/B,IAAMC,CAAAA,CAAa,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA,CACjDA,CAAAA,CAAW,SAAA,CAAY,gBAAA,CACvBA,CAAAA,CAAW,WAAA,CAAcpW,CAAAA,CAAE,qBAAqB,CAAA,CAChDoW,CAAAA,CAAW,aAAa,KAAA,CAAOH,CAAY,CAAA,CAC3C,IAAMI,CAAAA,CAAa,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA,CACjDA,CAAAA,CAAW,SAAA,CAAY,UAAA,CACvBA,CAAAA,CAAW,EAAA,CAAKJ,CAAAA,CAChBI,CAAAA,CAAW,KAAO,OAAA,CAClBA,CAAAA,CAAW,WAAA,CAAcrW,CAAAA,CAAE,2BAA2B,CAAA,CAEtD,IAAMoB,CAAAA,CAAS,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA,CAC3CA,CAAAA,CAAO,KAAA,CAAM,OAAA,CAAU,gEAAA,CAEvB,IAAMkV,CAAAA,CAAcxS,CAAAA,EAA4B,CAC9C8R,CAAAA,CAAS,mBAAA,CAAoB,SAAA,CAAWW,CAAS,CAAA,CACjDX,CAAAA,CAAS,KAAA,CAAM,OAAA,CAAU,GAAA,CACzBC,CAAAA,CAAM,KAAA,CAAM,SAAA,CAAY,8BAAA,CACxB,WAAW,IAAM,CACfD,CAAAA,CAAS,MAAA,EAAO,CAChBD,CAAAA,EAAmB,KAAA,EAAM,CACzBpU,CAAAA,CAAQuC,CAAM,EAChB,CAAA,CAAG,GAAG,EACR,CAAA,CAEMzC,CAAAA,CAAY,SAAS,aAAA,CAAc,QAAQ,CAAA,CACjDA,CAAAA,CAAU,SAAA,CAAY,cAAA,CACtBA,CAAAA,CAAU,WAAA,CAAcrB,CAAAA,CAAE,iBAAiB,CAAA,CAC3CqB,CAAAA,CAAU,gBAAA,CAAiB,OAAA,CAAS,IAAMiV,CAAAA,CAAW,IAAI,CAAC,CAAA,CAE1D,IAAME,CAAAA,CAAY,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA,CACjDA,CAAAA,CAAU,SAAA,CAAY,gBAAA,CACtBA,CAAAA,CAAU,WAAA,CAAcxW,CAAAA,CAAE,iBAAiB,CAAA,CAC3CwW,EAAU,gBAAA,CAAiB,OAAA,CAAS,IAAM,CACxC,IAAMtd,CAAAA,CAAOid,CAAAA,CAAU,KAAA,CAAM,IAAA,EAAK,CAC5BM,CAAAA,CAAQJ,CAAAA,CAAW,KAAA,CAAM,IAAA,EAAK,CACpC,GAAI,CAACnd,CAAAA,EAAQ,CAACud,CAAAA,CAAO,OAErB,GAAI,CADe,4BAAA,CACH,IAAA,CAAKA,CAAK,CAAA,CAAG,CAC3BJ,CAAAA,CAAW,KAAA,CAAM,WAAA,CAAc,6BAAA,CAC/B,MACF,CACAC,CAAAA,CAAW,CAAE,IAAA,CAAApd,CAAAA,CAAM,KAAA,CAAAud,CAAM,CAAC,EAC5B,CAAC,CAAA,CAGD,IAAMC,CAAAA,CAAqB,gDAAA,CACrBH,CAAAA,CAAapV,CAAAA,EAAa,CAC9B,IAAMwV,CAAAA,CAAKxV,CAAAA,CACX,GAAIwV,CAAAA,CAAG,GAAA,GAAQ,QAAA,CAAU,CACvBL,CAAAA,CAAW,IAAI,CAAA,CACf,MACF,CACA,GAAIK,CAAAA,CAAG,GAAA,GAAQ,KAAA,CAAO,CACpB,IAAM9U,CAAAA,CAAe,KAAA,CAAM,IAAA,CAAKgU,CAAAA,CAAM,gBAAA,CAA8Ba,CAAkB,CAAC,CAAA,CACvF,GAAI7U,CAAAA,CAAa,MAAA,GAAW,CAAA,CAAG,OAC/B,IAAMC,CAAAA,CAAQD,EAAa,CAAC,CAAA,CACtBE,CAAAA,CAAOF,CAAAA,CAAaA,CAAAA,CAAa,MAAA,CAAS,CAAC,CAAA,CACjD,GAAI,CAACC,CAAAA,EAAS,CAACC,CAAAA,CAAM,OACrB,IAAM6U,CAAAA,CAAS7M,EAAW,aAAA,CACtB4M,CAAAA,CAAG,QAAA,CAAA,CACDC,CAAAA,GAAW9U,CAAAA,EAAS,CAAC+T,CAAAA,CAAM,QAAA,CAASe,CAAM,CAAA,IAC5CD,CAAAA,CAAG,cAAA,EAAe,CAClB5U,CAAAA,CAAK,KAAA,EAAM,CAAA,CAAA,CAGT6U,IAAW7U,CAAAA,EAAQ,CAAC8T,CAAAA,CAAM,QAAA,CAASe,CAAM,CAAA,IAC3CD,CAAAA,CAAG,cAAA,EAAe,CAClB7U,CAAAA,CAAM,KAAA,EAAM,EAGlB,CACF,CAAA,CACA8T,CAAAA,CAAS,gBAAA,CAAiB,UAAWW,CAAS,CAAA,CAG9CX,CAAAA,CAAS,gBAAA,CAAiB,OAAA,CAAUzU,CAAAA,EAAM,CACpCA,CAAAA,CAAE,MAAA,GAAWyU,CAAAA,EAAUU,CAAAA,CAAW,IAAI,EAC5C,CAAC,CAAA,CAEDlV,CAAAA,CAAO,YAAYC,CAAS,CAAA,CAC5BD,CAAAA,CAAO,WAAA,CAAYoV,CAAS,CAAA,CAE5BX,CAAAA,CAAM,WAAA,CAAYE,CAAK,CAAA,CACvBF,CAAAA,CAAM,WAAA,CAAYK,CAAS,CAAA,CAC3BL,CAAAA,CAAM,WAAA,CAAYM,CAAS,CAAA,CAC3BN,CAAAA,CAAM,WAAA,CAAYO,CAAU,CAAA,CAC5BP,CAAAA,CAAM,WAAA,CAAYQ,CAAU,CAAA,CAC5BR,CAAAA,CAAM,WAAA,CAAYzU,CAAM,CAAA,CACxBwU,CAAAA,CAAS,WAAA,CAAYC,CAAK,EAE1B9L,CAAAA,CAAW,WAAA,CAAY6L,CAAQ,CAAA,CAG/B,qBAAA,CAAsB,IAAM,CAC1BA,CAAAA,CAAS,KAAA,CAAM,OAAA,CAAU,GAAA,CACzBC,CAAAA,CAAM,KAAA,CAAM,SAAA,CAAY,wBAAA,CACxBM,CAAAA,CAAU,QACZ,CAAC,EACH,CAAC,CACH,CC3mBO,SAASU,EAAAA,CAAale,CAAAA,CAA0C,CACrE,OAAOwa,EAAAA,CAAOxa,CAAM,CACtB,CCuBO,SAASme,GAAYne,CAAAA,CAAiD,CAK3E,IAAMoe,CAAAA,CAAYC,MAAAA,CAAOre,CAAM,CAAA,CAC/Boe,CAAAA,CAAU,OAAA,CAAUpe,CAAAA,CAEpB,GAAM,CAACoa,CAAAA,CAAUkE,CAAW,CAAA,CAAIC,QAAAA,CAAkC,IAAI,CAAA,CAEtE,OAAAC,SAAAA,CAAU,IAAM,CAMd,IAAIC,CAAAA,CAAU,IAAA,CACRC,CAAAA,CAAUR,EAAAA,CAAaE,CAAAA,CAAU,OAAO,CAAA,CAC9C,GAAI,CAACK,CAAAA,CAAS,CAGZC,CAAAA,CAAQ,OAAA,EAAQ,CAChB,MACF,CAMA,IAAMC,CAAAA,CAAYD,CAAAA,CAAQ,EAAA,CAAG,eAAA,CAAkBtD,CAAAA,EAAO,CACpDgD,CAAAA,CAAU,OAAA,CAAQ,cAAA,GAAiBhD,CAAE,EACvC,CAAC,CAAA,CACKwD,CAAAA,CAAYF,CAAAA,CAAQ,EAAA,CAAG,YAAA,CAAc,IAAM,CAC/CN,CAAAA,CAAU,OAAA,CAAQ,MAAA,KACpB,CAAC,CAAA,CACKS,CAAAA,CAAaH,CAAAA,CAAQ,GAAG,aAAA,CAAe,IAAM,CACjDN,CAAAA,CAAU,OAAA,CAAQ,OAAA,KACpB,CAAC,CAAA,CAED,OAAAE,CAAAA,CAAYI,CAAO,CAAA,CAEZ,IAAM,CACXD,CAAAA,CAAU,MACVE,CAAAA,EAAU,CACVC,CAAAA,EAAU,CACVC,CAAAA,EAAW,CACXH,CAAAA,CAAQ,OAAA,EAAQ,CAChBJ,CAAAA,CAAY,IAAI,EAClB,CAMF,CAAA,CAAG,EAAE,EAEElE,CACT","file":"react.js","sourcesContent":["// License: MIT\n// Author: Anton Medvedev <anton@medv.io>\n// Source: https://github.com/antonmedv/finder\nlet config;\nlet rootDocument;\nlet start;\nexport function finder(input, options) {\n start = new Date();\n if (input.nodeType !== Node.ELEMENT_NODE) {\n throw new Error(`Can't generate CSS selector for non-element node type.`);\n }\n if ('html' === input.tagName.toLowerCase()) {\n return 'html';\n }\n const defaults = {\n root: document.body,\n idName: (name) => true,\n className: (name) => true,\n tagName: (name) => true,\n attr: (name, value) => false,\n seedMinLength: 1,\n optimizedMinLength: 2,\n threshold: 1000,\n maxNumberOfTries: 10000,\n timeoutMs: undefined,\n };\n config = { ...defaults, ...options };\n rootDocument = findRootDocument(config.root, defaults);\n let path = bottomUpSearch(input, 'all', () => bottomUpSearch(input, 'two', () => bottomUpSearch(input, 'one', () => bottomUpSearch(input, 'none'))));\n if (path) {\n const optimized = sort(optimize(path, input));\n if (optimized.length > 0) {\n path = optimized[0];\n }\n return selector(path);\n }\n else {\n throw new Error(`Selector was not found.`);\n }\n}\nfunction findRootDocument(rootNode, defaults) {\n if (rootNode.nodeType === Node.DOCUMENT_NODE) {\n return rootNode;\n }\n if (rootNode === defaults.root) {\n return rootNode.ownerDocument;\n }\n return rootNode;\n}\nfunction bottomUpSearch(input, limit, fallback) {\n let path = null;\n let stack = [];\n let current = input;\n let i = 0;\n while (current) {\n const elapsedTime = new Date().getTime() - start.getTime();\n if (config.timeoutMs !== undefined && elapsedTime > config.timeoutMs) {\n throw new Error(`Timeout: Can't find a unique selector after ${elapsedTime}ms`);\n }\n let level = maybe(id(current)) ||\n maybe(...attr(current)) ||\n maybe(...classNames(current)) ||\n maybe(tagName(current)) || [any()];\n const nth = index(current);\n if (limit == 'all') {\n if (nth) {\n level = level.concat(level.filter(dispensableNth).map((node) => nthChild(node, nth)));\n }\n }\n else if (limit == 'two') {\n level = level.slice(0, 1);\n if (nth) {\n level = level.concat(level.filter(dispensableNth).map((node) => nthChild(node, nth)));\n }\n }\n else if (limit == 'one') {\n const [node] = (level = level.slice(0, 1));\n if (nth && dispensableNth(node)) {\n level = [nthChild(node, nth)];\n }\n }\n else if (limit == 'none') {\n level = [any()];\n if (nth) {\n level = [nthChild(level[0], nth)];\n }\n }\n for (let node of level) {\n node.level = i;\n }\n stack.push(level);\n if (stack.length >= config.seedMinLength) {\n path = findUniquePath(stack, fallback);\n if (path) {\n break;\n }\n }\n current = current.parentElement;\n i++;\n }\n if (!path) {\n path = findUniquePath(stack, fallback);\n }\n if (!path && fallback) {\n return fallback();\n }\n return path;\n}\nfunction findUniquePath(stack, fallback) {\n const paths = sort(combinations(stack));\n if (paths.length > config.threshold) {\n return fallback ? fallback() : null;\n }\n for (let candidate of paths) {\n if (unique(candidate)) {\n return candidate;\n }\n }\n return null;\n}\nfunction selector(path) {\n let node = path[0];\n let query = node.name;\n for (let i = 1; i < path.length; i++) {\n const level = path[i].level || 0;\n if (node.level === level - 1) {\n query = `${path[i].name} > ${query}`;\n }\n else {\n query = `${path[i].name} ${query}`;\n }\n node = path[i];\n }\n return query;\n}\nfunction penalty(path) {\n return path.map((node) => node.penalty).reduce((acc, i) => acc + i, 0);\n}\nfunction unique(path) {\n const css = selector(path);\n switch (rootDocument.querySelectorAll(css).length) {\n case 0:\n throw new Error(`Can't select any node with this selector: ${css}`);\n case 1:\n return true;\n default:\n return false;\n }\n}\nfunction id(input) {\n const elementId = input.getAttribute('id');\n if (elementId && config.idName(elementId)) {\n return {\n name: '#' + CSS.escape(elementId),\n penalty: 0,\n };\n }\n return null;\n}\nfunction attr(input) {\n const attrs = Array.from(input.attributes).filter((attr) => config.attr(attr.name, attr.value));\n return attrs.map((attr) => ({\n name: `[${CSS.escape(attr.name)}=\"${CSS.escape(attr.value)}\"]`,\n penalty: 0.5,\n }));\n}\nfunction classNames(input) {\n const names = Array.from(input.classList).filter(config.className);\n return names.map((name) => ({\n name: '.' + CSS.escape(name),\n penalty: 1,\n }));\n}\nfunction tagName(input) {\n const name = input.tagName.toLowerCase();\n if (config.tagName(name)) {\n return {\n name,\n penalty: 2,\n };\n }\n return null;\n}\nfunction any() {\n return {\n name: '*',\n penalty: 3,\n };\n}\nfunction index(input) {\n const parent = input.parentNode;\n if (!parent) {\n return null;\n }\n let child = parent.firstChild;\n if (!child) {\n return null;\n }\n let i = 0;\n while (child) {\n if (child.nodeType === Node.ELEMENT_NODE) {\n i++;\n }\n if (child === input) {\n break;\n }\n child = child.nextSibling;\n }\n return i;\n}\nfunction nthChild(node, i) {\n return {\n name: node.name + `:nth-child(${i})`,\n penalty: node.penalty + 1,\n };\n}\nfunction dispensableNth(node) {\n return node.name !== 'html' && !node.name.startsWith('#');\n}\nfunction maybe(...level) {\n const list = level.filter(notEmpty);\n if (list.length > 0) {\n return list;\n }\n return null;\n}\nfunction notEmpty(value) {\n return value !== null && value !== undefined;\n}\nfunction* combinations(stack, path = []) {\n if (stack.length > 0) {\n for (let node of stack[0]) {\n yield* combinations(stack.slice(1, stack.length), path.concat(node));\n }\n }\n else {\n yield path;\n }\n}\nfunction sort(paths) {\n return [...paths].sort((a, b) => penalty(a) - penalty(b));\n}\nfunction* optimize(path, input, scope = {\n counter: 0,\n visited: new Map(),\n}) {\n if (path.length > 2 && path.length > config.optimizedMinLength) {\n for (let i = 1; i < path.length - 1; i++) {\n if (scope.counter > config.maxNumberOfTries) {\n return; // Okay At least I tried!\n }\n scope.counter += 1;\n const newPath = [...path];\n newPath.splice(i, 1);\n const newPathKey = selector(newPath);\n if (scope.visited.has(newPathKey)) {\n return;\n }\n if (unique(newPath) && same(newPath, input)) {\n yield newPath;\n scope.visited.set(newPathKey, true);\n yield* optimize(newPath, input, scope);\n }\n }\n }\n}\nfunction same(path, input) {\n return rootDocument.querySelector(selector(path)) === input;\n}\n","/**\n * Element fingerprinting for robust DOM re-anchoring.\n *\n * Captures structural properties (child count, sibling index, stable attributes)\n * that survive CSS class changes and minor DOM reshuffling.\n * Inspired by Similo (academic state-of-the-art, 98.8% accuracy).\n */\n\nconst STABLE_ATTRS = [\"role\", \"aria-label\", \"type\", \"name\", \"href\", \"src\", \"data-testid\", \"data-id\"] as const;\n\n/** Simple 32-bit hash (djb2). */\nfunction djb2(str: string): string {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) + hash + str.charCodeAt(i)) | 0;\n }\n return (hash >>> 0).toString(36);\n}\n\n/**\n * Generate a compact structural fingerprint for a DOM element.\n *\n * Format: `\"childCount:siblingIdx:attrHash\"`\n * - `childCount` — number of direct child elements\n * - `siblingIdx` — position among same-tag siblings (0-based)\n * - `attrHash` — djb2 hash of stable attributes (role, aria-label, type, etc.)\n *\n * Tag name is NOT included — it's stored separately in `AnchorData.elementTag`.\n */\nexport function generateFingerprint(element: Element): string {\n const childCount = element.children.length;\n\n // Position among same-tag siblings\n let siblingIdx = 0;\n const parent = element.parentElement;\n if (parent) {\n for (const child of parent.children) {\n if (child === element) break;\n if (child.tagName === element.tagName) siblingIdx++;\n }\n }\n\n // Hash stable attributes\n const attrs: string[] = [];\n for (const attr of STABLE_ATTRS) {\n const val = element.getAttribute(attr);\n if (val) attrs.push(`${attr}=${val}`);\n }\n const attrHash = attrs.length > 0 ? djb2(attrs.join(\",\")) : \"0\";\n\n return `${childCount}:${siblingIdx}:${attrHash}`;\n}\n\n/**\n * Score how well a candidate element matches a stored fingerprint.\n * Returns 0–1.\n *\n * Weights:\n * - Child count match: 0.2 (tolerant — ±2 gets partial credit)\n * - Sibling index match: 0.4 (positional — most discriminating)\n * - Attribute hash match: 0.4 (identity — exact or nothing)\n */\nexport function scoreFingerprint(candidate: Element, storedFingerprint: string): number {\n const parts = storedFingerprint.split(\":\");\n if (parts.length !== 3) return 0;\n\n const [storedChildren, storedSibIdx, storedAttrHash] = parts;\n const storedChildCount = Number(storedChildren);\n const storedSibIndex = Number(storedSibIdx);\n if (Number.isNaN(storedChildCount) || Number.isNaN(storedSibIndex)) return 0;\n\n const candidateFp = generateFingerprint(candidate);\n const [candChildren, candSibIdx, candAttrHash] = candidateFp.split(\":\");\n\n let score = 0;\n\n // Child count (0.2)\n const childDiff = Math.abs(Number(candChildren) - storedChildCount);\n if (childDiff === 0) score += 0.2;\n else if (childDiff <= 2) score += 0.1;\n else if (childDiff <= 5) score += 0.03;\n\n // Sibling index (0.4)\n const sibDiff = Math.abs(Number(candSibIdx) - storedSibIndex);\n if (sibDiff === 0) score += 0.4;\n else if (sibDiff === 1) score += 0.2;\n else if (sibDiff <= 3) score += 0.08;\n\n // Attribute hash (0.4)\n if (candAttrHash === storedAttrHash) score += 0.4;\n\n return score;\n}\n","/**\n * Shared text-context helpers for DOM anchoring.\n * Used by both anchor generation (anchor.ts) and resolution (resolver.ts).\n */\n\n/**\n * Extract ~32 chars of text from the nearest sibling with content.\n * Walks up to 3 siblings in the given direction.\n */\nexport function adjacentText(element: Element, direction: \"before\" | \"after\"): string {\n const prop = direction === \"before\" ? \"previousElementSibling\" : \"nextElementSibling\";\n let sibling: Element | null = element[prop];\n let attempts = 3;\n\n while (sibling && attempts > 0) {\n const text = sibling.textContent?.trim();\n if (text) {\n return direction === \"before\" ? text.slice(-32) : text.slice(0, 32);\n }\n sibling = sibling[prop];\n attempts--;\n }\n\n return \"\";\n}\n\n/** Collect text from immediate siblings for disambiguation context. */\nexport function neighborText(element: Element): string {\n const prev = element.previousElementSibling?.textContent?.trim().slice(0, 40) ?? \"\";\n const next = element.nextElementSibling?.textContent?.trim().slice(0, 40) ?? \"\";\n return [prev, next].filter(Boolean).join(\" | \");\n}\n","/**\n * Generate an optimized XPath for a DOM element.\n *\n * Strategy:\n * - If the element has a unique id → //tag[@id='value']\n * - Otherwise, walk up the tree building /tag[position] segments\n * until we hit an ancestor with an id or reach <body>\n * - Cap depth at 6 levels to keep paths short\n */\nexport function generateXPath(element: Element): string {\n if (element.id) {\n const safeId = element.id.includes(\"'\") ? `concat('${element.id.replace(/'/g, \"',\\\"'\\\",'\")}')` : `'${element.id}'`;\n return `//${element.localName}[@id=${safeId}]`;\n }\n\n const segments: string[] = [];\n let current: Element | null = element;\n\n while (current && current !== document.body && segments.length < 6) {\n const tag = current.localName;\n const parent: Element | null = current.parentElement;\n\n if (current.id) {\n const safeId = current.id.includes(\"'\")\n ? `concat('${current.id.replace(/'/g, \"',\\\"'\\\",'\")}')`\n : `'${current.id}'`;\n segments.unshift(`/${tag}[@id=${safeId}]`);\n return \"/\" + segments.join(\"\");\n }\n\n // Compute position among same-tag siblings\n let position = 1;\n if (parent) {\n for (const sibling of parent.children) {\n if (sibling === current) break;\n if (sibling.localName === tag) position++;\n }\n }\n\n segments.unshift(`/${tag}[${position}]`);\n current = parent;\n }\n\n return \"/html/body\" + segments.join(\"\");\n}\n","import { finder } from \"@medv/finder\";\nimport type { AnchorData, RectData } from \"@siteping/core\";\nimport { generateFingerprint } from \"./fingerprint.js\";\nimport { adjacentText, neighborText } from \"./text-context.js\";\nimport { generateXPath } from \"./xpath.js\";\n\n/** HTML attribute hosts use to mark stable semantic anchors. */\nexport const ANCHOR_KEY_ATTR = \"data-feedback-anchor\";\n\n/**\n * Generate a multi-selector anchor for a DOM element.\n *\n * Resolution priority (used by `resolveAnchor`):\n * 1. Semantic anchor (`data-feedback-anchor` on closest ancestor) — hosts opt\n * into stable, narrow anchors that survive viewport changes and refactors\n * 2. Element id\n * 3. CSS selector via @medv/finder\n * 4. XPath\n * 5. Smart scan (fingerprint + text + prefix/suffix + neighbor)\n */\nexport function generateAnchor(element: Element): AnchorData {\n const cssSelector = finder(element, {\n // Filter out CSS-in-JS hashed class names\n className: (name: string) => !/^(css|sc|emotion|styled)-/.test(name) && !/^[a-z]{1,3}[A-Za-z0-9]{4,8}$/.test(name),\n // Prefer stable attributes\n attr: (name: string) => [\"data-testid\", \"data-id\", \"role\", \"aria-label\"].includes(name),\n // Exclude framework-generated dynamic IDs\n idName: (name: string) => !name.startsWith(\"radix-\") && !/^:r[0-9]+:$/.test(name),\n seedMinLength: 3,\n optimizedMinLength: 2,\n });\n\n const xpath = generateXPath(element);\n\n const rawText = element.textContent?.trim() ?? \"\";\n const textSnippet = rawText.slice(0, 120);\n\n const textPrefix = adjacentText(element, \"before\");\n const textSuffix = adjacentText(element, \"after\");\n const fingerprint = generateFingerprint(element);\n const neighbor = neighborText(element);\n\n const semanticAncestor = element.closest(`[${ANCHOR_KEY_ATTR}]`);\n const anchorKey = semanticAncestor?.getAttribute(ANCHOR_KEY_ATTR) ?? null;\n\n return {\n cssSelector,\n xpath,\n textSnippet,\n textPrefix,\n textSuffix,\n fingerprint,\n neighborText: neighbor,\n elementTag: element.tagName,\n elementId: element.id || undefined,\n anchorKey,\n };\n}\n\n/** Whether `el`'s bounding box fully contains `rect`. */\nfunction containsRect(el: Element, rect: DOMRect): boolean {\n const b = el.getBoundingClientRect();\n return b.left <= rect.x && b.top <= rect.y && b.right >= rect.x + rect.width && b.bottom >= rect.y + rect.height;\n}\n\n/**\n * Find the best DOM element to use as the rect's anchor.\n *\n * Priority:\n * 1. Closest ancestor with `data-feedback-anchor` whose bounds contain the rect —\n * semantic anchors are typically narrow section roots, so anchoring against\n * them keeps the percentage-based rect stable across viewport changes\n * instead of stretching to the width of `<main>` or `<body>`.\n * 2. Smallest ancestor that contains the rect (legacy behavior).\n * 3. `document.body` fallback — keeps percentages in [0, 1].\n */\nexport function findAnchorElement(rect: DOMRect, root: Element = document.documentElement): Element {\n const centerX = rect.x + rect.width / 2;\n const centerY = rect.y + rect.height / 2;\n\n const elementAtCenter = document.elementFromPoint(centerX, centerY);\n if (!elementAtCenter || elementAtCenter === root) return document.body;\n\n // Pass 1 — semantic anchor (host-controlled, most stable)\n let current: Element | null = elementAtCenter;\n while (current && current !== document.body) {\n if (current.hasAttribute(ANCHOR_KEY_ATTR) && containsRect(current, rect)) {\n return current;\n }\n current = current.parentElement;\n }\n\n // Pass 2 — original behavior: smallest ancestor that contains the rect\n current = elementAtCenter;\n while (current && current !== document.body) {\n if (containsRect(current, rect)) return current;\n current = current.parentElement;\n }\n\n return document.body;\n}\n\n/**\n * Convert absolute rectangle coordinates to percentages\n * relative to an anchor element's bounding box.\n */\nexport function rectToPercentages(rect: DOMRect, anchorBounds: DOMRect): RectData {\n // Guard against zero-dimension anchors (collapsed/hidden elements)\n if (anchorBounds.width <= 0 || anchorBounds.height <= 0) {\n return { xPct: 0, yPct: 0, wPct: 1, hPct: 1 };\n }\n return {\n xPct: (rect.x - anchorBounds.x) / anchorBounds.width,\n yPct: (rect.y - anchorBounds.y) / anchorBounds.height,\n wPct: rect.width / anchorBounds.width,\n hPct: rect.height / anchorBounds.height,\n };\n}\n","import type { FeedbackType } from \"@siteping/core\";\nimport { Z_INDEX_MAX } from \"./constants.js\";\nimport { el, parseSvg, setText } from \"./dom-utils.js\";\nimport type { TFunction } from \"./i18n/index.js\";\nimport { ICON_BUG, ICON_CHANGE, ICON_OTHER, ICON_QUESTION } from \"./icons.js\";\nimport { getTypeBgColor, getTypeColor, type ThemeColors } from \"./styles/theme.js\";\n\ninterface PopupResult {\n type: FeedbackType;\n message: string;\n}\n\ninterface TypeOption {\n type: FeedbackType;\n label: string;\n icon: string;\n}\n\n/**\n * Popup form shown after drawing an annotation rectangle.\n *\n * Glassmorphism design: frosted glass background, soft shadows,\n * pill-shaped type buttons, gradient submit button.\n * Lives outside Shadow DOM.\n */\nexport class Popup {\n private root: HTMLElement;\n private selectedType: FeedbackType | null = null;\n private textarea: HTMLTextAreaElement;\n private submitBtn: HTMLButtonElement;\n private resolve: ((result: PopupResult | null) => void) | null = null;\n private previouslyFocused: HTMLElement | null = null;\n private onKeydownTrap: ((e: KeyboardEvent) => void) | null = null;\n\n constructor(\n private readonly colors: ThemeColors,\n private readonly t: TFunction,\n ) {\n this.root = el(\"div\", {\n style: `\n position:fixed;\n z-index:${Z_INDEX_MAX};\n width:300px;\n padding:16px;\n border-radius:16px;\n background:${this.colors.glassBg};\n backdrop-filter:blur(24px);\n -webkit-backdrop-filter:blur(24px);\n border:1px solid ${this.colors.glassBorder};\n box-shadow:0 8px 32px ${this.colors.shadow}, 0 2px 8px ${this.colors.shadow};\n font-family:\"Inter\",system-ui,-apple-system,sans-serif;\n opacity:0;\n transform:translateY(8px) scale(0.98);\n transition:opacity 0.25s cubic-bezier(0.16, 1, 0.3, 1),transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);\n display:none;\n -webkit-font-smoothing:antialiased;\n `,\n });\n\n this.root.setAttribute(\"role\", \"dialog\");\n this.root.setAttribute(\"aria-modal\", \"true\");\n this.root.setAttribute(\"aria-label\", this.t(\"popup.ariaLabel\"));\n\n // Type selector grid (2x2)\n const typeOptions: TypeOption[] = [\n { type: \"question\", label: this.t(\"type.question\"), icon: ICON_QUESTION },\n { type: \"change\", label: this.t(\"type.change\"), icon: ICON_CHANGE },\n { type: \"bug\", label: this.t(\"type.bug\"), icon: ICON_BUG },\n { type: \"other\", label: this.t(\"type.other\"), icon: ICON_OTHER },\n ];\n const typeRow = el(\"div\", { style: \"display:grid;grid-template-columns:1fr 1fr;gap:6px;margin-bottom:12px;\" });\n for (const option of typeOptions) {\n const btn = document.createElement(\"button\");\n btn.style.cssText = `\n height:44px;\n border-radius:9999px;border:1px solid ${this.colors.border};\n background:${this.colors.glassBg};cursor:pointer;\n display:flex;align-items:center;justify-content:center;gap:5px;\n font-family:\"Inter\",system-ui,-apple-system,sans-serif;\n font-size:13px;font-weight:500;color:${this.colors.textTertiary};\n transition:all 0.2s ease;\n padding:0 12px;\n `;\n const icon = parseSvg(option.icon);\n icon.setAttribute(\"style\", \"width:13px;height:13px;flex-shrink:0;\");\n btn.appendChild(icon);\n const labelSpan = document.createElement(\"span\");\n setText(labelSpan, option.label);\n btn.appendChild(labelSpan);\n btn.dataset.type = option.type;\n btn.setAttribute(\"aria-pressed\", \"false\");\n\n btn.addEventListener(\"click\", () => {\n this.selectType(option.type, typeRow);\n });\n\n btn.addEventListener(\"mouseenter\", () => {\n if (btn.dataset.type !== this.selectedType) {\n const bgColor = getTypeBgColor(btn.dataset.type ?? \"\", this.colors);\n btn.style.background = bgColor;\n btn.style.borderColor = getTypeColor(btn.dataset.type ?? \"\", this.colors) + \"40\";\n }\n });\n\n btn.addEventListener(\"mouseleave\", () => {\n if (btn.dataset.type !== this.selectedType) {\n btn.style.background = this.colors.glassBg;\n btn.style.borderColor = this.colors.border;\n }\n });\n\n typeRow.appendChild(btn);\n }\n\n // Textarea\n this.textarea = document.createElement(\"textarea\");\n this.textarea.style.cssText = `\n width:100%;min-height:72px;max-height:152px;\n padding:10px 12px;border-radius:12px;\n border:1px solid ${this.colors.border};\n background:${this.colors.glassBgHeavy};\n color:${this.colors.text};font-family:\"Inter\",system-ui,-apple-system,sans-serif;\n font-size:13px;line-height:1.5;resize:vertical;\n outline:none;transition:all 0.2s ease;\n box-sizing:border-box;\n `;\n this.textarea.placeholder = this.t(\"popup.placeholder\");\n this.textarea.maxLength = 5000;\n this.textarea.setAttribute(\"aria-label\", this.t(\"popup.textareaAria\"));\n\n // Keyboard shortcut hint\n const hint = el(\"div\", {\n style: `\n font-size:11px;color:${this.colors.textTertiary};\n text-align:right;margin-top:4px;\n font-family:\"Inter\",system-ui,-apple-system,sans-serif;\n letter-spacing:0.01em;\n `,\n });\n // navigator.userAgentData is preferred; navigator.platform is deprecated\n // but still needed as fallback. If both are unavailable, fall back to user agent string parsing.\n const uaData = (navigator as Navigator & { userAgentData?: { platform?: string } }).userAgentData;\n const isMac = uaData\n ? uaData.platform === \"macOS\"\n : (navigator.platform?.includes(\"Mac\") ?? /Macintosh|Mac OS X/i.test(navigator.userAgent));\n setText(hint, isMac ? this.t(\"popup.submitHintMac\") : this.t(\"popup.submitHintOther\"));\n\n this.textarea.addEventListener(\"focus\", () => {\n this.textarea.style.borderColor = this.colors.accent;\n this.textarea.style.boxShadow = `0 0 0 3px ${this.colors.accent}14`;\n this.textarea.style.background = this.colors.bg;\n });\n this.textarea.addEventListener(\"blur\", () => {\n this.textarea.style.borderColor = this.colors.border;\n this.textarea.style.boxShadow = \"none\";\n this.textarea.style.background = this.colors.glassBgHeavy;\n });\n this.textarea.addEventListener(\"input\", () => {\n this.updateSubmitState();\n });\n this.textarea.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\" && (e.ctrlKey || e.metaKey)) {\n e.preventDefault();\n this.submit();\n }\n if (e.key === \"Escape\") {\n this.cancel();\n }\n });\n\n // Button row\n const btnRow = el(\"div\", { style: \"display:flex;justify-content:flex-end;gap:8px;margin-top:12px;\" });\n\n const cancelBtn = document.createElement(\"button\");\n cancelBtn.style.cssText = `\n height:34px;padding:0 16px;border-radius:9999px;\n border:1px solid ${this.colors.border};\n background:${this.colors.glassBg};\n color:${this.colors.textTertiary};font-family:\"Inter\",system-ui,-apple-system,sans-serif;\n font-size:13px;font-weight:500;cursor:pointer;\n transition:all 0.2s ease;\n `;\n setText(cancelBtn, this.t(\"popup.cancel\"));\n cancelBtn.addEventListener(\"click\", () => this.cancel());\n cancelBtn.addEventListener(\"mouseenter\", () => {\n cancelBtn.style.borderColor = this.colors.accent;\n cancelBtn.style.color = this.colors.accent;\n });\n cancelBtn.addEventListener(\"mouseleave\", () => {\n cancelBtn.style.borderColor = this.colors.border;\n cancelBtn.style.color = this.colors.textTertiary;\n });\n\n this.submitBtn = document.createElement(\"button\");\n this.submitBtn.style.cssText = `\n height:34px;padding:0 18px;border-radius:9999px;\n border:none;background:${this.colors.accentGradient};\n color:#fff;font-family:\"Inter\",system-ui,-apple-system,sans-serif;\n font-size:13px;font-weight:600;cursor:pointer;\n opacity:0.35;pointer-events:none;\n transition:all 0.2s ease;\n box-shadow:0 2px 8px ${this.colors.accentGlow};\n `;\n setText(this.submitBtn, this.t(\"popup.submit\"));\n this.submitBtn.addEventListener(\"click\", () => this.submit());\n\n btnRow.appendChild(cancelBtn);\n btnRow.appendChild(this.submitBtn);\n\n this.root.appendChild(typeRow);\n this.root.appendChild(this.textarea);\n this.root.appendChild(hint);\n this.root.appendChild(btnRow);\n document.body.appendChild(this.root);\n }\n\n /**\n * Show the popup near a drawn rectangle and return the user's input.\n * Returns null if cancelled.\n */\n show(rectBounds: DOMRect): Promise<PopupResult | null> {\n return new Promise((resolve) => {\n this.resolve = resolve;\n this.selectedType = null;\n this.textarea.value = \"\";\n this.updateSubmitState();\n this.resetTypeButtons();\n\n // Save focus to restore on close\n this.previouslyFocused = document.activeElement as HTMLElement | null;\n\n // Position: bottom-left of rect, 8px below\n const popupH = 220;\n const popupW = 300;\n let top = rectBounds.bottom + 8;\n let left = rectBounds.left;\n\n // Vertical: prefer below; fall back to above; otherwise clamp inside viewport\n if (top + popupH > window.innerHeight) {\n const aboveTop = rectBounds.top - popupH - 8;\n if (aboveTop >= 8) {\n top = aboveTop;\n } else {\n // Rect is taller than the viewport allows on either side —\n // clamp to keep the popup fully visible.\n top = window.innerHeight - popupH - 8;\n }\n }\n // Collision: flip right if not enough space on left\n if (left + popupW > window.innerWidth) {\n left = rectBounds.right - popupW;\n }\n left = Math.max(8, left);\n top = Math.max(8, top);\n\n this.root.style.top = `${top}px`;\n this.root.style.left = `${left}px`;\n this.root.style.display = \"block\";\n\n // Install focus trap\n this.onKeydownTrap = (e: KeyboardEvent) => {\n if (e.key === \"Tab\") {\n const focusableEls = Array.from(\n this.root.querySelectorAll<HTMLElement>(\n 'button:not([disabled]), textarea, input, [tabindex]:not([tabindex=\"-1\"])',\n ),\n );\n if (focusableEls.length === 0) return;\n const first = focusableEls[0];\n const last = focusableEls[focusableEls.length - 1];\n if (!first || !last) return;\n if (e.shiftKey) {\n if (document.activeElement === first || !this.root.contains(document.activeElement)) {\n e.preventDefault();\n last.focus();\n }\n } else {\n if (document.activeElement === last || !this.root.contains(document.activeElement)) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n };\n this.root.addEventListener(\"keydown\", this.onKeydownTrap);\n\n // Check prefers-reduced-motion live (not cached at construction time)\n const reduceMotion =\n typeof window !== \"undefined\" && window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n this.root.style.transition = reduceMotion ? \"none\" : \"\";\n\n // Trigger animation\n requestAnimationFrame(() => {\n this.root.style.opacity = \"1\";\n this.root.style.transform = \"translateY(0) scale(1)\";\n this.textarea.focus();\n });\n });\n }\n\n private selectType(type: FeedbackType, container: HTMLElement): void {\n this.selectedType = type;\n const buttons = container.querySelectorAll<HTMLButtonElement>(\"button\");\n for (const btn of buttons) {\n const isActive = btn.dataset.type === type;\n const color = getTypeColor(btn.dataset.type ?? \"\", this.colors);\n const bgColor = getTypeBgColor(btn.dataset.type ?? \"\", this.colors);\n btn.style.background = isActive ? bgColor : this.colors.glassBg;\n btn.style.borderColor = isActive ? color + \"60\" : this.colors.border;\n btn.style.color = isActive ? color : this.colors.textTertiary;\n btn.style.fontWeight = isActive ? \"600\" : \"500\";\n btn.setAttribute(\"aria-pressed\", String(isActive));\n }\n this.updateSubmitState();\n }\n\n private resetTypeButtons(): void {\n const buttons = this.root.querySelectorAll<HTMLButtonElement>(\"button[data-type]\");\n for (const btn of buttons) {\n btn.setAttribute(\"aria-pressed\", \"false\");\n btn.style.background = this.colors.glassBg;\n btn.style.borderColor = this.colors.border;\n btn.style.color = this.colors.textTertiary;\n btn.style.fontWeight = \"500\";\n }\n }\n\n private updateSubmitState(): void {\n const enabled = this.selectedType !== null && this.textarea.value.trim().length > 0;\n this.submitBtn.disabled = !enabled;\n this.submitBtn.style.opacity = enabled ? \"1\" : \"0.35\";\n this.submitBtn.style.pointerEvents = enabled ? \"auto\" : \"none\";\n }\n\n private submit(): void {\n if (!this.selectedType || !this.textarea.value.trim()) return;\n this.resolve?.({ type: this.selectedType, message: this.textarea.value.trim() });\n this.resolve = null;\n this.hideElement();\n }\n\n private cancel(): void {\n this.resolve?.(null);\n this.resolve = null;\n this.hideElement();\n }\n\n private hideElement(): void {\n // Remove focus trap\n if (this.onKeydownTrap) {\n this.root.removeEventListener(\"keydown\", this.onKeydownTrap);\n this.onKeydownTrap = null;\n }\n this.root.style.opacity = \"0\";\n this.root.style.transform = \"translateY(8px) scale(0.98)\";\n // Restore focus to the previously focused element\n this.previouslyFocused?.focus();\n this.previouslyFocused = null;\n setTimeout(() => {\n this.root.style.display = \"none\";\n }, 250);\n }\n\n destroy(): void {\n this.root.remove();\n }\n}\n","/**\n * Screenshot capture via html2canvas.\n *\n * `html2canvas` is a regular `dependency` of `@siteping/widget` — every\n * install gets it. We dynamic-import it so bundlers emit a separate chunk\n * loaded only when `enableScreenshot: true` triggers the first capture;\n * hosts that never enable screenshots pay only the disk-space cost.\n *\n * On capture failure (content-tainted canvas, version mismatch, missing 2D\n * context) we return `null` rather than throwing — the feedback is still\n * submitted, just without an image.\n */\n\ntype Html2CanvasFn = (element: HTMLElement, options?: Html2CanvasOptions) => Promise<HTMLCanvasElement>;\n\ninterface Html2CanvasOptions {\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n scale?: number;\n useCORS?: boolean;\n allowTaint?: boolean;\n logging?: boolean;\n ignoreElements?: (element: Element) => boolean;\n}\n\nlet cachedHtml2Canvas: Html2CanvasFn | null | undefined; // undefined = not loaded yet, null = failed\nlet warnedAboutMissingDep = false;\n\nasync function loadHtml2Canvas(): Promise<Html2CanvasFn | null> {\n if (cachedHtml2Canvas !== undefined) return cachedHtml2Canvas;\n try {\n // Static dynamic import — bundlers (Vite, webpack, esbuild) resolve this\n // at build time and emit a separate chunk loaded only on first capture.\n // html2canvas ships as a regular dependency so this resolves on every\n // install. Earlier attempts to dodge static resolution via magic comments\n // silently broke production: bare specifiers can't be resolved at runtime\n // in browsers without import maps.\n const mod = (await import(\"html2canvas\")) as { default?: Html2CanvasFn } & Html2CanvasFn;\n cachedHtml2Canvas = (mod.default ?? mod) as Html2CanvasFn;\n return cachedHtml2Canvas;\n } catch (err) {\n cachedHtml2Canvas = null;\n if (!warnedAboutMissingDep) {\n warnedAboutMissingDep = true;\n console.warn(\n \"[siteping] html2canvas import failed unexpectedly. Capture is disabled for this session — feedbacks are still submitted, just without screenshots. Underlying error:\",\n err,\n );\n }\n return null;\n }\n}\n\nexport interface CaptureOptions {\n /** JPEG quality 0..1 (default 0.85). */\n quality?: number;\n /** Max output width in CSS pixels (default 1200). Wider canvases are downscaled. */\n maxWidth?: number;\n}\n\n/**\n * Capture the page region within `rect` as a JPEG data URL. Returns `null`\n * on any failure — callers should not abort feedback submission.\n *\n * - Excludes Siteping's own overlay elements via `ignoreElements`\n * - Honors devicePixelRatio for crisp captures, then downscales to `maxWidth`\n * - JPEG at `quality` (0.85 = ~50–150 KB for a typical annotated area)\n */\nexport async function captureScreenshot(rect: DOMRect, options?: CaptureOptions): Promise<string | null> {\n const html2canvas = await loadHtml2Canvas();\n if (!html2canvas) return null;\n\n const quality = options?.quality ?? 0.85;\n const maxWidth = options?.maxWidth ?? 1200;\n\n try {\n const canvas = await html2canvas(document.body, {\n x: window.scrollX + rect.x,\n y: window.scrollY + rect.y,\n width: rect.width,\n height: rect.height,\n scale: window.devicePixelRatio,\n useCORS: true,\n allowTaint: true,\n logging: false,\n ignoreElements: (element: Element) => {\n return (\n element.tagName === \"SITEPING-WIDGET\" ||\n element.closest?.(\"siteping-widget\") !== null ||\n element.getAttribute?.(\"data-siteping-ignore\") === \"true\"\n );\n },\n });\n\n if (canvas.width <= maxWidth) {\n return canvas.toDataURL(\"image/jpeg\", quality);\n }\n\n // Downscale via an off-DOM canvas — keeps payload reasonable on\n // hi-DPI displays where the raw capture can be 2x–3x intended size.\n const ratio = maxWidth / canvas.width;\n const targetW = maxWidth;\n const targetH = Math.round(canvas.height * ratio);\n\n const scaled = document.createElement(\"canvas\");\n scaled.width = targetW;\n scaled.height = targetH;\n const ctx = scaled.getContext(\"2d\");\n if (!ctx) return null;\n ctx.drawImage(canvas, 0, 0, targetW, targetH);\n return scaled.toDataURL(\"image/jpeg\", quality);\n } catch (err) {\n console.warn(\"[siteping] Screenshot capture failed:\", err);\n return null;\n }\n}\n\n/** @internal — exposed for tests. Resets the dynamic-import cache. */\nexport function _resetScreenshotCacheForTests(): void {\n cachedHtml2Canvas = undefined;\n warnedAboutMissingDep = false;\n}\n","import type { AnnotationPayload, FeedbackType } from \"@siteping/core\";\nimport { Z_INDEX_MAX } from \"./constants.js\";\nimport { findAnchorElement, generateAnchor, rectToPercentages } from \"./dom/anchor.js\";\nimport { el, setText } from \"./dom-utils.js\";\nimport type { EventBus, WidgetEvents } from \"./events.js\";\nimport type { TFunction } from \"./i18n/index.js\";\nimport { Popup } from \"./popup.js\";\nimport { captureScreenshot } from \"./screenshot.js\";\nimport type { ThemeColors } from \"./styles/theme.js\";\n\nexport interface AnnotationComplete {\n annotation: AnnotationPayload;\n type: FeedbackType;\n message: string;\n /**\n * Base64 JPEG `data:` URL captured by html2canvas, or null when capture\n * is disabled / failed / the peer dep is missing.\n */\n screenshotDataUrl?: string | null | undefined;\n}\n\n/**\n * Annotation mode: full-page overlay with rectangle drawing.\n *\n * Glassmorphism design:\n * - Frosted glass toolbar at top\n * - Subtle tinted overlay\n * - Accent-colored drawing rectangle with glow\n */\nexport class Annotator {\n private overlay: HTMLElement | null = null;\n private toolbar: HTMLElement | null = null;\n private drawingRect: HTMLElement | null = null;\n private startX = 0;\n private startY = 0;\n private isDrawing = false;\n private isActive = false;\n private popup: Popup;\n private savedOverflow = \"\";\n private preActiveFocusElement: Element | null = null;\n private rafId: number | null = null;\n private pendingMoveEvent: MouseEvent | Touch | null = null;\n\n constructor(\n private readonly colors: ThemeColors,\n private readonly bus: EventBus<WidgetEvents>,\n private readonly t: TFunction,\n private readonly enableScreenshot: boolean = false,\n ) {\n this.popup = new Popup(colors, t);\n\n this.bus.on(\"annotation:start\", () => this.activate());\n }\n\n /**\n * Capture a screenshot of the drawn rect when `enableScreenshot` is on.\n * Returns null on disable / capture failure / missing peer dep — the\n * feedback is always submitted regardless.\n */\n private async maybeCapture(rect: DOMRect): Promise<string | null> {\n if (!this.enableScreenshot) return null;\n return captureScreenshot(rect);\n }\n\n private activate(): void {\n if (this.isActive) return;\n this.isActive = true;\n\n // Capture the focused element before activation for keyboard annotation\n this.preActiveFocusElement = document.activeElement;\n\n // Lock page scroll\n this.savedOverflow = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n\n // Overlay — subtle blue tint for depth\n this.overlay = el(\"div\", {\n style: `\n position:fixed;inset:0;\n z-index:${Z_INDEX_MAX - 1};\n background:rgba(15, 23, 42, 0.04);\n cursor:crosshair;\n `,\n });\n this.overlay.setAttribute(\"aria-hidden\", \"true\");\n\n // Toolbar — glassmorphism bar\n this.toolbar = el(\"div\", {\n style: `\n position:fixed;top:0;left:0;right:0;\n z-index:${Z_INDEX_MAX};\n height:52px;\n background:${this.colors.glassBg};\n backdrop-filter:blur(24px);\n -webkit-backdrop-filter:blur(24px);\n border-bottom:1px solid ${this.colors.glassBorder};\n display:flex;align-items:center;justify-content:center;gap:16px;\n font-family:\"Inter\",system-ui,-apple-system,sans-serif;\n font-size:14px;color:${this.colors.text};\n box-shadow:0 4px 16px ${this.colors.shadow};\n -webkit-font-smoothing:antialiased;\n `,\n });\n\n const dot = el(\"span\", {\n style: `\n width:8px;height:8px;border-radius:50%;\n background:${this.colors.accent};\n box-shadow:0 0 8px ${this.colors.accentGlow};\n animation:pulse 1.5s ease-in-out infinite;\n `,\n });\n\n // Add pulse animation inline (respects prefers-reduced-motion)\n const style = document.createElement(\"style\");\n style.textContent = [\n \"@keyframes pulse{0%,100%{opacity:1}50%{opacity:0.4}}\",\n \"@media(prefers-reduced-motion:reduce){@keyframes pulse{from,to{opacity:1}}}\",\n ].join(\"\");\n this.toolbar.appendChild(style);\n\n const instruction = el(\"span\", { style: \"font-weight:500;letter-spacing:-0.01em;\" });\n setText(instruction, this.t(\"annotator.instruction\"));\n\n const cancelBtn = document.createElement(\"button\");\n cancelBtn.style.cssText = `\n height:34px;padding:0 18px;border-radius:9999px;\n border:1px solid ${this.colors.border};\n background:${this.colors.glassBg};\n color:${this.colors.textTertiary};font-family:\"Inter\",system-ui,-apple-system,sans-serif;\n font-size:13px;font-weight:500;cursor:pointer;\n transition:all 0.2s ease;\n `;\n setText(cancelBtn, this.t(\"annotator.cancel\"));\n cancelBtn.addEventListener(\"click\", () => this.deactivate());\n cancelBtn.addEventListener(\"mouseenter\", () => {\n cancelBtn.style.borderColor = this.colors.typeBug;\n cancelBtn.style.color = this.colors.typeBug;\n cancelBtn.style.background = this.colors.typeBugBg;\n });\n cancelBtn.addEventListener(\"mouseleave\", () => {\n cancelBtn.style.borderColor = this.colors.border;\n cancelBtn.style.color = this.colors.textTertiary;\n cancelBtn.style.background = this.colors.glassBg;\n });\n\n this.toolbar.appendChild(dot);\n this.toolbar.appendChild(instruction);\n this.toolbar.appendChild(cancelBtn);\n\n // Mouse events\n this.overlay.addEventListener(\"mousedown\", this.onMouseDown);\n this.overlay.addEventListener(\"mousemove\", this.onMouseMove);\n this.overlay.addEventListener(\"mouseup\", this.onMouseUp);\n\n // Touch events (Surface Pro, iPad, etc.)\n this.overlay.addEventListener(\"touchstart\", this.onTouchStart, { passive: false });\n this.overlay.addEventListener(\"touchmove\", this.onTouchMove, { passive: false });\n this.overlay.addEventListener(\"touchend\", this.onTouchEnd);\n\n // Keyboard annotation: Enter selects the pre-activation focused element\n this.overlay.addEventListener(\"keydown\", this.onOverlayKeyDown);\n\n // Allow tab-through so keyboard users can reach underlying elements\n this.overlay.setAttribute(\"tabindex\", \"0\");\n\n // Escape to cancel\n document.addEventListener(\"keydown\", this.onKeyDown);\n\n document.body.appendChild(this.overlay);\n document.body.appendChild(this.toolbar);\n }\n\n private deactivate(): void {\n if (!this.isActive) return;\n this.isActive = false;\n this.isDrawing = false;\n this.preActiveFocusElement = null;\n\n // Cancel any pending rAF to prevent stale callbacks\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n this.pendingMoveEvent = null;\n\n document.body.style.overflow = this.savedOverflow;\n document.removeEventListener(\"keydown\", this.onKeyDown);\n\n this.overlay?.remove();\n this.toolbar?.remove();\n this.drawingRect?.remove();\n this.overlay = null;\n this.toolbar = null;\n this.drawingRect = null;\n\n this.bus.emit(\"annotation:end\");\n }\n\n private onKeyDown = (e: KeyboardEvent): void => {\n if (e.key === \"Escape\") this.deactivate();\n };\n\n /**\n * Keyboard annotation: pressing Enter while the overlay is active selects\n * the element that was focused before activation and creates a full-bounds\n * annotation covering that element (WCAG 2.1.1 Level A).\n */\n private onOverlayKeyDown = async (e: KeyboardEvent): Promise<void> => {\n if (e.key !== \"Enter\") return;\n e.preventDefault();\n\n const target = this.preActiveFocusElement;\n if (!target || !(target instanceof HTMLElement)) return;\n\n const bounds = target.getBoundingClientRect();\n if (bounds.width <= 0 || bounds.height <= 0) return;\n\n const rectBounds = new DOMRect(bounds.x, bounds.y, bounds.width, bounds.height);\n\n const result = await this.popup.show(rectBounds);\n if (!result) return;\n\n const anchor = generateAnchor(target);\n const annotation: AnnotationPayload = {\n anchor,\n rect: { xPct: 0, yPct: 0, wPct: 1, hPct: 1 },\n scrollX: window.scrollX,\n scrollY: window.scrollY,\n viewportW: window.innerWidth,\n viewportH: window.innerHeight,\n devicePixelRatio: window.devicePixelRatio,\n };\n\n // Capture before deactivate — overlay is intentionally ignored by the\n // capture predicate but the rect must still be on the page.\n const screenshotDataUrl = await this.maybeCapture(rectBounds);\n\n this.deactivate();\n\n this.bus.emit(\"annotation:complete\", {\n annotation,\n type: result.type,\n message: result.message,\n screenshotDataUrl,\n });\n };\n\n private onMouseDown = (e: MouseEvent): void => {\n this.startDrawing(e.clientX, e.clientY);\n };\n\n private onTouchStart = (e: TouchEvent): void => {\n e.preventDefault();\n const touch = e.touches[0];\n if (touch) this.startDrawing(touch.clientX, touch.clientY);\n };\n\n private startDrawing(clientX: number, clientY: number): void {\n this.isDrawing = true;\n this.startX = clientX;\n this.startY = clientY;\n\n this.drawingRect?.remove();\n this.drawingRect = el(\"div\", {\n style: `\n position:fixed;\n border:2px solid ${this.colors.accent};\n background:${this.colors.accent}12;\n pointer-events:none;\n border-radius:8px;\n box-shadow:0 0 16px ${this.colors.accentGlow};\n transition:box-shadow 0.15s ease;\n `,\n });\n this.overlay?.appendChild(this.drawingRect);\n }\n\n private onMouseMove = (e: MouseEvent): void => {\n this.scheduleRectUpdate(e);\n };\n\n private onTouchMove = (e: TouchEvent): void => {\n e.preventDefault();\n if (e.touches[0]) this.scheduleRectUpdate(e.touches[0]);\n };\n\n private scheduleRectUpdate(source: MouseEvent | Touch): void {\n if (!this.isDrawing || !this.drawingRect) return;\n\n this.pendingMoveEvent = source;\n if (this.rafId !== null) return;\n\n this.rafId = requestAnimationFrame(() => {\n this.rafId = null;\n const evt = this.pendingMoveEvent;\n if (!evt || !this.drawingRect) return;\n\n const x = Math.min(evt.clientX, this.startX);\n const y = Math.min(evt.clientY, this.startY);\n const w = Math.abs(evt.clientX - this.startX);\n const h = Math.abs(evt.clientY - this.startY);\n\n this.drawingRect.style.left = `${x}px`;\n this.drawingRect.style.top = `${y}px`;\n this.drawingRect.style.width = `${w}px`;\n this.drawingRect.style.height = `${h}px`;\n });\n }\n\n private onTouchEnd = async (e: TouchEvent): Promise<void> => {\n const touch = e.changedTouches[0];\n if (touch) await this.finishDrawing(touch.clientX, touch.clientY);\n };\n\n private onMouseUp = async (e: MouseEvent): Promise<void> => {\n await this.finishDrawing(e.clientX, e.clientY);\n };\n\n private finishDrawing = async (clientX: number, clientY: number): Promise<void> => {\n if (!this.isDrawing || !this.drawingRect) return;\n this.isDrawing = false;\n\n const x = Math.min(clientX, this.startX);\n const y = Math.min(clientY, this.startY);\n const w = Math.abs(clientX - this.startX);\n const h = Math.abs(clientY - this.startY);\n\n // Ignore tiny rectangles (accidental clicks)\n if (w < 10 || h < 10) {\n this.drawingRect.remove();\n this.drawingRect = null;\n return;\n }\n\n const rectBounds = new DOMRect(x, y, w, h);\n\n // Show popup for type + message\n const result = await this.popup.show(rectBounds);\n\n if (!result) {\n this.drawingRect?.remove();\n this.drawingRect = null;\n return;\n }\n\n // Build annotation payload BEFORE deactivating (needs overlay for elementFromPoint)\n const annotation = this.buildAnnotation(rectBounds);\n this.drawingRect?.remove();\n this.drawingRect = null;\n\n // Capture before deactivate — html2canvas walks the live DOM, and the\n // capture predicate skips siteping-widget elements so the overlay being\n // present on screen doesn't matter.\n const screenshotDataUrl = await this.maybeCapture(rectBounds);\n\n this.deactivate();\n\n // Emit via event bus (not DOM — overlay is already null after deactivate)\n this.bus.emit(\"annotation:complete\", {\n annotation,\n type: result.type,\n message: result.message,\n screenshotDataUrl,\n });\n };\n\n /**\n * Build an AnnotationPayload from a drawn rectangle.\n * Temporarily hides the overlay to access the real DOM underneath.\n */\n private buildAnnotation(rectBounds: DOMRect): AnnotationPayload {\n // Temporarily hide overlay to find the real element underneath\n if (this.overlay) this.overlay.style.pointerEvents = \"none\";\n const anchorElement = findAnchorElement(rectBounds);\n if (this.overlay) this.overlay.style.pointerEvents = \"auto\";\n\n const anchor = generateAnchor(anchorElement);\n const anchorBounds = anchorElement.getBoundingClientRect();\n const rect = rectToPercentages(rectBounds, anchorBounds);\n\n return {\n anchor,\n rect,\n scrollX: window.scrollX,\n scrollY: window.scrollY,\n viewportW: window.innerWidth,\n viewportH: window.innerHeight,\n devicePixelRatio: window.devicePixelRatio,\n };\n }\n destroy(): void {\n this.deactivate();\n this.popup.destroy();\n }\n}\n","/**\n * Typed error hierarchy for Siteping client/server boundaries.\n *\n * Consumers can `instanceof`-check or read `code` / `retryable` instead of\n * pattern-matching error messages. Designed to be additive on top of the\n * existing store errors (`StoreNotFoundError`, `StoreDuplicateError`) which\n * remain the canonical signals for server-side store implementations.\n *\n * Usage on the widget side (api-client.ts):\n * - fetch failures / aborts / timeouts → `SitepingNetworkError` (retryable)\n * - HTTP 4xx (except 401/403) → `SitepingValidationError` (not retryable)\n * - HTTP 401 / 403 → `SitepingAuthError` (not retryable)\n * - everything else → `SitepingError` generic\n *\n * `retryable` is meta information surfaced to host apps that want to wire\n * their own retry/queue/backoff strategy — the widget already retries\n * network failures via its built-in retry queue.\n */\n\nexport class SitepingError extends Error {\n readonly code: string;\n readonly retryable: boolean;\n\n constructor(message: string, code: string, retryable: boolean) {\n super(message);\n this.code = code;\n this.retryable = retryable;\n this.name = \"SitepingError\";\n }\n}\n\n/** Network-level failure: connection refused, DNS, CORS, timeout, abort. Retryable. */\nexport class SitepingNetworkError extends SitepingError {\n constructor(message: string) {\n super(message, \"NETWORK\", true);\n this.name = \"SitepingNetworkError\";\n }\n}\n\n/** Server rejected the request (4xx, not auth). Validation problem on the client side. */\nexport class SitepingValidationError extends SitepingError {\n constructor(message: string) {\n super(message, \"VALIDATION\", false);\n this.name = \"SitepingValidationError\";\n }\n}\n\n/** Server rejected auth (401 or 403). Not retryable without fresh credentials. */\nexport class SitepingAuthError extends SitepingError {\n constructor(message: string) {\n super(message, \"AUTH\", false);\n this.name = \"SitepingAuthError\";\n }\n}\n","// ---------------------------------------------------------------------------\n// Config\n// ---------------------------------------------------------------------------\n\n/** Configuration options for the Siteping widget. */\nexport interface SitepingConfig {\n /** HTTP endpoint that receives feedbacks (e.g. '/api/siteping'). Required unless `store` is provided. */\n endpoint?: string | undefined;\n /** Required — project identifier used to scope feedbacks */\n projectName: string;\n /** Direct store for client-side mode. When set, bypasses HTTP and uses the store directly in the browser. */\n store?: SitepingStore | undefined;\n /** FAB position — defaults to 'bottom-right' */\n position?: \"bottom-right\" | \"bottom-left\";\n /** Accent color for the widget UI — defaults to '#0066ff' */\n accentColor?: string;\n /** Show the widget even in production — defaults to false */\n forceShow?: boolean;\n /** Enable debug logging of lifecycle events — defaults to false */\n debug?: boolean;\n /** Color theme — defaults to 'light' */\n theme?: \"light\" | \"dark\" | \"auto\";\n /** UI locale — defaults to 'en'. Built-in: en, fr, de, es, it, pt (Brazilian), ru. Any other string falls back to English. */\n locale?: \"en\" | \"fr\" | \"de\" | \"es\" | \"it\" | \"pt\" | \"ru\" | (string & {}) | undefined;\n /**\n * Returns the current page scope for annotations and panel filtering.\n * Called on initial markers load and on `instance.refresh()`.\n *\n * Default: `{ url: window.location.pathname, urlPattern: null }` — annotations\n * are scoped strictly to the current pathname.\n *\n * Apps with parameterized routes (e.g. React Router) should return both the\n * concrete URL and the route template (e.g. `/orders/:orderId`) so the panel\n * can offer a \"this type of page\" filter that groups feedbacks by template.\n */\n getPageScope?: (() => PageScope) | undefined;\n /**\n * When true (default), the widget filters initial markers and panel results\n * by `feedback.url === scope.url`, so annotations created on one page never\n * leak to other pages — even if their CSS selector accidentally matches.\n * Set to `false` to revert to the legacy project-wide behavior.\n */\n scopeAnnotationsByUrl?: boolean | undefined;\n /**\n * Capture a JPEG screenshot of the annotated area on submit. Defaults to\n * `false` — opt-in because:\n *\n * - it adds runtime weight (~40 KB gzip dynamic chunk for html2canvas,\n * loaded only on first capture),\n * - it embeds page content in the feedback (privacy/GDPR consideration —\n * inform end users in your widget host UI when enabling).\n *\n * `html2canvas` ships as a regular dependency of `@siteping/widget` so the\n * dynamic import always resolves; you don't need to install anything extra.\n *\n * **Masking sensitive elements:** add `data-siteping-ignore=\"true\"` to any\n * element you do NOT want captured (password fields, credit-card forms,\n * API tokens shown in the UI, etc.). The capture predicate skips matching\n * elements *and their descendants*. Do this BEFORE turning on screenshots\n * in production — once a feedback is saved, the screenshot is in your DB\n * (or object storage) regardless of what was on the page.\n */\n enableScreenshot?: boolean | undefined;\n /**\n * Capture the last few `console.*` calls and failed network requests\n * (HTTP >= 400 or network error) at the moment a feedback is submitted.\n *\n * Lets reviewers replay the technical context that led to the report —\n * stack traces, 500 responses, dead third-party scripts. Great for the\n * \"the page just doesn't work\" feedback that contains zero detail.\n *\n * - `true` — capture with defaults (50 console / 20 network entries).\n * - `false` (default) — no capture, no monkey-patching.\n * - object — per-channel toggles + custom buffer sizes.\n *\n * **Privacy considerations:** console messages may contain anything the\n * host page logs, including user data. Failed network requests record the\n * URL (with query string) but never the response body. Inform end users\n * before enabling in environments where they might log sensitive values.\n */\n captureDiagnostics?:\n | boolean\n | {\n console?: boolean;\n network?: boolean;\n maxConsoleEntries?: number;\n maxNetworkEntries?: number;\n }\n | undefined;\n /** Called when the widget is skipped (production mode, mobile viewport) */\n onSkip?: (reason: \"production\" | \"mobile\") => void;\n\n // Events\n /** Called when the feedback panel is opened. */\n onOpen?: () => void;\n /** Called when the feedback panel is closed. */\n onClose?: () => void;\n onFeedbackSent?: (feedback: FeedbackResponse) => void;\n /**\n * Called when a feedback API call fails.\n *\n * The widget always emits a `SitepingError` (or a subclass:\n * `SitepingNetworkError`, `SitepingValidationError`, `SitepingAuthError`)\n * for HTTP-mode failures — host apps can `instanceof` to drive retry\n * logic, or read `error.code` (`\"NETWORK\" | \"VALIDATION\" | \"AUTH\" |\n * \"SERVER\"`) and `error.retryable`. The type is widened to `Error` so\n * direct-store callers can still surface raw errors without breaking the\n * contract.\n */\n onError?: (error: Error) => void;\n /** Called when the user starts drawing an annotation. */\n onAnnotationStart?: () => void;\n /** Called when the user finishes drawing an annotation. */\n onAnnotationEnd?: () => void;\n}\n\n/** Instance returned by initSiteping() with lifecycle methods. */\nexport interface SitepingInstance {\n /** Remove the widget from the DOM and clean up all listeners. */\n destroy: () => void;\n /** Open the panel programmatically */\n open: () => void;\n /** Close the panel */\n close: () => void;\n /** Reload feedbacks from server */\n refresh: () => void;\n /** Subscribe to a public widget event */\n on: <K extends keyof SitepingPublicEvents>(\n event: K,\n listener: (...args: SitepingPublicEvents[K]) => void,\n ) => () => void;\n /** Unsubscribe from a public widget event */\n off: <K extends keyof SitepingPublicEvents>(event: K, listener: (...args: SitepingPublicEvents[K]) => void) => void;\n}\n\n/** Events exposed to consumers via SitepingInstance.on / .off */\nexport interface SitepingPublicEvents {\n \"feedback:sent\": [FeedbackResponse];\n \"feedback:deleted\": [string];\n \"panel:open\": [];\n \"panel:close\": [];\n}\n\n// ---------------------------------------------------------------------------\n// Feedback\n// ---------------------------------------------------------------------------\n\n/** Single source of truth for feedback types — used by both TS types and Zod schemas. */\nexport const FEEDBACK_TYPES = [\"question\", \"change\", \"bug\", \"other\"] as const;\nexport type FeedbackType = (typeof FEEDBACK_TYPES)[number];\n\n/** Single source of truth for feedback statuses. */\nexport const FEEDBACK_STATUSES = [\"open\", \"resolved\"] as const;\nexport type FeedbackStatus = (typeof FEEDBACK_STATUSES)[number];\n\n/**\n * Page scope returned by `SitepingConfig.getPageScope()`.\n *\n * - `url`: concrete page identifier — usually `window.location.pathname`,\n * used as the strict scope for marker rendering.\n * - `urlPattern`: optional parameterized template (e.g. `/orders/:orderId`)\n * used by the panel's \"this type of page\" filter to group feedbacks across\n * instances of the same page kind.\n */\nexport interface PageScope {\n url: string;\n urlPattern: string | null;\n}\n\n// ---------------------------------------------------------------------------\n// Abstract Store — adapter pattern\n// ---------------------------------------------------------------------------\n\n/** Input for creating a feedback record in the store. */\nexport interface FeedbackCreateInput {\n projectName: string;\n type: FeedbackType;\n message: string;\n status: FeedbackStatus;\n url: string;\n /**\n * Optional parameterized URL template (e.g. `/orders/:orderId`) for the page\n * where the feedback was created. Allows the panel to filter feedbacks by\n * \"this type of page\" across different instances. Null when the host did not\n * provide a `getPageScope` callback or the route has no template.\n */\n urlPattern?: string | null | undefined;\n viewport: string;\n userAgent: string;\n authorName: string;\n authorEmail: string;\n clientId: string;\n annotations: AnnotationCreateInput[];\n /**\n * Base64 JPEG `data:` URL captured by the widget at submit time.\n *\n * Adapters with a configured `ScreenshotStorage` are expected to upload\n * this and persist the returned URL on `FeedbackRecord.screenshotUrl`.\n * Adapters without storage may persist the data URL inline (memory /\n * localStorage / dev) — the widget then renders it directly.\n */\n screenshotDataUrl?: string | null | undefined;\n /**\n * Optional console + failed-network snapshot captured by the widget when\n * `SitepingConfig.captureDiagnostics` is enabled. Stored as JSON on\n * `FeedbackRecord.diagnostics` so reviewers can replay the context.\n */\n diagnostics?: DiagnosticsSnapshot | null | undefined;\n}\n\n/** Input for a single annotation when creating a feedback. */\nexport interface AnnotationCreateInput {\n cssSelector: string;\n xpath: string;\n textSnippet: string;\n elementTag: string;\n elementId?: string | undefined;\n textPrefix: string;\n textSuffix: string;\n fingerprint: string;\n neighborText: string;\n /**\n * Semantic anchor identifier from the closest ancestor's `data-feedback-anchor`\n * attribute. When set, this is the most stable re-anchoring signal because\n * hosts deliberately place these on layout/section roots that survive DOM\n * refactors and viewport changes. Null when no semantic ancestor exists.\n */\n anchorKey?: string | null | undefined;\n xPct: number;\n yPct: number;\n wPct: number;\n hPct: number;\n scrollX: number;\n scrollY: number;\n viewportW: number;\n viewportH: number;\n devicePixelRatio: number;\n}\n\n/** Query parameters for fetching feedbacks. */\nexport interface FeedbackQuery {\n projectName: string;\n type?: FeedbackType | undefined;\n status?: FeedbackStatus | undefined;\n search?: string | undefined;\n page?: number | undefined;\n limit?: number | undefined;\n /**\n * Filter to feedbacks created on this exact URL (path). Used by the panel's\n * \"this page\" filter and by the markers loader to keep page scopes isolated.\n */\n url?: string | undefined;\n /**\n * Filter to feedbacks created on this URL pattern (e.g. `/orders/:orderId`).\n * Used by the panel's \"this type of page\" filter to group feedbacks across\n * different concrete instances of the same template.\n */\n urlPattern?: string | undefined;\n}\n\n/** Update payload for patching a feedback. */\nexport interface FeedbackUpdateInput {\n status: FeedbackStatus;\n resolvedAt: Date | null;\n}\n\n/** A persisted feedback record returned by the store. */\nexport interface FeedbackRecord {\n id: string;\n type: FeedbackType;\n message: string;\n status: FeedbackStatus;\n projectName: string;\n url: string;\n /**\n * Parameterized URL template the feedback was created on.\n * Null for legacy records or hosts without `getPageScope`.\n */\n urlPattern: string | null;\n authorName: string;\n authorEmail: string;\n viewport: string;\n userAgent: string;\n clientId: string;\n resolvedAt: Date | null;\n createdAt: Date;\n updatedAt: Date;\n annotations: AnnotationRecord[];\n /**\n * URL the widget renders as `<img src>`. Either an `https://...` from a\n * configured `ScreenshotStorage`, or a `data:image/jpeg;base64,...` URL\n * inline-persisted by adapters without storage. Null when no screenshot\n * was captured (legacy records, capture failed, or host disabled it).\n */\n screenshotUrl: string | null;\n /**\n * Console + failed-network snapshot captured at submit time. Null when\n * diagnostics weren't enabled on the widget side.\n */\n diagnostics: DiagnosticsSnapshot | null;\n}\n\n/** A persisted annotation record returned by the store. */\nexport interface AnnotationRecord {\n id: string;\n feedbackId: string;\n cssSelector: string;\n xpath: string;\n textSnippet: string;\n elementTag: string;\n elementId: string | null;\n textPrefix: string;\n textSuffix: string;\n fingerprint: string;\n neighborText: string;\n /**\n * Semantic anchor identifier from `data-feedback-anchor`. Null for legacy\n * annotations or those drawn outside any anchored region.\n */\n anchorKey: string | null;\n xPct: number;\n yPct: number;\n wPct: number;\n hPct: number;\n scrollX: number;\n scrollY: number;\n viewportW: number;\n viewportH: number;\n devicePixelRatio: number;\n createdAt: Date;\n}\n\n// ---------------------------------------------------------------------------\n// Store errors — throw these from adapter implementations\n// ---------------------------------------------------------------------------\n\n/**\n * Thrown when a record is not found during update or delete.\n *\n * Handlers translate this to HTTP 404. Adapters MUST throw this (not\n * ORM-specific errors) so the handler layer remains ORM-agnostic.\n */\nexport class StoreNotFoundError extends Error {\n readonly code = \"STORE_NOT_FOUND\" as const;\n constructor(message = \"Record not found\") {\n super(message);\n this.name = \"StoreNotFoundError\";\n }\n}\n\n/**\n * Thrown when a unique constraint is violated (e.g. duplicate `clientId`).\n *\n * Handlers use this to return the existing record instead of failing.\n */\nexport class StoreDuplicateError extends Error {\n readonly code = \"STORE_DUPLICATE\" as const;\n constructor(message = \"Duplicate record\") {\n super(message);\n this.name = \"StoreDuplicateError\";\n }\n}\n\n/** Type guard — works for `StoreNotFoundError` and ORM-specific equivalents (e.g. Prisma P2025). */\nexport function isStoreNotFound(error: unknown): boolean {\n if (error instanceof StoreNotFoundError) return true;\n // Backwards compat: Prisma's P2025\n return typeof error === \"object\" && error !== null && \"code\" in error && (error as { code: string }).code === \"P2025\";\n}\n\n/** Type guard — works for `StoreDuplicateError` and ORM-specific equivalents (e.g. Prisma P2002). */\nexport function isStoreDuplicate(error: unknown): boolean {\n if (error instanceof StoreDuplicateError) return true;\n // Backwards compat: Prisma's P2002\n return typeof error === \"object\" && error !== null && \"code\" in error && (error as { code: string }).code === \"P2002\";\n}\n\n// ---------------------------------------------------------------------------\n// Store helpers — shared conversion logic for adapters\n// ---------------------------------------------------------------------------\n\n/** Flatten a widget `AnnotationPayload` (nested anchor + rect) into a flat `AnnotationCreateInput`. */\nexport function flattenAnnotation(ann: AnnotationPayload): AnnotationCreateInput {\n return {\n cssSelector: ann.anchor.cssSelector,\n xpath: ann.anchor.xpath,\n textSnippet: ann.anchor.textSnippet,\n elementTag: ann.anchor.elementTag,\n elementId: ann.anchor.elementId,\n textPrefix: ann.anchor.textPrefix,\n textSuffix: ann.anchor.textSuffix,\n fingerprint: ann.anchor.fingerprint,\n neighborText: ann.anchor.neighborText,\n anchorKey: ann.anchor.anchorKey ?? null,\n xPct: ann.rect.xPct,\n yPct: ann.rect.yPct,\n wPct: ann.rect.wPct,\n hPct: ann.rect.hPct,\n scrollX: ann.scrollX,\n scrollY: ann.scrollY,\n viewportW: ann.viewportW,\n viewportH: ann.viewportH,\n devicePixelRatio: ann.devicePixelRatio,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Abstract Store — adapter pattern\n// ---------------------------------------------------------------------------\n\n/**\n * Abstract storage interface for Siteping.\n *\n * Any adapter (Prisma, Drizzle, raw SQL, localStorage, etc.) implements this\n * interface. The HTTP handler and widget `StoreClient` operate against\n * `SitepingStore`, decoupled from the storage backend.\n *\n * ## Error contract\n *\n * - **`updateFeedback` / `deleteFeedback`**: throw `StoreNotFoundError` when\n * the record does not exist.\n * - **`createFeedback`**: either return the existing record on duplicate\n * `clientId` (idempotent) or throw `StoreDuplicateError`. The handler\n * handles both patterns.\n * - Other methods should not throw on empty results — return empty arrays or `null`.\n */\nexport interface SitepingStore {\n /** Create a feedback with its annotations. Idempotent on `clientId` — return existing record on duplicate, or throw `StoreDuplicateError`. */\n createFeedback(data: FeedbackCreateInput): Promise<FeedbackRecord>;\n /** Paginated query with optional filters. Returns empty array (not error) when no results. */\n getFeedbacks(query: FeedbackQuery): Promise<{ feedbacks: FeedbackRecord[]; total: number }>;\n /** Lookup by client-generated UUID. Returns `null` (not error) when not found. */\n findByClientId(clientId: string): Promise<FeedbackRecord | null>;\n /** Update status/resolvedAt. Throws `StoreNotFoundError` if `id` does not exist. */\n updateFeedback(id: string, data: FeedbackUpdateInput): Promise<FeedbackRecord>;\n /** Delete a single record. Throws `StoreNotFoundError` if `id` does not exist. */\n deleteFeedback(id: string): Promise<void>;\n /** Bulk delete all feedbacks for a project. No-op (not error) if none exist. */\n deleteAllFeedbacks(projectName: string): Promise<void>;\n}\n\n/** Payload sent from the widget to the server when submitting feedback. */\nexport interface FeedbackPayload {\n projectName: string;\n type: FeedbackType;\n message: string;\n url: string;\n /**\n * Parameterized URL template (e.g. `/orders/:orderId`) supplied by\n * `SitepingConfig.getPageScope()`. Null when the host did not provide one.\n */\n urlPattern?: string | null | undefined;\n viewport: string;\n userAgent: string;\n authorName: string;\n authorEmail: string;\n annotations: AnnotationPayload[];\n /** Client-generated UUID for deduplication */\n clientId: string;\n /**\n * Base64 JPEG `data:` URL of the annotated area. Captured by the widget\n * when `enableScreenshot: true` is set in `SitepingConfig`. Null when\n * disabled or when capture failed silently.\n */\n screenshotDataUrl?: string | null | undefined;\n /**\n * Snapshot of the last few console messages and failed network requests\n * captured at submit time when `captureDiagnostics` is enabled.\n */\n diagnostics?: DiagnosticsSnapshot | null | undefined;\n}\n\n/** A single console entry captured by `ConsoleBuffer`. */\nexport interface ConsoleDiagnosticEntry {\n level: \"log\" | \"info\" | \"warn\" | \"error\";\n /** ISO 8601 timestamp captured at log time. */\n timestamp: string;\n /** Best-effort string representation of the original console args. */\n message: string;\n}\n\n/** A single failed network request captured by `NetworkBuffer`. */\nexport interface NetworkDiagnosticEntry {\n url: string;\n method: string;\n /** HTTP status; 0 when the request never reached the server. */\n status: number;\n /** End-to-end duration in ms. */\n durationMs: number;\n /** ISO 8601 timestamp at the moment the request was initiated. */\n timestamp: string;\n}\n\n/**\n * Diagnostics captured by the widget when `captureDiagnostics` is enabled.\n *\n * Both arrays are bounded (default: 50 console / 20 network). Adapters that\n * support diagnostics should persist this as a JSON blob alongside the\n * feedback so reviewers can replay the context that led to the report.\n */\nexport interface DiagnosticsSnapshot {\n console: ConsoleDiagnosticEntry[];\n network: NetworkDiagnosticEntry[];\n}\n\n// ---------------------------------------------------------------------------\n// Annotation — multi-selector anchoring (Hypothesis / W3C Web Annotation)\n// ---------------------------------------------------------------------------\n\n/** DOM anchoring data for re-attaching annotations to page elements. */\nexport interface AnchorData {\n /** CSS selector generated by @medv/finder — primary anchor */\n cssSelector: string;\n /** XPath — fallback 1 */\n xpath: string;\n /** First ~120 chars of element innerText — empty string if none */\n textSnippet: string;\n /** Tag name for validation (e.g. \"DIV\", \"SECTION\") */\n elementTag: string;\n /** Element id attribute if available — most stable */\n elementId?: string | undefined;\n /** ~32 chars of text before this element in document flow (disambiguation) */\n textPrefix: string;\n /** ~32 chars of text after this element in document flow (disambiguation) */\n textSuffix: string;\n /** Structural fingerprint: \"childCount:siblingIdx:attrHash\" */\n fingerprint: string;\n /** Text content of adjacent sibling elements (context) */\n neighborText: string;\n /**\n * Semantic anchor identifier from the closest ancestor's `data-feedback-anchor`\n * attribute. When set, this is the highest-priority re-anchoring signal —\n * hosts deliberately place these on layout/section roots that survive\n * viewport changes and DOM refactors.\n */\n anchorKey?: string | null | undefined;\n}\n\n/** Drawn rectangle coordinates as percentages relative to the anchor element. */\nexport interface RectData {\n /** X offset as fraction of anchor element width — must be in range [0, 1] */\n xPct: number;\n /** Y offset as fraction of anchor element height — must be in range [0, 1] */\n yPct: number;\n /** Width as fraction of anchor element width — must be in range [0, 1] */\n wPct: number;\n /** Height as fraction of anchor element height — must be in range [0, 1] */\n hPct: number;\n}\n\n/** Annotation data sent as part of a feedback submission. */\nexport interface AnnotationPayload {\n anchor: AnchorData;\n rect: RectData;\n scrollX: number;\n scrollY: number;\n viewportW: number;\n viewportH: number;\n devicePixelRatio: number;\n}\n\n// ---------------------------------------------------------------------------\n// API responses\n// ---------------------------------------------------------------------------\n\n/** Feedback record as returned by the API (dates serialized as strings). */\nexport interface FeedbackResponse {\n id: string;\n projectName: string;\n type: FeedbackType;\n message: string;\n status: FeedbackStatus;\n url: string;\n /** Parameterized URL template the feedback was created on, or null. */\n urlPattern: string | null;\n viewport: string;\n userAgent: string;\n authorName: string;\n authorEmail: string;\n resolvedAt: string | null;\n createdAt: string;\n updatedAt: string;\n annotations: AnnotationResponse[];\n /** Screenshot URL (data: or http:) — see `FeedbackRecord.screenshotUrl`. */\n screenshotUrl: string | null;\n /** Console + failed-network snapshot, or null when diagnostics weren't captured. */\n diagnostics: DiagnosticsSnapshot | null;\n}\n\n/** Annotation record as returned by the API. */\nexport interface AnnotationResponse {\n id: string;\n feedbackId: string;\n cssSelector: string;\n xpath: string;\n textSnippet: string;\n elementTag: string;\n elementId: string | null;\n textPrefix: string;\n textSuffix: string;\n fingerprint: string;\n neighborText: string;\n /** Semantic anchor identifier from `data-feedback-anchor`, or null. */\n anchorKey: string | null;\n xPct: number;\n yPct: number;\n wPct: number;\n hPct: number;\n scrollX: number;\n scrollY: number;\n viewportW: number;\n viewportH: number;\n devicePixelRatio: number;\n createdAt: string;\n}\n","import {\n type FeedbackPayload,\n type FeedbackResponse,\n type FeedbackStatus,\n type FeedbackType,\n SitepingAuthError,\n SitepingError,\n SitepingNetworkError,\n SitepingValidationError,\n} from \"@siteping/core\";\n\n/**\n * Map a non-OK Response to the appropriate typed error.\n * - 401 / 403 → `SitepingAuthError`\n * - 4xx → `SitepingValidationError`\n * - 5xx (or anything else) → generic `SitepingError`\n *\n * We consume the response body via `.text()` so the caller can keep the\n * server-supplied message in the thrown error. `text()` is awaited inside\n * a try/catch because some upstreams return `Content-Length: 0` with a\n * non-text type and `.text()` rejects.\n */\nasync function errorFromResponse(response: Response, label: string): Promise<SitepingError> {\n // Match the legacy fallback string (\"Unknown error\") so host apps that\n // already grep error messages don't break on the migration.\n const text = await response.text().catch(() => \"Unknown error\");\n const detail = text ? `${response.status} ${text}` : `${response.status}`;\n const message = `${label}: ${detail}`;\n if (response.status === 401 || response.status === 403) return new SitepingAuthError(message);\n if (response.status >= 400 && response.status < 500) return new SitepingValidationError(message);\n return new SitepingError(message, \"SERVER\", false);\n}\n\n/**\n * Normalise an exception thrown by `fetch` (or our timeout AbortController)\n * into a `SitepingNetworkError`. We treat AbortErrors as network failures\n * because in our code path they always come from the internal timeout, not\n * a user-driven cancellation.\n */\nfunction networkErrorFromException(error: unknown, label: string): SitepingNetworkError {\n if (error instanceof SitepingError) {\n // Already typed — only used when callers pass our own errors through.\n if (error instanceof SitepingNetworkError) return error;\n }\n const detail = error instanceof Error ? error.message : String(error);\n return new SitepingNetworkError(`${label}: ${detail}`);\n}\n\n/**\n * Abstract client interface used by the widget internals.\n *\n * `ApiClient` (HTTP mode) and `StoreClient` (direct store mode) both satisfy\n * this interface, allowing the widget to work identically in either mode.\n */\nexport interface WidgetClient {\n sendFeedback(payload: FeedbackPayload): Promise<FeedbackResponse>;\n getFeedbacks(\n projectName: string,\n options?: GetFeedbacksOptions,\n ): Promise<{ feedbacks: FeedbackResponse[]; total: number }>;\n resolveFeedback(id: string, resolved: boolean): Promise<FeedbackResponse>;\n deleteFeedback(id: string): Promise<void>;\n deleteAllFeedbacks(projectName: string): Promise<void>;\n}\n\n/** Options accepted by `WidgetClient.getFeedbacks`. */\nexport interface GetFeedbacksOptions {\n page?: number;\n limit?: number;\n type?: FeedbackType;\n status?: FeedbackStatus;\n search?: string;\n /** Restrict to feedbacks created on this exact URL (path). */\n url?: string;\n /** Restrict to feedbacks created on this URL pattern (e.g. `/orders/:orderId`). */\n urlPattern?: string;\n}\n\nconst MAX_RETRIES = 3;\nconst TIMEOUT_MS = 10_000;\nconst RETRY_QUEUE_KEY = \"siteping_retry_queue\";\nconst MAX_QUEUE_SIZE = 20;\n\n// ---------------------------------------------------------------------------\n// Core fetch with retry + exponential backoff + jitter\n// ---------------------------------------------------------------------------\n\nasync function resilientFetch(url: string, init: RequestInit, retries = MAX_RETRIES): Promise<Response> {\n for (let attempt = 0; attempt <= retries; attempt++) {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), TIMEOUT_MS);\n\n try {\n const response = await fetch(url, {\n ...init,\n signal: controller.signal,\n });\n clearTimeout(timeout);\n\n // Don't retry client errors (4xx) — only server errors (5xx)\n if (response.ok || (response.status >= 400 && response.status < 500)) {\n return response;\n }\n\n if (attempt === retries) return response;\n } catch (error) {\n clearTimeout(timeout);\n if (attempt === retries) throw error;\n }\n\n // Exponential backoff with jitter: 1s, 2s, 4s + random ±500ms\n const baseDelay = 1000 * 2 ** attempt;\n const jitter = Math.random() * 1000 - 500;\n await new Promise((r) => setTimeout(r, baseDelay + jitter));\n }\n\n throw new Error(\"Max retries exceeded\");\n}\n\n// ---------------------------------------------------------------------------\n// Retry queue — persist failed feedbacks for retry on next page load\n// ---------------------------------------------------------------------------\n\ntype RetryEntry = { endpoint: string; payload: FeedbackPayload };\n\nconst LOCK_NAME = \"siteping_retry_queue\";\n\n/**\n * Acquire a Web Lock to serialize cross-tab access to the retry queue.\n * Falls back to running the callback without locking on older browsers.\n */\nasync function withRetryLock<T>(callback: () => T | Promise<T>): Promise<T> {\n if (typeof navigator !== \"undefined\" && navigator.locks) {\n return navigator.locks.request(LOCK_NAME, () => callback());\n }\n return callback();\n}\n\nfunction queueForRetry(endpoint: string, payload: FeedbackPayload): void {\n // Fire-and-forget — we don't want to block the caller on the lock\n void withRetryLock(() => {\n try {\n const raw = localStorage.getItem(RETRY_QUEUE_KEY);\n const parsed: unknown = raw ? JSON.parse(raw) : [];\n const queue: RetryEntry[] = Array.isArray(parsed) ? (parsed as RetryEntry[]) : [];\n\n // Cap queue size to prevent unbounded localStorage growth\n if (queue.length >= MAX_QUEUE_SIZE) {\n queue.shift(); // Drop oldest entry\n }\n\n queue.push({ endpoint, payload });\n localStorage.setItem(RETRY_QUEUE_KEY, JSON.stringify(queue));\n } catch {\n // localStorage full or unavailable — silently drop\n }\n });\n}\n\nexport async function flushRetryQueue(endpoint: string): Promise<void> {\n await withRetryLock(async () => {\n try {\n const raw = localStorage.getItem(RETRY_QUEUE_KEY);\n if (!raw) return;\n\n const parsed: unknown = JSON.parse(raw);\n const queue: RetryEntry[] = Array.isArray(parsed) ? (parsed as RetryEntry[]) : [];\n\n const toRetry = queue.filter((e) => e.endpoint === endpoint);\n if (toRetry.length === 0) return;\n\n // Process items sequentially to avoid overwhelming the server\n const failed: RetryEntry[] = [];\n for (const entry of toRetry) {\n try {\n const res = await fetch(endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(entry.payload),\n });\n if (!res.ok) {\n failed.push(entry);\n }\n } catch {\n failed.push(entry);\n }\n }\n\n // Rebuild queue: keep unrelated entries + failed retries\n const remaining = queue.filter((e) => e.endpoint !== endpoint).concat(failed);\n if (remaining.length > 0) {\n localStorage.setItem(RETRY_QUEUE_KEY, JSON.stringify(remaining));\n } else {\n localStorage.removeItem(RETRY_QUEUE_KEY);\n }\n } catch {\n // Ignore — localStorage may be unavailable\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// API client\n// ---------------------------------------------------------------------------\n\nexport class ApiClient {\n constructor(\n private readonly endpoint: string,\n private readonly projectName: string,\n ) {}\n\n async sendFeedback(payload: FeedbackPayload): Promise<FeedbackResponse> {\n // Match the legacy contract: every failure path (network or HTTP) queues\n // for retry. Tests + host apps already rely on this — narrowing to\n // network-only would be a silent behaviour change.\n try {\n let response: Response;\n try {\n response = await resilientFetch(this.endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(payload),\n });\n } catch (error) {\n throw networkErrorFromException(error, \"Failed to send feedback\");\n }\n\n if (!response.ok) {\n throw await errorFromResponse(response, \"Failed to send feedback\");\n }\n\n return (await response.json()) as FeedbackResponse; // Server validates via Zod\n } catch (error) {\n queueForRetry(this.endpoint, payload);\n throw error;\n }\n }\n\n async getFeedbacks(\n projectName: string,\n options?: GetFeedbacksOptions,\n ): Promise<{ feedbacks: FeedbackResponse[]; total: number }> {\n const params = new URLSearchParams({ projectName });\n if (options?.page) params.set(\"page\", String(options.page));\n if (options?.limit) params.set(\"limit\", String(options.limit));\n if (options?.type) params.set(\"type\", options.type);\n if (options?.status) params.set(\"status\", options.status);\n if (options?.search) params.set(\"search\", options.search);\n if (options?.url) params.set(\"url\", options.url);\n if (options?.urlPattern) params.set(\"urlPattern\", options.urlPattern);\n\n let response: Response;\n try {\n response = await resilientFetch(`${this.endpoint}?${params.toString()}`, {\n method: \"GET\",\n cache: \"no-store\",\n });\n } catch (error) {\n throw networkErrorFromException(error, \"Failed to fetch feedbacks\");\n }\n\n if (!response.ok) {\n throw await errorFromResponse(response, \"Failed to fetch feedbacks\");\n }\n\n return (await response.json()) as { feedbacks: FeedbackResponse[]; total: number }; // Server validates via Zod\n }\n\n async resolveFeedback(id: string, resolved: boolean): Promise<FeedbackResponse> {\n let response: Response;\n try {\n response = await resilientFetch(this.endpoint, {\n method: \"PATCH\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ id, projectName: this.projectName, status: resolved ? \"resolved\" : \"open\" }),\n });\n } catch (error) {\n throw networkErrorFromException(error, \"Failed to update feedback\");\n }\n\n if (!response.ok) {\n throw await errorFromResponse(response, \"Failed to update feedback\");\n }\n\n return (await response.json()) as FeedbackResponse; // Server validates via Zod\n }\n\n async deleteFeedback(id: string): Promise<void> {\n let response: Response;\n try {\n response = await resilientFetch(this.endpoint, {\n method: \"DELETE\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ id, projectName: this.projectName }),\n });\n } catch (error) {\n throw networkErrorFromException(error, \"Failed to delete feedback\");\n }\n\n if (!response.ok) {\n throw await errorFromResponse(response, \"Failed to delete feedback\");\n }\n }\n\n async deleteAllFeedbacks(projectName: string): Promise<void> {\n let response: Response;\n try {\n response = await resilientFetch(this.endpoint, {\n method: \"DELETE\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ projectName, deleteAll: true }),\n });\n } catch (error) {\n throw networkErrorFromException(error, \"Failed to delete all feedbacks\");\n }\n\n if (!response.ok) {\n throw await errorFromResponse(response, \"Failed to delete all feedbacks\");\n }\n }\n}\n","/**\n * Console buffer — capture the last N `console.{log,info,warn,error}` calls\n * so they ship with every feedback submission.\n *\n * Why a ring buffer:\n * - **bounded memory** even on chatty pages (1000s of logs/min during dev),\n * - **last-N is the relevant slice** for debugging — what was happening just\n * before the user noticed the bug, not the full session history.\n *\n * Why monkey-patching instead of `console.dir`/Performance Timeline:\n * - host code already uses plain `console.*` everywhere, and many libraries\n * only emit through console (no other observable),\n * - patching is reversible via `dispose()` so the widget never leaves state\n * behind on `destroy()`.\n */\n\nconst DEFAULT_MAX_ENTRIES = 50;\nconst MAX_MESSAGE_LENGTH = 500;\n\n/** Per-entry shape — sent to the server in the diagnostics payload. */\nexport interface ConsoleEntry {\n level: \"log\" | \"info\" | \"warn\" | \"error\";\n /** ISO 8601 timestamp captured at log time. */\n timestamp: string;\n /** Best-effort string representation of the console args. */\n message: string;\n}\n\nconst LEVELS: Array<ConsoleEntry[\"level\"]> = [\"log\", \"info\", \"warn\", \"error\"];\n\n/**\n * Best-effort stringification that never throws.\n *\n * - `Error` → `Error: message\\nstack` (capped to 500 chars overall).\n * - circular / huge objects → fall back to `Object#toString()` or `\"[Unserializable]\"`.\n * - all output is truncated to `MAX_MESSAGE_LENGTH` so a single 5MB log\n * doesn't blow up the buffer (Slack-style 500 chars per row is plenty).\n */\nfunction serializeArg(arg: unknown): string {\n if (arg === null) return \"null\";\n if (arg === undefined) return \"undefined\";\n if (typeof arg === \"string\") return arg;\n if (typeof arg === \"number\" || typeof arg === \"boolean\" || typeof arg === \"bigint\") {\n return String(arg);\n }\n if (arg instanceof Error) {\n return `${arg.name}: ${arg.message}${arg.stack ? `\\n${arg.stack}` : \"\"}`;\n }\n try {\n // Replacer drops cycles + functions; functions stringify-default to\n // undefined and disappear from the output, which is the right call (we\n // don't want random function bodies in a feedback payload).\n const seen = new WeakSet<object>();\n return JSON.stringify(arg, (_key, value: unknown) => {\n if (typeof value === \"function\") return \"[Function]\";\n if (typeof value === \"symbol\") return value.toString();\n if (typeof value === \"object\" && value !== null) {\n if (seen.has(value as object)) return \"[Circular]\";\n seen.add(value as object);\n }\n return value;\n });\n } catch {\n try {\n return String(arg);\n } catch {\n return \"[Unserializable]\";\n }\n }\n}\n\nfunction formatArgs(args: readonly unknown[]): string {\n let out = \"\";\n for (let i = 0; i < args.length; i++) {\n if (i > 0) out += \" \";\n out += serializeArg(args[i]);\n if (out.length >= MAX_MESSAGE_LENGTH) break;\n }\n if (out.length > MAX_MESSAGE_LENGTH) {\n out = `${out.slice(0, MAX_MESSAGE_LENGTH - 1)}…`;\n }\n return out;\n}\n\n/**\n * Bounded ring buffer of console messages.\n *\n * Construction installs the wrappers immediately. `dispose()` restores the\n * originals exactly once (calling it twice is a no-op). Designed to be safe\n * against re-entrant or interleaved instances — each wrapper closes over the\n * original method, not over any global, so multiple buffers can coexist\n * (each captures its own copy of the args).\n */\nexport class ConsoleBuffer {\n private readonly maxEntries: number;\n private readonly entries: ConsoleEntry[] = [];\n private originals = new Map<ConsoleEntry[\"level\"], (...args: unknown[]) => void>();\n private disposed = false;\n\n constructor(maxEntries: number = DEFAULT_MAX_ENTRIES) {\n // Guard against pathological values — 0 disables silently, negative\n // numbers fall through to the default, and absurdly large numbers are\n // capped so a misuse can't OOM the page.\n this.maxEntries = Math.min(Math.max(Math.floor(maxEntries), 0), 1000);\n\n if (typeof console === \"undefined\") return;\n\n for (const level of LEVELS) {\n const original = (console as unknown as Record<string, ((...args: unknown[]) => void) | undefined>)[level];\n if (typeof original !== \"function\") continue;\n this.originals.set(level, original);\n\n const buffer = this;\n const wrapped = function (this: unknown, ...args: unknown[]): void {\n try {\n buffer.push(level, args);\n } catch {\n // Capturing must never break the host's console — swallow any\n // unexpected error from serialization so the original call\n // (right below) always still runs.\n }\n original.apply(this ?? console, args);\n };\n // Preserve the function name so devtools still show \"console.log\"\n // (browsers display the wrapper's name in stack traces).\n try {\n Object.defineProperty(wrapped, \"name\", { value: level });\n } catch {\n // Older engines reject defineProperty on function name — best-effort only.\n }\n (console as unknown as Record<string, unknown>)[level] = wrapped;\n }\n }\n\n private push(level: ConsoleEntry[\"level\"], args: readonly unknown[]): void {\n if (this.maxEntries === 0) return;\n if (this.entries.length >= this.maxEntries) {\n this.entries.shift();\n }\n this.entries.push({\n level,\n timestamp: new Date().toISOString(),\n message: formatArgs(args),\n });\n }\n\n /** Snapshot of captured entries — returns a new array each call. */\n getEntries(): ConsoleEntry[] {\n return this.entries.slice();\n }\n\n /** Restore the original console methods. Idempotent. */\n dispose(): void {\n if (this.disposed) return;\n this.disposed = true;\n if (typeof console === \"undefined\") return;\n for (const [level, original] of this.originals) {\n try {\n (console as unknown as Record<string, unknown>)[level] = original;\n } catch {\n // Console may be frozen in exotic environments — leave the wrapper\n // in place; it still proxies to the original via closure.\n }\n }\n this.originals.clear();\n }\n}\n","/**\n * Network buffer — capture the last N failed `fetch` / `XMLHttpRequest`\n * calls (HTTP >= 400 or network error) so they ship with each feedback.\n *\n * Captures only failures because:\n * - successful requests are usually irrelevant for the \"this thing is\n * broken\" workflow,\n * - keeping the volume tiny means we can ship the full payload to the\n * server without bloating Postgres.\n *\n * Both wrappers preserve the original semantics — return values, throws,\n * AbortController behaviour, etc. The only side effect is recording a\n * `NetworkEntry` on failure.\n */\n\nconst DEFAULT_MAX_ENTRIES = 20;\nconst MAX_URL_LENGTH = 2000;\n\n/** Per-entry shape — sent to the server in the diagnostics payload. */\nexport interface NetworkEntry {\n url: string;\n method: string;\n /** HTTP status or 0 when the request never reached the server (network error / CORS / abort). */\n status: number;\n /** End-to-end duration in ms, rounded to the nearest integer. */\n durationMs: number;\n /** ISO 8601 timestamp at the moment the request was initiated. */\n timestamp: string;\n}\n\nfunction truncateUrl(url: string): string {\n if (url.length <= MAX_URL_LENGTH) return url;\n return `${url.slice(0, MAX_URL_LENGTH - 1)}…`;\n}\n\nfunction urlString(input: unknown): string {\n if (typeof input === \"string\") return input;\n if (input instanceof URL) return input.href;\n // `Request` instances expose `.url`\n if (typeof input === \"object\" && input !== null && \"url\" in (input as { url?: unknown })) {\n const candidate = (input as { url?: unknown }).url;\n if (typeof candidate === \"string\") return candidate;\n }\n try {\n return String(input);\n } catch {\n return \"(unknown)\";\n }\n}\n\n/**\n * Bounded ring buffer of failed network requests.\n *\n * Construction monkey-patches `globalThis.fetch` and `XMLHttpRequest` and\n * stores the originals for `dispose()`. Wrappers are designed so that\n * multiple instances can coexist (each captures independently into its own\n * buffer, and the last one disposed restores the chain correctly via the\n * stored originals).\n */\nexport class NetworkBuffer {\n private readonly maxEntries: number;\n private readonly entries: NetworkEntry[] = [];\n private originalFetch: typeof fetch | null = null;\n private originalXhrOpen: typeof XMLHttpRequest.prototype.open | null = null;\n private originalXhrSend: typeof XMLHttpRequest.prototype.send | null = null;\n private disposed = false;\n\n constructor(maxEntries: number = DEFAULT_MAX_ENTRIES) {\n this.maxEntries = Math.min(Math.max(Math.floor(maxEntries), 0), 500);\n this.installFetch();\n this.installXhr();\n }\n\n private push(entry: NetworkEntry): void {\n if (this.maxEntries === 0) return;\n if (this.entries.length >= this.maxEntries) {\n this.entries.shift();\n }\n this.entries.push(entry);\n }\n\n private installFetch(): void {\n if (typeof globalThis.fetch !== \"function\") return;\n const original = globalThis.fetch;\n this.originalFetch = original;\n\n const wrapped: typeof fetch = async (input, init) => {\n const startedAt = new Date();\n const t0 = typeof performance !== \"undefined\" ? performance.now() : Date.now();\n const url = truncateUrl(urlString(input));\n const method = (init?.method ?? (input instanceof Request ? input.method : \"GET\")).toUpperCase();\n\n try {\n const response = await original(input, init);\n if (!response.ok) {\n const t1 = typeof performance !== \"undefined\" ? performance.now() : Date.now();\n this.push({\n url,\n method,\n status: response.status,\n durationMs: Math.round(t1 - t0),\n timestamp: startedAt.toISOString(),\n });\n }\n return response;\n } catch (err) {\n const t1 = typeof performance !== \"undefined\" ? performance.now() : Date.now();\n this.push({\n url,\n method,\n status: 0,\n durationMs: Math.round(t1 - t0),\n timestamp: startedAt.toISOString(),\n });\n throw err;\n }\n };\n\n globalThis.fetch = wrapped;\n }\n\n private installXhr(): void {\n if (typeof XMLHttpRequest === \"undefined\") return;\n const proto = XMLHttpRequest.prototype;\n const originalOpen = proto.open;\n const originalSend = proto.send;\n this.originalXhrOpen = originalOpen;\n this.originalXhrSend = originalSend;\n const buffer = this;\n\n // Store the open metadata on the XHR instance via a side-channel WeakMap\n // so each request is fully isolated even with concurrent opens.\n const meta = new WeakMap<XMLHttpRequest, { method: string; url: string; startedAt: Date; t0: number }>();\n\n proto.open = function (this: XMLHttpRequest, method: string, url: string | URL, ...rest: unknown[]) {\n try {\n meta.set(this, {\n method: method.toUpperCase(),\n url: truncateUrl(urlString(url)),\n startedAt: new Date(),\n t0: typeof performance !== \"undefined\" ? performance.now() : Date.now(),\n });\n } catch {\n // Ignore — metadata is best-effort, the underlying open() still runs.\n }\n // XHR.open has two overloaded signatures (3-arg sync, 5-arg async with\n // user/password). Cast to a loose function shape to forward every arg\n // without re-enumerating the overloads here.\n const looseOpen = originalOpen as unknown as (this: XMLHttpRequest, ...a: unknown[]) => void;\n return looseOpen.call(this, method, url, ...rest);\n } as typeof proto.open;\n\n proto.send = function (this: XMLHttpRequest, body?: Document | XMLHttpRequestBodyInit | null) {\n const info = meta.get(this);\n if (info) {\n // `loadend` fires for both success and failure — we just inspect the\n // status to decide whether to log. Use `once: true` so a re-sent XHR\n // doesn't accumulate listeners.\n const onEnd = () => {\n try {\n const t1 = typeof performance !== \"undefined\" ? performance.now() : Date.now();\n const status = this.status; // 0 on network error / abort\n if (status === 0 || status >= 400) {\n buffer.push({\n url: info.url,\n method: info.method,\n status,\n durationMs: Math.round(t1 - info.t0),\n timestamp: info.startedAt.toISOString(),\n });\n }\n } catch {\n // Listener must not throw — would surface as an \"Uncaught\" in\n // the host's console and pollute their logs.\n }\n };\n try {\n this.addEventListener(\"loadend\", onEnd, { once: true });\n } catch {\n // Older engines without options object — fall back to plain listener.\n try {\n this.addEventListener(\"loadend\", onEnd);\n } catch {\n // No-op\n }\n }\n }\n return originalSend.call(this, body ?? null);\n } as typeof proto.send;\n }\n\n /** Snapshot of captured entries — returns a new array each call. */\n getEntries(): NetworkEntry[] {\n return this.entries.slice();\n }\n\n /** Restore the original fetch + XHR methods. Idempotent. */\n dispose(): void {\n if (this.disposed) return;\n this.disposed = true;\n\n if (this.originalFetch && typeof globalThis.fetch === \"function\") {\n try {\n globalThis.fetch = this.originalFetch;\n } catch {\n // Best-effort\n }\n }\n if (typeof XMLHttpRequest !== \"undefined\") {\n try {\n if (this.originalXhrOpen) XMLHttpRequest.prototype.open = this.originalXhrOpen;\n if (this.originalXhrSend) XMLHttpRequest.prototype.send = this.originalXhrSend;\n } catch {\n // Best-effort\n }\n }\n }\n}\n","type Listener = (...args: unknown[]) => void;\n\n/**\n * Lightweight typed EventEmitter — zero dependencies.\n */\nexport class EventBus<E extends { [K in keyof E]: unknown[] }> {\n private listeners = new Map<keyof E, Set<Listener>>();\n\n on<K extends keyof E>(event: K, listener: (...args: E[K]) => void): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n const set = this.listeners.get(event)!;\n set.add(listener as Listener);\n\n return () => {\n set.delete(listener as Listener);\n };\n }\n\n off<K extends keyof E>(event: K, listener: (...args: E[K]) => void): void {\n const set = this.listeners.get(event);\n if (set) {\n set.delete(listener as Listener);\n }\n }\n\n emit<K extends keyof E>(event: K, ...args: E[K]): void {\n const set = this.listeners.get(event);\n if (!set) return;\n for (const fn of set) {\n try {\n fn(...args);\n } catch (err) {\n // Isolate listener errors — one bad listener must not kill others\n console.error(`[siteping] Error in event listener for \"${String(event)}\":`, err);\n }\n }\n }\n\n removeAll(): void {\n this.listeners.clear();\n }\n}\n\n// ---------------------------------------------------------------------------\n// Widget event types\n// ---------------------------------------------------------------------------\n\nexport interface WidgetEvents {\n open: [];\n close: [];\n \"feedback:sent\": [import(\"@siteping/core\").FeedbackResponse];\n \"feedback:deleted\": [string];\n \"feedback:all-deleted\": [];\n \"feedback:error\": [Error];\n \"annotation:start\": [];\n \"annotation:end\": [];\n \"annotation:complete\": [import(\"./annotator.js\").AnnotationComplete];\n \"annotations:toggle\": [boolean];\n \"panel:toggle\": [boolean];\n}\n\n/** Subset of WidgetEvents exposed to consumers via SitepingInstance */\nexport interface PublicWidgetEvents {\n \"feedback:sent\": [import(\"@siteping/core\").FeedbackResponse];\n \"feedback:deleted\": [string];\n \"panel:open\": [];\n \"panel:close\": [];\n}\n","import type { SitepingConfig } from \"@siteping/core\";\nimport { parseSvg, setText } from \"./dom-utils.js\";\nimport type { EventBus, WidgetEvents } from \"./events.js\";\nimport type { TFunction } from \"./i18n/index.js\";\nimport { ICON_ANNOTATE, ICON_CHAT, ICON_CLOSE, ICON_EYE, ICON_EYE_OFF, ICON_SITEPING } from \"./icons.js\";\n\ninterface RadialItem {\n id: string;\n icon: string;\n iconAlt?: string;\n label: string;\n}\n\nconst ITEM_GAP = 54;\n\n/**\n * Floating Action Button with radial menu and notification badge.\n *\n * Glassmorphism: gradient background, glow shadow, glass radial items.\n * Badge shows unresolved feedback count.\n */\nexport class Fab {\n private root: HTMLElement;\n private fab: HTMLButtonElement;\n private radialContainer: HTMLElement;\n private badgeEl: HTMLElement | null = null;\n private isOpen = false;\n private annotationsVisible = true;\n private items: RadialItem[];\n\n constructor(\n shadowRoot: ShadowRoot,\n config: SitepingConfig,\n private readonly bus: EventBus<WidgetEvents>,\n private readonly t: TFunction,\n ) {\n const position = config.position ?? \"bottom-right\";\n const isRight = position === \"bottom-right\";\n\n // Vertical stack above the FAB\n this.items = [\n { id: \"chat\", icon: ICON_CHAT, label: t(\"fab.messages\") },\n { id: \"annotate\", icon: ICON_ANNOTATE, label: t(\"fab.annotate\") },\n { id: \"toggle-annotations\", icon: ICON_EYE, iconAlt: ICON_EYE_OFF, label: t(\"fab.annotations\") },\n ];\n\n // FAB button — needs position:relative for badge positioning\n this.fab = document.createElement(\"button\");\n this.fab.className = `sp-fab sp-fab--${position} sp-anim-fab-in`;\n this.fab.style.position = \"fixed\"; // ensure fixed even with relative children\n this.fab.appendChild(parseSvg(ICON_SITEPING));\n this.fab.setAttribute(\"aria-label\", t(\"fab.aria\"));\n this.fab.setAttribute(\"aria-expanded\", \"false\");\n this.fab.addEventListener(\"click\", () => this.toggle());\n\n // Radial container\n this.radialContainer = document.createElement(\"div\");\n this.radialContainer.className = `sp-radial sp-radial--${position}`;\n this.radialContainer.setAttribute(\"role\", \"menu\");\n\n for (let i = 0; i < this.items.length; i++) {\n const item = this.items[i];\n if (!item) continue;\n const btn = document.createElement(\"button\");\n btn.className = \"sp-radial-item\";\n btn.style.setProperty(\"--sp-i\", String(i));\n btn.appendChild(parseSvg(item.icon));\n btn.setAttribute(\"role\", \"menuitem\");\n btn.setAttribute(\"aria-label\", item.label);\n btn.dataset.itemId = item.id;\n\n btn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.handleItemClick(item.id);\n });\n\n const label = document.createElement(\"span\");\n label.className = \"sp-radial-label\";\n label.textContent = item.label;\n label.style.cssText = isRight\n ? \"position:absolute; right:54px; top:50%; transform:translateY(-50%); white-space:nowrap;\"\n : \"position:absolute; left:54px; top:50%; transform:translateY(-50%); white-space:nowrap;\";\n btn.appendChild(label);\n\n this.radialContainer.appendChild(btn);\n }\n\n this.root = document.createElement(\"div\");\n this.root.appendChild(this.radialContainer);\n this.root.appendChild(this.fab);\n shadowRoot.appendChild(this.root);\n\n // Close radial menu on click outside.\n const host = shadowRoot.host;\n this.onDocumentClick = (e: MouseEvent) => {\n if (this.isOpen && !e.composedPath().includes(host)) {\n this.close();\n }\n };\n document.addEventListener(\"click\", this.onDocumentClick);\n\n // Escape on FAB or menu container closes the menu\n const handleEscape = (e: KeyboardEvent) => {\n if (e.key === \"Escape\" && this.isOpen) {\n e.stopPropagation();\n this.close();\n }\n };\n this.fab.addEventListener(\"keydown\", handleEscape);\n this.radialContainer.addEventListener(\"keydown\", handleEscape);\n\n // Arrow key navigation within the radial menu\n this.radialContainer.addEventListener(\"keydown\", (e) => {\n const items = Array.from(this.radialContainer.querySelectorAll<HTMLButtonElement>(\".sp-radial-item\"));\n if (items.length === 0 || !this.isOpen) return;\n const activeEl = (shadowRoot.activeElement ?? document.activeElement) as HTMLElement;\n const currentIndex = items.indexOf(activeEl as HTMLButtonElement);\n\n switch (e.key) {\n case \"ArrowUp\": {\n e.preventDefault();\n const nextIndex = currentIndex <= 0 ? items.length - 1 : currentIndex - 1;\n items[nextIndex]?.focus();\n break;\n }\n case \"ArrowDown\": {\n e.preventDefault();\n const nextIndex = currentIndex >= items.length - 1 ? 0 : currentIndex + 1;\n items[nextIndex]?.focus();\n break;\n }\n case \"Home\": {\n e.preventDefault();\n items[0]?.focus();\n break;\n }\n case \"End\": {\n e.preventDefault();\n items[items.length - 1]?.focus();\n break;\n }\n }\n });\n }\n\n private onDocumentClick: (e: MouseEvent) => void;\n\n /** Update the badge count. Pass 0 to hide. */\n updateBadge(count: number): void {\n if (count <= 0) {\n this.badgeEl?.remove();\n this.badgeEl = null;\n return;\n }\n\n if (!this.badgeEl) {\n this.badgeEl = document.createElement(\"span\");\n this.badgeEl.className = \"sp-fab-badge\";\n this.badgeEl.setAttribute(\"role\", \"status\");\n this.badgeEl.setAttribute(\"aria-live\", \"polite\");\n this.fab.appendChild(this.badgeEl);\n }\n\n const displayText = count > 99 ? \"99+\" : String(count);\n setText(this.badgeEl, displayText);\n this.badgeEl.setAttribute(\"aria-label\", this.t(\"fab.badge\").replace(\"{count}\", String(count)));\n }\n\n private toggle(): void {\n this.isOpen ? this.close() : this.open();\n }\n\n private open(): void {\n this.isOpen = true;\n this.setFabIcon(ICON_CLOSE);\n this.fab.setAttribute(\"aria-expanded\", \"true\");\n\n const buttons = this.radialContainer.querySelectorAll<HTMLButtonElement>(\".sp-radial-item\");\n buttons.forEach((btn, i) => {\n // Stack vertically above the FAB with initial offset + gap\n const y = -(16 + ITEM_GAP * (i + 1));\n btn.style.transform = `translate(0px, ${y}px) scale(1)`;\n btn.classList.add(\"sp-radial-item--open\");\n });\n\n // Focus the first menu item after animation\n requestAnimationFrame(() => {\n const firstItem = this.radialContainer.querySelector<HTMLButtonElement>(\".sp-radial-item\");\n firstItem?.focus();\n });\n }\n\n private close(): void {\n this.isOpen = false;\n this.setFabIcon(ICON_SITEPING);\n this.fab.setAttribute(\"aria-expanded\", \"false\");\n\n const buttons = this.radialContainer.querySelectorAll<HTMLButtonElement>(\".sp-radial-item\");\n buttons.forEach((btn) => {\n btn.style.transform = \"translate(0, 0) scale(0.8)\";\n btn.classList.remove(\"sp-radial-item--open\");\n });\n\n // Return focus to FAB\n this.fab.focus();\n }\n\n private setFabIcon(svgStr: string): void {\n const badge = this.badgeEl;\n this.fab.replaceChildren(parseSvg(svgStr));\n // Re-append badge after icon swap\n if (badge) this.fab.appendChild(badge);\n }\n\n private handleItemClick(id: string): void {\n this.close();\n\n switch (id) {\n case \"chat\":\n this.bus.emit(\"panel:toggle\", true);\n break;\n case \"annotate\":\n this.bus.emit(\"annotation:start\");\n break;\n case \"toggle-annotations\": {\n this.annotationsVisible = !this.annotationsVisible;\n this.bus.emit(\"annotations:toggle\", this.annotationsVisible);\n const btn = this.radialContainer.querySelector('[data-item-id=\"toggle-annotations\"]');\n if (btn) {\n btn.replaceChildren(parseSvg(this.annotationsVisible ? ICON_EYE : ICON_EYE_OFF));\n }\n break;\n }\n }\n }\n\n destroy(): void {\n document.removeEventListener(\"click\", this.onDocumentClick);\n this.root.remove();\n }\n}\n","const STORAGE_KEY = \"siteping_identity\";\n\nexport interface Identity {\n name: string;\n email: string;\n}\n\nexport function getIdentity(): Identity | null {\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n if (!raw) return null;\n const parsed: unknown = JSON.parse(raw);\n if (\n typeof parsed === \"object\" &&\n parsed !== null &&\n \"name\" in parsed &&\n typeof (parsed as Record<string, unknown>).name === \"string\" &&\n \"email\" in parsed &&\n typeof (parsed as Record<string, unknown>).email === \"string\"\n ) {\n const identity = parsed as Identity;\n if (identity.name && identity.email) return identity;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nexport function saveIdentity(identity: Identity): void {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(identity));\n } catch {\n // Quota exceeded or localStorage disabled — identity works for this session only\n }\n}\n","/**\n * Lightweight fuzzy text matching for DOM re-anchoring.\n * Zero dependencies — bundled into the widget.\n * Uses Levenshtein distance, optimized for short strings (~50 chars).\n */\n\n/**\n * Levenshtein edit distance.\n * O(n*m) time, O(min(n,m)) space.\n */\nexport function editDistance(a: string, b: string): number {\n if (a === b) return 0;\n if (a.length === 0) return b.length;\n if (b.length === 0) return a.length;\n\n // Ensure `a` is the shorter string for space optimization\n if (a.length > b.length) {\n const t = a;\n a = b;\n b = t;\n }\n\n const aLen = a.length;\n const bLen = b.length;\n let prev = new Array<number>(aLen + 1);\n for (let k = 0; k <= aLen; k++) prev[k] = k;\n let curr = new Array<number>(aLen + 1);\n\n for (let j = 1; j <= bLen; j++) {\n curr[0] = j;\n for (let i = 1; i <= aLen; i++) {\n // Indices are valid: i-1 in [0, aLen-1], j-1 in [0, bLen-1], loop bounds guarantee access\n const prevDiag = prev[i - 1] ?? 0;\n curr[i] = a[i - 1] === b[j - 1] ? prevDiag : 1 + Math.min(prevDiag, prev[i] ?? 0, curr[i - 1] ?? 0);\n }\n const tmp = prev;\n prev = curr;\n curr = tmp;\n }\n\n return prev[aLen] ?? 0; // aLen is within bounds — prev has aLen+1 entries\n}\n\n/**\n * Normalized similarity score (0–1, where 1 = identical).\n */\nexport function similarity(a: string, b: string): number {\n if (a === b) return 1;\n const maxLen = Math.max(a.length, b.length);\n if (maxLen === 0) return 1;\n return 1 - editDistance(a, b) / maxLen;\n}\n\n/**\n * Fuzzy substring search — checks if `needle` approximately exists in `haystack`.\n * Slides a window of `needle.length` over the haystack and returns the best\n * similarity score found. Returns 0 if below `minScore`.\n */\nexport function fuzzyIncludes(haystack: string, needle: string, minScore = 0.6): number {\n if (!needle || !haystack) return 0;\n if (haystack.includes(needle)) return 1;\n\n const nLen = needle.length;\n\n // If needle is longer than haystack, compare directly\n if (nLen > haystack.length) {\n const score = similarity(haystack, needle);\n return score >= minScore ? score : 0;\n }\n\n let best = 0;\n\n // Cap haystack to avoid O(n²) on huge text nodes\n const capped = haystack.length > 500 ? haystack.slice(0, 500) : haystack;\n const limit = capped.length - nLen;\n\n for (let i = 0; i <= limit; i++) {\n const window = capped.slice(i, i + nLen);\n const score = similarity(window, needle);\n if (score > best) best = score;\n if (best >= 0.95) break;\n }\n\n return best >= minScore ? best : 0;\n}\n","import type { AnchorData, RectData } from \"@siteping/core\";\nimport { ANCHOR_KEY_ATTR } from \"./anchor.js\";\nimport { scoreFingerprint } from \"./fingerprint.js\";\nimport { fuzzyIncludes, similarity } from \"./fuzzy.js\";\nimport { adjacentText, neighborText } from \"./text-context.js\";\n\nexport type ResolutionStrategy = \"anchorKey\" | \"id\" | \"css\" | \"xpath\" | \"scan\";\n\nexport interface AnchorResolution {\n element: Element;\n confidence: number;\n strategy: ResolutionStrategy;\n}\n\nexport interface ResolvedAnnotation {\n element: Element;\n rect: DOMRect;\n confidence: number;\n strategy: ResolutionStrategy;\n}\n\n/** Max elements to scan during smart fallback. */\nconst MAX_SCAN_CANDIDATES = 300;\n\n/** Minimum fuzzy text match score for CSS/XPath verification. */\nconst TEXT_MATCH_THRESHOLD = 0.3;\n\n/**\n * Verify that a resolved element's text content matches the stored snippet.\n * If no snippet is stored, returns true (no verification possible).\n * Uses fuzzy matching to tolerate minor text changes.\n */\nfunction textMatches(el: Element, anchor: AnchorData): boolean {\n if (!anchor.textSnippet) return true;\n const text = (el.textContent?.trim() ?? \"\").slice(0, 500);\n return fuzzyIncludes(text, anchor.textSnippet, 0.5) > TEXT_MATCH_THRESHOLD;\n}\n\n/**\n * Re-anchor an annotation using a multi-level fallback strategy\n * with text verification and confidence scoring.\n *\n * Resolution order:\n * 0. Semantic anchor key (`[data-feedback-anchor=\"X\"]`) — confidence 1.0\n * when host explicitly tagged the section. Tag name is NOT enforced —\n * hosts may legitimately refactor the wrapper element while keeping the\n * semantic key stable.\n * 1. getElementById + text verification — confidence 1.0\n * 2. CSS selector + text verification — confidence 0.95\n * 3. XPath + text verification — confidence 0.9\n * 4. Smart scan (fingerprint + text + prefix/suffix + neighbor) — up to 0.85\n *\n * Text verification prevents false matches when DOM elements are reordered.\n * Returns null if all strategies fail (annotation is orphaned).\n */\nexport function resolveAnchor(anchor: AnchorData): AnchorResolution | null {\n // Level 0: Semantic anchor key (host-controlled, most stable)\n if (anchor.anchorKey) {\n // Escape backslash and double-quote so an arbitrary key never breaks the selector\n const escaped = anchor.anchorKey.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n try {\n const el = document.querySelector(`[${ANCHOR_KEY_ATTR}=\"${escaped}\"]`);\n // Skip tagName check — semantic anchor identifies a section, not a tag\n if (el && textMatches(el, anchor)) {\n return { element: el, confidence: 1.0, strategy: \"anchorKey\" };\n }\n } catch {\n // Invalid attribute value — fall through to next strategy\n }\n }\n\n // Level 1: Element ID (most stable, still verify text)\n if (anchor.elementId) {\n const el = document.getElementById(anchor.elementId);\n if (el && el.tagName === anchor.elementTag && textMatches(el, anchor)) {\n return { element: el, confidence: 1.0, strategy: \"id\" };\n }\n }\n\n // Level 2: CSS Selector (with text verification)\n try {\n const el = document.querySelector(anchor.cssSelector);\n if (el && el.tagName === anchor.elementTag && textMatches(el, anchor)) {\n return { element: el, confidence: 0.95, strategy: \"css\" };\n }\n } catch {\n // Invalid selector — skip\n }\n\n // Level 3: XPath (with text verification)\n try {\n const result = document.evaluate(anchor.xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);\n const el = result.singleNodeValue;\n if (el instanceof Element && el.tagName === anchor.elementTag && textMatches(el, anchor)) {\n return { element: el, confidence: 0.9, strategy: \"xpath\" };\n }\n } catch {\n // Invalid XPath — skip\n }\n\n // Level 4: Smart scan — combine all available signals\n return smartScan(anchor);\n}\n\n/**\n * Scan DOM elements by tag and score each candidate using multiple signals:\n * fingerprint, text similarity, prefix/suffix context, neighbor text.\n *\n * Returns the best candidate above a 0.4 threshold, capped at 0.85 confidence\n * (smart scan is never 100% certain).\n */\nfunction smartScan(anchor: AnchorData): AnchorResolution | null {\n const tag = anchor.elementTag.toLowerCase();\n const candidates = document.querySelectorAll(tag);\n if (candidates.length === 0) return null;\n\n let bestElement: Element | null = null;\n let bestScore = 0;\n\n const limit = Math.min(candidates.length, MAX_SCAN_CANDIDATES);\n\n for (let i = 0; i < limit; i++) {\n const el = candidates[i];\n if (!el) continue;\n const score = scoreCandidate(el, anchor);\n if (score > bestScore) {\n bestScore = score;\n bestElement = el;\n if (bestScore >= 0.85) break;\n }\n }\n\n if (!bestElement || bestScore < 0.4) return null;\n\n return {\n element: bestElement,\n confidence: Math.min(bestScore, 0.85),\n strategy: \"scan\",\n };\n}\n\n/**\n * Score a candidate element against all stored anchor signals.\n *\n * Dynamic weighting — only active signals contribute, then normalized:\n * - Text snippet (fuzzy substring match): weight 40 (most reliable for reordering)\n * - Fingerprint (structural match): weight 20\n * - Prefix/suffix context: weight 20\n * - Neighbor text: weight 20\n */\nfunction scoreCandidate(candidate: Element, anchor: AnchorData): number {\n let score = 0;\n let totalWeight = 0;\n\n // Truncate to avoid O(n*m) explosion on huge text nodes\n const candidateText = (candidate.textContent?.trim() ?? \"\").slice(0, 500);\n\n // --- Text snippet (weight 40 — most important for reordered elements) ---\n if (anchor.textSnippet) {\n totalWeight += 40;\n score += fuzzyIncludes(candidateText, anchor.textSnippet, 0.5) * 40;\n }\n\n // --- Fingerprint (weight 20) ---\n if (anchor.fingerprint) {\n totalWeight += 20;\n score += scoreFingerprint(candidate, anchor.fingerprint) * 20;\n }\n\n // --- Prefix/suffix context (weight 20) ---\n if (anchor.textPrefix || anchor.textSuffix) {\n totalWeight += 20;\n let contextScore = 0;\n let contextParts = 0;\n\n if (anchor.textPrefix) {\n const prevText = adjacentText(candidate, \"before\");\n contextScore += prevText ? similarity(prevText, anchor.textPrefix) : 0;\n contextParts++;\n }\n\n if (anchor.textSuffix) {\n const nextText = adjacentText(candidate, \"after\");\n contextScore += nextText ? similarity(nextText, anchor.textSuffix) : 0;\n contextParts++;\n }\n\n if (contextParts > 0) {\n score += (contextScore / contextParts) * 20;\n }\n }\n\n // --- Neighbor text (weight 20) ---\n if (anchor.neighborText) {\n totalWeight += 20;\n const candidateNeighbor = neighborText(candidate);\n score += candidateNeighbor ? similarity(candidateNeighbor, anchor.neighborText) * 20 : 0;\n }\n\n return totalWeight > 0 ? score / totalWeight : 0;\n}\n\n/**\n * Resolve an annotation's position on the page.\n * Converts stored percentage-based rect back to absolute coordinates\n * using the current bounding box of the resolved anchor element.\n */\nexport function resolveAnnotation(anchor: AnchorData, rect: RectData): ResolvedAnnotation | null {\n const resolution = resolveAnchor(anchor);\n\n if (!resolution) return null;\n\n const bounds = resolution.element.getBoundingClientRect();\n const absoluteRect = new DOMRect(\n bounds.x + rect.xPct * bounds.width,\n bounds.y + rect.yPct * bounds.height,\n rect.wPct * bounds.width,\n rect.hPct * bounds.height,\n );\n\n return {\n element: resolution.element,\n rect: absoluteRect,\n confidence: resolution.confidence,\n strategy: resolution.strategy,\n };\n}\n","import type { AnchorData, FeedbackResponse, RectData } from \"@siteping/core\";\nimport { Z_INDEX_MAX } from \"./constants.js\";\nimport { resolveAnnotation } from \"./dom/resolver.js\";\nimport { el, setText } from \"./dom-utils.js\";\nimport type { EventBus, WidgetEvents } from \"./events.js\";\nimport { getTypeLabel, type TFunction } from \"./i18n/index.js\";\nimport { getTypeColor, type ThemeColors } from \"./styles/theme.js\";\nimport type { Tooltip } from \"./tooltip.js\";\n\ntype Annotation = FeedbackResponse[\"annotations\"][number];\n\nfunction toAnchorData(a: Annotation): AnchorData {\n return {\n cssSelector: a.cssSelector,\n xpath: a.xpath,\n textSnippet: a.textSnippet,\n elementTag: a.elementTag,\n elementId: a.elementId ?? undefined,\n textPrefix: a.textPrefix,\n textSuffix: a.textSuffix,\n fingerprint: a.fingerprint,\n neighborText: a.neighborText,\n anchorKey: a.anchorKey ?? null,\n };\n}\n\nfunction toRectData(a: Annotation): RectData {\n return { xPct: a.xPct, yPct: a.yPct, wPct: a.wPct, hPct: a.hPct };\n}\n\n/** Half of the 26px marker diameter — used for centering on anchor corner. */\nconst MARKER_OFFSET = 13;\n\n/** Convert a resolved rect to document-absolute marker position. */\nfunction markerPosition(rect: DOMRect): { top: number; left: number } {\n return {\n top: rect.top + window.scrollY - MARKER_OFFSET,\n left: rect.right + window.scrollX - MARKER_OFFSET,\n };\n}\n\ninterface MarkerEntry {\n feedback: FeedbackResponse;\n elements: HTMLElement[];\n baseTop: number;\n baseLeft: number;\n}\n\ninterface Cluster {\n entries: MarkerEntry[];\n elementIndices: number[];\n expanded: boolean;\n}\n\n/** Get the i-th marker element from a cluster. */\nfunction clusterMarker(cluster: Cluster, i: number): HTMLElement | undefined {\n const entry = cluster.entries[i];\n const elIdx = cluster.elementIndices[i];\n if (!entry || elIdx === undefined) return undefined;\n return entry.elements[elIdx];\n}\n\nconst HIGHLIGHT_FADE = 300;\nconst REPOSITION_DEBOUNCE = 200;\nconst LOW_CONFIDENCE_THRESHOLD = 0.7;\nconst CLUSTER_DISTANCE = 28;\nconst FAN_SPACING = 32;\n\n/**\n * Numbered markers on the page for each feedback annotation.\n *\n * Cluster system: click-to-expand (same pattern as Google Maps / Spiderfier).\n * Hover is only used for tooltip/scale on individual markers — never for expansion.\n */\nexport class MarkerManager {\n private container: HTMLElement;\n private entries: MarkerEntry[] = [];\n private highlightElements: HTMLElement[] = [];\n private pinnedFeedback: FeedbackResponse | null = null;\n private onDocumentClick: ((e: MouseEvent) => void) | null = null;\n private repositionTimer: number | null = null;\n private mutationObserver: MutationObserver | null = null;\n private scrollHandler: (() => void) | null = null;\n private resizeHandler: (() => void) | null = null;\n private anchorCache = new Map<string, WeakRef<Element>>();\n private clusters: Cluster[] = [];\n private onDocumentClickForClusters: ((e: MouseEvent) => void) | null = null;\n\n get count(): number {\n return this.entries.length;\n }\n\n constructor(\n private readonly colors: ThemeColors,\n private readonly tooltip: Tooltip,\n private readonly bus: EventBus<WidgetEvents>,\n private readonly t: TFunction,\n private readonly liveRegion: HTMLElement | null = null,\n ) {\n this.container = el(\"div\", {\n style: `position:absolute;top:0;left:0;pointer-events:none;z-index:${Z_INDEX_MAX - 1};`,\n });\n this.container.id = \"siteping-markers\";\n document.body.appendChild(this.container);\n\n this.bus.on(\"annotations:toggle\", (visible) => {\n this.container.style.display = visible ? \"block\" : \"none\";\n });\n\n this.resizeHandler = () => this.scheduleReposition();\n window.addEventListener(\"resize\", this.resizeHandler, { passive: true });\n\n this.scrollHandler = () => this.scheduleReposition();\n window.addEventListener(\"scroll\", this.scrollHandler, { passive: true, capture: true });\n\n // Re-resolve after DOM changes (SPA, lazy-load).\n // Filter out widget-owned mutations and skip batches with only irrelevant\n // changes. Filtering short-circuits at the first non-widget mutation, so\n // even large batches stop after one DOM walk.\n //\n // The filter is applied unconditionally — earlier versions had a >20-batch\n // fast-path that skipped filtering, but that lets reposition self-trigger\n // when `repositionAll` re-renders the pinned highlight (showHighlight\n // appends N elements to `this.container`); a host page churning lots of\n // DOM (infinite scroll) would then loop at the 200ms debounce interval.\n this.mutationObserver = new MutationObserver((mutations) => {\n let hasRelevantMutation = false;\n for (const m of mutations) {\n if (this.container.contains(m.target) || this.tooltip.contains(m.target)) continue;\n hasRelevantMutation = true;\n break;\n }\n if (hasRelevantMutation) this.scheduleReposition();\n });\n this.mutationObserver.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: false,\n characterData: false,\n });\n\n this.onDocumentClickForClusters = (e: MouseEvent) => {\n if (this.container.contains(e.target as Node)) return;\n this.collapseAllClusters();\n };\n document.addEventListener(\"click\", this.onDocumentClickForClusters);\n }\n\n private scheduleReposition(): void {\n if (this.repositionTimer) return;\n if (\"requestIdleCallback\" in window) {\n this.repositionTimer = window.requestIdleCallback(\n () => {\n this.repositionTimer = null;\n this.repositionAll();\n },\n { timeout: REPOSITION_DEBOUNCE + 100 },\n );\n } else {\n this.repositionTimer = +setTimeout(() => {\n this.repositionTimer = null;\n this.repositionAll();\n }, REPOSITION_DEBOUNCE);\n }\n }\n\n private repositionAll(): void {\n // Build set of valid keys to prune stale cache entries afterwards.\n const validKeys = new Set<string>();\n\n for (const entry of this.entries) {\n for (let i = 0; i < entry.feedback.annotations.length; i++) {\n const markerEl = entry.elements[i];\n if (!markerEl) continue;\n\n const annotation = entry.feedback.annotations[i];\n if (!annotation) continue;\n const cacheKey = `${entry.feedback.id}:${i}`;\n validKeys.add(cacheKey);\n\n // Try cached element first to avoid full resolution chain.\n const cachedRef = this.anchorCache.get(cacheKey);\n const cachedEl = cachedRef?.deref();\n let resolved: ReturnType<typeof resolveAnnotation>;\n\n if (cachedEl?.isConnected) {\n const anchorRect = cachedEl.getBoundingClientRect();\n const r = toRectData(annotation);\n resolved = {\n element: cachedEl,\n rect: new DOMRect(\n anchorRect.left + r.xPct * anchorRect.width,\n anchorRect.top + r.yPct * anchorRect.height,\n r.wPct * anchorRect.width,\n r.hPct * anchorRect.height,\n ),\n confidence: 1,\n strategy: \"css\",\n };\n } else {\n resolved = resolveAnnotation(toAnchorData(annotation), toRectData(annotation));\n if (resolved?.element) {\n this.anchorCache.set(cacheKey, new WeakRef(resolved.element));\n }\n }\n\n if (!resolved) {\n markerEl.style.display = \"none\";\n continue;\n }\n\n const pos = markerPosition(resolved.rect);\n entry.baseTop = pos.top;\n entry.baseLeft = pos.left;\n markerEl.style.display = \"flex\";\n this.applyConfidenceStyle(markerEl, resolved.confidence, entry.feedback);\n }\n }\n\n // Prune cache keys from deleted feedbacks to prevent memory leak.\n for (const key of this.anchorCache.keys()) {\n if (!validKeys.has(key)) this.anchorCache.delete(key);\n }\n\n this.applyClusterPositions();\n\n // Re-render the pinned highlight rectangle so it tracks the layout after\n // resize / SPA mutation. Marker dots reposition above; without this,\n // the highlight rect keeps its old pixel position and visibly drifts\n // away from the underlying content.\n if (this.pinnedFeedback) {\n this.showHighlight(this.pinnedFeedback);\n }\n }\n\n private applyClusterPositions(): void {\n for (const cluster of this.clusters) {\n if (cluster.expanded) {\n this.applyFanPositions(cluster);\n } else {\n this.applyStackPositions(cluster);\n }\n }\n }\n\n render(feedbacks: FeedbackResponse[]): void {\n this.clear();\n feedbacks.forEach((feedback, i) => {\n const entry = this.buildEntry(feedback, i + 1);\n this.entries.push(entry);\n });\n this.buildClusters();\n // Announce the number of visible markers to assistive tech (WCAG 4.1.3).\n // Skip the announcement when the host page has not provided a live\n // region (tests, embedded use cases) and when no marker is visible to\n // avoid noisy \"0 markers\" updates on every navigation.\n if (this.liveRegion && this.entries.length > 0) {\n this.liveRegion.textContent = this.t(\"marker.count\").replace(\"{count}\", String(this.entries.length));\n }\n }\n\n addFeedback(feedback: FeedbackResponse, index: number): void {\n const entry = this.buildEntry(feedback, index);\n for (const m of entry.elements) {\n m.style.animation = \"sp-marker-in 0.35s cubic-bezier(0.34,1.56,0.64,1) both\";\n }\n this.entries.push(entry);\n this.buildClusters();\n }\n\n private buildEntry(feedback: FeedbackResponse, index: number): MarkerEntry {\n const entry: MarkerEntry = { feedback, elements: [], baseTop: 0, baseLeft: 0 };\n for (const annotation of feedback.annotations) {\n const resolved = resolveAnnotation(toAnchorData(annotation), toRectData(annotation));\n if (!resolved) continue;\n const pos = markerPosition(resolved.rect);\n entry.baseTop = pos.top;\n entry.baseLeft = pos.left;\n const marker = this.createMarker(index, feedback, pos);\n this.applyConfidenceStyle(marker, resolved.confidence, feedback);\n this.container.appendChild(marker);\n entry.elements.push(marker);\n }\n return entry;\n }\n\n private buildClusters(): void {\n for (const badge of this.container.querySelectorAll<HTMLElement>(\".sp-cluster-badge\")) {\n badge.remove();\n }\n\n const allItems: { entry: MarkerEntry; elIdx: number }[] = [];\n for (const entry of this.entries) {\n for (let i = 0; i < entry.elements.length; i++) {\n allItems.push({ entry, elIdx: i });\n }\n }\n\n const used = new Set<number>();\n this.clusters = [];\n\n for (let i = 0; i < allItems.length; i++) {\n if (used.has(i)) continue;\n const itemI = allItems[i];\n if (!itemI) continue;\n const cluster: Cluster = {\n entries: [itemI.entry],\n elementIndices: [itemI.elIdx],\n expanded: false,\n };\n used.add(i);\n\n for (let j = i + 1; j < allItems.length; j++) {\n if (used.has(j)) continue;\n const a = itemI.entry;\n const itemJ = allItems[j];\n if (!itemJ) continue;\n const b = itemJ.entry;\n const dist = Math.sqrt((a.baseLeft - b.baseLeft) ** 2 + (a.baseTop - b.baseTop) ** 2);\n if (dist < CLUSTER_DISTANCE) {\n cluster.entries.push(b);\n cluster.elementIndices.push(itemJ.elIdx);\n used.add(j);\n }\n }\n\n this.clusters.push(cluster);\n }\n\n for (const cluster of this.clusters) {\n if (cluster.entries.length <= 1) continue;\n this.applyStackPositions(cluster);\n this.addClusterBadge(cluster);\n }\n }\n\n private applyStackPositions(cluster: Cluster): void {\n const first = cluster.entries[0];\n if (!first) return;\n const { baseTop, baseLeft } = first;\n const isSolo = cluster.entries.length <= 1;\n for (let i = 0; i < cluster.entries.length; i++) {\n const m = clusterMarker(cluster, i);\n if (!m) continue;\n m.style.top = `${baseTop + (isSolo ? 0 : i * 3)}px`;\n m.style.left = `${baseLeft + (isSolo ? 0 : i * 3)}px`;\n m.style.zIndex = String(i + 1);\n }\n }\n\n private applyFanPositions(cluster: Cluster): void {\n const first = cluster.entries[0];\n if (!first) return;\n const { baseTop, baseLeft } = first;\n const count = cluster.entries.length;\n const totalWidth = (count - 1) * FAN_SPACING;\n const startLeft = baseLeft - totalWidth / 2;\n\n for (let i = 0; i < count; i++) {\n const m = clusterMarker(cluster, i);\n if (!m) continue;\n m.style.top = `${baseTop}px`;\n m.style.left = `${startLeft + i * FAN_SPACING}px`;\n m.style.zIndex = String(10 + i);\n }\n }\n\n private addClusterBadge(cluster: Cluster): void {\n const topMarker = clusterMarker(cluster, cluster.entries.length - 1);\n if (!topMarker) return;\n const badge = el(\"div\", {\n class: \"sp-cluster-badge\",\n style: `\n position:absolute;top:-6px;right:-6px;\n min-width:16px;height:16px;padding:0 4px;\n border-radius:9999px;\n background:${this.colors.accent};color:#fff;\n font-size:10px;font-weight:700;\n display:flex;align-items:center;justify-content:center;\n border:1.5px solid #fff;\n pointer-events:none;\n font-family:\"Inter\",system-ui,-apple-system,sans-serif;\n line-height:1;\n `,\n });\n setText(badge, String(cluster.entries.length));\n topMarker.appendChild(badge);\n }\n\n private setBadgesVisible(cluster: Cluster, visible: boolean): void {\n for (let i = 0; i < cluster.entries.length; i++) {\n const badge = clusterMarker(cluster, i)?.querySelector(\".sp-cluster-badge\") as HTMLElement | null;\n if (badge) badge.style.display = visible ? \"flex\" : \"none\";\n }\n }\n\n private findCluster(marker: HTMLElement): Cluster | null {\n for (const cluster of this.clusters) {\n if (cluster.entries.length <= 1) continue;\n for (let i = 0; i < cluster.entries.length; i++) {\n if (clusterMarker(cluster, i) === marker) return cluster;\n }\n }\n return null;\n }\n\n private handleClusterClick(marker: HTMLElement, e: MouseEvent): boolean {\n const cluster = this.findCluster(marker);\n if (!cluster) return false;\n if (!cluster.expanded) {\n e.stopPropagation();\n this.collapseAllClusters();\n cluster.expanded = true;\n this.applyFanPositions(cluster);\n this.setBadgesVisible(cluster, false);\n return true;\n }\n return false;\n }\n\n private collapseCluster(cluster: Cluster): void {\n if (!cluster.expanded) return;\n cluster.expanded = false;\n this.applyStackPositions(cluster);\n this.setBadgesVisible(cluster, true);\n }\n\n private collapseAllClusters(): void {\n for (const cluster of this.clusters) {\n this.collapseCluster(cluster);\n }\n }\n\n private applyConfidenceStyle(marker: HTMLElement, confidence: number, feedback: FeedbackResponse): void {\n const isResolved = feedback.status === \"resolved\";\n if (confidence < LOW_CONFIDENCE_THRESHOLD && !isResolved) {\n marker.style.borderStyle = \"dashed\";\n marker.style.opacity = \"0.7\";\n marker.title = this.t(\"marker.approximate\").replace(\"{confidence}\", String(Math.round(confidence * 100)));\n } else {\n marker.style.borderStyle = \"solid\";\n marker.style.opacity = \"1\";\n marker.title = \"\";\n }\n }\n\n private createMarker(number: number, feedback: FeedbackResponse, pos: { top: number; left: number }): HTMLElement {\n const typeColor = getTypeColor(feedback.type, this.colors);\n const isResolved = feedback.status === \"resolved\";\n\n const marker = el(\"div\", {\n style: `\n position:absolute;\n top:${pos.top}px;\n left:${pos.left}px;\n width:26px;height:26px;\n border-radius:50%;\n background:${isResolved ? \"rgba(241,245,249,0.9)\" : \"rgba(255,255,255,0.92)\"};\n border:2px solid ${isResolved ? \"#cbd5e1\" : typeColor};\n display:flex;align-items:center;justify-content:center;\n font-family:\"Inter\",system-ui,-apple-system,sans-serif;\n font-size:11px;font-weight:700;\n color:${isResolved ? \"#94a3b8\" : typeColor};\n cursor:pointer;pointer-events:auto;\n box-shadow:${isResolved ? \"0 2px 8px rgba(0,0,0,0.06)\" : `0 2px 12px ${typeColor}25, 0 2px 6px rgba(0,0,0,0.06)`};\n transition:top 0.25s cubic-bezier(0.34, 1.56, 0.64, 1), left 0.25s cubic-bezier(0.34, 1.56, 0.64, 1), transform 0.15s ease, box-shadow 0.15s ease;\n user-select:none;\n -webkit-font-smoothing:antialiased;\n `,\n });\n marker.dataset.feedbackId = feedback.id;\n marker.setAttribute(\"tabindex\", \"0\");\n marker.setAttribute(\"role\", \"button\");\n const truncatedMessage = feedback.message.length > 60 ? `${feedback.message.slice(0, 60)}...` : feedback.message;\n const ariaLabel = this.t(\"marker.aria\")\n .replace(\"{number}\", String(number))\n .replace(\"{type}\", getTypeLabel(feedback.type, this.t))\n .replace(\"{message}\", truncatedMessage);\n marker.setAttribute(\"aria-label\", ariaLabel);\n marker.setAttribute(\"aria-describedby\", this.tooltip.tooltipId);\n setText(marker, isResolved ? \"\\u2713\" : String(number));\n\n marker.addEventListener(\"mouseenter\", () => {\n marker.style.transform = \"scale(1.2)\";\n marker.style.boxShadow = isResolved\n ? \"0 4px 16px rgba(0,0,0,0.1)\"\n : `0 4px 20px ${typeColor}35, 0 4px 12px rgba(0,0,0,0.08)`;\n this.tooltip.show(feedback, marker.getBoundingClientRect());\n if (!this.pinnedFeedback) this.showHighlight(feedback);\n });\n\n marker.addEventListener(\"mouseleave\", () => {\n marker.style.transform = \"scale(1)\";\n marker.style.boxShadow = isResolved\n ? \"0 2px 8px rgba(0,0,0,0.06)\"\n : `0 2px 12px ${typeColor}25, 0 2px 6px rgba(0,0,0,0.06)`;\n this.tooltip.scheduleHide();\n if (!this.pinnedFeedback) this.clearHighlight();\n });\n\n // WCAG 1.4.13 — tooltip must be reachable via keyboard (focus), not only\n // hover. Mirror mouseenter/mouseleave behaviour for focus/blur so a sighted\n // keyboard user gets the same affordance as a mouse user.\n marker.addEventListener(\"focus\", () => {\n this.tooltip.show(feedback, marker.getBoundingClientRect());\n if (!this.pinnedFeedback) this.showHighlight(feedback);\n });\n\n marker.addEventListener(\"blur\", () => {\n this.tooltip.scheduleHide();\n if (!this.pinnedFeedback) this.clearHighlight();\n });\n\n const activateMarker = (e: MouseEvent | KeyboardEvent) => {\n if (e instanceof MouseEvent && this.handleClusterClick(marker, e)) return;\n this.pinHighlight(feedback);\n this.bus.emit(\"panel:toggle\", true);\n marker.dispatchEvent(\n new CustomEvent(\"sp-marker-click\", {\n detail: { feedbackId: feedback.id },\n bubbles: true,\n }),\n );\n };\n\n marker.addEventListener(\"click\", (e) => activateMarker(e));\n marker.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n activateMarker(e);\n }\n });\n\n return marker;\n }\n\n highlight(feedbackId: string): void {\n for (const entry of this.entries) {\n if (entry.feedback.id === feedbackId) {\n for (const markerEl of entry.elements) {\n markerEl.style.animation = \"sp-pulse-ring 0.7s ease-out\";\n markerEl.addEventListener(\n \"animationend\",\n () => {\n markerEl.style.animation = \"\";\n },\n { once: true },\n );\n }\n }\n }\n }\n\n showHighlight(feedback: FeedbackResponse): void {\n this.removeHighlightElements();\n for (const annotation of feedback.annotations) {\n const resolved = resolveAnnotation(toAnchorData(annotation), toRectData(annotation));\n if (!resolved) continue;\n\n const typeColor = getTypeColor(feedback.type, this.colors);\n const rect = resolved.rect;\n const highlight = el(\"div\", {\n style: `\n position:absolute;\n top:${rect.top + window.scrollY}px;\n left:${rect.left + window.scrollX}px;\n width:${rect.width}px;height:${rect.height}px;\n border:2px solid ${typeColor};\n background:${typeColor}0c;\n border-radius:8px;\n pointer-events:none;z-index:-1;\n opacity:0;\n box-shadow:0 0 16px ${typeColor}20;\n transition:opacity ${HIGHLIGHT_FADE}ms ease;\n `,\n });\n this.container.appendChild(highlight);\n this.highlightElements.push(highlight);\n void highlight.offsetHeight; // Force reflow for CSS transition\n highlight.style.opacity = \"1\";\n }\n }\n\n pinHighlight(feedback: FeedbackResponse): void {\n this.unpinHighlight();\n this.showHighlight(feedback);\n this.pinnedFeedback = feedback;\n this.onDocumentClick = (e: MouseEvent) => {\n if (this.container.contains(e.target as Node)) return;\n this.unpinHighlight();\n };\n document.addEventListener(\"click\", this.onDocumentClick, { capture: true });\n }\n\n private unpinHighlight(): void {\n if (this.onDocumentClick) {\n document.removeEventListener(\"click\", this.onDocumentClick, { capture: true });\n this.onDocumentClick = null;\n }\n this.pinnedFeedback = null;\n this.clearHighlight();\n }\n\n private clearHighlight(): void {\n for (const h of this.highlightElements) {\n h.style.opacity = \"0\";\n setTimeout(() => h.remove(), HIGHLIGHT_FADE);\n }\n this.highlightElements = [];\n }\n\n private removeHighlightElements(): void {\n for (const h of this.highlightElements) h.remove();\n this.highlightElements = [];\n }\n\n clear(): void {\n this.unpinHighlight();\n this.container.replaceChildren();\n this.entries = [];\n this.clusters = [];\n this.anchorCache.clear();\n }\n\n destroy(): void {\n this.unpinHighlight();\n if (this.repositionTimer) {\n if (\"cancelIdleCallback\" in window) {\n window.cancelIdleCallback(this.repositionTimer);\n }\n clearTimeout(this.repositionTimer);\n }\n if (this.resizeHandler) window.removeEventListener(\"resize\", this.resizeHandler);\n if (this.scrollHandler) window.removeEventListener(\"scroll\", this.scrollHandler, { capture: true });\n if (this.onDocumentClickForClusters) document.removeEventListener(\"click\", this.onDocumentClickForClusters);\n this.mutationObserver?.disconnect();\n this.container.remove();\n }\n}\n","import {\n type AnnotationRecord,\n type AnnotationResponse,\n type FeedbackPayload,\n type FeedbackRecord,\n type FeedbackResponse,\n flattenAnnotation,\n type SitepingStore,\n} from \"@siteping/core\";\nimport type { GetFeedbacksOptions, WidgetClient } from \"./api-client.js\";\n\n/**\n * `WidgetClient` implementation that delegates directly to a `SitepingStore`.\n *\n * Used in client-side mode — the widget calls the store in-process instead of\n * making HTTP requests. Handles the same conversions the HTTP handler normally\n * performs: flattening annotations and serializing dates.\n */\nexport class StoreClient implements WidgetClient {\n constructor(\n private readonly store: SitepingStore,\n private readonly projectName: string,\n ) {}\n\n async sendFeedback(payload: FeedbackPayload): Promise<FeedbackResponse> {\n const record = await this.store.createFeedback({\n projectName: payload.projectName,\n type: payload.type,\n message: payload.message,\n status: \"open\",\n url: payload.url,\n urlPattern: payload.urlPattern ?? null,\n viewport: payload.viewport,\n userAgent: payload.userAgent,\n authorName: payload.authorName,\n authorEmail: payload.authorEmail,\n clientId: payload.clientId,\n annotations: payload.annotations.map(flattenAnnotation),\n screenshotDataUrl: payload.screenshotDataUrl ?? null,\n });\n\n return toResponse(record);\n }\n\n async getFeedbacks(\n projectName: string,\n options?: GetFeedbacksOptions,\n ): Promise<{ feedbacks: FeedbackResponse[]; total: number }> {\n const { feedbacks, total } = await this.store.getFeedbacks({\n projectName,\n page: options?.page,\n limit: options?.limit,\n type: options?.type,\n status: options?.status,\n search: options?.search,\n url: options?.url,\n urlPattern: options?.urlPattern,\n });\n\n return { feedbacks: feedbacks.map(toResponse), total };\n }\n\n async resolveFeedback(id: string, resolved: boolean): Promise<FeedbackResponse> {\n const record = await this.store.updateFeedback(id, {\n status: resolved ? \"resolved\" : \"open\",\n resolvedAt: resolved ? new Date() : null,\n });\n return toResponse(record);\n }\n\n async deleteFeedback(id: string): Promise<void> {\n await this.store.deleteFeedback(id);\n }\n\n async deleteAllFeedbacks(projectName: string): Promise<void> {\n await this.store.deleteAllFeedbacks(projectName);\n }\n}\n\n// ---------------------------------------------------------------------------\n// FeedbackRecord (Date) → FeedbackResponse (string) serialization\n// ---------------------------------------------------------------------------\n\nfunction toResponse(record: FeedbackRecord): FeedbackResponse {\n return {\n id: record.id,\n projectName: record.projectName,\n type: record.type,\n message: record.message,\n status: record.status,\n url: record.url,\n urlPattern: record.urlPattern ?? null,\n viewport: record.viewport,\n userAgent: record.userAgent,\n authorName: record.authorName,\n authorEmail: record.authorEmail,\n resolvedAt: record.resolvedAt?.toISOString() ?? null,\n createdAt: record.createdAt.toISOString(),\n updatedAt: record.updatedAt.toISOString(),\n annotations: record.annotations.map(toAnnotationResponse),\n screenshotUrl: record.screenshotUrl ?? null,\n diagnostics: record.diagnostics ?? null,\n };\n}\n\nfunction toAnnotationResponse(ann: AnnotationRecord): AnnotationResponse {\n return {\n id: ann.id,\n feedbackId: ann.feedbackId,\n cssSelector: ann.cssSelector,\n xpath: ann.xpath,\n textSnippet: ann.textSnippet,\n elementTag: ann.elementTag,\n elementId: ann.elementId,\n textPrefix: ann.textPrefix,\n textSuffix: ann.textSuffix,\n fingerprint: ann.fingerprint,\n neighborText: ann.neighborText,\n anchorKey: ann.anchorKey ?? null,\n xPct: ann.xPct,\n yPct: ann.yPct,\n wPct: ann.wPct,\n hPct: ann.hPct,\n scrollX: ann.scrollX,\n scrollY: ann.scrollY,\n viewportW: ann.viewportW,\n viewportH: ann.viewportH,\n devicePixelRatio: ann.devicePixelRatio,\n createdAt: ann.createdAt.toISOString(),\n };\n}\n","/**\n * CSS keyframes and animation utilities — Glassmorphism edition.\n *\n * Uses CSS-only spring animations via linear() timing function\n * and refined easing curves for premium motion design.\n */\n\n// Spring easing — computed from a spring simulation (damping: 15, stiffness: 100)\nconst SPRING_LINEAR = `linear(0, 0.006, 0.025, 0.06, 0.11, 0.17, 0.25, 0.34, 0.45, 0.56, 0.67, 0.78, 0.88, 0.95, 1.01, 1.04, 1.05, 1.04, 1.02, 1, 0.99, 1)`;\n\n// Ease-out-expo — fast start, smooth deceleration\nconst EASE_OUT_EXPO = `cubic-bezier(0.16, 1, 0.3, 1)`;\n\n// Spring overshoot — bouncy entrance\nconst SPRING_OVERSHOOT = `cubic-bezier(0.34, 1.56, 0.64, 1)`;\n\n// Smooth decel — for glass transitions\nconst EASE_OUT_QUART = `cubic-bezier(0.25, 1, 0.5, 1)`;\n\nexport const ANIMATION_CSS = `\n /* ---- Keyframes ---- */\n\n @keyframes sp-fab-in {\n from {\n transform: scale(0) rotate(-180deg);\n opacity: 0;\n }\n to {\n transform: scale(1) rotate(0deg);\n opacity: 1;\n }\n }\n\n @keyframes sp-fab-glow {\n 0%, 100% { box-shadow: 0 4px 20px var(--sp-accent-glow), 0 2px 8px rgba(0, 0, 0, 0.08); }\n 50% { box-shadow: 0 4px 28px var(--sp-accent-glow), 0 2px 12px rgba(0, 0, 0, 0.1); }\n }\n\n @keyframes sp-marker-in {\n 0% {\n transform: scale(0);\n opacity: 0;\n }\n 60% {\n transform: scale(1.2);\n opacity: 1;\n }\n 100% {\n transform: scale(1);\n }\n }\n\n @keyframes sp-pulse-ring {\n 0% {\n box-shadow: 0 0 0 0 var(--sp-accent-glow);\n }\n 70% {\n box-shadow: 0 0 0 8px transparent;\n }\n 100% {\n box-shadow: 0 0 0 0 transparent;\n }\n }\n\n @keyframes sp-flash-bg {\n 0% { background-color: var(--sp-accent-light); }\n 100% { background-color: transparent; }\n }\n\n @keyframes sp-slide-up {\n from {\n transform: translateY(8px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n }\n\n @keyframes sp-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n\n @keyframes sp-shimmer {\n 0% { background-position: -200% 0; }\n 100% { background-position: 200% 0; }\n }\n\n /* ---- Animation classes ---- */\n\n .sp-anim-fab-in {\n animation: sp-fab-in 0.5s ${SPRING_LINEAR} both;\n }\n\n .sp-anim-marker-in {\n animation: sp-marker-in 0.35s ${SPRING_OVERSHOOT} both;\n }\n\n .sp-anim-pulse {\n animation: sp-pulse-ring 0.7s ease-out;\n }\n\n .sp-anim-flash {\n animation: sp-flash-bg 0.5s ${EASE_OUT_QUART};\n }\n\n .sp-anim-slide-up {\n animation: sp-slide-up 0.3s ${EASE_OUT_EXPO} both;\n }\n\n .sp-anim-fade-in {\n animation: sp-fade-in 0.2s ease-out both;\n }\n\n /* ---- Transition utilities ---- */\n\n .sp-panel {\n transform: translateX(110%);\n transition: transform 0.4s ${EASE_OUT_EXPO};\n }\n\n .sp-panel.sp-panel--open {\n transform: translateX(0);\n }\n\n .sp-radial-item {\n opacity: 0;\n pointer-events: none;\n transform: translate(0, 0) scale(0.8);\n transition:\n transform 0.35s ${SPRING_OVERSHOOT},\n opacity 0.2s ease,\n background 0.2s ease,\n border-color 0.2s ease,\n box-shadow 0.2s ease;\n }\n\n .sp-radial-item.sp-radial-item--open {\n opacity: 1;\n pointer-events: auto;\n }\n\n /* Stagger delay via CSS custom property --sp-i */\n .sp-radial-item {\n transition-delay: calc(var(--sp-i, 0) * 50ms);\n }\n\n /* ---- Card stagger animation ---- */\n\n @keyframes sp-card-in {\n from {\n transform: translateY(12px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n }\n\n .sp-card {\n animation: sp-card-in 0.35s ${EASE_OUT_EXPO} both;\n animation-delay: calc(var(--sp-card-i, 0) * 40ms);\n }\n\n /* ---- Loading spinner ---- */\n\n @keyframes sp-spin {\n to { transform: rotate(360deg); }\n }\n\n .sp-spinner {\n width: 20px;\n height: 20px;\n border: 2px solid var(--sp-border);\n border-top-color: var(--sp-accent);\n border-radius: 50%;\n animation: sp-spin 0.6s linear infinite;\n }\n\n /* ---- Badge bounce ---- */\n\n @keyframes sp-badge-in {\n 0% { transform: scale(0); }\n 60% { transform: scale(1.3); }\n 100% { transform: scale(1); }\n }\n\n .sp-fab-badge {\n animation: sp-badge-in 0.4s ${SPRING_OVERSHOOT} both;\n }\n\n /* ---- Reduced motion ---- */\n\n @media (prefers-reduced-motion: reduce) {\n *, *::before, *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n }\n\n`;\n","import { Z_INDEX_MAX } from \"../constants.js\";\nimport { EXPORT_CSS } from \"../export-utils.js\";\nimport { BULK_CSS } from \"../panel-bulk.js\";\nimport { DETAIL_CSS } from \"../panel-detail.js\";\nimport { SORT_CSS } from \"../panel-sort.js\";\nimport { STATS_CSS } from \"../panel-stats.js\";\nimport { SHORTCUTS_CSS } from \"../shortcuts.js\";\nimport { ANIMATION_CSS } from \"./animations.js\";\nimport { cssVariables, type ThemeColors } from \"./theme.js\";\n\n/**\n * Build the complete CSS stylesheet for the Shadow DOM.\n *\n * Design: Glassmorphism — frosted glass surfaces, soft depth,\n * accent gradients, premium micro-interactions.\n *\n * Principles:\n * - :host uses `all: initial` to block inherited styles\n * - All classes prefixed with sp- (defense in depth)\n * - CSS custom properties for theming\n * - No external fonts — system-ui stack (Inter if available)\n * - :focus-visible on all interactive elements\n * - prefers-reduced-motion support\n */\nexport function buildStyles(colors: ThemeColors): string {\n return `\n :host {\n all: initial;\n position: fixed;\n z-index: ${Z_INDEX_MAX};\n font-family: var(--sp-font);\n font-size: 14px;\n line-height: 1.5;\n color: var(--sp-text);\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n ${cssVariables(colors)}\n\n /* Identity modal — theme-aware backdrop + panel */\n --sp-identity-bg: ${colors.glassBgHeavy};\n --sp-identity-overlay: ${colors.bg === \"#ffffff\" ? \"rgba(15, 23, 42, 0.2)\" : \"rgba(0, 0, 0, 0.4)\"};\n }\n\n *, *::before, *::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n }\n\n /* ============================\n Focus visible (accessibility)\n ============================ */\n\n :focus-visible {\n outline: 2px solid var(--sp-accent);\n outline-offset: 2px;\n /* Double-ring against any background colour: the bg-coloured halo\n separates the accent ring from busy host-page surfaces. */\n box-shadow: 0 0 0 4px var(--sp-bg);\n }\n\n /* ============================\n FAB (Floating Action Button)\n ============================ */\n\n .sp-fab {\n position: fixed;\n width: 52px;\n height: 52px;\n border-radius: var(--sp-radius-full);\n background: var(--sp-accent-gradient);\n color: #fff;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow:\n 0 4px 20px var(--sp-accent-glow),\n 0 2px 8px rgba(0, 0, 0, 0.08);\n transition:\n transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1),\n box-shadow 0.3s ease;\n outline: none;\n }\n\n .sp-fab:focus-visible {\n outline: 2px solid #fff;\n outline-offset: 3px;\n }\n\n .sp-fab:hover {\n transform: translateY(-2px) scale(1.05);\n box-shadow:\n 0 8px 28px var(--sp-accent-glow),\n 0 4px 12px rgba(0, 0, 0, 0.1);\n }\n\n .sp-fab:active {\n transform: translateY(0) scale(0.95);\n transition-duration: 0.1s;\n }\n\n .sp-fab--bottom-right {\n bottom: 24px;\n right: 24px;\n }\n\n .sp-fab--bottom-left {\n bottom: 24px;\n left: 24px;\n }\n\n .sp-fab svg {\n width: 22px;\n height: 22px;\n fill: currentColor;\n transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);\n }\n\n /* ---- FAB Badge ---- */\n\n .sp-fab-badge {\n position: absolute;\n top: -4px;\n right: -4px;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n border-radius: var(--sp-radius-full);\n background: #ef4444;\n color: #fff;\n font-size: 11px;\n font-weight: 700;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 2px solid #fff;\n pointer-events: none;\n font-family: var(--sp-font);\n line-height: 1;\n }\n\n /* ============================\n Radial Menu\n ============================ */\n\n .sp-radial {\n position: fixed;\n pointer-events: none;\n width: 52px;\n height: 52px;\n }\n\n .sp-radial--bottom-right {\n bottom: 24px;\n right: 24px;\n }\n\n .sp-radial--bottom-left {\n bottom: 24px;\n left: 24px;\n }\n\n .sp-radial-item {\n position: absolute;\n left: 4px;\n bottom: 4px;\n width: 44px;\n height: 44px;\n border-radius: var(--sp-radius-full);\n background: var(--sp-glass-bg-heavy);\n backdrop-filter: blur(var(--sp-blur));\n -webkit-backdrop-filter: blur(var(--sp-blur));\n color: var(--sp-text);\n border: 1px solid var(--sp-glass-border);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: var(--sp-shadow-md);\n font-size: 12px;\n font-weight: 600;\n }\n\n .sp-radial-item:hover,\n .sp-radial-item:focus-visible {\n background: rgba(255, 255, 255, 0.95);\n border-color: var(--sp-accent);\n color: var(--sp-accent);\n box-shadow:\n var(--sp-shadow-md),\n 0 0 0 3px var(--sp-accent-light);\n outline: none;\n }\n\n .sp-radial-item svg {\n width: 18px;\n height: 18px;\n flex-shrink: 0;\n stroke: currentColor;\n fill: none;\n }\n\n .sp-radial-label {\n white-space: nowrap;\n font-size: 12px;\n font-weight: 500;\n color: var(--sp-text);\n pointer-events: none;\n opacity: 0;\n padding: 4px 12px;\n border-radius: var(--sp-radius);\n background: var(--sp-glass-bg-heavy);\n backdrop-filter: blur(12px);\n -webkit-backdrop-filter: blur(12px);\n border: 1px solid var(--sp-glass-border);\n box-shadow: var(--sp-shadow-sm);\n transform: translateX(4px);\n transition: opacity 0.2s ease, transform 0.2s ease;\n }\n\n .sp-radial-item:hover .sp-radial-label,\n .sp-radial-item:focus-visible .sp-radial-label {\n opacity: 1;\n transform: translateX(0);\n }\n\n /* ============================\n Panel (Side drawer)\n ============================ */\n\n .sp-panel {\n position: fixed;\n top: 0;\n right: 0;\n width: 400px;\n max-width: 100vw;\n height: 100vh;\n height: 100dvh;\n background: var(--sp-glass-bg);\n backdrop-filter: blur(var(--sp-blur-heavy));\n -webkit-backdrop-filter: blur(var(--sp-blur-heavy));\n border-left: 1px solid var(--sp-glass-border);\n box-shadow: var(--sp-shadow-xl);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n @media (max-width: 480px) {\n .sp-panel {\n width: 100vw;\n border-left: none;\n }\n }\n\n .sp-panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n border-bottom: 1px solid var(--sp-border);\n background: var(--sp-glass-bg-heavy);\n backdrop-filter: blur(var(--sp-blur));\n -webkit-backdrop-filter: blur(var(--sp-blur));\n position: relative;\n z-index: 2;\n }\n\n .sp-panel-title {\n font-size: 17px;\n font-weight: 700;\n color: var(--sp-text);\n letter-spacing: -0.02em;\n }\n\n .sp-panel-close {\n width: 44px;\n height: 44px;\n border-radius: var(--sp-radius);\n border: none;\n background: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--sp-text-tertiary);\n transition: all 0.2s ease;\n }\n\n .sp-panel-close:hover {\n background: var(--sp-bg-hover);\n color: var(--sp-text);\n }\n\n .sp-panel-close svg {\n width: 16px;\n height: 16px;\n }\n\n /* ============================\n Filters & Search\n ============================ */\n\n .sp-filters {\n padding: 16px 24px;\n border-bottom: 1px solid var(--sp-border);\n background: var(--sp-glass-bg-heavy);\n backdrop-filter: blur(var(--sp-blur));\n -webkit-backdrop-filter: blur(var(--sp-blur));\n position: sticky;\n top: 0;\n z-index: 1;\n }\n\n .sp-search-wrap {\n position: relative;\n margin-bottom: 12px;\n }\n\n .sp-search {\n width: 100%;\n height: 40px;\n padding: 0 12px 0 38px;\n border-radius: var(--sp-radius);\n border: 1px solid var(--sp-border);\n background: var(--sp-glass-bg-heavy);\n color: var(--sp-text);\n font-family: var(--sp-font);\n font-size: 13px;\n outline: none;\n transition: all 0.2s ease;\n }\n\n .sp-search::placeholder {\n color: var(--sp-text-tertiary);\n }\n\n .sp-search:focus {\n border-color: var(--sp-accent);\n box-shadow: 0 0 0 3px var(--sp-accent-light);\n background: #fff;\n }\n\n .sp-search-icon {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--sp-text-tertiary);\n width: 16px;\n height: 16px;\n transition: color 0.2s ease;\n }\n\n .sp-search:focus ~ .sp-search-icon,\n .sp-search-wrap:focus-within .sp-search-icon {\n color: var(--sp-accent);\n }\n\n /* ============================\n Filter bar (type dropdown + status segmented)\n ============================ */\n\n .sp-filter-bar {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 8px;\n flex-wrap: wrap;\n }\n\n /* ============================\n Type filter dropdown\n ============================ */\n\n .sp-filter-dropdown {\n position: relative;\n flex: 1 1 auto;\n min-width: 0;\n }\n\n .sp-filter-dropdown-btn {\n --sp-chip-color: var(--sp-text-secondary);\n --sp-chip-bg: var(--sp-glass-bg-heavy);\n\n display: inline-flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n height: 32px;\n padding: 0 8px 0 10px;\n border-radius: var(--sp-radius-full);\n border: 1px solid var(--sp-border);\n background: var(--sp-glass-bg-heavy);\n color: var(--sp-text);\n font-family: var(--sp-font);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n white-space: nowrap;\n transition: background 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;\n }\n\n .sp-filter-dropdown-btn:hover {\n border-color: var(--sp-chip-color);\n background: var(--sp-chip-bg);\n }\n\n .sp-filter-dropdown-btn[aria-expanded=\"true\"] {\n border-color: var(--sp-chip-color);\n background: var(--sp-chip-bg);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--sp-chip-color) 14%, transparent);\n }\n\n .sp-filter-dropdown-btn--filtered {\n border-color: var(--sp-chip-color);\n background: var(--sp-chip-bg);\n }\n\n .sp-filter-dropdown-btn__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n flex-shrink: 0;\n color: var(--sp-chip-color);\n }\n\n .sp-filter-dropdown-btn__icon svg {\n width: 14px;\n height: 14px;\n }\n\n .sp-filter-dropdown-btn__label {\n display: inline-flex;\n align-items: baseline;\n gap: 6px;\n flex: 1;\n min-width: 0;\n overflow: hidden;\n }\n\n .sp-filter-dropdown-btn__prefix {\n color: var(--sp-text-tertiary);\n font-weight: 500;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n }\n\n .sp-filter-dropdown-btn__value {\n color: var(--sp-chip-color);\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .sp-filter-dropdown-btn__chevron {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n flex-shrink: 0;\n color: var(--sp-text-tertiary);\n transition: transform 0.18s ease, color 0.18s ease;\n }\n\n .sp-filter-dropdown-btn__chevron svg {\n width: 12px;\n height: 12px;\n }\n\n .sp-filter-dropdown-btn[aria-expanded=\"true\"] .sp-filter-dropdown-btn__chevron {\n transform: rotate(180deg);\n color: var(--sp-chip-color);\n }\n\n .sp-filter-dropdown-menu {\n position: absolute;\n top: calc(100% + 6px);\n left: 0;\n right: 0;\n min-width: 180px;\n padding: 4px;\n border-radius: var(--sp-radius);\n background: var(--sp-glass-bg-heavy);\n backdrop-filter: blur(var(--sp-blur-heavy));\n -webkit-backdrop-filter: blur(var(--sp-blur-heavy));\n border: 1px solid var(--sp-glass-border);\n box-shadow: var(--sp-shadow-md);\n z-index: 10;\n animation: sp-filter-menu-in 0.15s ease-out both;\n }\n\n @keyframes sp-filter-menu-in {\n from { opacity: 0; transform: translateY(-4px) scale(0.98); }\n to { opacity: 1; transform: translateY(0) scale(1); }\n }\n\n .sp-filter-dropdown-option {\n --sp-chip-color: var(--sp-text-secondary);\n --sp-chip-bg: transparent;\n\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 8px 10px;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: var(--sp-text);\n font-family: var(--sp-font);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n text-align: left;\n transition: background 0.12s ease, color 0.12s ease;\n }\n\n .sp-filter-dropdown-option__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n flex-shrink: 0;\n border-radius: 6px;\n background: var(--sp-chip-bg);\n color: var(--sp-chip-color);\n }\n\n .sp-filter-dropdown-option__icon svg {\n width: 13px;\n height: 13px;\n }\n\n .sp-filter-dropdown-option__label {\n flex: 1;\n min-width: 0;\n }\n\n .sp-filter-dropdown-option__check {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n flex-shrink: 0;\n color: var(--sp-chip-color);\n }\n\n .sp-filter-dropdown-option__check svg {\n width: 13px;\n height: 13px;\n }\n\n .sp-filter-dropdown-option:hover {\n background: var(--sp-bg-hover);\n }\n\n .sp-filter-dropdown-option--active {\n color: var(--sp-chip-color);\n font-weight: 600;\n }\n\n .sp-filter-dropdown-option--active:hover {\n background: var(--sp-chip-bg);\n }\n\n /* ============================\n Status segmented control\n ============================ */\n\n .sp-segmented {\n display: inline-flex;\n align-items: stretch;\n padding: 2px;\n border-radius: var(--sp-radius-full);\n border: 1px solid var(--sp-border);\n background: var(--sp-glass-bg-heavy);\n flex-shrink: 0;\n }\n\n .sp-segmented__btn {\n --sp-chip-color: var(--sp-text-tertiary);\n --sp-chip-bg: transparent;\n\n display: inline-flex;\n align-items: center;\n gap: 5px;\n height: 26px;\n padding: 0 10px;\n border: none;\n border-radius: var(--sp-radius-full);\n background: transparent;\n color: var(--sp-text-secondary);\n font-family: var(--sp-font);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n white-space: nowrap;\n transition: background 0.18s ease, color 0.18s ease, box-shadow 0.18s ease;\n }\n\n .sp-segmented__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 13px;\n height: 13px;\n flex-shrink: 0;\n color: var(--sp-chip-color);\n transition: color 0.18s ease, transform 0.18s ease;\n }\n\n .sp-segmented__icon svg {\n width: 13px;\n height: 13px;\n }\n\n .sp-segmented__btn:hover {\n color: var(--sp-chip-color);\n }\n\n .sp-segmented__btn:hover .sp-segmented__icon {\n color: var(--sp-chip-color);\n }\n\n .sp-segmented__btn--active {\n background: var(--sp-chip-bg);\n color: var(--sp-chip-color);\n font-weight: 600;\n box-shadow:\n inset 0 0 0 1px color-mix(in srgb, var(--sp-chip-color) 35%, transparent),\n 0 1px 2px rgba(0, 0, 0, 0.04);\n }\n\n .sp-segmented__btn--active .sp-segmented__icon {\n color: var(--sp-chip-color);\n }\n\n .sp-segmented__btn--open.sp-segmented__btn--active .sp-segmented__icon {\n animation: sp-segmented-pulse 2.4s ease-in-out infinite;\n }\n\n @keyframes sp-segmented-pulse {\n 0%, 100% { transform: scale(1); }\n 50% { transform: scale(0.85); }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .sp-filter-dropdown-btn,\n .sp-filter-dropdown-btn__chevron,\n .sp-filter-dropdown-option,\n .sp-segmented__btn,\n .sp-segmented__icon {\n transition: none;\n }\n .sp-filter-dropdown-menu {\n animation: none;\n }\n .sp-segmented__btn--open.sp-segmented__btn--active .sp-segmented__icon {\n animation: none;\n }\n }\n\n /* ============================\n Feedback Cards\n ============================ */\n\n .sp-list {\n flex: 1;\n overflow-y: auto;\n padding: 8px 12px;\n }\n\n .sp-list::-webkit-scrollbar {\n width: 6px;\n }\n\n .sp-list::-webkit-scrollbar-track {\n background: transparent;\n }\n\n .sp-list::-webkit-scrollbar-thumb {\n background: var(--sp-border);\n border-radius: var(--sp-radius-full);\n }\n\n .sp-list::-webkit-scrollbar-thumb:hover {\n background: var(--sp-text-tertiary);\n }\n\n .sp-card {\n display: flex;\n padding: 14px 16px;\n margin-bottom: 6px;\n cursor: pointer;\n border-radius: var(--sp-radius);\n background: var(--sp-glass-bg-heavy);\n border: 1px solid var(--sp-glass-border);\n box-shadow: var(--sp-shadow-xs);\n transition: all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);\n }\n\n .sp-card:hover {\n background: #fff;\n border-color: var(--sp-border);\n box-shadow: var(--sp-shadow-md);\n transform: translateY(-2px);\n }\n\n .sp-card:active {\n transform: translateY(0) scale(0.99);\n transition-duration: 0.1s;\n }\n\n .sp-card-bar {\n width: 3px;\n border-radius: var(--sp-radius-full);\n margin-right: 14px;\n flex-shrink: 0;\n }\n\n .sp-card-body {\n flex: 1;\n min-width: 0;\n }\n\n .sp-card-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n }\n\n .sp-card-number {\n font-size: 12px;\n font-weight: 700;\n color: var(--sp-text-tertiary);\n font-variant-numeric: tabular-nums;\n }\n\n .sp-badge {\n padding: 2px 10px;\n border-radius: var(--sp-radius-full);\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.02em;\n }\n\n .sp-card-date {\n font-size: 11px;\n color: var(--sp-text-tertiary);\n margin-left: auto;\n }\n\n .sp-card-message {\n font-size: 13px;\n line-height: 1.5;\n color: var(--sp-text);\n display: -webkit-box;\n -webkit-line-clamp: 3;\n -webkit-box-orient: vertical;\n overflow: hidden;\n }\n\n .sp-card-message--expanded {\n -webkit-line-clamp: unset;\n }\n\n .sp-card-expand {\n font-size: 12px;\n font-weight: 500;\n color: var(--sp-accent);\n cursor: pointer;\n background: none;\n border: none;\n padding: 4px 0;\n font-family: var(--sp-font);\n transition: opacity 0.15s ease;\n }\n\n .sp-card-expand:hover {\n opacity: 0.8;\n }\n\n .sp-card-footer {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 6px;\n margin-top: 10px;\n }\n\n .sp-btn-resolve,\n .sp-btn-delete {\n padding: 8px 14px;\n border-radius: var(--sp-radius-full);\n border: 1px solid var(--sp-border);\n background: transparent;\n color: var(--sp-text-secondary);\n font-family: var(--sp-font);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 4px;\n transition: all 0.2s ease;\n }\n\n .sp-btn-resolve svg,\n .sp-btn-delete svg {\n width: 14px;\n height: 14px;\n }\n\n .sp-btn-resolve:hover {\n border-color: #22c55e;\n color: #22c55e;\n background: rgba(34, 197, 94, 0.06);\n }\n\n .sp-btn-delete:hover {\n border-color: #ef4444;\n color: #ef4444;\n background: rgba(239, 68, 68, 0.06);\n }\n\n .sp-btn-resolve:disabled,\n .sp-btn-delete:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n }\n\n .sp-spinner--sm {\n width: 14px;\n height: 14px;\n }\n\n /* ---- Delete All (header) ---- */\n\n .sp-panel-header-right {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .sp-btn-delete-all {\n padding: 5px 12px;\n border-radius: var(--sp-radius-full);\n border: 1px solid var(--sp-border);\n background: transparent;\n color: var(--sp-text-tertiary);\n font-family: var(--sp-font);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 4px;\n transition: all 0.2s ease;\n }\n\n .sp-btn-delete-all svg {\n width: 13px;\n height: 13px;\n }\n\n .sp-btn-delete-all:hover {\n border-color: #ef4444;\n color: #ef4444;\n background: rgba(239, 68, 68, 0.06);\n }\n\n .sp-btn-delete-all:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n }\n\n /* ---- Confirm Dialog ---- */\n\n .sp-confirm-backdrop {\n position: fixed;\n inset: 0;\n background: var(--sp-backdrop, rgba(15, 23, 42, 0.2));\n backdrop-filter: blur(var(--sp-blur));\n -webkit-backdrop-filter: blur(var(--sp-blur));\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: ${Z_INDEX_MAX};\n opacity: 0;\n transition: opacity 0.2s ease;\n }\n\n .sp-confirm-dialog {\n width: 340px;\n padding: 28px;\n border-radius: 20px;\n background: var(--sp-glass-bg-heavy);\n backdrop-filter: blur(var(--sp-blur-heavy));\n -webkit-backdrop-filter: blur(var(--sp-blur-heavy));\n border: 1px solid var(--sp-glass-border);\n box-shadow: var(--sp-shadow-xl);\n font-family: var(--sp-font);\n transform: translateY(8px) scale(0.97);\n transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);\n }\n\n .sp-confirm-title {\n font-size: 17px;\n font-weight: 700;\n color: var(--sp-text);\n letter-spacing: -0.02em;\n margin-bottom: 8px;\n }\n\n .sp-confirm-message {\n font-size: 14px;\n color: var(--sp-text-secondary);\n line-height: 1.5;\n margin-bottom: 20px;\n }\n\n .sp-confirm-actions {\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n }\n\n .sp-btn-danger {\n height: 40px;\n padding: 0 22px;\n border-radius: var(--sp-radius);\n border: none;\n background: #ef4444;\n color: #fff;\n font-family: var(--sp-font);\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n box-shadow: 0 2px 8px rgba(239, 68, 68, 0.25);\n }\n\n .sp-btn-danger:hover {\n background: #dc2626;\n box-shadow: 0 4px 16px rgba(239, 68, 68, 0.3);\n transform: translateY(-1px);\n }\n\n .sp-btn-danger:active {\n transform: translateY(0) scale(0.98);\n transition-duration: 0.1s;\n }\n\n .sp-card--resolved {\n opacity: 0.5;\n }\n\n .sp-card--resolved .sp-card-message {\n text-decoration: line-through;\n text-decoration-color: var(--sp-text-tertiary);\n }\n\n /* ============================\n Loading State\n ============================ */\n\n .sp-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 48px 24px;\n }\n\n /* ============================\n Identity Form\n ============================ */\n\n .sp-identity-title {\n font-size: 17px;\n font-weight: 700;\n color: var(--sp-text);\n letter-spacing: -0.02em;\n }\n\n .sp-input {\n width: 100%;\n height: 42px;\n padding: 0 14px;\n border-radius: var(--sp-radius);\n border: 1px solid var(--sp-border);\n background: var(--sp-glass-bg-heavy);\n color: var(--sp-text);\n font-family: var(--sp-font);\n font-size: 14px;\n outline: none;\n transition: all 0.2s ease;\n }\n\n .sp-input::placeholder {\n color: var(--sp-text-tertiary);\n }\n\n .sp-input:focus {\n border-color: var(--sp-accent);\n box-shadow: 0 0 0 3px var(--sp-accent-light);\n background: #fff;\n }\n\n .sp-input-label {\n font-size: 13px;\n font-weight: 500;\n color: var(--sp-text-secondary);\n margin-bottom: 6px;\n display: block;\n }\n\n /* ============================\n Buttons\n ============================ */\n\n .sp-btn-primary {\n height: 40px;\n padding: 0 22px;\n border-radius: var(--sp-radius);\n border: none;\n background: var(--sp-accent-gradient);\n color: #fff;\n font-family: var(--sp-font);\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n box-shadow: 0 2px 8px var(--sp-accent-glow);\n }\n\n .sp-btn-primary:hover {\n box-shadow: 0 4px 16px var(--sp-accent-glow);\n transform: translateY(-1px);\n }\n\n .sp-btn-primary:active {\n transform: translateY(0) scale(0.98);\n transition-duration: 0.1s;\n }\n\n .sp-btn-primary:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n transform: none;\n box-shadow: none;\n }\n\n .sp-btn-ghost {\n height: 40px;\n padding: 0 22px;\n border-radius: var(--sp-radius);\n border: 1px solid var(--sp-border);\n background: var(--sp-glass-bg-heavy);\n color: var(--sp-text-secondary);\n font-family: var(--sp-font);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .sp-btn-ghost:hover {\n border-color: var(--sp-accent);\n color: var(--sp-accent);\n background: var(--sp-accent-light);\n }\n\n /* ============================\n Empty State\n ============================ */\n\n .sp-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 56px 24px;\n color: var(--sp-text-tertiary);\n text-align: center;\n gap: 8px;\n animation: sp-fade-in 0.3s ease-out both;\n }\n\n .sp-empty-text {\n font-size: 14px;\n font-weight: 500;\n }\n\n /* ============================\n Load More\n ============================ */\n\n .sp-load-more-wrap {\n display: flex;\n justify-content: center;\n padding: 12px 0 4px;\n }\n\n .sp-btn-load-more {\n width: 100%;\n }\n\n /* ============================\n Forced Colors / High Contrast\n ============================ */\n\n @media (forced-colors: active) {\n .sp-fab,\n .sp-radial-item,\n .sp-filter-dropdown-btn,\n .sp-segmented,\n .sp-segmented__btn,\n .sp-card,\n .sp-panel-close,\n .sp-search,\n .sp-btn-resolve,\n .sp-btn-delete,\n .sp-btn-delete-all,\n .sp-btn-primary,\n .sp-btn-ghost,\n .sp-btn-danger,\n .sp-card-expand,\n .sp-input,\n .sp-confirm-dialog {\n border: 2px solid ButtonText !important;\n background: Canvas !important;\n color: ButtonText !important;\n }\n\n .sp-segmented__btn--active {\n background: Highlight !important;\n color: HighlightText !important;\n }\n\n .sp-filter-dropdown-menu {\n border: 2px solid ButtonText !important;\n background: Canvas !important;\n }\n\n .sp-filter-dropdown-option--active {\n background: Highlight !important;\n color: HighlightText !important;\n }\n\n .sp-fab:focus-visible,\n .sp-radial-item:focus-visible,\n .sp-filter-dropdown-btn:focus-visible,\n .sp-segmented__btn:focus-visible,\n .sp-filter-dropdown-option:focus-visible,\n .sp-panel-close:focus-visible,\n .sp-btn-resolve:focus-visible,\n .sp-btn-delete:focus-visible,\n .sp-btn-delete-all:focus-visible,\n .sp-btn-primary:focus-visible,\n .sp-btn-ghost:focus-visible,\n .sp-btn-danger:focus-visible,\n .sp-card-expand:focus-visible,\n .sp-input:focus-visible,\n .sp-search:focus-visible {\n outline: 3px solid Highlight !important;\n }\n\n .sp-panel {\n border: 2px solid ButtonText !important;\n }\n\n .sp-fab-badge {\n border: 2px solid ButtonText !important;\n background: Canvas !important;\n color: ButtonText !important;\n }\n\n .sp-card-bar {\n background: ButtonText !important;\n }\n }\n\n ${ANIMATION_CSS}\n ${STATS_CSS}\n ${SORT_CSS}\n ${BULK_CSS}\n ${EXPORT_CSS}\n ${SHORTCUTS_CSS}\n ${DETAIL_CSS}\n `;\n}\n","import type { FeedbackResponse } from \"@siteping/core\";\nimport { Z_INDEX_MAX } from \"./constants.js\";\nimport { el, formatRelativeDate, setText } from \"./dom-utils.js\";\nimport { createT, getTypeLabel } from \"./i18n/index.js\";\nimport { getTypeBgColor, getTypeColor, type ThemeColors } from \"./styles/theme.js\";\n\nconst SHOW_DELAY = 120;\nconst HIDE_DELAY = 80;\n\n/**\n * Tooltip shown on annotation marker hover.\n *\n * Glassmorphism design: frosted glass with pastel badge,\n * smooth entrance animation, directional arrow.\n * Lives outside Shadow DOM.\n */\nexport class Tooltip {\n private root: HTMLElement;\n private arrow: HTMLElement;\n private showTimer: ReturnType<typeof setTimeout> | null = null;\n private hideTimer: ReturnType<typeof setTimeout> | null = null;\n private currentFeedbackId: string | null = null;\n\n readonly tooltipId = \"sp-tooltip\";\n\n constructor(\n private readonly colors: ThemeColors,\n private readonly locale: string = \"en\",\n ) {\n this.root = el(\"div\", {\n style: `\n position: fixed;\n z-index: ${Z_INDEX_MAX};\n max-width: 280px;\n padding: 12px 14px;\n border-radius: 14px;\n background: ${this.colors.glassBgHeavy};\n backdrop-filter: blur(24px);\n -webkit-backdrop-filter: blur(24px);\n border: 1px solid ${this.colors.glassBorder};\n box-shadow: 0 8px 32px ${this.colors.shadow}, 0 2px 8px ${this.colors.shadow};\n font-family: \"Inter\", system-ui, -apple-system, sans-serif;\n pointer-events: auto;\n opacity: 0;\n transform: translateY(6px) scale(0.97);\n transition: opacity 0.2s cubic-bezier(0.16, 1, 0.3, 1), transform 0.2s cubic-bezier(0.16, 1, 0.3, 1);\n visibility: hidden;\n -webkit-font-smoothing: antialiased;\n `,\n });\n\n this.root.setAttribute(\"role\", \"tooltip\");\n this.root.id = this.tooltipId;\n\n // Arrow element\n this.arrow = el(\"div\", {\n style: `\n position: absolute;\n width: 12px;\n height: 12px;\n background: ${this.colors.glassBgHeavy};\n border: 1px solid ${this.colors.glassBorder};\n transform: rotate(45deg);\n pointer-events: none;\n `,\n });\n this.root.appendChild(this.arrow);\n\n this.root.addEventListener(\"mouseenter\", () => this.cancelHide());\n this.root.addEventListener(\"mouseleave\", () => this.scheduleHide());\n document.body.appendChild(this.root);\n }\n\n show(feedback: FeedbackResponse, anchorRect: DOMRect): void {\n if (this.currentFeedbackId === feedback.id) return;\n this.cancelHide();\n this.cancelShow();\n\n this.showTimer = setTimeout(() => {\n this.currentFeedbackId = feedback.id;\n this.render(feedback);\n this.position(anchorRect);\n\n // Check prefers-reduced-motion live (not cached at construction time)\n const reduceMotion =\n typeof window !== \"undefined\" && window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n this.root.style.transition = reduceMotion ? \"none\" : \"\";\n\n this.root.style.visibility = \"visible\";\n this.root.style.opacity = \"1\";\n this.root.style.transform = \"translateY(0) scale(1)\";\n }, SHOW_DELAY);\n }\n\n scheduleHide(): void {\n this.cancelHide();\n this.hideTimer = setTimeout(() => this.hide(), HIDE_DELAY);\n }\n\n hide(): void {\n this.cancelShow();\n this.currentFeedbackId = null;\n this.root.style.opacity = \"0\";\n this.root.style.transform = \"translateY(6px) scale(0.97)\";\n setTimeout(() => {\n if (!this.currentFeedbackId) {\n this.root.style.visibility = \"hidden\";\n }\n }, 200);\n }\n\n private cancelShow(): void {\n if (this.showTimer) {\n clearTimeout(this.showTimer);\n this.showTimer = null;\n }\n }\n\n private cancelHide(): void {\n if (this.hideTimer) {\n clearTimeout(this.hideTimer);\n this.hideTimer = null;\n }\n }\n\n private render(feedback: FeedbackResponse): void {\n // Clear previous content safely (except arrow)\n const children = Array.from(this.root.children);\n for (const child of children) {\n if (child !== this.arrow) child.remove();\n }\n\n const typeColor = getTypeColor(feedback.type, this.colors);\n const typeBg = getTypeBgColor(feedback.type, this.colors);\n const t = createT(this.locale);\n const typeLabel = getTypeLabel(feedback.type, t);\n\n // Header row: badge + date\n const header = el(\"div\", { style: \"display:flex;align-items:center;gap:8px;margin-bottom:8px;\" });\n\n const badge = el(\"span\", {\n style: `\n padding:3px 10px;border-radius:9999px;\n font-size:11px;font-weight:600;\n color:${typeColor};background:${typeBg};\n letter-spacing:0.02em;\n `,\n });\n setText(badge, typeLabel);\n\n const date = el(\"span\", { style: `font-size:11px;color:${this.colors.textSecondary};margin-left:auto;` });\n setText(date, formatRelativeDate(feedback.createdAt, this.locale));\n\n header.appendChild(badge);\n header.appendChild(date);\n\n // Message body (safe — textContent only)\n const body = el(\"div\", {\n style: `font-size:13px;line-height:1.55;color:${this.colors.text};display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;`,\n });\n setText(body, feedback.message);\n\n // Insert content before arrow\n this.root.insertBefore(header, this.arrow);\n this.root.insertBefore(body, this.arrow);\n }\n\n private position(anchorRect: DOMRect): void {\n const tooltipRect = this.root.getBoundingClientRect();\n const gap = 10;\n\n let top = anchorRect.top - tooltipRect.height - gap;\n let left = anchorRect.left + anchorRect.width / 2 - tooltipRect.width / 2;\n let isAbove = true;\n\n // Flip below if not enough space above\n if (top < 8) {\n top = anchorRect.bottom + gap;\n isAbove = false;\n }\n\n left = Math.max(8, Math.min(left, window.innerWidth - tooltipRect.width - 8));\n\n this.root.style.top = `${top}px`;\n this.root.style.left = `${left}px`;\n\n // Position arrow\n const arrowLeft = Math.max(16, Math.min(anchorRect.left + anchorRect.width / 2 - left - 6, tooltipRect.width - 22));\n\n if (isAbove) {\n // Arrow at bottom, pointing down\n this.arrow.style.cssText = `\n position:absolute;\n width:12px;height:12px;\n background:${this.colors.glassBgHeavy};\n border-right:1px solid ${this.colors.glassBorder};\n border-bottom:1px solid ${this.colors.glassBorder};\n transform:rotate(45deg);\n pointer-events:none;\n bottom:-6px;\n left:${arrowLeft}px;\n `;\n } else {\n // Arrow at top, pointing up\n this.arrow.style.cssText = `\n position:absolute;\n width:12px;height:12px;\n background:${this.colors.glassBgHeavy};\n border-left:1px solid ${this.colors.glassBorder};\n border-top:1px solid ${this.colors.glassBorder};\n transform:rotate(45deg);\n pointer-events:none;\n top:-6px;\n left:${arrowLeft}px;\n `;\n }\n }\n\n /** Check if a DOM node belongs to this tooltip (for MutationObserver filtering). */\n contains(node: Node): boolean {\n return this.root.contains(node);\n }\n\n destroy(): void {\n this.cancelShow();\n this.cancelHide();\n this.root.remove();\n }\n}\n","import type {\n DiagnosticsSnapshot,\n FeedbackPayload,\n FeedbackResponse,\n PageScope,\n SitepingConfig,\n SitepingInstance,\n SitepingPublicEvents,\n} from \"@siteping/core\";\nimport { Annotator } from \"./annotator.js\";\nimport { ApiClient, flushRetryQueue, type WidgetClient } from \"./api-client.js\";\nimport { MOBILE_BREAKPOINT, PAGE_SIZE, Z_INDEX_MAX } from \"./constants.js\";\nimport { ConsoleBuffer } from \"./diagnostics/console-buffer.js\";\nimport { NetworkBuffer } from \"./diagnostics/network-buffer.js\";\nimport { EventBus, type PublicWidgetEvents, type WidgetEvents } from \"./events.js\";\nimport { Fab } from \"./fab.js\";\nimport { createT, loadLocale, type TFunction } from \"./i18n/index.js\";\nimport { getIdentity, type Identity, saveIdentity } from \"./identity.js\";\nimport { MarkerManager } from \"./markers.js\";\nimport type { Panel as PanelType } from \"./panel.js\";\nimport { StoreClient } from \"./store-client.js\";\nimport { buildStyles } from \"./styles/base.js\";\nimport { buildThemeColors } from \"./styles/theme.js\";\nimport { Tooltip } from \"./tooltip.js\";\n\n/** Singleton guard — prevents duplicate widgets from overlapping */\nlet instance: SitepingInstance | null = null;\n\ninterface NormalisedDiagnostics {\n console: boolean;\n network: boolean;\n maxConsoleEntries: number;\n maxNetworkEntries: number;\n}\n\n/**\n * Resolve `SitepingConfig.captureDiagnostics` into a normalised shape.\n *\n * - `undefined` / `false` → everything off (no monkey-patching).\n * - `true` → console + network on with the defaults (50 / 20).\n * - object → per-channel toggles + optional custom sizes; missing booleans\n * default to `true` so users can pass `{ maxConsoleEntries: 200 }` and\n * still get both channels.\n */\nfunction normaliseDiagnosticsOptions(value: SitepingConfig[\"captureDiagnostics\"]): NormalisedDiagnostics {\n if (value === undefined || value === false) {\n return { console: false, network: false, maxConsoleEntries: 50, maxNetworkEntries: 20 };\n }\n if (value === true) {\n return { console: true, network: true, maxConsoleEntries: 50, maxNetworkEntries: 20 };\n }\n return {\n console: value.console !== false,\n network: value.network !== false,\n maxConsoleEntries: typeof value.maxConsoleEntries === \"number\" ? value.maxConsoleEntries : 50,\n maxNetworkEntries: typeof value.maxNetworkEntries === \"number\" ? value.maxNetworkEntries : 20,\n };\n}\n\n/** Build a no-op SitepingInstance for when the widget is skipped */\nfunction skippedInstance(): SitepingInstance {\n const noop = () => {};\n return {\n destroy: noop,\n open: noop,\n close: noop,\n refresh: noop,\n on: () => noop,\n off: noop,\n };\n}\n\n/**\n * Main widget launcher — orchestrates all UI components.\n *\n * Architecture:\n * - Creates a <siteping-widget> custom element in the document\n * - Attaches a closed Shadow DOM for CSS isolation\n * - FAB + Panel live inside the Shadow DOM\n * - Overlay, markers, tooltips live outside (appended to document.body)\n */\nexport function launch(config: SitepingConfig): SitepingInstance {\n // Debug helper — only logs when config.debug is true\n const log: (...args: unknown[]) => void = config.debug\n ? (...args: unknown[]) => console.debug(\"[siteping]\", ...args)\n : () => {};\n\n // Guard: prevent duplicate initSiteping() calls\n if (instance) {\n log(\"initSiteping() called more than once — returning existing instance\");\n return instance;\n }\n\n // Guard: only show in development (forceShow bypasses)\n if (!config.forceShow) {\n try {\n // Check for Node/bundler production environment — avoid import.meta\n // which causes \"Critical dependency\" warnings in Next.js webpack builds\n if (typeof process !== \"undefined\" && process.env?.NODE_ENV === \"production\") {\n const reason = \"production\";\n console.info(\"[siteping] Widget not loaded: production mode detected. Use forceShow: true to override.\");\n config.onSkip?.(reason);\n return skippedInstance();\n }\n } catch {\n // Silently ignore — browser or restricted environment\n }\n }\n\n // Guard: desktop only (< MOBILE_BREAKPOINT = hidden)\n if (window.innerWidth < MOBILE_BREAKPOINT) {\n const reason = \"mobile\";\n console.info(`[siteping] Widget not loaded: viewport width < ${MOBILE_BREAKPOINT}px (mobile not supported).`);\n config.onSkip?.(reason);\n return skippedInstance();\n }\n\n // Guard: validate required config fields\n if (!config.store && (!config.endpoint || typeof config.endpoint !== \"string\")) {\n console.error(\n \"[siteping] Missing 'endpoint' or 'store' in config. Provide an endpoint like '/api/siteping' or a SitepingStore instance.\",\n );\n return skippedInstance();\n }\n if (!config.projectName || typeof config.projectName !== \"string\") {\n console.error(\"[siteping] Missing or invalid 'projectName' in config. Expected a non-empty string.\");\n return skippedInstance();\n }\n\n const locale = config.locale ?? \"en\";\n // Kick off the locale fetch immediately so the panel can render in the\n // resolved language as soon as it mounts. English is bundled synchronously\n // and used as the fallback while the chunk is in flight.\n if (locale !== \"en\") {\n loadLocale(locale).catch(() => {\n /* fallback to English — already handled by createT */\n });\n }\n const t = createT(locale);\n\n // Page scope — concrete URL + optional template, used to keep annotations\n // and panel results scoped to the current page. The widget calls this on\n // every initial markers load and on `instance.refresh()`, so SPA hosts can\n // re-fetch when the route changes.\n const scopeAnnotationsByUrl = config.scopeAnnotationsByUrl ?? true;\n const getScope = (): PageScope => {\n try {\n const result = config.getPageScope?.();\n if (result) return result;\n } catch (e) {\n log(\"getPageScope() threw, falling back to pathname:\", e);\n }\n return { url: window.location.pathname, urlPattern: null };\n };\n\n log(\"Initializing widget\", {\n projectName: config.projectName,\n theme: config.theme ?? \"light\",\n locale,\n scopeAnnotationsByUrl,\n });\n\n // Diagnostics — capture console + failed network at submit time when\n // `captureDiagnostics` is set. Buffers are installed eagerly so they\n // cover the entire session, then snapshotted in the annotation handler\n // below. We default to `false` even in dev to avoid surprise side\n // effects; users opt in via the config flag.\n const diagnosticsOpts = normaliseDiagnosticsOptions(config.captureDiagnostics);\n const consoleBuffer = diagnosticsOpts.console ? new ConsoleBuffer(diagnosticsOpts.maxConsoleEntries) : null;\n const networkBuffer = diagnosticsOpts.network ? new NetworkBuffer(diagnosticsOpts.maxNetworkEntries) : null;\n\n const colors = buildThemeColors(config.accentColor, config.theme);\n const bus = new EventBus<WidgetEvents>();\n const publicBus = new EventBus<PublicWidgetEvents>();\n\n // Client-side mode (store) vs HTTP mode (endpoint)\n const client: WidgetClient = config.store\n ? new StoreClient(config.store, config.projectName)\n : new ApiClient(config.endpoint as string, config.projectName);\n\n // Wire config callbacks to event bus\n if (config.onOpen) bus.on(\"open\", config.onOpen);\n if (config.onClose) bus.on(\"close\", config.onClose);\n if (config.onFeedbackSent) bus.on(\"feedback:sent\", config.onFeedbackSent);\n if (config.onError) bus.on(\"feedback:error\", config.onError);\n if (config.onAnnotationStart) bus.on(\"annotation:start\", config.onAnnotationStart);\n if (config.onAnnotationEnd) bus.on(\"annotation:end\", config.onAnnotationEnd);\n\n // Bridge internal events to public bus\n bus.on(\"feedback:sent\", (fb) => publicBus.emit(\"feedback:sent\", fb));\n bus.on(\"feedback:deleted\", (id) => publicBus.emit(\"feedback:deleted\", id));\n bus.on(\"open\", () => publicBus.emit(\"panel:open\"));\n bus.on(\"close\", () => publicBus.emit(\"panel:close\"));\n\n // Debug logging for key lifecycle events\n bus.on(\"open\", () => log(\"Panel opened\"));\n bus.on(\"close\", () => log(\"Panel closed\"));\n bus.on(\"feedback:sent\", (fb) => log(\"Feedback sent\", fb.id));\n bus.on(\"feedback:error\", (err) => log(\"Feedback failed\", err.message));\n bus.on(\"annotation:start\", () => log(\"Annotation started\"));\n bus.on(\"annotation:end\", () => log(\"Annotation ended\"));\n\n // Create host element + Shadow DOM\n const host = document.createElement(\"siteping-widget\");\n host.style.cssText = `position:fixed;z-index:${Z_INDEX_MAX};`;\n // Use open mode only for testing — closed in production for CSS isolation.\n // Shadow DOM mode is determined by environment, never by public config.\n let isTestEnv = false;\n try {\n // Dynamic key prevents bundlers (tsup/esbuild) from statically replacing\n // process.env.NODE_ENV at build time — the widget needs runtime detection\n // so E2E tests can set globalThis.process = { env: { NODE_ENV: 'test' } }\n const envKey = \"NODE_\" + \"ENV\";\n if (typeof process !== \"undefined\" && process.env?.[envKey] === \"test\") {\n isTestEnv = true;\n }\n } catch {\n // Silently ignore — browser or restricted environment\n }\n const shadowMode = isTestEnv ? (\"open\" as const) : (\"closed\" as const);\n const shadow = host.attachShadow({ mode: shadowMode });\n\n // Inject styles into Shadow DOM — adoptedStyleSheets with fallback for Safari < 16.4\n const supportsAdoptedStyleSheets = \"adoptedStyleSheets\" in ShadowRoot.prototype;\n if (supportsAdoptedStyleSheets) {\n const sheet = new CSSStyleSheet();\n sheet.replaceSync(buildStyles(colors));\n shadow.adoptedStyleSheets = [sheet];\n } else {\n const style = document.createElement(\"style\");\n style.textContent = buildStyles(colors);\n (shadow as unknown as DocumentFragment).appendChild(style);\n }\n\n document.body.appendChild(host);\n\n // Screen reader live region for feedback submission announcements\n const liveRegion = document.createElement(\"div\");\n liveRegion.setAttribute(\"role\", \"status\");\n liveRegion.setAttribute(\"aria-live\", \"polite\");\n liveRegion.setAttribute(\"aria-atomic\", \"true\");\n liveRegion.style.cssText =\n \"position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;\";\n document.body.appendChild(liveRegion);\n\n // Components outside Shadow DOM\n const tooltip = new Tooltip(colors, locale);\n const markers = new MarkerManager(colors, tooltip, bus, t, liveRegion);\n\n // Components inside Shadow DOM\n const fab = new Fab(shadow, config, bus, t);\n\n // Lazy-load Panel on first use (FAB click, instance.open, etc.) to keep the\n // initial bundle small. Panel + sub-modules are ~14 KB gzip on their own.\n // Memoize the import promise so subsequent calls reuse the same instance.\n let panelInstance: PanelType | null = null;\n let panelPromise: Promise<PanelType> | null = null;\n let destroyed = false;\n async function loadPanel(): Promise<PanelType | null> {\n if (destroyed) return null;\n if (panelInstance) return panelInstance;\n if (!panelPromise) {\n panelPromise = import(\"./panel.js\").then((mod) => {\n if (destroyed) return null as unknown as PanelType;\n panelInstance = new mod.Panel(shadow, colors, bus, client, config.projectName, markers, t, locale, {\n getScope,\n scopeAnnotationsByUrl,\n });\n return panelInstance;\n });\n }\n return panelPromise;\n }\n\n // Prefetch Panel in idle time so the first FAB click doesn't pay the\n // network/parse cost of the dynamic import. The chunk still ships lazily\n // (saves first-paint gzip), but it's already warming up by the time the\n // user is likely to click. Falls back to setTimeout in browsers without\n // requestIdleCallback (Safari before 17).\n if (typeof window !== \"undefined\") {\n const prefetch = () => {\n if (!destroyed) void loadPanel();\n };\n const ric = (window as { requestIdleCallback?: (cb: () => void) => void }).requestIdleCallback;\n if (typeof ric === \"function\") ric(prefetch);\n else setTimeout(prefetch, 200);\n }\n\n // The FAB emits `panel:toggle` on chat click — we intercept here so the\n // launcher (which holds the lazy loader) can drive the Panel lifecycle.\n // Panel itself also subscribes to `panel:toggle` once loaded; once the\n // dynamic import resolves we manually call `p.open()` because the missed\n // initial emit can't be replayed.\n let pendingOpen = false;\n const unsubToggle = bus.on(\"panel:toggle\", (open) => {\n if (panelInstance) return; // Real Panel already handles subsequent toggles\n if (open) {\n pendingOpen = true;\n loadPanel()\n .then((p) => {\n if (p && pendingOpen) p.open();\n pendingOpen = false;\n })\n .catch((err) => log(\"Failed to lazy-load panel:\", err));\n } else {\n pendingOpen = false;\n }\n });\n\n const annotator = new Annotator(colors, bus, t, config.enableScreenshot ?? false);\n\n // Handle annotation completion via event bus (not DOM events)\n // Concurrency guard: prevent duplicate submissions if user draws two annotations quickly\n let submitting = false;\n const unsubAnnotation = bus.on(\"annotation:complete\", async (data) => {\n if (submitting) return;\n submitting = true;\n try {\n const { annotation, type, message, screenshotDataUrl } = data;\n\n // Ensure identity\n let identity = getIdentity();\n if (!identity) {\n identity = await promptIdentity(shadow, t);\n if (!identity) return; // User cancelled\n saveIdentity(identity);\n }\n\n // crypto.randomUUID() throws in non-secure contexts (plain HTTP)\n const clientId = (() => {\n try {\n return crypto.randomUUID();\n } catch {\n return `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n }\n })();\n\n // Use scope.url as the single source of truth — same identifier the\n // panel filter and marker filter use. If we stored full URLs here while\n // filtering by pathname, freshly-created feedbacks would never match\n // their own scope filter and would vanish from the UI immediately.\n // Default scope.url is `window.location.pathname` (no query string,\n // so token/key/secret query params can't leak by construction). Hosts\n // that need origin or query in the identifier override `getPageScope`.\n const scope = getScope();\n\n // Snapshot the buffers right before submit so the captured slice\n // matches the moment the user clicked \"send\", not some earlier point.\n let diagnostics: DiagnosticsSnapshot | null = null;\n if (consoleBuffer || networkBuffer) {\n diagnostics = {\n console: consoleBuffer?.getEntries() ?? [],\n network: networkBuffer?.getEntries() ?? [],\n };\n }\n\n const payload: FeedbackPayload = {\n projectName: config.projectName,\n type,\n message,\n url: scope.url,\n urlPattern: scope.urlPattern,\n viewport: `${window.innerWidth}x${window.innerHeight}`,\n userAgent: navigator.userAgent,\n authorName: identity.name,\n authorEmail: identity.email,\n annotations: [annotation],\n clientId,\n screenshotDataUrl: screenshotDataUrl ?? null,\n diagnostics,\n };\n\n try {\n const response = await client.sendFeedback(payload);\n bus.emit(\"feedback:sent\", response);\n // Compare against the scope captured before submit (route may have\n // changed during the network round-trip — re-reading scope here\n // would race with SPA navigation).\n if (!scopeAnnotationsByUrl || response.url === scope.url) {\n markers.addFeedback(response, markers.count + 1);\n }\n liveRegion.textContent = t(\"feedback.sent.confirmation\");\n // Only refresh the panel if it has been loaded — `refresh()` is a\n // no-op when the panel is closed, so skipping the dynamic import here\n // avoids loading 14 KB of code that would otherwise do nothing.\n if (panelInstance) await panelInstance.refresh();\n } catch (error) {\n bus.emit(\"feedback:error\", error instanceof Error ? error : new Error(String(error)));\n liveRegion.textContent = t(\"feedback.error.message\");\n }\n } finally {\n submitting = false;\n }\n });\n\n // Load markers immediately on page load. We always pass the current page URL\n // when scopeAnnotationsByUrl is enabled so the server narrows results to the\n // current page — preventing annotations from one page accidentally rendering\n // on another (when CSS selectors happen to match unrelated elements).\n const initialScope = getScope();\n const initialOptions = scopeAnnotationsByUrl ? { limit: PAGE_SIZE, url: initialScope.url } : { limit: PAGE_SIZE };\n client\n .getFeedbacks(config.projectName, initialOptions)\n .then(({ feedbacks }: { feedbacks: FeedbackResponse[] }) => {\n // Defensive client-side filter — backend may not yet support the `url` query.\n const visible = scopeAnnotationsByUrl ? feedbacks.filter((f) => f.url === initialScope.url) : feedbacks;\n markers.render(visible);\n })\n .catch((err) => {\n log(\"Failed to load initial markers:\", err);\n });\n\n // Flush retry queue on load (HTTP mode only — store mode has no retry queue)\n if (config.endpoint) {\n flushRetryQueue(config.endpoint)\n .then(() => log(\"Retry queue flushed\"))\n .catch(() => {});\n }\n\n instance = {\n destroy: () => {\n log(\"Destroying widget\");\n destroyed = true;\n pendingOpen = false;\n unsubAnnotation();\n unsubToggle();\n fab.destroy();\n panelInstance?.destroy();\n annotator.destroy();\n markers.destroy();\n tooltip.destroy();\n // Restore the original console / fetch / XHR so the host page isn't\n // left with patched globals after the widget tears itself down.\n consoleBuffer?.dispose();\n networkBuffer?.dispose();\n bus.removeAll();\n publicBus.removeAll();\n liveRegion.remove();\n host.remove();\n instance = null;\n },\n open: () => {\n // Emit synchronously so consumers wired through `onOpen` / `panel:open`\n // see the open event immediately, even before the Panel module has\n // finished loading on the first call.\n bus.emit(\"panel:toggle\", true);\n },\n close: () => {\n if (panelInstance) {\n panelInstance.close();\n } else {\n // Cancel a pending open before the panel has loaded.\n pendingOpen = false;\n }\n },\n refresh: () => {\n // When the panel is open, its `refresh()` already runs `loadFeedbacks()`\n // which renders markers. Doing a second fetch here would race with that\n // one — the loser overwrites the winner's markers, off by a generation.\n // So: when the panel is open, delegate. When it's closed, fetch markers\n // ourselves (the panel won't, but SPA hosts still need the new page's\n // markers after a route change).\n if (panelInstance?.isCurrentlyOpen) {\n panelInstance.refresh();\n return;\n }\n\n const scope = getScope();\n const opts = scopeAnnotationsByUrl ? { limit: PAGE_SIZE, url: scope.url } : { limit: PAGE_SIZE };\n client\n .getFeedbacks(config.projectName, opts)\n .then(({ feedbacks }: { feedbacks: FeedbackResponse[] }) => {\n const visible = scopeAnnotationsByUrl ? feedbacks.filter((f) => f.url === scope.url) : feedbacks;\n markers.render(visible);\n })\n .catch(() => {});\n },\n on: <K extends keyof SitepingPublicEvents>(event: K, listener: (...args: SitepingPublicEvents[K]) => void) => {\n // Safe cast: SitepingPublicEvents and PublicWidgetEvents have identical keys and value types\n type TargetKey = K & keyof PublicWidgetEvents;\n return publicBus.on(event as TargetKey, listener as unknown as (...args: PublicWidgetEvents[TargetKey]) => void);\n },\n off: <K extends keyof SitepingPublicEvents>(event: K, listener: (...args: SitepingPublicEvents[K]) => void) => {\n // Safe cast: SitepingPublicEvents and PublicWidgetEvents have identical keys and value types\n type TargetKey = K & keyof PublicWidgetEvents;\n publicBus.off(event as TargetKey, listener as unknown as (...args: PublicWidgetEvents[TargetKey]) => void);\n },\n };\n\n return instance;\n}\n\n/**\n * Show a modal identity form inside the Shadow DOM.\n * Glassmorphism: frosted backdrop, glass modal, gradient CTA.\n * Returns null if the user cancels.\n */\nfunction promptIdentity(shadowRoot: ShadowRoot, t: TFunction): Promise<Identity | null> {\n return new Promise((resolve) => {\n // Save the currently focused element to restore on close\n const previouslyFocused = (shadowRoot.activeElement ?? document.activeElement) as HTMLElement | null;\n\n const backdrop = document.createElement(\"div\");\n backdrop.style.cssText = `\n position:fixed;inset:0;\n background:var(--sp-identity-overlay);\n backdrop-filter:blur(8px);\n -webkit-backdrop-filter:blur(8px);\n display:flex;align-items:center;justify-content:center;\n z-index:${Z_INDEX_MAX};\n opacity:0;transition:opacity 0.25s ease;\n `;\n\n const modal = document.createElement(\"div\");\n modal.style.cssText = `\n width:340px;padding:28px;border-radius:var(--sp-radius-xl);\n background:var(--sp-identity-bg);\n backdrop-filter:blur(var(--sp-blur-heavy));\n -webkit-backdrop-filter:blur(var(--sp-blur-heavy));\n border:1px solid var(--sp-glass-border);\n box-shadow:0 16px 48px var(--sp-shadow), 0 8px 16px var(--sp-shadow);\n font-family:var(--sp-font, \"Inter\",system-ui,-apple-system,sans-serif);\n color:var(--sp-text);\n transform:translateY(12px) scale(0.97);\n transition:transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);\n -webkit-font-smoothing:antialiased;\n `;\n\n const titleId = `sp-identity-title-${Date.now()}`;\n modal.setAttribute(\"role\", \"dialog\");\n modal.setAttribute(\"aria-modal\", \"true\");\n modal.setAttribute(\"aria-labelledby\", titleId);\n\n const title = document.createElement(\"div\");\n title.className = \"sp-identity-title\";\n title.id = titleId;\n title.textContent = t(\"identity.title\");\n title.style.marginBottom = \"20px\";\n\n const nameInputId = `sp-identity-name-${Date.now()}`;\n const emailInputId = `sp-identity-email-${Date.now()}`;\n\n const nameLabel = document.createElement(\"label\");\n nameLabel.className = \"sp-input-label\";\n nameLabel.textContent = t(\"identity.nameLabel\");\n nameLabel.setAttribute(\"for\", nameInputId);\n const nameInput = document.createElement(\"input\");\n nameInput.className = \"sp-input\";\n nameInput.id = nameInputId;\n nameInput.type = \"text\";\n nameInput.placeholder = t(\"identity.namePlaceholder\");\n nameInput.style.marginBottom = \"14px\";\n\n const emailLabel = document.createElement(\"label\");\n emailLabel.className = \"sp-input-label\";\n emailLabel.textContent = t(\"identity.emailLabel\");\n emailLabel.setAttribute(\"for\", emailInputId);\n const emailInput = document.createElement(\"input\");\n emailInput.className = \"sp-input\";\n emailInput.id = emailInputId;\n emailInput.type = \"email\";\n emailInput.placeholder = t(\"identity.emailPlaceholder\");\n\n const btnRow = document.createElement(\"div\");\n btnRow.style.cssText = \"display:flex;gap:8px;justify-content:flex-end;margin-top:20px;\";\n\n const closeModal = (result: Identity | null) => {\n backdrop.removeEventListener(\"keydown\", onKeydown);\n backdrop.style.opacity = \"0\";\n modal.style.transform = \"translateY(12px) scale(0.97)\";\n setTimeout(() => {\n backdrop.remove();\n previouslyFocused?.focus();\n resolve(result);\n }, 250);\n };\n\n const cancelBtn = document.createElement(\"button\");\n cancelBtn.className = \"sp-btn-ghost\";\n cancelBtn.textContent = t(\"identity.cancel\");\n cancelBtn.addEventListener(\"click\", () => closeModal(null));\n\n const submitBtn = document.createElement(\"button\");\n submitBtn.className = \"sp-btn-primary\";\n submitBtn.textContent = t(\"identity.submit\");\n submitBtn.addEventListener(\"click\", () => {\n const name = nameInput.value.trim();\n const email = emailInput.value.trim();\n if (!name || !email) return;\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(email)) {\n emailInput.style.borderColor = \"var(--sp-type-bug, #ef4444)\";\n return;\n }\n closeModal({ name, email });\n });\n\n // Focus trap: cycle Tab/Shift+Tab within the modal\n const focusableSelectors = 'input, button, [tabindex]:not([tabindex=\"-1\"])';\n const onKeydown = (e: Event) => {\n const ke = e as KeyboardEvent;\n if (ke.key === \"Escape\") {\n closeModal(null);\n return;\n }\n if (ke.key === \"Tab\") {\n const focusableEls = Array.from(modal.querySelectorAll<HTMLElement>(focusableSelectors));\n if (focusableEls.length === 0) return;\n const first = focusableEls[0];\n const last = focusableEls[focusableEls.length - 1];\n if (!first || !last) return;\n const active = shadowRoot.activeElement as HTMLElement | null;\n if (ke.shiftKey) {\n if (active === first || !modal.contains(active)) {\n ke.preventDefault();\n last.focus();\n }\n } else {\n if (active === last || !modal.contains(active)) {\n ke.preventDefault();\n first.focus();\n }\n }\n }\n };\n backdrop.addEventListener(\"keydown\", onKeydown);\n\n // Close on backdrop click\n backdrop.addEventListener(\"click\", (e) => {\n if (e.target === backdrop) closeModal(null);\n });\n\n btnRow.appendChild(cancelBtn);\n btnRow.appendChild(submitBtn);\n\n modal.appendChild(title);\n modal.appendChild(nameLabel);\n modal.appendChild(nameInput);\n modal.appendChild(emailLabel);\n modal.appendChild(emailInput);\n modal.appendChild(btnRow);\n backdrop.appendChild(modal);\n\n shadowRoot.appendChild(backdrop);\n\n // Animate in\n requestAnimationFrame(() => {\n backdrop.style.opacity = \"1\";\n modal.style.transform = \"translateY(0) scale(1)\";\n nameInput.focus();\n });\n });\n}\n","import type { SitepingConfig, SitepingInstance } from \"@siteping/core\";\nimport { launch } from \"./launcher.js\";\n\nexport type {\n AnchorData,\n AnnotationPayload,\n AnnotationResponse,\n FeedbackPayload,\n FeedbackResponse,\n FeedbackStatus,\n FeedbackType,\n RectData,\n SitepingConfig,\n SitepingInstance,\n SitepingPublicEvents,\n SitepingStore,\n} from \"@siteping/core\";\n\nexport type { Identity } from \"./identity.js\";\n\n/**\n * Initialize the Siteping feedback widget.\n *\n * @example\n * ```ts\n * import { initSiteping } from '@siteping/widget'\n *\n * const { destroy } = initSiteping({\n * endpoint: '/api/siteping',\n * projectName: 'my-project',\n * })\n * ```\n */\nexport function initSiteping(config: SitepingConfig): SitepingInstance {\n return launch(config);\n}\n","/**\n * React helper for `@siteping/widget`.\n *\n * `useSiteping` initialises the widget once for the lifetime of the component\n * tree, even under React.StrictMode's double-invoke effect dance. Returns the\n * `SitepingInstance` so consumers can drive `open()` / `close()` / `refresh()`\n * programmatically from anywhere in their tree.\n *\n * Why a dedicated entry instead of a snippet in the README:\n * - StrictMode mounts every effect twice in dev, which the obvious\n * `useEffect(() => { const i = initSiteping(...); return i.destroy }, [])`\n * handles fine for *re-mount*, but not for the brief window where the\n * second mount sees a still-alive widget (the widget's own singleton guard\n * logs an info message and returns the existing instance — surprising\n * noise for developers).\n * - The hook also captures the latest `config` in a ref so callbacks (e.g.\n * `onFeedbackSent`) read closure values without re-initialising the widget.\n *\n * Peer dep on react ≥ 18 (declared as optional in package.json), so projects\n * that never import `@siteping/widget/react` don't need React installed.\n */\n\nimport type { SitepingConfig, SitepingInstance } from \"@siteping/core\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { initSiteping } from \"./index.js\";\n\n/**\n * Initialise the SitePing widget for the lifetime of the calling component.\n *\n * Safe to call from a Server Component file as long as the component itself\n * is marked `\"use client\"` — the hook bails out cleanly on the server because\n * `useEffect` never runs there.\n *\n * @example Next.js App Router\n * ```tsx\n * \"use client\"\n * import { useSiteping } from \"@siteping/widget/react\"\n *\n * export function FeedbackProvider({ children }: { children: React.ReactNode }) {\n * useSiteping({\n * endpoint: \"/api/siteping\",\n * projectName: \"my-app\",\n * })\n * return <>{children}</>\n * }\n * ```\n *\n * @example Driving the panel programmatically\n * ```tsx\n * \"use client\"\n * import { useSiteping } from \"@siteping/widget/react\"\n *\n * export function HelpButton() {\n * const widget = useSiteping({ endpoint: \"/api/siteping\", projectName: \"my-app\" })\n * return <button onClick={() => widget?.open()}>Need help?</button>\n * }\n * ```\n */\nexport function useSiteping(config: SitepingConfig): SitepingInstance | null {\n // Keep callbacks fresh without retriggering the init effect. The widget\n // captures the *initial* config; we mirror updated handlers via the bridge\n // below so consumers can change `onFeedbackSent` between renders without\n // tearing the widget down.\n const configRef = useRef(config);\n configRef.current = config;\n\n const [instance, setInstance] = useState<SitepingInstance | null>(null);\n\n useEffect(() => {\n // `mounted` flag deals with the StrictMode double-effect: the cleanup of\n // the first run fires between the two `init` calls, so we set the flag\n // false in cleanup and skip late state updates. The widget itself has\n // its own singleton guard, so even if we managed to call init() twice\n // in a row we'd get the same instance back.\n let mounted = true;\n const created = initSiteping(configRef.current);\n if (!mounted) {\n // Cleanup already ran (StrictMode dev edge case) — tear down to avoid\n // leaving a dangling widget in the DOM.\n created.destroy();\n return;\n }\n\n // Bridge mutable callbacks: subscribe through the widget's public event\n // bus so we can call whatever the *latest* config has set. This lets\n // hosts change `onFeedbackSent`, `onError`, etc. between renders without\n // recreating the widget.\n const unsubSent = created.on(\"feedback:sent\", (fb) => {\n configRef.current.onFeedbackSent?.(fb);\n });\n const unsubOpen = created.on(\"panel:open\", () => {\n configRef.current.onOpen?.();\n });\n const unsubClose = created.on(\"panel:close\", () => {\n configRef.current.onClose?.();\n });\n\n setInstance(created);\n\n return () => {\n mounted = false;\n unsubSent();\n unsubOpen();\n unsubClose();\n created.destroy();\n setInstance(null);\n };\n // The init effect intentionally has an empty dep array — config changes\n // are forwarded through configRef.current, not through re-init. Hosts\n // that need a fresh widget (e.g. swapping endpoint at runtime) should\n // unmount the component that owns the hook.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return instance;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../node_modules/.bun/@medv+finder@3.2.0/node_modules/@medv/finder/finder.js","../src/dom/fingerprint.ts","../src/dom/text-context.ts","../src/dom/xpath.ts","../src/dom/anchor.ts","../src/popup.ts","../src/screenshot.ts","../src/annotator.ts","../../core/src/errors.ts","../../core/src/types.ts","../src/api-client.ts","../src/diagnostics/console-buffer.ts","../src/diagnostics/network-buffer.ts","../src/events.ts","../src/fab.ts","../src/identity.ts","../src/dom/fuzzy.ts","../src/dom/resolver.ts","../src/markers.ts","../src/store-client.ts","../src/styles/animations.ts","../src/styles/base.ts","../src/tooltip.ts","../src/launcher.ts","../src/index.ts","../src/react.ts"],"names":["config","rootDocument","start","finder","input","options","defaults","name","value","findRootDocument","path","bottomUpSearch","optimized","sort","optimize","selector","rootNode","limit","fallback","stack","current","i","elapsedTime","level","maybe","id","attr","classNames","tagName","any","nth","index","dispensableNth","node","nthChild","findUniquePath","paths","combinations","candidate","unique","query","penalty","acc","css","elementId","parent","child","list","notEmpty","a","b","scope","newPath","newPathKey","same","STABLE_ATTRS","djb2","str","hash","generateFingerprint","element","childCount","siblingIdx","attrs","val","attrHash","scoreFingerprint","storedFingerprint","parts","storedChildren","storedSibIdx","storedAttrHash","storedChildCount","storedSibIndex","candidateFp","candChildren","candSibIdx","candAttrHash","score","childDiff","sibDiff","adjacentText","direction","prop","sibling","attempts","text","neighborText","prev","next","generateXPath","safeId","segments","tag","position","ANCHOR_KEY_ATTR","generateAnchor","cssSelector","xpath","textSnippet","textPrefix","textSuffix","fingerprint","neighbor","anchorKey","containsRect","el","rect","findAnchorElement","root","centerX","centerY","elementAtCenter","rectToPercentages","anchorBounds","Popup","colors","t","typeOptions","ICON_QUESTION","ICON_CHANGE","ICON_BUG","ICON_OTHER","typeRow","option","btn","icon","parseSvg","labelSpan","setText","bgColor","getTypeBgColor","getTypeColor","hint","uaData","isMac","e","btnRow","cancelBtn","rectBounds","resolve","popupH","popupW","top","left","aboveTop","focusableEls","first","last","reduceMotion","type","container","buttons","isActive","color","enabled","cachedHtml2Canvas","warnedAboutMissingDep","loadHtml2Canvas","mod","err","captureScreenshot","html2canvas","quality","maxWidth","canvas","ratio","targetW","targetH","scaled","ctx","Annotator","bus","enableScreenshot","dot","style","instruction","target","bounds","result","annotation","screenshotDataUrl","touch","clientX","clientY","source","evt","x","y","w","h","anchorElement","anchor","SitepingError","message","code","retryable","SitepingNetworkError","SitepingValidationError","SitepingAuthError","flattenAnnotation","ann","errorFromResponse","response","label","detail","networkErrorFromException","error","MAX_RETRIES","TIMEOUT_MS","RETRY_QUEUE_KEY","MAX_QUEUE_SIZE","resilientFetch","url","init","retries","attempt","controller","timeout","baseDelay","jitter","r","LOCK_NAME","withRetryLock","callback","queueForRetry","endpoint","payload","raw","parsed","queue","flushRetryQueue","toRetry","failed","entry","remaining","ApiClient","projectName","params","resolved","LEVELS","serializeArg","arg","seen","_key","formatArgs","args","out","ConsoleBuffer","maxEntries","original","buffer","wrapped","truncateUrl","urlString","NetworkBuffer","startedAt","t0","method","t1","proto","originalOpen","originalSend","meta","rest","body","info","onEnd","status","EventBus","event","listener","set","fn","ITEM_GAP","Fab","shadowRoot","isRight","ICON_CHAT","ICON_ANNOTATE","ICON_EYE","ICON_EYE_OFF","ICON_SITEPING","item","host","handleEscape","items","activeEl","currentIndex","nextIndex","count","displayText","ICON_CLOSE","svgStr","badge","STORAGE_KEY","getIdentity","identity","saveIdentity","editDistance","aLen","bLen","k","curr","j","prevDiag","tmp","similarity","maxLen","fuzzyIncludes","haystack","needle","minScore","nLen","best","capped","window","MAX_SCAN_CANDIDATES","TEXT_MATCH_THRESHOLD","textMatches","resolveAnchor","escaped","smartScan","candidates","bestElement","bestScore","scoreCandidate","totalWeight","candidateText","contextScore","contextParts","prevText","nextText","candidateNeighbor","resolveAnnotation","resolution","absoluteRect","toAnchorData","toRectData","MARKER_OFFSET","markerPosition","clusterMarker","cluster","elIdx","HIGHLIGHT_FADE","REPOSITION_DEBOUNCE","LOW_CONFIDENCE_THRESHOLD","CLUSTER_DISTANCE","FAN_SPACING","MarkerManager","tooltip","liveRegion","visible","mutations","hasRelevantMutation","m","validKeys","markerEl","cacheKey","cachedEl","anchorRect","pos","key","feedbacks","feedback","marker","allItems","used","itemI","itemJ","baseTop","baseLeft","isSolo","totalWidth","startLeft","topMarker","confidence","isResolved","number","typeColor","truncatedMessage","ariaLabel","getTypeLabel","activateMarker","feedbackId","highlight","StoreClient","store","record","toResponse","total","toAnnotationResponse","SPRING_LINEAR","EASE_OUT_EXPO","SPRING_OVERSHOOT","EASE_OUT_QUART","ANIMATION_CSS","buildStyles","cssVariables","STATS_CSS","SORT_CSS","BULK_CSS","EXPORT_CSS","SHORTCUTS_CSS","DETAIL_CSS","SHOW_DELAY","HIDE_DELAY","Tooltip","locale","children","typeBg","createT","typeLabel","header","date","formatRelativeDate","tooltipRect","gap","isAbove","arrowLeft","instance","normaliseDiagnosticsOptions","skippedInstance","noop","normaliseDeepLinkOptions","launch","log","reason","loadLocale","scopeAnnotationsByUrl","getScope","diagnosticsOpts","consoleBuffer","networkBuffer","buildThemeColors","publicBus","client","fb","isTestEnv","shadowMode","shadow","sheet","markers","fab","panelInstance","panelPromise","destroyed","loadPanel","prefetch","ric","pendingOpen","unsubToggle","open","p","annotator","submitting","unsubAnnotation","data","promptIdentity","clientId","diagnostics","initialScope","initialOptions","deepLinkOpts","f","focusId","matched","opts","previouslyFocused","backdrop","modal","titleId","title","nameInputId","emailInputId","nameLabel","nameInput","emailLabel","emailInput","closeModal","onKeydown","submitBtn","email","focusableSelectors","ke","active","initSiteping","useSiteping","configRef","useRef","setInstance","useState","useEffect","mounted","created","unsubSent","unsubOpen","unsubClose"],"mappings":"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AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAAA,EA21BtF,UAAW,CAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA,IAAA,EAuStBwR,EAAa;AAAA,IAAA,EACbG,GAAS;AAAA,IAAA,EACTC,CAAQ;AAAA,IAAA,EACRC,CAAQ;AAAA,IAAA,EACRC,CAAU;AAAA,IAAA,EACVC,CAAa;AAAA,IAAA,EACbC,GAAU;AAAA,EAAA,CAEhB,CC5qCA,IAAMC,EAAAA,CAAa,GAAA,CACbC,GAAa,EAAA,CASNC,EAAAA,CAAN,KAAc,CASnB,WAAA,CACmBnS,CAAAA,CACAoS,EAAiB,IAAA,CAClC,CAFiB,IAAA,CAAA,MAAA,CAAApS,CAAAA,CACA,IAAA,CAAA,MAAA,CAAAoS,CAAAA,CAEjB,KAAK,IAAA,CAAO9S,CAAAA,CAAG,KAAA,CAAO,CACpB,KAAA,CAAO;AAAA;AAAA,iBAAA,EAEM,UAAW,CAAA;AAAA;AAAA;AAAA;AAAA,oBAAA,EAIR,IAAA,CAAK,OAAO,YAAY,CAAA;AAAA;AAAA;AAAA,0BAAA,EAGlB,IAAA,CAAK,OAAO,WAAW,CAAA;AAAA,+BAAA,EAClB,KAAK,MAAA,CAAO,MAAM,CAAA,YAAA,EAAe,IAAA,CAAK,OAAO,MAAM,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAAA,CAShF,CAAC,CAAA,CAED,IAAA,CAAK,KAAK,YAAA,CAAa,MAAA,CAAQ,SAAS,CAAA,CACxC,IAAA,CAAK,IAAA,CAAK,EAAA,CAAK,KAAK,SAAA,CAGpB,IAAA,CAAK,MAAQA,CAAAA,CAAG,KAAA,CAAO,CACrB,KAAA,CAAO;AAAA;AAAA;AAAA;AAAA,oBAAA,EAIS,IAAA,CAAK,OAAO,YAAY,CAAA;AAAA,0BAAA,EAClB,IAAA,CAAK,OAAO,WAAW,CAAA;AAAA;AAAA;AAAA,MAAA,CAI/C,CAAC,CAAA,CACD,IAAA,CAAK,IAAA,CAAK,WAAA,CAAY,IAAA,CAAK,KAAK,CAAA,CAEhC,IAAA,CAAK,IAAA,CAAK,gBAAA,CAAiB,YAAA,CAAc,IAAM,KAAK,UAAA,EAAY,CAAA,CAChE,IAAA,CAAK,IAAA,CAAK,gBAAA,CAAiB,YAAA,CAAc,IAAM,IAAA,CAAK,YAAA,EAAc,CAAA,CAClE,QAAA,CAAS,IAAA,CAAK,YAAY,IAAA,CAAK,IAAI,EACrC,CA7CmB,MAAA,CACA,MAAA,CAVX,IAAA,CACA,KAAA,CACA,SAAA,CAAkD,IAAA,CAClD,SAAA,CAAkD,IAAA,CAClD,iBAAA,CAAmC,IAAA,CAElC,SAAA,CAAY,YAAA,CAkDrB,IAAA,CAAKkQ,CAAAA,CAA4BJ,CAAAA,CAA2B,CACtD,IAAA,CAAK,iBAAA,GAAsBI,CAAAA,CAAS,EAAA,GACxC,IAAA,CAAK,UAAA,EAAW,CAChB,IAAA,CAAK,UAAA,EAAW,CAEhB,KAAK,SAAA,CAAY,UAAA,CAAW,IAAM,CAChC,IAAA,CAAK,iBAAA,CAAoBA,CAAAA,CAAS,EAAA,CAClC,IAAA,CAAK,MAAA,CAAOA,CAAQ,CAAA,CACpB,IAAA,CAAK,QAAA,CAASJ,CAAU,CAAA,CAGxB,IAAMnN,CAAAA,CACJ,OAAO,MAAA,CAAW,GAAA,EAAe,MAAA,CAAO,UAAA,CAAW,kCAAkC,CAAA,CAAE,OAAA,CACzF,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,WAAaA,CAAAA,CAAe,MAAA,CAAS,EAAA,CAErD,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,UAAA,CAAa,SAAA,CAC7B,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,OAAA,CAAU,GAAA,CAC1B,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,SAAA,CAAY,yBAC9B,CAAA,CAAGgQ,EAAU,CAAA,EACf,CAEA,YAAA,EAAqB,CACnB,IAAA,CAAK,UAAA,EAAW,CAChB,IAAA,CAAK,SAAA,CAAY,UAAA,CAAW,IAAM,IAAA,CAAK,IAAA,EAAK,CAAGC,EAAU,EAC3D,CAEA,IAAA,EAAa,CACX,IAAA,CAAK,UAAA,EAAW,CAChB,IAAA,CAAK,iBAAA,CAAoB,IAAA,CACzB,KAAK,IAAA,CAAK,KAAA,CAAM,OAAA,CAAU,GAAA,CAC1B,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,SAAA,CAAY,6BAAA,CAC5B,UAAA,CAAW,IAAM,CACV,IAAA,CAAK,iBAAA,GACR,KAAK,IAAA,CAAK,KAAA,CAAM,UAAA,CAAa,QAAA,EAEjC,CAAA,CAAG,GAAG,EACR,CAEQ,UAAA,EAAmB,CACrB,IAAA,CAAK,SAAA,GACP,YAAA,CAAa,IAAA,CAAK,SAAS,CAAA,CAC3B,IAAA,CAAK,SAAA,CAAY,IAAA,EAErB,CAEQ,UAAA,EAAmB,CACrB,IAAA,CAAK,SAAA,GACP,YAAA,CAAa,IAAA,CAAK,SAAS,CAAA,CAC3B,IAAA,CAAK,SAAA,CAAY,MAErB,CAEQ,MAAA,CAAO1C,GAAAA,CAAkC,CAE/C,IAAM6C,CAAAA,CAAW,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA,CAC9C,IAAA,IAAW3W,CAAAA,IAAS2W,CAAAA,CACd3W,CAAAA,GAAU,IAAA,CAAK,KAAA,EAAOA,CAAAA,CAAM,MAAA,EAAO,CAGzC,IAAM6U,CAAAA,CAAYvP,CAAAA,CAAawO,GAAAA,CAAS,IAAA,CAAM,IAAA,CAAK,MAAM,CAAA,CACnD8C,CAAAA,CAASvR,EAAeyO,GAAAA,CAAS,IAAA,CAAM,IAAA,CAAK,MAAM,CAAA,CAClDvP,CAAAA,CAAIsS,CAAAA,CAAQ,IAAA,CAAK,MAAM,CAAA,CACvBC,CAAAA,CAAY9B,GAAAA,CAAalB,GAAAA,CAAS,IAAA,CAAMvP,CAAC,CAAA,CAGzCwS,CAAAA,CAASnT,CAAAA,CAAG,KAAA,CAAO,CAAE,KAAA,CAAO,4DAA6D,CAAC,CAAA,CAE1F4L,CAAAA,CAAQ5L,CAAAA,CAAG,MAAA,CAAQ,CACvB,KAAA,CAAO;AAAA;AAAA;AAAA,cAAA,EAGGiR,CAAS,eAAe+B,CAAM,CAAA;AAAA;AAAA,MAAA,CAG1C,CAAC,CAAA,CACDzR,CAAAA,CAAQqK,CAAAA,CAAOsH,CAAS,EAExB,IAAME,CAAAA,CAAOpT,CAAAA,CAAG,MAAA,CAAQ,CAAE,KAAA,CAAO,CAAA,qBAAA,EAAwB,IAAA,CAAK,MAAA,CAAO,aAAa,CAAA,kBAAA,CAAqB,CAAC,CAAA,CACxGuB,CAAAA,CAAQ6R,EAAMC,CAAAA,CAAmBnD,GAAAA,CAAS,SAAA,CAAW,IAAA,CAAK,MAAM,CAAC,CAAA,CAEjEiD,CAAAA,CAAO,WAAA,CAAYvH,CAAK,CAAA,CACxBuH,CAAAA,CAAO,WAAA,CAAYC,CAAI,EAGvB,IAAMrJ,GAAAA,CAAO/J,CAAAA,CAAG,KAAA,CAAO,CACrB,KAAA,CAAO,CAAA,sCAAA,EAAyC,IAAA,CAAK,MAAA,CAAO,IAAI,CAAA,sFAAA,CAClE,CAAC,CAAA,CACDuB,CAAAA,CAAQwI,IAAMmG,GAAAA,CAAS,OAAO,CAAA,CAG9B,IAAA,CAAK,KAAK,YAAA,CAAaiD,CAAAA,CAAQ,IAAA,CAAK,KAAK,EACzC,IAAA,CAAK,IAAA,CAAK,YAAA,CAAapJ,GAAAA,CAAM,KAAK,KAAK,EACzC,CAEQ,QAAA,CAAS+F,EAA2B,CAC1C,IAAMwD,CAAAA,CAAc,IAAA,CAAK,KAAK,qBAAA,EAAsB,CAC9CC,CAAAA,CAAM,EAAA,CAERlR,EAAMyN,CAAAA,CAAW,GAAA,CAAMwD,CAAAA,CAAY,MAAA,CAASC,EAC5CjR,CAAAA,CAAOwN,CAAAA,CAAW,IAAA,CAAOA,CAAAA,CAAW,MAAQ,CAAA,CAAIwD,CAAAA,CAAY,KAAA,CAAQ,CAAA,CACpEE,EAAU,IAAA,CAGVnR,CAAAA,CAAM,CAAA,GACRA,CAAAA,CAAMyN,EAAW,MAAA,CAASyD,CAAAA,CAC1BC,CAAAA,CAAU,KAAA,CAAA,CAGZlR,EAAO,IAAA,CAAK,GAAA,CAAI,CAAA,CAAG,IAAA,CAAK,IAAIA,CAAAA,CAAM,MAAA,CAAO,UAAA,CAAagR,CAAAA,CAAY,MAAQ,CAAC,CAAC,CAAA,CAE5E,IAAA,CAAK,KAAK,KAAA,CAAM,GAAA,CAAM,CAAA,EAAGjR,CAAG,KAC5B,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,IAAA,CAAO,GAAGC,CAAI,CAAA,EAAA,CAAA,CAG9B,IAAMmR,CAAAA,CAAY,KAAK,GAAA,CAAI,EAAA,CAAI,IAAA,CAAK,GAAA,CAAI3D,EAAW,IAAA,CAAOA,CAAAA,CAAW,KAAA,CAAQ,CAAA,CAAIxN,EAAO,CAAA,CAAGgR,CAAAA,CAAY,KAAA,CAAQ,EAAE,CAAC,CAAA,CAE9GE,CAAAA,CAEF,IAAA,CAAK,KAAA,CAAM,MAAM,OAAA,CAAU;AAAA;AAAA;AAAA,mBAAA,EAGZ,IAAA,CAAK,OAAO,YAAY,CAAA;AAAA,+BAAA,EACZ,IAAA,CAAK,OAAO,WAAW,CAAA;AAAA,gCAAA,EACtB,IAAA,CAAK,OAAO,WAAW,CAAA;AAAA;AAAA;AAAA;AAAA,aAAA,EAI1CC,CAAS,CAAA;AAAA,MAAA,CAAA,CAIlB,IAAA,CAAK,KAAA,CAAM,KAAA,CAAM,OAAA,CAAU;AAAA;AAAA;AAAA,mBAAA,EAGZ,IAAA,CAAK,OAAO,YAAY,CAAA;AAAA,8BAAA,EACb,IAAA,CAAK,OAAO,WAAW,CAAA;AAAA,6BAAA,EACxB,IAAA,CAAK,OAAO,WAAW,CAAA;AAAA;AAAA;AAAA;AAAA,aAAA,EAIvCA,CAAS,CAAA;AAAA,MAAA,EAGtB,CAGA,QAAA,CAASlY,CAAAA,CAAqB,CAC5B,OAAO,KAAK,IAAA,CAAK,QAAA,CAASA,CAAI,CAChC,CAEA,OAAA,EAAgB,CACd,IAAA,CAAK,UAAA,GACL,IAAA,CAAK,UAAA,EAAW,CAChB,IAAA,CAAK,KAAK,MAAA,GACZ,CACF,CAAA,CC1MA,IAAImY,EAAAA,CAAoC,IAAA,CAkBxC,SAASC,EAAAA,CAA4B7Z,EAAoE,CACvG,OAAIA,CAAAA,GAAU,MAAA,EAAaA,IAAU,KAAA,CAC5B,CAAE,OAAA,CAAS,KAAA,CAAO,QAAS,KAAA,CAAO,iBAAA,CAAmB,EAAA,CAAI,iBAAA,CAAmB,EAAG,CAAA,CAEpFA,CAAAA,GAAU,IAAA,CACL,CAAE,QAAS,IAAA,CAAM,OAAA,CAAS,IAAA,CAAM,iBAAA,CAAmB,GAAI,iBAAA,CAAmB,EAAG,CAAA,CAE/E,CACL,QAASA,CAAAA,CAAM,OAAA,GAAY,KAAA,CAC3B,OAAA,CAASA,EAAM,OAAA,GAAY,KAAA,CAC3B,iBAAA,CAAmB,OAAOA,EAAM,iBAAA,EAAsB,QAAA,CAAWA,EAAM,iBAAA,CAAoB,EAAA,CAC3F,kBAAmB,OAAOA,CAAAA,CAAM,iBAAA,EAAsB,QAAA,CAAWA,EAAM,iBAAA,CAAoB,EAC7F,CACF,CAGA,SAAS8Z,EAAAA,EAAoC,CAC3C,IAAMC,CAAAA,CAAO,IAAM,CAAC,CAAA,CACpB,OAAO,CACL,QAASA,CAAAA,CACT,IAAA,CAAMA,CAAAA,CACN,KAAA,CAAOA,EACP,OAAA,CAASA,CAAAA,CACT,aAAA,CAAe,IAAM,MACrB,EAAA,CAAI,IAAMA,CAAAA,CACV,GAAA,CAAKA,CACP,CACF,CAeA,SAASC,EAAAA,CAAyBha,EAAuD,CACvF,OAAIA,CAAAA,GAAU,MAAA,EAAaA,IAAU,KAAA,CAAc,CAAE,OAAA,CAAS,KAAA,CAAO,MAAO,UAAW,CAAA,CACnFA,CAAAA,GAAU,IAAA,CAAa,CAAE,OAAA,CAAS,IAAA,CAAM,KAAA,CAAO,UAAW,EACvD,CAAE,OAAA,CAAS,IAAA,CAAM,KAAA,CAAOA,EAAM,KAAA,EAAS,UAAW,CAC3D,CAWO,SAASia,EAAAA,CAAOza,CAAAA,CAA0C,CAE/D,IAAM0a,EAAoC1a,CAAAA,CAAO,KAAA,CAC7C,IAAIsP,CAAAA,GAAoB,OAAA,CAAQ,MAAM,YAAA,CAAc,GAAGA,CAAI,CAAA,CAC3D,IAAM,CAAC,CAAA,CAGX,GAAI8K,EAAAA,CACF,OAAAM,CAAAA,CAAI,yEAAoE,CAAA,CACjEN,EAAAA,CAIT,GAAI,CAACpa,CAAAA,CAAO,SAAA,CACV,GAAI,CAGF,GAAI,OAAO,OAAA,CAAY,GAAA,CAGrB,OAAAA,CAAAA,CAAO,MAAA,GAFQ,YAEO,CAAA,CACfsa,IAEX,CAAA,KAAQ,CAER,CAIF,GAAI,MAAA,CAAO,UAAA,CAAa,GAAA,CAAmB,CACzC,IAAMK,CAAAA,CAAS,QAAA,CACf,OACA3a,CAAAA,CAAO,MAAA,GAAS2a,CAAM,CAAA,CACfL,IACT,CAGA,GAAI,CAACta,EAAO,KAAA,GAAU,CAACA,CAAAA,CAAO,QAAA,EAAY,OAAOA,CAAAA,CAAO,QAAA,EAAa,QAAA,CAAA,CACnE,OAAA,OAAA,CAAQ,MACN,2HACF,CAAA,CACOsa,EAAAA,EAAgB,CAEzB,GAAI,CAACta,CAAAA,CAAO,WAAA,EAAe,OAAOA,EAAO,WAAA,EAAgB,QAAA,CACvD,eAAQ,KAAA,CAAM,qFAAqF,EAC5Fsa,EAAAA,EAAgB,CAGzB,IAAMd,CAAAA,CAASxZ,EAAO,MAAA,EAAU,IAAA,CAI5BwZ,CAAAA,GAAW,IAAA,EACboB,EAAWpB,CAAM,CAAA,CAAE,KAAA,CAAM,IAAM,CAE/B,CAAC,CAAA,CAEH,IAAMnS,CAAAA,CAAIsS,EAAQH,CAAM,CAAA,CAMlBqB,CAAAA,CAAwB7a,CAAAA,CAAO,uBAAyB,IAAA,CACxD8a,CAAAA,CAAW,IAAiB,CAChC,GAAI,CACF,IAAM3P,CAAAA,CAASnL,CAAAA,CAAO,gBAAe,CACrC,GAAImL,EAAQ,OAAOA,CACrB,OAAS3C,CAAAA,CAAG,CACVkS,CAAAA,CAAI,iDAAA,CAAmDlS,CAAC,EAC1D,CACA,OAAO,CAAE,IAAK,MAAA,CAAO,QAAA,CAAS,QAAA,CAAU,UAAA,CAAY,IAAK,CAC3D,CAAA,CAEAkS,CAAAA,CAAI,qBAAA,CAAuB,CACzB,WAAA,CAAa1a,CAAAA,CAAO,WAAA,CACpB,KAAA,CAAOA,EAAO,KAAA,EAAS,OAAA,CACvB,MAAA,CAAAwZ,CAAAA,CACA,sBAAAqB,CACF,CAAC,CAAA,CAOD,IAAME,EAAkBV,EAAAA,CAA4Bra,CAAAA,CAAO,kBAAkB,CAAA,CACvEgb,CAAAA,CAAgBD,EAAgB,OAAA,CAAU,IAAIvL,EAAAA,CAAcuL,CAAAA,CAAgB,iBAAiB,CAAA,CAAI,IAAA,CACjGE,CAAAA,CAAgBF,CAAAA,CAAgB,QAAU,IAAIhL,EAAAA,CAAcgL,CAAAA,CAAgB,iBAAiB,EAAI,IAAA,CAEjG3T,CAAAA,CAAS8T,CAAAA,CAAiBlb,CAAAA,CAAO,YAAaA,CAAAA,CAAO,KAAK,CAAA,CAC1D4K,CAAAA,CAAM,IAAIiG,CAAAA,CACVsK,CAAAA,CAAY,IAAItK,CAAAA,CAGhBuK,EAAuBpb,CAAAA,CAAO,KAAA,CAChC,IAAIkY,EAAAA,CAAYlY,EAAO,KAAA,CAAOA,CAAAA,CAAO,WAAW,CAAA,CAChD,IAAI4O,EAAAA,CAAU5O,CAAAA,CAAO,QAAA,CAAoBA,CAAAA,CAAO,WAAW,CAAA,CAG3DA,CAAAA,CAAO,MAAA,EAAQ4K,CAAAA,CAAI,GAAG,MAAA,CAAQ5K,CAAAA,CAAO,MAAM,CAAA,CAC3CA,EAAO,OAAA,EAAS4K,CAAAA,CAAI,EAAA,CAAG,OAAA,CAAS5K,EAAO,OAAO,CAAA,CAC9CA,CAAAA,CAAO,cAAA,EAAgB4K,EAAI,EAAA,CAAG,eAAA,CAAiB5K,CAAAA,CAAO,cAAc,EACpEA,CAAAA,CAAO,OAAA,EAAS4K,CAAAA,CAAI,EAAA,CAAG,iBAAkB5K,CAAAA,CAAO,OAAO,EACvDA,CAAAA,CAAO,iBAAA,EAAmB4K,EAAI,EAAA,CAAG,kBAAA,CAAoB5K,CAAAA,CAAO,iBAAiB,EAC7EA,CAAAA,CAAO,eAAA,EAAiB4K,CAAAA,CAAI,EAAA,CAAG,iBAAkB5K,CAAAA,CAAO,eAAe,CAAA,CAG3E4K,CAAAA,CAAI,GAAG,eAAA,CAAkByQ,CAAAA,EAAOF,CAAAA,CAAU,IAAA,CAAK,gBAAiBE,CAAE,CAAC,CAAA,CACnEzQ,CAAAA,CAAI,GAAG,kBAAA,CAAqBnJ,CAAAA,EAAO0Z,CAAAA,CAAU,IAAA,CAAK,mBAAoB1Z,CAAE,CAAC,CAAA,CACzEmJ,CAAAA,CAAI,GAAG,MAAA,CAAQ,IAAMuQ,CAAAA,CAAU,IAAA,CAAK,YAAY,CAAC,CAAA,CACjDvQ,CAAAA,CAAI,EAAA,CAAG,QAAS,IAAMuQ,CAAAA,CAAU,IAAA,CAAK,aAAa,CAAC,CAAA,CAGnDvQ,CAAAA,CAAI,EAAA,CAAG,MAAA,CAAQ,IAAM8P,CAAAA,CAAI,cAAc,CAAC,CAAA,CACxC9P,EAAI,EAAA,CAAG,OAAA,CAAS,IAAM8P,CAAAA,CAAI,cAAc,CAAC,CAAA,CACzC9P,CAAAA,CAAI,EAAA,CAAG,gBAAkByQ,CAAAA,EAAOX,CAAAA,CAAI,eAAA,CAAiBW,CAAAA,CAAG,EAAE,CAAC,CAAA,CAC3DzQ,EAAI,EAAA,CAAG,gBAAA,CAAmBZ,GAAQ0Q,CAAAA,CAAI,iBAAA,CAAmB1Q,CAAAA,CAAI,OAAO,CAAC,CAAA,CACrEY,CAAAA,CAAI,EAAA,CAAG,kBAAA,CAAoB,IAAM8P,CAAAA,CAAI,oBAAoB,CAAC,CAAA,CAC1D9P,EAAI,EAAA,CAAG,gBAAA,CAAkB,IAAM8P,CAAAA,CAAI,kBAAkB,CAAC,CAAA,CAGtD,IAAM9I,CAAAA,CAAO,SAAS,aAAA,CAAc,iBAAiB,CAAA,CACrDA,CAAAA,CAAK,MAAM,OAAA,CAAU,CAAA,uBAAA,EAA0B,UAAW,CAAA,CAAA,CAAA,CAG1D,IAAI0J,CAAAA,CAAY,KAAA,CAChB,GAAI,CAKE,OAAO,OAAA,CAAY,GAAA,EAAe,OAAA,CAAQ,GAAA,GAD/B,UAC2C,CAAA,GAAM,MAAA,GAC9DA,CAAAA,CAAY,CAAA,CAAA,EAEhB,MAAQ,CAER,CACA,IAAMC,CAAAA,CAAaD,EAAa,MAAA,CAAoB,QAAA,CAC9CE,CAAAA,CAAS5J,CAAAA,CAAK,aAAa,CAAE,IAAA,CAAM2J,CAAW,CAAC,EAIrD,GADmC,oBAAA,GAAwB,UAAA,CAAW,SAAA,CACtC,CAC9B,IAAME,CAAAA,CAAQ,IAAI,aAAA,CAClBA,EAAM,WAAA,CAAY5C,EAAAA,CAAYzR,CAAM,CAAC,CAAA,CACrCoU,EAAO,kBAAA,CAAqB,CAACC,CAAK,EACpC,MAAO,CACL,IAAM1Q,CAAAA,CAAQ,QAAA,CAAS,cAAc,OAAO,CAAA,CAC5CA,CAAAA,CAAM,WAAA,CAAc8N,GAAYzR,CAAM,CAAA,CACrCoU,CAAAA,CAAuC,WAAA,CAAYzQ,CAAK,EAC3D,CAEA,QAAA,CAAS,IAAA,CAAK,YAAY6G,CAAI,CAAA,CAG9B,IAAMmE,CAAAA,CAAa,SAAS,aAAA,CAAc,KAAK,CAAA,CAC/CA,CAAAA,CAAW,aAAa,MAAA,CAAQ,QAAQ,EACxCA,CAAAA,CAAW,YAAA,CAAa,YAAa,QAAQ,CAAA,CAC7CA,CAAAA,CAAW,YAAA,CAAa,cAAe,MAAM,CAAA,CAC7CA,CAAAA,CAAW,KAAA,CAAM,QACf,+FAAA,CACF,QAAA,CAAS,IAAA,CAAK,WAAA,CAAYA,CAAU,CAAA,CAGpC,IAAMD,CAAAA,CAAU,IAAIyD,GAAQnS,CAAAA,CAAQoS,CAAM,CAAA,CACpCkC,CAAAA,CAAU,IAAI7F,EAAAA,CAAczO,CAAAA,CAAQ0O,CAAAA,CAASlL,CAAAA,CAAKvD,EAAG0O,CAAU,CAAA,CAG/D4F,CAAAA,CAAM,IAAIxK,GAAIqK,CAAAA,CAAQxb,CAAAA,CAAQ4K,EAAKvD,CAAC,CAAA,CAKtCuU,EAAkC,IAAA,CAClCC,CAAAA,CAA0C,IAAA,CAC1CC,GAAAA,CAAY,MAChB,eAAeC,CAAAA,EAAuC,CACpD,OAAID,IAAkB,IAAA,CAClBF,CAAAA,GACCC,CAAAA,GACHA,CAAAA,CAAe,OAAO,qBAAY,CAAA,CAAE,IAAA,CAAM9R,CAAAA,EACpC+R,IAAkB,IAAA,EACtBF,CAAAA,CAAgB,IAAI7R,CAAAA,CAAI,MAAMyR,CAAAA,CAAQpU,CAAAA,CAAQwD,CAAAA,CAAKwQ,CAAAA,CAAQpb,EAAO,WAAA,CAAa0b,CAAAA,CAASrU,CAAAA,CAAGmS,CAAAA,CAAQ,CACjG,QAAA,CAAAsB,CAAAA,CACA,qBAAA,CAAAD,CACF,CAAC,CAAA,CACMe,CAAAA,CACR,CAAA,CAAA,CAEIC,CAAAA,CACT,CAOA,GAAI,OAAO,MAAA,CAAW,GAAA,CAAa,CACjC,IAAMG,CAAAA,CAAW,IAAM,CAChBF,KAAgBC,CAAAA,GACvB,CAAA,CACME,CAAAA,CAAO,OAA8D,mBAAA,CACvE,OAAOA,CAAAA,EAAQ,UAAA,CAAYA,EAAID,CAAQ,CAAA,CACtC,UAAA,CAAWA,CAAAA,CAAU,GAAG,EAC/B,CAOA,IAAIE,CAAAA,CAAc,MACZC,EAAAA,CAAcvR,CAAAA,CAAI,GAAG,cAAA,CAAiBwR,CAAAA,EAAS,CAC/CR,CAAAA,GACAQ,CAAAA,EACFF,CAAAA,CAAc,IAAA,CACdH,GAAU,CACP,IAAA,CAAMM,CAAAA,EAAM,CACPA,GAAKH,CAAAA,EAAaG,CAAAA,CAAE,IAAA,EAAK,CAC7BH,EAAc,MAChB,CAAC,CAAA,CACA,KAAA,CAAOlS,GAAQ0Q,CAAAA,CAAI,4BAAA,CAA8B1Q,CAAG,CAAC,GAExDkS,CAAAA,CAAc,KAAA,EAElB,CAAC,CAAA,CAEKI,GAAY,IAAI3R,EAAAA,CAAUvD,CAAAA,CAAQwD,CAAAA,CAAKvD,EAAGrH,CAAAA,CAAO,gBAAA,EAAoB,KAAK,CAAA,CAI5Euc,GAAa,KAAA,CACXC,EAAAA,CAAkB5R,CAAAA,CAAI,EAAA,CAAG,sBAAuB,MAAO6R,CAAAA,EAAS,CACpE,GAAI,CAAAF,EAAAA,CACJ,CAAAA,EAAAA,CAAa,IAAA,CACb,GAAI,CACF,GAAM,CAAE,UAAA,CAAAnR,EAAY,IAAA,CAAA9B,CAAAA,CAAM,OAAA,CAAA4C,CAAAA,CAAS,kBAAAb,EAAkB,CAAA,CAAIoR,CAAAA,CAKrDhK,CAAAA,CAAWzS,EAAO,QAAA,EAAYwS,EAAAA,EAAY,CAC9C,GAAI,CAACC,CAAAA,CAAU,CAEb,GADAA,CAAAA,CAAW,MAAMiK,GAAelB,CAAAA,CAAQnU,CAAC,CAAA,CACrC,CAACoL,EAAU,OACfC,EAAAA,CAAaD,CAAQ,EACvB,CAGA,IAAMkK,EAAAA,CAAAA,CAAY,IAAM,CACtB,GAAI,CACF,OAAO,MAAA,CAAO,UAAA,EAChB,CAAA,KAAQ,CACN,OAAO,CAAA,EAAG,KAAK,GAAA,EAAK,CAAA,CAAA,EAAI,IAAA,CAAK,QAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,MAAM,CAAC,CAAC,CAAA,CAC7D,CACF,IAAG,CASGxZ,EAAAA,CAAQ2X,CAAAA,EAAS,CAInB8B,GAA0C,IAAA,CAAA,CAC1C5B,CAAAA,EAAiBC,CAAAA,IACnB2B,EAAAA,CAAc,CACZ,OAAA,CAAS5B,CAAAA,EAAe,UAAA,EAAW,EAAK,EAAC,CACzC,OAAA,CAASC,CAAAA,EAAe,UAAA,IAAgB,EAC1C,CAAA,CAAA,CAGF,IAAM9M,GAA2B,CAC/B,WAAA,CAAanO,CAAAA,CAAO,WAAA,CACpB,KAAAsJ,CAAAA,CACA,OAAA,CAAA4C,CAAAA,CACA,GAAA,CAAK/I,GAAM,GAAA,CACX,UAAA,CAAYA,GAAM,UAAA,CAClB,QAAA,CAAU,GAAG,MAAA,CAAO,UAAU,CAAA,CAAA,EAAI,MAAA,CAAO,WAAW,CAAA,CAAA,CACpD,SAAA,CAAW,SAAA,CAAU,SAAA,CACrB,WAAYsP,CAAAA,CAAS,IAAA,CACrB,WAAA,CAAaA,CAAAA,CAAS,MACtB,WAAA,CAAa,CAACrH,CAAU,CAAA,CACxB,SAAAuR,EAAAA,CACA,iBAAA,CAAmBtR,EAAAA,EAAqB,IAAA,CACxC,YAAAuR,EACF,CAAA,CAEA,GAAI,CACF,IAAMjQ,CAAAA,CAAW,MAAMyO,CAAAA,CAAO,YAAA,CAAajN,EAAO,CAAA,CAClDvD,CAAAA,CAAI,KAAK,eAAA,CAAiB+B,CAAQ,GAI9B,CAACkO,CAAAA,EAAyBlO,CAAAA,CAAS,GAAA,GAAQxJ,GAAM,GAAA,GACnDuY,CAAAA,CAAQ,WAAA,CAAY/O,CAAAA,CAAU+O,EAAQ,KAAA,CAAQ,CAAC,CAAA,CAEjD3F,CAAAA,CAAW,YAAc1O,CAAAA,CAAE,4BAA4B,CAAA,CAInDuU,CAAAA,EAAe,MAAMA,CAAAA,CAAc,OAAA,GACzC,CAAA,MAAS7O,EAAO,CACdnC,CAAAA,CAAI,IAAA,CAAK,gBAAA,CAAkBmC,aAAiB,KAAA,CAAQA,CAAAA,CAAQ,IAAI,KAAA,CAAM,OAAOA,CAAK,CAAC,CAAC,CAAA,CACpFgJ,CAAAA,CAAW,YAAc1O,CAAAA,CAAE,wBAAwB,EACrD,CACF,QAAE,CACAkV,EAAAA,CAAa,MACf,CAAA,CACF,CAAC,CAAA,CAMKM,EAAAA,CAAe/B,CAAAA,EAAS,CACxBgC,GAAiBjC,CAAAA,CAAwB,CAAE,KAAA,CAAO,EAAA,CAAW,IAAKgC,EAAAA,CAAa,GAAI,CAAA,CAAI,CAAE,MAAO,EAAU,CAAA,CAC1GE,EAAAA,CAAevC,EAAAA,CAAyBxa,EAAO,QAAQ,CAAA,CAC7D,OAAAob,CAAAA,CACG,aAAapb,CAAAA,CAAO,WAAA,CAAa8c,EAAc,CAAA,CAC/C,KAAK,CAAC,CAAE,SAAA,CAAAnG,CAAU,IAAyC,CAE1D,IAAMX,CAAAA,CAAU6E,CAAAA,CAAwBlE,EAAU,MAAA,CAAQqG,CAAAA,EAAMA,CAAAA,CAAE,GAAA,GAAQH,GAAa,GAAG,CAAA,CAAIlG,CAAAA,CAK9F,GAJA+E,EAAQ,MAAA,CAAO1F,CAAO,CAAA,CAIlB+G,EAAAA,CAAa,QACf,GAAI,CACF,IAAME,CAAAA,CAAU,IAAI,eAAA,CAAgB,MAAA,CAAO,QAAA,CAAS,MAAM,EAAE,GAAA,CAAIF,EAAAA,CAAa,KAAK,CAAA,CAClF,GAAIE,EAAS,CACX,IAAMC,CAAAA,CAAUxB,CAAAA,CAAQ,cAAcuB,CAAO,CAAA,CAC7CvC,CAAAA,CACE,CAAA,UAAA,EAAaqC,GAAa,KAAK,CAAA,CAAA,EAAIE,CAAO,CAAA,CAAA,EAAIC,EAAU,SAAA,CAAY,kCAAkC,CAAA,CACxG,EACF,CACF,CAAA,MAAS1U,CAAAA,CAAG,CACVkS,CAAAA,CAAI,2BAA4BlS,CAAC,EACnC,CAEJ,CAAC,EACA,KAAA,CAAOwB,CAAAA,EAAQ,CACd0Q,CAAAA,CAAI,kCAAmC1Q,CAAG,EAC5C,CAAC,CAAA,CAGChK,CAAAA,CAAO,UACTuO,EAAAA,CAAgBvO,CAAAA,CAAO,QAAQ,CAAA,CAC5B,KAAK,IAAM0a,CAAAA,CAAI,qBAAqB,CAAC,EACrC,KAAA,CAAM,IAAM,CAAC,CAAC,EAGnBN,EAAAA,CAAW,CACT,OAAA,CAAS,IAAM,CACbM,CAAAA,CAAI,mBAAmB,CAAA,CACvBoB,GAAAA,CAAY,KACZI,CAAAA,CAAc,KAAA,CACdM,EAAAA,EAAgB,CAChBL,IAAY,CACZR,CAAAA,CAAI,OAAA,EAAQ,CACZC,GAAe,OAAA,EAAQ,CACvBU,GAAU,OAAA,EAAQ,CAClBZ,EAAQ,OAAA,EAAQ,CAChB5F,CAAAA,CAAQ,OAAA,GAGRkF,CAAAA,EAAe,OAAA,EAAQ,CACvBC,CAAAA,EAAe,SAAQ,CACvBrQ,CAAAA,CAAI,SAAA,EAAU,CACduQ,EAAU,SAAA,EAAU,CACpBpF,CAAAA,CAAW,MAAA,GACXnE,CAAAA,CAAK,MAAA,EAAO,CACZwI,EAAAA,CAAW,KACb,CAAA,CACA,IAAA,CAAM,IAAM,CAIVxP,EAAI,IAAA,CAAK,cAAA,CAAgB,IAAI,EAC/B,EACA,KAAA,CAAO,IAAM,CACPgR,CAAAA,CACFA,EAAc,KAAA,EAAM,CAGpBM,CAAAA,CAAc,MAElB,EACA,aAAA,CAAgBlE,CAAAA,EAMP0D,CAAAA,CAAQ,aAAA,CAAc1D,CAAU,CAAA,CAEzC,OAAA,CAAS,IAAM,CAOb,GAAI4D,CAAAA,EAAe,eAAA,CAAiB,CAClCA,CAAAA,CAAc,SAAQ,CACtB,MACF,CAEA,IAAMzY,EAAQ2X,CAAAA,EAAS,CACjBqC,CAAAA,CAAOtC,CAAAA,CAAwB,CAAE,KAAA,CAAO,EAAA,CAAW,GAAA,CAAK1X,CAAAA,CAAM,GAAI,CAAA,CAAI,CAAE,MAAO,EAAU,CAAA,CAC/FiY,EACG,YAAA,CAAapb,CAAAA,CAAO,WAAA,CAAamd,CAAI,EACrC,IAAA,CAAK,CAAC,CAAE,SAAA,CAAAxG,CAAU,CAAA,GAAyC,CAC1D,IAAMX,CAAAA,CAAU6E,EAAwBlE,CAAAA,CAAU,MAAA,CAAQqG,EAAAA,EAAMA,EAAAA,CAAE,MAAQ7Z,CAAAA,CAAM,GAAG,CAAA,CAAIwT,CAAAA,CACvF+E,EAAQ,MAAA,CAAO1F,CAAO,EACxB,CAAC,EACA,KAAA,CAAM,IAAM,CAAC,CAAC,EACnB,CAAA,CACA,EAAA,CAAI,CAAuClF,CAAAA,CAAUC,CAAAA,GAG5CoK,EAAU,EAAA,CAAGrK,CAAAA,CAAoBC,CAAuE,CAAA,CAEjH,IAAK,CAAuCD,CAAAA,CAAUC,CAAAA,GAAyD,CAG7GoK,EAAU,GAAA,CAAIrK,CAAAA,CAAoBC,CAAuE,EAC3G,CACF,CAAA,CAEOqJ,EACT,CAOA,SAASsC,GAAetL,CAAAA,CAAwB/J,CAAAA,CAAwC,CACtF,OAAO,IAAI,OAAA,CAASuB,CAAAA,EAAY,CAE9B,IAAMwU,EAAqBhM,CAAAA,CAAW,aAAA,EAAiB,QAAA,CAAS,aAAA,CAE1DiM,EAAW,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA,CAC7CA,CAAAA,CAAS,MAAM,OAAA,CAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAAA,EAMb,UAAW,CAAA;AAAA;AAAA,IAAA,CAAA,CAIvB,IAAMC,EAAQ,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA,CAC1CA,CAAAA,CAAM,MAAM,OAAA,CAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAAA,CActB,IAAMC,CAAAA,CAAU,CAAA,kBAAA,EAAqB,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,CAC/CD,CAAAA,CAAM,YAAA,CAAa,MAAA,CAAQ,QAAQ,CAAA,CACnCA,CAAAA,CAAM,YAAA,CAAa,YAAA,CAAc,MAAM,CAAA,CACvCA,CAAAA,CAAM,YAAA,CAAa,iBAAA,CAAmBC,CAAO,CAAA,CAE7C,IAAMC,CAAAA,CAAQ,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA,CAC1CA,EAAM,SAAA,CAAY,mBAAA,CAClBA,CAAAA,CAAM,EAAA,CAAKD,CAAAA,CACXC,CAAAA,CAAM,WAAA,CAAcnW,CAAAA,CAAE,gBAAgB,CAAA,CACtCmW,CAAAA,CAAM,KAAA,CAAM,YAAA,CAAe,MAAA,CAE3B,IAAMC,CAAAA,CAAc,oBAAoB,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,CAC5CC,CAAAA,CAAe,CAAA,kBAAA,EAAqB,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,CAE9CC,CAAAA,CAAY,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA,CAChDA,CAAAA,CAAU,UAAY,gBAAA,CACtBA,CAAAA,CAAU,WAAA,CAActW,CAAAA,CAAE,oBAAoB,CAAA,CAC9CsW,CAAAA,CAAU,YAAA,CAAa,KAAA,CAAOF,CAAW,CAAA,CACzC,IAAMG,CAAAA,CAAY,QAAA,CAAS,aAAA,CAAc,OAAO,EAChDA,CAAAA,CAAU,SAAA,CAAY,UAAA,CACtBA,CAAAA,CAAU,EAAA,CAAKH,CAAAA,CACfG,CAAAA,CAAU,IAAA,CAAO,MAAA,CACjBA,CAAAA,CAAU,WAAA,CAAcvW,CAAAA,CAAE,0BAA0B,CAAA,CACpDuW,CAAAA,CAAU,KAAA,CAAM,aAAe,MAAA,CAE/B,IAAMC,CAAAA,CAAa,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA,CACjDA,CAAAA,CAAW,SAAA,CAAY,gBAAA,CACvBA,CAAAA,CAAW,WAAA,CAAcxW,CAAAA,CAAE,qBAAqB,CAAA,CAChDwW,CAAAA,CAAW,aAAa,KAAA,CAAOH,CAAY,CAAA,CAC3C,IAAMI,CAAAA,CAAa,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA,CACjDA,CAAAA,CAAW,SAAA,CAAY,UAAA,CACvBA,CAAAA,CAAW,EAAA,CAAKJ,CAAAA,CAChBI,CAAAA,CAAW,KAAO,OAAA,CAClBA,CAAAA,CAAW,WAAA,CAAczW,CAAAA,CAAE,2BAA2B,CAAA,CAEtD,IAAMoB,CAAAA,CAAS,QAAA,CAAS,aAAA,CAAc,KAAK,CAAA,CAC3CA,CAAAA,CAAO,KAAA,CAAM,OAAA,CAAU,gEAAA,CAEvB,IAAMsV,CAAAA,CAAc5S,CAAAA,EAA4B,CAC9CkS,CAAAA,CAAS,mBAAA,CAAoB,SAAA,CAAWW,CAAS,CAAA,CACjDX,CAAAA,CAAS,KAAA,CAAM,OAAA,CAAU,GAAA,CACzBC,CAAAA,CAAM,KAAA,CAAM,SAAA,CAAY,8BAAA,CACxB,WAAW,IAAM,CACfD,CAAAA,CAAS,MAAA,EAAO,CAChBD,CAAAA,EAAmB,KAAA,EAAM,CACzBxU,CAAAA,CAAQuC,CAAM,EAChB,CAAA,CAAG,GAAG,EACR,CAAA,CAEMzC,CAAAA,CAAY,SAAS,aAAA,CAAc,QAAQ,CAAA,CACjDA,CAAAA,CAAU,SAAA,CAAY,cAAA,CACtBA,CAAAA,CAAU,WAAA,CAAcrB,CAAAA,CAAE,iBAAiB,CAAA,CAC3CqB,CAAAA,CAAU,gBAAA,CAAiB,OAAA,CAAS,IAAMqV,CAAAA,CAAW,IAAI,CAAC,CAAA,CAE1D,IAAME,CAAAA,CAAY,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA,CACjDA,CAAAA,CAAU,SAAA,CAAY,gBAAA,CACtBA,CAAAA,CAAU,WAAA,CAAc5W,CAAAA,CAAE,iBAAiB,CAAA,CAC3C4W,EAAU,gBAAA,CAAiB,OAAA,CAAS,IAAM,CACxC,IAAM1d,CAAAA,CAAOqd,CAAAA,CAAU,KAAA,CAAM,IAAA,EAAK,CAC5BM,CAAAA,CAAQJ,CAAAA,CAAW,KAAA,CAAM,IAAA,EAAK,CACpC,GAAI,CAACvd,CAAAA,EAAQ,CAAC2d,CAAAA,CAAO,OAErB,GAAI,CADe,4BAAA,CACH,IAAA,CAAKA,CAAK,CAAA,CAAG,CAC3BJ,CAAAA,CAAW,KAAA,CAAM,WAAA,CAAc,6BAAA,CAC/B,MACF,CACAC,CAAAA,CAAW,CAAE,IAAA,CAAAxd,CAAAA,CAAM,KAAA,CAAA2d,CAAM,CAAC,EAC5B,CAAC,CAAA,CAGD,IAAMC,CAAAA,CAAqB,gDAAA,CACrBH,CAAAA,CAAaxV,CAAAA,EAAa,CAC9B,IAAM4V,CAAAA,CAAK5V,CAAAA,CACX,GAAI4V,CAAAA,CAAG,GAAA,GAAQ,QAAA,CAAU,CACvBL,CAAAA,CAAW,IAAI,CAAA,CACf,MACF,CACA,GAAIK,CAAAA,CAAG,GAAA,GAAQ,KAAA,CAAO,CACpB,IAAMlV,CAAAA,CAAe,KAAA,CAAM,IAAA,CAAKoU,CAAAA,CAAM,gBAAA,CAA8Ba,CAAkB,CAAC,CAAA,CACvF,GAAIjV,CAAAA,CAAa,MAAA,GAAW,CAAA,CAAG,OAC/B,IAAMC,CAAAA,CAAQD,EAAa,CAAC,CAAA,CACtBE,CAAAA,CAAOF,CAAAA,CAAaA,CAAAA,CAAa,MAAA,CAAS,CAAC,CAAA,CACjD,GAAI,CAACC,CAAAA,EAAS,CAACC,CAAAA,CAAM,OACrB,IAAMiV,CAAAA,CAASjN,EAAW,aAAA,CACtBgN,CAAAA,CAAG,QAAA,CAAA,CACDC,CAAAA,GAAWlV,CAAAA,EAAS,CAACmU,CAAAA,CAAM,QAAA,CAASe,CAAM,CAAA,IAC5CD,CAAAA,CAAG,cAAA,EAAe,CAClBhV,CAAAA,CAAK,KAAA,EAAM,CAAA,CAAA,CAGTiV,IAAWjV,CAAAA,EAAQ,CAACkU,CAAAA,CAAM,QAAA,CAASe,CAAM,CAAA,IAC3CD,CAAAA,CAAG,cAAA,EAAe,CAClBjV,CAAAA,CAAM,KAAA,EAAM,EAGlB,CACF,CAAA,CACAkU,CAAAA,CAAS,gBAAA,CAAiB,UAAWW,CAAS,CAAA,CAG9CX,CAAAA,CAAS,gBAAA,CAAiB,OAAA,CAAU7U,CAAAA,EAAM,CACpCA,CAAAA,CAAE,MAAA,GAAW6U,CAAAA,EAAUU,CAAAA,CAAW,IAAI,EAC5C,CAAC,CAAA,CAEDtV,CAAAA,CAAO,YAAYC,CAAS,CAAA,CAC5BD,CAAAA,CAAO,WAAA,CAAYwV,CAAS,CAAA,CAE5BX,CAAAA,CAAM,WAAA,CAAYE,CAAK,CAAA,CACvBF,CAAAA,CAAM,WAAA,CAAYK,CAAS,CAAA,CAC3BL,CAAAA,CAAM,WAAA,CAAYM,CAAS,CAAA,CAC3BN,CAAAA,CAAM,WAAA,CAAYO,CAAU,CAAA,CAC5BP,CAAAA,CAAM,WAAA,CAAYQ,CAAU,CAAA,CAC5BR,CAAAA,CAAM,WAAA,CAAY7U,CAAM,CAAA,CACxB4U,CAAAA,CAAS,WAAA,CAAYC,CAAK,EAE1BlM,CAAAA,CAAW,WAAA,CAAYiM,CAAQ,CAAA,CAG/B,qBAAA,CAAsB,IAAM,CAC1BA,CAAAA,CAAS,KAAA,CAAM,OAAA,CAAU,GAAA,CACzBC,CAAAA,CAAM,KAAA,CAAM,SAAA,CAAY,wBAAA,CACxBM,CAAAA,CAAU,QACZ,CAAC,EACH,CAAC,CACH,CC1pBO,SAASU,EAAAA,CAAate,CAAAA,CAA0C,CACrE,OAAOya,EAAAA,CAAOza,CAAM,CACtB,CCuBO,SAASue,GAAYve,CAAAA,CAAiD,CAK3E,IAAMwe,CAAAA,CAAYC,MAAAA,CAAOze,CAAM,CAAA,CAC/Bwe,CAAAA,CAAU,OAAA,CAAUxe,CAAAA,CAEpB,GAAM,CAACoa,CAAAA,CAAUsE,CAAW,CAAA,CAAIC,QAAAA,CAAkC,IAAI,CAAA,CAEtE,OAAAC,SAAAA,CAAU,IAAM,CAMd,IAAIC,CAAAA,CAAU,IAAA,CACRC,CAAAA,CAAUR,EAAAA,CAAaE,CAAAA,CAAU,OAAO,CAAA,CAC9C,GAAI,CAACK,CAAAA,CAAS,CAGZC,CAAAA,CAAQ,OAAA,EAAQ,CAChB,MACF,CAMA,IAAMC,CAAAA,CAAYD,CAAAA,CAAQ,EAAA,CAAG,eAAA,CAAkBzD,CAAAA,EAAO,CACpDmD,CAAAA,CAAU,OAAA,CAAQ,cAAA,GAAiBnD,CAAE,EACvC,CAAC,CAAA,CACK2D,CAAAA,CAAYF,CAAAA,CAAQ,EAAA,CAAG,YAAA,CAAc,IAAM,CAC/CN,CAAAA,CAAU,OAAA,CAAQ,MAAA,KACpB,CAAC,CAAA,CACKS,CAAAA,CAAaH,CAAAA,CAAQ,GAAG,aAAA,CAAe,IAAM,CACjDN,CAAAA,CAAU,OAAA,CAAQ,OAAA,KACpB,CAAC,CAAA,CAED,OAAAE,CAAAA,CAAYI,CAAO,CAAA,CAEZ,IAAM,CACXD,CAAAA,CAAU,MACVE,CAAAA,EAAU,CACVC,CAAAA,EAAU,CACVC,CAAAA,EAAW,CACXH,CAAAA,CAAQ,OAAA,EAAQ,CAChBJ,CAAAA,CAAY,IAAI,EAClB,CAMF,CAAA,CAAG,EAAE,EAEEtE,CACT","file":"react.js","sourcesContent":["// License: MIT\n// Author: Anton Medvedev <anton@medv.io>\n// Source: https://github.com/antonmedv/finder\nlet config;\nlet rootDocument;\nlet start;\nexport function finder(input, options) {\n start = new Date();\n if (input.nodeType !== Node.ELEMENT_NODE) {\n throw new Error(`Can't generate CSS selector for non-element node type.`);\n }\n if ('html' === input.tagName.toLowerCase()) {\n return 'html';\n }\n const defaults = {\n root: document.body,\n idName: (name) => true,\n className: (name) => true,\n tagName: (name) => true,\n attr: (name, value) => false,\n seedMinLength: 1,\n optimizedMinLength: 2,\n threshold: 1000,\n maxNumberOfTries: 10000,\n timeoutMs: undefined,\n };\n config = { ...defaults, ...options };\n rootDocument = findRootDocument(config.root, defaults);\n let path = bottomUpSearch(input, 'all', () => bottomUpSearch(input, 'two', () => bottomUpSearch(input, 'one', () => bottomUpSearch(input, 'none'))));\n if (path) {\n const optimized = sort(optimize(path, input));\n if (optimized.length > 0) {\n path = optimized[0];\n }\n return selector(path);\n }\n else {\n throw new Error(`Selector was not found.`);\n }\n}\nfunction findRootDocument(rootNode, defaults) {\n if (rootNode.nodeType === Node.DOCUMENT_NODE) {\n return rootNode;\n }\n if (rootNode === defaults.root) {\n return rootNode.ownerDocument;\n }\n return rootNode;\n}\nfunction bottomUpSearch(input, limit, fallback) {\n let path = null;\n let stack = [];\n let current = input;\n let i = 0;\n while (current) {\n const elapsedTime = new Date().getTime() - start.getTime();\n if (config.timeoutMs !== undefined && elapsedTime > config.timeoutMs) {\n throw new Error(`Timeout: Can't find a unique selector after ${elapsedTime}ms`);\n }\n let level = maybe(id(current)) ||\n maybe(...attr(current)) ||\n maybe(...classNames(current)) ||\n maybe(tagName(current)) || [any()];\n const nth = index(current);\n if (limit == 'all') {\n if (nth) {\n level = level.concat(level.filter(dispensableNth).map((node) => nthChild(node, nth)));\n }\n }\n else if (limit == 'two') {\n level = level.slice(0, 1);\n if (nth) {\n level = level.concat(level.filter(dispensableNth).map((node) => nthChild(node, nth)));\n }\n }\n else if (limit == 'one') {\n const [node] = (level = level.slice(0, 1));\n if (nth && dispensableNth(node)) {\n level = [nthChild(node, nth)];\n }\n }\n else if (limit == 'none') {\n level = [any()];\n if (nth) {\n level = [nthChild(level[0], nth)];\n }\n }\n for (let node of level) {\n node.level = i;\n }\n stack.push(level);\n if (stack.length >= config.seedMinLength) {\n path = findUniquePath(stack, fallback);\n if (path) {\n break;\n }\n }\n current = current.parentElement;\n i++;\n }\n if (!path) {\n path = findUniquePath(stack, fallback);\n }\n if (!path && fallback) {\n return fallback();\n }\n return path;\n}\nfunction findUniquePath(stack, fallback) {\n const paths = sort(combinations(stack));\n if (paths.length > config.threshold) {\n return fallback ? fallback() : null;\n }\n for (let candidate of paths) {\n if (unique(candidate)) {\n return candidate;\n }\n }\n return null;\n}\nfunction selector(path) {\n let node = path[0];\n let query = node.name;\n for (let i = 1; i < path.length; i++) {\n const level = path[i].level || 0;\n if (node.level === level - 1) {\n query = `${path[i].name} > ${query}`;\n }\n else {\n query = `${path[i].name} ${query}`;\n }\n node = path[i];\n }\n return query;\n}\nfunction penalty(path) {\n return path.map((node) => node.penalty).reduce((acc, i) => acc + i, 0);\n}\nfunction unique(path) {\n const css = selector(path);\n switch (rootDocument.querySelectorAll(css).length) {\n case 0:\n throw new Error(`Can't select any node with this selector: ${css}`);\n case 1:\n return true;\n default:\n return false;\n }\n}\nfunction id(input) {\n const elementId = input.getAttribute('id');\n if (elementId && config.idName(elementId)) {\n return {\n name: '#' + CSS.escape(elementId),\n penalty: 0,\n };\n }\n return null;\n}\nfunction attr(input) {\n const attrs = Array.from(input.attributes).filter((attr) => config.attr(attr.name, attr.value));\n return attrs.map((attr) => ({\n name: `[${CSS.escape(attr.name)}=\"${CSS.escape(attr.value)}\"]`,\n penalty: 0.5,\n }));\n}\nfunction classNames(input) {\n const names = Array.from(input.classList).filter(config.className);\n return names.map((name) => ({\n name: '.' + CSS.escape(name),\n penalty: 1,\n }));\n}\nfunction tagName(input) {\n const name = input.tagName.toLowerCase();\n if (config.tagName(name)) {\n return {\n name,\n penalty: 2,\n };\n }\n return null;\n}\nfunction any() {\n return {\n name: '*',\n penalty: 3,\n };\n}\nfunction index(input) {\n const parent = input.parentNode;\n if (!parent) {\n return null;\n }\n let child = parent.firstChild;\n if (!child) {\n return null;\n }\n let i = 0;\n while (child) {\n if (child.nodeType === Node.ELEMENT_NODE) {\n i++;\n }\n if (child === input) {\n break;\n }\n child = child.nextSibling;\n }\n return i;\n}\nfunction nthChild(node, i) {\n return {\n name: node.name + `:nth-child(${i})`,\n penalty: node.penalty + 1,\n };\n}\nfunction dispensableNth(node) {\n return node.name !== 'html' && !node.name.startsWith('#');\n}\nfunction maybe(...level) {\n const list = level.filter(notEmpty);\n if (list.length > 0) {\n return list;\n }\n return null;\n}\nfunction notEmpty(value) {\n return value !== null && value !== undefined;\n}\nfunction* combinations(stack, path = []) {\n if (stack.length > 0) {\n for (let node of stack[0]) {\n yield* combinations(stack.slice(1, stack.length), path.concat(node));\n }\n }\n else {\n yield path;\n }\n}\nfunction sort(paths) {\n return [...paths].sort((a, b) => penalty(a) - penalty(b));\n}\nfunction* optimize(path, input, scope = {\n counter: 0,\n visited: new Map(),\n}) {\n if (path.length > 2 && path.length > config.optimizedMinLength) {\n for (let i = 1; i < path.length - 1; i++) {\n if (scope.counter > config.maxNumberOfTries) {\n return; // Okay At least I tried!\n }\n scope.counter += 1;\n const newPath = [...path];\n newPath.splice(i, 1);\n const newPathKey = selector(newPath);\n if (scope.visited.has(newPathKey)) {\n return;\n }\n if (unique(newPath) && same(newPath, input)) {\n yield newPath;\n scope.visited.set(newPathKey, true);\n yield* optimize(newPath, input, scope);\n }\n }\n }\n}\nfunction same(path, input) {\n return rootDocument.querySelector(selector(path)) === input;\n}\n","/**\n * Element fingerprinting for robust DOM re-anchoring.\n *\n * Captures structural properties (child count, sibling index, stable attributes)\n * that survive CSS class changes and minor DOM reshuffling.\n * Inspired by Similo (academic state-of-the-art, 98.8% accuracy).\n */\n\nconst STABLE_ATTRS = [\"role\", \"aria-label\", \"type\", \"name\", \"href\", \"src\", \"data-testid\", \"data-id\"] as const;\n\n/** Simple 32-bit hash (djb2). */\nfunction djb2(str: string): string {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) + hash + str.charCodeAt(i)) | 0;\n }\n return (hash >>> 0).toString(36);\n}\n\n/**\n * Generate a compact structural fingerprint for a DOM element.\n *\n * Format: `\"childCount:siblingIdx:attrHash\"`\n * - `childCount` — number of direct child elements\n * - `siblingIdx` — position among same-tag siblings (0-based)\n * - `attrHash` — djb2 hash of stable attributes (role, aria-label, type, etc.)\n *\n * Tag name is NOT included — it's stored separately in `AnchorData.elementTag`.\n */\nexport function generateFingerprint(element: Element): string {\n const childCount = element.children.length;\n\n // Position among same-tag siblings\n let siblingIdx = 0;\n const parent = element.parentElement;\n if (parent) {\n for (const child of parent.children) {\n if (child === element) break;\n if (child.tagName === element.tagName) siblingIdx++;\n }\n }\n\n // Hash stable attributes\n const attrs: string[] = [];\n for (const attr of STABLE_ATTRS) {\n const val = element.getAttribute(attr);\n if (val) attrs.push(`${attr}=${val}`);\n }\n const attrHash = attrs.length > 0 ? djb2(attrs.join(\",\")) : \"0\";\n\n return `${childCount}:${siblingIdx}:${attrHash}`;\n}\n\n/**\n * Score how well a candidate element matches a stored fingerprint.\n * Returns 0–1.\n *\n * Weights:\n * - Child count match: 0.2 (tolerant — ±2 gets partial credit)\n * - Sibling index match: 0.4 (positional — most discriminating)\n * - Attribute hash match: 0.4 (identity — exact or nothing)\n */\nexport function scoreFingerprint(candidate: Element, storedFingerprint: string): number {\n const parts = storedFingerprint.split(\":\");\n if (parts.length !== 3) return 0;\n\n const [storedChildren, storedSibIdx, storedAttrHash] = parts;\n const storedChildCount = Number(storedChildren);\n const storedSibIndex = Number(storedSibIdx);\n if (Number.isNaN(storedChildCount) || Number.isNaN(storedSibIndex)) return 0;\n\n const candidateFp = generateFingerprint(candidate);\n const [candChildren, candSibIdx, candAttrHash] = candidateFp.split(\":\");\n\n let score = 0;\n\n // Child count (0.2)\n const childDiff = Math.abs(Number(candChildren) - storedChildCount);\n if (childDiff === 0) score += 0.2;\n else if (childDiff <= 2) score += 0.1;\n else if (childDiff <= 5) score += 0.03;\n\n // Sibling index (0.4)\n const sibDiff = Math.abs(Number(candSibIdx) - storedSibIndex);\n if (sibDiff === 0) score += 0.4;\n else if (sibDiff === 1) score += 0.2;\n else if (sibDiff <= 3) score += 0.08;\n\n // Attribute hash (0.4)\n if (candAttrHash === storedAttrHash) score += 0.4;\n\n return score;\n}\n","/**\n * Shared text-context helpers for DOM anchoring.\n * Used by both anchor generation (anchor.ts) and resolution (resolver.ts).\n */\n\n/**\n * Extract ~32 chars of text from the nearest sibling with content.\n * Walks up to 3 siblings in the given direction.\n */\nexport function adjacentText(element: Element, direction: \"before\" | \"after\"): string {\n const prop = direction === \"before\" ? \"previousElementSibling\" : \"nextElementSibling\";\n let sibling: Element | null = element[prop];\n let attempts = 3;\n\n while (sibling && attempts > 0) {\n const text = sibling.textContent?.trim();\n if (text) {\n return direction === \"before\" ? text.slice(-32) : text.slice(0, 32);\n }\n sibling = sibling[prop];\n attempts--;\n }\n\n return \"\";\n}\n\n/** Collect text from immediate siblings for disambiguation context. */\nexport function neighborText(element: Element): string {\n const prev = element.previousElementSibling?.textContent?.trim().slice(0, 40) ?? \"\";\n const next = element.nextElementSibling?.textContent?.trim().slice(0, 40) ?? \"\";\n return [prev, next].filter(Boolean).join(\" | \");\n}\n","/**\n * Generate an optimized XPath for a DOM element.\n *\n * Strategy:\n * - If the element has a unique id → //tag[@id='value']\n * - Otherwise, walk up the tree building /tag[position] segments\n * until we hit an ancestor with an id or reach <body>\n * - Cap depth at 6 levels to keep paths short\n */\nexport function generateXPath(element: Element): string {\n if (element.id) {\n const safeId = element.id.includes(\"'\") ? `concat('${element.id.replace(/'/g, \"',\\\"'\\\",'\")}')` : `'${element.id}'`;\n return `//${element.localName}[@id=${safeId}]`;\n }\n\n const segments: string[] = [];\n let current: Element | null = element;\n\n while (current && current !== document.body && segments.length < 6) {\n const tag = current.localName;\n const parent: Element | null = current.parentElement;\n\n if (current.id) {\n const safeId = current.id.includes(\"'\")\n ? `concat('${current.id.replace(/'/g, \"',\\\"'\\\",'\")}')`\n : `'${current.id}'`;\n segments.unshift(`/${tag}[@id=${safeId}]`);\n return \"/\" + segments.join(\"\");\n }\n\n // Compute position among same-tag siblings\n let position = 1;\n if (parent) {\n for (const sibling of parent.children) {\n if (sibling === current) break;\n if (sibling.localName === tag) position++;\n }\n }\n\n segments.unshift(`/${tag}[${position}]`);\n current = parent;\n }\n\n return \"/html/body\" + segments.join(\"\");\n}\n","import { finder } from \"@medv/finder\";\nimport type { AnchorData, RectData } from \"@siteping/core\";\nimport { generateFingerprint } from \"./fingerprint.js\";\nimport { adjacentText, neighborText } from \"./text-context.js\";\nimport { generateXPath } from \"./xpath.js\";\n\n/** HTML attribute hosts use to mark stable semantic anchors. */\nexport const ANCHOR_KEY_ATTR = \"data-feedback-anchor\";\n\n/**\n * Generate a multi-selector anchor for a DOM element.\n *\n * Resolution priority (used by `resolveAnchor`):\n * 1. Semantic anchor (`data-feedback-anchor` on closest ancestor) — hosts opt\n * into stable, narrow anchors that survive viewport changes and refactors\n * 2. Element id\n * 3. CSS selector via @medv/finder\n * 4. XPath\n * 5. Smart scan (fingerprint + text + prefix/suffix + neighbor)\n */\nexport function generateAnchor(element: Element): AnchorData {\n const cssSelector = finder(element, {\n // Filter out CSS-in-JS hashed class names\n className: (name: string) => !/^(css|sc|emotion|styled)-/.test(name) && !/^[a-z]{1,3}[A-Za-z0-9]{4,8}$/.test(name),\n // Prefer stable attributes\n attr: (name: string) => [\"data-testid\", \"data-id\", \"role\", \"aria-label\"].includes(name),\n // Exclude framework-generated dynamic IDs\n idName: (name: string) => !name.startsWith(\"radix-\") && !/^:r[0-9]+:$/.test(name),\n seedMinLength: 3,\n optimizedMinLength: 2,\n });\n\n const xpath = generateXPath(element);\n\n const rawText = element.textContent?.trim() ?? \"\";\n const textSnippet = rawText.slice(0, 120);\n\n const textPrefix = adjacentText(element, \"before\");\n const textSuffix = adjacentText(element, \"after\");\n const fingerprint = generateFingerprint(element);\n const neighbor = neighborText(element);\n\n const semanticAncestor = element.closest(`[${ANCHOR_KEY_ATTR}]`);\n const anchorKey = semanticAncestor?.getAttribute(ANCHOR_KEY_ATTR) ?? null;\n\n return {\n cssSelector,\n xpath,\n textSnippet,\n textPrefix,\n textSuffix,\n fingerprint,\n neighborText: neighbor,\n elementTag: element.tagName,\n elementId: element.id || undefined,\n anchorKey,\n };\n}\n\n/** Whether `el`'s bounding box fully contains `rect`. */\nfunction containsRect(el: Element, rect: DOMRect): boolean {\n const b = el.getBoundingClientRect();\n return b.left <= rect.x && b.top <= rect.y && b.right >= rect.x + rect.width && b.bottom >= rect.y + rect.height;\n}\n\n/**\n * Find the best DOM element to use as the rect's anchor.\n *\n * Priority:\n * 1. Closest ancestor with `data-feedback-anchor` whose bounds contain the rect —\n * semantic anchors are typically narrow section roots, so anchoring against\n * them keeps the percentage-based rect stable across viewport changes\n * instead of stretching to the width of `<main>` or `<body>`.\n * 2. Smallest ancestor that contains the rect (legacy behavior).\n * 3. `document.body` fallback — keeps percentages in [0, 1].\n */\nexport function findAnchorElement(rect: DOMRect, root: Element = document.documentElement): Element {\n const centerX = rect.x + rect.width / 2;\n const centerY = rect.y + rect.height / 2;\n\n const elementAtCenter = document.elementFromPoint(centerX, centerY);\n if (!elementAtCenter || elementAtCenter === root) return document.body;\n\n // Pass 1 — semantic anchor (host-controlled, most stable)\n let current: Element | null = elementAtCenter;\n while (current && current !== document.body) {\n if (current.hasAttribute(ANCHOR_KEY_ATTR) && containsRect(current, rect)) {\n return current;\n }\n current = current.parentElement;\n }\n\n // Pass 2 — original behavior: smallest ancestor that contains the rect\n current = elementAtCenter;\n while (current && current !== document.body) {\n if (containsRect(current, rect)) return current;\n current = current.parentElement;\n }\n\n return document.body;\n}\n\n/**\n * Convert absolute rectangle coordinates to percentages\n * relative to an anchor element's bounding box.\n */\nexport function rectToPercentages(rect: DOMRect, anchorBounds: DOMRect): RectData {\n // Guard against zero-dimension anchors (collapsed/hidden elements)\n if (anchorBounds.width <= 0 || anchorBounds.height <= 0) {\n return { xPct: 0, yPct: 0, wPct: 1, hPct: 1 };\n }\n return {\n xPct: (rect.x - anchorBounds.x) / anchorBounds.width,\n yPct: (rect.y - anchorBounds.y) / anchorBounds.height,\n wPct: rect.width / anchorBounds.width,\n hPct: rect.height / anchorBounds.height,\n };\n}\n","import type { FeedbackType } from \"@siteping/core\";\nimport { Z_INDEX_MAX } from \"./constants.js\";\nimport { el, parseSvg, setText } from \"./dom-utils.js\";\nimport type { TFunction } from \"./i18n/index.js\";\nimport { ICON_BUG, ICON_CHANGE, ICON_OTHER, ICON_QUESTION } from \"./icons.js\";\nimport { getTypeBgColor, getTypeColor, type ThemeColors } from \"./styles/theme.js\";\n\ninterface PopupResult {\n type: FeedbackType;\n message: string;\n}\n\ninterface TypeOption {\n type: FeedbackType;\n label: string;\n icon: string;\n}\n\n/**\n * Popup form shown after drawing an annotation rectangle.\n *\n * Glassmorphism design: frosted glass background, soft shadows,\n * pill-shaped type buttons, gradient submit button.\n * Lives outside Shadow DOM.\n */\nexport class Popup {\n private root: HTMLElement;\n private selectedType: FeedbackType | null = null;\n private textarea: HTMLTextAreaElement;\n private submitBtn: HTMLButtonElement;\n private resolve: ((result: PopupResult | null) => void) | null = null;\n private previouslyFocused: HTMLElement | null = null;\n private onKeydownTrap: ((e: KeyboardEvent) => void) | null = null;\n\n constructor(\n private readonly colors: ThemeColors,\n private readonly t: TFunction,\n ) {\n this.root = el(\"div\", {\n style: `\n position:fixed;\n z-index:${Z_INDEX_MAX};\n width:300px;\n padding:16px;\n border-radius:16px;\n background:${this.colors.glassBg};\n backdrop-filter:blur(24px);\n -webkit-backdrop-filter:blur(24px);\n border:1px solid ${this.colors.glassBorder};\n box-shadow:0 8px 32px ${this.colors.shadow}, 0 2px 8px ${this.colors.shadow};\n font-family:\"Inter\",system-ui,-apple-system,sans-serif;\n opacity:0;\n transform:translateY(8px) scale(0.98);\n transition:opacity 0.25s cubic-bezier(0.16, 1, 0.3, 1),transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);\n display:none;\n -webkit-font-smoothing:antialiased;\n `,\n });\n\n this.root.setAttribute(\"role\", \"dialog\");\n this.root.setAttribute(\"aria-modal\", \"true\");\n this.root.setAttribute(\"aria-label\", this.t(\"popup.ariaLabel\"));\n\n // Type selector grid (2x2)\n const typeOptions: TypeOption[] = [\n { type: \"question\", label: this.t(\"type.question\"), icon: ICON_QUESTION },\n { type: \"change\", label: this.t(\"type.change\"), icon: ICON_CHANGE },\n { type: \"bug\", label: this.t(\"type.bug\"), icon: ICON_BUG },\n { type: \"other\", label: this.t(\"type.other\"), icon: ICON_OTHER },\n ];\n const typeRow = el(\"div\", { style: \"display:grid;grid-template-columns:1fr 1fr;gap:6px;margin-bottom:12px;\" });\n for (const option of typeOptions) {\n const btn = document.createElement(\"button\");\n btn.style.cssText = `\n height:44px;\n border-radius:9999px;border:1px solid ${this.colors.border};\n background:${this.colors.glassBg};cursor:pointer;\n display:flex;align-items:center;justify-content:center;gap:5px;\n font-family:\"Inter\",system-ui,-apple-system,sans-serif;\n font-size:13px;font-weight:500;color:${this.colors.textTertiary};\n transition:all 0.2s ease;\n padding:0 12px;\n `;\n const icon = parseSvg(option.icon);\n icon.setAttribute(\"style\", \"width:13px;height:13px;flex-shrink:0;\");\n btn.appendChild(icon);\n const labelSpan = document.createElement(\"span\");\n setText(labelSpan, option.label);\n btn.appendChild(labelSpan);\n btn.dataset.type = option.type;\n btn.setAttribute(\"aria-pressed\", \"false\");\n\n btn.addEventListener(\"click\", () => {\n this.selectType(option.type, typeRow);\n });\n\n btn.addEventListener(\"mouseenter\", () => {\n if (btn.dataset.type !== this.selectedType) {\n const bgColor = getTypeBgColor(btn.dataset.type ?? \"\", this.colors);\n btn.style.background = bgColor;\n btn.style.borderColor = getTypeColor(btn.dataset.type ?? \"\", this.colors) + \"40\";\n }\n });\n\n btn.addEventListener(\"mouseleave\", () => {\n if (btn.dataset.type !== this.selectedType) {\n btn.style.background = this.colors.glassBg;\n btn.style.borderColor = this.colors.border;\n }\n });\n\n typeRow.appendChild(btn);\n }\n\n // Textarea\n this.textarea = document.createElement(\"textarea\");\n this.textarea.style.cssText = `\n width:100%;min-height:72px;max-height:152px;\n padding:10px 12px;border-radius:12px;\n border:1px solid ${this.colors.border};\n background:${this.colors.glassBgHeavy};\n color:${this.colors.text};font-family:\"Inter\",system-ui,-apple-system,sans-serif;\n font-size:13px;line-height:1.5;resize:vertical;\n outline:none;transition:all 0.2s ease;\n box-sizing:border-box;\n `;\n this.textarea.placeholder = this.t(\"popup.placeholder\");\n this.textarea.maxLength = 5000;\n this.textarea.setAttribute(\"aria-label\", this.t(\"popup.textareaAria\"));\n\n // Keyboard shortcut hint\n const hint = el(\"div\", {\n style: `\n font-size:11px;color:${this.colors.textTertiary};\n text-align:right;margin-top:4px;\n font-family:\"Inter\",system-ui,-apple-system,sans-serif;\n letter-spacing:0.01em;\n `,\n });\n // navigator.userAgentData is preferred; navigator.platform is deprecated\n // but still needed as fallback. If both are unavailable, fall back to user agent string parsing.\n const uaData = (navigator as Navigator & { userAgentData?: { platform?: string } }).userAgentData;\n const isMac = uaData\n ? uaData.platform === \"macOS\"\n : (navigator.platform?.includes(\"Mac\") ?? /Macintosh|Mac OS X/i.test(navigator.userAgent));\n setText(hint, isMac ? this.t(\"popup.submitHintMac\") : this.t(\"popup.submitHintOther\"));\n\n this.textarea.addEventListener(\"focus\", () => {\n this.textarea.style.borderColor = this.colors.accent;\n this.textarea.style.boxShadow = `0 0 0 3px ${this.colors.accent}14`;\n this.textarea.style.background = this.colors.bg;\n });\n this.textarea.addEventListener(\"blur\", () => {\n this.textarea.style.borderColor = this.colors.border;\n this.textarea.style.boxShadow = \"none\";\n this.textarea.style.background = this.colors.glassBgHeavy;\n });\n this.textarea.addEventListener(\"input\", () => {\n this.updateSubmitState();\n });\n this.textarea.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\" && (e.ctrlKey || e.metaKey)) {\n e.preventDefault();\n this.submit();\n }\n if (e.key === \"Escape\") {\n this.cancel();\n }\n });\n\n // Button row\n const btnRow = el(\"div\", { style: \"display:flex;justify-content:flex-end;gap:8px;margin-top:12px;\" });\n\n const cancelBtn = document.createElement(\"button\");\n cancelBtn.style.cssText = `\n height:34px;padding:0 16px;border-radius:9999px;\n border:1px solid ${this.colors.border};\n background:${this.colors.glassBg};\n color:${this.colors.textTertiary};font-family:\"Inter\",system-ui,-apple-system,sans-serif;\n font-size:13px;font-weight:500;cursor:pointer;\n transition:all 0.2s ease;\n `;\n setText(cancelBtn, this.t(\"popup.cancel\"));\n cancelBtn.addEventListener(\"click\", () => this.cancel());\n cancelBtn.addEventListener(\"mouseenter\", () => {\n cancelBtn.style.borderColor = this.colors.accent;\n cancelBtn.style.color = this.colors.accent;\n });\n cancelBtn.addEventListener(\"mouseleave\", () => {\n cancelBtn.style.borderColor = this.colors.border;\n cancelBtn.style.color = this.colors.textTertiary;\n });\n\n this.submitBtn = document.createElement(\"button\");\n this.submitBtn.style.cssText = `\n height:34px;padding:0 18px;border-radius:9999px;\n border:none;background:${this.colors.accentGradient};\n color:#fff;font-family:\"Inter\",system-ui,-apple-system,sans-serif;\n font-size:13px;font-weight:600;cursor:pointer;\n opacity:0.35;pointer-events:none;\n transition:all 0.2s ease;\n box-shadow:0 2px 8px ${this.colors.accentGlow};\n `;\n setText(this.submitBtn, this.t(\"popup.submit\"));\n this.submitBtn.addEventListener(\"click\", () => this.submit());\n\n btnRow.appendChild(cancelBtn);\n btnRow.appendChild(this.submitBtn);\n\n this.root.appendChild(typeRow);\n this.root.appendChild(this.textarea);\n this.root.appendChild(hint);\n this.root.appendChild(btnRow);\n document.body.appendChild(this.root);\n }\n\n /**\n * Show the popup near a drawn rectangle and return the user's input.\n * Returns null if cancelled.\n */\n show(rectBounds: DOMRect): Promise<PopupResult | null> {\n return new Promise((resolve) => {\n this.resolve = resolve;\n this.selectedType = null;\n this.textarea.value = \"\";\n this.updateSubmitState();\n this.resetTypeButtons();\n\n // Save focus to restore on close\n this.previouslyFocused = document.activeElement as HTMLElement | null;\n\n // Position: bottom-left of rect, 8px below\n const popupH = 220;\n const popupW = 300;\n let top = rectBounds.bottom + 8;\n let left = rectBounds.left;\n\n // Vertical: prefer below; fall back to above; otherwise clamp inside viewport\n if (top + popupH > window.innerHeight) {\n const aboveTop = rectBounds.top - popupH - 8;\n if (aboveTop >= 8) {\n top = aboveTop;\n } else {\n // Rect is taller than the viewport allows on either side —\n // clamp to keep the popup fully visible.\n top = window.innerHeight - popupH - 8;\n }\n }\n // Collision: flip right if not enough space on left\n if (left + popupW > window.innerWidth) {\n left = rectBounds.right - popupW;\n }\n left = Math.max(8, left);\n top = Math.max(8, top);\n\n this.root.style.top = `${top}px`;\n this.root.style.left = `${left}px`;\n this.root.style.display = \"block\";\n\n // Install focus trap\n this.onKeydownTrap = (e: KeyboardEvent) => {\n if (e.key === \"Tab\") {\n const focusableEls = Array.from(\n this.root.querySelectorAll<HTMLElement>(\n 'button:not([disabled]), textarea, input, [tabindex]:not([tabindex=\"-1\"])',\n ),\n );\n if (focusableEls.length === 0) return;\n const first = focusableEls[0];\n const last = focusableEls[focusableEls.length - 1];\n if (!first || !last) return;\n if (e.shiftKey) {\n if (document.activeElement === first || !this.root.contains(document.activeElement)) {\n e.preventDefault();\n last.focus();\n }\n } else {\n if (document.activeElement === last || !this.root.contains(document.activeElement)) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n };\n this.root.addEventListener(\"keydown\", this.onKeydownTrap);\n\n // Check prefers-reduced-motion live (not cached at construction time)\n const reduceMotion =\n typeof window !== \"undefined\" && window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n this.root.style.transition = reduceMotion ? \"none\" : \"\";\n\n // Trigger animation\n requestAnimationFrame(() => {\n this.root.style.opacity = \"1\";\n this.root.style.transform = \"translateY(0) scale(1)\";\n this.textarea.focus();\n });\n });\n }\n\n private selectType(type: FeedbackType, container: HTMLElement): void {\n this.selectedType = type;\n const buttons = container.querySelectorAll<HTMLButtonElement>(\"button\");\n for (const btn of buttons) {\n const isActive = btn.dataset.type === type;\n const color = getTypeColor(btn.dataset.type ?? \"\", this.colors);\n const bgColor = getTypeBgColor(btn.dataset.type ?? \"\", this.colors);\n btn.style.background = isActive ? bgColor : this.colors.glassBg;\n btn.style.borderColor = isActive ? color + \"60\" : this.colors.border;\n btn.style.color = isActive ? color : this.colors.textTertiary;\n btn.style.fontWeight = isActive ? \"600\" : \"500\";\n btn.setAttribute(\"aria-pressed\", String(isActive));\n }\n this.updateSubmitState();\n }\n\n private resetTypeButtons(): void {\n const buttons = this.root.querySelectorAll<HTMLButtonElement>(\"button[data-type]\");\n for (const btn of buttons) {\n btn.setAttribute(\"aria-pressed\", \"false\");\n btn.style.background = this.colors.glassBg;\n btn.style.borderColor = this.colors.border;\n btn.style.color = this.colors.textTertiary;\n btn.style.fontWeight = \"500\";\n }\n }\n\n private updateSubmitState(): void {\n const enabled = this.selectedType !== null && this.textarea.value.trim().length > 0;\n this.submitBtn.disabled = !enabled;\n this.submitBtn.style.opacity = enabled ? \"1\" : \"0.35\";\n this.submitBtn.style.pointerEvents = enabled ? \"auto\" : \"none\";\n }\n\n private submit(): void {\n if (!this.selectedType || !this.textarea.value.trim()) return;\n this.resolve?.({ type: this.selectedType, message: this.textarea.value.trim() });\n this.resolve = null;\n this.hideElement();\n }\n\n private cancel(): void {\n this.resolve?.(null);\n this.resolve = null;\n this.hideElement();\n }\n\n private hideElement(): void {\n // Remove focus trap\n if (this.onKeydownTrap) {\n this.root.removeEventListener(\"keydown\", this.onKeydownTrap);\n this.onKeydownTrap = null;\n }\n this.root.style.opacity = \"0\";\n this.root.style.transform = \"translateY(8px) scale(0.98)\";\n // Restore focus to the previously focused element\n this.previouslyFocused?.focus();\n this.previouslyFocused = null;\n setTimeout(() => {\n this.root.style.display = \"none\";\n }, 250);\n }\n\n destroy(): void {\n this.root.remove();\n }\n}\n","/**\n * Screenshot capture via html2canvas.\n *\n * `html2canvas` is a regular `dependency` of `@siteping/widget` — every\n * install gets it. We dynamic-import it so bundlers emit a separate chunk\n * loaded only when `enableScreenshot: true` triggers the first capture;\n * hosts that never enable screenshots pay only the disk-space cost.\n *\n * On capture failure (content-tainted canvas, version mismatch, missing 2D\n * context) we return `null` rather than throwing — the feedback is still\n * submitted, just without an image.\n */\n\ntype Html2CanvasFn = (element: HTMLElement, options?: Html2CanvasOptions) => Promise<HTMLCanvasElement>;\n\ninterface Html2CanvasOptions {\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n scale?: number;\n useCORS?: boolean;\n allowTaint?: boolean;\n logging?: boolean;\n ignoreElements?: (element: Element) => boolean;\n}\n\nlet cachedHtml2Canvas: Html2CanvasFn | null | undefined; // undefined = not loaded yet, null = failed\nlet warnedAboutMissingDep = false;\n\nasync function loadHtml2Canvas(): Promise<Html2CanvasFn | null> {\n if (cachedHtml2Canvas !== undefined) return cachedHtml2Canvas;\n try {\n // Static dynamic import — bundlers (Vite, webpack, esbuild) resolve this\n // at build time and emit a separate chunk loaded only on first capture.\n // html2canvas ships as a regular dependency so this resolves on every\n // install. Earlier attempts to dodge static resolution via magic comments\n // silently broke production: bare specifiers can't be resolved at runtime\n // in browsers without import maps.\n const mod = (await import(\"html2canvas\")) as { default?: Html2CanvasFn } & Html2CanvasFn;\n cachedHtml2Canvas = (mod.default ?? mod) as Html2CanvasFn;\n return cachedHtml2Canvas;\n } catch (err) {\n cachedHtml2Canvas = null;\n if (!warnedAboutMissingDep) {\n warnedAboutMissingDep = true;\n console.warn(\n \"[siteping] html2canvas import failed unexpectedly. Capture is disabled for this session — feedbacks are still submitted, just without screenshots. Underlying error:\",\n err,\n );\n }\n return null;\n }\n}\n\nexport interface CaptureOptions {\n /** JPEG quality 0..1 (default 0.85). */\n quality?: number;\n /** Max output width in CSS pixels (default 1200). Wider canvases are downscaled. */\n maxWidth?: number;\n}\n\n/**\n * Capture the page region within `rect` as a JPEG data URL. Returns `null`\n * on any failure — callers should not abort feedback submission.\n *\n * - Excludes Siteping's own overlay elements via `ignoreElements`\n * - Honors devicePixelRatio for crisp captures, then downscales to `maxWidth`\n * - JPEG at `quality` (0.85 = ~50–150 KB for a typical annotated area)\n */\nexport async function captureScreenshot(rect: DOMRect, options?: CaptureOptions): Promise<string | null> {\n const html2canvas = await loadHtml2Canvas();\n if (!html2canvas) return null;\n\n const quality = options?.quality ?? 0.85;\n const maxWidth = options?.maxWidth ?? 1200;\n\n try {\n const canvas = await html2canvas(document.body, {\n x: window.scrollX + rect.x,\n y: window.scrollY + rect.y,\n width: rect.width,\n height: rect.height,\n scale: window.devicePixelRatio,\n useCORS: true,\n allowTaint: true,\n logging: false,\n ignoreElements: (element: Element) => {\n return (\n element.tagName === \"SITEPING-WIDGET\" ||\n element.closest?.(\"siteping-widget\") !== null ||\n element.getAttribute?.(\"data-siteping-ignore\") === \"true\"\n );\n },\n });\n\n if (canvas.width <= maxWidth) {\n return canvas.toDataURL(\"image/jpeg\", quality);\n }\n\n // Downscale via an off-DOM canvas — keeps payload reasonable on\n // hi-DPI displays where the raw capture can be 2x–3x intended size.\n const ratio = maxWidth / canvas.width;\n const targetW = maxWidth;\n const targetH = Math.round(canvas.height * ratio);\n\n const scaled = document.createElement(\"canvas\");\n scaled.width = targetW;\n scaled.height = targetH;\n const ctx = scaled.getContext(\"2d\");\n if (!ctx) return null;\n ctx.drawImage(canvas, 0, 0, targetW, targetH);\n return scaled.toDataURL(\"image/jpeg\", quality);\n } catch (err) {\n console.warn(\"[siteping] Screenshot capture failed:\", err);\n return null;\n }\n}\n\n/** @internal — exposed for tests. Resets the dynamic-import cache. */\nexport function _resetScreenshotCacheForTests(): void {\n cachedHtml2Canvas = undefined;\n warnedAboutMissingDep = false;\n}\n","import type { AnnotationPayload, FeedbackType } from \"@siteping/core\";\nimport { Z_INDEX_MAX } from \"./constants.js\";\nimport { findAnchorElement, generateAnchor, rectToPercentages } from \"./dom/anchor.js\";\nimport { el, setText } from \"./dom-utils.js\";\nimport type { EventBus, WidgetEvents } from \"./events.js\";\nimport type { TFunction } from \"./i18n/index.js\";\nimport { Popup } from \"./popup.js\";\nimport { captureScreenshot } from \"./screenshot.js\";\nimport type { ThemeColors } from \"./styles/theme.js\";\n\nexport interface AnnotationComplete {\n annotation: AnnotationPayload;\n type: FeedbackType;\n message: string;\n /**\n * Base64 JPEG `data:` URL captured by html2canvas, or null when capture\n * is disabled / failed / the peer dep is missing.\n */\n screenshotDataUrl?: string | null | undefined;\n}\n\n/**\n * Annotation mode: full-page overlay with rectangle drawing.\n *\n * Glassmorphism design:\n * - Frosted glass toolbar at top\n * - Subtle tinted overlay\n * - Accent-colored drawing rectangle with glow\n */\nexport class Annotator {\n private overlay: HTMLElement | null = null;\n private toolbar: HTMLElement | null = null;\n private drawingRect: HTMLElement | null = null;\n private startX = 0;\n private startY = 0;\n private isDrawing = false;\n private isActive = false;\n private popup: Popup;\n private savedOverflow = \"\";\n private preActiveFocusElement: Element | null = null;\n private rafId: number | null = null;\n private pendingMoveEvent: MouseEvent | Touch | null = null;\n\n constructor(\n private readonly colors: ThemeColors,\n private readonly bus: EventBus<WidgetEvents>,\n private readonly t: TFunction,\n private readonly enableScreenshot: boolean = false,\n ) {\n this.popup = new Popup(colors, t);\n\n this.bus.on(\"annotation:start\", () => this.activate());\n }\n\n /**\n * Capture a screenshot of the drawn rect when `enableScreenshot` is on.\n * Returns null on disable / capture failure / missing peer dep — the\n * feedback is always submitted regardless.\n */\n private async maybeCapture(rect: DOMRect): Promise<string | null> {\n if (!this.enableScreenshot) return null;\n return captureScreenshot(rect);\n }\n\n private activate(): void {\n if (this.isActive) return;\n this.isActive = true;\n\n // Capture the focused element before activation for keyboard annotation\n this.preActiveFocusElement = document.activeElement;\n\n // Lock page scroll\n this.savedOverflow = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n\n // Overlay — subtle blue tint for depth\n this.overlay = el(\"div\", {\n style: `\n position:fixed;inset:0;\n z-index:${Z_INDEX_MAX - 1};\n background:rgba(15, 23, 42, 0.04);\n cursor:crosshair;\n `,\n });\n this.overlay.setAttribute(\"aria-hidden\", \"true\");\n\n // Toolbar — glassmorphism bar\n this.toolbar = el(\"div\", {\n style: `\n position:fixed;top:0;left:0;right:0;\n z-index:${Z_INDEX_MAX};\n height:52px;\n background:${this.colors.glassBg};\n backdrop-filter:blur(24px);\n -webkit-backdrop-filter:blur(24px);\n border-bottom:1px solid ${this.colors.glassBorder};\n display:flex;align-items:center;justify-content:center;gap:16px;\n font-family:\"Inter\",system-ui,-apple-system,sans-serif;\n font-size:14px;color:${this.colors.text};\n box-shadow:0 4px 16px ${this.colors.shadow};\n -webkit-font-smoothing:antialiased;\n `,\n });\n\n const dot = el(\"span\", {\n style: `\n width:8px;height:8px;border-radius:50%;\n background:${this.colors.accent};\n box-shadow:0 0 8px ${this.colors.accentGlow};\n animation:pulse 1.5s ease-in-out infinite;\n `,\n });\n\n // Add pulse animation inline (respects prefers-reduced-motion)\n const style = document.createElement(\"style\");\n style.textContent = [\n \"@keyframes pulse{0%,100%{opacity:1}50%{opacity:0.4}}\",\n \"@media(prefers-reduced-motion:reduce){@keyframes pulse{from,to{opacity:1}}}\",\n ].join(\"\");\n this.toolbar.appendChild(style);\n\n const instruction = el(\"span\", { style: \"font-weight:500;letter-spacing:-0.01em;\" });\n setText(instruction, this.t(\"annotator.instruction\"));\n\n const cancelBtn = document.createElement(\"button\");\n cancelBtn.style.cssText = `\n height:34px;padding:0 18px;border-radius:9999px;\n border:1px solid ${this.colors.border};\n background:${this.colors.glassBg};\n color:${this.colors.textTertiary};font-family:\"Inter\",system-ui,-apple-system,sans-serif;\n font-size:13px;font-weight:500;cursor:pointer;\n transition:all 0.2s ease;\n `;\n setText(cancelBtn, this.t(\"annotator.cancel\"));\n cancelBtn.addEventListener(\"click\", () => this.deactivate());\n cancelBtn.addEventListener(\"mouseenter\", () => {\n cancelBtn.style.borderColor = this.colors.typeBug;\n cancelBtn.style.color = this.colors.typeBug;\n cancelBtn.style.background = this.colors.typeBugBg;\n });\n cancelBtn.addEventListener(\"mouseleave\", () => {\n cancelBtn.style.borderColor = this.colors.border;\n cancelBtn.style.color = this.colors.textTertiary;\n cancelBtn.style.background = this.colors.glassBg;\n });\n\n this.toolbar.appendChild(dot);\n this.toolbar.appendChild(instruction);\n this.toolbar.appendChild(cancelBtn);\n\n // Mouse events\n this.overlay.addEventListener(\"mousedown\", this.onMouseDown);\n this.overlay.addEventListener(\"mousemove\", this.onMouseMove);\n this.overlay.addEventListener(\"mouseup\", this.onMouseUp);\n\n // Touch events (Surface Pro, iPad, etc.)\n this.overlay.addEventListener(\"touchstart\", this.onTouchStart, { passive: false });\n this.overlay.addEventListener(\"touchmove\", this.onTouchMove, { passive: false });\n this.overlay.addEventListener(\"touchend\", this.onTouchEnd);\n\n // Keyboard annotation: Enter selects the pre-activation focused element\n this.overlay.addEventListener(\"keydown\", this.onOverlayKeyDown);\n\n // Allow tab-through so keyboard users can reach underlying elements\n this.overlay.setAttribute(\"tabindex\", \"0\");\n\n // Escape to cancel\n document.addEventListener(\"keydown\", this.onKeyDown);\n\n document.body.appendChild(this.overlay);\n document.body.appendChild(this.toolbar);\n }\n\n private deactivate(): void {\n if (!this.isActive) return;\n this.isActive = false;\n this.isDrawing = false;\n this.preActiveFocusElement = null;\n\n // Cancel any pending rAF to prevent stale callbacks\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n this.pendingMoveEvent = null;\n\n document.body.style.overflow = this.savedOverflow;\n document.removeEventListener(\"keydown\", this.onKeyDown);\n\n this.overlay?.remove();\n this.toolbar?.remove();\n this.drawingRect?.remove();\n this.overlay = null;\n this.toolbar = null;\n this.drawingRect = null;\n\n this.bus.emit(\"annotation:end\");\n }\n\n private onKeyDown = (e: KeyboardEvent): void => {\n if (e.key === \"Escape\") this.deactivate();\n };\n\n /**\n * Keyboard annotation: pressing Enter while the overlay is active selects\n * the element that was focused before activation and creates a full-bounds\n * annotation covering that element (WCAG 2.1.1 Level A).\n */\n private onOverlayKeyDown = async (e: KeyboardEvent): Promise<void> => {\n if (e.key !== \"Enter\") return;\n e.preventDefault();\n\n const target = this.preActiveFocusElement;\n if (!target || !(target instanceof HTMLElement)) return;\n\n const bounds = target.getBoundingClientRect();\n if (bounds.width <= 0 || bounds.height <= 0) return;\n\n const rectBounds = new DOMRect(bounds.x, bounds.y, bounds.width, bounds.height);\n\n const result = await this.popup.show(rectBounds);\n if (!result) return;\n\n const anchor = generateAnchor(target);\n const annotation: AnnotationPayload = {\n anchor,\n rect: { xPct: 0, yPct: 0, wPct: 1, hPct: 1 },\n scrollX: window.scrollX,\n scrollY: window.scrollY,\n viewportW: window.innerWidth,\n viewportH: window.innerHeight,\n devicePixelRatio: window.devicePixelRatio,\n };\n\n // Capture before deactivate — overlay is intentionally ignored by the\n // capture predicate but the rect must still be on the page.\n const screenshotDataUrl = await this.maybeCapture(rectBounds);\n\n this.deactivate();\n\n this.bus.emit(\"annotation:complete\", {\n annotation,\n type: result.type,\n message: result.message,\n screenshotDataUrl,\n });\n };\n\n private onMouseDown = (e: MouseEvent): void => {\n this.startDrawing(e.clientX, e.clientY);\n };\n\n private onTouchStart = (e: TouchEvent): void => {\n e.preventDefault();\n const touch = e.touches[0];\n if (touch) this.startDrawing(touch.clientX, touch.clientY);\n };\n\n private startDrawing(clientX: number, clientY: number): void {\n this.isDrawing = true;\n this.startX = clientX;\n this.startY = clientY;\n\n this.drawingRect?.remove();\n this.drawingRect = el(\"div\", {\n style: `\n position:fixed;\n border:2px solid ${this.colors.accent};\n background:${this.colors.accent}12;\n pointer-events:none;\n border-radius:8px;\n box-shadow:0 0 16px ${this.colors.accentGlow};\n transition:box-shadow 0.15s ease;\n `,\n });\n this.overlay?.appendChild(this.drawingRect);\n }\n\n private onMouseMove = (e: MouseEvent): void => {\n this.scheduleRectUpdate(e);\n };\n\n private onTouchMove = (e: TouchEvent): void => {\n e.preventDefault();\n if (e.touches[0]) this.scheduleRectUpdate(e.touches[0]);\n };\n\n private scheduleRectUpdate(source: MouseEvent | Touch): void {\n if (!this.isDrawing || !this.drawingRect) return;\n\n this.pendingMoveEvent = source;\n if (this.rafId !== null) return;\n\n this.rafId = requestAnimationFrame(() => {\n this.rafId = null;\n const evt = this.pendingMoveEvent;\n if (!evt || !this.drawingRect) return;\n\n const x = Math.min(evt.clientX, this.startX);\n const y = Math.min(evt.clientY, this.startY);\n const w = Math.abs(evt.clientX - this.startX);\n const h = Math.abs(evt.clientY - this.startY);\n\n this.drawingRect.style.left = `${x}px`;\n this.drawingRect.style.top = `${y}px`;\n this.drawingRect.style.width = `${w}px`;\n this.drawingRect.style.height = `${h}px`;\n });\n }\n\n private onTouchEnd = async (e: TouchEvent): Promise<void> => {\n const touch = e.changedTouches[0];\n if (touch) await this.finishDrawing(touch.clientX, touch.clientY);\n };\n\n private onMouseUp = async (e: MouseEvent): Promise<void> => {\n await this.finishDrawing(e.clientX, e.clientY);\n };\n\n private finishDrawing = async (clientX: number, clientY: number): Promise<void> => {\n if (!this.isDrawing || !this.drawingRect) return;\n this.isDrawing = false;\n\n const x = Math.min(clientX, this.startX);\n const y = Math.min(clientY, this.startY);\n const w = Math.abs(clientX - this.startX);\n const h = Math.abs(clientY - this.startY);\n\n // Ignore tiny rectangles (accidental clicks)\n if (w < 10 || h < 10) {\n this.drawingRect.remove();\n this.drawingRect = null;\n return;\n }\n\n const rectBounds = new DOMRect(x, y, w, h);\n\n // Show popup for type + message\n const result = await this.popup.show(rectBounds);\n\n if (!result) {\n this.drawingRect?.remove();\n this.drawingRect = null;\n return;\n }\n\n // Build annotation payload BEFORE deactivating (needs overlay for elementFromPoint)\n const annotation = this.buildAnnotation(rectBounds);\n this.drawingRect?.remove();\n this.drawingRect = null;\n\n // Capture before deactivate — html2canvas walks the live DOM, and the\n // capture predicate skips siteping-widget elements so the overlay being\n // present on screen doesn't matter.\n const screenshotDataUrl = await this.maybeCapture(rectBounds);\n\n this.deactivate();\n\n // Emit via event bus (not DOM — overlay is already null after deactivate)\n this.bus.emit(\"annotation:complete\", {\n annotation,\n type: result.type,\n message: result.message,\n screenshotDataUrl,\n });\n };\n\n /**\n * Build an AnnotationPayload from a drawn rectangle.\n * Temporarily hides the overlay to access the real DOM underneath.\n */\n private buildAnnotation(rectBounds: DOMRect): AnnotationPayload {\n // Temporarily hide overlay to find the real element underneath\n if (this.overlay) this.overlay.style.pointerEvents = \"none\";\n const anchorElement = findAnchorElement(rectBounds);\n if (this.overlay) this.overlay.style.pointerEvents = \"auto\";\n\n const anchor = generateAnchor(anchorElement);\n const anchorBounds = anchorElement.getBoundingClientRect();\n const rect = rectToPercentages(rectBounds, anchorBounds);\n\n return {\n anchor,\n rect,\n scrollX: window.scrollX,\n scrollY: window.scrollY,\n viewportW: window.innerWidth,\n viewportH: window.innerHeight,\n devicePixelRatio: window.devicePixelRatio,\n };\n }\n destroy(): void {\n this.deactivate();\n this.popup.destroy();\n }\n}\n","/**\n * Typed error hierarchy for Siteping client/server boundaries.\n *\n * Consumers can `instanceof`-check or read `code` / `retryable` instead of\n * pattern-matching error messages. Designed to be additive on top of the\n * existing store errors (`StoreNotFoundError`, `StoreDuplicateError`) which\n * remain the canonical signals for server-side store implementations.\n *\n * Usage on the widget side (api-client.ts):\n * - fetch failures / aborts / timeouts → `SitepingNetworkError` (retryable)\n * - HTTP 4xx (except 401/403) → `SitepingValidationError` (not retryable)\n * - HTTP 401 / 403 → `SitepingAuthError` (not retryable)\n * - everything else → `SitepingError` generic\n *\n * `retryable` is meta information surfaced to host apps that want to wire\n * their own retry/queue/backoff strategy — the widget already retries\n * network failures via its built-in retry queue.\n */\n\nexport class SitepingError extends Error {\n readonly code: string;\n readonly retryable: boolean;\n\n constructor(message: string, code: string, retryable: boolean) {\n super(message);\n this.code = code;\n this.retryable = retryable;\n this.name = \"SitepingError\";\n }\n}\n\n/** Network-level failure: connection refused, DNS, CORS, timeout, abort. Retryable. */\nexport class SitepingNetworkError extends SitepingError {\n constructor(message: string) {\n super(message, \"NETWORK\", true);\n this.name = \"SitepingNetworkError\";\n }\n}\n\n/** Server rejected the request (4xx, not auth). Validation problem on the client side. */\nexport class SitepingValidationError extends SitepingError {\n constructor(message: string) {\n super(message, \"VALIDATION\", false);\n this.name = \"SitepingValidationError\";\n }\n}\n\n/** Server rejected auth (401 or 403). Not retryable without fresh credentials. */\nexport class SitepingAuthError extends SitepingError {\n constructor(message: string) {\n super(message, \"AUTH\", false);\n this.name = \"SitepingAuthError\";\n }\n}\n","// ---------------------------------------------------------------------------\n// Config\n// ---------------------------------------------------------------------------\n\n/** Configuration options for the Siteping widget. */\nexport interface SitepingConfig {\n /** HTTP endpoint that receives feedbacks (e.g. '/api/siteping'). Required unless `store` is provided. */\n endpoint?: string | undefined;\n /** Required — project identifier used to scope feedbacks */\n projectName: string;\n /** Direct store for client-side mode. When set, bypasses HTTP and uses the store directly in the browser. */\n store?: SitepingStore | undefined;\n /** FAB position — defaults to 'bottom-right' */\n position?: \"bottom-right\" | \"bottom-left\";\n /** Accent color for the widget UI — defaults to '#0066ff' */\n accentColor?: string;\n /** Show the widget even in production — defaults to false */\n forceShow?: boolean;\n /** Enable debug logging of lifecycle events — defaults to false */\n debug?: boolean;\n /** Color theme — defaults to 'light' */\n theme?: \"light\" | \"dark\" | \"auto\";\n /** UI locale — defaults to 'en'. Built-in: en, fr, de, es, it, pt (Brazilian), ru. Any other string falls back to English. */\n locale?: \"en\" | \"fr\" | \"de\" | \"es\" | \"it\" | \"pt\" | \"ru\" | (string & {}) | undefined;\n /**\n * Returns the current page scope for annotations and panel filtering.\n * Called on initial markers load and on `instance.refresh()`.\n *\n * Default: `{ url: window.location.pathname, urlPattern: null }` — annotations\n * are scoped strictly to the current pathname.\n *\n * Apps with parameterized routes (e.g. React Router) should return both the\n * concrete URL and the route template (e.g. `/orders/:orderId`) so the panel\n * can offer a \"this type of page\" filter that groups feedbacks by template.\n */\n getPageScope?: (() => PageScope) | undefined;\n /**\n * When true (default), the widget filters initial markers and panel results\n * by `feedback.url === scope.url`, so annotations created on one page never\n * leak to other pages — even if their CSS selector accidentally matches.\n * Set to `false` to revert to the legacy project-wide behavior.\n */\n scopeAnnotationsByUrl?: boolean | undefined;\n /**\n * Capture a JPEG screenshot of the annotated area on submit. Defaults to\n * `false` — opt-in because:\n *\n * - it adds runtime weight (~40 KB gzip dynamic chunk for html2canvas,\n * loaded only on first capture),\n * - it embeds page content in the feedback (privacy/GDPR consideration —\n * inform end users in your widget host UI when enabling).\n *\n * `html2canvas` ships as a regular dependency of `@siteping/widget` so the\n * dynamic import always resolves; you don't need to install anything extra.\n *\n * **Masking sensitive elements:** add `data-siteping-ignore=\"true\"` to any\n * element you do NOT want captured (password fields, credit-card forms,\n * API tokens shown in the UI, etc.). The capture predicate skips matching\n * elements *and their descendants*. Do this BEFORE turning on screenshots\n * in production — once a feedback is saved, the screenshot is in your DB\n * (or object storage) regardless of what was on the page.\n */\n enableScreenshot?: boolean | undefined;\n /**\n * Capture the last few `console.*` calls and failed network requests\n * (HTTP >= 400 or network error) at the moment a feedback is submitted.\n *\n * Lets reviewers replay the technical context that led to the report —\n * stack traces, 500 responses, dead third-party scripts. Great for the\n * \"the page just doesn't work\" feedback that contains zero detail.\n *\n * - `true` — capture with defaults (50 console / 20 network entries).\n * - `false` (default) — no capture, no monkey-patching.\n * - object — per-channel toggles + custom buffer sizes.\n *\n * **Privacy considerations:** console messages may contain anything the\n * host page logs, including user data. Failed network requests record the\n * URL (with query string) but never the response body. Inform end users\n * before enabling in environments where they might log sensitive values.\n */\n captureDiagnostics?:\n | boolean\n | {\n console?: boolean;\n network?: boolean;\n maxConsoleEntries?: number;\n maxNetworkEntries?: number;\n }\n | undefined;\n /** Called when the widget is skipped (production mode, mobile viewport) */\n onSkip?: (reason: \"production\" | \"mobile\") => void;\n /**\n * Auto-focus a specific annotation when its ID appears in the URL query\n * string. Lets hosts deeplink directly into a feedback from external\n * systems (Zammad tickets, Slack notifications, dashboard rows).\n *\n * When enabled, the widget reads the configured query parameter from\n * `window.location.search` right after the initial markers load. If the\n * value matches a visible feedback ID, the widget scrolls the annotation\n * into view, pins its highlight, and pulses the marker — the same visual\n * affordance a marker click produces.\n *\n * - `false` / `undefined` (default): no URL parsing. Existing behavior\n * unchanged, no host URL inspection.\n * - `true`: enabled with default query parameter name `siteping`.\n * - object: enabled with a custom parameter name. Use this to avoid\n * clashes with host-app query keys.\n *\n * Only the initial load triggers focus. Subsequent URL changes (SPA\n * navigation, `history.pushState`, hash updates) are ignored —\n * deliberate, to avoid surprising re-scrolls during normal browsing.\n * Hosts that need re-focus on route change can call\n * `instance.focusFeedback(id)` explicitly.\n */\n deepLink?: boolean | { param?: string } | undefined;\n /**\n * Pre-fill author identity from the host application — typically the\n * currently signed-in user. When set, the widget uses these values\n * directly and never shows the identity modal, even on first feedback.\n *\n * Use case: SSO-integrated apps where the end user is already\n * authenticated by the host. Avoids the awkward \"enter your name and\n * email\" prompt for users the host already knows.\n *\n * When unset (default), the widget falls back to localStorage and shows\n * the modal on first feedback as before — existing behavior unchanged.\n *\n * Note: `config.identity` is **not** persisted to localStorage. It is\n * read at widget init time, not on every render. Hosts that need live\n * identity updates after sign-in/sign-out should currently remount the\n * widget (e.g. via a React `key` on the wrapping component). See\n * https://github.com/NeosiaNexus/SitePing/issues/85 for tracking a\n * future enhancement that propagates identity updates without a remount.\n */\n identity?: { name: string; email: string } | undefined;\n\n // Events\n /** Called when the feedback panel is opened. */\n onOpen?: () => void;\n /** Called when the feedback panel is closed. */\n onClose?: () => void;\n onFeedbackSent?: (feedback: FeedbackResponse) => void;\n /**\n * Called when a feedback API call fails.\n *\n * The widget always emits a `SitepingError` (or a subclass:\n * `SitepingNetworkError`, `SitepingValidationError`, `SitepingAuthError`)\n * for HTTP-mode failures — host apps can `instanceof` to drive retry\n * logic, or read `error.code` (`\"NETWORK\" | \"VALIDATION\" | \"AUTH\" |\n * \"SERVER\"`) and `error.retryable`. The type is widened to `Error` so\n * direct-store callers can still surface raw errors without breaking the\n * contract.\n */\n onError?: (error: Error) => void;\n /** Called when the user starts drawing an annotation. */\n onAnnotationStart?: () => void;\n /** Called when the user finishes drawing an annotation. */\n onAnnotationEnd?: () => void;\n}\n\n/** Instance returned by initSiteping() with lifecycle methods. */\nexport interface SitepingInstance {\n /** Remove the widget from the DOM and clean up all listeners. */\n destroy: () => void;\n /** Open the panel programmatically */\n open: () => void;\n /** Close the panel */\n close: () => void;\n /** Reload feedbacks from server */\n refresh: () => void;\n /**\n * Scroll the matching annotation into view, pin its highlight, and\n * pulse its marker. Returns `true` when a visible feedback matched the\n * given ID, `false` otherwise (unknown ID, feedback on another URL when\n * `scopeAnnotationsByUrl` filtered it out, or markers not yet loaded).\n *\n * Counterpart to the `deepLink` config option for hosts that prefer to\n * drive focus from JS (e.g., a notification click handler) instead of a\n * URL query parameter.\n */\n focusFeedback: (feedbackId: string) => boolean;\n /** Subscribe to a public widget event */\n on: <K extends keyof SitepingPublicEvents>(\n event: K,\n listener: (...args: SitepingPublicEvents[K]) => void,\n ) => () => void;\n /** Unsubscribe from a public widget event */\n off: <K extends keyof SitepingPublicEvents>(event: K, listener: (...args: SitepingPublicEvents[K]) => void) => void;\n}\n\n/** Events exposed to consumers via SitepingInstance.on / .off */\nexport interface SitepingPublicEvents {\n \"feedback:sent\": [FeedbackResponse];\n \"feedback:deleted\": [string];\n \"panel:open\": [];\n \"panel:close\": [];\n}\n\n// ---------------------------------------------------------------------------\n// Feedback\n// ---------------------------------------------------------------------------\n\n/** Single source of truth for feedback types — used by both TS types and Zod schemas. */\nexport const FEEDBACK_TYPES = [\"question\", \"change\", \"bug\", \"other\"] as const;\nexport type FeedbackType = (typeof FEEDBACK_TYPES)[number];\n\n/** Single source of truth for feedback statuses. */\nexport const FEEDBACK_STATUSES = [\"open\", \"resolved\"] as const;\nexport type FeedbackStatus = (typeof FEEDBACK_STATUSES)[number];\n\n/**\n * Page scope returned by `SitepingConfig.getPageScope()`.\n *\n * - `url`: concrete page identifier — usually `window.location.pathname`,\n * used as the strict scope for marker rendering.\n * - `urlPattern`: optional parameterized template (e.g. `/orders/:orderId`)\n * used by the panel's \"this type of page\" filter to group feedbacks across\n * instances of the same page kind.\n */\nexport interface PageScope {\n url: string;\n urlPattern: string | null;\n}\n\n// ---------------------------------------------------------------------------\n// Abstract Store — adapter pattern\n// ---------------------------------------------------------------------------\n\n/** Input for creating a feedback record in the store. */\nexport interface FeedbackCreateInput {\n projectName: string;\n type: FeedbackType;\n message: string;\n status: FeedbackStatus;\n url: string;\n /**\n * Optional parameterized URL template (e.g. `/orders/:orderId`) for the page\n * where the feedback was created. Allows the panel to filter feedbacks by\n * \"this type of page\" across different instances. Null when the host did not\n * provide a `getPageScope` callback or the route has no template.\n */\n urlPattern?: string | null | undefined;\n viewport: string;\n userAgent: string;\n authorName: string;\n authorEmail: string;\n clientId: string;\n annotations: AnnotationCreateInput[];\n /**\n * Base64 JPEG `data:` URL captured by the widget at submit time.\n *\n * Adapters with a configured `ScreenshotStorage` are expected to upload\n * this and persist the returned URL on `FeedbackRecord.screenshotUrl`.\n * Adapters without storage may persist the data URL inline (memory /\n * localStorage / dev) — the widget then renders it directly.\n */\n screenshotDataUrl?: string | null | undefined;\n /**\n * Optional console + failed-network snapshot captured by the widget when\n * `SitepingConfig.captureDiagnostics` is enabled. Stored as JSON on\n * `FeedbackRecord.diagnostics` so reviewers can replay the context.\n */\n diagnostics?: DiagnosticsSnapshot | null | undefined;\n}\n\n/** Input for a single annotation when creating a feedback. */\nexport interface AnnotationCreateInput {\n cssSelector: string;\n xpath: string;\n textSnippet: string;\n elementTag: string;\n elementId?: string | undefined;\n textPrefix: string;\n textSuffix: string;\n fingerprint: string;\n neighborText: string;\n /**\n * Semantic anchor identifier from the closest ancestor's `data-feedback-anchor`\n * attribute. When set, this is the most stable re-anchoring signal because\n * hosts deliberately place these on layout/section roots that survive DOM\n * refactors and viewport changes. Null when no semantic ancestor exists.\n */\n anchorKey?: string | null | undefined;\n xPct: number;\n yPct: number;\n wPct: number;\n hPct: number;\n scrollX: number;\n scrollY: number;\n viewportW: number;\n viewportH: number;\n devicePixelRatio: number;\n}\n\n/** Query parameters for fetching feedbacks. */\nexport interface FeedbackQuery {\n projectName: string;\n type?: FeedbackType | undefined;\n status?: FeedbackStatus | undefined;\n search?: string | undefined;\n page?: number | undefined;\n limit?: number | undefined;\n /**\n * Filter to feedbacks created on this exact URL (path). Used by the panel's\n * \"this page\" filter and by the markers loader to keep page scopes isolated.\n */\n url?: string | undefined;\n /**\n * Filter to feedbacks created on this URL pattern (e.g. `/orders/:orderId`).\n * Used by the panel's \"this type of page\" filter to group feedbacks across\n * different concrete instances of the same template.\n */\n urlPattern?: string | undefined;\n}\n\n/** Update payload for patching a feedback. */\nexport interface FeedbackUpdateInput {\n status: FeedbackStatus;\n resolvedAt: Date | null;\n}\n\n/** A persisted feedback record returned by the store. */\nexport interface FeedbackRecord {\n id: string;\n type: FeedbackType;\n message: string;\n status: FeedbackStatus;\n projectName: string;\n url: string;\n /**\n * Parameterized URL template the feedback was created on.\n * Null for legacy records or hosts without `getPageScope`.\n */\n urlPattern: string | null;\n authorName: string;\n authorEmail: string;\n viewport: string;\n userAgent: string;\n clientId: string;\n resolvedAt: Date | null;\n createdAt: Date;\n updatedAt: Date;\n annotations: AnnotationRecord[];\n /**\n * URL the widget renders as `<img src>`. Either an `https://...` from a\n * configured `ScreenshotStorage`, or a `data:image/jpeg;base64,...` URL\n * inline-persisted by adapters without storage. Null when no screenshot\n * was captured (legacy records, capture failed, or host disabled it).\n */\n screenshotUrl: string | null;\n /**\n * Console + failed-network snapshot captured at submit time. Null when\n * diagnostics weren't enabled on the widget side.\n */\n diagnostics: DiagnosticsSnapshot | null;\n}\n\n/** A persisted annotation record returned by the store. */\nexport interface AnnotationRecord {\n id: string;\n feedbackId: string;\n cssSelector: string;\n xpath: string;\n textSnippet: string;\n elementTag: string;\n elementId: string | null;\n textPrefix: string;\n textSuffix: string;\n fingerprint: string;\n neighborText: string;\n /**\n * Semantic anchor identifier from `data-feedback-anchor`. Null for legacy\n * annotations or those drawn outside any anchored region.\n */\n anchorKey: string | null;\n xPct: number;\n yPct: number;\n wPct: number;\n hPct: number;\n scrollX: number;\n scrollY: number;\n viewportW: number;\n viewportH: number;\n devicePixelRatio: number;\n createdAt: Date;\n}\n\n// ---------------------------------------------------------------------------\n// Store errors — throw these from adapter implementations\n// ---------------------------------------------------------------------------\n\n/**\n * Thrown when a record is not found during update or delete.\n *\n * Handlers translate this to HTTP 404. Adapters MUST throw this (not\n * ORM-specific errors) so the handler layer remains ORM-agnostic.\n */\nexport class StoreNotFoundError extends Error {\n readonly code = \"STORE_NOT_FOUND\" as const;\n constructor(message = \"Record not found\") {\n super(message);\n this.name = \"StoreNotFoundError\";\n }\n}\n\n/**\n * Thrown when a unique constraint is violated (e.g. duplicate `clientId`).\n *\n * Handlers use this to return the existing record instead of failing.\n */\nexport class StoreDuplicateError extends Error {\n readonly code = \"STORE_DUPLICATE\" as const;\n constructor(message = \"Duplicate record\") {\n super(message);\n this.name = \"StoreDuplicateError\";\n }\n}\n\n/** Type guard — works for `StoreNotFoundError` and ORM-specific equivalents (e.g. Prisma P2025). */\nexport function isStoreNotFound(error: unknown): boolean {\n if (error instanceof StoreNotFoundError) return true;\n // Backwards compat: Prisma's P2025\n return typeof error === \"object\" && error !== null && \"code\" in error && (error as { code: string }).code === \"P2025\";\n}\n\n/** Type guard — works for `StoreDuplicateError` and ORM-specific equivalents (e.g. Prisma P2002). */\nexport function isStoreDuplicate(error: unknown): boolean {\n if (error instanceof StoreDuplicateError) return true;\n // Backwards compat: Prisma's P2002\n return typeof error === \"object\" && error !== null && \"code\" in error && (error as { code: string }).code === \"P2002\";\n}\n\n// ---------------------------------------------------------------------------\n// Store helpers — shared conversion logic for adapters\n// ---------------------------------------------------------------------------\n\n/** Flatten a widget `AnnotationPayload` (nested anchor + rect) into a flat `AnnotationCreateInput`. */\nexport function flattenAnnotation(ann: AnnotationPayload): AnnotationCreateInput {\n return {\n cssSelector: ann.anchor.cssSelector,\n xpath: ann.anchor.xpath,\n textSnippet: ann.anchor.textSnippet,\n elementTag: ann.anchor.elementTag,\n elementId: ann.anchor.elementId,\n textPrefix: ann.anchor.textPrefix,\n textSuffix: ann.anchor.textSuffix,\n fingerprint: ann.anchor.fingerprint,\n neighborText: ann.anchor.neighborText,\n anchorKey: ann.anchor.anchorKey ?? null,\n xPct: ann.rect.xPct,\n yPct: ann.rect.yPct,\n wPct: ann.rect.wPct,\n hPct: ann.rect.hPct,\n scrollX: ann.scrollX,\n scrollY: ann.scrollY,\n viewportW: ann.viewportW,\n viewportH: ann.viewportH,\n devicePixelRatio: ann.devicePixelRatio,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Abstract Store — adapter pattern\n// ---------------------------------------------------------------------------\n\n/**\n * Abstract storage interface for Siteping.\n *\n * Any adapter (Prisma, Drizzle, raw SQL, localStorage, etc.) implements this\n * interface. The HTTP handler and widget `StoreClient` operate against\n * `SitepingStore`, decoupled from the storage backend.\n *\n * ## Error contract\n *\n * - **`updateFeedback` / `deleteFeedback`**: throw `StoreNotFoundError` when\n * the record does not exist.\n * - **`createFeedback`**: either return the existing record on duplicate\n * `clientId` (idempotent) or throw `StoreDuplicateError`. The handler\n * handles both patterns.\n * - Other methods should not throw on empty results — return empty arrays or `null`.\n */\nexport interface SitepingStore {\n /** Create a feedback with its annotations. Idempotent on `clientId` — return existing record on duplicate, or throw `StoreDuplicateError`. */\n createFeedback(data: FeedbackCreateInput): Promise<FeedbackRecord>;\n /** Paginated query with optional filters. Returns empty array (not error) when no results. */\n getFeedbacks(query: FeedbackQuery): Promise<{ feedbacks: FeedbackRecord[]; total: number }>;\n /** Lookup by client-generated UUID. Returns `null` (not error) when not found. */\n findByClientId(clientId: string): Promise<FeedbackRecord | null>;\n /** Update status/resolvedAt. Throws `StoreNotFoundError` if `id` does not exist. */\n updateFeedback(id: string, data: FeedbackUpdateInput): Promise<FeedbackRecord>;\n /** Delete a single record. Throws `StoreNotFoundError` if `id` does not exist. */\n deleteFeedback(id: string): Promise<void>;\n /** Bulk delete all feedbacks for a project. No-op (not error) if none exist. */\n deleteAllFeedbacks(projectName: string): Promise<void>;\n}\n\n/** Payload sent from the widget to the server when submitting feedback. */\nexport interface FeedbackPayload {\n projectName: string;\n type: FeedbackType;\n message: string;\n url: string;\n /**\n * Parameterized URL template (e.g. `/orders/:orderId`) supplied by\n * `SitepingConfig.getPageScope()`. Null when the host did not provide one.\n */\n urlPattern?: string | null | undefined;\n viewport: string;\n userAgent: string;\n authorName: string;\n authorEmail: string;\n annotations: AnnotationPayload[];\n /** Client-generated UUID for deduplication */\n clientId: string;\n /**\n * Base64 JPEG `data:` URL of the annotated area. Captured by the widget\n * when `enableScreenshot: true` is set in `SitepingConfig`. Null when\n * disabled or when capture failed silently.\n */\n screenshotDataUrl?: string | null | undefined;\n /**\n * Snapshot of the last few console messages and failed network requests\n * captured at submit time when `captureDiagnostics` is enabled.\n */\n diagnostics?: DiagnosticsSnapshot | null | undefined;\n}\n\n/** A single console entry captured by `ConsoleBuffer`. */\nexport interface ConsoleDiagnosticEntry {\n level: \"log\" | \"info\" | \"warn\" | \"error\";\n /** ISO 8601 timestamp captured at log time. */\n timestamp: string;\n /** Best-effort string representation of the original console args. */\n message: string;\n}\n\n/** A single failed network request captured by `NetworkBuffer`. */\nexport interface NetworkDiagnosticEntry {\n url: string;\n method: string;\n /** HTTP status; 0 when the request never reached the server. */\n status: number;\n /** End-to-end duration in ms. */\n durationMs: number;\n /** ISO 8601 timestamp at the moment the request was initiated. */\n timestamp: string;\n}\n\n/**\n * Diagnostics captured by the widget when `captureDiagnostics` is enabled.\n *\n * Both arrays are bounded (default: 50 console / 20 network). Adapters that\n * support diagnostics should persist this as a JSON blob alongside the\n * feedback so reviewers can replay the context that led to the report.\n */\nexport interface DiagnosticsSnapshot {\n console: ConsoleDiagnosticEntry[];\n network: NetworkDiagnosticEntry[];\n}\n\n// ---------------------------------------------------------------------------\n// Annotation — multi-selector anchoring (Hypothesis / W3C Web Annotation)\n// ---------------------------------------------------------------------------\n\n/** DOM anchoring data for re-attaching annotations to page elements. */\nexport interface AnchorData {\n /** CSS selector generated by @medv/finder — primary anchor */\n cssSelector: string;\n /** XPath — fallback 1 */\n xpath: string;\n /** First ~120 chars of element innerText — empty string if none */\n textSnippet: string;\n /** Tag name for validation (e.g. \"DIV\", \"SECTION\") */\n elementTag: string;\n /** Element id attribute if available — most stable */\n elementId?: string | undefined;\n /** ~32 chars of text before this element in document flow (disambiguation) */\n textPrefix: string;\n /** ~32 chars of text after this element in document flow (disambiguation) */\n textSuffix: string;\n /** Structural fingerprint: \"childCount:siblingIdx:attrHash\" */\n fingerprint: string;\n /** Text content of adjacent sibling elements (context) */\n neighborText: string;\n /**\n * Semantic anchor identifier from the closest ancestor's `data-feedback-anchor`\n * attribute. When set, this is the highest-priority re-anchoring signal —\n * hosts deliberately place these on layout/section roots that survive\n * viewport changes and DOM refactors.\n */\n anchorKey?: string | null | undefined;\n}\n\n/** Drawn rectangle coordinates as percentages relative to the anchor element. */\nexport interface RectData {\n /** X offset as fraction of anchor element width — must be in range [0, 1] */\n xPct: number;\n /** Y offset as fraction of anchor element height — must be in range [0, 1] */\n yPct: number;\n /** Width as fraction of anchor element width — must be in range [0, 1] */\n wPct: number;\n /** Height as fraction of anchor element height — must be in range [0, 1] */\n hPct: number;\n}\n\n/** Annotation data sent as part of a feedback submission. */\nexport interface AnnotationPayload {\n anchor: AnchorData;\n rect: RectData;\n scrollX: number;\n scrollY: number;\n viewportW: number;\n viewportH: number;\n devicePixelRatio: number;\n}\n\n// ---------------------------------------------------------------------------\n// API responses\n// ---------------------------------------------------------------------------\n\n/** Feedback record as returned by the API (dates serialized as strings). */\nexport interface FeedbackResponse {\n id: string;\n projectName: string;\n type: FeedbackType;\n message: string;\n status: FeedbackStatus;\n url: string;\n /** Parameterized URL template the feedback was created on, or null. */\n urlPattern: string | null;\n viewport: string;\n userAgent: string;\n authorName: string;\n authorEmail: string;\n resolvedAt: string | null;\n createdAt: string;\n updatedAt: string;\n annotations: AnnotationResponse[];\n /** Screenshot URL (data: or http:) — see `FeedbackRecord.screenshotUrl`. */\n screenshotUrl: string | null;\n /** Console + failed-network snapshot, or null when diagnostics weren't captured. */\n diagnostics: DiagnosticsSnapshot | null;\n}\n\n/** Annotation record as returned by the API. */\nexport interface AnnotationResponse {\n id: string;\n feedbackId: string;\n cssSelector: string;\n xpath: string;\n textSnippet: string;\n elementTag: string;\n elementId: string | null;\n textPrefix: string;\n textSuffix: string;\n fingerprint: string;\n neighborText: string;\n /** Semantic anchor identifier from `data-feedback-anchor`, or null. */\n anchorKey: string | null;\n xPct: number;\n yPct: number;\n wPct: number;\n hPct: number;\n scrollX: number;\n scrollY: number;\n viewportW: number;\n viewportH: number;\n devicePixelRatio: number;\n createdAt: string;\n}\n","import {\n type FeedbackPayload,\n type FeedbackResponse,\n type FeedbackStatus,\n type FeedbackType,\n SitepingAuthError,\n SitepingError,\n SitepingNetworkError,\n SitepingValidationError,\n} from \"@siteping/core\";\n\n/**\n * Map a non-OK Response to the appropriate typed error.\n * - 401 / 403 → `SitepingAuthError`\n * - 4xx → `SitepingValidationError`\n * - 5xx (or anything else) → generic `SitepingError`\n *\n * We consume the response body via `.text()` so the caller can keep the\n * server-supplied message in the thrown error. `text()` is awaited inside\n * a try/catch because some upstreams return `Content-Length: 0` with a\n * non-text type and `.text()` rejects.\n */\nasync function errorFromResponse(response: Response, label: string): Promise<SitepingError> {\n // Match the legacy fallback string (\"Unknown error\") so host apps that\n // already grep error messages don't break on the migration.\n const text = await response.text().catch(() => \"Unknown error\");\n const detail = text ? `${response.status} ${text}` : `${response.status}`;\n const message = `${label}: ${detail}`;\n if (response.status === 401 || response.status === 403) return new SitepingAuthError(message);\n if (response.status >= 400 && response.status < 500) return new SitepingValidationError(message);\n return new SitepingError(message, \"SERVER\", false);\n}\n\n/**\n * Normalise an exception thrown by `fetch` (or our timeout AbortController)\n * into a `SitepingNetworkError`. We treat AbortErrors as network failures\n * because in our code path they always come from the internal timeout, not\n * a user-driven cancellation.\n */\nfunction networkErrorFromException(error: unknown, label: string): SitepingNetworkError {\n if (error instanceof SitepingError) {\n // Already typed — only used when callers pass our own errors through.\n if (error instanceof SitepingNetworkError) return error;\n }\n const detail = error instanceof Error ? error.message : String(error);\n return new SitepingNetworkError(`${label}: ${detail}`);\n}\n\n/**\n * Abstract client interface used by the widget internals.\n *\n * `ApiClient` (HTTP mode) and `StoreClient` (direct store mode) both satisfy\n * this interface, allowing the widget to work identically in either mode.\n */\nexport interface WidgetClient {\n sendFeedback(payload: FeedbackPayload): Promise<FeedbackResponse>;\n getFeedbacks(\n projectName: string,\n options?: GetFeedbacksOptions,\n ): Promise<{ feedbacks: FeedbackResponse[]; total: number }>;\n resolveFeedback(id: string, resolved: boolean): Promise<FeedbackResponse>;\n deleteFeedback(id: string): Promise<void>;\n deleteAllFeedbacks(projectName: string): Promise<void>;\n}\n\n/** Options accepted by `WidgetClient.getFeedbacks`. */\nexport interface GetFeedbacksOptions {\n page?: number;\n limit?: number;\n type?: FeedbackType;\n status?: FeedbackStatus;\n search?: string;\n /** Restrict to feedbacks created on this exact URL (path). */\n url?: string;\n /** Restrict to feedbacks created on this URL pattern (e.g. `/orders/:orderId`). */\n urlPattern?: string;\n}\n\nconst MAX_RETRIES = 3;\nconst TIMEOUT_MS = 10_000;\nconst RETRY_QUEUE_KEY = \"siteping_retry_queue\";\nconst MAX_QUEUE_SIZE = 20;\n\n// ---------------------------------------------------------------------------\n// Core fetch with retry + exponential backoff + jitter\n// ---------------------------------------------------------------------------\n\nasync function resilientFetch(url: string, init: RequestInit, retries = MAX_RETRIES): Promise<Response> {\n for (let attempt = 0; attempt <= retries; attempt++) {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), TIMEOUT_MS);\n\n try {\n const response = await fetch(url, {\n ...init,\n signal: controller.signal,\n });\n clearTimeout(timeout);\n\n // Don't retry client errors (4xx) — only server errors (5xx)\n if (response.ok || (response.status >= 400 && response.status < 500)) {\n return response;\n }\n\n if (attempt === retries) return response;\n } catch (error) {\n clearTimeout(timeout);\n if (attempt === retries) throw error;\n }\n\n // Exponential backoff with jitter: 1s, 2s, 4s + random ±500ms\n const baseDelay = 1000 * 2 ** attempt;\n const jitter = Math.random() * 1000 - 500;\n await new Promise((r) => setTimeout(r, baseDelay + jitter));\n }\n\n throw new Error(\"Max retries exceeded\");\n}\n\n// ---------------------------------------------------------------------------\n// Retry queue — persist failed feedbacks for retry on next page load\n// ---------------------------------------------------------------------------\n\ntype RetryEntry = { endpoint: string; payload: FeedbackPayload };\n\nconst LOCK_NAME = \"siteping_retry_queue\";\n\n/**\n * Acquire a Web Lock to serialize cross-tab access to the retry queue.\n * Falls back to running the callback without locking on older browsers.\n */\nasync function withRetryLock<T>(callback: () => T | Promise<T>): Promise<T> {\n if (typeof navigator !== \"undefined\" && navigator.locks) {\n return navigator.locks.request(LOCK_NAME, () => callback());\n }\n return callback();\n}\n\nfunction queueForRetry(endpoint: string, payload: FeedbackPayload): void {\n // Fire-and-forget — we don't want to block the caller on the lock\n void withRetryLock(() => {\n try {\n const raw = localStorage.getItem(RETRY_QUEUE_KEY);\n const parsed: unknown = raw ? JSON.parse(raw) : [];\n const queue: RetryEntry[] = Array.isArray(parsed) ? (parsed as RetryEntry[]) : [];\n\n // Cap queue size to prevent unbounded localStorage growth\n if (queue.length >= MAX_QUEUE_SIZE) {\n queue.shift(); // Drop oldest entry\n }\n\n queue.push({ endpoint, payload });\n localStorage.setItem(RETRY_QUEUE_KEY, JSON.stringify(queue));\n } catch {\n // localStorage full or unavailable — silently drop\n }\n });\n}\n\nexport async function flushRetryQueue(endpoint: string): Promise<void> {\n await withRetryLock(async () => {\n try {\n const raw = localStorage.getItem(RETRY_QUEUE_KEY);\n if (!raw) return;\n\n const parsed: unknown = JSON.parse(raw);\n const queue: RetryEntry[] = Array.isArray(parsed) ? (parsed as RetryEntry[]) : [];\n\n const toRetry = queue.filter((e) => e.endpoint === endpoint);\n if (toRetry.length === 0) return;\n\n // Process items sequentially to avoid overwhelming the server\n const failed: RetryEntry[] = [];\n for (const entry of toRetry) {\n try {\n const res = await fetch(endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(entry.payload),\n });\n if (!res.ok) {\n failed.push(entry);\n }\n } catch {\n failed.push(entry);\n }\n }\n\n // Rebuild queue: keep unrelated entries + failed retries\n const remaining = queue.filter((e) => e.endpoint !== endpoint).concat(failed);\n if (remaining.length > 0) {\n localStorage.setItem(RETRY_QUEUE_KEY, JSON.stringify(remaining));\n } else {\n localStorage.removeItem(RETRY_QUEUE_KEY);\n }\n } catch {\n // Ignore — localStorage may be unavailable\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// API client\n// ---------------------------------------------------------------------------\n\nexport class ApiClient {\n constructor(\n private readonly endpoint: string,\n private readonly projectName: string,\n ) {}\n\n async sendFeedback(payload: FeedbackPayload): Promise<FeedbackResponse> {\n // Match the legacy contract: every failure path (network or HTTP) queues\n // for retry. Tests + host apps already rely on this — narrowing to\n // network-only would be a silent behaviour change.\n try {\n let response: Response;\n try {\n response = await resilientFetch(this.endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(payload),\n });\n } catch (error) {\n throw networkErrorFromException(error, \"Failed to send feedback\");\n }\n\n if (!response.ok) {\n throw await errorFromResponse(response, \"Failed to send feedback\");\n }\n\n return (await response.json()) as FeedbackResponse; // Server validates via Zod\n } catch (error) {\n queueForRetry(this.endpoint, payload);\n throw error;\n }\n }\n\n async getFeedbacks(\n projectName: string,\n options?: GetFeedbacksOptions,\n ): Promise<{ feedbacks: FeedbackResponse[]; total: number }> {\n const params = new URLSearchParams({ projectName });\n if (options?.page) params.set(\"page\", String(options.page));\n if (options?.limit) params.set(\"limit\", String(options.limit));\n if (options?.type) params.set(\"type\", options.type);\n if (options?.status) params.set(\"status\", options.status);\n if (options?.search) params.set(\"search\", options.search);\n if (options?.url) params.set(\"url\", options.url);\n if (options?.urlPattern) params.set(\"urlPattern\", options.urlPattern);\n\n let response: Response;\n try {\n response = await resilientFetch(`${this.endpoint}?${params.toString()}`, {\n method: \"GET\",\n cache: \"no-store\",\n });\n } catch (error) {\n throw networkErrorFromException(error, \"Failed to fetch feedbacks\");\n }\n\n if (!response.ok) {\n throw await errorFromResponse(response, \"Failed to fetch feedbacks\");\n }\n\n return (await response.json()) as { feedbacks: FeedbackResponse[]; total: number }; // Server validates via Zod\n }\n\n async resolveFeedback(id: string, resolved: boolean): Promise<FeedbackResponse> {\n let response: Response;\n try {\n response = await resilientFetch(this.endpoint, {\n method: \"PATCH\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ id, projectName: this.projectName, status: resolved ? \"resolved\" : \"open\" }),\n });\n } catch (error) {\n throw networkErrorFromException(error, \"Failed to update feedback\");\n }\n\n if (!response.ok) {\n throw await errorFromResponse(response, \"Failed to update feedback\");\n }\n\n return (await response.json()) as FeedbackResponse; // Server validates via Zod\n }\n\n async deleteFeedback(id: string): Promise<void> {\n let response: Response;\n try {\n response = await resilientFetch(this.endpoint, {\n method: \"DELETE\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ id, projectName: this.projectName }),\n });\n } catch (error) {\n throw networkErrorFromException(error, \"Failed to delete feedback\");\n }\n\n if (!response.ok) {\n throw await errorFromResponse(response, \"Failed to delete feedback\");\n }\n }\n\n async deleteAllFeedbacks(projectName: string): Promise<void> {\n let response: Response;\n try {\n response = await resilientFetch(this.endpoint, {\n method: \"DELETE\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ projectName, deleteAll: true }),\n });\n } catch (error) {\n throw networkErrorFromException(error, \"Failed to delete all feedbacks\");\n }\n\n if (!response.ok) {\n throw await errorFromResponse(response, \"Failed to delete all feedbacks\");\n }\n }\n}\n","/**\n * Console buffer — capture the last N `console.{log,info,warn,error}` calls\n * so they ship with every feedback submission.\n *\n * Why a ring buffer:\n * - **bounded memory** even on chatty pages (1000s of logs/min during dev),\n * - **last-N is the relevant slice** for debugging — what was happening just\n * before the user noticed the bug, not the full session history.\n *\n * Why monkey-patching instead of `console.dir`/Performance Timeline:\n * - host code already uses plain `console.*` everywhere, and many libraries\n * only emit through console (no other observable),\n * - patching is reversible via `dispose()` so the widget never leaves state\n * behind on `destroy()`.\n */\n\nconst DEFAULT_MAX_ENTRIES = 50;\nconst MAX_MESSAGE_LENGTH = 500;\n\n/** Per-entry shape — sent to the server in the diagnostics payload. */\nexport interface ConsoleEntry {\n level: \"log\" | \"info\" | \"warn\" | \"error\";\n /** ISO 8601 timestamp captured at log time. */\n timestamp: string;\n /** Best-effort string representation of the console args. */\n message: string;\n}\n\nconst LEVELS: Array<ConsoleEntry[\"level\"]> = [\"log\", \"info\", \"warn\", \"error\"];\n\n/**\n * Best-effort stringification that never throws.\n *\n * - `Error` → `Error: message\\nstack` (capped to 500 chars overall).\n * - circular / huge objects → fall back to `Object#toString()` or `\"[Unserializable]\"`.\n * - all output is truncated to `MAX_MESSAGE_LENGTH` so a single 5MB log\n * doesn't blow up the buffer (Slack-style 500 chars per row is plenty).\n */\nfunction serializeArg(arg: unknown): string {\n if (arg === null) return \"null\";\n if (arg === undefined) return \"undefined\";\n if (typeof arg === \"string\") return arg;\n if (typeof arg === \"number\" || typeof arg === \"boolean\" || typeof arg === \"bigint\") {\n return String(arg);\n }\n if (arg instanceof Error) {\n return `${arg.name}: ${arg.message}${arg.stack ? `\\n${arg.stack}` : \"\"}`;\n }\n try {\n // Replacer drops cycles + functions; functions stringify-default to\n // undefined and disappear from the output, which is the right call (we\n // don't want random function bodies in a feedback payload).\n const seen = new WeakSet<object>();\n return JSON.stringify(arg, (_key, value: unknown) => {\n if (typeof value === \"function\") return \"[Function]\";\n if (typeof value === \"symbol\") return value.toString();\n if (typeof value === \"object\" && value !== null) {\n if (seen.has(value as object)) return \"[Circular]\";\n seen.add(value as object);\n }\n return value;\n });\n } catch {\n try {\n return String(arg);\n } catch {\n return \"[Unserializable]\";\n }\n }\n}\n\nfunction formatArgs(args: readonly unknown[]): string {\n let out = \"\";\n for (let i = 0; i < args.length; i++) {\n if (i > 0) out += \" \";\n out += serializeArg(args[i]);\n if (out.length >= MAX_MESSAGE_LENGTH) break;\n }\n if (out.length > MAX_MESSAGE_LENGTH) {\n out = `${out.slice(0, MAX_MESSAGE_LENGTH - 1)}…`;\n }\n return out;\n}\n\n/**\n * Bounded ring buffer of console messages.\n *\n * Construction installs the wrappers immediately. `dispose()` restores the\n * originals exactly once (calling it twice is a no-op). Designed to be safe\n * against re-entrant or interleaved instances — each wrapper closes over the\n * original method, not over any global, so multiple buffers can coexist\n * (each captures its own copy of the args).\n */\nexport class ConsoleBuffer {\n private readonly maxEntries: number;\n private readonly entries: ConsoleEntry[] = [];\n private originals = new Map<ConsoleEntry[\"level\"], (...args: unknown[]) => void>();\n private disposed = false;\n\n constructor(maxEntries: number = DEFAULT_MAX_ENTRIES) {\n // Guard against pathological values — 0 disables silently, negative\n // numbers fall through to the default, and absurdly large numbers are\n // capped so a misuse can't OOM the page.\n this.maxEntries = Math.min(Math.max(Math.floor(maxEntries), 0), 1000);\n\n if (typeof console === \"undefined\") return;\n\n for (const level of LEVELS) {\n const original = (console as unknown as Record<string, ((...args: unknown[]) => void) | undefined>)[level];\n if (typeof original !== \"function\") continue;\n this.originals.set(level, original);\n\n const buffer = this;\n const wrapped = function (this: unknown, ...args: unknown[]): void {\n try {\n buffer.push(level, args);\n } catch {\n // Capturing must never break the host's console — swallow any\n // unexpected error from serialization so the original call\n // (right below) always still runs.\n }\n original.apply(this ?? console, args);\n };\n // Preserve the function name so devtools still show \"console.log\"\n // (browsers display the wrapper's name in stack traces).\n try {\n Object.defineProperty(wrapped, \"name\", { value: level });\n } catch {\n // Older engines reject defineProperty on function name — best-effort only.\n }\n (console as unknown as Record<string, unknown>)[level] = wrapped;\n }\n }\n\n private push(level: ConsoleEntry[\"level\"], args: readonly unknown[]): void {\n if (this.maxEntries === 0) return;\n if (this.entries.length >= this.maxEntries) {\n this.entries.shift();\n }\n this.entries.push({\n level,\n timestamp: new Date().toISOString(),\n message: formatArgs(args),\n });\n }\n\n /** Snapshot of captured entries — returns a new array each call. */\n getEntries(): ConsoleEntry[] {\n return this.entries.slice();\n }\n\n /** Restore the original console methods. Idempotent. */\n dispose(): void {\n if (this.disposed) return;\n this.disposed = true;\n if (typeof console === \"undefined\") return;\n for (const [level, original] of this.originals) {\n try {\n (console as unknown as Record<string, unknown>)[level] = original;\n } catch {\n // Console may be frozen in exotic environments — leave the wrapper\n // in place; it still proxies to the original via closure.\n }\n }\n this.originals.clear();\n }\n}\n","/**\n * Network buffer — capture the last N failed `fetch` / `XMLHttpRequest`\n * calls (HTTP >= 400 or network error) so they ship with each feedback.\n *\n * Captures only failures because:\n * - successful requests are usually irrelevant for the \"this thing is\n * broken\" workflow,\n * - keeping the volume tiny means we can ship the full payload to the\n * server without bloating Postgres.\n *\n * Both wrappers preserve the original semantics — return values, throws,\n * AbortController behaviour, etc. The only side effect is recording a\n * `NetworkEntry` on failure.\n */\n\nconst DEFAULT_MAX_ENTRIES = 20;\nconst MAX_URL_LENGTH = 2000;\n\n/** Per-entry shape — sent to the server in the diagnostics payload. */\nexport interface NetworkEntry {\n url: string;\n method: string;\n /** HTTP status or 0 when the request never reached the server (network error / CORS / abort). */\n status: number;\n /** End-to-end duration in ms, rounded to the nearest integer. */\n durationMs: number;\n /** ISO 8601 timestamp at the moment the request was initiated. */\n timestamp: string;\n}\n\nfunction truncateUrl(url: string): string {\n if (url.length <= MAX_URL_LENGTH) return url;\n return `${url.slice(0, MAX_URL_LENGTH - 1)}…`;\n}\n\nfunction urlString(input: unknown): string {\n if (typeof input === \"string\") return input;\n if (input instanceof URL) return input.href;\n // `Request` instances expose `.url`\n if (typeof input === \"object\" && input !== null && \"url\" in (input as { url?: unknown })) {\n const candidate = (input as { url?: unknown }).url;\n if (typeof candidate === \"string\") return candidate;\n }\n try {\n return String(input);\n } catch {\n return \"(unknown)\";\n }\n}\n\n/**\n * Bounded ring buffer of failed network requests.\n *\n * Construction monkey-patches `globalThis.fetch` and `XMLHttpRequest` and\n * stores the originals for `dispose()`. Wrappers are designed so that\n * multiple instances can coexist (each captures independently into its own\n * buffer, and the last one disposed restores the chain correctly via the\n * stored originals).\n */\nexport class NetworkBuffer {\n private readonly maxEntries: number;\n private readonly entries: NetworkEntry[] = [];\n private originalFetch: typeof fetch | null = null;\n private originalXhrOpen: typeof XMLHttpRequest.prototype.open | null = null;\n private originalXhrSend: typeof XMLHttpRequest.prototype.send | null = null;\n private disposed = false;\n\n constructor(maxEntries: number = DEFAULT_MAX_ENTRIES) {\n this.maxEntries = Math.min(Math.max(Math.floor(maxEntries), 0), 500);\n this.installFetch();\n this.installXhr();\n }\n\n private push(entry: NetworkEntry): void {\n if (this.maxEntries === 0) return;\n if (this.entries.length >= this.maxEntries) {\n this.entries.shift();\n }\n this.entries.push(entry);\n }\n\n private installFetch(): void {\n if (typeof globalThis.fetch !== \"function\") return;\n const original = globalThis.fetch;\n this.originalFetch = original;\n\n const wrapped: typeof fetch = async (input, init) => {\n const startedAt = new Date();\n const t0 = typeof performance !== \"undefined\" ? performance.now() : Date.now();\n const url = truncateUrl(urlString(input));\n const method = (init?.method ?? (input instanceof Request ? input.method : \"GET\")).toUpperCase();\n\n try {\n const response = await original(input, init);\n if (!response.ok) {\n const t1 = typeof performance !== \"undefined\" ? performance.now() : Date.now();\n this.push({\n url,\n method,\n status: response.status,\n durationMs: Math.round(t1 - t0),\n timestamp: startedAt.toISOString(),\n });\n }\n return response;\n } catch (err) {\n const t1 = typeof performance !== \"undefined\" ? performance.now() : Date.now();\n this.push({\n url,\n method,\n status: 0,\n durationMs: Math.round(t1 - t0),\n timestamp: startedAt.toISOString(),\n });\n throw err;\n }\n };\n\n globalThis.fetch = wrapped;\n }\n\n private installXhr(): void {\n if (typeof XMLHttpRequest === \"undefined\") return;\n const proto = XMLHttpRequest.prototype;\n const originalOpen = proto.open;\n const originalSend = proto.send;\n this.originalXhrOpen = originalOpen;\n this.originalXhrSend = originalSend;\n const buffer = this;\n\n // Store the open metadata on the XHR instance via a side-channel WeakMap\n // so each request is fully isolated even with concurrent opens.\n const meta = new WeakMap<XMLHttpRequest, { method: string; url: string; startedAt: Date; t0: number }>();\n\n proto.open = function (this: XMLHttpRequest, method: string, url: string | URL, ...rest: unknown[]) {\n try {\n meta.set(this, {\n method: method.toUpperCase(),\n url: truncateUrl(urlString(url)),\n startedAt: new Date(),\n t0: typeof performance !== \"undefined\" ? performance.now() : Date.now(),\n });\n } catch {\n // Ignore — metadata is best-effort, the underlying open() still runs.\n }\n // XHR.open has two overloaded signatures (3-arg sync, 5-arg async with\n // user/password). Cast to a loose function shape to forward every arg\n // without re-enumerating the overloads here.\n const looseOpen = originalOpen as unknown as (this: XMLHttpRequest, ...a: unknown[]) => void;\n return looseOpen.call(this, method, url, ...rest);\n } as typeof proto.open;\n\n proto.send = function (this: XMLHttpRequest, body?: Document | XMLHttpRequestBodyInit | null) {\n const info = meta.get(this);\n if (info) {\n // `loadend` fires for both success and failure — we just inspect the\n // status to decide whether to log. Use `once: true` so a re-sent XHR\n // doesn't accumulate listeners.\n const onEnd = () => {\n try {\n const t1 = typeof performance !== \"undefined\" ? performance.now() : Date.now();\n const status = this.status; // 0 on network error / abort\n if (status === 0 || status >= 400) {\n buffer.push({\n url: info.url,\n method: info.method,\n status,\n durationMs: Math.round(t1 - info.t0),\n timestamp: info.startedAt.toISOString(),\n });\n }\n } catch {\n // Listener must not throw — would surface as an \"Uncaught\" in\n // the host's console and pollute their logs.\n }\n };\n try {\n this.addEventListener(\"loadend\", onEnd, { once: true });\n } catch {\n // Older engines without options object — fall back to plain listener.\n try {\n this.addEventListener(\"loadend\", onEnd);\n } catch {\n // No-op\n }\n }\n }\n return originalSend.call(this, body ?? null);\n } as typeof proto.send;\n }\n\n /** Snapshot of captured entries — returns a new array each call. */\n getEntries(): NetworkEntry[] {\n return this.entries.slice();\n }\n\n /** Restore the original fetch + XHR methods. Idempotent. */\n dispose(): void {\n if (this.disposed) return;\n this.disposed = true;\n\n if (this.originalFetch && typeof globalThis.fetch === \"function\") {\n try {\n globalThis.fetch = this.originalFetch;\n } catch {\n // Best-effort\n }\n }\n if (typeof XMLHttpRequest !== \"undefined\") {\n try {\n if (this.originalXhrOpen) XMLHttpRequest.prototype.open = this.originalXhrOpen;\n if (this.originalXhrSend) XMLHttpRequest.prototype.send = this.originalXhrSend;\n } catch {\n // Best-effort\n }\n }\n }\n}\n","type Listener = (...args: unknown[]) => void;\n\n/**\n * Lightweight typed EventEmitter — zero dependencies.\n */\nexport class EventBus<E extends { [K in keyof E]: unknown[] }> {\n private listeners = new Map<keyof E, Set<Listener>>();\n\n on<K extends keyof E>(event: K, listener: (...args: E[K]) => void): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n const set = this.listeners.get(event)!;\n set.add(listener as Listener);\n\n return () => {\n set.delete(listener as Listener);\n };\n }\n\n off<K extends keyof E>(event: K, listener: (...args: E[K]) => void): void {\n const set = this.listeners.get(event);\n if (set) {\n set.delete(listener as Listener);\n }\n }\n\n emit<K extends keyof E>(event: K, ...args: E[K]): void {\n const set = this.listeners.get(event);\n if (!set) return;\n for (const fn of set) {\n try {\n fn(...args);\n } catch (err) {\n // Isolate listener errors — one bad listener must not kill others\n console.error(`[siteping] Error in event listener for \"${String(event)}\":`, err);\n }\n }\n }\n\n removeAll(): void {\n this.listeners.clear();\n }\n}\n\n// ---------------------------------------------------------------------------\n// Widget event types\n// ---------------------------------------------------------------------------\n\nexport interface WidgetEvents {\n open: [];\n close: [];\n \"feedback:sent\": [import(\"@siteping/core\").FeedbackResponse];\n \"feedback:deleted\": [string];\n \"feedback:all-deleted\": [];\n \"feedback:error\": [Error];\n \"annotation:start\": [];\n \"annotation:end\": [];\n \"annotation:complete\": [import(\"./annotator.js\").AnnotationComplete];\n \"annotations:toggle\": [boolean];\n \"panel:toggle\": [boolean];\n}\n\n/** Subset of WidgetEvents exposed to consumers via SitepingInstance */\nexport interface PublicWidgetEvents {\n \"feedback:sent\": [import(\"@siteping/core\").FeedbackResponse];\n \"feedback:deleted\": [string];\n \"panel:open\": [];\n \"panel:close\": [];\n}\n","import type { SitepingConfig } from \"@siteping/core\";\nimport { parseSvg, setText } from \"./dom-utils.js\";\nimport type { EventBus, WidgetEvents } from \"./events.js\";\nimport type { TFunction } from \"./i18n/index.js\";\nimport { ICON_ANNOTATE, ICON_CHAT, ICON_CLOSE, ICON_EYE, ICON_EYE_OFF, ICON_SITEPING } from \"./icons.js\";\n\ninterface RadialItem {\n id: string;\n icon: string;\n iconAlt?: string;\n label: string;\n}\n\nconst ITEM_GAP = 54;\n\n/**\n * Floating Action Button with radial menu and notification badge.\n *\n * Glassmorphism: gradient background, glow shadow, glass radial items.\n * Badge shows unresolved feedback count.\n */\nexport class Fab {\n private root: HTMLElement;\n private fab: HTMLButtonElement;\n private radialContainer: HTMLElement;\n private badgeEl: HTMLElement | null = null;\n private isOpen = false;\n private annotationsVisible = true;\n private items: RadialItem[];\n\n constructor(\n shadowRoot: ShadowRoot,\n config: SitepingConfig,\n private readonly bus: EventBus<WidgetEvents>,\n private readonly t: TFunction,\n ) {\n const position = config.position ?? \"bottom-right\";\n const isRight = position === \"bottom-right\";\n\n // Vertical stack above the FAB\n this.items = [\n { id: \"chat\", icon: ICON_CHAT, label: t(\"fab.messages\") },\n { id: \"annotate\", icon: ICON_ANNOTATE, label: t(\"fab.annotate\") },\n { id: \"toggle-annotations\", icon: ICON_EYE, iconAlt: ICON_EYE_OFF, label: t(\"fab.annotations\") },\n ];\n\n // FAB button — needs position:relative for badge positioning\n this.fab = document.createElement(\"button\");\n this.fab.className = `sp-fab sp-fab--${position} sp-anim-fab-in`;\n this.fab.style.position = \"fixed\"; // ensure fixed even with relative children\n this.fab.appendChild(parseSvg(ICON_SITEPING));\n this.fab.setAttribute(\"aria-label\", t(\"fab.aria\"));\n this.fab.setAttribute(\"aria-expanded\", \"false\");\n this.fab.addEventListener(\"click\", () => this.toggle());\n\n // Radial container\n this.radialContainer = document.createElement(\"div\");\n this.radialContainer.className = `sp-radial sp-radial--${position}`;\n this.radialContainer.setAttribute(\"role\", \"menu\");\n\n for (let i = 0; i < this.items.length; i++) {\n const item = this.items[i];\n if (!item) continue;\n const btn = document.createElement(\"button\");\n btn.className = \"sp-radial-item\";\n btn.style.setProperty(\"--sp-i\", String(i));\n btn.appendChild(parseSvg(item.icon));\n btn.setAttribute(\"role\", \"menuitem\");\n btn.setAttribute(\"aria-label\", item.label);\n btn.dataset.itemId = item.id;\n\n btn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.handleItemClick(item.id);\n });\n\n const label = document.createElement(\"span\");\n label.className = \"sp-radial-label\";\n label.textContent = item.label;\n label.style.cssText = isRight\n ? \"position:absolute; right:54px; top:50%; transform:translateY(-50%); white-space:nowrap;\"\n : \"position:absolute; left:54px; top:50%; transform:translateY(-50%); white-space:nowrap;\";\n btn.appendChild(label);\n\n this.radialContainer.appendChild(btn);\n }\n\n this.root = document.createElement(\"div\");\n this.root.appendChild(this.radialContainer);\n this.root.appendChild(this.fab);\n shadowRoot.appendChild(this.root);\n\n // Close radial menu on click outside.\n const host = shadowRoot.host;\n this.onDocumentClick = (e: MouseEvent) => {\n if (this.isOpen && !e.composedPath().includes(host)) {\n this.close();\n }\n };\n document.addEventListener(\"click\", this.onDocumentClick);\n\n // Escape on FAB or menu container closes the menu\n const handleEscape = (e: KeyboardEvent) => {\n if (e.key === \"Escape\" && this.isOpen) {\n e.stopPropagation();\n this.close();\n }\n };\n this.fab.addEventListener(\"keydown\", handleEscape);\n this.radialContainer.addEventListener(\"keydown\", handleEscape);\n\n // Arrow key navigation within the radial menu\n this.radialContainer.addEventListener(\"keydown\", (e) => {\n const items = Array.from(this.radialContainer.querySelectorAll<HTMLButtonElement>(\".sp-radial-item\"));\n if (items.length === 0 || !this.isOpen) return;\n const activeEl = (shadowRoot.activeElement ?? document.activeElement) as HTMLElement;\n const currentIndex = items.indexOf(activeEl as HTMLButtonElement);\n\n switch (e.key) {\n case \"ArrowUp\": {\n e.preventDefault();\n const nextIndex = currentIndex <= 0 ? items.length - 1 : currentIndex - 1;\n items[nextIndex]?.focus();\n break;\n }\n case \"ArrowDown\": {\n e.preventDefault();\n const nextIndex = currentIndex >= items.length - 1 ? 0 : currentIndex + 1;\n items[nextIndex]?.focus();\n break;\n }\n case \"Home\": {\n e.preventDefault();\n items[0]?.focus();\n break;\n }\n case \"End\": {\n e.preventDefault();\n items[items.length - 1]?.focus();\n break;\n }\n }\n });\n }\n\n private onDocumentClick: (e: MouseEvent) => void;\n\n /** Update the badge count. Pass 0 to hide. */\n updateBadge(count: number): void {\n if (count <= 0) {\n this.badgeEl?.remove();\n this.badgeEl = null;\n return;\n }\n\n if (!this.badgeEl) {\n this.badgeEl = document.createElement(\"span\");\n this.badgeEl.className = \"sp-fab-badge\";\n this.badgeEl.setAttribute(\"role\", \"status\");\n this.badgeEl.setAttribute(\"aria-live\", \"polite\");\n this.fab.appendChild(this.badgeEl);\n }\n\n const displayText = count > 99 ? \"99+\" : String(count);\n setText(this.badgeEl, displayText);\n this.badgeEl.setAttribute(\"aria-label\", this.t(\"fab.badge\").replace(\"{count}\", String(count)));\n }\n\n private toggle(): void {\n this.isOpen ? this.close() : this.open();\n }\n\n private open(): void {\n this.isOpen = true;\n this.setFabIcon(ICON_CLOSE);\n this.fab.setAttribute(\"aria-expanded\", \"true\");\n\n const buttons = this.radialContainer.querySelectorAll<HTMLButtonElement>(\".sp-radial-item\");\n buttons.forEach((btn, i) => {\n // Stack vertically above the FAB with initial offset + gap\n const y = -(16 + ITEM_GAP * (i + 1));\n btn.style.transform = `translate(0px, ${y}px) scale(1)`;\n btn.classList.add(\"sp-radial-item--open\");\n });\n\n // Focus the first menu item after animation\n requestAnimationFrame(() => {\n const firstItem = this.radialContainer.querySelector<HTMLButtonElement>(\".sp-radial-item\");\n firstItem?.focus();\n });\n }\n\n private close(): void {\n this.isOpen = false;\n this.setFabIcon(ICON_SITEPING);\n this.fab.setAttribute(\"aria-expanded\", \"false\");\n\n const buttons = this.radialContainer.querySelectorAll<HTMLButtonElement>(\".sp-radial-item\");\n buttons.forEach((btn) => {\n btn.style.transform = \"translate(0, 0) scale(0.8)\";\n btn.classList.remove(\"sp-radial-item--open\");\n });\n\n // Return focus to FAB\n this.fab.focus();\n }\n\n private setFabIcon(svgStr: string): void {\n const badge = this.badgeEl;\n this.fab.replaceChildren(parseSvg(svgStr));\n // Re-append badge after icon swap\n if (badge) this.fab.appendChild(badge);\n }\n\n private handleItemClick(id: string): void {\n this.close();\n\n switch (id) {\n case \"chat\":\n this.bus.emit(\"panel:toggle\", true);\n break;\n case \"annotate\":\n this.bus.emit(\"annotation:start\");\n break;\n case \"toggle-annotations\": {\n this.annotationsVisible = !this.annotationsVisible;\n this.bus.emit(\"annotations:toggle\", this.annotationsVisible);\n const btn = this.radialContainer.querySelector('[data-item-id=\"toggle-annotations\"]');\n if (btn) {\n btn.replaceChildren(parseSvg(this.annotationsVisible ? ICON_EYE : ICON_EYE_OFF));\n }\n break;\n }\n }\n }\n\n destroy(): void {\n document.removeEventListener(\"click\", this.onDocumentClick);\n this.root.remove();\n }\n}\n","const STORAGE_KEY = \"siteping_identity\";\n\nexport interface Identity {\n name: string;\n email: string;\n}\n\nexport function getIdentity(): Identity | null {\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n if (!raw) return null;\n const parsed: unknown = JSON.parse(raw);\n if (\n typeof parsed === \"object\" &&\n parsed !== null &&\n \"name\" in parsed &&\n typeof (parsed as Record<string, unknown>).name === \"string\" &&\n \"email\" in parsed &&\n typeof (parsed as Record<string, unknown>).email === \"string\"\n ) {\n const identity = parsed as Identity;\n if (identity.name && identity.email) return identity;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nexport function saveIdentity(identity: Identity): void {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(identity));\n } catch {\n // Quota exceeded or localStorage disabled — identity works for this session only\n }\n}\n","/**\n * Lightweight fuzzy text matching for DOM re-anchoring.\n * Zero dependencies — bundled into the widget.\n * Uses Levenshtein distance, optimized for short strings (~50 chars).\n */\n\n/**\n * Levenshtein edit distance.\n * O(n*m) time, O(min(n,m)) space.\n */\nexport function editDistance(a: string, b: string): number {\n if (a === b) return 0;\n if (a.length === 0) return b.length;\n if (b.length === 0) return a.length;\n\n // Ensure `a` is the shorter string for space optimization\n if (a.length > b.length) {\n const t = a;\n a = b;\n b = t;\n }\n\n const aLen = a.length;\n const bLen = b.length;\n let prev = new Array<number>(aLen + 1);\n for (let k = 0; k <= aLen; k++) prev[k] = k;\n let curr = new Array<number>(aLen + 1);\n\n for (let j = 1; j <= bLen; j++) {\n curr[0] = j;\n for (let i = 1; i <= aLen; i++) {\n // Indices are valid: i-1 in [0, aLen-1], j-1 in [0, bLen-1], loop bounds guarantee access\n const prevDiag = prev[i - 1] ?? 0;\n curr[i] = a[i - 1] === b[j - 1] ? prevDiag : 1 + Math.min(prevDiag, prev[i] ?? 0, curr[i - 1] ?? 0);\n }\n const tmp = prev;\n prev = curr;\n curr = tmp;\n }\n\n return prev[aLen] ?? 0; // aLen is within bounds — prev has aLen+1 entries\n}\n\n/**\n * Normalized similarity score (0–1, where 1 = identical).\n */\nexport function similarity(a: string, b: string): number {\n if (a === b) return 1;\n const maxLen = Math.max(a.length, b.length);\n if (maxLen === 0) return 1;\n return 1 - editDistance(a, b) / maxLen;\n}\n\n/**\n * Fuzzy substring search — checks if `needle` approximately exists in `haystack`.\n * Slides a window of `needle.length` over the haystack and returns the best\n * similarity score found. Returns 0 if below `minScore`.\n */\nexport function fuzzyIncludes(haystack: string, needle: string, minScore = 0.6): number {\n if (!needle || !haystack) return 0;\n if (haystack.includes(needle)) return 1;\n\n const nLen = needle.length;\n\n // If needle is longer than haystack, compare directly\n if (nLen > haystack.length) {\n const score = similarity(haystack, needle);\n return score >= minScore ? score : 0;\n }\n\n let best = 0;\n\n // Cap haystack to avoid O(n²) on huge text nodes\n const capped = haystack.length > 500 ? haystack.slice(0, 500) : haystack;\n const limit = capped.length - nLen;\n\n for (let i = 0; i <= limit; i++) {\n const window = capped.slice(i, i + nLen);\n const score = similarity(window, needle);\n if (score > best) best = score;\n if (best >= 0.95) break;\n }\n\n return best >= minScore ? best : 0;\n}\n","import type { AnchorData, RectData } from \"@siteping/core\";\nimport { ANCHOR_KEY_ATTR } from \"./anchor.js\";\nimport { scoreFingerprint } from \"./fingerprint.js\";\nimport { fuzzyIncludes, similarity } from \"./fuzzy.js\";\nimport { adjacentText, neighborText } from \"./text-context.js\";\n\nexport type ResolutionStrategy = \"anchorKey\" | \"id\" | \"css\" | \"xpath\" | \"scan\";\n\nexport interface AnchorResolution {\n element: Element;\n confidence: number;\n strategy: ResolutionStrategy;\n}\n\nexport interface ResolvedAnnotation {\n element: Element;\n rect: DOMRect;\n confidence: number;\n strategy: ResolutionStrategy;\n}\n\n/** Max elements to scan during smart fallback. */\nconst MAX_SCAN_CANDIDATES = 300;\n\n/** Minimum fuzzy text match score for CSS/XPath verification. */\nconst TEXT_MATCH_THRESHOLD = 0.3;\n\n/**\n * Verify that a resolved element's text content matches the stored snippet.\n * If no snippet is stored, returns true (no verification possible).\n * Uses fuzzy matching to tolerate minor text changes.\n */\nfunction textMatches(el: Element, anchor: AnchorData): boolean {\n if (!anchor.textSnippet) return true;\n const text = (el.textContent?.trim() ?? \"\").slice(0, 500);\n return fuzzyIncludes(text, anchor.textSnippet, 0.5) > TEXT_MATCH_THRESHOLD;\n}\n\n/**\n * Re-anchor an annotation using a multi-level fallback strategy\n * with text verification and confidence scoring.\n *\n * Resolution order:\n * 0. Semantic anchor key (`[data-feedback-anchor=\"X\"]`) — confidence 1.0\n * when host explicitly tagged the section. Tag name is NOT enforced —\n * hosts may legitimately refactor the wrapper element while keeping the\n * semantic key stable.\n * 1. getElementById + text verification — confidence 1.0\n * 2. CSS selector + text verification — confidence 0.95\n * 3. XPath + text verification — confidence 0.9\n * 4. Smart scan (fingerprint + text + prefix/suffix + neighbor) — up to 0.85\n *\n * Text verification prevents false matches when DOM elements are reordered.\n * Returns null if all strategies fail (annotation is orphaned).\n */\nexport function resolveAnchor(anchor: AnchorData): AnchorResolution | null {\n // Level 0: Semantic anchor key (host-controlled, most stable)\n if (anchor.anchorKey) {\n // Escape backslash and double-quote so an arbitrary key never breaks the selector\n const escaped = anchor.anchorKey.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n try {\n const el = document.querySelector(`[${ANCHOR_KEY_ATTR}=\"${escaped}\"]`);\n // Skip tagName check — semantic anchor identifies a section, not a tag\n if (el && textMatches(el, anchor)) {\n return { element: el, confidence: 1.0, strategy: \"anchorKey\" };\n }\n } catch {\n // Invalid attribute value — fall through to next strategy\n }\n }\n\n // Level 1: Element ID (most stable, still verify text)\n if (anchor.elementId) {\n const el = document.getElementById(anchor.elementId);\n if (el && el.tagName === anchor.elementTag && textMatches(el, anchor)) {\n return { element: el, confidence: 1.0, strategy: \"id\" };\n }\n }\n\n // Level 2: CSS Selector (with text verification)\n try {\n const el = document.querySelector(anchor.cssSelector);\n if (el && el.tagName === anchor.elementTag && textMatches(el, anchor)) {\n return { element: el, confidence: 0.95, strategy: \"css\" };\n }\n } catch {\n // Invalid selector — skip\n }\n\n // Level 3: XPath (with text verification)\n try {\n const result = document.evaluate(anchor.xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);\n const el = result.singleNodeValue;\n if (el instanceof Element && el.tagName === anchor.elementTag && textMatches(el, anchor)) {\n return { element: el, confidence: 0.9, strategy: \"xpath\" };\n }\n } catch {\n // Invalid XPath — skip\n }\n\n // Level 4: Smart scan — combine all available signals\n return smartScan(anchor);\n}\n\n/**\n * Scan DOM elements by tag and score each candidate using multiple signals:\n * fingerprint, text similarity, prefix/suffix context, neighbor text.\n *\n * Returns the best candidate above a 0.4 threshold, capped at 0.85 confidence\n * (smart scan is never 100% certain).\n */\nfunction smartScan(anchor: AnchorData): AnchorResolution | null {\n const tag = anchor.elementTag.toLowerCase();\n const candidates = document.querySelectorAll(tag);\n if (candidates.length === 0) return null;\n\n let bestElement: Element | null = null;\n let bestScore = 0;\n\n const limit = Math.min(candidates.length, MAX_SCAN_CANDIDATES);\n\n for (let i = 0; i < limit; i++) {\n const el = candidates[i];\n if (!el) continue;\n const score = scoreCandidate(el, anchor);\n if (score > bestScore) {\n bestScore = score;\n bestElement = el;\n if (bestScore >= 0.85) break;\n }\n }\n\n if (!bestElement || bestScore < 0.4) return null;\n\n return {\n element: bestElement,\n confidence: Math.min(bestScore, 0.85),\n strategy: \"scan\",\n };\n}\n\n/**\n * Score a candidate element against all stored anchor signals.\n *\n * Dynamic weighting — only active signals contribute, then normalized:\n * - Text snippet (fuzzy substring match): weight 40 (most reliable for reordering)\n * - Fingerprint (structural match): weight 20\n * - Prefix/suffix context: weight 20\n * - Neighbor text: weight 20\n */\nfunction scoreCandidate(candidate: Element, anchor: AnchorData): number {\n let score = 0;\n let totalWeight = 0;\n\n // Truncate to avoid O(n*m) explosion on huge text nodes\n const candidateText = (candidate.textContent?.trim() ?? \"\").slice(0, 500);\n\n // --- Text snippet (weight 40 — most important for reordered elements) ---\n if (anchor.textSnippet) {\n totalWeight += 40;\n score += fuzzyIncludes(candidateText, anchor.textSnippet, 0.5) * 40;\n }\n\n // --- Fingerprint (weight 20) ---\n if (anchor.fingerprint) {\n totalWeight += 20;\n score += scoreFingerprint(candidate, anchor.fingerprint) * 20;\n }\n\n // --- Prefix/suffix context (weight 20) ---\n if (anchor.textPrefix || anchor.textSuffix) {\n totalWeight += 20;\n let contextScore = 0;\n let contextParts = 0;\n\n if (anchor.textPrefix) {\n const prevText = adjacentText(candidate, \"before\");\n contextScore += prevText ? similarity(prevText, anchor.textPrefix) : 0;\n contextParts++;\n }\n\n if (anchor.textSuffix) {\n const nextText = adjacentText(candidate, \"after\");\n contextScore += nextText ? similarity(nextText, anchor.textSuffix) : 0;\n contextParts++;\n }\n\n if (contextParts > 0) {\n score += (contextScore / contextParts) * 20;\n }\n }\n\n // --- Neighbor text (weight 20) ---\n if (anchor.neighborText) {\n totalWeight += 20;\n const candidateNeighbor = neighborText(candidate);\n score += candidateNeighbor ? similarity(candidateNeighbor, anchor.neighborText) * 20 : 0;\n }\n\n return totalWeight > 0 ? score / totalWeight : 0;\n}\n\n/**\n * Resolve an annotation's position on the page.\n * Converts stored percentage-based rect back to absolute coordinates\n * using the current bounding box of the resolved anchor element.\n */\nexport function resolveAnnotation(anchor: AnchorData, rect: RectData): ResolvedAnnotation | null {\n const resolution = resolveAnchor(anchor);\n\n if (!resolution) return null;\n\n const bounds = resolution.element.getBoundingClientRect();\n const absoluteRect = new DOMRect(\n bounds.x + rect.xPct * bounds.width,\n bounds.y + rect.yPct * bounds.height,\n rect.wPct * bounds.width,\n rect.hPct * bounds.height,\n );\n\n return {\n element: resolution.element,\n rect: absoluteRect,\n confidence: resolution.confidence,\n strategy: resolution.strategy,\n };\n}\n","import type { AnchorData, FeedbackResponse, RectData } from \"@siteping/core\";\nimport { Z_INDEX_MAX } from \"./constants.js\";\nimport { resolveAnnotation } from \"./dom/resolver.js\";\nimport { el, setText } from \"./dom-utils.js\";\nimport type { EventBus, WidgetEvents } from \"./events.js\";\nimport { getTypeLabel, type TFunction } from \"./i18n/index.js\";\nimport { getTypeColor, type ThemeColors } from \"./styles/theme.js\";\nimport type { Tooltip } from \"./tooltip.js\";\n\ntype Annotation = FeedbackResponse[\"annotations\"][number];\n\nfunction toAnchorData(a: Annotation): AnchorData {\n return {\n cssSelector: a.cssSelector,\n xpath: a.xpath,\n textSnippet: a.textSnippet,\n elementTag: a.elementTag,\n elementId: a.elementId ?? undefined,\n textPrefix: a.textPrefix,\n textSuffix: a.textSuffix,\n fingerprint: a.fingerprint,\n neighborText: a.neighborText,\n anchorKey: a.anchorKey ?? null,\n };\n}\n\nfunction toRectData(a: Annotation): RectData {\n return { xPct: a.xPct, yPct: a.yPct, wPct: a.wPct, hPct: a.hPct };\n}\n\n/** Half of the 26px marker diameter — used for centering on anchor corner. */\nconst MARKER_OFFSET = 13;\n\n/** Convert a resolved rect to document-absolute marker position. */\nfunction markerPosition(rect: DOMRect): { top: number; left: number } {\n return {\n top: rect.top + window.scrollY - MARKER_OFFSET,\n left: rect.right + window.scrollX - MARKER_OFFSET,\n };\n}\n\ninterface MarkerEntry {\n feedback: FeedbackResponse;\n elements: HTMLElement[];\n baseTop: number;\n baseLeft: number;\n}\n\ninterface Cluster {\n entries: MarkerEntry[];\n elementIndices: number[];\n expanded: boolean;\n}\n\n/** Get the i-th marker element from a cluster. */\nfunction clusterMarker(cluster: Cluster, i: number): HTMLElement | undefined {\n const entry = cluster.entries[i];\n const elIdx = cluster.elementIndices[i];\n if (!entry || elIdx === undefined) return undefined;\n return entry.elements[elIdx];\n}\n\nconst HIGHLIGHT_FADE = 300;\nconst REPOSITION_DEBOUNCE = 200;\nconst LOW_CONFIDENCE_THRESHOLD = 0.7;\nconst CLUSTER_DISTANCE = 28;\nconst FAN_SPACING = 32;\n\n/**\n * Numbered markers on the page for each feedback annotation.\n *\n * Cluster system: click-to-expand (same pattern as Google Maps / Spiderfier).\n * Hover is only used for tooltip/scale on individual markers — never for expansion.\n */\nexport class MarkerManager {\n private container: HTMLElement;\n private entries: MarkerEntry[] = [];\n private highlightElements: HTMLElement[] = [];\n private pinnedFeedback: FeedbackResponse | null = null;\n private onDocumentClick: ((e: MouseEvent) => void) | null = null;\n private repositionTimer: number | null = null;\n private mutationObserver: MutationObserver | null = null;\n private scrollHandler: (() => void) | null = null;\n private resizeHandler: (() => void) | null = null;\n private anchorCache = new Map<string, WeakRef<Element>>();\n private clusters: Cluster[] = [];\n private onDocumentClickForClusters: ((e: MouseEvent) => void) | null = null;\n\n get count(): number {\n return this.entries.length;\n }\n\n constructor(\n private readonly colors: ThemeColors,\n private readonly tooltip: Tooltip,\n private readonly bus: EventBus<WidgetEvents>,\n private readonly t: TFunction,\n private readonly liveRegion: HTMLElement | null = null,\n ) {\n this.container = el(\"div\", {\n style: `position:absolute;top:0;left:0;pointer-events:none;z-index:${Z_INDEX_MAX - 1};`,\n });\n this.container.id = \"siteping-markers\";\n document.body.appendChild(this.container);\n\n this.bus.on(\"annotations:toggle\", (visible) => {\n this.container.style.display = visible ? \"block\" : \"none\";\n });\n\n this.resizeHandler = () => this.scheduleReposition();\n window.addEventListener(\"resize\", this.resizeHandler, { passive: true });\n\n this.scrollHandler = () => this.scheduleReposition();\n window.addEventListener(\"scroll\", this.scrollHandler, { passive: true, capture: true });\n\n // Re-resolve after DOM changes (SPA, lazy-load).\n // Filter out widget-owned mutations and skip batches with only irrelevant\n // changes. Filtering short-circuits at the first non-widget mutation, so\n // even large batches stop after one DOM walk.\n //\n // The filter is applied unconditionally — earlier versions had a >20-batch\n // fast-path that skipped filtering, but that lets reposition self-trigger\n // when `repositionAll` re-renders the pinned highlight (showHighlight\n // appends N elements to `this.container`); a host page churning lots of\n // DOM (infinite scroll) would then loop at the 200ms debounce interval.\n this.mutationObserver = new MutationObserver((mutations) => {\n let hasRelevantMutation = false;\n for (const m of mutations) {\n if (this.container.contains(m.target) || this.tooltip.contains(m.target)) continue;\n hasRelevantMutation = true;\n break;\n }\n if (hasRelevantMutation) this.scheduleReposition();\n });\n this.mutationObserver.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: false,\n characterData: false,\n });\n\n this.onDocumentClickForClusters = (e: MouseEvent) => {\n if (this.container.contains(e.target as Node)) return;\n this.collapseAllClusters();\n };\n document.addEventListener(\"click\", this.onDocumentClickForClusters);\n }\n\n private scheduleReposition(): void {\n if (this.repositionTimer) return;\n if (\"requestIdleCallback\" in window) {\n this.repositionTimer = window.requestIdleCallback(\n () => {\n this.repositionTimer = null;\n this.repositionAll();\n },\n { timeout: REPOSITION_DEBOUNCE + 100 },\n );\n } else {\n this.repositionTimer = +setTimeout(() => {\n this.repositionTimer = null;\n this.repositionAll();\n }, REPOSITION_DEBOUNCE);\n }\n }\n\n private repositionAll(): void {\n // Build set of valid keys to prune stale cache entries afterwards.\n const validKeys = new Set<string>();\n\n for (const entry of this.entries) {\n for (let i = 0; i < entry.feedback.annotations.length; i++) {\n const markerEl = entry.elements[i];\n if (!markerEl) continue;\n\n const annotation = entry.feedback.annotations[i];\n if (!annotation) continue;\n const cacheKey = `${entry.feedback.id}:${i}`;\n validKeys.add(cacheKey);\n\n // Try cached element first to avoid full resolution chain.\n const cachedRef = this.anchorCache.get(cacheKey);\n const cachedEl = cachedRef?.deref();\n let resolved: ReturnType<typeof resolveAnnotation>;\n\n if (cachedEl?.isConnected) {\n const anchorRect = cachedEl.getBoundingClientRect();\n const r = toRectData(annotation);\n resolved = {\n element: cachedEl,\n rect: new DOMRect(\n anchorRect.left + r.xPct * anchorRect.width,\n anchorRect.top + r.yPct * anchorRect.height,\n r.wPct * anchorRect.width,\n r.hPct * anchorRect.height,\n ),\n confidence: 1,\n strategy: \"css\",\n };\n } else {\n resolved = resolveAnnotation(toAnchorData(annotation), toRectData(annotation));\n if (resolved?.element) {\n this.anchorCache.set(cacheKey, new WeakRef(resolved.element));\n }\n }\n\n if (!resolved) {\n markerEl.style.display = \"none\";\n continue;\n }\n\n const pos = markerPosition(resolved.rect);\n entry.baseTop = pos.top;\n entry.baseLeft = pos.left;\n markerEl.style.display = \"flex\";\n this.applyConfidenceStyle(markerEl, resolved.confidence, entry.feedback);\n }\n }\n\n // Prune cache keys from deleted feedbacks to prevent memory leak.\n for (const key of this.anchorCache.keys()) {\n if (!validKeys.has(key)) this.anchorCache.delete(key);\n }\n\n this.applyClusterPositions();\n\n // Re-render the pinned highlight rectangle so it tracks the layout after\n // resize / SPA mutation. Marker dots reposition above; without this,\n // the highlight rect keeps its old pixel position and visibly drifts\n // away from the underlying content.\n if (this.pinnedFeedback) {\n this.showHighlight(this.pinnedFeedback);\n }\n }\n\n private applyClusterPositions(): void {\n for (const cluster of this.clusters) {\n if (cluster.expanded) {\n this.applyFanPositions(cluster);\n } else {\n this.applyStackPositions(cluster);\n }\n }\n }\n\n render(feedbacks: FeedbackResponse[]): void {\n this.clear();\n feedbacks.forEach((feedback, i) => {\n const entry = this.buildEntry(feedback, i + 1);\n this.entries.push(entry);\n });\n this.buildClusters();\n // Announce the number of visible markers to assistive tech (WCAG 4.1.3).\n // Skip the announcement when the host page has not provided a live\n // region (tests, embedded use cases) and when no marker is visible to\n // avoid noisy \"0 markers\" updates on every navigation.\n if (this.liveRegion && this.entries.length > 0) {\n this.liveRegion.textContent = this.t(\"marker.count\").replace(\"{count}\", String(this.entries.length));\n }\n }\n\n addFeedback(feedback: FeedbackResponse, index: number): void {\n const entry = this.buildEntry(feedback, index);\n for (const m of entry.elements) {\n m.style.animation = \"sp-marker-in 0.35s cubic-bezier(0.34,1.56,0.64,1) both\";\n }\n this.entries.push(entry);\n this.buildClusters();\n }\n\n private buildEntry(feedback: FeedbackResponse, index: number): MarkerEntry {\n const entry: MarkerEntry = { feedback, elements: [], baseTop: 0, baseLeft: 0 };\n for (const annotation of feedback.annotations) {\n const resolved = resolveAnnotation(toAnchorData(annotation), toRectData(annotation));\n if (!resolved) continue;\n const pos = markerPosition(resolved.rect);\n entry.baseTop = pos.top;\n entry.baseLeft = pos.left;\n const marker = this.createMarker(index, feedback, pos);\n this.applyConfidenceStyle(marker, resolved.confidence, feedback);\n this.container.appendChild(marker);\n entry.elements.push(marker);\n }\n return entry;\n }\n\n private buildClusters(): void {\n for (const badge of this.container.querySelectorAll<HTMLElement>(\".sp-cluster-badge\")) {\n badge.remove();\n }\n\n const allItems: { entry: MarkerEntry; elIdx: number }[] = [];\n for (const entry of this.entries) {\n for (let i = 0; i < entry.elements.length; i++) {\n allItems.push({ entry, elIdx: i });\n }\n }\n\n const used = new Set<number>();\n this.clusters = [];\n\n for (let i = 0; i < allItems.length; i++) {\n if (used.has(i)) continue;\n const itemI = allItems[i];\n if (!itemI) continue;\n const cluster: Cluster = {\n entries: [itemI.entry],\n elementIndices: [itemI.elIdx],\n expanded: false,\n };\n used.add(i);\n\n for (let j = i + 1; j < allItems.length; j++) {\n if (used.has(j)) continue;\n const a = itemI.entry;\n const itemJ = allItems[j];\n if (!itemJ) continue;\n const b = itemJ.entry;\n const dist = Math.sqrt((a.baseLeft - b.baseLeft) ** 2 + (a.baseTop - b.baseTop) ** 2);\n if (dist < CLUSTER_DISTANCE) {\n cluster.entries.push(b);\n cluster.elementIndices.push(itemJ.elIdx);\n used.add(j);\n }\n }\n\n this.clusters.push(cluster);\n }\n\n for (const cluster of this.clusters) {\n if (cluster.entries.length <= 1) continue;\n this.applyStackPositions(cluster);\n this.addClusterBadge(cluster);\n }\n }\n\n private applyStackPositions(cluster: Cluster): void {\n const first = cluster.entries[0];\n if (!first) return;\n const { baseTop, baseLeft } = first;\n const isSolo = cluster.entries.length <= 1;\n for (let i = 0; i < cluster.entries.length; i++) {\n const m = clusterMarker(cluster, i);\n if (!m) continue;\n m.style.top = `${baseTop + (isSolo ? 0 : i * 3)}px`;\n m.style.left = `${baseLeft + (isSolo ? 0 : i * 3)}px`;\n m.style.zIndex = String(i + 1);\n }\n }\n\n private applyFanPositions(cluster: Cluster): void {\n const first = cluster.entries[0];\n if (!first) return;\n const { baseTop, baseLeft } = first;\n const count = cluster.entries.length;\n const totalWidth = (count - 1) * FAN_SPACING;\n const startLeft = baseLeft - totalWidth / 2;\n\n for (let i = 0; i < count; i++) {\n const m = clusterMarker(cluster, i);\n if (!m) continue;\n m.style.top = `${baseTop}px`;\n m.style.left = `${startLeft + i * FAN_SPACING}px`;\n m.style.zIndex = String(10 + i);\n }\n }\n\n private addClusterBadge(cluster: Cluster): void {\n const topMarker = clusterMarker(cluster, cluster.entries.length - 1);\n if (!topMarker) return;\n const badge = el(\"div\", {\n class: \"sp-cluster-badge\",\n style: `\n position:absolute;top:-6px;right:-6px;\n min-width:16px;height:16px;padding:0 4px;\n border-radius:9999px;\n background:${this.colors.accent};color:#fff;\n font-size:10px;font-weight:700;\n display:flex;align-items:center;justify-content:center;\n border:1.5px solid #fff;\n pointer-events:none;\n font-family:\"Inter\",system-ui,-apple-system,sans-serif;\n line-height:1;\n `,\n });\n setText(badge, String(cluster.entries.length));\n topMarker.appendChild(badge);\n }\n\n private setBadgesVisible(cluster: Cluster, visible: boolean): void {\n for (let i = 0; i < cluster.entries.length; i++) {\n const badge = clusterMarker(cluster, i)?.querySelector(\".sp-cluster-badge\") as HTMLElement | null;\n if (badge) badge.style.display = visible ? \"flex\" : \"none\";\n }\n }\n\n private findCluster(marker: HTMLElement): Cluster | null {\n for (const cluster of this.clusters) {\n if (cluster.entries.length <= 1) continue;\n for (let i = 0; i < cluster.entries.length; i++) {\n if (clusterMarker(cluster, i) === marker) return cluster;\n }\n }\n return null;\n }\n\n private handleClusterClick(marker: HTMLElement, e: MouseEvent): boolean {\n const cluster = this.findCluster(marker);\n if (!cluster) return false;\n if (!cluster.expanded) {\n e.stopPropagation();\n this.collapseAllClusters();\n cluster.expanded = true;\n this.applyFanPositions(cluster);\n this.setBadgesVisible(cluster, false);\n return true;\n }\n return false;\n }\n\n private collapseCluster(cluster: Cluster): void {\n if (!cluster.expanded) return;\n cluster.expanded = false;\n this.applyStackPositions(cluster);\n this.setBadgesVisible(cluster, true);\n }\n\n private collapseAllClusters(): void {\n for (const cluster of this.clusters) {\n this.collapseCluster(cluster);\n }\n }\n\n private applyConfidenceStyle(marker: HTMLElement, confidence: number, feedback: FeedbackResponse): void {\n const isResolved = feedback.status === \"resolved\";\n if (confidence < LOW_CONFIDENCE_THRESHOLD && !isResolved) {\n marker.style.borderStyle = \"dashed\";\n marker.style.opacity = \"0.7\";\n marker.title = this.t(\"marker.approximate\").replace(\"{confidence}\", String(Math.round(confidence * 100)));\n } else {\n marker.style.borderStyle = \"solid\";\n marker.style.opacity = \"1\";\n marker.title = \"\";\n }\n }\n\n private createMarker(number: number, feedback: FeedbackResponse, pos: { top: number; left: number }): HTMLElement {\n const typeColor = getTypeColor(feedback.type, this.colors);\n const isResolved = feedback.status === \"resolved\";\n\n const marker = el(\"div\", {\n style: `\n position:absolute;\n top:${pos.top}px;\n left:${pos.left}px;\n width:26px;height:26px;\n border-radius:50%;\n background:${isResolved ? \"rgba(241,245,249,0.9)\" : \"rgba(255,255,255,0.92)\"};\n border:2px solid ${isResolved ? \"#cbd5e1\" : typeColor};\n display:flex;align-items:center;justify-content:center;\n font-family:\"Inter\",system-ui,-apple-system,sans-serif;\n font-size:11px;font-weight:700;\n color:${isResolved ? \"#94a3b8\" : typeColor};\n cursor:pointer;pointer-events:auto;\n box-shadow:${isResolved ? \"0 2px 8px rgba(0,0,0,0.06)\" : `0 2px 12px ${typeColor}25, 0 2px 6px rgba(0,0,0,0.06)`};\n transition:top 0.25s cubic-bezier(0.34, 1.56, 0.64, 1), left 0.25s cubic-bezier(0.34, 1.56, 0.64, 1), transform 0.15s ease, box-shadow 0.15s ease;\n user-select:none;\n -webkit-font-smoothing:antialiased;\n `,\n });\n marker.dataset.feedbackId = feedback.id;\n marker.setAttribute(\"tabindex\", \"0\");\n marker.setAttribute(\"role\", \"button\");\n const truncatedMessage = feedback.message.length > 60 ? `${feedback.message.slice(0, 60)}...` : feedback.message;\n const ariaLabel = this.t(\"marker.aria\")\n .replace(\"{number}\", String(number))\n .replace(\"{type}\", getTypeLabel(feedback.type, this.t))\n .replace(\"{message}\", truncatedMessage);\n marker.setAttribute(\"aria-label\", ariaLabel);\n marker.setAttribute(\"aria-describedby\", this.tooltip.tooltipId);\n setText(marker, isResolved ? \"\\u2713\" : String(number));\n\n marker.addEventListener(\"mouseenter\", () => {\n marker.style.transform = \"scale(1.2)\";\n marker.style.boxShadow = isResolved\n ? \"0 4px 16px rgba(0,0,0,0.1)\"\n : `0 4px 20px ${typeColor}35, 0 4px 12px rgba(0,0,0,0.08)`;\n this.tooltip.show(feedback, marker.getBoundingClientRect());\n if (!this.pinnedFeedback) this.showHighlight(feedback);\n });\n\n marker.addEventListener(\"mouseleave\", () => {\n marker.style.transform = \"scale(1)\";\n marker.style.boxShadow = isResolved\n ? \"0 2px 8px rgba(0,0,0,0.06)\"\n : `0 2px 12px ${typeColor}25, 0 2px 6px rgba(0,0,0,0.06)`;\n this.tooltip.scheduleHide();\n if (!this.pinnedFeedback) this.clearHighlight();\n });\n\n // WCAG 1.4.13 — tooltip must be reachable via keyboard (focus), not only\n // hover. Mirror mouseenter/mouseleave behaviour for focus/blur so a sighted\n // keyboard user gets the same affordance as a mouse user.\n marker.addEventListener(\"focus\", () => {\n this.tooltip.show(feedback, marker.getBoundingClientRect());\n if (!this.pinnedFeedback) this.showHighlight(feedback);\n });\n\n marker.addEventListener(\"blur\", () => {\n this.tooltip.scheduleHide();\n if (!this.pinnedFeedback) this.clearHighlight();\n });\n\n const activateMarker = (e: MouseEvent | KeyboardEvent) => {\n if (e instanceof MouseEvent && this.handleClusterClick(marker, e)) return;\n this.pinHighlight(feedback);\n this.bus.emit(\"panel:toggle\", true);\n marker.dispatchEvent(\n new CustomEvent(\"sp-marker-click\", {\n detail: { feedbackId: feedback.id },\n bubbles: true,\n }),\n );\n };\n\n marker.addEventListener(\"click\", (e) => activateMarker(e));\n marker.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n activateMarker(e);\n }\n });\n\n return marker;\n }\n\n /**\n * Scroll the annotation into view, pin its highlight, and pulse its marker.\n *\n * Powers the `deepLink` config option and the public\n * `instance.focusFeedback(id)` method. Returns `false` when no entry\n * matches — caller logs that case, the manager stays silent.\n *\n * Scrolling uses the marker element's current document position via\n * `scrollIntoView`, not the original `scrollX/scrollY` captured at\n * annotation time. That keeps the focus correct after layout changes\n * (responsive breakpoints, lazy-loaded content) because the marker has\n * already been re-positioned to track the live anchor.\n */\n focusFeedback(feedbackId: string): boolean {\n const entry = this.entries.find((e) => e.feedback.id === feedbackId);\n if (!entry) return false;\n const markerEl = entry.elements[0];\n if (markerEl) {\n markerEl.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n }\n this.pinHighlight(entry.feedback);\n this.highlight(feedbackId);\n return true;\n }\n\n highlight(feedbackId: string): void {\n for (const entry of this.entries) {\n if (entry.feedback.id === feedbackId) {\n for (const markerEl of entry.elements) {\n markerEl.style.animation = \"sp-pulse-ring 0.7s ease-out\";\n markerEl.addEventListener(\n \"animationend\",\n () => {\n markerEl.style.animation = \"\";\n },\n { once: true },\n );\n }\n }\n }\n }\n\n showHighlight(feedback: FeedbackResponse): void {\n this.removeHighlightElements();\n for (const annotation of feedback.annotations) {\n const resolved = resolveAnnotation(toAnchorData(annotation), toRectData(annotation));\n if (!resolved) continue;\n\n const typeColor = getTypeColor(feedback.type, this.colors);\n const rect = resolved.rect;\n const highlight = el(\"div\", {\n style: `\n position:absolute;\n top:${rect.top + window.scrollY}px;\n left:${rect.left + window.scrollX}px;\n width:${rect.width}px;height:${rect.height}px;\n border:2px solid ${typeColor};\n background:${typeColor}0c;\n border-radius:8px;\n pointer-events:none;z-index:-1;\n opacity:0;\n box-shadow:0 0 16px ${typeColor}20;\n transition:opacity ${HIGHLIGHT_FADE}ms ease;\n `,\n });\n this.container.appendChild(highlight);\n this.highlightElements.push(highlight);\n void highlight.offsetHeight; // Force reflow for CSS transition\n highlight.style.opacity = \"1\";\n }\n }\n\n pinHighlight(feedback: FeedbackResponse): void {\n this.unpinHighlight();\n this.showHighlight(feedback);\n this.pinnedFeedback = feedback;\n this.onDocumentClick = (e: MouseEvent) => {\n if (this.container.contains(e.target as Node)) return;\n this.unpinHighlight();\n };\n document.addEventListener(\"click\", this.onDocumentClick, { capture: true });\n }\n\n private unpinHighlight(): void {\n if (this.onDocumentClick) {\n document.removeEventListener(\"click\", this.onDocumentClick, { capture: true });\n this.onDocumentClick = null;\n }\n this.pinnedFeedback = null;\n this.clearHighlight();\n }\n\n private clearHighlight(): void {\n for (const h of this.highlightElements) {\n h.style.opacity = \"0\";\n setTimeout(() => h.remove(), HIGHLIGHT_FADE);\n }\n this.highlightElements = [];\n }\n\n private removeHighlightElements(): void {\n for (const h of this.highlightElements) h.remove();\n this.highlightElements = [];\n }\n\n clear(): void {\n this.unpinHighlight();\n this.container.replaceChildren();\n this.entries = [];\n this.clusters = [];\n this.anchorCache.clear();\n }\n\n destroy(): void {\n this.unpinHighlight();\n if (this.repositionTimer) {\n if (\"cancelIdleCallback\" in window) {\n window.cancelIdleCallback(this.repositionTimer);\n }\n clearTimeout(this.repositionTimer);\n }\n if (this.resizeHandler) window.removeEventListener(\"resize\", this.resizeHandler);\n if (this.scrollHandler) window.removeEventListener(\"scroll\", this.scrollHandler, { capture: true });\n if (this.onDocumentClickForClusters) document.removeEventListener(\"click\", this.onDocumentClickForClusters);\n this.mutationObserver?.disconnect();\n this.container.remove();\n }\n}\n","import {\n type AnnotationRecord,\n type AnnotationResponse,\n type FeedbackPayload,\n type FeedbackRecord,\n type FeedbackResponse,\n flattenAnnotation,\n type SitepingStore,\n} from \"@siteping/core\";\nimport type { GetFeedbacksOptions, WidgetClient } from \"./api-client.js\";\n\n/**\n * `WidgetClient` implementation that delegates directly to a `SitepingStore`.\n *\n * Used in client-side mode — the widget calls the store in-process instead of\n * making HTTP requests. Handles the same conversions the HTTP handler normally\n * performs: flattening annotations and serializing dates.\n */\nexport class StoreClient implements WidgetClient {\n constructor(\n private readonly store: SitepingStore,\n private readonly projectName: string,\n ) {}\n\n async sendFeedback(payload: FeedbackPayload): Promise<FeedbackResponse> {\n const record = await this.store.createFeedback({\n projectName: payload.projectName,\n type: payload.type,\n message: payload.message,\n status: \"open\",\n url: payload.url,\n urlPattern: payload.urlPattern ?? null,\n viewport: payload.viewport,\n userAgent: payload.userAgent,\n authorName: payload.authorName,\n authorEmail: payload.authorEmail,\n clientId: payload.clientId,\n annotations: payload.annotations.map(flattenAnnotation),\n screenshotDataUrl: payload.screenshotDataUrl ?? null,\n });\n\n return toResponse(record);\n }\n\n async getFeedbacks(\n projectName: string,\n options?: GetFeedbacksOptions,\n ): Promise<{ feedbacks: FeedbackResponse[]; total: number }> {\n const { feedbacks, total } = await this.store.getFeedbacks({\n projectName,\n page: options?.page,\n limit: options?.limit,\n type: options?.type,\n status: options?.status,\n search: options?.search,\n url: options?.url,\n urlPattern: options?.urlPattern,\n });\n\n return { feedbacks: feedbacks.map(toResponse), total };\n }\n\n async resolveFeedback(id: string, resolved: boolean): Promise<FeedbackResponse> {\n const record = await this.store.updateFeedback(id, {\n status: resolved ? \"resolved\" : \"open\",\n resolvedAt: resolved ? new Date() : null,\n });\n return toResponse(record);\n }\n\n async deleteFeedback(id: string): Promise<void> {\n await this.store.deleteFeedback(id);\n }\n\n async deleteAllFeedbacks(projectName: string): Promise<void> {\n await this.store.deleteAllFeedbacks(projectName);\n }\n}\n\n// ---------------------------------------------------------------------------\n// FeedbackRecord (Date) → FeedbackResponse (string) serialization\n// ---------------------------------------------------------------------------\n\nfunction toResponse(record: FeedbackRecord): FeedbackResponse {\n return {\n id: record.id,\n projectName: record.projectName,\n type: record.type,\n message: record.message,\n status: record.status,\n url: record.url,\n urlPattern: record.urlPattern ?? null,\n viewport: record.viewport,\n userAgent: record.userAgent,\n authorName: record.authorName,\n authorEmail: record.authorEmail,\n resolvedAt: record.resolvedAt?.toISOString() ?? null,\n createdAt: record.createdAt.toISOString(),\n updatedAt: record.updatedAt.toISOString(),\n annotations: record.annotations.map(toAnnotationResponse),\n screenshotUrl: record.screenshotUrl ?? null,\n diagnostics: record.diagnostics ?? null,\n };\n}\n\nfunction toAnnotationResponse(ann: AnnotationRecord): AnnotationResponse {\n return {\n id: ann.id,\n feedbackId: ann.feedbackId,\n cssSelector: ann.cssSelector,\n xpath: ann.xpath,\n textSnippet: ann.textSnippet,\n elementTag: ann.elementTag,\n elementId: ann.elementId,\n textPrefix: ann.textPrefix,\n textSuffix: ann.textSuffix,\n fingerprint: ann.fingerprint,\n neighborText: ann.neighborText,\n anchorKey: ann.anchorKey ?? null,\n xPct: ann.xPct,\n yPct: ann.yPct,\n wPct: ann.wPct,\n hPct: ann.hPct,\n scrollX: ann.scrollX,\n scrollY: ann.scrollY,\n viewportW: ann.viewportW,\n viewportH: ann.viewportH,\n devicePixelRatio: ann.devicePixelRatio,\n createdAt: ann.createdAt.toISOString(),\n };\n}\n","/**\n * CSS keyframes and animation utilities — Glassmorphism edition.\n *\n * Uses CSS-only spring animations via linear() timing function\n * and refined easing curves for premium motion design.\n */\n\n// Spring easing — computed from a spring simulation (damping: 15, stiffness: 100)\nconst SPRING_LINEAR = `linear(0, 0.006, 0.025, 0.06, 0.11, 0.17, 0.25, 0.34, 0.45, 0.56, 0.67, 0.78, 0.88, 0.95, 1.01, 1.04, 1.05, 1.04, 1.02, 1, 0.99, 1)`;\n\n// Ease-out-expo — fast start, smooth deceleration\nconst EASE_OUT_EXPO = `cubic-bezier(0.16, 1, 0.3, 1)`;\n\n// Spring overshoot — bouncy entrance\nconst SPRING_OVERSHOOT = `cubic-bezier(0.34, 1.56, 0.64, 1)`;\n\n// Smooth decel — for glass transitions\nconst EASE_OUT_QUART = `cubic-bezier(0.25, 1, 0.5, 1)`;\n\nexport const ANIMATION_CSS = `\n /* ---- Keyframes ---- */\n\n @keyframes sp-fab-in {\n from {\n transform: scale(0) rotate(-180deg);\n opacity: 0;\n }\n to {\n transform: scale(1) rotate(0deg);\n opacity: 1;\n }\n }\n\n @keyframes sp-fab-glow {\n 0%, 100% { box-shadow: 0 4px 20px var(--sp-accent-glow), 0 2px 8px rgba(0, 0, 0, 0.08); }\n 50% { box-shadow: 0 4px 28px var(--sp-accent-glow), 0 2px 12px rgba(0, 0, 0, 0.1); }\n }\n\n @keyframes sp-marker-in {\n 0% {\n transform: scale(0);\n opacity: 0;\n }\n 60% {\n transform: scale(1.2);\n opacity: 1;\n }\n 100% {\n transform: scale(1);\n }\n }\n\n @keyframes sp-pulse-ring {\n 0% {\n box-shadow: 0 0 0 0 var(--sp-accent-glow);\n }\n 70% {\n box-shadow: 0 0 0 8px transparent;\n }\n 100% {\n box-shadow: 0 0 0 0 transparent;\n }\n }\n\n @keyframes sp-flash-bg {\n 0% { background-color: var(--sp-accent-light); }\n 100% { background-color: transparent; }\n }\n\n @keyframes sp-slide-up {\n from {\n transform: translateY(8px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n }\n\n @keyframes sp-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n\n @keyframes sp-shimmer {\n 0% { background-position: -200% 0; }\n 100% { background-position: 200% 0; }\n }\n\n /* ---- Animation classes ---- */\n\n .sp-anim-fab-in {\n animation: sp-fab-in 0.5s ${SPRING_LINEAR} both;\n }\n\n .sp-anim-marker-in {\n animation: sp-marker-in 0.35s ${SPRING_OVERSHOOT} both;\n }\n\n .sp-anim-pulse {\n animation: sp-pulse-ring 0.7s ease-out;\n }\n\n .sp-anim-flash {\n animation: sp-flash-bg 0.5s ${EASE_OUT_QUART};\n }\n\n .sp-anim-slide-up {\n animation: sp-slide-up 0.3s ${EASE_OUT_EXPO} both;\n }\n\n .sp-anim-fade-in {\n animation: sp-fade-in 0.2s ease-out both;\n }\n\n /* ---- Transition utilities ---- */\n\n .sp-panel {\n transform: translateX(110%);\n transition: transform 0.4s ${EASE_OUT_EXPO};\n }\n\n .sp-panel.sp-panel--open {\n transform: translateX(0);\n }\n\n .sp-radial-item {\n opacity: 0;\n pointer-events: none;\n transform: translate(0, 0) scale(0.8);\n transition:\n transform 0.35s ${SPRING_OVERSHOOT},\n opacity 0.2s ease,\n background 0.2s ease,\n border-color 0.2s ease,\n box-shadow 0.2s ease;\n }\n\n .sp-radial-item.sp-radial-item--open {\n opacity: 1;\n pointer-events: auto;\n }\n\n /* Stagger delay via CSS custom property --sp-i */\n .sp-radial-item {\n transition-delay: calc(var(--sp-i, 0) * 50ms);\n }\n\n /* ---- Card stagger animation ---- */\n\n @keyframes sp-card-in {\n from {\n transform: translateY(12px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n }\n\n .sp-card {\n animation: sp-card-in 0.35s ${EASE_OUT_EXPO} both;\n animation-delay: calc(var(--sp-card-i, 0) * 40ms);\n }\n\n /* ---- Loading spinner ---- */\n\n @keyframes sp-spin {\n to { transform: rotate(360deg); }\n }\n\n .sp-spinner {\n width: 20px;\n height: 20px;\n border: 2px solid var(--sp-border);\n border-top-color: var(--sp-accent);\n border-radius: 50%;\n animation: sp-spin 0.6s linear infinite;\n }\n\n /* ---- Badge bounce ---- */\n\n @keyframes sp-badge-in {\n 0% { transform: scale(0); }\n 60% { transform: scale(1.3); }\n 100% { transform: scale(1); }\n }\n\n .sp-fab-badge {\n animation: sp-badge-in 0.4s ${SPRING_OVERSHOOT} both;\n }\n\n /* ---- Reduced motion ---- */\n\n @media (prefers-reduced-motion: reduce) {\n *, *::before, *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n }\n\n`;\n","import { Z_INDEX_MAX } from \"../constants.js\";\nimport { EXPORT_CSS } from \"../export-utils.js\";\nimport { BULK_CSS } from \"../panel-bulk.js\";\nimport { DETAIL_CSS } from \"../panel-detail.js\";\nimport { SORT_CSS } from \"../panel-sort.js\";\nimport { STATS_CSS } from \"../panel-stats.js\";\nimport { SHORTCUTS_CSS } from \"../shortcuts.js\";\nimport { ANIMATION_CSS } from \"./animations.js\";\nimport { cssVariables, type ThemeColors } from \"./theme.js\";\n\n/**\n * Build the complete CSS stylesheet for the Shadow DOM.\n *\n * Design: Glassmorphism — frosted glass surfaces, soft depth,\n * accent gradients, premium micro-interactions.\n *\n * Principles:\n * - :host uses `all: initial` to block inherited styles\n * - All classes prefixed with sp- (defense in depth)\n * - CSS custom properties for theming\n * - No external fonts — system-ui stack (Inter if available)\n * - :focus-visible on all interactive elements\n * - prefers-reduced-motion support\n */\nexport function buildStyles(colors: ThemeColors): string {\n return `\n :host {\n all: initial;\n position: fixed;\n z-index: ${Z_INDEX_MAX};\n font-family: var(--sp-font);\n font-size: 14px;\n line-height: 1.5;\n color: var(--sp-text);\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n ${cssVariables(colors)}\n\n /* Identity modal — theme-aware backdrop + panel */\n --sp-identity-bg: ${colors.glassBgHeavy};\n --sp-identity-overlay: ${colors.bg === \"#ffffff\" ? \"rgba(15, 23, 42, 0.2)\" : \"rgba(0, 0, 0, 0.4)\"};\n }\n\n *, *::before, *::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n }\n\n /* ============================\n Focus visible (accessibility)\n ============================ */\n\n :focus-visible {\n outline: 2px solid var(--sp-accent);\n outline-offset: 2px;\n /* Double-ring against any background colour: the bg-coloured halo\n separates the accent ring from busy host-page surfaces. */\n box-shadow: 0 0 0 4px var(--sp-bg);\n }\n\n /* ============================\n FAB (Floating Action Button)\n ============================ */\n\n .sp-fab {\n position: fixed;\n width: 52px;\n height: 52px;\n border-radius: var(--sp-radius-full);\n background: var(--sp-accent-gradient);\n color: #fff;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow:\n 0 4px 20px var(--sp-accent-glow),\n 0 2px 8px rgba(0, 0, 0, 0.08);\n transition:\n transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1),\n box-shadow 0.3s ease;\n outline: none;\n }\n\n .sp-fab:focus-visible {\n outline: 2px solid #fff;\n outline-offset: 3px;\n }\n\n .sp-fab:hover {\n transform: translateY(-2px) scale(1.05);\n box-shadow:\n 0 8px 28px var(--sp-accent-glow),\n 0 4px 12px rgba(0, 0, 0, 0.1);\n }\n\n .sp-fab:active {\n transform: translateY(0) scale(0.95);\n transition-duration: 0.1s;\n }\n\n .sp-fab--bottom-right {\n bottom: 24px;\n right: 24px;\n }\n\n .sp-fab--bottom-left {\n bottom: 24px;\n left: 24px;\n }\n\n .sp-fab svg {\n width: 22px;\n height: 22px;\n fill: currentColor;\n transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);\n }\n\n /* ---- FAB Badge ---- */\n\n .sp-fab-badge {\n position: absolute;\n top: -4px;\n right: -4px;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n border-radius: var(--sp-radius-full);\n background: #ef4444;\n color: #fff;\n font-size: 11px;\n font-weight: 700;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 2px solid #fff;\n pointer-events: none;\n font-family: var(--sp-font);\n line-height: 1;\n }\n\n /* ============================\n Radial Menu\n ============================ */\n\n .sp-radial {\n position: fixed;\n pointer-events: none;\n width: 52px;\n height: 52px;\n }\n\n .sp-radial--bottom-right {\n bottom: 24px;\n right: 24px;\n }\n\n .sp-radial--bottom-left {\n bottom: 24px;\n left: 24px;\n }\n\n .sp-radial-item {\n position: absolute;\n left: 4px;\n bottom: 4px;\n width: 44px;\n height: 44px;\n border-radius: var(--sp-radius-full);\n background: var(--sp-glass-bg-heavy);\n backdrop-filter: blur(var(--sp-blur));\n -webkit-backdrop-filter: blur(var(--sp-blur));\n color: var(--sp-text);\n border: 1px solid var(--sp-glass-border);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: var(--sp-shadow-md);\n font-size: 12px;\n font-weight: 600;\n }\n\n .sp-radial-item:hover,\n .sp-radial-item:focus-visible {\n background: rgba(255, 255, 255, 0.95);\n border-color: var(--sp-accent);\n color: var(--sp-accent);\n box-shadow:\n var(--sp-shadow-md),\n 0 0 0 3px var(--sp-accent-light);\n outline: none;\n }\n\n .sp-radial-item svg {\n width: 18px;\n height: 18px;\n flex-shrink: 0;\n stroke: currentColor;\n fill: none;\n }\n\n .sp-radial-label {\n white-space: nowrap;\n font-size: 12px;\n font-weight: 500;\n color: var(--sp-text);\n pointer-events: none;\n opacity: 0;\n padding: 4px 12px;\n border-radius: var(--sp-radius);\n background: var(--sp-glass-bg-heavy);\n backdrop-filter: blur(12px);\n -webkit-backdrop-filter: blur(12px);\n border: 1px solid var(--sp-glass-border);\n box-shadow: var(--sp-shadow-sm);\n transform: translateX(4px);\n transition: opacity 0.2s ease, transform 0.2s ease;\n }\n\n .sp-radial-item:hover .sp-radial-label,\n .sp-radial-item:focus-visible .sp-radial-label {\n opacity: 1;\n transform: translateX(0);\n }\n\n /* ============================\n Panel (Side drawer)\n ============================ */\n\n .sp-panel {\n position: fixed;\n top: 0;\n right: 0;\n width: 400px;\n max-width: 100vw;\n height: 100vh;\n height: 100dvh;\n background: var(--sp-glass-bg);\n backdrop-filter: blur(var(--sp-blur-heavy));\n -webkit-backdrop-filter: blur(var(--sp-blur-heavy));\n border-left: 1px solid var(--sp-glass-border);\n box-shadow: var(--sp-shadow-xl);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n @media (max-width: 480px) {\n .sp-panel {\n width: 100vw;\n border-left: none;\n }\n }\n\n .sp-panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n border-bottom: 1px solid var(--sp-border);\n background: var(--sp-glass-bg-heavy);\n backdrop-filter: blur(var(--sp-blur));\n -webkit-backdrop-filter: blur(var(--sp-blur));\n position: relative;\n z-index: 2;\n }\n\n .sp-panel-title {\n font-size: 17px;\n font-weight: 700;\n color: var(--sp-text);\n letter-spacing: -0.02em;\n }\n\n .sp-panel-close {\n width: 44px;\n height: 44px;\n border-radius: var(--sp-radius);\n border: none;\n background: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--sp-text-tertiary);\n transition: all 0.2s ease;\n }\n\n .sp-panel-close:hover {\n background: var(--sp-bg-hover);\n color: var(--sp-text);\n }\n\n .sp-panel-close svg {\n width: 16px;\n height: 16px;\n }\n\n /* ============================\n Filters & Search\n ============================ */\n\n .sp-filters {\n padding: 16px 24px;\n border-bottom: 1px solid var(--sp-border);\n background: var(--sp-glass-bg-heavy);\n backdrop-filter: blur(var(--sp-blur));\n -webkit-backdrop-filter: blur(var(--sp-blur));\n position: sticky;\n top: 0;\n z-index: 1;\n }\n\n .sp-search-wrap {\n position: relative;\n margin-bottom: 12px;\n }\n\n .sp-search {\n width: 100%;\n height: 40px;\n padding: 0 12px 0 38px;\n border-radius: var(--sp-radius);\n border: 1px solid var(--sp-border);\n background: var(--sp-glass-bg-heavy);\n color: var(--sp-text);\n font-family: var(--sp-font);\n font-size: 13px;\n outline: none;\n transition: all 0.2s ease;\n }\n\n .sp-search::placeholder {\n color: var(--sp-text-tertiary);\n }\n\n .sp-search:focus {\n border-color: var(--sp-accent);\n box-shadow: 0 0 0 3px var(--sp-accent-light);\n background: #fff;\n }\n\n .sp-search-icon {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--sp-text-tertiary);\n width: 16px;\n height: 16px;\n transition: color 0.2s ease;\n }\n\n .sp-search:focus ~ .sp-search-icon,\n .sp-search-wrap:focus-within .sp-search-icon {\n color: var(--sp-accent);\n }\n\n /* ============================\n Filter bar (type dropdown + status segmented)\n ============================ */\n\n .sp-filter-bar {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 8px;\n flex-wrap: wrap;\n }\n\n /* ============================\n Type filter dropdown\n ============================ */\n\n .sp-filter-dropdown {\n position: relative;\n flex: 1 1 auto;\n min-width: 0;\n }\n\n .sp-filter-dropdown-btn {\n --sp-chip-color: var(--sp-text-secondary);\n --sp-chip-bg: var(--sp-glass-bg-heavy);\n\n display: inline-flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n height: 32px;\n padding: 0 8px 0 10px;\n border-radius: var(--sp-radius-full);\n border: 1px solid var(--sp-border);\n background: var(--sp-glass-bg-heavy);\n color: var(--sp-text);\n font-family: var(--sp-font);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n white-space: nowrap;\n transition: background 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;\n }\n\n .sp-filter-dropdown-btn:hover {\n border-color: var(--sp-chip-color);\n background: var(--sp-chip-bg);\n }\n\n .sp-filter-dropdown-btn[aria-expanded=\"true\"] {\n border-color: var(--sp-chip-color);\n background: var(--sp-chip-bg);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--sp-chip-color) 14%, transparent);\n }\n\n .sp-filter-dropdown-btn--filtered {\n border-color: var(--sp-chip-color);\n background: var(--sp-chip-bg);\n }\n\n .sp-filter-dropdown-btn__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n flex-shrink: 0;\n color: var(--sp-chip-color);\n }\n\n .sp-filter-dropdown-btn__icon svg {\n width: 14px;\n height: 14px;\n }\n\n .sp-filter-dropdown-btn__label {\n display: inline-flex;\n align-items: baseline;\n gap: 6px;\n flex: 1;\n min-width: 0;\n overflow: hidden;\n }\n\n .sp-filter-dropdown-btn__prefix {\n color: var(--sp-text-tertiary);\n font-weight: 500;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n }\n\n .sp-filter-dropdown-btn__value {\n color: var(--sp-chip-color);\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .sp-filter-dropdown-btn__chevron {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n flex-shrink: 0;\n color: var(--sp-text-tertiary);\n transition: transform 0.18s ease, color 0.18s ease;\n }\n\n .sp-filter-dropdown-btn__chevron svg {\n width: 12px;\n height: 12px;\n }\n\n .sp-filter-dropdown-btn[aria-expanded=\"true\"] .sp-filter-dropdown-btn__chevron {\n transform: rotate(180deg);\n color: var(--sp-chip-color);\n }\n\n .sp-filter-dropdown-menu {\n position: absolute;\n top: calc(100% + 6px);\n left: 0;\n right: 0;\n min-width: 180px;\n padding: 4px;\n border-radius: var(--sp-radius);\n background: var(--sp-glass-bg-heavy);\n backdrop-filter: blur(var(--sp-blur-heavy));\n -webkit-backdrop-filter: blur(var(--sp-blur-heavy));\n border: 1px solid var(--sp-glass-border);\n box-shadow: var(--sp-shadow-md);\n z-index: 10;\n animation: sp-filter-menu-in 0.15s ease-out both;\n }\n\n @keyframes sp-filter-menu-in {\n from { opacity: 0; transform: translateY(-4px) scale(0.98); }\n to { opacity: 1; transform: translateY(0) scale(1); }\n }\n\n .sp-filter-dropdown-option {\n --sp-chip-color: var(--sp-text-secondary);\n --sp-chip-bg: transparent;\n\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 8px 10px;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: var(--sp-text);\n font-family: var(--sp-font);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n text-align: left;\n transition: background 0.12s ease, color 0.12s ease;\n }\n\n .sp-filter-dropdown-option__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n flex-shrink: 0;\n border-radius: 6px;\n background: var(--sp-chip-bg);\n color: var(--sp-chip-color);\n }\n\n .sp-filter-dropdown-option__icon svg {\n width: 13px;\n height: 13px;\n }\n\n .sp-filter-dropdown-option__label {\n flex: 1;\n min-width: 0;\n }\n\n .sp-filter-dropdown-option__check {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n flex-shrink: 0;\n color: var(--sp-chip-color);\n }\n\n .sp-filter-dropdown-option__check svg {\n width: 13px;\n height: 13px;\n }\n\n .sp-filter-dropdown-option:hover {\n background: var(--sp-bg-hover);\n }\n\n .sp-filter-dropdown-option--active {\n color: var(--sp-chip-color);\n font-weight: 600;\n }\n\n .sp-filter-dropdown-option--active:hover {\n background: var(--sp-chip-bg);\n }\n\n /* ============================\n Status segmented control\n ============================ */\n\n .sp-segmented {\n display: inline-flex;\n align-items: stretch;\n padding: 2px;\n border-radius: var(--sp-radius-full);\n border: 1px solid var(--sp-border);\n background: var(--sp-glass-bg-heavy);\n flex-shrink: 0;\n }\n\n .sp-segmented__btn {\n --sp-chip-color: var(--sp-text-tertiary);\n --sp-chip-bg: transparent;\n\n display: inline-flex;\n align-items: center;\n gap: 5px;\n height: 26px;\n padding: 0 10px;\n border: none;\n border-radius: var(--sp-radius-full);\n background: transparent;\n color: var(--sp-text-secondary);\n font-family: var(--sp-font);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n white-space: nowrap;\n transition: background 0.18s ease, color 0.18s ease, box-shadow 0.18s ease;\n }\n\n .sp-segmented__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 13px;\n height: 13px;\n flex-shrink: 0;\n color: var(--sp-chip-color);\n transition: color 0.18s ease, transform 0.18s ease;\n }\n\n .sp-segmented__icon svg {\n width: 13px;\n height: 13px;\n }\n\n .sp-segmented__btn:hover {\n color: var(--sp-chip-color);\n }\n\n .sp-segmented__btn:hover .sp-segmented__icon {\n color: var(--sp-chip-color);\n }\n\n .sp-segmented__btn--active {\n background: var(--sp-chip-bg);\n color: var(--sp-chip-color);\n font-weight: 600;\n box-shadow:\n inset 0 0 0 1px color-mix(in srgb, var(--sp-chip-color) 35%, transparent),\n 0 1px 2px rgba(0, 0, 0, 0.04);\n }\n\n .sp-segmented__btn--active .sp-segmented__icon {\n color: var(--sp-chip-color);\n }\n\n .sp-segmented__btn--open.sp-segmented__btn--active .sp-segmented__icon {\n animation: sp-segmented-pulse 2.4s ease-in-out infinite;\n }\n\n @keyframes sp-segmented-pulse {\n 0%, 100% { transform: scale(1); }\n 50% { transform: scale(0.85); }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .sp-filter-dropdown-btn,\n .sp-filter-dropdown-btn__chevron,\n .sp-filter-dropdown-option,\n .sp-segmented__btn,\n .sp-segmented__icon {\n transition: none;\n }\n .sp-filter-dropdown-menu {\n animation: none;\n }\n .sp-segmented__btn--open.sp-segmented__btn--active .sp-segmented__icon {\n animation: none;\n }\n }\n\n /* ============================\n Feedback Cards\n ============================ */\n\n .sp-list {\n flex: 1;\n overflow-y: auto;\n padding: 8px 12px;\n }\n\n .sp-list::-webkit-scrollbar {\n width: 6px;\n }\n\n .sp-list::-webkit-scrollbar-track {\n background: transparent;\n }\n\n .sp-list::-webkit-scrollbar-thumb {\n background: var(--sp-border);\n border-radius: var(--sp-radius-full);\n }\n\n .sp-list::-webkit-scrollbar-thumb:hover {\n background: var(--sp-text-tertiary);\n }\n\n .sp-card {\n display: flex;\n padding: 14px 16px;\n margin-bottom: 6px;\n cursor: pointer;\n border-radius: var(--sp-radius);\n background: var(--sp-glass-bg-heavy);\n border: 1px solid var(--sp-glass-border);\n box-shadow: var(--sp-shadow-xs);\n transition: all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);\n }\n\n .sp-card:hover {\n background: #fff;\n border-color: var(--sp-border);\n box-shadow: var(--sp-shadow-md);\n transform: translateY(-2px);\n }\n\n .sp-card:active {\n transform: translateY(0) scale(0.99);\n transition-duration: 0.1s;\n }\n\n .sp-card-bar {\n width: 3px;\n border-radius: var(--sp-radius-full);\n margin-right: 14px;\n flex-shrink: 0;\n }\n\n .sp-card-body {\n flex: 1;\n min-width: 0;\n }\n\n .sp-card-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n }\n\n .sp-card-number {\n font-size: 12px;\n font-weight: 700;\n color: var(--sp-text-tertiary);\n font-variant-numeric: tabular-nums;\n }\n\n .sp-badge {\n padding: 2px 10px;\n border-radius: var(--sp-radius-full);\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.02em;\n }\n\n .sp-card-date {\n font-size: 11px;\n color: var(--sp-text-tertiary);\n margin-left: auto;\n }\n\n .sp-card-message {\n font-size: 13px;\n line-height: 1.5;\n color: var(--sp-text);\n display: -webkit-box;\n -webkit-line-clamp: 3;\n -webkit-box-orient: vertical;\n overflow: hidden;\n }\n\n .sp-card-message--expanded {\n -webkit-line-clamp: unset;\n }\n\n .sp-card-expand {\n font-size: 12px;\n font-weight: 500;\n color: var(--sp-accent);\n cursor: pointer;\n background: none;\n border: none;\n padding: 4px 0;\n font-family: var(--sp-font);\n transition: opacity 0.15s ease;\n }\n\n .sp-card-expand:hover {\n opacity: 0.8;\n }\n\n .sp-card-footer {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 6px;\n margin-top: 10px;\n }\n\n .sp-btn-resolve,\n .sp-btn-delete {\n padding: 8px 14px;\n border-radius: var(--sp-radius-full);\n border: 1px solid var(--sp-border);\n background: transparent;\n color: var(--sp-text-secondary);\n font-family: var(--sp-font);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 4px;\n transition: all 0.2s ease;\n }\n\n .sp-btn-resolve svg,\n .sp-btn-delete svg {\n width: 14px;\n height: 14px;\n }\n\n .sp-btn-resolve:hover {\n border-color: #22c55e;\n color: #22c55e;\n background: rgba(34, 197, 94, 0.06);\n }\n\n .sp-btn-delete:hover {\n border-color: #ef4444;\n color: #ef4444;\n background: rgba(239, 68, 68, 0.06);\n }\n\n .sp-btn-resolve:disabled,\n .sp-btn-delete:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n }\n\n .sp-spinner--sm {\n width: 14px;\n height: 14px;\n }\n\n /* ---- Delete All (header) ---- */\n\n .sp-panel-header-right {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .sp-btn-delete-all {\n padding: 5px 12px;\n border-radius: var(--sp-radius-full);\n border: 1px solid var(--sp-border);\n background: transparent;\n color: var(--sp-text-tertiary);\n font-family: var(--sp-font);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 4px;\n transition: all 0.2s ease;\n }\n\n .sp-btn-delete-all svg {\n width: 13px;\n height: 13px;\n }\n\n .sp-btn-delete-all:hover {\n border-color: #ef4444;\n color: #ef4444;\n background: rgba(239, 68, 68, 0.06);\n }\n\n .sp-btn-delete-all:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n }\n\n /* ---- Confirm Dialog ---- */\n\n .sp-confirm-backdrop {\n position: fixed;\n inset: 0;\n background: var(--sp-backdrop, rgba(15, 23, 42, 0.2));\n backdrop-filter: blur(var(--sp-blur));\n -webkit-backdrop-filter: blur(var(--sp-blur));\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: ${Z_INDEX_MAX};\n opacity: 0;\n transition: opacity 0.2s ease;\n }\n\n .sp-confirm-dialog {\n width: 340px;\n padding: 28px;\n border-radius: 20px;\n background: var(--sp-glass-bg-heavy);\n backdrop-filter: blur(var(--sp-blur-heavy));\n -webkit-backdrop-filter: blur(var(--sp-blur-heavy));\n border: 1px solid var(--sp-glass-border);\n box-shadow: var(--sp-shadow-xl);\n font-family: var(--sp-font);\n transform: translateY(8px) scale(0.97);\n transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);\n }\n\n .sp-confirm-title {\n font-size: 17px;\n font-weight: 700;\n color: var(--sp-text);\n letter-spacing: -0.02em;\n margin-bottom: 8px;\n }\n\n .sp-confirm-message {\n font-size: 14px;\n color: var(--sp-text-secondary);\n line-height: 1.5;\n margin-bottom: 20px;\n }\n\n .sp-confirm-actions {\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n }\n\n .sp-btn-danger {\n height: 40px;\n padding: 0 22px;\n border-radius: var(--sp-radius);\n border: none;\n background: #ef4444;\n color: #fff;\n font-family: var(--sp-font);\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n box-shadow: 0 2px 8px rgba(239, 68, 68, 0.25);\n }\n\n .sp-btn-danger:hover {\n background: #dc2626;\n box-shadow: 0 4px 16px rgba(239, 68, 68, 0.3);\n transform: translateY(-1px);\n }\n\n .sp-btn-danger:active {\n transform: translateY(0) scale(0.98);\n transition-duration: 0.1s;\n }\n\n .sp-card--resolved {\n opacity: 0.5;\n }\n\n .sp-card--resolved .sp-card-message {\n text-decoration: line-through;\n text-decoration-color: var(--sp-text-tertiary);\n }\n\n /* ============================\n Loading State\n ============================ */\n\n .sp-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 48px 24px;\n }\n\n /* ============================\n Identity Form\n ============================ */\n\n .sp-identity-title {\n font-size: 17px;\n font-weight: 700;\n color: var(--sp-text);\n letter-spacing: -0.02em;\n }\n\n .sp-input {\n width: 100%;\n height: 42px;\n padding: 0 14px;\n border-radius: var(--sp-radius);\n border: 1px solid var(--sp-border);\n background: var(--sp-glass-bg-heavy);\n color: var(--sp-text);\n font-family: var(--sp-font);\n font-size: 14px;\n outline: none;\n transition: all 0.2s ease;\n }\n\n .sp-input::placeholder {\n color: var(--sp-text-tertiary);\n }\n\n .sp-input:focus {\n border-color: var(--sp-accent);\n box-shadow: 0 0 0 3px var(--sp-accent-light);\n background: #fff;\n }\n\n .sp-input-label {\n font-size: 13px;\n font-weight: 500;\n color: var(--sp-text-secondary);\n margin-bottom: 6px;\n display: block;\n }\n\n /* ============================\n Buttons\n ============================ */\n\n .sp-btn-primary {\n height: 40px;\n padding: 0 22px;\n border-radius: var(--sp-radius);\n border: none;\n background: var(--sp-accent-gradient);\n color: #fff;\n font-family: var(--sp-font);\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n box-shadow: 0 2px 8px var(--sp-accent-glow);\n }\n\n .sp-btn-primary:hover {\n box-shadow: 0 4px 16px var(--sp-accent-glow);\n transform: translateY(-1px);\n }\n\n .sp-btn-primary:active {\n transform: translateY(0) scale(0.98);\n transition-duration: 0.1s;\n }\n\n .sp-btn-primary:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n transform: none;\n box-shadow: none;\n }\n\n .sp-btn-ghost {\n height: 40px;\n padding: 0 22px;\n border-radius: var(--sp-radius);\n border: 1px solid var(--sp-border);\n background: var(--sp-glass-bg-heavy);\n color: var(--sp-text-secondary);\n font-family: var(--sp-font);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .sp-btn-ghost:hover {\n border-color: var(--sp-accent);\n color: var(--sp-accent);\n background: var(--sp-accent-light);\n }\n\n /* ============================\n Empty State\n ============================ */\n\n .sp-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 56px 24px;\n color: var(--sp-text-tertiary);\n text-align: center;\n gap: 8px;\n animation: sp-fade-in 0.3s ease-out both;\n }\n\n .sp-empty-text {\n font-size: 14px;\n font-weight: 500;\n }\n\n /* ============================\n Load More\n ============================ */\n\n .sp-load-more-wrap {\n display: flex;\n justify-content: center;\n padding: 12px 0 4px;\n }\n\n .sp-btn-load-more {\n width: 100%;\n }\n\n /* ============================\n Forced Colors / High Contrast\n ============================ */\n\n @media (forced-colors: active) {\n .sp-fab,\n .sp-radial-item,\n .sp-filter-dropdown-btn,\n .sp-segmented,\n .sp-segmented__btn,\n .sp-card,\n .sp-panel-close,\n .sp-search,\n .sp-btn-resolve,\n .sp-btn-delete,\n .sp-btn-delete-all,\n .sp-btn-primary,\n .sp-btn-ghost,\n .sp-btn-danger,\n .sp-card-expand,\n .sp-input,\n .sp-confirm-dialog {\n border: 2px solid ButtonText !important;\n background: Canvas !important;\n color: ButtonText !important;\n }\n\n .sp-segmented__btn--active {\n background: Highlight !important;\n color: HighlightText !important;\n }\n\n .sp-filter-dropdown-menu {\n border: 2px solid ButtonText !important;\n background: Canvas !important;\n }\n\n .sp-filter-dropdown-option--active {\n background: Highlight !important;\n color: HighlightText !important;\n }\n\n .sp-fab:focus-visible,\n .sp-radial-item:focus-visible,\n .sp-filter-dropdown-btn:focus-visible,\n .sp-segmented__btn:focus-visible,\n .sp-filter-dropdown-option:focus-visible,\n .sp-panel-close:focus-visible,\n .sp-btn-resolve:focus-visible,\n .sp-btn-delete:focus-visible,\n .sp-btn-delete-all:focus-visible,\n .sp-btn-primary:focus-visible,\n .sp-btn-ghost:focus-visible,\n .sp-btn-danger:focus-visible,\n .sp-card-expand:focus-visible,\n .sp-input:focus-visible,\n .sp-search:focus-visible {\n outline: 3px solid Highlight !important;\n }\n\n .sp-panel {\n border: 2px solid ButtonText !important;\n }\n\n .sp-fab-badge {\n border: 2px solid ButtonText !important;\n background: Canvas !important;\n color: ButtonText !important;\n }\n\n .sp-card-bar {\n background: ButtonText !important;\n }\n }\n\n ${ANIMATION_CSS}\n ${STATS_CSS}\n ${SORT_CSS}\n ${BULK_CSS}\n ${EXPORT_CSS}\n ${SHORTCUTS_CSS}\n ${DETAIL_CSS}\n `;\n}\n","import type { FeedbackResponse } from \"@siteping/core\";\nimport { Z_INDEX_MAX } from \"./constants.js\";\nimport { el, formatRelativeDate, setText } from \"./dom-utils.js\";\nimport { createT, getTypeLabel } from \"./i18n/index.js\";\nimport { getTypeBgColor, getTypeColor, type ThemeColors } from \"./styles/theme.js\";\n\nconst SHOW_DELAY = 120;\nconst HIDE_DELAY = 80;\n\n/**\n * Tooltip shown on annotation marker hover.\n *\n * Glassmorphism design: frosted glass with pastel badge,\n * smooth entrance animation, directional arrow.\n * Lives outside Shadow DOM.\n */\nexport class Tooltip {\n private root: HTMLElement;\n private arrow: HTMLElement;\n private showTimer: ReturnType<typeof setTimeout> | null = null;\n private hideTimer: ReturnType<typeof setTimeout> | null = null;\n private currentFeedbackId: string | null = null;\n\n readonly tooltipId = \"sp-tooltip\";\n\n constructor(\n private readonly colors: ThemeColors,\n private readonly locale: string = \"en\",\n ) {\n this.root = el(\"div\", {\n style: `\n position: fixed;\n z-index: ${Z_INDEX_MAX};\n max-width: 280px;\n padding: 12px 14px;\n border-radius: 14px;\n background: ${this.colors.glassBgHeavy};\n backdrop-filter: blur(24px);\n -webkit-backdrop-filter: blur(24px);\n border: 1px solid ${this.colors.glassBorder};\n box-shadow: 0 8px 32px ${this.colors.shadow}, 0 2px 8px ${this.colors.shadow};\n font-family: \"Inter\", system-ui, -apple-system, sans-serif;\n pointer-events: auto;\n opacity: 0;\n transform: translateY(6px) scale(0.97);\n transition: opacity 0.2s cubic-bezier(0.16, 1, 0.3, 1), transform 0.2s cubic-bezier(0.16, 1, 0.3, 1);\n visibility: hidden;\n -webkit-font-smoothing: antialiased;\n `,\n });\n\n this.root.setAttribute(\"role\", \"tooltip\");\n this.root.id = this.tooltipId;\n\n // Arrow element\n this.arrow = el(\"div\", {\n style: `\n position: absolute;\n width: 12px;\n height: 12px;\n background: ${this.colors.glassBgHeavy};\n border: 1px solid ${this.colors.glassBorder};\n transform: rotate(45deg);\n pointer-events: none;\n `,\n });\n this.root.appendChild(this.arrow);\n\n this.root.addEventListener(\"mouseenter\", () => this.cancelHide());\n this.root.addEventListener(\"mouseleave\", () => this.scheduleHide());\n document.body.appendChild(this.root);\n }\n\n show(feedback: FeedbackResponse, anchorRect: DOMRect): void {\n if (this.currentFeedbackId === feedback.id) return;\n this.cancelHide();\n this.cancelShow();\n\n this.showTimer = setTimeout(() => {\n this.currentFeedbackId = feedback.id;\n this.render(feedback);\n this.position(anchorRect);\n\n // Check prefers-reduced-motion live (not cached at construction time)\n const reduceMotion =\n typeof window !== \"undefined\" && window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n this.root.style.transition = reduceMotion ? \"none\" : \"\";\n\n this.root.style.visibility = \"visible\";\n this.root.style.opacity = \"1\";\n this.root.style.transform = \"translateY(0) scale(1)\";\n }, SHOW_DELAY);\n }\n\n scheduleHide(): void {\n this.cancelHide();\n this.hideTimer = setTimeout(() => this.hide(), HIDE_DELAY);\n }\n\n hide(): void {\n this.cancelShow();\n this.currentFeedbackId = null;\n this.root.style.opacity = \"0\";\n this.root.style.transform = \"translateY(6px) scale(0.97)\";\n setTimeout(() => {\n if (!this.currentFeedbackId) {\n this.root.style.visibility = \"hidden\";\n }\n }, 200);\n }\n\n private cancelShow(): void {\n if (this.showTimer) {\n clearTimeout(this.showTimer);\n this.showTimer = null;\n }\n }\n\n private cancelHide(): void {\n if (this.hideTimer) {\n clearTimeout(this.hideTimer);\n this.hideTimer = null;\n }\n }\n\n private render(feedback: FeedbackResponse): void {\n // Clear previous content safely (except arrow)\n const children = Array.from(this.root.children);\n for (const child of children) {\n if (child !== this.arrow) child.remove();\n }\n\n const typeColor = getTypeColor(feedback.type, this.colors);\n const typeBg = getTypeBgColor(feedback.type, this.colors);\n const t = createT(this.locale);\n const typeLabel = getTypeLabel(feedback.type, t);\n\n // Header row: badge + date\n const header = el(\"div\", { style: \"display:flex;align-items:center;gap:8px;margin-bottom:8px;\" });\n\n const badge = el(\"span\", {\n style: `\n padding:3px 10px;border-radius:9999px;\n font-size:11px;font-weight:600;\n color:${typeColor};background:${typeBg};\n letter-spacing:0.02em;\n `,\n });\n setText(badge, typeLabel);\n\n const date = el(\"span\", { style: `font-size:11px;color:${this.colors.textSecondary};margin-left:auto;` });\n setText(date, formatRelativeDate(feedback.createdAt, this.locale));\n\n header.appendChild(badge);\n header.appendChild(date);\n\n // Message body (safe — textContent only)\n const body = el(\"div\", {\n style: `font-size:13px;line-height:1.55;color:${this.colors.text};display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;`,\n });\n setText(body, feedback.message);\n\n // Insert content before arrow\n this.root.insertBefore(header, this.arrow);\n this.root.insertBefore(body, this.arrow);\n }\n\n private position(anchorRect: DOMRect): void {\n const tooltipRect = this.root.getBoundingClientRect();\n const gap = 10;\n\n let top = anchorRect.top - tooltipRect.height - gap;\n let left = anchorRect.left + anchorRect.width / 2 - tooltipRect.width / 2;\n let isAbove = true;\n\n // Flip below if not enough space above\n if (top < 8) {\n top = anchorRect.bottom + gap;\n isAbove = false;\n }\n\n left = Math.max(8, Math.min(left, window.innerWidth - tooltipRect.width - 8));\n\n this.root.style.top = `${top}px`;\n this.root.style.left = `${left}px`;\n\n // Position arrow\n const arrowLeft = Math.max(16, Math.min(anchorRect.left + anchorRect.width / 2 - left - 6, tooltipRect.width - 22));\n\n if (isAbove) {\n // Arrow at bottom, pointing down\n this.arrow.style.cssText = `\n position:absolute;\n width:12px;height:12px;\n background:${this.colors.glassBgHeavy};\n border-right:1px solid ${this.colors.glassBorder};\n border-bottom:1px solid ${this.colors.glassBorder};\n transform:rotate(45deg);\n pointer-events:none;\n bottom:-6px;\n left:${arrowLeft}px;\n `;\n } else {\n // Arrow at top, pointing up\n this.arrow.style.cssText = `\n position:absolute;\n width:12px;height:12px;\n background:${this.colors.glassBgHeavy};\n border-left:1px solid ${this.colors.glassBorder};\n border-top:1px solid ${this.colors.glassBorder};\n transform:rotate(45deg);\n pointer-events:none;\n top:-6px;\n left:${arrowLeft}px;\n `;\n }\n }\n\n /** Check if a DOM node belongs to this tooltip (for MutationObserver filtering). */\n contains(node: Node): boolean {\n return this.root.contains(node);\n }\n\n destroy(): void {\n this.cancelShow();\n this.cancelHide();\n this.root.remove();\n }\n}\n","import type {\n DiagnosticsSnapshot,\n FeedbackPayload,\n FeedbackResponse,\n PageScope,\n SitepingConfig,\n SitepingInstance,\n SitepingPublicEvents,\n} from \"@siteping/core\";\nimport { Annotator } from \"./annotator.js\";\nimport { ApiClient, flushRetryQueue, type WidgetClient } from \"./api-client.js\";\nimport { MOBILE_BREAKPOINT, PAGE_SIZE, Z_INDEX_MAX } from \"./constants.js\";\nimport { ConsoleBuffer } from \"./diagnostics/console-buffer.js\";\nimport { NetworkBuffer } from \"./diagnostics/network-buffer.js\";\nimport { EventBus, type PublicWidgetEvents, type WidgetEvents } from \"./events.js\";\nimport { Fab } from \"./fab.js\";\nimport { createT, loadLocale, type TFunction } from \"./i18n/index.js\";\nimport { getIdentity, type Identity, saveIdentity } from \"./identity.js\";\nimport { MarkerManager } from \"./markers.js\";\nimport type { Panel as PanelType } from \"./panel.js\";\nimport { StoreClient } from \"./store-client.js\";\nimport { buildStyles } from \"./styles/base.js\";\nimport { buildThemeColors } from \"./styles/theme.js\";\nimport { Tooltip } from \"./tooltip.js\";\n\n/** Singleton guard — prevents duplicate widgets from overlapping */\nlet instance: SitepingInstance | null = null;\n\ninterface NormalisedDiagnostics {\n console: boolean;\n network: boolean;\n maxConsoleEntries: number;\n maxNetworkEntries: number;\n}\n\n/**\n * Resolve `SitepingConfig.captureDiagnostics` into a normalised shape.\n *\n * - `undefined` / `false` → everything off (no monkey-patching).\n * - `true` → console + network on with the defaults (50 / 20).\n * - object → per-channel toggles + optional custom sizes; missing booleans\n * default to `true` so users can pass `{ maxConsoleEntries: 200 }` and\n * still get both channels.\n */\nfunction normaliseDiagnosticsOptions(value: SitepingConfig[\"captureDiagnostics\"]): NormalisedDiagnostics {\n if (value === undefined || value === false) {\n return { console: false, network: false, maxConsoleEntries: 50, maxNetworkEntries: 20 };\n }\n if (value === true) {\n return { console: true, network: true, maxConsoleEntries: 50, maxNetworkEntries: 20 };\n }\n return {\n console: value.console !== false,\n network: value.network !== false,\n maxConsoleEntries: typeof value.maxConsoleEntries === \"number\" ? value.maxConsoleEntries : 50,\n maxNetworkEntries: typeof value.maxNetworkEntries === \"number\" ? value.maxNetworkEntries : 20,\n };\n}\n\n/** Build a no-op SitepingInstance for when the widget is skipped */\nfunction skippedInstance(): SitepingInstance {\n const noop = () => {};\n return {\n destroy: noop,\n open: noop,\n close: noop,\n refresh: noop,\n focusFeedback: () => false,\n on: () => noop,\n off: noop,\n };\n}\n\ninterface NormalisedDeepLink {\n enabled: boolean;\n param: string;\n}\n\n/**\n * Resolve `SitepingConfig.deepLink` into a normalised shape.\n *\n * - `undefined` / `false` → disabled, no URL parsing.\n * - `true` → enabled with default param name `siteping`.\n * - object → enabled with optional custom param name. A bare empty object\n * `{}` falls back to the default param so callers never need to repeat it.\n */\nfunction normaliseDeepLinkOptions(value: SitepingConfig[\"deepLink\"]): NormalisedDeepLink {\n if (value === undefined || value === false) return { enabled: false, param: \"siteping\" };\n if (value === true) return { enabled: true, param: \"siteping\" };\n return { enabled: true, param: value.param ?? \"siteping\" };\n}\n\n/**\n * Main widget launcher — orchestrates all UI components.\n *\n * Architecture:\n * - Creates a <siteping-widget> custom element in the document\n * - Attaches a closed Shadow DOM for CSS isolation\n * - FAB + Panel live inside the Shadow DOM\n * - Overlay, markers, tooltips live outside (appended to document.body)\n */\nexport function launch(config: SitepingConfig): SitepingInstance {\n // Debug helper — only logs when config.debug is true\n const log: (...args: unknown[]) => void = config.debug\n ? (...args: unknown[]) => console.debug(\"[siteping]\", ...args)\n : () => {};\n\n // Guard: prevent duplicate initSiteping() calls\n if (instance) {\n log(\"initSiteping() called more than once — returning existing instance\");\n return instance;\n }\n\n // Guard: only show in development (forceShow bypasses)\n if (!config.forceShow) {\n try {\n // Check for Node/bundler production environment — avoid import.meta\n // which causes \"Critical dependency\" warnings in Next.js webpack builds\n if (typeof process !== \"undefined\" && process.env?.NODE_ENV === \"production\") {\n const reason = \"production\";\n console.info(\"[siteping] Widget not loaded: production mode detected. Use forceShow: true to override.\");\n config.onSkip?.(reason);\n return skippedInstance();\n }\n } catch {\n // Silently ignore — browser or restricted environment\n }\n }\n\n // Guard: desktop only (< MOBILE_BREAKPOINT = hidden)\n if (window.innerWidth < MOBILE_BREAKPOINT) {\n const reason = \"mobile\";\n console.info(`[siteping] Widget not loaded: viewport width < ${MOBILE_BREAKPOINT}px (mobile not supported).`);\n config.onSkip?.(reason);\n return skippedInstance();\n }\n\n // Guard: validate required config fields\n if (!config.store && (!config.endpoint || typeof config.endpoint !== \"string\")) {\n console.error(\n \"[siteping] Missing 'endpoint' or 'store' in config. Provide an endpoint like '/api/siteping' or a SitepingStore instance.\",\n );\n return skippedInstance();\n }\n if (!config.projectName || typeof config.projectName !== \"string\") {\n console.error(\"[siteping] Missing or invalid 'projectName' in config. Expected a non-empty string.\");\n return skippedInstance();\n }\n\n const locale = config.locale ?? \"en\";\n // Kick off the locale fetch immediately so the panel can render in the\n // resolved language as soon as it mounts. English is bundled synchronously\n // and used as the fallback while the chunk is in flight.\n if (locale !== \"en\") {\n loadLocale(locale).catch(() => {\n /* fallback to English — already handled by createT */\n });\n }\n const t = createT(locale);\n\n // Page scope — concrete URL + optional template, used to keep annotations\n // and panel results scoped to the current page. The widget calls this on\n // every initial markers load and on `instance.refresh()`, so SPA hosts can\n // re-fetch when the route changes.\n const scopeAnnotationsByUrl = config.scopeAnnotationsByUrl ?? true;\n const getScope = (): PageScope => {\n try {\n const result = config.getPageScope?.();\n if (result) return result;\n } catch (e) {\n log(\"getPageScope() threw, falling back to pathname:\", e);\n }\n return { url: window.location.pathname, urlPattern: null };\n };\n\n log(\"Initializing widget\", {\n projectName: config.projectName,\n theme: config.theme ?? \"light\",\n locale,\n scopeAnnotationsByUrl,\n });\n\n // Diagnostics — capture console + failed network at submit time when\n // `captureDiagnostics` is set. Buffers are installed eagerly so they\n // cover the entire session, then snapshotted in the annotation handler\n // below. We default to `false` even in dev to avoid surprise side\n // effects; users opt in via the config flag.\n const diagnosticsOpts = normaliseDiagnosticsOptions(config.captureDiagnostics);\n const consoleBuffer = diagnosticsOpts.console ? new ConsoleBuffer(diagnosticsOpts.maxConsoleEntries) : null;\n const networkBuffer = diagnosticsOpts.network ? new NetworkBuffer(diagnosticsOpts.maxNetworkEntries) : null;\n\n const colors = buildThemeColors(config.accentColor, config.theme);\n const bus = new EventBus<WidgetEvents>();\n const publicBus = new EventBus<PublicWidgetEvents>();\n\n // Client-side mode (store) vs HTTP mode (endpoint)\n const client: WidgetClient = config.store\n ? new StoreClient(config.store, config.projectName)\n : new ApiClient(config.endpoint as string, config.projectName);\n\n // Wire config callbacks to event bus\n if (config.onOpen) bus.on(\"open\", config.onOpen);\n if (config.onClose) bus.on(\"close\", config.onClose);\n if (config.onFeedbackSent) bus.on(\"feedback:sent\", config.onFeedbackSent);\n if (config.onError) bus.on(\"feedback:error\", config.onError);\n if (config.onAnnotationStart) bus.on(\"annotation:start\", config.onAnnotationStart);\n if (config.onAnnotationEnd) bus.on(\"annotation:end\", config.onAnnotationEnd);\n\n // Bridge internal events to public bus\n bus.on(\"feedback:sent\", (fb) => publicBus.emit(\"feedback:sent\", fb));\n bus.on(\"feedback:deleted\", (id) => publicBus.emit(\"feedback:deleted\", id));\n bus.on(\"open\", () => publicBus.emit(\"panel:open\"));\n bus.on(\"close\", () => publicBus.emit(\"panel:close\"));\n\n // Debug logging for key lifecycle events\n bus.on(\"open\", () => log(\"Panel opened\"));\n bus.on(\"close\", () => log(\"Panel closed\"));\n bus.on(\"feedback:sent\", (fb) => log(\"Feedback sent\", fb.id));\n bus.on(\"feedback:error\", (err) => log(\"Feedback failed\", err.message));\n bus.on(\"annotation:start\", () => log(\"Annotation started\"));\n bus.on(\"annotation:end\", () => log(\"Annotation ended\"));\n\n // Create host element + Shadow DOM\n const host = document.createElement(\"siteping-widget\");\n host.style.cssText = `position:fixed;z-index:${Z_INDEX_MAX};`;\n // Use open mode only for testing — closed in production for CSS isolation.\n // Shadow DOM mode is determined by environment, never by public config.\n let isTestEnv = false;\n try {\n // Dynamic key prevents bundlers (tsup/esbuild) from statically replacing\n // process.env.NODE_ENV at build time — the widget needs runtime detection\n // so E2E tests can set globalThis.process = { env: { NODE_ENV: 'test' } }\n const envKey = \"NODE_\" + \"ENV\";\n if (typeof process !== \"undefined\" && process.env?.[envKey] === \"test\") {\n isTestEnv = true;\n }\n } catch {\n // Silently ignore — browser or restricted environment\n }\n const shadowMode = isTestEnv ? (\"open\" as const) : (\"closed\" as const);\n const shadow = host.attachShadow({ mode: shadowMode });\n\n // Inject styles into Shadow DOM — adoptedStyleSheets with fallback for Safari < 16.4\n const supportsAdoptedStyleSheets = \"adoptedStyleSheets\" in ShadowRoot.prototype;\n if (supportsAdoptedStyleSheets) {\n const sheet = new CSSStyleSheet();\n sheet.replaceSync(buildStyles(colors));\n shadow.adoptedStyleSheets = [sheet];\n } else {\n const style = document.createElement(\"style\");\n style.textContent = buildStyles(colors);\n (shadow as unknown as DocumentFragment).appendChild(style);\n }\n\n document.body.appendChild(host);\n\n // Screen reader live region for feedback submission announcements\n const liveRegion = document.createElement(\"div\");\n liveRegion.setAttribute(\"role\", \"status\");\n liveRegion.setAttribute(\"aria-live\", \"polite\");\n liveRegion.setAttribute(\"aria-atomic\", \"true\");\n liveRegion.style.cssText =\n \"position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;\";\n document.body.appendChild(liveRegion);\n\n // Components outside Shadow DOM\n const tooltip = new Tooltip(colors, locale);\n const markers = new MarkerManager(colors, tooltip, bus, t, liveRegion);\n\n // Components inside Shadow DOM\n const fab = new Fab(shadow, config, bus, t);\n\n // Lazy-load Panel on first use (FAB click, instance.open, etc.) to keep the\n // initial bundle small. Panel + sub-modules are ~14 KB gzip on their own.\n // Memoize the import promise so subsequent calls reuse the same instance.\n let panelInstance: PanelType | null = null;\n let panelPromise: Promise<PanelType> | null = null;\n let destroyed = false;\n async function loadPanel(): Promise<PanelType | null> {\n if (destroyed) return null;\n if (panelInstance) return panelInstance;\n if (!panelPromise) {\n panelPromise = import(\"./panel.js\").then((mod) => {\n if (destroyed) return null as unknown as PanelType;\n panelInstance = new mod.Panel(shadow, colors, bus, client, config.projectName, markers, t, locale, {\n getScope,\n scopeAnnotationsByUrl,\n });\n return panelInstance;\n });\n }\n return panelPromise;\n }\n\n // Prefetch Panel in idle time so the first FAB click doesn't pay the\n // network/parse cost of the dynamic import. The chunk still ships lazily\n // (saves first-paint gzip), but it's already warming up by the time the\n // user is likely to click. Falls back to setTimeout in browsers without\n // requestIdleCallback (Safari before 17).\n if (typeof window !== \"undefined\") {\n const prefetch = () => {\n if (!destroyed) void loadPanel();\n };\n const ric = (window as { requestIdleCallback?: (cb: () => void) => void }).requestIdleCallback;\n if (typeof ric === \"function\") ric(prefetch);\n else setTimeout(prefetch, 200);\n }\n\n // The FAB emits `panel:toggle` on chat click — we intercept here so the\n // launcher (which holds the lazy loader) can drive the Panel lifecycle.\n // Panel itself also subscribes to `panel:toggle` once loaded; once the\n // dynamic import resolves we manually call `p.open()` because the missed\n // initial emit can't be replayed.\n let pendingOpen = false;\n const unsubToggle = bus.on(\"panel:toggle\", (open) => {\n if (panelInstance) return; // Real Panel already handles subsequent toggles\n if (open) {\n pendingOpen = true;\n loadPanel()\n .then((p) => {\n if (p && pendingOpen) p.open();\n pendingOpen = false;\n })\n .catch((err) => log(\"Failed to lazy-load panel:\", err));\n } else {\n pendingOpen = false;\n }\n });\n\n const annotator = new Annotator(colors, bus, t, config.enableScreenshot ?? false);\n\n // Handle annotation completion via event bus (not DOM events)\n // Concurrency guard: prevent duplicate submissions if user draws two annotations quickly\n let submitting = false;\n const unsubAnnotation = bus.on(\"annotation:complete\", async (data) => {\n if (submitting) return;\n submitting = true;\n try {\n const { annotation, type, message, screenshotDataUrl } = data;\n\n // Ensure identity — config wins (host-provided), then localStorage,\n // then prompt the user as a last resort. Host-provided identity is\n // not persisted: the host stays the source of truth on every render.\n let identity = config.identity ?? getIdentity();\n if (!identity) {\n identity = await promptIdentity(shadow, t);\n if (!identity) return; // User cancelled\n saveIdentity(identity);\n }\n\n // crypto.randomUUID() throws in non-secure contexts (plain HTTP)\n const clientId = (() => {\n try {\n return crypto.randomUUID();\n } catch {\n return `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n }\n })();\n\n // Use scope.url as the single source of truth — same identifier the\n // panel filter and marker filter use. If we stored full URLs here while\n // filtering by pathname, freshly-created feedbacks would never match\n // their own scope filter and would vanish from the UI immediately.\n // Default scope.url is `window.location.pathname` (no query string,\n // so token/key/secret query params can't leak by construction). Hosts\n // that need origin or query in the identifier override `getPageScope`.\n const scope = getScope();\n\n // Snapshot the buffers right before submit so the captured slice\n // matches the moment the user clicked \"send\", not some earlier point.\n let diagnostics: DiagnosticsSnapshot | null = null;\n if (consoleBuffer || networkBuffer) {\n diagnostics = {\n console: consoleBuffer?.getEntries() ?? [],\n network: networkBuffer?.getEntries() ?? [],\n };\n }\n\n const payload: FeedbackPayload = {\n projectName: config.projectName,\n type,\n message,\n url: scope.url,\n urlPattern: scope.urlPattern,\n viewport: `${window.innerWidth}x${window.innerHeight}`,\n userAgent: navigator.userAgent,\n authorName: identity.name,\n authorEmail: identity.email,\n annotations: [annotation],\n clientId,\n screenshotDataUrl: screenshotDataUrl ?? null,\n diagnostics,\n };\n\n try {\n const response = await client.sendFeedback(payload);\n bus.emit(\"feedback:sent\", response);\n // Compare against the scope captured before submit (route may have\n // changed during the network round-trip — re-reading scope here\n // would race with SPA navigation).\n if (!scopeAnnotationsByUrl || response.url === scope.url) {\n markers.addFeedback(response, markers.count + 1);\n }\n liveRegion.textContent = t(\"feedback.sent.confirmation\");\n // Only refresh the panel if it has been loaded — `refresh()` is a\n // no-op when the panel is closed, so skipping the dynamic import here\n // avoids loading 14 KB of code that would otherwise do nothing.\n if (panelInstance) await panelInstance.refresh();\n } catch (error) {\n bus.emit(\"feedback:error\", error instanceof Error ? error : new Error(String(error)));\n liveRegion.textContent = t(\"feedback.error.message\");\n }\n } finally {\n submitting = false;\n }\n });\n\n // Load markers immediately on page load. We always pass the current page URL\n // when scopeAnnotationsByUrl is enabled so the server narrows results to the\n // current page — preventing annotations from one page accidentally rendering\n // on another (when CSS selectors happen to match unrelated elements).\n const initialScope = getScope();\n const initialOptions = scopeAnnotationsByUrl ? { limit: PAGE_SIZE, url: initialScope.url } : { limit: PAGE_SIZE };\n const deepLinkOpts = normaliseDeepLinkOptions(config.deepLink);\n client\n .getFeedbacks(config.projectName, initialOptions)\n .then(({ feedbacks }: { feedbacks: FeedbackResponse[] }) => {\n // Defensive client-side filter — backend may not yet support the `url` query.\n const visible = scopeAnnotationsByUrl ? feedbacks.filter((f) => f.url === initialScope.url) : feedbacks;\n markers.render(visible);\n // Apply deeplink focus once markers exist. Failures here are\n // non-fatal — a malformed URL or an unknown ID just leaves the page\n // as the user found it, so log and move on.\n if (deepLinkOpts.enabled) {\n try {\n const focusId = new URLSearchParams(window.location.search).get(deepLinkOpts.param);\n if (focusId) {\n const matched = markers.focusFeedback(focusId);\n log(\n `deepLink ?${deepLinkOpts.param}=${focusId} ${matched ? \"focused\" : \"did not match a visible feedback\"}`,\n );\n }\n } catch (e) {\n log(\"deepLink parsing failed:\", e);\n }\n }\n })\n .catch((err) => {\n log(\"Failed to load initial markers:\", err);\n });\n\n // Flush retry queue on load (HTTP mode only — store mode has no retry queue)\n if (config.endpoint) {\n flushRetryQueue(config.endpoint)\n .then(() => log(\"Retry queue flushed\"))\n .catch(() => {});\n }\n\n instance = {\n destroy: () => {\n log(\"Destroying widget\");\n destroyed = true;\n pendingOpen = false;\n unsubAnnotation();\n unsubToggle();\n fab.destroy();\n panelInstance?.destroy();\n annotator.destroy();\n markers.destroy();\n tooltip.destroy();\n // Restore the original console / fetch / XHR so the host page isn't\n // left with patched globals after the widget tears itself down.\n consoleBuffer?.dispose();\n networkBuffer?.dispose();\n bus.removeAll();\n publicBus.removeAll();\n liveRegion.remove();\n host.remove();\n instance = null;\n },\n open: () => {\n // Emit synchronously so consumers wired through `onOpen` / `panel:open`\n // see the open event immediately, even before the Panel module has\n // finished loading on the first call.\n bus.emit(\"panel:toggle\", true);\n },\n close: () => {\n if (panelInstance) {\n panelInstance.close();\n } else {\n // Cancel a pending open before the panel has loaded.\n pendingOpen = false;\n }\n },\n focusFeedback: (feedbackId: string) => {\n // Returns false when no entry matches — unknown ID, feedback filtered\n // out by `scopeAnnotationsByUrl`, or markers not yet loaded (the\n // initial getFeedbacks is async, and the widget exposes no public\n // \"markers ready\" event today). Hosts that race against initial load\n // can retry, or trigger focus from a user gesture instead.\n return markers.focusFeedback(feedbackId);\n },\n refresh: () => {\n // When the panel is open, its `refresh()` already runs `loadFeedbacks()`\n // which renders markers. Doing a second fetch here would race with that\n // one — the loser overwrites the winner's markers, off by a generation.\n // So: when the panel is open, delegate. When it's closed, fetch markers\n // ourselves (the panel won't, but SPA hosts still need the new page's\n // markers after a route change).\n if (panelInstance?.isCurrentlyOpen) {\n panelInstance.refresh();\n return;\n }\n\n const scope = getScope();\n const opts = scopeAnnotationsByUrl ? { limit: PAGE_SIZE, url: scope.url } : { limit: PAGE_SIZE };\n client\n .getFeedbacks(config.projectName, opts)\n .then(({ feedbacks }: { feedbacks: FeedbackResponse[] }) => {\n const visible = scopeAnnotationsByUrl ? feedbacks.filter((f) => f.url === scope.url) : feedbacks;\n markers.render(visible);\n })\n .catch(() => {});\n },\n on: <K extends keyof SitepingPublicEvents>(event: K, listener: (...args: SitepingPublicEvents[K]) => void) => {\n // Safe cast: SitepingPublicEvents and PublicWidgetEvents have identical keys and value types\n type TargetKey = K & keyof PublicWidgetEvents;\n return publicBus.on(event as TargetKey, listener as unknown as (...args: PublicWidgetEvents[TargetKey]) => void);\n },\n off: <K extends keyof SitepingPublicEvents>(event: K, listener: (...args: SitepingPublicEvents[K]) => void) => {\n // Safe cast: SitepingPublicEvents and PublicWidgetEvents have identical keys and value types\n type TargetKey = K & keyof PublicWidgetEvents;\n publicBus.off(event as TargetKey, listener as unknown as (...args: PublicWidgetEvents[TargetKey]) => void);\n },\n };\n\n return instance;\n}\n\n/**\n * Show a modal identity form inside the Shadow DOM.\n * Glassmorphism: frosted backdrop, glass modal, gradient CTA.\n * Returns null if the user cancels.\n */\nfunction promptIdentity(shadowRoot: ShadowRoot, t: TFunction): Promise<Identity | null> {\n return new Promise((resolve) => {\n // Save the currently focused element to restore on close\n const previouslyFocused = (shadowRoot.activeElement ?? document.activeElement) as HTMLElement | null;\n\n const backdrop = document.createElement(\"div\");\n backdrop.style.cssText = `\n position:fixed;inset:0;\n background:var(--sp-identity-overlay);\n backdrop-filter:blur(8px);\n -webkit-backdrop-filter:blur(8px);\n display:flex;align-items:center;justify-content:center;\n z-index:${Z_INDEX_MAX};\n opacity:0;transition:opacity 0.25s ease;\n `;\n\n const modal = document.createElement(\"div\");\n modal.style.cssText = `\n width:340px;padding:28px;border-radius:var(--sp-radius-xl);\n background:var(--sp-identity-bg);\n backdrop-filter:blur(var(--sp-blur-heavy));\n -webkit-backdrop-filter:blur(var(--sp-blur-heavy));\n border:1px solid var(--sp-glass-border);\n box-shadow:0 16px 48px var(--sp-shadow), 0 8px 16px var(--sp-shadow);\n font-family:var(--sp-font, \"Inter\",system-ui,-apple-system,sans-serif);\n color:var(--sp-text);\n transform:translateY(12px) scale(0.97);\n transition:transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);\n -webkit-font-smoothing:antialiased;\n `;\n\n const titleId = `sp-identity-title-${Date.now()}`;\n modal.setAttribute(\"role\", \"dialog\");\n modal.setAttribute(\"aria-modal\", \"true\");\n modal.setAttribute(\"aria-labelledby\", titleId);\n\n const title = document.createElement(\"div\");\n title.className = \"sp-identity-title\";\n title.id = titleId;\n title.textContent = t(\"identity.title\");\n title.style.marginBottom = \"20px\";\n\n const nameInputId = `sp-identity-name-${Date.now()}`;\n const emailInputId = `sp-identity-email-${Date.now()}`;\n\n const nameLabel = document.createElement(\"label\");\n nameLabel.className = \"sp-input-label\";\n nameLabel.textContent = t(\"identity.nameLabel\");\n nameLabel.setAttribute(\"for\", nameInputId);\n const nameInput = document.createElement(\"input\");\n nameInput.className = \"sp-input\";\n nameInput.id = nameInputId;\n nameInput.type = \"text\";\n nameInput.placeholder = t(\"identity.namePlaceholder\");\n nameInput.style.marginBottom = \"14px\";\n\n const emailLabel = document.createElement(\"label\");\n emailLabel.className = \"sp-input-label\";\n emailLabel.textContent = t(\"identity.emailLabel\");\n emailLabel.setAttribute(\"for\", emailInputId);\n const emailInput = document.createElement(\"input\");\n emailInput.className = \"sp-input\";\n emailInput.id = emailInputId;\n emailInput.type = \"email\";\n emailInput.placeholder = t(\"identity.emailPlaceholder\");\n\n const btnRow = document.createElement(\"div\");\n btnRow.style.cssText = \"display:flex;gap:8px;justify-content:flex-end;margin-top:20px;\";\n\n const closeModal = (result: Identity | null) => {\n backdrop.removeEventListener(\"keydown\", onKeydown);\n backdrop.style.opacity = \"0\";\n modal.style.transform = \"translateY(12px) scale(0.97)\";\n setTimeout(() => {\n backdrop.remove();\n previouslyFocused?.focus();\n resolve(result);\n }, 250);\n };\n\n const cancelBtn = document.createElement(\"button\");\n cancelBtn.className = \"sp-btn-ghost\";\n cancelBtn.textContent = t(\"identity.cancel\");\n cancelBtn.addEventListener(\"click\", () => closeModal(null));\n\n const submitBtn = document.createElement(\"button\");\n submitBtn.className = \"sp-btn-primary\";\n submitBtn.textContent = t(\"identity.submit\");\n submitBtn.addEventListener(\"click\", () => {\n const name = nameInput.value.trim();\n const email = emailInput.value.trim();\n if (!name || !email) return;\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(email)) {\n emailInput.style.borderColor = \"var(--sp-type-bug, #ef4444)\";\n return;\n }\n closeModal({ name, email });\n });\n\n // Focus trap: cycle Tab/Shift+Tab within the modal\n const focusableSelectors = 'input, button, [tabindex]:not([tabindex=\"-1\"])';\n const onKeydown = (e: Event) => {\n const ke = e as KeyboardEvent;\n if (ke.key === \"Escape\") {\n closeModal(null);\n return;\n }\n if (ke.key === \"Tab\") {\n const focusableEls = Array.from(modal.querySelectorAll<HTMLElement>(focusableSelectors));\n if (focusableEls.length === 0) return;\n const first = focusableEls[0];\n const last = focusableEls[focusableEls.length - 1];\n if (!first || !last) return;\n const active = shadowRoot.activeElement as HTMLElement | null;\n if (ke.shiftKey) {\n if (active === first || !modal.contains(active)) {\n ke.preventDefault();\n last.focus();\n }\n } else {\n if (active === last || !modal.contains(active)) {\n ke.preventDefault();\n first.focus();\n }\n }\n }\n };\n backdrop.addEventListener(\"keydown\", onKeydown);\n\n // Close on backdrop click\n backdrop.addEventListener(\"click\", (e) => {\n if (e.target === backdrop) closeModal(null);\n });\n\n btnRow.appendChild(cancelBtn);\n btnRow.appendChild(submitBtn);\n\n modal.appendChild(title);\n modal.appendChild(nameLabel);\n modal.appendChild(nameInput);\n modal.appendChild(emailLabel);\n modal.appendChild(emailInput);\n modal.appendChild(btnRow);\n backdrop.appendChild(modal);\n\n shadowRoot.appendChild(backdrop);\n\n // Animate in\n requestAnimationFrame(() => {\n backdrop.style.opacity = \"1\";\n modal.style.transform = \"translateY(0) scale(1)\";\n nameInput.focus();\n });\n });\n}\n","import type { SitepingConfig, SitepingInstance } from \"@siteping/core\";\nimport { launch } from \"./launcher.js\";\n\nexport type {\n AnchorData,\n AnnotationPayload,\n AnnotationResponse,\n FeedbackPayload,\n FeedbackResponse,\n FeedbackStatus,\n FeedbackType,\n RectData,\n SitepingConfig,\n SitepingInstance,\n SitepingPublicEvents,\n SitepingStore,\n} from \"@siteping/core\";\n\nexport type { Identity } from \"./identity.js\";\n\n/**\n * Initialize the Siteping feedback widget.\n *\n * @example\n * ```ts\n * import { initSiteping } from '@siteping/widget'\n *\n * const { destroy } = initSiteping({\n * endpoint: '/api/siteping',\n * projectName: 'my-project',\n * })\n * ```\n */\nexport function initSiteping(config: SitepingConfig): SitepingInstance {\n return launch(config);\n}\n","/**\n * React helper for `@siteping/widget`.\n *\n * `useSiteping` initialises the widget once for the lifetime of the component\n * tree, even under React.StrictMode's double-invoke effect dance. Returns the\n * `SitepingInstance` so consumers can drive `open()` / `close()` / `refresh()`\n * programmatically from anywhere in their tree.\n *\n * Why a dedicated entry instead of a snippet in the README:\n * - StrictMode mounts every effect twice in dev, which the obvious\n * `useEffect(() => { const i = initSiteping(...); return i.destroy }, [])`\n * handles fine for *re-mount*, but not for the brief window where the\n * second mount sees a still-alive widget (the widget's own singleton guard\n * logs an info message and returns the existing instance — surprising\n * noise for developers).\n * - The hook also captures the latest `config` in a ref so callbacks (e.g.\n * `onFeedbackSent`) read closure values without re-initialising the widget.\n *\n * Peer dep on react ≥ 18 (declared as optional in package.json), so projects\n * that never import `@siteping/widget/react` don't need React installed.\n */\n\nimport type { SitepingConfig, SitepingInstance } from \"@siteping/core\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { initSiteping } from \"./index.js\";\n\n/**\n * Initialise the SitePing widget for the lifetime of the calling component.\n *\n * Safe to call from a Server Component file as long as the component itself\n * is marked `\"use client\"` — the hook bails out cleanly on the server because\n * `useEffect` never runs there.\n *\n * @example Next.js App Router\n * ```tsx\n * \"use client\"\n * import { useSiteping } from \"@siteping/widget/react\"\n *\n * export function FeedbackProvider({ children }: { children: React.ReactNode }) {\n * useSiteping({\n * endpoint: \"/api/siteping\",\n * projectName: \"my-app\",\n * })\n * return <>{children}</>\n * }\n * ```\n *\n * @example Driving the panel programmatically\n * ```tsx\n * \"use client\"\n * import { useSiteping } from \"@siteping/widget/react\"\n *\n * export function HelpButton() {\n * const widget = useSiteping({ endpoint: \"/api/siteping\", projectName: \"my-app\" })\n * return <button onClick={() => widget?.open()}>Need help?</button>\n * }\n * ```\n */\nexport function useSiteping(config: SitepingConfig): SitepingInstance | null {\n // Keep callbacks fresh without retriggering the init effect. The widget\n // captures the *initial* config; we mirror updated handlers via the bridge\n // below so consumers can change `onFeedbackSent` between renders without\n // tearing the widget down.\n const configRef = useRef(config);\n configRef.current = config;\n\n const [instance, setInstance] = useState<SitepingInstance | null>(null);\n\n useEffect(() => {\n // `mounted` flag deals with the StrictMode double-effect: the cleanup of\n // the first run fires between the two `init` calls, so we set the flag\n // false in cleanup and skip late state updates. The widget itself has\n // its own singleton guard, so even if we managed to call init() twice\n // in a row we'd get the same instance back.\n let mounted = true;\n const created = initSiteping(configRef.current);\n if (!mounted) {\n // Cleanup already ran (StrictMode dev edge case) — tear down to avoid\n // leaving a dangling widget in the DOM.\n created.destroy();\n return;\n }\n\n // Bridge mutable callbacks: subscribe through the widget's public event\n // bus so we can call whatever the *latest* config has set. This lets\n // hosts change `onFeedbackSent`, `onError`, etc. between renders without\n // recreating the widget.\n const unsubSent = created.on(\"feedback:sent\", (fb) => {\n configRef.current.onFeedbackSent?.(fb);\n });\n const unsubOpen = created.on(\"panel:open\", () => {\n configRef.current.onOpen?.();\n });\n const unsubClose = created.on(\"panel:close\", () => {\n configRef.current.onClose?.();\n });\n\n setInstance(created);\n\n return () => {\n mounted = false;\n unsubSent();\n unsubOpen();\n unsubClose();\n created.destroy();\n setInstance(null);\n };\n // The init effect intentionally has an empty dep array — config changes\n // are forwarded through configRef.current, not through re-init. Hosts\n // that need a fresh widget (e.g. swapping endpoint at runtime) should\n // unmount the component that owns the hook.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return instance;\n}\n"]}
|