@siteping/widget 0.9.11 → 0.9.12
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/dist/index.global.js +50 -43
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +37 -30
- package/dist/index.js.map +1 -1
- package/dist/react.js +37 -30
- package/dist/react.js.map +1 -1
- package/package.json +1 -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","../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","errorFromResponse","response","label","detail","message","SitepingAuthError","SitepingValidationError","SitepingError","networkErrorFromException","error","SitepingNetworkError","MAX_RETRIES","TIMEOUT_MS","RETRY_QUEUE_KEY","MAX_QUEUE_SIZE","resilientFetch","url","init","retries","attempt","controller","timeout","baseDelay","jitter","r","LOCK_NAME","withRetryLock","callback","readQueue","raw","parsed","queueForRetry","endpoint","payload","queue","normalizeName","normalizeEmail","flushRetryQueue","currentIdentity","toRetry","unrelated","dropped","entry","failed","remaining","parseJsonAs","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","isIdentity","hasOwn","email","getIdentity","saveIdentity","identity","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","flattenAnnotation","toResponse","total","toAnnotationResponse","ann","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","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,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;A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","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","import {\n type FeedbackPayload,\n type FeedbackResponse,\n type FeedbackResponseList,\n type FeedbackStatus,\n type FeedbackType,\n SitepingAuthError,\n SitepingError,\n SitepingNetworkError,\n SitepingValidationError,\n} from \"@siteping/core\";\nimport type { Identity } from \"./identity.js\";\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 SitepingNetworkError) return error;\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(projectName: string, options?: GetFeedbacksOptions): Promise<FeedbackResponseList>;\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\ninterface RetryEntry {\n endpoint: string;\n payload: FeedbackPayload;\n}\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 readQueue(): RetryEntry[] {\n const raw = localStorage.getItem(RETRY_QUEUE_KEY);\n if (!raw) return [];\n const parsed: unknown = JSON.parse(raw);\n return Array.isArray(parsed) ? (parsed as RetryEntry[]) : [];\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 queue = readQueue();\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\nfunction normalizeName(value: string): string {\n return value.trim();\n}\n\nfunction normalizeEmail(value: string): string {\n return value.trim().toLowerCase();\n}\n\n/**\n * Flush queued feedbacks for `endpoint`. When `currentIdentity` is provided,\n * entries whose stored author doesn't match it are dropped rather than replayed.\n * This prevents user A's offline feedback from being POSTed under user B's\n * identity after a session change. When omitted, all entries are replayed to\n * preserve the legacy behavior for callers that don't track identity.\n */\nexport async function flushRetryQueue(endpoint: string, currentIdentity?: Identity | null): Promise<void> {\n await withRetryLock(async () => {\n try {\n const queue = readQueue();\n if (queue.length === 0) return;\n\n const toRetry: RetryEntry[] = [];\n const unrelated: RetryEntry[] = [];\n let dropped = 0;\n\n for (const entry of queue) {\n if (entry.endpoint !== endpoint) {\n unrelated.push(entry);\n continue;\n }\n\n if (\n !currentIdentity ||\n (normalizeName(entry.payload.authorName) === normalizeName(currentIdentity.name) &&\n normalizeEmail(entry.payload.authorEmail) === normalizeEmail(currentIdentity.email))\n ) {\n toRetry.push(entry);\n } else {\n dropped += 1;\n }\n }\n\n if (toRetry.length === 0 && dropped === 0) return;\n\n if (dropped > 0) {\n console.debug(\"[siteping] flushRetryQueue: dropped\", dropped, \"stale entries (identity changed)\");\n }\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 = unrelated.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\n/** Parse a JSON body and assert its TypeScript shape — server-side Zod is the source of truth. */\nasync function parseJsonAs<T>(response: Response): Promise<T> {\n return (await response.json()) as T;\n}\n\nexport class ApiClient implements WidgetClient {\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 parseJsonAs<FeedbackResponse>(response);\n } catch (error) {\n queueForRetry(this.endpoint, payload);\n throw error;\n }\n }\n\n async getFeedbacks(projectName: string, options?: GetFeedbacksOptions): Promise<FeedbackResponseList> {\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 parseJsonAs<FeedbackResponseList>(response);\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 parseJsonAs<FeedbackResponse>(response);\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","import type {\n FeedbackResponse,\n SitepingPublicEventListener,\n SitepingPublicEvents,\n SitepingUnsubscribe,\n} from \"@siteping/core\";\nimport type { AnnotationComplete } from \"./annotator.js\";\n\n/** Listener signature for a single key of an `EventBus` event map. */\nexport type EventListener<E extends Record<keyof E, unknown[]>, K extends keyof E> = (...args: E[K]) => void;\n\n/**\n * Lightweight typed `EventEmitter` — zero dependencies.\n *\n * The generic constraint guarantees each event maps to a tuple of argument\n * types, so subscribers and emitters share the exact same shape.\n */\nexport class EventBus<E extends Record<keyof E, unknown[]>> {\n private readonly listeners = new Map<keyof E, Set<EventListener<E, keyof E>>>();\n\n on<K extends keyof E>(event: K, listener: EventListener<E, K>): SitepingUnsubscribe {\n let set = this.listeners.get(event);\n if (!set) {\n set = new Set();\n this.listeners.set(event, set);\n }\n set.add(listener as EventListener<E, keyof E>);\n\n return () => {\n set?.delete(listener as EventListener<E, keyof E>);\n };\n }\n\n off<K extends keyof E>(event: K, listener: EventListener<E, K>): void {\n this.listeners.get(event)?.delete(listener as EventListener<E, keyof E>);\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 as (...a: E[K]) => void)(...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\n/** Full internal event map — broader than the public surface exposed to hosts. */\nexport interface WidgetEvents {\n open: [];\n close: [];\n \"feedback:sent\": [FeedbackResponse];\n \"feedback:deleted\": [FeedbackResponse[\"id\"]];\n \"feedback:all-deleted\": [];\n \"feedback:error\": [Error];\n \"annotation:start\": [];\n \"annotation:end\": [];\n \"annotation:complete\": [AnnotationComplete];\n \"annotations:toggle\": [boolean];\n \"panel:toggle\": [boolean];\n}\n\n/**\n * Subset of `WidgetEvents` exposed to consumers via `SitepingInstance`.\n *\n * Kept structurally identical to `SitepingPublicEvents` from `@siteping/core`\n * so the launcher can bridge between the two without runtime casts. The\n * `satisfies` clause locks that contract at compile time — drift in either\n * side surfaces here.\n */\nexport type PublicWidgetEvents = SitepingPublicEvents;\n\n/** Re-export the listener signature for ergonomics on the widget side. */\nexport type PublicWidgetEventListener<K extends keyof PublicWidgetEvents> = SitepingPublicEventListener<K>;\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","import { hasOwn } from \"@siteping/core\";\n\nconst STORAGE_KEY = \"siteping_identity\";\n\nexport interface Identity {\n name: string;\n email: string;\n}\n\n/** Type guard — narrows an unknown value to `Identity` only when both fields are non-empty strings. */\nfunction isIdentity(value: unknown): value is Identity {\n if (!hasOwn(value, \"name\") || !hasOwn(value, \"email\")) return false;\n const name = (value as { name: unknown }).name;\n const email = (value as { email: unknown }).email;\n return typeof name === \"string\" && typeof email === \"string\" && name.length > 0 && email.length > 0;\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 return isIdentity(parsed) ? parsed : 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 type FeedbackResponseList,\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(projectName: string, options?: GetFeedbacksOptions): Promise<FeedbackResponseList> {\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 PageScope,\n SitepingConfig,\n SitepingInstance,\n SitepingPublicEventListener,\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 // The earlier guard guarantees one of `store` / `endpoint` is set; we\n // capture the chosen branch in a typed local so TypeScript narrows on\n // each side without resorting to a non-null assertion.\n const client: WidgetClient = (() => {\n if (config.store) return new StoreClient(config.store, config.projectName);\n const endpoint = config.endpoint;\n if (typeof endpoint !== \"string\" || endpoint.length === 0) {\n throw new Error(\"[siteping] internal invariant: endpoint must be a non-empty string in HTTP mode\");\n }\n return new ApiClient(endpoint, config.projectName);\n })();\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 }) => {\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, config.identity ?? getIdentity())\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 }) => {\n const visible = scopeAnnotationsByUrl ? feedbacks.filter((f) => f.url === scope.url) : feedbacks;\n markers.render(visible);\n })\n .catch(() => {});\n },\n // `PublicWidgetEvents` is a structural alias of `SitepingPublicEvents`, so\n // these on/off forwarders compose without any runtime cast.\n on: <K extends keyof SitepingPublicEvents>(event: K, listener: SitepingPublicEventListener<K>) =>\n publicBus.on(event, listener),\n off: <K extends keyof SitepingPublicEvents>(event: K, listener: SitepingPublicEventListener<K>) => {\n publicBus.off(event, listener);\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","../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","TYPE_LABEL_KEYS","isMacPlatform","uaData","Popup","colors","t","typeOptions","ICON_QUESTION","ICON_CHANGE","ICON_BUG","ICON_OTHER","option","btn","icon","parseSvg","bgColor","getTypeBgColor","getTypeColor","e","btnRow","typeButtons","type","key","labelSpan","setText","rectBounds","onSubmit","resolve","popupH","popupW","top","left","aboveTop","focusableEls","first","last","reduceMotion","container","buttons","isActive","color","enabled","result","submitter","spinner","cachedHtml2Canvas","warnedAboutMissingDep","loadHtml2Canvas","mod","err","captureScreenshot","html2canvas","quality","maxWidth","canvas","ratio","targetW","targetH","scaled","ctx","Annotator","bus","enableScreenshot","dot","style","instruction","cancelBtn","target","bounds","annotation","screenshotCache","formResult","touch","clientX","clientY","source","evt","x","y","w","h","screenshotDataUrl","reject","cleanup","unsubSent","unsubError","unsubCancelled","reason","anchorElement","anchor","errorFromResponse","response","label","detail","message","SitepingAuthError","SitepingValidationError","SitepingError","networkErrorFromException","error","SitepingNetworkError","MAX_RETRIES","TIMEOUT_MS","RETRY_QUEUE_KEY","MAX_QUEUE_SIZE","resilientFetch","url","init","retries","attempt","controller","timeout","baseDelay","jitter","r","LOCK_NAME","withRetryLock","callback","readQueue","raw","parsed","queueForRetry","endpoint","payload","queue","normalizeName","normalizeEmail","flushRetryQueue","currentIdentity","toRetry","unrelated","dropped","entry","failed","remaining","parseJsonAs","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","ITEM_LABEL_KEYS","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","isIdentity","hasOwn","email","getIdentity","saveIdentity","identity","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","openCount","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","flattenAnnotation","toResponse","total","toAnnotationResponse","ann","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","localeReady","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","focusableSelectors","ke","active","initSiteping","useSiteping","configRef","useRef","setInstance","useState","useEffect","mounted","created","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,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,EAuStB0S,EAAa;AAAA,IAAA,EACbG,GAAS;AAAA,IAAA,EACTC,CAAQ;AAAA,IAAA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","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, Translations } 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\n// Map each feedback type to its translation key, so `refreshLabels()` can\n// re-localize the existing type buttons without re-rendering the popup.\nconst TYPE_LABEL_KEYS: Record<FeedbackType, keyof Translations> = {\n question: \"type.question\",\n change: \"type.change\",\n bug: \"type.bug\",\n other: \"type.other\",\n};\n\n/**\n * Detect whether the host platform uses ⌘+Enter (macOS) vs Ctrl+Enter.\n * Resolved at call time so we can recompute the popup hint when the locale\n * dictionary lands.\n */\nfunction isMacPlatform(): boolean {\n const uaData = (navigator as Navigator & { userAgentData?: { platform?: string } }).userAgentData;\n return uaData\n ? uaData.platform === \"macOS\"\n : (navigator.platform?.includes(\"Mac\") ?? /Macintosh|Mac OS X/i.test(navigator.userAgent));\n}\n\ninterface PopupResult {\n type: FeedbackType;\n message: string;\n}\n\ninterface TypeOption {\n type: FeedbackType;\n icon: string;\n}\n\n/**\n * Optional async hook called when the user clicks \"Send\". While the returned\n * promise is pending the popup stays visible in a submitting state (spinner\n * on the submit button, every other control disabled). On resolution the\n * popup closes and `show()` resolves with the submitted result; on rejection\n * the popup restores so the user can retry without re-entering the form.\n */\ntype PopupSubmitHandler = (result: PopupResult) => Promise<void>;\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 cancelBtn: HTMLButtonElement;\n private typeRow: HTMLElement;\n private submitLabel: HTMLSpanElement;\n private hint: HTMLElement;\n private resolve: ((result: PopupResult | null) => void) | null = null;\n private previouslyFocused: HTMLElement | null = null;\n private onKeydownTrap: ((e: KeyboardEvent) => void) | null = null;\n private onSubmit: PopupSubmitHandler | null = null;\n private submittingState = false;\n /** WAAPI handle for the running spinner — cancelled when submitting ends. */\n private spinnerAnimation: Animation | 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 // Screenshot capture now runs while the popup is still visible (so the\n // spinner can show during the upload). Without this attribute the popup\n // would appear baked into the captured JPEG.\n this.root.setAttribute(\"data-siteping-ignore\", \"true\");\n // The dialog `aria-label` is bound by `applyLabels()` at the end of the\n // constructor, alongside every other `t()`-derived string.\n\n // Type selector grid (2x2). Labels are bound later by `applyLabels()` —\n // the constructor only builds the structure (icon + empty label span).\n const typeOptions: TypeOption[] = [\n { type: \"question\", icon: ICON_QUESTION },\n { type: \"change\", icon: ICON_CHANGE },\n { type: \"bug\", icon: ICON_BUG },\n { type: \"other\", icon: ICON_OTHER },\n ];\n this.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 btn.appendChild(document.createElement(\"span\"));\n btn.dataset.type = option.type;\n btn.setAttribute(\"aria-pressed\", \"false\");\n\n btn.addEventListener(\"click\", () => {\n if (this.submittingState) return;\n this.selectType(option.type, this.typeRow);\n });\n\n btn.addEventListener(\"mouseenter\", () => {\n if (this.submittingState) return;\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 (this.submittingState) return;\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 this.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.maxLength = 5000;\n\n // Keyboard shortcut hint\n this.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\n this.textarea.addEventListener(\"focus\", () => {\n if (this.submittingState) return;\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 if (this.submittingState) return;\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 (this.submittingState) return;\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 this.cancelBtn = document.createElement(\"button\");\n this.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 this.cancelBtn.addEventListener(\"click\", () => this.cancel());\n this.cancelBtn.addEventListener(\"mouseenter\", () => {\n if (this.submittingState) return;\n this.cancelBtn.style.borderColor = this.colors.accent;\n this.cancelBtn.style.color = this.colors.accent;\n });\n this.cancelBtn.addEventListener(\"mouseleave\", () => {\n if (this.submittingState) return;\n this.cancelBtn.style.borderColor = this.colors.border;\n this.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 display:inline-flex;align-items:center;justify-content:center;min-width:64px;\n `;\n // The submit label lives in its own <span> so the submitting-state spinner\n // can be appended/removed without disturbing it. `applyLabels()` binds its\n // text — never `setText` the button itself or it would wipe the spinner.\n this.submitLabel = document.createElement(\"span\");\n this.submitBtn.appendChild(this.submitLabel);\n this.submitBtn.addEventListener(\"click\", () => this.submit());\n\n btnRow.appendChild(this.cancelBtn);\n btnRow.appendChild(this.submitBtn);\n\n this.root.appendChild(this.typeRow);\n this.root.appendChild(this.textarea);\n this.root.appendChild(this.hint);\n this.root.appendChild(btnRow);\n document.body.appendChild(this.root);\n\n // Bind every `t()`-derived string into the freshly-built DOM. Kept as a\n // single pass so the constructor and `refreshLabels()` never drift.\n this.applyLabels();\n }\n\n /**\n * Re-read every `t(...)`-derived label, placeholder, and aria-label from\n * the active translation function. Idempotent — call after the locale\n * dictionary has finished loading so the popup swaps from the English\n * fallback to the configured language.\n */\n refreshLabels(): void {\n this.applyLabels();\n }\n\n /**\n * Walk the already-built DOM and bind every translation-derived string —\n * the dialog `aria-label`, the four type-button labels, the textarea\n * `placeholder` + `aria-label`, the `⌘+Enter` / `Ctrl+Enter` hint, and the\n * cancel/submit `textContent`. The single source of truth for which node\n * gets which `t()` string, shared by the constructor and `refreshLabels()`\n * so the two can never drift.\n */\n private applyLabels(): void {\n this.root.setAttribute(\"aria-label\", this.t(\"popup.ariaLabel\"));\n\n const typeButtons = this.root.querySelectorAll<HTMLButtonElement>(\"button[data-type]\");\n for (const btn of typeButtons) {\n const type = btn.dataset.type as FeedbackType | undefined;\n if (!type) continue;\n const key = TYPE_LABEL_KEYS[type];\n if (!key) continue;\n const labelSpan = btn.querySelector<HTMLSpanElement>(\"span\");\n if (labelSpan) setText(labelSpan, this.t(key));\n }\n\n this.textarea.placeholder = this.t(\"popup.placeholder\");\n this.textarea.setAttribute(\"aria-label\", this.t(\"popup.textareaAria\"));\n\n setText(this.hint, isMacPlatform() ? this.t(\"popup.submitHintMac\") : this.t(\"popup.submitHintOther\"));\n setText(this.cancelBtn, this.t(\"popup.cancel\"));\n // Target the label <span>, not the button — the button also hosts the\n // submitting-state spinner, which `setText` on the button would erase.\n setText(this.submitLabel, this.t(\"popup.submit\"));\n }\n\n /**\n * Show the popup near a drawn rectangle and return the user's input.\n * Returns null if cancelled.\n *\n * When `onSubmit` is provided the popup stays visible while the handler\n * runs — the submit button shows a spinner, every other control is\n * disabled. On success the popup closes; on rejection it restores so the\n * user can retry without re-entering the form.\n */\n show(rectBounds: DOMRect, onSubmit?: PopupSubmitHandler): Promise<PopupResult | null> {\n return new Promise((resolve) => {\n this.resolve = resolve;\n this.onSubmit = onSubmit ?? null;\n this.selectedType = null;\n this.textarea.value = \"\";\n this.submittingState = false;\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:not([disabled]), input:not([disabled]), [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.disabled = 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 btn.style.cursor = \"pointer\";\n }\n }\n\n private updateSubmitState(): void {\n if (this.submittingState) return;\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.submittingState) return;\n if (!this.selectedType || !this.textarea.value.trim()) return;\n\n const result: PopupResult = { type: this.selectedType, message: this.textarea.value.trim() };\n\n if (!this.onSubmit) {\n // Legacy fire-and-forget path: resolve immediately and hide.\n this.resolve?.(result);\n this.resolve = null;\n this.hideElement();\n return;\n }\n\n this.enterSubmittingState();\n const submitter = this.onSubmit;\n submitter(result)\n .then(() => {\n this.resolve?.(result);\n this.resolve = null;\n this.hideElement();\n })\n .catch(() => {\n // Restore the form so the user can edit and retry. The caller is\n // responsible for surfacing the error (live region / toast) — we\n // intentionally do not show inline error text in the popup.\n this.exitSubmittingState();\n });\n }\n\n private cancel(): void {\n if (this.submittingState) return;\n this.resolve?.(null);\n this.resolve = null;\n this.hideElement();\n }\n\n /**\n * Swap the submit button's text for a spinner and freeze every other\n * control. Mirrors the panel's resolve/delete buttons (`sp-spinner--sm`)\n * but renders inline because the popup lives outside the Shadow DOM\n * and therefore can't reach the panel's CSS classes.\n */\n private enterSubmittingState(): void {\n this.submittingState = true;\n\n // Submit: spinner instead of text, keep button width stable\n this.submitLabel.style.display = \"none\";\n this.submitBtn.disabled = true;\n this.submitBtn.style.cursor = \"wait\";\n this.submitBtn.style.opacity = \"0.85\";\n this.submitBtn.setAttribute(\"aria-busy\", \"true\");\n this.submitBtn.appendChild(this.buildSpinner());\n\n // Cancel: dimmed and non-interactive — abandoning mid-upload would leak a\n // half-sent feedback on the server, so we hold the user until we know.\n this.cancelBtn.disabled = true;\n this.cancelBtn.style.opacity = \"0.5\";\n this.cancelBtn.style.cursor = \"not-allowed\";\n this.cancelBtn.style.pointerEvents = \"none\";\n\n // Textarea + type buttons: read-only\n this.textarea.disabled = true;\n this.textarea.style.opacity = \"0.6\";\n const typeButtons = this.typeRow.querySelectorAll<HTMLButtonElement>(\"button\");\n for (const btn of typeButtons) {\n btn.disabled = true;\n btn.style.cursor = \"not-allowed\";\n btn.style.opacity = \"0.6\";\n }\n }\n\n private exitSubmittingState(): void {\n this.submittingState = false;\n\n // Submit — tear down the spinner: cancel the WAAPI animation explicitly\n // (it has `iterations: Infinity`, so it never ends on its own) before\n // removing the element it drives.\n this.spinnerAnimation?.cancel();\n this.spinnerAnimation = null;\n const spinner = this.submitBtn.querySelector<HTMLDivElement>('[data-role=\"sp-popup-spinner\"]');\n spinner?.remove();\n this.submitLabel.style.display = \"\";\n this.submitBtn.removeAttribute(\"aria-busy\");\n this.submitBtn.style.cursor = \"pointer\";\n\n // Cancel\n this.cancelBtn.disabled = false;\n this.cancelBtn.style.opacity = \"1\";\n this.cancelBtn.style.cursor = \"pointer\";\n this.cancelBtn.style.pointerEvents = \"auto\";\n\n // Textarea + type buttons\n this.textarea.disabled = false;\n this.textarea.style.opacity = \"1\";\n const typeButtons = this.typeRow.querySelectorAll<HTMLButtonElement>(\"button\");\n for (const btn of typeButtons) {\n btn.disabled = false;\n btn.style.cursor = \"pointer\";\n btn.style.opacity = \"1\";\n }\n\n // Recompute submit enabled state from the (preserved) form fields\n this.updateSubmitState();\n }\n\n /**\n * Build a spinner element styled inline. Web Animations API drives the\n * rotation so we don't have to inject `@keyframes` into the host document.\n * Respects `prefers-reduced-motion`: omits the animation and falls back to\n * a static ring. The returned `Animation` handle is stored on the instance\n * so `exitSubmittingState()` can explicitly cancel it.\n */\n private buildSpinner(): HTMLDivElement {\n const spinner = document.createElement(\"div\");\n spinner.dataset.role = \"sp-popup-spinner\";\n spinner.style.cssText = `\n width:14px;height:14px;\n border:2px solid rgba(255,255,255,0.35);\n border-top-color:#fff;\n border-radius:50%;\n box-sizing:border-box;\n `;\n const reduceMotion =\n typeof window !== \"undefined\" &&\n typeof window.matchMedia === \"function\" &&\n window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n // Web Animations API is available in every browser we target; the guard\n // is defensive for jsdom in tests, where `animate` may be undefined.\n if (!reduceMotion && typeof spinner.animate === \"function\") {\n this.spinnerAnimation = spinner.animate([{ transform: \"rotate(0deg)\" }, { transform: \"rotate(360deg)\" }], {\n duration: 600,\n iterations: Infinity,\n easing: \"linear\",\n });\n }\n return spinner;\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 // Make sure the submitting decoration doesn't leak into the next show()\n if (this.submittingState) this.exitSubmittingState();\n this.onSubmit = null;\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 // Settle a pending `show()` promise so it cannot outlive teardown — a\n // `destroy()` mid-submit would otherwise leak the awaiting closure (and\n // whatever it retains: the annotation, the base64 screenshot). Resolving\n // with `null` reads as \"cancelled\", matching `cancel()`.\n if (this.submittingState) this.exitSubmittingState();\n this.resolve?.(null);\n this.resolve = null;\n this.onSubmit = null;\n if (this.onKeydownTrap) {\n this.root.removeEventListener(\"keydown\", this.onKeydownTrap);\n this.onKeydownTrap = null;\n }\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 * Reject handle for the in-flight `runSubmission` promise, or null when no\n * submission is pending. Serves two purposes: a non-null value means a\n * submission is in flight (so pointer-driven drawing is suppressed — the\n * popup is open), and `destroy()` calls it to settle the promise rather\n * than leaving the awaiting closure hung past teardown.\n */\n private rejectPendingSubmission: ((reason: Error) => void) | 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 * Re-read every `t(...)`-derived label inside the popup. The annotator's\n * own toolbar text is created fresh on every `activate()` call, so only\n * the long-lived popup needs explicit re-localization here.\n */\n refreshLabels(): void {\n this.popup.refreshLabels();\n }\n\n /**\n * True while a submission is in flight (popup open, `runSubmission`\n * pending). Drawing a second rectangle in this window would orphan the\n * first `popup.show()` promise and start a second, concurrent\n * `runSubmission` — so all drawing entry points are no-ops while it holds.\n */\n private get submissionInFlight(): boolean {\n return this.rejectPendingSubmission !== null;\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 // A submission is already running with the popup open — ignore so we\n // can't orphan the first `popup.show()` / `runSubmission` pair.\n if (this.submissionInFlight) return;\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 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 // Submission stays inside the popup so the user gets a visible spinner\n // until the server confirms — see finishDrawing for the rationale.\n const screenshotCache: { value?: string | null } = {};\n const result = await this.popup.show(rectBounds, (formResult) =>\n this.runSubmission(annotation, formResult, rectBounds, screenshotCache),\n );\n\n if (result) this.deactivate();\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 // Suppress pointer-driven drawing while a submission is in flight: the\n // popup is open over the page, and starting a second rectangle would\n // orphan the first `popup.show()` promise (and its `runSubmission`).\n // This also closes a latent bug where drawing during the open popup\n // already overwrote `Popup.resolve`.\n if (this.submissionInFlight) return;\n\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 // Build annotation payload BEFORE the popup opens — the overlay is still\n // up so `findAnchorElement` can briefly disable pointer events on it.\n const annotation = this.buildAnnotation(rectBounds);\n\n // Keep the drawn rectangle visible while the popup is open so the user\n // can see what they're sending feedback about — including while the\n // submit-spinner is running. We only remove it after the popup closes.\n const screenshotCache: { value?: string | null } = {};\n const result = await this.popup.show(rectBounds, (formResult) =>\n this.runSubmission(annotation, formResult, rectBounds, screenshotCache),\n );\n\n this.drawingRect?.remove();\n this.drawingRect = null;\n if (result) this.deactivate();\n };\n\n /**\n * Submit handler passed into `popup.show()`. Captures the screenshot once\n * (cached across retries) and emits `annotation:complete` on the bus, then\n * waits for one of three terminal signals:\n *\n * - `feedback:sent` — resolve (popup closes).\n * - `feedback:error` — reject with the genuine error (popup restores for\n * retry; the launcher surfaces the error to the host).\n * - `submission:cancelled` — reject as a silent abort (popup restores; no\n * error is surfaced — e.g. the user cancelled the identity prompt).\n *\n * Submissions are serialized by the drawing guards (`submissionInFlight`),\n * so exactly one `runSubmission` is ever live — the global outcome events\n * cannot cross-wire between submissions and need no correlation id.\n */\n private async runSubmission(\n annotation: AnnotationPayload,\n formResult: { type: FeedbackType; message: string },\n rectBounds: DOMRect,\n screenshotCache: { value?: string | null },\n ): Promise<void> {\n // Screenshot capture is the slow part. Capture once and reuse the\n // cached data URL on every retry — re-running html2canvas after each\n // failed submit would punish the user for a network blip.\n if (screenshotCache.value === undefined) {\n screenshotCache.value = await this.maybeCapture(rectBounds);\n }\n const screenshotDataUrl = screenshotCache.value;\n\n await new Promise<void>((resolve, reject) => {\n const cleanup = () => {\n unsubSent();\n unsubError();\n unsubCancelled();\n this.rejectPendingSubmission = null;\n };\n const unsubSent = this.bus.on(\"feedback:sent\", () => {\n cleanup();\n resolve();\n });\n const unsubError = this.bus.on(\"feedback:error\", (err) => {\n cleanup();\n reject(err);\n });\n const unsubCancelled = this.bus.on(\"submission:cancelled\", () => {\n cleanup();\n // Silent abort — the popup restores but no error is surfaced.\n reject(new Error(\"Feedback submission cancelled\"));\n });\n\n // Expose the reject handle so `destroy()` mid-submit can settle this\n // promise instead of leaving the awaiting closure hung past teardown.\n this.rejectPendingSubmission = (reason) => {\n cleanup();\n reject(reason);\n };\n\n this.bus.emit(\"annotation:complete\", {\n annotation,\n type: formResult.type,\n message: formResult.message,\n screenshotDataUrl,\n });\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 // Settle an in-flight submission BEFORE tearing down the popup, so the\n // `runSubmission` promise cannot outlive teardown. The launcher's\n // `destroy()` also calls `bus.removeAll()`, which would otherwise strip\n // the terminal-event listeners and leave the promise — and the base64\n // screenshot it retains — hung forever.\n this.rejectPendingSubmission?.(new Error(\"Annotator destroyed during submission\"));\n this.popup.destroy();\n }\n}\n","import {\n type FeedbackPayload,\n type FeedbackResponse,\n type FeedbackResponseList,\n type FeedbackStatus,\n type FeedbackType,\n SitepingAuthError,\n SitepingError,\n SitepingNetworkError,\n SitepingValidationError,\n} from \"@siteping/core\";\nimport type { Identity } from \"./identity.js\";\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 SitepingNetworkError) return error;\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(projectName: string, options?: GetFeedbacksOptions): Promise<FeedbackResponseList>;\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\ninterface RetryEntry {\n endpoint: string;\n payload: FeedbackPayload;\n}\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 readQueue(): RetryEntry[] {\n const raw = localStorage.getItem(RETRY_QUEUE_KEY);\n if (!raw) return [];\n const parsed: unknown = JSON.parse(raw);\n return Array.isArray(parsed) ? (parsed as RetryEntry[]) : [];\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 queue = readQueue();\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\nfunction normalizeName(value: string): string {\n return value.trim();\n}\n\nfunction normalizeEmail(value: string): string {\n return value.trim().toLowerCase();\n}\n\n/**\n * Flush queued feedbacks for `endpoint`. When `currentIdentity` is provided,\n * entries whose stored author doesn't match it are dropped rather than replayed.\n * This prevents user A's offline feedback from being POSTed under user B's\n * identity after a session change. When omitted, all entries are replayed to\n * preserve the legacy behavior for callers that don't track identity.\n */\nexport async function flushRetryQueue(endpoint: string, currentIdentity?: Identity | null): Promise<void> {\n await withRetryLock(async () => {\n try {\n const queue = readQueue();\n if (queue.length === 0) return;\n\n const toRetry: RetryEntry[] = [];\n const unrelated: RetryEntry[] = [];\n let dropped = 0;\n\n for (const entry of queue) {\n if (entry.endpoint !== endpoint) {\n unrelated.push(entry);\n continue;\n }\n\n if (\n !currentIdentity ||\n (normalizeName(entry.payload.authorName) === normalizeName(currentIdentity.name) &&\n normalizeEmail(entry.payload.authorEmail) === normalizeEmail(currentIdentity.email))\n ) {\n toRetry.push(entry);\n } else {\n dropped += 1;\n }\n }\n\n if (toRetry.length === 0 && dropped === 0) return;\n\n if (dropped > 0) {\n console.debug(\"[siteping] flushRetryQueue: dropped\", dropped, \"stale entries (identity changed)\");\n }\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 = unrelated.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\n/** Parse a JSON body and assert its TypeScript shape — server-side Zod is the source of truth. */\nasync function parseJsonAs<T>(response: Response): Promise<T> {\n return (await response.json()) as T;\n}\n\nexport class ApiClient implements WidgetClient {\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 parseJsonAs<FeedbackResponse>(response);\n } catch (error) {\n queueForRetry(this.endpoint, payload);\n throw error;\n }\n }\n\n async getFeedbacks(projectName: string, options?: GetFeedbacksOptions): Promise<FeedbackResponseList> {\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 parseJsonAs<FeedbackResponseList>(response);\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 parseJsonAs<FeedbackResponse>(response);\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","import type {\n FeedbackResponse,\n SitepingPublicEventListener,\n SitepingPublicEvents,\n SitepingUnsubscribe,\n} from \"@siteping/core\";\nimport type { AnnotationComplete } from \"./annotator.js\";\n\n/** Listener signature for a single key of an `EventBus` event map. */\nexport type EventListener<E extends Record<keyof E, unknown[]>, K extends keyof E> = (...args: E[K]) => void;\n\n/**\n * Lightweight typed `EventEmitter` — zero dependencies.\n *\n * The generic constraint guarantees each event maps to a tuple of argument\n * types, so subscribers and emitters share the exact same shape.\n */\nexport class EventBus<E extends Record<keyof E, unknown[]>> {\n private readonly listeners = new Map<keyof E, Set<EventListener<E, keyof E>>>();\n\n on<K extends keyof E>(event: K, listener: EventListener<E, K>): SitepingUnsubscribe {\n let set = this.listeners.get(event);\n if (!set) {\n set = new Set();\n this.listeners.set(event, set);\n }\n set.add(listener as EventListener<E, keyof E>);\n\n return () => {\n set?.delete(listener as EventListener<E, keyof E>);\n };\n }\n\n off<K extends keyof E>(event: K, listener: EventListener<E, K>): void {\n this.listeners.get(event)?.delete(listener as EventListener<E, keyof E>);\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 as (...a: E[K]) => void)(...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\n/** Full internal event map — broader than the public surface exposed to hosts. */\nexport interface WidgetEvents {\n open: [];\n close: [];\n \"feedback:sent\": [FeedbackResponse];\n \"feedback:deleted\": [FeedbackResponse[\"id\"]];\n \"feedback:all-deleted\": [];\n \"feedback:error\": [Error];\n /** Emitted whenever the marker set changes — payload is the open (unresolved) count for the current page. */\n \"markers:changed\": [number];\n \"annotation:start\": [];\n \"annotation:end\": [];\n \"annotation:complete\": [AnnotationComplete];\n /**\n * Internal-only: a feedback submission was aborted by a benign user action\n * (e.g. cancelling the identity prompt). Distinct from `feedback:error` so a\n * cancellation does not surface through the host's `onError` callback. Not\n * part of `PublicWidgetEvents` — never exposed to consumers.\n */\n \"submission:cancelled\": [];\n \"annotations:toggle\": [boolean];\n \"panel:toggle\": [boolean];\n}\n\n/**\n * Subset of `WidgetEvents` exposed to consumers via `SitepingInstance`.\n *\n * Kept structurally identical to `SitepingPublicEvents` from `@siteping/core`\n * so the launcher can bridge between the two without runtime casts. The\n * `satisfies` clause locks that contract at compile time — drift in either\n * side surfaces here.\n */\nexport type PublicWidgetEvents = SitepingPublicEvents;\n\n/** Re-export the listener signature for ergonomics on the widget side. */\nexport type PublicWidgetEventListener<K extends keyof PublicWidgetEvents> = SitepingPublicEventListener<K>;\n","import type { SitepingConfig } from \"@siteping/core\";\nimport { parseSvg, setText } from \"./dom-utils.js\";\nimport type { EventBus, WidgetEvents } from \"./events.js\";\nimport type { TFunction, Translations } from \"./i18n/index.js\";\nimport { ICON_ANNOTATE, ICON_CHAT, ICON_CLOSE, ICON_EYE, ICON_EYE_OFF, ICON_SITEPING } from \"./icons.js\";\n\n/** Closed set of radial menu item ids — keeps the label lookup exhaustive. */\ntype RadialItemId = \"chat\" | \"annotate\" | \"toggle-annotations\";\n\ninterface RadialItem {\n id: RadialItemId;\n icon: string;\n iconAlt?: string;\n}\n\nconst ITEM_GAP = 54;\n\n// Stable mapping between radial item ids and their translation keys. The\n// label is fully derived from this map via `t()`, so the constructor and\n// `applyLabels()` share one source of truth for which node gets which string.\nconst ITEM_LABEL_KEYS: Record<RadialItemId, keyof Translations> = {\n chat: \"fab.messages\",\n annotate: \"fab.annotate\",\n \"toggle-annotations\": \"fab.annotations\",\n};\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 },\n { id: \"annotate\", icon: ICON_ANNOTATE },\n { id: \"toggle-annotations\", icon: ICON_EYE, iconAlt: ICON_EYE_OFF },\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-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.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.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 // Bind every `t()`-derived string into the freshly-built DOM. Kept as a\n // single pass so the constructor and `refreshLabels()` never drift.\n this.applyLabels();\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 /**\n * Re-read every `t(...)`-derived label and aria-label from the active\n * translation function. Idempotent — call after the locale dictionary has\n * finished loading so the FAB labels swap from the English fallback to the\n * configured language.\n */\n refreshLabels(): void {\n this.applyLabels();\n }\n\n /**\n * Walk the already-built DOM and bind every translation-derived string —\n * the FAB `aria-label`, each radial item's `aria-label`, and each\n * `.sp-radial-label` `textContent`. The single source of truth for which\n * node gets which `t()` string, shared by the constructor and\n * `refreshLabels()` so the two can never drift.\n */\n private applyLabels(): void {\n this.fab.setAttribute(\"aria-label\", this.t(\"fab.aria\"));\n\n const buttons = this.radialContainer.querySelectorAll<HTMLButtonElement>(\".sp-radial-item\");\n for (const btn of buttons) {\n const id = btn.dataset.itemId as RadialItemId | undefined;\n if (!id) continue;\n const key = ITEM_LABEL_KEYS[id];\n if (!key) continue;\n const label = this.t(key);\n btn.setAttribute(\"aria-label\", label);\n const labelSpan = btn.querySelector<HTMLSpanElement>(\".sp-radial-label\");\n if (labelSpan) setText(labelSpan, label);\n }\n }\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: RadialItemId): 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","import { hasOwn } from \"@siteping/core\";\n\nconst STORAGE_KEY = \"siteping_identity\";\n\nexport interface Identity {\n name: string;\n email: string;\n}\n\n/** Type guard — narrows an unknown value to `Identity` only when both fields are non-empty strings. */\nfunction isIdentity(value: unknown): value is Identity {\n if (!hasOwn(value, \"name\") || !hasOwn(value, \"email\")) return false;\n const name = (value as { name: unknown }).name;\n const email = (value as { email: unknown }).email;\n return typeof name === \"string\" && typeof email === \"string\" && name.length > 0 && email.length > 0;\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 return isIdentity(parsed) ? parsed : 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 /** Last `openCount` broadcast via `markers:changed` (-1 = never emitted). */\n private lastOpenCount = -1;\n\n get count(): number {\n return this.entries.length;\n }\n\n get openCount(): number {\n let count = 0;\n for (const entry of this.entries) {\n if (entry.feedback.status === \"open\") count++;\n }\n return count;\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 /**\n * Emit `markers:changed` only when the open count actually moved.\n *\n * Mutations that re-render the same set (panel search keystrokes, filter\n * toggles, \"load more\") all call `render()` without changing the page's\n * open count — emitting unconditionally would rebuild the FAB badge DOM on\n * every keystroke. The `-1` sentinel guarantees the first render still\n * emits, even when the page has zero open feedbacks.\n */\n private emitMarkersChanged(): void {\n const openCount = this.openCount;\n if (openCount === this.lastOpenCount) return;\n this.lastOpenCount = openCount;\n this.bus.emit(\"markers:changed\", openCount);\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 this.emitMarkersChanged();\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 this.emitMarkersChanged();\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 type FeedbackResponseList,\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(projectName: string, options?: GetFeedbacksOptions): Promise<FeedbackResponseList> {\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 PageScope,\n SitepingConfig,\n SitepingInstance,\n SitepingPublicEventListener,\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. English is bundled synchronously\n // and used as the fallback while the chunk is in flight. The launcher\n // awaits `localeReady` before rendering markers and re-localizes the FAB\n // and popup once the dictionary lands — both are mounted synchronously so\n // the widget is interactive immediately, but their labels start in the\n // English fallback until the chunk arrives.\n const localeReady: Promise<unknown> =\n locale === \"en\"\n ? Promise.resolve()\n : loadLocale(locale).catch(() => {\n /* fallback to English — already handled by createT */\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 // The earlier guard guarantees one of `store` / `endpoint` is set; we\n // capture the chosen branch in a typed local so TypeScript narrows on\n // each side without resorting to a non-null assertion.\n const client: WidgetClient = (() => {\n if (config.store) return new StoreClient(config.store, config.projectName);\n const endpoint = config.endpoint;\n if (typeof endpoint !== \"string\" || endpoint.length === 0) {\n throw new Error(\"[siteping] internal invariant: endpoint must be a non-empty string in HTTP mode\");\n }\n return new ApiClient(endpoint, config.projectName);\n })();\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 // Keep the FAB unread-count badge in sync with the visible markers. Marker\n // mutations (initial render, addFeedback after submit, panel-driven resolve /\n // delete / bulk-delete via re-render) all emit `markers:changed`, so a single\n // listener covers every path that can change the open count.\n bus.on(\"markers:changed\", (openCount) => fab.updateBadge(openCount));\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 // Once the locale dictionary lands, swap the FAB + popup labels from the\n // English fallback to the configured language. `t` already resolves to the\n // loaded dictionary at call time, so the markers list rendered below (which\n // calls `t` lazily) only needs to wait on `localeReady` once.\n if (locale !== \"en\") {\n localeReady.then(() => {\n if (destroyed) return;\n fab.refreshLabels();\n annotator.refreshLabels();\n });\n }\n\n // Handle annotation completion via event bus (not DOM events).\n // Concurrency guard: a second `annotation:complete` while one is still in\n // flight must not start a duplicate submission. The Annotator already\n // serializes its own submissions (no second annotation can be drawn while\n // the popup is open), so this is defence-in-depth — but it must not *silently*\n // drop the event: a dropped event would leave any waiting `runSubmission`\n // listener hung forever. We emit `submission:cancelled` so the waiter\n // unblocks as a benign abort (the popup restores, `onError` is not called).\n let submitting = false;\n const unsubAnnotation = bus.on(\"annotation:complete\", async (data) => {\n if (submitting) {\n bus.emit(\"submission:cancelled\");\n return;\n }\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) {\n // User cancelled the identity prompt. Emit `submission:cancelled`\n // (not `feedback:error`) so the popup's pending submit handler\n // unblocks and restores the form — cancelling a prompt is a benign\n // user action, so `config.onError` must not fire for it.\n bus.emit(\"submission:cancelled\");\n return;\n }\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 // Render markers only once both the feedbacks and the locale dictionary are\n // ready. Marker aria-labels are built via `t(...)` at render time — without\n // this `Promise.all`, a fast HTTP response could outrun a slow locale chunk\n // and freeze marker labels in the English fallback for non-English locales.\n Promise.all([client.getFeedbacks(config.projectName, initialOptions), localeReady])\n .then(([{ feedbacks }]) => {\n if (destroyed) return;\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, config.identity ?? getIdentity())\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 }) => {\n const visible = scopeAnnotationsByUrl ? feedbacks.filter((f) => f.url === scope.url) : feedbacks;\n markers.render(visible);\n })\n .catch(() => {});\n },\n // `PublicWidgetEvents` is a structural alias of `SitepingPublicEvents`, so\n // these on/off forwarders compose without any runtime cast.\n on: <K extends keyof SitepingPublicEvents>(event: K, listener: SitepingPublicEventListener<K>) =>\n publicBus.on(event, listener),\n off: <K extends keyof SitepingPublicEvents>(event: K, listener: SitepingPublicEventListener<K>) => {\n publicBus.off(event, listener);\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"]}
|