@unnoodle/browser 0.1.0 → 0.1.1

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.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../node_modules/.pnpm/fuse.js@7.1.0/node_modules/fuse.js/dist/fuse.mjs","../src/api/http.ts","../src/api/widget.ts","../src/api/auth.ts","../src/api/glossary.ts","../src/api/memories.ts","../src/api/clarifications.ts","../src/features/memory/elementSnapshot.ts","../src/features/memory/elementPicker.ts","../src/features/memory/overlayArrow.ts","../src/features/memory/captureOrchestrator.ts","../src/features/memory/captureModeController.ts","../src/ui/safeCSS.ts","../src/ui/button.ts","../src/ui/panel/styles.ts","../src/ui/panel/views/loginView.ts","../src/ui/panel/utils.ts","../src/ui/panel/views/clarificationView.ts","../src/ui/panel/views/captureView.ts","../src/ui/captureForm.ts","../src/ui/stateChangeBanner.ts","../src/ui/listViews.ts","../src/ui/panel/panelLayout.ts","../src/ui/panel/views/homeView.ts","../src/ui/panel.ts","../src/ui/rail/railStyles.ts","../src/ui/rail/railIdentity.ts","../src/ui/rail/railCoreActions.ts","../src/ui/rail/railAuth.ts","../src/ui/rail/rail.ts","../src/ui/mount.ts","../src/ui/highlighter.ts","../src/ui/termSuggester.ts","../src/widget/widgetController.ts","../src/features/memory/stateWatcher.ts","../src/features/memory/meaningInference.ts","../src/features/memory/liveRenderer.ts","../src/features/memory/memoryDetailController.ts","../src/index.ts"],"names":["isArray","value","getTag","baseToString","result","toString","isString","isNumber","isBoolean","isObjectLike","isObject","isDefined","isBlank","INCORRECT_INDEX_TYPE","LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY","key","PATTERN_LENGTH_TOO_LARGE","max","MISSING_KEY_PROPERTY","name","INVALID_KEY_WEIGHT_VALUE","hasOwn","KeyStore","keys","totalWeight","obj","createKey","keyId","path","id","src","weight","getFn","createKeyPath","createKeyId","get","list","arr","deepGet","index","i","len","MatchOptions","BasicOptions","a","b","FuzzyOptions","AdvancedOptions","Config","__spreadValues","SPACE","norm","mantissa","cache","m","numTokens","n","FuseIndex","fieldNormWeight","docs","records","idx","doc","docIndex","item","record","keyIndex","subRecords","stack","nestedArrIndex","subRecord","k","createIndex","myIndex","parseIndex","data","computeScore$1","pattern","errors","currentLocation","expectedLocation","distance","ignoreLocation","accuracy","proximity","convertMaskToIndices","matchmask","minMatchCharLength","indices","start","end","match","MAX_BITS","search","text","patternAlphabet","location","threshold","findAllMatches","includeMatches","patternLen","textLen","currentThreshold","bestLocation","computeMatches","matchMask","score","lastBitArr","finalScore","binMax","mask","binMin","binMid","finish","bitArr","j","charMatch","createPatternAlphabet","char","stripDiacritics","str","BitapSearch","isCaseSensitive","ignoreDiacritics","addChunk","startIndex","remainder","allIndices","totalScore","hasMatches","alphabet","isMatch","BaseMatch","getMatch","exp","matches","ExactMatch","InverseExactMatch","PrefixExactMatch","InversePrefixExactMatch","SuffixExactMatch","InverseSuffixExactMatch","FuzzyMatch","IncludeMatch","searchers","searchersLen","SPACE_RE","OR_TOKEN","parseQuery","options","query","results","queryItem","found","searcher","token","MultiMatchSet","ExtendedSearch","_","numMatches","qLen","pLen","type","registeredSearchers","register","args","createSearcher","searcherClass","LogicalOperator","KeyType","isExpression","isPath","isLeaf","convertToExplicit","parse","auto","next","isQueryPath","node","computeScore","ignoreFieldNorm","transformMatches","transformScore","format","includeScore","transformers","transformer","Fuse","predicate","limit","shouldSort","sortFn","expression","evaluate","res","child","resultMap","expResults","DEFAULT_BASE_URL","resolvedBaseUrl","config","_a","_b","apiKeyHeaders","safeGetToken","e","ApiError","message","status","body","initWidget","userToken","url","headers","response","searchTerms","contextId","loginUser","credentials","fetchOAuthProviders","getDiscussions","termId","postComment","__spreadProps","bodyText","updateTerm","updates","generateAiDefinition","term","pageContext","pageUrl","err","createSuggestedTerm","definition","createGlossaryTerm","createProductMemory","payload","addProductMemoryEntry","memoryId","updateProductMemoryEntry","entryId","listProductMemories","page","getProductMemory","deleteProductMemory","deleteProductMemoryEntry","fetchContextDiscussions","postContextDiscussion","responseBody","postContextReply","questionId","IMPLICIT_ROLES","inferRole","el","explicit","inlineComputedStyles","source","clone","computed","prop","inlineStylesDeep","sourceChildren","cloneChildren","srcChild","clnChild","absolutifyUrls","img","srcset","resolved","part","descriptor","abs","defensiveStrip","s","all","toRemove","attr","snapshotElement","rect","RING_ID","RING_CSS","EXCLUDED_IDS","ElementPicker","callbacks","ring","SVG_ID","ARROW_COLOR","MARKER_ID","computePath","from","to","panelIsRight","x1","y1","x2","y2","tension","cx1","cx2","buildSvg","svg","defs","marker","arrowPolygon","OverlayArrow","fromRect","toRect","CaptureOrchestrator","title","explanation","elementSnapshot","watchForChanges","AddEntryOrchestrator","_title","CaptureModeController","panel","picker","arrow","orchestrator","getToken","getGlossary","onSaveComplete","mode","error","panelShell","onUpdate","panelRect","elementRect","createCaptureModeController","orchestratorOverride","controller","safeCSS","css","createButton","onTrigger","shadowTokens","host","shadow","style","tokenStyle","wrap","btn","tip","isMac","isDragging","hasMoved","startX","startY","originRight","originTopPx","readPosition","right","rawTop","topPx","onMouseDown","pos","onMouseMove","dx","dy","newRight","clamp","newTopPx","onMouseUp","onTouchStart","t","onTouchMove","onTouchEnd","active","min","PANEL_STYLES","POPOUT_OVERRIDE_STYLE","renderLoginView","cb","providers","showGoogle","showMicrosoft","hasSso","ssoSectionHtml","backBtn","back","emailEl","passEl","submitEl","handleSubmit","email","password","ssoHandler","googleBtn","microsoftBtn","setLoginLoadingState","loading","setLoginErrorState","errEl","escapeHtml","renderClarificationDetailView","discussion","canReply","_c","authorLabel","date","repliesHtml","r","replyFormHtml","textarea","submitBtn","errorEl","enterPickModeView","strip","onCancel","prompt","cancelBtn","fresh","showCaptureDescribeView","snapshot","onSave","onPickAgain","descView","preview","pickAgainBtn","freshPickAgain","saveBtn","freshSave","setCaptureLoadingState","setCaptureErrorState","exitCaptureModeView","createCaptureForm","container","html","titleInput","explanationTextarea","snapshotContainer","pickBtn","watchToggle","newPickBtn","picking","cancelCaptureBtn","BANNER_ATTR","showStateChangeBanner","inferredMeaning","onDismiss","hideStateChangeBanner","banner","dismissBtn","existing","ListViewManager","allTerms","discussions","canPost","memories","terms","memory","addBtn","_d","discussionId","getListViewCSS","MIN_WIDTH","MAX_WIDTH_ABS","LS_WIDTH_KEY","LS_SIDE_KEY","createPanelLayout","refs","popoutBtn","dockBtn","closeBtn","pinLeftBtn","pinRightBtn","halfBtn","halfExitBtn","fullscreenBtn","fullscreenExitBtn","resizeHandle","_currentWidth","stored","_side","_popoutWin","_isPopout","_popoutInterval","_isHalfScreen","_isFullscreen","_wasOpenOnFullscreenEnter","_resizing","_resizeStartX","_resizeStartWidth","show","railOffset","marginProp","hide","popout","win","rootTokens","overrideStyle","adopted","triggerBtn","_reattach","winAlreadyClosing","readopted","overrideEl","_setSide","side","_toggleHalfScreen","rOff","halfWidth","_toggleFullscreen","_onResizeMove","vwMax","maxWidth","delta","newWidth","_onResizeUp","cleanup","handleClose","MAX_HOME_ITEMS","renderHomeView","headerSubtitle","isAuthenticated","_e","_f","onTermClick","onRequireLogin","onAddConcept","onOpenSearch","onCaptureUiState","onShowAllConcepts","isRelevantToPage","conceptRowsHtml","buildConceptsBody","filtTerms","isFiltering","filtRelevant","filtOther","hasBothGroups","relevantHtml","otherHeadHtml","visibleRelevant","otherCap","visibleOther","hiddenOther","hiddenRelevant","showMoreHtml","conceptsBlockHtml","wireConceptClicks","row","wireShowAllButtons","conceptsBtn","applyConceptFilter","q","conceptsSecEl","secHeader","ql","filtered","tmp","searchInput","searchDebounce","sec","showAddTermForm","loadClarificationsView","onClarificationClick","onShowAllClarifications","onAskQuestion","clarificationsSection","clarBody","sectionHeader","askBtn","showAskQuestionForm","emptyBtn","postsHtml","d","card","showAllBtn","section","emptyState","form","afterEl","insertAfter","nameInput","defInput","createPanel","onLogin","onSearch","workspaceUrl","onClose","onBack","onAddComment","onEditTerm","onRequestEdit","onOpenMemories","onViewMemoryDetail","onUpdateEntryExplanation","onPopout","onReattach","onSsoLogin","onPostReply","onAddEntryToMemory","onDeleteMemory","onDeleteEntry","onShowAllMemories","header","footer","listViewStyle","_layout","msg","showToast","setLoading","setError","_isAuthenticated","showLogin","p","lastHomeData","savedData","showTerms","setLoginLoading","setLoginError","cachedClarificationsState","activeFormController","listViewManager","currentHomeData","loadClarifications","limitedMemories","showHomeMemoryItems","showSearchResults","renderTermsView","showAllConcepts","initializeListViewManager","showAllClarifications","showAllMemories","listView","listHeader","clarSection","contextName","_totalCount","activeQuery","renderNoResults","renderTerm","debounceTimer","captureBtn","uiStatesTab","abbr","link","showTermDetail","opts","editBtn","editBtnEl","showCommentForm","body2","showEditForm","termInput","setCommentLoading","_loading","setCommentError","_message","setEditLoading","setEditError","showSuggestedTerms","suggestions","onAdd","termsList","termName","showAiModal","onSubmit","overlay","charCount","updateCount","setAiModalLoading","toast","setAuthenticated","auth","bar","showMemoriesList","hasMore","append","glossaryTab","listContainer","itemsHtml","renderMemoryItem","loadMoreContainer","timeAgo","formatTimeAgo","count","showMemoryDetail","entriesHtml","entry","roleLabel","readMode","writeMode","deleteBtn","deleteMemoryBtn","isoString","diff","showNewMemoryForm","onPickElement","onCancelCapture","bodyEl","element","showAddEntryForm","memoryTitle","updateFormSnapshot","setFormPickingMode","showStateChangeNotification","hideStateChangeNotification","showClarificationDetail","enterPickMode","showCaptureDescribe","setCaptureLoading","setCaptureError","exitCaptureMode","restoreHomeView","getStripEl","empty","railStyles","createRailIdentity","initials","root","avatar","tooltip","createRailCoreActions","state","icons","action","createRailAuth","isLoggedIn","iconSVG","tooltipText","createRail","identity","core","railShell","rail","RAIL_WIDTH","setState","mountUI","button","mountRailUI","railState","railCallbacks","panelCallbacks","SKIP_TAGS","SKIP_IDS","HIGHLIGHT_CLASS","HIGHLIGHT_STYLE","escapeRegex","Highlighter","regex","termMap","span","parent","sorted","patterns","abbrKey","textNode","fragments","lastIndex","matched","anchor","fragment","MAX_SUGGESTIONS","MIN_FREQUENCY","STOP_WORDS","TermSuggester","existingTerms","glossarySet","freq","RUN_RE","runMatch","words","phrase","lower","candidates","c","WidgetController","parts","first","lastPart","last","provider","questionBody","railMount","plugin","jwt","payloadB64","b64","msUntilExpiry","baseUrl","popupUrl","popup","closedPoll","onMessage","event","expectedOrigin","_g","limitedClarifications","limitedDiscussions","updated","trimmed","localResults","serverResults","glossary","edited","pageResp","captureState","StateWatcher","onStateChange","mutations","before","meaningful","attrMutation","charMutation","childMutations","allNodes","TEXT_LOADING_RE","TEXT_ERROR_RE","TEXT_SUCCESS_RE","CLASS_RULES","classSet","cls","addedClasses","after","beforeSet","inferMeaning","attribute","newClasses","label","LIVE_RING_ID","LiveRenderer","urlsMatch","current","MemoryDetailController","stateWatcher","targetingEngine","onDiff","firstEntry","meta","target","_controller","initUnnoodle","validateConfig","sessionKey","savedToken","openUnnoodle","closeUnnoodle","destroyUnnoodle","Unnoodle"],"mappings":"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AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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","file":"index.js","sourcesContent":["/**\n * Fuse.js v7.1.0 - Lightweight fuzzy-search (http://fusejs.io)\n *\n * Copyright (c) 2025 Kiro Risk (http://kiro.me)\n * All Rights Reserved. Apache Software License 2.0\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\nfunction isArray(value) {\n return !Array.isArray\n ? getTag(value) === '[object Array]'\n : Array.isArray(value)\n}\n\n// Adapted from: https://github.com/lodash/lodash/blob/master/.internal/baseToString.js\nconst INFINITY = 1 / 0;\nfunction baseToString(value) {\n // Exit early for strings to avoid a performance hit in some environments.\n if (typeof value == 'string') {\n return value\n }\n let result = value + '';\n return result == '0' && 1 / value == -INFINITY ? '-0' : result\n}\n\nfunction toString(value) {\n return value == null ? '' : baseToString(value)\n}\n\nfunction isString(value) {\n return typeof value === 'string'\n}\n\nfunction isNumber(value) {\n return typeof value === 'number'\n}\n\n// Adapted from: https://github.com/lodash/lodash/blob/master/isBoolean.js\nfunction isBoolean(value) {\n return (\n value === true ||\n value === false ||\n (isObjectLike(value) && getTag(value) == '[object Boolean]')\n )\n}\n\nfunction isObject(value) {\n return typeof value === 'object'\n}\n\n// Checks if `value` is object-like.\nfunction isObjectLike(value) {\n return isObject(value) && value !== null\n}\n\nfunction isDefined(value) {\n return value !== undefined && value !== null\n}\n\nfunction isBlank(value) {\n return !value.trim().length\n}\n\n// Gets the `toStringTag` of `value`.\n// Adapted from: https://github.com/lodash/lodash/blob/master/.internal/getTag.js\nfunction getTag(value) {\n return value == null\n ? value === undefined\n ? '[object Undefined]'\n : '[object Null]'\n : Object.prototype.toString.call(value)\n}\n\nconst EXTENDED_SEARCH_UNAVAILABLE = 'Extended search is not available';\n\nconst INCORRECT_INDEX_TYPE = \"Incorrect 'index' type\";\n\nconst LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY = (key) =>\n `Invalid value for key ${key}`;\n\nconst PATTERN_LENGTH_TOO_LARGE = (max) =>\n `Pattern length exceeds max of ${max}.`;\n\nconst MISSING_KEY_PROPERTY = (name) => `Missing ${name} property in key`;\n\nconst INVALID_KEY_WEIGHT_VALUE = (key) =>\n `Property 'weight' in key '${key}' must be a positive integer`;\n\nconst hasOwn = Object.prototype.hasOwnProperty;\n\nclass KeyStore {\n constructor(keys) {\n this._keys = [];\n this._keyMap = {};\n\n let totalWeight = 0;\n\n keys.forEach((key) => {\n let obj = createKey(key);\n\n this._keys.push(obj);\n this._keyMap[obj.id] = obj;\n\n totalWeight += obj.weight;\n });\n\n // Normalize weights so that their sum is equal to 1\n this._keys.forEach((key) => {\n key.weight /= totalWeight;\n });\n }\n get(keyId) {\n return this._keyMap[keyId]\n }\n keys() {\n return this._keys\n }\n toJSON() {\n return JSON.stringify(this._keys)\n }\n}\n\nfunction createKey(key) {\n let path = null;\n let id = null;\n let src = null;\n let weight = 1;\n let getFn = null;\n\n if (isString(key) || isArray(key)) {\n src = key;\n path = createKeyPath(key);\n id = createKeyId(key);\n } else {\n if (!hasOwn.call(key, 'name')) {\n throw new Error(MISSING_KEY_PROPERTY('name'))\n }\n\n const name = key.name;\n src = name;\n\n if (hasOwn.call(key, 'weight')) {\n weight = key.weight;\n\n if (weight <= 0) {\n throw new Error(INVALID_KEY_WEIGHT_VALUE(name))\n }\n }\n\n path = createKeyPath(name);\n id = createKeyId(name);\n getFn = key.getFn;\n }\n\n return { path, id, weight, src, getFn }\n}\n\nfunction createKeyPath(key) {\n return isArray(key) ? key : key.split('.')\n}\n\nfunction createKeyId(key) {\n return isArray(key) ? key.join('.') : key\n}\n\nfunction get(obj, path) {\n let list = [];\n let arr = false;\n\n const deepGet = (obj, path, index) => {\n if (!isDefined(obj)) {\n return\n }\n if (!path[index]) {\n // If there's no path left, we've arrived at the object we care about.\n list.push(obj);\n } else {\n let key = path[index];\n\n const value = obj[key];\n\n if (!isDefined(value)) {\n return\n }\n\n // If we're at the last value in the path, and if it's a string/number/bool,\n // add it to the list\n if (\n index === path.length - 1 &&\n (isString(value) || isNumber(value) || isBoolean(value))\n ) {\n list.push(toString(value));\n } else if (isArray(value)) {\n arr = true;\n // Search each item in the array.\n for (let i = 0, len = value.length; i < len; i += 1) {\n deepGet(value[i], path, index + 1);\n }\n } else if (path.length) {\n // An object. Recurse further.\n deepGet(value, path, index + 1);\n }\n }\n };\n\n // Backwards compatibility (since path used to be a string)\n deepGet(obj, isString(path) ? path.split('.') : path, 0);\n\n return arr ? list : list[0]\n}\n\nconst MatchOptions = {\n // Whether the matches should be included in the result set. When `true`, each record in the result\n // set will include the indices of the matched characters.\n // These can consequently be used for highlighting purposes.\n includeMatches: false,\n // When `true`, the matching function will continue to the end of a search pattern even if\n // a perfect match has already been located in the string.\n findAllMatches: false,\n // Minimum number of characters that must be matched before a result is considered a match\n minMatchCharLength: 1\n};\n\nconst BasicOptions = {\n // When `true`, the algorithm continues searching to the end of the input even if a perfect\n // match is found before the end of the same input.\n isCaseSensitive: false,\n // When `true`, the algorithm will ignore diacritics (accents) in comparisons\n ignoreDiacritics: false,\n // When true, the matching function will continue to the end of a search pattern even if\n includeScore: false,\n // List of properties that will be searched. This also supports nested properties.\n keys: [],\n // Whether to sort the result list, by score\n shouldSort: true,\n // Default sort function: sort by ascending score, ascending index\n sortFn: (a, b) =>\n a.score === b.score ? (a.idx < b.idx ? -1 : 1) : a.score < b.score ? -1 : 1\n};\n\nconst FuzzyOptions = {\n // Approximately where in the text is the pattern expected to be found?\n location: 0,\n // At what point does the match algorithm give up. A threshold of '0.0' requires a perfect match\n // (of both letters and location), a threshold of '1.0' would match anything.\n threshold: 0.6,\n // Determines how close the match must be to the fuzzy location (specified above).\n // An exact letter match which is 'distance' characters away from the fuzzy location\n // would score as a complete mismatch. A distance of '0' requires the match be at\n // the exact location specified, a threshold of '1000' would require a perfect match\n // to be within 800 characters of the fuzzy location to be found using a 0.8 threshold.\n distance: 100\n};\n\nconst AdvancedOptions = {\n // When `true`, it enables the use of unix-like search commands\n useExtendedSearch: false,\n // The get function to use when fetching an object's properties.\n // The default will search nested paths *ie foo.bar.baz*\n getFn: get,\n // When `true`, search will ignore `location` and `distance`, so it won't matter\n // where in the string the pattern appears.\n // More info: https://fusejs.io/concepts/scoring-theory.html#fuzziness-score\n ignoreLocation: false,\n // When `true`, the calculation for the relevance score (used for sorting) will\n // ignore the field-length norm.\n // More info: https://fusejs.io/concepts/scoring-theory.html#field-length-norm\n ignoreFieldNorm: false,\n // The weight to determine how much field length norm effects scoring.\n fieldNormWeight: 1\n};\n\nvar Config = {\n ...BasicOptions,\n ...MatchOptions,\n ...FuzzyOptions,\n ...AdvancedOptions\n};\n\nconst SPACE = /[^ ]+/g;\n\n// Field-length norm: the shorter the field, the higher the weight.\n// Set to 3 decimals to reduce index size.\nfunction norm(weight = 1, mantissa = 3) {\n const cache = new Map();\n const m = Math.pow(10, mantissa);\n\n return {\n get(value) {\n const numTokens = value.match(SPACE).length;\n\n if (cache.has(numTokens)) {\n return cache.get(numTokens)\n }\n\n // Default function is 1/sqrt(x), weight makes that variable\n const norm = 1 / Math.pow(numTokens, 0.5 * weight);\n\n // In place of `toFixed(mantissa)`, for faster computation\n const n = parseFloat(Math.round(norm * m) / m);\n\n cache.set(numTokens, n);\n\n return n\n },\n clear() {\n cache.clear();\n }\n }\n}\n\nclass FuseIndex {\n constructor({\n getFn = Config.getFn,\n fieldNormWeight = Config.fieldNormWeight\n } = {}) {\n this.norm = norm(fieldNormWeight, 3);\n this.getFn = getFn;\n this.isCreated = false;\n\n this.setIndexRecords();\n }\n setSources(docs = []) {\n this.docs = docs;\n }\n setIndexRecords(records = []) {\n this.records = records;\n }\n setKeys(keys = []) {\n this.keys = keys;\n this._keysMap = {};\n keys.forEach((key, idx) => {\n this._keysMap[key.id] = idx;\n });\n }\n create() {\n if (this.isCreated || !this.docs.length) {\n return\n }\n\n this.isCreated = true;\n\n // List is Array<String>\n if (isString(this.docs[0])) {\n this.docs.forEach((doc, docIndex) => {\n this._addString(doc, docIndex);\n });\n } else {\n // List is Array<Object>\n this.docs.forEach((doc, docIndex) => {\n this._addObject(doc, docIndex);\n });\n }\n\n this.norm.clear();\n }\n // Adds a doc to the end of the index\n add(doc) {\n const idx = this.size();\n\n if (isString(doc)) {\n this._addString(doc, idx);\n } else {\n this._addObject(doc, idx);\n }\n }\n // Removes the doc at the specified index of the index\n removeAt(idx) {\n this.records.splice(idx, 1);\n\n // Change ref index of every subsquent doc\n for (let i = idx, len = this.size(); i < len; i += 1) {\n this.records[i].i -= 1;\n }\n }\n getValueForItemAtKeyId(item, keyId) {\n return item[this._keysMap[keyId]]\n }\n size() {\n return this.records.length\n }\n _addString(doc, docIndex) {\n if (!isDefined(doc) || isBlank(doc)) {\n return\n }\n\n let record = {\n v: doc,\n i: docIndex,\n n: this.norm.get(doc)\n };\n\n this.records.push(record);\n }\n _addObject(doc, docIndex) {\n let record = { i: docIndex, $: {} };\n\n // Iterate over every key (i.e, path), and fetch the value at that key\n this.keys.forEach((key, keyIndex) => {\n let value = key.getFn ? key.getFn(doc) : this.getFn(doc, key.path);\n\n if (!isDefined(value)) {\n return\n }\n\n if (isArray(value)) {\n let subRecords = [];\n const stack = [{ nestedArrIndex: -1, value }];\n\n while (stack.length) {\n const { nestedArrIndex, value } = stack.pop();\n\n if (!isDefined(value)) {\n continue\n }\n\n if (isString(value) && !isBlank(value)) {\n let subRecord = {\n v: value,\n i: nestedArrIndex,\n n: this.norm.get(value)\n };\n\n subRecords.push(subRecord);\n } else if (isArray(value)) {\n value.forEach((item, k) => {\n stack.push({\n nestedArrIndex: k,\n value: item\n });\n });\n } else ;\n }\n record.$[keyIndex] = subRecords;\n } else if (isString(value) && !isBlank(value)) {\n let subRecord = {\n v: value,\n n: this.norm.get(value)\n };\n\n record.$[keyIndex] = subRecord;\n }\n });\n\n this.records.push(record);\n }\n toJSON() {\n return {\n keys: this.keys,\n records: this.records\n }\n }\n}\n\nfunction createIndex(\n keys,\n docs,\n { getFn = Config.getFn, fieldNormWeight = Config.fieldNormWeight } = {}\n) {\n const myIndex = new FuseIndex({ getFn, fieldNormWeight });\n myIndex.setKeys(keys.map(createKey));\n myIndex.setSources(docs);\n myIndex.create();\n return myIndex\n}\n\nfunction parseIndex(\n data,\n { getFn = Config.getFn, fieldNormWeight = Config.fieldNormWeight } = {}\n) {\n const { keys, records } = data;\n const myIndex = new FuseIndex({ getFn, fieldNormWeight });\n myIndex.setKeys(keys);\n myIndex.setIndexRecords(records);\n return myIndex\n}\n\nfunction computeScore$1(\n pattern,\n {\n errors = 0,\n currentLocation = 0,\n expectedLocation = 0,\n distance = Config.distance,\n ignoreLocation = Config.ignoreLocation\n } = {}\n) {\n const accuracy = errors / pattern.length;\n\n if (ignoreLocation) {\n return accuracy\n }\n\n const proximity = Math.abs(expectedLocation - currentLocation);\n\n if (!distance) {\n // Dodge divide by zero error.\n return proximity ? 1.0 : accuracy\n }\n\n return accuracy + proximity / distance\n}\n\nfunction convertMaskToIndices(\n matchmask = [],\n minMatchCharLength = Config.minMatchCharLength\n) {\n let indices = [];\n let start = -1;\n let end = -1;\n let i = 0;\n\n for (let len = matchmask.length; i < len; i += 1) {\n let match = matchmask[i];\n if (match && start === -1) {\n start = i;\n } else if (!match && start !== -1) {\n end = i - 1;\n if (end - start + 1 >= minMatchCharLength) {\n indices.push([start, end]);\n }\n start = -1;\n }\n }\n\n // (i-1 - start) + 1 => i - start\n if (matchmask[i - 1] && i - start >= minMatchCharLength) {\n indices.push([start, i - 1]);\n }\n\n return indices\n}\n\n// Machine word size\nconst MAX_BITS = 32;\n\nfunction search(\n text,\n pattern,\n patternAlphabet,\n {\n location = Config.location,\n distance = Config.distance,\n threshold = Config.threshold,\n findAllMatches = Config.findAllMatches,\n minMatchCharLength = Config.minMatchCharLength,\n includeMatches = Config.includeMatches,\n ignoreLocation = Config.ignoreLocation\n } = {}\n) {\n if (pattern.length > MAX_BITS) {\n throw new Error(PATTERN_LENGTH_TOO_LARGE(MAX_BITS))\n }\n\n const patternLen = pattern.length;\n // Set starting location at beginning text and initialize the alphabet.\n const textLen = text.length;\n // Handle the case when location > text.length\n const expectedLocation = Math.max(0, Math.min(location, textLen));\n // Highest score beyond which we give up.\n let currentThreshold = threshold;\n // Is there a nearby exact match? (speedup)\n let bestLocation = expectedLocation;\n\n // Performance: only computer matches when the minMatchCharLength > 1\n // OR if `includeMatches` is true.\n const computeMatches = minMatchCharLength > 1 || includeMatches;\n // A mask of the matches, used for building the indices\n const matchMask = computeMatches ? Array(textLen) : [];\n\n let index;\n\n // Get all exact matches, here for speed up\n while ((index = text.indexOf(pattern, bestLocation)) > -1) {\n let score = computeScore$1(pattern, {\n currentLocation: index,\n expectedLocation,\n distance,\n ignoreLocation\n });\n\n currentThreshold = Math.min(score, currentThreshold);\n bestLocation = index + patternLen;\n\n if (computeMatches) {\n let i = 0;\n while (i < patternLen) {\n matchMask[index + i] = 1;\n i += 1;\n }\n }\n }\n\n // Reset the best location\n bestLocation = -1;\n\n let lastBitArr = [];\n let finalScore = 1;\n let binMax = patternLen + textLen;\n\n const mask = 1 << (patternLen - 1);\n\n for (let i = 0; i < patternLen; i += 1) {\n // Scan for the best match; each iteration allows for one more error.\n // Run a binary search to determine how far from the match location we can stray\n // at this error level.\n let binMin = 0;\n let binMid = binMax;\n\n while (binMin < binMid) {\n const score = computeScore$1(pattern, {\n errors: i,\n currentLocation: expectedLocation + binMid,\n expectedLocation,\n distance,\n ignoreLocation\n });\n\n if (score <= currentThreshold) {\n binMin = binMid;\n } else {\n binMax = binMid;\n }\n\n binMid = Math.floor((binMax - binMin) / 2 + binMin);\n }\n\n // Use the result from this iteration as the maximum for the next.\n binMax = binMid;\n\n let start = Math.max(1, expectedLocation - binMid + 1);\n let finish = findAllMatches\n ? textLen\n : Math.min(expectedLocation + binMid, textLen) + patternLen;\n\n // Initialize the bit array\n let bitArr = Array(finish + 2);\n\n bitArr[finish + 1] = (1 << i) - 1;\n\n for (let j = finish; j >= start; j -= 1) {\n let currentLocation = j - 1;\n let charMatch = patternAlphabet[text.charAt(currentLocation)];\n\n if (computeMatches) {\n // Speed up: quick bool to int conversion (i.e, `charMatch ? 1 : 0`)\n matchMask[currentLocation] = +!!charMatch;\n }\n\n // First pass: exact match\n bitArr[j] = ((bitArr[j + 1] << 1) | 1) & charMatch;\n\n // Subsequent passes: fuzzy match\n if (i) {\n bitArr[j] |=\n ((lastBitArr[j + 1] | lastBitArr[j]) << 1) | 1 | lastBitArr[j + 1];\n }\n\n if (bitArr[j] & mask) {\n finalScore = computeScore$1(pattern, {\n errors: i,\n currentLocation,\n expectedLocation,\n distance,\n ignoreLocation\n });\n\n // This match will almost certainly be better than any existing match.\n // But check anyway.\n if (finalScore <= currentThreshold) {\n // Indeed it is\n currentThreshold = finalScore;\n bestLocation = currentLocation;\n\n // Already passed `loc`, downhill from here on in.\n if (bestLocation <= expectedLocation) {\n break\n }\n\n // When passing `bestLocation`, don't exceed our current distance from `expectedLocation`.\n start = Math.max(1, 2 * expectedLocation - bestLocation);\n }\n }\n }\n\n // No hope for a (better) match at greater error levels.\n const score = computeScore$1(pattern, {\n errors: i + 1,\n currentLocation: expectedLocation,\n expectedLocation,\n distance,\n ignoreLocation\n });\n\n if (score > currentThreshold) {\n break\n }\n\n lastBitArr = bitArr;\n }\n\n const result = {\n isMatch: bestLocation >= 0,\n // Count exact matches (those with a score of 0) to be \"almost\" exact\n score: Math.max(0.001, finalScore)\n };\n\n if (computeMatches) {\n const indices = convertMaskToIndices(matchMask, minMatchCharLength);\n if (!indices.length) {\n result.isMatch = false;\n } else if (includeMatches) {\n result.indices = indices;\n }\n }\n\n return result\n}\n\nfunction createPatternAlphabet(pattern) {\n let mask = {};\n\n for (let i = 0, len = pattern.length; i < len; i += 1) {\n const char = pattern.charAt(i);\n mask[char] = (mask[char] || 0) | (1 << (len - i - 1));\n }\n\n return mask\n}\n\nconst stripDiacritics = String.prototype.normalize\n ? ((str) => str.normalize('NFD').replace(/[\\u0300-\\u036F\\u0483-\\u0489\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u0610-\\u061A\\u064B-\\u065F\\u0670\\u06D6-\\u06DC\\u06DF-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0711\\u0730-\\u074A\\u07A6-\\u07B0\\u07EB-\\u07F3\\u07FD\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u082D\\u0859-\\u085B\\u08D3-\\u08E1\\u08E3-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962\\u0963\\u0981-\\u0983\\u09BC\\u09BE-\\u09C4\\u09C7\\u09C8\\u09CB-\\u09CD\\u09D7\\u09E2\\u09E3\\u09FE\\u0A01-\\u0A03\\u0A3C\\u0A3E-\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A70\\u0A71\\u0A75\\u0A81-\\u0A83\\u0ABC\\u0ABE-\\u0AC5\\u0AC7-\\u0AC9\\u0ACB-\\u0ACD\\u0AE2\\u0AE3\\u0AFA-\\u0AFF\\u0B01-\\u0B03\\u0B3C\\u0B3E-\\u0B44\\u0B47\\u0B48\\u0B4B-\\u0B4D\\u0B56\\u0B57\\u0B62\\u0B63\\u0B82\\u0BBE-\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCD\\u0BD7\\u0C00-\\u0C04\\u0C3E-\\u0C44\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C62\\u0C63\\u0C81-\\u0C83\\u0CBC\\u0CBE-\\u0CC4\\u0CC6-\\u0CC8\\u0CCA-\\u0CCD\\u0CD5\\u0CD6\\u0CE2\\u0CE3\\u0D00-\\u0D03\\u0D3B\\u0D3C\\u0D3E-\\u0D44\\u0D46-\\u0D48\\u0D4A-\\u0D4D\\u0D57\\u0D62\\u0D63\\u0D82\\u0D83\\u0DCA\\u0DCF-\\u0DD4\\u0DD6\\u0DD8-\\u0DDF\\u0DF2\\u0DF3\\u0E31\\u0E34-\\u0E3A\\u0E47-\\u0E4E\\u0EB1\\u0EB4-\\u0EB9\\u0EBB\\u0EBC\\u0EC8-\\u0ECD\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F3E\\u0F3F\\u0F71-\\u0F84\\u0F86\\u0F87\\u0F8D-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u102B-\\u103E\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F\\u109A-\\u109D\\u135D-\\u135F\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17B4-\\u17D3\\u17DD\\u180B-\\u180D\\u1885\\u1886\\u18A9\\u1920-\\u192B\\u1930-\\u193B\\u1A17-\\u1A1B\\u1A55-\\u1A5E\\u1A60-\\u1A7C\\u1A7F\\u1AB0-\\u1ABE\\u1B00-\\u1B04\\u1B34-\\u1B44\\u1B6B-\\u1B73\\u1B80-\\u1B82\\u1BA1-\\u1BAD\\u1BE6-\\u1BF3\\u1C24-\\u1C37\\u1CD0-\\u1CD2\\u1CD4-\\u1CE8\\u1CED\\u1CF2-\\u1CF4\\u1CF7-\\u1CF9\\u1DC0-\\u1DF9\\u1DFB-\\u1DFF\\u20D0-\\u20F0\\u2CEF-\\u2CF1\\u2D7F\\u2DE0-\\u2DFF\\u302A-\\u302F\\u3099\\u309A\\uA66F-\\uA672\\uA674-\\uA67D\\uA69E\\uA69F\\uA6F0\\uA6F1\\uA802\\uA806\\uA80B\\uA823-\\uA827\\uA880\\uA881\\uA8B4-\\uA8C5\\uA8E0-\\uA8F1\\uA8FF\\uA926-\\uA92D\\uA947-\\uA953\\uA980-\\uA983\\uA9B3-\\uA9C0\\uA9E5\\uAA29-\\uAA36\\uAA43\\uAA4C\\uAA4D\\uAA7B-\\uAA7D\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAEB-\\uAAEF\\uAAF5\\uAAF6\\uABE3-\\uABEA\\uABEC\\uABED\\uFB1E\\uFE00-\\uFE0F\\uFE20-\\uFE2F]/g, ''))\n : ((str) => str);\n\nclass BitapSearch {\n constructor(\n pattern,\n {\n location = Config.location,\n threshold = Config.threshold,\n distance = Config.distance,\n includeMatches = Config.includeMatches,\n findAllMatches = Config.findAllMatches,\n minMatchCharLength = Config.minMatchCharLength,\n isCaseSensitive = Config.isCaseSensitive,\n ignoreDiacritics = Config.ignoreDiacritics,\n ignoreLocation = Config.ignoreLocation\n } = {}\n ) {\n this.options = {\n location,\n threshold,\n distance,\n includeMatches,\n findAllMatches,\n minMatchCharLength,\n isCaseSensitive,\n ignoreDiacritics,\n ignoreLocation\n };\n\n pattern = isCaseSensitive ? pattern : pattern.toLowerCase();\n pattern = ignoreDiacritics ? stripDiacritics(pattern) : pattern;\n this.pattern = pattern;\n\n this.chunks = [];\n\n if (!this.pattern.length) {\n return\n }\n\n const addChunk = (pattern, startIndex) => {\n this.chunks.push({\n pattern,\n alphabet: createPatternAlphabet(pattern),\n startIndex\n });\n };\n\n const len = this.pattern.length;\n\n if (len > MAX_BITS) {\n let i = 0;\n const remainder = len % MAX_BITS;\n const end = len - remainder;\n\n while (i < end) {\n addChunk(this.pattern.substr(i, MAX_BITS), i);\n i += MAX_BITS;\n }\n\n if (remainder) {\n const startIndex = len - MAX_BITS;\n addChunk(this.pattern.substr(startIndex), startIndex);\n }\n } else {\n addChunk(this.pattern, 0);\n }\n }\n\n searchIn(text) {\n const { isCaseSensitive, ignoreDiacritics, includeMatches } = this.options;\n\n text = isCaseSensitive ? text : text.toLowerCase();\n text = ignoreDiacritics ? stripDiacritics(text) : text;\n\n // Exact match\n if (this.pattern === text) {\n let result = {\n isMatch: true,\n score: 0\n };\n\n if (includeMatches) {\n result.indices = [[0, text.length - 1]];\n }\n\n return result\n }\n\n // Otherwise, use Bitap algorithm\n const {\n location,\n distance,\n threshold,\n findAllMatches,\n minMatchCharLength,\n ignoreLocation\n } = this.options;\n\n let allIndices = [];\n let totalScore = 0;\n let hasMatches = false;\n\n this.chunks.forEach(({ pattern, alphabet, startIndex }) => {\n const { isMatch, score, indices } = search(text, pattern, alphabet, {\n location: location + startIndex,\n distance,\n threshold,\n findAllMatches,\n minMatchCharLength,\n includeMatches,\n ignoreLocation\n });\n\n if (isMatch) {\n hasMatches = true;\n }\n\n totalScore += score;\n\n if (isMatch && indices) {\n allIndices = [...allIndices, ...indices];\n }\n });\n\n let result = {\n isMatch: hasMatches,\n score: hasMatches ? totalScore / this.chunks.length : 1\n };\n\n if (hasMatches && includeMatches) {\n result.indices = allIndices;\n }\n\n return result\n }\n}\n\nclass BaseMatch {\n constructor(pattern) {\n this.pattern = pattern;\n }\n static isMultiMatch(pattern) {\n return getMatch(pattern, this.multiRegex)\n }\n static isSingleMatch(pattern) {\n return getMatch(pattern, this.singleRegex)\n }\n search(/*text*/) {}\n}\n\nfunction getMatch(pattern, exp) {\n const matches = pattern.match(exp);\n return matches ? matches[1] : null\n}\n\n// Token: 'file\n\nclass ExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'exact'\n }\n static get multiRegex() {\n return /^=\"(.*)\"$/\n }\n static get singleRegex() {\n return /^=(.*)$/\n }\n search(text) {\n const isMatch = text === this.pattern;\n\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [0, this.pattern.length - 1]\n }\n }\n}\n\n// Token: !fire\n\nclass InverseExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'inverse-exact'\n }\n static get multiRegex() {\n return /^!\"(.*)\"$/\n }\n static get singleRegex() {\n return /^!(.*)$/\n }\n search(text) {\n const index = text.indexOf(this.pattern);\n const isMatch = index === -1;\n\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [0, text.length - 1]\n }\n }\n}\n\n// Token: ^file\n\nclass PrefixExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'prefix-exact'\n }\n static get multiRegex() {\n return /^\\^\"(.*)\"$/\n }\n static get singleRegex() {\n return /^\\^(.*)$/\n }\n search(text) {\n const isMatch = text.startsWith(this.pattern);\n\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [0, this.pattern.length - 1]\n }\n }\n}\n\n// Token: !^fire\n\nclass InversePrefixExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'inverse-prefix-exact'\n }\n static get multiRegex() {\n return /^!\\^\"(.*)\"$/\n }\n static get singleRegex() {\n return /^!\\^(.*)$/\n }\n search(text) {\n const isMatch = !text.startsWith(this.pattern);\n\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [0, text.length - 1]\n }\n }\n}\n\n// Token: .file$\n\nclass SuffixExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'suffix-exact'\n }\n static get multiRegex() {\n return /^\"(.*)\"\\$$/\n }\n static get singleRegex() {\n return /^(.*)\\$$/\n }\n search(text) {\n const isMatch = text.endsWith(this.pattern);\n\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [text.length - this.pattern.length, text.length - 1]\n }\n }\n}\n\n// Token: !.file$\n\nclass InverseSuffixExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'inverse-suffix-exact'\n }\n static get multiRegex() {\n return /^!\"(.*)\"\\$$/\n }\n static get singleRegex() {\n return /^!(.*)\\$$/\n }\n search(text) {\n const isMatch = !text.endsWith(this.pattern);\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [0, text.length - 1]\n }\n }\n}\n\nclass FuzzyMatch extends BaseMatch {\n constructor(\n pattern,\n {\n location = Config.location,\n threshold = Config.threshold,\n distance = Config.distance,\n includeMatches = Config.includeMatches,\n findAllMatches = Config.findAllMatches,\n minMatchCharLength = Config.minMatchCharLength,\n isCaseSensitive = Config.isCaseSensitive,\n ignoreDiacritics = Config.ignoreDiacritics,\n ignoreLocation = Config.ignoreLocation\n } = {}\n ) {\n super(pattern);\n this._bitapSearch = new BitapSearch(pattern, {\n location,\n threshold,\n distance,\n includeMatches,\n findAllMatches,\n minMatchCharLength,\n isCaseSensitive,\n ignoreDiacritics,\n ignoreLocation\n });\n }\n static get type() {\n return 'fuzzy'\n }\n static get multiRegex() {\n return /^\"(.*)\"$/\n }\n static get singleRegex() {\n return /^(.*)$/\n }\n search(text) {\n return this._bitapSearch.searchIn(text)\n }\n}\n\n// Token: 'file\n\nclass IncludeMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'include'\n }\n static get multiRegex() {\n return /^'\"(.*)\"$/\n }\n static get singleRegex() {\n return /^'(.*)$/\n }\n search(text) {\n let location = 0;\n let index;\n\n const indices = [];\n const patternLen = this.pattern.length;\n\n // Get all exact matches\n while ((index = text.indexOf(this.pattern, location)) > -1) {\n location = index + patternLen;\n indices.push([index, location - 1]);\n }\n\n const isMatch = !!indices.length;\n\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices\n }\n }\n}\n\n// ❗Order is important. DO NOT CHANGE.\nconst searchers = [\n ExactMatch,\n IncludeMatch,\n PrefixExactMatch,\n InversePrefixExactMatch,\n InverseSuffixExactMatch,\n SuffixExactMatch,\n InverseExactMatch,\n FuzzyMatch\n];\n\nconst searchersLen = searchers.length;\n\n// Regex to split by spaces, but keep anything in quotes together\nconst SPACE_RE = / +(?=(?:[^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)/;\nconst OR_TOKEN = '|';\n\n// Return a 2D array representation of the query, for simpler parsing.\n// Example:\n// \"^core go$ | rb$ | py$ xy$\" => [[\"^core\", \"go$\"], [\"rb$\"], [\"py$\", \"xy$\"]]\nfunction parseQuery(pattern, options = {}) {\n return pattern.split(OR_TOKEN).map((item) => {\n let query = item\n .trim()\n .split(SPACE_RE)\n .filter((item) => item && !!item.trim());\n\n let results = [];\n for (let i = 0, len = query.length; i < len; i += 1) {\n const queryItem = query[i];\n\n // 1. Handle multiple query match (i.e, once that are quoted, like `\"hello world\"`)\n let found = false;\n let idx = -1;\n while (!found && ++idx < searchersLen) {\n const searcher = searchers[idx];\n let token = searcher.isMultiMatch(queryItem);\n if (token) {\n results.push(new searcher(token, options));\n found = true;\n }\n }\n\n if (found) {\n continue\n }\n\n // 2. Handle single query matches (i.e, once that are *not* quoted)\n idx = -1;\n while (++idx < searchersLen) {\n const searcher = searchers[idx];\n let token = searcher.isSingleMatch(queryItem);\n if (token) {\n results.push(new searcher(token, options));\n break\n }\n }\n }\n\n return results\n })\n}\n\n// These extended matchers can return an array of matches, as opposed\n// to a singl match\nconst MultiMatchSet = new Set([FuzzyMatch.type, IncludeMatch.type]);\n\n/**\n * Command-like searching\n * ======================\n *\n * Given multiple search terms delimited by spaces.e.g. `^jscript .python$ ruby !java`,\n * search in a given text.\n *\n * Search syntax:\n *\n * | Token | Match type | Description |\n * | ----------- | -------------------------- | -------------------------------------- |\n * | `jscript` | fuzzy-match | Items that fuzzy match `jscript` |\n * | `=scheme` | exact-match | Items that are `scheme` |\n * | `'python` | include-match | Items that include `python` |\n * | `!ruby` | inverse-exact-match | Items that do not include `ruby` |\n * | `^java` | prefix-exact-match | Items that start with `java` |\n * | `!^earlang` | inverse-prefix-exact-match | Items that do not start with `earlang` |\n * | `.js$` | suffix-exact-match | Items that end with `.js` |\n * | `!.go$` | inverse-suffix-exact-match | Items that do not end with `.go` |\n *\n * A single pipe character acts as an OR operator. For example, the following\n * query matches entries that start with `core` and end with either`go`, `rb`,\n * or`py`.\n *\n * ```\n * ^core go$ | rb$ | py$\n * ```\n */\nclass ExtendedSearch {\n constructor(\n pattern,\n {\n isCaseSensitive = Config.isCaseSensitive,\n ignoreDiacritics = Config.ignoreDiacritics,\n includeMatches = Config.includeMatches,\n minMatchCharLength = Config.minMatchCharLength,\n ignoreLocation = Config.ignoreLocation,\n findAllMatches = Config.findAllMatches,\n location = Config.location,\n threshold = Config.threshold,\n distance = Config.distance\n } = {}\n ) {\n this.query = null;\n this.options = {\n isCaseSensitive,\n ignoreDiacritics,\n includeMatches,\n minMatchCharLength,\n findAllMatches,\n ignoreLocation,\n location,\n threshold,\n distance\n };\n\n pattern = isCaseSensitive ? pattern : pattern.toLowerCase();\n pattern = ignoreDiacritics ? stripDiacritics(pattern) : pattern;\n this.pattern = pattern;\n this.query = parseQuery(this.pattern, this.options);\n }\n\n static condition(_, options) {\n return options.useExtendedSearch\n }\n\n searchIn(text) {\n const query = this.query;\n\n if (!query) {\n return {\n isMatch: false,\n score: 1\n }\n }\n\n const { includeMatches, isCaseSensitive, ignoreDiacritics } = this.options;\n\n text = isCaseSensitive ? text : text.toLowerCase();\n text = ignoreDiacritics ? stripDiacritics(text) : text;\n\n let numMatches = 0;\n let allIndices = [];\n let totalScore = 0;\n\n // ORs\n for (let i = 0, qLen = query.length; i < qLen; i += 1) {\n const searchers = query[i];\n\n // Reset indices\n allIndices.length = 0;\n numMatches = 0;\n\n // ANDs\n for (let j = 0, pLen = searchers.length; j < pLen; j += 1) {\n const searcher = searchers[j];\n const { isMatch, indices, score } = searcher.search(text);\n\n if (isMatch) {\n numMatches += 1;\n totalScore += score;\n if (includeMatches) {\n const type = searcher.constructor.type;\n if (MultiMatchSet.has(type)) {\n allIndices = [...allIndices, ...indices];\n } else {\n allIndices.push(indices);\n }\n }\n } else {\n totalScore = 0;\n numMatches = 0;\n allIndices.length = 0;\n break\n }\n }\n\n // OR condition, so if TRUE, return\n if (numMatches) {\n let result = {\n isMatch: true,\n score: totalScore / numMatches\n };\n\n if (includeMatches) {\n result.indices = allIndices;\n }\n\n return result\n }\n }\n\n // Nothing was matched\n return {\n isMatch: false,\n score: 1\n }\n }\n}\n\nconst registeredSearchers = [];\n\nfunction register(...args) {\n registeredSearchers.push(...args);\n}\n\nfunction createSearcher(pattern, options) {\n for (let i = 0, len = registeredSearchers.length; i < len; i += 1) {\n let searcherClass = registeredSearchers[i];\n if (searcherClass.condition(pattern, options)) {\n return new searcherClass(pattern, options)\n }\n }\n\n return new BitapSearch(pattern, options)\n}\n\nconst LogicalOperator = {\n AND: '$and',\n OR: '$or'\n};\n\nconst KeyType = {\n PATH: '$path',\n PATTERN: '$val'\n};\n\nconst isExpression = (query) =>\n !!(query[LogicalOperator.AND] || query[LogicalOperator.OR]);\n\nconst isPath = (query) => !!query[KeyType.PATH];\n\nconst isLeaf = (query) =>\n !isArray(query) && isObject(query) && !isExpression(query);\n\nconst convertToExplicit = (query) => ({\n [LogicalOperator.AND]: Object.keys(query).map((key) => ({\n [key]: query[key]\n }))\n});\n\n// When `auto` is `true`, the parse function will infer and initialize and add\n// the appropriate `Searcher` instance\nfunction parse(query, options, { auto = true } = {}) {\n const next = (query) => {\n let keys = Object.keys(query);\n\n const isQueryPath = isPath(query);\n\n if (!isQueryPath && keys.length > 1 && !isExpression(query)) {\n return next(convertToExplicit(query))\n }\n\n if (isLeaf(query)) {\n const key = isQueryPath ? query[KeyType.PATH] : keys[0];\n\n const pattern = isQueryPath ? query[KeyType.PATTERN] : query[key];\n\n if (!isString(pattern)) {\n throw new Error(LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY(key))\n }\n\n const obj = {\n keyId: createKeyId(key),\n pattern\n };\n\n if (auto) {\n obj.searcher = createSearcher(pattern, options);\n }\n\n return obj\n }\n\n let node = {\n children: [],\n operator: keys[0]\n };\n\n keys.forEach((key) => {\n const value = query[key];\n\n if (isArray(value)) {\n value.forEach((item) => {\n node.children.push(next(item));\n });\n }\n });\n\n return node\n };\n\n if (!isExpression(query)) {\n query = convertToExplicit(query);\n }\n\n return next(query)\n}\n\n// Practical scoring function\nfunction computeScore(\n results,\n { ignoreFieldNorm = Config.ignoreFieldNorm }\n) {\n results.forEach((result) => {\n let totalScore = 1;\n\n result.matches.forEach(({ key, norm, score }) => {\n const weight = key ? key.weight : null;\n\n totalScore *= Math.pow(\n score === 0 && weight ? Number.EPSILON : score,\n (weight || 1) * (ignoreFieldNorm ? 1 : norm)\n );\n });\n\n result.score = totalScore;\n });\n}\n\nfunction transformMatches(result, data) {\n const matches = result.matches;\n data.matches = [];\n\n if (!isDefined(matches)) {\n return\n }\n\n matches.forEach((match) => {\n if (!isDefined(match.indices) || !match.indices.length) {\n return\n }\n\n const { indices, value } = match;\n\n let obj = {\n indices,\n value\n };\n\n if (match.key) {\n obj.key = match.key.src;\n }\n\n if (match.idx > -1) {\n obj.refIndex = match.idx;\n }\n\n data.matches.push(obj);\n });\n}\n\nfunction transformScore(result, data) {\n data.score = result.score;\n}\n\nfunction format(\n results,\n docs,\n {\n includeMatches = Config.includeMatches,\n includeScore = Config.includeScore\n } = {}\n) {\n const transformers = [];\n\n if (includeMatches) transformers.push(transformMatches);\n if (includeScore) transformers.push(transformScore);\n\n return results.map((result) => {\n const { idx } = result;\n\n const data = {\n item: docs[idx],\n refIndex: idx\n };\n\n if (transformers.length) {\n transformers.forEach((transformer) => {\n transformer(result, data);\n });\n }\n\n return data\n })\n}\n\nclass Fuse {\n constructor(docs, options = {}, index) {\n this.options = { ...Config, ...options };\n\n if (\n this.options.useExtendedSearch &&\n !true\n ) {\n throw new Error(EXTENDED_SEARCH_UNAVAILABLE)\n }\n\n this._keyStore = new KeyStore(this.options.keys);\n\n this.setCollection(docs, index);\n }\n\n setCollection(docs, index) {\n this._docs = docs;\n\n if (index && !(index instanceof FuseIndex)) {\n throw new Error(INCORRECT_INDEX_TYPE)\n }\n\n this._myIndex =\n index ||\n createIndex(this.options.keys, this._docs, {\n getFn: this.options.getFn,\n fieldNormWeight: this.options.fieldNormWeight\n });\n }\n\n add(doc) {\n if (!isDefined(doc)) {\n return\n }\n\n this._docs.push(doc);\n this._myIndex.add(doc);\n }\n\n remove(predicate = (/* doc, idx */) => false) {\n const results = [];\n\n for (let i = 0, len = this._docs.length; i < len; i += 1) {\n const doc = this._docs[i];\n if (predicate(doc, i)) {\n this.removeAt(i);\n i -= 1;\n len -= 1;\n\n results.push(doc);\n }\n }\n\n return results\n }\n\n removeAt(idx) {\n this._docs.splice(idx, 1);\n this._myIndex.removeAt(idx);\n }\n\n getIndex() {\n return this._myIndex\n }\n\n search(query, { limit = -1 } = {}) {\n const {\n includeMatches,\n includeScore,\n shouldSort,\n sortFn,\n ignoreFieldNorm\n } = this.options;\n\n let results = isString(query)\n ? isString(this._docs[0])\n ? this._searchStringList(query)\n : this._searchObjectList(query)\n : this._searchLogical(query);\n\n computeScore(results, { ignoreFieldNorm });\n\n if (shouldSort) {\n results.sort(sortFn);\n }\n\n if (isNumber(limit) && limit > -1) {\n results = results.slice(0, limit);\n }\n\n return format(results, this._docs, {\n includeMatches,\n includeScore\n })\n }\n\n _searchStringList(query) {\n const searcher = createSearcher(query, this.options);\n const { records } = this._myIndex;\n const results = [];\n\n // Iterate over every string in the index\n records.forEach(({ v: text, i: idx, n: norm }) => {\n if (!isDefined(text)) {\n return\n }\n\n const { isMatch, score, indices } = searcher.searchIn(text);\n\n if (isMatch) {\n results.push({\n item: text,\n idx,\n matches: [{ score, value: text, norm, indices }]\n });\n }\n });\n\n return results\n }\n\n _searchLogical(query) {\n\n const expression = parse(query, this.options);\n\n const evaluate = (node, item, idx) => {\n if (!node.children) {\n const { keyId, searcher } = node;\n\n const matches = this._findMatches({\n key: this._keyStore.get(keyId),\n value: this._myIndex.getValueForItemAtKeyId(item, keyId),\n searcher\n });\n\n if (matches && matches.length) {\n return [\n {\n idx,\n item,\n matches\n }\n ]\n }\n\n return []\n }\n\n const res = [];\n for (let i = 0, len = node.children.length; i < len; i += 1) {\n const child = node.children[i];\n const result = evaluate(child, item, idx);\n if (result.length) {\n res.push(...result);\n } else if (node.operator === LogicalOperator.AND) {\n return []\n }\n }\n return res\n };\n\n const records = this._myIndex.records;\n const resultMap = {};\n const results = [];\n\n records.forEach(({ $: item, i: idx }) => {\n if (isDefined(item)) {\n let expResults = evaluate(expression, item, idx);\n\n if (expResults.length) {\n // Dedupe when adding\n if (!resultMap[idx]) {\n resultMap[idx] = { idx, item, matches: [] };\n results.push(resultMap[idx]);\n }\n expResults.forEach(({ matches }) => {\n resultMap[idx].matches.push(...matches);\n });\n }\n }\n });\n\n return results\n }\n\n _searchObjectList(query) {\n const searcher = createSearcher(query, this.options);\n const { keys, records } = this._myIndex;\n const results = [];\n\n // List is Array<Object>\n records.forEach(({ $: item, i: idx }) => {\n if (!isDefined(item)) {\n return\n }\n\n let matches = [];\n\n // Iterate over every key (i.e, path), and fetch the value at that key\n keys.forEach((key, keyIndex) => {\n matches.push(\n ...this._findMatches({\n key,\n value: item[keyIndex],\n searcher\n })\n );\n });\n\n if (matches.length) {\n results.push({\n idx,\n item,\n matches\n });\n }\n });\n\n return results\n }\n _findMatches({ key, value, searcher }) {\n if (!isDefined(value)) {\n return []\n }\n\n let matches = [];\n\n if (isArray(value)) {\n value.forEach(({ v: text, i: idx, n: norm }) => {\n if (!isDefined(text)) {\n return\n }\n\n const { isMatch, score, indices } = searcher.searchIn(text);\n\n if (isMatch) {\n matches.push({\n score,\n key,\n value: text,\n idx,\n norm,\n indices\n });\n }\n });\n } else {\n const { v: text, n: norm } = value;\n\n const { isMatch, score, indices } = searcher.searchIn(text);\n\n if (isMatch) {\n matches.push({ score, key, value: text, norm, indices });\n }\n }\n\n return matches\n }\n}\n\nFuse.version = '7.1.0';\nFuse.createIndex = createIndex;\nFuse.parseIndex = parseIndex;\nFuse.config = Config;\n\n{\n Fuse.parseQuery = parse;\n}\n\n{\n register(ExtendedSearch);\n}\n\nexport { Fuse as default };\n","/**\n * HTTP primitives — base URL, headers, token helper, typed error.\n * Every api/* module imports from here; nothing else should.\n */\nimport type { UnnoodleConfig } from \"../types/config\";\n\nconst DEFAULT_BASE_URL = \"https://api.unnoodle.com\";\n\nexport function resolvedBaseUrl(config: UnnoodleConfig): string {\n return config.baseUrl?.replace(/\\/$/, \"\") ?? DEFAULT_BASE_URL;\n}\n\n/**\n * Builds headers for API-key-authenticated requests.\n * Auth token is resolved at call-time — never stored.\n */\nexport function apiKeyHeaders(config: UnnoodleConfig): Record<string, string> {\n return {\n \"Content-Type\": \"application/json\",\n \"X-Unnoodle-Api-Key\": config.apiKey,\n };\n}\n\n/**\n * Safely calls config.getAuthToken without throwing.\n * Returns null on any error or when not configured.\n */\nexport function safeGetToken(config: UnnoodleConfig): string | null {\n if (typeof config.getAuthToken !== \"function\") return null;\n try {\n return config.getAuthToken() ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Typed error for API failures.\n * Lets consumers distinguish HTTP errors from network errors.\n */\nexport class ApiError extends Error {\n public readonly status: number;\n public readonly body: string;\n\n constructor(message: string, status: number, body: string) {\n super(message);\n this.name = \"ApiError\";\n this.status = status;\n this.body = body;\n }\n}\n","import type {\n UnnoodleConfig,\n WidgetInitResponse,\n GlossaryTerm,\n} from \"../types/config\";\nimport { resolvedBaseUrl, apiKeyHeaders, safeGetToken, ApiError } from \"./http\";\n\n// ---------------------------------------------------------------------------\n// POST /api/init — SDK widget initialization\n// ---------------------------------------------------------------------------\n\n/**\n * Initializes the widget: resolves/creates the context and returns its full\n * glossary in one round-trip.\n *\n * Authentication: X-Unnoodle-Api-Key header (no user JWT required for public\n * contexts; JWT may optionally personalise results).\n */\nexport async function initWidget(\n config: UnnoodleConfig,\n userToken?: string | null,\n): Promise<WidgetInitResponse> {\n const url = `${resolvedBaseUrl(config)}/api/init`;\n const headers: Record<string, string> = apiKeyHeaders(config);\n const token = userToken !== undefined ? userToken : safeGetToken(config);\n\n if (token) {\n headers[\"Authorization\"] = `Bearer ${token}`;\n }\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ context: config.context }),\n });\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle /api/init error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n\n return response.json() as Promise<WidgetInitResponse>;\n}\n\n// ---------------------------------------------------------------------------\n// GET /api/contexts/:id/glossary/search?q= — instant server-side search\n// ---------------------------------------------------------------------------\n\n/**\n * Searches glossary terms within a specific context on the backend.\n */\nexport async function searchTerms(\n config: UnnoodleConfig,\n contextId: number,\n query: string,\n userToken?: string | null,\n): Promise<GlossaryTerm[]> {\n const url = `${resolvedBaseUrl(config)}/api/contexts/${contextId}/glossary/search?q=${encodeURIComponent(query)}`;\n const headers: Record<string, string> = apiKeyHeaders(config);\n const token = userToken !== undefined ? userToken : safeGetToken(config);\n\n if (token) {\n headers[\"Authorization\"] = `Bearer ${token}`;\n }\n\n const response = await fetch(url, { headers });\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle search error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n\n return response.json() as Promise<GlossaryTerm[]>;\n}\n","import type {\n UnnoodleConfig,\n LoginRequest,\n AuthResponse,\n SsoProviders,\n} from \"../types/config\";\nimport { resolvedBaseUrl, apiKeyHeaders, ApiError } from \"./http\";\n\n// ---------------------------------------------------------------------------\n// POST /api/auth/login — in-panel user login\n// ---------------------------------------------------------------------------\n\n/**\n * Authenticates a user via the Unnoodle backend.\n * The returned token must be held in memory by the caller — never written to\n * localStorage or sessionStorage.\n */\nexport async function loginUser(\n config: UnnoodleConfig,\n credentials: LoginRequest,\n): Promise<AuthResponse> {\n const url = `${resolvedBaseUrl(config)}/api/auth/login`;\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: apiKeyHeaders(config),\n body: JSON.stringify(credentials),\n });\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle login error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n\n return response.json() as Promise<AuthResponse>;\n}\n\n// ---------------------------------------------------------------------------\n// GET /api/auth/oauth/providers — SSO provider availability for the tenant\n// ---------------------------------------------------------------------------\n\n/**\n * Returns which SSO providers are enabled for the current tenant.\n * Never throws — on any error (network, 4xx, 5xx) returns both providers\n * as disabled so the widget gracefully falls back to password-only login.\n */\nexport async function fetchOAuthProviders(\n config: UnnoodleConfig,\n): Promise<SsoProviders> {\n const url = `${resolvedBaseUrl(config)}/api/auth/oauth/providers`;\n try {\n const response = await fetch(url, { headers: apiKeyHeaders(config) });\n if (!response.ok) {\n return { googleEnabled: false, microsoftEnabled: false };\n }\n return response.json() as Promise<SsoProviders>;\n } catch {\n return { googleEnabled: false, microsoftEnabled: false };\n }\n}\n","import type {\n UnnoodleConfig,\n DiscussionPost,\n GlossaryTerm,\n GlossaryTermUpdateRequest,\n} from \"../types/config\";\nimport { resolvedBaseUrl, apiKeyHeaders, safeGetToken, ApiError } from \"./http\";\n\n// ---------------------------------------------------------------------------\n// GET /api/glossary/:termId/discussions — read discussion thread\n// ---------------------------------------------------------------------------\n\n/**\n * Fetches the discussion thread for a term. Public read — no JWT required,\n * but a token will be forwarded if provided.\n */\nexport async function getDiscussions(\n config: UnnoodleConfig,\n termId: number,\n userToken?: string | null,\n): Promise<DiscussionPost[]> {\n const url = `${resolvedBaseUrl(config)}/api/glossary/${termId}/discussions`;\n const headers: Record<string, string> = apiKeyHeaders(config);\n const token = userToken !== undefined ? userToken : safeGetToken(config);\n if (token) headers[\"Authorization\"] = `Bearer ${token}`;\n\n const response = await fetch(url, { headers });\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle discussions error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n return response.json() as Promise<DiscussionPost[]>;\n}\n\n// ---------------------------------------------------------------------------\n// POST /api/glossary/:termId/discussions — post a comment (requires JWT)\n// ---------------------------------------------------------------------------\n\n/**\n * Posts a comment (question) on a term. Requires a valid user JWT.\n */\nexport async function postComment(\n config: UnnoodleConfig,\n termId: number,\n body: string,\n userToken: string,\n): Promise<DiscussionPost> {\n const url = `${resolvedBaseUrl(config)}/api/glossary/${termId}/discussions`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ body }),\n });\n if (!response.ok) {\n const bodyText = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle post comment error: ${response.status} ${response.statusText}`,\n response.status,\n bodyText,\n );\n }\n return response.json() as Promise<DiscussionPost>;\n}\n\n// ---------------------------------------------------------------------------\n// PUT /api/glossary/:termId — edit a term (requires JWT + MEMBER/ADMIN role)\n// ---------------------------------------------------------------------------\n\n/**\n * Updates an existing glossary term. Requires a valid user JWT.\n * The server enforces that the caller has MEMBER or ADMIN role.\n */\nexport async function updateTerm(\n config: UnnoodleConfig,\n termId: number,\n updates: GlossaryTermUpdateRequest,\n userToken: string,\n): Promise<GlossaryTerm> {\n const url = `${resolvedBaseUrl(config)}/api/glossary/${termId}`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n const response = await fetch(url, {\n method: \"PUT\",\n headers,\n body: JSON.stringify(updates),\n });\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle update term error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n return response.json() as Promise<GlossaryTerm>;\n}\n\n// ---------------------------------------------------------------------------\n// POST /api/sdk/glossary/ai-generate — generate an AI definition for a term\n// ---------------------------------------------------------------------------\n\n/**\n * Requests an AI-generated definition for a candidate term.\n * Requires both API key (for tenant context) and user JWT (write gate).\n * Does NOT persist anything — backend returns definition only.\n */\nexport async function generateAiDefinition(\n config: UnnoodleConfig,\n term: string,\n pageContext: string,\n pageUrl: string,\n userToken: string,\n): Promise<string> {\n const url = `${resolvedBaseUrl(config)}/api/sdk/glossary/ai-generate`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ term, context: pageContext, pageUrl }),\n });\n } catch (err) {\n throw new ApiError(\n err instanceof Error ? err.message : \"Network error\",\n 0,\n \"\",\n );\n }\n\n if (!response.ok) {\n const bodyText = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle ai-generate error: ${response.status} ${response.statusText}`,\n response.status,\n bodyText,\n );\n }\n\n const data = (await response.json()) as { definition: string };\n return data.definition;\n}\n\n// ---------------------------------------------------------------------------\n// POST /api/contexts/:contextId/glossary — submit a suggested term (PENDING)\n// ---------------------------------------------------------------------------\n\n/**\n * Submits a user-reviewed AI-generated definition as a PENDING term.\n * Requires user JWT. The term will await workspace admin approval.\n */\nexport async function createSuggestedTerm(\n config: UnnoodleConfig,\n contextId: number,\n term: string,\n definition: string,\n userToken: string,\n): Promise<GlossaryTerm> {\n const url = `${resolvedBaseUrl(config)}/api/contexts/${contextId}/glossary`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n term,\n definition,\n status: \"PENDING\",\n aiGenerated: true,\n }),\n });\n } catch (err) {\n throw new ApiError(\n err instanceof Error ? err.message : \"Network error\",\n 0,\n \"\",\n );\n }\n\n if (!response.ok) {\n const bodyText = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle create suggested term error: ${response.status} ${response.statusText}`,\n response.status,\n bodyText,\n );\n }\n\n return response.json() as Promise<GlossaryTerm>;\n}\n\n// ---------------------------------------------------------------------------\n// POST /api/contexts/:contextId/glossary — create a new glossary term (user)\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a new glossary term (ACTIVE status, not AI-generated).\n * Requires user JWT.\n */\nexport async function createGlossaryTerm(\n config: UnnoodleConfig,\n contextId: number,\n term: string,\n definition: string,\n userToken: string,\n): Promise<GlossaryTerm> {\n const url = `${resolvedBaseUrl(config)}/api/contexts/${contextId}/glossary`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ term, definition }),\n });\n } catch (err) {\n throw new ApiError(\n err instanceof Error ? err.message : \"Network error\",\n 0,\n \"\",\n );\n }\n\n if (!response.ok) {\n const bodyText = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle create glossary term error: ${response.status} ${response.statusText}`,\n response.status,\n bodyText,\n );\n }\n\n return response.json() as Promise<GlossaryTerm>;\n}\n","import type {\n UnnoodleConfig,\n CreateProductMemoryPayload,\n AddProductMemoryEntryPayload,\n UpdateProductMemoryEntryPayload,\n UpdateProductMemoryTitlePayload,\n ProductMemoryDetailResponse,\n ProductMemoryResponse,\n ProductMemoriesPageResponse,\n} from \"../types/config\";\nimport { resolvedBaseUrl, apiKeyHeaders, safeGetToken, ApiError } from \"./http\";\n\n// ---------------------------------------------------------------------------\n// POST /api/product-memories — create memory with first entry\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a new ProductMemory with title + first stage entry.\n */\nexport async function createProductMemory(\n config: UnnoodleConfig,\n payload: CreateProductMemoryPayload,\n userToken: string,\n): Promise<ProductMemoryDetailResponse> {\n const url = `${resolvedBaseUrl(config)}/api/product-memories`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(payload),\n });\n } catch (err) {\n throw new ApiError(\n err instanceof Error ? err.message : \"Network error\",\n 0,\n \"\",\n );\n }\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle create-product-memory error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n\n return response.json() as Promise<ProductMemoryDetailResponse>;\n}\n\n// ---------------------------------------------------------------------------\n// POST /api/product-memories/:id/entries — add a stage entry\n// ---------------------------------------------------------------------------\n\nexport async function addProductMemoryEntry(\n config: UnnoodleConfig,\n memoryId: number,\n payload: AddProductMemoryEntryPayload,\n userToken: string,\n): Promise<ProductMemoryDetailResponse> {\n const url = `${resolvedBaseUrl(config)}/api/product-memories/${memoryId}/entries`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle add-entry error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n\n return response.json() as Promise<ProductMemoryDetailResponse>;\n}\n\n// ---------------------------------------------------------------------------\n// PATCH /api/product-memories/:id/entries/:entryId — update explanation\n// ---------------------------------------------------------------------------\n\nexport async function updateProductMemoryEntry(\n config: UnnoodleConfig,\n memoryId: number,\n entryId: number,\n payload: UpdateProductMemoryEntryPayload,\n userToken: string,\n): Promise<ProductMemoryDetailResponse> {\n const url = `${resolvedBaseUrl(config)}/api/product-memories/${memoryId}/entries/${entryId}`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n const response = await fetch(url, {\n method: \"PATCH\",\n headers,\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle update-entry error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n\n return response.json() as Promise<ProductMemoryDetailResponse>;\n}\n\n// ---------------------------------------------------------------------------\n// PATCH /api/product-memories/:id — rename memory\n// ---------------------------------------------------------------------------\n\nexport async function updateProductMemoryTitle(\n config: UnnoodleConfig,\n id: number,\n payload: UpdateProductMemoryTitlePayload,\n userToken: string,\n): Promise<ProductMemoryDetailResponse> {\n const url = `${resolvedBaseUrl(config)}/api/product-memories/${id}`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n const response = await fetch(url, {\n method: \"PATCH\",\n headers,\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle rename-memory error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n\n return response.json() as Promise<ProductMemoryDetailResponse>;\n}\n\n// ---------------------------------------------------------------------------\n// GET /api/product-memories?page= — paginated list\n// ---------------------------------------------------------------------------\n\nexport async function listProductMemories(\n config: UnnoodleConfig,\n page: number,\n userToken?: string | null,\n): Promise<ProductMemoriesPageResponse> {\n const url = `${resolvedBaseUrl(config)}/api/product-memories?page=${page}&size=20`;\n const headers: Record<string, string> = { ...apiKeyHeaders(config) };\n const token = userToken !== undefined ? userToken : safeGetToken(config);\n\n if (token) {\n headers[\"Authorization\"] = `Bearer ${token}`;\n }\n\n const response = await fetch(url, { headers });\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle list-memories error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n\n return response.json() as Promise<ProductMemoriesPageResponse>;\n}\n\n// ---------------------------------------------------------------------------\n// GET /api/product-memories/:id — full detail\n// ---------------------------------------------------------------------------\n\nexport async function getProductMemory(\n config: UnnoodleConfig,\n id: number,\n userToken?: string | null,\n): Promise<ProductMemoryDetailResponse> {\n const url = `${resolvedBaseUrl(config)}/api/product-memories/${id}`;\n const headers: Record<string, string> = { ...apiKeyHeaders(config) };\n\n if (userToken) {\n headers[\"Authorization\"] = `Bearer ${userToken}`;\n }\n\n const response = await fetch(url, { headers });\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle get-memory error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n\n return response.json() as Promise<ProductMemoryDetailResponse>;\n}\n\n// ---------------------------------------------------------------------------\n// DELETE /api/product-memories/:id — delete memory\n// ---------------------------------------------------------------------------\n\nexport async function deleteProductMemory(\n config: UnnoodleConfig,\n memoryId: number,\n userToken: string,\n): Promise<void> {\n const url = `${resolvedBaseUrl(config)}/api/product-memories/${memoryId}`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n const response = await fetch(url, { method: \"DELETE\", headers });\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle delete-memory error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n // 204 No Content — no body to parse\n}\n\n// ---------------------------------------------------------------------------\n// DELETE /api/product-memories/:id/entries/:entryId — delete entry\n// ---------------------------------------------------------------------------\n\nexport async function deleteProductMemoryEntry(\n config: UnnoodleConfig,\n memoryId: number,\n entryId: number,\n userToken: string,\n): Promise<ProductMemoryDetailResponse> {\n const url = `${resolvedBaseUrl(config)}/api/product-memories/${memoryId}/entries/${entryId}`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n const response = await fetch(url, { method: \"DELETE\", headers });\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle delete-entry error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n\n return response.json() as Promise<ProductMemoryDetailResponse>;\n}\n","import type { UnnoodleConfig, ContextDiscussion } from \"../types/config\";\nimport { resolvedBaseUrl, apiKeyHeaders, safeGetToken, ApiError } from \"./http\";\n\n// ---------------------------------------------------------------------------\n// GET /api/contexts/:contextId/discussions — context-level clarification thread\n// ---------------------------------------------------------------------------\n\n/**\n * Fetches the full clarification thread for a context.\n * Readable by SDK API keys and authenticated users alike.\n */\nexport async function fetchContextDiscussions(\n config: UnnoodleConfig,\n contextId: number,\n userToken?: string | null,\n): Promise<ContextDiscussion[]> {\n const url = `${resolvedBaseUrl(config)}/api/contexts/${contextId}/discussions`;\n const headers: Record<string, string> = apiKeyHeaders(config);\n const token = userToken !== undefined ? userToken : safeGetToken(config);\n if (token) headers[\"Authorization\"] = `Bearer ${token}`;\n\n const response = await fetch(url, { headers });\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle GET context discussions error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n return response.json() as Promise<ContextDiscussion[]>;\n}\n\n// ---------------------------------------------------------------------------\n// POST /api/contexts/:contextId/discussions — post a clarification question\n// ---------------------------------------------------------------------------\n\n/**\n * Posts a new top-level clarification question on a context.\n * Requires a logged-in user JWT — SDK API keys are rejected by the backend.\n */\nexport async function postContextDiscussion(\n config: UnnoodleConfig,\n contextId: number,\n body: string,\n userToken: string,\n): Promise<ContextDiscussion> {\n const url = `${resolvedBaseUrl(config)}/api/contexts/${contextId}/discussions`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ body }),\n });\n\n if (!response.ok) {\n const responseBody = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle POST context discussion error: ${response.status} ${response.statusText}`,\n response.status,\n responseBody,\n );\n }\n return response.json() as Promise<ContextDiscussion>;\n}\n\n// ---------------------------------------------------------------------------\n// POST /api/contexts/:contextId/discussions/:questionId/replies\n// ---------------------------------------------------------------------------\n\n/**\n * Posts a reply to an existing clarification question.\n * Requires a logged-in user JWT.\n */\nexport async function postContextReply(\n config: UnnoodleConfig,\n contextId: number,\n questionId: number,\n body: string,\n userToken: string,\n): Promise<ContextDiscussion> {\n const url = `${resolvedBaseUrl(config)}/api/contexts/${contextId}/discussions/${questionId}/replies`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ body }),\n });\n\n if (!response.ok) {\n const responseBody = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle POST context reply error: ${response.status} ${response.statusText}`,\n response.status,\n responseBody,\n );\n }\n return response.json() as Promise<ContextDiscussion>;\n}\n","/**\n * elementSnapshot\n *\n * Single responsibility:\n * Capture a frozen, self-contained visual representation of a live\n * DOM element — without touching the host application.\n *\n * Strategy (Option A — deep clone + inline computed styles):\n * 1. Clone the element subtree.\n * 2. Walk every node in the clone and copy window.getComputedStyle() as\n * inline styles so the clone is visually independent of host stylesheets.\n * 3. Absolutify relative image src values so images still load when the\n * clone is rendered inside the panel Shadow DOM.\n * 4. Return the clone's outerHTML alongside structured metadata.\n *\n * Known limitations (all browsers, by design):\n * - Host @font-face fonts fall back to the system font inside Shadow DOM.\n * - <canvas> contents render blank (canvas pixel data is not clonable).\n * - Interactive state (:hover, :focus) is not preserved — frozen snapshot.\n */\n\n// ---------------------------------------------------------------------------\n// Public contracts\n// ---------------------------------------------------------------------------\n\n/**\n * Structured representation of a captured DOM element.\n * The `html` field contains the style-inlined clone; all other fields\n * provide machine-readable metadata for storage and display.\n */\nexport interface ElementSnapshot {\n /** outerHTML of the style-inlined clone — safe to inject into a container. */\n html: string;\n /** Original element width in CSS pixels at time of capture. */\n naturalWidth: number;\n /** Original element height in CSS pixels at time of capture. */\n naturalHeight: number;\n /** Lower-case tag name, e.g. \"button\", \"section\", \"div\". */\n tag: string;\n /** ARIA role — explicit attribute value, or inferred from tag. Null if unknown. */\n role: string | null;\n /** Trimmed visible text content of the element and its descendants. */\n text: string;\n /** Bounding rect in viewport coordinates at time of capture. */\n rect: DOMRect;\n /** Element's id attribute — most stable identifier for targeting. Undefined if absent. */\n id?: string;\n /** Element's data-testid attribute — second-most stable identifier. Undefined if absent. */\n dataTestId?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Role inference\n// ---------------------------------------------------------------------------\n\n/** Implicit ARIA roles for common HTML tags (subset covering most business UI). */\nconst IMPLICIT_ROLES: Record<string, string> = {\n button: \"button\",\n a: \"link\",\n input: \"textbox\",\n select: \"listbox\",\n textarea: \"textbox\",\n img: \"img\",\n table: \"table\",\n nav: \"navigation\",\n main: \"main\",\n header: \"banner\",\n footer: \"contentinfo\",\n aside: \"complementary\",\n section: \"region\",\n form: \"form\",\n h1: \"heading\",\n h2: \"heading\",\n h3: \"heading\",\n h4: \"heading\",\n h5: \"heading\",\n h6: \"heading\",\n li: \"listitem\",\n ul: \"list\",\n ol: \"list\",\n};\n\nfunction inferRole(el: HTMLElement): string | null {\n const explicit = el.getAttribute(\"role\");\n if (explicit) return explicit;\n return IMPLICIT_ROLES[el.tagName.toLowerCase()] ?? null;\n}\n\n// ---------------------------------------------------------------------------\n// Style inlining\n// ---------------------------------------------------------------------------\n\n/**\n * Copy all computed style properties from a live element onto its clone node.\n * This makes the clone visually self-contained — it no longer needs the host\n * app's stylesheets to look correct.\n */\nfunction inlineComputedStyles(source: Element, clone: Element): void {\n if (!(source instanceof HTMLElement) || !(clone instanceof HTMLElement))\n return;\n\n const computed = window.getComputedStyle(source);\n for (const prop of Array.from(computed)) {\n try {\n clone.style.setProperty(prop, computed.getPropertyValue(prop));\n } catch {\n // Some properties are read-only in certain browsers — skip silently.\n }\n }\n}\n\n/**\n * Recursively inline computed styles on an element and all its descendants.\n * Source and clone trees must have identical structure (produced by cloneNode).\n */\nfunction inlineStylesDeep(source: Element, clone: Element): void {\n inlineComputedStyles(source, clone);\n\n const sourceChildren = source.children;\n const cloneChildren = clone.children;\n\n for (let i = 0; i < sourceChildren.length; i++) {\n const srcChild = sourceChildren[i];\n const clnChild = cloneChildren[i];\n if (srcChild && clnChild) {\n inlineStylesDeep(srcChild, clnChild);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// URL absolutification\n// ---------------------------------------------------------------------------\n\n/**\n * Convert relative src/href values on media elements to absolute URLs so\n * they continue to load when rendered inside the panel's Shadow DOM.\n */\nfunction absolutifyUrls(clone: Element): void {\n clone.querySelectorAll(\"img[src]\").forEach((img) => {\n const src = img.getAttribute(\"src\");\n if (src && !src.startsWith(\"http\") && !src.startsWith(\"data:\")) {\n try {\n img.setAttribute(\"src\", new URL(src, window.location.href).href);\n } catch {\n // Malformed URL — leave as-is.\n }\n }\n });\n\n clone.querySelectorAll(\"source[srcset]\").forEach((source) => {\n const srcset = source.getAttribute(\"srcset\");\n if (srcset) {\n const resolved = srcset\n .split(\",\")\n .map((part) => {\n const [url, descriptor] = part.trim().split(/\\s+/);\n if (!url || url.startsWith(\"http\") || url.startsWith(\"data:\"))\n return part;\n try {\n const abs = new URL(url, window.location.href).href;\n return descriptor ? `${abs} ${descriptor}` : abs;\n } catch {\n return part;\n }\n })\n .join(\", \");\n source.setAttribute(\"srcset\", resolved);\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Defensive pre-send strip\n// ---------------------------------------------------------------------------\n\n/**\n * Removes executable content from a DOM clone before the HTML string is\n * handed off to the server. This is defense-in-depth only — the authoritative\n * sanitization happens server-side in SnapshotHtmlSanitizer.\n *\n * Operates on the clone (mutates it), never touches the source element.\n */\nfunction defensiveStrip(clone: HTMLElement): void {\n // Remove all <script> elements\n clone.querySelectorAll(\"script\").forEach((s) => s.remove());\n\n // Remove on* event-handler attributes from every element in the subtree\n const all = [clone, ...Array.from(clone.querySelectorAll(\"*\"))];\n for (const el of all) {\n const toRemove: string[] = [];\n for (const attr of Array.from(el.attributes)) {\n if (/^on/i.test(attr.name)) toRemove.push(attr.name);\n }\n toRemove.forEach((name) => el.removeAttribute(name));\n }\n}\n\n// ---------------------------------------------------------------------------\n// Main export\n// ---------------------------------------------------------------------------\n\n/**\n * Captures a frozen snapshot of the given element.\n *\n * The returned `html` string contains a style-inlined clone that renders\n * visually near-identically to the original element, with no dependency on\n * the host application's stylesheets.\n *\n * @param el The live host-app element to snapshot. Must be attached to DOM.\n */\nexport function snapshotElement(el: HTMLElement): ElementSnapshot {\n const rect = el.getBoundingClientRect();\n\n // Deep clone (true = include all descendants)\n const clone = el.cloneNode(true) as HTMLElement;\n\n // Inline all computed styles recursively\n inlineStylesDeep(el, clone);\n\n // Resolve relative media URLs\n absolutifyUrls(clone);\n\n // Defense-in-depth: strip executable content before returning the HTML string\n defensiveStrip(clone);\n\n return {\n html: clone.outerHTML,\n naturalWidth: rect.width,\n naturalHeight: rect.height,\n tag: el.tagName.toLowerCase(),\n role: inferRole(el),\n text: (el.textContent ?? \"\").trim().replace(/\\s+/g, \" \"),\n rect,\n id: el.id || undefined,\n dataTestId: el.getAttribute(\"data-testid\") || undefined,\n };\n}\n","/**\n * ElementPicker\n *\n * Single responsibility:\n * Let the user select any element on the host application by hovering\n * and clicking — without modifying the host application's DOM or code.\n *\n * Behaviour:\n * - On start(): attaches mouseover + click listeners to document.\n * - A floating highlight ring (position:fixed) tracks the hovered element.\n * - On click: fires onPick(element), removes all listeners and the ring.\n * - Guards: the Unnoodle panel host and the highlight ring itself are\n * excluded from selection so the user cannot accidentally pick our own UI.\n * - stop(): externally cancels pick mode and cleans up.\n *\n * Zero coupling to panel, API, or state machine — purely a DOM interaction\n * tool that reports back via callbacks.\n */\n\n// ---------------------------------------------------------------------------\n// Public contracts\n// ---------------------------------------------------------------------------\n\nexport interface ElementPickerCallbacks {\n /** Fired when the user clicks an element. Picker has already torn itself down. */\n onPick: (element: HTMLElement) => void;\n /** Fired when stop() is called externally (user cancelled). */\n onCancel: () => void;\n}\n\nexport interface IElementPicker {\n /** Begin pick mode — attaches listeners and renders highlight ring. */\n start(): void;\n /** End pick mode — removes listeners and highlight ring, fires onCancel. */\n stop(): void;\n}\n\n// ---------------------------------------------------------------------------\n// Highlight ring styles\n// ---------------------------------------------------------------------------\n\nconst RING_ID = \"unnoodle-pick-ring\";\n\nconst RING_CSS = `\n position: fixed;\n pointer-events: none;\n z-index: 2147483645;\n border: 2px dashed #5C4EFA;\n border-radius: 4px;\n background: rgba(92, 78, 250, 0.06);\n transition: top 0.05s, left 0.05s, width 0.05s, height 0.05s;\n box-shadow: 0 0 0 9999px rgba(0,0,0,0.08);\n`;\n\n// IDs and class names belonging to the Unnoodle widget — never pick these.\nconst EXCLUDED_IDS = new Set([\n \"unnoodle-btn-host\",\n \"unnoodle-panel-host\",\n RING_ID,\n]);\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\nexport class ElementPicker implements IElementPicker {\n private callbacks: ElementPickerCallbacks;\n private ring: HTMLElement | null = null;\n private currentTarget: HTMLElement | null = null;\n\n // Bound references so the same function pointer can be removed\n private boundMouseover = this.handleMouseover.bind(this);\n private boundClick = this.handleClick.bind(this);\n private boundKeydown = this.handleKeydown.bind(this);\n\n constructor(callbacks: ElementPickerCallbacks) {\n this.callbacks = callbacks;\n }\n\n // ── Public API ────────────────────────────────────────────────────────────\n\n start(): void {\n this.createRing();\n document.addEventListener(\"mouseover\", this.boundMouseover, true);\n document.addEventListener(\"click\", this.boundClick, true);\n document.addEventListener(\"keydown\", this.boundKeydown, true);\n }\n\n stop(): void {\n this.teardown();\n this.callbacks.onCancel();\n }\n\n // ── Internal ──────────────────────────────────────────────────────────────\n\n private createRing(): void {\n const ring = document.createElement(\"div\");\n ring.id = RING_ID;\n ring.setAttribute(\"data-testid\", \"unnoodle-pick-ring\");\n ring.style.cssText = RING_CSS;\n // Set critical properties explicitly so they are always readable,\n // even in environments (jsdom) that do not parse all cssText values.\n ring.style.pointerEvents = \"none\";\n ring.style.display = \"none\"; // hidden until first hover\n document.body.appendChild(ring);\n this.ring = ring;\n }\n\n private removeRing(): void {\n this.ring?.remove();\n this.ring = null;\n }\n\n private teardown(): void {\n document.removeEventListener(\"mouseover\", this.boundMouseover, true);\n document.removeEventListener(\"click\", this.boundClick, true);\n document.removeEventListener(\"keydown\", this.boundKeydown, true);\n this.removeRing();\n this.currentTarget = null;\n // Restore host-app cursor\n document.documentElement.style.removeProperty(\"cursor\");\n }\n\n private isExcluded(el: HTMLElement): boolean {\n // Walk up the tree — exclude if any ancestor is an Unnoodle host\n let node: HTMLElement | null = el;\n while (node) {\n if (EXCLUDED_IDS.has(node.id)) return true;\n node = node.parentElement;\n }\n return false;\n }\n\n private handleMouseover(e: Event): void {\n const el = e.target as HTMLElement;\n if (!el || this.isExcluded(el)) return;\n\n this.currentTarget = el;\n document.documentElement.style.cursor = \"crosshair\";\n\n if (!this.ring) return;\n const rect = el.getBoundingClientRect();\n this.ring.style.display = \"block\";\n this.ring.style.top = `${rect.top}px`;\n this.ring.style.left = `${rect.left}px`;\n this.ring.style.width = `${rect.width}px`;\n this.ring.style.height = `${rect.height}px`;\n }\n\n private handleClick(e: Event): void {\n const el = e.target as HTMLElement;\n if (!el || this.isExcluded(el)) return;\n\n // Prevent the host app from acting on this click\n e.preventDefault();\n e.stopPropagation();\n\n this.teardown();\n this.callbacks.onPick(el);\n }\n\n private handleKeydown(e: KeyboardEvent): void {\n // Escape cancels pick mode\n if (e.key === \"Escape\") {\n this.stop();\n }\n }\n}\n","/**\n * OverlayArrow\n *\n * Single responsibility:\n * Draw and manage a single dotted directed SVG arrow from a source rect\n * (panel edge) to a target rect (captured element on the host app),\n * rendered in a full-viewport fixed SVG overlay.\n *\n * Design decisions:\n * - One `<svg>` element is injected into document.body with\n * position:fixed, pointer-events:none, full viewport coverage.\n * - Arrow is a `<path>` with stroke-dasharray for the dotted effect,\n * plus a small arrowhead `<marker>`.\n * - update() recalculates the path from new rects (call on scroll/resize).\n * - remove() tears down the SVG and any listeners.\n * - Only one arrow at a time — calling draw() again replaces the previous.\n */\n\n// ---------------------------------------------------------------------------\n// Public contracts\n// ---------------------------------------------------------------------------\n\nexport interface IOverlayArrow {\n /** Draw the arrow. Replaces any previously drawn arrow. */\n draw(fromRect: DOMRect, toRect: DOMRect): void;\n /** Recalculate position (call on scroll / resize). */\n update(fromRect: DOMRect, toRect: DOMRect): void;\n /** Remove the SVG overlay from the DOM entirely. */\n remove(): void;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst SVG_ID = \"unnoodle-overlay-arrow\";\nconst ARROW_COLOR = \"#5C4EFA\";\nconst STROKE_WIDTH = 1.5;\nconst DASH = \"5 4\";\nconst MARKER_ID = \"unn-arrow-head\";\n\n// ---------------------------------------------------------------------------\n// Path computation\n// ---------------------------------------------------------------------------\n\n/**\n * Compute a smooth cubic bezier path between the panel edge and the target\n * element edge, choosing the shortest route based on which side the panel is on.\n *\n * - Panel on the LEFT → start: panel right edge → end: element left edge\n * - Panel on the RIGHT → start: panel left edge → end: element right edge\n *\n * orient=\"auto\" on the marker means the arrowhead rotates automatically to\n * match the path direction, so no extra marker changes are needed.\n */\nfunction computePath(from: DOMRect, to: DOMRect): string {\n const panelIsRight = from.left > to.right;\n\n // Start from the panel edge that faces the target element\n const x1 = panelIsRight ? from.left : from.right;\n const y1 = from.top + from.height / 2;\n\n // End at the target edge that faces the panel\n const x2 = panelIsRight ? to.right : to.left;\n const y2 = to.top + to.height / 2;\n\n // Control points — horizontal tension proportional to horizontal distance\n const tension = Math.abs(x2 - x1) * 0.4;\n const cx1 = panelIsRight ? x1 - tension : x1 + tension;\n const cx2 = panelIsRight ? x2 + tension : x2 - tension;\n\n return `M ${x1} ${y1} C ${cx1} ${y1}, ${cx2} ${y2}, ${x2} ${y2}`;\n}\n\n// ---------------------------------------------------------------------------\n// SVG construction\n// ---------------------------------------------------------------------------\n\nfunction buildSvg(): SVGSVGElement {\n const svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n svg.id = SVG_ID;\n svg.setAttribute(\"data-testid\", \"unnoodle-overlay-arrow\");\n svg.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n pointer-events: none;\n z-index: 2147483644;\n overflow: visible;\n `;\n\n // Arrowhead marker definition\n const defs = document.createElementNS(\"http://www.w3.org/2000/svg\", \"defs\");\n const marker = document.createElementNS(\n \"http://www.w3.org/2000/svg\",\n \"marker\",\n );\n marker.setAttribute(\"id\", MARKER_ID);\n marker.setAttribute(\"markerWidth\", \"8\");\n marker.setAttribute(\"markerHeight\", \"8\");\n marker.setAttribute(\"refX\", \"6\");\n marker.setAttribute(\"refY\", \"3\");\n marker.setAttribute(\"orient\", \"auto\");\n marker.setAttribute(\"markerUnits\", \"strokeWidth\");\n\n const arrowPolygon = document.createElementNS(\n \"http://www.w3.org/2000/svg\",\n \"polygon\",\n );\n arrowPolygon.setAttribute(\"points\", \"0 0, 6 3, 0 6\");\n arrowPolygon.setAttribute(\"fill\", ARROW_COLOR);\n marker.appendChild(arrowPolygon);\n defs.appendChild(marker);\n svg.appendChild(defs);\n\n // The path element — will be updated with computed coordinates\n const path = document.createElementNS(\"http://www.w3.org/2000/svg\", \"path\");\n path.setAttribute(\"data-testid\", \"unnoodle-arrow-path\");\n path.setAttribute(\"fill\", \"none\");\n path.setAttribute(\"stroke\", ARROW_COLOR);\n path.setAttribute(\"stroke-width\", String(STROKE_WIDTH));\n path.setAttribute(\"stroke-dasharray\", DASH);\n path.setAttribute(\"stroke-linecap\", \"round\");\n path.setAttribute(\"marker-end\", `url(#${MARKER_ID})`);\n svg.appendChild(path);\n\n return svg;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\nexport class OverlayArrow implements IOverlayArrow {\n private svg: SVGSVGElement | null = null;\n\n draw(fromRect: DOMRect, toRect: DOMRect): void {\n // Replace any previous arrow\n this.remove();\n\n const svg = buildSvg();\n const path = svg.querySelector(\"path\")!;\n path.setAttribute(\"d\", computePath(fromRect, toRect));\n\n document.body.appendChild(svg);\n this.svg = svg;\n }\n\n update(fromRect: DOMRect, toRect: DOMRect): void {\n if (!this.svg) return;\n const path = this.svg.querySelector(\"path\");\n if (path) {\n path.setAttribute(\"d\", computePath(fromRect, toRect));\n }\n }\n\n remove(): void {\n this.svg?.remove();\n this.svg = null;\n }\n}\n","/**\n * CaptureOrchestrator\n *\n * Single responsibility:\n * Sequence the single API call that constitutes a \"capture with meaning\":\n * POST /api/product-memories — creates a ProductMemory with title + first entry\n *\n * The class knows nothing about the UI (no DOM, no bar, no panel).\n * It is injected into CaptureModeController via the ICaptureOrchestrator\n * interface so it can be replaced with a stub in tests.\n */\n\nimport type {\n UnnoodleConfig,\n ProductMemoryDetailResponse,\n} from \"../../types/config\";\nimport type { ElementSnapshot } from \"./elementSnapshot\";\nimport { createProductMemory, addProductMemoryEntry } from \"../../core/apiClient\";\n\n// ---------------------------------------------------------------------------\n// Public contracts\n// ---------------------------------------------------------------------------\n\n/** Successful result of a capture-with-title operation. */\nexport interface CaptureOrchestratorResult {\n /** The created ProductMemory (title + first stage entry). */\n memory: ProductMemoryDetailResponse;\n}\n\n/** Stable interface so unit tests can inject a fake double. */\nexport interface ICaptureOrchestrator {\n execute(\n config: UnnoodleConfig,\n token: string,\n /** User-provided title for the new ProductMemory group (empty string for add-entry). */\n title: string,\n /** Explanation text describing what this UI element means. */\n explanation: string,\n /** The element snapshot produced by the browser-side pick flow. */\n elementSnapshot: ElementSnapshot,\n /** When true, start watching the element for DOM mutations after capture. */\n watchForChanges?: boolean,\n ): Promise<CaptureOrchestratorResult>;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\nexport class CaptureOrchestrator implements ICaptureOrchestrator {\n /**\n * Creates a ProductMemory with title + first entry in a single API call.\n * Both URL and timestamp are read from the browser context at call time.\n *\n * @param config Widget configuration (base URL, API key, …)\n * @param token Authenticated user JWT\n * @param title Human-authored title for the ProductMemory group\n * @param elementSnapshot Style-inlined outerHTML + metadata of the picked element\n */\n async execute(\n config: UnnoodleConfig,\n token: string,\n title: string,\n explanation: string,\n elementSnapshot: ElementSnapshot,\n watchForChanges = false,\n ): Promise<CaptureOrchestratorResult> {\n const memory = await createProductMemory(\n config,\n {\n title,\n explanation: explanation || title,\n snapshotHtml: elementSnapshot.html,\n url: window.location.href,\n pageTitle: document.title,\n capturedAt: new Date().toISOString(),\n targetingMetadata: {\n id: elementSnapshot.id,\n dataTestId: elementSnapshot.dataTestId,\n tag: elementSnapshot.tag,\n role: elementSnapshot.role,\n text: elementSnapshot.text,\n },\n watchForChanges,\n },\n token,\n );\n\n return { memory };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Add-entry variant — appends a new element snapshot to an existing memory\n// ---------------------------------------------------------------------------\n\n/**\n * Used when the user clicks \"Add Entry\" from a memory detail view.\n * Calls POST /api/product-memories/:id/entries instead of creating a new memory.\n */\nexport class AddEntryOrchestrator implements ICaptureOrchestrator {\n constructor(private readonly memoryId: number) {}\n\n async execute(\n config: UnnoodleConfig,\n token: string,\n /** Ignored for add-entry — title belongs to the existing memory. */\n _title: string,\n /** Explanation text typed in the capture form. */\n explanation: string,\n elementSnapshot: ElementSnapshot,\n ): Promise<CaptureOrchestratorResult> {\n const memory = await addProductMemoryEntry(\n config,\n this.memoryId,\n {\n explanation,\n snapshotHtml: elementSnapshot.html,\n url: window.location.href,\n pageTitle: document.title,\n capturedAt: new Date().toISOString(),\n targetingMetadata: {\n id: elementSnapshot.id,\n dataTestId: elementSnapshot.dataTestId,\n tag: elementSnapshot.tag,\n role: elementSnapshot.role,\n text: elementSnapshot.text,\n },\n },\n token,\n );\n\n return { memory };\n }\n}\n","/**\n * CaptureModeController\n *\n * Single responsibility:\n * Orchestrate the end-to-end \"capture UI + add meaning\" flow.\n *\n * State machine:\n * idle → picking → describing → saving → idle\n *\n * Dependencies are injected via interfaces — no direct imports of concrete\n * implementations — making every dependency swappable in tests.\n *\n * Panel (view) — renders UI states, fires events back via callbacks\n * ElementPicker (tool) — hover + click pick mode on host app\n * OverlayArrow (tool) — SVG dotted arrow from panel to picked element\n * Orchestrator (API) — sequences POST /ui-states → POST /product-memories\n */\n\nimport type { ElementSnapshot } from \"./elementSnapshot\";\nimport { snapshotElement } from \"./elementSnapshot\";\nimport type { IElementPicker } from \"./elementPicker\";\nimport type { IOverlayArrow } from \"./overlayArrow\";\nimport type { ICaptureOrchestrator } from \"./captureOrchestrator\";\nimport type { UnnoodleConfig, GlossaryTerm } from \"../../types/config\";\n\n// ---------------------------------------------------------------------------\n// Panel interface — only what captureModeController needs to call\n// ---------------------------------------------------------------------------\n\n/**\n * The subset of PanelControls that CaptureModeController interacts with.\n * Defined here so panel.ts does not need to import this file.\n */\nexport interface CapturePanelControls {\n /** Show the \"click an element to select it\" prompt in the context-strip. */\n enterPickMode(onCancel: () => void): void;\n /**\n * Navigate the panel body to the describe-and-save view, showing the\n * captured element snapshot alongside a description textarea.\n */\n showCaptureDescribe(\n snapshot: ElementSnapshot,\n onSave: (description: string) => void,\n onPickAgain: () => void,\n ): void;\n /** Signal that saving is in progress (disable inputs). */\n setCaptureLoading(loading: boolean): void;\n /** Surface an error inside the describe view. */\n setCaptureError(message: string): void;\n /** Restore the panel to normal home view, context-strip to idle. */\n exitCaptureMode(): void;\n /** Restore the home view with the provided data */\n restoreHomeView(data: any): void;\n /** Brief toast notification. */\n showToast(message: string): void;\n /** The panel host element — used to compute the arrow source rect. */\n readonly element: HTMLElement;\n /** Show full-screen form for creating a new memory */\n showNewMemoryForm(\n onPickElement: () => void,\n onCancelCapture: () => void,\n onSave: (\n title: string,\n explanation: string,\n watchForChanges: boolean,\n ) => void,\n onCancel: () => void,\n ): void;\n /** Show full-screen form for adding entry to existing memory */\n showAddEntryForm(\n memoryTitle: string,\n onPickElement: () => void,\n onCancelCapture: () => void,\n onSave: (explanation: string) => void,\n onCancel: () => void,\n ): void;\n /** Update the snapshot preview in the currently open form */\n updateFormSnapshot(snapshot: ElementSnapshot): void;\n /** Set form picking mode visual state */\n setFormPickingMode(enabled: boolean): void;\n}\n\n// ---------------------------------------------------------------------------\n// State type\n// ---------------------------------------------------------------------------\n\ntype CaptureState = \"idle\" | \"form-open\" | \"picking\" | \"saving\";\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\nexport class CaptureModeController {\n private state: CaptureState = \"idle\";\n private pickedElement: HTMLElement | null = null;\n private snapshot: ElementSnapshot | null = null;\n private scrollHandler: (() => void) | null = null;\n private resizeHandler: (() => void) | null = null;\n private homeData: any = null;\n\n constructor(\n private readonly panel: CapturePanelControls,\n private readonly picker: IElementPicker,\n private readonly arrow: IOverlayArrow,\n private readonly orchestrator: ICaptureOrchestrator,\n private readonly config: UnnoodleConfig,\n private readonly getToken: () => string | null,\n private readonly getGlossary: () => GlossaryTerm[],\n private readonly onSaveComplete?: () => void,\n private readonly mode:\n | { type: \"new-memory\" }\n | { type: \"add-entry\"; memoryTitle: string } = { type: \"new-memory\" },\n ) {}\n\n // ── Public API ─────────────────────────────────────────────────────────────\n\n /**\n * Store the home data so we can restore it after capture\n */\n setHomeData(data: any): void {\n this.homeData = data;\n }\n\n /**\n * Begin the capture flow — idempotent if already active.\n * Transitions: idle → form-open\n */\n start(): void {\n console.log(\"[unnoodle] CaptureModeController.start() called\", {\n state: this.state,\n mode: this.mode,\n });\n\n if (this.state !== \"idle\") return;\n this.state = \"form-open\";\n\n if (this.mode.type === \"new-memory\") {\n this.panel.showNewMemoryForm(\n () => {\n console.log(\"[unnoodle] Pick element callback triggered\");\n this.onPickElementClicked();\n },\n () => {\n console.log(\"[unnoodle] Cancel capture callback triggered\");\n this.onCancelCapture();\n },\n (title: string, explanation: string, watchForChanges: boolean) => {\n console.log(\"[unnoodle] Save callback triggered\", {\n title,\n explanation,\n watchForChanges,\n });\n void this.onSaveWithTitle(title, explanation, watchForChanges);\n },\n () => {\n console.log(\"[unnoodle] Cancel callback triggered\");\n this.cancel();\n },\n );\n } else {\n // Add entry mode\n this.panel.showAddEntryForm(\n this.mode.memoryTitle,\n () => {\n console.log(\n \"[unnoodle] Pick element callback triggered (add entry mode)\",\n );\n this.onPickElementClicked();\n },\n () => {\n console.log(\n \"[unnoodle] Cancel capture callback triggered (add entry mode)\",\n );\n this.onCancelCapture();\n },\n (explanation: string) => {\n console.log(\"[unnoodle] Save callback triggered (add entry mode)\", {\n explanation,\n });\n void this.onSaveWithExplanation(explanation);\n },\n () => {\n console.log(\"[unnoodle] Cancel callback triggered (add entry mode)\");\n this.cancel();\n },\n );\n }\n }\n\n /**\n * Called by the ElementPicker when the user selects an element.\n * Public so the picker factory can reference it without closure hacks.\n * Treat as internal — call only from ElementPicker.onPick.\n */\n _onElementPicked(el: HTMLElement): void {\n this.onElementPicked(el);\n }\n\n /**\n * Abort any active capture flow and return to idle.\n * Safe to call from any state.\n */\n cancel(): void {\n console.log(\"[unnoodle] cancel() called, current state:\", this.state);\n this.cleanup();\n console.log(\"[unnoodle] Restoring home view after cancel\");\n // Instead of exitCaptureMode (which is for strip-based UI), restore the home view\n if (this.homeData) {\n this.panel.restoreHomeView(this.homeData);\n } else {\n this.panel.exitCaptureMode();\n }\n console.log(\"[unnoodle] Calling onSaveComplete to reload home memories\");\n this.onSaveComplete?.();\n console.log(\"[unnoodle] cancel() completed\");\n }\n\n // ── Internal state transitions ─────────────────────────────────────────────\n\n private onPickElementClicked(): void {\n if (this.state !== \"form-open\") return;\n this.state = \"picking\";\n this.panel.setFormPickingMode(true);\n this.picker.start();\n }\n\n onCancelCapture(): void {\n console.log(\n \"[unnoodle] onCancelCapture() called, current state:\",\n this.state,\n );\n if (this.state === \"picking\") {\n this.state = \"form-open\";\n this.panel.setFormPickingMode(false);\n console.log(\"[unnoodle] Exited picking mode, returned to form\");\n }\n }\n\n private onElementPicked(el: HTMLElement): void {\n console.log(\"[unnoodle] onElementPicked called\", {\n state: this.state,\n element: el,\n });\n if (this.state !== \"picking\") {\n console.log(\n \"[unnoodle] onElementPicked - wrong state, expected 'picking', got\",\n this.state,\n );\n return;\n }\n\n console.log(\"[unnoodle] onElementPicked - setting state to form-open\");\n this.state = \"form-open\";\n this.pickedElement = el;\n\n // Exit picking mode UI\n this.panel.setFormPickingMode(false);\n\n // Freeze a visual snapshot of the picked element\n console.log(\"[unnoodle] onElementPicked - creating snapshot\");\n this.snapshot = snapshotElement(el);\n console.log(\n \"[unnoodle] onElementPicked - snapshot created:\",\n this.snapshot,\n );\n\n // Update the form's snapshot preview\n console.log(\"[unnoodle] onElementPicked - updating form snapshot\");\n this.panel.updateFormSnapshot(this.snapshot);\n\n // Draw the dotted arrow from the panel edge to the element and keep it\n // tracking while the user scrolls or resizes the window.\n console.log(\"[unnoodle] onElementPicked - drawing arrow\");\n this.redrawArrow();\n this.startTrackingArrow();\n console.log(\"[unnoodle] onElementPicked completed, state:\", this.state);\n }\n\n private async onSaveWithTitle(\n title: string,\n explanation: string,\n watchForChanges: boolean,\n ): Promise<void> {\n await this.performSave(title, explanation, watchForChanges);\n }\n\n private async onSaveWithExplanation(explanation: string): Promise<void> {\n // For add-entry mode, title is empty since it's adding to existing memory\n await this.performSave(\"\", explanation, false);\n }\n\n private async performSave(\n title: string,\n explanation: string,\n watchForChanges: boolean,\n ): Promise<void> {\n console.log(\"[unnoodle] performSave called\", {\n title,\n explanation,\n state: this.state,\n snapshot: this.snapshot,\n });\n\n if (this.state !== \"form-open\") {\n console.log(\"[unnoodle] performSave - wrong state, returning\");\n return;\n }\n if (!this.snapshot) {\n console.log(\n \"[unnoodle] performSave - no snapshot, user didn't pick element, returning\",\n );\n // User clicked save without picking an element\n return;\n }\n\n this.state = \"saving\";\n console.log(\"[unnoodle] performSave - state set to saving, getting token\");\n\n const token = this.getToken();\n console.log(\"[unnoodle] performSave - token obtained:\", !!token);\n\n if (!token) {\n console.log(\n \"[unnoodle] performSave - no token, returning to form-open state\",\n );\n // This shouldn't happen as the form shouldn't be shown if not logged in\n this.state = \"form-open\";\n return;\n }\n\n try {\n console.log(\"[unnoodle] performSave - executing orchestrator\");\n await this.orchestrator.execute(\n this.config,\n token,\n title,\n explanation,\n this.snapshot,\n watchForChanges,\n );\n console.log(\"[unnoodle] performSave - orchestrator success, cleaning up\");\n this.cleanup();\n console.log(\"[unnoodle] Restoring home view after save\");\n // Instead of exitCaptureMode, restore the home view\n if (this.homeData) {\n this.panel.restoreHomeView(this.homeData);\n } else {\n this.panel.exitCaptureMode();\n }\n console.log(\"[unnoodle] Showing toast\");\n this.panel.showToast(\"Captured ✓\");\n console.log(\"[unnoodle] Calling onSaveComplete callback\");\n this.onSaveComplete?.();\n console.log(\"[unnoodle] performSave completed successfully\");\n } catch (error) {\n console.log(\"[unnoodle] performSave - orchestrator failed\", error);\n this.state = \"form-open\";\n // Error handling is now the responsibility of the form\n }\n }\n\n // ── Helpers ────────────────────────────────────────────────────────────────\n\n /**\n * Recalculate fresh rects and push them to arrow.update().\n * Called by scroll / resize listeners while the arrow is live.\n */\n private updateArrow(): void {\n if (!this.pickedElement) return;\n const panelShell =\n (this.panel.element.shadowRoot?.querySelector(\n \".panel-shell\",\n ) as HTMLElement | null) ?? this.panel.element;\n this.arrow.update(\n panelShell.getBoundingClientRect(),\n this.pickedElement.getBoundingClientRect(),\n );\n }\n\n /** Attach scroll + resize listeners that keep the arrow in sync. */\n private startTrackingArrow(): void {\n this.stopTrackingArrow(); // guard against double-registration\n const onUpdate = () => this.updateArrow();\n this.scrollHandler = onUpdate;\n this.resizeHandler = onUpdate;\n // capture:true catches scroll on any nested scrollable container\n window.addEventListener(\"scroll\", this.scrollHandler, {\n capture: true,\n passive: true,\n });\n window.addEventListener(\"resize\", this.resizeHandler, { passive: true });\n }\n\n /** Remove scroll + resize listeners (call before removing the arrow). */\n private stopTrackingArrow(): void {\n if (this.scrollHandler) {\n window.removeEventListener(\"scroll\", this.scrollHandler, {\n capture: true,\n });\n this.scrollHandler = null;\n }\n if (this.resizeHandler) {\n window.removeEventListener(\"resize\", this.resizeHandler);\n this.resizeHandler = null;\n }\n }\n\n private redrawArrow(): void {\n if (!this.pickedElement) return;\n // panel.element is the zero-size shadow host div (all:initial CSS makes it\n // have no layout dimensions). Use the .panel-shell inside the shadow root\n // which is the real fixed-position panel visible on screen.\n const panelShell =\n (this.panel.element.shadowRoot?.querySelector(\n \".panel-shell\",\n ) as HTMLElement | null) ?? this.panel.element;\n const panelRect = panelShell.getBoundingClientRect();\n const elementRect = this.pickedElement.getBoundingClientRect();\n this.arrow.draw(panelRect, elementRect);\n }\n\n private cleanup(): void {\n this.stopTrackingArrow();\n this.arrow.remove();\n this.pickedElement = null;\n this.snapshot = null;\n this.state = \"idle\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// Factory — wires concrete implementations together\n// ---------------------------------------------------------------------------\n\nimport { ElementPicker } from \"./elementPicker\";\nimport { OverlayArrow } from \"./overlayArrow\";\nimport { CaptureOrchestrator } from \"./captureOrchestrator\";\nimport type { ICaptureOrchestrator } from \"./captureOrchestrator\";\n\n/**\n * Construct a CaptureModeController with its standard concrete dependencies.\n * Called by WidgetController for both \"new memory\" and \"add entry\" flows.\n */\nexport function createCaptureModeController(\n panel: CapturePanelControls,\n config: UnnoodleConfig,\n getToken: () => string | null,\n getGlossary: () => GlossaryTerm[],\n onSaveComplete?: () => void,\n orchestratorOverride?: ICaptureOrchestrator,\n mode: { type: \"new-memory\" } | { type: \"add-entry\"; memoryTitle: string } = {\n type: \"new-memory\",\n },\n): CaptureModeController {\n const orchestrator = orchestratorOverride ?? new CaptureOrchestrator();\n\n const controller = new CaptureModeController(\n panel,\n new ElementPicker({\n onPick: (el) => controller._onElementPicked(el),\n onCancel: () => controller.onCancelCapture(),\n }),\n new OverlayArrow(),\n orchestrator,\n config,\n getToken,\n getGlossary,\n onSaveComplete,\n mode,\n );\n\n return controller;\n}\n","/**\n * Normalize CSS that may have been double-escaped by webpack's eval-source-map.\n *\n * When esbuild/tsup minifies the SDK it converts template-literal CSS strings\n * to regular JS string literals, representing newlines as the escape sequence\n * `\\n` (backslash + n) in source. In production / non-eval builds the browser\n * JS engine parses `\\n` → real newline and CSS is valid.\n *\n * But Next.js (and other webpack-based hosts) default to `eval-source-map` in\n * development, which wraps every module in `eval(\"…\")`. The serialisation step\n * must escape each `\\n` in the module source as `\\\\n` inside the eval string.\n * After eval(), the JS string then contains the two characters `\\` and `n` (not\n * a newline). The CSS parser reads `\\n` as an escaped identifier — effectively\n * `n` — prepending it to every rule selector and silently breaking all styles.\n *\n * This helper repairs that case at injection time. In the normal (non-eval)\n * path every `\\n` in the string IS already a real newline character (charCode\n * 10), so the regex `/\\\\n/g` (which matches literal backslash+n) never fires\n * and the function is a no-op.\n *\n * Apply this to every `style.textContent = …` call in the SDK that sets CSS.\n */\nexport function safeCSS(css: string): string {\n // Repair double-escaped sequences produced by webpack eval-source-map.\n // Only fires when the string contains literal backslash characters (the\n // eval-wrapped case). Real newlines/tabs are unaffected.\n return css.replace(/\\\\n/g, \"\\n\").replace(/\\\\t/g, \"\\t\");\n}\n","import { safeCSS } from \"./safeCSS\";\n\n/**\n * Renders the floating trigger button using Shadow DOM.\n * The button is draggable — position is stored in memory for the session\n * (never persisted to localStorage).\n * Returns a cleanup function that removes the element and all listeners.\n */\nexport function createButton(\n onTrigger: () => void,\n /**\n * A CSS `:host { … }` block containing --unn-* custom properties.\n * Pass the output of getShadowDomTokens() from @unnoodle/design-system\n * so the button can consume design tokens inside its shadow root.\n */\n shadowTokens?: string,\n): {\n element: HTMLElement;\n cleanup: () => void;\n setProgress: (active: boolean) => void;\n} {\n const host = document.createElement(\"div\");\n host.id = \"unnoodle-btn-host\";\n // Host must be positioned so the inner button's fixed position works correctly\n host.style.cssText =\n \"position:fixed;right:14px;top:50%;transform:translateY(-50%);z-index:2147483647;\";\n\n const shadow = host.attachShadow({ mode: \"open\" });\n\n const style = document.createElement(\"style\");\n style.textContent = safeCSS(`\n :host { all: initial; }\n\n /* Wrapper — gives ::after tooltip a positioning context */\n .btn-wrap {\n position: relative;\n display: inline-flex;\n align-items: center;\n }\n\n /* Rounded-square trigger button */\n .trigger {\n width: 38px; height: 38px;\n border-radius: 4px;\n border: none; padding: 0; cursor: pointer;\n position: relative;\n display: flex; align-items: center; justify-content: center; gap: 0;\n background: linear-gradient(160deg, #2c3440 0%, #1a1f27 100%);\n /* Layered box-shadow — creates a \"gradient shadow\" depth effect */\n box-shadow:\n 0 1px 2px rgba(0,0,0,0.30),\n 0 3px 8px rgba(0,0,0,0.38),\n 0 8px 20px rgba(0,0,0,0.22),\n 0 1px 0 rgba(255,255,255,0.06) inset;\n color: rgba(255,255,255,0.85);\n font-family: var(--unn-font-family, system-ui, sans-serif);\n font-size: 11px; font-weight: 700; letter-spacing: 0.5px;\n /* Text shadow for glyph depth */\n text-shadow: 0 1px 3px rgba(0,0,0,0.65), 0 -1px 0 rgba(255,255,255,0.10);\n -webkit-user-select: none; user-select: none;\n transition:\n transform 0.18s cubic-bezier(0.34,1.35,0.64,1),\n box-shadow 0.18s ease,\n filter 0.18s ease;\n }\n\n /*\n * Spinning progress ring — only visible when .trigger has .loading class.\n * Toggle via setProgress(true/false) from the returned API.\n * Uses the mask XOR trick: outer box minus content-box = thin padding ring.\n * The conic-gradient rotates to give a sweeping arc effect.\n */\n .trigger.loading::after {\n content: '';\n position: absolute;\n /* 1px gap + 1px border = 2px outside button edge */\n inset: -2px;\n border-radius: 6px; /* 4px + 2px */\n padding: 1px; /* controls ring thickness */\n background: conic-gradient(\n from 0deg,\n transparent 0deg,\n rgba(0,0,0,0.75) 80deg,\n transparent 160deg\n );\n /* Hollow ring mask: reveal only the 1px padding strip */\n -webkit-mask:\n linear-gradient(#fff 0 0) content-box,\n linear-gradient(#fff 0 0);\n mask:\n linear-gradient(#fff 0 0) content-box,\n linear-gradient(#fff 0 0);\n -webkit-mask-composite: destination-out;\n mask-composite: exclude;\n pointer-events: none;\n animation: unn-ring-spin 2.4s linear infinite;\n }\n\n @keyframes unn-ring-spin {\n to { transform: rotate(360deg); }\n }\n\n .trigger.dragging { transition: none; }\n\n .trigger:not(.dragging):hover {\n transform: scale(1.08);\n box-shadow:\n 0 2px 4px rgba(0,0,0,0.35),\n 0 6px 16px rgba(0,0,0,0.48),\n 0 14px 32px rgba(0,0,0,0.22),\n 0 1px 0 rgba(255,255,255,0.10) inset;\n filter: brightness(1.18);\n }\n .trigger:not(.dragging):active { transform: scale(0.94); }\n .trigger:focus-visible { outline: 2px solid rgba(255,255,255,0.55); outline-offset: 2px; }\n\n /* Tooltip */\n .tip {\n position: absolute;\n right: calc(100% + 10px);\n top: 50%; transform: translateY(-50%);\n background: rgba(18,18,26,0.90);\n color: #fff;\n font-family: var(--unn-font-family, system-ui, sans-serif);\n font-size: 9px; font-weight: 500;\n white-space: nowrap;\n padding: 3px 7px; border-radius: 4px;\n opacity: 0; pointer-events: none;\n transition: opacity 0.15s ease;\n backdrop-filter: blur(4px);\n }\n .trigger:not(.dragging):hover ~ .tip,\n .trigger:not(.dragging):focus-visible ~ .tip { opacity: 1; }\n `);\n\n if (shadowTokens) {\n const tokenStyle = document.createElement(\"style\");\n tokenStyle.textContent = safeCSS(shadowTokens);\n shadow.appendChild(tokenStyle);\n }\n shadow.appendChild(style);\n\n const wrap = document.createElement(\"div\");\n wrap.className = \"btn-wrap\";\n\n const btn = document.createElement(\"button\");\n btn.className = \"trigger\";\n btn.setAttribute(\"aria-label\", \"Open Unnoodle\");\n btn.setAttribute(\"data-testid\", \"widget-trigger-button\");\n btn.textContent = \"U\\u2229\";\n // Keyboard trigger (Enter / Space) — not using \"click\" because mousedown+mouseup\n // already calls onTrigger() on mouse release, and a \"click\" listener would fire\n // a second time causing an immediate open→close double-toggle.\n btn.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onTrigger();\n }\n });\n\n const tip = document.createElement(\"span\");\n tip.className = \"tip\";\n const isMac = /mac/i.test(navigator.platform || navigator.userAgent);\n tip.textContent = isMac ? \"⌘U\" : \"Ctrl+U\";\n\n wrap.appendChild(btn);\n wrap.appendChild(tip);\n shadow.appendChild(wrap);\n\n // ---------------------------------------------------------------------------\n // Drag logic — moves the host element (fixed-position anchor)\n // ---------------------------------------------------------------------------\n let isDragging = false;\n let hasMoved = false;\n let startX = 0;\n let startY = 0;\n let originRight = 0;\n let originTopPx = 0;\n\n function readPosition(): { right: number; topPx: number } {\n const right = parseFloat(host.style.right) || 14;\n const rawTop = host.style.top;\n const topPx = rawTop.endsWith(\"%\")\n ? (parseFloat(rawTop) / 100) * window.innerHeight - 68\n : parseFloat(rawTop) || window.innerHeight / 2 - 68;\n return { right, topPx };\n }\n\n function onMouseDown(e: MouseEvent) {\n if (e.button !== 0) return;\n isDragging = true;\n hasMoved = false;\n btn.classList.add(\"dragging\");\n startX = e.clientX;\n startY = e.clientY;\n const pos = readPosition();\n originRight = pos.right;\n originTopPx = pos.topPx;\n e.preventDefault();\n }\n\n function onMouseMove(e: MouseEvent) {\n if (!isDragging) return;\n const dx = e.clientX - startX;\n const dy = e.clientY - startY;\n if (Math.abs(dx) > 3 || Math.abs(dy) > 3) hasMoved = true;\n const newRight = clamp(originRight - dx, 8, window.innerWidth - 46);\n const newTopPx = clamp(originTopPx + dy, 8, window.innerHeight - 160);\n host.style.right = `${newRight}px`;\n host.style.top = `${newTopPx}px`;\n host.style.transform = \"none\";\n }\n\n function onMouseUp(e: MouseEvent) {\n if (!isDragging) return;\n isDragging = false;\n btn.classList.remove(\"dragging\");\n if (!hasMoved) {\n onTrigger();\n }\n e.preventDefault();\n }\n\n function onTouchStart(e: TouchEvent) {\n const t = e.touches[0];\n if (!t) return;\n isDragging = true;\n hasMoved = false;\n btn.classList.add(\"dragging\");\n startX = t.clientX;\n startY = t.clientY;\n const pos = readPosition();\n originRight = pos.right;\n originTopPx = pos.topPx;\n }\n\n function onTouchMove(e: TouchEvent) {\n if (!isDragging) return;\n const t = e.touches[0];\n if (!t) return;\n const dx = t.clientX - startX;\n const dy = t.clientY - startY;\n if (Math.abs(dx) > 3 || Math.abs(dy) > 3) hasMoved = true;\n const newRight = clamp(originRight - dx, 8, window.innerWidth - 46);\n const newTopPx = clamp(originTopPx + dy, 8, window.innerHeight - 160);\n host.style.right = `${newRight}px`;\n host.style.top = `${newTopPx}px`;\n host.style.transform = \"none\";\n e.preventDefault();\n }\n\n function onTouchEnd() {\n if (!isDragging) return;\n isDragging = false;\n btn.classList.remove(\"dragging\");\n if (!hasMoved) onTrigger();\n }\n\n btn.addEventListener(\"mousedown\", onMouseDown);\n document.addEventListener(\"mousemove\", onMouseMove);\n document.addEventListener(\"mouseup\", onMouseUp);\n\n btn.addEventListener(\"touchstart\", onTouchStart, { passive: true });\n document.addEventListener(\"touchmove\", onTouchMove, { passive: false });\n document.addEventListener(\"touchend\", onTouchEnd);\n\n const cleanup = () => {\n btn.removeEventListener(\"mousedown\", onMouseDown);\n btn.removeEventListener(\"touchstart\", onTouchStart);\n document.removeEventListener(\"mousemove\", onMouseMove);\n document.removeEventListener(\"mouseup\", onMouseUp);\n document.removeEventListener(\"touchmove\", onTouchMove);\n document.removeEventListener(\"touchend\", onTouchEnd);\n host.remove();\n };\n\n const setProgress = (active: boolean) => {\n btn.classList.toggle(\"loading\", active);\n btn.setAttribute(\"aria-busy\", String(active));\n };\n\n return { element: host, cleanup, setProgress };\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n","/** Panel shadow-DOM CSS. Pure CSS string — no template dependencies. */\nexport const PANEL_STYLES = `\n :host {\n all: initial;\n /* ═══════════════════════════════════════════════════════════════\n Widget scale tokens — change values here to affect everywhere\n ═══════════════════════════════════════════════════════════════ */\n\n /* Font sizes */\n --w-font-xxs: 10px; /* product-memory heading */\n --w-font-xs: 10px; /* footer, panel subtitle, upper labels */\n --w-font-sm: 11px; /* form labels, tab-btn, section headings */\n --w-font-base: 12px; /* body text, search, buttons, term defs */\n --w-font-md: 13px; /* term names, inputs, form-submit */\n --w-font-display: 13px; /* AI modal term emphasis */\n --w-font-lg: 13px; /* panel title */\n --w-font-xl: 15px; /* login heading */\n\n /* Font weights */\n --w-weight-normal: 400;\n --w-weight-medium: 400; /* labels, tab-btn */\n --w-weight-semi: 500; /* headings, buttons */\n --w-weight-bold: 600; /* term detail name */\n\n /* Spacing — vertical */\n --w-space-v-xs: 4px; /* small inner gaps */\n --w-space-v-sm: 8px; /* post padding, pm textarea */\n --w-space-v-md: 10px; /* section padding-top/bottom, term items */\n --w-space-v-lg: 12px; /* header, discussions, meta padding-v */\n --w-space-v-xl: 20px; /* login form padding-top/bottom */\n\n /* Spacing — horizontal */\n --w-space-h-sm: 12px; /* login form inner padding */\n --w-space-h-md: 16px; /* global horizontal gutter */\n --w-space-h-lg: 18px; /* login outer horizontal padding */\n\n /* Spacing — numeric scale (used by home view, skeleton loaders) */\n --w-space-1: 4px;\n --w-space-2: 8px;\n --w-space-3: 12px;\n --w-space-4: 16px;\n\n /* Border */\n --w-border-width: 1px; /* all interactive element borders */\n\n /* Border radii */\n --w-radius-xs: 3px; /* tiny elements, pm editor btn */\n --w-radius-1: 4px; /* home view rows, search bar */\n --w-radius-sm: 4px; /* tabs, capture-btn, suggestions, pm btns */\n --w-radius-md: 5px; /* action-btn */\n --w-radius-lg: 6px; /* inputs, SSO btns, form submits, toast, modal */\n --w-radius-pill: 10px; /* term pills */\n\n /* Panel dimensions */\n --w-panel-width: 400px;\n\n /* Spinner */\n --w-spinner-size: 34px;\n --w-spinner-border: 3px;\n }\n *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\n\n .panel-shell {\n position: fixed; top: 0; right: 0; bottom: 0;\n width: var(--w-panel-width); max-width: 100vw;\n z-index: 2147483647;\n transform: translateX(100%);\n transition: transform 0.28s cubic-bezier(0.4,0,0.2,1), width 0.28s cubic-bezier(0.4,0,0.2,1);\n \n border-left: 0.5px solid var(--unn-color-border-default);\n box-shadow: inset 6px 0 12px rgba(0,0,0,0.06), inset -4px 0 10px rgba(0,0,0,0.04), inset 0 6px 12px rgba(0,0,0,0.06), inset 0 -4px 10px rgba(0,0,0,0.04);\n padding: 3px;\n display: flex; flex-direction: column;\n background: var(--unn-color-bg-secondary, #f5f5f7);\n }\n .panel-shell.open { transform: translateX(0); }\n .panel {\n flex: 1; min-height: 0;\n display: flex; flex-direction: column;\n font-family: var(--unn-font-family);\n background: var(--unn-color-bg-primary);\n border-radius: 6px;\n overflow: hidden;\n }\n\n /* Header */\n .panel-header {\n display: flex; align-items: center; justify-content: space-between;\n padding: 5px 6px 5px 12px;\n background: linear-gradient(160deg, #2c3440 0%, #1a1f27 100%);\n color: var(--unn-color-text-inverse);\n border-radius: 6px 6px 0 0; flex-shrink: 0;\n }\n .panel-header-brand { display: flex; align-items: baseline; gap: 4px; min-width: 0; }\n .panel-title { font-size: var(--w-font-base); font-weight: var(--w-weight-bold); letter-spacing: 0.01em; white-space: nowrap; }\n .panel-title-sep { font-size: var(--w-font-xs); opacity: 0.35; line-height: 1; }\n .panel-subtitle { font-size: var(--w-font-xs); opacity: 0.60; white-space: nowrap; }\n .panel-header-actions { display: flex; align-items: center; gap: 1px; flex-shrink: 0; }\n .panel-header-separator { width: 1px; height: 11px; background: rgba(255,255,255,0.25); margin: 0 3px; flex-shrink: 0; }\n .panel-close, .panel-popout, .panel-dock, .panel-pin-left, .panel-pin-right,\n .panel-half, .panel-half-exit,\n .panel-fullscreen, .panel-fullscreen-exit {\n background: none; border: none; cursor: pointer; color: var(--unn-color-text-inverse);\n width: 24px; height: 24px;\n display: flex; align-items: center; justify-content: center;\n border-radius: var(--w-radius-xs); opacity: 0.75; transition: opacity 0.15s, background 0.15s;\n }\n .panel-close:hover, .panel-popout:hover, .panel-dock:hover,\n .panel-pin-left:hover, .panel-pin-right:hover,\n .panel-half:hover, .panel-half-exit:hover,\n .panel-fullscreen:hover, .panel-fullscreen-exit:hover { opacity: 1; background: rgba(255,255,255,0.18); }\n .panel-close svg, .panel-popout svg, .panel-dock svg,\n .panel-half svg, .panel-half-exit svg,\n .panel-fullscreen svg, .panel-fullscreen-exit svg { width: 14px; height: 14px; fill: currentColor; stroke: none; }\n .panel-pin-left svg, .panel-pin-right svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 16; }\n .panel-pin-right svg { transform: scaleX(-1); }\n .panel-popout[hidden], .panel-dock[hidden] { display: none !important; }\n .panel-half[hidden], .panel-half-exit[hidden] { display: none !important; }\n .panel-pin-left.active, .panel-pin-right.active { background: rgba(255,255,255,0.25) !important; opacity: 1 !important; }\n\n /* Left-side docking */\n .panel-shell.left-side {\n right: auto; left: 0;\n transform: translateX(-100%);\n border-left: none;\n border-right: 0.5px solid var(--unn-color-border-default);\n }\n .panel-shell.left-side.open { transform: translateX(0); }\n\n /* Half-screen (50vw) */\n .panel-shell.half-screen {\n width: 50vw !important; max-width: 50vw !important;\n }\n\n /* Fullscreen */\n .panel-shell.fullscreen {\n left: 0 !important; right: 0 !important;\n width: 100vw !important; max-width: 100vw !important;\n transform: none !important;\n border-radius: 0 !important;\n border: none !important;\n box-shadow: none !important;\n padding: 0 !important;\n background: transparent !important;\n }\n .panel-shell.fullscreen.open { transform: none !important; }\n .panel-shell.fullscreen .panel { border-radius: 0 !important; }\n .panel-fullscreen[hidden], .panel-fullscreen-exit[hidden] { display: none !important; }\n\n /* Body */\n .panel-body { flex: 1; overflow-y: auto; display: flex; flex-direction: column; }\n\n /* Footer */\n .panel-footer {\n padding: 4px 14px; border-top: 1px solid var(--unn-color-border-default);\n display: flex; align-items: center; justify-content: center; flex-shrink: 0;\n }\n .panel-footer a { font-size: var(--w-font-xs); color: var(--unn-color-text-subtle); text-decoration: none; opacity: 0.8; }\n .panel-footer a:hover { color: var(--unn-color-text-muted); opacity: 1; }\n\n /* ---- Utility states ---- */\n .state-center {\n flex: 1; display: flex; flex-direction: column;\n align-items: center; justify-content: center;\n gap: 14px; padding: 24px;\n }\n .spinner {\n width: var(--w-spinner-size); height: var(--w-spinner-size);\n border: var(--w-spinner-border) solid var(--unn-color-border-default); border-top-color: var(--unn-color-brand-primary);\n border-radius: 50%;\n animation: spin 0.7s linear infinite;\n }\n @keyframes spin { to { transform: rotate(360deg); } }\n .state-msg { font-size: var(--w-font-base); color: var(--unn-color-text-muted); text-align: center; line-height: 1.5; }\n .state-error-icon { stroke: var(--unn-color-status-error); fill: none; width: 40px; height: 40px; }\n\n /* ---- Login view ---- */\n .login-form {\n padding: var(--w-space-v-xl) var(--w-space-h-lg);\n display: flex; flex-direction: column; gap: 14px;\n }\n .login-heading {\n font-size: var(--w-font-xl); font-weight: var(--w-weight-semi); color: var(--unn-color-text-primary); text-align: center;\n }\n .login-sub {\n font-size: var(--w-font-sm); color: var(--unn-color-text-muted); text-align: center; margin-top: -8px;\n }\n .form-field { display: flex; flex-direction: column; gap: 5px; }\n .form-label { font-size: var(--w-font-sm); font-weight: var(--w-weight-medium); color: var(--unn-color-text-body); }\n .form-input {\n width: 100%; padding: 9px 12px;\n border: var(--w-border-width) solid var(--unn-color-border-subtle); border-radius: var(--w-radius-lg);\n font-size: var(--w-font-md); color: var(--unn-color-text-primary);\n outline: none; transition: border-color 0.15s;\n }\n .form-input:focus { border-color: var(--unn-color-brand-primary); }\n .form-submit {\n width: 100%; padding: 10px 16px;\n background: var(--unn-color-brand-primary); color: var(--unn-color-text-inverse);\n border: none; border-radius: var(--w-radius-lg);\n font-size: var(--w-font-md); font-weight: var(--w-weight-semi); cursor: pointer;\n transition: opacity 0.15s, transform 0.1s;\n }\n .form-submit:hover { opacity: 0.9; }\n .form-submit:active { transform: scale(0.98); }\n .form-submit:disabled { opacity: 0.6; cursor: not-allowed; }\n .login-error {\n font-size: var(--w-font-sm); color: var(--unn-color-status-error);\n background: var(--unn-color-error-tint); border: 1px solid var(--unn-color-error-tint-border);\n border-radius: var(--w-radius-sm); padding: 8px 10px;\n display: none;\n }\n .login-error.visible { display: block; }\n .login-back-btn {\n all: unset; cursor: pointer; display: inline-flex; align-items: center; gap: 3px;\n font-size: var(--w-font-sm); color: var(--unn-color-text-muted);\n margin-bottom: -4px;\n }\n .login-back-btn:hover { color: var(--unn-color-text-primary); }\n\n /* ---- SSO buttons ---- */\n .sso-divider {\n display: flex; align-items: center; gap: 10px; margin: 4px 0;\n }\n .sso-divider-line {\n flex: 1; height: 1px; background: var(--unn-color-border-default);\n }\n .sso-divider-text {\n font-size: var(--w-font-xs); color: var(--unn-color-text-muted); white-space: nowrap;\n }\n .sso-buttons { display: flex; flex-direction: column; gap: 8px; }\n .sso-btn {\n display: flex; align-items: center; justify-content: center; gap: 10px;\n width: 100%; padding: 9px 12px;\n border: var(--w-border-width) solid var(--unn-color-border-subtle); border-radius: var(--w-radius-lg);\n background: var(--unn-color-bg-primary); color: var(--unn-color-text-primary);\n font-size: var(--w-font-base); font-weight: var(--w-weight-medium); cursor: pointer;\n transition: background 0.15s, border-color 0.15s;\n }\n .sso-btn:hover { background: var(--unn-color-bg-subtle); border-color: var(--unn-color-border-default); }\n .sso-btn svg { flex-shrink: 0; }\n\n /* ---- Search ---- */\n .search-bar {\n padding: var(--w-space-v-md) var(--w-space-h-md); border-bottom: 1px solid var(--unn-color-border-default);\n flex-shrink: 0;\n }\n .search-input {\n width: 100%; padding: 8px 12px;\n border: var(--w-border-width) solid var(--unn-color-border-subtle); border-radius: var(--w-radius-lg);\n font-size: var(--w-font-base); color: var(--unn-color-text-primary);\n outline: none; transition: border-color 0.15s;\n }\n .search-input:focus { border-color: var(--unn-color-brand-primary); }\n\n /* ---- Terms list ---- */\n .terms-list { flex: 1; overflow-y: auto; padding: 0; }\n .context-label {\n padding: 10px 18px 6px;\n font-size: var(--w-font-xs); font-weight: var(--w-weight-semi); color: var(--unn-color-text-subtle);\n text-transform: uppercase; letter-spacing: 0.05em;\n }\n .term-item {\n padding: var(--w-space-v-md) var(--w-space-h-md);\n border-bottom: 1px solid var(--unn-color-border-default);\n cursor: default;\n transition: background 0.1s;\n }\n .term-item:hover { background: var(--unn-color-bg-secondary); }\n .term-name {\n font-size: var(--w-font-md); font-weight: var(--w-weight-semi); color: var(--unn-color-text-primary);\n display: flex; align-items: center; gap: 6px;\n }\n .term-abbr {\n font-size: var(--w-font-xxs); font-weight: var(--w-weight-medium);\n background: var(--unn-color-accent-tint-bg); color: var(--unn-color-accent-strong);\n border-radius: var(--w-radius-xs); padding: 1px 5px;\n }\n .term-def {\n font-size: var(--w-font-sm); color: var(--unn-color-text-muted); margin-top: 4px; line-height: 1.5;\n }\n .term-link {\n font-size: var(--w-font-xs); color: var(--unn-color-brand-primary);\n text-decoration: none; margin-top: 4px; display: inline-block;\n }\n .term-link:hover { text-decoration: underline; }\n .no-results {\n padding: 28px 18px; text-align: center;\n font-size: var(--w-font-base); color: var(--unn-color-text-subtle);\n }\n\n /* ---- Term card (clickable row inside list item) ---- */\n .term-card {\n cursor: pointer;\n }\n .term-card:hover .term-name { color: var(--unn-color-brand-primary); }\n\n /* ---- Term detail view ---- */\n .term-detail-view {\n display: flex; flex-direction: column; flex: 1; overflow-y: auto;\n }\n .detail-back {\n display: flex; align-items: center;\n padding: 10px 18px; border-bottom: 1px solid var(--unn-color-border-default); flex-shrink: 0;\n }\n .back-btn {\n background: none; border: none; cursor: pointer;\n font-size: var(--w-font-base); color: var(--unn-color-brand-primary); font-weight: var(--w-weight-medium);\n display: flex; align-items: center; gap: 4px; padding: 4px 0;\n }\n .back-btn:hover { text-decoration: underline; }\n .detail-content {\n padding: 18px 18px 10px;\n }\n .detail-term-name {\n font-size: var(--w-font-xl); font-weight: var(--w-weight-bold); color: var(--unn-color-text-primary);\n }\n .detail-term-def {\n font-size: var(--w-font-base); color: var(--unn-color-text-muted); margin-top: 8px; line-height: 1.6;\n }\n .detail-actions {\n display: flex; gap: 8px;\n padding: 10px 18px; border-bottom: 1px solid var(--unn-color-border-default); flex-shrink: 0;\n }\n .action-btn {\n padding: 7px 14px; border-radius: var(--w-radius-md); font-size: var(--w-font-base); font-weight: var(--w-weight-medium);\n cursor: pointer; border: var(--w-border-width) solid var(--unn-color-brand-primary);\n background: var(--unn-color-bg-primary); color: var(--unn-color-brand-primary);\n transition: background 0.15s, color 0.15s;\n }\n .action-btn:hover { background: var(--unn-color-brand-primary); color: var(--unn-color-text-inverse); }\n .discussions-section { padding: var(--w-space-v-lg) var(--w-space-h-md); flex: 1; }\n .discussions-heading {\n font-size: var(--w-font-xs); font-weight: var(--w-weight-semi); color: var(--unn-color-text-subtle);\n text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 10px;\n }\n .discussion-post {\n padding: var(--w-space-v-sm) var(--w-space-h-sm);\n border-bottom: 1px solid var(--unn-color-border-default);\n font-size: var(--w-font-base); color: var(--unn-color-text-body);\n line-height: 1.5;\n }\n .discussion-post:last-child { border-bottom: none; }\n .discussions-empty {\n font-size: var(--w-font-base); color: var(--unn-color-text-subtle); text-align: center; padding: 16px 0;\n }\n\n /* ---- Comment form view ---- */\n .comment-form-view {\n display: flex; flex-direction: column; flex: 1; overflow-y: auto;\n }\n .comment-textarea {\n margin: var(--w-space-v-lg) var(--w-space-h-md); padding: var(--w-space-v-sm) 12px;\n border: var(--w-border-width) solid var(--unn-color-border-subtle); border-radius: var(--w-radius-lg);\n font-size: var(--w-font-base); color: var(--unn-color-text-primary); min-height: 100px; resize: vertical;\n outline: none; transition: border-color 0.15s;\n font-family: inherit;\n }\n .comment-textarea:focus { border-color: var(--unn-color-brand-primary); }\n .comment-submit {\n margin: 0 18px; padding: 10px 16px;\n background: var(--unn-color-brand-primary); color: var(--unn-color-text-inverse);\n border: none; border-radius: var(--w-radius-lg);\n font-size: var(--w-font-md); font-weight: var(--w-weight-semi); cursor: pointer;\n transition: opacity 0.15s;\n }\n .comment-submit:hover { opacity: 0.9; }\n .comment-submit:disabled { opacity: 0.6; cursor: not-allowed; }\n\n /* ---- Edit form view ---- */\n .edit-form-view {\n display: flex; flex-direction: column; flex: 1; overflow-y: auto;\n padding: var(--w-space-v-lg) var(--w-space-h-md); gap: 12px;\n }\n .edit-label {\n font-size: var(--w-font-sm); font-weight: var(--w-weight-medium); color: var(--unn-color-text-body);\n margin-bottom: 4px; display: block;\n }\n .edit-input {\n width: 100%; padding: 9px 12px;\n border: var(--w-border-width) solid var(--unn-color-border-subtle); border-radius: var(--w-radius-lg);\n font-size: var(--w-font-md); color: var(--unn-color-text-primary);\n outline: none; transition: border-color 0.15s;\n }\n .edit-input:focus { border-color: var(--unn-color-brand-primary); }\n .edit-textarea {\n width: 100%; padding: 9px 12px;\n border: var(--w-border-width) solid var(--unn-color-border-subtle); border-radius: var(--w-radius-lg);\n font-size: var(--w-font-base); color: var(--unn-color-text-primary); min-height: 80px; resize: vertical;\n outline: none; transition: border-color 0.15s;\n font-family: inherit;\n }\n .edit-textarea:focus { border-color: var(--unn-color-brand-primary); }\n .edit-submit {\n padding: 10px 16px;\n background: var(--unn-color-brand-primary); color: var(--unn-color-text-inverse);\n border: none; border-radius: var(--w-radius-lg);\n font-size: var(--w-font-md); font-weight: var(--w-weight-semi); cursor: pointer;\n transition: opacity 0.15s;\n }\n .edit-submit:hover { opacity: 0.9; }\n\n /* ---- Suggested terms section ---- */\n .suggestions-section { padding: var(--w-space-v-md) var(--w-space-h-md) 16px; }\n .suggestions-heading {\n font-size: var(--w-font-xs); font-weight: var(--w-weight-semi); color: var(--unn-color-text-subtle);\n text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 8px;\n }\n .suggestion-item {\n display: flex; align-items: center; justify-content: space-between;\n padding: 8px 0; border-bottom: 1px solid var(--unn-color-border-default);\n }\n .suggestion-item:last-child { border-bottom: none; }\n .suggestion-info { display: flex; flex-direction: column; gap: 2px; }\n .suggestion-term { font-size: var(--w-font-base); font-weight: var(--w-weight-semi); color: var(--unn-color-text-primary); }\n .suggestion-count { font-size: var(--w-font-xs); color: var(--unn-color-text-subtle); }\n .suggestion-add {\n padding: 4px 10px; border-radius: var(--w-radius-sm); font-size: var(--w-font-sm); font-weight: var(--w-weight-medium);\n cursor: pointer; border: var(--w-border-width) solid var(--unn-color-brand-primary);\n background: var(--unn-color-bg-primary); color: var(--unn-color-brand-primary);\n flex-shrink: 0;\n transition: background 0.15s, color 0.15s;\n }\n .suggestion-add:hover { background: var(--unn-color-brand-primary); color: var(--unn-color-text-inverse); }\n\n /* ---- AI definition modal ---- */\n .ai-modal-overlay {\n position: absolute; inset: 0;\n background: rgba(255,255,255,0.96);\n display: flex; flex-direction: column;\n z-index: 10; padding: 24px 20px; gap: 14px;\n overflow-y: auto;\n }\n .ai-modal-title {\n font-size: var(--w-font-md); font-weight: var(--w-weight-semi); color: var(--unn-color-text-primary);\n }\n .ai-modal-term {\n font-size: var(--w-font-display); font-weight: var(--w-weight-bold); color: var(--unn-color-brand-primary);\n }\n .ai-modal-label {\n font-size: var(--w-font-sm); font-weight: var(--w-weight-medium); color: var(--unn-color-text-body); margin-bottom: 4px; display: block;\n }\n .ai-modal-textarea {\n width: 100%; padding: 9px 12px;\n border: var(--w-border-width) solid var(--unn-color-border-subtle); border-radius: var(--w-radius-lg);\n font-size: var(--w-font-base); color: var(--unn-color-text-primary); min-height: 120px; resize: vertical;\n outline: none; transition: border-color 0.15s;\n font-family: inherit;\n }\n .ai-modal-textarea:focus { border-color: var(--unn-color-brand-primary); }\n .ai-modal-char-count { font-size: var(--w-font-xs); color: var(--unn-color-text-subtle); text-align: right; }\n .ai-modal-actions { display: flex; gap: 8px; }\n .ai-modal-submit {\n flex: 1; padding: 10px 16px;\n background: var(--unn-color-brand-primary); color: var(--unn-color-text-inverse);\n border: none; border-radius: var(--w-radius-lg);\n font-size: var(--w-font-md); font-weight: var(--w-weight-semi); cursor: pointer;\n transition: opacity 0.15s;\n }\n .ai-modal-submit:hover { opacity: 0.9; }\n .ai-modal-submit:disabled { opacity: 0.6; cursor: not-allowed; }\n .ai-modal-cancel {\n padding: 10px 16px; border-radius: var(--w-radius-lg); font-size: var(--w-font-md);\n font-weight: var(--w-weight-medium); cursor: pointer;\n border: var(--w-border-width) solid var(--unn-color-border-subtle); background: var(--unn-color-bg-primary); color: var(--unn-color-text-body);\n transition: border-color 0.15s;\n }\n .ai-modal-cancel:hover { border-color: var(--unn-color-text-subtle); }\n\n /* ---- Toast notification ---- */\n .toast {\n position: absolute; bottom: 60px; left: 16px; right: 16px;\n background: var(--unn-color-brand-dark); color: var(--unn-color-text-inverse);\n padding: 10px 14px; border-radius: var(--w-radius-lg);\n font-size: var(--w-font-base); font-weight: var(--w-weight-medium);\n z-index: 20; text-align: center;\n animation: toast-in 0.2s ease;\n }\n @keyframes toast-in {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n }\n\n /* ---- UI States action bar (captures + tab nav) ---- */\n .action-bar {\n display: flex; align-items: center; justify-content: space-between;\n padding: 8px 18px; border-bottom: 1px solid var(--unn-color-border-default);\n flex-shrink: 0; gap: 8px;\n }\n .action-bar-tabs { display: flex; gap: 4px; }\n .tab-btn {\n padding: 5px 12px; border-radius: var(--w-radius-sm); font-size: var(--w-font-sm); font-weight: var(--w-weight-medium);\n cursor: pointer; border: var(--w-border-width) solid transparent;\n background: var(--unn-color-bg-tertiary); color: var(--unn-color-text-muted);\n transition: background 0.15s, color 0.15s;\n }\n .tab-btn:hover { background: var(--unn-color-border-default); color: var(--unn-color-text-body); }\n .tab-btn.active {\n background: var(--unn-color-brand-primary); color: var(--unn-color-text-inverse); border-color: var(--unn-color-brand-primary);\n }\n .capture-btn {\n padding: 5px 12px; border-radius: var(--w-radius-sm); font-size: var(--w-font-sm); font-weight: var(--w-weight-semi);\n cursor: pointer;\n border: var(--w-border-width) solid var(--unn-color-brand-primary); background: var(--unn-color-bg-primary); color: var(--unn-color-brand-primary);\n transition: background 0.15s, color 0.15s, opacity 0.15s;\n display: flex; align-items: center; gap: 5px;\n white-space: nowrap;\n }\n .capture-btn:hover { background: var(--unn-color-brand-primary); color: var(--unn-color-text-inverse); }\n .capture-btn:active { transform: scale(0.97); }\n .capture-btn:disabled { opacity: 0.5; cursor: not-allowed; }\n .capture-btn svg { width: 13px; height: 13px; stroke: currentColor; fill: none; stroke-width: 2; }\n\n /* ---- UI States list view ---- */\n .ui-states-list {\n flex: 1; overflow-y: auto; padding: 0;\n }\n .ui-state-item {\n padding: var(--w-space-v-md) var(--w-space-h-md); border-bottom: 1px solid var(--unn-color-border-default);\n transition: background 0.1s;\n }\n .ui-state-item:hover { background: var(--unn-color-bg-secondary); }\n .ui-state-url {\n font-size: var(--w-font-base); font-weight: var(--w-weight-semi); color: var(--unn-color-text-primary);\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n max-width: 280px;\n }\n .ui-state-meta {\n font-size: var(--w-font-xs); color: var(--unn-color-text-subtle); margin-top: 3px;\n display: flex; gap: 8px; align-items: center; flex-wrap: wrap;\n }\n .ui-state-role-badge {\n font-size: var(--w-font-xxs); font-weight: var(--w-weight-semi); padding: 1px 6px;\n border-radius: var(--w-radius-xs); background: var(--unn-color-accent-tint-bg); color: var(--unn-color-accent-strong);\n text-transform: uppercase; letter-spacing: 0.04em;\n }\n .ui-state-terms-preview {\n font-size: var(--w-font-xs); color: var(--unn-color-text-muted); margin-top: 4px;\n }\n .ui-state-actions {\n margin-top: 8px; display: flex; gap: 6px;\n }\n .view-detail-btn {\n padding: 4px 10px; border-radius: var(--w-radius-sm); font-size: var(--w-font-sm); font-weight: var(--w-weight-medium);\n cursor: pointer; border: var(--w-border-width) solid var(--unn-color-brand-primary);\n background: var(--unn-color-bg-primary); color: var(--unn-color-brand-primary);\n transition: background 0.15s, color 0.15s;\n }\n .view-detail-btn:hover { background: var(--unn-color-brand-primary); color: var(--unn-color-text-inverse); }\n\n /* ---- Load more ---- */\n .load-more-container { padding: var(--w-space-v-md) var(--w-space-h-md); text-align: center; }\n .load-more-btn {\n width: 100%; padding: 8px 16px; border-radius: var(--w-radius-lg);\n font-size: var(--w-font-base); font-weight: var(--w-weight-medium); cursor: pointer;\n border: var(--w-border-width) solid var(--unn-color-border-subtle); background: var(--unn-color-bg-primary); color: var(--unn-color-text-body);\n transition: background 0.15s;\n }\n .load-more-btn:hover { background: var(--unn-color-bg-tertiary); }\n\n /* ---- UI States empty state ---- */\n .ui-states-empty {\n padding: 40px 18px; text-align: center;\n }\n .ui-states-empty-icon {\n width: 40px; height: 40px; stroke: var(--unn-color-border-subtle); fill: none;\n margin: 0 auto 12px;\n }\n .ui-states-empty-text {\n font-size: var(--w-font-base); color: var(--unn-color-text-subtle); line-height: 1.5;\n }\n\n /* ---- UI State detail view ---- */\n .ui-state-detail-view {\n display: flex; flex-direction: column; flex: 1; overflow-y: auto;\n }\n .detail-meta-section { padding: var(--w-space-v-lg) var(--w-space-h-md); border-bottom: 1px solid var(--unn-color-border-default); }\n .detail-page-title {\n font-size: var(--w-font-lg, 15px); font-weight: var(--w-weight-semi); color: var(--unn-color-text-primary);\n padding: var(--w-space-v-md) var(--w-space-h-md) 2px; flex-shrink: 0;\n }\n .detail-meta-row {\n display: flex; gap: 12px; font-size: var(--w-font-sm); color: var(--unn-color-text-muted);\n flex-wrap: wrap; align-items: center;\n }\n .detail-section { padding: var(--w-space-v-md) var(--w-space-h-md); border-bottom: 1px solid var(--unn-color-border-default); }\n .detail-section-heading {\n font-size: var(--w-font-xs); font-weight: var(--w-weight-semi); color: var(--unn-color-text-subtle);\n text-transform: uppercase; letter-spacing: 0.05em;\n margin-bottom: 8px; display: flex; justify-content: space-between;\n align-items: center; cursor: pointer; user-select: none;\n }\n .detail-section-heading svg {\n width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 2;\n transition: transform 0.2s;\n }\n .detail-section-heading.collapsed svg { transform: rotate(-90deg); }\n .detail-section-content { display: flex; flex-wrap: wrap; gap: 6px; }\n .detail-section-content.collapsed { display: none; }\n .detail-section-list {\n font-size: var(--w-font-sm); color: var(--unn-color-text-body); line-height: 1.6;\n padding-left: 16px;\n }\n .detail-section-list.collapsed { display: none; }\n\n /* ---- Term pill / link in state detail ---- */\n .ui-state-term-link {\n display: inline-flex; align-items: center;\n padding: 3px 10px; border-radius: var(--w-radius-pill);\n font-size: var(--w-font-xs); font-weight: var(--w-weight-semi);\n background: var(--unn-color-accent-tint-bg); color: var(--unn-color-accent-strong);\n cursor: pointer; border: none;\n transition: background 0.15s, color 0.15s;\n }\n .ui-state-term-link:hover { background: var(--unn-color-accent-strong); color: var(--unn-color-text-inverse); }\n\n /* ---- Product Memory section ---- */\n .product-memory-section {\n padding: 10px var(--w-space-h-md);\n border-top: 1px solid var(--unn-color-border-default);\n }\n .product-memory-heading {\n font-size: var(--w-font-xxs); font-weight: var(--w-weight-bold); color: var(--unn-color-text-muted);\n text-transform: uppercase; letter-spacing: 0.05em;\n margin-bottom: 8px;\n }\n .product-memory-text {\n font-size: var(--w-font-base); color: var(--unn-color-text-primary); line-height: 1.6;\n white-space: pre-wrap; word-break: break-word;\n margin-bottom: 8px;\n }\n .product-memory-textarea {\n width: 100%; box-sizing: border-box;\n font-size: var(--w-font-base); color: var(--unn-color-text-primary); line-height: 1.6;\n border: 1px solid var(--unn-color-border-subtle); border-radius: var(--w-radius-sm);\n padding: 8px 10px; resize: vertical; min-height: 80px;\n font-family: inherit; background: var(--unn-color-bg-primary);\n margin-bottom: 8px;\n }\n .product-memory-textarea:focus {\n outline: none; border-color: var(--unn-color-brand-primary);\n box-shadow: 0 0 0 2px var(--unn-focus-ring-color);\n }\n .product-memory-actions {\n display: flex; gap: 6px; justify-content: flex-end;\n }\n .product-memory-edit-btn {\n font-size: var(--w-font-sm); font-weight: var(--w-weight-semi); color: var(--unn-color-accent);\n background: none; border: none; cursor: pointer;\n padding: 4px 8px; border-radius: var(--w-radius-xs);\n }\n .product-memory-edit-btn:hover { background: var(--unn-color-accent-tint-bg); }\n .product-memory-delete-entry-btn {\n font-size: var(--w-font-sm); color: var(--unn-color-text-muted);\n background: none; border: none; cursor: pointer;\n padding: 4px 6px; border-radius: var(--w-radius-xs);\n opacity: 0.7;\n }\n .product-memory-delete-entry-btn:hover { \n background: #fee; color: #d63; opacity: 1; \n }\n .product-memory-save-btn {\n font-size: var(--w-font-sm); font-weight: var(--w-weight-semi); color: var(--unn-color-text-inverse);\n background: var(--unn-color-brand-primary); border: none; cursor: pointer;\n padding: 5px 14px; border-radius: var(--w-radius-sm);\n }\n .product-memory-save-btn:hover { opacity: 0.85; }\n .product-memory-save-btn:disabled { opacity: 0.5; cursor: not-allowed; }\n .product-memory-cancel-btn {\n font-size: var(--w-font-sm); font-weight: var(--w-weight-semi); color: var(--unn-color-text-muted);\n background: none; border: 1px solid var(--unn-color-border-subtle); cursor: pointer;\n padding: 4px 10px; border-radius: var(--w-radius-sm);\n }\n .product-memory-cancel-btn:hover { background: var(--unn-color-bg-tertiary); }\n .detail-actions {\n display: flex;\n gap: 6px;\n justify-content: space-between;\n align-items: center;\n padding: var(--w-space-v-md) var(--w-space-h-md);\n border-top: 1px solid var(--unn-color-border-subtle);\n margin-top: 4px;\n }\n .detail-delete-btn, .detail-add-btn {\n font-size: var(--w-font-xs); font-weight: 500; border: none;\n border-radius: var(--w-radius-sm); cursor: pointer; padding: 5px 12px;\n }\n .detail-delete-btn {\n background: var(--unn-color-bg-tertiary);\n color: var(--unn-color-text-muted);\n }\n .detail-delete-btn:hover {\n background: var(--unn-color-border-default);\n }\n .detail-add-btn {\n background: var(--unn-color-brand-primary);\n color: #fff;\n }\n .detail-add-btn:hover {\n opacity: 0.88;\n }\n\n /* ---- Snapshot preview in state-detail view ---- */\n .ui-state-snapshot-preview {\n max-height: 180px; overflow: hidden;\n border-bottom: 1px solid var(--unn-color-border-default);\n background: var(--unn-color-bg-secondary);\n padding: 6px var(--w-space-h-md);\n }\n .ui-state-snapshot-preview * { pointer-events: none; }\n\n /* ---- Replay highlight (glossary terms on page) ---- */\n .unnoodle-replay-highlight {\n background: var(--unn-color-accent-tint);\n border-bottom: 2px solid var(--unn-color-brand-primary);\n border-radius: 2px;\n animation: replay-pulse 0.6s ease-out;\n }\n @keyframes replay-pulse {\n from { background: var(--unn-color-accent-tint-strong); }\n to { background: var(--unn-color-accent-tint); }\n }\n\n /* ---- Drag-resize handle ---- */\n .panel-resize-handle {\n position: absolute; left: 0; top: 0; bottom: 0;\n width: 6px; cursor: col-resize; z-index: 10;\n }\n .panel-resize-handle:hover { background: var(--unn-color-accent-tint); }\n .panel-shell.left-side .panel-resize-handle { left: auto; right: 0; }\n\n /* ---- Skeleton loaders ---- */\n @keyframes skeleton-shimmer {\n 0% { background-position: -400px 0; }\n 100% { background-position: 400px 0; }\n }\n .skeleton-line {\n border-radius: 4px;\n background: linear-gradient(90deg,\n var(--unn-color-border) 25%,\n color-mix(in srgb, var(--unn-color-border) 40%, var(--unn-color-bg)) 50%,\n var(--unn-color-border) 75%);\n background-size: 800px 100%;\n animation: skeleton-shimmer 1.4s infinite linear;\n }\n .skeleton-home {\n padding: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n text-align: center;\n }\n .skeleton-loading-header {\n padding: 0 24px 32px;\n }\n .skeleton-loading-brand {\n font-size: 20px; font-weight: 700;\n color: var(--unn-color-brand-primary);\n letter-spacing: -0.01em;\n margin-bottom: 12px;\n }\n .skeleton-loading-title {\n font-size: var(--w-font-base); font-weight: 600;\n color: var(--unn-color-text-primary);\n margin-bottom: 6px;\n }\n .skeleton-loading-sub {\n font-size: var(--w-font-sm);\n color: var(--unn-color-text-subtle);\n }\n .skeleton-body {\n width: 100%; padding: 0 24px;\n display: flex; flex-direction: column; gap: 16px;\n }\n .skeleton-strip {\n padding: 10px 0 8px;\n }\n .skeleton-section {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding-bottom: var(--w-space-2);\n }\n .skeleton-section-head {\n height: 9px;\n width: 28%;\n border-radius: 4px;\n background: linear-gradient(90deg,\n var(--unn-color-border) 25%,\n color-mix(in srgb, var(--unn-color-border) 40%, var(--unn-color-bg)) 50%,\n var(--unn-color-border) 75%);\n background-size: 800px 100%;\n animation: skeleton-shimmer 1.4s infinite linear;\n margin-bottom: 4px;\n }\n .skeleton-row {\n height: 24px;\n display: flex;\n align-items: center;\n border-radius: var(--w-radius-1);\n }\n\n /* ---- Home view layout ---- */\n .home-view {\n display: flex; flex-direction: column; height: 100%; overflow: hidden;\n background: var(--unn-color-bg-primary);\n }\n\n /* ---- Context strip — always visible action toolbar ---- */\n .context-strip {\n display: flex; align-items: center; gap: 6px;\n padding: 6px 10px;\n border-bottom: 1px solid var(--unn-color-border-default);\n flex-shrink: 0;\n min-height: 38px;\n }\n .strip-idle {\n display: flex; align-items: center; gap: 6px; width: 100%;\n }\n .strip-btn {\n display: inline-flex; align-items: center; gap: 4px;\n padding: 3px 10px; border-radius: var(--w-radius-lg);\n border: 1px solid var(--unn-color-border-default);\n background: var(--unn-color-bg-secondary);\n color: var(--unn-color-text-secondary); font-size: var(--w-font-sm);\n cursor: pointer; transition: background 0.15s, color 0.15s;\n }\n .strip-btn:hover { background: var(--unn-color-bg-hover); color: var(--unn-color-text-primary); }\n .strip-btn svg { width: 13px; height: 13px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }\n /* Pick-mode state */\n .pick-mode-prompt {\n display: none; align-items: center; gap: 8px; width: 100%;\n }\n .pick-prompt-text {\n flex: 1; font-size: var(--w-font-sm); color: var(--unn-color-text-secondary);\n font-style: italic;\n }\n .strip-cancel-btn {\n padding: 2px 8px; border-radius: var(--w-radius-lg);\n border: 1px solid var(--unn-color-border-default);\n background: transparent; color: var(--unn-color-text-secondary);\n font-size: var(--w-font-xs); cursor: pointer;\n }\n .strip-cancel-btn:hover { color: var(--unn-color-text-primary); border-color: var(--unn-color-text-primary); }\n /* Capture-describe view */\n .capture-describe-view {\n display: none; flex-direction: column; gap: 6px; width: 100%; padding: 4px 0;\n }\n .capture-snapshot-preview {\n max-height: 120px; overflow: hidden; border-radius: var(--w-radius-1);\n border: 1px solid var(--unn-color-border-default);\n background: var(--unn-color-bg-secondary);\n }\n .capture-snapshot-meta {\n font-size: var(--w-font-xs); color: var(--unn-color-text-secondary); padding: 2px 4px;\n }\n .capture-description-input {\n width: 100%; box-sizing: border-box; resize: none;\n border: 1px solid var(--unn-color-border-default);\n border-radius: var(--w-radius-1);\n background: var(--unn-color-bg-secondary);\n color: var(--unn-color-text-primary); font-size: var(--w-font-sm);\n padding: 6px 8px; outline: none; font-family: inherit;\n }\n .capture-description-input:focus { border-color: var(--unn-color-accent); }\n .capture-error {\n font-size: var(--w-font-xs); color: var(--unn-color-error, #d32f2f); margin: 0;\n }\n .capture-actions {\n display: flex; gap: 6px; justify-content: flex-end;\n }\n .capture-save-btn {\n padding: 3px 12px; border-radius: var(--w-radius-lg);\n border: none; background: var(--unn-color-accent); color: #fff;\n font-size: var(--w-font-sm); cursor: pointer;\n }\n .capture-save-btn:disabled { opacity: 0.6; cursor: not-allowed; }\n /* Search bar — always visible */\n .home-search-bar {\n padding: 8px 10px 2px;\n flex-shrink: 0;\n }\n .home-search-input {\n width: 100%; box-sizing: border-box; height: 26px;\n border: 1px solid var(--unn-color-border-default);\n border-radius: var(--w-radius-lg);\n background: var(--unn-color-bg-secondary);\n color: var(--unn-color-text-primary); font-size: var(--w-font-sm);\n padding: 0 10px; outline: none;\n transition: border-color 0.15s, box-shadow 0.15s;\n }\n .home-search-input:focus {\n border-color: var(--unn-color-brand-primary);\n box-shadow: 0 0 0 3px var(--unn-color-brand-tint);\n }\n\n /* Sections scroll area */\n .home-sections {\n flex: 1; overflow-y: auto;\n padding: 10px 10px 20px;\n display: flex; flex-direction: column; gap: 24px;\n }\n\n /* ---- Sections — no card border, grouped by heading + spacing ---- */\n .home-section { /* bare container, no border/bg */ }\n .home-section:not(:last-child) {\n border-bottom: 1px solid var(--unn-color-border-default);\n padding-bottom: 20px;\n }\n .home-section-header {\n display: flex; align-items: center; justify-content: space-between;\n padding: 0 0 6px;\n }\n .home-section-title {\n display: flex; align-items: center; gap: 6px;\n font-size: 10px; font-weight: 700; letter-spacing: 0.07em;\n text-transform: uppercase; color: var(--unn-color-text-muted);\n }\n .home-section-dot {\n width: 12px; height: 12px; flex-shrink: 0;\n display: flex; align-items: center; justify-content: center;\n }\n .home-section-dot svg {\n width: 12px; height: 12px; display: block;\n }\n .home-section-add {\n font-size: 15px; font-weight: 400; line-height: 1;\n color: var(--unn-color-brand-primary);\n background: transparent;\n border: none; cursor: pointer;\n padding: 0 2px; border-radius: var(--w-radius-sm);\n transition: color 0.15s; flex-shrink: 0;\n }\n .home-section-add:hover { color: var(--unn-color-accent-strong); }\n .home-section-add:disabled { color: var(--unn-color-text-subtle); cursor: default; }\n .home-section-show-all {\n font-size: 10px; font-weight: 400; line-height: 1;\n color: var(--unn-color-text-secondary);\n background: transparent;\n border: none; cursor: pointer;\n padding: 2px 4px; border-radius: var(--w-radius-sm);\n transition: color 0.15s; flex-shrink: 0;\n margin-right: 4px;\n }\n .home-section-show-all:hover { \n color: var(--unn-color-text); \n background: var(--unn-color-surface-subtle);\n }\n .home-section-helper {\n font-size: 10px; color: var(--unn-color-text-subtle);\n margin: -4px 0 6px; line-height: 1.4;\n }\n\n /* ---- Concept rows ---- */\n .concept-row {\n display: flex; align-items: center; gap: 8px;\n padding: 6px 6px; cursor: pointer;\n margin: 0 -6px;\n transition: background 0.12s;\n border-radius: var(--w-radius-sm);\n }\n .concept-row:hover { background: var(--unn-color-bg-secondary); }\n .concept-row:hover .concept-name { color: var(--unn-color-brand-primary); }\n .concept-name {\n flex: 1; font-size: var(--w-font-base); font-weight: 500;\n color: var(--unn-color-text-primary);\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n transition: color 0.12s;\n }\n .concept-abbr {\n font-size: var(--w-font-xs); color: var(--unn-color-accent-strong);\n background: var(--unn-color-accent-tint-bg);\n border-radius: var(--w-radius-pill);\n padding: 1px 7px; white-space: nowrap; flex-shrink: 0; font-weight: 500;\n }\n .concept-chevron {\n flex-shrink: 0; color: var(--unn-color-text-subtle);\n opacity: 0.35; transition: opacity 0.12s, color 0.12s;\n }\n .concept-chevron svg { width: 12px; height: 12px; stroke: currentColor; fill: none; stroke-width: 2.5; }\n .concept-row:hover .concept-chevron { opacity: 1; color: var(--unn-color-brand-primary); }\n .concept-subheading {\n font-size: 10px; font-weight: 700; letter-spacing: 0.06em;\n text-transform: uppercase; color: var(--unn-color-text-subtle);\n padding: 8px 0 4px; margin-top: 4px;\n }\n .concept-subheading:first-child { margin-top: 0; }\n\n /* ---- Section empty states ---- */\n .section-empty { padding: 14px 0 6px; text-align: left; }\n .section-empty-title {\n font-size: var(--w-font-sm); font-weight: 600;\n color: var(--unn-color-text-body); margin-bottom: 4px;\n }\n .section-empty-text {\n font-size: var(--w-font-sm); color: var(--unn-color-text-subtle); line-height: 1.5;\n margin-bottom: 12px;\n }\n .section-empty-action {\n all: unset; display: inline-flex; cursor: pointer;\n font-size: var(--w-font-sm); font-weight: 500;\n color: var(--unn-color-text-primary);\n border: 1px solid var(--unn-color-border-default);\n border-radius: var(--w-radius-sm);\n padding: 5px 12px;\n transition: background 0.15s, border-color 0.15s;\n }\n .section-empty-action:hover {\n background: var(--unn-color-bg-secondary);\n border-color: var(--unn-color-text-muted);\n }\n\n /* ---- Memory items in PRODUCT MEMORY home section ---- */\n .memory-item {\n display: flex; align-items: center; gap: 8px;\n padding: 6px 6px; cursor: pointer;\n margin: 0 -6px;\n transition: background 0.12s;\n border-radius: var(--w-radius-sm);\n }\n .memory-item:hover { background: var(--unn-color-bg-secondary); }\n .memory-item:hover .memory-item-title { color: var(--unn-color-brand-primary); }\n .memory-item:hover .concept-chevron { opacity: 1; color: var(--unn-color-brand-primary); }\n .memory-item-content {\n flex: 1; min-width: 0;\n }\n .memory-item-title {\n font-size: var(--w-font-base); font-weight: 500;\n color: var(--unn-color-text-primary);\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n transition: color 0.12s;\n }\n .memory-item-meta {\n font-size: var(--w-font-xs); color: var(--unn-color-text-subtle);\n margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n }\n\n /* ---- Show-all link ---- */\n .home-show-more {\n display: block; width: 100%; box-sizing: border-box;\n padding: 6px 0; font-size: var(--w-font-xs); font-weight: 500;\n color: var(--unn-color-brand-primary); cursor: pointer; text-align: left;\n margin-top: 2px; text-decoration: none;\n transition: color 0.15s;\n }\n .home-show-more:hover { \n color: var(--unn-color-accent-strong); \n text-decoration: underline;\n }\n\n /* ---- Discussion cards in home ---- */\n .discussion-card {\n display: flex; align-items: flex-start; gap: 8px;\n padding: 6px 6px; cursor: pointer;\n margin: 0 -6px;\n transition: background 0.12s;\n border-radius: var(--w-radius-sm);\n }\n .discussion-card:hover { background: var(--unn-color-bg-tertiary); }\n .discussion-card:hover .concept-chevron { opacity: 1; color: var(--unn-color-brand-primary); }\n .discussion-card-main {\n flex: 1;\n }\n .discussion-meta {\n display: flex; align-items: center; gap: 5px;\n font-size: 10px; color: var(--unn-color-text-subtle);\n margin-bottom: 3px; font-weight: 500;\n }\n .discussion-meta-dot {\n width: 4px; height: 4px; border-radius: 50%;\n background: var(--unn-color-brand-secondary); flex-shrink: 0;\n }\n .discussion-body {\n margin: 0; font-size: var(--w-font-sm); color: var(--unn-color-text-body);\n white-space: pre-wrap; word-break: break-word; line-height: 1.5;\n display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;\n }\n .discussion-replies { margin-top: 5px; padding-left: 10px; border-left: 2px solid var(--unn-color-border-default); }\n .discussion-reply { margin-top: 4px; }\n\n /* ---- Clarification detail view ---- */\n .clarif-label {\n font-size: var(--w-font-xs); font-weight: 600; letter-spacing: 0.06em;\n text-transform: uppercase; color: var(--unn-color-text-subtle);\n margin-bottom: 6px;\n }\n .clarif-question {\n margin: 0 0 4px; font-size: var(--w-font-md);\n color: var(--unn-color-text-primary); line-height: 1.5;\n font-weight: var(--w-weight-semi); white-space: pre-wrap; word-break: break-word;\n }\n .clarif-empty-replies {\n font-size: var(--w-font-sm); color: var(--unn-color-text-subtle);\n padding: 6px 0;\n }\n .clarif-reply-item {\n padding: 6px 0;\n border-bottom: 1px solid var(--unn-color-border-subtle);\n }\n .clarif-reply-item:last-child { border-bottom: none; }\n .clarif-reply-form {\n padding: 10px 12px 12px;\n border-top: 1px solid var(--unn-color-border-default);\n margin-top: 6px;\n }\n\n /* ---- Ask Question form ---- */\n .ask-form { padding: 10px 12px; border-bottom: 1px solid var(--unn-color-border-default); }\n .ask-textarea {\n width: 100%; box-sizing: border-box;\n border: 1px solid var(--unn-color-border-default);\n border-radius: var(--w-radius-sm);\n background: var(--unn-color-bg-secondary);\n color: var(--unn-color-text-primary); font-size: var(--w-font-sm);\n padding: 7px 10px; resize: vertical; outline: none; font-family: inherit;\n transition: border-color 0.15s;\n }\n .ask-textarea:focus { border-color: var(--unn-color-brand-primary); }\n .ask-actions { display: flex; gap: 6px; justify-content: flex-end; margin-top: 6px; }\n .ask-cancel, .ask-submit {\n font-size: var(--w-font-xs); font-weight: 500; border: none;\n border-radius: var(--w-radius-sm); cursor: pointer; padding: 5px 12px;\n }\n .ask-cancel { background: var(--unn-color-bg-tertiary); color: var(--unn-color-text-muted); }\n .ask-cancel:hover { background: var(--unn-color-border-default); }\n .ask-submit { background: var(--unn-color-brand-primary); color: #fff; }\n .ask-submit:hover { opacity: 0.88; }\n .ask-submit:disabled { opacity: 0.5; cursor: default; }\n\n /* ---- Add Term form ---- */\n .add-term-form { padding: 10px 12px; border-bottom: 1px solid var(--unn-color-border-default); }\n .add-term-input {\n width: 100%; box-sizing: border-box;\n border: 1px solid var(--unn-color-border-default);\n border-radius: var(--w-radius-sm);\n background: var(--unn-color-bg-secondary);\n color: var(--unn-color-text-primary); font-size: var(--w-font-sm);\n padding: 7px 10px; outline: none; font-family: inherit;\n transition: border-color 0.15s;\n }\n .add-term-input:focus { border-color: var(--unn-color-brand-primary); }\n .add-term-input + .add-term-input { margin-top: 6px; }\n`;\n\n/** CSS injected into the ShadowRoot when the panel runs in a popup window. */\nexport const POPOUT_OVERRIDE_STYLE = `\n .panel-shell {\n position: static !important;\n width: 100vw !important; height: 100vh !important;\n transform: none !important;\n max-width: 100vw !important;\n border-radius: 0 !important;\n box-shadow: none !important;\n }\n .panel-shell.open { transform: none !important; }\n .panel {\n border-radius: 0 !important;\n border: none !important;\n /* Fallback bg if CSS vars haven't re-resolved after adoptNode */\n background: var(--unn-color-bg-primary, #ffffff) !important;\n }\n`;\n","import type { SsoProviders } from \"../../types/config\";\n\nexport interface LoginViewCallbacks {\n onLogin: (email: string, password: string) => void;\n onSsoLogin?: (provider: string) => void;\n /** If provided, a back button is rendered and this callback is invoked on click. */\n onBack?: (() => void) | null;\n}\n\nexport function renderLoginView(\n body: HTMLElement,\n cb: LoginViewCallbacks,\n providers?: SsoProviders,\n): void {\n const showGoogle = providers?.googleEnabled === true;\n const showMicrosoft = providers?.microsoftEnabled === true;\n const hasSso = showGoogle || showMicrosoft;\n\n const googleBtnHtml = showGoogle\n ? `<button class=\"sso-btn\" type=\"button\" data-testid=\"widget-sso-google-btn\" aria-label=\"Continue with Google\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path fill=\"#4285F4\" d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z\"/>\n <path fill=\"#34A853\" d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"/>\n <path fill=\"#FBBC05\" d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l3.66-2.84z\"/>\n <path fill=\"#EA4335\" d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"/>\n </svg>\n <span>Continue with Google</span>\n </button>`\n : \"\";\n\n const microsoftBtnHtml = showMicrosoft\n ? `<button class=\"sso-btn\" type=\"button\" data-testid=\"widget-sso-microsoft-btn\" aria-label=\"Continue with Microsoft\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 23 23\" aria-hidden=\"true\">\n <rect x=\"1\" y=\"1\" width=\"10\" height=\"10\" fill=\"#F25022\"/>\n <rect x=\"12\" y=\"1\" width=\"10\" height=\"10\" fill=\"#7FBA00\"/>\n <rect x=\"1\" y=\"12\" width=\"10\" height=\"10\" fill=\"#00A4EF\"/>\n <rect x=\"12\" y=\"12\" width=\"10\" height=\"10\" fill=\"#FFB900\"/>\n </svg>\n <span>Continue with Microsoft</span>\n </button>`\n : \"\";\n\n const dividerHtml = hasSso\n ? `<div class=\"sso-divider\" data-testid=\"widget-sso-divider\">\n <div class=\"sso-divider-line\"></div>\n <span class=\"sso-divider-text\">or sign in with</span>\n <div class=\"sso-divider-line\"></div>\n </div>`\n : \"\";\n\n const ssoSectionHtml = hasSso\n ? `${dividerHtml}<div class=\"sso-buttons\">${googleBtnHtml}${microsoftBtnHtml}</div>`\n : \"\";\n\n body.innerHTML = `\n <div class=\"login-form\">\n ${cb.onBack ? `<button class=\"login-back-btn\" data-testid=\"widget-login-back\" type=\"button\">‹ Back</button>` : \"\"}\n <h2 class=\"login-heading\">Sign in to Unnoodle</h2>\n <p class=\"login-sub\">Access your team's glossary</p>\n <div class=\"login-error\" role=\"alert\" data-testid=\"widget-login-error\"></div>\n <div class=\"form-field\">\n <label class=\"form-label\" for=\"unn-email\">Email</label>\n <input class=\"form-input\" id=\"unn-email\" type=\"email\"\n autocomplete=\"email\" placeholder=\"you@company.com\" required\n data-testid=\"widget-login-email\" />\n </div>\n <div class=\"form-field\">\n <label class=\"form-label\" for=\"unn-password\">Password</label>\n <input class=\"form-input\" id=\"unn-password\" type=\"password\"\n autocomplete=\"current-password\" placeholder=\"••••••••\" required\n data-testid=\"widget-login-password\" />\n </div>\n <button class=\"form-submit\" id=\"unn-submit\" data-testid=\"widget-login-submit\">Sign in</button>\n ${ssoSectionHtml}\n </div>\n `;\n\n const backBtn = body.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-login-back\"]',\n );\n if (backBtn && cb.onBack) {\n const back = cb.onBack;\n backBtn.addEventListener(\"click\", () => back());\n }\n\n const emailEl = body.querySelector(\"#unn-email\") as HTMLInputElement;\n const passEl = body.querySelector(\"#unn-password\") as HTMLInputElement;\n const submitEl = body.querySelector(\"#unn-submit\") as HTMLButtonElement;\n\n const handleSubmit = (e: Event) => {\n e.preventDefault();\n const email = emailEl.value.trim();\n const password = passEl.value;\n if (!email || !password) return;\n cb.onLogin(email, password);\n };\n\n submitEl.addEventListener(\"click\", handleSubmit);\n // Allow Enter key to submit\n passEl.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\") handleSubmit(e);\n });\n\n // Wire up SSO buttons\n if (cb.onSsoLogin) {\n const ssoHandler = cb.onSsoLogin;\n if (showGoogle) {\n const googleBtn = body.querySelector(\n '[data-testid=\"widget-sso-google-btn\"]',\n ) as HTMLButtonElement | null;\n googleBtn?.addEventListener(\"click\", () => ssoHandler(\"google\"));\n }\n if (showMicrosoft) {\n const microsoftBtn = body.querySelector(\n '[data-testid=\"widget-sso-microsoft-btn\"]',\n ) as HTMLButtonElement | null;\n microsoftBtn?.addEventListener(\"click\", () => ssoHandler(\"microsoft\"));\n }\n }\n\n emailEl.focus();\n}\n\nexport function setLoginLoadingState(\n body: HTMLElement,\n loading: boolean,\n): void {\n const submitEl = body.querySelector(\n \"#unn-submit\",\n ) as HTMLButtonElement | null;\n if (!submitEl) return;\n submitEl.disabled = loading;\n submitEl.textContent = loading ? \"Signing in\\u2026\" : \"Sign in\";\n}\n\nexport function setLoginErrorState(body: HTMLElement, message: string): void {\n const errEl = body.querySelector(\".login-error\") as HTMLElement | null;\n if (!errEl) return;\n errEl.textContent = message;\n errEl.classList.add(\"visible\");\n}\n","/** HTML-escape user content to prevent XSS. */\nexport function escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#039;\");\n}\n","import type { ContextDiscussion } from \"../../types/config\";\nimport { escapeHtml } from \"../utils\";\n\nexport interface ClarificationViewCallbacks {\n onBack?: () => void;\n onPostReply?: (contextId: number, discussionId: number, text: string) => void;\n}\n\nexport function renderClarificationDetailView(\n body: HTMLElement,\n discussion: ContextDiscussion,\n canReply: boolean,\n cb: ClarificationViewCallbacks,\n): void {\n const authorLabel = escapeHtml(discussion.authorName ?? \"Unknown\");\n const date = discussion.createdAt\n ? new Date(discussion.createdAt).toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n })\n : \"\";\n\n const repliesHtml =\n (discussion.replies ?? []).length === 0\n ? `<div class=\"clarif-empty-replies\">No replies yet.</div>`\n : discussion.replies\n .map(\n (r) => `\n <div class=\"clarif-reply-item\">\n <div class=\"discussion-meta\">\n <span class=\"discussion-meta-dot\"></span>\n ${escapeHtml(r.authorName ?? \"Unknown\")} &middot;\n ${new Date(r.createdAt).toLocaleDateString(undefined, { month: \"short\", day: \"numeric\" })}\n </div>\n <p class=\"discussion-body\" style=\"-webkit-line-clamp:unset\">${escapeHtml(r.body)}</p>\n </div>`,\n )\n .join(\"\");\n\n const replyFormHtml = canReply\n ? `<div class=\"clarif-reply-form\" data-testid=\"widget-reply-form\">\n <textarea class=\"ask-textarea\" data-testid=\"widget-reply-textarea\"\n placeholder=\"Write a reply…\" maxlength=\"2000\" rows=\"3\"></textarea>\n <div class=\"ask-actions\">\n <button class=\"ask-submit\" data-testid=\"widget-reply-submit\">Reply</button>\n </div>\n <p class=\"ask-error\" style=\"display:none\"></p>\n </div>`\n : ``;\n\n body.innerHTML = `\n <div class=\"term-detail-view\" data-testid=\"widget-clarif-detail\">\n <div class=\"detail-back\">\n <button class=\"back-btn\" data-testid=\"widget-back-btn\">&#8592; Back</button>\n </div>\n <div class=\"detail-content\">\n <div class=\"detail-body\">\n <div class=\"clarif-label\">CLARIFICATION</div>\n <p class=\"clarif-question\">${escapeHtml(discussion.body)}</p>\n <div class=\"discussion-meta\" style=\"margin-top:6px\">\n <span class=\"discussion-meta-dot\"></span>\n ${authorLabel} &middot; ${date}\n </div>\n </div>\n </div>\n <div class=\"discussions-section\">\n <div class=\"discussions-heading\">Replies (${(discussion.replies ?? []).length})</div>\n ${repliesHtml}\n </div>\n ${replyFormHtml}\n </div>\n `;\n\n const backBtn = body.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-back-btn\"]',\n )!;\n backBtn.addEventListener(\"click\", () => cb.onBack?.());\n\n if (canReply) {\n const textarea = body.querySelector<HTMLTextAreaElement>(\n '[data-testid=\"widget-reply-textarea\"]',\n )!;\n const submitBtn = body.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-reply-submit\"]',\n )!;\n const errorEl = body.querySelector<HTMLParagraphElement>(\".ask-error\")!;\n\n submitBtn.addEventListener(\"click\", () => {\n const text = textarea.value.trim();\n if (!text) return;\n errorEl.style.display = \"none\";\n submitBtn.disabled = true;\n submitBtn.textContent = \"Posting\\u2026\";\n cb.onPostReply?.(discussion.contextId, discussion.id, text);\n });\n }\n}\n","import type { ElementSnapshot } from \"../../core/product-memory/elementSnapshot\";\n\nexport function enterPickModeView(strip: HTMLElement, onCancel: () => void): void {\n (strip.querySelector<HTMLElement>(\".strip-idle\") as HTMLElement).style.display = \"none\";\n const prompt = strip.querySelector<HTMLElement>(\".pick-mode-prompt\") as HTMLElement;\n prompt.style.display = \"flex\";\n (strip.querySelector<HTMLElement>(\".capture-describe-view\") as HTMLElement).style.display = \"none\";\n // Clone cancel button to remove stale listeners\n const cancelBtn = strip.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-context-strip-cancel-btn\"]',\n )!;\n const fresh = cancelBtn.cloneNode(true) as HTMLButtonElement;\n fresh.addEventListener(\"click\", onCancel);\n cancelBtn.replaceWith(fresh);\n}\n\nexport function showCaptureDescribeView(\n strip: HTMLElement,\n snapshot: ElementSnapshot,\n onSave: (description: string) => void,\n onPickAgain: () => void,\n): void {\n (strip.querySelector<HTMLElement>(\".strip-idle\") as HTMLElement).style.display = \"none\";\n (strip.querySelector<HTMLElement>(\".pick-mode-prompt\") as HTMLElement).style.display = \"none\";\n const descView = strip.querySelector<HTMLElement>(\".capture-describe-view\") as HTMLElement;\n descView.style.display = \"flex\";\n // Populate snapshot preview\n const preview = descView.querySelector<HTMLElement>(\n '[data-testid=\"widget-capture-snapshot-preview\"]',\n ) as HTMLElement;\n preview.innerHTML = snapshot.html;\n // Wire pick-again (clone to remove stale listeners)\n const pickAgainBtn = descView.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-capture-pick-again-btn\"]',\n )!;\n const freshPickAgain = pickAgainBtn.cloneNode(true) as HTMLButtonElement;\n freshPickAgain.addEventListener(\"click\", onPickAgain);\n pickAgainBtn.replaceWith(freshPickAgain);\n // Wire save (clone to remove stale listeners)\n const saveBtn = descView.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-capture-save-btn\"]',\n )!;\n const freshSave = saveBtn.cloneNode(true) as HTMLButtonElement;\n (descView.querySelector<HTMLElement>(\".capture-error\") as HTMLElement).style.display = \"none\";\n freshSave.addEventListener(\"click\", () => {\n const textarea = descView.querySelector<HTMLTextAreaElement>(\n '[data-testid=\"widget-capture-description-input\"]',\n )!;\n void onSave(textarea.value.trim());\n });\n saveBtn.replaceWith(freshSave);\n}\n\nexport function setCaptureLoadingState(strip: HTMLElement, loading: boolean): void {\n const saveBtn = strip.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-capture-save-btn\"]',\n );\n if (!saveBtn) return;\n saveBtn.disabled = loading;\n saveBtn.textContent = loading ? \"Saving\\u2026\" : \"Save\";\n}\n\nexport function setCaptureErrorState(strip: HTMLElement, message: string): void {\n const err = strip.querySelector<HTMLElement>(\".capture-error\");\n if (!err) return;\n err.textContent = message;\n err.style.display = message ? \"block\" : \"none\";\n}\n\nexport function exitCaptureModeView(strip: HTMLElement): void {\n (strip.querySelector<HTMLElement>(\".strip-idle\") as HTMLElement).style.display = \"flex\";\n (strip.querySelector<HTMLElement>(\".pick-mode-prompt\") as HTMLElement).style.display = \"none\";\n (strip.querySelector<HTMLElement>(\".capture-describe-view\") as HTMLElement).style.display = \"none\";\n const textarea = strip.querySelector<HTMLTextAreaElement>(\n '[data-testid=\"widget-capture-description-input\"]',\n );\n if (textarea) textarea.value = \"\";\n const errEl = strip.querySelector<HTMLElement>(\".capture-error\");\n if (errEl) {\n errEl.textContent = \"\";\n errEl.style.display = \"none\";\n }\n}\n","/**\n * Capture Form Controller\n *\n * Renders the \"New Memory / Add Entry\" form UI and manages its state.\n * Used by panel.ts to implement showNewMemoryForm() and showAddEntryForm().\n */\n\nimport { safeCSS } from \"./safeCSS\";\nimport type { ElementSnapshot } from \"../core/product-memory/elementSnapshot\";\n\nexport interface CaptureFormCallbacks {\n onPickElement: () => void;\n onCancelCapture: () => void;\n onSave: (\n title: string,\n explanation: string,\n watchForChanges: boolean,\n ) => void;\n onCancel: () => void;\n}\n\nexport interface CaptureFormController {\n /** Update the snapshot preview (called after UI state is picked) */\n setSnapshot: (snapshot: ElementSnapshot | null) => void;\n /** Show picking mode UI (dashed border, cancel button, progress text) */\n setPickingMode: (picking: boolean) => void;\n /** Toggle loading state on the save button */\n setLoading: (loading: boolean) => void;\n /** Show an error message */\n setError: (message: string) => void;\n /** Clear the form (reset inputs) */\n clear: () => void;\n}\n\nexport interface CaptureFormOptions {\n /** Whether to show the title input field (hidden for \"add entry\" mode) */\n showTitle: boolean;\n /** Main header text (e.g., memory title for add entry mode) */\n headerText?: string;\n /** Optional subheader text (e.g., \"Add new entry\") */\n subheaderText?: string;\n}\n\n/**\n * Renders the capture form HTML and returns a controller to manage its state.\n * Does NOT mount it to the DOM — caller is responsible for appending the returned element.\n */\nexport function createCaptureForm(\n callbacks: CaptureFormCallbacks,\n options: CaptureFormOptions,\n): { element: HTMLElement; controller: CaptureFormController } {\n const container = document.createElement(\"div\");\n container.className = \"capture-form-container\";\n container.setAttribute(\"data-testid\", \"widget-capture-form\");\n\n const html = `\n <style>\n ${safeCSS(`\n .capture-form-container {\n display: flex;\n flex-direction: column;\n gap: var(--w-space-4);\n padding: var(--w-space-h-md);\n background: var(--unn-color-bg-primary);\n overflow-y: auto;\n flex: 1;\n height: 100%;\n }\n .capture-form-header {\n font-size: var(--w-font-xl);\n font-weight: var(--w-weight-bold);\n color: var(--unn-color-text-primary);\n margin: 0 0 4px 0;\n line-height: 1.3;\n }\n .capture-form-subheader {\n font-size: var(--w-font-md);\n font-weight: var(--w-weight-medium);\n color: var(--unn-color-text-secondary);\n margin: 0 0 16px 0;\n }\n .capture-form-field {\n display: flex;\n flex-direction: column;\n gap: 5px;\n }\n .capture-form-label {\n font-size: var(--w-font-sm);\n font-weight: var(--w-weight-medium);\n color: var(--unn-color-text-body);\n }\n .capture-form-input,\n .capture-form-textarea {\n width: 100%;\n padding: 9px 12px;\n border: var(--w-border-width) solid var(--unn-color-border-subtle);\n border-radius: var(--w-radius-lg);\n font-size: var(--w-font-md);\n font-family: inherit;\n color: var(--unn-color-text-primary);\n outline: none;\n transition: border-color 0.15s;\n box-sizing: border-box;\n }\n .capture-form-input:focus,\n .capture-form-textarea:focus {\n border-color: var(--unn-color-brand-primary);\n }\n .capture-form-textarea {\n min-height: 100px;\n resize: vertical;\n }\n .capture-form-snapshot-container {\n border: var(--w-border-width) solid var(--unn-color-border-default);\n border-radius: var(--w-radius-1);\n padding: 12px;\n background: var(--unn-color-bg-secondary);\n min-height: 80px;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n transition: border 0.2s;\n }\n .capture-form-snapshot-container.picking {\n border: 2px dashed var(--unn-color-brand-primary);\n }\n .capture-form-snapshot-empty {\n color: var(--unn-color-text-subtle);\n font-size: var(--w-font-sm);\n }\n .capture-form-snapshot-preview {\n max-width: 100%;\n overflow: hidden;\n }\n .capture-form-pick-btn {\n padding: 3px 10px;\n background: var(--unn-color-bg-secondary);\n border: var(--w-border-width) solid var(--unn-color-border-default);\n border-radius: var(--w-radius-lg);\n font-size: var(--w-font-sm);\n font-weight: var(--w-weight-medium);\n color: var(--unn-color-text-secondary);\n cursor: pointer;\n transition: all 0.15s;\n }\n .capture-form-pick-btn:hover {\n background: var(--unn-color-bg-hover);\n color: var(--unn-color-text-primary);\n }\n .capture-form-pick-btn:active {\n background: var(--unn-color-bg-subtle);\n }\n .capture-form-cancel-capture-btn {\n padding: 3px 10px;\n background: var(--unn-color-bg-tertiary);\n border: var(--w-border-width) solid var(--unn-color-border-default);\n border-radius: var(--w-radius-lg);\n font-size: var(--w-font-sm);\n font-weight: var(--w-weight-medium);\n color: var(--unn-color-text-muted);\n cursor: pointer;\n transition: all 0.15s;\n }\n .capture-form-cancel-capture-btn:hover {\n background: var(--unn-color-border-default);\n }\n .capture-form-actions {\n display: flex;\n gap: 6px;\n justify-content: flex-end;\n margin-top: 6px;\n }\n .capture-form-save-btn,\n .capture-form-cancel-btn {\n font-size: var(--w-font-xs);\n font-weight: 500;\n border: none;\n border-radius: var(--w-radius-sm);\n cursor: pointer;\n padding: 5px 12px;\n }\n .capture-form-save-btn {\n background: var(--unn-color-brand-primary);\n color: #fff;\n }\n .capture-form-save-btn:hover:not(:disabled) {\n opacity: 0.88;\n }\n .capture-form-save-btn:disabled {\n opacity: 0.5;\n cursor: default;\n }\n .capture-form-cancel-btn {\n background: var(--unn-color-bg-tertiary);\n color: var(--unn-color-text-muted);\n }\n .capture-form-cancel-btn:hover {\n background: var(--unn-color-border-default);\n }\n .capture-form-watch-row {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 2px;\n }\n .capture-form-watch-checkbox {\n width: 16px;\n height: 16px;\n cursor: pointer;\n accent-color: var(--unn-color-brand-primary);\n flex-shrink: 0;\n }\n .capture-form-watch-label {\n font-size: var(--w-font-sm);\n color: var(--unn-color-text-body);\n cursor: pointer;\n user-select: none;\n }\n .capture-form-error {\n color: var(--unn-color-status-error);\n font-size: var(--w-font-sm);\n margin-top: -8px;\n display: none;\n }\n .capture-form-error.visible {\n display: block;\n }\n `)}\n </style>\n <h2 class=\"capture-form-header\">${options.headerText || (options.showTitle ? \"New Product Memory\" : \"Add Entry\")}</h2>\n ${options.subheaderText ? `<p class=\"capture-form-subheader\">${options.subheaderText}</p>` : \"\"}\n \n ${\n options.showTitle\n ? `\n <div class=\"capture-form-field\">\n <label class=\"capture-form-label\" for=\"capture-form-title\">Title *</label>\n <input\n type=\"text\"\n id=\"capture-form-title\"\n class=\"capture-form-input\"\n placeholder=\"e.g., User profile page redesign\"\n data-testid=\"widget-capture-form-title\"\n />\n </div>\n `\n : \"\"\n }\n \n <div class=\"capture-form-field\">\n <label class=\"capture-form-label\">Captured UI State</label>\n <div class=\"capture-form-snapshot-container\" data-testid=\"widget-capture-form-snapshot\">\n <div class=\"capture-form-snapshot-empty\">No UI state captured yet</div>\n <button\n type=\"button\"\n class=\"capture-form-pick-btn\"\n data-testid=\"widget-capture-form-pick-btn\"\n >\n Pick UI state\n </button>\n </div>\n </div>\n \n <div class=\"capture-form-field\">\n <label class=\"capture-form-label\" for=\"capture-form-explanation\">Explanation *</label>\n <textarea\n id=\"capture-form-explanation\"\n class=\"capture-form-textarea\"\n placeholder=\"Describe what this UI state means in your product...\"\n data-testid=\"widget-capture-form-explanation\"\n ></textarea>\n </div>\n \n <div class=\"capture-form-watch-row\">\n <input\n type=\"checkbox\"\n id=\"capture-form-watch\"\n class=\"capture-form-watch-checkbox\"\n data-testid=\"widget-capture-form-watch-toggle\"\n />\n <label class=\"capture-form-watch-label\" for=\"capture-form-watch\">\n Watch for changes\n </label>\n </div>\n\n <div class=\"capture-form-error\" data-testid=\"widget-capture-form-error\"></div>\n \n <div class=\"capture-form-actions\">\n <button\n type=\"button\"\n class=\"capture-form-cancel-btn\"\n data-testid=\"widget-capture-form-cancel\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n class=\"capture-form-save-btn\"\n data-testid=\"widget-capture-form-save\"\n >\n Save\n </button>\n </div>\n `;\n\n container.innerHTML = html;\n\n // Wire up event listeners\n const titleInput = container.querySelector<HTMLInputElement>(\n \"#capture-form-title\",\n );\n const explanationTextarea = container.querySelector<HTMLTextAreaElement>(\n \"#capture-form-explanation\",\n )!;\n const snapshotContainer = container.querySelector<HTMLElement>(\n \".capture-form-snapshot-container\",\n )!;\n const pickBtn = container.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-capture-form-pick-btn\"]',\n )!;\n const saveBtn = container.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-capture-form-save\"]',\n )!;\n const cancelBtn = container.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-capture-form-cancel\"]',\n )!;\n const errorEl = container.querySelector<HTMLElement>(\n '[data-testid=\"widget-capture-form-error\"]',\n )!;\n const watchToggle = container.querySelector<HTMLInputElement>(\n '[data-testid=\"widget-capture-form-watch-toggle\"]',\n )!;\n\n console.log(\"[unnoodle] Form elements found:\", {\n titleInput,\n explanationTextarea,\n snapshotContainer,\n pickBtn,\n saveBtn,\n cancelBtn,\n errorEl,\n });\n\n pickBtn.addEventListener(\"click\", () => {\n console.log(\"[unnoodle] Pick button clicked\");\n callbacks.onPickElement();\n });\n cancelBtn.addEventListener(\"click\", () => {\n console.log(\"[unnoodle] Cancel button clicked\");\n callbacks.onCancel();\n });\n saveBtn.addEventListener(\"click\", () => {\n console.log(\"[unnoodle] Save button clicked\");\n const title = titleInput ? titleInput.value.trim() : \"\";\n const explanation = explanationTextarea.value.trim();\n\n // Basic validation\n if (options.showTitle && !title) {\n errorEl.textContent = \"Title is required\";\n errorEl.classList.add(\"visible\");\n return;\n }\n if (!explanation) {\n errorEl.textContent = \"Explanation is required\";\n errorEl.classList.add(\"visible\");\n return;\n }\n\n errorEl.classList.remove(\"visible\");\n callbacks.onSave(title, explanation, watchToggle.checked);\n });\n\n // Controller methods\n const controller: CaptureFormController = {\n setSnapshot: (snapshot: ElementSnapshot | null) => {\n if (snapshot) {\n snapshotContainer.className = \"capture-form-snapshot-container\";\n snapshotContainer.innerHTML = `<div class=\"capture-form-snapshot-preview\">${snapshot.html}</div>`;\n } else {\n snapshotContainer.className = \"capture-form-snapshot-container\";\n snapshotContainer.innerHTML = `\n <div class=\"capture-form-snapshot-empty\">No UI state captured yet</div>\n <button\n type=\"button\"\n class=\"capture-form-pick-btn\"\n data-testid=\"widget-capture-form-pick-btn\"\n >\n Pick UI state\n </button>\n `;\n // Re-wire the pick button event listener\n const newPickBtn = snapshotContainer.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-capture-form-pick-btn\"]',\n );\n if (newPickBtn) {\n newPickBtn.addEventListener(\"click\", () => {\n console.log(\"[unnoodle] Pick button clicked\");\n callbacks.onPickElement();\n });\n }\n }\n },\n\n setPickingMode: (picking: boolean) => {\n if (picking) {\n snapshotContainer.className = \"capture-form-snapshot-container picking\";\n snapshotContainer.innerHTML = `\n <div class=\"capture-form-snapshot-empty\">UI state capture in progress...</div>\n <button\n type=\"button\"\n class=\"capture-form-cancel-capture-btn\"\n data-testid=\"widget-capture-form-cancel-capture-btn\"\n >\n Cancel capture\n </button>\n `;\n // Wire the cancel capture button\n const cancelCaptureBtn =\n snapshotContainer.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-capture-form-cancel-capture-btn\"]',\n );\n if (cancelCaptureBtn) {\n cancelCaptureBtn.addEventListener(\"click\", () => {\n console.log(\"[unnoodle] Cancel capture clicked\");\n callbacks.onCancelCapture();\n });\n }\n } else {\n // Reset to normal state - inline the setSnapshot(null) logic\n snapshotContainer.className = \"capture-form-snapshot-container\";\n snapshotContainer.innerHTML = `\n <div class=\"capture-form-snapshot-empty\">No UI state captured yet</div>\n <button\n type=\"button\"\n class=\"capture-form-pick-btn\"\n data-testid=\"widget-capture-form-pick-btn\"\n >\n Pick UI state\n </button>\n `;\n // Re-wire the pick button event listener\n const newPickBtn = snapshotContainer.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-capture-form-pick-btn\"]',\n );\n if (newPickBtn) {\n newPickBtn.addEventListener(\"click\", () => {\n console.log(\"[unnoodle] Pick button clicked\");\n callbacks.onPickElement();\n });\n }\n }\n },\n\n setLoading: (loading: boolean) => {\n saveBtn.disabled = loading;\n saveBtn.textContent = loading ? \"Saving…\" : \"Save\";\n pickBtn.disabled = loading;\n cancelBtn.disabled = loading;\n if (titleInput) titleInput.disabled = loading;\n explanationTextarea.disabled = loading;\n },\n\n setError: (message: string) => {\n errorEl.textContent = message;\n errorEl.classList.add(\"visible\");\n },\n\n clear: () => {\n if (titleInput) titleInput.value = \"\";\n explanationTextarea.value = \"\";\n snapshotContainer.className = \"capture-form-snapshot-container\";\n snapshotContainer.innerHTML = `\n <div class=\"capture-form-snapshot-empty\">No UI state captured yet</div>\n <button\n type=\"button\"\n class=\"capture-form-pick-btn\"\n data-testid=\"widget-capture-form-pick-btn\"\n >\n Pick UI state\n </button>\n `;\n // Re-wire the pick button event listener\n const newPickBtn = snapshotContainer.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-capture-form-pick-btn\"]',\n );\n if (newPickBtn) {\n newPickBtn.addEventListener(\"click\", () => {\n console.log(\"[unnoodle] Pick button clicked\");\n callbacks.onPickElement();\n });\n }\n errorEl.classList.remove(\"visible\");\n errorEl.textContent = \"\";\n },\n };\n\n return { element: container, controller };\n}\n","/**\n * stateChangeBanner\n *\n * Single responsibility:\n * Render a persistent \"New state detected — Save it?\" notification banner\n * inside a given container element and wire up the Save / Dismiss actions.\n *\n * Usage:\n * showStateChangeBanner(container, meaning, onSave, onDismiss);\n * hideStateChangeBanner(container);\n *\n * Only one banner is shown at a time per container — calling show() again\n * replaces any existing banner.\n *\n * Design principles:\n * - No DOM queries outside the provided container.\n * - No network calls, no imports from API or orchestration layers.\n * - All actions surface through callbacks.\n */\n\nimport { safeCSS } from \"./safeCSS\";\n\n// ---------------------------------------------------------------------------\n// Internal sentinel\n// ---------------------------------------------------------------------------\n\nconst BANNER_ATTR = \"data-unnoodle-state-banner\";\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Insert (or replace) the state-change notification banner at the top of\n * `container`.\n *\n * @param container The element to prepend the banner into.\n * @param inferredMeaning Pre-filled description from inferMeaning(). When\n * null the banner shows a generic prompt.\n * @param onSave Called when the user clicks \"Save new state\".\n * @param onDismiss Called when the user dismisses the banner.\n */\nexport function showStateChangeBanner(\n container: HTMLElement,\n inferredMeaning: string | null,\n onSave: () => void,\n onDismiss: () => void,\n): void {\n hideStateChangeBanner(container);\n\n const banner = document.createElement(\"div\");\n banner.setAttribute(BANNER_ATTR, \"true\");\n banner.setAttribute(\"data-testid\", \"state-change-banner\");\n banner.setAttribute(\"role\", \"status\");\n banner.setAttribute(\"aria-live\", \"polite\");\n\n banner.innerHTML = `\n <style>\n ${safeCSS(`\n [${BANNER_ATTR}] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 10px 12px;\n background: var(--unn-color-bg-secondary, #f0f4ff);\n border-bottom: 2px solid var(--unn-color-brand-primary, #4f46e5);\n font-size: 13px;\n flex-shrink: 0;\n }\n [${BANNER_ATTR}] .scb-heading {\n font-weight: 600;\n color: var(--unn-color-text-primary, #111);\n display: flex;\n align-items: center;\n gap: 6px;\n }\n [${BANNER_ATTR}] .scb-meaning {\n color: var(--unn-color-text-body, #444);\n font-size: 12px;\n }\n [${BANNER_ATTR}] .scb-actions {\n display: flex;\n gap: 6px;\n align-items: center;\n }\n [${BANNER_ATTR}] .scb-save-btn {\n padding: 4px 12px;\n background: var(--unn-color-brand-primary, #4f46e5);\n color: #fff;\n border: none;\n border-radius: 4px;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n }\n [${BANNER_ATTR}] .scb-save-btn:hover {\n opacity: 0.88;\n }\n [${BANNER_ATTR}] .scb-dismiss-btn {\n padding: 4px 10px;\n background: transparent;\n color: var(--unn-color-text-muted, #888);\n border: 1px solid var(--unn-color-border-subtle, #ddd);\n border-radius: 4px;\n font-size: 12px;\n cursor: pointer;\n }\n [${BANNER_ATTR}] .scb-dismiss-btn:hover {\n background: var(--unn-color-bg-hover, #e9e9e9);\n }\n `)}\n </style>\n <div class=\"scb-heading\">\n <span aria-hidden=\"true\">🔍</span>\n New state detected — Save it?\n </div>\n ${\n inferredMeaning\n ? `<div class=\"scb-meaning\" data-testid=\"state-change-banner-meaning\">${inferredMeaning}</div>`\n : \"\"\n }\n <div class=\"scb-actions\">\n <button type=\"button\" class=\"scb-save-btn\" data-testid=\"state-change-banner-save\">\n Save new state\n </button>\n <button type=\"button\" class=\"scb-dismiss-btn\" data-testid=\"state-change-banner-dismiss\">\n Dismiss\n </button>\n </div>\n `;\n\n const saveBtn = banner.querySelector<HTMLButtonElement>(\n '[data-testid=\"state-change-banner-save\"]',\n )!;\n const dismissBtn = banner.querySelector<HTMLButtonElement>(\n '[data-testid=\"state-change-banner-dismiss\"]',\n )!;\n\n saveBtn.addEventListener(\"click\", () => {\n hideStateChangeBanner(container);\n onSave();\n });\n\n dismissBtn.addEventListener(\"click\", () => {\n hideStateChangeBanner(container);\n onDismiss();\n });\n\n container.prepend(banner);\n}\n\n/**\n * Remove the state-change notification banner from `container`, if present.\n * Safe to call when no banner is shown.\n */\nexport function hideStateChangeBanner(container: HTMLElement): void {\n const existing = container.querySelector<HTMLElement>(`[${BANNER_ATTR}]`);\n existing?.remove();\n}\n","import type {\n GlossaryTerm,\n ContextDiscussion,\n ProductMemoryResponse,\n WidgetInitResponse,\n} from \"../types/config\";\n\n/**\n * Escapes HTML characters in a string\n */\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#039;\");\n}\n\n/**\n * Callbacks for list view interactions\n */\nexport interface ListViewCallbacks {\n onTermClick?: (termId: number) => void;\n onDiscussionClick?: (discussionId: number) => void;\n onMemoryClick?: (memoryId: number) => void;\n onBackToHome?: () => void;\n onAddTerm?: () => void;\n onAddDiscussion?: () => void;\n onAddMemory?: () => void;\n onRequireLogin?: () => void;\n}\n\n/**\n * Creates and manages list views for all categories.\n * Keeps heavy list rendering logic separate from the main panel.\n */\nexport class ListViewManager {\n private container: HTMLElement;\n private callbacks: ListViewCallbacks;\n\n constructor(container: HTMLElement, callbacks: ListViewCallbacks = {}) {\n this.container = container;\n this.callbacks = callbacks;\n }\n\n /**\n * Shows all vocabulary terms in a list view\n */\n showAllTerms(data: WidgetInitResponse, allTerms: GlossaryTerm[]): void {\n console.log(\n \"DEBUG: ListViewManager.showAllTerms called with\",\n allTerms.length,\n \"terms\",\n );\n const html = `\n <div class=\"list-view\" data-testid=\"widget-terms-list-view\">\n <div class=\"list-header\">\n <button class=\"list-back-btn\" data-testid=\"widget-back-to-home\">\n ← Back\n </button>\n <div class=\"list-title\">\n <h2>Vocabulary</h2>\n <span class=\"list-count\">${allTerms.length} terms</span>\n </div>\n <button class=\"list-add-btn\" data-testid=\"widget-add-term\">\n + Add\n </button>\n </div>\n <div class=\"list-body\">\n ${this.renderTermsList(allTerms)}\n </div>\n </div>\n `;\n\n this.container.innerHTML = html;\n this.attachTermsListeners();\n }\n\n /**\n * Shows all clarifications in a list view\n */\n showAllClarifications(\n discussions: ContextDiscussion[],\n canPost: boolean,\n ): void {\n console.log(\n \"DEBUG: ListViewManager.showAllClarifications called with\",\n discussions.length,\n \"discussions\",\n );\n const html = `\n <div class=\"list-view\" data-testid=\"widget-clarifications-list-view\">\n <div class=\"list-header\">\n <button class=\"list-back-btn\" data-testid=\"widget-back-to-home\">\n ← Back\n </button>\n <div class=\"list-title\">\n <h2>Clarifications</h2>\n <span class=\"list-count\">${discussions.length} questions</span>\n </div>\n <button class=\"list-add-btn\" data-testid=\"widget-ask-question\">\n + Ask\n </button>\n </div>\n <div class=\"list-body\">\n ${this.renderClarificationsList(discussions)}\n </div>\n </div>\n `;\n\n this.container.innerHTML = html;\n this.attachClarificationsListeners();\n }\n\n /**\n * Shows all product memories in a list view\n */\n showAllMemories(memories: ProductMemoryResponse[], canPost: boolean): void {\n console.log(\n \"DEBUG: ListViewManager.showAllMemories called with\",\n memories.length,\n \"memories\",\n );\n const html = `\n <div class=\"list-view\" data-testid=\"widget-memories-list-view\">\n <div class=\"list-header\">\n <button class=\"list-back-btn\" data-testid=\"widget-back-to-home\">\n ← Back\n </button>\n <div class=\"list-title\">\n <h2>Product Memories</h2>\n <span class=\"list-count\">${memories.length} memories</span>\n </div>\n <button class=\"list-add-btn\" data-testid=\"widget-new-memory\">\n + New\n </button>\n </div>\n <div class=\"list-body\">\n ${this.renderMemoriesList(memories)}\n </div>\n </div>\n `;\n\n this.container.innerHTML = html;\n this.attachMemoriesListeners();\n }\n\n /**\n * Renders the terms list content\n */\n private renderTermsList(terms: GlossaryTerm[]): string {\n if (terms.length === 0) {\n return `\n <div class=\"list-empty\">\n <div class=\"list-empty-title\">No vocabulary terms yet.</div>\n <div class=\"list-empty-text\">Start building your shared vocabulary.</div>\n </div>\n `;\n }\n\n return terms\n .map(\n (term) => `\n <div class=\"list-item\" data-testid=\"widget-term-list-item\" data-term-id=\"${term.id}\">\n <div class=\"list-item-main\">\n <div class=\"list-item-title\">${escapeHtml(term.term)}</div>\n <div class=\"list-item-subtitle\">${escapeHtml(term.definition)}</div>\n ${term.abbreviation ? `<div class=\"list-item-tag\">${escapeHtml(term.abbreviation)}</div>` : \"\"}\n </div>\n <div class=\"list-item-action\">\n <svg viewBox=\"0 0 24 24\" width=\"12\" height=\"12\">\n <polyline points=\"9 18 15 12 9 6\"></polyline>\n </svg>\n </div>\n </div>\n `,\n )\n .join(\"\");\n }\n\n /**\n * Renders the clarifications list content\n */\n private renderClarificationsList(discussions: ContextDiscussion[]): string {\n if (discussions.length === 0) {\n return `\n <div class=\"list-empty\">\n <div class=\"list-empty-title\">No questions yet.</div>\n <div class=\"list-empty-text\">Ask if something about this interface is unclear.</div>\n </div>\n `;\n }\n\n return discussions\n .map(\n (discussion) => `\n <div class=\"list-item\" data-testid=\"widget-clarification-list-item\" data-discussion-id=\"${discussion.id}\">\n <div class=\"list-item-main\">\n <div class=\"list-item-title\">${escapeHtml(discussion.body)}</div>\n <div class=\"list-item-subtitle\">\n ${escapeHtml(discussion.authorName || \"Unknown\")} · \n ${new Date(discussion.createdAt).toLocaleDateString(undefined, { month: \"short\", day: \"numeric\" })}\n ${discussion.replies && discussion.replies.length > 0 ? ` · ${discussion.replies.length} replies` : \"\"}\n </div>\n </div>\n <div class=\"list-item-action\">\n <svg viewBox=\"0 0 24 24\" width=\"12\" height=\"12\">\n <polyline points=\"9 18 15 12 9 6\"></polyline>\n </svg>\n </div>\n </div>\n `,\n )\n .join(\"\");\n }\n\n /**\n * Renders the memories list content\n */\n private renderMemoriesList(memories: ProductMemoryResponse[]): string {\n if (memories.length === 0) {\n return `\n <div class=\"list-empty\">\n <div class=\"list-empty-title\">No captures yet.</div>\n <div class=\"list-empty-text\">Capture elements so teammates can understand the interface faster.</div>\n </div>\n `;\n }\n\n return memories\n .map(\n (memory) => `\n <div class=\"list-item\" data-testid=\"widget-memory-list-item\" data-memory-id=\"${memory.id}\">\n <div class=\"list-item-main\">\n <div class=\"list-item-title\">${escapeHtml(memory.title)}</div>\n <div class=\"list-item-subtitle\">\n ${memory.entryCount} entries · \n ${new Date(memory.updatedAt).toLocaleDateString(undefined, { month: \"short\", day: \"numeric\" })}\n </div>\n </div>\n <div class=\"list-item-action\">\n <svg viewBox=\"0 0 24 24\" width=\"12\" height=\"12\">\n <polyline points=\"9 18 15 12 9 6\"></polyline>\n </svg>\n </div>\n </div>\n `,\n )\n .join(\"\");\n }\n\n /**\n * Attaches event listeners for terms list\n */\n private attachTermsListeners(): void {\n // Back button\n const backBtn = this.container.querySelector(\n '[data-testid=\"widget-back-to-home\"]',\n );\n backBtn?.addEventListener(\"click\", () => this.callbacks.onBackToHome?.());\n\n // Add button\n const addBtn = this.container.querySelector(\n '[data-testid=\"widget-add-term\"]',\n );\n addBtn?.addEventListener(\"click\", () => this.callbacks.onAddTerm?.());\n\n // Term items\n const termItems = this.container.querySelectorAll(\n '[data-testid=\"widget-term-list-item\"]',\n );\n termItems.forEach((item) => {\n item.addEventListener(\"click\", () => {\n const termId = parseInt(item.getAttribute(\"data-term-id\") || \"0\", 10);\n this.callbacks.onTermClick?.(termId);\n });\n });\n }\n\n /**\n * Attaches event listeners for clarifications list\n */\n private attachClarificationsListeners(): void {\n // Back button\n const backBtn = this.container.querySelector(\n '[data-testid=\"widget-back-to-home\"]',\n );\n backBtn?.addEventListener(\"click\", () => this.callbacks.onBackToHome?.());\n\n // Add button\n const addBtn = this.container.querySelector(\n '[data-testid=\"widget-add-clarification\"]',\n );\n addBtn?.addEventListener(\"click\", () => {\n if (addBtn?.getAttribute(\"data-requires-login\") === \"true\") {\n this.callbacks.onRequireLogin?.();\n } else {\n this.callbacks.onAddDiscussion?.();\n }\n });\n\n // Discussion items\n const discussionItems = this.container.querySelectorAll(\n '[data-testid=\"widget-clarification-list-item\"]',\n );\n discussionItems.forEach((item) => {\n item.addEventListener(\"click\", () => {\n const discussionId = parseInt(\n item.getAttribute(\"data-discussion-id\") || \"0\",\n 10,\n );\n this.callbacks.onDiscussionClick?.(discussionId);\n });\n });\n }\n\n /**\n * Attaches event listeners for memories list\n */\n private attachMemoriesListeners(): void {\n // Back button\n const backBtn = this.container.querySelector(\n '[data-testid=\"widget-back-to-home\"]',\n );\n backBtn?.addEventListener(\"click\", () => this.callbacks.onBackToHome?.());\n\n // Add button\n const addBtn = this.container.querySelector(\n '[data-testid=\"widget-add-memory\"]',\n );\n addBtn?.addEventListener(\"click\", () => {\n if (addBtn?.getAttribute(\"data-requires-login\") === \"true\") {\n this.callbacks.onRequireLogin?.();\n } else {\n this.callbacks.onAddMemory?.();\n }\n });\n\n // Memory items\n const memoryItems = this.container.querySelectorAll(\n '[data-testid=\"widget-memory-list-item\"]',\n );\n memoryItems.forEach((item) => {\n item.addEventListener(\"click\", () => {\n const memoryId = parseInt(\n item.getAttribute(\"data-memory-id\") || \"0\",\n 10,\n );\n this.callbacks.onMemoryClick?.(memoryId);\n });\n });\n }\n}\n\n/**\n * Gets the CSS for list views (to be injected into shadow DOM)\n */\nexport function getListViewCSS(): string {\n return `\n .list-view {\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n\n .list-header {\n display: flex;\n align-items: center;\n gap: var(--w-space-2, 8px);\n padding: var(--w-space-h-md) var(--w-space-h-md) var(--w-space-v-md);\n border-bottom: 1px solid var(--unn-color-border-subtle, #e2e8f0);\n background: var(--unn-color-surface, #ffffff);\n }\n\n .list-back-btn, .list-add-btn {\n background: none;\n border: none;\n cursor: pointer;\n font-size: var(--w-font-base);\n color: var(--unn-color-brand-primary);\n font-weight: var(--w-weight-medium);\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px 0;\n transition: all 0.15s ease;\n }\n\n .list-back-btn:hover, .list-add-btn:hover {\n text-decoration: underline;\n }\n\n .list-title {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: var(--w-space-1, 4px);\n }\n\n .list-title h2 {\n margin: 0;\n font-size: var(--w-font-lg);\n font-weight: var(--w-weight-semi);\n color: var(--unn-color-text, #111827);\n }\n\n .list-count {\n font-size: var(--w-font-sm);\n color: var(--unn-color-text-secondary, #6b7280);\n }\n\n .list-body {\n flex: 1;\n overflow-y: auto;\n padding: var(--w-space-v-sm);\n }\n\n .list-item {\n display: flex;\n align-items: center;\n gap: var(--w-space-3, 12px);\n padding: var(--w-space-v-sm);\n border-radius: var(--w-radius-1);\n cursor: pointer;\n transition: background-color 0.15s ease;\n border: 1px solid transparent;\n }\n\n .list-item:hover {\n background: var(--unn-color-bg-secondary);\n }\n\n .list-item:hover .list-item-title {\n color: var(--unn-color-brand-primary);\n }\n\n .list-item-main {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: var(--w-space-1, 4px);\n min-width: 0;\n }\n\n .list-item-title {\n font-size: var(--w-font-base);\n font-weight: var(--w-weight-medium);\n color: var(--unn-color-text, #111827);\n word-break: break-word;\n line-height: 1.4;\n }\n\n .list-item-subtitle {\n font-size: var(--w-font-sm);\n color: var(--unn-color-text-secondary, #6b7280);\n line-height: 1.4;\n }\n\n .list-item-tag {\n font-size: var(--w-font-xs);\n color: var(--unn-color-accent, #3b82f6);\n background: var(--unn-color-accent-subtle, #dbeafe);\n padding: 2px 6px;\n border-radius: var(--w-radius-sm, 4px);\n align-self: flex-start;\n margin-top: 2px;\n }\n\n .list-item-action {\n flex-shrink: 0; \n color: var(--unn-color-text-subtle);\n opacity: 0.35; \n transition: opacity 0.12s, color 0.12s;\n }\n \n .list-item-action svg { \n stroke: currentColor; \n fill: none; \n stroke-width: 2.5; \n }\n\n .list-item:hover .list-item-action {\n opacity: 1; \n color: var(--unn-color-brand-primary);\n }\n\n .list-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: var(--w-space-v-xl) var(--w-space-4);\n height: 200px;\n }\n\n .list-empty-title {\n font-size: var(--w-font-lg);\n font-weight: var(--w-weight-medium);\n color: var(--unn-color-text, #111827);\n margin-bottom: var(--w-space-2, 8px);\n }\n\n .list-empty-text {\n font-size: var(--w-font-base);\n color: var(--unn-color-text-secondary, #6b7280);\n line-height: 1.5;\n }\n `;\n}\n","import { safeCSS } from \"../safeCSS\";\nimport { POPOUT_OVERRIDE_STYLE } from \"./styles\";\n\nexport const MIN_WIDTH = 320;\nexport const MAX_WIDTH_ABS = 800;\nconst LS_WIDTH_KEY = \"unnoodle_panel_width\";\nconst LS_SIDE_KEY = \"unnoodle_panel_side\";\n\nexport interface PanelLayoutRefs {\n host: HTMLElement;\n shadow: ShadowRoot;\n panelShell: HTMLElement;\n popoutBtn: HTMLButtonElement;\n dockBtn: HTMLButtonElement;\n closeBtn: HTMLButtonElement;\n pinLeftBtn: HTMLButtonElement;\n pinRightBtn: HTMLButtonElement;\n halfBtn: HTMLButtonElement;\n halfExitBtn: HTMLButtonElement;\n fullscreenBtn: HTMLButtonElement;\n fullscreenExitBtn: HTMLButtonElement;\n resizeHandle: HTMLElement;\n}\n\nexport interface PanelLayoutCallbacks {\n onClose?: () => void;\n onPopout?: () => void;\n onReattach?: () => void;\n onToast?: (message: string) => void;\n shadowTokens?: string;\n}\n\nexport interface PanelLayoutController {\n show: () => void;\n hide: () => void;\n popout: () => void;\n cleanup: () => void;\n isPopout: () => boolean;\n currentWidth: () => number;\n}\n\nexport function createPanelLayout(\n refs: PanelLayoutRefs,\n callbacks: PanelLayoutCallbacks,\n): PanelLayoutController {\n const {\n host,\n shadow,\n panelShell,\n popoutBtn,\n dockBtn,\n closeBtn,\n pinLeftBtn,\n pinRightBtn,\n halfBtn,\n halfExitBtn,\n fullscreenBtn,\n fullscreenExitBtn,\n resizeHandle,\n } = refs;\n\n // ---- Width state ---------------------------------------------------------\n let _currentWidth = 400;\n try {\n const stored = localStorage.getItem(LS_WIDTH_KEY);\n if (stored) {\n const n = Number(stored);\n if (Number.isFinite(n) && n >= MIN_WIDTH) _currentWidth = n;\n }\n } catch {\n /* ignore */\n }\n panelShell.style.width = `${_currentWidth}px`;\n\n // ---- Side state ----------------------------------------------------------\n let _side: \"left\" | \"right\" = \"right\";\n try {\n const stored = localStorage.getItem(LS_SIDE_KEY);\n if (stored === \"left\" || stored === \"right\") _side = stored;\n } catch {\n /* ignore */\n }\n\n // ---- Popout state --------------------------------------------------------\n let _popoutWin: Window | null = null;\n let _isPopout = false;\n let _popoutInterval: ReturnType<typeof setInterval> | null = null;\n\n // ---- Screen mode state ---------------------------------------------------\n let _isHalfScreen = false;\n let _isFullscreen = false;\n let _wasOpenOnFullscreenEnter = false;\n\n // ---- Drag-resize state ---------------------------------------------------\n let _resizing = false;\n let _resizeStartX = 0;\n let _resizeStartWidth = 0;\n\n // ---- Show / Hide ---------------------------------------------------------\n\n function show() {\n if (_isPopout) return;\n panelShell.classList.add(\"open\");\n host.setAttribute(\"data-panel-open\", \"true\");\n const railHost = document.getElementById(\"unnoodle-rail-host\");\n const railOffset = railHost ? 34 : 0;\n if (railOffset) {\n panelShell.style.right = `${railOffset}px`;\n }\n if (!_isFullscreen) {\n const marginProp = _side === \"right\" ? \"margin-right\" : \"margin-left\";\n document.body.style.transition = `${marginProp} 0.28s cubic-bezier(0.4,0,0.2,1)`;\n if (_side === \"right\") {\n document.body.style.marginRight = `${_currentWidth + railOffset}px`;\n document.body.style.marginLeft = \"\";\n } else {\n document.body.style.marginLeft = `${_currentWidth}px`;\n document.body.style.marginRight = railOffset ? `${railOffset}px` : \"\";\n }\n }\n const btn = document.getElementById(\"unnoodle-btn-host\");\n if (btn) btn.style.display = \"none\";\n }\n\n function hide() {\n if (_isPopout) return;\n if (_isHalfScreen) {\n _isHalfScreen = false;\n panelShell.classList.remove(\"half-screen\");\n halfBtn.hidden = false;\n halfExitBtn.hidden = true;\n }\n if (_isFullscreen) {\n _isFullscreen = false;\n panelShell.classList.remove(\"fullscreen\");\n fullscreenBtn.hidden = false;\n fullscreenExitBtn.hidden = true;\n _wasOpenOnFullscreenEnter = false;\n }\n panelShell.classList.remove(\"open\");\n host.removeAttribute(\"data-panel-open\");\n panelShell.style.right = \"\";\n const railHost = document.getElementById(\"unnoodle-rail-host\");\n const railOffset = railHost ? 34 : 0;\n document.body.style.marginRight = railOffset ? `${railOffset}px` : \"\";\n document.body.style.marginLeft = \"\";\n const btn = document.getElementById(\"unnoodle-btn-host\");\n if (btn) btn.style.removeProperty(\"display\");\n }\n\n // ---- Popout / Reattach ---------------------------------------------------\n\n function popout() {\n if (_isPopout) {\n if (_popoutWin && !_popoutWin.closed) _popoutWin.focus();\n return;\n }\n\n const win = window.open(\n \"about:blank\",\n \"unnoodle_panel\",\n \"width=440,height=720,resizable=yes,scrollbars=no,status=no,location=no,toolbar=no,menubar=no\",\n );\n if (!win) {\n callbacks.onToast?.(\n \"Allow popups for this site to use the detached panel.\",\n );\n return;\n }\n\n const rootTokens = callbacks.shadowTokens\n ? callbacks.shadowTokens.replace(/:host\\b/g, \":root\")\n : \"\";\n\n win.document.write(\n `<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Unnoodle</title>` +\n `<style>*{margin:0;padding:0;box-sizing:border-box;}html,body{height:100%;overflow:hidden;}</style>` +\n (rootTokens ? `<style>${rootTokens}</style>` : \"\") +\n `</head><body style=\"height:100%\"></body></html>`,\n );\n win.document.close();\n\n const overrideStyle = document.createElement(\"style\");\n overrideStyle.setAttribute(\"data-unnoodle-popout\", \"true\");\n overrideStyle.textContent = safeCSS(POPOUT_OVERRIDE_STYLE);\n shadow.appendChild(overrideStyle);\n\n const adopted = win.document.adoptNode(host) as HTMLElement;\n adopted.style.cssText = \"display:block;width:100%;height:100%;\";\n win.document.body.appendChild(adopted);\n\n _popoutWin = win;\n _isPopout = true;\n\n panelShell.classList.add(\"open\");\n\n popoutBtn.hidden = true;\n dockBtn.hidden = false;\n closeBtn.hidden = true;\n\n document.body.style.marginRight = \"\";\n document.body.style.marginLeft = \"\";\n const triggerBtn = document.getElementById(\"unnoodle-btn-host\");\n if (triggerBtn) triggerBtn.style.display = \"none\";\n\n callbacks.onPopout?.();\n\n win.addEventListener(\"beforeunload\", () => {\n _reattach(true);\n });\n\n _popoutInterval = setInterval(() => {\n if (win.closed) {\n clearInterval(_popoutInterval!);\n _popoutInterval = null;\n _reattach(true);\n }\n }, 500);\n }\n\n function _reattach(winAlreadyClosing = false) {\n if (!_isPopout) return;\n _isPopout = false;\n\n if (_popoutInterval) {\n clearInterval(_popoutInterval);\n _popoutInterval = null;\n }\n\n const readopted = document.adoptNode(host) as HTMLElement;\n readopted.style.cssText = \"\";\n document.body.appendChild(readopted);\n\n const overrideEl = shadow.querySelector(\"[data-unnoodle-popout]\");\n if (overrideEl) overrideEl.remove();\n\n panelShell.classList.remove(\"open\");\n host.removeAttribute(\"data-panel-open\");\n\n popoutBtn.hidden = false;\n dockBtn.hidden = true;\n closeBtn.hidden = false;\n\n const triggerBtn = document.getElementById(\"unnoodle-btn-host\");\n if (triggerBtn) triggerBtn.style.removeProperty(\"display\");\n\n if (!winAlreadyClosing && _popoutWin && !_popoutWin.closed) {\n _popoutWin.close();\n }\n _popoutWin = null;\n\n callbacks.onReattach?.();\n }\n\n // ---- Side pin ------------------------------------------------------------\n\n function _setSide(side: \"left\" | \"right\") {\n _side = side;\n try {\n localStorage.setItem(LS_SIDE_KEY, side);\n } catch {\n /* ignore */\n }\n if (side === \"left\") {\n panelShell.classList.add(\"left-side\");\n pinLeftBtn.classList.add(\"active\");\n pinRightBtn.classList.remove(\"active\");\n } else {\n panelShell.classList.remove(\"left-side\");\n pinRightBtn.classList.add(\"active\");\n pinLeftBtn.classList.remove(\"active\");\n }\n if (panelShell.classList.contains(\"open\") && !_isPopout && !_isFullscreen) {\n document.body.style.marginRight =\n side === \"right\" ? `${_currentWidth}px` : \"\";\n document.body.style.marginLeft =\n side === \"left\" ? `${_currentWidth}px` : \"\";\n }\n }\n\n if (_side === \"left\") _setSide(\"left\");\n\n // ---- Half-screen ---------------------------------------------------------\n\n function _toggleHalfScreen() {\n _isHalfScreen = !_isHalfScreen;\n if (_isHalfScreen) {\n if (_isFullscreen) {\n _isFullscreen = false;\n panelShell.classList.remove(\"fullscreen\");\n fullscreenBtn.hidden = false;\n fullscreenExitBtn.hidden = true;\n _wasOpenOnFullscreenEnter = false;\n }\n panelShell.classList.add(\"half-screen\");\n halfBtn.hidden = true;\n halfExitBtn.hidden = false;\n if (panelShell.classList.contains(\"open\") && !_isPopout) {\n const rOff = document.getElementById(\"unnoodle-rail-host\") ? 34 : 0;\n const halfWidth = Math.round(window.innerWidth * 0.5);\n if (_side === \"right\") {\n document.body.style.marginRight = `${halfWidth + rOff}px`;\n document.body.style.marginLeft = \"\";\n } else {\n document.body.style.marginLeft = `${halfWidth}px`;\n document.body.style.marginRight = rOff ? `${rOff}px` : \"\";\n }\n }\n } else {\n panelShell.classList.remove(\"half-screen\");\n halfBtn.hidden = false;\n halfExitBtn.hidden = true;\n if (panelShell.classList.contains(\"open\") && !_isPopout) {\n const rOff = document.getElementById(\"unnoodle-rail-host\") ? 34 : 0;\n if (_side === \"right\") {\n document.body.style.marginRight = `${_currentWidth + rOff}px`;\n document.body.style.marginLeft = \"\";\n } else {\n document.body.style.marginLeft = `${_currentWidth}px`;\n document.body.style.marginRight = rOff ? `${rOff}px` : \"\";\n }\n }\n }\n }\n\n // ---- Fullscreen ----------------------------------------------------------\n\n function _toggleFullscreen() {\n _isFullscreen = !_isFullscreen;\n if (_isFullscreen) {\n if (_isHalfScreen) {\n _isHalfScreen = false;\n panelShell.classList.remove(\"half-screen\");\n halfBtn.hidden = false;\n halfExitBtn.hidden = true;\n }\n _wasOpenOnFullscreenEnter =\n panelShell.classList.contains(\"open\") && !_isPopout;\n panelShell.classList.add(\"fullscreen\");\n fullscreenBtn.hidden = true;\n fullscreenExitBtn.hidden = false;\n document.body.style.marginRight = \"\";\n document.body.style.marginLeft = \"\";\n } else {\n panelShell.classList.remove(\"fullscreen\");\n fullscreenBtn.hidden = false;\n fullscreenExitBtn.hidden = true;\n if (_wasOpenOnFullscreenEnter && panelShell.classList.contains(\"open\")) {\n const rOff = document.getElementById(\"unnoodle-rail-host\") ? 34 : 0;\n if (_side === \"right\") {\n document.body.style.marginRight = `${_currentWidth + rOff}px`;\n document.body.style.marginLeft = \"\";\n } else {\n document.body.style.marginLeft = `${_currentWidth}px`;\n document.body.style.marginRight = rOff ? `${rOff}px` : \"\";\n }\n }\n _wasOpenOnFullscreenEnter = false;\n }\n }\n\n // ---- Drag-resize ---------------------------------------------------------\n\n function _onResizeMove(e: MouseEvent): void {\n if (!_resizing || _isPopout) return;\n const vwMax =\n window.innerWidth > 0\n ? Math.floor(window.innerWidth * 0.6)\n : MAX_WIDTH_ABS;\n const maxWidth = Math.min(MAX_WIDTH_ABS, vwMax);\n const delta =\n _side === \"right\"\n ? _resizeStartX - e.clientX\n : e.clientX - _resizeStartX;\n const newWidth = Math.max(\n MIN_WIDTH,\n Math.min(maxWidth, _resizeStartWidth + delta),\n );\n _currentWidth = newWidth;\n panelShell.style.width = `${newWidth}px`;\n if (panelShell.classList.contains(\"open\") && !_isFullscreen) {\n const rOff = document.getElementById(\"unnoodle-rail-host\") ? 34 : 0;\n if (_side === \"right\") {\n document.body.style.marginRight = `${newWidth + rOff}px`;\n document.body.style.marginLeft = \"\";\n } else {\n document.body.style.marginLeft = `${newWidth}px`;\n document.body.style.marginRight = rOff ? `${rOff}px` : \"\";\n }\n }\n }\n\n function _onResizeUp(): void {\n if (!_resizing) return;\n _resizing = false;\n document.removeEventListener(\"mousemove\", _onResizeMove);\n document.removeEventListener(\"mouseup\", _onResizeUp);\n try {\n localStorage.setItem(LS_WIDTH_KEY, String(_currentWidth));\n } catch {\n /* ignore */\n }\n }\n\n // ---- Cleanup -------------------------------------------------------------\n\n function cleanup() {\n document.removeEventListener(\"mousemove\", _onResizeMove);\n document.removeEventListener(\"mouseup\", _onResizeUp);\n if (_isPopout) _reattach(false);\n document.body.style.marginRight = \"\";\n document.body.style.marginLeft = \"\";\n const btn = document.getElementById(\"unnoodle-btn-host\");\n if (btn) btn.style.removeProperty(\"display\");\n }\n\n // ---- Wire button listeners -----------------------------------------------\n\n const handleClose = () => {\n hide();\n callbacks.onClose?.();\n };\n closeBtn.addEventListener(\"click\", handleClose);\n\n dockBtn.addEventListener(\"click\", () => _reattach(false));\n popoutBtn.addEventListener(\"click\", () => popout());\n pinLeftBtn.addEventListener(\"click\", () => _setSide(\"left\"));\n pinRightBtn.addEventListener(\"click\", () => _setSide(\"right\"));\n halfBtn.addEventListener(\"click\", () => _toggleHalfScreen());\n halfExitBtn.addEventListener(\"click\", () => _toggleHalfScreen());\n fullscreenBtn.addEventListener(\"click\", () => _toggleFullscreen());\n fullscreenExitBtn.addEventListener(\"click\", () => _toggleFullscreen());\n\n resizeHandle.addEventListener(\"mousedown\", (e: MouseEvent) => {\n if (_isPopout) return;\n _resizing = true;\n _resizeStartX = e.clientX;\n _resizeStartWidth = _currentWidth;\n document.addEventListener(\"mousemove\", _onResizeMove);\n document.addEventListener(\"mouseup\", _onResizeUp);\n e.preventDefault();\n });\n\n return {\n show,\n hide,\n popout,\n cleanup,\n isPopout: () => _isPopout,\n currentWidth: () => _currentWidth,\n };\n}\n","import type {\n WidgetInitResponse,\n GlossaryTerm,\n ContextDiscussion,\n} from \"../../../types/config\";\nimport { escapeHtml } from \"../utils\";\n\nexport const MAX_HOME_ITEMS = 5;\n\nexport interface HomeViewCallbacks {\n onTermClick?: (term: GlossaryTerm) => void;\n onRequireLogin?: () => void;\n onAddConcept?: (term: string, definition: string) => void;\n onOpenSearch?: () => void;\n onCaptureUiState?: () => void;\n onShowAllConcepts?: () => void;\n onClarificationClick?: (discussion: ContextDiscussion) => void;\n onShowAllClarifications?: () => void;\n onAskQuestion?: (contextId: number, questionBody: string) => void;\n}\n\nexport function renderHomeView(\n body: HTMLElement,\n headerSubtitle: Element | null,\n data: WidgetInitResponse,\n callbacks: HomeViewCallbacks,\n isAuthenticated: boolean,\n): void {\n const {\n onTermClick,\n onRequireLogin,\n onAddConcept,\n onOpenSearch,\n onCaptureUiState,\n onShowAllConcepts,\n } = callbacks;\n\n if (headerSubtitle) headerSubtitle.textContent = data.context.name;\n\n const terms = data.glossary;\n\n // Helper: is this term present in the current page body text?\n function isRelevantToPage(t: GlossaryTerm): boolean {\n const rx = new RegExp(\n `\\\\b${t.term.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}\\\\b`,\n \"i\",\n );\n return rx.test(document.body?.innerText ?? \"\");\n }\n\n const conceptRowsHtml = (list: GlossaryTerm[]) =>\n list\n .map(\n (t) => `\n <div class=\"concept-row\" data-testid=\"widget-term-card\" data-term-id=\"${t.id}\">\n <span class=\"concept-name\">${escapeHtml(t.term)}</span>\n ${t.abbreviation ? `<span class=\"concept-abbr\">${escapeHtml(t.abbreviation)}</span>` : \"\"}\n <span class=\"concept-chevron\"><svg viewBox=\"0 0 24 24\"><polyline points=\"9 18 15 12 9 6\"/></svg></span>\n </div>`,\n )\n .join(\"\");\n\n function buildConceptsBody(\n filtTerms: GlossaryTerm[],\n isFiltering: boolean,\n ): string {\n const filtRelevant = filtTerms.filter(isRelevantToPage);\n const filtOther = filtTerms.filter((t) => !isRelevantToPage(t));\n const hasBothGroups = filtRelevant.length > 0 && filtOther.length > 0;\n\n if (filtTerms.length === 0) {\n return isFiltering\n ? `<div class=\"section-empty\" data-testid=\"widget-glossary-empty\"><div class=\"section-empty-title\">No matching concepts.</div></div>`\n : `<div class=\"section-empty\"><div class=\"section-empty-title\">No product concepts defined yet.</div><div class=\"section-empty-text\">Start building shared vocabulary for this context.</div><button class=\"section-empty-action\" data-testid=\"widget-add-concept-empty\">Add Concept</button></div>`;\n }\n\n const relevantHtml =\n filtRelevant.length > 0\n ? `<div class=\"concept-subheading\">Used on this page</div>${conceptRowsHtml(filtRelevant)}`\n : \"\";\n const otherHeadHtml = hasBothGroups\n ? `<div class=\"concept-subheading\">Other concepts in this context</div>`\n : \"\";\n\n if (isFiltering) {\n return relevantHtml + otherHeadHtml + conceptRowsHtml(filtOther);\n }\n\n const visibleRelevant = filtRelevant.slice(0, MAX_HOME_ITEMS);\n const otherCap = Math.max(MAX_HOME_ITEMS - visibleRelevant.length, 0);\n const visibleOther = filtOther.slice(0, otherCap);\n const hiddenOther = filtOther.slice(otherCap);\n const hiddenRelevant = filtRelevant.slice(MAX_HOME_ITEMS);\n const showMoreHtml =\n filtTerms.length > MAX_HOME_ITEMS\n ? `<div class=\"home-concepts-hidden\" style=\"display:none\">${conceptRowsHtml(hiddenRelevant)}${conceptRowsHtml(hiddenOther)}</div>` +\n `<a href=\"#\" class=\"home-show-more home-show-more-concepts\" data-testid=\"widget-show-all-concepts\">Show all ${filtTerms.length} vocabulary →</a>`\n : ``;\n\n const relevantBlockHtml =\n visibleRelevant.length > 0\n ? `<div class=\"concept-subheading\">Used on this page</div>${conceptRowsHtml(visibleRelevant)}`\n : \"\";\n\n return (\n relevantBlockHtml +\n otherHeadHtml +\n conceptRowsHtml(visibleOther) +\n showMoreHtml\n );\n }\n\n const conceptsBlockHtml = buildConceptsBody(terms, false);\n\n body.innerHTML = `\n <div class=\"home-view\" data-testid=\"widget-home-view\">\n <div class=\"context-strip\" data-testid=\"widget-context-strip\" style=\"display:none !important\">\n <!-- idle state -->\n <div class=\"strip-idle\">\n <button class=\"strip-btn\" data-testid=\"widget-add-ui-meaning-btn\" aria-label=\"Add UI Meaning\">\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"3\"/><path d=\"M12 1v4M12 19v4M4.22 4.22l2.83 2.83M16.95 16.95l2.83 2.83M1 12h4M19 12h4M4.22 19.78l2.83-2.83M16.95 7.05l2.83-2.83\"/></svg>\n Add UI Meaning\n </button>\n </div>\n <!-- pick-mode state -->\n <div class=\"pick-mode-prompt\" data-testid=\"widget-pick-mode-prompt\">\n <span class=\"pick-prompt-text\">Click any element on the page&hellip;</span>\n <button class=\"strip-cancel-btn\" data-testid=\"widget-context-strip-cancel-btn\" aria-label=\"Cancel pick mode\">Cancel</button>\n </div>\n <!-- capture-describe state -->\n <div class=\"capture-describe-view\" data-testid=\"widget-capture-describe-view\">\n <div class=\"capture-snapshot-preview\" data-testid=\"widget-capture-snapshot-preview\"></div>\n <textarea class=\"capture-description-input\" data-testid=\"widget-capture-description-input\"\n placeholder=\"Describe what this UI state means\\u2026\" rows=\"3\" maxlength=\"2000\"></textarea>\n <p class=\"capture-error\" style=\"display:none\"></p>\n <div class=\"capture-actions\">\n <button class=\"strip-cancel-btn\" data-testid=\"widget-capture-pick-again-btn\">Pick Again</button>\n <button class=\"capture-save-btn\" data-testid=\"widget-capture-save-btn\">Save</button>\n </div>\n </div>\n </div>\n <div class=\"home-search-bar\" data-testid=\"widget-home-search-bar\">\n <input class=\"home-search-input\" id=\"unn-home-search\" type=\"search\"\n placeholder=\"Search\\u2026\" autocomplete=\"off\" aria-label=\"Search\"\n data-testid=\"widget-home-search-input\" />\n </div>\n <div class=\"home-sections\">\n <div class=\"home-section\" data-section=\"memory\">\n <div class=\"home-section-header\">\n <span class=\"home-section-title\"><span class=\"home-section-dot\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" fill=\"currentColor\" viewBox=\"0 0 256 256\"><path d=\"M248,124a56.11,56.11,0,0,0-32-50.61V72a48,48,0,0,0-88-26.49A48,48,0,0,0,40,72v1.39a56,56,0,0,0,0,101.2V176a48,48,0,0,0,88,26.49A48,48,0,0,0,216,176v-1.41A56.09,56.09,0,0,0,248,124ZM88,208a32,32,0,0,1-31.81-28.56A55.87,55.87,0,0,0,64,180h8a8,8,0,0,0,0-16H64A40,40,0,0,1,50.67,86.27,8,8,0,0,0,56,78.73V72a32,32,0,0,1,64,0v68.26A47.8,47.8,0,0,0,88,128a8,8,0,0,0,0,16,32,32,0,0,1,0,64Zm104-44h-8a8,8,0,0,0,0,16h8a55.87,55.87,0,0,0,7.81-.56A32,32,0,1,1,168,144a8,8,0,0,0,0-16,47.8,47.8,0,0,0-32,12.26V72a32,32,0,0,1,64,0v6.73a8,8,0,0,0,5.33,7.54A40,40,0,0,1,192,164Zm16-52a8,8,0,0,1-8,8h-4a36,36,0,0,1-36-36V80a8,8,0,0,1,16,0v4a20,20,0,0,0,20,20h4A8,8,0,0,1,208,112ZM60,120H56a8,8,0,0,1,0-16h4A20,20,0,0,0,80,84V80a8,8,0,0,1,16,0v4A36,36,0,0,1,60,120Z\"></path></svg></span>PRODUCT MEMORY</span>\n <button class=\"home-section-add\" data-testid=\"widget-add-ui-meaning\">+</button>\n </div>\n <div class=\"home-section-helper\">Explain what elements on this screen do.</div>\n <div class=\"section-empty\">\n <div class=\"section-empty-title\">No UI explanations yet.</div>\n <div class=\"section-empty-text\">Explain what elements on this screen do so teammates can understand the interface faster.</div>\n <button class=\"section-empty-action\" data-testid=\"widget-add-ui-meaning-empty\">Add UI Meaning</button>\n </div>\n </div>\n <div class=\"home-section\" data-section=\"concepts\">\n <div class=\"home-section-header\">\n <span class=\"home-section-title\"><span class=\"home-section-dot\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" fill=\"currentColor\" viewBox=\"0 0 256 256\"><path d=\"M232,48H160a40,40,0,0,0-32,16A40,40,0,0,0,96,48H24a8,8,0,0,0-8,8V200a8,8,0,0,0,8,8H96a24,24,0,0,1,24,24,8,8,0,0,0,16,0,24,24,0,0,1,24-24h72a8,8,0,0,0,8-8V56A8,8,0,0,0,232,48ZM96,192H32V64H96a24,24,0,0,1,24,24V200A39.81,39.81,0,0,0,96,192Zm128,0H160a39.81,39.81,0,0,0-24,8V88a24,24,0,0,1,24-24h64ZM160,88h40a8,8,0,0,1,0,16H160a8,8,0,0,1,0-16Zm48,40a8,8,0,0,1-8,8H160a8,8,0,0,1,0-16h40A8,8,0,0,1,208,128Zm0,32a8,8,0,0,1-8,8H160a8,8,0,0,1,0-16h40A8,8,0,0,1,208,160Z\"></path></svg></span>PRODUCT VOCABULARY</span>\n <button class=\"home-section-add\" data-testid=\"widget-add-concept\">+</button>\n </div>\n <div class=\"home-section-helper\">Key terms used in this product.</div>\n ${conceptsBlockHtml}\n </div>\n <div class=\"home-section\" data-section=\"clarifications\" data-context-id=\"${data.context.id}\">\n <div class=\"home-section-header\">\n <span class=\"home-section-title\"><span class=\"home-section-dot\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" fill=\"currentColor\" viewBox=\"0 0 256 256\"><path d=\"M225.86,102.82c-3.77-3.94-7.67-8-9.14-11.57-1.36-3.27-1.44-8.69-1.52-13.94-.15-9.76-.31-20.82-8-28.51s-18.75-7.85-28.51-8c-5.25-.08-10.67-.16-13.94-1.52-3.56-1.47-7.63-5.37-11.57-9.14C146.28,23.51,138.44,16,128,16s-18.27,7.51-25.18,14.14c-3.94,3.77-8,7.67-11.57,9.14C88,40.64,82.56,40.72,77.31,40.8c-9.76.15-20.82.31-28.51,8S41,67.55,40.8,77.31c-.08,5.25-.16,10.67-1.52,13.94-1.47,3.56-5.37,7.63-9.14,11.57C23.51,109.72,16,117.56,16,128s7.51,18.27,14.14,25.18c3.77,3.94,7.67,8,9.14,11.57,1.36,3.27,1.44,8.69,1.52,13.94.15,9.76.31,20.82,8,28.51s18.75,7.85,28.51,8c5.25.08,10.67.16,13.94,1.52,3.56,1.47,7.63,5.37,11.57,9.14C109.72,232.49,117.56,240,128,240s18.27-7.51,25.18-14.14c3.94-3.77,8-7.67,11.57-9.14,3.27-1.36,8.69-1.44,13.94-1.52,9.76-.15,20.82-.31,28.51-8s7.85-18.75,8-28.51c.08-5.25.16-10.67,1.52-13.94,1.47-3.56,5.37-7.63,9.14-11.57C232.49,146.28,240,138.44,240,128S232.49,109.73,225.86,102.82Zm-11.55,39.29c-4.79,5-9.75,10.17-12.38,16.52-2.52,6.1-2.63,13.07-2.73,19.82-.1,7-.21,14.33-3.32,17.43s-10.39,3.22-17.43,3.32c-6.75.1-13.72.21-19.82,2.73-6.35,2.63-11.52,7.59-16.52,12.38S132,224,128,224s-9.15-4.92-14.11-9.69-10.17-9.75-16.52-12.38c-6.1-2.52-13.07-2.63-19.82-2.73-7-.1-14.33-.21-17.43-3.32s-3.22-10.39-3.32-17.43c-.1-6.75-.21-13.72-2.73-19.82-2.63-6.35-7.59-11.52-12.38-16.52S32,132,32,128s4.92-9.15,9.69-14.11,9.75-10.17,12.38-16.52c2.52-6.1,2.63-13.07,2.73-19.82.1-7,.21-14.33,3.32-17.43S70.51,56.9,77.55,56.8c6.75-.1,13.72-.21,19.82-2.73,6.35-2.63,11.52-7.59,16.52-12.38S124,32,128,32s9.15,4.92,14.11,9.69,10.17,9.75,16.52,12.38c6.1,2.52,13.07,2.63,19.82,2.73,7,.1,14.33.21,17.43,3.32s3.22,10.39,3.32,17.43c.1,6.75.21,13.72,2.73,19.82,2.63,6.35,7.59,11.52,12.38,16.52S224,124,224,128,219.08,137.15,214.31,142.11ZM140,180a12,12,0,1,1-12-12A12,12,0,0,1,140,180Zm28-72c0,17.38-13.76,31.93-32,35.28V144a8,8,0,0,1-16,0v-8a8,8,0,0,1,8-8c13.23,0,24-9,24-20s-10.77-20-24-20-24,9-24,20v4a8,8,0,0,1-16,0v-4c0-19.85,17.94-36,40-36S168,88.15,168,108Z\"></path></svg></span>CLARIFICATIONS</span>\n <button class=\"home-section-add\" data-testid=\"widget-ask-question-btn\">+</button>\n </div>\n <div class=\"home-section-helper\">Ask if something on this page is unclear. Owners will respond.</div>\n <div class=\"clarifications-body\">\n <div class=\"skeleton-row\"><div class=\"skeleton-line\" style=\"width:70%;height:9px;border-radius:4px;\"></div></div>\n </div>\n </div>\n </div>\n </div>\n `;\n\n // Wire: concept row clicks (reused after in-place filter updates)\n const wireConceptClicks = (container: Element) => {\n container\n .querySelectorAll<HTMLDivElement>(\"[data-testid='widget-term-card']\")\n .forEach((row) => {\n row.addEventListener(\"click\", () => {\n const termId = Number(row.dataset.termId);\n const term = terms.find((t) => t.id === termId);\n if (term) onTermClick?.(term);\n });\n });\n };\n\n wireConceptClicks(body);\n\n function wireShowAllButtons() {\n const conceptsBtn = body.querySelector<HTMLButtonElement>(\n \"[data-testid='widget-show-all-concepts']\",\n );\n if (conceptsBtn) {\n conceptsBtn.addEventListener(\"click\", (e) => {\n e.preventDefault();\n onShowAllConcepts?.();\n });\n }\n }\n\n wireShowAllButtons();\n\n function applyConceptFilter(q: string) {\n const conceptsSecEl = body.querySelector<HTMLElement>(\n \"[data-section='concepts']\",\n );\n if (!conceptsSecEl) return;\n const secHeader = conceptsSecEl.querySelector<HTMLElement>(\n \".home-section-header\",\n );\n if (!secHeader) return;\n\n const isFiltering = q.length >= 2;\n const ql = q.toLowerCase();\n const filtered = isFiltering\n ? terms.filter(\n (t) =>\n t.term.toLowerCase().includes(ql) ||\n t.definition.toLowerCase().includes(ql) ||\n (t.abbreviation ?? \"\").toLowerCase().includes(ql),\n )\n : terms;\n\n const tmp = document.createElement(\"div\");\n tmp.innerHTML = buildConceptsBody(filtered, isFiltering);\n\n while (conceptsSecEl.lastChild && conceptsSecEl.lastChild !== secHeader) {\n conceptsSecEl.removeChild(conceptsSecEl.lastChild);\n }\n while (tmp.firstChild) conceptsSecEl.appendChild(tmp.firstChild);\n\n wireConceptClicks(conceptsSecEl);\n }\n\n body\n .querySelector<HTMLButtonElement>(\"[data-testid='widget-search-toggle']\")\n ?.addEventListener(\"click\", () => {\n onOpenSearch?.();\n });\n\n const searchInput = body.querySelector<HTMLInputElement>(\n \"[data-testid='widget-home-search-input']\",\n );\n\n let searchDebounce: ReturnType<typeof setTimeout> | undefined = undefined;\n\n searchInput?.addEventListener(\"input\", () => {\n clearTimeout(searchDebounce);\n searchDebounce = setTimeout(() => {\n applyConceptFilter(searchInput.value);\n }, 200);\n });\n\n body\n .querySelector<HTMLButtonElement>(\"[data-testid='widget-add-concept']\")\n ?.addEventListener(\"click\", () => {\n if (!isAuthenticated) {\n onRequireLogin?.();\n return;\n }\n const sec = body.querySelector<HTMLElement>(\"[data-section='concepts']\");\n if (sec) showAddTermForm(sec, undefined, onAddConcept);\n });\n\n body\n .querySelector<HTMLButtonElement>(\n \"[data-testid='widget-add-concept-empty']\",\n )\n ?.addEventListener(\"click\", () => {\n if (!isAuthenticated) {\n onRequireLogin?.();\n return;\n }\n const sec = body.querySelector<HTMLElement>(\"[data-section='concepts']\");\n if (sec) showAddTermForm(sec, undefined, onAddConcept);\n });\n\n body\n .querySelector<HTMLButtonElement>(\"[data-testid='widget-add-ui-meaning']\")\n ?.addEventListener(\"click\", () => {\n onCaptureUiState?.();\n });\n\n body\n .querySelector<HTMLButtonElement>(\n \"[data-testid='widget-add-ui-meaning-empty']\",\n )\n ?.addEventListener(\"click\", () => {\n onCaptureUiState?.();\n });\n\n body\n .querySelector<HTMLButtonElement>(\n \"[data-testid='widget-add-ui-meaning-btn']\",\n )\n ?.addEventListener(\"click\", () => {\n onCaptureUiState?.();\n });\n}\n\nexport function loadClarificationsView(\n body: HTMLElement,\n discussions: ContextDiscussion[],\n canPost: boolean,\n callbacks: Pick<\n HomeViewCallbacks,\n | \"onRequireLogin\"\n | \"onClarificationClick\"\n | \"onShowAllClarifications\"\n | \"onAskQuestion\"\n >,\n): void {\n const {\n onRequireLogin,\n onClarificationClick,\n onShowAllClarifications,\n onAskQuestion,\n } = callbacks;\n\n const clarificationsSection = body.querySelector<HTMLElement>(\n \"[data-section='clarifications']\",\n );\n if (!clarificationsSection) return;\n\n const clarBody = clarificationsSection.querySelector(\".clarifications-body\");\n if (!clarBody) return;\n\n const sectionHeader = clarificationsSection.querySelector(\n \".home-section-header\",\n );\n const askBtn =\n sectionHeader?.querySelector<HTMLButtonElement>(\".home-section-add\");\n if (askBtn) {\n askBtn.addEventListener(\"click\", () => {\n if (canPost) {\n const contextId = Number(clarificationsSection.dataset.contextId);\n showAskQuestionForm(clarificationsSection, contextId, onAskQuestion);\n } else {\n onRequireLogin?.();\n }\n });\n }\n\n if (discussions.length === 0) {\n clarBody.innerHTML = `<div class=\"section-empty\"><div class=\"section-empty-title\">No questions yet.</div><div class=\"section-empty-text\">Ask here if something about this interface is unclear.</div><button class=\"section-empty-action\" data-testid=\"widget-ask-question-empty\">Ask Question</button></div>`;\n\n const emptyBtn = clarBody.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-ask-question-empty\"]',\n );\n if (emptyBtn) {\n emptyBtn.addEventListener(\"click\", () => {\n if (canPost) {\n const contextId = Number(clarificationsSection.dataset.contextId);\n showAskQuestionForm(clarificationsSection, contextId, onAskQuestion);\n } else {\n onRequireLogin?.();\n }\n });\n }\n return;\n }\n\n const postsHtml = discussions\n .slice(0, MAX_HOME_ITEMS)\n .map((d) => {\n const authorLabel = d.authorName ? escapeHtml(d.authorName) : \"Unknown\";\n const date = d.createdAt\n ? new Date(d.createdAt).toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n })\n : \"\";\n const repliesHtml = (d.replies ?? [])\n .map(\n (r) => `\n <div class=\"discussion-reply\">\n <div class=\"discussion-meta\"><span class=\"discussion-meta-dot\"></span>${escapeHtml(r.authorName ?? \"Unknown\")} · ${new Date(r.createdAt).toLocaleDateString(undefined, { month: \"short\", day: \"numeric\" })}</div>\n <p class=\"discussion-body\">${escapeHtml(r.body)}</p>\n </div>`,\n )\n .join(\"\");\n return `\n <div class=\"discussion-card\" data-discussion-id=\"${d.id}\">\n <div class=\"discussion-card-main\">\n <div class=\"discussion-meta\"><span class=\"discussion-meta-dot\"></span>${authorLabel} · ${date}</div>\n <p class=\"discussion-body\">${escapeHtml(d.body)}</p>\n ${repliesHtml ? `<div class=\"discussion-replies\">${repliesHtml}</div>` : \"\"}\n </div>\n <span class=\"concept-chevron\"><svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><polyline points=\"9 18 15 12 9 6\"/></svg></span>\n </div>`;\n })\n .join(\"\");\n\n const showMoreHtml =\n discussions.length > MAX_HOME_ITEMS\n ? `<a href=\"#\" class=\"home-show-more home-show-more-clarifications\" data-testid=\"widget-show-all-clarifications\">Show all ${discussions.length} clarifications →</a>`\n : ``;\n\n clarBody.innerHTML = postsHtml + showMoreHtml;\n\n clarBody.querySelectorAll<HTMLElement>(\".discussion-card\").forEach((card) => {\n card.addEventListener(\"click\", () => {\n const id = Number(card.dataset.discussionId);\n const discussion = discussions.find((d) => d.id === id);\n if (discussion) onClarificationClick?.(discussion);\n });\n });\n\n const showAllBtn = clarBody.querySelector<HTMLButtonElement>(\n \"[data-testid='widget-show-all-clarifications']\",\n );\n if (showAllBtn) {\n showAllBtn.addEventListener(\"click\", (e) => {\n e.preventDefault();\n onShowAllClarifications?.();\n });\n }\n}\n\nexport function showAskQuestionForm(\n section: HTMLElement,\n contextId: number,\n onAskQuestion?: (contextId: number, questionBody: string) => void,\n): void {\n const clarBody = section.querySelector(\".clarifications-body\");\n if (!clarBody) return;\n if (clarBody.querySelector(\".ask-form\")) return; // already open\n\n const emptyState = clarBody.querySelector<HTMLElement>(\".section-empty\");\n if (emptyState) emptyState.style.display = \"none\";\n\n const form = document.createElement(\"div\");\n form.className = \"ask-form\";\n form.innerHTML = `\n <textarea class=\"ask-textarea\" placeholder=\"Your question\\u2026\" maxlength=\"2000\" rows=\"3\"></textarea>\n <div class=\"ask-actions\">\n <button class=\"ask-cancel\">Cancel</button>\n <button class=\"ask-submit\" data-testid=\"widget-ask-submit\">Send</button>\n </div>\n <p class=\"ask-error\" style=\"display:none\"></p>\n `;\n clarBody.insertBefore(form, clarBody.firstChild);\n\n const textarea = form.querySelector<HTMLTextAreaElement>(\".ask-textarea\")!;\n const cancelBtn = form.querySelector<HTMLButtonElement>(\".ask-cancel\")!;\n const submitBtn = form.querySelector<HTMLButtonElement>(\".ask-submit\")!;\n\n textarea.focus();\n cancelBtn.addEventListener(\"click\", () => {\n form.remove();\n if (emptyState) emptyState.style.display = \"\";\n });\n submitBtn.addEventListener(\"click\", () => {\n const text = textarea.value.trim();\n if (!text) return;\n submitBtn.disabled = true;\n submitBtn.textContent = \"Sending\\u2026\";\n onAskQuestion?.(contextId, text);\n form.remove();\n });\n}\n\n/**\n * Shows an inline form inside the vocabulary section for adding a new term.\n */\nexport function showAddTermForm(\n section: HTMLElement,\n afterEl?: HTMLElement,\n onAddConcept?: (term: string, definition: string) => void,\n): void {\n if (section.querySelector(\".add-term-form\")) return;\n\n const insertAfter =\n afterEl ??\n section.querySelector<HTMLElement>(\".home-section-helper\") ??\n section.querySelector<HTMLElement>(\".home-section-header\");\n if (!insertAfter) return;\n\n const form = document.createElement(\"div\");\n form.className = \"add-term-form\";\n form.innerHTML = `\n <input class=\"add-term-input\" type=\"text\" placeholder=\"Term name\\u2026\" maxlength=\"100\" data-testid=\"widget-add-term-name\" />\n <textarea class=\"add-term-input ask-textarea\" placeholder=\"Definition\\u2026\" maxlength=\"5000\" rows=\"3\" data-testid=\"widget-add-term-definition\"></textarea>\n <div class=\"ask-actions\">\n <button class=\"ask-cancel\" data-testid=\"widget-add-term-cancel\">Cancel</button>\n <button class=\"ask-submit\" data-testid=\"widget-add-term-submit\">Add</button>\n </div>\n <p class=\"ask-error\" style=\"display:none\" data-testid=\"widget-add-term-error\"></p>\n `;\n insertAfter.after(form);\n\n const nameInput = form.querySelector<HTMLInputElement>(\n \"[data-testid='widget-add-term-name']\",\n )!;\n const defInput = form.querySelector<HTMLTextAreaElement>(\n \"[data-testid='widget-add-term-definition']\",\n )!;\n const cancelBtn = form.querySelector<HTMLButtonElement>(\n \"[data-testid='widget-add-term-cancel']\",\n )!;\n const submitBtn = form.querySelector<HTMLButtonElement>(\n \"[data-testid='widget-add-term-submit']\",\n )!;\n const errorEl = form.querySelector<HTMLParagraphElement>(\n \"[data-testid='widget-add-term-error']\",\n )!;\n\n nameInput.focus();\n\n cancelBtn.addEventListener(\"click\", () => form.remove());\n\n submitBtn.addEventListener(\"click\", () => {\n const term = nameInput.value.trim();\n const definition = defInput.value.trim();\n if (!term || !definition) {\n errorEl.textContent = \"Both term and definition are required.\";\n errorEl.style.display = \"\";\n return;\n }\n errorEl.style.display = \"none\";\n submitBtn.disabled = true;\n submitBtn.textContent = \"Adding\\u2026\";\n onAddConcept?.(term, definition);\n form.remove();\n });\n}\n","import type {\n WidgetInitResponse,\n GlossaryTerm,\n DiscussionPost,\n ContextDiscussion,\n GlossaryTermUpdateRequest,\n TermSuggestion,\n ProductMemoryResponse,\n ProductMemoryDetailResponse,\n SsoProviders,\n} from \"../types/config\";\nimport { safeCSS } from \"./safeCSS\";\nimport { PANEL_STYLES } from \"./panel/styles\";\nimport { renderLoginView, setLoginLoadingState, setLoginErrorState } from \"./panel/views/loginView\";\nimport { renderClarificationDetailView } from \"./panel/views/clarificationView\";\nimport {\n enterPickModeView,\n showCaptureDescribeView,\n setCaptureLoadingState,\n setCaptureErrorState,\n exitCaptureModeView,\n} from \"./panel/views/captureView\";\nimport { escapeHtml } from \"./panel/utils\";\nimport type { ElementSnapshot } from \"../features/memory/elementSnapshot\";\nimport { createCaptureForm, type CaptureFormController } from \"./captureForm\";\nimport {\n showStateChangeBanner,\n hideStateChangeBanner,\n} from \"./stateChangeBanner\";\nimport {\n ListViewManager,\n getListViewCSS,\n type ListViewCallbacks,\n} from \"./listViews\";\nimport { createPanelLayout } from \"./panel/panelLayout\";\nimport {\n renderHomeView as renderHomeViewFn,\n loadClarificationsView,\n showAskQuestionForm,\n showAddTermForm,\n MAX_HOME_ITEMS,\n} from \"./panel/views/homeView\";\n\nexport interface PanelControls {\n element: HTMLElement;\n show: () => void;\n hide: () => void;\n showLogin: (providers?: SsoProviders) => void;\n setLoginLoading: (loading: boolean) => void;\n setLoginError: (message: string) => void;\n setLoading: () => void;\n showTerms: (data: WidgetInitResponse) => void;\n showSearchResults: (terms: GlossaryTerm[], query: string) => void;\n setError: (message: string) => void;\n /** Phase 2: show term detail with discussion thread */\n showTermDetail: (\n term: GlossaryTerm,\n discussions: DiscussionPost[],\n opts?: { showEdit?: boolean },\n ) => void;\n /** Phase 2: show comment textarea inside the drawer */\n showCommentForm: (termId: number) => void;\n /** Phase 2: show edit-term form inside the drawer */\n showEditForm: (term: GlossaryTerm) => void;\n setCommentLoading: (loading: boolean) => void;\n setCommentError: (message: string) => void;\n setEditLoading: (loading: boolean) => void;\n setEditError: (message: string) => void;\n /** Phase 3: append AI-suggested terms below the glossary list */\n showSuggestedTerms: (\n suggestions: TermSuggestion[],\n onAdd: (termName: string) => void,\n ) => void;\n /** Phase 3: overlay modal to review/edit AI-generated definition */\n showAiModal: (\n term: string,\n definition: string,\n onSubmit: (editedDefinition: string) => void,\n onCancel: () => void,\n ) => void;\n /** Phase 3: toggle submit button loading state inside modal */\n setAiModalLoading: (loading: boolean) => void;\n /** Phase 3: transient success/info toast at bottom of panel */\n showToast: (message: string) => void;\n /** UI States: show/hide the capture button + UI States tab (call after login/logout) */\n setAuthenticated: (auth: boolean) => void;\n /** Product Memories: render the paginated list of memories */\n showMemoriesList: (\n memories: ProductMemoryResponse[],\n page: number,\n hasMore: boolean,\n append?: boolean,\n ) => void;\n /** Product Memories: render the detail view for a single memory */\n showMemoryDetail: (memory: ProductMemoryDetailResponse) => void;\n cleanup: () => void;\n /** Pop the panel out into its own browser window */\n popout: () => void;\n /** Phase 2: update the Clarifications section with loaded discussion data */\n loadClarifications: (\n discussions: ContextDiscussion[],\n canPost: boolean,\n ) => void;\n /** Show the detail view for a single clarification question + its replies */\n showClarificationDetail: (\n discussion: ContextDiscussion,\n canReply: boolean,\n ) => void;\n /** Capture flow: enter pick mode (hover-highlight + click to select an element) */\n enterPickMode: (onCancel: () => void) => void;\n /** Capture flow: show describe-capture view with element snapshot preview */\n showCaptureDescribe: (\n snapshot: ElementSnapshot,\n onSave: (description: string) => void,\n onPickAgain: () => void,\n ) => void;\n /** Capture flow: toggle loading state on the save button */\n setCaptureLoading: (loading: boolean) => void;\n /** Capture flow: show an error message in the describe view */\n setCaptureError: (message: string) => void;\n /** Capture flow: return context-strip to idle state */\n exitCaptureMode: () => void;\n /**\n * Populate the PRODUCT MEMORY section of the home view with captured memories.\n * Call after showTerms() resolves — empty array renders the empty state.\n */\n showHomeMemoryItems: (memories: ProductMemoryResponse[]) => void;\n /** Show All Views: display all concepts in a list format */\n showAllConcepts: (terms: GlossaryTerm[]) => void;\n /** Show All Views: display all clarifications in a list format */\n showAllClarifications: (\n discussions: ContextDiscussion[],\n canPost: boolean,\n ) => void;\n /** Show All Views: display all product memories in a list format */\n showAllMemories: (\n memories: ProductMemoryResponse[],\n canPost: boolean,\n ) => void;\n /** Capture flow: show full-screen form for creating a new memory */\n showNewMemoryForm: (\n onPickElement: () => void,\n onCancelCapture: () => void,\n onSave: (\n title: string,\n explanation: string,\n watchForChanges: boolean,\n ) => void,\n onCancel: () => void,\n ) => void;\n /** Capture flow: show full-screen form for adding entry to existing memory */\n showAddEntryForm: (\n memoryTitle: string,\n onPickElement: () => void,\n onCancelCapture: () => void,\n onSave: (explanation: string) => void,\n onCancel: () => void,\n ) => void;\n /** Capture flow: update the snapshot preview in the currently open form */\n updateFormSnapshot: (snapshot: ElementSnapshot) => void;\n /** Set picking mode UI state (dashed border, progress text, cancel button) */\n setFormPickingMode: (picking: boolean) => void;\n /** Restore the home view with the provided data */\n restoreHomeView: (data: any) => void;\n /**\n * Show (or replace) the \"New state detected — Save it?\" notification banner\n * at the top of the panel body.\n *\n * @param inferredMeaning Pre-inferred state label from inferMeaning(). Pass\n * null to show a generic prompt.\n * @param onSave Called when user clicks \"Save new state\".\n * @param onDismiss Called when user clicks \"Dismiss\".\n */\n showStateChangeNotification: (\n inferredMeaning: string | null,\n onSave: () => void,\n onDismiss: () => void,\n ) => void;\n /** Remove the state-change notification banner, if present. */\n hideStateChangeNotification: () => void;\n}\n\n/**\n * Creates the Phase-3 panel using Shadow DOM.\n * Fully isolated from host-app styles.\n *\n * Views:\n * login — email/password form; on submit calls onLogin callback\n * terms — searchable glossary list with header + optional footer link\n */\nexport function createPanel(\n onLogin: (email: string, password: string) => void,\n onSearch: (query: string) => void,\n workspaceUrl?: string,\n onClose?: () => void,\n onBack?: () => void,\n onAddComment?: (termId: number, body: string) => void,\n onEditTerm?: (termId: number, updates: GlossaryTermUpdateRequest) => void,\n onTermClick?: (term: GlossaryTerm) => void,\n onRequestEdit?: (termId: number) => void,\n onCaptureUiState?: () => void,\n onOpenMemories?: () => void,\n onViewMemoryDetail?: (id: number) => void,\n onUpdateEntryExplanation?: (\n memoryId: number,\n entryId: number,\n explanation: string,\n ) => void,\n onPopout?: () => void,\n onReattach?: () => void,\n /**\n * Called when the user clicks a provider SSO button (Google or Microsoft).\n * The controller opens a popup and handles the token handoff.\n */\n onSsoLogin?: (provider: \"google\" | \"microsoft\") => void,\n /**\n * A CSS `:host { … }` block containing --unn-* custom properties.\n * Pass the output of getShadowDomTokens() from @unnoodle/design-system\n * so the widget can consume design tokens inside its shadow root.\n */\n shadowTokens?: string,\n /** Phase 2: called when the user submits a clarification question. */\n onAskQuestion?: (contextId: number, body: string) => void,\n /** Called when an unauthenticated user clicks a write-action button (+). */\n onRequireLogin?: () => void,\n /** Called when the user submits the inline add-vocabulary form. */\n onAddConcept?: (term: string, definition: string) => void,\n /** Called when the user clicks the search icon in the home view to open the full search/terms view. */\n onOpenSearch?: () => void,\n /** Called when the user clicks a clarification card on the home view. */\n onClarificationClick?: (discussion: ContextDiscussion) => void,\n /** Called when the user submits a reply inside the clarification detail view. */\n onPostReply?: (contextId: number, questionId: number, body: string) => void,\n /** Called when the user clicks \"Add Entry\" in the memory detail view. */\n onAddEntryToMemory?: (memoryId: number) => void,\n /** Called when the user clicks to delete a product memory. */\n onDeleteMemory?: (memoryId: number) => void,\n /** Called when the user clicks to delete an entry from a memory. */\n onDeleteEntry?: (memoryId: number, entryId: number) => void,\n /** Called when the user clicks \"Show All\" in the Product Vocabulary section. */\n onShowAllConcepts?: () => void,\n /** Called when the user clicks \"Show All\" in the Clarifications section. */\n onShowAllClarifications?: () => void,\n /** Called when the user clicks \"Show All\" in the Product Memory section. */\n onShowAllMemories?: () => void,\n): PanelControls {\n const host = document.createElement(\"div\");\n host.id = \"unnoodle-panel-host\";\n host.setAttribute(\"data-testid\", \"widget-panel-host\");\n\n const shadow = host.attachShadow({ mode: \"open\" });\n\n // -------------------------------------------------------------------------\n // Styles\n // -------------------------------------------------------------------------\n const style = document.createElement(\"style\");\n style.textContent = safeCSS(PANEL_STYLES);\n\n // -------------------------------------------------------------------------\n // DOM Structure\n // -------------------------------------------------------------------------\n const panel = document.createElement(\"div\");\n panel.className = \"panel\";\n panel.setAttribute(\"role\", \"complementary\");\n panel.setAttribute(\"aria-label\", \"Unnoodle Glossary\");\n\n // Header\n const header = document.createElement(\"div\");\n header.className = \"panel-header\";\n header.innerHTML = `\n <div class=\"panel-header-brand\">\n <span class=\"panel-title\">Unnoodle</span>\n <span class=\"panel-title-sep\">·</span>\n <span class=\"panel-subtitle\">Glossary</span>\n </div>\n <div class=\"panel-header-actions\">\n <button class=\"panel-pin-left\" aria-label=\"Pin to left\" data-testid=\"widget-panel-pin-left\" title=\"Dock to left side\">\n <svg viewBox=\"0 0 256 256\" aria-hidden=\"true\"><rect x=\"32\" y=\"48\" width=\"192\" height=\"160\" rx=\"8\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"16\"/><line x1=\"88\" y1=\"48\" x2=\"88\" y2=\"208\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"16\"/></svg>\n </button>\n <button class=\"panel-pin-right active\" aria-label=\"Pin to right\" data-testid=\"widget-panel-pin-right\" title=\"Dock to right side\">\n <svg viewBox=\"0 0 256 256\" aria-hidden=\"true\"><rect x=\"32\" y=\"48\" width=\"192\" height=\"160\" rx=\"8\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"16\"/><line x1=\"88\" y1=\"48\" x2=\"88\" y2=\"208\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"16\"/></svg>\n </button>\n <div class=\"panel-header-separator\" aria-hidden=\"true\"></div>\n <button class=\"panel-half\" aria-label=\"Expand to half width\" data-testid=\"widget-panel-half\" title=\"Expand to 50% width\">\n <svg viewBox=\"0 0 256 256\" aria-hidden=\"true\"><path d=\"M200,40H56A16,16,0,0,0,40,56V200a16,16,0,0,0,16,16H200a16,16,0,0,0,16-16V56A16,16,0,0,0,200,40Zm-64,80h64v16H136Zm0-16V88h64v16Zm0,48h64v16H136Zm64-80H136V56h64ZM56,56h64V200H56ZM200,200H136V184h64v16Z\"/></svg>\n </button>\n <button class=\"panel-half-exit\" aria-label=\"Exit half width\" data-testid=\"widget-panel-half-exit\" title=\"Restore width\" hidden>\n <svg viewBox=\"0 0 256 256\" aria-hidden=\"true\"><path d=\"M200,40H56A16,16,0,0,0,40,56V200a16,16,0,0,0,16,16H200a16,16,0,0,0,16-16V56A16,16,0,0,0,200,40Zm0,160H56V56H200Z\"/></svg>\n </button>\n <button class=\"panel-fullscreen\" aria-label=\"Fullscreen\" data-testid=\"widget-panel-fullscreen\" title=\"Expand to full width\">\n <svg viewBox=\"0 0 256 256\" aria-hidden=\"true\"><path d=\"M216,48V88a8,8,0,0,1-16,0V56H168a8,8,0,0,1,0-16h40A8,8,0,0,1,216,48ZM88,200H56V168a8,8,0,0,0-16,0v40a8,8,0,0,0,8,8H88a8,8,0,0,0,0-16Zm120-40a8,8,0,0,0-8,8v32H168a8,8,0,0,0,0,16h40a8,8,0,0,0,8-8V168A8,8,0,0,0,208,160ZM88,40H48a8,8,0,0,0-8,8V88a8,8,0,0,0,16,0V56H88a8,8,0,0,0,0-16Z\"/></svg>\n </button>\n <button class=\"panel-fullscreen-exit\" aria-label=\"Exit fullscreen\" data-testid=\"widget-panel-fullscreen-exit\" title=\"Exit fullscreen\" hidden>\n <svg viewBox=\"0 0 256 256\" aria-hidden=\"true\"><path d=\"M136,40V96a8,8,0,0,0,8,8h56a8,8,0,0,0,0-16H160V40a8,8,0,0,0-16,0ZM96,152H40a8,8,0,0,0,0,16H96v56a8,8,0,0,0,16,0V160A8,8,0,0,0,96,152Zm64,0a8,8,0,0,0-8,8v56a8,8,0,0,0,16,0V168h56a8,8,0,0,0,0-16ZM96,104h56a8,8,0,0,0,0-16H112V40a8,8,0,0,0-16,0V96A8,8,0,0,0,96,104Z\"/></svg>\n </button>\n <!-- popout temporarily disabled — TODO: fix CSS vars after adoptNode -->\n <button class=\"panel-popout\" aria-label=\"Pop out panel\" data-testid=\"widget-panel-popout\" title=\"Open in separate window\" hidden>\n <svg viewBox=\"0 0 256 256\" aria-hidden=\"true\"><path d=\"M224,104a8,8,0,0,1-16,0V59.32l-66.33,66.34a8,8,0,0,1-11.32-11.32L196.68,48H152a8,8,0,0,1,0-16h64a8,8,0,0,1,8,8Zm-40,24a8,8,0,0,0-8,8v72H48V80h72a8,8,0,0,0,0-16H48A16,16,0,0,0,32,80V208a16,16,0,0,0,16,16H176a16,16,0,0,0,16-16V136A8,8,0,0,0,184,128Z\"/></svg>\n </button>\n <button class=\"panel-dock\" aria-label=\"Dock panel\" data-testid=\"widget-panel-dock\" title=\"Dock back to main window\" hidden>\n <svg viewBox=\"0 0 256 256\" aria-hidden=\"true\"><path d=\"M224,104a8,8,0,0,1-16,0V59.32l-66.33,66.34a8,8,0,0,1-11.32-11.32L196.68,48H152a8,8,0,0,1,0-16h64a8,8,0,0,1,8,8Zm-40,24a8,8,0,0,0-8,8v72H48V80h72a8,8,0,0,0,0-16H48A16,16,0,0,0,32,80V208a16,16,0,0,0,16,16H176a16,16,0,0,0,16-16V136A8,8,0,0,0,184,128Z\"/></svg>\n </button>\n <button class=\"panel-close\" aria-label=\"Close panel\" data-testid=\"widget-panel-close\">\n <svg viewBox=\"0 0 256 256\" aria-hidden=\"true\"><path d=\"M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z\"/></svg>\n </button>\n </div>\n `;\n\n // Body\n const body = document.createElement(\"div\");\n body.className = \"panel-body\";\n\n // Footer\n const footer = document.createElement(\"div\");\n footer.className = \"panel-footer\";\n footer.innerHTML = `<a href=\"https://unnoodle.com\" target=\"_blank\" rel=\"noopener\">Product knowledge powered by Unnoodle</a>`;\n\n panel.appendChild(header);\n panel.appendChild(body);\n panel.appendChild(footer);\n\n // Drag-resize handle (must sit inside the panel so position:absolute works)\n const resizeHandle = document.createElement(\"div\");\n resizeHandle.className = \"panel-resize-handle\";\n resizeHandle.setAttribute(\"data-testid\", \"widget-panel-resize-handle\");\n panel.appendChild(resizeHandle);\n\n // If the host app supplied design tokens (via getShadowDomTokens() from\n // @unnoodle/design-system), prepend them as a separate <style> so all\n // --unn-* CSS custom properties are available within this shadow root.\n // Wrap panel in shell container (shell carries the inset shadow; panel has just border + content)\n const panelShell = document.createElement(\"div\");\n panelShell.className = \"panel-shell\";\n panelShell.appendChild(panel);\n\n if (shadowTokens) {\n const tokenStyle = document.createElement(\"style\");\n tokenStyle.textContent = safeCSS(shadowTokens);\n shadow.appendChild(tokenStyle);\n }\n shadow.appendChild(style);\n\n // Add list view CSS\n const listViewStyle = document.createElement(\"style\");\n listViewStyle.textContent = safeCSS(getListViewCSS());\n shadow.appendChild(listViewStyle);\n shadow.appendChild(panelShell);\n\n // -------------------------------------------------------------------------\n // Event wiring: query layout buttons, delegate to panelLayout\n // -------------------------------------------------------------------------\n const closeBtn = header.querySelector(\".panel-close\") as HTMLButtonElement;\n const popoutBtn = header.querySelector(\".panel-popout\") as HTMLButtonElement;\n const dockBtn = header.querySelector(\".panel-dock\") as HTMLButtonElement;\n const pinLeftBtn = header.querySelector(\n \".panel-pin-left\",\n ) as HTMLButtonElement;\n const pinRightBtn = header.querySelector(\n \".panel-pin-right\",\n ) as HTMLButtonElement;\n const halfBtn = header.querySelector(\".panel-half\") as HTMLButtonElement;\n const halfExitBtn = header.querySelector(\n \".panel-half-exit\",\n ) as HTMLButtonElement;\n const fullscreenBtn = header.querySelector(\n \".panel-fullscreen\",\n ) as HTMLButtonElement;\n const fullscreenExitBtn = header.querySelector(\n \".panel-fullscreen-exit\",\n ) as HTMLButtonElement;\n\n // ---- Panel layout controller (popout, pin, resize, show/hide) -----------\n\n const _layout = createPanelLayout(\n {\n host,\n shadow,\n panelShell,\n popoutBtn,\n dockBtn,\n closeBtn,\n pinLeftBtn,\n pinRightBtn,\n halfBtn,\n halfExitBtn,\n fullscreenBtn,\n fullscreenExitBtn,\n resizeHandle,\n },\n {\n ...(onClose && { onClose }),\n ...(onPopout && { onPopout }),\n ...(onReattach && { onReattach }),\n onToast: (msg) => showToast(msg),\n ...(shadowTokens && { shadowTokens }),\n },\n );\n\n function show() {\n _layout.show();\n }\n\n function hide() {\n _layout.hide();\n }\n\n function popout() {\n _layout.popout();\n }\n\n function setLoading() {\n body.innerHTML = `\n <div class=\"skeleton-home\" data-testid=\"widget-loading\">\n <div class=\"skeleton-loading-header\">\n <div class=\"skeleton-loading-brand\">Unnoodle</div>\n <div class=\"skeleton-loading-title\">Loading knowledge for this context…</div>\n <div class=\"skeleton-loading-sub\">Helping your team understand this interface</div>\n </div>\n <div class=\"skeleton-body\">\n <div class=\"skeleton-section\">\n <div class=\"skeleton-section-head\"></div>\n <div class=\"skeleton-row\"><div class=\"skeleton-line\" style=\"width:55%;height:9px;\"></div></div>\n </div>\n <div class=\"skeleton-section\">\n <div class=\"skeleton-section-head\"></div>\n <div class=\"skeleton-row\"><div class=\"skeleton-line\" style=\"width:72%;height:9px;\"></div></div>\n <div class=\"skeleton-row\"><div class=\"skeleton-line\" style=\"width:48%;height:9px;\"></div></div>\n <div class=\"skeleton-row\"><div class=\"skeleton-line\" style=\"width:63%;height:9px;\"></div></div>\n <div class=\"skeleton-row\"><div class=\"skeleton-line\" style=\"width:38%;height:9px;\"></div></div>\n </div>\n <div class=\"skeleton-section\">\n <div class=\"skeleton-section-head\"></div>\n <div class=\"skeleton-row\"><div class=\"skeleton-line\" style=\"width:80%;height:9px;\"></div></div>\n </div>\n </div>\n </div>\n `;\n }\n\n function setError(message: string) {\n body.innerHTML = `\n <div class=\"state-center\" data-testid=\"widget-panel-error\">\n <svg class=\"state-error-icon\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"/>\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"/>\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"/>\n </svg>\n <p class=\"state-msg\">${escapeHtml(message)}</p>\n </div>\n `;\n }\n\n // ---- Panel controls (auth state) ----------------------------------------\n /** Whether a user is currently authenticated — controls ui-states action bar visibility. */\n let _isAuthenticated = false;\n\n // ---- Login view ----------------------------------------------------------\n\n function showLogin(providers?: SsoProviders) {\n renderLoginView(\n body,\n {\n onLogin,\n ...(onSsoLogin && { onSsoLogin: (p: string) => onSsoLogin(p as \"google\" | \"microsoft\") }),\n onBack: lastHomeData\n ? () => {\n const savedData = lastHomeData!;\n lastHomeData = savedData;\n showTerms(savedData);\n }\n : null,\n },\n providers,\n );\n }\n\n function setLoginLoading(loading: boolean) {\n setLoginLoadingState(body, loading);\n }\n\n function setLoginError(message: string) {\n setLoginErrorState(body, message);\n }\n\n // ---- Terms / search view -------------------------------------------------\n\n let lastHomeData: WidgetInitResponse | null = null;\n let cachedClarificationsState: {\n discussions: ContextDiscussion[];\n canPost: boolean;\n } | null = null;\n let currentClarification: ContextDiscussion | null = null;\n let activeFormController: CaptureFormController | null = null;\n\n // List view management\n let listViewManager: ListViewManager | null = null;\n let currentViewMode: \"home\" | \"list\" = \"home\";\n let currentHomeData: WidgetInitResponse | null = null;\n\n function showTerms(data: WidgetInitResponse) {\n lastHomeData = data;\n currentHomeData = data; // Store for list views\n currentViewMode = \"home\";\n renderHomeView(data);\n // Restore clarifications state immediately after re-rendering home view\n // (renderHomeView resets the section to a skeleton; re-applying the cached\n // state prevents the empty-state from disappearing on back-navigation).\n if (cachedClarificationsState) {\n loadClarifications(\n cachedClarificationsState.discussions,\n cachedClarificationsState.canPost,\n );\n }\n // Restore product memories from the init response if available\n if (data.productMemories !== undefined) {\n const limitedMemories = data.productMemories.slice(0, 5);\n showHomeMemoryItems(limitedMemories);\n }\n }\n\n function showSearchResults(terms: GlossaryTerm[], query: string) {\n renderTermsView(terms, null, terms.length, query);\n }\n\n // Show All methods - display list views for each category\n function showAllConcepts(terms: GlossaryTerm[]) {\n currentViewMode = \"list\";\n initializeListViewManager();\n if (!currentHomeData) {\n return;\n }\n listViewManager?.showAllTerms(currentHomeData, terms);\n }\n\n function showAllClarifications(\n discussions: ContextDiscussion[],\n canPost: boolean,\n ) {\n currentViewMode = \"list\";\n initializeListViewManager();\n listViewManager?.showAllClarifications(discussions, canPost);\n }\n\n function showAllMemories(\n memories: ProductMemoryResponse[],\n canPost: boolean,\n ) {\n currentViewMode = \"list\";\n initializeListViewManager();\n listViewManager?.showAllMemories(memories, canPost);\n }\n\n function initializeListViewManager() {\n if (!listViewManager) {\n const callbacks: ListViewCallbacks = {\n onTermClick: (termId) => {\n // Find term and show detail (reuse existing logic)\n const term = currentHomeData?.glossary.find((t) => t.id === termId);\n if (term && onTermClick) {\n onTermClick(term);\n }\n },\n onDiscussionClick: (discussionId) => {\n // Show clarification detail (reuse existing logic)\n if (onClarificationClick && cachedClarificationsState) {\n const discussion = cachedClarificationsState.discussions.find(\n (d) => d.id === discussionId,\n );\n if (discussion) {\n onClarificationClick(discussion);\n }\n }\n },\n onMemoryClick: (memoryId) => {\n // Show memory detail (reuse existing logic)\n if (onViewMemoryDetail) {\n onViewMemoryDetail(memoryId);\n }\n },\n onBackToHome: () => {\n // Use the main onBack callback to ensure proper section restoration\n onBack?.();\n },\n onAddTerm: () => {\n if (!_isAuthenticated) {\n onRequireLogin?.();\n return;\n }\n // In list view, find the list-view container and show form there\n const listView = body.querySelector<HTMLElement>(\n \"[data-testid='widget-terms-list-view']\",\n );\n if (listView) {\n const listHeader =\n listView.querySelector<HTMLElement>(\".list-header\");\n if (listHeader) showAddTermForm(listView, listHeader, onAddConcept);\n }\n },\n onAddDiscussion: () => {\n // Show ask question form for clarifications\n const clarSection = body.querySelector(\n '[data-section=\"clarifications\"]',\n );\n const contextId = currentHomeData?.context.id;\n if (clarSection && contextId) {\n showAskQuestionForm(clarSection as HTMLElement, contextId, onAskQuestion);\n }\n },\n onAddMemory: () => onCaptureUiState?.(),\n onRequireLogin: () => onRequireLogin?.(),\n };\n listViewManager = new ListViewManager(body, callbacks);\n }\n }\n\n function renderHomeView(data: WidgetInitResponse) {\n renderHomeViewFn(\n body,\n header.querySelector(\".panel-subtitle\"),\n data,\n {\n ...(onTermClick && { onTermClick }),\n ...(onRequireLogin && { onRequireLogin }),\n ...(onAddConcept && { onAddConcept }),\n ...(onOpenSearch && { onOpenSearch }),\n ...(onCaptureUiState && { onCaptureUiState }),\n ...(onShowAllConcepts && { onShowAllConcepts }),\n ...(onClarificationClick && { onClarificationClick }),\n ...(onShowAllClarifications && { onShowAllClarifications }),\n ...(onAskQuestion && { onAskQuestion }),\n },\n _isAuthenticated,\n );\n }\n\n\n function loadClarifications(\n discussions: ContextDiscussion[],\n canPost: boolean,\n ): void {\n // Cache so we can restore after back-navigation re-renders the home view.\n cachedClarificationsState = { discussions, canPost };\n loadClarificationsView(body, discussions, canPost, {\n ...(onRequireLogin && { onRequireLogin }),\n ...(onClarificationClick && { onClarificationClick }),\n ...(onShowAllClarifications && { onShowAllClarifications }),\n ...(onAskQuestion && { onAskQuestion }),\n });\n }\n\n function renderTermsView(\n terms: GlossaryTerm[],\n contextName: string | null,\n _totalCount: number,\n activeQuery: string,\n ) {\n // Build search bar + action bar + list wrapper\n body.innerHTML = `\n <div class=\"search-bar\">\n <input class=\"search-input\" id=\"unn-search\" type=\"search\"\n placeholder=\"Search terms…\" autocomplete=\"off\"\n value=\"${escapeHtml(activeQuery)}\" aria-label=\"Search glossary terms\"\n data-testid=\"widget-glossary-search\" />\n </div>\n <div class=\"action-bar\" id=\"unn-action-bar\" style=\"display:${_isAuthenticated ? \"flex\" : \"none\"}\">\n <div class=\"action-bar-tabs\">\n <button class=\"tab-btn active\" data-testid=\"widget-glossary-tab\">Glossary</button>\n <button class=\"tab-btn\" data-testid=\"widget-ui-states-tab\">UI States</button>\n </div>\n <button class=\"capture-btn\" data-testid=\"widget-ui-state-capture-btn\"\n title=\"Capture the current page state\">\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"3\"/>\n <path d=\"M3 9a2 2 0 0 1 2-2h1l2-3h8l2 3h1a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"/>\n </svg>\n Capture\n </button>\n </div>\n <div class=\"terms-list\" id=\"unn-terms-list\" data-testid=\"widget-glossary-list\">\n ${contextName ? `<div class=\"context-label\">${escapeHtml(contextName)}</div>` : \"\"}\n ${terms.length === 0 ? renderNoResults(activeQuery) : terms.map(renderTerm).join(\"\")}\n </div>\n `;\n\n // Wire up search input (debounced)\n const searchInput = body.querySelector(\"#unn-search\") as HTMLInputElement;\n let debounceTimer: ReturnType<typeof setTimeout>;\n searchInput.addEventListener(\"input\", () => {\n clearTimeout(debounceTimer);\n debounceTimer = setTimeout(() => {\n onSearch(searchInput.value);\n }, 220);\n });\n\n // Wire up term card clicks for detail view (Phase 2)\n if (onTermClick) {\n const termsList = body.querySelector(\"#unn-terms-list\") as HTMLElement;\n termsList.addEventListener(\"click\", (e) => {\n const card = (e.target as HTMLElement).closest(\n \"[data-testid='widget-term-card']\",\n );\n if (!card) return;\n const item = card.closest(\"[data-term-id]\") as HTMLElement | null;\n if (!item) return;\n const termId = parseInt(item.getAttribute(\"data-term-id\") ?? \"-1\", 10);\n const found = terms.find((t) => t.id === termId);\n if (found) onTermClick(found);\n });\n }\n\n // Wire up capture button\n const captureBtn = body.querySelector(\n '[data-testid=\"widget-ui-state-capture-btn\"]',\n ) as HTMLButtonElement | null;\n captureBtn?.addEventListener(\"click\", () => {\n if (captureBtn.disabled) return;\n captureBtn.disabled = true;\n captureBtn.textContent = \"Capturing…\";\n onCaptureUiState?.();\n // Re-enable after a short delay (controller will show toast)\n setTimeout(() => {\n if (captureBtn) {\n captureBtn.disabled = false;\n captureBtn.innerHTML = `\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" style=\"width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2\">\n <circle cx=\"12\" cy=\"12\" r=\"3\"/>\n <path d=\"M3 9a2 2 0 0 1 2-2h1l2-3h8l2 3h1a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"/>\n </svg>\n Capture\n `;\n }\n }, 2000);\n });\n\n // Wire up UI States tab\n const uiStatesTab = body.querySelector(\n '[data-testid=\"widget-ui-states-tab\"]',\n ) as HTMLButtonElement | null;\n uiStatesTab?.addEventListener(\"click\", () => onOpenMemories?.());\n\n // Focus search so keyboard works immediately\n searchInput.focus();\n }\n\n function renderTerm(term: GlossaryTerm): string {\n const abbr = term.abbreviation\n ? `<span class=\"term-abbr\">${escapeHtml(term.abbreviation)}</span>`\n : \"\";\n const link = workspaceUrl\n ? `<a class=\"term-link\" href=\"${escapeHtml(workspaceUrl)}/glossary/${term.id}\" target=\"_blank\" rel=\"noopener\">View details →</a>`\n : \"\";\n return `\n <div class=\"term-item\" data-term-id=\"${term.id}\" data-testid=\"widget-glossary-item\">\n <div class=\"term-card\" data-testid=\"widget-term-card\">\n <div class=\"term-name\">${escapeHtml(term.term)}${abbr}</div>\n <div class=\"term-def\">${escapeHtml(term.definition)}</div>\n </div>\n ${link}\n </div>\n `;\n }\n\n function renderNoResults(query: string): string {\n return `<div class=\"no-results\" data-testid=\"widget-glossary-empty\">${query ? `No results for \"${escapeHtml(query)}\"` : \"No terms found.\"}</div>`;\n }\n\n function cleanup() {\n _layout.cleanup();\n host.remove();\n }\n\n // Phase 2: Term detail view\n function showTermDetail(\n term: GlossaryTerm,\n discussions: DiscussionPost[],\n opts?: { showEdit?: boolean },\n ): void {\n const postsHtml =\n discussions.length === 0\n ? `<div class=\"discussions-empty\" data-testid=\"widget-discussion-empty\">No comments yet. Be the first to comment!</div>`\n : discussions\n .map(\n (d) =>\n `<div class=\"discussion-post\" data-testid=\"widget-discussion-post\">${escapeHtml(d.body)}</div>`,\n )\n .join(\"\");\n\n const editBtn = opts?.showEdit\n ? `<button class=\"action-btn edit-btn\" data-testid=\"widget-edit-btn\">Edit Term</button>`\n : \"\";\n\n body.innerHTML = `\n <div class=\"term-detail-view\">\n <div class=\"detail-back\">\n <button class=\"back-btn\" data-testid=\"widget-back-btn\">← Back to list</button>\n </div>\n <div class=\"detail-content\">\n <div data-testid=\"widget-term-detail\" class=\"detail-body\">\n <h3 class=\"detail-term-name\">${escapeHtml(term.term)}</h3>\n <p class=\"detail-term-def\">${escapeHtml(term.definition)}</p>\n </div>\n </div>\n <div class=\"detail-actions\">\n <button class=\"action-btn\" data-testid=\"widget-add-comment-btn\">Add Comment</button>\n ${editBtn}\n </div>\n <div class=\"discussions-section\">\n <div class=\"discussions-heading\">Discussion</div>\n ${postsHtml}\n </div>\n </div>\n `;\n\n const backBtn = body.querySelector(\n '[data-testid=\"widget-back-btn\"]',\n ) as HTMLButtonElement;\n backBtn.addEventListener(\"click\", () => onBack?.());\n\n const addCommentBtn = body.querySelector(\n '[data-testid=\"widget-add-comment-btn\"]',\n ) as HTMLButtonElement;\n addCommentBtn.addEventListener(\"click\", () => {\n // The controller handles login-gating; we fire it as a request to show the comment form\n // We pass the termId via a custom event or directly via onAddComment with no body to request form display;\n // Instead we expose a dedicated callback; for now trigger via onAddComment(termId, \"__SHOW_FORM__\")\n // Actually: in Phase 2, the controller needs a separate onRequestComment(termId) callback.\n // Simpler: emit a data attr on the button and let the controller handle via onAddComment with sentinel\n // Cleanest: separate onRequestAddComment callback on createPanel. But to avoid adding another param,\n // reuse onAddComment with empty body — controller checks for this pattern.\n onAddComment?.(term.id, \"\");\n });\n\n if (opts?.showEdit) {\n const editBtnEl = body.querySelector(\n '[data-testid=\"widget-edit-btn\"]',\n ) as HTMLButtonElement | null;\n editBtnEl?.addEventListener(\"click\", () => {\n onRequestEdit?.(term.id);\n });\n }\n }\n\n // Phase 2: Comment form\n function showCommentForm(termId: number): void {\n body.innerHTML = `\n <div class=\"comment-form-view\">\n <div class=\"detail-back\">\n <button class=\"back-btn\" data-testid=\"widget-back-btn\">← Back</button>\n </div>\n <textarea\n class=\"comment-textarea\"\n data-testid=\"widget-comment-body\"\n placeholder=\"Share your thoughts on this term…\"\n ></textarea>\n <button class=\"comment-submit\" data-testid=\"widget-comment-submit\">Submit Comment</button>\n </div>\n `;\n\n const backBtn = body.querySelector(\n '[data-testid=\"widget-back-btn\"]',\n ) as HTMLButtonElement;\n backBtn.addEventListener(\"click\", () => onBack?.());\n\n const submitBtn = body.querySelector(\n '[data-testid=\"widget-comment-submit\"]',\n ) as HTMLButtonElement;\n const textarea = body.querySelector(\n '[data-testid=\"widget-comment-body\"]',\n ) as HTMLTextAreaElement;\n submitBtn.addEventListener(\"click\", () => {\n const body2 = textarea.value.trim();\n if (!body2) return;\n onAddComment?.(termId, body2);\n });\n }\n\n // Phase 2: Edit form\n function showEditForm(term: GlossaryTerm): void {\n body.innerHTML = `\n <div class=\"edit-form-view\">\n <div class=\"detail-back\">\n <button class=\"back-btn\" data-testid=\"widget-back-btn\">← Back</button>\n </div>\n <div>\n <label class=\"edit-label\" for=\"unn-edit-term\">Term</label>\n <input\n class=\"edit-input\"\n id=\"unn-edit-term\"\n type=\"text\"\n data-testid=\"widget-edit-term-input\"\n value=\"${escapeHtml(term.term)}\"\n />\n </div>\n <div>\n <label class=\"edit-label\" for=\"unn-edit-def\">Definition</label>\n <textarea\n class=\"edit-textarea\"\n id=\"unn-edit-def\"\n data-testid=\"widget-edit-definition-input\"\n >${escapeHtml(term.definition)}</textarea>\n </div>\n <button class=\"edit-submit\" data-testid=\"widget-edit-submit\">Save Changes</button>\n </div>\n `;\n\n const backBtn = body.querySelector(\n '[data-testid=\"widget-back-btn\"]',\n ) as HTMLButtonElement;\n backBtn.addEventListener(\"click\", () => onBack?.());\n\n const termInput = body.querySelector(\n '[data-testid=\"widget-edit-term-input\"]',\n ) as HTMLInputElement;\n const defInput = body.querySelector(\n '[data-testid=\"widget-edit-definition-input\"]',\n ) as HTMLTextAreaElement;\n const submitBtn = body.querySelector(\n '[data-testid=\"widget-edit-submit\"]',\n ) as HTMLButtonElement;\n\n submitBtn.addEventListener(\"click\", () => {\n onEditTerm?.(term.id, {\n term: termInput.value,\n definition: defInput.value,\n });\n });\n }\n\n function setCommentLoading(_loading: boolean): void {\n /* stub */\n }\n\n function setCommentError(_message: string): void {\n /* stub */\n }\n\n function setEditLoading(_loading: boolean): void {\n /* stub */\n }\n\n function setEditError(_message: string): void {\n /* stub */\n }\n\n // Phase 3: Suggested terms section\n\n function showSuggestedTerms(\n suggestions: TermSuggestion[],\n onAdd: (termName: string) => void,\n ): void {\n if (suggestions.length === 0) return;\n\n // Remove any existing suggestions section\n const existing = body.querySelector(\".suggestions-section\");\n if (existing) existing.remove();\n\n const termsList = body.querySelector(\".terms-list\");\n if (!termsList) return;\n\n const section = document.createElement(\"div\");\n section.className = \"suggestions-section\";\n section.innerHTML = `\n <div class=\"suggestions-heading\" data-testid=\"widget-suggestions-heading\">\n Suggested Terms\n </div>\n ${suggestions\n .map(\n (s) => `\n <div class=\"suggestion-item\" data-testid=\"widget-suggestion-item\">\n <div class=\"suggestion-info\">\n <span class=\"suggestion-term\">${escapeHtml(s.term)}</span>\n <span class=\"suggestion-count\">mentioned ${s.count}×</span>\n </div>\n <button\n class=\"suggestion-add\"\n data-testid=\"widget-suggestion-add\"\n data-term=\"${escapeHtml(s.term)}\"\n >+ Add</button>\n </div>`,\n )\n .join(\"\")}\n `;\n\n // Wire click handlers\n section.querySelectorAll(\".suggestion-add\").forEach((btn) => {\n btn.addEventListener(\"click\", () => {\n const termName = (btn as HTMLElement).dataset.term ?? \"\";\n onAdd(termName);\n });\n });\n\n termsList.after(section);\n }\n\n // Phase 3: AI definition modal\n\n function showAiModal(\n term: string,\n definition: string,\n onSubmit: (editedDefinition: string) => void,\n onCancel: () => void,\n ): void {\n // Remove any existing modal\n panel.querySelector(\".ai-modal-overlay\")?.remove();\n\n const overlay = document.createElement(\"div\");\n overlay.className = \"ai-modal-overlay\";\n overlay.setAttribute(\"data-testid\", \"widget-ai-modal\");\n overlay.innerHTML = `\n <div class=\"ai-modal-title\">AI Generated Definition</div>\n <div class=\"ai-modal-term\">${escapeHtml(term)}</div>\n <div>\n <label class=\"ai-modal-label\" for=\"unn-ai-def\">Review &amp; edit the definition:</label>\n <textarea\n class=\"ai-modal-textarea\"\n id=\"unn-ai-def\"\n data-testid=\"widget-ai-definition\"\n maxlength=\"500\"\n >${escapeHtml(definition)}</textarea>\n <div class=\"ai-modal-char-count\" id=\"unn-ai-char\">0 / 500</div>\n </div>\n <div class=\"ai-modal-actions\">\n <button class=\"ai-modal-cancel\" data-testid=\"widget-ai-cancel\">Cancel</button>\n <button class=\"ai-modal-submit\" data-testid=\"widget-ai-submit\">Submit for Approval</button>\n </div>\n `;\n\n const textarea = overlay.querySelector(\n '[data-testid=\"widget-ai-definition\"]',\n ) as HTMLTextAreaElement;\n const charCount = overlay.querySelector(\"#unn-ai-char\") as HTMLElement;\n\n const updateCount = () => {\n charCount.textContent = `${textarea.value.length} / 500`;\n };\n textarea.addEventListener(\"input\", updateCount);\n updateCount();\n\n const submitBtn = overlay.querySelector(\n '[data-testid=\"widget-ai-submit\"]',\n ) as HTMLButtonElement;\n submitBtn.addEventListener(\"click\", () => {\n onSubmit(textarea.value);\n });\n\n const cancelBtn = overlay.querySelector(\n '[data-testid=\"widget-ai-cancel\"]',\n ) as HTMLButtonElement;\n cancelBtn.addEventListener(\"click\", () => {\n overlay.remove();\n onCancel();\n });\n\n panel.appendChild(overlay);\n }\n\n function setAiModalLoading(loading: boolean): void {\n const btn = panel.querySelector(\n '[data-testid=\"widget-ai-submit\"]',\n ) as HTMLButtonElement | null;\n if (!btn) return;\n btn.disabled = loading;\n btn.textContent = loading ? \"Submitting…\" : \"Submit for Approval\";\n }\n\n // Phase 3: Toast notification\n\n function showToast(message: string): void {\n // Remove any previous toast\n panel.querySelector(\".toast\")?.remove();\n\n const toast = document.createElement(\"div\");\n toast.className = \"toast\";\n toast.setAttribute(\"data-testid\", \"widget-toast\");\n toast.textContent = message;\n panel.appendChild(toast);\n\n setTimeout(() => toast.remove(), 4000);\n }\n\n // UI States: auth state — controls action bar visibility\n\n function setAuthenticated(auth: boolean): void {\n _isAuthenticated = auth;\n const bar = body.querySelector(\"#unn-action-bar\") as HTMLElement | null;\n if (bar) bar.style.display = auth ? \"flex\" : \"none\";\n }\n\n // Product Memories: list view\n\n function showMemoriesList(\n memories: ProductMemoryResponse[],\n page: number,\n hasMore: boolean,\n append = false,\n ): void {\n if (!append) {\n body.innerHTML = `\n <div class=\"action-bar\" id=\"unn-action-bar\" style=\"display:flex\">\n <div class=\"action-bar-tabs\">\n <button class=\"tab-btn\" data-testid=\"widget-glossary-tab\">Glossary</button>\n <button class=\"tab-btn active\" data-testid=\"widget-ui-states-tab\">Captures</button>\n </div>\n <button class=\"capture-btn\" data-testid=\"widget-ui-state-capture-btn\"\n title=\"Capture the current page state\">\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" style=\"width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2\">\n <circle cx=\"12\" cy=\"12\" r=\"3\"/>\n <path d=\"M3 9a2 2 0 0 1 2-2h1l2-3h8l2 3h1a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"/>\n </svg>\n Capture\n </button>\n </div>\n <div class=\"ui-states-list\" id=\"unn-ui-states-list\" data-testid=\"widget-ui-states-list\"></div>\n `;\n\n // Wire Glossary tab → back to terms\n const glossaryTab = body.querySelector(\n '[data-testid=\"widget-glossary-tab\"]',\n ) as HTMLButtonElement | null;\n glossaryTab?.addEventListener(\"click\", () => onBack?.());\n\n // Wire capture btn\n const captureBtn = body.querySelector(\n '[data-testid=\"widget-ui-state-capture-btn\"]',\n ) as HTMLButtonElement | null;\n captureBtn?.addEventListener(\"click\", () => {\n if (captureBtn.disabled) return;\n captureBtn.disabled = true;\n captureBtn.textContent = \"Capturing…\";\n onCaptureUiState?.();\n setTimeout(() => {\n if (captureBtn) {\n captureBtn.disabled = false;\n captureBtn.innerHTML = `\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" style=\"width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2\">\n <circle cx=\"12\" cy=\"12\" r=\"3\"/>\n <path d=\"M3 9a2 2 0 0 1 2-2h1l2-3h8l2 3h1a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"/>\n </svg>\n Capture\n `;\n }\n }, 2000);\n });\n }\n\n const listContainer = body.querySelector(\n \"#unn-ui-states-list\",\n ) as HTMLElement | null;\n if (!listContainer) return;\n\n // Remove the load more button if it exists (will be re-added below if needed)\n body.querySelector(\".load-more-container\")?.remove();\n\n if (memories.length === 0 && !append) {\n listContainer.innerHTML = `\n <div class=\"ui-states-empty\" data-testid=\"widget-ui-states-empty\">\n <svg class=\"ui-states-empty-icon\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" aria-hidden=\"true\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/>\n <path d=\"M9 9h6M9 12h6M9 15h4\"/>\n </svg>\n <p class=\"ui-states-empty-text\">\n No captures yet.<br/>\n Click <strong>Capture</strong> to snapshot an element.\n </p>\n </div>\n `;\n return;\n }\n\n // Render memory items\n const itemsHtml = memories.map((m) => renderMemoryItem(m)).join(\"\");\n listContainer.insertAdjacentHTML(\"beforeend\", itemsHtml);\n\n // Wire view detail clicks\n listContainer\n .querySelectorAll('[data-testid=\"widget-ui-state-detail-btn\"]')\n .forEach((btn) => {\n const id = parseInt((btn as HTMLElement).dataset.stateId ?? \"-1\", 10);\n btn.addEventListener(\"click\", () => {\n if (!isNaN(id)) onViewMemoryDetail?.(id);\n });\n });\n\n // Load more button\n if (hasMore) {\n const loadMoreContainer = document.createElement(\"div\");\n loadMoreContainer.className = \"load-more-container\";\n loadMoreContainer.innerHTML = `\n <button class=\"load-more-btn\" data-testid=\"widget-ui-states-load-more\"\n data-page=\"${page + 1}\">\n Load more\n </button>\n `;\n loadMoreContainer\n .querySelector('[data-testid=\"widget-ui-states-load-more\"]')\n ?.addEventListener(\"click\", () => onOpenMemories?.());\n body.appendChild(loadMoreContainer);\n }\n }\n\n function renderMemoryItem(memory: ProductMemoryResponse): string {\n const timeAgo = formatTimeAgo(memory.updatedAt);\n const count = memory.entryCount;\n\n return `\n <div class=\"ui-state-item\" data-testid=\"widget-ui-state-item\" data-state-id=\"${memory.id}\">\n <div class=\"ui-state-url\" title=\"${escapeHtml(memory.title)}\">${escapeHtml(memory.title)}</div>\n <div class=\"ui-state-meta\">\n <span>${escapeHtml(timeAgo)}</span>\n <span class=\"ui-state-role-badge\">${count} ${count === 1 ? \"entry\" : \"entries\"}</span>\n </div>\n <div class=\"ui-state-actions\">\n <button class=\"view-detail-btn\"\n data-testid=\"widget-ui-state-detail-btn\"\n data-state-id=\"${memory.id}\">\n View Details\n </button>\n </div>\n </div>\n `;\n }\n\n // UI States: detail view\n\n function showMemoryDetail(memory: ProductMemoryDetailResponse): void {\n const entriesHtml = memory.entries\n .map((entry, idx) => {\n const timeAgo = formatTimeAgo(entry.capturedAt);\n const roleLabel = escapeHtml(entry.capturedByRole ?? \"\");\n return `\n <div class=\"pm-entry\" data-entry-id=\"${entry.id}\">\n <div class=\"detail-meta-section\">\n <div class=\"detail-meta-row\">\n <span>${escapeHtml(timeAgo)}</span>\n ${roleLabel ? `<span class=\"ui-state-role-badge\">${roleLabel}</span>` : \"\"}\n ${entry.capturedByName ? `<span>${escapeHtml(entry.capturedByName)}</span>` : \"\"}\n </div>\n </div>\n ${entry.snapshotHtml ? `<div class=\"ui-state-snapshot-preview\" data-testid=\"widget-ui-state-snapshot-preview-${entry.id}\"></div>` : \"\"}\n <div class=\"product-memory-section\" data-testid=\"widget-product-memory-section-${entry.id}\">\n <div class=\"product-memory-heading\">Entry ${idx + 1} · Explanation</div>\n ${\n entry.explanation\n ? `\n <div class=\"product-memory-read-mode\" data-testid=\"widget-product-memory-read\">\n <div class=\"product-memory-text\" data-testid=\"widget-product-memory-text\">${escapeHtml(entry.explanation)}</div>\n <div class=\"product-memory-actions\">\n <button class=\"product-memory-edit-btn\" data-testid=\"widget-product-memory-edit-btn\">Edit</button>\n <button class=\"product-memory-delete-entry-btn\" data-testid=\"widget-product-memory-delete-entry-btn\" data-entry-id=\"${entry.id}\" title=\"Delete Entry\">🗑</button>\n </div>\n </div>\n <div class=\"product-memory-write-mode\" data-testid=\"widget-product-memory-write\" style=\"display:none\">\n <textarea class=\"product-memory-textarea\" data-testid=\"widget-product-memory-textarea\"\n placeholder=\"Describe what this snapshot represents…\"\n maxlength=\"2000\">${escapeHtml(entry.explanation)}</textarea>\n <div class=\"product-memory-actions\">\n <button class=\"product-memory-cancel-btn\" data-testid=\"widget-product-memory-cancel-btn\">Cancel</button>\n <button class=\"product-memory-save-btn\" data-testid=\"widget-product-memory-save-btn\">Save</button>\n </div>\n </div>`\n : `\n <div class=\"product-memory-write-mode\" data-testid=\"widget-product-memory-write\">\n <textarea class=\"product-memory-textarea\" data-testid=\"widget-product-memory-textarea\"\n placeholder=\"Describe what this snapshot represents…\"\n maxlength=\"2000\"></textarea>\n <div class=\"product-memory-actions\">\n <button class=\"product-memory-save-btn\" data-testid=\"widget-product-memory-save-btn\">Add Explanation</button>\n </div>\n </div>`\n }\n </div>\n </div>\n `;\n })\n .join('<hr class=\"pm-entry-divider\">');\n\n body.innerHTML = `\n <div class=\"ui-state-detail-view\" data-testid=\"widget-ui-state-detail\">\n <div class=\"detail-back\">\n <button class=\"back-btn\" data-testid=\"widget-ui-state-back-btn\">← Captures</button>\n </div>\n <div class=\"detail-page-title\">${escapeHtml(memory.title)}</div>\n ${\n memory.entries.length === 0\n ? `<div class=\"ui-states-empty\" data-testid=\"widget-ui-states-empty\">\n <p class=\"ui-states-empty-text\">No entries yet. Capture an element to get started.</p>\n </div>`\n : entriesHtml\n }\n <div class=\"detail-actions\">\n <button class=\"detail-delete-btn\" data-testid=\"widget-delete-memory-btn\" data-memory-id=\"${memory.id}\">\n Delete Memory\n </button>\n <button class=\"detail-add-btn\" data-testid=\"widget-add-entry-btn\">\n + Add Entry\n </button>\n </div>\n </div>\n `;\n\n // Inject sanitized snapshot HTML for each entry\n memory.entries.forEach((entry) => {\n if (!entry.snapshotHtml) return;\n const preview = body.querySelector(\n `[data-testid=\"widget-ui-state-snapshot-preview-${entry.id}\"]`,\n ) as HTMLElement | null;\n if (preview) preview.innerHTML = entry.snapshotHtml;\n });\n\n // Wire back button → context-aware navigation (home or Show All list)\n body\n .querySelector('[data-testid=\"widget-ui-state-back-btn\"]')\n ?.addEventListener(\"click\", () => onBack?.());\n\n // Wire add-entry button → start a new capture targeting this memory\n body\n .querySelector('[data-testid=\"widget-add-entry-btn\"]')\n ?.addEventListener(\"click\", () => onAddEntryToMemory?.(memory.id));\n\n // Wire explanation edit/save per entry\n memory.entries.forEach((entry) => {\n const section = body.querySelector(\n `[data-testid=\"widget-product-memory-section-${entry.id}\"]`,\n ) as HTMLElement | null;\n if (!section) return;\n\n const readMode = section.querySelector(\n '[data-testid=\"widget-product-memory-read\"]',\n ) as HTMLElement | null;\n const writeMode = section.querySelector(\n '[data-testid=\"widget-product-memory-write\"]',\n ) as HTMLElement | null;\n const textarea = section.querySelector(\n '[data-testid=\"widget-product-memory-textarea\"]',\n ) as HTMLTextAreaElement | null;\n const saveBtn = section.querySelector(\n '[data-testid=\"widget-product-memory-save-btn\"]',\n ) as HTMLButtonElement | null;\n const editBtn = section.querySelector(\n '[data-testid=\"widget-product-memory-edit-btn\"]',\n ) as HTMLButtonElement | null;\n const cancelBtn = section.querySelector(\n '[data-testid=\"widget-product-memory-cancel-btn\"]',\n ) as HTMLButtonElement | null;\n\n editBtn?.addEventListener(\"click\", () => {\n if (readMode) readMode.style.display = \"none\";\n if (writeMode) writeMode.style.display = \"\";\n textarea?.focus();\n });\n\n cancelBtn?.addEventListener(\"click\", () => {\n if (writeMode) writeMode.style.display = \"none\";\n if (readMode) readMode.style.display = \"\";\n });\n\n saveBtn?.addEventListener(\"click\", () => {\n const explanation = textarea?.value.trim() ?? \"\";\n if (!explanation) return;\n if (saveBtn) {\n saveBtn.disabled = true;\n saveBtn.textContent = \"Saving…\";\n }\n onUpdateEntryExplanation?.(memory.id, entry.id, explanation);\n });\n });\n\n // Wire delete entry buttons\n memory.entries.forEach((entry) => {\n const deleteBtn = body.querySelector(\n `[data-testid=\"widget-product-memory-delete-entry-btn\"][data-entry-id=\"${entry.id}\"]`,\n ) as HTMLButtonElement | null;\n\n deleteBtn?.addEventListener(\"click\", (e) => {\n e.preventDefault();\n const confirmed = confirm(\n \"Are you sure you want to delete this entry? This action cannot be undone.\",\n );\n if (confirmed) {\n onDeleteEntry?.(memory.id, entry.id);\n }\n });\n });\n\n // Wire delete memory button\n const deleteMemoryBtn = body.querySelector(\n '[data-testid=\"widget-delete-memory-btn\"]',\n ) as HTMLButtonElement | null;\n\n deleteMemoryBtn?.addEventListener(\"click\", (e) => {\n e.preventDefault();\n const confirmed = confirm(\n `Are you sure you want to delete \"${memory.title}\"? This will delete all entries and cannot be undone.`,\n );\n if (confirmed) {\n onDeleteMemory?.(memory.id);\n }\n });\n }\n\n // ── Utility helpers ────────────────────────────────────────────────────────\n\n function formatTimeAgo(isoString: string): string {\n try {\n const diff = Math.floor(\n (Date.now() - new Date(isoString).getTime()) / 1000,\n );\n if (diff < 60) return \"just now\";\n if (diff < 3600) return `${Math.floor(diff / 60)}m ago`;\n if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`;\n if (diff < 604800) return `${Math.floor(diff / 86400)}d ago`;\n return new Date(isoString).toLocaleDateString();\n } catch {\n return \"unknown time\";\n }\n }\n\n function safeHostname(url: string): string {\n try {\n const u = new URL(url);\n return u.hostname + u.pathname;\n } catch {\n return url.slice(0, 60);\n }\n }\n\n // ── Capture form methods ─────────────────────────────────────────────\n\n function showNewMemoryForm(\n onPickElement: () => void,\n onCancelCapture: () => void,\n onSave: (\n title: string,\n explanation: string,\n watchForChanges: boolean,\n ) => void,\n onCancel: () => void,\n ): void {\n console.log(\"[unnoodle] showNewMemoryForm called\");\n\n // Use the body variable that's already available in this scope\n // instead of trying to query for it within host\n const bodyEl = body;\n console.log(\"[unnoodle] Using body element:\", bodyEl);\n\n if (!bodyEl) {\n console.log(\"[unnoodle] No body element available, returning early\");\n return;\n }\n\n console.log(\"[unnoodle] Creating capture form...\");\n const { element, controller } = createCaptureForm(\n { onPickElement, onCancelCapture, onSave, onCancel },\n { showTitle: true },\n );\n\n console.log(\"[unnoodle] Capture form created:\", element);\n activeFormController = controller;\n\n console.log(\"[unnoodle] Clearing bodyEl and appending form...\");\n bodyEl.innerHTML = \"\";\n bodyEl.appendChild(element);\n console.log(\n \"[unnoodle] Form appended successfully, bodyEl.innerHTML length is now:\",\n bodyEl.innerHTML.length,\n );\n }\n\n function showAddEntryForm(\n memoryTitle: string,\n onPickElement: () => void,\n onCancelCapture: () => void,\n onSave: (explanation: string) => void,\n onCancel: () => void,\n ): void {\n // Use the body variable that's already available in this scope\n const bodyEl = body;\n if (!bodyEl) return;\n\n const { element, controller } = createCaptureForm(\n {\n onPickElement,\n onCancelCapture,\n onSave: (_title: string, explanation: string) => {\n onSave(explanation);\n },\n onCancel: () => {\n onCancel();\n },\n },\n {\n showTitle: false,\n headerText: memoryTitle,\n subheaderText: \"Add new entry\",\n },\n );\n\n activeFormController = controller;\n bodyEl.innerHTML = \"\";\n bodyEl.appendChild(element);\n }\n\n function updateFormSnapshot(snapshot: ElementSnapshot): void {\n if (activeFormController) {\n activeFormController.setSnapshot(snapshot);\n }\n }\n\n function setFormPickingMode(picking: boolean): void {\n if (activeFormController) {\n activeFormController.setPickingMode(picking);\n }\n }\n\n function showStateChangeNotification(\n inferredMeaning: string | null,\n onSave: () => void,\n onDismiss: () => void,\n ): void {\n showStateChangeBanner(body, inferredMeaning, onSave, onDismiss);\n }\n\n function hideStateChangeNotification(): void {\n hideStateChangeBanner(body);\n }\n\n return {\n element: host,\n show,\n hide,\n showLogin,\n setLoginLoading,\n setLoginError,\n setLoading,\n showTerms,\n showSearchResults,\n setError,\n showTermDetail,\n showCommentForm,\n showEditForm,\n setCommentLoading,\n setCommentError,\n setEditLoading,\n setEditError,\n showSuggestedTerms,\n showAiModal,\n setAiModalLoading,\n showToast,\n setAuthenticated,\n showMemoriesList,\n showMemoryDetail,\n cleanup,\n popout,\n loadClarifications,\n showClarificationDetail,\n enterPickMode,\n showCaptureDescribe,\n setCaptureLoading,\n setCaptureError,\n exitCaptureMode,\n restoreHomeView,\n showHomeMemoryItems,\n showAllConcepts,\n showAllClarifications,\n showAllMemories,\n showNewMemoryForm,\n showAddEntryForm,\n updateFormSnapshot,\n setFormPickingMode,\n showStateChangeNotification,\n hideStateChangeNotification,\n };\n\n // ---- Clarification detail view -------------------------------------------\n\n function showClarificationDetail(\n discussion: ContextDiscussion,\n canReply: boolean,\n ): void {\n currentClarification = discussion;\n renderClarificationDetailView(body, discussion, canReply, {\n onBack: () => onBack?.(),\n ...(onPostReply && { onPostReply }),\n });\n }\n\n // ---- Capture mode UI methods --------------------------------------------\n\n function getStripEl() {\n return body.querySelector<HTMLElement>(\n '[data-testid=\"widget-context-strip\"]',\n );\n }\n\n function enterPickMode(onCancel: () => void): void {\n const strip = getStripEl();\n if (!strip) return;\n enterPickModeView(strip, onCancel);\n }\n\n function showCaptureDescribe(\n snapshot: ElementSnapshot,\n onSave: (description: string) => void,\n onPickAgain: () => void,\n ): void {\n const strip = getStripEl();\n if (!strip) return;\n showCaptureDescribeView(strip, snapshot, onSave, onPickAgain);\n }\n\n function setCaptureLoading(loading: boolean): void {\n const strip = getStripEl();\n if (!strip) return;\n setCaptureLoadingState(strip, loading);\n }\n\n function setCaptureError(message: string): void {\n const strip = getStripEl();\n if (!strip) return;\n setCaptureErrorState(strip, message);\n }\n\n function exitCaptureMode(): void {\n const strip = getStripEl();\n if (!strip) return;\n exitCaptureModeView(strip);\n }\n\n function restoreHomeView(data: any): void {\n console.log(\"[unnoodle] restoreHomeView called with data:\", data);\n showTerms(data);\n }\n\n // ---- Home product-memory list -----------------------------------------\n\n function showHomeMemoryItems(memories: ProductMemoryResponse[]): void {\n const section = body.querySelector<HTMLElement>('[data-section=\"memory\"]');\n if (!section) return;\n\n // Remove previous items / empty-state / show-all button (keep header + helper divs)\n section\n .querySelectorAll(\n \".memory-item, .section-empty, .home-show-more-memories\",\n )\n .forEach((el) => el.remove());\n\n if (memories.length === 0) {\n const empty = document.createElement(\"div\");\n empty.className = \"section-empty\";\n empty.innerHTML = `\n <div class=\"section-empty-title\">No captures yet.</div>\n <div class=\"section-empty-text\">Capture elements on this screen so teammates can understand the interface faster.</div>\n <button class=\"section-empty-action\" data-testid=\"widget-add-ui-meaning-empty\">Add Capture</button>\n `;\n empty\n .querySelector('[data-testid=\"widget-add-ui-meaning-empty\"]')\n ?.addEventListener(\"click\", () => {\n onCaptureUiState?.();\n });\n section.appendChild(empty);\n return;\n }\n\n for (const m of memories.slice(0, MAX_HOME_ITEMS)) {\n // Limit to MAX_HOME_ITEMS on home view\n const item = document.createElement(\"div\");\n item.className = \"memory-item\";\n item.setAttribute(\"data-testid\", \"widget-memory-item\");\n item.setAttribute(\"data-ui-state-id\", String(m.id));\n const title = escapeHtml(m.title);\n const date = formatTimeAgo(m.updatedAt);\n const count = m.entryCount;\n item.innerHTML = `\n <div class=\"memory-item-content\">\n <div class=\"memory-item-title\">${title}</div>\n <div class=\"memory-item-meta\">${date} · ${count} ${count === 1 ? \"entry\" : \"entries\"}</div>\n </div>\n <span class=\"concept-chevron\"><svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><polyline points=\"9 18 15 12 9 6\"/></svg></span>\n `;\n item.addEventListener(\"click\", () => {\n onViewMemoryDetail?.(m.id);\n });\n section.appendChild(item);\n }\n\n if (memories.length > MAX_HOME_ITEMS) {\n const showAllBtn = document.createElement(\"a\");\n showAllBtn.className = \"home-show-more home-show-more-memories\";\n showAllBtn.setAttribute(\"data-testid\", \"widget-show-all-memories\");\n showAllBtn.setAttribute(\"href\", \"#\");\n showAllBtn.textContent = `Show all ${memories.length} memories →`;\n showAllBtn.addEventListener(\"click\", (e) => {\n e.preventDefault();\n onShowAllMemories?.();\n });\n section.appendChild(showAllBtn);\n }\n }\n}\n","// Unnoodle Rail CSS (exported as string)\nexport const railStyles = `\n:host {\n all: initial;\n}\n/* Rail shell — fixed to right edge, pushes body content like panel-shell */\n.rail-shell {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 34px;\n z-index: 2147483647;\n display: flex;\n flex-direction: column;\n padding: 3px;\n background: var(--unn-color-bg-secondary, #f5f5f7);\n border-left: 0.5px solid var(--unn-color-border-default, #e0e0e0);\n box-shadow: inset 6px 0 12px rgba(0,0,0,0.06), inset -4px 0 10px rgba(0,0,0,0.04), inset 0 6px 12px rgba(0,0,0,0.06), inset 0 -4px 10px rgba(0,0,0,0.04);\n transition: width 0.28s cubic-bezier(0.4,0,0.2,1);\n box-sizing: border-box;\n}\n.rail {\n flex: 1;\n width: 100%;\n background: linear-gradient(160deg, #2c3440 0%, #1a1f27 100%);\n box-shadow:\n 0 1px 2px rgba(0,0,0,0.30),\n 0 3px 8px rgba(0,0,0,0.38),\n 0 8px 20px rgba(0,0,0,0.22),\n 0 1px 0 rgba(255,255,255,0.06) inset;\n border-radius: 6px;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n box-sizing: border-box;\n overflow: hidden;\n}\n.rail-section {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding-top: 16px;\n padding-bottom: 16px;\n}\n.rail-identity {\n margin-bottom: 18px;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n.rail-avatar {\n width: 28px;\n height: 28px;\n border-radius: 50%;\n background: linear-gradient(160deg, #2c3440 0%, #1a1f27 100%);\n color: #fff;\n font-family: var(--unn-font-family, system-ui, sans-serif);\n font-size: 11px;\n font-weight: 700;\n letter-spacing: 0.5px;\n display: flex;\n align-items: center;\n justify-content: center;\n text-shadow: 0 1px 3px rgba(0,0,0,0.65), 0 -1px 0 rgba(255,255,255,0.10);\n user-select: none;\n}\n.rail-avatar--icon {\n background: none;\n width: auto;\n height: auto;\n}\n.rail-core {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 14px;\n}\n.rail-item {\n width: 100%;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: none;\n cursor: pointer;\n outline: none;\n padding: 0;\n position: relative;\n transition: background 120ms;\n}\n.rail-item.active {\n background: rgba(255,255,255,0.10);\n}\n.rail-item .icon {\n width: 18px;\n height: 18px;\n display: block;\n transition: transform 120ms, opacity 120ms;\n fill: #ffffff;\n opacity: 0.65;\n}\n.rail-item.active .icon {\n opacity: 1;\n}\n.rail-item:hover .icon {\n transform: scale(1.05);\n opacity: 1;\n}\n.rail-item .label {\n display: none !important;\n}\n\n/* Tooltip styles for rail icons */\n.rail-tooltip {\n position: absolute;\n left: 110%;\n top: 50%;\n transform: translateY(-50%);\n background: #222;\n color: #fff;\n font-size: 13px;\n font-family: var(--unn-font-family, system-ui, sans-serif);\n padding: 4px 10px;\n border-radius: 4px;\n white-space: nowrap;\n box-shadow: 0 2px 8px rgba(0,0,0,0.18);\n opacity: 0;\n pointer-events: none;\n z-index: 10;\n transition: opacity 0.08s;\n}\n.rail-item:hover .rail-tooltip {\n opacity: 1;\n pointer-events: auto;\n}\n.rail-auth-btn {\n position: relative;\n}\n.rail-auth-btn .rail-tooltip {\n position: absolute;\n left: 110%;\n top: 50%;\n transform: translateY(-50%);\n background: #222;\n color: #fff;\n font-size: 13px;\n font-family: var(--unn-font-family, system-ui, sans-serif);\n padding: 4px 10px;\n border-radius: 4px;\n white-space: nowrap;\n box-shadow: 0 2px 8px rgba(0,0,0,0.18);\n opacity: 0;\n pointer-events: none;\n z-index: 10;\n transition: opacity 0.08s;\n}\n.rail-auth-btn:hover .rail-tooltip {\n opacity: 1;\n pointer-events: auto;\n}\n .rail-glow {\n position: absolute;\n left: 2px;\n top: 50%;\n transform: translateY(-50%);\n width: 28px;\n height: 28px;\n border-radius: 50%;\n background: radial-gradient(circle, #fff 0%, #fff 80%, transparent 100%);\n opacity: 0.55;\n filter: blur(4px);\n z-index: 0;\n pointer-events: none;\n animation: rail-glow-pulse 2s infinite alternate;\n display: none;\n }\n .rail-glow.active {\n display: block;\n }\n@keyframes rail-glow-pulse {\n 0% { opacity: 0.35; }\n 100% { opacity: 0.6; }\n}\n\n.rail-auth {\n margin-bottom: 12px;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n.rail-auth-btn {\n width: 100%;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: none;\n cursor: pointer;\n outline: none;\n padding: 0;\n font-family: var(--unn-font-family, system-ui, sans-serif);\n font-size: 14px;\n font-weight: 400;\n color: #222;\n transition: background 120ms;\n}\n .rail-auth-btn .icon {\n width: 18px;\n height: 18px;\n display: block;\n transition: transform 120ms;\n fill: #ffffff;\n }\n .rail-auth-btn:hover .icon {\n transform: scale(1.05);\n }\n .rail-auth-btn .label {\n opacity: 0;\n margin-left: 16px;\n font-size: 14px;\n font-weight: 400;\n color: #fff;\n white-space: nowrap;\n pointer-events: none;\n transition: opacity 150ms;\n }\n .rail:hover .rail-auth-btn .label {\n opacity: 1;\n pointer-events: auto;\n }\n\n/* ---- Brand icon (U∩) at top of rail ---- */\n.rail-brand {\n padding-top: 7px;\n padding-bottom: 2px;\n flex-shrink: 0;\n}\n`;\n","// Top section: user initials avatar (falls back to generic icon)\nexport function createRailIdentity(initials: string | null): HTMLElement {\n const root = document.createElement(\"div\");\n root.className = \"rail-identity rail-section\";\n\n if (initials) {\n const avatar = document.createElement(\"div\");\n avatar.className = \"rail-avatar\";\n avatar.textContent = initials;\n avatar.style.position = \"relative\";\n const tooltip = document.createElement(\"span\");\n tooltip.className = \"rail-tooltip\";\n tooltip.textContent = \"Profile\";\n avatar.appendChild(tooltip);\n root.appendChild(avatar);\n } else {\n const btn = document.createElement(\"button\");\n btn.className = \"rail-item\";\n btn.type = \"button\";\n btn.tabIndex = 0;\n btn.innerHTML = `<svg class=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" fill=\"#ffffff\" viewBox=\"0 0 256 256\"><path d=\"M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24ZM74.08,197.5a64,64,0,0,1,107.84,0,87.83,87.83,0,0,1-107.84,0ZM96,120a32,32,0,1,1,32,32A32,32,0,0,1,96,120Zm97.76,66.41a79.66,79.66,0,0,0-36.06-28.75,48,48,0,1,0-59.4,0,79.66,79.66,0,0,0-36.06,28.75,88,88,0,1,1,131.52,0Z\"></path></svg>`;\n const tooltip = document.createElement(\"span\");\n tooltip.className = \"rail-tooltip\";\n tooltip.textContent = \"Profile\";\n btn.appendChild(tooltip);\n root.appendChild(btn);\n }\n\n return root;\n}\n","// Middle section: Overview, Memory, Vocabulary, Clarifications\nexport interface RailCoreActionsCallbacks {\n onOverview: () => void;\n onMemory: () => void;\n onVocabulary: () => void;\n onClarifications: () => void;\n}\n\nexport function createRailCoreActions(\n state: { activeSection: string | null; hasMemoryGlow: boolean },\n cb: RailCoreActionsCallbacks,\n): HTMLElement {\n const root = document.createElement(\"div\");\n root.className = \"rail-core rail-section\";\n\n // Official Phosphor Regular SVGs (18×18, white fill)\n const icons = {\n house: `<svg class=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" fill=\"#ffffff\" viewBox=\"0 0 256 256\"><path d=\"M240,208H224V136l2.34,2.34A8,8,0,0,0,237.66,127L139.31,28.68a16,16,0,0,0-22.62,0L18.34,127a8,8,0,0,0,11.32,11.31L32,136v72H16a8,8,0,0,0,0,16H240a8,8,0,0,0,0-16ZM48,120l80-80,80,80v88H160V152a8,8,0,0,0-8-8H104a8,8,0,0,0-8,8v56H48Zm96,88H112V160h32Z\"></path></svg>`,\n brain: `<svg class=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" fill=\"#ffffff\" viewBox=\"0 0 256 256\"><path d=\"M248,124a56.11,56.11,0,0,0-32-50.61V72a48,48,0,0,0-88-26.49A48,48,0,0,0,40,72v1.39a56,56,0,0,0,0,101.2V176a48,48,0,0,0,88,26.49A48,48,0,0,0,216,176v-1.41A56.09,56.09,0,0,0,248,124ZM88,208a32,32,0,0,1-31.81-28.56A55.87,55.87,0,0,0,64,180h8a8,8,0,0,0,0-16H64A40,40,0,0,1,50.67,86.27,8,8,0,0,0,56,78.73V72a32,32,0,0,1,64,0v68.26A47.8,47.8,0,0,0,88,128a8,8,0,0,0,0,16,32,32,0,0,1,0,64Zm104-44h-8a8,8,0,0,0,0,16h8a55.87,55.87,0,0,0,7.81-.56A32,32,0,1,1,168,144a8,8,0,0,0,0-16,47.8,47.8,0,0,0-32,12.26V72a32,32,0,0,1,64,0v6.73a8,8,0,0,0,5.33,7.54A40,40,0,0,1,192,164Zm16-52a8,8,0,0,1-8,8h-4a36,36,0,0,1-36-36V80a8,8,0,0,1,16,0v4a20,20,0,0,0,20,20h4A8,8,0,0,1,208,112ZM60,120H56a8,8,0,0,1,0-16h4A20,20,0,0,0,80,84V80a8,8,0,0,1,16,0v4A36,36,0,0,1,60,120Z\"></path></svg>`,\n book: `<svg class=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" fill=\"#ffffff\" viewBox=\"0 0 256 256\"><path d=\"M232,48H160a40,40,0,0,0-32,16A40,40,0,0,0,96,48H24a8,8,0,0,0-8,8V200a8,8,0,0,0,8,8H96a24,24,0,0,1,24,24,8,8,0,0,0,16,0,24,24,0,0,1,24-24h72a8,8,0,0,0,8-8V56A8,8,0,0,0,232,48ZM96,192H32V64H96a24,24,0,0,1,24,24V200A39.81,39.81,0,0,0,96,192Zm128,0H160a39.81,39.81,0,0,0-24,8V88a24,24,0,0,1,24-24h64ZM160,88h40a8,8,0,0,1,0,16H160a8,8,0,0,1,0-16Zm48,40a8,8,0,0,1-8,8H160a8,8,0,0,1,0-16h40A8,8,0,0,1,208,128Zm0,32a8,8,0,0,1-8,8H160a8,8,0,0,1,0-16h40A8,8,0,0,1,208,160Z\"></path></svg>`,\n question: `<svg class=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" fill=\"#ffffff\" viewBox=\"0 0 256 256\"><path d=\"M225.86,102.82c-3.77-3.94-7.67-8-9.14-11.57-1.36-3.27-1.44-8.69-1.52-13.94-.15-9.76-.31-20.82-8-28.51s-18.75-7.85-28.51-8c-5.25-.08-10.67-.16-13.94-1.52-3.56-1.47-7.63-5.37-11.57-9.14C146.28,23.51,138.44,16,128,16s-18.27,7.51-25.18,14.14c-3.94,3.77-8,7.67-11.57,9.14C88,40.64,82.56,40.72,77.31,40.8c-9.76.15-20.82.31-28.51,8S41,67.55,40.8,77.31c-.08,5.25-.16,10.67-1.52,13.94-1.47,3.56-5.37,7.63-9.14,11.57C23.51,109.72,16,117.56,16,128s7.51,18.27,14.14,25.18c3.77,3.94,7.67,8,9.14,11.57,1.36,3.27,1.44,8.69,1.52,13.94.15,9.76.31,20.82,8,28.51s18.75,7.85,28.51,8c5.25.08,10.67.16,13.94,1.52,3.56,1.47,7.63,5.37,11.57,9.14C109.72,232.49,117.56,240,128,240s18.27-7.51,25.18-14.14c3.94-3.77,8-7.67,11.57-9.14,3.27-1.36,8.69-1.44,13.94-1.52,9.76-.15,20.82-.31,28.51-8s7.85-18.75,8-28.51c.08-5.25.16-10.67,1.52-13.94,1.47-3.56,5.37-7.63,9.14-11.57C232.49,146.28,240,138.44,240,128S232.49,109.73,225.86,102.82Zm-11.55,39.29c-4.79,5-9.75,10.17-12.38,16.52-2.52,6.1-2.63,13.07-2.73,19.82-.1,7-.21,14.33-3.32,17.43s-10.39,3.22-17.43,3.32c-6.75.1-13.72.21-19.82,2.73-6.35,2.63-11.52,7.59-16.52,12.38S132,224,128,224s-9.15-4.92-14.11-9.69-10.17-9.75-16.52-12.38c-6.1-2.52-13.07-2.63-19.82-2.73-7-.1-14.33-.21-17.43-3.32s-3.22-10.39-3.32-17.43c-.1-6.75-.21-13.72-2.73-19.82-2.63-6.35-7.59-11.52-12.38-16.52S32,132,32,128s4.92-9.15,9.69-14.11,9.75-10.17,12.38-16.52c2.52-6.1,2.63-13.07,2.73-19.82.1-7,.21-14.33,3.32-17.43S70.51,56.9,77.55,56.8c6.75-.1,13.72-.21,19.82-2.73,6.35-2.63,11.52-7.59,16.52-12.38S124,32,128,32s9.15,4.92,14.11,9.69,10.17,9.75,16.52,12.38c6.1,2.52,13.07,2.63,19.82,2.73,7,.1,14.33.21,17.43,3.32s3.22,10.39,3.32,17.43c.1,6.75.21,13.72,2.73,19.82,2.63,6.35,7.59,11.52,12.38,16.52S224,124,224,128,219.08,137.15,214.31,142.11ZM140,180a12,12,0,1,1-12-12A12,12,0,0,1,140,180Zm28-72c0,17.38-13.76,31.93-32,35.28V144a8,8,0,0,1-16,0v-8a8,8,0,0,1,8-8c13.23,0,24-9,24-20s-10.77-20-24-20-24,9-24,20v4a8,8,0,0,1-16,0v-4c0-19.85,17.94-36,40-36S168,88.15,168,108Z\"></path></svg>`,\n };\n\n const actions = [\n {\n key: \"overview\",\n icon: icons.house,\n label: \"Overview\",\n cb: cb.onOverview,\n },\n { key: \"memory\", icon: icons.brain, label: \"Memory\", cb: cb.onMemory },\n {\n key: \"vocabulary\",\n icon: icons.book,\n label: \"Vocabulary\",\n cb: cb.onVocabulary,\n },\n {\n key: \"clarifications\",\n icon: icons.question,\n label: \"Clarifications\",\n cb: cb.onClarifications,\n },\n ];\n\n actions.forEach((action) => {\n const btn = document.createElement(\"button\");\n btn.className =\n \"rail-item\" + (state.activeSection === action.key ? \" active\" : \"\");\n btn.type = \"button\";\n btn.tabIndex = 0;\n btn.innerHTML =\n (action.key === \"memory\"\n ? `<div class=\"rail-glow${state.hasMemoryGlow ? \" active\" : \"\"}\"></div>`\n : \"\") + action.icon;\n // Add custom tooltip\n const tooltip = document.createElement(\"span\");\n tooltip.className = \"rail-tooltip\";\n tooltip.textContent = action.label;\n btn.appendChild(tooltip);\n btn.addEventListener(\"click\", action.cb);\n root.appendChild(btn);\n });\n\n return root;\n}\n","// Bottom section: Login/Logout\nexport interface RailAuthCallbacks {\n onLogin: () => void;\n onLogout: () => void;\n}\n\nexport function createRailAuth(\n isLoggedIn: boolean,\n cb: RailAuthCallbacks,\n): HTMLElement {\n const root = document.createElement(\"div\");\n root.className = \"rail-auth rail-section\";\n const btn = document.createElement(\"button\");\n btn.className = \"rail-auth-btn\";\n btn.type = \"button\";\n btn.tabIndex = 0;\n let iconSVG, tooltipText;\n if (isLoggedIn) {\n iconSVG = `<svg class=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" fill=\"#ffffff\" viewBox=\"0 0 256 256\"><path d=\"M120,216a8,8,0,0,1-8,8H48a8,8,0,0,1-8-8V40a8,8,0,0,1,8-8h64a8,8,0,0,1,0,16H56V208h56A8,8,0,0,1,120,216Zm109.66-93.66-40-40a8,8,0,0,0-11.32,11.32L204.69,120H112a8,8,0,0,0,0,16h92.69l-26.35,26.34a8,8,0,0,0,11.32,11.32l40-40A8,8,0,0,0,229.66,122.34Z\"></path></svg>`;\n tooltipText = \"Logout\";\n btn.addEventListener(\"click\", cb.onLogout);\n } else {\n iconSVG = `<svg class=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" fill=\"#ffffff\" viewBox=\"0 0 256 256\"><path d=\"M141.66,133.66l-40,40a8,8,0,0,1-11.32-11.32L116.69,136H24a8,8,0,0,1,0-16h92.69L90.34,93.66a8,8,0,0,1,11.32-11.32l40,40A8,8,0,0,1,141.66,133.66ZM200,32H136a8,8,0,0,0,0,16h56V208H136a8,8,0,0,0,0,16h64a8,8,0,0,0,8-8V40A8,8,0,0,0,200,32Z\"></path></svg>`;\n tooltipText = \"Login\";\n btn.addEventListener(\"click\", cb.onLogin);\n }\n btn.innerHTML = iconSVG;\n // Add custom tooltip\n const tooltip = document.createElement(\"span\");\n tooltip.className = \"rail-tooltip\";\n tooltip.textContent = tooltipText;\n btn.appendChild(tooltip);\n root.appendChild(btn);\n return root;\n}\n","// Assembles the Unnoodle Rail from sections, manages state\nimport { railStyles } from \"./railStyles\";\nimport { createRailIdentity } from \"./railIdentity\";\nimport {\n createRailCoreActions,\n RailCoreActionsCallbacks,\n} from \"./railCoreActions\";\nimport { createRailAuth, RailAuthCallbacks } from \"./railAuth\";\n\nexport interface RailState {\n isLoggedIn: boolean;\n initials: string | null;\n activeSection: \"overview\" | \"memory\" | \"vocabulary\" | \"clarifications\" | null;\n hasMemoryGlow: boolean;\n}\n\nexport interface RailCallbacks\n extends RailCoreActionsCallbacks, RailAuthCallbacks {}\n\nexport function createRail(\n state: RailState,\n cb: RailCallbacks,\n): {\n element: HTMLElement;\n setState: (s: Partial<RailState>) => void;\n cleanup: () => void;\n} {\n const host = document.createElement(\"div\");\n host.id = \"unnoodle-rail-host\";\n const shadow = host.attachShadow({ mode: \"open\" });\n\n // Style\n const style = document.createElement(\"style\");\n style.textContent = railStyles;\n shadow.appendChild(style);\n\n // Sections\n let identity = createRailIdentity(state.initials);\n let core = createRailCoreActions(\n {\n activeSection: state.activeSection,\n hasMemoryGlow: state.hasMemoryGlow,\n },\n cb,\n );\n let auth = createRailAuth(state.isLoggedIn, cb);\n\n // Rail shell (fixed positioned wrapper, like panel-shell)\n const railShell = document.createElement(\"div\");\n railShell.className = \"rail-shell\";\n\n const rail = document.createElement(\"nav\");\n rail.className = \"rail\";\n rail.appendChild(identity);\n rail.appendChild(core);\n rail.appendChild(auth);\n\n railShell.appendChild(rail);\n shadow.appendChild(railShell);\n\n // Push body content so the rail doesn't overlay the page\n const RAIL_WIDTH = 34;\n document.body.style.transition =\n \"margin-right 0.28s cubic-bezier(0.4,0,0.2,1)\";\n document.body.style.marginRight = `${RAIL_WIDTH}px`;\n\n // State update\n function setState(s: Partial<RailState>) {\n // Remove old\n rail.removeChild(identity);\n rail.removeChild(core);\n rail.removeChild(auth);\n // New\n identity = createRailIdentity(s.initials ?? state.initials);\n core = createRailCoreActions(\n {\n activeSection: s.activeSection ?? state.activeSection,\n hasMemoryGlow: s.hasMemoryGlow ?? state.hasMemoryGlow,\n },\n cb,\n );\n auth = createRailAuth(s.isLoggedIn ?? state.isLoggedIn, cb);\n rail.appendChild(identity);\n rail.appendChild(core);\n rail.appendChild(auth);\n // Update state\n Object.assign(state, s);\n }\n\n // Cleanup\n function cleanup() {\n host.remove();\n document.body.style.marginRight = \"\";\n }\n\n return { element: host, setState, cleanup };\n}\n","import { createButton } from \"./button\";\nimport { createPanel, type PanelControls } from \"./panel\";\nimport type { GlossaryTerm, GlossaryTermUpdateRequest } from \"../types/config\";\nimport { createRail, RailState, RailCallbacks } from \"./rail/rail\";\n\nexport interface MountedUI {\n panel: PanelControls;\n /** Toggle the spinning progress ring or rail state. */\n setProgress: (active: boolean) => void;\n cleanup: () => void;\n}\n\nexport interface MountedRailUI {\n panel: PanelControls;\n setRailState: (s: Partial<RailState>) => void;\n cleanup: () => void;\n}\n\n/**\n * Mounts the button and panel host elements into the document body.\n * Both use Shadow DOM so they are fully isolated from host app styles.\n */\n/**\n * Mounts the button and panel host elements into the document body.\n * Both use Shadow DOM so they are fully isolated from host app styles.\n * This is the default (button) version.\n */\nexport function mountUI(\n onTrigger: () => void,\n onLogin: (email: string, password: string) => void,\n onSearch: (query: string) => void,\n workspaceUrl?: string,\n onClose?: () => void,\n onBack?: () => void,\n onAddComment?: (termId: number, body: string) => void,\n onEditTerm?: (termId: number, updates: GlossaryTermUpdateRequest) => void,\n onTermClick?: (term: GlossaryTerm) => void,\n onRequestEdit?: (termId: number) => void,\n onCaptureUiState?: () => void,\n onOpenMemories?: () => void,\n onViewMemoryDetail?: (id: number) => void,\n onUpdateEntryExplanation?: (\n memoryId: number,\n entryId: number,\n explanation: string,\n ) => void,\n onPopout?: () => void,\n onReattach?: () => void,\n onSsoLogin?: (provider: \"google\" | \"microsoft\") => void,\n shadowTokens?: string,\n onAskQuestion?: (contextId: number, body: string) => void,\n onRequireLogin?: () => void,\n onAddConcept?: (term: string, definition: string) => void,\n onOpenSearch?: () => void,\n onClarificationClick?: (\n discussion: import(\"../types/config\").ContextDiscussion,\n ) => void,\n onPostReply?: (contextId: number, questionId: number, body: string) => void,\n onAddEntryToMemory?: (memoryId: number) => void,\n onDeleteMemory?: (memoryId: number) => void,\n onDeleteEntry?: (memoryId: number, entryId: number) => void,\n onShowAllConcepts?: () => void,\n onShowAllClarifications?: () => void,\n onShowAllMemories?: () => void,\n): MountedUI {\n const panel = createPanel(\n onLogin,\n onSearch,\n workspaceUrl,\n onClose,\n onBack,\n onAddComment,\n onEditTerm,\n onTermClick,\n onRequestEdit,\n onCaptureUiState,\n onOpenMemories,\n onViewMemoryDetail,\n onUpdateEntryExplanation,\n onPopout,\n onReattach,\n onSsoLogin,\n shadowTokens,\n onAskQuestion,\n onRequireLogin,\n onAddConcept,\n onOpenSearch,\n onClarificationClick,\n onPostReply,\n onAddEntryToMemory,\n onDeleteMemory,\n onDeleteEntry,\n onShowAllConcepts,\n onShowAllClarifications,\n onShowAllMemories,\n );\n const button = createButton(onTrigger, shadowTokens);\n\n document.body.appendChild(panel.element);\n document.body.appendChild(button.element);\n\n const cleanup = () => {\n button.cleanup();\n panel.cleanup();\n };\n\n return { panel, setProgress: button.setProgress, cleanup };\n}\n\n/**\n * Mounts the Unnoodle Rail and panel host elements into the document body.\n * The rail is feature-flagged and state-driven.\n */\nexport function mountRailUI(\n railState: RailState,\n railCallbacks: RailCallbacks,\n panelCallbacks: Parameters<typeof createPanel>,\n): MountedRailUI {\n const panel = createPanel(...panelCallbacks);\n const rail = createRail(railState, railCallbacks);\n document.body.appendChild(panel.element);\n document.body.appendChild(rail.element);\n const cleanup = () => {\n rail.cleanup();\n panel.cleanup();\n };\n return {\n panel,\n setRailState: rail.setState,\n cleanup,\n };\n}\n","import type { GlossaryTerm } from \"../types/config\";\n\n/** Tags whose text content we never highlight */\nconst SKIP_TAGS = new Set([\n \"INPUT\",\n \"TEXTAREA\",\n \"SCRIPT\",\n \"STYLE\",\n \"CODE\",\n \"PRE\",\n \"KBD\",\n \"SAMP\",\n \"VAR\",\n \"NOSCRIPT\",\n \"BUTTON\",\n \"SELECT\",\n \"OPTION\",\n \"OPTGROUP\",\n]);\n\n/** Unnoodle shadow-host element IDs to exclude from DOM walking */\nconst SKIP_IDS = new Set([\"unnoodle-panel-host\", \"unnoodle-btn-host\"]);\n\nconst HIGHLIGHT_CLASS = \"unnoodle-highlight\";\n\nconst HIGHLIGHT_STYLE = [\n \"border-bottom: 1px dotted currentColor\",\n \"cursor: pointer\",\n \"opacity: 0.85\",\n \"text-decoration: none\",\n].join(\"; \");\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Scans the host page DOM and wraps glossary term occurrences in highlighted\n * spans. Call `apply()` when the panel opens and `remove()` when it closes.\n *\n * Safety rules:\n * - Skips script/style/code/pre and other non-prose tags\n * - Skips contenteditable regions\n * - Skips the unnoodle widget hosts (Shadow DOM)\n * - Skips DEPRECATED terms\n * - Whole-word matches only (word-boundary regex)\n * - Longer terms take priority over shorter ones (no partial collisions)\n * - Never double-wraps already-highlighted spans\n */\nexport class Highlighter {\n private onTermClick: (term: GlossaryTerm) => void;\n private highlights: HTMLElement[] = [];\n\n constructor(onTermClick: (term: GlossaryTerm) => void) {\n this.onTermClick = onTermClick;\n }\n\n /** Highlight all active terms in the current document. */\n apply(terms: GlossaryTerm[]): void {\n this.remove();\n const active = terms.filter((t) => t.status === \"ACTIVE\");\n if (active.length === 0) return;\n\n const { regex, termMap } = this.buildPattern(active);\n this.walkAndHighlight(document.body, regex, termMap);\n }\n\n /** Remove all highlights and restore original text nodes. */\n remove(): void {\n // Iterate in reverse to preserve sibling ordering during restoration\n for (let i = this.highlights.length - 1; i >= 0; i--) {\n const span = this.highlights[i]!;\n const parent = span.parentNode;\n if (!parent) continue;\n parent.replaceChild(\n document.createTextNode(span.textContent ?? \"\"),\n span,\n );\n parent.normalize();\n }\n this.highlights = [];\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Builds a single combined regex from all terms so that each text node is\n * processed in one pass. Terms are sorted longest-first so \"API Gateway\"\n * matches before a standalone \"API\".\n */\n private buildPattern(terms: GlossaryTerm[]): {\n regex: RegExp;\n termMap: Map<string, GlossaryTerm>;\n } {\n const termMap = new Map<string, GlossaryTerm>();\n const sorted = [...terms].sort((a, b) => b.term.length - a.term.length);\n const patterns: string[] = [];\n\n for (const term of sorted) {\n const key = term.term.toLowerCase();\n if (!termMap.has(key)) {\n termMap.set(key, term);\n patterns.push(escapeRegex(term.term));\n }\n if (term.abbreviation) {\n const abbrKey = term.abbreviation.toLowerCase();\n if (!termMap.has(abbrKey)) {\n termMap.set(abbrKey, term);\n patterns.push(escapeRegex(term.abbreviation));\n }\n }\n }\n\n if (patterns.length === 0) {\n return { regex: /(?!)/g, termMap };\n }\n\n const regex = new RegExp(`\\\\b(${patterns.join(\"|\")})\\\\b`, \"gi\");\n return { regex, termMap };\n }\n\n private walkAndHighlight(\n node: Node,\n regex: RegExp,\n termMap: Map<string, GlossaryTerm>,\n ): void {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const el = node as Element;\n\n // Skip unnoodle widget hosts (Shadow DOM)\n if (SKIP_IDS.has(el.id)) return;\n\n // Never re-highlight an existing span\n if (el.classList.contains(HIGHLIGHT_CLASS)) return;\n\n // Skip contenteditable regions\n if (el.getAttribute(\"contenteditable\") != null) return;\n\n // Skip non-prose tag types\n if (SKIP_TAGS.has(el.tagName)) return;\n\n // Snapshot childNodes before walking so mutations don't skew iteration\n for (const child of Array.from(el.childNodes)) {\n this.walkAndHighlight(child, regex, termMap);\n }\n } else if (node.nodeType === Node.TEXT_NODE) {\n this.highlightTextNode(node as Text, regex, termMap);\n }\n }\n\n private highlightTextNode(\n textNode: Text,\n regex: RegExp,\n termMap: Map<string, GlossaryTerm>,\n ): void {\n const text = textNode.textContent ?? \"\";\n if (!text.trim()) return;\n\n regex.lastIndex = 0;\n const fragments: (string | HTMLElement)[] = [];\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(text)) !== null) {\n const matched = match[0];\n const term = termMap.get(matched.toLowerCase());\n if (!term) continue;\n\n if (match.index > lastIndex) {\n fragments.push(text.slice(lastIndex, match.index));\n }\n\n const span = document.createElement(\"span\");\n span.className = HIGHLIGHT_CLASS;\n span.dataset.termId = String(term.id);\n span.textContent = matched;\n span.title =\n term.definition.length > 120\n ? `${term.definition.slice(0, 120)}…`\n : term.definition;\n span.style.cssText = HIGHLIGHT_STYLE;\n span.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.onTermClick(term);\n });\n\n fragments.push(span);\n this.highlights.push(span);\n lastIndex = match.index + matched.length;\n }\n\n if (fragments.length === 0) return;\n\n fragments.push(text.slice(lastIndex));\n\n const parent = textNode.parentNode;\n if (!parent) return;\n const anchor = textNode.nextSibling;\n parent.removeChild(textNode);\n\n for (const fragment of fragments) {\n if (typeof fragment === \"string\") {\n if (fragment) {\n parent.insertBefore(document.createTextNode(fragment), anchor);\n }\n } else {\n parent.insertBefore(fragment, anchor);\n }\n }\n }\n}\n","import type { GlossaryTerm, TermSuggestion } from \"../types/config\";\n\n/** Tags whose text content we never scan for candidate terms */\nconst SKIP_TAGS = new Set([\n \"INPUT\",\n \"TEXTAREA\",\n \"SCRIPT\",\n \"STYLE\",\n \"CODE\",\n \"PRE\",\n \"KBD\",\n \"SAMP\",\n \"VAR\",\n \"NOSCRIPT\",\n \"BUTTON\",\n \"SELECT\",\n \"OPTION\",\n \"OPTGROUP\",\n]);\n\n/** Unnoodle shadow-host element IDs — skip entirely */\nconst SKIP_IDS = new Set([\"unnoodle-panel-host\", \"unnoodle-btn-host\"]);\n\n/** Maximum number of suggestions to return */\nconst MAX_SUGGESTIONS = 5;\n\n/** Minimum number of occurrences for a candidate to qualify */\nconst MIN_FREQUENCY = 2;\n\n/**\n * Common English words that are capitalised purely due to sentence position —\n * these produce far too many false positives to be useful suggestions.\n */\nconst STOP_WORDS = new Set([\n \"The\",\n \"This\",\n \"These\",\n \"Those\",\n \"That\",\n \"Then\",\n \"There\",\n \"They\",\n \"Their\",\n \"When\",\n \"Where\",\n \"What\",\n \"Why\",\n \"How\",\n \"With\",\n \"From\",\n \"Into\",\n \"Has\",\n \"Have\",\n \"Was\",\n \"Were\",\n \"For\",\n \"But\",\n \"And\",\n \"Or\",\n \"In\",\n \"On\",\n \"At\",\n \"By\",\n \"Us\",\n \"We\",\n \"He\",\n \"She\",\n \"It\",\n \"Our\",\n \"Its\",\n \"You\",\n \"Your\",\n \"His\",\n \"Her\",\n \"An\",\n \"As\",\n \"Be\",\n \"Do\",\n \"To\",\n \"If\",\n \"Of\",\n \"So\",\n \"Up\",\n \"I\",\n]);\n\n/**\n * Scans the host-page DOM for candidate glossary terms: capitalized\n * phrases that appear multiple times and are not already in the glossary.\n *\n * Call `scan(glossary)` after the glossary loads.\n * Call `getPageContext(term)` to extract surrounding text for AI context.\n */\nexport class TermSuggester {\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n /**\n * Scans the current document and returns the top N candidate terms\n * sorted by frequency descending.\n *\n * Algorithm:\n * 1. Extract visible text, skipping code/script/input/unnoodle zones.\n * 2. Find all maximal runs of consecutive capitalised words.\n * 3. Within each run, enumerate every 1-, 2-, and 3-word sub-phrase that\n * starts at each position — this ensures \"Circuit Breaker\" is counted\n * even when preceded by \"Use\", rather than being consumed as part of the\n * longer phrase \"Use Circuit Breaker\".\n * 4. Aggregate frequency, filter by MIN_FREQUENCY, cap at MAX_SUGGESTIONS.\n */\n scan(existingTerms: GlossaryTerm[]): TermSuggestion[] {\n const glossarySet = this.buildGlossarySet(existingTerms);\n const text = this.extractText(document.body);\n\n const freq = new Map<string, number>();\n\n /**\n * Matches a maximal run of consecutive capitalised words (separated only\n * by whitespace). Each run is then split into individual words for the\n * n-gram enumeration below.\n */\n const RUN_RE = /[A-Z][a-zA-Z]*(?:\\s+[A-Z][a-zA-Z]*)*/g;\n let runMatch: RegExpExecArray | null;\n\n while ((runMatch = RUN_RE.exec(text)) !== null) {\n const words = runMatch[0].split(/\\s+/);\n\n for (let i = 0; i < words.length; i++) {\n // Skip if the first word of the candidate is a stop word\n if (STOP_WORDS.has(words[i]!)) continue;\n\n for (let len = 1; len <= Math.min(3, words.length - i); len++) {\n const phrase = words.slice(i, i + len).join(\" \");\n if (phrase.length < 2) continue;\n if (glossarySet.has(phrase.toLowerCase())) continue;\n freq.set(phrase, (freq.get(phrase) ?? 0) + 1);\n }\n }\n }\n\n return [...freq.entries()]\n .filter(([, count]) => count >= MIN_FREQUENCY)\n .sort((a, b) => b[1] - a[1])\n .slice(0, MAX_SUGGESTIONS)\n .map(([term, count]) => ({ term, count }));\n }\n\n /**\n * Returns the text of the paragraph/block element that contains the\n * first occurrence of `term` in the page. Used as AI context.\n */\n getPageContext(term: string): string {\n const lower = term.toLowerCase();\n const candidates = Array.from(\n document.body.querySelectorAll(\"p, li, blockquote, td, section, article\"),\n );\n\n for (const el of candidates) {\n if (SKIP_TAGS.has(el.tagName)) continue;\n if (SKIP_IDS.has(el.id)) continue;\n const text = el.textContent ?? \"\";\n if (text.toLowerCase().includes(lower)) {\n // Return truncated to 500 chars to keep prompt size sane\n return text.slice(0, 500).trim();\n }\n }\n\n return \"\";\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n private buildGlossarySet(terms: GlossaryTerm[]): Set<string> {\n const s = new Set<string>();\n for (const t of terms) {\n s.add(t.term.toLowerCase());\n if (t.abbreviation) s.add(t.abbreviation.toLowerCase());\n }\n return s;\n }\n\n private extractText(node: Node): string {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const el = node as Element;\n if (SKIP_IDS.has(el.id)) return \"\";\n if (SKIP_TAGS.has(el.tagName)) return \"\";\n if (el.getAttribute(\"contenteditable\") != null) return \"\";\n return Array.from(el.childNodes)\n .map((c) => this.extractText(c))\n .join(\" \");\n }\n if (node.nodeType === Node.TEXT_NODE) {\n return node.textContent ?? \"\";\n }\n return \"\";\n }\n}\n","import type {\n UnnoodleConfig,\n WidgetInitResponse,\n GlossaryTerm,\n ContextDiscussion,\n GlossaryTermUpdateRequest,\n ProductMemoryResponse,\n ProductMemoryDetailResponse,\n SsoProviders,\n} from \"../types/config\";\nimport Fuse, { type FuseResult } from \"fuse.js\";\nimport {\n initWidget,\n searchTerms,\n loginUser,\n fetchOAuthProviders,\n getDiscussions,\n postComment,\n updateTerm,\n generateAiDefinition,\n createSuggestedTerm,\n createProductMemory,\n listProductMemories,\n getProductMemory,\n updateProductMemoryEntry,\n fetchContextDiscussions,\n postContextDiscussion,\n postContextReply,\n deleteProductMemory,\n deleteProductMemoryEntry,\n createGlossaryTerm,\n ApiError,\n} from \"../core/apiClient\";\nimport {\n createCaptureModeController,\n type CaptureModeController,\n} from \"../features/memory/captureModeController\";\nimport { AddEntryOrchestrator } from \"../features/memory/captureOrchestrator\";\nimport { mountUI, mountRailUI, type MountedUI } from \"../ui/mount\";\nimport { Highlighter } from \"../ui/highlighter\";\nimport { TermSuggester } from \"../ui/termSuggester\";\n\nexport type WidgetView = \"login\" | \"terms\";\n\n/**\n * Controls the full widget lifecycle:\n *\n * 1. Mount floating button + panel (Shadow DOM)\n * 2. On open — load terms immediately using the API key alone (no login required)\n * 3. If a user JWT is already available (from sessionStorage), attach it so the\n * server can personalise results — but it is never required for reads.\n * 4. Write actions (Phase 2) will prompt inline login when needed.\n * 5. Terms panel shows searchable glossary list\n * 6. Keyboard shortcut Cmd/Ctrl+U toggles open/close\n */\nexport class WidgetController {\n constructor(config: UnnoodleConfig) {\n this.config = config;\n }\n private config!: UnnoodleConfig;\n private ui: MountedUI | null = null;\n private rail: { setRailState?: (s: any) => void } | null = null;\n private isOpen = false;\n private isFetching = false;\n private keydownHandler: ((e: KeyboardEvent) => void) | null = null;\n private authToken: string | null = null;\n private tokenExpiryTimer: ReturnType<typeof setTimeout> | null = null;\n private cachedResponse: WidgetInitResponse | null = null;\n private cachedDiscussions: ContextDiscussion[] | null = null;\n private cachedHomeMemories: ProductMemoryResponse[] | null = null;\n private highlighter: Highlighter | null = null;\n private suggester: TermSuggester | null = null;\n private captureModeController: CaptureModeController | null = null;\n private activeSuggestion: any = null;\n private ssoProviders: SsoProviders | null = null;\n private ssoPopupCleanup: (() => void) | null = null;\n private fuseIndex: any = null;\n private currentTerm: GlossaryTerm | null = null;\n private currentDiscussion: ContextDiscussion | null = null;\n private currentMemory: ProductMemoryDetailResponse | null = null;\n private memories: ProductMemoryResponse[] = [];\n private memoriesPage: number = 0;\n private hasMoreMemories: boolean = false;\n private pendingAction: (() => void) | null = null;\n private sessionKey: string = \"unnoodle_jwt\";\n\n /**\n * Returns user initials for the rail avatar, using config or session info if available.\n */\n private getUserInitials(): string {\n let name = (this.config as any).userName as string | undefined;\n let email = (this.config as any).userEmail as string | undefined;\n if (!name && this.authToken) {\n try {\n const token = this.authToken;\n if (token) {\n const parts = token.split(\".\");\n if (parts.length === 3 && typeof parts[1] === \"string\") {\n const payload = JSON.parse(atob(parts[1]));\n name = payload.name;\n email = payload.email;\n }\n }\n } catch {}\n }\n if (name) {\n const parts = name.trim().split(\" \");\n if (parts.length === 1)\n return parts[0] && parts[0][0] ? parts[0][0].toUpperCase() : \"?\";\n const first = parts[0] && parts[0][0] ? parts[0][0] : \"\";\n const lastPart = parts[parts.length - 1];\n const last = lastPart && lastPart[0] ? lastPart[0] : \"\";\n return (first + last).toUpperCase() || \"?\";\n }\n if (email && email[0]) return email[0].toUpperCase();\n return \"?\";\n }\n\n init(): void {\n if (!this.config) {\n throw new Error(\"WidgetController: config is not set\");\n }\n const shadowTokens = this.config.theme?.shadowTokens;\n // Feature flag: useRail\n if ((this.config as any).useRail) {\n // Minimal state for demo: initials, login, active section, memory glow\n const isLoggedIn = !!this.resolveToken();\n const initials = isLoggedIn ? this.getUserInitials() : null;\n const railState = {\n isLoggedIn,\n initials,\n activeSection: \"overview\" as const,\n hasMemoryGlow: false,\n };\n const railCallbacks = {\n onOverview: () => this.open(),\n onMemory: () => {\n if (!this.isOpen) this.open();\n const token = !!this.resolveToken();\n if (this.cachedResponse?.productMemories) {\n this.ui?.panel.showAllMemories(\n this.cachedResponse.productMemories,\n token,\n );\n } else if (this.cachedHomeMemories) {\n this.ui?.panel.showAllMemories(this.cachedHomeMemories, token);\n } else {\n this.ui?.panel.showAllMemories?.([], token);\n }\n },\n onVocabulary: () => {\n if (!this.isOpen) this.open();\n if (this.cachedResponse) {\n this.ui?.panel.showAllConcepts(this.cachedResponse.glossary);\n } else {\n this.ui?.panel.showAllConcepts?.([]);\n }\n },\n onClarifications: () => {\n if (!this.isOpen) this.open();\n const token = !!this.resolveToken();\n if (this.cachedDiscussions) {\n this.ui?.panel.showAllClarifications(this.cachedDiscussions, token);\n } else {\n this.ui?.panel.showAllClarifications?.([], token);\n }\n },\n onLogin: () => {\n if (!this.isOpen) {\n this.isOpen = true;\n this.ui?.panel.show();\n }\n void this.showLoginWithProviders();\n },\n onLogout: () => {\n this.clearAuthToken();\n void this.showLoginWithProviders();\n },\n };\n const panelCallbacks = [\n (email: string, password: string) => this.handleLogin(email, password),\n (query: string) => this.handleSearch(query),\n this.config.workspaceUrl,\n () => {\n this.isOpen = false;\n this.highlighter?.remove();\n },\n () => this.handleBack(),\n (termId: number, body: string) => this.handleAddComment(termId, body),\n (termId: number, updates: GlossaryTermUpdateRequest) =>\n this.handleEditTerm(termId, updates),\n (term: GlossaryTerm) => this.handleTermClick(term),\n (termId: number) => this.handleRequestEdit(termId),\n () => {\n if (!this.resolveToken()) {\n void this.showLoginWithProviders();\n } else {\n this.captureModeController?.start();\n }\n },\n () => {\n void this.loadMemories(0, false);\n },\n (id: number) => {\n void this.handleViewMemoryDetail(id);\n },\n (memoryId: number, entryId: number, explanation: string) => {\n void this.handleUpdateEntryExplanation(\n memoryId,\n entryId,\n explanation,\n );\n },\n () => {\n this.isOpen = false;\n this.highlighter?.remove();\n },\n () => {\n this.isOpen = false;\n },\n (provider: \"google\" | \"microsoft\") => {\n this.handleSsoLogin(provider);\n },\n shadowTokens,\n (contextId: number, questionBody: string) => {\n void this.handleAskQuestion(contextId, questionBody);\n },\n () => {\n if (!this.resolveToken()) {\n void this.showLoginWithProviders();\n }\n },\n // onAddConcept: user submitted inline add-vocabulary form\n (term: string, definition: string) => {\n void this.handleCreateTerm(term, definition);\n },\n () => {\n if (this.cachedResponse) {\n this.ui?.panel.showSearchResults(this.cachedResponse.glossary, \"\");\n this.ui?.panel.setAuthenticated(!!this.resolveToken());\n }\n },\n (discussion: ContextDiscussion) => {\n this.handleClarificationClick(discussion);\n },\n (contextId: number, questionId: number, body: string) => {\n void this.handlePostReply(contextId, questionId, body);\n },\n (memoryId: number) => {\n this.handleAddEntryToMemory(memoryId);\n },\n (memoryId: number) => {\n void this.handleDeleteMemory(memoryId);\n },\n (memoryId: number, entryId: number) => {\n void this.handleDeleteEntry(memoryId, entryId);\n },\n () => {\n if (this.cachedResponse) {\n this.ui?.panel.showAllConcepts(this.cachedResponse.glossary);\n }\n },\n () => {\n if (this.cachedDiscussions) {\n this.ui?.panel.showAllClarifications(\n this.cachedDiscussions,\n !!this.resolveToken(),\n );\n }\n },\n () => {\n if (this.cachedResponse?.productMemories) {\n this.ui?.panel.showAllMemories(\n this.cachedResponse.productMemories,\n !!this.resolveToken(),\n );\n }\n },\n ] as Parameters<typeof mountRailUI>[2];\n const railMount = mountRailUI(railState, railCallbacks, panelCallbacks);\n this.ui = {\n panel: railMount.panel,\n setProgress: () => {},\n cleanup: railMount.cleanup,\n };\n this.rail = railMount;\n } else {\n this.ui = mountUI(\n () => this.toggle(),\n (email, password) => this.handleLogin(email, password),\n (query) => this.handleSearch(query),\n this.config.workspaceUrl,\n () => {\n this.isOpen = false;\n this.highlighter?.remove();\n },\n () => this.handleBack(),\n (termId, body) => this.handleAddComment(termId, body),\n (termId, updates) => this.handleEditTerm(termId, updates),\n (term) => this.handleTermClick(term),\n (termId) => this.handleRequestEdit(termId),\n () => {\n console.log(\"[unnoodle] onCaptureUiState callback triggered\", {\n captureModeController: !!this.captureModeController,\n ui: !!this.ui,\n });\n if (!this.resolveToken()) {\n void this.showLoginWithProviders();\n } else {\n this.captureModeController?.start();\n }\n },\n () => {\n void this.loadMemories(0, false);\n },\n (id) => {\n void this.handleViewMemoryDetail(id);\n },\n (memoryId, entryId, explanation) => {\n void this.handleUpdateEntryExplanation(\n memoryId,\n entryId,\n explanation,\n );\n },\n // onPopout: panel leaves the main window — treat as closed so toggle() re-opens correctly\n () => {\n this.isOpen = false;\n this.highlighter?.remove();\n },\n // onReattach: panel returns to main window in closed state\n () => {\n this.isOpen = false;\n },\n // onSsoLogin: open popup for Google/Microsoft SSO from the login form\n (provider: \"google\" | \"microsoft\") => {\n this.handleSsoLogin(provider);\n },\n shadowTokens,\n // onAskQuestion: post a new clarification question on the context\n (contextId: number, questionBody: string) => {\n void this.handleAskQuestion(contextId, questionBody);\n },\n // onRequireLogin: unauthenticated user clicked a write-action button\n () => {\n if (!this.resolveToken()) {\n void this.showLoginWithProviders();\n }\n },\n // onAddConcept: user submitted inline add-vocabulary form\n (term: string, definition: string) => {\n void this.handleCreateTerm(term, definition);\n },\n // onOpenSearch: user clicked the search icon in home view → open terms/search view\n () => {\n if (this.cachedResponse) {\n this.ui?.panel.showSearchResults(this.cachedResponse.glossary, \"\");\n this.ui?.panel.setAuthenticated(!!this.resolveToken());\n }\n },\n // onClarificationClick: user clicked a clarification card → navigate to detail view\n (discussion: ContextDiscussion) => {\n this.handleClarificationClick(discussion);\n },\n // onPostReply: user submitted a reply in clarification detail view\n (contextId: number, questionId: number, body: string) => {\n void this.handlePostReply(contextId, questionId, body);\n },\n // onAddEntryToMemory: capture a new element and append it to an existing memory\n (memoryId: number) => {\n this.handleAddEntryToMemory(memoryId);\n },\n // onDeleteMemory: delete an entire product memory\n (memoryId: number) => {\n void this.handleDeleteMemory(memoryId);\n },\n // onDeleteEntry: delete an entry from a product memory\n (memoryId: number, entryId: number) => {\n void this.handleDeleteEntry(memoryId, entryId);\n },\n // onShowAllConcepts: user clicked \"Show All\" in Product Vocabulary section\n () => {\n console.log(\n \"DEBUG: onShowAllConcepts called, cachedResponse:\",\n !!this.cachedResponse,\n );\n if (this.cachedResponse) {\n console.log(\n \"DEBUG: Calling showAllConcepts with\",\n this.cachedResponse.glossary.length,\n \"terms\",\n );\n this.ui?.panel.showAllConcepts(this.cachedResponse.glossary);\n }\n },\n // onShowAllClarifications: user clicked \"Show All\" in Clarifications section\n () => {\n console.log(\n \"DEBUG: onShowAllClarifications called, cachedDiscussions:\",\n !!this.cachedDiscussions,\n );\n if (this.cachedDiscussions) {\n console.log(\n \"DEBUG: Calling showAllClarifications with\",\n this.cachedDiscussions.length,\n \"discussions\",\n );\n this.ui?.panel.showAllClarifications(\n this.cachedDiscussions,\n !!this.resolveToken(),\n );\n }\n },\n // onShowAllMemories: user clicked \"Show All\" in Product Memories section\n () => {\n console.log(\"DEBUG: onShowAllMemories called\", {\n hasCachedResponse: !!this.cachedResponse,\n hasResponseMemories: !!this.cachedResponse?.productMemories,\n hasCachedHomeMemories: !!this.cachedHomeMemories,\n });\n // Use cached data like other sections (consistent behavior)\n if (this.cachedResponse?.productMemories) {\n console.log(\n \"DEBUG: Using cached memories from main response\",\n this.cachedResponse.productMemories.length,\n );\n this.ui?.panel.showAllMemories(\n this.cachedResponse.productMemories,\n !!this.resolveToken(),\n );\n } else if (this.cachedHomeMemories) {\n console.log(\n \"DEBUG: Using cached memories from separate cache\",\n this.cachedHomeMemories.length,\n );\n this.ui?.panel.showAllMemories(\n this.cachedHomeMemories,\n !!this.resolveToken(),\n );\n } else {\n console.log(\"DEBUG: No cached memories, fetching via API\");\n void this.loadAllMemories();\n }\n },\n );\n }\n\n this.captureModeController = createCaptureModeController(\n this.ui.panel,\n this.config,\n () => this.resolveToken(),\n () => this.cachedResponse?.glossary ?? [],\n () => void this.loadHomeMemoryItems(),\n );\n\n this.keydownHandler = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key === \"u\") {\n e.preventDefault();\n this.toggle();\n }\n };\n document.addEventListener(\"keydown\", this.keydownHandler);\n\n this.highlighter = new Highlighter((term) => this.handleTermClick(term));\n this.suggester = new TermSuggester();\n\n // Run onInit plugins\n if (this.config._plugins) {\n for (const plugin of this.config._plugins) {\n try {\n plugin.onInit?.(this.config);\n } catch {\n /* fail silently per plugin */\n }\n }\n }\n }\n\n open(): void {\n if (this.isOpen || !this.ui) return;\n this.isOpen = true;\n this.ui.panel.show();\n this.loadTerms();\n }\n\n close(): void {\n if (!this.isOpen || !this.ui) return;\n this.isOpen = false;\n this.highlighter?.remove();\n this.ui.panel.hide();\n }\n\n toggle(): void {\n this.isOpen ? this.close() : this.open();\n }\n\n /**\n * Show or hide the spinning progress ring on the trigger button.\n * Call `setProgress(true)` when a background task starts and\n * `setProgress(false)` when it completes.\n */\n setProgress(active: boolean): void {\n this.ui?.setProgress(active);\n }\n\n destroy(): void {\n if (this.keydownHandler) {\n document.removeEventListener(\"keydown\", this.keydownHandler);\n this.keydownHandler = null;\n }\n if (this.tokenExpiryTimer !== null) {\n clearTimeout(this.tokenExpiryTimer);\n this.tokenExpiryTimer = null;\n }\n this.highlighter?.remove();\n this.highlighter = null;\n this.suggester = null;\n this.captureModeController = null;\n this.activeSuggestion = null;\n this.ssoProviders = null;\n this.ssoPopupCleanup?.();\n this.ssoPopupCleanup = null;\n this.ui?.cleanup();\n this.ui = null;\n this.authToken = null;\n this.cachedResponse = null;\n this.cachedDiscussions = null;\n this.cachedHomeMemories = null;\n this.fuseIndex = null;\n this.currentTerm = null;\n this.pendingAction = null;\n try {\n sessionStorage.removeItem(this.sessionKey);\n } catch {\n /* ignore */\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n private resolveToken(): string | null {\n if (this.authToken) return this.authToken;\n return typeof this.config.getAuthToken === \"function\"\n ? (this.config.getAuthToken() ?? null)\n : null;\n }\n\n /**\n * Clear the stored auth token and remove it from sessionStorage.\n * Called when the JWT expiry timer fires.\n */\n private clearAuthToken(): void {\n this.authToken = null;\n try {\n sessionStorage.removeItem(this.sessionKey);\n } catch {\n /* ignore */\n }\n }\n\n /**\n * Schedule a timer that fires exactly when the JWT expires.\n * On expiry the token is cleared and, if the panel is open, a login panel\n * is shown — no outbound HTTP call is needed (cross-origin cookie restriction).\n */\n private scheduleTokenExpiry(jwt: string): void {\n if (this.tokenExpiryTimer !== null) {\n clearTimeout(this.tokenExpiryTimer);\n this.tokenExpiryTimer = null;\n }\n try {\n const parts = jwt.split(\".\");\n if (parts.length !== 3) return;\n const payloadB64 = parts[1];\n if (!payloadB64) return;\n const b64 = payloadB64.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const payload = JSON.parse(atob(b64)) as { exp?: unknown };\n if (typeof payload.exp !== \"number\") return;\n const expSeconds: number = payload.exp;\n\n const msUntilExpiry = expSeconds * 1000 - Date.now();\n if (msUntilExpiry <= 0) {\n // Already expired — clear immediately\n this.clearAuthToken();\n return;\n }\n\n this.tokenExpiryTimer = setTimeout(() => {\n this.tokenExpiryTimer = null;\n this.clearAuthToken();\n // If the panel is open prompt the user to sign in again\n if (this.isOpen && this.ui) {\n void this.showLoginWithProviders();\n }\n }, msUntilExpiry);\n } catch {\n /* malformed JWT payload — silently ignore */\n }\n }\n\n /**\n * Fetches SSO providers (once, cached) then shows the login form with the\n * correct SSO buttons for this tenant. Never throws — provider fetch errors\n * fall back to password-only login.\n */\n private async showLoginWithProviders(): Promise<void> {\n if (!this.ui) return;\n if (!this.ssoProviders) {\n this.ssoProviders = await fetchOAuthProviders(this.config);\n }\n // Guard again: component may have been destroyed while the fetch was in flight.\n if (!this.ui) return;\n this.ui.panel.showLogin(this.ssoProviders);\n }\n\n /**\n * Opens a popup window for Google or Microsoft OAuth.\n * Listens for a postMessage with type \"unnoodle-oauth-token\" from the popup,\n * stores the JWT, and loads the glossary (or runs any pending write-gate action).\n */\n private handleSsoLogin(provider: \"google\" | \"microsoft\"): void {\n if (!this.ui) return;\n\n const baseUrl =\n this.config.baseUrl?.replace(/\\/$/, \"\") ?? \"https://api.unnoodle.com\";\n const popupUrl = `${baseUrl}/api/auth/oauth/${provider}?widget=true`;\n\n const popup = window.open(\n popupUrl,\n \"unnoodle-sso\",\n \"width=500,height=650,scrollbars=yes,resizable=yes\",\n );\n\n // Remove any stale SSO listener from a previous attempt\n this.ssoPopupCleanup?.();\n this.ssoPopupCleanup = null;\n\n const cleanup = () => {\n clearInterval(closedPoll);\n window.removeEventListener(\"message\", onMessage);\n this.ssoPopupCleanup = null;\n };\n\n const onMessage = (event: MessageEvent) => {\n // Validate that the message originates from the configured API server\n try {\n const expectedOrigin = new URL(baseUrl).origin;\n if (event.origin !== expectedOrigin) return;\n } catch {\n // Malformed baseUrl — skip origin check (dev fallback)\n }\n\n if (\n !event.data ||\n typeof event.data !== \"object\" ||\n (event.data as Record<string, unknown>).type !==\n \"unnoodle-oauth-token\" ||\n typeof (event.data as Record<string, unknown>).token !== \"string\"\n ) {\n return;\n }\n\n cleanup();\n\n const token = (event.data as Record<string, string>).token;\n if (!token) return; // Safety check\n\n this.authToken = token;\n try {\n sessionStorage.setItem(this.sessionKey, token);\n } catch {\n /* ignore */\n }\n this.scheduleTokenExpiry(token);\n popup?.close();\n\n // Execute pending write-gate action if one was set, otherwise load terms\n if (this.pendingAction) {\n const action = this.pendingAction;\n this.pendingAction = null;\n action();\n } else {\n void this.fetchTerms(token);\n }\n };\n\n // Poll so we can clean up if the user closes the popup without completing\n const closedPoll = setInterval(() => {\n if (popup?.closed) cleanup();\n }, 500);\n\n this.ssoPopupCleanup = cleanup;\n window.addEventListener(\"message\", onMessage);\n }\n\n /**\n * Loads terms using the API key alone — no user login required.\n * If a JWT is present in sessionStorage it is forwarded so the server can\n * personalise results, but the read succeeds regardless.\n * Uses the cached response on subsequent opens to avoid redundant network calls.\n */\n private loadTerms(): void {\n if (this.cachedResponse) {\n this.ui?.panel.showTerms(this.cachedResponse);\n this.captureModeController?.setHomeData(this.cachedResponse);\n this.highlighter?.apply(this.cachedResponse.glossary);\n this.showSuggestions(this.cachedResponse.glossary);\n\n // Load clarifications: ALWAYS check main response cache first (like concepts)\n if (this.cachedResponse.clarifications !== undefined) {\n console.log(\n \"[DEBUG] Loading clarifications from main response cache\",\n this.cachedResponse.clarifications.length,\n );\n this.cachedDiscussions = this.cachedResponse.clarifications;\n this.ui?.panel.loadClarifications(\n this.cachedResponse.clarifications,\n !!this.resolveToken(),\n );\n } else if (this.cachedDiscussions) {\n this.ui?.panel.loadClarifications(\n this.cachedDiscussions,\n !!this.resolveToken(),\n );\n } else {\n void this.fetchDiscussions(this.cachedResponse.context.id);\n }\n\n // Load product memories: ALWAYS check main response cache first (like concepts)\n if (this.cachedResponse.productMemories !== undefined) {\n console.log(\n \"[DEBUG] Loading memories from main response cache\",\n this.cachedResponse.productMemories.length,\n );\n this.cachedHomeMemories = this.cachedResponse.productMemories;\n this.ui?.panel.showHomeMemoryItems(this.cachedResponse.productMemories);\n } else if (this.cachedHomeMemories) {\n console.log(\n \"[DEBUG] Using cached home memories from separate cache\",\n this.cachedHomeMemories.length,\n );\n this.ui?.panel.showHomeMemoryItems(this.cachedHomeMemories);\n } else {\n // Fallback: fetch product memories separately (same as initial load)\n void this.loadHomeMemoryItems();\n }\n return;\n }\n // Pass token if available (personalisation), but null is fine for reads.\n this.fetchTerms(this.resolveToken());\n }\n\n private async handleLogin(email: string, password: string): Promise<void> {\n if (!this.ui) return;\n this.ui.panel.setLoginLoading(true);\n\n try {\n const auth = await loginUser(this.config, { email, password });\n this.authToken = auth.token;\n try {\n sessionStorage.setItem(this.sessionKey, auth.token);\n } catch {\n /* ignore */\n }\n this.scheduleTokenExpiry(auth.token);\n\n // Execute any pending write-gate action (e.g., show comment form or edit form)\n if (this.pendingAction) {\n const action = this.pendingAction;\n this.pendingAction = null;\n action();\n } else {\n await this.fetchTerms(auth.token);\n }\n } catch (err) {\n const message =\n err instanceof ApiError && err.status === 401\n ? \"Invalid email or password.\"\n : \"Login failed. Please try again.\";\n this.ui.panel.setLoginError(message);\n } finally {\n this.ui?.panel.setLoginLoading(false);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Phase 2: Term detail, comment, edit\n // ---------------------------------------------------------------------------\n\n private async handleTermClick(term: GlossaryTerm): Promise<void> {\n if (!this.ui) return;\n this.currentTerm = term;\n const token = this.resolveToken();\n\n this.ui.panel.setLoading();\n try {\n const discussions = await getDiscussions(\n this.config,\n term.id,\n token ?? undefined,\n );\n if (this.ui) {\n // Always show Edit button — login gate fires when clicked if no token\n this.ui.panel.showTermDetail(term, discussions, { showEdit: true });\n }\n } catch {\n // Show detail without discussions on error\n if (this.ui) {\n this.ui.panel.showTermDetail(term, [], { showEdit: true });\n }\n }\n }\n\n private handleBack(): void {\n if (!this.ui || !this.cachedResponse) return;\n this.currentTerm = null;\n this.pendingAction = null;\n this.ui.panel.showTerms(this.cachedResponse);\n this.captureModeController?.setHomeData(this.cachedResponse);\n\n // Reload clarifications: ALWAYS check main response cache first (like concepts)\n if (this.cachedResponse.clarifications !== undefined) {\n this.cachedDiscussions = this.cachedResponse.clarifications;\n this.ui.panel.loadClarifications(\n this.cachedResponse.clarifications,\n !!this.resolveToken(),\n );\n } else if (this.cachedDiscussions) {\n this.ui.panel.loadClarifications(\n this.cachedDiscussions,\n !!this.resolveToken(),\n );\n }\n\n // Reload product memories: ALWAYS check main response cache first (like concepts)\n if (this.cachedResponse.productMemories !== undefined) {\n this.cachedHomeMemories = this.cachedResponse.productMemories;\n this.ui.panel.showHomeMemoryItems(this.cachedResponse.productMemories);\n } else if (this.cachedHomeMemories) {\n this.ui.panel.showHomeMemoryItems(this.cachedHomeMemories);\n } else {\n // Fallback: fetch product memories separately (same as initial load)\n void this.loadHomeMemoryItems();\n }\n }\n\n private handleAddComment(termId: number, body: string): void {\n if (!this.ui) return;\n\n if (!body) {\n // \"Show comment form\" request from the Add Comment button\n const token = this.resolveToken();\n if (!token) {\n // Write gate: login required\n this.pendingAction = () => this.ui?.panel.showCommentForm(termId);\n void this.showLoginWithProviders();\n } else {\n this.ui.panel.showCommentForm(termId);\n }\n } else {\n // Actual submission — post the comment (fire-and-forget for now)\n void this.submitComment(termId, body);\n }\n }\n\n private handleRequestEdit(termId: number): void {\n if (!this.ui) return;\n const term =\n this.currentTerm ??\n this.cachedResponse?.glossary.find((t) => t.id === termId) ??\n null;\n if (!term) return;\n\n const token = this.resolveToken();\n if (!token) {\n this.pendingAction = () => this.ui?.panel.showEditForm(term);\n void this.showLoginWithProviders();\n } else {\n this.ui.panel.showEditForm(term);\n }\n }\n\n private handleEditTerm(\n termId: number,\n updates: GlossaryTermUpdateRequest,\n ): void {\n // Fire-and-forget edit submission\n void this.submitEdit(termId, updates);\n }\n\n private async submitComment(termId: number, body: string): Promise<void> {\n const token = this.resolveToken();\n if (!token || !this.ui) return;\n this.ui.panel.setCommentLoading(true);\n try {\n await postComment(this.config, termId, body, token);\n // Reload discussions after posting\n const discussions = await getDiscussions(this.config, termId, token);\n if (this.ui && this.currentTerm) {\n this.ui.panel.showTermDetail(this.currentTerm, discussions, {\n showEdit: true,\n });\n }\n } catch (err) {\n const message =\n err instanceof ApiError\n ? err.message\n : \"Failed to post comment. Please try again.\";\n this.ui?.panel.setCommentError(message);\n } finally {\n this.ui?.panel.setCommentLoading(false);\n }\n }\n\n private async submitEdit(\n termId: number,\n updates: GlossaryTermUpdateRequest,\n ): Promise<void> {\n const token = this.resolveToken();\n if (!token || !this.ui) return;\n this.ui.panel.setEditLoading(true);\n try {\n await updateTerm(this.config, termId, updates, token);\n // Invalidate cache and reload\n this.cachedResponse = null;\n this.fuseIndex = null;\n await this.fetchTerms(token);\n } catch (err) {\n const message =\n err instanceof ApiError\n ? err.message\n : \"Failed to update term. Please try again.\";\n this.ui?.panel.setEditError(message);\n } finally {\n this.ui?.panel.setEditLoading(false);\n }\n }\n\n private async fetchTerms(token: string | null): Promise<void> {\n if (this.isFetching || !this.ui) return;\n this.isFetching = true;\n this.setProgress(true);\n this.ui.panel.setLoading();\n\n try {\n const response = await initWidget(this.config, token);\n this.cachedResponse = response;\n this.highlighter?.apply(response.glossary);\n\n // Notify plugins\n if (this.config._plugins) {\n for (const plugin of this.config._plugins) {\n try {\n plugin.onResponse?.(response);\n } catch {\n /* fail silently per plugin */\n }\n }\n }\n\n if (this.ui) {\n this.ui.panel.showTerms(response);\n this.captureModeController?.setHomeData(response);\n this.showSuggestions(response.glossary);\n // Signal authenticated state so action bar is shown for logged-in users\n this.ui.panel.setAuthenticated(!!this.resolveToken());\n\n // Load clarifications: use included data if available, otherwise fetch separately\n if (response.clarifications !== undefined) {\n // Use included clarifications from init response (apply 5-item limit)\n const limitedClarifications = response.clarifications.slice(0, 5);\n this.cachedDiscussions = limitedClarifications;\n // Ensure clarifications are in main response cache\n this.cachedResponse.clarifications = limitedClarifications;\n this.ui.panel.loadClarifications(\n limitedClarifications,\n !!this.resolveToken(),\n );\n } else {\n // Fallback: fetch context discussions separately for backward compatibility\n void this.fetchDiscussions(response.context.id);\n }\n\n // Load product memories: use included data if available, otherwise fetch separately\n if (response.productMemories !== undefined) {\n // Use included product memories from init response (apply 5-item limit)\n const limitedMemories = response.productMemories.slice(0, 5);\n this.cachedHomeMemories = limitedMemories;\n // Ensure memories are in main response cache\n this.cachedResponse.productMemories = limitedMemories;\n this.ui.panel.showHomeMemoryItems(limitedMemories);\n } else {\n // Fallback: fetch product memories separately for backward compatibility\n void this.loadHomeMemoryItems();\n }\n }\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n\n if (this.config._plugins) {\n for (const plugin of this.config._plugins) {\n try {\n plugin.onError?.(error);\n } catch {\n /* fail silently per plugin */\n }\n }\n }\n\n if (this.ui) {\n this.ui.panel.setError(\n \"Could not load terms. Please check your connection and try again.\",\n );\n }\n } finally {\n this.isFetching = false;\n this.setProgress(false);\n }\n }\n\n /**\n * Fetches context-level clarifications and pushes them to the panel.\n * Errors are swallowed so they don't affect the main glossary view.\n * Applies 5-item limit for consistency with unified init response.\n */\n private async fetchDiscussions(contextId: number): Promise<void> {\n if (!this.ui) return;\n try {\n const discussions = await fetchContextDiscussions(\n this.config,\n contextId,\n this.resolveToken(),\n );\n // Apply 5-item limit for consistency\n const limitedDiscussions = discussions.slice(0, 5);\n\n // Store in both separate cache AND main response cache for reliability\n this.cachedDiscussions = limitedDiscussions;\n if (this.cachedResponse) {\n this.cachedResponse.clarifications = limitedDiscussions;\n }\n\n this.ui.panel.loadClarifications(\n limitedDiscussions,\n !!this.resolveToken(),\n );\n } catch (err) {\n // Non-fatal: show empty state rather than leaving skeleton forever\n if (this.ui) {\n this.ui.panel.loadClarifications([], !!this.resolveToken());\n }\n }\n }\n\n /**\n * Posts a new clarification question and refreshes the Clarifications section.\n */\n private async handleCreateTerm(\n term: string,\n definition: string,\n ): Promise<void> {\n const token = this.resolveToken();\n if (!token || !this.ui || !this.cachedResponse) return;\n try {\n await createGlossaryTerm(\n this.config,\n this.cachedResponse.context.id,\n term,\n definition,\n token,\n );\n // Re-fetch so the new term appears in the list\n await this.fetchTerms(token);\n } catch (err) {\n const message =\n err instanceof ApiError\n ? err.message\n : \"Failed to add term. Please try again.\";\n this.ui.panel.showToast(message);\n }\n }\n\n private async handleAskQuestion(\n contextId: number,\n questionBody: string,\n ): Promise<void> {\n const token = this.resolveToken();\n if (!token || !this.ui) return;\n try {\n await postContextDiscussion(this.config, contextId, questionBody, token);\n // Re-fetch the full thread so replies are included\n await this.fetchDiscussions(contextId);\n } catch (err) {\n const message =\n err instanceof ApiError\n ? err.message\n : \"Failed to post question. Please try again.\";\n this.ui.panel.showToast(message);\n }\n }\n\n private handleClarificationClick(discussion: ContextDiscussion): void {\n if (!this.ui) return;\n this.currentDiscussion = discussion;\n const canReply = !!this.resolveToken();\n this.ui.panel.showClarificationDetail(discussion, canReply);\n }\n\n private async handlePostReply(\n contextId: number,\n questionId: number,\n body: string,\n ): Promise<void> {\n const token = this.resolveToken();\n if (!token || !this.ui) return;\n try {\n await postContextReply(this.config, contextId, questionId, body, token);\n // Re-fetch the full discussion thread to get updated replies\n const discussions = await fetchContextDiscussions(\n this.config,\n contextId,\n token,\n );\n this.cachedDiscussions = discussions;\n const updated = discussions.find((d) => d.id === questionId);\n if (updated) {\n this.currentDiscussion = updated;\n this.ui.panel.showClarificationDetail(updated, true);\n }\n this.ui.panel.loadClarifications(discussions, true);\n } catch (err) {\n const message =\n err instanceof ApiError\n ? err.message\n : \"Failed to post reply. Please try again.\";\n this.ui?.panel.showToast(message);\n }\n }\n\n private async handleSearch(query: string): Promise<void> {\n if (!this.ui || !this.cachedResponse) return;\n\n const trimmed = query.trim();\n\n if (!trimmed) {\n // Empty query — restore full cached list\n this.ui.panel.showTerms(this.cachedResponse);\n this.captureModeController?.setHomeData(this.cachedResponse);\n void this.loadHomeMemoryItems();\n return;\n }\n\n // Client-side fuzzy search via Fuse.js (instant, no network)\n if (!this.fuseIndex) {\n this.fuseIndex = this.buildFuseIndex(this.cachedResponse.glossary);\n }\n const fuseResults = this.fuseIndex.search(trimmed);\n const localResults: GlossaryTerm[] = fuseResults.map(\n (r: FuseResult<GlossaryTerm>) => r.item,\n );\n\n // Show local results instantly\n this.ui.panel.showSearchResults(localResults, trimmed);\n\n // Then do a server-side search for deeper/ranked results\n try {\n const token = this.resolveToken();\n const serverResults = await searchTerms(\n this.config,\n this.cachedResponse.context.id,\n trimmed,\n token,\n );\n // Only update if the search query is still the same (user hasn't typed more)\n if (this.ui) {\n this.ui.panel.showSearchResults(serverResults, trimmed);\n }\n } catch {\n // Already showing local results — server error is not fatal\n }\n }\n\n // ---------------------------------------------------------------------------\n // Phase 3: Suggested terms\n // ---------------------------------------------------------------------------\n\n /** Build a Fuse.js index over a glossary for fuzzy client-side search. */\n private buildFuseIndex(glossary: GlossaryTerm[]): Fuse<GlossaryTerm> {\n return new Fuse(glossary, {\n keys: [\n { name: \"term\", weight: 3 },\n { name: \"abbreviation\", weight: 2 },\n { name: \"definition\", weight: 1 },\n ],\n threshold: 0.35, // 0 = exact match, 1 = match anything\n includeScore: true,\n ignoreLocation: true,\n minMatchCharLength: 2,\n });\n }\n\n /**\n * Scans the host page for candidate terms and shows them below the glossary\n * list if at least one is found.\n */\n private showSuggestions(glossary: GlossaryTerm[]): void {\n if (!this.ui || !this.suggester) return;\n const suggestions = this.suggester.scan(glossary);\n if (suggestions.length === 0) return;\n this.ui.panel.showSuggestedTerms(suggestions, (termName) =>\n this.handleAddSuggestion(termName),\n );\n }\n\n /**\n * Called when the user clicks \"+ Add\" on a suggested term.\n * Login-gated: if no token, shows the login form and sets a pending action.\n * If token present: calls AI generate endpoint, then opens review modal.\n */\n private handleAddSuggestion(termName: string): void {\n if (!this.ui) return;\n this.activeSuggestion = termName;\n\n const token = this.resolveToken();\n if (!token) {\n this.pendingAction = () => this.openAiGenerateFlow(termName);\n void this.showLoginWithProviders();\n return;\n }\n void this.openAiGenerateFlow(termName);\n }\n\n private async openAiGenerateFlow(termName: string): Promise<void> {\n if (!this.ui) return;\n const token = this.resolveToken();\n if (!token) return;\n\n const pageContext = this.suggester?.getPageContext(termName) ?? \"\";\n const pageUrl = typeof window !== \"undefined\" ? window.location.href : \"\";\n\n this.ui.panel.setAiModalLoading(false); // reset if re-used\n\n try {\n const definition = await generateAiDefinition(\n this.config,\n termName,\n pageContext,\n pageUrl,\n token,\n );\n\n this.ui?.panel.showAiModal(\n termName,\n definition,\n (edited) => void this.submitSuggestedTerm(termName, edited),\n () => {\n // Cancel → return to terms list\n if (this.cachedResponse && this.ui) {\n this.ui.panel.showTerms(this.cachedResponse);\n this.captureModeController?.setHomeData(this.cachedResponse);\n this.showSuggestions(this.cachedResponse.glossary);\n void this.loadHomeMemoryItems();\n }\n },\n );\n } catch {\n // AI generate failed — fall back to empty definition modal\n this.ui?.panel.showAiModal(\n termName,\n \"\",\n (edited) => void this.submitSuggestedTerm(termName, edited),\n () => {\n if (this.cachedResponse && this.ui) {\n this.ui.panel.showTerms(this.cachedResponse);\n this.captureModeController?.setHomeData(this.cachedResponse);\n this.showSuggestions(this.cachedResponse.glossary);\n void this.loadHomeMemoryItems();\n }\n },\n );\n }\n }\n\n // ---------------------------------------------------------------------------\n // Product Memories\n // ---------------------------------------------------------------------------\n\n private async loadMemories(page: number, append = false): Promise<void> {\n if (!this.ui) return;\n const token = this.resolveToken();\n\n try {\n const pageResp = await listProductMemories(this.config, page, token);\n if (!append) this.memories = [];\n this.memories = [...this.memories, ...pageResp.content];\n this.memoriesPage = pageResp.number;\n this.hasMoreMemories = !pageResp.last;\n this.ui.panel.showMemoriesList(\n pageResp.content,\n pageResp.number,\n !pageResp.last,\n append,\n );\n } catch (err) {\n const message =\n err instanceof ApiError\n ? err.message\n : \"Could not load Product Memories.\";\n this.ui.panel.showToast(message);\n }\n }\n\n /**\n * Loads all product memories for the list view.\n */\n private async loadAllMemories(): Promise<void> {\n if (!this.ui) return;\n const token = this.resolveToken();\n\n try {\n // Load first page to get all memories for list view (20 per page is the API default)\n // For list view, first page should be sufficient for most use cases\n const pageResp = await listProductMemories(this.config, 0, token);\n this.ui?.panel.showAllMemories(pageResp.content, !!token);\n } catch (err) {\n console.error(\"[unnoodle] loadAllMemories failed:\", err);\n this.ui?.panel.showAllMemories([], false);\n }\n }\n\n /**\n * Loads product memories for the home page. Applies 5-item limit for consistency.\n * Fallback when product memories are not included in init response.\n */\n private async loadHomeMemoryItems(): Promise<void> {\n if (!this.ui) return;\n const token = this.resolveToken();\n\n try {\n const pageResp = await listProductMemories(this.config, 0, token);\n // Apply 5-item limit for consistency with unified init response\n const limitedMemories = pageResp.content.slice(0, 5);\n\n // Store in both separate cache AND main response cache for reliability\n this.cachedHomeMemories = limitedMemories;\n if (this.cachedResponse) {\n this.cachedResponse.productMemories = limitedMemories;\n }\n\n this.ui?.panel.showHomeMemoryItems(limitedMemories);\n } catch (err) {\n console.error(\"loadHomeMemoryItems failed:\", err);\n this.ui?.panel.showHomeMemoryItems([]);\n }\n }\n\n private async handleViewMemoryDetail(id: number): Promise<void> {\n if (!this.ui) return;\n const token = this.resolveToken();\n\n try {\n const memory = await getProductMemory(this.config, id, token);\n this.currentMemory = memory;\n this.ui.panel.showMemoryDetail(memory);\n } catch {\n this.ui.panel.showToast(\"Could not load memory details.\");\n }\n }\n\n private async handleUpdateEntryExplanation(\n memoryId: number,\n entryId: number,\n explanation: string,\n ): Promise<void> {\n if (!this.ui) return;\n const token = this.resolveToken();\n if (!token) return;\n\n try {\n const updated = await updateProductMemoryEntry(\n this.config,\n memoryId,\n entryId,\n { explanation },\n token,\n );\n this.currentMemory = updated;\n this.ui.panel.showMemoryDetail(updated);\n this.ui.panel.showToast(\"Explanation saved ✓\");\n } catch {\n this.ui.panel.showToast(\"Could not save explanation.\");\n }\n }\n\n /**\n * Show the \"add entry\" form for the currently viewed memory.\n * Uses the same CaptureModeController as new memories, but in \"add-entry\" mode.\n */\n private handleAddEntryToMemory(memoryId: number): void {\n if (!this.ui || !this.currentMemory) return;\n const token = this.resolveToken();\n if (!token) {\n void this.showLoginWithProviders();\n return;\n }\n const addController = createCaptureModeController(\n this.ui.panel,\n this.config,\n () => this.resolveToken(),\n () => this.cachedResponse?.glossary ?? [],\n // On save: navigate back to updated detail view\n () => void this.handleViewMemoryDetail(memoryId),\n new AddEntryOrchestrator(memoryId),\n { type: \"add-entry\", memoryTitle: this.currentMemory.title },\n );\n addController.start();\n }\n\n /**\n * Delete a product memory and navigate back to the memories list.\n */\n private async handleDeleteMemory(memoryId: number): Promise<void> {\n if (!this.ui) return;\n const token = this.resolveToken();\n if (!token) return;\n\n try {\n await deleteProductMemory(this.config, memoryId, token);\n this.ui.panel.showToast(\"Memory deleted ✓\");\n // Navigate back to memories list\n await this.loadMemories(0, false);\n } catch {\n this.ui.panel.showToast(\"Could not delete memory.\");\n }\n }\n\n /**\n * Delete an entry from a product memory and reload the detail view.\n */\n private async handleDeleteEntry(\n memoryId: number,\n entryId: number,\n ): Promise<void> {\n if (!this.ui) return;\n const token = this.resolveToken();\n if (!token) return;\n\n try {\n const updated = await deleteProductMemoryEntry(\n this.config,\n memoryId,\n entryId,\n token,\n );\n this.currentMemory = updated;\n this.ui.panel.showMemoryDetail(updated);\n this.ui.panel.showToast(\"Entry deleted ✓\");\n } catch {\n this.ui.panel.showToast(\"Could not delete entry.\");\n }\n }\n\n private async submitSuggestedTerm(\n termName: string,\n definition: string,\n ): Promise<void> {\n if (!this.ui || !this.cachedResponse) return;\n const token = this.resolveToken();\n if (!token) return;\n\n this.ui.panel.setAiModalLoading(true);\n try {\n await createSuggestedTerm(\n this.config,\n this.cachedResponse.context.id,\n termName,\n definition,\n token,\n );\n\n // Close modal, show toast, re-render terms\n this.ui.panel.showTerms(this.cachedResponse);\n this.captureModeController?.setHomeData(this.cachedResponse);\n this.showSuggestions(this.cachedResponse.glossary);\n void this.loadHomeMemoryItems();\n this.ui.panel.showToast(\"Term submitted for approval\");\n this.activeSuggestion = null;\n } catch (err) {\n this.ui.panel.setAiModalLoading(false);\n const message =\n err instanceof ApiError\n ? err.message\n : \"Failed to submit term. Please try again.\";\n // Re-show modal with error — simplest approach: just log for now\n void message; // consumed by crash-safe no-op for now\n }\n }\n}\n","/**\n * StateWatcher\n *\n * Single responsibility:\n * Observe a captured DOM element for meaningful state changes and report\n * them via a callback — enabling automatic new-state detection in the UI\n * memory timeline.\n *\n * Behaviour:\n * - watch(el, onStateChange): attaches a MutationObserver that listens for\n * text, attribute, and structural changes on the element and its subtree.\n * - Changes are debounced for 500ms so rapid successive mutations (e.g.\n * CSS class toggling during an animation) produce a single diff.\n * - Noise filter: style attribute mutations are ignored (too noisy).\n * - unwatch(): disconnects the observer and cancels pending callbacks.\n *\n * Change classification (StateDiff.type):\n * - \"text\" — visible text content changed (textContent assignment\n * fires a childList mutation with only text nodes, or a\n * characterData mutation on a text node directly).\n * - \"attribute\" — a non-style attribute changed (class, disabled,\n * aria-*, data-*, etc.).\n * - \"structure\" — child elements were added or removed.\n *\n * Design principles:\n * - No DOM mutation — observer only.\n * - No coupling to panel, API, or captureOrchestrator.\n * - before/after are always strings (attribute values, textContent, or\n * serialised child counts for structural diffs).\n */\n\n// ---------------------------------------------------------------------------\n// Public contracts\n// ---------------------------------------------------------------------------\n\nexport interface StateDiff {\n /** Category of the detected change. */\n type: \"text\" | \"attribute\" | \"structure\";\n /** Name of the changed attribute — only set when type === \"attribute\". */\n attribute?: string;\n /** State before the change. */\n before: string;\n /** State after the change. */\n after: string;\n}\n\nexport interface IStateWatcher {\n /**\n * Begin watching `el` for meaningful mutations.\n * Calls `onStateChange` (debounced 500ms) when a diff is detected.\n * Replaces any previous watch.\n */\n watch(el: Element, onStateChange: (diff: StateDiff) => void): void;\n /**\n * Stop watching. Cancels any pending debounced callback.\n * Safe to call when no watch is active.\n */\n unwatch(): void;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/** Lightweight snapshot of the element state taken at watch() / after each flush. */\ninterface ElementState {\n textContent: string;\n innerHTML: string;\n}\n\nfunction captureState(el: Element): ElementState {\n return {\n textContent: el.textContent ?? \"\",\n innerHTML: el.innerHTML,\n };\n}\n\nexport class StateWatcher implements IStateWatcher {\n private observer: MutationObserver | null = null;\n private timerId: ReturnType<typeof setTimeout> | null = null;\n private pendingMutations: MutationRecord[] = [];\n private watchedEl: Element | null = null;\n private callback: ((diff: StateDiff) => void) | null = null;\n /** Snapshot of watched element state at the start of the current quiet window. */\n private preBatchState: ElementState | null = null;\n\n watch(el: Element, onStateChange: (diff: StateDiff) => void): void {\n this.unwatch();\n this.watchedEl = el;\n this.callback = onStateChange;\n this.preBatchState = captureState(el);\n\n this.observer = new MutationObserver((mutations) => {\n for (const m of mutations) {\n this.pendingMutations.push(m);\n }\n this.scheduleFlush();\n });\n\n this.observer.observe(el, {\n childList: true,\n subtree: true,\n characterData: true,\n characterDataOldValue: true,\n attributes: true,\n attributeOldValue: true,\n });\n }\n\n unwatch(): void {\n if (this.timerId !== null) {\n clearTimeout(this.timerId);\n this.timerId = null;\n }\n this.observer?.disconnect();\n this.observer = null;\n this.pendingMutations = [];\n this.preBatchState = null;\n this.watchedEl = null;\n this.callback = null;\n }\n\n // ── Private ───────────────────────────────────────────────────────────────\n\n private scheduleFlush(): void {\n if (this.timerId !== null) clearTimeout(this.timerId);\n this.timerId = setTimeout(() => this.flush(), 500);\n }\n\n private flush(): void {\n this.timerId = null;\n\n const mutations = [...this.pendingMutations];\n this.pendingMutations = [];\n\n if (!this.watchedEl || !this.callback || !this.preBatchState) return;\n\n const diff = this.computeDiff(\n mutations,\n this.preBatchState,\n this.watchedEl,\n );\n\n if (diff) {\n this.preBatchState = captureState(this.watchedEl);\n this.callback(diff);\n } else {\n // No meaningful change — update pre-batch snapshot so we stay fresh\n this.preBatchState = captureState(this.watchedEl);\n }\n }\n\n private computeDiff(\n mutations: MutationRecord[],\n before: ElementState,\n el: Element,\n ): StateDiff | null {\n // Filter out style-only noise\n const meaningful = mutations.filter(\n (m) => !(m.type === \"attributes\" && m.attributeName === \"style\"),\n );\n\n if (meaningful.length === 0) return null;\n\n // Priority: attribute > characterData > childList\n const attrMutation = meaningful.find((m) => m.type === \"attributes\");\n if (attrMutation) {\n const attr = attrMutation.attributeName!;\n return {\n type: \"attribute\",\n attribute: attr,\n before: attrMutation.oldValue ?? \"\",\n after: el.getAttribute(attr) ?? \"\",\n };\n }\n\n const charMutation = meaningful.find((m) => m.type === \"characterData\");\n if (charMutation) {\n return {\n type: \"text\",\n before: charMutation.oldValue ?? \"\",\n after: (charMutation.target as CharacterData).data,\n };\n }\n\n // childList mutations — distinguish text-only from structural\n const childMutations = meaningful.filter((m) => m.type === \"childList\");\n if (childMutations.length > 0) {\n const allNodes: Node[] = [];\n for (const m of childMutations) {\n for (const n of Array.from(m.addedNodes)) allNodes.push(n);\n for (const n of Array.from(m.removedNodes)) allNodes.push(n);\n }\n\n const isTextOnly = allNodes.every((n) => n.nodeType === Node.TEXT_NODE);\n\n if (isTextOnly) {\n return {\n type: \"text\",\n before: before.textContent,\n after: el.textContent ?? \"\",\n };\n }\n\n return {\n type: \"structure\",\n before: before.innerHTML,\n after: el.innerHTML,\n };\n }\n\n return null;\n }\n}\n","/**\n * meaningInference\n *\n * Single responsibility:\n * Given a StateDiff and the current live element, produce a concise\n * human-readable string suggesting what UI state the change represents.\n * Returns null when no confident semantic meaning can be inferred.\n *\n * Rule-based approach (no ML, fully deterministic):\n *\n * Text changes — keyword scan of diff.after:\n * loading/spinner/submitting/saving → \"Loading state\"\n * error/failed/invalid/try again → \"Error state\"\n * success/saved/complete/done → \"Success state\"\n *\n * Attribute changes on \"class\":\n * Newly added class keyword scan (diff.after classes minus diff.before classes):\n * loading/spinner/pending → \"Loading state\"\n * disabled/inactive → \"Disabled state\"\n * error/invalid/danger → \"Error state\"\n * success/valid/done → \"Success state\"\n * active/selected/open → \"Active state\"\n * collapsed/closed/hidden → \"Collapsed state\"\n *\n * The \"disabled\" attribute:\n * Attribute present after change → \"Disabled state\"\n * Attribute absent after change → \"Enabled state\"\n *\n * ARIA attributes:\n * aria-expanded = \"true\" → \"Expanded state\"\n * aria-expanded = \"false\" → \"Collapsed state\"\n * aria-selected = \"true\" → \"Selected state\"\n * aria-busy = \"true\" → \"Loading state\"\n * aria-label changed → \"Label changed to: <value>\"\n *\n * Structure changes → null (caller decides context).\n *\n * Design principles:\n * - Pure function — no side effects, no DOM mutation.\n * - Returns null rather than guessing.\n * - Deterministic output for testability.\n */\n\nimport type { StateDiff } from \"./stateWatcher\";\n\n// ---------------------------------------------------------------------------\n// Keyword maps\n// ---------------------------------------------------------------------------\n\nconst TEXT_LOADING_RE = /\\b(loading|spinner|submitting|saving|please wait)\\b/i;\nconst TEXT_ERROR_RE =\n /\\b(error|failed|invalid|failure|try again|went wrong)\\b/i;\nconst TEXT_SUCCESS_RE = /\\b(success|saved|complete|done|submitted|finished)\\b/i;\n\nconst CLASS_RULES: Array<[RegExp, string]> = [\n [/\\b(loading|spinner|pending|busy)\\b/, \"Loading state\"],\n [/\\b(disabled|inactive|unavailable)\\b/, \"Disabled state\"],\n [/\\b(error|invalid|danger|fail)\\b/, \"Error state\"],\n [/\\b(success|valid|done|complete)\\b/, \"Success state\"],\n [/\\b(active|selected|open|checked|focused)\\b/, \"Active state\"],\n [/\\b(collapsed|closed|hidden)\\b/, \"Collapsed state\"],\n];\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction classSet(cls: string): Set<string> {\n return new Set(cls.split(/\\s+/).filter(Boolean));\n}\n\n/** Returns the classes present in `after` that were NOT in `before`. */\nfunction addedClasses(before: string, after: string): string {\n const beforeSet = classSet(before);\n return [...classSet(after)].filter((c) => !beforeSet.has(c)).join(\" \");\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Infer a human-readable state meaning from a StateDiff.\n *\n * @param diff The state change detected by StateWatcher.\n * @param el The live element after the change (used for attribute reads).\n * @returns A short description, or null if no meaning can be inferred.\n */\nexport function inferMeaning(diff: StateDiff, el: Element): string | null {\n // ── Text changes ──────────────────────────────────────────────────────────\n if (diff.type === \"text\") {\n const text = diff.after;\n if (TEXT_LOADING_RE.test(text)) return \"Loading state\";\n if (TEXT_ERROR_RE.test(text)) return \"Error state\";\n if (TEXT_SUCCESS_RE.test(text)) return \"Success state\";\n return null;\n }\n\n // ── Attribute changes ─────────────────────────────────────────────────────\n if (diff.type === \"attribute\") {\n const { attribute, after } = diff;\n\n // class — find newly added semantic classes\n if (attribute === \"class\") {\n const newClasses = addedClasses(diff.before, after);\n if (newClasses) {\n for (const [pattern, label] of CLASS_RULES) {\n if (pattern.test(newClasses)) return label;\n }\n }\n return null;\n }\n\n // disabled boolean attribute\n if (attribute === \"disabled\") {\n return el.hasAttribute(\"disabled\") ? \"Disabled state\" : \"Enabled state\";\n }\n\n // ARIA attributes\n if (attribute === \"aria-expanded\") {\n return after === \"true\" ? \"Expanded state\" : \"Collapsed state\";\n }\n if (attribute === \"aria-selected\") {\n return after === \"true\" ? \"Selected state\" : null;\n }\n if (attribute === \"aria-busy\") {\n return after === \"true\" ? \"Loading state\" : null;\n }\n if (attribute === \"aria-label\") {\n const trimmed = after.trim();\n return trimmed ? `Label changed to: ${trimmed}` : null;\n }\n\n return null;\n }\n\n // ── Structure changes — no semantic inference ─────────────────────────────\n return null;\n}\n","/**\n * LiveRenderer\n *\n * Single responsibility:\n * Highlight the DOM element that corresponds to a captured ProductMemory\n * entry — giving the viewer a live \"this is the element\" pointer.\n *\n * Behaviour:\n * - show(el): scrolls the element into view then draws a read-only highlight\n * ring (position:fixed) over the element's bounding rect.\n * - hide(): removes the ring from the DOM.\n * - Calling hide() before show() is safe (no-op).\n * - Calling show() a second time replaces the previous ring.\n *\n * Design principles:\n * - No click handlers — read-only visual indicator only.\n * - No coupling to panel, API, or state machine.\n * - Reuses the same visual language as ElementPicker (dashed Unnoodle violet\n * ring) but with a solid fill to distinguish \"live\" from \"pick\" mode.\n */\n\n// ---------------------------------------------------------------------------\n// Public contracts\n// ---------------------------------------------------------------------------\n\nexport interface ILiveRenderer {\n /** Scroll the element into view and draw the live highlight ring. */\n show(el: Element): void;\n /** Remove the highlight ring. Safe to call when ring is not shown. */\n hide(): void;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst LIVE_RING_ID = \"unnoodle-live-ring\";\n\nconst RING_CSS = `\n position: fixed;\n pointer-events: none;\n z-index: 2147483645;\n border: 2px solid #5C4EFA;\n border-radius: 4px;\n background: rgba(92, 78, 250, 0.10);\n box-shadow: 0 0 0 1px rgba(92, 78, 250, 0.35), 0 0 8px rgba(92, 78, 250, 0.25);\n`;\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\nexport class LiveRenderer implements ILiveRenderer {\n private ring: HTMLElement | null = null;\n\n show(el: Element): void {\n // Remove any previous ring first (idempotent)\n this.hide();\n\n // Scroll the element into view so the user can see it\n el.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n\n const rect = el.getBoundingClientRect();\n\n const ring = document.createElement(\"div\");\n ring.id = LIVE_RING_ID;\n ring.setAttribute(\"data-testid\", \"unnoodle-live-ring\");\n ring.style.cssText = RING_CSS;\n ring.style.top = `${rect.top}px`;\n ring.style.left = `${rect.left}px`;\n ring.style.width = `${rect.width}px`;\n ring.style.height = `${rect.height}px`;\n\n document.body.appendChild(ring);\n this.ring = ring;\n }\n\n hide(): void {\n this.ring?.remove();\n this.ring = null;\n }\n}\n","/**\n * MemoryDetailController\n *\n * Single responsibility:\n * After a ProductMemory is loaded, optionally start a StateWatcher on the\n * originally captured DOM element and surface its diffs via an onDiff\n * callback — enabling automatic new-state detection.\n *\n * Behaviour:\n * load(memory, onDiff):\n * 1. Unloads any prior watch.\n * 2. If memory.watchForChanges is false, does nothing more.\n * 3. Checks that the first entry's URL matches the current page URL\n * (origin + pathname only, ignoring query / hash).\n * 4. Uses TargetingEngine.resolve() to find the captured element.\n * 5. Starts StateWatcher.watch(el, onDiff).\n *\n * unload():\n * Stops any active StateWatcher. Safe to call when nothing is watching.\n *\n * Design principles:\n * - No DOM mutation.\n * - All dependencies are injected via interfaces for full testability.\n */\n\nimport type { ProductMemoryDetailResponse } from \"../../types/config\";\nimport type { IStateWatcher, StateDiff } from \"./stateWatcher\";\nimport type { ITargetingEngine, StoredTarget } from \"./targetingEngine\";\n\n// ---------------------------------------------------------------------------\n// Public interface\n// ---------------------------------------------------------------------------\n\nexport interface IMemoryDetailController {\n load(\n memory: ProductMemoryDetailResponse,\n onDiff: (diff: StateDiff) => void,\n ): void;\n unload(): void;\n}\n\n// ---------------------------------------------------------------------------\n// URL matching helper\n// ---------------------------------------------------------------------------\n\n/**\n * Returns true when stored origin+pathname matches the current page URL.\n * Query parameters and hash are intentionally ignored so navigating to\n * /form?step=2 still matches a memory captured at /form.\n */\nfunction urlsMatch(stored: string, current: string): boolean {\n try {\n const s = new URL(stored);\n const c = new URL(current);\n return s.origin === c.origin && s.pathname === c.pathname;\n } catch {\n return stored === current;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\nexport class MemoryDetailController implements IMemoryDetailController {\n constructor(\n private readonly stateWatcher: IStateWatcher,\n private readonly targetingEngine: ITargetingEngine,\n ) {}\n\n load(\n memory: ProductMemoryDetailResponse,\n onDiff: (diff: StateDiff) => void,\n ): void {\n this.unload();\n\n if (!memory.watchForChanges) return;\n\n const firstEntry = memory.entries[0];\n if (!firstEntry) return;\n\n if (!urlsMatch(firstEntry.url, window.location.href)) return;\n\n const meta = firstEntry.targetingMetadata;\n if (!meta) return;\n\n const target: StoredTarget = {\n ...(meta.id !== undefined && { id: meta.id }),\n ...(meta.dataTestId !== undefined && { dataTestId: meta.dataTestId }),\n tag: meta.tag,\n role: meta.role ?? null,\n text: meta.text ?? \"\",\n url: firstEntry.url,\n };\n\n const el = this.targetingEngine.resolve(target);\n if (!el) return;\n\n this.stateWatcher.watch(el, onDiff);\n }\n\n unload(): void {\n this.stateWatcher.unwatch();\n }\n}\n","import type { UnnoodleConfig } from \"./types/config\";\nimport { WidgetController } from \"./widget/widgetController\";\n\nexport type {\n UnnoodleConfig,\n UnnoodlePlugin,\n UnnoodleContext,\n UnnoodleApiResponse,\n UnnoodleAction,\n} from \"./types/config\";\n\n// Product-memory sub-system — publicly exported for SDK consumers and E2E use.\nexport { StateWatcher } from \"./features/memory/stateWatcher\";\nexport type {\n IStateWatcher,\n StateDiff,\n} from \"./features/memory/stateWatcher\";\nexport { inferMeaning } from \"./features/memory/meaningInference\";\nexport { LiveRenderer } from \"./features/memory/liveRenderer\";\nexport type { ILiveRenderer } from \"./features/memory/liveRenderer\";\nexport { MemoryDetailController } from \"./features/memory/memoryDetailController\";\nexport type { IMemoryDetailController } from \"./features/memory/memoryDetailController\";\n\nlet _controller: WidgetController | null = null;\n\n/**\n * Initializes the Unnoodle widget SDK.\n *\n * Call once when your application boots. Safe to call in SSR environments —\n * it will no-op if `document` is not available.\n *\n * @example\n * ```ts\n * import { initUnnoodle } from \"@unnoodle/browser\";\n *\n * initUnnoodle({ apiKey: \"pk_live_abc123\", context: \"engineering\" });\n * ```\n */\nexport function initUnnoodle(config: UnnoodleConfig): void {\n // SSR / non-browser guard\n if (typeof document === \"undefined\") {\n return;\n }\n\n if (!validateConfig(config)) {\n return;\n }\n\n // Destroy any existing instance before reinitializing.\n // Preserve the auth token so that framework lifecycles (e.g. React Strict\n // Mode's simulated unmount+remount) don't inadvertently log the user out.\n if (_controller) {\n const sessionKey = `unnoodle_token_${config.apiKey.slice(-8)}`;\n let savedToken: string | null = null;\n try {\n savedToken = sessionStorage.getItem(sessionKey);\n } catch {\n /* ignore — sessionStorage unavailable */\n }\n _controller.destroy();\n _controller = null;\n if (savedToken) {\n try {\n sessionStorage.setItem(sessionKey, savedToken);\n } catch {\n /* ignore */\n }\n }\n }\n\n _controller = new WidgetController(config);\n _controller.init();\n}\n\n/**\n * Programmatically open the Unnoodle panel.\n * No-op if the SDK has not been initialized.\n */\nexport function openUnnoodle(): void {\n _controller?.open();\n}\n\n/**\n * Programmatically close the Unnoodle panel.\n * No-op if the SDK has not been initialized.\n */\nexport function closeUnnoodle(): void {\n _controller?.close();\n}\n\n/**\n * Tear down the Unnoodle widget and remove all DOM elements and listeners.\n * Useful for single-page apps that need to clean up on route change.\n */\nexport function destroyUnnoodle(): void {\n _controller?.destroy();\n _controller = null;\n}\n\n/**\n * Namespace-style API — preferred for script-tag / CDN usage.\n *\n * @example\n * ```ts\n * import { Unnoodle } from \"@unnoodle/browser\";\n *\n * Unnoodle.init({ apiKey: \"pk_live_abc123\", context: \"engineering\" });\n * ```\n */\nexport const Unnoodle = {\n /** Initialize the Unnoodle widget SDK. Equivalent to `initUnnoodle()`. */\n init: initUnnoodle,\n /** Programmatically open the panel. */\n open: openUnnoodle,\n /** Programmatically close the panel. */\n close: closeUnnoodle,\n /** Tear down the widget and remove all DOM elements. */\n destroy: destroyUnnoodle,\n} as const;\n\nfunction validateConfig(config: UnnoodleConfig): boolean {\n if (!config || typeof config !== \"object\") {\n console.warn(\"[Unnoodle] initUnnoodle() requires a config object.\");\n return false;\n }\n\n if (\n !config.apiKey ||\n typeof config.apiKey !== \"string\" ||\n config.apiKey.trim() === \"\"\n ) {\n console.warn(\n \"[Unnoodle] initUnnoodle() requires a non-empty `apiKey` string (e.g. pk_live_xxx).\",\n );\n return false;\n }\n\n if (\n !config.context ||\n typeof config.context !== \"string\" ||\n config.context.trim() === \"\"\n ) {\n console.warn(\n \"[Unnoodle] initUnnoodle() requires a non-empty `context` string.\",\n );\n return false;\n }\n\n if (\n config.environment &&\n ![\"dev\", \"staging\", \"prod\"].includes(config.environment)\n ) {\n console.warn(\n `[Unnoodle] Invalid environment \"${config.environment}\". Must be \"dev\", \"staging\", or \"prod\". Defaulting to \"prod\".`,\n );\n }\n\n return true;\n}\n"]}
1
+ {"version":3,"sources":["../../../node_modules/.pnpm/fuse.js@7.1.0/node_modules/fuse.js/dist/fuse.mjs","../src/api/http.ts","../src/api/widget.ts","../src/api/auth.ts","../src/api/glossary.ts","../src/api/memories.ts","../src/api/clarifications.ts","../src/api/ask.ts","../src/features/memory/elementSnapshot.ts","../src/features/memory/elementPicker.ts","../src/features/memory/overlayArrow.ts","../src/features/memory/captureOrchestrator.ts","../src/features/memory/captureModeController.ts","../src/ui/safeCSS.ts","../src/ui/button.ts","../src/ui/panel/styles.ts","../src/ui/panel/views/loginView.ts","../src/ui/panel/utils.ts","../src/ui/panel/views/clarificationView.ts","../src/ui/panel/views/captureView.ts","../src/ui/panel/views/askView.ts","../src/ui/captureForm.ts","../src/ui/stateChangeBanner.ts","../src/ui/listViews.ts","../src/ui/panel/panelLayout.ts","../src/ui/panel/views/homeView.ts","../src/ui/panel.ts","../src/ui/rail/railStyles.ts","../src/ui/rail/railIdentity.ts","../src/ui/rail/railCoreActions.ts","../src/ui/rail/railAuth.ts","../src/ui/rail/rail.ts","../src/ui/mount.ts","../src/ui/highlighter.ts","../src/ui/termSuggester.ts","../src/widget/widgetController.ts","../src/features/memory/stateWatcher.ts","../src/features/memory/meaningInference.ts","../src/features/memory/liveRenderer.ts","../src/features/memory/memoryDetailController.ts","../src/index.ts"],"names":["isArray","value","getTag","baseToString","result","INFINITY","toString","isString","isNumber","isBoolean","isObjectLike","isObject","isDefined","isBlank","INCORRECT_INDEX_TYPE","LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY","key","PATTERN_LENGTH_TOO_LARGE","max","MISSING_KEY_PROPERTY","name","INVALID_KEY_WEIGHT_VALUE","hasOwn","KeyStore","keys","totalWeight","obj","createKey","keyId","path","id","src","weight","getFn","createKeyPath","createKeyId","get","list","arr","deepGet","index","i","len","MatchOptions","BasicOptions","a","b","FuzzyOptions","AdvancedOptions","Config","SPACE","norm","mantissa","cache","m","numTokens","n","FuseIndex","fieldNormWeight","docs","records","idx","doc","docIndex","item","record","keyIndex","subRecords","stack","nestedArrIndex","subRecord","k","createIndex","myIndex","parseIndex","data","computeScore$1","pattern","errors","currentLocation","expectedLocation","distance","ignoreLocation","accuracy","proximity","convertMaskToIndices","matchmask","minMatchCharLength","indices","start","end","match","MAX_BITS","search","text","patternAlphabet","location","threshold","findAllMatches","includeMatches","patternLen","textLen","currentThreshold","bestLocation","computeMatches","matchMask","score","lastBitArr","finalScore","binMax","mask","binMin","binMid","finish","bitArr","j","charMatch","createPatternAlphabet","char","stripDiacritics","str","BitapSearch","isCaseSensitive","ignoreDiacritics","addChunk","startIndex","remainder","allIndices","totalScore","hasMatches","alphabet","isMatch","BaseMatch","getMatch","exp","matches","ExactMatch","InverseExactMatch","PrefixExactMatch","InversePrefixExactMatch","SuffixExactMatch","InverseSuffixExactMatch","FuzzyMatch","IncludeMatch","searchers","searchersLen","SPACE_RE","OR_TOKEN","parseQuery","options","query","results","queryItem","found","searcher","token","MultiMatchSet","ExtendedSearch","_","numMatches","qLen","pLen","type","registeredSearchers","register","args","createSearcher","searcherClass","LogicalOperator","KeyType","isExpression","isPath","isLeaf","convertToExplicit","parse","auto","next","isQueryPath","node","computeScore","ignoreFieldNorm","transformMatches","transformScore","format","includeScore","transformers","transformer","Fuse","predicate","limit","shouldSort","sortFn","expression","evaluate","res","child","resultMap","expResults","DEFAULT_BASE_URL","resolvedBaseUrl","config","apiKeyHeaders","safeGetToken","ApiError","message","status","body","initWidget","userToken","url","headers","response","searchTerms","contextId","loginUser","credentials","fetchOAuthProviders","getDiscussions","termId","postComment","bodyText","updateTerm","updates","generateAiDefinition","term","pageContext","pageUrl","err","createSuggestedTerm","definition","createGlossaryTerm","createProductMemory","payload","addProductMemoryEntry","memoryId","updateProductMemoryEntry","entryId","listProductMemories","page","getProductMemory","deleteProductMemory","deleteProductMemoryEntry","fetchContextDiscussions","postContextDiscussion","responseBody","postContextReply","questionId","AskRateLimitedError","retryAfter","AskBusyError","ASK_TIMEOUT_MS","askHeaders","retryAfterSeconds","raw","askQuestion","question","signal","ctrl","timedOut","timer","forwardAbort","getAskStatus","IMPLICIT_ROLES","inferRole","el","explicit","inlineComputedStyles","source","clone","computed","prop","inlineStylesDeep","sourceChildren","cloneChildren","srcChild","clnChild","absolutifyUrls","img","srcset","resolved","part","descriptor","abs","defensiveStrip","s","all","toRemove","attr","snapshotElement","rect","RING_ID","RING_CSS","EXCLUDED_IDS","ElementPicker","callbacks","ring","e","SVG_ID","ARROW_COLOR","MARKER_ID","computePath","from","to","panelIsRight","x1","y1","x2","y2","tension","cx1","cx2","buildSvg","svg","defs","marker","arrowPolygon","OverlayArrow","fromRect","toRect","CaptureOrchestrator","title","explanation","elementSnapshot","watchForChanges","AddEntryOrchestrator","_title","CaptureModeController","panel","picker","arrow","orchestrator","getToken","getGlossary","onSaveComplete","mode","error","panelShell","onUpdate","panelRect","elementRect","createCaptureModeController","orchestratorOverride","controller","safeCSS","css","createButton","onTrigger","shadowTokens","host","shadow","style","tokenStyle","wrap","btn","tip","isMac","isDragging","hasMoved","startX","startY","originRight","originTopPx","readPosition","right","rawTop","topPx","onMouseDown","pos","onMouseMove","dx","dy","newRight","clamp","newTopPx","onMouseUp","onTouchStart","t","onTouchMove","onTouchEnd","active","min","PANEL_STYLES","POPOUT_OVERRIDE_STYLE","renderLoginView","cb","providers","showGoogle","showMicrosoft","hasSso","ssoSectionHtml","backBtn","back","emailEl","passEl","submitEl","handleSubmit","email","password","ssoHandler","setLoginLoadingState","loading","setLoginErrorState","errEl","escapeHtml","renderClarificationDetailView","discussion","canReply","authorLabel","date","repliesHtml","r","replyFormHtml","textarea","submitBtn","errorEl","enterPickModeView","strip","onCancel","prompt","cancelBtn","fresh","showCaptureDescribeView","snapshot","onSave","onPickAgain","descView","preview","pickAgainBtn","freshPickAgain","saveBtn","freshSave","setCaptureLoadingState","setCaptureErrorState","exitCaptureModeView","FIRST_USE_NOTICE","firstUseNoticeDismissed","renderAnswerHtml","answer","refs","ref","label","chipHtml","safeId","STALE_AFTER_SECONDS","clockOf","builtAt","stalenessSeconds","parsed","ms","d","stalenessLine","p","graph","staleness","asOf","statusStalenessLine","createAskView","lastStatus","esc","root","resultEl","inputEl","ensure","render","stalenessHtml","line","testid","notesHtml","notes","pathsHtml","paths","rows","chips","confidenceHtml","conf","c","provenanceHtml","bits","wireNotes","submit","input","disabled","notice","formHtml","limits","counter","setLoading","clearLoading","showAnswer","narrated","prose","showError","retryable","createCaptureForm","container","html","titleInput","explanationTextarea","snapshotContainer","pickBtn","watchToggle","newPickBtn","picking","cancelCaptureBtn","BANNER_ATTR","showStateChangeBanner","inferredMeaning","onDismiss","hideStateChangeBanner","banner","dismissBtn","ListViewManager","allTerms","discussions","canPost","memories","terms","memory","addBtn","discussionId","getListViewCSS","MIN_WIDTH","MAX_WIDTH_ABS","LS_WIDTH_KEY","LS_SIDE_KEY","createPanelLayout","popoutBtn","dockBtn","closeBtn","pinLeftBtn","pinRightBtn","halfBtn","halfExitBtn","fullscreenBtn","fullscreenExitBtn","resizeHandle","_currentWidth","stored","_side","_popoutWin","_isPopout","_popoutInterval","_isHalfScreen","_isFullscreen","_wasOpenOnFullscreenEnter","_resizing","_resizeStartX","_resizeStartWidth","show","railOffset","marginProp","hide","popout","win","rootTokens","overrideStyle","adopted","triggerBtn","_reattach","winAlreadyClosing","readopted","overrideEl","_setSide","side","_toggleHalfScreen","rOff","halfWidth","_toggleFullscreen","_onResizeMove","vwMax","maxWidth","delta","newWidth","_onResizeUp","cleanup","handleClose","MAX_HOME_ITEMS","renderHomeView","headerSubtitle","isAuthenticated","onTermClick","onRequireLogin","onAddConcept","onOpenSearch","onCaptureUiState","onShowAllConcepts","onOpenAsk","isRelevantToPage","conceptRowsHtml","buildConceptsBody","filtTerms","isFiltering","filtRelevant","filtOther","hasBothGroups","relevantHtml","otherHeadHtml","visibleRelevant","otherCap","visibleOther","hiddenOther","hiddenRelevant","showMoreHtml","conceptsBlockHtml","wireConceptClicks","row","wireShowAllButtons","conceptsBtn","applyConceptFilter","q","conceptsSecEl","secHeader","ql","filtered","tmp","searchInput","searchDebounce","sec","showAddTermForm","loadClarificationsView","onClarificationClick","onShowAllClarifications","onAskQuestion","clarificationsSection","clarBody","askBtn","showAskQuestionForm","emptyBtn","postsHtml","card","showAllBtn","section","emptyState","form","afterEl","insertAfter","nameInput","defInput","createPanel","onLogin","onSearch","workspaceUrl","onClose","onBack","onAddComment","onEditTerm","onRequestEdit","onOpenMemories","onViewMemoryDetail","onUpdateEntryExplanation","onPopout","onReattach","onSsoLogin","onPostReply","onAddEntryToMemory","onDeleteMemory","onDeleteEntry","onShowAllMemories","onAsk","header","footer","listViewStyle","_layout","msg","showToast","setError","_isAuthenticated","showLogin","lastHomeData","savedData","showTerms","setLoginLoading","setLoginError","cachedClarificationsState","activeFormController","listViewManager","currentHomeData","loadClarifications","limitedMemories","showHomeMemoryItems","showSearchResults","renderTermsView","showAllConcepts","initializeListViewManager","showAllClarifications","showAllMemories","listView","listHeader","clarSection","contextName","_totalCount","activeQuery","renderNoResults","renderTerm","debounceTimer","captureBtn","abbr","link","showTermDetail","opts","editBtn","showCommentForm","body2","showEditForm","termInput","setCommentLoading","_loading","setCommentError","_message","setEditLoading","setEditError","showSuggestedTerms","suggestions","onAdd","existing","termsList","termName","showAiModal","onSubmit","overlay","charCount","updateCount","setAiModalLoading","toast","setAuthenticated","auth","bar","showMemoriesList","hasMore","append","listContainer","itemsHtml","renderMemoryItem","loadMoreContainer","timeAgo","formatTimeAgo","count","showMemoryDetail","entriesHtml","entry","roleLabel","readMode","writeMode","isoString","diff","showNewMemoryForm","onPickElement","onCancelCapture","bodyEl","element","showAddEntryForm","memoryTitle","updateFormSnapshot","setFormPickingMode","showStateChangeNotification","hideStateChangeNotification","askView","ensureAskView","showAsk","setAskLoading","clearAskLoading","showAskAnswer","showAskError","showClarificationDetail","enterPickMode","showCaptureDescribe","setCaptureLoading","setCaptureError","exitCaptureMode","restoreHomeView","getStripEl","empty","railStyles","createRailIdentity","initials","avatar","tooltip","createRailCoreActions","state","icons","action","createRailAuth","isLoggedIn","iconSVG","tooltipText","createRail","identity","core","railShell","rail","RAIL_WIDTH","setState","mountUI","button","mountRailUI","railState","railCallbacks","panelCallbacks","SKIP_TAGS","SKIP_IDS","HIGHLIGHT_CLASS","HIGHLIGHT_STYLE","escapeRegex","Highlighter","regex","termMap","span","parent","sorted","patterns","abbrKey","textNode","fragments","lastIndex","matched","anchor","fragment","MAX_SUGGESTIONS","MIN_FREQUENCY","STOP_WORDS","TermSuggester","existingTerms","glossarySet","freq","RUN_RE","runMatch","words","phrase","lower","candidates","MFA_NOT_SUPPORTED_MESSAGE","WidgetController","parts","first","lastPart","last","provider","questionBody","railMount","plugin","jwt","payloadB64","b64","msUntilExpiry","baseUrl","popupUrl","popup","closedPoll","onMessage","event","expectedOrigin","attempt","seconds","minutes","resolve","limitedClarifications","limitedDiscussions","updated","trimmed","localResults","serverResults","glossary","edited","pageResp","captureState","StateWatcher","onStateChange","mutations","before","meaningful","attrMutation","charMutation","childMutations","allNodes","TEXT_LOADING_RE","TEXT_ERROR_RE","TEXT_SUCCESS_RE","CLASS_RULES","classSet","cls","addedClasses","after","beforeSet","inferMeaning","attribute","newClasses","LIVE_RING_ID","LiveRenderer","urlsMatch","current","MemoryDetailController","stateWatcher","targetingEngine","onDiff","firstEntry","meta","target","_controller","initUnnoodle","validateConfig","sessionKey","savedToken","openUnnoodle","closeUnnoodle","destroyUnnoodle","Unnoodle"],"mappings":"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AAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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","file":"index.js","sourcesContent":["/**\n * Fuse.js v7.1.0 - Lightweight fuzzy-search (http://fusejs.io)\n *\n * Copyright (c) 2025 Kiro Risk (http://kiro.me)\n * All Rights Reserved. Apache Software License 2.0\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\nfunction isArray(value) {\n return !Array.isArray\n ? getTag(value) === '[object Array]'\n : Array.isArray(value)\n}\n\n// Adapted from: https://github.com/lodash/lodash/blob/master/.internal/baseToString.js\nconst INFINITY = 1 / 0;\nfunction baseToString(value) {\n // Exit early for strings to avoid a performance hit in some environments.\n if (typeof value == 'string') {\n return value\n }\n let result = value + '';\n return result == '0' && 1 / value == -INFINITY ? '-0' : result\n}\n\nfunction toString(value) {\n return value == null ? '' : baseToString(value)\n}\n\nfunction isString(value) {\n return typeof value === 'string'\n}\n\nfunction isNumber(value) {\n return typeof value === 'number'\n}\n\n// Adapted from: https://github.com/lodash/lodash/blob/master/isBoolean.js\nfunction isBoolean(value) {\n return (\n value === true ||\n value === false ||\n (isObjectLike(value) && getTag(value) == '[object Boolean]')\n )\n}\n\nfunction isObject(value) {\n return typeof value === 'object'\n}\n\n// Checks if `value` is object-like.\nfunction isObjectLike(value) {\n return isObject(value) && value !== null\n}\n\nfunction isDefined(value) {\n return value !== undefined && value !== null\n}\n\nfunction isBlank(value) {\n return !value.trim().length\n}\n\n// Gets the `toStringTag` of `value`.\n// Adapted from: https://github.com/lodash/lodash/blob/master/.internal/getTag.js\nfunction getTag(value) {\n return value == null\n ? value === undefined\n ? '[object Undefined]'\n : '[object Null]'\n : Object.prototype.toString.call(value)\n}\n\nconst EXTENDED_SEARCH_UNAVAILABLE = 'Extended search is not available';\n\nconst INCORRECT_INDEX_TYPE = \"Incorrect 'index' type\";\n\nconst LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY = (key) =>\n `Invalid value for key ${key}`;\n\nconst PATTERN_LENGTH_TOO_LARGE = (max) =>\n `Pattern length exceeds max of ${max}.`;\n\nconst MISSING_KEY_PROPERTY = (name) => `Missing ${name} property in key`;\n\nconst INVALID_KEY_WEIGHT_VALUE = (key) =>\n `Property 'weight' in key '${key}' must be a positive integer`;\n\nconst hasOwn = Object.prototype.hasOwnProperty;\n\nclass KeyStore {\n constructor(keys) {\n this._keys = [];\n this._keyMap = {};\n\n let totalWeight = 0;\n\n keys.forEach((key) => {\n let obj = createKey(key);\n\n this._keys.push(obj);\n this._keyMap[obj.id] = obj;\n\n totalWeight += obj.weight;\n });\n\n // Normalize weights so that their sum is equal to 1\n this._keys.forEach((key) => {\n key.weight /= totalWeight;\n });\n }\n get(keyId) {\n return this._keyMap[keyId]\n }\n keys() {\n return this._keys\n }\n toJSON() {\n return JSON.stringify(this._keys)\n }\n}\n\nfunction createKey(key) {\n let path = null;\n let id = null;\n let src = null;\n let weight = 1;\n let getFn = null;\n\n if (isString(key) || isArray(key)) {\n src = key;\n path = createKeyPath(key);\n id = createKeyId(key);\n } else {\n if (!hasOwn.call(key, 'name')) {\n throw new Error(MISSING_KEY_PROPERTY('name'))\n }\n\n const name = key.name;\n src = name;\n\n if (hasOwn.call(key, 'weight')) {\n weight = key.weight;\n\n if (weight <= 0) {\n throw new Error(INVALID_KEY_WEIGHT_VALUE(name))\n }\n }\n\n path = createKeyPath(name);\n id = createKeyId(name);\n getFn = key.getFn;\n }\n\n return { path, id, weight, src, getFn }\n}\n\nfunction createKeyPath(key) {\n return isArray(key) ? key : key.split('.')\n}\n\nfunction createKeyId(key) {\n return isArray(key) ? key.join('.') : key\n}\n\nfunction get(obj, path) {\n let list = [];\n let arr = false;\n\n const deepGet = (obj, path, index) => {\n if (!isDefined(obj)) {\n return\n }\n if (!path[index]) {\n // If there's no path left, we've arrived at the object we care about.\n list.push(obj);\n } else {\n let key = path[index];\n\n const value = obj[key];\n\n if (!isDefined(value)) {\n return\n }\n\n // If we're at the last value in the path, and if it's a string/number/bool,\n // add it to the list\n if (\n index === path.length - 1 &&\n (isString(value) || isNumber(value) || isBoolean(value))\n ) {\n list.push(toString(value));\n } else if (isArray(value)) {\n arr = true;\n // Search each item in the array.\n for (let i = 0, len = value.length; i < len; i += 1) {\n deepGet(value[i], path, index + 1);\n }\n } else if (path.length) {\n // An object. Recurse further.\n deepGet(value, path, index + 1);\n }\n }\n };\n\n // Backwards compatibility (since path used to be a string)\n deepGet(obj, isString(path) ? path.split('.') : path, 0);\n\n return arr ? list : list[0]\n}\n\nconst MatchOptions = {\n // Whether the matches should be included in the result set. When `true`, each record in the result\n // set will include the indices of the matched characters.\n // These can consequently be used for highlighting purposes.\n includeMatches: false,\n // When `true`, the matching function will continue to the end of a search pattern even if\n // a perfect match has already been located in the string.\n findAllMatches: false,\n // Minimum number of characters that must be matched before a result is considered a match\n minMatchCharLength: 1\n};\n\nconst BasicOptions = {\n // When `true`, the algorithm continues searching to the end of the input even if a perfect\n // match is found before the end of the same input.\n isCaseSensitive: false,\n // When `true`, the algorithm will ignore diacritics (accents) in comparisons\n ignoreDiacritics: false,\n // When true, the matching function will continue to the end of a search pattern even if\n includeScore: false,\n // List of properties that will be searched. This also supports nested properties.\n keys: [],\n // Whether to sort the result list, by score\n shouldSort: true,\n // Default sort function: sort by ascending score, ascending index\n sortFn: (a, b) =>\n a.score === b.score ? (a.idx < b.idx ? -1 : 1) : a.score < b.score ? -1 : 1\n};\n\nconst FuzzyOptions = {\n // Approximately where in the text is the pattern expected to be found?\n location: 0,\n // At what point does the match algorithm give up. A threshold of '0.0' requires a perfect match\n // (of both letters and location), a threshold of '1.0' would match anything.\n threshold: 0.6,\n // Determines how close the match must be to the fuzzy location (specified above).\n // An exact letter match which is 'distance' characters away from the fuzzy location\n // would score as a complete mismatch. A distance of '0' requires the match be at\n // the exact location specified, a threshold of '1000' would require a perfect match\n // to be within 800 characters of the fuzzy location to be found using a 0.8 threshold.\n distance: 100\n};\n\nconst AdvancedOptions = {\n // When `true`, it enables the use of unix-like search commands\n useExtendedSearch: false,\n // The get function to use when fetching an object's properties.\n // The default will search nested paths *ie foo.bar.baz*\n getFn: get,\n // When `true`, search will ignore `location` and `distance`, so it won't matter\n // where in the string the pattern appears.\n // More info: https://fusejs.io/concepts/scoring-theory.html#fuzziness-score\n ignoreLocation: false,\n // When `true`, the calculation for the relevance score (used for sorting) will\n // ignore the field-length norm.\n // More info: https://fusejs.io/concepts/scoring-theory.html#field-length-norm\n ignoreFieldNorm: false,\n // The weight to determine how much field length norm effects scoring.\n fieldNormWeight: 1\n};\n\nvar Config = {\n ...BasicOptions,\n ...MatchOptions,\n ...FuzzyOptions,\n ...AdvancedOptions\n};\n\nconst SPACE = /[^ ]+/g;\n\n// Field-length norm: the shorter the field, the higher the weight.\n// Set to 3 decimals to reduce index size.\nfunction norm(weight = 1, mantissa = 3) {\n const cache = new Map();\n const m = Math.pow(10, mantissa);\n\n return {\n get(value) {\n const numTokens = value.match(SPACE).length;\n\n if (cache.has(numTokens)) {\n return cache.get(numTokens)\n }\n\n // Default function is 1/sqrt(x), weight makes that variable\n const norm = 1 / Math.pow(numTokens, 0.5 * weight);\n\n // In place of `toFixed(mantissa)`, for faster computation\n const n = parseFloat(Math.round(norm * m) / m);\n\n cache.set(numTokens, n);\n\n return n\n },\n clear() {\n cache.clear();\n }\n }\n}\n\nclass FuseIndex {\n constructor({\n getFn = Config.getFn,\n fieldNormWeight = Config.fieldNormWeight\n } = {}) {\n this.norm = norm(fieldNormWeight, 3);\n this.getFn = getFn;\n this.isCreated = false;\n\n this.setIndexRecords();\n }\n setSources(docs = []) {\n this.docs = docs;\n }\n setIndexRecords(records = []) {\n this.records = records;\n }\n setKeys(keys = []) {\n this.keys = keys;\n this._keysMap = {};\n keys.forEach((key, idx) => {\n this._keysMap[key.id] = idx;\n });\n }\n create() {\n if (this.isCreated || !this.docs.length) {\n return\n }\n\n this.isCreated = true;\n\n // List is Array<String>\n if (isString(this.docs[0])) {\n this.docs.forEach((doc, docIndex) => {\n this._addString(doc, docIndex);\n });\n } else {\n // List is Array<Object>\n this.docs.forEach((doc, docIndex) => {\n this._addObject(doc, docIndex);\n });\n }\n\n this.norm.clear();\n }\n // Adds a doc to the end of the index\n add(doc) {\n const idx = this.size();\n\n if (isString(doc)) {\n this._addString(doc, idx);\n } else {\n this._addObject(doc, idx);\n }\n }\n // Removes the doc at the specified index of the index\n removeAt(idx) {\n this.records.splice(idx, 1);\n\n // Change ref index of every subsquent doc\n for (let i = idx, len = this.size(); i < len; i += 1) {\n this.records[i].i -= 1;\n }\n }\n getValueForItemAtKeyId(item, keyId) {\n return item[this._keysMap[keyId]]\n }\n size() {\n return this.records.length\n }\n _addString(doc, docIndex) {\n if (!isDefined(doc) || isBlank(doc)) {\n return\n }\n\n let record = {\n v: doc,\n i: docIndex,\n n: this.norm.get(doc)\n };\n\n this.records.push(record);\n }\n _addObject(doc, docIndex) {\n let record = { i: docIndex, $: {} };\n\n // Iterate over every key (i.e, path), and fetch the value at that key\n this.keys.forEach((key, keyIndex) => {\n let value = key.getFn ? key.getFn(doc) : this.getFn(doc, key.path);\n\n if (!isDefined(value)) {\n return\n }\n\n if (isArray(value)) {\n let subRecords = [];\n const stack = [{ nestedArrIndex: -1, value }];\n\n while (stack.length) {\n const { nestedArrIndex, value } = stack.pop();\n\n if (!isDefined(value)) {\n continue\n }\n\n if (isString(value) && !isBlank(value)) {\n let subRecord = {\n v: value,\n i: nestedArrIndex,\n n: this.norm.get(value)\n };\n\n subRecords.push(subRecord);\n } else if (isArray(value)) {\n value.forEach((item, k) => {\n stack.push({\n nestedArrIndex: k,\n value: item\n });\n });\n } else ;\n }\n record.$[keyIndex] = subRecords;\n } else if (isString(value) && !isBlank(value)) {\n let subRecord = {\n v: value,\n n: this.norm.get(value)\n };\n\n record.$[keyIndex] = subRecord;\n }\n });\n\n this.records.push(record);\n }\n toJSON() {\n return {\n keys: this.keys,\n records: this.records\n }\n }\n}\n\nfunction createIndex(\n keys,\n docs,\n { getFn = Config.getFn, fieldNormWeight = Config.fieldNormWeight } = {}\n) {\n const myIndex = new FuseIndex({ getFn, fieldNormWeight });\n myIndex.setKeys(keys.map(createKey));\n myIndex.setSources(docs);\n myIndex.create();\n return myIndex\n}\n\nfunction parseIndex(\n data,\n { getFn = Config.getFn, fieldNormWeight = Config.fieldNormWeight } = {}\n) {\n const { keys, records } = data;\n const myIndex = new FuseIndex({ getFn, fieldNormWeight });\n myIndex.setKeys(keys);\n myIndex.setIndexRecords(records);\n return myIndex\n}\n\nfunction computeScore$1(\n pattern,\n {\n errors = 0,\n currentLocation = 0,\n expectedLocation = 0,\n distance = Config.distance,\n ignoreLocation = Config.ignoreLocation\n } = {}\n) {\n const accuracy = errors / pattern.length;\n\n if (ignoreLocation) {\n return accuracy\n }\n\n const proximity = Math.abs(expectedLocation - currentLocation);\n\n if (!distance) {\n // Dodge divide by zero error.\n return proximity ? 1.0 : accuracy\n }\n\n return accuracy + proximity / distance\n}\n\nfunction convertMaskToIndices(\n matchmask = [],\n minMatchCharLength = Config.minMatchCharLength\n) {\n let indices = [];\n let start = -1;\n let end = -1;\n let i = 0;\n\n for (let len = matchmask.length; i < len; i += 1) {\n let match = matchmask[i];\n if (match && start === -1) {\n start = i;\n } else if (!match && start !== -1) {\n end = i - 1;\n if (end - start + 1 >= minMatchCharLength) {\n indices.push([start, end]);\n }\n start = -1;\n }\n }\n\n // (i-1 - start) + 1 => i - start\n if (matchmask[i - 1] && i - start >= minMatchCharLength) {\n indices.push([start, i - 1]);\n }\n\n return indices\n}\n\n// Machine word size\nconst MAX_BITS = 32;\n\nfunction search(\n text,\n pattern,\n patternAlphabet,\n {\n location = Config.location,\n distance = Config.distance,\n threshold = Config.threshold,\n findAllMatches = Config.findAllMatches,\n minMatchCharLength = Config.minMatchCharLength,\n includeMatches = Config.includeMatches,\n ignoreLocation = Config.ignoreLocation\n } = {}\n) {\n if (pattern.length > MAX_BITS) {\n throw new Error(PATTERN_LENGTH_TOO_LARGE(MAX_BITS))\n }\n\n const patternLen = pattern.length;\n // Set starting location at beginning text and initialize the alphabet.\n const textLen = text.length;\n // Handle the case when location > text.length\n const expectedLocation = Math.max(0, Math.min(location, textLen));\n // Highest score beyond which we give up.\n let currentThreshold = threshold;\n // Is there a nearby exact match? (speedup)\n let bestLocation = expectedLocation;\n\n // Performance: only computer matches when the minMatchCharLength > 1\n // OR if `includeMatches` is true.\n const computeMatches = minMatchCharLength > 1 || includeMatches;\n // A mask of the matches, used for building the indices\n const matchMask = computeMatches ? Array(textLen) : [];\n\n let index;\n\n // Get all exact matches, here for speed up\n while ((index = text.indexOf(pattern, bestLocation)) > -1) {\n let score = computeScore$1(pattern, {\n currentLocation: index,\n expectedLocation,\n distance,\n ignoreLocation\n });\n\n currentThreshold = Math.min(score, currentThreshold);\n bestLocation = index + patternLen;\n\n if (computeMatches) {\n let i = 0;\n while (i < patternLen) {\n matchMask[index + i] = 1;\n i += 1;\n }\n }\n }\n\n // Reset the best location\n bestLocation = -1;\n\n let lastBitArr = [];\n let finalScore = 1;\n let binMax = patternLen + textLen;\n\n const mask = 1 << (patternLen - 1);\n\n for (let i = 0; i < patternLen; i += 1) {\n // Scan for the best match; each iteration allows for one more error.\n // Run a binary search to determine how far from the match location we can stray\n // at this error level.\n let binMin = 0;\n let binMid = binMax;\n\n while (binMin < binMid) {\n const score = computeScore$1(pattern, {\n errors: i,\n currentLocation: expectedLocation + binMid,\n expectedLocation,\n distance,\n ignoreLocation\n });\n\n if (score <= currentThreshold) {\n binMin = binMid;\n } else {\n binMax = binMid;\n }\n\n binMid = Math.floor((binMax - binMin) / 2 + binMin);\n }\n\n // Use the result from this iteration as the maximum for the next.\n binMax = binMid;\n\n let start = Math.max(1, expectedLocation - binMid + 1);\n let finish = findAllMatches\n ? textLen\n : Math.min(expectedLocation + binMid, textLen) + patternLen;\n\n // Initialize the bit array\n let bitArr = Array(finish + 2);\n\n bitArr[finish + 1] = (1 << i) - 1;\n\n for (let j = finish; j >= start; j -= 1) {\n let currentLocation = j - 1;\n let charMatch = patternAlphabet[text.charAt(currentLocation)];\n\n if (computeMatches) {\n // Speed up: quick bool to int conversion (i.e, `charMatch ? 1 : 0`)\n matchMask[currentLocation] = +!!charMatch;\n }\n\n // First pass: exact match\n bitArr[j] = ((bitArr[j + 1] << 1) | 1) & charMatch;\n\n // Subsequent passes: fuzzy match\n if (i) {\n bitArr[j] |=\n ((lastBitArr[j + 1] | lastBitArr[j]) << 1) | 1 | lastBitArr[j + 1];\n }\n\n if (bitArr[j] & mask) {\n finalScore = computeScore$1(pattern, {\n errors: i,\n currentLocation,\n expectedLocation,\n distance,\n ignoreLocation\n });\n\n // This match will almost certainly be better than any existing match.\n // But check anyway.\n if (finalScore <= currentThreshold) {\n // Indeed it is\n currentThreshold = finalScore;\n bestLocation = currentLocation;\n\n // Already passed `loc`, downhill from here on in.\n if (bestLocation <= expectedLocation) {\n break\n }\n\n // When passing `bestLocation`, don't exceed our current distance from `expectedLocation`.\n start = Math.max(1, 2 * expectedLocation - bestLocation);\n }\n }\n }\n\n // No hope for a (better) match at greater error levels.\n const score = computeScore$1(pattern, {\n errors: i + 1,\n currentLocation: expectedLocation,\n expectedLocation,\n distance,\n ignoreLocation\n });\n\n if (score > currentThreshold) {\n break\n }\n\n lastBitArr = bitArr;\n }\n\n const result = {\n isMatch: bestLocation >= 0,\n // Count exact matches (those with a score of 0) to be \"almost\" exact\n score: Math.max(0.001, finalScore)\n };\n\n if (computeMatches) {\n const indices = convertMaskToIndices(matchMask, minMatchCharLength);\n if (!indices.length) {\n result.isMatch = false;\n } else if (includeMatches) {\n result.indices = indices;\n }\n }\n\n return result\n}\n\nfunction createPatternAlphabet(pattern) {\n let mask = {};\n\n for (let i = 0, len = pattern.length; i < len; i += 1) {\n const char = pattern.charAt(i);\n mask[char] = (mask[char] || 0) | (1 << (len - i - 1));\n }\n\n return mask\n}\n\nconst stripDiacritics = String.prototype.normalize\n ? ((str) => str.normalize('NFD').replace(/[\\u0300-\\u036F\\u0483-\\u0489\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u0610-\\u061A\\u064B-\\u065F\\u0670\\u06D6-\\u06DC\\u06DF-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0711\\u0730-\\u074A\\u07A6-\\u07B0\\u07EB-\\u07F3\\u07FD\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u082D\\u0859-\\u085B\\u08D3-\\u08E1\\u08E3-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962\\u0963\\u0981-\\u0983\\u09BC\\u09BE-\\u09C4\\u09C7\\u09C8\\u09CB-\\u09CD\\u09D7\\u09E2\\u09E3\\u09FE\\u0A01-\\u0A03\\u0A3C\\u0A3E-\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A70\\u0A71\\u0A75\\u0A81-\\u0A83\\u0ABC\\u0ABE-\\u0AC5\\u0AC7-\\u0AC9\\u0ACB-\\u0ACD\\u0AE2\\u0AE3\\u0AFA-\\u0AFF\\u0B01-\\u0B03\\u0B3C\\u0B3E-\\u0B44\\u0B47\\u0B48\\u0B4B-\\u0B4D\\u0B56\\u0B57\\u0B62\\u0B63\\u0B82\\u0BBE-\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCD\\u0BD7\\u0C00-\\u0C04\\u0C3E-\\u0C44\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C62\\u0C63\\u0C81-\\u0C83\\u0CBC\\u0CBE-\\u0CC4\\u0CC6-\\u0CC8\\u0CCA-\\u0CCD\\u0CD5\\u0CD6\\u0CE2\\u0CE3\\u0D00-\\u0D03\\u0D3B\\u0D3C\\u0D3E-\\u0D44\\u0D46-\\u0D48\\u0D4A-\\u0D4D\\u0D57\\u0D62\\u0D63\\u0D82\\u0D83\\u0DCA\\u0DCF-\\u0DD4\\u0DD6\\u0DD8-\\u0DDF\\u0DF2\\u0DF3\\u0E31\\u0E34-\\u0E3A\\u0E47-\\u0E4E\\u0EB1\\u0EB4-\\u0EB9\\u0EBB\\u0EBC\\u0EC8-\\u0ECD\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F3E\\u0F3F\\u0F71-\\u0F84\\u0F86\\u0F87\\u0F8D-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u102B-\\u103E\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F\\u109A-\\u109D\\u135D-\\u135F\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17B4-\\u17D3\\u17DD\\u180B-\\u180D\\u1885\\u1886\\u18A9\\u1920-\\u192B\\u1930-\\u193B\\u1A17-\\u1A1B\\u1A55-\\u1A5E\\u1A60-\\u1A7C\\u1A7F\\u1AB0-\\u1ABE\\u1B00-\\u1B04\\u1B34-\\u1B44\\u1B6B-\\u1B73\\u1B80-\\u1B82\\u1BA1-\\u1BAD\\u1BE6-\\u1BF3\\u1C24-\\u1C37\\u1CD0-\\u1CD2\\u1CD4-\\u1CE8\\u1CED\\u1CF2-\\u1CF4\\u1CF7-\\u1CF9\\u1DC0-\\u1DF9\\u1DFB-\\u1DFF\\u20D0-\\u20F0\\u2CEF-\\u2CF1\\u2D7F\\u2DE0-\\u2DFF\\u302A-\\u302F\\u3099\\u309A\\uA66F-\\uA672\\uA674-\\uA67D\\uA69E\\uA69F\\uA6F0\\uA6F1\\uA802\\uA806\\uA80B\\uA823-\\uA827\\uA880\\uA881\\uA8B4-\\uA8C5\\uA8E0-\\uA8F1\\uA8FF\\uA926-\\uA92D\\uA947-\\uA953\\uA980-\\uA983\\uA9B3-\\uA9C0\\uA9E5\\uAA29-\\uAA36\\uAA43\\uAA4C\\uAA4D\\uAA7B-\\uAA7D\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAEB-\\uAAEF\\uAAF5\\uAAF6\\uABE3-\\uABEA\\uABEC\\uABED\\uFB1E\\uFE00-\\uFE0F\\uFE20-\\uFE2F]/g, ''))\n : ((str) => str);\n\nclass BitapSearch {\n constructor(\n pattern,\n {\n location = Config.location,\n threshold = Config.threshold,\n distance = Config.distance,\n includeMatches = Config.includeMatches,\n findAllMatches = Config.findAllMatches,\n minMatchCharLength = Config.minMatchCharLength,\n isCaseSensitive = Config.isCaseSensitive,\n ignoreDiacritics = Config.ignoreDiacritics,\n ignoreLocation = Config.ignoreLocation\n } = {}\n ) {\n this.options = {\n location,\n threshold,\n distance,\n includeMatches,\n findAllMatches,\n minMatchCharLength,\n isCaseSensitive,\n ignoreDiacritics,\n ignoreLocation\n };\n\n pattern = isCaseSensitive ? pattern : pattern.toLowerCase();\n pattern = ignoreDiacritics ? stripDiacritics(pattern) : pattern;\n this.pattern = pattern;\n\n this.chunks = [];\n\n if (!this.pattern.length) {\n return\n }\n\n const addChunk = (pattern, startIndex) => {\n this.chunks.push({\n pattern,\n alphabet: createPatternAlphabet(pattern),\n startIndex\n });\n };\n\n const len = this.pattern.length;\n\n if (len > MAX_BITS) {\n let i = 0;\n const remainder = len % MAX_BITS;\n const end = len - remainder;\n\n while (i < end) {\n addChunk(this.pattern.substr(i, MAX_BITS), i);\n i += MAX_BITS;\n }\n\n if (remainder) {\n const startIndex = len - MAX_BITS;\n addChunk(this.pattern.substr(startIndex), startIndex);\n }\n } else {\n addChunk(this.pattern, 0);\n }\n }\n\n searchIn(text) {\n const { isCaseSensitive, ignoreDiacritics, includeMatches } = this.options;\n\n text = isCaseSensitive ? text : text.toLowerCase();\n text = ignoreDiacritics ? stripDiacritics(text) : text;\n\n // Exact match\n if (this.pattern === text) {\n let result = {\n isMatch: true,\n score: 0\n };\n\n if (includeMatches) {\n result.indices = [[0, text.length - 1]];\n }\n\n return result\n }\n\n // Otherwise, use Bitap algorithm\n const {\n location,\n distance,\n threshold,\n findAllMatches,\n minMatchCharLength,\n ignoreLocation\n } = this.options;\n\n let allIndices = [];\n let totalScore = 0;\n let hasMatches = false;\n\n this.chunks.forEach(({ pattern, alphabet, startIndex }) => {\n const { isMatch, score, indices } = search(text, pattern, alphabet, {\n location: location + startIndex,\n distance,\n threshold,\n findAllMatches,\n minMatchCharLength,\n includeMatches,\n ignoreLocation\n });\n\n if (isMatch) {\n hasMatches = true;\n }\n\n totalScore += score;\n\n if (isMatch && indices) {\n allIndices = [...allIndices, ...indices];\n }\n });\n\n let result = {\n isMatch: hasMatches,\n score: hasMatches ? totalScore / this.chunks.length : 1\n };\n\n if (hasMatches && includeMatches) {\n result.indices = allIndices;\n }\n\n return result\n }\n}\n\nclass BaseMatch {\n constructor(pattern) {\n this.pattern = pattern;\n }\n static isMultiMatch(pattern) {\n return getMatch(pattern, this.multiRegex)\n }\n static isSingleMatch(pattern) {\n return getMatch(pattern, this.singleRegex)\n }\n search(/*text*/) {}\n}\n\nfunction getMatch(pattern, exp) {\n const matches = pattern.match(exp);\n return matches ? matches[1] : null\n}\n\n// Token: 'file\n\nclass ExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'exact'\n }\n static get multiRegex() {\n return /^=\"(.*)\"$/\n }\n static get singleRegex() {\n return /^=(.*)$/\n }\n search(text) {\n const isMatch = text === this.pattern;\n\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [0, this.pattern.length - 1]\n }\n }\n}\n\n// Token: !fire\n\nclass InverseExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'inverse-exact'\n }\n static get multiRegex() {\n return /^!\"(.*)\"$/\n }\n static get singleRegex() {\n return /^!(.*)$/\n }\n search(text) {\n const index = text.indexOf(this.pattern);\n const isMatch = index === -1;\n\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [0, text.length - 1]\n }\n }\n}\n\n// Token: ^file\n\nclass PrefixExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'prefix-exact'\n }\n static get multiRegex() {\n return /^\\^\"(.*)\"$/\n }\n static get singleRegex() {\n return /^\\^(.*)$/\n }\n search(text) {\n const isMatch = text.startsWith(this.pattern);\n\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [0, this.pattern.length - 1]\n }\n }\n}\n\n// Token: !^fire\n\nclass InversePrefixExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'inverse-prefix-exact'\n }\n static get multiRegex() {\n return /^!\\^\"(.*)\"$/\n }\n static get singleRegex() {\n return /^!\\^(.*)$/\n }\n search(text) {\n const isMatch = !text.startsWith(this.pattern);\n\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [0, text.length - 1]\n }\n }\n}\n\n// Token: .file$\n\nclass SuffixExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'suffix-exact'\n }\n static get multiRegex() {\n return /^\"(.*)\"\\$$/\n }\n static get singleRegex() {\n return /^(.*)\\$$/\n }\n search(text) {\n const isMatch = text.endsWith(this.pattern);\n\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [text.length - this.pattern.length, text.length - 1]\n }\n }\n}\n\n// Token: !.file$\n\nclass InverseSuffixExactMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'inverse-suffix-exact'\n }\n static get multiRegex() {\n return /^!\"(.*)\"\\$$/\n }\n static get singleRegex() {\n return /^!(.*)\\$$/\n }\n search(text) {\n const isMatch = !text.endsWith(this.pattern);\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices: [0, text.length - 1]\n }\n }\n}\n\nclass FuzzyMatch extends BaseMatch {\n constructor(\n pattern,\n {\n location = Config.location,\n threshold = Config.threshold,\n distance = Config.distance,\n includeMatches = Config.includeMatches,\n findAllMatches = Config.findAllMatches,\n minMatchCharLength = Config.minMatchCharLength,\n isCaseSensitive = Config.isCaseSensitive,\n ignoreDiacritics = Config.ignoreDiacritics,\n ignoreLocation = Config.ignoreLocation\n } = {}\n ) {\n super(pattern);\n this._bitapSearch = new BitapSearch(pattern, {\n location,\n threshold,\n distance,\n includeMatches,\n findAllMatches,\n minMatchCharLength,\n isCaseSensitive,\n ignoreDiacritics,\n ignoreLocation\n });\n }\n static get type() {\n return 'fuzzy'\n }\n static get multiRegex() {\n return /^\"(.*)\"$/\n }\n static get singleRegex() {\n return /^(.*)$/\n }\n search(text) {\n return this._bitapSearch.searchIn(text)\n }\n}\n\n// Token: 'file\n\nclass IncludeMatch extends BaseMatch {\n constructor(pattern) {\n super(pattern);\n }\n static get type() {\n return 'include'\n }\n static get multiRegex() {\n return /^'\"(.*)\"$/\n }\n static get singleRegex() {\n return /^'(.*)$/\n }\n search(text) {\n let location = 0;\n let index;\n\n const indices = [];\n const patternLen = this.pattern.length;\n\n // Get all exact matches\n while ((index = text.indexOf(this.pattern, location)) > -1) {\n location = index + patternLen;\n indices.push([index, location - 1]);\n }\n\n const isMatch = !!indices.length;\n\n return {\n isMatch,\n score: isMatch ? 0 : 1,\n indices\n }\n }\n}\n\n// ❗Order is important. DO NOT CHANGE.\nconst searchers = [\n ExactMatch,\n IncludeMatch,\n PrefixExactMatch,\n InversePrefixExactMatch,\n InverseSuffixExactMatch,\n SuffixExactMatch,\n InverseExactMatch,\n FuzzyMatch\n];\n\nconst searchersLen = searchers.length;\n\n// Regex to split by spaces, but keep anything in quotes together\nconst SPACE_RE = / +(?=(?:[^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)/;\nconst OR_TOKEN = '|';\n\n// Return a 2D array representation of the query, for simpler parsing.\n// Example:\n// \"^core go$ | rb$ | py$ xy$\" => [[\"^core\", \"go$\"], [\"rb$\"], [\"py$\", \"xy$\"]]\nfunction parseQuery(pattern, options = {}) {\n return pattern.split(OR_TOKEN).map((item) => {\n let query = item\n .trim()\n .split(SPACE_RE)\n .filter((item) => item && !!item.trim());\n\n let results = [];\n for (let i = 0, len = query.length; i < len; i += 1) {\n const queryItem = query[i];\n\n // 1. Handle multiple query match (i.e, once that are quoted, like `\"hello world\"`)\n let found = false;\n let idx = -1;\n while (!found && ++idx < searchersLen) {\n const searcher = searchers[idx];\n let token = searcher.isMultiMatch(queryItem);\n if (token) {\n results.push(new searcher(token, options));\n found = true;\n }\n }\n\n if (found) {\n continue\n }\n\n // 2. Handle single query matches (i.e, once that are *not* quoted)\n idx = -1;\n while (++idx < searchersLen) {\n const searcher = searchers[idx];\n let token = searcher.isSingleMatch(queryItem);\n if (token) {\n results.push(new searcher(token, options));\n break\n }\n }\n }\n\n return results\n })\n}\n\n// These extended matchers can return an array of matches, as opposed\n// to a singl match\nconst MultiMatchSet = new Set([FuzzyMatch.type, IncludeMatch.type]);\n\n/**\n * Command-like searching\n * ======================\n *\n * Given multiple search terms delimited by spaces.e.g. `^jscript .python$ ruby !java`,\n * search in a given text.\n *\n * Search syntax:\n *\n * | Token | Match type | Description |\n * | ----------- | -------------------------- | -------------------------------------- |\n * | `jscript` | fuzzy-match | Items that fuzzy match `jscript` |\n * | `=scheme` | exact-match | Items that are `scheme` |\n * | `'python` | include-match | Items that include `python` |\n * | `!ruby` | inverse-exact-match | Items that do not include `ruby` |\n * | `^java` | prefix-exact-match | Items that start with `java` |\n * | `!^earlang` | inverse-prefix-exact-match | Items that do not start with `earlang` |\n * | `.js$` | suffix-exact-match | Items that end with `.js` |\n * | `!.go$` | inverse-suffix-exact-match | Items that do not end with `.go` |\n *\n * A single pipe character acts as an OR operator. For example, the following\n * query matches entries that start with `core` and end with either`go`, `rb`,\n * or`py`.\n *\n * ```\n * ^core go$ | rb$ | py$\n * ```\n */\nclass ExtendedSearch {\n constructor(\n pattern,\n {\n isCaseSensitive = Config.isCaseSensitive,\n ignoreDiacritics = Config.ignoreDiacritics,\n includeMatches = Config.includeMatches,\n minMatchCharLength = Config.minMatchCharLength,\n ignoreLocation = Config.ignoreLocation,\n findAllMatches = Config.findAllMatches,\n location = Config.location,\n threshold = Config.threshold,\n distance = Config.distance\n } = {}\n ) {\n this.query = null;\n this.options = {\n isCaseSensitive,\n ignoreDiacritics,\n includeMatches,\n minMatchCharLength,\n findAllMatches,\n ignoreLocation,\n location,\n threshold,\n distance\n };\n\n pattern = isCaseSensitive ? pattern : pattern.toLowerCase();\n pattern = ignoreDiacritics ? stripDiacritics(pattern) : pattern;\n this.pattern = pattern;\n this.query = parseQuery(this.pattern, this.options);\n }\n\n static condition(_, options) {\n return options.useExtendedSearch\n }\n\n searchIn(text) {\n const query = this.query;\n\n if (!query) {\n return {\n isMatch: false,\n score: 1\n }\n }\n\n const { includeMatches, isCaseSensitive, ignoreDiacritics } = this.options;\n\n text = isCaseSensitive ? text : text.toLowerCase();\n text = ignoreDiacritics ? stripDiacritics(text) : text;\n\n let numMatches = 0;\n let allIndices = [];\n let totalScore = 0;\n\n // ORs\n for (let i = 0, qLen = query.length; i < qLen; i += 1) {\n const searchers = query[i];\n\n // Reset indices\n allIndices.length = 0;\n numMatches = 0;\n\n // ANDs\n for (let j = 0, pLen = searchers.length; j < pLen; j += 1) {\n const searcher = searchers[j];\n const { isMatch, indices, score } = searcher.search(text);\n\n if (isMatch) {\n numMatches += 1;\n totalScore += score;\n if (includeMatches) {\n const type = searcher.constructor.type;\n if (MultiMatchSet.has(type)) {\n allIndices = [...allIndices, ...indices];\n } else {\n allIndices.push(indices);\n }\n }\n } else {\n totalScore = 0;\n numMatches = 0;\n allIndices.length = 0;\n break\n }\n }\n\n // OR condition, so if TRUE, return\n if (numMatches) {\n let result = {\n isMatch: true,\n score: totalScore / numMatches\n };\n\n if (includeMatches) {\n result.indices = allIndices;\n }\n\n return result\n }\n }\n\n // Nothing was matched\n return {\n isMatch: false,\n score: 1\n }\n }\n}\n\nconst registeredSearchers = [];\n\nfunction register(...args) {\n registeredSearchers.push(...args);\n}\n\nfunction createSearcher(pattern, options) {\n for (let i = 0, len = registeredSearchers.length; i < len; i += 1) {\n let searcherClass = registeredSearchers[i];\n if (searcherClass.condition(pattern, options)) {\n return new searcherClass(pattern, options)\n }\n }\n\n return new BitapSearch(pattern, options)\n}\n\nconst LogicalOperator = {\n AND: '$and',\n OR: '$or'\n};\n\nconst KeyType = {\n PATH: '$path',\n PATTERN: '$val'\n};\n\nconst isExpression = (query) =>\n !!(query[LogicalOperator.AND] || query[LogicalOperator.OR]);\n\nconst isPath = (query) => !!query[KeyType.PATH];\n\nconst isLeaf = (query) =>\n !isArray(query) && isObject(query) && !isExpression(query);\n\nconst convertToExplicit = (query) => ({\n [LogicalOperator.AND]: Object.keys(query).map((key) => ({\n [key]: query[key]\n }))\n});\n\n// When `auto` is `true`, the parse function will infer and initialize and add\n// the appropriate `Searcher` instance\nfunction parse(query, options, { auto = true } = {}) {\n const next = (query) => {\n let keys = Object.keys(query);\n\n const isQueryPath = isPath(query);\n\n if (!isQueryPath && keys.length > 1 && !isExpression(query)) {\n return next(convertToExplicit(query))\n }\n\n if (isLeaf(query)) {\n const key = isQueryPath ? query[KeyType.PATH] : keys[0];\n\n const pattern = isQueryPath ? query[KeyType.PATTERN] : query[key];\n\n if (!isString(pattern)) {\n throw new Error(LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY(key))\n }\n\n const obj = {\n keyId: createKeyId(key),\n pattern\n };\n\n if (auto) {\n obj.searcher = createSearcher(pattern, options);\n }\n\n return obj\n }\n\n let node = {\n children: [],\n operator: keys[0]\n };\n\n keys.forEach((key) => {\n const value = query[key];\n\n if (isArray(value)) {\n value.forEach((item) => {\n node.children.push(next(item));\n });\n }\n });\n\n return node\n };\n\n if (!isExpression(query)) {\n query = convertToExplicit(query);\n }\n\n return next(query)\n}\n\n// Practical scoring function\nfunction computeScore(\n results,\n { ignoreFieldNorm = Config.ignoreFieldNorm }\n) {\n results.forEach((result) => {\n let totalScore = 1;\n\n result.matches.forEach(({ key, norm, score }) => {\n const weight = key ? key.weight : null;\n\n totalScore *= Math.pow(\n score === 0 && weight ? Number.EPSILON : score,\n (weight || 1) * (ignoreFieldNorm ? 1 : norm)\n );\n });\n\n result.score = totalScore;\n });\n}\n\nfunction transformMatches(result, data) {\n const matches = result.matches;\n data.matches = [];\n\n if (!isDefined(matches)) {\n return\n }\n\n matches.forEach((match) => {\n if (!isDefined(match.indices) || !match.indices.length) {\n return\n }\n\n const { indices, value } = match;\n\n let obj = {\n indices,\n value\n };\n\n if (match.key) {\n obj.key = match.key.src;\n }\n\n if (match.idx > -1) {\n obj.refIndex = match.idx;\n }\n\n data.matches.push(obj);\n });\n}\n\nfunction transformScore(result, data) {\n data.score = result.score;\n}\n\nfunction format(\n results,\n docs,\n {\n includeMatches = Config.includeMatches,\n includeScore = Config.includeScore\n } = {}\n) {\n const transformers = [];\n\n if (includeMatches) transformers.push(transformMatches);\n if (includeScore) transformers.push(transformScore);\n\n return results.map((result) => {\n const { idx } = result;\n\n const data = {\n item: docs[idx],\n refIndex: idx\n };\n\n if (transformers.length) {\n transformers.forEach((transformer) => {\n transformer(result, data);\n });\n }\n\n return data\n })\n}\n\nclass Fuse {\n constructor(docs, options = {}, index) {\n this.options = { ...Config, ...options };\n\n if (\n this.options.useExtendedSearch &&\n !true\n ) {\n throw new Error(EXTENDED_SEARCH_UNAVAILABLE)\n }\n\n this._keyStore = new KeyStore(this.options.keys);\n\n this.setCollection(docs, index);\n }\n\n setCollection(docs, index) {\n this._docs = docs;\n\n if (index && !(index instanceof FuseIndex)) {\n throw new Error(INCORRECT_INDEX_TYPE)\n }\n\n this._myIndex =\n index ||\n createIndex(this.options.keys, this._docs, {\n getFn: this.options.getFn,\n fieldNormWeight: this.options.fieldNormWeight\n });\n }\n\n add(doc) {\n if (!isDefined(doc)) {\n return\n }\n\n this._docs.push(doc);\n this._myIndex.add(doc);\n }\n\n remove(predicate = (/* doc, idx */) => false) {\n const results = [];\n\n for (let i = 0, len = this._docs.length; i < len; i += 1) {\n const doc = this._docs[i];\n if (predicate(doc, i)) {\n this.removeAt(i);\n i -= 1;\n len -= 1;\n\n results.push(doc);\n }\n }\n\n return results\n }\n\n removeAt(idx) {\n this._docs.splice(idx, 1);\n this._myIndex.removeAt(idx);\n }\n\n getIndex() {\n return this._myIndex\n }\n\n search(query, { limit = -1 } = {}) {\n const {\n includeMatches,\n includeScore,\n shouldSort,\n sortFn,\n ignoreFieldNorm\n } = this.options;\n\n let results = isString(query)\n ? isString(this._docs[0])\n ? this._searchStringList(query)\n : this._searchObjectList(query)\n : this._searchLogical(query);\n\n computeScore(results, { ignoreFieldNorm });\n\n if (shouldSort) {\n results.sort(sortFn);\n }\n\n if (isNumber(limit) && limit > -1) {\n results = results.slice(0, limit);\n }\n\n return format(results, this._docs, {\n includeMatches,\n includeScore\n })\n }\n\n _searchStringList(query) {\n const searcher = createSearcher(query, this.options);\n const { records } = this._myIndex;\n const results = [];\n\n // Iterate over every string in the index\n records.forEach(({ v: text, i: idx, n: norm }) => {\n if (!isDefined(text)) {\n return\n }\n\n const { isMatch, score, indices } = searcher.searchIn(text);\n\n if (isMatch) {\n results.push({\n item: text,\n idx,\n matches: [{ score, value: text, norm, indices }]\n });\n }\n });\n\n return results\n }\n\n _searchLogical(query) {\n\n const expression = parse(query, this.options);\n\n const evaluate = (node, item, idx) => {\n if (!node.children) {\n const { keyId, searcher } = node;\n\n const matches = this._findMatches({\n key: this._keyStore.get(keyId),\n value: this._myIndex.getValueForItemAtKeyId(item, keyId),\n searcher\n });\n\n if (matches && matches.length) {\n return [\n {\n idx,\n item,\n matches\n }\n ]\n }\n\n return []\n }\n\n const res = [];\n for (let i = 0, len = node.children.length; i < len; i += 1) {\n const child = node.children[i];\n const result = evaluate(child, item, idx);\n if (result.length) {\n res.push(...result);\n } else if (node.operator === LogicalOperator.AND) {\n return []\n }\n }\n return res\n };\n\n const records = this._myIndex.records;\n const resultMap = {};\n const results = [];\n\n records.forEach(({ $: item, i: idx }) => {\n if (isDefined(item)) {\n let expResults = evaluate(expression, item, idx);\n\n if (expResults.length) {\n // Dedupe when adding\n if (!resultMap[idx]) {\n resultMap[idx] = { idx, item, matches: [] };\n results.push(resultMap[idx]);\n }\n expResults.forEach(({ matches }) => {\n resultMap[idx].matches.push(...matches);\n });\n }\n }\n });\n\n return results\n }\n\n _searchObjectList(query) {\n const searcher = createSearcher(query, this.options);\n const { keys, records } = this._myIndex;\n const results = [];\n\n // List is Array<Object>\n records.forEach(({ $: item, i: idx }) => {\n if (!isDefined(item)) {\n return\n }\n\n let matches = [];\n\n // Iterate over every key (i.e, path), and fetch the value at that key\n keys.forEach((key, keyIndex) => {\n matches.push(\n ...this._findMatches({\n key,\n value: item[keyIndex],\n searcher\n })\n );\n });\n\n if (matches.length) {\n results.push({\n idx,\n item,\n matches\n });\n }\n });\n\n return results\n }\n _findMatches({ key, value, searcher }) {\n if (!isDefined(value)) {\n return []\n }\n\n let matches = [];\n\n if (isArray(value)) {\n value.forEach(({ v: text, i: idx, n: norm }) => {\n if (!isDefined(text)) {\n return\n }\n\n const { isMatch, score, indices } = searcher.searchIn(text);\n\n if (isMatch) {\n matches.push({\n score,\n key,\n value: text,\n idx,\n norm,\n indices\n });\n }\n });\n } else {\n const { v: text, n: norm } = value;\n\n const { isMatch, score, indices } = searcher.searchIn(text);\n\n if (isMatch) {\n matches.push({ score, key, value: text, norm, indices });\n }\n }\n\n return matches\n }\n}\n\nFuse.version = '7.1.0';\nFuse.createIndex = createIndex;\nFuse.parseIndex = parseIndex;\nFuse.config = Config;\n\n{\n Fuse.parseQuery = parse;\n}\n\n{\n register(ExtendedSearch);\n}\n\nexport { Fuse as default };\n","/**\n * HTTP primitives — base URL, headers, token helper, typed error.\n * Every api/* module imports from here; nothing else should.\n */\nimport type { UnnoodleConfig } from \"../types/config\";\n\nconst DEFAULT_BASE_URL = \"https://api.unnoodle.com\";\n\nexport function resolvedBaseUrl(config: UnnoodleConfig): string {\n return config.baseUrl?.replace(/\\/$/, \"\") ?? DEFAULT_BASE_URL;\n}\n\n/**\n * Builds headers for API-key-authenticated requests.\n * Auth token is resolved at call-time — never stored.\n */\nexport function apiKeyHeaders(config: UnnoodleConfig): Record<string, string> {\n return {\n \"Content-Type\": \"application/json\",\n \"X-Unnoodle-Api-Key\": config.apiKey,\n };\n}\n\n/**\n * Safely calls config.getAuthToken without throwing.\n * Returns null on any error or when not configured.\n */\nexport function safeGetToken(config: UnnoodleConfig): string | null {\n if (typeof config.getAuthToken !== \"function\") return null;\n try {\n return config.getAuthToken() ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Typed error for API failures.\n * Lets consumers distinguish HTTP errors from network errors.\n */\nexport class ApiError extends Error {\n public readonly status: number;\n public readonly body: string;\n\n constructor(message: string, status: number, body: string) {\n super(message);\n this.name = \"ApiError\";\n this.status = status;\n this.body = body;\n }\n}\n","import type {\n UnnoodleConfig,\n WidgetInitResponse,\n GlossaryTerm,\n} from \"../types/config\";\nimport { resolvedBaseUrl, apiKeyHeaders, safeGetToken, ApiError } from \"./http\";\n\n// ---------------------------------------------------------------------------\n// POST /api/init — SDK widget initialization\n// ---------------------------------------------------------------------------\n\n/**\n * Initializes the widget: resolves/creates the context and returns its full\n * glossary in one round-trip.\n *\n * Authentication: X-Unnoodle-Api-Key header (no user JWT required for public\n * contexts; JWT may optionally personalise results).\n */\nexport async function initWidget(\n config: UnnoodleConfig,\n userToken?: string | null,\n): Promise<WidgetInitResponse> {\n const url = `${resolvedBaseUrl(config)}/api/init`;\n const headers: Record<string, string> = apiKeyHeaders(config);\n const token = userToken !== undefined ? userToken : safeGetToken(config);\n\n if (token) {\n headers[\"Authorization\"] = `Bearer ${token}`;\n }\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ context: config.context }),\n });\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle /api/init error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n\n return response.json() as Promise<WidgetInitResponse>;\n}\n\n// ---------------------------------------------------------------------------\n// GET /api/contexts/:id/glossary/search?q= — instant server-side search\n// ---------------------------------------------------------------------------\n\n/**\n * Searches glossary terms within a specific context on the backend.\n */\nexport async function searchTerms(\n config: UnnoodleConfig,\n contextId: number,\n query: string,\n userToken?: string | null,\n): Promise<GlossaryTerm[]> {\n const url = `${resolvedBaseUrl(config)}/api/contexts/${contextId}/glossary/search?q=${encodeURIComponent(query)}`;\n const headers: Record<string, string> = apiKeyHeaders(config);\n const token = userToken !== undefined ? userToken : safeGetToken(config);\n\n if (token) {\n headers[\"Authorization\"] = `Bearer ${token}`;\n }\n\n const response = await fetch(url, { headers });\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle search error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n\n return response.json() as Promise<GlossaryTerm[]>;\n}\n","import type {\n UnnoodleConfig,\n LoginRequest,\n AuthResponse,\n SsoProviders,\n} from \"../types/config\";\nimport { resolvedBaseUrl, apiKeyHeaders, ApiError } from \"./http\";\n\n// ---------------------------------------------------------------------------\n// POST /api/auth/login — in-panel user login\n// ---------------------------------------------------------------------------\n\n/**\n * Authenticates a user via the Unnoodle backend.\n * The returned token must be held in memory by the caller — never written to\n * localStorage or sessionStorage.\n */\nexport async function loginUser(\n config: UnnoodleConfig,\n credentials: LoginRequest,\n): Promise<AuthResponse> {\n const url = `${resolvedBaseUrl(config)}/api/auth/login`;\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: apiKeyHeaders(config),\n body: JSON.stringify(credentials),\n });\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle login error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n\n return response.json() as Promise<AuthResponse>;\n}\n\n// ---------------------------------------------------------------------------\n// GET /api/auth/oauth/providers — SSO provider availability for the tenant\n// ---------------------------------------------------------------------------\n\n/**\n * Returns which SSO providers are enabled for the current tenant.\n * Never throws — on any error (network, 4xx, 5xx) returns both providers\n * as disabled so the widget gracefully falls back to password-only login.\n */\nexport async function fetchOAuthProviders(\n config: UnnoodleConfig,\n): Promise<SsoProviders> {\n const url = `${resolvedBaseUrl(config)}/api/auth/oauth/providers`;\n try {\n const response = await fetch(url, { headers: apiKeyHeaders(config) });\n if (!response.ok) {\n return { googleEnabled: false, microsoftEnabled: false };\n }\n return response.json() as Promise<SsoProviders>;\n } catch {\n return { googleEnabled: false, microsoftEnabled: false };\n }\n}\n","import type {\n UnnoodleConfig,\n DiscussionPost,\n GlossaryTerm,\n GlossaryTermUpdateRequest,\n} from \"../types/config\";\nimport { resolvedBaseUrl, apiKeyHeaders, safeGetToken, ApiError } from \"./http\";\n\n// ---------------------------------------------------------------------------\n// GET /api/glossary/:termId/discussions — read discussion thread\n// ---------------------------------------------------------------------------\n\n/**\n * Fetches the discussion thread for a term. Public read — no JWT required,\n * but a token will be forwarded if provided.\n */\nexport async function getDiscussions(\n config: UnnoodleConfig,\n termId: number,\n userToken?: string | null,\n): Promise<DiscussionPost[]> {\n const url = `${resolvedBaseUrl(config)}/api/glossary/${termId}/discussions`;\n const headers: Record<string, string> = apiKeyHeaders(config);\n const token = userToken !== undefined ? userToken : safeGetToken(config);\n if (token) headers[\"Authorization\"] = `Bearer ${token}`;\n\n const response = await fetch(url, { headers });\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle discussions error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n return response.json() as Promise<DiscussionPost[]>;\n}\n\n// ---------------------------------------------------------------------------\n// POST /api/glossary/:termId/discussions — post a comment (requires JWT)\n// ---------------------------------------------------------------------------\n\n/**\n * Posts a comment (question) on a term. Requires a valid user JWT.\n */\nexport async function postComment(\n config: UnnoodleConfig,\n termId: number,\n body: string,\n userToken: string,\n): Promise<DiscussionPost> {\n const url = `${resolvedBaseUrl(config)}/api/glossary/${termId}/discussions`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ body }),\n });\n if (!response.ok) {\n const bodyText = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle post comment error: ${response.status} ${response.statusText}`,\n response.status,\n bodyText,\n );\n }\n return response.json() as Promise<DiscussionPost>;\n}\n\n// ---------------------------------------------------------------------------\n// PUT /api/glossary/:termId — edit a term (requires JWT + MEMBER/ADMIN role)\n// ---------------------------------------------------------------------------\n\n/**\n * Updates an existing glossary term. Requires a valid user JWT.\n * The server enforces that the caller has MEMBER or ADMIN role.\n */\nexport async function updateTerm(\n config: UnnoodleConfig,\n termId: number,\n updates: GlossaryTermUpdateRequest,\n userToken: string,\n): Promise<GlossaryTerm> {\n const url = `${resolvedBaseUrl(config)}/api/glossary/${termId}`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n const response = await fetch(url, {\n method: \"PUT\",\n headers,\n body: JSON.stringify(updates),\n });\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle update term error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n return response.json() as Promise<GlossaryTerm>;\n}\n\n// ---------------------------------------------------------------------------\n// POST /api/sdk/glossary/ai-generate — generate an AI definition for a term\n// ---------------------------------------------------------------------------\n\n/**\n * Requests an AI-generated definition for a candidate term.\n * Requires both API key (for tenant context) and user JWT (write gate).\n * Does NOT persist anything — backend returns definition only.\n */\nexport async function generateAiDefinition(\n config: UnnoodleConfig,\n term: string,\n pageContext: string,\n pageUrl: string,\n userToken: string,\n): Promise<string> {\n const url = `${resolvedBaseUrl(config)}/api/sdk/glossary/ai-generate`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ term, context: pageContext, pageUrl }),\n });\n } catch (err) {\n throw new ApiError(\n err instanceof Error ? err.message : \"Network error\",\n 0,\n \"\",\n );\n }\n\n if (!response.ok) {\n const bodyText = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle ai-generate error: ${response.status} ${response.statusText}`,\n response.status,\n bodyText,\n );\n }\n\n const data = (await response.json()) as { definition: string };\n return data.definition;\n}\n\n// ---------------------------------------------------------------------------\n// POST /api/contexts/:contextId/glossary — submit a suggested term (PENDING)\n// ---------------------------------------------------------------------------\n\n/**\n * Submits a user-reviewed AI-generated definition as a PENDING term.\n * Requires user JWT. The term will await workspace admin approval.\n */\nexport async function createSuggestedTerm(\n config: UnnoodleConfig,\n contextId: number,\n term: string,\n definition: string,\n userToken: string,\n): Promise<GlossaryTerm> {\n const url = `${resolvedBaseUrl(config)}/api/contexts/${contextId}/glossary`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n term,\n definition,\n status: \"PENDING\",\n aiGenerated: true,\n }),\n });\n } catch (err) {\n throw new ApiError(\n err instanceof Error ? err.message : \"Network error\",\n 0,\n \"\",\n );\n }\n\n if (!response.ok) {\n const bodyText = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle create suggested term error: ${response.status} ${response.statusText}`,\n response.status,\n bodyText,\n );\n }\n\n return response.json() as Promise<GlossaryTerm>;\n}\n\n// ---------------------------------------------------------------------------\n// POST /api/contexts/:contextId/glossary — create a new glossary term (user)\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a new glossary term (ACTIVE status, not AI-generated).\n * Requires user JWT.\n */\nexport async function createGlossaryTerm(\n config: UnnoodleConfig,\n contextId: number,\n term: string,\n definition: string,\n userToken: string,\n): Promise<GlossaryTerm> {\n const url = `${resolvedBaseUrl(config)}/api/contexts/${contextId}/glossary`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ term, definition }),\n });\n } catch (err) {\n throw new ApiError(\n err instanceof Error ? err.message : \"Network error\",\n 0,\n \"\",\n );\n }\n\n if (!response.ok) {\n const bodyText = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle create glossary term error: ${response.status} ${response.statusText}`,\n response.status,\n bodyText,\n );\n }\n\n return response.json() as Promise<GlossaryTerm>;\n}\n","import type {\n UnnoodleConfig,\n CreateProductMemoryPayload,\n AddProductMemoryEntryPayload,\n UpdateProductMemoryEntryPayload,\n UpdateProductMemoryTitlePayload,\n ProductMemoryDetailResponse,\n ProductMemoryResponse,\n ProductMemoriesPageResponse,\n} from \"../types/config\";\nimport { resolvedBaseUrl, apiKeyHeaders, safeGetToken, ApiError } from \"./http\";\n\n// ---------------------------------------------------------------------------\n// POST /api/product-memories — create memory with first entry\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a new ProductMemory with title + first stage entry.\n */\nexport async function createProductMemory(\n config: UnnoodleConfig,\n payload: CreateProductMemoryPayload,\n userToken: string,\n): Promise<ProductMemoryDetailResponse> {\n const url = `${resolvedBaseUrl(config)}/api/product-memories`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(payload),\n });\n } catch (err) {\n throw new ApiError(\n err instanceof Error ? err.message : \"Network error\",\n 0,\n \"\",\n );\n }\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle create-product-memory error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n\n return response.json() as Promise<ProductMemoryDetailResponse>;\n}\n\n// ---------------------------------------------------------------------------\n// POST /api/product-memories/:id/entries — add a stage entry\n// ---------------------------------------------------------------------------\n\nexport async function addProductMemoryEntry(\n config: UnnoodleConfig,\n memoryId: number,\n payload: AddProductMemoryEntryPayload,\n userToken: string,\n): Promise<ProductMemoryDetailResponse> {\n const url = `${resolvedBaseUrl(config)}/api/product-memories/${memoryId}/entries`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle add-entry error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n\n return response.json() as Promise<ProductMemoryDetailResponse>;\n}\n\n// ---------------------------------------------------------------------------\n// PATCH /api/product-memories/:id/entries/:entryId — update explanation\n// ---------------------------------------------------------------------------\n\nexport async function updateProductMemoryEntry(\n config: UnnoodleConfig,\n memoryId: number,\n entryId: number,\n payload: UpdateProductMemoryEntryPayload,\n userToken: string,\n): Promise<ProductMemoryDetailResponse> {\n const url = `${resolvedBaseUrl(config)}/api/product-memories/${memoryId}/entries/${entryId}`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n const response = await fetch(url, {\n method: \"PATCH\",\n headers,\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle update-entry error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n\n return response.json() as Promise<ProductMemoryDetailResponse>;\n}\n\n// ---------------------------------------------------------------------------\n// PATCH /api/product-memories/:id — rename memory\n// ---------------------------------------------------------------------------\n\nexport async function updateProductMemoryTitle(\n config: UnnoodleConfig,\n id: number,\n payload: UpdateProductMemoryTitlePayload,\n userToken: string,\n): Promise<ProductMemoryDetailResponse> {\n const url = `${resolvedBaseUrl(config)}/api/product-memories/${id}`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n const response = await fetch(url, {\n method: \"PATCH\",\n headers,\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle rename-memory error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n\n return response.json() as Promise<ProductMemoryDetailResponse>;\n}\n\n// ---------------------------------------------------------------------------\n// GET /api/product-memories?page= — paginated list\n// ---------------------------------------------------------------------------\n\nexport async function listProductMemories(\n config: UnnoodleConfig,\n page: number,\n userToken?: string | null,\n): Promise<ProductMemoriesPageResponse> {\n const url = `${resolvedBaseUrl(config)}/api/product-memories?page=${page}&size=20`;\n const headers: Record<string, string> = { ...apiKeyHeaders(config) };\n const token = userToken !== undefined ? userToken : safeGetToken(config);\n\n if (token) {\n headers[\"Authorization\"] = `Bearer ${token}`;\n }\n\n const response = await fetch(url, { headers });\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle list-memories error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n\n return response.json() as Promise<ProductMemoriesPageResponse>;\n}\n\n// ---------------------------------------------------------------------------\n// GET /api/product-memories/:id — full detail\n// ---------------------------------------------------------------------------\n\nexport async function getProductMemory(\n config: UnnoodleConfig,\n id: number,\n userToken?: string | null,\n): Promise<ProductMemoryDetailResponse> {\n const url = `${resolvedBaseUrl(config)}/api/product-memories/${id}`;\n const headers: Record<string, string> = { ...apiKeyHeaders(config) };\n\n if (userToken) {\n headers[\"Authorization\"] = `Bearer ${userToken}`;\n }\n\n const response = await fetch(url, { headers });\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle get-memory error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n\n return response.json() as Promise<ProductMemoryDetailResponse>;\n}\n\n// ---------------------------------------------------------------------------\n// DELETE /api/product-memories/:id — delete memory\n// ---------------------------------------------------------------------------\n\nexport async function deleteProductMemory(\n config: UnnoodleConfig,\n memoryId: number,\n userToken: string,\n): Promise<void> {\n const url = `${resolvedBaseUrl(config)}/api/product-memories/${memoryId}`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n const response = await fetch(url, { method: \"DELETE\", headers });\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle delete-memory error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n // 204 No Content — no body to parse\n}\n\n// ---------------------------------------------------------------------------\n// DELETE /api/product-memories/:id/entries/:entryId — delete entry\n// ---------------------------------------------------------------------------\n\nexport async function deleteProductMemoryEntry(\n config: UnnoodleConfig,\n memoryId: number,\n entryId: number,\n userToken: string,\n): Promise<ProductMemoryDetailResponse> {\n const url = `${resolvedBaseUrl(config)}/api/product-memories/${memoryId}/entries/${entryId}`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n const response = await fetch(url, { method: \"DELETE\", headers });\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle delete-entry error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n\n return response.json() as Promise<ProductMemoryDetailResponse>;\n}\n","import type { UnnoodleConfig, ContextDiscussion } from \"../types/config\";\nimport { resolvedBaseUrl, apiKeyHeaders, safeGetToken, ApiError } from \"./http\";\n\n// ---------------------------------------------------------------------------\n// GET /api/contexts/:contextId/discussions — context-level clarification thread\n// ---------------------------------------------------------------------------\n\n/**\n * Fetches the full clarification thread for a context.\n * Readable by SDK API keys and authenticated users alike.\n */\nexport async function fetchContextDiscussions(\n config: UnnoodleConfig,\n contextId: number,\n userToken?: string | null,\n): Promise<ContextDiscussion[]> {\n const url = `${resolvedBaseUrl(config)}/api/contexts/${contextId}/discussions`;\n const headers: Record<string, string> = apiKeyHeaders(config);\n const token = userToken !== undefined ? userToken : safeGetToken(config);\n if (token) headers[\"Authorization\"] = `Bearer ${token}`;\n\n const response = await fetch(url, { headers });\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle GET context discussions error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n return response.json() as Promise<ContextDiscussion[]>;\n}\n\n// ---------------------------------------------------------------------------\n// POST /api/contexts/:contextId/discussions — post a clarification question\n// ---------------------------------------------------------------------------\n\n/**\n * Posts a new top-level clarification question on a context.\n * Requires a logged-in user JWT — SDK API keys are rejected by the backend.\n */\nexport async function postContextDiscussion(\n config: UnnoodleConfig,\n contextId: number,\n body: string,\n userToken: string,\n): Promise<ContextDiscussion> {\n const url = `${resolvedBaseUrl(config)}/api/contexts/${contextId}/discussions`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ body }),\n });\n\n if (!response.ok) {\n const responseBody = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle POST context discussion error: ${response.status} ${response.statusText}`,\n response.status,\n responseBody,\n );\n }\n return response.json() as Promise<ContextDiscussion>;\n}\n\n// ---------------------------------------------------------------------------\n// POST /api/contexts/:contextId/discussions/:questionId/replies\n// ---------------------------------------------------------------------------\n\n/**\n * Posts a reply to an existing clarification question.\n * Requires a logged-in user JWT.\n */\nexport async function postContextReply(\n config: UnnoodleConfig,\n contextId: number,\n questionId: number,\n body: string,\n userToken: string,\n): Promise<ContextDiscussion> {\n const url = `${resolvedBaseUrl(config)}/api/contexts/${contextId}/discussions/${questionId}/replies`;\n const headers: Record<string, string> = {\n ...apiKeyHeaders(config),\n Authorization: `Bearer ${userToken}`,\n };\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ body }),\n });\n\n if (!response.ok) {\n const responseBody = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle POST context reply error: ${response.status} ${response.statusText}`,\n response.status,\n responseBody,\n );\n }\n return response.json() as Promise<ContextDiscussion>;\n}\n","/**\n * Ask endpoints — LQ-12 / LLD §13.2. Mirrors the shape of `memories.ts`:\n * `resolvedBaseUrl` + `apiKeyHeaders`, `Authorization` from `safeGetToken`,\n * `ApiError` on every non-2xx.\n *\n * The only two statuses the view needs to tell apart are mapped to typed\n * errors so the retry/backoff policy lives in the controller, not in a string\n * comparison: 429 (`AskRateLimitedError`) and 503 (`AskBusyError`), both\n * carrying `Retry-After` in seconds.\n */\nimport type { UnnoodleConfig } from \"../types/config\";\nimport type { AskAnswer, AskStatus } from \"../types/ask\";\nimport { resolvedBaseUrl, apiKeyHeaders, safeGetToken, ApiError } from \"./http\";\n\n/** 429 — per-tenant minute or day bucket exhausted (E-Q2). */\nexport class AskRateLimitedError extends ApiError {\n public readonly retryAfter: number;\n constructor(body: string, retryAfter: number) {\n super(\"Ask rate limited\", 429, body);\n this.name = \"AskRateLimitedError\";\n this.retryAfter = retryAfter;\n }\n}\n\n/** 503 — bulkhead full, ask disabled, or spend cap (E-Q3). Retryable once. */\nexport class AskBusyError extends ApiError {\n public readonly retryAfter: number;\n constructor(body: string, retryAfter: number) {\n super(\"Ask unavailable\", 503, body);\n this.name = \"AskBusyError\";\n this.retryAfter = retryAfter;\n }\n}\n\n/** HLD §10.3: the Panel gives up on a question after 15 s. */\nexport const ASK_TIMEOUT_MS = 15_000;\n\nfunction askHeaders(\n config: UnnoodleConfig,\n userToken?: string | null,\n): Record<string, string> {\n const headers: Record<string, string> = apiKeyHeaders(config);\n const token = userToken !== undefined ? userToken : safeGetToken(config);\n if (token) headers[\"Authorization\"] = `Bearer ${token}`;\n return headers;\n}\n\nfunction retryAfterSeconds(response: Response): number {\n const raw = Number(response.headers.get(\"Retry-After\") ?? \"0\");\n return Number.isFinite(raw) && raw > 0 ? raw : 0;\n}\n\n// ---------------------------------------------------------------------------\n// POST /api/ask — ask a question about the product\n// ---------------------------------------------------------------------------\n\n/**\n * Asks one question. Always resolves to an `AskAnswer` or throws:\n * `AskRateLimitedError` (429), `AskBusyError` (503), `ApiError` for any other\n * non-2xx or for a network failure/timeout (`status: 0`), or a DOMException\n * named `AbortError` when the CALLER's signal aborted (view closed) — the\n * caller distinguishes that case and stays silent (R4-16).\n *\n * The internal 15 s deadline never surfaces as an AbortError: a timeout is a\n * condition the user should see, an abort is not.\n */\nexport async function askQuestion(\n config: UnnoodleConfig,\n question: string,\n pageUrl: string,\n userToken?: string | null,\n signal?: AbortSignal,\n): Promise<AskAnswer> {\n const url = `${resolvedBaseUrl(config)}/api/ask`;\n const headers = askHeaders(config, userToken);\n\n const ctrl = new AbortController();\n let timedOut = false;\n const timer = setTimeout(() => {\n timedOut = true;\n ctrl.abort();\n }, ASK_TIMEOUT_MS);\n\n // The LLD's rev-1 snippet accepted `signal` and then ignored it, so closing\n // the view left the request running. Chain it onto the internal controller.\n const forwardAbort = () => ctrl.abort();\n if (signal) {\n if (signal.aborted) ctrl.abort();\n else signal.addEventListener(\"abort\", forwardAbort);\n }\n\n try {\n let response: Response;\n try {\n response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ question, pageUrl }),\n signal: ctrl.signal,\n });\n } catch (err) {\n if (signal?.aborted && !timedOut) throw err; // caller aborted — stay silent\n if (timedOut) throw new ApiError(\"Ask timed out\", 0, \"\");\n throw new ApiError(err instanceof Error ? err.message : \"Network error\", 0, \"\");\n }\n\n if (response.ok) return (await response.json()) as AskAnswer;\n\n const body = await response.text().catch(() => \"\");\n if (response.status === 429) {\n throw new AskRateLimitedError(body, retryAfterSeconds(response));\n }\n if (response.status === 503) {\n throw new AskBusyError(body, retryAfterSeconds(response));\n }\n throw new ApiError(\n `Unnoodle ask error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n } finally {\n clearTimeout(timer);\n if (signal) signal.removeEventListener(\"abort\", forwardAbort);\n }\n}\n\n// ---------------------------------------------------------------------------\n// GET /api/ask/status — graph freshness and remaining limits\n// ---------------------------------------------------------------------------\n\n/**\n * Page-load call. E-Q13 guarantees the server never 5xxes here and reports a\n * disabled tenant as a 200 with `enabled:false` — so a thrown error from this\n * function means transport or auth, never \"ask is off\".\n */\nexport async function getAskStatus(\n config: UnnoodleConfig,\n userToken?: string | null,\n): Promise<AskStatus> {\n const url = `${resolvedBaseUrl(config)}/api/ask/status`;\n const headers = askHeaders(config, userToken);\n\n let response: Response;\n try {\n response = await fetch(url, { headers });\n } catch (err) {\n throw new ApiError(err instanceof Error ? err.message : \"Network error\", 0, \"\");\n }\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new ApiError(\n `Unnoodle ask-status error: ${response.status} ${response.statusText}`,\n response.status,\n body,\n );\n }\n return response.json() as Promise<AskStatus>;\n}\n","/**\n * elementSnapshot\n *\n * Single responsibility:\n * Capture a frozen, self-contained visual representation of a live\n * DOM element — without touching the host application.\n *\n * Strategy (Option A — deep clone + inline computed styles):\n * 1. Clone the element subtree.\n * 2. Walk every node in the clone and copy window.getComputedStyle() as\n * inline styles so the clone is visually independent of host stylesheets.\n * 3. Absolutify relative image src values so images still load when the\n * clone is rendered inside the panel Shadow DOM.\n * 4. Return the clone's outerHTML alongside structured metadata.\n *\n * Known limitations (all browsers, by design):\n * - Host @font-face fonts fall back to the system font inside Shadow DOM.\n * - <canvas> contents render blank (canvas pixel data is not clonable).\n * - Interactive state (:hover, :focus) is not preserved — frozen snapshot.\n */\n\n// ---------------------------------------------------------------------------\n// Public contracts\n// ---------------------------------------------------------------------------\n\n/**\n * Structured representation of a captured DOM element.\n * The `html` field contains the style-inlined clone; all other fields\n * provide machine-readable metadata for storage and display.\n */\nexport interface ElementSnapshot {\n /** outerHTML of the style-inlined clone — safe to inject into a container. */\n html: string;\n /** Original element width in CSS pixels at time of capture. */\n naturalWidth: number;\n /** Original element height in CSS pixels at time of capture. */\n naturalHeight: number;\n /** Lower-case tag name, e.g. \"button\", \"section\", \"div\". */\n tag: string;\n /** ARIA role — explicit attribute value, or inferred from tag. Null if unknown. */\n role: string | null;\n /** Trimmed visible text content of the element and its descendants. */\n text: string;\n /** Bounding rect in viewport coordinates at time of capture. */\n rect: DOMRect;\n /** Element's id attribute — most stable identifier for targeting. Undefined if absent. */\n id?: string;\n /** Element's data-testid attribute — second-most stable identifier. Undefined if absent. */\n dataTestId?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Role inference\n// ---------------------------------------------------------------------------\n\n/** Implicit ARIA roles for common HTML tags (subset covering most business UI). */\nconst IMPLICIT_ROLES: Record<string, string> = {\n button: \"button\",\n a: \"link\",\n input: \"textbox\",\n select: \"listbox\",\n textarea: \"textbox\",\n img: \"img\",\n table: \"table\",\n nav: \"navigation\",\n main: \"main\",\n header: \"banner\",\n footer: \"contentinfo\",\n aside: \"complementary\",\n section: \"region\",\n form: \"form\",\n h1: \"heading\",\n h2: \"heading\",\n h3: \"heading\",\n h4: \"heading\",\n h5: \"heading\",\n h6: \"heading\",\n li: \"listitem\",\n ul: \"list\",\n ol: \"list\",\n};\n\nfunction inferRole(el: HTMLElement): string | null {\n const explicit = el.getAttribute(\"role\");\n if (explicit) return explicit;\n return IMPLICIT_ROLES[el.tagName.toLowerCase()] ?? null;\n}\n\n// ---------------------------------------------------------------------------\n// Style inlining\n// ---------------------------------------------------------------------------\n\n/**\n * Copy all computed style properties from a live element onto its clone node.\n * This makes the clone visually self-contained — it no longer needs the host\n * app's stylesheets to look correct.\n */\nfunction inlineComputedStyles(source: Element, clone: Element): void {\n if (!(source instanceof HTMLElement) || !(clone instanceof HTMLElement))\n return;\n\n const computed = window.getComputedStyle(source);\n for (const prop of Array.from(computed)) {\n try {\n clone.style.setProperty(prop, computed.getPropertyValue(prop));\n } catch {\n // Some properties are read-only in certain browsers — skip silently.\n }\n }\n}\n\n/**\n * Recursively inline computed styles on an element and all its descendants.\n * Source and clone trees must have identical structure (produced by cloneNode).\n */\nfunction inlineStylesDeep(source: Element, clone: Element): void {\n inlineComputedStyles(source, clone);\n\n const sourceChildren = source.children;\n const cloneChildren = clone.children;\n\n for (let i = 0; i < sourceChildren.length; i++) {\n const srcChild = sourceChildren[i];\n const clnChild = cloneChildren[i];\n if (srcChild && clnChild) {\n inlineStylesDeep(srcChild, clnChild);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// URL absolutification\n// ---------------------------------------------------------------------------\n\n/**\n * Convert relative src/href values on media elements to absolute URLs so\n * they continue to load when rendered inside the panel's Shadow DOM.\n */\nfunction absolutifyUrls(clone: Element): void {\n clone.querySelectorAll(\"img[src]\").forEach((img) => {\n const src = img.getAttribute(\"src\");\n if (src && !src.startsWith(\"http\") && !src.startsWith(\"data:\")) {\n try {\n img.setAttribute(\"src\", new URL(src, window.location.href).href);\n } catch {\n // Malformed URL — leave as-is.\n }\n }\n });\n\n clone.querySelectorAll(\"source[srcset]\").forEach((source) => {\n const srcset = source.getAttribute(\"srcset\");\n if (srcset) {\n const resolved = srcset\n .split(\",\")\n .map((part) => {\n const [url, descriptor] = part.trim().split(/\\s+/);\n if (!url || url.startsWith(\"http\") || url.startsWith(\"data:\"))\n return part;\n try {\n const abs = new URL(url, window.location.href).href;\n return descriptor ? `${abs} ${descriptor}` : abs;\n } catch {\n return part;\n }\n })\n .join(\", \");\n source.setAttribute(\"srcset\", resolved);\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Defensive pre-send strip\n// ---------------------------------------------------------------------------\n\n/**\n * Removes executable content from a DOM clone before the HTML string is\n * handed off to the server. This is defense-in-depth only — the authoritative\n * sanitization happens server-side in SnapshotHtmlSanitizer.\n *\n * Operates on the clone (mutates it), never touches the source element.\n */\nfunction defensiveStrip(clone: HTMLElement): void {\n // Remove all <script> elements\n clone.querySelectorAll(\"script\").forEach((s) => s.remove());\n\n // Remove on* event-handler attributes from every element in the subtree\n const all = [clone, ...Array.from(clone.querySelectorAll(\"*\"))];\n for (const el of all) {\n const toRemove: string[] = [];\n for (const attr of Array.from(el.attributes)) {\n if (/^on/i.test(attr.name)) toRemove.push(attr.name);\n }\n toRemove.forEach((name) => el.removeAttribute(name));\n }\n}\n\n// ---------------------------------------------------------------------------\n// Main export\n// ---------------------------------------------------------------------------\n\n/**\n * Captures a frozen snapshot of the given element.\n *\n * The returned `html` string contains a style-inlined clone that renders\n * visually near-identically to the original element, with no dependency on\n * the host application's stylesheets.\n *\n * @param el The live host-app element to snapshot. Must be attached to DOM.\n */\nexport function snapshotElement(el: HTMLElement): ElementSnapshot {\n const rect = el.getBoundingClientRect();\n\n // Deep clone (true = include all descendants)\n const clone = el.cloneNode(true) as HTMLElement;\n\n // Inline all computed styles recursively\n inlineStylesDeep(el, clone);\n\n // Resolve relative media URLs\n absolutifyUrls(clone);\n\n // Defense-in-depth: strip executable content before returning the HTML string\n defensiveStrip(clone);\n\n return {\n html: clone.outerHTML,\n naturalWidth: rect.width,\n naturalHeight: rect.height,\n tag: el.tagName.toLowerCase(),\n role: inferRole(el),\n text: (el.textContent ?? \"\").trim().replace(/\\s+/g, \" \"),\n rect,\n id: el.id || undefined,\n dataTestId: el.getAttribute(\"data-testid\") || undefined,\n };\n}\n","/**\n * ElementPicker\n *\n * Single responsibility:\n * Let the user select any element on the host application by hovering\n * and clicking — without modifying the host application's DOM or code.\n *\n * Behaviour:\n * - On start(): attaches mouseover + click listeners to document.\n * - A floating highlight ring (position:fixed) tracks the hovered element.\n * - On click: fires onPick(element), removes all listeners and the ring.\n * - Guards: the Unnoodle panel host and the highlight ring itself are\n * excluded from selection so the user cannot accidentally pick our own UI.\n * - stop(): externally cancels pick mode and cleans up.\n *\n * Zero coupling to panel, API, or state machine — purely a DOM interaction\n * tool that reports back via callbacks.\n */\n\n// ---------------------------------------------------------------------------\n// Public contracts\n// ---------------------------------------------------------------------------\n\nexport interface ElementPickerCallbacks {\n /** Fired when the user clicks an element. Picker has already torn itself down. */\n onPick: (element: HTMLElement) => void;\n /** Fired when stop() is called externally (user cancelled). */\n onCancel: () => void;\n}\n\nexport interface IElementPicker {\n /** Begin pick mode — attaches listeners and renders highlight ring. */\n start(): void;\n /** End pick mode — removes listeners and highlight ring, fires onCancel. */\n stop(): void;\n}\n\n// ---------------------------------------------------------------------------\n// Highlight ring styles\n// ---------------------------------------------------------------------------\n\nconst RING_ID = \"unnoodle-pick-ring\";\n\nconst RING_CSS = `\n position: fixed;\n pointer-events: none;\n z-index: 2147483645;\n border: 2px dashed #5C4EFA;\n border-radius: 4px;\n background: rgba(92, 78, 250, 0.06);\n transition: top 0.05s, left 0.05s, width 0.05s, height 0.05s;\n box-shadow: 0 0 0 9999px rgba(0,0,0,0.08);\n`;\n\n// IDs and class names belonging to the Unnoodle widget — never pick these.\nconst EXCLUDED_IDS = new Set([\n \"unnoodle-btn-host\",\n \"unnoodle-panel-host\",\n RING_ID,\n]);\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\nexport class ElementPicker implements IElementPicker {\n private callbacks: ElementPickerCallbacks;\n private ring: HTMLElement | null = null;\n private currentTarget: HTMLElement | null = null;\n\n // Bound references so the same function pointer can be removed\n private boundMouseover = this.handleMouseover.bind(this);\n private boundClick = this.handleClick.bind(this);\n private boundKeydown = this.handleKeydown.bind(this);\n\n constructor(callbacks: ElementPickerCallbacks) {\n this.callbacks = callbacks;\n }\n\n // ── Public API ────────────────────────────────────────────────────────────\n\n start(): void {\n this.createRing();\n document.addEventListener(\"mouseover\", this.boundMouseover, true);\n document.addEventListener(\"click\", this.boundClick, true);\n document.addEventListener(\"keydown\", this.boundKeydown, true);\n }\n\n stop(): void {\n this.teardown();\n this.callbacks.onCancel();\n }\n\n // ── Internal ──────────────────────────────────────────────────────────────\n\n private createRing(): void {\n const ring = document.createElement(\"div\");\n ring.id = RING_ID;\n ring.setAttribute(\"data-testid\", \"unnoodle-pick-ring\");\n ring.style.cssText = RING_CSS;\n // Set critical properties explicitly so they are always readable,\n // even in environments (jsdom) that do not parse all cssText values.\n ring.style.pointerEvents = \"none\";\n ring.style.display = \"none\"; // hidden until first hover\n document.body.appendChild(ring);\n this.ring = ring;\n }\n\n private removeRing(): void {\n this.ring?.remove();\n this.ring = null;\n }\n\n private teardown(): void {\n document.removeEventListener(\"mouseover\", this.boundMouseover, true);\n document.removeEventListener(\"click\", this.boundClick, true);\n document.removeEventListener(\"keydown\", this.boundKeydown, true);\n this.removeRing();\n this.currentTarget = null;\n // Restore host-app cursor\n document.documentElement.style.removeProperty(\"cursor\");\n }\n\n private isExcluded(el: HTMLElement): boolean {\n // Walk up the tree — exclude if any ancestor is an Unnoodle host\n let node: HTMLElement | null = el;\n while (node) {\n if (EXCLUDED_IDS.has(node.id)) return true;\n node = node.parentElement;\n }\n return false;\n }\n\n private handleMouseover(e: Event): void {\n const el = e.target as HTMLElement;\n if (!el || this.isExcluded(el)) return;\n\n this.currentTarget = el;\n document.documentElement.style.cursor = \"crosshair\";\n\n if (!this.ring) return;\n const rect = el.getBoundingClientRect();\n this.ring.style.display = \"block\";\n this.ring.style.top = `${rect.top}px`;\n this.ring.style.left = `${rect.left}px`;\n this.ring.style.width = `${rect.width}px`;\n this.ring.style.height = `${rect.height}px`;\n }\n\n private handleClick(e: Event): void {\n const el = e.target as HTMLElement;\n if (!el || this.isExcluded(el)) return;\n\n // Prevent the host app from acting on this click\n e.preventDefault();\n e.stopPropagation();\n\n this.teardown();\n this.callbacks.onPick(el);\n }\n\n private handleKeydown(e: KeyboardEvent): void {\n // Escape cancels pick mode\n if (e.key === \"Escape\") {\n this.stop();\n }\n }\n}\n","/**\n * OverlayArrow\n *\n * Single responsibility:\n * Draw and manage a single dotted directed SVG arrow from a source rect\n * (panel edge) to a target rect (captured element on the host app),\n * rendered in a full-viewport fixed SVG overlay.\n *\n * Design decisions:\n * - One `<svg>` element is injected into document.body with\n * position:fixed, pointer-events:none, full viewport coverage.\n * - Arrow is a `<path>` with stroke-dasharray for the dotted effect,\n * plus a small arrowhead `<marker>`.\n * - update() recalculates the path from new rects (call on scroll/resize).\n * - remove() tears down the SVG and any listeners.\n * - Only one arrow at a time — calling draw() again replaces the previous.\n */\n\n// ---------------------------------------------------------------------------\n// Public contracts\n// ---------------------------------------------------------------------------\n\nexport interface IOverlayArrow {\n /** Draw the arrow. Replaces any previously drawn arrow. */\n draw(fromRect: DOMRect, toRect: DOMRect): void;\n /** Recalculate position (call on scroll / resize). */\n update(fromRect: DOMRect, toRect: DOMRect): void;\n /** Remove the SVG overlay from the DOM entirely. */\n remove(): void;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst SVG_ID = \"unnoodle-overlay-arrow\";\nconst ARROW_COLOR = \"#5C4EFA\";\nconst STROKE_WIDTH = 1.5;\nconst DASH = \"5 4\";\nconst MARKER_ID = \"unn-arrow-head\";\n\n// ---------------------------------------------------------------------------\n// Path computation\n// ---------------------------------------------------------------------------\n\n/**\n * Compute a smooth cubic bezier path between the panel edge and the target\n * element edge, choosing the shortest route based on which side the panel is on.\n *\n * - Panel on the LEFT → start: panel right edge → end: element left edge\n * - Panel on the RIGHT → start: panel left edge → end: element right edge\n *\n * orient=\"auto\" on the marker means the arrowhead rotates automatically to\n * match the path direction, so no extra marker changes are needed.\n */\nfunction computePath(from: DOMRect, to: DOMRect): string {\n const panelIsRight = from.left > to.right;\n\n // Start from the panel edge that faces the target element\n const x1 = panelIsRight ? from.left : from.right;\n const y1 = from.top + from.height / 2;\n\n // End at the target edge that faces the panel\n const x2 = panelIsRight ? to.right : to.left;\n const y2 = to.top + to.height / 2;\n\n // Control points — horizontal tension proportional to horizontal distance\n const tension = Math.abs(x2 - x1) * 0.4;\n const cx1 = panelIsRight ? x1 - tension : x1 + tension;\n const cx2 = panelIsRight ? x2 + tension : x2 - tension;\n\n return `M ${x1} ${y1} C ${cx1} ${y1}, ${cx2} ${y2}, ${x2} ${y2}`;\n}\n\n// ---------------------------------------------------------------------------\n// SVG construction\n// ---------------------------------------------------------------------------\n\nfunction buildSvg(): SVGSVGElement {\n const svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n svg.id = SVG_ID;\n svg.setAttribute(\"data-testid\", \"unnoodle-overlay-arrow\");\n svg.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n pointer-events: none;\n z-index: 2147483644;\n overflow: visible;\n `;\n\n // Arrowhead marker definition\n const defs = document.createElementNS(\"http://www.w3.org/2000/svg\", \"defs\");\n const marker = document.createElementNS(\n \"http://www.w3.org/2000/svg\",\n \"marker\",\n );\n marker.setAttribute(\"id\", MARKER_ID);\n marker.setAttribute(\"markerWidth\", \"8\");\n marker.setAttribute(\"markerHeight\", \"8\");\n marker.setAttribute(\"refX\", \"6\");\n marker.setAttribute(\"refY\", \"3\");\n marker.setAttribute(\"orient\", \"auto\");\n marker.setAttribute(\"markerUnits\", \"strokeWidth\");\n\n const arrowPolygon = document.createElementNS(\n \"http://www.w3.org/2000/svg\",\n \"polygon\",\n );\n arrowPolygon.setAttribute(\"points\", \"0 0, 6 3, 0 6\");\n arrowPolygon.setAttribute(\"fill\", ARROW_COLOR);\n marker.appendChild(arrowPolygon);\n defs.appendChild(marker);\n svg.appendChild(defs);\n\n // The path element — will be updated with computed coordinates\n const path = document.createElementNS(\"http://www.w3.org/2000/svg\", \"path\");\n path.setAttribute(\"data-testid\", \"unnoodle-arrow-path\");\n path.setAttribute(\"fill\", \"none\");\n path.setAttribute(\"stroke\", ARROW_COLOR);\n path.setAttribute(\"stroke-width\", String(STROKE_WIDTH));\n path.setAttribute(\"stroke-dasharray\", DASH);\n path.setAttribute(\"stroke-linecap\", \"round\");\n path.setAttribute(\"marker-end\", `url(#${MARKER_ID})`);\n svg.appendChild(path);\n\n return svg;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\nexport class OverlayArrow implements IOverlayArrow {\n private svg: SVGSVGElement | null = null;\n\n draw(fromRect: DOMRect, toRect: DOMRect): void {\n // Replace any previous arrow\n this.remove();\n\n const svg = buildSvg();\n const path = svg.querySelector(\"path\")!;\n path.setAttribute(\"d\", computePath(fromRect, toRect));\n\n document.body.appendChild(svg);\n this.svg = svg;\n }\n\n update(fromRect: DOMRect, toRect: DOMRect): void {\n if (!this.svg) return;\n const path = this.svg.querySelector(\"path\");\n if (path) {\n path.setAttribute(\"d\", computePath(fromRect, toRect));\n }\n }\n\n remove(): void {\n this.svg?.remove();\n this.svg = null;\n }\n}\n","/**\n * CaptureOrchestrator\n *\n * Single responsibility:\n * Sequence the single API call that constitutes a \"capture with meaning\":\n * POST /api/product-memories — creates a ProductMemory with title + first entry\n *\n * The class knows nothing about the UI (no DOM, no bar, no panel).\n * It is injected into CaptureModeController via the ICaptureOrchestrator\n * interface so it can be replaced with a stub in tests.\n */\n\nimport type {\n UnnoodleConfig,\n ProductMemoryDetailResponse,\n} from \"../../types/config\";\nimport type { ElementSnapshot } from \"./elementSnapshot\";\nimport { createProductMemory, addProductMemoryEntry } from \"../../core/apiClient\";\n\n// ---------------------------------------------------------------------------\n// Public contracts\n// ---------------------------------------------------------------------------\n\n/** Successful result of a capture-with-title operation. */\nexport interface CaptureOrchestratorResult {\n /** The created ProductMemory (title + first stage entry). */\n memory: ProductMemoryDetailResponse;\n}\n\n/** Stable interface so unit tests can inject a fake double. */\nexport interface ICaptureOrchestrator {\n execute(\n config: UnnoodleConfig,\n token: string,\n /** User-provided title for the new ProductMemory group (empty string for add-entry). */\n title: string,\n /** Explanation text describing what this UI element means. */\n explanation: string,\n /** The element snapshot produced by the browser-side pick flow. */\n elementSnapshot: ElementSnapshot,\n /** When true, start watching the element for DOM mutations after capture. */\n watchForChanges?: boolean,\n ): Promise<CaptureOrchestratorResult>;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\nexport class CaptureOrchestrator implements ICaptureOrchestrator {\n /**\n * Creates a ProductMemory with title + first entry in a single API call.\n * Both URL and timestamp are read from the browser context at call time.\n *\n * @param config Widget configuration (base URL, API key, …)\n * @param token Authenticated user JWT\n * @param title Human-authored title for the ProductMemory group\n * @param elementSnapshot Style-inlined outerHTML + metadata of the picked element\n */\n async execute(\n config: UnnoodleConfig,\n token: string,\n title: string,\n explanation: string,\n elementSnapshot: ElementSnapshot,\n watchForChanges = false,\n ): Promise<CaptureOrchestratorResult> {\n const memory = await createProductMemory(\n config,\n {\n title,\n explanation: explanation || title,\n snapshotHtml: elementSnapshot.html,\n url: window.location.href,\n pageTitle: document.title,\n capturedAt: new Date().toISOString(),\n targetingMetadata: {\n id: elementSnapshot.id,\n dataTestId: elementSnapshot.dataTestId,\n tag: elementSnapshot.tag,\n role: elementSnapshot.role,\n text: elementSnapshot.text,\n },\n watchForChanges,\n },\n token,\n );\n\n return { memory };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Add-entry variant — appends a new element snapshot to an existing memory\n// ---------------------------------------------------------------------------\n\n/**\n * Used when the user clicks \"Add Entry\" from a memory detail view.\n * Calls POST /api/product-memories/:id/entries instead of creating a new memory.\n */\nexport class AddEntryOrchestrator implements ICaptureOrchestrator {\n constructor(private readonly memoryId: number) {}\n\n async execute(\n config: UnnoodleConfig,\n token: string,\n /** Ignored for add-entry — title belongs to the existing memory. */\n _title: string,\n /** Explanation text typed in the capture form. */\n explanation: string,\n elementSnapshot: ElementSnapshot,\n ): Promise<CaptureOrchestratorResult> {\n const memory = await addProductMemoryEntry(\n config,\n this.memoryId,\n {\n explanation,\n snapshotHtml: elementSnapshot.html,\n url: window.location.href,\n pageTitle: document.title,\n capturedAt: new Date().toISOString(),\n targetingMetadata: {\n id: elementSnapshot.id,\n dataTestId: elementSnapshot.dataTestId,\n tag: elementSnapshot.tag,\n role: elementSnapshot.role,\n text: elementSnapshot.text,\n },\n },\n token,\n );\n\n return { memory };\n }\n}\n","/**\n * CaptureModeController\n *\n * Single responsibility:\n * Orchestrate the end-to-end \"capture UI + add meaning\" flow.\n *\n * State machine:\n * idle → picking → describing → saving → idle\n *\n * Dependencies are injected via interfaces — no direct imports of concrete\n * implementations — making every dependency swappable in tests.\n *\n * Panel (view) — renders UI states, fires events back via callbacks\n * ElementPicker (tool) — hover + click pick mode on host app\n * OverlayArrow (tool) — SVG dotted arrow from panel to picked element\n * Orchestrator (API) — sequences POST /ui-states → POST /product-memories\n */\n\nimport type { ElementSnapshot } from \"./elementSnapshot\";\nimport { snapshotElement } from \"./elementSnapshot\";\nimport type { IElementPicker } from \"./elementPicker\";\nimport type { IOverlayArrow } from \"./overlayArrow\";\nimport type { ICaptureOrchestrator } from \"./captureOrchestrator\";\nimport type { UnnoodleConfig, GlossaryTerm } from \"../../types/config\";\n\n// ---------------------------------------------------------------------------\n// Panel interface — only what captureModeController needs to call\n// ---------------------------------------------------------------------------\n\n/**\n * The subset of PanelControls that CaptureModeController interacts with.\n * Defined here so panel.ts does not need to import this file.\n */\nexport interface CapturePanelControls {\n /** Show the \"click an element to select it\" prompt in the context-strip. */\n enterPickMode(onCancel: () => void): void;\n /**\n * Navigate the panel body to the describe-and-save view, showing the\n * captured element snapshot alongside a description textarea.\n */\n showCaptureDescribe(\n snapshot: ElementSnapshot,\n onSave: (description: string) => void,\n onPickAgain: () => void,\n ): void;\n /** Signal that saving is in progress (disable inputs). */\n setCaptureLoading(loading: boolean): void;\n /** Surface an error inside the describe view. */\n setCaptureError(message: string): void;\n /** Restore the panel to normal home view, context-strip to idle. */\n exitCaptureMode(): void;\n /** Restore the home view with the provided data */\n restoreHomeView(data: any): void;\n /** Brief toast notification. */\n showToast(message: string): void;\n /** The panel host element — used to compute the arrow source rect. */\n readonly element: HTMLElement;\n /** Show full-screen form for creating a new memory */\n showNewMemoryForm(\n onPickElement: () => void,\n onCancelCapture: () => void,\n onSave: (\n title: string,\n explanation: string,\n watchForChanges: boolean,\n ) => void,\n onCancel: () => void,\n ): void;\n /** Show full-screen form for adding entry to existing memory */\n showAddEntryForm(\n memoryTitle: string,\n onPickElement: () => void,\n onCancelCapture: () => void,\n onSave: (explanation: string) => void,\n onCancel: () => void,\n ): void;\n /** Update the snapshot preview in the currently open form */\n updateFormSnapshot(snapshot: ElementSnapshot): void;\n /** Set form picking mode visual state */\n setFormPickingMode(enabled: boolean): void;\n}\n\n// ---------------------------------------------------------------------------\n// State type\n// ---------------------------------------------------------------------------\n\ntype CaptureState = \"idle\" | \"form-open\" | \"picking\" | \"saving\";\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\nexport class CaptureModeController {\n private state: CaptureState = \"idle\";\n private pickedElement: HTMLElement | null = null;\n private snapshot: ElementSnapshot | null = null;\n private scrollHandler: (() => void) | null = null;\n private resizeHandler: (() => void) | null = null;\n private homeData: any = null;\n\n constructor(\n private readonly panel: CapturePanelControls,\n private readonly picker: IElementPicker,\n private readonly arrow: IOverlayArrow,\n private readonly orchestrator: ICaptureOrchestrator,\n private readonly config: UnnoodleConfig,\n private readonly getToken: () => string | null,\n private readonly getGlossary: () => GlossaryTerm[],\n private readonly onSaveComplete?: () => void,\n private readonly mode:\n | { type: \"new-memory\" }\n | { type: \"add-entry\"; memoryTitle: string } = { type: \"new-memory\" },\n ) {}\n\n // ── Public API ─────────────────────────────────────────────────────────────\n\n /**\n * Store the home data so we can restore it after capture\n */\n setHomeData(data: any): void {\n this.homeData = data;\n }\n\n /**\n * Begin the capture flow — idempotent if already active.\n * Transitions: idle → form-open\n */\n start(): void {\n console.log(\"[unnoodle] CaptureModeController.start() called\", {\n state: this.state,\n mode: this.mode,\n });\n\n if (this.state !== \"idle\") return;\n this.state = \"form-open\";\n\n if (this.mode.type === \"new-memory\") {\n this.panel.showNewMemoryForm(\n () => {\n console.log(\"[unnoodle] Pick element callback triggered\");\n this.onPickElementClicked();\n },\n () => {\n console.log(\"[unnoodle] Cancel capture callback triggered\");\n this.onCancelCapture();\n },\n (title: string, explanation: string, watchForChanges: boolean) => {\n console.log(\"[unnoodle] Save callback triggered\", {\n title,\n explanation,\n watchForChanges,\n });\n void this.onSaveWithTitle(title, explanation, watchForChanges);\n },\n () => {\n console.log(\"[unnoodle] Cancel callback triggered\");\n this.cancel();\n },\n );\n } else {\n // Add entry mode\n this.panel.showAddEntryForm(\n this.mode.memoryTitle,\n () => {\n console.log(\n \"[unnoodle] Pick element callback triggered (add entry mode)\",\n );\n this.onPickElementClicked();\n },\n () => {\n console.log(\n \"[unnoodle] Cancel capture callback triggered (add entry mode)\",\n );\n this.onCancelCapture();\n },\n (explanation: string) => {\n console.log(\"[unnoodle] Save callback triggered (add entry mode)\", {\n explanation,\n });\n void this.onSaveWithExplanation(explanation);\n },\n () => {\n console.log(\"[unnoodle] Cancel callback triggered (add entry mode)\");\n this.cancel();\n },\n );\n }\n }\n\n /**\n * Called by the ElementPicker when the user selects an element.\n * Public so the picker factory can reference it without closure hacks.\n * Treat as internal — call only from ElementPicker.onPick.\n */\n _onElementPicked(el: HTMLElement): void {\n this.onElementPicked(el);\n }\n\n /**\n * Abort any active capture flow and return to idle.\n * Safe to call from any state.\n */\n cancel(): void {\n console.log(\"[unnoodle] cancel() called, current state:\", this.state);\n this.cleanup();\n console.log(\"[unnoodle] Restoring home view after cancel\");\n // Instead of exitCaptureMode (which is for strip-based UI), restore the home view\n if (this.homeData) {\n this.panel.restoreHomeView(this.homeData);\n } else {\n this.panel.exitCaptureMode();\n }\n console.log(\"[unnoodle] Calling onSaveComplete to reload home memories\");\n this.onSaveComplete?.();\n console.log(\"[unnoodle] cancel() completed\");\n }\n\n // ── Internal state transitions ─────────────────────────────────────────────\n\n private onPickElementClicked(): void {\n if (this.state !== \"form-open\") return;\n this.state = \"picking\";\n this.panel.setFormPickingMode(true);\n this.picker.start();\n }\n\n onCancelCapture(): void {\n console.log(\n \"[unnoodle] onCancelCapture() called, current state:\",\n this.state,\n );\n if (this.state === \"picking\") {\n this.state = \"form-open\";\n this.panel.setFormPickingMode(false);\n console.log(\"[unnoodle] Exited picking mode, returned to form\");\n }\n }\n\n private onElementPicked(el: HTMLElement): void {\n console.log(\"[unnoodle] onElementPicked called\", {\n state: this.state,\n element: el,\n });\n if (this.state !== \"picking\") {\n console.log(\n \"[unnoodle] onElementPicked - wrong state, expected 'picking', got\",\n this.state,\n );\n return;\n }\n\n console.log(\"[unnoodle] onElementPicked - setting state to form-open\");\n this.state = \"form-open\";\n this.pickedElement = el;\n\n // Exit picking mode UI\n this.panel.setFormPickingMode(false);\n\n // Freeze a visual snapshot of the picked element\n console.log(\"[unnoodle] onElementPicked - creating snapshot\");\n this.snapshot = snapshotElement(el);\n console.log(\n \"[unnoodle] onElementPicked - snapshot created:\",\n this.snapshot,\n );\n\n // Update the form's snapshot preview\n console.log(\"[unnoodle] onElementPicked - updating form snapshot\");\n this.panel.updateFormSnapshot(this.snapshot);\n\n // Draw the dotted arrow from the panel edge to the element and keep it\n // tracking while the user scrolls or resizes the window.\n console.log(\"[unnoodle] onElementPicked - drawing arrow\");\n this.redrawArrow();\n this.startTrackingArrow();\n console.log(\"[unnoodle] onElementPicked completed, state:\", this.state);\n }\n\n private async onSaveWithTitle(\n title: string,\n explanation: string,\n watchForChanges: boolean,\n ): Promise<void> {\n await this.performSave(title, explanation, watchForChanges);\n }\n\n private async onSaveWithExplanation(explanation: string): Promise<void> {\n // For add-entry mode, title is empty since it's adding to existing memory\n await this.performSave(\"\", explanation, false);\n }\n\n private async performSave(\n title: string,\n explanation: string,\n watchForChanges: boolean,\n ): Promise<void> {\n console.log(\"[unnoodle] performSave called\", {\n title,\n explanation,\n state: this.state,\n snapshot: this.snapshot,\n });\n\n if (this.state !== \"form-open\") {\n console.log(\"[unnoodle] performSave - wrong state, returning\");\n return;\n }\n if (!this.snapshot) {\n console.log(\n \"[unnoodle] performSave - no snapshot, user didn't pick element, returning\",\n );\n // User clicked save without picking an element\n return;\n }\n\n this.state = \"saving\";\n console.log(\"[unnoodle] performSave - state set to saving, getting token\");\n\n const token = this.getToken();\n console.log(\"[unnoodle] performSave - token obtained:\", !!token);\n\n if (!token) {\n console.log(\n \"[unnoodle] performSave - no token, returning to form-open state\",\n );\n // This shouldn't happen as the form shouldn't be shown if not logged in\n this.state = \"form-open\";\n return;\n }\n\n try {\n console.log(\"[unnoodle] performSave - executing orchestrator\");\n await this.orchestrator.execute(\n this.config,\n token,\n title,\n explanation,\n this.snapshot,\n watchForChanges,\n );\n console.log(\"[unnoodle] performSave - orchestrator success, cleaning up\");\n this.cleanup();\n console.log(\"[unnoodle] Restoring home view after save\");\n // Instead of exitCaptureMode, restore the home view\n if (this.homeData) {\n this.panel.restoreHomeView(this.homeData);\n } else {\n this.panel.exitCaptureMode();\n }\n console.log(\"[unnoodle] Showing toast\");\n this.panel.showToast(\"Captured ✓\");\n console.log(\"[unnoodle] Calling onSaveComplete callback\");\n this.onSaveComplete?.();\n console.log(\"[unnoodle] performSave completed successfully\");\n } catch (error) {\n console.log(\"[unnoodle] performSave - orchestrator failed\", error);\n this.state = \"form-open\";\n // Error handling is now the responsibility of the form\n }\n }\n\n // ── Helpers ────────────────────────────────────────────────────────────────\n\n /**\n * Recalculate fresh rects and push them to arrow.update().\n * Called by scroll / resize listeners while the arrow is live.\n */\n private updateArrow(): void {\n if (!this.pickedElement) return;\n const panelShell =\n (this.panel.element.shadowRoot?.querySelector(\n \".panel-shell\",\n ) as HTMLElement | null) ?? this.panel.element;\n this.arrow.update(\n panelShell.getBoundingClientRect(),\n this.pickedElement.getBoundingClientRect(),\n );\n }\n\n /** Attach scroll + resize listeners that keep the arrow in sync. */\n private startTrackingArrow(): void {\n this.stopTrackingArrow(); // guard against double-registration\n const onUpdate = () => this.updateArrow();\n this.scrollHandler = onUpdate;\n this.resizeHandler = onUpdate;\n // capture:true catches scroll on any nested scrollable container\n window.addEventListener(\"scroll\", this.scrollHandler, {\n capture: true,\n passive: true,\n });\n window.addEventListener(\"resize\", this.resizeHandler, { passive: true });\n }\n\n /** Remove scroll + resize listeners (call before removing the arrow). */\n private stopTrackingArrow(): void {\n if (this.scrollHandler) {\n window.removeEventListener(\"scroll\", this.scrollHandler, {\n capture: true,\n });\n this.scrollHandler = null;\n }\n if (this.resizeHandler) {\n window.removeEventListener(\"resize\", this.resizeHandler);\n this.resizeHandler = null;\n }\n }\n\n private redrawArrow(): void {\n if (!this.pickedElement) return;\n // panel.element is the zero-size shadow host div (all:initial CSS makes it\n // have no layout dimensions). Use the .panel-shell inside the shadow root\n // which is the real fixed-position panel visible on screen.\n const panelShell =\n (this.panel.element.shadowRoot?.querySelector(\n \".panel-shell\",\n ) as HTMLElement | null) ?? this.panel.element;\n const panelRect = panelShell.getBoundingClientRect();\n const elementRect = this.pickedElement.getBoundingClientRect();\n this.arrow.draw(panelRect, elementRect);\n }\n\n private cleanup(): void {\n this.stopTrackingArrow();\n this.arrow.remove();\n this.pickedElement = null;\n this.snapshot = null;\n this.state = \"idle\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// Factory — wires concrete implementations together\n// ---------------------------------------------------------------------------\n\nimport { ElementPicker } from \"./elementPicker\";\nimport { OverlayArrow } from \"./overlayArrow\";\nimport { CaptureOrchestrator } from \"./captureOrchestrator\";\nimport type { ICaptureOrchestrator } from \"./captureOrchestrator\";\n\n/**\n * Construct a CaptureModeController with its standard concrete dependencies.\n * Called by WidgetController for both \"new memory\" and \"add entry\" flows.\n */\nexport function createCaptureModeController(\n panel: CapturePanelControls,\n config: UnnoodleConfig,\n getToken: () => string | null,\n getGlossary: () => GlossaryTerm[],\n onSaveComplete?: () => void,\n orchestratorOverride?: ICaptureOrchestrator,\n mode: { type: \"new-memory\" } | { type: \"add-entry\"; memoryTitle: string } = {\n type: \"new-memory\",\n },\n): CaptureModeController {\n const orchestrator = orchestratorOverride ?? new CaptureOrchestrator();\n\n const controller = new CaptureModeController(\n panel,\n new ElementPicker({\n onPick: (el) => controller._onElementPicked(el),\n onCancel: () => controller.onCancelCapture(),\n }),\n new OverlayArrow(),\n orchestrator,\n config,\n getToken,\n getGlossary,\n onSaveComplete,\n mode,\n );\n\n return controller;\n}\n","/**\n * Normalize CSS that may have been double-escaped by webpack's eval-source-map.\n *\n * When esbuild/tsup minifies the SDK it converts template-literal CSS strings\n * to regular JS string literals, representing newlines as the escape sequence\n * `\\n` (backslash + n) in source. In production / non-eval builds the browser\n * JS engine parses `\\n` → real newline and CSS is valid.\n *\n * But Next.js (and other webpack-based hosts) default to `eval-source-map` in\n * development, which wraps every module in `eval(\"…\")`. The serialisation step\n * must escape each `\\n` in the module source as `\\\\n` inside the eval string.\n * After eval(), the JS string then contains the two characters `\\` and `n` (not\n * a newline). The CSS parser reads `\\n` as an escaped identifier — effectively\n * `n` — prepending it to every rule selector and silently breaking all styles.\n *\n * This helper repairs that case at injection time. In the normal (non-eval)\n * path every `\\n` in the string IS already a real newline character (charCode\n * 10), so the regex `/\\\\n/g` (which matches literal backslash+n) never fires\n * and the function is a no-op.\n *\n * Apply this to every `style.textContent = …` call in the SDK that sets CSS.\n */\nexport function safeCSS(css: string): string {\n // Repair double-escaped sequences produced by webpack eval-source-map.\n // Only fires when the string contains literal backslash characters (the\n // eval-wrapped case). Real newlines/tabs are unaffected.\n return css.replace(/\\\\n/g, \"\\n\").replace(/\\\\t/g, \"\\t\");\n}\n","import { safeCSS } from \"./safeCSS\";\n\n/**\n * Renders the floating trigger button using Shadow DOM.\n * The button is draggable — position is stored in memory for the session\n * (never persisted to localStorage).\n * Returns a cleanup function that removes the element and all listeners.\n */\nexport function createButton(\n onTrigger: () => void,\n /**\n * A CSS `:host { … }` block containing --unn-* custom properties.\n * Pass the output of getShadowDomTokens() from @unnoodle/design-system\n * so the button can consume design tokens inside its shadow root.\n */\n shadowTokens?: string,\n): {\n element: HTMLElement;\n cleanup: () => void;\n setProgress: (active: boolean) => void;\n} {\n const host = document.createElement(\"div\");\n host.id = \"unnoodle-btn-host\";\n // Host must be positioned so the inner button's fixed position works correctly\n host.style.cssText =\n \"position:fixed;right:14px;top:50%;transform:translateY(-50%);z-index:2147483647;\";\n\n const shadow = host.attachShadow({ mode: \"open\" });\n\n const style = document.createElement(\"style\");\n style.textContent = safeCSS(`\n :host { all: initial; }\n\n /* Wrapper — gives ::after tooltip a positioning context */\n .btn-wrap {\n position: relative;\n display: inline-flex;\n align-items: center;\n }\n\n /* Rounded-square trigger button */\n .trigger {\n width: 38px; height: 38px;\n border-radius: 4px;\n border: none; padding: 0; cursor: pointer;\n position: relative;\n display: flex; align-items: center; justify-content: center; gap: 0;\n background: linear-gradient(160deg, #2c3440 0%, #1a1f27 100%);\n /* Layered box-shadow — creates a \"gradient shadow\" depth effect */\n box-shadow:\n 0 1px 2px rgba(0,0,0,0.30),\n 0 3px 8px rgba(0,0,0,0.38),\n 0 8px 20px rgba(0,0,0,0.22),\n 0 1px 0 rgba(255,255,255,0.06) inset;\n color: rgba(255,255,255,0.85);\n font-family: var(--unn-font-family, system-ui, sans-serif);\n font-size: 11px; font-weight: 700; letter-spacing: 0.5px;\n /* Text shadow for glyph depth */\n text-shadow: 0 1px 3px rgba(0,0,0,0.65), 0 -1px 0 rgba(255,255,255,0.10);\n -webkit-user-select: none; user-select: none;\n transition:\n transform 0.18s cubic-bezier(0.34,1.35,0.64,1),\n box-shadow 0.18s ease,\n filter 0.18s ease;\n }\n\n /*\n * Spinning progress ring — only visible when .trigger has .loading class.\n * Toggle via setProgress(true/false) from the returned API.\n * Uses the mask XOR trick: outer box minus content-box = thin padding ring.\n * The conic-gradient rotates to give a sweeping arc effect.\n */\n .trigger.loading::after {\n content: '';\n position: absolute;\n /* 1px gap + 1px border = 2px outside button edge */\n inset: -2px;\n border-radius: 6px; /* 4px + 2px */\n padding: 1px; /* controls ring thickness */\n background: conic-gradient(\n from 0deg,\n transparent 0deg,\n rgba(0,0,0,0.75) 80deg,\n transparent 160deg\n );\n /* Hollow ring mask: reveal only the 1px padding strip */\n -webkit-mask:\n linear-gradient(#fff 0 0) content-box,\n linear-gradient(#fff 0 0);\n mask:\n linear-gradient(#fff 0 0) content-box,\n linear-gradient(#fff 0 0);\n -webkit-mask-composite: destination-out;\n mask-composite: exclude;\n pointer-events: none;\n animation: unn-ring-spin 2.4s linear infinite;\n }\n\n @keyframes unn-ring-spin {\n to { transform: rotate(360deg); }\n }\n\n .trigger.dragging { transition: none; }\n\n .trigger:not(.dragging):hover {\n transform: scale(1.08);\n box-shadow:\n 0 2px 4px rgba(0,0,0,0.35),\n 0 6px 16px rgba(0,0,0,0.48),\n 0 14px 32px rgba(0,0,0,0.22),\n 0 1px 0 rgba(255,255,255,0.10) inset;\n filter: brightness(1.18);\n }\n .trigger:not(.dragging):active { transform: scale(0.94); }\n .trigger:focus-visible { outline: 2px solid rgba(255,255,255,0.55); outline-offset: 2px; }\n\n /* Tooltip */\n .tip {\n position: absolute;\n right: calc(100% + 10px);\n top: 50%; transform: translateY(-50%);\n background: rgba(18,18,26,0.90);\n color: #fff;\n font-family: var(--unn-font-family, system-ui, sans-serif);\n font-size: 9px; font-weight: 500;\n white-space: nowrap;\n padding: 3px 7px; border-radius: 4px;\n opacity: 0; pointer-events: none;\n transition: opacity 0.15s ease;\n backdrop-filter: blur(4px);\n }\n .trigger:not(.dragging):hover ~ .tip,\n .trigger:not(.dragging):focus-visible ~ .tip { opacity: 1; }\n `);\n\n if (shadowTokens) {\n const tokenStyle = document.createElement(\"style\");\n tokenStyle.textContent = safeCSS(shadowTokens);\n shadow.appendChild(tokenStyle);\n }\n shadow.appendChild(style);\n\n const wrap = document.createElement(\"div\");\n wrap.className = \"btn-wrap\";\n\n const btn = document.createElement(\"button\");\n btn.className = \"trigger\";\n btn.setAttribute(\"aria-label\", \"Open Unnoodle\");\n btn.setAttribute(\"data-testid\", \"widget-trigger-button\");\n btn.textContent = \"U\\u2229\";\n // Keyboard trigger (Enter / Space) — not using \"click\" because mousedown+mouseup\n // already calls onTrigger() on mouse release, and a \"click\" listener would fire\n // a second time causing an immediate open→close double-toggle.\n btn.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onTrigger();\n }\n });\n\n const tip = document.createElement(\"span\");\n tip.className = \"tip\";\n const isMac = /mac/i.test(navigator.platform || navigator.userAgent);\n tip.textContent = isMac ? \"⌘U\" : \"Ctrl+U\";\n\n wrap.appendChild(btn);\n wrap.appendChild(tip);\n shadow.appendChild(wrap);\n\n // ---------------------------------------------------------------------------\n // Drag logic — moves the host element (fixed-position anchor)\n // ---------------------------------------------------------------------------\n let isDragging = false;\n let hasMoved = false;\n let startX = 0;\n let startY = 0;\n let originRight = 0;\n let originTopPx = 0;\n\n function readPosition(): { right: number; topPx: number } {\n const right = parseFloat(host.style.right) || 14;\n const rawTop = host.style.top;\n const topPx = rawTop.endsWith(\"%\")\n ? (parseFloat(rawTop) / 100) * window.innerHeight - 68\n : parseFloat(rawTop) || window.innerHeight / 2 - 68;\n return { right, topPx };\n }\n\n function onMouseDown(e: MouseEvent) {\n if (e.button !== 0) return;\n isDragging = true;\n hasMoved = false;\n btn.classList.add(\"dragging\");\n startX = e.clientX;\n startY = e.clientY;\n const pos = readPosition();\n originRight = pos.right;\n originTopPx = pos.topPx;\n e.preventDefault();\n }\n\n function onMouseMove(e: MouseEvent) {\n if (!isDragging) return;\n const dx = e.clientX - startX;\n const dy = e.clientY - startY;\n if (Math.abs(dx) > 3 || Math.abs(dy) > 3) hasMoved = true;\n const newRight = clamp(originRight - dx, 8, window.innerWidth - 46);\n const newTopPx = clamp(originTopPx + dy, 8, window.innerHeight - 160);\n host.style.right = `${newRight}px`;\n host.style.top = `${newTopPx}px`;\n host.style.transform = \"none\";\n }\n\n function onMouseUp(e: MouseEvent) {\n if (!isDragging) return;\n isDragging = false;\n btn.classList.remove(\"dragging\");\n if (!hasMoved) {\n onTrigger();\n }\n e.preventDefault();\n }\n\n function onTouchStart(e: TouchEvent) {\n const t = e.touches[0];\n if (!t) return;\n isDragging = true;\n hasMoved = false;\n btn.classList.add(\"dragging\");\n startX = t.clientX;\n startY = t.clientY;\n const pos = readPosition();\n originRight = pos.right;\n originTopPx = pos.topPx;\n }\n\n function onTouchMove(e: TouchEvent) {\n if (!isDragging) return;\n const t = e.touches[0];\n if (!t) return;\n const dx = t.clientX - startX;\n const dy = t.clientY - startY;\n if (Math.abs(dx) > 3 || Math.abs(dy) > 3) hasMoved = true;\n const newRight = clamp(originRight - dx, 8, window.innerWidth - 46);\n const newTopPx = clamp(originTopPx + dy, 8, window.innerHeight - 160);\n host.style.right = `${newRight}px`;\n host.style.top = `${newTopPx}px`;\n host.style.transform = \"none\";\n e.preventDefault();\n }\n\n function onTouchEnd() {\n if (!isDragging) return;\n isDragging = false;\n btn.classList.remove(\"dragging\");\n if (!hasMoved) onTrigger();\n }\n\n btn.addEventListener(\"mousedown\", onMouseDown);\n document.addEventListener(\"mousemove\", onMouseMove);\n document.addEventListener(\"mouseup\", onMouseUp);\n\n btn.addEventListener(\"touchstart\", onTouchStart, { passive: true });\n document.addEventListener(\"touchmove\", onTouchMove, { passive: false });\n document.addEventListener(\"touchend\", onTouchEnd);\n\n const cleanup = () => {\n btn.removeEventListener(\"mousedown\", onMouseDown);\n btn.removeEventListener(\"touchstart\", onTouchStart);\n document.removeEventListener(\"mousemove\", onMouseMove);\n document.removeEventListener(\"mouseup\", onMouseUp);\n document.removeEventListener(\"touchmove\", onTouchMove);\n document.removeEventListener(\"touchend\", onTouchEnd);\n host.remove();\n };\n\n const setProgress = (active: boolean) => {\n btn.classList.toggle(\"loading\", active);\n btn.setAttribute(\"aria-busy\", String(active));\n };\n\n return { element: host, cleanup, setProgress };\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n","/** Panel shadow-DOM CSS. Pure CSS string — no template dependencies. */\nexport const PANEL_STYLES = `\n :host {\n all: initial;\n /* ═══════════════════════════════════════════════════════════════\n Widget scale tokens — change values here to affect everywhere\n ═══════════════════════════════════════════════════════════════ */\n\n /* Font sizes */\n --w-font-xxs: 10px; /* product-memory heading */\n --w-font-xs: 10px; /* footer, panel subtitle, upper labels */\n --w-font-sm: 11px; /* form labels, tab-btn, section headings */\n --w-font-base: 12px; /* body text, search, buttons, term defs */\n --w-font-md: 13px; /* term names, inputs, form-submit */\n --w-font-display: 13px; /* AI modal term emphasis */\n --w-font-lg: 13px; /* panel title */\n --w-font-xl: 15px; /* login heading */\n\n /* Font weights */\n --w-weight-normal: 400;\n --w-weight-medium: 400; /* labels, tab-btn */\n --w-weight-semi: 500; /* headings, buttons */\n --w-weight-bold: 600; /* term detail name */\n\n /* Spacing — vertical */\n --w-space-v-xs: 4px; /* small inner gaps */\n --w-space-v-sm: 8px; /* post padding, pm textarea */\n --w-space-v-md: 10px; /* section padding-top/bottom, term items */\n --w-space-v-lg: 12px; /* header, discussions, meta padding-v */\n --w-space-v-xl: 20px; /* login form padding-top/bottom */\n\n /* Spacing — horizontal */\n --w-space-h-sm: 12px; /* login form inner padding */\n --w-space-h-md: 16px; /* global horizontal gutter */\n --w-space-h-lg: 18px; /* login outer horizontal padding */\n\n /* Spacing — numeric scale (used by home view, skeleton loaders) */\n --w-space-1: 4px;\n --w-space-2: 8px;\n --w-space-3: 12px;\n --w-space-4: 16px;\n\n /* Border */\n --w-border-width: 1px; /* all interactive element borders */\n\n /* Border radii */\n --w-radius-xs: 3px; /* tiny elements, pm editor btn */\n --w-radius-1: 4px; /* home view rows, search bar */\n --w-radius-sm: 4px; /* tabs, capture-btn, suggestions, pm btns */\n --w-radius-md: 5px; /* action-btn */\n --w-radius-lg: 6px; /* inputs, SSO btns, form submits, toast, modal */\n --w-radius-pill: 10px; /* term pills */\n\n /* Panel dimensions */\n --w-panel-width: 400px;\n\n /* Spinner */\n --w-spinner-size: 34px;\n --w-spinner-border: 3px;\n }\n *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\n\n .panel-shell {\n position: fixed; top: 0; right: 0; bottom: 0;\n width: var(--w-panel-width); max-width: 100vw;\n z-index: 2147483647;\n transform: translateX(100%);\n transition: transform 0.28s cubic-bezier(0.4,0,0.2,1), width 0.28s cubic-bezier(0.4,0,0.2,1);\n \n border-left: 0.5px solid var(--unn-color-border-default);\n box-shadow: inset 6px 0 12px rgba(0,0,0,0.06), inset -4px 0 10px rgba(0,0,0,0.04), inset 0 6px 12px rgba(0,0,0,0.06), inset 0 -4px 10px rgba(0,0,0,0.04);\n padding: 3px;\n display: flex; flex-direction: column;\n background: var(--unn-color-bg-secondary, #f5f5f7);\n }\n .panel-shell.open { transform: translateX(0); }\n .panel {\n flex: 1; min-height: 0;\n display: flex; flex-direction: column;\n font-family: var(--unn-font-family);\n background: var(--unn-color-bg-primary);\n border-radius: 6px;\n overflow: hidden;\n }\n\n /* Header */\n .panel-header {\n display: flex; align-items: center; justify-content: space-between;\n padding: 5px 6px 5px 12px;\n background: linear-gradient(160deg, #2c3440 0%, #1a1f27 100%);\n color: var(--unn-color-text-inverse);\n border-radius: 6px 6px 0 0; flex-shrink: 0;\n }\n .panel-header-brand { display: flex; align-items: baseline; gap: 4px; min-width: 0; }\n .panel-title { font-size: var(--w-font-base); font-weight: var(--w-weight-bold); letter-spacing: 0.01em; white-space: nowrap; }\n .panel-title-sep { font-size: var(--w-font-xs); opacity: 0.35; line-height: 1; }\n .panel-subtitle { font-size: var(--w-font-xs); opacity: 0.60; white-space: nowrap; }\n .panel-header-actions { display: flex; align-items: center; gap: 1px; flex-shrink: 0; }\n .panel-header-separator { width: 1px; height: 11px; background: rgba(255,255,255,0.25); margin: 0 3px; flex-shrink: 0; }\n .panel-close, .panel-popout, .panel-dock, .panel-pin-left, .panel-pin-right,\n .panel-half, .panel-half-exit,\n .panel-fullscreen, .panel-fullscreen-exit {\n background: none; border: none; cursor: pointer; color: var(--unn-color-text-inverse);\n width: 24px; height: 24px;\n display: flex; align-items: center; justify-content: center;\n border-radius: var(--w-radius-xs); opacity: 0.75; transition: opacity 0.15s, background 0.15s;\n }\n .panel-close:hover, .panel-popout:hover, .panel-dock:hover,\n .panel-pin-left:hover, .panel-pin-right:hover,\n .panel-half:hover, .panel-half-exit:hover,\n .panel-fullscreen:hover, .panel-fullscreen-exit:hover { opacity: 1; background: rgba(255,255,255,0.18); }\n .panel-close svg, .panel-popout svg, .panel-dock svg,\n .panel-half svg, .panel-half-exit svg,\n .panel-fullscreen svg, .panel-fullscreen-exit svg { width: 14px; height: 14px; fill: currentColor; stroke: none; }\n .panel-pin-left svg, .panel-pin-right svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 16; }\n .panel-pin-right svg { transform: scaleX(-1); }\n .panel-popout[hidden], .panel-dock[hidden] { display: none !important; }\n .panel-half[hidden], .panel-half-exit[hidden] { display: none !important; }\n .panel-pin-left.active, .panel-pin-right.active { background: rgba(255,255,255,0.25) !important; opacity: 1 !important; }\n\n /* Left-side docking */\n .panel-shell.left-side {\n right: auto; left: 0;\n transform: translateX(-100%);\n border-left: none;\n border-right: 0.5px solid var(--unn-color-border-default);\n }\n .panel-shell.left-side.open { transform: translateX(0); }\n\n /* Half-screen (50vw) */\n .panel-shell.half-screen {\n width: 50vw !important; max-width: 50vw !important;\n }\n\n /* Fullscreen */\n .panel-shell.fullscreen {\n left: 0 !important; right: 0 !important;\n width: 100vw !important; max-width: 100vw !important;\n transform: none !important;\n border-radius: 0 !important;\n border: none !important;\n box-shadow: none !important;\n padding: 0 !important;\n background: transparent !important;\n }\n .panel-shell.fullscreen.open { transform: none !important; }\n .panel-shell.fullscreen .panel { border-radius: 0 !important; }\n .panel-fullscreen[hidden], .panel-fullscreen-exit[hidden] { display: none !important; }\n\n /* Body */\n .panel-body { flex: 1; overflow-y: auto; display: flex; flex-direction: column; }\n\n /* Footer */\n .panel-footer {\n padding: 4px 14px; border-top: 1px solid var(--unn-color-border-default);\n display: flex; align-items: center; justify-content: center; flex-shrink: 0;\n }\n .panel-footer a { font-size: var(--w-font-xs); color: var(--unn-color-text-subtle); text-decoration: none; opacity: 0.8; }\n .panel-footer a:hover { color: var(--unn-color-text-muted); opacity: 1; }\n\n /* ---- Utility states ---- */\n .state-center {\n flex: 1; display: flex; flex-direction: column;\n align-items: center; justify-content: center;\n gap: 14px; padding: 24px;\n }\n .spinner {\n width: var(--w-spinner-size); height: var(--w-spinner-size);\n border: var(--w-spinner-border) solid var(--unn-color-border-default); border-top-color: var(--unn-color-brand-primary);\n border-radius: 50%;\n animation: spin 0.7s linear infinite;\n }\n @keyframes spin { to { transform: rotate(360deg); } }\n .state-msg { font-size: var(--w-font-base); color: var(--unn-color-text-muted); text-align: center; line-height: 1.5; }\n .state-error-icon { stroke: var(--unn-color-status-error); fill: none; width: 40px; height: 40px; }\n\n /* ---- Login view ---- */\n .login-form {\n padding: var(--w-space-v-xl) var(--w-space-h-lg);\n display: flex; flex-direction: column; gap: 14px;\n }\n .login-heading {\n font-size: var(--w-font-xl); font-weight: var(--w-weight-semi); color: var(--unn-color-text-primary); text-align: center;\n }\n .login-sub {\n font-size: var(--w-font-sm); color: var(--unn-color-text-muted); text-align: center; margin-top: -8px;\n }\n .form-field { display: flex; flex-direction: column; gap: 5px; }\n .form-label { font-size: var(--w-font-sm); font-weight: var(--w-weight-medium); color: var(--unn-color-text-body); }\n .form-input {\n width: 100%; padding: 9px 12px;\n border: var(--w-border-width) solid var(--unn-color-border-subtle); border-radius: var(--w-radius-lg);\n font-size: var(--w-font-md); color: var(--unn-color-text-primary);\n outline: none; transition: border-color 0.15s;\n }\n .form-input:focus { border-color: var(--unn-color-brand-primary); }\n .form-submit {\n width: 100%; padding: 10px 16px;\n background: var(--unn-color-brand-primary); color: var(--unn-color-text-inverse);\n border: none; border-radius: var(--w-radius-lg);\n font-size: var(--w-font-md); font-weight: var(--w-weight-semi); cursor: pointer;\n transition: opacity 0.15s, transform 0.1s;\n }\n .form-submit:hover { opacity: 0.9; }\n .form-submit:active { transform: scale(0.98); }\n .form-submit:disabled { opacity: 0.6; cursor: not-allowed; }\n .login-error {\n font-size: var(--w-font-sm); color: var(--unn-color-status-error);\n background: var(--unn-color-error-tint); border: 1px solid var(--unn-color-error-tint-border);\n border-radius: var(--w-radius-sm); padding: 8px 10px;\n display: none;\n }\n .login-error.visible { display: block; }\n .login-back-btn {\n all: unset; cursor: pointer; display: inline-flex; align-items: center; gap: 3px;\n font-size: var(--w-font-sm); color: var(--unn-color-text-muted);\n margin-bottom: -4px;\n }\n .login-back-btn:hover { color: var(--unn-color-text-primary); }\n\n /* ---- SSO buttons ---- */\n .sso-divider {\n display: flex; align-items: center; gap: 10px; margin: 4px 0;\n }\n .sso-divider-line {\n flex: 1; height: 1px; background: var(--unn-color-border-default);\n }\n .sso-divider-text {\n font-size: var(--w-font-xs); color: var(--unn-color-text-muted); white-space: nowrap;\n }\n .sso-buttons { display: flex; flex-direction: column; gap: 8px; }\n .sso-btn {\n display: flex; align-items: center; justify-content: center; gap: 10px;\n width: 100%; padding: 9px 12px;\n border: var(--w-border-width) solid var(--unn-color-border-subtle); border-radius: var(--w-radius-lg);\n background: var(--unn-color-bg-primary); color: var(--unn-color-text-primary);\n font-size: var(--w-font-base); font-weight: var(--w-weight-medium); cursor: pointer;\n transition: background 0.15s, border-color 0.15s;\n }\n .sso-btn:hover { background: var(--unn-color-bg-subtle); border-color: var(--unn-color-border-default); }\n .sso-btn svg { flex-shrink: 0; }\n\n /* ---- Search ---- */\n .search-bar {\n padding: var(--w-space-v-md) var(--w-space-h-md); border-bottom: 1px solid var(--unn-color-border-default);\n flex-shrink: 0;\n }\n .search-input {\n width: 100%; padding: 8px 12px;\n border: var(--w-border-width) solid var(--unn-color-border-subtle); border-radius: var(--w-radius-lg);\n font-size: var(--w-font-base); color: var(--unn-color-text-primary);\n outline: none; transition: border-color 0.15s;\n }\n .search-input:focus { border-color: var(--unn-color-brand-primary); }\n\n /* ---- Terms list ---- */\n .terms-list { flex: 1; overflow-y: auto; padding: 0; }\n .context-label {\n padding: 10px 18px 6px;\n font-size: var(--w-font-xs); font-weight: var(--w-weight-semi); color: var(--unn-color-text-subtle);\n text-transform: uppercase; letter-spacing: 0.05em;\n }\n .term-item {\n padding: var(--w-space-v-md) var(--w-space-h-md);\n border-bottom: 1px solid var(--unn-color-border-default);\n cursor: default;\n transition: background 0.1s;\n }\n .term-item:hover { background: var(--unn-color-bg-secondary); }\n .term-name {\n font-size: var(--w-font-md); font-weight: var(--w-weight-semi); color: var(--unn-color-text-primary);\n display: flex; align-items: center; gap: 6px;\n }\n .term-abbr {\n font-size: var(--w-font-xxs); font-weight: var(--w-weight-medium);\n background: var(--unn-color-accent-tint-bg); color: var(--unn-color-accent-strong);\n border-radius: var(--w-radius-xs); padding: 1px 5px;\n }\n .term-def {\n font-size: var(--w-font-sm); color: var(--unn-color-text-muted); margin-top: 4px; line-height: 1.5;\n }\n .term-link {\n font-size: var(--w-font-xs); color: var(--unn-color-brand-primary);\n text-decoration: none; margin-top: 4px; display: inline-block;\n }\n .term-link:hover { text-decoration: underline; }\n .no-results {\n padding: 28px 18px; text-align: center;\n font-size: var(--w-font-base); color: var(--unn-color-text-subtle);\n }\n\n /* ---- Term card (clickable row inside list item) ---- */\n .term-card {\n cursor: pointer;\n }\n .term-card:hover .term-name { color: var(--unn-color-brand-primary); }\n\n /* ---- Term detail view ---- */\n .term-detail-view {\n display: flex; flex-direction: column; flex: 1; overflow-y: auto;\n }\n .detail-back {\n display: flex; align-items: center;\n padding: 10px 18px; border-bottom: 1px solid var(--unn-color-border-default); flex-shrink: 0;\n }\n .back-btn {\n background: none; border: none; cursor: pointer;\n font-size: var(--w-font-base); color: var(--unn-color-brand-primary); font-weight: var(--w-weight-medium);\n display: flex; align-items: center; gap: 4px; padding: 4px 0;\n }\n .back-btn:hover { text-decoration: underline; }\n .detail-content {\n padding: 18px 18px 10px;\n }\n .detail-term-name {\n font-size: var(--w-font-xl); font-weight: var(--w-weight-bold); color: var(--unn-color-text-primary);\n }\n .detail-term-def {\n font-size: var(--w-font-base); color: var(--unn-color-text-muted); margin-top: 8px; line-height: 1.6;\n }\n .detail-actions {\n display: flex; gap: 8px;\n padding: 10px 18px; border-bottom: 1px solid var(--unn-color-border-default); flex-shrink: 0;\n }\n .action-btn {\n padding: 7px 14px; border-radius: var(--w-radius-md); font-size: var(--w-font-base); font-weight: var(--w-weight-medium);\n cursor: pointer; border: var(--w-border-width) solid var(--unn-color-brand-primary);\n background: var(--unn-color-bg-primary); color: var(--unn-color-brand-primary);\n transition: background 0.15s, color 0.15s;\n }\n .action-btn:hover { background: var(--unn-color-brand-primary); color: var(--unn-color-text-inverse); }\n .discussions-section { padding: var(--w-space-v-lg) var(--w-space-h-md); flex: 1; }\n .discussions-heading {\n font-size: var(--w-font-xs); font-weight: var(--w-weight-semi); color: var(--unn-color-text-subtle);\n text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 10px;\n }\n .discussion-post {\n padding: var(--w-space-v-sm) var(--w-space-h-sm);\n border-bottom: 1px solid var(--unn-color-border-default);\n font-size: var(--w-font-base); color: var(--unn-color-text-body);\n line-height: 1.5;\n }\n .discussion-post:last-child { border-bottom: none; }\n .discussions-empty {\n font-size: var(--w-font-base); color: var(--unn-color-text-subtle); text-align: center; padding: 16px 0;\n }\n\n /* ---- Comment form view ---- */\n .comment-form-view {\n display: flex; flex-direction: column; flex: 1; overflow-y: auto;\n }\n .comment-textarea {\n margin: var(--w-space-v-lg) var(--w-space-h-md); padding: var(--w-space-v-sm) 12px;\n border: var(--w-border-width) solid var(--unn-color-border-subtle); border-radius: var(--w-radius-lg);\n font-size: var(--w-font-base); color: var(--unn-color-text-primary); min-height: 100px; resize: vertical;\n outline: none; transition: border-color 0.15s;\n font-family: inherit;\n }\n .comment-textarea:focus { border-color: var(--unn-color-brand-primary); }\n .comment-submit {\n margin: 0 18px; padding: 10px 16px;\n background: var(--unn-color-brand-primary); color: var(--unn-color-text-inverse);\n border: none; border-radius: var(--w-radius-lg);\n font-size: var(--w-font-md); font-weight: var(--w-weight-semi); cursor: pointer;\n transition: opacity 0.15s;\n }\n .comment-submit:hover { opacity: 0.9; }\n .comment-submit:disabled { opacity: 0.6; cursor: not-allowed; }\n\n /* ---- Edit form view ---- */\n .edit-form-view {\n display: flex; flex-direction: column; flex: 1; overflow-y: auto;\n padding: var(--w-space-v-lg) var(--w-space-h-md); gap: 12px;\n }\n .edit-label {\n font-size: var(--w-font-sm); font-weight: var(--w-weight-medium); color: var(--unn-color-text-body);\n margin-bottom: 4px; display: block;\n }\n .edit-input {\n width: 100%; padding: 9px 12px;\n border: var(--w-border-width) solid var(--unn-color-border-subtle); border-radius: var(--w-radius-lg);\n font-size: var(--w-font-md); color: var(--unn-color-text-primary);\n outline: none; transition: border-color 0.15s;\n }\n .edit-input:focus { border-color: var(--unn-color-brand-primary); }\n .edit-textarea {\n width: 100%; padding: 9px 12px;\n border: var(--w-border-width) solid var(--unn-color-border-subtle); border-radius: var(--w-radius-lg);\n font-size: var(--w-font-base); color: var(--unn-color-text-primary); min-height: 80px; resize: vertical;\n outline: none; transition: border-color 0.15s;\n font-family: inherit;\n }\n .edit-textarea:focus { border-color: var(--unn-color-brand-primary); }\n .edit-submit {\n padding: 10px 16px;\n background: var(--unn-color-brand-primary); color: var(--unn-color-text-inverse);\n border: none; border-radius: var(--w-radius-lg);\n font-size: var(--w-font-md); font-weight: var(--w-weight-semi); cursor: pointer;\n transition: opacity 0.15s;\n }\n .edit-submit:hover { opacity: 0.9; }\n\n /* ---- Suggested terms section ---- */\n .suggestions-section { padding: var(--w-space-v-md) var(--w-space-h-md) 16px; }\n .suggestions-heading {\n font-size: var(--w-font-xs); font-weight: var(--w-weight-semi); color: var(--unn-color-text-subtle);\n text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 8px;\n }\n .suggestion-item {\n display: flex; align-items: center; justify-content: space-between;\n padding: 8px 0; border-bottom: 1px solid var(--unn-color-border-default);\n }\n .suggestion-item:last-child { border-bottom: none; }\n .suggestion-info { display: flex; flex-direction: column; gap: 2px; }\n .suggestion-term { font-size: var(--w-font-base); font-weight: var(--w-weight-semi); color: var(--unn-color-text-primary); }\n .suggestion-count { font-size: var(--w-font-xs); color: var(--unn-color-text-subtle); }\n .suggestion-add {\n padding: 4px 10px; border-radius: var(--w-radius-sm); font-size: var(--w-font-sm); font-weight: var(--w-weight-medium);\n cursor: pointer; border: var(--w-border-width) solid var(--unn-color-brand-primary);\n background: var(--unn-color-bg-primary); color: var(--unn-color-brand-primary);\n flex-shrink: 0;\n transition: background 0.15s, color 0.15s;\n }\n .suggestion-add:hover { background: var(--unn-color-brand-primary); color: var(--unn-color-text-inverse); }\n\n /* ---- AI definition modal ---- */\n .ai-modal-overlay {\n position: absolute; inset: 0;\n background: rgba(255,255,255,0.96);\n display: flex; flex-direction: column;\n z-index: 10; padding: 24px 20px; gap: 14px;\n overflow-y: auto;\n }\n .ai-modal-title {\n font-size: var(--w-font-md); font-weight: var(--w-weight-semi); color: var(--unn-color-text-primary);\n }\n .ai-modal-term {\n font-size: var(--w-font-display); font-weight: var(--w-weight-bold); color: var(--unn-color-brand-primary);\n }\n .ai-modal-label {\n font-size: var(--w-font-sm); font-weight: var(--w-weight-medium); color: var(--unn-color-text-body); margin-bottom: 4px; display: block;\n }\n .ai-modal-textarea {\n width: 100%; padding: 9px 12px;\n border: var(--w-border-width) solid var(--unn-color-border-subtle); border-radius: var(--w-radius-lg);\n font-size: var(--w-font-base); color: var(--unn-color-text-primary); min-height: 120px; resize: vertical;\n outline: none; transition: border-color 0.15s;\n font-family: inherit;\n }\n .ai-modal-textarea:focus { border-color: var(--unn-color-brand-primary); }\n .ai-modal-char-count { font-size: var(--w-font-xs); color: var(--unn-color-text-subtle); text-align: right; }\n .ai-modal-actions { display: flex; gap: 8px; }\n .ai-modal-submit {\n flex: 1; padding: 10px 16px;\n background: var(--unn-color-brand-primary); color: var(--unn-color-text-inverse);\n border: none; border-radius: var(--w-radius-lg);\n font-size: var(--w-font-md); font-weight: var(--w-weight-semi); cursor: pointer;\n transition: opacity 0.15s;\n }\n .ai-modal-submit:hover { opacity: 0.9; }\n .ai-modal-submit:disabled { opacity: 0.6; cursor: not-allowed; }\n .ai-modal-cancel {\n padding: 10px 16px; border-radius: var(--w-radius-lg); font-size: var(--w-font-md);\n font-weight: var(--w-weight-medium); cursor: pointer;\n border: var(--w-border-width) solid var(--unn-color-border-subtle); background: var(--unn-color-bg-primary); color: var(--unn-color-text-body);\n transition: border-color 0.15s;\n }\n .ai-modal-cancel:hover { border-color: var(--unn-color-text-subtle); }\n\n /* ---- Toast notification ---- */\n .toast {\n position: absolute; bottom: 60px; left: 16px; right: 16px;\n background: var(--unn-color-brand-dark); color: var(--unn-color-text-inverse);\n padding: 10px 14px; border-radius: var(--w-radius-lg);\n font-size: var(--w-font-base); font-weight: var(--w-weight-medium);\n z-index: 20; text-align: center;\n animation: toast-in 0.2s ease;\n }\n @keyframes toast-in {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n }\n\n /* ---- UI States action bar (captures + tab nav) ---- */\n .action-bar {\n display: flex; align-items: center; justify-content: space-between;\n padding: 8px 18px; border-bottom: 1px solid var(--unn-color-border-default);\n flex-shrink: 0; gap: 8px;\n }\n .action-bar-tabs { display: flex; gap: 4px; }\n .tab-btn {\n padding: 5px 12px; border-radius: var(--w-radius-sm); font-size: var(--w-font-sm); font-weight: var(--w-weight-medium);\n cursor: pointer; border: var(--w-border-width) solid transparent;\n background: var(--unn-color-bg-tertiary); color: var(--unn-color-text-muted);\n transition: background 0.15s, color 0.15s;\n }\n .tab-btn:hover { background: var(--unn-color-border-default); color: var(--unn-color-text-body); }\n .tab-btn.active {\n background: var(--unn-color-brand-primary); color: var(--unn-color-text-inverse); border-color: var(--unn-color-brand-primary);\n }\n .capture-btn {\n padding: 5px 12px; border-radius: var(--w-radius-sm); font-size: var(--w-font-sm); font-weight: var(--w-weight-semi);\n cursor: pointer;\n border: var(--w-border-width) solid var(--unn-color-brand-primary); background: var(--unn-color-bg-primary); color: var(--unn-color-brand-primary);\n transition: background 0.15s, color 0.15s, opacity 0.15s;\n display: flex; align-items: center; gap: 5px;\n white-space: nowrap;\n }\n .capture-btn:hover { background: var(--unn-color-brand-primary); color: var(--unn-color-text-inverse); }\n .capture-btn:active { transform: scale(0.97); }\n .capture-btn:disabled { opacity: 0.5; cursor: not-allowed; }\n .capture-btn svg { width: 13px; height: 13px; stroke: currentColor; fill: none; stroke-width: 2; }\n\n /* ---- UI States list view ---- */\n .ui-states-list {\n flex: 1; overflow-y: auto; padding: 0;\n }\n .ui-state-item {\n padding: var(--w-space-v-md) var(--w-space-h-md); border-bottom: 1px solid var(--unn-color-border-default);\n transition: background 0.1s;\n }\n .ui-state-item:hover { background: var(--unn-color-bg-secondary); }\n .ui-state-url {\n font-size: var(--w-font-base); font-weight: var(--w-weight-semi); color: var(--unn-color-text-primary);\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n max-width: 280px;\n }\n .ui-state-meta {\n font-size: var(--w-font-xs); color: var(--unn-color-text-subtle); margin-top: 3px;\n display: flex; gap: 8px; align-items: center; flex-wrap: wrap;\n }\n .ui-state-role-badge {\n font-size: var(--w-font-xxs); font-weight: var(--w-weight-semi); padding: 1px 6px;\n border-radius: var(--w-radius-xs); background: var(--unn-color-accent-tint-bg); color: var(--unn-color-accent-strong);\n text-transform: uppercase; letter-spacing: 0.04em;\n }\n .ui-state-terms-preview {\n font-size: var(--w-font-xs); color: var(--unn-color-text-muted); margin-top: 4px;\n }\n .ui-state-actions {\n margin-top: 8px; display: flex; gap: 6px;\n }\n .view-detail-btn {\n padding: 4px 10px; border-radius: var(--w-radius-sm); font-size: var(--w-font-sm); font-weight: var(--w-weight-medium);\n cursor: pointer; border: var(--w-border-width) solid var(--unn-color-brand-primary);\n background: var(--unn-color-bg-primary); color: var(--unn-color-brand-primary);\n transition: background 0.15s, color 0.15s;\n }\n .view-detail-btn:hover { background: var(--unn-color-brand-primary); color: var(--unn-color-text-inverse); }\n\n /* ---- Load more ---- */\n .load-more-container { padding: var(--w-space-v-md) var(--w-space-h-md); text-align: center; }\n .load-more-btn {\n width: 100%; padding: 8px 16px; border-radius: var(--w-radius-lg);\n font-size: var(--w-font-base); font-weight: var(--w-weight-medium); cursor: pointer;\n border: var(--w-border-width) solid var(--unn-color-border-subtle); background: var(--unn-color-bg-primary); color: var(--unn-color-text-body);\n transition: background 0.15s;\n }\n .load-more-btn:hover { background: var(--unn-color-bg-tertiary); }\n\n /* ---- UI States empty state ---- */\n .ui-states-empty {\n padding: 40px 18px; text-align: center;\n }\n .ui-states-empty-icon {\n width: 40px; height: 40px; stroke: var(--unn-color-border-subtle); fill: none;\n margin: 0 auto 12px;\n }\n .ui-states-empty-text {\n font-size: var(--w-font-base); color: var(--unn-color-text-subtle); line-height: 1.5;\n }\n\n /* ---- UI State detail view ---- */\n .ui-state-detail-view {\n display: flex; flex-direction: column; flex: 1; overflow-y: auto;\n }\n .detail-meta-section { padding: var(--w-space-v-lg) var(--w-space-h-md); border-bottom: 1px solid var(--unn-color-border-default); }\n .detail-page-title {\n font-size: var(--w-font-lg, 15px); font-weight: var(--w-weight-semi); color: var(--unn-color-text-primary);\n padding: var(--w-space-v-md) var(--w-space-h-md) 2px; flex-shrink: 0;\n }\n .detail-meta-row {\n display: flex; gap: 12px; font-size: var(--w-font-sm); color: var(--unn-color-text-muted);\n flex-wrap: wrap; align-items: center;\n }\n .detail-section { padding: var(--w-space-v-md) var(--w-space-h-md); border-bottom: 1px solid var(--unn-color-border-default); }\n .detail-section-heading {\n font-size: var(--w-font-xs); font-weight: var(--w-weight-semi); color: var(--unn-color-text-subtle);\n text-transform: uppercase; letter-spacing: 0.05em;\n margin-bottom: 8px; display: flex; justify-content: space-between;\n align-items: center; cursor: pointer; user-select: none;\n }\n .detail-section-heading svg {\n width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 2;\n transition: transform 0.2s;\n }\n .detail-section-heading.collapsed svg { transform: rotate(-90deg); }\n .detail-section-content { display: flex; flex-wrap: wrap; gap: 6px; }\n .detail-section-content.collapsed { display: none; }\n .detail-section-list {\n font-size: var(--w-font-sm); color: var(--unn-color-text-body); line-height: 1.6;\n padding-left: 16px;\n }\n .detail-section-list.collapsed { display: none; }\n\n /* ---- Term pill / link in state detail ---- */\n .ui-state-term-link {\n display: inline-flex; align-items: center;\n padding: 3px 10px; border-radius: var(--w-radius-pill);\n font-size: var(--w-font-xs); font-weight: var(--w-weight-semi);\n background: var(--unn-color-accent-tint-bg); color: var(--unn-color-accent-strong);\n cursor: pointer; border: none;\n transition: background 0.15s, color 0.15s;\n }\n .ui-state-term-link:hover { background: var(--unn-color-accent-strong); color: var(--unn-color-text-inverse); }\n\n /* ---- Product Memory section ---- */\n .product-memory-section {\n padding: 10px var(--w-space-h-md);\n border-top: 1px solid var(--unn-color-border-default);\n }\n .product-memory-heading {\n font-size: var(--w-font-xxs); font-weight: var(--w-weight-bold); color: var(--unn-color-text-muted);\n text-transform: uppercase; letter-spacing: 0.05em;\n margin-bottom: 8px;\n }\n .product-memory-text {\n font-size: var(--w-font-base); color: var(--unn-color-text-primary); line-height: 1.6;\n white-space: pre-wrap; word-break: break-word;\n margin-bottom: 8px;\n }\n .product-memory-textarea {\n width: 100%; box-sizing: border-box;\n font-size: var(--w-font-base); color: var(--unn-color-text-primary); line-height: 1.6;\n border: 1px solid var(--unn-color-border-subtle); border-radius: var(--w-radius-sm);\n padding: 8px 10px; resize: vertical; min-height: 80px;\n font-family: inherit; background: var(--unn-color-bg-primary);\n margin-bottom: 8px;\n }\n .product-memory-textarea:focus {\n outline: none; border-color: var(--unn-color-brand-primary);\n box-shadow: 0 0 0 2px var(--unn-focus-ring-color);\n }\n .product-memory-actions {\n display: flex; gap: 6px; justify-content: flex-end;\n }\n .product-memory-edit-btn {\n font-size: var(--w-font-sm); font-weight: var(--w-weight-semi); color: var(--unn-color-accent);\n background: none; border: none; cursor: pointer;\n padding: 4px 8px; border-radius: var(--w-radius-xs);\n }\n .product-memory-edit-btn:hover { background: var(--unn-color-accent-tint-bg); }\n .product-memory-delete-entry-btn {\n font-size: var(--w-font-sm); color: var(--unn-color-text-muted);\n background: none; border: none; cursor: pointer;\n padding: 4px 6px; border-radius: var(--w-radius-xs);\n opacity: 0.7;\n }\n .product-memory-delete-entry-btn:hover { \n background: #fee; color: #d63; opacity: 1; \n }\n .product-memory-save-btn {\n font-size: var(--w-font-sm); font-weight: var(--w-weight-semi); color: var(--unn-color-text-inverse);\n background: var(--unn-color-brand-primary); border: none; cursor: pointer;\n padding: 5px 14px; border-radius: var(--w-radius-sm);\n }\n .product-memory-save-btn:hover { opacity: 0.85; }\n .product-memory-save-btn:disabled { opacity: 0.5; cursor: not-allowed; }\n .product-memory-cancel-btn {\n font-size: var(--w-font-sm); font-weight: var(--w-weight-semi); color: var(--unn-color-text-muted);\n background: none; border: 1px solid var(--unn-color-border-subtle); cursor: pointer;\n padding: 4px 10px; border-radius: var(--w-radius-sm);\n }\n .product-memory-cancel-btn:hover { background: var(--unn-color-bg-tertiary); }\n .detail-actions {\n display: flex;\n gap: 6px;\n justify-content: space-between;\n align-items: center;\n padding: var(--w-space-v-md) var(--w-space-h-md);\n border-top: 1px solid var(--unn-color-border-subtle);\n margin-top: 4px;\n }\n .detail-delete-btn, .detail-add-btn {\n font-size: var(--w-font-xs); font-weight: 500; border: none;\n border-radius: var(--w-radius-sm); cursor: pointer; padding: 5px 12px;\n }\n .detail-delete-btn {\n background: var(--unn-color-bg-tertiary);\n color: var(--unn-color-text-muted);\n }\n .detail-delete-btn:hover {\n background: var(--unn-color-border-default);\n }\n .detail-add-btn {\n background: var(--unn-color-brand-primary);\n color: #fff;\n }\n .detail-add-btn:hover {\n opacity: 0.88;\n }\n\n /* ---- Snapshot preview in state-detail view ---- */\n .ui-state-snapshot-preview {\n max-height: 180px; overflow: hidden;\n border-bottom: 1px solid var(--unn-color-border-default);\n background: var(--unn-color-bg-secondary);\n padding: 6px var(--w-space-h-md);\n }\n .ui-state-snapshot-preview * { pointer-events: none; }\n\n /* ---- Replay highlight (glossary terms on page) ---- */\n .unnoodle-replay-highlight {\n background: var(--unn-color-accent-tint);\n border-bottom: 2px solid var(--unn-color-brand-primary);\n border-radius: 2px;\n animation: replay-pulse 0.6s ease-out;\n }\n @keyframes replay-pulse {\n from { background: var(--unn-color-accent-tint-strong); }\n to { background: var(--unn-color-accent-tint); }\n }\n\n /* ---- Drag-resize handle ---- */\n .panel-resize-handle {\n position: absolute; left: 0; top: 0; bottom: 0;\n width: 6px; cursor: col-resize; z-index: 10;\n }\n .panel-resize-handle:hover { background: var(--unn-color-accent-tint); }\n .panel-shell.left-side .panel-resize-handle { left: auto; right: 0; }\n\n /* ---- Skeleton loaders ---- */\n @keyframes skeleton-shimmer {\n 0% { background-position: -400px 0; }\n 100% { background-position: 400px 0; }\n }\n .skeleton-line {\n border-radius: 4px;\n background: linear-gradient(90deg,\n var(--unn-color-border) 25%,\n color-mix(in srgb, var(--unn-color-border) 40%, var(--unn-color-bg)) 50%,\n var(--unn-color-border) 75%);\n background-size: 800px 100%;\n animation: skeleton-shimmer 1.4s infinite linear;\n }\n .skeleton-home {\n padding: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n text-align: center;\n }\n .skeleton-loading-header {\n padding: 0 24px 32px;\n }\n .skeleton-loading-brand {\n font-size: 20px; font-weight: 700;\n color: var(--unn-color-brand-primary);\n letter-spacing: -0.01em;\n margin-bottom: 12px;\n }\n .skeleton-loading-title {\n font-size: var(--w-font-base); font-weight: 600;\n color: var(--unn-color-text-primary);\n margin-bottom: 6px;\n }\n .skeleton-loading-sub {\n font-size: var(--w-font-sm);\n color: var(--unn-color-text-subtle);\n }\n .skeleton-body {\n width: 100%; padding: 0 24px;\n display: flex; flex-direction: column; gap: 16px;\n }\n .skeleton-strip {\n padding: 10px 0 8px;\n }\n .skeleton-section {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding-bottom: var(--w-space-2);\n }\n .skeleton-section-head {\n height: 9px;\n width: 28%;\n border-radius: 4px;\n background: linear-gradient(90deg,\n var(--unn-color-border) 25%,\n color-mix(in srgb, var(--unn-color-border) 40%, var(--unn-color-bg)) 50%,\n var(--unn-color-border) 75%);\n background-size: 800px 100%;\n animation: skeleton-shimmer 1.4s infinite linear;\n margin-bottom: 4px;\n }\n .skeleton-row {\n height: 24px;\n display: flex;\n align-items: center;\n border-radius: var(--w-radius-1);\n }\n\n /* ---- Home view layout ---- */\n .home-view {\n display: flex; flex-direction: column; height: 100%; overflow: hidden;\n background: var(--unn-color-bg-primary);\n }\n\n /* ---- Context strip — always visible action toolbar ---- */\n .context-strip {\n display: flex; align-items: center; gap: 6px;\n padding: 6px 10px;\n border-bottom: 1px solid var(--unn-color-border-default);\n flex-shrink: 0;\n min-height: 38px;\n }\n .strip-idle {\n display: flex; align-items: center; gap: 6px; width: 100%;\n }\n .strip-btn {\n display: inline-flex; align-items: center; gap: 4px;\n padding: 3px 10px; border-radius: var(--w-radius-lg);\n border: 1px solid var(--unn-color-border-default);\n background: var(--unn-color-bg-secondary);\n color: var(--unn-color-text-secondary); font-size: var(--w-font-sm);\n cursor: pointer; transition: background 0.15s, color 0.15s;\n }\n .strip-btn:hover { background: var(--unn-color-bg-hover); color: var(--unn-color-text-primary); }\n .strip-btn svg { width: 13px; height: 13px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }\n /* Pick-mode state */\n .pick-mode-prompt {\n display: none; align-items: center; gap: 8px; width: 100%;\n }\n .pick-prompt-text {\n flex: 1; font-size: var(--w-font-sm); color: var(--unn-color-text-secondary);\n font-style: italic;\n }\n .strip-cancel-btn {\n padding: 2px 8px; border-radius: var(--w-radius-lg);\n border: 1px solid var(--unn-color-border-default);\n background: transparent; color: var(--unn-color-text-secondary);\n font-size: var(--w-font-xs); cursor: pointer;\n }\n .strip-cancel-btn:hover { color: var(--unn-color-text-primary); border-color: var(--unn-color-text-primary); }\n /* Capture-describe view */\n .capture-describe-view {\n display: none; flex-direction: column; gap: 6px; width: 100%; padding: 4px 0;\n }\n .capture-snapshot-preview {\n max-height: 120px; overflow: hidden; border-radius: var(--w-radius-1);\n border: 1px solid var(--unn-color-border-default);\n background: var(--unn-color-bg-secondary);\n }\n .capture-snapshot-meta {\n font-size: var(--w-font-xs); color: var(--unn-color-text-secondary); padding: 2px 4px;\n }\n .capture-description-input {\n width: 100%; box-sizing: border-box; resize: none;\n border: 1px solid var(--unn-color-border-default);\n border-radius: var(--w-radius-1);\n background: var(--unn-color-bg-secondary);\n color: var(--unn-color-text-primary); font-size: var(--w-font-sm);\n padding: 6px 8px; outline: none; font-family: inherit;\n }\n .capture-description-input:focus { border-color: var(--unn-color-accent); }\n .capture-error {\n font-size: var(--w-font-xs); color: var(--unn-color-error, #d32f2f); margin: 0;\n }\n .capture-actions {\n display: flex; gap: 6px; justify-content: flex-end;\n }\n .capture-save-btn {\n padding: 3px 12px; border-radius: var(--w-radius-lg);\n border: none; background: var(--unn-color-accent); color: #fff;\n font-size: var(--w-font-sm); cursor: pointer;\n }\n .capture-save-btn:disabled { opacity: 0.6; cursor: not-allowed; }\n /* Search bar — always visible */\n .home-search-bar {\n padding: 8px 10px 2px;\n flex-shrink: 0;\n }\n .home-search-input {\n width: 100%; box-sizing: border-box; height: 26px;\n border: 1px solid var(--unn-color-border-default);\n border-radius: var(--w-radius-lg);\n background: var(--unn-color-bg-secondary);\n color: var(--unn-color-text-primary); font-size: var(--w-font-sm);\n padding: 0 10px; outline: none;\n transition: border-color 0.15s, box-shadow 0.15s;\n }\n .home-search-input:focus {\n border-color: var(--unn-color-brand-primary);\n box-shadow: 0 0 0 3px var(--unn-color-brand-tint);\n }\n\n /* Sections scroll area */\n .home-sections {\n flex: 1; overflow-y: auto;\n padding: 10px 10px 20px;\n display: flex; flex-direction: column; gap: 24px;\n }\n\n /* ---- Sections — no card border, grouped by heading + spacing ---- */\n .home-section { /* bare container, no border/bg */ }\n .home-section:not(:last-child) {\n border-bottom: 1px solid var(--unn-color-border-default);\n padding-bottom: 20px;\n }\n .home-section-header {\n display: flex; align-items: center; justify-content: space-between;\n padding: 0 0 6px;\n }\n .home-section-title {\n display: flex; align-items: center; gap: 6px;\n font-size: 10px; font-weight: 700; letter-spacing: 0.07em;\n text-transform: uppercase; color: var(--unn-color-text-muted);\n }\n .home-section-dot {\n width: 12px; height: 12px; flex-shrink: 0;\n display: flex; align-items: center; justify-content: center;\n }\n .home-section-dot svg {\n width: 12px; height: 12px; display: block;\n }\n .home-section-add {\n font-size: 15px; font-weight: 400; line-height: 1;\n color: var(--unn-color-brand-primary);\n background: transparent;\n border: none; cursor: pointer;\n padding: 0 2px; border-radius: var(--w-radius-sm);\n transition: color 0.15s; flex-shrink: 0;\n }\n .home-section-add:hover { color: var(--unn-color-accent-strong); }\n .home-section-add:disabled { color: var(--unn-color-text-subtle); cursor: default; }\n .home-section-show-all {\n font-size: 10px; font-weight: 400; line-height: 1;\n color: var(--unn-color-text-secondary);\n background: transparent;\n border: none; cursor: pointer;\n padding: 2px 4px; border-radius: var(--w-radius-sm);\n transition: color 0.15s; flex-shrink: 0;\n margin-right: 4px;\n }\n .home-section-show-all:hover { \n color: var(--unn-color-text); \n background: var(--unn-color-surface-subtle);\n }\n .home-section-helper {\n font-size: 10px; color: var(--unn-color-text-subtle);\n margin: -4px 0 6px; line-height: 1.4;\n }\n\n /* ---- Concept rows ---- */\n .concept-row {\n display: flex; align-items: center; gap: 8px;\n padding: 6px 6px; cursor: pointer;\n margin: 0 -6px;\n transition: background 0.12s;\n border-radius: var(--w-radius-sm);\n }\n .concept-row:hover { background: var(--unn-color-bg-secondary); }\n .concept-row:hover .concept-name { color: var(--unn-color-brand-primary); }\n .concept-name {\n flex: 1; font-size: var(--w-font-base); font-weight: 500;\n color: var(--unn-color-text-primary);\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n transition: color 0.12s;\n }\n .concept-abbr {\n font-size: var(--w-font-xs); color: var(--unn-color-accent-strong);\n background: var(--unn-color-accent-tint-bg);\n border-radius: var(--w-radius-pill);\n padding: 1px 7px; white-space: nowrap; flex-shrink: 0; font-weight: 500;\n }\n .concept-chevron {\n flex-shrink: 0; color: var(--unn-color-text-subtle);\n opacity: 0.35; transition: opacity 0.12s, color 0.12s;\n }\n .concept-chevron svg { width: 12px; height: 12px; stroke: currentColor; fill: none; stroke-width: 2.5; }\n .concept-row:hover .concept-chevron { opacity: 1; color: var(--unn-color-brand-primary); }\n .concept-subheading {\n font-size: 10px; font-weight: 700; letter-spacing: 0.06em;\n text-transform: uppercase; color: var(--unn-color-text-subtle);\n padding: 8px 0 4px; margin-top: 4px;\n }\n .concept-subheading:first-child { margin-top: 0; }\n\n /* ---- Section empty states ---- */\n .section-empty { padding: 14px 0 6px; text-align: left; }\n .section-empty-title {\n font-size: var(--w-font-sm); font-weight: 600;\n color: var(--unn-color-text-body); margin-bottom: 4px;\n }\n .section-empty-text {\n font-size: var(--w-font-sm); color: var(--unn-color-text-subtle); line-height: 1.5;\n margin-bottom: 12px;\n }\n .section-empty-action {\n all: unset; display: inline-flex; cursor: pointer;\n font-size: var(--w-font-sm); font-weight: 500;\n color: var(--unn-color-text-primary);\n border: 1px solid var(--unn-color-border-default);\n border-radius: var(--w-radius-sm);\n padding: 5px 12px;\n transition: background 0.15s, border-color 0.15s;\n }\n .section-empty-action:hover {\n background: var(--unn-color-bg-secondary);\n border-color: var(--unn-color-text-muted);\n }\n\n /* ---- Memory items in PRODUCT MEMORY home section ---- */\n .memory-item {\n display: flex; align-items: center; gap: 8px;\n padding: 6px 6px; cursor: pointer;\n margin: 0 -6px;\n transition: background 0.12s;\n border-radius: var(--w-radius-sm);\n }\n .memory-item:hover { background: var(--unn-color-bg-secondary); }\n .memory-item:hover .memory-item-title { color: var(--unn-color-brand-primary); }\n .memory-item:hover .concept-chevron { opacity: 1; color: var(--unn-color-brand-primary); }\n .memory-item-content {\n flex: 1; min-width: 0;\n }\n .memory-item-title {\n font-size: var(--w-font-base); font-weight: 500;\n color: var(--unn-color-text-primary);\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n transition: color 0.12s;\n }\n .memory-item-meta {\n font-size: var(--w-font-xs); color: var(--unn-color-text-subtle);\n margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n }\n\n /* ---- Show-all link ---- */\n .home-show-more {\n display: block; width: 100%; box-sizing: border-box;\n padding: 6px 0; font-size: var(--w-font-xs); font-weight: 500;\n color: var(--unn-color-brand-primary); cursor: pointer; text-align: left;\n margin-top: 2px; text-decoration: none;\n transition: color 0.15s;\n }\n .home-show-more:hover { \n color: var(--unn-color-accent-strong); \n text-decoration: underline;\n }\n\n /* ---- Discussion cards in home ---- */\n .discussion-card {\n display: flex; align-items: flex-start; gap: 8px;\n padding: 6px 6px; cursor: pointer;\n margin: 0 -6px;\n transition: background 0.12s;\n border-radius: var(--w-radius-sm);\n }\n .discussion-card:hover { background: var(--unn-color-bg-tertiary); }\n .discussion-card:hover .concept-chevron { opacity: 1; color: var(--unn-color-brand-primary); }\n .discussion-card-main {\n flex: 1;\n }\n .discussion-meta {\n display: flex; align-items: center; gap: 5px;\n font-size: 10px; color: var(--unn-color-text-subtle);\n margin-bottom: 3px; font-weight: 500;\n }\n .discussion-meta-dot {\n width: 4px; height: 4px; border-radius: 50%;\n background: var(--unn-color-brand-secondary); flex-shrink: 0;\n }\n .discussion-body {\n margin: 0; font-size: var(--w-font-sm); color: var(--unn-color-text-body);\n white-space: pre-wrap; word-break: break-word; line-height: 1.5;\n display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;\n }\n .discussion-replies { margin-top: 5px; padding-left: 10px; border-left: 2px solid var(--unn-color-border-default); }\n .discussion-reply { margin-top: 4px; }\n\n /* ---- Clarification detail view ---- */\n .clarif-label {\n font-size: var(--w-font-xs); font-weight: 600; letter-spacing: 0.06em;\n text-transform: uppercase; color: var(--unn-color-text-subtle);\n margin-bottom: 6px;\n }\n .clarif-question {\n margin: 0 0 4px; font-size: var(--w-font-md);\n color: var(--unn-color-text-primary); line-height: 1.5;\n font-weight: var(--w-weight-semi); white-space: pre-wrap; word-break: break-word;\n }\n .clarif-empty-replies {\n font-size: var(--w-font-sm); color: var(--unn-color-text-subtle);\n padding: 6px 0;\n }\n .clarif-reply-item {\n padding: 6px 0;\n border-bottom: 1px solid var(--unn-color-border-subtle);\n }\n .clarif-reply-item:last-child { border-bottom: none; }\n .clarif-reply-form {\n padding: 10px 12px 12px;\n border-top: 1px solid var(--unn-color-border-default);\n margin-top: 6px;\n }\n\n /* ---- Ask Question form ---- */\n .ask-form { padding: 10px 12px; border-bottom: 1px solid var(--unn-color-border-default); }\n .ask-textarea {\n width: 100%; box-sizing: border-box;\n border: 1px solid var(--unn-color-border-default);\n border-radius: var(--w-radius-sm);\n background: var(--unn-color-bg-secondary);\n color: var(--unn-color-text-primary); font-size: var(--w-font-sm);\n padding: 7px 10px; resize: vertical; outline: none; font-family: inherit;\n transition: border-color 0.15s;\n }\n .ask-textarea:focus { border-color: var(--unn-color-brand-primary); }\n .ask-actions { display: flex; gap: 6px; justify-content: flex-end; margin-top: 6px; }\n .ask-cancel, .ask-submit {\n font-size: var(--w-font-xs); font-weight: 500; border: none;\n border-radius: var(--w-radius-sm); cursor: pointer; padding: 5px 12px;\n }\n .ask-cancel { background: var(--unn-color-bg-tertiary); color: var(--unn-color-text-muted); }\n .ask-cancel:hover { background: var(--unn-color-border-default); }\n .ask-submit { background: var(--unn-color-brand-primary); color: #fff; }\n .ask-submit:hover { opacity: 0.88; }\n .ask-submit:disabled { opacity: 0.5; cursor: default; }\n\n /* ---- Add Term form ---- */\n .add-term-form { padding: 10px 12px; border-bottom: 1px solid var(--unn-color-border-default); }\n .add-term-input {\n width: 100%; box-sizing: border-box;\n border: 1px solid var(--unn-color-border-default);\n border-radius: var(--w-radius-sm);\n background: var(--unn-color-bg-secondary);\n color: var(--unn-color-text-primary); font-size: var(--w-font-sm);\n padding: 7px 10px; outline: none; font-family: inherit;\n transition: border-color 0.15s;\n }\n .add-term-input:focus { border-color: var(--unn-color-brand-primary); }\n .add-term-input + .add-term-input { margin-top: 6px; }\n /* ── Ask view (LQ-12) ─────────────────────────────────────────────── */\n .home-ask-entry {\n display: flex; align-items: center; gap: 6px; width: 100%;\n margin: 0 0 6px 0; padding: 8px 10px; cursor: pointer; text-align: left;\n font-family: inherit; font-size: var(--w-font-base);\n color: var(--unn-color-text-primary);\n background: var(--unn-color-bg-tertiary);\n border: 1px solid var(--unn-color-border-default); border-radius: 6px;\n }\n .home-ask-entry:hover { border-color: var(--unn-color-brand-primary); }\n .ask-view { display: flex; flex-direction: column; }\n .askv-head { padding: 10px 12px 4px; }\n .askv-title {\n font-size: var(--w-font-md); font-weight: var(--w-weight-semi);\n color: var(--unn-color-text-primary);\n }\n .askv-notice {\n display: flex; align-items: flex-start; gap: 8px; margin: 8px 12px;\n padding: 8px 10px; border-radius: 6px; line-height: 1.4;\n font-size: var(--w-font-sm); color: var(--unn-color-text-muted);\n background: var(--unn-color-bg-tertiary);\n border: 1px solid var(--unn-color-border-default);\n }\n .askv-notice-dismiss {\n flex: 0 0 auto; cursor: pointer; font-family: inherit;\n font-size: var(--w-font-sm); padding: 2px 8px; border-radius: 4px;\n background: transparent; color: var(--unn-color-brand-primary);\n border: 1px solid var(--unn-color-border-default);\n }\n .askv-form { padding: 8px 12px 0; }\n .askv-form-footer {\n display: flex; align-items: center; justify-content: space-between;\n margin-top: 6px;\n }\n .askv-counter { font-size: var(--w-font-xs); color: var(--unn-color-text-muted); }\n .askv-limits, .askv-provenance {\n padding: 6px 12px; font-size: var(--w-font-xs);\n color: var(--unn-color-text-muted);\n }\n .askv-disabled {\n margin: 8px 12px; padding: 10px; border-radius: 6px;\n font-size: var(--w-font-base); color: var(--unn-color-text-muted);\n background: var(--unn-color-bg-tertiary);\n border: 1px solid var(--unn-color-border-default);\n }\n .askv-result { padding: 0 12px 12px; }\n .askv-staleness { font-size: var(--w-font-xs); margin: 6px 0; }\n .askv-tone-ok { color: var(--unn-color-text-muted); }\n .askv-tone-muted { color: var(--unn-color-text-muted); opacity: 0.85; }\n .askv-tone-warn { color: #b45309; }\n .askv-loading {\n display: flex; align-items: center; gap: 8px; padding: 12px 0;\n font-size: var(--w-font-base); color: var(--unn-color-text-muted);\n }\n .askv-spinner {\n width: 12px; height: 12px; border-radius: 50%;\n border: 2px solid var(--unn-color-border-default);\n border-top-color: var(--unn-color-brand-primary);\n animation: askv-spin 0.7s linear infinite;\n }\n @keyframes askv-spin { to { transform: rotate(360deg); } }\n .askv-answer {\n font-size: var(--w-font-base); line-height: 1.55; white-space: pre-wrap;\n color: var(--unn-color-text-primary);\n }\n .askv-unnarrated {\n font-size: var(--w-font-base); line-height: 1.5; margin-bottom: 8px;\n color: var(--unn-color-text-muted);\n }\n .ask-chip {\n display: inline-block; margin: 0 2px; padding: 1px 6px;\n border-radius: 10px; font-size: var(--w-font-xs); white-space: nowrap;\n background: var(--unn-color-bg-tertiary);\n color: var(--unn-color-text-primary);\n border: 1px solid var(--unn-color-border-default);\n }\n .askv-section { margin-top: 12px; }\n .askv-section-title {\n font-size: var(--w-font-xxs); letter-spacing: 0.06em;\n color: var(--unn-color-text-muted); margin-bottom: 4px;\n }\n .askv-path { display: flex; flex-wrap: wrap; align-items: center; gap: 2px; padding: 3px 0; }\n .askv-path-arrow { color: var(--unn-color-text-muted); font-size: var(--w-font-xs); }\n .askv-note {\n padding: 6px 8px; margin-bottom: 4px; cursor: pointer; border-radius: 6px;\n border: 1px solid var(--unn-color-border-default);\n }\n .askv-note:hover { border-color: var(--unn-color-brand-primary); }\n .askv-note-title {\n font-size: var(--w-font-base); font-weight: var(--w-weight-semi);\n color: var(--unn-color-text-primary);\n }\n .askv-note-route, .askv-note-body {\n font-size: var(--w-font-xs); color: var(--unn-color-text-muted); margin-top: 2px;\n }\n .askv-confidence-row {\n display: flex; gap: 6px; flex-wrap: wrap;\n font-size: var(--w-font-xs); color: var(--unn-color-text-muted);\n }\n .askv-confidence-claim { color: var(--unn-color-text-primary); }\n .askv-error {\n display: flex; align-items: center; justify-content: space-between; gap: 8px;\n margin-top: 10px; padding: 8px 10px; border-radius: 6px;\n font-size: var(--w-font-base); color: #b42318;\n background: var(--unn-color-bg-tertiary); border: 1px solid #f3c6c2;\n }\n .askv-retry {\n flex: 0 0 auto; cursor: pointer; font-family: inherit;\n font-size: var(--w-font-sm); padding: 3px 8px; border-radius: 4px;\n background: var(--unn-color-brand-primary); color: #fff; border: none;\n }\n\n`;\n\n/** CSS injected into the ShadowRoot when the panel runs in a popup window. */\nexport const POPOUT_OVERRIDE_STYLE = `\n .panel-shell {\n position: static !important;\n width: 100vw !important; height: 100vh !important;\n transform: none !important;\n max-width: 100vw !important;\n border-radius: 0 !important;\n box-shadow: none !important;\n }\n .panel-shell.open { transform: none !important; }\n .panel {\n border-radius: 0 !important;\n border: none !important;\n /* Fallback bg if CSS vars haven't re-resolved after adoptNode */\n background: var(--unn-color-bg-primary, #ffffff) !important;\n }\n`;\n","import type { SsoProviders } from \"../../types/config\";\n\nexport interface LoginViewCallbacks {\n onLogin: (email: string, password: string) => void;\n onSsoLogin?: (provider: string) => void;\n /** If provided, a back button is rendered and this callback is invoked on click. */\n onBack?: (() => void) | null;\n}\n\nexport function renderLoginView(\n body: HTMLElement,\n cb: LoginViewCallbacks,\n providers?: SsoProviders,\n): void {\n const showGoogle = providers?.googleEnabled === true;\n const showMicrosoft = providers?.microsoftEnabled === true;\n const hasSso = showGoogle || showMicrosoft;\n\n const googleBtnHtml = showGoogle\n ? `<button class=\"sso-btn\" type=\"button\" data-testid=\"widget-sso-google-btn\" aria-label=\"Continue with Google\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path fill=\"#4285F4\" d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z\"/>\n <path fill=\"#34A853\" d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"/>\n <path fill=\"#FBBC05\" d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l3.66-2.84z\"/>\n <path fill=\"#EA4335\" d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"/>\n </svg>\n <span>Continue with Google</span>\n </button>`\n : \"\";\n\n const microsoftBtnHtml = showMicrosoft\n ? `<button class=\"sso-btn\" type=\"button\" data-testid=\"widget-sso-microsoft-btn\" aria-label=\"Continue with Microsoft\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 23 23\" aria-hidden=\"true\">\n <rect x=\"1\" y=\"1\" width=\"10\" height=\"10\" fill=\"#F25022\"/>\n <rect x=\"12\" y=\"1\" width=\"10\" height=\"10\" fill=\"#7FBA00\"/>\n <rect x=\"1\" y=\"12\" width=\"10\" height=\"10\" fill=\"#00A4EF\"/>\n <rect x=\"12\" y=\"12\" width=\"10\" height=\"10\" fill=\"#FFB900\"/>\n </svg>\n <span>Continue with Microsoft</span>\n </button>`\n : \"\";\n\n const dividerHtml = hasSso\n ? `<div class=\"sso-divider\" data-testid=\"widget-sso-divider\">\n <div class=\"sso-divider-line\"></div>\n <span class=\"sso-divider-text\">or sign in with</span>\n <div class=\"sso-divider-line\"></div>\n </div>`\n : \"\";\n\n const ssoSectionHtml = hasSso\n ? `${dividerHtml}<div class=\"sso-buttons\">${googleBtnHtml}${microsoftBtnHtml}</div>`\n : \"\";\n\n body.innerHTML = `\n <div class=\"login-form\">\n ${cb.onBack ? `<button class=\"login-back-btn\" data-testid=\"widget-login-back\" type=\"button\">‹ Back</button>` : \"\"}\n <h2 class=\"login-heading\">Sign in to Unnoodle</h2>\n <p class=\"login-sub\">Access your team's glossary</p>\n <div class=\"login-error\" role=\"alert\" data-testid=\"widget-login-error\"></div>\n <div class=\"form-field\">\n <label class=\"form-label\" for=\"unn-email\">Email</label>\n <input class=\"form-input\" id=\"unn-email\" type=\"email\"\n autocomplete=\"email\" placeholder=\"you@company.com\" required\n data-testid=\"widget-login-email\" />\n </div>\n <div class=\"form-field\">\n <label class=\"form-label\" for=\"unn-password\">Password</label>\n <input class=\"form-input\" id=\"unn-password\" type=\"password\"\n autocomplete=\"current-password\" placeholder=\"••••••••\" required\n data-testid=\"widget-login-password\" />\n </div>\n <button class=\"form-submit\" id=\"unn-submit\" data-testid=\"widget-login-submit\">Sign in</button>\n ${ssoSectionHtml}\n </div>\n `;\n\n const backBtn = body.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-login-back\"]',\n );\n if (backBtn && cb.onBack) {\n const back = cb.onBack;\n backBtn.addEventListener(\"click\", () => back());\n }\n\n const emailEl = body.querySelector(\"#unn-email\") as HTMLInputElement;\n const passEl = body.querySelector(\"#unn-password\") as HTMLInputElement;\n const submitEl = body.querySelector(\"#unn-submit\") as HTMLButtonElement;\n\n const handleSubmit = (e: Event) => {\n e.preventDefault();\n const email = emailEl.value.trim();\n const password = passEl.value;\n if (!email || !password) return;\n cb.onLogin(email, password);\n };\n\n submitEl.addEventListener(\"click\", handleSubmit);\n // Allow Enter key to submit\n passEl.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\") handleSubmit(e);\n });\n\n // Wire up SSO buttons\n if (cb.onSsoLogin) {\n const ssoHandler = cb.onSsoLogin;\n if (showGoogle) {\n const googleBtn = body.querySelector(\n '[data-testid=\"widget-sso-google-btn\"]',\n ) as HTMLButtonElement | null;\n googleBtn?.addEventListener(\"click\", () => ssoHandler(\"google\"));\n }\n if (showMicrosoft) {\n const microsoftBtn = body.querySelector(\n '[data-testid=\"widget-sso-microsoft-btn\"]',\n ) as HTMLButtonElement | null;\n microsoftBtn?.addEventListener(\"click\", () => ssoHandler(\"microsoft\"));\n }\n }\n\n emailEl.focus();\n}\n\nexport function setLoginLoadingState(\n body: HTMLElement,\n loading: boolean,\n): void {\n const submitEl = body.querySelector(\n \"#unn-submit\",\n ) as HTMLButtonElement | null;\n if (!submitEl) return;\n submitEl.disabled = loading;\n submitEl.textContent = loading ? \"Signing in\\u2026\" : \"Sign in\";\n}\n\nexport function setLoginErrorState(body: HTMLElement, message: string): void {\n const errEl = body.querySelector(\".login-error\") as HTMLElement | null;\n if (!errEl) return;\n errEl.textContent = message;\n errEl.classList.add(\"visible\");\n}\n","/** HTML-escape user content to prevent XSS. */\nexport function escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#039;\");\n}\n","import type { ContextDiscussion } from \"../../types/config\";\nimport { escapeHtml } from \"../utils\";\n\nexport interface ClarificationViewCallbacks {\n onBack?: () => void;\n onPostReply?: (contextId: number, discussionId: number, text: string) => void;\n}\n\nexport function renderClarificationDetailView(\n body: HTMLElement,\n discussion: ContextDiscussion,\n canReply: boolean,\n cb: ClarificationViewCallbacks,\n): void {\n const authorLabel = escapeHtml(discussion.authorName ?? \"Unknown\");\n const date = discussion.createdAt\n ? new Date(discussion.createdAt).toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n })\n : \"\";\n\n const repliesHtml =\n (discussion.replies ?? []).length === 0\n ? `<div class=\"clarif-empty-replies\">No replies yet.</div>`\n : discussion.replies\n .map(\n (r) => `\n <div class=\"clarif-reply-item\">\n <div class=\"discussion-meta\">\n <span class=\"discussion-meta-dot\"></span>\n ${escapeHtml(r.authorName ?? \"Unknown\")} &middot;\n ${new Date(r.createdAt).toLocaleDateString(undefined, { month: \"short\", day: \"numeric\" })}\n </div>\n <p class=\"discussion-body\" style=\"-webkit-line-clamp:unset\">${escapeHtml(r.body)}</p>\n </div>`,\n )\n .join(\"\");\n\n const replyFormHtml = canReply\n ? `<div class=\"clarif-reply-form\" data-testid=\"widget-reply-form\">\n <textarea class=\"ask-textarea\" data-testid=\"widget-reply-textarea\"\n placeholder=\"Write a reply…\" maxlength=\"2000\" rows=\"3\"></textarea>\n <div class=\"ask-actions\">\n <button class=\"ask-submit\" data-testid=\"widget-reply-submit\">Reply</button>\n </div>\n <p class=\"ask-error\" style=\"display:none\"></p>\n </div>`\n : ``;\n\n body.innerHTML = `\n <div class=\"term-detail-view\" data-testid=\"widget-clarif-detail\">\n <div class=\"detail-back\">\n <button class=\"back-btn\" data-testid=\"widget-back-btn\">&#8592; Back</button>\n </div>\n <div class=\"detail-content\">\n <div class=\"detail-body\">\n <div class=\"clarif-label\">CLARIFICATION</div>\n <p class=\"clarif-question\">${escapeHtml(discussion.body)}</p>\n <div class=\"discussion-meta\" style=\"margin-top:6px\">\n <span class=\"discussion-meta-dot\"></span>\n ${authorLabel} &middot; ${date}\n </div>\n </div>\n </div>\n <div class=\"discussions-section\">\n <div class=\"discussions-heading\">Replies (${(discussion.replies ?? []).length})</div>\n ${repliesHtml}\n </div>\n ${replyFormHtml}\n </div>\n `;\n\n const backBtn = body.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-back-btn\"]',\n )!;\n backBtn.addEventListener(\"click\", () => cb.onBack?.());\n\n if (canReply) {\n const textarea = body.querySelector<HTMLTextAreaElement>(\n '[data-testid=\"widget-reply-textarea\"]',\n )!;\n const submitBtn = body.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-reply-submit\"]',\n )!;\n const errorEl = body.querySelector<HTMLParagraphElement>(\".ask-error\")!;\n\n submitBtn.addEventListener(\"click\", () => {\n const text = textarea.value.trim();\n if (!text) return;\n errorEl.style.display = \"none\";\n submitBtn.disabled = true;\n submitBtn.textContent = \"Posting\\u2026\";\n cb.onPostReply?.(discussion.contextId, discussion.id, text);\n });\n }\n}\n","import type { ElementSnapshot } from \"../../core/product-memory/elementSnapshot\";\n\nexport function enterPickModeView(strip: HTMLElement, onCancel: () => void): void {\n (strip.querySelector<HTMLElement>(\".strip-idle\") as HTMLElement).style.display = \"none\";\n const prompt = strip.querySelector<HTMLElement>(\".pick-mode-prompt\") as HTMLElement;\n prompt.style.display = \"flex\";\n (strip.querySelector<HTMLElement>(\".capture-describe-view\") as HTMLElement).style.display = \"none\";\n // Clone cancel button to remove stale listeners\n const cancelBtn = strip.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-context-strip-cancel-btn\"]',\n )!;\n const fresh = cancelBtn.cloneNode(true) as HTMLButtonElement;\n fresh.addEventListener(\"click\", onCancel);\n cancelBtn.replaceWith(fresh);\n}\n\nexport function showCaptureDescribeView(\n strip: HTMLElement,\n snapshot: ElementSnapshot,\n onSave: (description: string) => void,\n onPickAgain: () => void,\n): void {\n (strip.querySelector<HTMLElement>(\".strip-idle\") as HTMLElement).style.display = \"none\";\n (strip.querySelector<HTMLElement>(\".pick-mode-prompt\") as HTMLElement).style.display = \"none\";\n const descView = strip.querySelector<HTMLElement>(\".capture-describe-view\") as HTMLElement;\n descView.style.display = \"flex\";\n // Populate snapshot preview\n const preview = descView.querySelector<HTMLElement>(\n '[data-testid=\"widget-capture-snapshot-preview\"]',\n ) as HTMLElement;\n preview.innerHTML = snapshot.html;\n // Wire pick-again (clone to remove stale listeners)\n const pickAgainBtn = descView.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-capture-pick-again-btn\"]',\n )!;\n const freshPickAgain = pickAgainBtn.cloneNode(true) as HTMLButtonElement;\n freshPickAgain.addEventListener(\"click\", onPickAgain);\n pickAgainBtn.replaceWith(freshPickAgain);\n // Wire save (clone to remove stale listeners)\n const saveBtn = descView.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-capture-save-btn\"]',\n )!;\n const freshSave = saveBtn.cloneNode(true) as HTMLButtonElement;\n (descView.querySelector<HTMLElement>(\".capture-error\") as HTMLElement).style.display = \"none\";\n freshSave.addEventListener(\"click\", () => {\n const textarea = descView.querySelector<HTMLTextAreaElement>(\n '[data-testid=\"widget-capture-description-input\"]',\n )!;\n void onSave(textarea.value.trim());\n });\n saveBtn.replaceWith(freshSave);\n}\n\nexport function setCaptureLoadingState(strip: HTMLElement, loading: boolean): void {\n const saveBtn = strip.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-capture-save-btn\"]',\n );\n if (!saveBtn) return;\n saveBtn.disabled = loading;\n saveBtn.textContent = loading ? \"Saving\\u2026\" : \"Save\";\n}\n\nexport function setCaptureErrorState(strip: HTMLElement, message: string): void {\n const err = strip.querySelector<HTMLElement>(\".capture-error\");\n if (!err) return;\n err.textContent = message;\n err.style.display = message ? \"block\" : \"none\";\n}\n\nexport function exitCaptureModeView(strip: HTMLElement): void {\n (strip.querySelector<HTMLElement>(\".strip-idle\") as HTMLElement).style.display = \"flex\";\n (strip.querySelector<HTMLElement>(\".pick-mode-prompt\") as HTMLElement).style.display = \"none\";\n (strip.querySelector<HTMLElement>(\".capture-describe-view\") as HTMLElement).style.display = \"none\";\n const textarea = strip.querySelector<HTMLTextAreaElement>(\n '[data-testid=\"widget-capture-description-input\"]',\n );\n if (textarea) textarea.value = \"\";\n const errEl = strip.querySelector<HTMLElement>(\".capture-error\");\n if (errEl) {\n errEl.textContent = \"\";\n errEl.style.display = \"none\";\n }\n}\n","/**\n * The Ask view — LQ-12 / LLD §13.3, HLD §10.\n *\n * Renders the question box, the answer with `[nX]` references turned into\n * chips, the un-narrated fallback (paths + notes when the model produced no\n * prose), the authored notes, the confidence claims, and the staleness /\n * provenance lines.\n *\n * Every string that reaches this module is untrusted: the answer is model\n * output a note author can steer, and a route class is derived from a captured\n * URL. `escapeHtml` is injected rather than imported so the escaping seam is\n * visible at the call site and directly testable (R4-02).\n */\nimport type {\n AskAnswer,\n AskNote,\n AskProvenance,\n AskStatus,\n NodeRef,\n} from \"../../../types/ask\";\n\nexport interface AskViewCallbacks {\n onAsk: (question: string) => void;\n onOpenMemory?: (memoryId: number) => void;\n onBack?: () => void;\n}\n\nexport interface AskViewControls {\n /** Question box + staleness line; the first-use notice until dismissed. */\n render(status: AskStatus | null): void;\n /** Disable the input, show the spinner and \"asking…\". */\n setLoading(): void;\n /** Re-enable the input without rendering a result (abort path). */\n clearLoading(): void;\n /** Prose with chips; paths + notes when `answer === \"\"`; staleness line. */\n showAnswer(answer: AskAnswer): void;\n showError(message: string, retryable: boolean): void;\n}\n\n/** HLD §10.1: the question box caps the question at 500 characters. */\nexport const ASK_MAX_QUESTION_CHARS = 500;\n\nconst FIRST_USE_NOTICE =\n \"Your question is sent to OpenAI. Names of buttons and fields are never \" +\n \"sent — only page routes and your team's notes.\";\n\n/**\n * \"dismissed once, remembered in memory for the session\" (HLD §10.1, A §12.3).\n * Deliberately module state and not storage: the notice is a session courtesy,\n * not a consent record, and nothing about the user is persisted for it.\n */\nlet firstUseNoticeDismissed = false;\n\n/** Test-only: the notice is module state, so a test must be able to reset it. */\nexport function resetAskFirstUseNotice(): void {\n firstUseNoticeDismissed = false;\n}\n\n// ---------------------------------------------------------------------------\n// R4-02 — the escaping seam\n// ---------------------------------------------------------------------------\n\n/**\n * `[n4]` → `<span class=\"ask-chip\" data-ref=\"n4\"\n * data-testid=\"widget-ask-chip-n4\">page · /invoices</span>`.\n *\n * ORDER IS LOAD-BEARING (R4-02, critical). The return value goes to\n * `innerHTML`, and `answer` is model output that can contain anything a note\n * author put in front of it. Therefore:\n *\n * 1. `escapeHtml(answer)` — FIRST, on the whole string\n * 2. THEN substitute `/\\[n\\d+\\]/g` — the only markup this function introduces\n * 3. `escapeHtml(routeClass)` and `escapeHtml(kind)` before they enter the\n * span — a route class is derived from a captured URL and is not\n * trusted either\n *\n * Escaping AFTER substitution would neutralise the spans (and double-escape\n * every entity the first pass produced); escaping only the answer would let a\n * route class carrying `\"><img onerror=...>` execute in the customer's own\n * page. The `[nN]` token survives step 1 untouched because it contains no\n * escapable character, which is what makes this order possible at all.\n *\n * A reference the map does not know is dropped, matching the server-side\n * parser, which never emits a ref it could not resolve (LLD §9.3).\n */\nexport function renderAnswerHtml(\n answer: string,\n refs: Record<string, NodeRef>,\n escapeHtml: (s: string) => string,\n): string {\n // 1 — escape the whole untrusted string first.\n const escaped = escapeHtml(answer ?? \"\");\n\n // 2 — substitute; this is the only markup introduced here.\n return escaped.replace(/\\[n\\d+\\]/g, (token) => {\n const id = token.slice(1, -1); // `\\d` only: safe as an attribute value\n const ref = refs?.[id];\n if (!ref) return \"\"; // invented ref — dropped, never resolved\n // 3 — escape each field before it enters the span.\n const label = `${escapeHtml(ref.kind ?? \"\")} · ${escapeHtml(ref.routeClass ?? \"\")}`;\n return (\n `<span class=\"ask-chip\" data-ref=\"${id}\" ` +\n `data-testid=\"widget-ask-chip-${id}\" title=\"${escapeHtml(ref.tier ?? \"\")}\">` +\n `${label}</span>`\n );\n });\n}\n\n/** A chip for a ref id used outside the prose (paths list). Same rule 3. */\nfunction chipHtml(\n id: string,\n ref: NodeRef | undefined,\n escapeHtml: (s: string) => string,\n): string {\n if (!ref) return \"\";\n const safeId = escapeHtml(id);\n return (\n `<span class=\"ask-chip\" data-ref=\"${safeId}\" ` +\n `data-testid=\"widget-ask-path-chip-${safeId}\">` +\n `${escapeHtml(ref.kind ?? \"\")} · ${escapeHtml(ref.routeClass ?? \"\")}</span>`\n );\n}\n\n// ---------------------------------------------------------------------------\n// Staleness\n// ---------------------------------------------------------------------------\n\nexport interface StalenessLine {\n text: string;\n tone: \"ok\" | \"warn\" | \"muted\";\n}\n\n/** Past this, a warm graph is still served but shown amber (LLD §13.3). */\nconst STALE_AFTER_SECONDS = 3600;\n\nfunction clockOf(builtAt: string | undefined, stalenessSeconds: number): string {\n const parsed = builtAt ? Date.parse(builtAt) : NaN;\n const ms = Number.isNaN(parsed)\n ? Date.now() - Math.max(0, stalenessSeconds) * 1000\n : parsed;\n const d = new Date(ms);\n if (Number.isNaN(d.getTime())) return \"\";\n return `${String(d.getHours()).padStart(2, \"0\")}:${String(d.getMinutes()).padStart(2, \"0\")}`;\n}\n\n/**\n * `\"warm\"` → `graph as of HH:MM · generation g` (amber past 3600 s) ·\n * `\"cold\"` → `graph warming up — team notes only` · `\"empty\"`/`\"none\"` →\n * `no graph yet — team notes only` · `\"no-anchor\"` → `\"\"` · `\"stale\"` → amber\n * line. `\"erased\"` is not in the LLD's list; it is the authored-only case, so\n * it takes the same wording as `empty`/`none` with a muted tone.\n */\nexport function stalenessLine(p: AskProvenance): StalenessLine {\n const graph = p?.graph;\n const staleness = p?.stalenessSeconds ?? 0;\n const asOf = () =>\n `graph as of ${clockOf(p?.builtAt, staleness)} · generation ${p?.generation ?? 0}`;\n\n switch (graph) {\n case \"warm\":\n return { text: asOf(), tone: staleness > STALE_AFTER_SECONDS ? \"warn\" : \"ok\" };\n case \"stale\":\n return { text: asOf(), tone: \"warn\" };\n case \"cold\":\n return { text: \"graph warming up — team notes only\", tone: \"muted\" };\n case \"empty\":\n case \"none\":\n case \"erased\":\n return { text: \"no graph yet — team notes only\", tone: \"muted\" };\n case \"no-anchor\":\n return { text: \"\", tone: \"muted\" };\n default:\n return { text: \"\", tone: \"muted\" };\n }\n}\n\n/**\n * `GET /api/ask/status` carries no `builtAt`, so the pre-question line is\n * derived from `stalenessSeconds` against the local clock. Same wording.\n */\nfunction statusStalenessLine(status: AskStatus): StalenessLine {\n return stalenessLine({\n graph: status.graph,\n notes: \"ok\",\n model: \"ok\",\n generation: status.generation,\n appBuild: \"\",\n builtAt: \"\",\n stalenessSeconds: status.stalenessSeconds,\n flowsConsidered: 0,\n });\n}\n\n// ---------------------------------------------------------------------------\n// The view\n// ---------------------------------------------------------------------------\n\nexport function createAskView(\n body: HTMLElement,\n cb: AskViewCallbacks,\n escapeHtml: (s: string) => string,\n): AskViewControls {\n let lastStatus: AskStatus | null = null;\n\n const esc = (s: unknown) => escapeHtml(String(s ?? \"\"));\n\n function root(): HTMLElement | null {\n return body.querySelector<HTMLElement>('[data-testid=\"widget-ask-view\"]');\n }\n\n function resultEl(): HTMLElement | null {\n return body.querySelector<HTMLElement>('[data-testid=\"widget-ask-result\"]');\n }\n\n function inputEl(): HTMLTextAreaElement | null {\n return body.querySelector<HTMLTextAreaElement>(\n '[data-testid=\"widget-ask-input\"]',\n );\n }\n\n function submitEl(): HTMLButtonElement | null {\n return body.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-ask-submit\"]',\n );\n }\n\n /** Every mutator works on a rendered view; build one if it is missing. */\n function ensure(): void {\n if (!root()) render(lastStatus);\n }\n\n function stalenessHtml(line: StalenessLine, testid: string): string {\n if (!line.text) return \"\";\n return `<div class=\"askv-staleness askv-tone-${line.tone}\" data-testid=\"${testid}\">${esc(line.text)}</div>`;\n }\n\n function notesHtml(notes: AskNote[]): string {\n if (!notes || notes.length === 0) return \"\";\n const rows = notes\n .map(\n (n) => `\n <div class=\"askv-note\" data-testid=\"widget-ask-note\" data-memory-id=\"${Number(n.memoryId) || 0}\">\n <div class=\"askv-note-title\">${esc(n.title)}</div>\n ${n.route ? `<div class=\"askv-note-route\">${esc(n.route)}</div>` : \"\"}\n <div class=\"askv-note-body\">${esc(n.explanation)}</div>\n </div>`,\n )\n .join(\"\");\n return `\n <div class=\"askv-section\" data-testid=\"widget-ask-notes\">\n <div class=\"askv-section-title\">FROM YOUR TEAM'S NOTES</div>\n ${rows}\n </div>`;\n }\n\n function pathsHtml(a: AskAnswer): string {\n const paths = a.paths ?? [];\n if (paths.length === 0) return \"\";\n const rows = paths\n .map((p) => {\n const chips = (p.refs ?? [])\n .map((id) => chipHtml(id, a.references?.[id], escapeHtml))\n .filter(Boolean)\n .join('<span class=\"askv-path-arrow\">→</span>');\n if (!chips) return \"\";\n return `<div class=\"askv-path\" data-testid=\"widget-ask-path\">${chips}</div>`;\n })\n .filter(Boolean)\n .join(\"\");\n if (!rows) return \"\";\n return `\n <div class=\"askv-section\" data-testid=\"widget-ask-paths\">\n <div class=\"askv-section-title\">WHAT THE GRAPH SHOWS</div>\n ${rows}\n </div>`;\n }\n\n function confidenceHtml(a: AskAnswer): string {\n const conf = a.confidence ?? [];\n if (conf.length === 0) return \"\";\n const rows = conf\n .map(\n (c) => `\n <div class=\"askv-confidence-row\" data-testid=\"widget-ask-confidence-row\">\n <span class=\"askv-confidence-claim\">${esc(c.claim)}</span>\n <span class=\"askv-confidence-basis\">${esc(c.basis)}</span>\n <span class=\"askv-confidence-assumption\">${esc(c.assumption)}</span>\n </div>`,\n )\n .join(\"\");\n return `\n <div class=\"askv-section\" data-testid=\"widget-ask-confidence\">\n <div class=\"askv-section-title\">CONFIDENCE</div>\n ${rows}\n </div>`;\n }\n\n function provenanceHtml(a: AskAnswer): string {\n const p = a.provenance;\n if (!p) return \"\";\n const bits = [\n `retrieval ${Math.max(0, Math.round(a.timing?.retrievalMs ?? 0))} ms`,\n `model ${Math.max(0, Math.round(a.timing?.modelMs ?? 0))} ms`,\n `notes ${p.notes}`,\n `model ${p.model}`,\n `${p.flowsConsidered ?? 0} flow${(p.flowsConsidered ?? 0) === 1 ? \"\" : \"s\"} considered`,\n ];\n if (p.appBuild) bits.push(`build ${p.appBuild}`);\n return `<div class=\"askv-provenance\" data-testid=\"widget-ask-provenance\">${esc(bits.join(\" · \"))}</div>`;\n }\n\n function wireNotes(): void {\n body\n .querySelectorAll<HTMLElement>('[data-testid=\"widget-ask-note\"]')\n .forEach((el) => {\n el.addEventListener(\"click\", () => {\n const id = Number(el.dataset.memoryId);\n if (id) cb.onOpenMemory?.(id);\n });\n });\n }\n\n function submit(): void {\n const input = inputEl();\n if (!input) return;\n const question = input.value.trim();\n if (!question) return;\n cb.onAsk(question);\n }\n\n function render(status: AskStatus | null): void {\n lastStatus = status;\n\n const disabled = status !== null && status.enabled === false;\n const notice =\n firstUseNoticeDismissed || disabled\n ? \"\"\n : `<div class=\"askv-notice\" data-testid=\"widget-ask-first-use-notice\">\n <span>${esc(FIRST_USE_NOTICE)}</span>\n <button class=\"askv-notice-dismiss\" data-testid=\"widget-ask-notice-dismiss\" aria-label=\"Dismiss\">Got it</button>\n </div>`;\n\n const formHtml = disabled\n ? `<div class=\"askv-disabled\" data-testid=\"widget-ask-disabled\">\n Ask is turned off for this workspace.\n </div>`\n : `<div class=\"askv-form\">\n <textarea class=\"ask-textarea\" data-testid=\"widget-ask-input\" rows=\"3\"\n maxlength=\"${ASK_MAX_QUESTION_CHARS}\"\n placeholder=\"How do I create an invoice?\" aria-label=\"Your question\"></textarea>\n <div class=\"askv-form-footer\">\n <span class=\"askv-counter\" data-testid=\"widget-ask-counter\">0/${ASK_MAX_QUESTION_CHARS}</span>\n <button class=\"ask-submit\" data-testid=\"widget-ask-submit\">Ask</button>\n </div>\n </div>`;\n\n const limits =\n status && status.enabled && status.limits\n ? `<div class=\"askv-limits\" data-testid=\"widget-ask-limits\">${esc(\n `${Math.max(0, status.limits.remainingToday)} of ${status.limits.perDay} questions left today`,\n )}</div>`\n : \"\";\n\n body.innerHTML = `\n <div class=\"ask-view\" data-testid=\"widget-ask-view\">\n <div class=\"detail-back\">\n <button class=\"back-btn\" data-testid=\"widget-back-btn\">&#8592; Back</button>\n </div>\n <div class=\"askv-head\">\n <div class=\"askv-title\">Ask about this product</div>\n ${status ? stalenessHtml(statusStalenessLine(status), \"widget-ask-status-staleness\") : \"\"}\n </div>\n ${notice}\n ${formHtml}\n ${limits}\n <div class=\"askv-result\" data-testid=\"widget-ask-result\"></div>\n </div>\n `;\n\n body\n .querySelector<HTMLButtonElement>('[data-testid=\"widget-back-btn\"]')\n ?.addEventListener(\"click\", () => cb.onBack?.());\n\n body\n .querySelector<HTMLButtonElement>('[data-testid=\"widget-ask-notice-dismiss\"]')\n ?.addEventListener(\"click\", () => {\n firstUseNoticeDismissed = true;\n body.querySelector('[data-testid=\"widget-ask-first-use-notice\"]')?.remove();\n });\n\n if (!disabled) {\n const input = inputEl();\n const counter = body.querySelector<HTMLElement>(\n '[data-testid=\"widget-ask-counter\"]',\n );\n input?.addEventListener(\"input\", () => {\n if (counter) {\n counter.textContent = `${input.value.length}/${ASK_MAX_QUESTION_CHARS}`;\n }\n });\n input?.addEventListener(\"keydown\", (e: KeyboardEvent) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n submit();\n }\n });\n submitEl()?.addEventListener(\"click\", submit);\n }\n }\n\n function setLoading(): void {\n ensure();\n const input = inputEl();\n if (input) input.disabled = true;\n const btn = submitEl();\n if (btn) {\n btn.disabled = true;\n btn.textContent = \"Asking…\";\n }\n const result = resultEl();\n if (result) {\n result.innerHTML = `\n <div class=\"askv-loading\" data-testid=\"widget-ask-loading\">\n <span class=\"askv-spinner\" aria-hidden=\"true\"></span>\n <span>Asking…</span>\n </div>`;\n }\n }\n\n function clearLoading(): void {\n const input = inputEl();\n if (input) input.disabled = false;\n const btn = submitEl();\n if (btn) {\n btn.disabled = false;\n btn.textContent = \"Ask\";\n }\n body.querySelector('[data-testid=\"widget-ask-loading\"]')?.remove();\n }\n\n function showAnswer(a: AskAnswer): void {\n ensure();\n clearLoading();\n const result = resultEl();\n if (!result) return;\n\n const narrated = typeof a.answer === \"string\" && a.answer.trim() !== \"\";\n const prose = narrated\n ? `<div class=\"askv-answer\" data-testid=\"widget-ask-answer\">${renderAnswerHtml(\n a.answer,\n a.references ?? {},\n escapeHtml,\n )}</div>`\n : `<div class=\"askv-unnarrated\" data-testid=\"widget-ask-unnarrated\">\n Unnoodle couldn't write this up, so here is what it found.\n </div>`;\n\n result.innerHTML = `\n ${stalenessHtml(stalenessLine(a.provenance), \"widget-ask-staleness\")}\n ${prose}\n ${narrated ? \"\" : pathsHtml(a)}\n ${notesHtml(a.notes ?? [])}\n ${confidenceHtml(a)}\n ${provenanceHtml(a)}\n `;\n\n const input = inputEl();\n if (input) input.value = \"\";\n const counter = body.querySelector<HTMLElement>(\n '[data-testid=\"widget-ask-counter\"]',\n );\n if (counter) counter.textContent = `0/${ASK_MAX_QUESTION_CHARS}`;\n\n wireNotes();\n }\n\n function showError(message: string, retryable: boolean): void {\n ensure();\n clearLoading();\n const result = resultEl();\n if (!result) return;\n result.innerHTML = `\n <div class=\"askv-error\" data-testid=\"widget-ask-error\" data-retryable=\"${retryable ? \"true\" : \"false\"}\" role=\"alert\">\n <span>${esc(message)}</span>\n ${retryable ? `<button class=\"askv-retry\" data-testid=\"widget-ask-retry\">Try again</button>` : \"\"}\n </div>`;\n body\n .querySelector<HTMLButtonElement>('[data-testid=\"widget-ask-retry\"]')\n ?.addEventListener(\"click\", submit);\n }\n\n return { render, setLoading, clearLoading, showAnswer, showError };\n}\n","/**\n * Capture Form Controller\n *\n * Renders the \"New Memory / Add Entry\" form UI and manages its state.\n * Used by panel.ts to implement showNewMemoryForm() and showAddEntryForm().\n */\n\nimport { safeCSS } from \"./safeCSS\";\nimport type { ElementSnapshot } from \"../core/product-memory/elementSnapshot\";\n\nexport interface CaptureFormCallbacks {\n onPickElement: () => void;\n onCancelCapture: () => void;\n onSave: (\n title: string,\n explanation: string,\n watchForChanges: boolean,\n ) => void;\n onCancel: () => void;\n}\n\nexport interface CaptureFormController {\n /** Update the snapshot preview (called after UI state is picked) */\n setSnapshot: (snapshot: ElementSnapshot | null) => void;\n /** Show picking mode UI (dashed border, cancel button, progress text) */\n setPickingMode: (picking: boolean) => void;\n /** Toggle loading state on the save button */\n setLoading: (loading: boolean) => void;\n /** Show an error message */\n setError: (message: string) => void;\n /** Clear the form (reset inputs) */\n clear: () => void;\n}\n\nexport interface CaptureFormOptions {\n /** Whether to show the title input field (hidden for \"add entry\" mode) */\n showTitle: boolean;\n /** Main header text (e.g., memory title for add entry mode) */\n headerText?: string;\n /** Optional subheader text (e.g., \"Add new entry\") */\n subheaderText?: string;\n}\n\n/**\n * Renders the capture form HTML and returns a controller to manage its state.\n * Does NOT mount it to the DOM — caller is responsible for appending the returned element.\n */\nexport function createCaptureForm(\n callbacks: CaptureFormCallbacks,\n options: CaptureFormOptions,\n): { element: HTMLElement; controller: CaptureFormController } {\n const container = document.createElement(\"div\");\n container.className = \"capture-form-container\";\n container.setAttribute(\"data-testid\", \"widget-capture-form\");\n\n const html = `\n <style>\n ${safeCSS(`\n .capture-form-container {\n display: flex;\n flex-direction: column;\n gap: var(--w-space-4);\n padding: var(--w-space-h-md);\n background: var(--unn-color-bg-primary);\n overflow-y: auto;\n flex: 1;\n height: 100%;\n }\n .capture-form-header {\n font-size: var(--w-font-xl);\n font-weight: var(--w-weight-bold);\n color: var(--unn-color-text-primary);\n margin: 0 0 4px 0;\n line-height: 1.3;\n }\n .capture-form-subheader {\n font-size: var(--w-font-md);\n font-weight: var(--w-weight-medium);\n color: var(--unn-color-text-secondary);\n margin: 0 0 16px 0;\n }\n .capture-form-field {\n display: flex;\n flex-direction: column;\n gap: 5px;\n }\n .capture-form-label {\n font-size: var(--w-font-sm);\n font-weight: var(--w-weight-medium);\n color: var(--unn-color-text-body);\n }\n .capture-form-input,\n .capture-form-textarea {\n width: 100%;\n padding: 9px 12px;\n border: var(--w-border-width) solid var(--unn-color-border-subtle);\n border-radius: var(--w-radius-lg);\n font-size: var(--w-font-md);\n font-family: inherit;\n color: var(--unn-color-text-primary);\n outline: none;\n transition: border-color 0.15s;\n box-sizing: border-box;\n }\n .capture-form-input:focus,\n .capture-form-textarea:focus {\n border-color: var(--unn-color-brand-primary);\n }\n .capture-form-textarea {\n min-height: 100px;\n resize: vertical;\n }\n .capture-form-snapshot-container {\n border: var(--w-border-width) solid var(--unn-color-border-default);\n border-radius: var(--w-radius-1);\n padding: 12px;\n background: var(--unn-color-bg-secondary);\n min-height: 80px;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n transition: border 0.2s;\n }\n .capture-form-snapshot-container.picking {\n border: 2px dashed var(--unn-color-brand-primary);\n }\n .capture-form-snapshot-empty {\n color: var(--unn-color-text-subtle);\n font-size: var(--w-font-sm);\n }\n .capture-form-snapshot-preview {\n max-width: 100%;\n overflow: hidden;\n }\n .capture-form-pick-btn {\n padding: 3px 10px;\n background: var(--unn-color-bg-secondary);\n border: var(--w-border-width) solid var(--unn-color-border-default);\n border-radius: var(--w-radius-lg);\n font-size: var(--w-font-sm);\n font-weight: var(--w-weight-medium);\n color: var(--unn-color-text-secondary);\n cursor: pointer;\n transition: all 0.15s;\n }\n .capture-form-pick-btn:hover {\n background: var(--unn-color-bg-hover);\n color: var(--unn-color-text-primary);\n }\n .capture-form-pick-btn:active {\n background: var(--unn-color-bg-subtle);\n }\n .capture-form-cancel-capture-btn {\n padding: 3px 10px;\n background: var(--unn-color-bg-tertiary);\n border: var(--w-border-width) solid var(--unn-color-border-default);\n border-radius: var(--w-radius-lg);\n font-size: var(--w-font-sm);\n font-weight: var(--w-weight-medium);\n color: var(--unn-color-text-muted);\n cursor: pointer;\n transition: all 0.15s;\n }\n .capture-form-cancel-capture-btn:hover {\n background: var(--unn-color-border-default);\n }\n .capture-form-actions {\n display: flex;\n gap: 6px;\n justify-content: flex-end;\n margin-top: 6px;\n }\n .capture-form-save-btn,\n .capture-form-cancel-btn {\n font-size: var(--w-font-xs);\n font-weight: 500;\n border: none;\n border-radius: var(--w-radius-sm);\n cursor: pointer;\n padding: 5px 12px;\n }\n .capture-form-save-btn {\n background: var(--unn-color-brand-primary);\n color: #fff;\n }\n .capture-form-save-btn:hover:not(:disabled) {\n opacity: 0.88;\n }\n .capture-form-save-btn:disabled {\n opacity: 0.5;\n cursor: default;\n }\n .capture-form-cancel-btn {\n background: var(--unn-color-bg-tertiary);\n color: var(--unn-color-text-muted);\n }\n .capture-form-cancel-btn:hover {\n background: var(--unn-color-border-default);\n }\n .capture-form-watch-row {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 2px;\n }\n .capture-form-watch-checkbox {\n width: 16px;\n height: 16px;\n cursor: pointer;\n accent-color: var(--unn-color-brand-primary);\n flex-shrink: 0;\n }\n .capture-form-watch-label {\n font-size: var(--w-font-sm);\n color: var(--unn-color-text-body);\n cursor: pointer;\n user-select: none;\n }\n .capture-form-error {\n color: var(--unn-color-status-error);\n font-size: var(--w-font-sm);\n margin-top: -8px;\n display: none;\n }\n .capture-form-error.visible {\n display: block;\n }\n `)}\n </style>\n <h2 class=\"capture-form-header\">${options.headerText || (options.showTitle ? \"New Product Memory\" : \"Add Entry\")}</h2>\n ${options.subheaderText ? `<p class=\"capture-form-subheader\">${options.subheaderText}</p>` : \"\"}\n \n ${\n options.showTitle\n ? `\n <div class=\"capture-form-field\">\n <label class=\"capture-form-label\" for=\"capture-form-title\">Title *</label>\n <input\n type=\"text\"\n id=\"capture-form-title\"\n class=\"capture-form-input\"\n placeholder=\"e.g., User profile page redesign\"\n data-testid=\"widget-capture-form-title\"\n />\n </div>\n `\n : \"\"\n }\n \n <div class=\"capture-form-field\">\n <label class=\"capture-form-label\">Captured UI State</label>\n <div class=\"capture-form-snapshot-container\" data-testid=\"widget-capture-form-snapshot\">\n <div class=\"capture-form-snapshot-empty\">No UI state captured yet</div>\n <button\n type=\"button\"\n class=\"capture-form-pick-btn\"\n data-testid=\"widget-capture-form-pick-btn\"\n >\n Pick UI state\n </button>\n </div>\n </div>\n \n <div class=\"capture-form-field\">\n <label class=\"capture-form-label\" for=\"capture-form-explanation\">Explanation *</label>\n <textarea\n id=\"capture-form-explanation\"\n class=\"capture-form-textarea\"\n placeholder=\"Describe what this UI state means in your product...\"\n data-testid=\"widget-capture-form-explanation\"\n ></textarea>\n </div>\n \n <div class=\"capture-form-watch-row\">\n <input\n type=\"checkbox\"\n id=\"capture-form-watch\"\n class=\"capture-form-watch-checkbox\"\n data-testid=\"widget-capture-form-watch-toggle\"\n />\n <label class=\"capture-form-watch-label\" for=\"capture-form-watch\">\n Watch for changes\n </label>\n </div>\n\n <div class=\"capture-form-error\" data-testid=\"widget-capture-form-error\"></div>\n \n <div class=\"capture-form-actions\">\n <button\n type=\"button\"\n class=\"capture-form-cancel-btn\"\n data-testid=\"widget-capture-form-cancel\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n class=\"capture-form-save-btn\"\n data-testid=\"widget-capture-form-save\"\n >\n Save\n </button>\n </div>\n `;\n\n container.innerHTML = html;\n\n // Wire up event listeners\n const titleInput = container.querySelector<HTMLInputElement>(\n \"#capture-form-title\",\n );\n const explanationTextarea = container.querySelector<HTMLTextAreaElement>(\n \"#capture-form-explanation\",\n )!;\n const snapshotContainer = container.querySelector<HTMLElement>(\n \".capture-form-snapshot-container\",\n )!;\n const pickBtn = container.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-capture-form-pick-btn\"]',\n )!;\n const saveBtn = container.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-capture-form-save\"]',\n )!;\n const cancelBtn = container.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-capture-form-cancel\"]',\n )!;\n const errorEl = container.querySelector<HTMLElement>(\n '[data-testid=\"widget-capture-form-error\"]',\n )!;\n const watchToggle = container.querySelector<HTMLInputElement>(\n '[data-testid=\"widget-capture-form-watch-toggle\"]',\n )!;\n\n console.log(\"[unnoodle] Form elements found:\", {\n titleInput,\n explanationTextarea,\n snapshotContainer,\n pickBtn,\n saveBtn,\n cancelBtn,\n errorEl,\n });\n\n pickBtn.addEventListener(\"click\", () => {\n console.log(\"[unnoodle] Pick button clicked\");\n callbacks.onPickElement();\n });\n cancelBtn.addEventListener(\"click\", () => {\n console.log(\"[unnoodle] Cancel button clicked\");\n callbacks.onCancel();\n });\n saveBtn.addEventListener(\"click\", () => {\n console.log(\"[unnoodle] Save button clicked\");\n const title = titleInput ? titleInput.value.trim() : \"\";\n const explanation = explanationTextarea.value.trim();\n\n // Basic validation\n if (options.showTitle && !title) {\n errorEl.textContent = \"Title is required\";\n errorEl.classList.add(\"visible\");\n return;\n }\n if (!explanation) {\n errorEl.textContent = \"Explanation is required\";\n errorEl.classList.add(\"visible\");\n return;\n }\n\n errorEl.classList.remove(\"visible\");\n callbacks.onSave(title, explanation, watchToggle.checked);\n });\n\n // Controller methods\n const controller: CaptureFormController = {\n setSnapshot: (snapshot: ElementSnapshot | null) => {\n if (snapshot) {\n snapshotContainer.className = \"capture-form-snapshot-container\";\n snapshotContainer.innerHTML = `<div class=\"capture-form-snapshot-preview\">${snapshot.html}</div>`;\n } else {\n snapshotContainer.className = \"capture-form-snapshot-container\";\n snapshotContainer.innerHTML = `\n <div class=\"capture-form-snapshot-empty\">No UI state captured yet</div>\n <button\n type=\"button\"\n class=\"capture-form-pick-btn\"\n data-testid=\"widget-capture-form-pick-btn\"\n >\n Pick UI state\n </button>\n `;\n // Re-wire the pick button event listener\n const newPickBtn = snapshotContainer.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-capture-form-pick-btn\"]',\n );\n if (newPickBtn) {\n newPickBtn.addEventListener(\"click\", () => {\n console.log(\"[unnoodle] Pick button clicked\");\n callbacks.onPickElement();\n });\n }\n }\n },\n\n setPickingMode: (picking: boolean) => {\n if (picking) {\n snapshotContainer.className = \"capture-form-snapshot-container picking\";\n snapshotContainer.innerHTML = `\n <div class=\"capture-form-snapshot-empty\">UI state capture in progress...</div>\n <button\n type=\"button\"\n class=\"capture-form-cancel-capture-btn\"\n data-testid=\"widget-capture-form-cancel-capture-btn\"\n >\n Cancel capture\n </button>\n `;\n // Wire the cancel capture button\n const cancelCaptureBtn =\n snapshotContainer.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-capture-form-cancel-capture-btn\"]',\n );\n if (cancelCaptureBtn) {\n cancelCaptureBtn.addEventListener(\"click\", () => {\n console.log(\"[unnoodle] Cancel capture clicked\");\n callbacks.onCancelCapture();\n });\n }\n } else {\n // Reset to normal state - inline the setSnapshot(null) logic\n snapshotContainer.className = \"capture-form-snapshot-container\";\n snapshotContainer.innerHTML = `\n <div class=\"capture-form-snapshot-empty\">No UI state captured yet</div>\n <button\n type=\"button\"\n class=\"capture-form-pick-btn\"\n data-testid=\"widget-capture-form-pick-btn\"\n >\n Pick UI state\n </button>\n `;\n // Re-wire the pick button event listener\n const newPickBtn = snapshotContainer.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-capture-form-pick-btn\"]',\n );\n if (newPickBtn) {\n newPickBtn.addEventListener(\"click\", () => {\n console.log(\"[unnoodle] Pick button clicked\");\n callbacks.onPickElement();\n });\n }\n }\n },\n\n setLoading: (loading: boolean) => {\n saveBtn.disabled = loading;\n saveBtn.textContent = loading ? \"Saving…\" : \"Save\";\n pickBtn.disabled = loading;\n cancelBtn.disabled = loading;\n if (titleInput) titleInput.disabled = loading;\n explanationTextarea.disabled = loading;\n },\n\n setError: (message: string) => {\n errorEl.textContent = message;\n errorEl.classList.add(\"visible\");\n },\n\n clear: () => {\n if (titleInput) titleInput.value = \"\";\n explanationTextarea.value = \"\";\n snapshotContainer.className = \"capture-form-snapshot-container\";\n snapshotContainer.innerHTML = `\n <div class=\"capture-form-snapshot-empty\">No UI state captured yet</div>\n <button\n type=\"button\"\n class=\"capture-form-pick-btn\"\n data-testid=\"widget-capture-form-pick-btn\"\n >\n Pick UI state\n </button>\n `;\n // Re-wire the pick button event listener\n const newPickBtn = snapshotContainer.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-capture-form-pick-btn\"]',\n );\n if (newPickBtn) {\n newPickBtn.addEventListener(\"click\", () => {\n console.log(\"[unnoodle] Pick button clicked\");\n callbacks.onPickElement();\n });\n }\n errorEl.classList.remove(\"visible\");\n errorEl.textContent = \"\";\n },\n };\n\n return { element: container, controller };\n}\n","/**\n * stateChangeBanner\n *\n * Single responsibility:\n * Render a persistent \"New state detected — Save it?\" notification banner\n * inside a given container element and wire up the Save / Dismiss actions.\n *\n * Usage:\n * showStateChangeBanner(container, meaning, onSave, onDismiss);\n * hideStateChangeBanner(container);\n *\n * Only one banner is shown at a time per container — calling show() again\n * replaces any existing banner.\n *\n * Design principles:\n * - No DOM queries outside the provided container.\n * - No network calls, no imports from API or orchestration layers.\n * - All actions surface through callbacks.\n */\n\nimport { safeCSS } from \"./safeCSS\";\n\n// ---------------------------------------------------------------------------\n// Internal sentinel\n// ---------------------------------------------------------------------------\n\nconst BANNER_ATTR = \"data-unnoodle-state-banner\";\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Insert (or replace) the state-change notification banner at the top of\n * `container`.\n *\n * @param container The element to prepend the banner into.\n * @param inferredMeaning Pre-filled description from inferMeaning(). When\n * null the banner shows a generic prompt.\n * @param onSave Called when the user clicks \"Save new state\".\n * @param onDismiss Called when the user dismisses the banner.\n */\nexport function showStateChangeBanner(\n container: HTMLElement,\n inferredMeaning: string | null,\n onSave: () => void,\n onDismiss: () => void,\n): void {\n hideStateChangeBanner(container);\n\n const banner = document.createElement(\"div\");\n banner.setAttribute(BANNER_ATTR, \"true\");\n banner.setAttribute(\"data-testid\", \"state-change-banner\");\n banner.setAttribute(\"role\", \"status\");\n banner.setAttribute(\"aria-live\", \"polite\");\n\n banner.innerHTML = `\n <style>\n ${safeCSS(`\n [${BANNER_ATTR}] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 10px 12px;\n background: var(--unn-color-bg-secondary, #f0f4ff);\n border-bottom: 2px solid var(--unn-color-brand-primary, #4f46e5);\n font-size: 13px;\n flex-shrink: 0;\n }\n [${BANNER_ATTR}] .scb-heading {\n font-weight: 600;\n color: var(--unn-color-text-primary, #111);\n display: flex;\n align-items: center;\n gap: 6px;\n }\n [${BANNER_ATTR}] .scb-meaning {\n color: var(--unn-color-text-body, #444);\n font-size: 12px;\n }\n [${BANNER_ATTR}] .scb-actions {\n display: flex;\n gap: 6px;\n align-items: center;\n }\n [${BANNER_ATTR}] .scb-save-btn {\n padding: 4px 12px;\n background: var(--unn-color-brand-primary, #4f46e5);\n color: #fff;\n border: none;\n border-radius: 4px;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n }\n [${BANNER_ATTR}] .scb-save-btn:hover {\n opacity: 0.88;\n }\n [${BANNER_ATTR}] .scb-dismiss-btn {\n padding: 4px 10px;\n background: transparent;\n color: var(--unn-color-text-muted, #888);\n border: 1px solid var(--unn-color-border-subtle, #ddd);\n border-radius: 4px;\n font-size: 12px;\n cursor: pointer;\n }\n [${BANNER_ATTR}] .scb-dismiss-btn:hover {\n background: var(--unn-color-bg-hover, #e9e9e9);\n }\n `)}\n </style>\n <div class=\"scb-heading\">\n <span aria-hidden=\"true\">🔍</span>\n New state detected — Save it?\n </div>\n ${\n inferredMeaning\n ? `<div class=\"scb-meaning\" data-testid=\"state-change-banner-meaning\">${inferredMeaning}</div>`\n : \"\"\n }\n <div class=\"scb-actions\">\n <button type=\"button\" class=\"scb-save-btn\" data-testid=\"state-change-banner-save\">\n Save new state\n </button>\n <button type=\"button\" class=\"scb-dismiss-btn\" data-testid=\"state-change-banner-dismiss\">\n Dismiss\n </button>\n </div>\n `;\n\n const saveBtn = banner.querySelector<HTMLButtonElement>(\n '[data-testid=\"state-change-banner-save\"]',\n )!;\n const dismissBtn = banner.querySelector<HTMLButtonElement>(\n '[data-testid=\"state-change-banner-dismiss\"]',\n )!;\n\n saveBtn.addEventListener(\"click\", () => {\n hideStateChangeBanner(container);\n onSave();\n });\n\n dismissBtn.addEventListener(\"click\", () => {\n hideStateChangeBanner(container);\n onDismiss();\n });\n\n container.prepend(banner);\n}\n\n/**\n * Remove the state-change notification banner from `container`, if present.\n * Safe to call when no banner is shown.\n */\nexport function hideStateChangeBanner(container: HTMLElement): void {\n const existing = container.querySelector<HTMLElement>(`[${BANNER_ATTR}]`);\n existing?.remove();\n}\n","import type {\n GlossaryTerm,\n ContextDiscussion,\n ProductMemoryResponse,\n WidgetInitResponse,\n} from \"../types/config\";\n\n/**\n * Escapes HTML characters in a string\n */\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#039;\");\n}\n\n/**\n * Callbacks for list view interactions\n */\nexport interface ListViewCallbacks {\n onTermClick?: (termId: number) => void;\n onDiscussionClick?: (discussionId: number) => void;\n onMemoryClick?: (memoryId: number) => void;\n onBackToHome?: () => void;\n onAddTerm?: () => void;\n onAddDiscussion?: () => void;\n onAddMemory?: () => void;\n onRequireLogin?: () => void;\n}\n\n/**\n * Creates and manages list views for all categories.\n * Keeps heavy list rendering logic separate from the main panel.\n */\nexport class ListViewManager {\n private container: HTMLElement;\n private callbacks: ListViewCallbacks;\n\n constructor(container: HTMLElement, callbacks: ListViewCallbacks = {}) {\n this.container = container;\n this.callbacks = callbacks;\n }\n\n /**\n * Shows all vocabulary terms in a list view\n */\n showAllTerms(data: WidgetInitResponse, allTerms: GlossaryTerm[]): void {\n console.log(\n \"DEBUG: ListViewManager.showAllTerms called with\",\n allTerms.length,\n \"terms\",\n );\n const html = `\n <div class=\"list-view\" data-testid=\"widget-terms-list-view\">\n <div class=\"list-header\">\n <button class=\"list-back-btn\" data-testid=\"widget-back-to-home\">\n ← Back\n </button>\n <div class=\"list-title\">\n <h2>Vocabulary</h2>\n <span class=\"list-count\">${allTerms.length} terms</span>\n </div>\n <button class=\"list-add-btn\" data-testid=\"widget-add-term\">\n + Add\n </button>\n </div>\n <div class=\"list-body\">\n ${this.renderTermsList(allTerms)}\n </div>\n </div>\n `;\n\n this.container.innerHTML = html;\n this.attachTermsListeners();\n }\n\n /**\n * Shows all clarifications in a list view\n */\n showAllClarifications(\n discussions: ContextDiscussion[],\n canPost: boolean,\n ): void {\n console.log(\n \"DEBUG: ListViewManager.showAllClarifications called with\",\n discussions.length,\n \"discussions\",\n );\n const html = `\n <div class=\"list-view\" data-testid=\"widget-clarifications-list-view\">\n <div class=\"list-header\">\n <button class=\"list-back-btn\" data-testid=\"widget-back-to-home\">\n ← Back\n </button>\n <div class=\"list-title\">\n <h2>Clarifications</h2>\n <span class=\"list-count\">${discussions.length} questions</span>\n </div>\n <button class=\"list-add-btn\" data-testid=\"widget-ask-question\">\n + Ask\n </button>\n </div>\n <div class=\"list-body\">\n ${this.renderClarificationsList(discussions)}\n </div>\n </div>\n `;\n\n this.container.innerHTML = html;\n this.attachClarificationsListeners();\n }\n\n /**\n * Shows all product memories in a list view\n */\n showAllMemories(memories: ProductMemoryResponse[], canPost: boolean): void {\n console.log(\n \"DEBUG: ListViewManager.showAllMemories called with\",\n memories.length,\n \"memories\",\n );\n const html = `\n <div class=\"list-view\" data-testid=\"widget-memories-list-view\">\n <div class=\"list-header\">\n <button class=\"list-back-btn\" data-testid=\"widget-back-to-home\">\n ← Back\n </button>\n <div class=\"list-title\">\n <h2>Product Memories</h2>\n <span class=\"list-count\">${memories.length} memories</span>\n </div>\n <button class=\"list-add-btn\" data-testid=\"widget-new-memory\">\n + New\n </button>\n </div>\n <div class=\"list-body\">\n ${this.renderMemoriesList(memories)}\n </div>\n </div>\n `;\n\n this.container.innerHTML = html;\n this.attachMemoriesListeners();\n }\n\n /**\n * Renders the terms list content\n */\n private renderTermsList(terms: GlossaryTerm[]): string {\n if (terms.length === 0) {\n return `\n <div class=\"list-empty\">\n <div class=\"list-empty-title\">No vocabulary terms yet.</div>\n <div class=\"list-empty-text\">Start building your shared vocabulary.</div>\n </div>\n `;\n }\n\n return terms\n .map(\n (term) => `\n <div class=\"list-item\" data-testid=\"widget-term-list-item\" data-term-id=\"${term.id}\">\n <div class=\"list-item-main\">\n <div class=\"list-item-title\">${escapeHtml(term.term)}</div>\n <div class=\"list-item-subtitle\">${escapeHtml(term.definition)}</div>\n ${term.abbreviation ? `<div class=\"list-item-tag\">${escapeHtml(term.abbreviation)}</div>` : \"\"}\n </div>\n <div class=\"list-item-action\">\n <svg viewBox=\"0 0 24 24\" width=\"12\" height=\"12\">\n <polyline points=\"9 18 15 12 9 6\"></polyline>\n </svg>\n </div>\n </div>\n `,\n )\n .join(\"\");\n }\n\n /**\n * Renders the clarifications list content\n */\n private renderClarificationsList(discussions: ContextDiscussion[]): string {\n if (discussions.length === 0) {\n return `\n <div class=\"list-empty\">\n <div class=\"list-empty-title\">No questions yet.</div>\n <div class=\"list-empty-text\">Ask if something about this interface is unclear.</div>\n </div>\n `;\n }\n\n return discussions\n .map(\n (discussion) => `\n <div class=\"list-item\" data-testid=\"widget-clarification-list-item\" data-discussion-id=\"${discussion.id}\">\n <div class=\"list-item-main\">\n <div class=\"list-item-title\">${escapeHtml(discussion.body)}</div>\n <div class=\"list-item-subtitle\">\n ${escapeHtml(discussion.authorName || \"Unknown\")} · \n ${new Date(discussion.createdAt).toLocaleDateString(undefined, { month: \"short\", day: \"numeric\" })}\n ${discussion.replies && discussion.replies.length > 0 ? ` · ${discussion.replies.length} replies` : \"\"}\n </div>\n </div>\n <div class=\"list-item-action\">\n <svg viewBox=\"0 0 24 24\" width=\"12\" height=\"12\">\n <polyline points=\"9 18 15 12 9 6\"></polyline>\n </svg>\n </div>\n </div>\n `,\n )\n .join(\"\");\n }\n\n /**\n * Renders the memories list content\n */\n private renderMemoriesList(memories: ProductMemoryResponse[]): string {\n if (memories.length === 0) {\n return `\n <div class=\"list-empty\">\n <div class=\"list-empty-title\">No captures yet.</div>\n <div class=\"list-empty-text\">Capture elements so teammates can understand the interface faster.</div>\n </div>\n `;\n }\n\n return memories\n .map(\n (memory) => `\n <div class=\"list-item\" data-testid=\"widget-memory-list-item\" data-memory-id=\"${memory.id}\">\n <div class=\"list-item-main\">\n <div class=\"list-item-title\">${escapeHtml(memory.title)}</div>\n <div class=\"list-item-subtitle\">\n ${memory.entryCount} entries · \n ${new Date(memory.updatedAt).toLocaleDateString(undefined, { month: \"short\", day: \"numeric\" })}\n </div>\n </div>\n <div class=\"list-item-action\">\n <svg viewBox=\"0 0 24 24\" width=\"12\" height=\"12\">\n <polyline points=\"9 18 15 12 9 6\"></polyline>\n </svg>\n </div>\n </div>\n `,\n )\n .join(\"\");\n }\n\n /**\n * Attaches event listeners for terms list\n */\n private attachTermsListeners(): void {\n // Back button\n const backBtn = this.container.querySelector(\n '[data-testid=\"widget-back-to-home\"]',\n );\n backBtn?.addEventListener(\"click\", () => this.callbacks.onBackToHome?.());\n\n // Add button\n const addBtn = this.container.querySelector(\n '[data-testid=\"widget-add-term\"]',\n );\n addBtn?.addEventListener(\"click\", () => this.callbacks.onAddTerm?.());\n\n // Term items\n const termItems = this.container.querySelectorAll(\n '[data-testid=\"widget-term-list-item\"]',\n );\n termItems.forEach((item) => {\n item.addEventListener(\"click\", () => {\n const termId = parseInt(item.getAttribute(\"data-term-id\") || \"0\", 10);\n this.callbacks.onTermClick?.(termId);\n });\n });\n }\n\n /**\n * Attaches event listeners for clarifications list\n */\n private attachClarificationsListeners(): void {\n // Back button\n const backBtn = this.container.querySelector(\n '[data-testid=\"widget-back-to-home\"]',\n );\n backBtn?.addEventListener(\"click\", () => this.callbacks.onBackToHome?.());\n\n // Add button\n const addBtn = this.container.querySelector(\n '[data-testid=\"widget-add-clarification\"]',\n );\n addBtn?.addEventListener(\"click\", () => {\n if (addBtn?.getAttribute(\"data-requires-login\") === \"true\") {\n this.callbacks.onRequireLogin?.();\n } else {\n this.callbacks.onAddDiscussion?.();\n }\n });\n\n // Discussion items\n const discussionItems = this.container.querySelectorAll(\n '[data-testid=\"widget-clarification-list-item\"]',\n );\n discussionItems.forEach((item) => {\n item.addEventListener(\"click\", () => {\n const discussionId = parseInt(\n item.getAttribute(\"data-discussion-id\") || \"0\",\n 10,\n );\n this.callbacks.onDiscussionClick?.(discussionId);\n });\n });\n }\n\n /**\n * Attaches event listeners for memories list\n */\n private attachMemoriesListeners(): void {\n // Back button\n const backBtn = this.container.querySelector(\n '[data-testid=\"widget-back-to-home\"]',\n );\n backBtn?.addEventListener(\"click\", () => this.callbacks.onBackToHome?.());\n\n // Add button\n const addBtn = this.container.querySelector(\n '[data-testid=\"widget-add-memory\"]',\n );\n addBtn?.addEventListener(\"click\", () => {\n if (addBtn?.getAttribute(\"data-requires-login\") === \"true\") {\n this.callbacks.onRequireLogin?.();\n } else {\n this.callbacks.onAddMemory?.();\n }\n });\n\n // Memory items\n const memoryItems = this.container.querySelectorAll(\n '[data-testid=\"widget-memory-list-item\"]',\n );\n memoryItems.forEach((item) => {\n item.addEventListener(\"click\", () => {\n const memoryId = parseInt(\n item.getAttribute(\"data-memory-id\") || \"0\",\n 10,\n );\n this.callbacks.onMemoryClick?.(memoryId);\n });\n });\n }\n}\n\n/**\n * Gets the CSS for list views (to be injected into shadow DOM)\n */\nexport function getListViewCSS(): string {\n return `\n .list-view {\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n\n .list-header {\n display: flex;\n align-items: center;\n gap: var(--w-space-2, 8px);\n padding: var(--w-space-h-md) var(--w-space-h-md) var(--w-space-v-md);\n border-bottom: 1px solid var(--unn-color-border-subtle, #e2e8f0);\n background: var(--unn-color-surface, #ffffff);\n }\n\n .list-back-btn, .list-add-btn {\n background: none;\n border: none;\n cursor: pointer;\n font-size: var(--w-font-base);\n color: var(--unn-color-brand-primary);\n font-weight: var(--w-weight-medium);\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px 0;\n transition: all 0.15s ease;\n }\n\n .list-back-btn:hover, .list-add-btn:hover {\n text-decoration: underline;\n }\n\n .list-title {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: var(--w-space-1, 4px);\n }\n\n .list-title h2 {\n margin: 0;\n font-size: var(--w-font-lg);\n font-weight: var(--w-weight-semi);\n color: var(--unn-color-text, #111827);\n }\n\n .list-count {\n font-size: var(--w-font-sm);\n color: var(--unn-color-text-secondary, #6b7280);\n }\n\n .list-body {\n flex: 1;\n overflow-y: auto;\n padding: var(--w-space-v-sm);\n }\n\n .list-item {\n display: flex;\n align-items: center;\n gap: var(--w-space-3, 12px);\n padding: var(--w-space-v-sm);\n border-radius: var(--w-radius-1);\n cursor: pointer;\n transition: background-color 0.15s ease;\n border: 1px solid transparent;\n }\n\n .list-item:hover {\n background: var(--unn-color-bg-secondary);\n }\n\n .list-item:hover .list-item-title {\n color: var(--unn-color-brand-primary);\n }\n\n .list-item-main {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: var(--w-space-1, 4px);\n min-width: 0;\n }\n\n .list-item-title {\n font-size: var(--w-font-base);\n font-weight: var(--w-weight-medium);\n color: var(--unn-color-text, #111827);\n word-break: break-word;\n line-height: 1.4;\n }\n\n .list-item-subtitle {\n font-size: var(--w-font-sm);\n color: var(--unn-color-text-secondary, #6b7280);\n line-height: 1.4;\n }\n\n .list-item-tag {\n font-size: var(--w-font-xs);\n color: var(--unn-color-accent, #3b82f6);\n background: var(--unn-color-accent-subtle, #dbeafe);\n padding: 2px 6px;\n border-radius: var(--w-radius-sm, 4px);\n align-self: flex-start;\n margin-top: 2px;\n }\n\n .list-item-action {\n flex-shrink: 0; \n color: var(--unn-color-text-subtle);\n opacity: 0.35; \n transition: opacity 0.12s, color 0.12s;\n }\n \n .list-item-action svg { \n stroke: currentColor; \n fill: none; \n stroke-width: 2.5; \n }\n\n .list-item:hover .list-item-action {\n opacity: 1; \n color: var(--unn-color-brand-primary);\n }\n\n .list-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: var(--w-space-v-xl) var(--w-space-4);\n height: 200px;\n }\n\n .list-empty-title {\n font-size: var(--w-font-lg);\n font-weight: var(--w-weight-medium);\n color: var(--unn-color-text, #111827);\n margin-bottom: var(--w-space-2, 8px);\n }\n\n .list-empty-text {\n font-size: var(--w-font-base);\n color: var(--unn-color-text-secondary, #6b7280);\n line-height: 1.5;\n }\n `;\n}\n","import { safeCSS } from \"../safeCSS\";\nimport { POPOUT_OVERRIDE_STYLE } from \"./styles\";\n\nexport const MIN_WIDTH = 320;\nexport const MAX_WIDTH_ABS = 800;\nconst LS_WIDTH_KEY = \"unnoodle_panel_width\";\nconst LS_SIDE_KEY = \"unnoodle_panel_side\";\n\nexport interface PanelLayoutRefs {\n host: HTMLElement;\n shadow: ShadowRoot;\n panelShell: HTMLElement;\n popoutBtn: HTMLButtonElement;\n dockBtn: HTMLButtonElement;\n closeBtn: HTMLButtonElement;\n pinLeftBtn: HTMLButtonElement;\n pinRightBtn: HTMLButtonElement;\n halfBtn: HTMLButtonElement;\n halfExitBtn: HTMLButtonElement;\n fullscreenBtn: HTMLButtonElement;\n fullscreenExitBtn: HTMLButtonElement;\n resizeHandle: HTMLElement;\n}\n\nexport interface PanelLayoutCallbacks {\n onClose?: () => void;\n onPopout?: () => void;\n onReattach?: () => void;\n onToast?: (message: string) => void;\n shadowTokens?: string;\n}\n\nexport interface PanelLayoutController {\n show: () => void;\n hide: () => void;\n popout: () => void;\n cleanup: () => void;\n isPopout: () => boolean;\n currentWidth: () => number;\n}\n\nexport function createPanelLayout(\n refs: PanelLayoutRefs,\n callbacks: PanelLayoutCallbacks,\n): PanelLayoutController {\n const {\n host,\n shadow,\n panelShell,\n popoutBtn,\n dockBtn,\n closeBtn,\n pinLeftBtn,\n pinRightBtn,\n halfBtn,\n halfExitBtn,\n fullscreenBtn,\n fullscreenExitBtn,\n resizeHandle,\n } = refs;\n\n // ---- Width state ---------------------------------------------------------\n let _currentWidth = 400;\n try {\n const stored = localStorage.getItem(LS_WIDTH_KEY);\n if (stored) {\n const n = Number(stored);\n if (Number.isFinite(n) && n >= MIN_WIDTH) _currentWidth = n;\n }\n } catch {\n /* ignore */\n }\n panelShell.style.width = `${_currentWidth}px`;\n\n // ---- Side state ----------------------------------------------------------\n let _side: \"left\" | \"right\" = \"right\";\n try {\n const stored = localStorage.getItem(LS_SIDE_KEY);\n if (stored === \"left\" || stored === \"right\") _side = stored;\n } catch {\n /* ignore */\n }\n\n // ---- Popout state --------------------------------------------------------\n let _popoutWin: Window | null = null;\n let _isPopout = false;\n let _popoutInterval: ReturnType<typeof setInterval> | null = null;\n\n // ---- Screen mode state ---------------------------------------------------\n let _isHalfScreen = false;\n let _isFullscreen = false;\n let _wasOpenOnFullscreenEnter = false;\n\n // ---- Drag-resize state ---------------------------------------------------\n let _resizing = false;\n let _resizeStartX = 0;\n let _resizeStartWidth = 0;\n\n // ---- Show / Hide ---------------------------------------------------------\n\n function show() {\n if (_isPopout) return;\n panelShell.classList.add(\"open\");\n host.setAttribute(\"data-panel-open\", \"true\");\n const railHost = document.getElementById(\"unnoodle-rail-host\");\n const railOffset = railHost ? 34 : 0;\n if (railOffset) {\n panelShell.style.right = `${railOffset}px`;\n }\n if (!_isFullscreen) {\n const marginProp = _side === \"right\" ? \"margin-right\" : \"margin-left\";\n document.body.style.transition = `${marginProp} 0.28s cubic-bezier(0.4,0,0.2,1)`;\n if (_side === \"right\") {\n document.body.style.marginRight = `${_currentWidth + railOffset}px`;\n document.body.style.marginLeft = \"\";\n } else {\n document.body.style.marginLeft = `${_currentWidth}px`;\n document.body.style.marginRight = railOffset ? `${railOffset}px` : \"\";\n }\n }\n const btn = document.getElementById(\"unnoodle-btn-host\");\n if (btn) btn.style.display = \"none\";\n }\n\n function hide() {\n if (_isPopout) return;\n if (_isHalfScreen) {\n _isHalfScreen = false;\n panelShell.classList.remove(\"half-screen\");\n halfBtn.hidden = false;\n halfExitBtn.hidden = true;\n }\n if (_isFullscreen) {\n _isFullscreen = false;\n panelShell.classList.remove(\"fullscreen\");\n fullscreenBtn.hidden = false;\n fullscreenExitBtn.hidden = true;\n _wasOpenOnFullscreenEnter = false;\n }\n panelShell.classList.remove(\"open\");\n host.removeAttribute(\"data-panel-open\");\n panelShell.style.right = \"\";\n const railHost = document.getElementById(\"unnoodle-rail-host\");\n const railOffset = railHost ? 34 : 0;\n document.body.style.marginRight = railOffset ? `${railOffset}px` : \"\";\n document.body.style.marginLeft = \"\";\n const btn = document.getElementById(\"unnoodle-btn-host\");\n if (btn) btn.style.removeProperty(\"display\");\n }\n\n // ---- Popout / Reattach ---------------------------------------------------\n\n function popout() {\n if (_isPopout) {\n if (_popoutWin && !_popoutWin.closed) _popoutWin.focus();\n return;\n }\n\n const win = window.open(\n \"about:blank\",\n \"unnoodle_panel\",\n \"width=440,height=720,resizable=yes,scrollbars=no,status=no,location=no,toolbar=no,menubar=no\",\n );\n if (!win) {\n callbacks.onToast?.(\n \"Allow popups for this site to use the detached panel.\",\n );\n return;\n }\n\n const rootTokens = callbacks.shadowTokens\n ? callbacks.shadowTokens.replace(/:host\\b/g, \":root\")\n : \"\";\n\n win.document.write(\n `<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Unnoodle</title>` +\n `<style>*{margin:0;padding:0;box-sizing:border-box;}html,body{height:100%;overflow:hidden;}</style>` +\n (rootTokens ? `<style>${rootTokens}</style>` : \"\") +\n `</head><body style=\"height:100%\"></body></html>`,\n );\n win.document.close();\n\n const overrideStyle = document.createElement(\"style\");\n overrideStyle.setAttribute(\"data-unnoodle-popout\", \"true\");\n overrideStyle.textContent = safeCSS(POPOUT_OVERRIDE_STYLE);\n shadow.appendChild(overrideStyle);\n\n const adopted = win.document.adoptNode(host) as HTMLElement;\n adopted.style.cssText = \"display:block;width:100%;height:100%;\";\n win.document.body.appendChild(adopted);\n\n _popoutWin = win;\n _isPopout = true;\n\n panelShell.classList.add(\"open\");\n\n popoutBtn.hidden = true;\n dockBtn.hidden = false;\n closeBtn.hidden = true;\n\n document.body.style.marginRight = \"\";\n document.body.style.marginLeft = \"\";\n const triggerBtn = document.getElementById(\"unnoodle-btn-host\");\n if (triggerBtn) triggerBtn.style.display = \"none\";\n\n callbacks.onPopout?.();\n\n win.addEventListener(\"beforeunload\", () => {\n _reattach(true);\n });\n\n _popoutInterval = setInterval(() => {\n if (win.closed) {\n clearInterval(_popoutInterval!);\n _popoutInterval = null;\n _reattach(true);\n }\n }, 500);\n }\n\n function _reattach(winAlreadyClosing = false) {\n if (!_isPopout) return;\n _isPopout = false;\n\n if (_popoutInterval) {\n clearInterval(_popoutInterval);\n _popoutInterval = null;\n }\n\n const readopted = document.adoptNode(host) as HTMLElement;\n readopted.style.cssText = \"\";\n document.body.appendChild(readopted);\n\n const overrideEl = shadow.querySelector(\"[data-unnoodle-popout]\");\n if (overrideEl) overrideEl.remove();\n\n panelShell.classList.remove(\"open\");\n host.removeAttribute(\"data-panel-open\");\n\n popoutBtn.hidden = false;\n dockBtn.hidden = true;\n closeBtn.hidden = false;\n\n const triggerBtn = document.getElementById(\"unnoodle-btn-host\");\n if (triggerBtn) triggerBtn.style.removeProperty(\"display\");\n\n if (!winAlreadyClosing && _popoutWin && !_popoutWin.closed) {\n _popoutWin.close();\n }\n _popoutWin = null;\n\n callbacks.onReattach?.();\n }\n\n // ---- Side pin ------------------------------------------------------------\n\n function _setSide(side: \"left\" | \"right\") {\n _side = side;\n try {\n localStorage.setItem(LS_SIDE_KEY, side);\n } catch {\n /* ignore */\n }\n if (side === \"left\") {\n panelShell.classList.add(\"left-side\");\n pinLeftBtn.classList.add(\"active\");\n pinRightBtn.classList.remove(\"active\");\n } else {\n panelShell.classList.remove(\"left-side\");\n pinRightBtn.classList.add(\"active\");\n pinLeftBtn.classList.remove(\"active\");\n }\n if (panelShell.classList.contains(\"open\") && !_isPopout && !_isFullscreen) {\n document.body.style.marginRight =\n side === \"right\" ? `${_currentWidth}px` : \"\";\n document.body.style.marginLeft =\n side === \"left\" ? `${_currentWidth}px` : \"\";\n }\n }\n\n if (_side === \"left\") _setSide(\"left\");\n\n // ---- Half-screen ---------------------------------------------------------\n\n function _toggleHalfScreen() {\n _isHalfScreen = !_isHalfScreen;\n if (_isHalfScreen) {\n if (_isFullscreen) {\n _isFullscreen = false;\n panelShell.classList.remove(\"fullscreen\");\n fullscreenBtn.hidden = false;\n fullscreenExitBtn.hidden = true;\n _wasOpenOnFullscreenEnter = false;\n }\n panelShell.classList.add(\"half-screen\");\n halfBtn.hidden = true;\n halfExitBtn.hidden = false;\n if (panelShell.classList.contains(\"open\") && !_isPopout) {\n const rOff = document.getElementById(\"unnoodle-rail-host\") ? 34 : 0;\n const halfWidth = Math.round(window.innerWidth * 0.5);\n if (_side === \"right\") {\n document.body.style.marginRight = `${halfWidth + rOff}px`;\n document.body.style.marginLeft = \"\";\n } else {\n document.body.style.marginLeft = `${halfWidth}px`;\n document.body.style.marginRight = rOff ? `${rOff}px` : \"\";\n }\n }\n } else {\n panelShell.classList.remove(\"half-screen\");\n halfBtn.hidden = false;\n halfExitBtn.hidden = true;\n if (panelShell.classList.contains(\"open\") && !_isPopout) {\n const rOff = document.getElementById(\"unnoodle-rail-host\") ? 34 : 0;\n if (_side === \"right\") {\n document.body.style.marginRight = `${_currentWidth + rOff}px`;\n document.body.style.marginLeft = \"\";\n } else {\n document.body.style.marginLeft = `${_currentWidth}px`;\n document.body.style.marginRight = rOff ? `${rOff}px` : \"\";\n }\n }\n }\n }\n\n // ---- Fullscreen ----------------------------------------------------------\n\n function _toggleFullscreen() {\n _isFullscreen = !_isFullscreen;\n if (_isFullscreen) {\n if (_isHalfScreen) {\n _isHalfScreen = false;\n panelShell.classList.remove(\"half-screen\");\n halfBtn.hidden = false;\n halfExitBtn.hidden = true;\n }\n _wasOpenOnFullscreenEnter =\n panelShell.classList.contains(\"open\") && !_isPopout;\n panelShell.classList.add(\"fullscreen\");\n fullscreenBtn.hidden = true;\n fullscreenExitBtn.hidden = false;\n document.body.style.marginRight = \"\";\n document.body.style.marginLeft = \"\";\n } else {\n panelShell.classList.remove(\"fullscreen\");\n fullscreenBtn.hidden = false;\n fullscreenExitBtn.hidden = true;\n if (_wasOpenOnFullscreenEnter && panelShell.classList.contains(\"open\")) {\n const rOff = document.getElementById(\"unnoodle-rail-host\") ? 34 : 0;\n if (_side === \"right\") {\n document.body.style.marginRight = `${_currentWidth + rOff}px`;\n document.body.style.marginLeft = \"\";\n } else {\n document.body.style.marginLeft = `${_currentWidth}px`;\n document.body.style.marginRight = rOff ? `${rOff}px` : \"\";\n }\n }\n _wasOpenOnFullscreenEnter = false;\n }\n }\n\n // ---- Drag-resize ---------------------------------------------------------\n\n function _onResizeMove(e: MouseEvent): void {\n if (!_resizing || _isPopout) return;\n const vwMax =\n window.innerWidth > 0\n ? Math.floor(window.innerWidth * 0.6)\n : MAX_WIDTH_ABS;\n const maxWidth = Math.min(MAX_WIDTH_ABS, vwMax);\n const delta =\n _side === \"right\"\n ? _resizeStartX - e.clientX\n : e.clientX - _resizeStartX;\n const newWidth = Math.max(\n MIN_WIDTH,\n Math.min(maxWidth, _resizeStartWidth + delta),\n );\n _currentWidth = newWidth;\n panelShell.style.width = `${newWidth}px`;\n if (panelShell.classList.contains(\"open\") && !_isFullscreen) {\n const rOff = document.getElementById(\"unnoodle-rail-host\") ? 34 : 0;\n if (_side === \"right\") {\n document.body.style.marginRight = `${newWidth + rOff}px`;\n document.body.style.marginLeft = \"\";\n } else {\n document.body.style.marginLeft = `${newWidth}px`;\n document.body.style.marginRight = rOff ? `${rOff}px` : \"\";\n }\n }\n }\n\n function _onResizeUp(): void {\n if (!_resizing) return;\n _resizing = false;\n document.removeEventListener(\"mousemove\", _onResizeMove);\n document.removeEventListener(\"mouseup\", _onResizeUp);\n try {\n localStorage.setItem(LS_WIDTH_KEY, String(_currentWidth));\n } catch {\n /* ignore */\n }\n }\n\n // ---- Cleanup -------------------------------------------------------------\n\n function cleanup() {\n document.removeEventListener(\"mousemove\", _onResizeMove);\n document.removeEventListener(\"mouseup\", _onResizeUp);\n if (_isPopout) _reattach(false);\n document.body.style.marginRight = \"\";\n document.body.style.marginLeft = \"\";\n const btn = document.getElementById(\"unnoodle-btn-host\");\n if (btn) btn.style.removeProperty(\"display\");\n }\n\n // ---- Wire button listeners -----------------------------------------------\n\n const handleClose = () => {\n hide();\n callbacks.onClose?.();\n };\n closeBtn.addEventListener(\"click\", handleClose);\n\n dockBtn.addEventListener(\"click\", () => _reattach(false));\n popoutBtn.addEventListener(\"click\", () => popout());\n pinLeftBtn.addEventListener(\"click\", () => _setSide(\"left\"));\n pinRightBtn.addEventListener(\"click\", () => _setSide(\"right\"));\n halfBtn.addEventListener(\"click\", () => _toggleHalfScreen());\n halfExitBtn.addEventListener(\"click\", () => _toggleHalfScreen());\n fullscreenBtn.addEventListener(\"click\", () => _toggleFullscreen());\n fullscreenExitBtn.addEventListener(\"click\", () => _toggleFullscreen());\n\n resizeHandle.addEventListener(\"mousedown\", (e: MouseEvent) => {\n if (_isPopout) return;\n _resizing = true;\n _resizeStartX = e.clientX;\n _resizeStartWidth = _currentWidth;\n document.addEventListener(\"mousemove\", _onResizeMove);\n document.addEventListener(\"mouseup\", _onResizeUp);\n e.preventDefault();\n });\n\n return {\n show,\n hide,\n popout,\n cleanup,\n isPopout: () => _isPopout,\n currentWidth: () => _currentWidth,\n };\n}\n","import type {\n WidgetInitResponse,\n GlossaryTerm,\n ContextDiscussion,\n} from \"../../../types/config\";\nimport { escapeHtml } from \"../utils\";\n\nexport const MAX_HOME_ITEMS = 5;\n\nexport interface HomeViewCallbacks {\n onTermClick?: (term: GlossaryTerm) => void;\n onRequireLogin?: () => void;\n onAddConcept?: (term: string, definition: string) => void;\n onOpenSearch?: () => void;\n onCaptureUiState?: () => void;\n onShowAllConcepts?: () => void;\n onClarificationClick?: (discussion: ContextDiscussion) => void;\n onShowAllClarifications?: () => void;\n onAskQuestion?: (contextId: number, questionBody: string) => void;\n /** LQ-12: user clicked the \"Ask about this product\" row above the search bar. */\n onOpenAsk?: () => void;\n}\n\nexport function renderHomeView(\n body: HTMLElement,\n headerSubtitle: Element | null,\n data: WidgetInitResponse,\n callbacks: HomeViewCallbacks,\n isAuthenticated: boolean,\n): void {\n const {\n onTermClick,\n onRequireLogin,\n onAddConcept,\n onOpenSearch,\n onCaptureUiState,\n onShowAllConcepts,\n onOpenAsk,\n } = callbacks;\n\n if (headerSubtitle) headerSubtitle.textContent = data.context.name;\n\n const terms = data.glossary;\n\n // Helper: is this term present in the current page body text?\n function isRelevantToPage(t: GlossaryTerm): boolean {\n const rx = new RegExp(\n `\\\\b${t.term.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}\\\\b`,\n \"i\",\n );\n return rx.test(document.body?.innerText ?? \"\");\n }\n\n const conceptRowsHtml = (list: GlossaryTerm[]) =>\n list\n .map(\n (t) => `\n <div class=\"concept-row\" data-testid=\"widget-term-card\" data-term-id=\"${t.id}\">\n <span class=\"concept-name\">${escapeHtml(t.term)}</span>\n ${t.abbreviation ? `<span class=\"concept-abbr\">${escapeHtml(t.abbreviation)}</span>` : \"\"}\n <span class=\"concept-chevron\"><svg viewBox=\"0 0 24 24\"><polyline points=\"9 18 15 12 9 6\"/></svg></span>\n </div>`,\n )\n .join(\"\");\n\n function buildConceptsBody(\n filtTerms: GlossaryTerm[],\n isFiltering: boolean,\n ): string {\n const filtRelevant = filtTerms.filter(isRelevantToPage);\n const filtOther = filtTerms.filter((t) => !isRelevantToPage(t));\n const hasBothGroups = filtRelevant.length > 0 && filtOther.length > 0;\n\n if (filtTerms.length === 0) {\n return isFiltering\n ? `<div class=\"section-empty\" data-testid=\"widget-glossary-empty\"><div class=\"section-empty-title\">No matching concepts.</div></div>`\n : `<div class=\"section-empty\"><div class=\"section-empty-title\">No product concepts defined yet.</div><div class=\"section-empty-text\">Start building shared vocabulary for this context.</div><button class=\"section-empty-action\" data-testid=\"widget-add-concept-empty\">Add Concept</button></div>`;\n }\n\n const relevantHtml =\n filtRelevant.length > 0\n ? `<div class=\"concept-subheading\">Used on this page</div>${conceptRowsHtml(filtRelevant)}`\n : \"\";\n const otherHeadHtml = hasBothGroups\n ? `<div class=\"concept-subheading\">Other concepts in this context</div>`\n : \"\";\n\n if (isFiltering) {\n return relevantHtml + otherHeadHtml + conceptRowsHtml(filtOther);\n }\n\n const visibleRelevant = filtRelevant.slice(0, MAX_HOME_ITEMS);\n const otherCap = Math.max(MAX_HOME_ITEMS - visibleRelevant.length, 0);\n const visibleOther = filtOther.slice(0, otherCap);\n const hiddenOther = filtOther.slice(otherCap);\n const hiddenRelevant = filtRelevant.slice(MAX_HOME_ITEMS);\n const showMoreHtml =\n filtTerms.length > MAX_HOME_ITEMS\n ? `<div class=\"home-concepts-hidden\" style=\"display:none\">${conceptRowsHtml(hiddenRelevant)}${conceptRowsHtml(hiddenOther)}</div>` +\n `<a href=\"#\" class=\"home-show-more home-show-more-concepts\" data-testid=\"widget-show-all-concepts\">Show all ${filtTerms.length} vocabulary →</a>`\n : ``;\n\n const relevantBlockHtml =\n visibleRelevant.length > 0\n ? `<div class=\"concept-subheading\">Used on this page</div>${conceptRowsHtml(visibleRelevant)}`\n : \"\";\n\n return (\n relevantBlockHtml +\n otherHeadHtml +\n conceptRowsHtml(visibleOther) +\n showMoreHtml\n );\n }\n\n const conceptsBlockHtml = buildConceptsBody(terms, false);\n\n body.innerHTML = `\n <div class=\"home-view\" data-testid=\"widget-home-view\">\n <div class=\"context-strip\" data-testid=\"widget-context-strip\" style=\"display:none !important\">\n <!-- idle state -->\n <div class=\"strip-idle\">\n <button class=\"strip-btn\" data-testid=\"widget-add-ui-meaning-btn\" aria-label=\"Add UI Meaning\">\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"3\"/><path d=\"M12 1v4M12 19v4M4.22 4.22l2.83 2.83M16.95 16.95l2.83 2.83M1 12h4M19 12h4M4.22 19.78l2.83-2.83M16.95 7.05l2.83-2.83\"/></svg>\n Add UI Meaning\n </button>\n </div>\n <!-- pick-mode state -->\n <div class=\"pick-mode-prompt\" data-testid=\"widget-pick-mode-prompt\">\n <span class=\"pick-prompt-text\">Click any element on the page&hellip;</span>\n <button class=\"strip-cancel-btn\" data-testid=\"widget-context-strip-cancel-btn\" aria-label=\"Cancel pick mode\">Cancel</button>\n </div>\n <!-- capture-describe state -->\n <div class=\"capture-describe-view\" data-testid=\"widget-capture-describe-view\">\n <div class=\"capture-snapshot-preview\" data-testid=\"widget-capture-snapshot-preview\"></div>\n <textarea class=\"capture-description-input\" data-testid=\"widget-capture-description-input\"\n placeholder=\"Describe what this UI state means\\u2026\" rows=\"3\" maxlength=\"2000\"></textarea>\n <p class=\"capture-error\" style=\"display:none\"></p>\n <div class=\"capture-actions\">\n <button class=\"strip-cancel-btn\" data-testid=\"widget-capture-pick-again-btn\">Pick Again</button>\n <button class=\"capture-save-btn\" data-testid=\"widget-capture-save-btn\">Save</button>\n </div>\n </div>\n </div>\n <button class=\"home-ask-entry\" data-testid=\"widget-ask-entry\">\n Ask about this product\\u2026\n </button>\n <div class=\"home-search-bar\" data-testid=\"widget-home-search-bar\">\n <input class=\"home-search-input\" id=\"unn-home-search\" type=\"search\"\n placeholder=\"Search\\u2026\" autocomplete=\"off\" aria-label=\"Search\"\n data-testid=\"widget-home-search-input\" />\n </div>\n <div class=\"home-sections\">\n <div class=\"home-section\" data-section=\"memory\">\n <div class=\"home-section-header\">\n <span class=\"home-section-title\"><span class=\"home-section-dot\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" fill=\"currentColor\" viewBox=\"0 0 256 256\"><path d=\"M248,124a56.11,56.11,0,0,0-32-50.61V72a48,48,0,0,0-88-26.49A48,48,0,0,0,40,72v1.39a56,56,0,0,0,0,101.2V176a48,48,0,0,0,88,26.49A48,48,0,0,0,216,176v-1.41A56.09,56.09,0,0,0,248,124ZM88,208a32,32,0,0,1-31.81-28.56A55.87,55.87,0,0,0,64,180h8a8,8,0,0,0,0-16H64A40,40,0,0,1,50.67,86.27,8,8,0,0,0,56,78.73V72a32,32,0,0,1,64,0v68.26A47.8,47.8,0,0,0,88,128a8,8,0,0,0,0,16,32,32,0,0,1,0,64Zm104-44h-8a8,8,0,0,0,0,16h8a55.87,55.87,0,0,0,7.81-.56A32,32,0,1,1,168,144a8,8,0,0,0,0-16,47.8,47.8,0,0,0-32,12.26V72a32,32,0,0,1,64,0v6.73a8,8,0,0,0,5.33,7.54A40,40,0,0,1,192,164Zm16-52a8,8,0,0,1-8,8h-4a36,36,0,0,1-36-36V80a8,8,0,0,1,16,0v4a20,20,0,0,0,20,20h4A8,8,0,0,1,208,112ZM60,120H56a8,8,0,0,1,0-16h4A20,20,0,0,0,80,84V80a8,8,0,0,1,16,0v4A36,36,0,0,1,60,120Z\"></path></svg></span>PRODUCT MEMORY</span>\n <button class=\"home-section-add\" data-testid=\"widget-add-ui-meaning\">+</button>\n </div>\n <div class=\"home-section-helper\">Explain what elements on this screen do.</div>\n <div class=\"section-empty\">\n <div class=\"section-empty-title\">No UI explanations yet.</div>\n <div class=\"section-empty-text\">Explain what elements on this screen do so teammates can understand the interface faster.</div>\n <button class=\"section-empty-action\" data-testid=\"widget-add-ui-meaning-empty\">Add UI Meaning</button>\n </div>\n </div>\n <div class=\"home-section\" data-section=\"concepts\">\n <div class=\"home-section-header\">\n <span class=\"home-section-title\"><span class=\"home-section-dot\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" fill=\"currentColor\" viewBox=\"0 0 256 256\"><path d=\"M232,48H160a40,40,0,0,0-32,16A40,40,0,0,0,96,48H24a8,8,0,0,0-8,8V200a8,8,0,0,0,8,8H96a24,24,0,0,1,24,24,8,8,0,0,0,16,0,24,24,0,0,1,24-24h72a8,8,0,0,0,8-8V56A8,8,0,0,0,232,48ZM96,192H32V64H96a24,24,0,0,1,24,24V200A39.81,39.81,0,0,0,96,192Zm128,0H160a39.81,39.81,0,0,0-24,8V88a24,24,0,0,1,24-24h64ZM160,88h40a8,8,0,0,1,0,16H160a8,8,0,0,1,0-16Zm48,40a8,8,0,0,1-8,8H160a8,8,0,0,1,0-16h40A8,8,0,0,1,208,128Zm0,32a8,8,0,0,1-8,8H160a8,8,0,0,1,0-16h40A8,8,0,0,1,208,160Z\"></path></svg></span>PRODUCT VOCABULARY</span>\n <button class=\"home-section-add\" data-testid=\"widget-add-concept\">+</button>\n </div>\n <div class=\"home-section-helper\">Key terms used in this product.</div>\n ${conceptsBlockHtml}\n </div>\n <div class=\"home-section\" data-section=\"clarifications\" data-context-id=\"${data.context.id}\">\n <div class=\"home-section-header\">\n <span class=\"home-section-title\"><span class=\"home-section-dot\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" fill=\"currentColor\" viewBox=\"0 0 256 256\"><path d=\"M225.86,102.82c-3.77-3.94-7.67-8-9.14-11.57-1.36-3.27-1.44-8.69-1.52-13.94-.15-9.76-.31-20.82-8-28.51s-18.75-7.85-28.51-8c-5.25-.08-10.67-.16-13.94-1.52-3.56-1.47-7.63-5.37-11.57-9.14C146.28,23.51,138.44,16,128,16s-18.27,7.51-25.18,14.14c-3.94,3.77-8,7.67-11.57,9.14C88,40.64,82.56,40.72,77.31,40.8c-9.76.15-20.82.31-28.51,8S41,67.55,40.8,77.31c-.08,5.25-.16,10.67-1.52,13.94-1.47,3.56-5.37,7.63-9.14,11.57C23.51,109.72,16,117.56,16,128s7.51,18.27,14.14,25.18c3.77,3.94,7.67,8,9.14,11.57,1.36,3.27,1.44,8.69,1.52,13.94.15,9.76.31,20.82,8,28.51s18.75,7.85,28.51,8c5.25.08,10.67.16,13.94,1.52,3.56,1.47,7.63,5.37,11.57,9.14C109.72,232.49,117.56,240,128,240s18.27-7.51,25.18-14.14c3.94-3.77,8-7.67,11.57-9.14,3.27-1.36,8.69-1.44,13.94-1.52,9.76-.15,20.82-.31,28.51-8s7.85-18.75,8-28.51c.08-5.25.16-10.67,1.52-13.94,1.47-3.56,5.37-7.63,9.14-11.57C232.49,146.28,240,138.44,240,128S232.49,109.73,225.86,102.82Zm-11.55,39.29c-4.79,5-9.75,10.17-12.38,16.52-2.52,6.1-2.63,13.07-2.73,19.82-.1,7-.21,14.33-3.32,17.43s-10.39,3.22-17.43,3.32c-6.75.1-13.72.21-19.82,2.73-6.35,2.63-11.52,7.59-16.52,12.38S132,224,128,224s-9.15-4.92-14.11-9.69-10.17-9.75-16.52-12.38c-6.1-2.52-13.07-2.63-19.82-2.73-7-.1-14.33-.21-17.43-3.32s-3.22-10.39-3.32-17.43c-.1-6.75-.21-13.72-2.73-19.82-2.63-6.35-7.59-11.52-12.38-16.52S32,132,32,128s4.92-9.15,9.69-14.11,9.75-10.17,12.38-16.52c2.52-6.1,2.63-13.07,2.73-19.82.1-7,.21-14.33,3.32-17.43S70.51,56.9,77.55,56.8c6.75-.1,13.72-.21,19.82-2.73,6.35-2.63,11.52-7.59,16.52-12.38S124,32,128,32s9.15,4.92,14.11,9.69,10.17,9.75,16.52,12.38c6.1,2.52,13.07,2.63,19.82,2.73,7,.1,14.33.21,17.43,3.32s3.22,10.39,3.32,17.43c.1,6.75.21,13.72,2.73,19.82,2.63,6.35,7.59,11.52,12.38,16.52S224,124,224,128,219.08,137.15,214.31,142.11ZM140,180a12,12,0,1,1-12-12A12,12,0,0,1,140,180Zm28-72c0,17.38-13.76,31.93-32,35.28V144a8,8,0,0,1-16,0v-8a8,8,0,0,1,8-8c13.23,0,24-9,24-20s-10.77-20-24-20-24,9-24,20v4a8,8,0,0,1-16,0v-4c0-19.85,17.94-36,40-36S168,88.15,168,108Z\"></path></svg></span>CLARIFICATIONS</span>\n <button class=\"home-section-add\" data-testid=\"widget-ask-question-btn\">+</button>\n </div>\n <div class=\"home-section-helper\">Ask if something on this page is unclear. Owners will respond.</div>\n <div class=\"clarifications-body\">\n <div class=\"skeleton-row\"><div class=\"skeleton-line\" style=\"width:70%;height:9px;border-radius:4px;\"></div></div>\n </div>\n </div>\n </div>\n </div>\n `;\n\n // Wire: concept row clicks (reused after in-place filter updates)\n const wireConceptClicks = (container: Element) => {\n container\n .querySelectorAll<HTMLDivElement>(\"[data-testid='widget-term-card']\")\n .forEach((row) => {\n row.addEventListener(\"click\", () => {\n const termId = Number(row.dataset.termId);\n const term = terms.find((t) => t.id === termId);\n if (term) onTermClick?.(term);\n });\n });\n };\n\n wireConceptClicks(body);\n\n function wireShowAllButtons() {\n const conceptsBtn = body.querySelector<HTMLButtonElement>(\n \"[data-testid='widget-show-all-concepts']\",\n );\n if (conceptsBtn) {\n conceptsBtn.addEventListener(\"click\", (e) => {\n e.preventDefault();\n onShowAllConcepts?.();\n });\n }\n }\n\n wireShowAllButtons();\n\n function applyConceptFilter(q: string) {\n const conceptsSecEl = body.querySelector<HTMLElement>(\n \"[data-section='concepts']\",\n );\n if (!conceptsSecEl) return;\n const secHeader = conceptsSecEl.querySelector<HTMLElement>(\n \".home-section-header\",\n );\n if (!secHeader) return;\n\n const isFiltering = q.length >= 2;\n const ql = q.toLowerCase();\n const filtered = isFiltering\n ? terms.filter(\n (t) =>\n t.term.toLowerCase().includes(ql) ||\n t.definition.toLowerCase().includes(ql) ||\n (t.abbreviation ?? \"\").toLowerCase().includes(ql),\n )\n : terms;\n\n const tmp = document.createElement(\"div\");\n tmp.innerHTML = buildConceptsBody(filtered, isFiltering);\n\n while (conceptsSecEl.lastChild && conceptsSecEl.lastChild !== secHeader) {\n conceptsSecEl.removeChild(conceptsSecEl.lastChild);\n }\n while (tmp.firstChild) conceptsSecEl.appendChild(tmp.firstChild);\n\n wireConceptClicks(conceptsSecEl);\n }\n\n body\n .querySelector<HTMLButtonElement>(\"[data-testid='widget-search-toggle']\")\n ?.addEventListener(\"click\", () => {\n onOpenSearch?.();\n });\n\n body\n .querySelector<HTMLButtonElement>(\"[data-testid='widget-ask-entry']\")\n ?.addEventListener(\"click\", () => {\n onOpenAsk?.();\n });\n\n const searchInput = body.querySelector<HTMLInputElement>(\n \"[data-testid='widget-home-search-input']\",\n );\n\n let searchDebounce: ReturnType<typeof setTimeout> | undefined = undefined;\n\n searchInput?.addEventListener(\"input\", () => {\n clearTimeout(searchDebounce);\n searchDebounce = setTimeout(() => {\n applyConceptFilter(searchInput.value);\n }, 200);\n });\n\n body\n .querySelector<HTMLButtonElement>(\"[data-testid='widget-add-concept']\")\n ?.addEventListener(\"click\", () => {\n if (!isAuthenticated) {\n onRequireLogin?.();\n return;\n }\n const sec = body.querySelector<HTMLElement>(\"[data-section='concepts']\");\n if (sec) showAddTermForm(sec, undefined, onAddConcept);\n });\n\n body\n .querySelector<HTMLButtonElement>(\n \"[data-testid='widget-add-concept-empty']\",\n )\n ?.addEventListener(\"click\", () => {\n if (!isAuthenticated) {\n onRequireLogin?.();\n return;\n }\n const sec = body.querySelector<HTMLElement>(\"[data-section='concepts']\");\n if (sec) showAddTermForm(sec, undefined, onAddConcept);\n });\n\n body\n .querySelector<HTMLButtonElement>(\"[data-testid='widget-add-ui-meaning']\")\n ?.addEventListener(\"click\", () => {\n onCaptureUiState?.();\n });\n\n body\n .querySelector<HTMLButtonElement>(\n \"[data-testid='widget-add-ui-meaning-empty']\",\n )\n ?.addEventListener(\"click\", () => {\n onCaptureUiState?.();\n });\n\n body\n .querySelector<HTMLButtonElement>(\n \"[data-testid='widget-add-ui-meaning-btn']\",\n )\n ?.addEventListener(\"click\", () => {\n onCaptureUiState?.();\n });\n}\n\nexport function loadClarificationsView(\n body: HTMLElement,\n discussions: ContextDiscussion[],\n canPost: boolean,\n callbacks: Pick<\n HomeViewCallbacks,\n | \"onRequireLogin\"\n | \"onClarificationClick\"\n | \"onShowAllClarifications\"\n | \"onAskQuestion\"\n >,\n): void {\n const {\n onRequireLogin,\n onClarificationClick,\n onShowAllClarifications,\n onAskQuestion,\n } = callbacks;\n\n const clarificationsSection = body.querySelector<HTMLElement>(\n \"[data-section='clarifications']\",\n );\n if (!clarificationsSection) return;\n\n const clarBody = clarificationsSection.querySelector(\".clarifications-body\");\n if (!clarBody) return;\n\n const sectionHeader = clarificationsSection.querySelector(\n \".home-section-header\",\n );\n const askBtn =\n sectionHeader?.querySelector<HTMLButtonElement>(\".home-section-add\");\n if (askBtn) {\n askBtn.addEventListener(\"click\", () => {\n if (canPost) {\n const contextId = Number(clarificationsSection.dataset.contextId);\n showAskQuestionForm(clarificationsSection, contextId, onAskQuestion);\n } else {\n onRequireLogin?.();\n }\n });\n }\n\n if (discussions.length === 0) {\n clarBody.innerHTML = `<div class=\"section-empty\"><div class=\"section-empty-title\">No questions yet.</div><div class=\"section-empty-text\">Ask here if something about this interface is unclear.</div><button class=\"section-empty-action\" data-testid=\"widget-ask-question-empty\">Ask Question</button></div>`;\n\n const emptyBtn = clarBody.querySelector<HTMLButtonElement>(\n '[data-testid=\"widget-ask-question-empty\"]',\n );\n if (emptyBtn) {\n emptyBtn.addEventListener(\"click\", () => {\n if (canPost) {\n const contextId = Number(clarificationsSection.dataset.contextId);\n showAskQuestionForm(clarificationsSection, contextId, onAskQuestion);\n } else {\n onRequireLogin?.();\n }\n });\n }\n return;\n }\n\n const postsHtml = discussions\n .slice(0, MAX_HOME_ITEMS)\n .map((d) => {\n const authorLabel = d.authorName ? escapeHtml(d.authorName) : \"Unknown\";\n const date = d.createdAt\n ? new Date(d.createdAt).toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n })\n : \"\";\n const repliesHtml = (d.replies ?? [])\n .map(\n (r) => `\n <div class=\"discussion-reply\">\n <div class=\"discussion-meta\"><span class=\"discussion-meta-dot\"></span>${escapeHtml(r.authorName ?? \"Unknown\")} · ${new Date(r.createdAt).toLocaleDateString(undefined, { month: \"short\", day: \"numeric\" })}</div>\n <p class=\"discussion-body\">${escapeHtml(r.body)}</p>\n </div>`,\n )\n .join(\"\");\n return `\n <div class=\"discussion-card\" data-discussion-id=\"${d.id}\">\n <div class=\"discussion-card-main\">\n <div class=\"discussion-meta\"><span class=\"discussion-meta-dot\"></span>${authorLabel} · ${date}</div>\n <p class=\"discussion-body\">${escapeHtml(d.body)}</p>\n ${repliesHtml ? `<div class=\"discussion-replies\">${repliesHtml}</div>` : \"\"}\n </div>\n <span class=\"concept-chevron\"><svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><polyline points=\"9 18 15 12 9 6\"/></svg></span>\n </div>`;\n })\n .join(\"\");\n\n const showMoreHtml =\n discussions.length > MAX_HOME_ITEMS\n ? `<a href=\"#\" class=\"home-show-more home-show-more-clarifications\" data-testid=\"widget-show-all-clarifications\">Show all ${discussions.length} clarifications →</a>`\n : ``;\n\n clarBody.innerHTML = postsHtml + showMoreHtml;\n\n clarBody.querySelectorAll<HTMLElement>(\".discussion-card\").forEach((card) => {\n card.addEventListener(\"click\", () => {\n const id = Number(card.dataset.discussionId);\n const discussion = discussions.find((d) => d.id === id);\n if (discussion) onClarificationClick?.(discussion);\n });\n });\n\n const showAllBtn = clarBody.querySelector<HTMLButtonElement>(\n \"[data-testid='widget-show-all-clarifications']\",\n );\n if (showAllBtn) {\n showAllBtn.addEventListener(\"click\", (e) => {\n e.preventDefault();\n onShowAllClarifications?.();\n });\n }\n}\n\nexport function showAskQuestionForm(\n section: HTMLElement,\n contextId: number,\n onAskQuestion?: (contextId: number, questionBody: string) => void,\n): void {\n const clarBody = section.querySelector(\".clarifications-body\");\n if (!clarBody) return;\n if (clarBody.querySelector(\".ask-form\")) return; // already open\n\n const emptyState = clarBody.querySelector<HTMLElement>(\".section-empty\");\n if (emptyState) emptyState.style.display = \"none\";\n\n const form = document.createElement(\"div\");\n form.className = \"ask-form\";\n form.innerHTML = `\n <textarea class=\"ask-textarea\" placeholder=\"Your question\\u2026\" maxlength=\"2000\" rows=\"3\"></textarea>\n <div class=\"ask-actions\">\n <button class=\"ask-cancel\">Cancel</button>\n <button class=\"ask-submit\" data-testid=\"widget-ask-submit\">Send</button>\n </div>\n <p class=\"ask-error\" style=\"display:none\"></p>\n `;\n clarBody.insertBefore(form, clarBody.firstChild);\n\n const textarea = form.querySelector<HTMLTextAreaElement>(\".ask-textarea\")!;\n const cancelBtn = form.querySelector<HTMLButtonElement>(\".ask-cancel\")!;\n const submitBtn = form.querySelector<HTMLButtonElement>(\".ask-submit\")!;\n\n textarea.focus();\n cancelBtn.addEventListener(\"click\", () => {\n form.remove();\n if (emptyState) emptyState.style.display = \"\";\n });\n submitBtn.addEventListener(\"click\", () => {\n const text = textarea.value.trim();\n if (!text) return;\n submitBtn.disabled = true;\n submitBtn.textContent = \"Sending\\u2026\";\n onAskQuestion?.(contextId, text);\n form.remove();\n });\n}\n\n/**\n * Shows an inline form inside the vocabulary section for adding a new term.\n */\nexport function showAddTermForm(\n section: HTMLElement,\n afterEl?: HTMLElement,\n onAddConcept?: (term: string, definition: string) => void,\n): void {\n if (section.querySelector(\".add-term-form\")) return;\n\n const insertAfter =\n afterEl ??\n section.querySelector<HTMLElement>(\".home-section-helper\") ??\n section.querySelector<HTMLElement>(\".home-section-header\");\n if (!insertAfter) return;\n\n const form = document.createElement(\"div\");\n form.className = \"add-term-form\";\n form.innerHTML = `\n <input class=\"add-term-input\" type=\"text\" placeholder=\"Term name\\u2026\" maxlength=\"100\" data-testid=\"widget-add-term-name\" />\n <textarea class=\"add-term-input ask-textarea\" placeholder=\"Definition\\u2026\" maxlength=\"5000\" rows=\"3\" data-testid=\"widget-add-term-definition\"></textarea>\n <div class=\"ask-actions\">\n <button class=\"ask-cancel\" data-testid=\"widget-add-term-cancel\">Cancel</button>\n <button class=\"ask-submit\" data-testid=\"widget-add-term-submit\">Add</button>\n </div>\n <p class=\"ask-error\" style=\"display:none\" data-testid=\"widget-add-term-error\"></p>\n `;\n insertAfter.after(form);\n\n const nameInput = form.querySelector<HTMLInputElement>(\n \"[data-testid='widget-add-term-name']\",\n )!;\n const defInput = form.querySelector<HTMLTextAreaElement>(\n \"[data-testid='widget-add-term-definition']\",\n )!;\n const cancelBtn = form.querySelector<HTMLButtonElement>(\n \"[data-testid='widget-add-term-cancel']\",\n )!;\n const submitBtn = form.querySelector<HTMLButtonElement>(\n \"[data-testid='widget-add-term-submit']\",\n )!;\n const errorEl = form.querySelector<HTMLParagraphElement>(\n \"[data-testid='widget-add-term-error']\",\n )!;\n\n nameInput.focus();\n\n cancelBtn.addEventListener(\"click\", () => form.remove());\n\n submitBtn.addEventListener(\"click\", () => {\n const term = nameInput.value.trim();\n const definition = defInput.value.trim();\n if (!term || !definition) {\n errorEl.textContent = \"Both term and definition are required.\";\n errorEl.style.display = \"\";\n return;\n }\n errorEl.style.display = \"none\";\n submitBtn.disabled = true;\n submitBtn.textContent = \"Adding\\u2026\";\n onAddConcept?.(term, definition);\n form.remove();\n });\n}\n","import type {\n WidgetInitResponse,\n GlossaryTerm,\n DiscussionPost,\n ContextDiscussion,\n GlossaryTermUpdateRequest,\n TermSuggestion,\n ProductMemoryResponse,\n ProductMemoryDetailResponse,\n SsoProviders,\n} from \"../types/config\";\nimport { safeCSS } from \"./safeCSS\";\nimport { PANEL_STYLES } from \"./panel/styles\";\nimport { renderLoginView, setLoginLoadingState, setLoginErrorState } from \"./panel/views/loginView\";\nimport { renderClarificationDetailView } from \"./panel/views/clarificationView\";\nimport {\n enterPickModeView,\n showCaptureDescribeView,\n setCaptureLoadingState,\n setCaptureErrorState,\n exitCaptureModeView,\n} from \"./panel/views/captureView\";\nimport { escapeHtml } from \"./panel/utils\";\nimport { createAskView, type AskViewControls } from \"./panel/views/askView\";\nimport type { AskAnswer, AskStatus } from \"../types/ask\";\nimport type { ElementSnapshot } from \"../features/memory/elementSnapshot\";\nimport { createCaptureForm, type CaptureFormController } from \"./captureForm\";\nimport {\n showStateChangeBanner,\n hideStateChangeBanner,\n} from \"./stateChangeBanner\";\nimport {\n ListViewManager,\n getListViewCSS,\n type ListViewCallbacks,\n} from \"./listViews\";\nimport { createPanelLayout } from \"./panel/panelLayout\";\nimport {\n renderHomeView as renderHomeViewFn,\n loadClarificationsView,\n showAskQuestionForm,\n showAddTermForm,\n MAX_HOME_ITEMS,\n} from \"./panel/views/homeView\";\n\nexport interface PanelControls {\n element: HTMLElement;\n show: () => void;\n hide: () => void;\n showLogin: (providers?: SsoProviders) => void;\n setLoginLoading: (loading: boolean) => void;\n setLoginError: (message: string) => void;\n setLoading: () => void;\n showTerms: (data: WidgetInitResponse) => void;\n showSearchResults: (terms: GlossaryTerm[], query: string) => void;\n setError: (message: string) => void;\n /** Phase 2: show term detail with discussion thread */\n showTermDetail: (\n term: GlossaryTerm,\n discussions: DiscussionPost[],\n opts?: { showEdit?: boolean },\n ) => void;\n /** Phase 2: show comment textarea inside the drawer */\n showCommentForm: (termId: number) => void;\n /** Phase 2: show edit-term form inside the drawer */\n showEditForm: (term: GlossaryTerm) => void;\n setCommentLoading: (loading: boolean) => void;\n setCommentError: (message: string) => void;\n setEditLoading: (loading: boolean) => void;\n setEditError: (message: string) => void;\n /** Phase 3: append AI-suggested terms below the glossary list */\n showSuggestedTerms: (\n suggestions: TermSuggestion[],\n onAdd: (termName: string) => void,\n ) => void;\n /** Phase 3: overlay modal to review/edit AI-generated definition */\n showAiModal: (\n term: string,\n definition: string,\n onSubmit: (editedDefinition: string) => void,\n onCancel: () => void,\n ) => void;\n /** Phase 3: toggle submit button loading state inside modal */\n setAiModalLoading: (loading: boolean) => void;\n /** Phase 3: transient success/info toast at bottom of panel */\n showToast: (message: string) => void;\n /** UI States: show/hide the capture button + UI States tab (call after login/logout) */\n setAuthenticated: (auth: boolean) => void;\n /** Product Memories: render the paginated list of memories */\n showMemoriesList: (\n memories: ProductMemoryResponse[],\n page: number,\n hasMore: boolean,\n append?: boolean,\n ) => void;\n /** Product Memories: render the detail view for a single memory */\n showMemoryDetail: (memory: ProductMemoryDetailResponse) => void;\n cleanup: () => void;\n /** Pop the panel out into its own browser window */\n popout: () => void;\n /** Phase 2: update the Clarifications section with loaded discussion data */\n loadClarifications: (\n discussions: ContextDiscussion[],\n canPost: boolean,\n ) => void;\n /** Show the detail view for a single clarification question + its replies */\n showClarificationDetail: (\n discussion: ContextDiscussion,\n canReply: boolean,\n ) => void;\n /** Capture flow: enter pick mode (hover-highlight + click to select an element) */\n enterPickMode: (onCancel: () => void) => void;\n /** Capture flow: show describe-capture view with element snapshot preview */\n showCaptureDescribe: (\n snapshot: ElementSnapshot,\n onSave: (description: string) => void,\n onPickAgain: () => void,\n ) => void;\n /** Capture flow: toggle loading state on the save button */\n setCaptureLoading: (loading: boolean) => void;\n /** Capture flow: show an error message in the describe view */\n setCaptureError: (message: string) => void;\n /** Capture flow: return context-strip to idle state */\n exitCaptureMode: () => void;\n /**\n * Populate the PRODUCT MEMORY section of the home view with captured memories.\n * Call after showTerms() resolves — empty array renders the empty state.\n */\n showHomeMemoryItems: (memories: ProductMemoryResponse[]) => void;\n /** Show All Views: display all concepts in a list format */\n showAllConcepts: (terms: GlossaryTerm[]) => void;\n /** Show All Views: display all clarifications in a list format */\n showAllClarifications: (\n discussions: ContextDiscussion[],\n canPost: boolean,\n ) => void;\n /** Show All Views: display all product memories in a list format */\n showAllMemories: (\n memories: ProductMemoryResponse[],\n canPost: boolean,\n ) => void;\n /** Capture flow: show full-screen form for creating a new memory */\n showNewMemoryForm: (\n onPickElement: () => void,\n onCancelCapture: () => void,\n onSave: (\n title: string,\n explanation: string,\n watchForChanges: boolean,\n ) => void,\n onCancel: () => void,\n ) => void;\n /** Capture flow: show full-screen form for adding entry to existing memory */\n showAddEntryForm: (\n memoryTitle: string,\n onPickElement: () => void,\n onCancelCapture: () => void,\n onSave: (explanation: string) => void,\n onCancel: () => void,\n ) => void;\n /** Capture flow: update the snapshot preview in the currently open form */\n updateFormSnapshot: (snapshot: ElementSnapshot) => void;\n /** Set picking mode UI state (dashed border, progress text, cancel button) */\n setFormPickingMode: (picking: boolean) => void;\n /** Restore the home view with the provided data */\n restoreHomeView: (data: any) => void;\n /**\n * Show (or replace) the \"New state detected — Save it?\" notification banner\n * at the top of the panel body.\n *\n * @param inferredMeaning Pre-inferred state label from inferMeaning(). Pass\n * null to show a generic prompt.\n * @param onSave Called when user clicks \"Save new state\".\n * @param onDismiss Called when user clicks \"Dismiss\".\n */\n showStateChangeNotification: (\n inferredMeaning: string | null,\n onSave: () => void,\n onDismiss: () => void,\n ) => void;\n /** Remove the state-change notification banner, if present. */\n hideStateChangeNotification: () => void;\n /**\n * LQ-12: show the Ask view. `status` is `GET /api/ask/status` or null when\n * that call failed — a null status renders the question box with no\n * staleness line, `{enabled:false}` renders the disabled notice instead.\n */\n showAsk: (status: AskStatus | null) => void;\n /** LQ-12: disable the question box and show the spinner. */\n setAskLoading: () => void;\n /** LQ-12: re-enable the question box without rendering a result (abort). */\n clearAskLoading: () => void;\n /** LQ-12: render an answer — chips, notes, staleness and provenance. */\n showAskAnswer: (answer: AskAnswer) => void;\n /** LQ-12: render an ask failure; `retryable` shows a \"Try again\" button. */\n showAskError: (message: string, retryable: boolean) => void;\n}\n\n/**\n * Creates the Phase-3 panel using Shadow DOM.\n * Fully isolated from host-app styles.\n *\n * Views:\n * login — email/password form; on submit calls onLogin callback\n * terms — searchable glossary list with header + optional footer link\n */\nexport function createPanel(\n onLogin: (email: string, password: string) => void,\n onSearch: (query: string) => void,\n workspaceUrl?: string,\n onClose?: () => void,\n onBack?: () => void,\n onAddComment?: (termId: number, body: string) => void,\n onEditTerm?: (termId: number, updates: GlossaryTermUpdateRequest) => void,\n onTermClick?: (term: GlossaryTerm) => void,\n onRequestEdit?: (termId: number) => void,\n onCaptureUiState?: () => void,\n onOpenMemories?: () => void,\n onViewMemoryDetail?: (id: number) => void,\n onUpdateEntryExplanation?: (\n memoryId: number,\n entryId: number,\n explanation: string,\n ) => void,\n onPopout?: () => void,\n onReattach?: () => void,\n /**\n * Called when the user clicks a provider SSO button (Google or Microsoft).\n * The controller opens a popup and handles the token handoff.\n */\n onSsoLogin?: (provider: \"google\" | \"microsoft\") => void,\n /**\n * A CSS `:host { … }` block containing --unn-* custom properties.\n * Pass the output of getShadowDomTokens() from @unnoodle/design-system\n * so the widget can consume design tokens inside its shadow root.\n */\n shadowTokens?: string,\n /** Phase 2: called when the user submits a clarification question. */\n onAskQuestion?: (contextId: number, body: string) => void,\n /** Called when an unauthenticated user clicks a write-action button (+). */\n onRequireLogin?: () => void,\n /** Called when the user submits the inline add-vocabulary form. */\n onAddConcept?: (term: string, definition: string) => void,\n /** Called when the user clicks the search icon in the home view to open the full search/terms view. */\n onOpenSearch?: () => void,\n /** Called when the user clicks a clarification card on the home view. */\n onClarificationClick?: (discussion: ContextDiscussion) => void,\n /** Called when the user submits a reply inside the clarification detail view. */\n onPostReply?: (contextId: number, questionId: number, body: string) => void,\n /** Called when the user clicks \"Add Entry\" in the memory detail view. */\n onAddEntryToMemory?: (memoryId: number) => void,\n /** Called when the user clicks to delete a product memory. */\n onDeleteMemory?: (memoryId: number) => void,\n /** Called when the user clicks to delete an entry from a memory. */\n onDeleteEntry?: (memoryId: number, entryId: number) => void,\n /** Called when the user clicks \"Show All\" in the Product Vocabulary section. */\n onShowAllConcepts?: () => void,\n /** Called when the user clicks \"Show All\" in the Clarifications section. */\n onShowAllClarifications?: () => void,\n /** Called when the user clicks \"Show All\" in the Product Memory section. */\n onShowAllMemories?: () => void,\n /** LQ-12: called when the user submits a question in the Ask view. */\n onAsk?: (question: string) => void,\n /** LQ-12: called when the user opens the Ask view from the home row. */\n onOpenAsk?: () => void,\n): PanelControls {\n const host = document.createElement(\"div\");\n host.id = \"unnoodle-panel-host\";\n host.setAttribute(\"data-testid\", \"widget-panel-host\");\n\n const shadow = host.attachShadow({ mode: \"open\" });\n\n // -------------------------------------------------------------------------\n // Styles\n // -------------------------------------------------------------------------\n const style = document.createElement(\"style\");\n style.textContent = safeCSS(PANEL_STYLES);\n\n // -------------------------------------------------------------------------\n // DOM Structure\n // -------------------------------------------------------------------------\n const panel = document.createElement(\"div\");\n panel.className = \"panel\";\n panel.setAttribute(\"role\", \"complementary\");\n panel.setAttribute(\"aria-label\", \"Unnoodle Glossary\");\n\n // Header\n const header = document.createElement(\"div\");\n header.className = \"panel-header\";\n header.innerHTML = `\n <div class=\"panel-header-brand\">\n <span class=\"panel-title\">Unnoodle</span>\n <span class=\"panel-title-sep\">·</span>\n <span class=\"panel-subtitle\">Glossary</span>\n </div>\n <div class=\"panel-header-actions\">\n <button class=\"panel-pin-left\" aria-label=\"Pin to left\" data-testid=\"widget-panel-pin-left\" title=\"Dock to left side\">\n <svg viewBox=\"0 0 256 256\" aria-hidden=\"true\"><rect x=\"32\" y=\"48\" width=\"192\" height=\"160\" rx=\"8\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"16\"/><line x1=\"88\" y1=\"48\" x2=\"88\" y2=\"208\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"16\"/></svg>\n </button>\n <button class=\"panel-pin-right active\" aria-label=\"Pin to right\" data-testid=\"widget-panel-pin-right\" title=\"Dock to right side\">\n <svg viewBox=\"0 0 256 256\" aria-hidden=\"true\"><rect x=\"32\" y=\"48\" width=\"192\" height=\"160\" rx=\"8\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"16\"/><line x1=\"88\" y1=\"48\" x2=\"88\" y2=\"208\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"16\"/></svg>\n </button>\n <div class=\"panel-header-separator\" aria-hidden=\"true\"></div>\n <button class=\"panel-half\" aria-label=\"Expand to half width\" data-testid=\"widget-panel-half\" title=\"Expand to 50% width\">\n <svg viewBox=\"0 0 256 256\" aria-hidden=\"true\"><path d=\"M200,40H56A16,16,0,0,0,40,56V200a16,16,0,0,0,16,16H200a16,16,0,0,0,16-16V56A16,16,0,0,0,200,40Zm-64,80h64v16H136Zm0-16V88h64v16Zm0,48h64v16H136Zm64-80H136V56h64ZM56,56h64V200H56ZM200,200H136V184h64v16Z\"/></svg>\n </button>\n <button class=\"panel-half-exit\" aria-label=\"Exit half width\" data-testid=\"widget-panel-half-exit\" title=\"Restore width\" hidden>\n <svg viewBox=\"0 0 256 256\" aria-hidden=\"true\"><path d=\"M200,40H56A16,16,0,0,0,40,56V200a16,16,0,0,0,16,16H200a16,16,0,0,0,16-16V56A16,16,0,0,0,200,40Zm0,160H56V56H200Z\"/></svg>\n </button>\n <button class=\"panel-fullscreen\" aria-label=\"Fullscreen\" data-testid=\"widget-panel-fullscreen\" title=\"Expand to full width\">\n <svg viewBox=\"0 0 256 256\" aria-hidden=\"true\"><path d=\"M216,48V88a8,8,0,0,1-16,0V56H168a8,8,0,0,1,0-16h40A8,8,0,0,1,216,48ZM88,200H56V168a8,8,0,0,0-16,0v40a8,8,0,0,0,8,8H88a8,8,0,0,0,0-16Zm120-40a8,8,0,0,0-8,8v32H168a8,8,0,0,0,0,16h40a8,8,0,0,0,8-8V168A8,8,0,0,0,208,160ZM88,40H48a8,8,0,0,0-8,8V88a8,8,0,0,0,16,0V56H88a8,8,0,0,0,0-16Z\"/></svg>\n </button>\n <button class=\"panel-fullscreen-exit\" aria-label=\"Exit fullscreen\" data-testid=\"widget-panel-fullscreen-exit\" title=\"Exit fullscreen\" hidden>\n <svg viewBox=\"0 0 256 256\" aria-hidden=\"true\"><path d=\"M136,40V96a8,8,0,0,0,8,8h56a8,8,0,0,0,0-16H160V40a8,8,0,0,0-16,0ZM96,152H40a8,8,0,0,0,0,16H96v56a8,8,0,0,0,16,0V160A8,8,0,0,0,96,152Zm64,0a8,8,0,0,0-8,8v56a8,8,0,0,0,16,0V168h56a8,8,0,0,0,0-16ZM96,104h56a8,8,0,0,0,0-16H112V40a8,8,0,0,0-16,0V96A8,8,0,0,0,96,104Z\"/></svg>\n </button>\n <!-- popout temporarily disabled — TODO: fix CSS vars after adoptNode -->\n <button class=\"panel-popout\" aria-label=\"Pop out panel\" data-testid=\"widget-panel-popout\" title=\"Open in separate window\" hidden>\n <svg viewBox=\"0 0 256 256\" aria-hidden=\"true\"><path d=\"M224,104a8,8,0,0,1-16,0V59.32l-66.33,66.34a8,8,0,0,1-11.32-11.32L196.68,48H152a8,8,0,0,1,0-16h64a8,8,0,0,1,8,8Zm-40,24a8,8,0,0,0-8,8v72H48V80h72a8,8,0,0,0,0-16H48A16,16,0,0,0,32,80V208a16,16,0,0,0,16,16H176a16,16,0,0,0,16-16V136A8,8,0,0,0,184,128Z\"/></svg>\n </button>\n <button class=\"panel-dock\" aria-label=\"Dock panel\" data-testid=\"widget-panel-dock\" title=\"Dock back to main window\" hidden>\n <svg viewBox=\"0 0 256 256\" aria-hidden=\"true\"><path d=\"M224,104a8,8,0,0,1-16,0V59.32l-66.33,66.34a8,8,0,0,1-11.32-11.32L196.68,48H152a8,8,0,0,1,0-16h64a8,8,0,0,1,8,8Zm-40,24a8,8,0,0,0-8,8v72H48V80h72a8,8,0,0,0,0-16H48A16,16,0,0,0,32,80V208a16,16,0,0,0,16,16H176a16,16,0,0,0,16-16V136A8,8,0,0,0,184,128Z\"/></svg>\n </button>\n <button class=\"panel-close\" aria-label=\"Close panel\" data-testid=\"widget-panel-close\">\n <svg viewBox=\"0 0 256 256\" aria-hidden=\"true\"><path d=\"M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z\"/></svg>\n </button>\n </div>\n `;\n\n // Body\n const body = document.createElement(\"div\");\n body.className = \"panel-body\";\n\n // Footer\n const footer = document.createElement(\"div\");\n footer.className = \"panel-footer\";\n footer.innerHTML = `<a href=\"https://unnoodle.com\" target=\"_blank\" rel=\"noopener\">Product knowledge powered by Unnoodle</a>`;\n\n panel.appendChild(header);\n panel.appendChild(body);\n panel.appendChild(footer);\n\n // Drag-resize handle (must sit inside the panel so position:absolute works)\n const resizeHandle = document.createElement(\"div\");\n resizeHandle.className = \"panel-resize-handle\";\n resizeHandle.setAttribute(\"data-testid\", \"widget-panel-resize-handle\");\n panel.appendChild(resizeHandle);\n\n // If the host app supplied design tokens (via getShadowDomTokens() from\n // @unnoodle/design-system), prepend them as a separate <style> so all\n // --unn-* CSS custom properties are available within this shadow root.\n // Wrap panel in shell container (shell carries the inset shadow; panel has just border + content)\n const panelShell = document.createElement(\"div\");\n panelShell.className = \"panel-shell\";\n panelShell.appendChild(panel);\n\n if (shadowTokens) {\n const tokenStyle = document.createElement(\"style\");\n tokenStyle.textContent = safeCSS(shadowTokens);\n shadow.appendChild(tokenStyle);\n }\n shadow.appendChild(style);\n\n // Add list view CSS\n const listViewStyle = document.createElement(\"style\");\n listViewStyle.textContent = safeCSS(getListViewCSS());\n shadow.appendChild(listViewStyle);\n shadow.appendChild(panelShell);\n\n // -------------------------------------------------------------------------\n // Event wiring: query layout buttons, delegate to panelLayout\n // -------------------------------------------------------------------------\n const closeBtn = header.querySelector(\".panel-close\") as HTMLButtonElement;\n const popoutBtn = header.querySelector(\".panel-popout\") as HTMLButtonElement;\n const dockBtn = header.querySelector(\".panel-dock\") as HTMLButtonElement;\n const pinLeftBtn = header.querySelector(\n \".panel-pin-left\",\n ) as HTMLButtonElement;\n const pinRightBtn = header.querySelector(\n \".panel-pin-right\",\n ) as HTMLButtonElement;\n const halfBtn = header.querySelector(\".panel-half\") as HTMLButtonElement;\n const halfExitBtn = header.querySelector(\n \".panel-half-exit\",\n ) as HTMLButtonElement;\n const fullscreenBtn = header.querySelector(\n \".panel-fullscreen\",\n ) as HTMLButtonElement;\n const fullscreenExitBtn = header.querySelector(\n \".panel-fullscreen-exit\",\n ) as HTMLButtonElement;\n\n // ---- Panel layout controller (popout, pin, resize, show/hide) -----------\n\n const _layout = createPanelLayout(\n {\n host,\n shadow,\n panelShell,\n popoutBtn,\n dockBtn,\n closeBtn,\n pinLeftBtn,\n pinRightBtn,\n halfBtn,\n halfExitBtn,\n fullscreenBtn,\n fullscreenExitBtn,\n resizeHandle,\n },\n {\n ...(onClose && { onClose }),\n ...(onPopout && { onPopout }),\n ...(onReattach && { onReattach }),\n onToast: (msg) => showToast(msg),\n ...(shadowTokens && { shadowTokens }),\n },\n );\n\n function show() {\n _layout.show();\n }\n\n function hide() {\n _layout.hide();\n }\n\n function popout() {\n _layout.popout();\n }\n\n function setLoading() {\n body.innerHTML = `\n <div class=\"skeleton-home\" data-testid=\"widget-loading\">\n <div class=\"skeleton-loading-header\">\n <div class=\"skeleton-loading-brand\">Unnoodle</div>\n <div class=\"skeleton-loading-title\">Loading knowledge for this context…</div>\n <div class=\"skeleton-loading-sub\">Helping your team understand this interface</div>\n </div>\n <div class=\"skeleton-body\">\n <div class=\"skeleton-section\">\n <div class=\"skeleton-section-head\"></div>\n <div class=\"skeleton-row\"><div class=\"skeleton-line\" style=\"width:55%;height:9px;\"></div></div>\n </div>\n <div class=\"skeleton-section\">\n <div class=\"skeleton-section-head\"></div>\n <div class=\"skeleton-row\"><div class=\"skeleton-line\" style=\"width:72%;height:9px;\"></div></div>\n <div class=\"skeleton-row\"><div class=\"skeleton-line\" style=\"width:48%;height:9px;\"></div></div>\n <div class=\"skeleton-row\"><div class=\"skeleton-line\" style=\"width:63%;height:9px;\"></div></div>\n <div class=\"skeleton-row\"><div class=\"skeleton-line\" style=\"width:38%;height:9px;\"></div></div>\n </div>\n <div class=\"skeleton-section\">\n <div class=\"skeleton-section-head\"></div>\n <div class=\"skeleton-row\"><div class=\"skeleton-line\" style=\"width:80%;height:9px;\"></div></div>\n </div>\n </div>\n </div>\n `;\n }\n\n function setError(message: string) {\n body.innerHTML = `\n <div class=\"state-center\" data-testid=\"widget-panel-error\">\n <svg class=\"state-error-icon\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"/>\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"/>\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"/>\n </svg>\n <p class=\"state-msg\">${escapeHtml(message)}</p>\n </div>\n `;\n }\n\n // ---- Panel controls (auth state) ----------------------------------------\n /** Whether a user is currently authenticated — controls ui-states action bar visibility. */\n let _isAuthenticated = false;\n\n // ---- Login view ----------------------------------------------------------\n\n function showLogin(providers?: SsoProviders) {\n renderLoginView(\n body,\n {\n onLogin,\n ...(onSsoLogin && { onSsoLogin: (p: string) => onSsoLogin(p as \"google\" | \"microsoft\") }),\n onBack: lastHomeData\n ? () => {\n const savedData = lastHomeData!;\n lastHomeData = savedData;\n showTerms(savedData);\n }\n : null,\n },\n providers,\n );\n }\n\n function setLoginLoading(loading: boolean) {\n setLoginLoadingState(body, loading);\n }\n\n function setLoginError(message: string) {\n setLoginErrorState(body, message);\n }\n\n // ---- Terms / search view -------------------------------------------------\n\n let lastHomeData: WidgetInitResponse | null = null;\n let cachedClarificationsState: {\n discussions: ContextDiscussion[];\n canPost: boolean;\n } | null = null;\n let currentClarification: ContextDiscussion | null = null;\n let activeFormController: CaptureFormController | null = null;\n\n // List view management\n let listViewManager: ListViewManager | null = null;\n let currentViewMode: \"home\" | \"list\" = \"home\";\n let currentHomeData: WidgetInitResponse | null = null;\n\n function showTerms(data: WidgetInitResponse) {\n lastHomeData = data;\n currentHomeData = data; // Store for list views\n currentViewMode = \"home\";\n renderHomeView(data);\n // Restore clarifications state immediately after re-rendering home view\n // (renderHomeView resets the section to a skeleton; re-applying the cached\n // state prevents the empty-state from disappearing on back-navigation).\n if (cachedClarificationsState) {\n loadClarifications(\n cachedClarificationsState.discussions,\n cachedClarificationsState.canPost,\n );\n }\n // Restore product memories from the init response if available\n if (data.productMemories !== undefined) {\n const limitedMemories = data.productMemories.slice(0, 5);\n showHomeMemoryItems(limitedMemories);\n }\n }\n\n function showSearchResults(terms: GlossaryTerm[], query: string) {\n renderTermsView(terms, null, terms.length, query);\n }\n\n // Show All methods - display list views for each category\n function showAllConcepts(terms: GlossaryTerm[]) {\n currentViewMode = \"list\";\n initializeListViewManager();\n if (!currentHomeData) {\n return;\n }\n listViewManager?.showAllTerms(currentHomeData, terms);\n }\n\n function showAllClarifications(\n discussions: ContextDiscussion[],\n canPost: boolean,\n ) {\n currentViewMode = \"list\";\n initializeListViewManager();\n listViewManager?.showAllClarifications(discussions, canPost);\n }\n\n function showAllMemories(\n memories: ProductMemoryResponse[],\n canPost: boolean,\n ) {\n currentViewMode = \"list\";\n initializeListViewManager();\n listViewManager?.showAllMemories(memories, canPost);\n }\n\n function initializeListViewManager() {\n if (!listViewManager) {\n const callbacks: ListViewCallbacks = {\n onTermClick: (termId) => {\n // Find term and show detail (reuse existing logic)\n const term = currentHomeData?.glossary.find((t) => t.id === termId);\n if (term && onTermClick) {\n onTermClick(term);\n }\n },\n onDiscussionClick: (discussionId) => {\n // Show clarification detail (reuse existing logic)\n if (onClarificationClick && cachedClarificationsState) {\n const discussion = cachedClarificationsState.discussions.find(\n (d) => d.id === discussionId,\n );\n if (discussion) {\n onClarificationClick(discussion);\n }\n }\n },\n onMemoryClick: (memoryId) => {\n // Show memory detail (reuse existing logic)\n if (onViewMemoryDetail) {\n onViewMemoryDetail(memoryId);\n }\n },\n onBackToHome: () => {\n // Use the main onBack callback to ensure proper section restoration\n onBack?.();\n },\n onAddTerm: () => {\n if (!_isAuthenticated) {\n onRequireLogin?.();\n return;\n }\n // In list view, find the list-view container and show form there\n const listView = body.querySelector<HTMLElement>(\n \"[data-testid='widget-terms-list-view']\",\n );\n if (listView) {\n const listHeader =\n listView.querySelector<HTMLElement>(\".list-header\");\n if (listHeader) showAddTermForm(listView, listHeader, onAddConcept);\n }\n },\n onAddDiscussion: () => {\n // Show ask question form for clarifications\n const clarSection = body.querySelector(\n '[data-section=\"clarifications\"]',\n );\n const contextId = currentHomeData?.context.id;\n if (clarSection && contextId) {\n showAskQuestionForm(clarSection as HTMLElement, contextId, onAskQuestion);\n }\n },\n onAddMemory: () => onCaptureUiState?.(),\n onRequireLogin: () => onRequireLogin?.(),\n };\n listViewManager = new ListViewManager(body, callbacks);\n }\n }\n\n function renderHomeView(data: WidgetInitResponse) {\n renderHomeViewFn(\n body,\n header.querySelector(\".panel-subtitle\"),\n data,\n {\n ...(onTermClick && { onTermClick }),\n ...(onRequireLogin && { onRequireLogin }),\n ...(onAddConcept && { onAddConcept }),\n ...(onOpenSearch && { onOpenSearch }),\n ...(onCaptureUiState && { onCaptureUiState }),\n ...(onShowAllConcepts && { onShowAllConcepts }),\n ...(onClarificationClick && { onClarificationClick }),\n ...(onShowAllClarifications && { onShowAllClarifications }),\n ...(onAskQuestion && { onAskQuestion }),\n ...(onOpenAsk && { onOpenAsk }),\n },\n _isAuthenticated,\n );\n }\n\n\n function loadClarifications(\n discussions: ContextDiscussion[],\n canPost: boolean,\n ): void {\n // Cache so we can restore after back-navigation re-renders the home view.\n cachedClarificationsState = { discussions, canPost };\n loadClarificationsView(body, discussions, canPost, {\n ...(onRequireLogin && { onRequireLogin }),\n ...(onClarificationClick && { onClarificationClick }),\n ...(onShowAllClarifications && { onShowAllClarifications }),\n ...(onAskQuestion && { onAskQuestion }),\n });\n }\n\n function renderTermsView(\n terms: GlossaryTerm[],\n contextName: string | null,\n _totalCount: number,\n activeQuery: string,\n ) {\n // Build search bar + action bar + list wrapper\n body.innerHTML = `\n <div class=\"search-bar\">\n <input class=\"search-input\" id=\"unn-search\" type=\"search\"\n placeholder=\"Search terms…\" autocomplete=\"off\"\n value=\"${escapeHtml(activeQuery)}\" aria-label=\"Search glossary terms\"\n data-testid=\"widget-glossary-search\" />\n </div>\n <div class=\"action-bar\" id=\"unn-action-bar\" style=\"display:${_isAuthenticated ? \"flex\" : \"none\"}\">\n <div class=\"action-bar-tabs\">\n <button class=\"tab-btn active\" data-testid=\"widget-glossary-tab\">Glossary</button>\n <button class=\"tab-btn\" data-testid=\"widget-ui-states-tab\">UI States</button>\n </div>\n <button class=\"capture-btn\" data-testid=\"widget-ui-state-capture-btn\"\n title=\"Capture the current page state\">\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"3\"/>\n <path d=\"M3 9a2 2 0 0 1 2-2h1l2-3h8l2 3h1a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"/>\n </svg>\n Capture\n </button>\n </div>\n <div class=\"terms-list\" id=\"unn-terms-list\" data-testid=\"widget-glossary-list\">\n ${contextName ? `<div class=\"context-label\">${escapeHtml(contextName)}</div>` : \"\"}\n ${terms.length === 0 ? renderNoResults(activeQuery) : terms.map(renderTerm).join(\"\")}\n </div>\n `;\n\n // Wire up search input (debounced)\n const searchInput = body.querySelector(\"#unn-search\") as HTMLInputElement;\n let debounceTimer: ReturnType<typeof setTimeout>;\n searchInput.addEventListener(\"input\", () => {\n clearTimeout(debounceTimer);\n debounceTimer = setTimeout(() => {\n onSearch(searchInput.value);\n }, 220);\n });\n\n // Wire up term card clicks for detail view (Phase 2)\n if (onTermClick) {\n const termsList = body.querySelector(\"#unn-terms-list\") as HTMLElement;\n termsList.addEventListener(\"click\", (e) => {\n const card = (e.target as HTMLElement).closest(\n \"[data-testid='widget-term-card']\",\n );\n if (!card) return;\n const item = card.closest(\"[data-term-id]\") as HTMLElement | null;\n if (!item) return;\n const termId = parseInt(item.getAttribute(\"data-term-id\") ?? \"-1\", 10);\n const found = terms.find((t) => t.id === termId);\n if (found) onTermClick(found);\n });\n }\n\n // Wire up capture button\n const captureBtn = body.querySelector(\n '[data-testid=\"widget-ui-state-capture-btn\"]',\n ) as HTMLButtonElement | null;\n captureBtn?.addEventListener(\"click\", () => {\n if (captureBtn.disabled) return;\n captureBtn.disabled = true;\n captureBtn.textContent = \"Capturing…\";\n onCaptureUiState?.();\n // Re-enable after a short delay (controller will show toast)\n setTimeout(() => {\n if (captureBtn) {\n captureBtn.disabled = false;\n captureBtn.innerHTML = `\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" style=\"width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2\">\n <circle cx=\"12\" cy=\"12\" r=\"3\"/>\n <path d=\"M3 9a2 2 0 0 1 2-2h1l2-3h8l2 3h1a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"/>\n </svg>\n Capture\n `;\n }\n }, 2000);\n });\n\n // Wire up UI States tab\n const uiStatesTab = body.querySelector(\n '[data-testid=\"widget-ui-states-tab\"]',\n ) as HTMLButtonElement | null;\n uiStatesTab?.addEventListener(\"click\", () => onOpenMemories?.());\n\n // Focus search so keyboard works immediately\n searchInput.focus();\n }\n\n function renderTerm(term: GlossaryTerm): string {\n const abbr = term.abbreviation\n ? `<span class=\"term-abbr\">${escapeHtml(term.abbreviation)}</span>`\n : \"\";\n const link = workspaceUrl\n ? `<a class=\"term-link\" href=\"${escapeHtml(workspaceUrl)}/glossary/${term.id}\" target=\"_blank\" rel=\"noopener\">View details →</a>`\n : \"\";\n return `\n <div class=\"term-item\" data-term-id=\"${term.id}\" data-testid=\"widget-glossary-item\">\n <div class=\"term-card\" data-testid=\"widget-term-card\">\n <div class=\"term-name\">${escapeHtml(term.term)}${abbr}</div>\n <div class=\"term-def\">${escapeHtml(term.definition)}</div>\n </div>\n ${link}\n </div>\n `;\n }\n\n function renderNoResults(query: string): string {\n return `<div class=\"no-results\" data-testid=\"widget-glossary-empty\">${query ? `No results for \"${escapeHtml(query)}\"` : \"No terms found.\"}</div>`;\n }\n\n function cleanup() {\n _layout.cleanup();\n host.remove();\n }\n\n // Phase 2: Term detail view\n function showTermDetail(\n term: GlossaryTerm,\n discussions: DiscussionPost[],\n opts?: { showEdit?: boolean },\n ): void {\n const postsHtml =\n discussions.length === 0\n ? `<div class=\"discussions-empty\" data-testid=\"widget-discussion-empty\">No comments yet. Be the first to comment!</div>`\n : discussions\n .map(\n (d) =>\n `<div class=\"discussion-post\" data-testid=\"widget-discussion-post\">${escapeHtml(d.body)}</div>`,\n )\n .join(\"\");\n\n const editBtn = opts?.showEdit\n ? `<button class=\"action-btn edit-btn\" data-testid=\"widget-edit-btn\">Edit Term</button>`\n : \"\";\n\n body.innerHTML = `\n <div class=\"term-detail-view\">\n <div class=\"detail-back\">\n <button class=\"back-btn\" data-testid=\"widget-back-btn\">← Back to list</button>\n </div>\n <div class=\"detail-content\">\n <div data-testid=\"widget-term-detail\" class=\"detail-body\">\n <h3 class=\"detail-term-name\">${escapeHtml(term.term)}</h3>\n <p class=\"detail-term-def\">${escapeHtml(term.definition)}</p>\n </div>\n </div>\n <div class=\"detail-actions\">\n <button class=\"action-btn\" data-testid=\"widget-add-comment-btn\">Add Comment</button>\n ${editBtn}\n </div>\n <div class=\"discussions-section\">\n <div class=\"discussions-heading\">Discussion</div>\n ${postsHtml}\n </div>\n </div>\n `;\n\n const backBtn = body.querySelector(\n '[data-testid=\"widget-back-btn\"]',\n ) as HTMLButtonElement;\n backBtn.addEventListener(\"click\", () => onBack?.());\n\n const addCommentBtn = body.querySelector(\n '[data-testid=\"widget-add-comment-btn\"]',\n ) as HTMLButtonElement;\n addCommentBtn.addEventListener(\"click\", () => {\n // The controller handles login-gating; we fire it as a request to show the comment form\n // We pass the termId via a custom event or directly via onAddComment with no body to request form display;\n // Instead we expose a dedicated callback; for now trigger via onAddComment(termId, \"__SHOW_FORM__\")\n // Actually: in Phase 2, the controller needs a separate onRequestComment(termId) callback.\n // Simpler: emit a data attr on the button and let the controller handle via onAddComment with sentinel\n // Cleanest: separate onRequestAddComment callback on createPanel. But to avoid adding another param,\n // reuse onAddComment with empty body — controller checks for this pattern.\n onAddComment?.(term.id, \"\");\n });\n\n if (opts?.showEdit) {\n const editBtnEl = body.querySelector(\n '[data-testid=\"widget-edit-btn\"]',\n ) as HTMLButtonElement | null;\n editBtnEl?.addEventListener(\"click\", () => {\n onRequestEdit?.(term.id);\n });\n }\n }\n\n // Phase 2: Comment form\n function showCommentForm(termId: number): void {\n body.innerHTML = `\n <div class=\"comment-form-view\">\n <div class=\"detail-back\">\n <button class=\"back-btn\" data-testid=\"widget-back-btn\">← Back</button>\n </div>\n <textarea\n class=\"comment-textarea\"\n data-testid=\"widget-comment-body\"\n placeholder=\"Share your thoughts on this term…\"\n ></textarea>\n <button class=\"comment-submit\" data-testid=\"widget-comment-submit\">Submit Comment</button>\n </div>\n `;\n\n const backBtn = body.querySelector(\n '[data-testid=\"widget-back-btn\"]',\n ) as HTMLButtonElement;\n backBtn.addEventListener(\"click\", () => onBack?.());\n\n const submitBtn = body.querySelector(\n '[data-testid=\"widget-comment-submit\"]',\n ) as HTMLButtonElement;\n const textarea = body.querySelector(\n '[data-testid=\"widget-comment-body\"]',\n ) as HTMLTextAreaElement;\n submitBtn.addEventListener(\"click\", () => {\n const body2 = textarea.value.trim();\n if (!body2) return;\n onAddComment?.(termId, body2);\n });\n }\n\n // Phase 2: Edit form\n function showEditForm(term: GlossaryTerm): void {\n body.innerHTML = `\n <div class=\"edit-form-view\">\n <div class=\"detail-back\">\n <button class=\"back-btn\" data-testid=\"widget-back-btn\">← Back</button>\n </div>\n <div>\n <label class=\"edit-label\" for=\"unn-edit-term\">Term</label>\n <input\n class=\"edit-input\"\n id=\"unn-edit-term\"\n type=\"text\"\n data-testid=\"widget-edit-term-input\"\n value=\"${escapeHtml(term.term)}\"\n />\n </div>\n <div>\n <label class=\"edit-label\" for=\"unn-edit-def\">Definition</label>\n <textarea\n class=\"edit-textarea\"\n id=\"unn-edit-def\"\n data-testid=\"widget-edit-definition-input\"\n >${escapeHtml(term.definition)}</textarea>\n </div>\n <button class=\"edit-submit\" data-testid=\"widget-edit-submit\">Save Changes</button>\n </div>\n `;\n\n const backBtn = body.querySelector(\n '[data-testid=\"widget-back-btn\"]',\n ) as HTMLButtonElement;\n backBtn.addEventListener(\"click\", () => onBack?.());\n\n const termInput = body.querySelector(\n '[data-testid=\"widget-edit-term-input\"]',\n ) as HTMLInputElement;\n const defInput = body.querySelector(\n '[data-testid=\"widget-edit-definition-input\"]',\n ) as HTMLTextAreaElement;\n const submitBtn = body.querySelector(\n '[data-testid=\"widget-edit-submit\"]',\n ) as HTMLButtonElement;\n\n submitBtn.addEventListener(\"click\", () => {\n onEditTerm?.(term.id, {\n term: termInput.value,\n definition: defInput.value,\n });\n });\n }\n\n function setCommentLoading(_loading: boolean): void {\n /* stub */\n }\n\n function setCommentError(_message: string): void {\n /* stub */\n }\n\n function setEditLoading(_loading: boolean): void {\n /* stub */\n }\n\n function setEditError(_message: string): void {\n /* stub */\n }\n\n // Phase 3: Suggested terms section\n\n function showSuggestedTerms(\n suggestions: TermSuggestion[],\n onAdd: (termName: string) => void,\n ): void {\n if (suggestions.length === 0) return;\n\n // Remove any existing suggestions section\n const existing = body.querySelector(\".suggestions-section\");\n if (existing) existing.remove();\n\n const termsList = body.querySelector(\".terms-list\");\n if (!termsList) return;\n\n const section = document.createElement(\"div\");\n section.className = \"suggestions-section\";\n section.innerHTML = `\n <div class=\"suggestions-heading\" data-testid=\"widget-suggestions-heading\">\n Suggested Terms\n </div>\n ${suggestions\n .map(\n (s) => `\n <div class=\"suggestion-item\" data-testid=\"widget-suggestion-item\">\n <div class=\"suggestion-info\">\n <span class=\"suggestion-term\">${escapeHtml(s.term)}</span>\n <span class=\"suggestion-count\">mentioned ${s.count}×</span>\n </div>\n <button\n class=\"suggestion-add\"\n data-testid=\"widget-suggestion-add\"\n data-term=\"${escapeHtml(s.term)}\"\n >+ Add</button>\n </div>`,\n )\n .join(\"\")}\n `;\n\n // Wire click handlers\n section.querySelectorAll(\".suggestion-add\").forEach((btn) => {\n btn.addEventListener(\"click\", () => {\n const termName = (btn as HTMLElement).dataset.term ?? \"\";\n onAdd(termName);\n });\n });\n\n termsList.after(section);\n }\n\n // Phase 3: AI definition modal\n\n function showAiModal(\n term: string,\n definition: string,\n onSubmit: (editedDefinition: string) => void,\n onCancel: () => void,\n ): void {\n // Remove any existing modal\n panel.querySelector(\".ai-modal-overlay\")?.remove();\n\n const overlay = document.createElement(\"div\");\n overlay.className = \"ai-modal-overlay\";\n overlay.setAttribute(\"data-testid\", \"widget-ai-modal\");\n overlay.innerHTML = `\n <div class=\"ai-modal-title\">AI Generated Definition</div>\n <div class=\"ai-modal-term\">${escapeHtml(term)}</div>\n <div>\n <label class=\"ai-modal-label\" for=\"unn-ai-def\">Review &amp; edit the definition:</label>\n <textarea\n class=\"ai-modal-textarea\"\n id=\"unn-ai-def\"\n data-testid=\"widget-ai-definition\"\n maxlength=\"500\"\n >${escapeHtml(definition)}</textarea>\n <div class=\"ai-modal-char-count\" id=\"unn-ai-char\">0 / 500</div>\n </div>\n <div class=\"ai-modal-actions\">\n <button class=\"ai-modal-cancel\" data-testid=\"widget-ai-cancel\">Cancel</button>\n <button class=\"ai-modal-submit\" data-testid=\"widget-ai-submit\">Submit for Approval</button>\n </div>\n `;\n\n const textarea = overlay.querySelector(\n '[data-testid=\"widget-ai-definition\"]',\n ) as HTMLTextAreaElement;\n const charCount = overlay.querySelector(\"#unn-ai-char\") as HTMLElement;\n\n const updateCount = () => {\n charCount.textContent = `${textarea.value.length} / 500`;\n };\n textarea.addEventListener(\"input\", updateCount);\n updateCount();\n\n const submitBtn = overlay.querySelector(\n '[data-testid=\"widget-ai-submit\"]',\n ) as HTMLButtonElement;\n submitBtn.addEventListener(\"click\", () => {\n onSubmit(textarea.value);\n });\n\n const cancelBtn = overlay.querySelector(\n '[data-testid=\"widget-ai-cancel\"]',\n ) as HTMLButtonElement;\n cancelBtn.addEventListener(\"click\", () => {\n overlay.remove();\n onCancel();\n });\n\n panel.appendChild(overlay);\n }\n\n function setAiModalLoading(loading: boolean): void {\n const btn = panel.querySelector(\n '[data-testid=\"widget-ai-submit\"]',\n ) as HTMLButtonElement | null;\n if (!btn) return;\n btn.disabled = loading;\n btn.textContent = loading ? \"Submitting…\" : \"Submit for Approval\";\n }\n\n // Phase 3: Toast notification\n\n function showToast(message: string): void {\n // Remove any previous toast\n panel.querySelector(\".toast\")?.remove();\n\n const toast = document.createElement(\"div\");\n toast.className = \"toast\";\n toast.setAttribute(\"data-testid\", \"widget-toast\");\n toast.textContent = message;\n panel.appendChild(toast);\n\n setTimeout(() => toast.remove(), 4000);\n }\n\n // UI States: auth state — controls action bar visibility\n\n function setAuthenticated(auth: boolean): void {\n _isAuthenticated = auth;\n const bar = body.querySelector(\"#unn-action-bar\") as HTMLElement | null;\n if (bar) bar.style.display = auth ? \"flex\" : \"none\";\n }\n\n // Product Memories: list view\n\n function showMemoriesList(\n memories: ProductMemoryResponse[],\n page: number,\n hasMore: boolean,\n append = false,\n ): void {\n if (!append) {\n body.innerHTML = `\n <div class=\"action-bar\" id=\"unn-action-bar\" style=\"display:flex\">\n <div class=\"action-bar-tabs\">\n <button class=\"tab-btn\" data-testid=\"widget-glossary-tab\">Glossary</button>\n <button class=\"tab-btn active\" data-testid=\"widget-ui-states-tab\">Captures</button>\n </div>\n <button class=\"capture-btn\" data-testid=\"widget-ui-state-capture-btn\"\n title=\"Capture the current page state\">\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" style=\"width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2\">\n <circle cx=\"12\" cy=\"12\" r=\"3\"/>\n <path d=\"M3 9a2 2 0 0 1 2-2h1l2-3h8l2 3h1a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"/>\n </svg>\n Capture\n </button>\n </div>\n <div class=\"ui-states-list\" id=\"unn-ui-states-list\" data-testid=\"widget-ui-states-list\"></div>\n `;\n\n // Wire Glossary tab → back to terms\n const glossaryTab = body.querySelector(\n '[data-testid=\"widget-glossary-tab\"]',\n ) as HTMLButtonElement | null;\n glossaryTab?.addEventListener(\"click\", () => onBack?.());\n\n // Wire capture btn\n const captureBtn = body.querySelector(\n '[data-testid=\"widget-ui-state-capture-btn\"]',\n ) as HTMLButtonElement | null;\n captureBtn?.addEventListener(\"click\", () => {\n if (captureBtn.disabled) return;\n captureBtn.disabled = true;\n captureBtn.textContent = \"Capturing…\";\n onCaptureUiState?.();\n setTimeout(() => {\n if (captureBtn) {\n captureBtn.disabled = false;\n captureBtn.innerHTML = `\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" style=\"width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2\">\n <circle cx=\"12\" cy=\"12\" r=\"3\"/>\n <path d=\"M3 9a2 2 0 0 1 2-2h1l2-3h8l2 3h1a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"/>\n </svg>\n Capture\n `;\n }\n }, 2000);\n });\n }\n\n const listContainer = body.querySelector(\n \"#unn-ui-states-list\",\n ) as HTMLElement | null;\n if (!listContainer) return;\n\n // Remove the load more button if it exists (will be re-added below if needed)\n body.querySelector(\".load-more-container\")?.remove();\n\n if (memories.length === 0 && !append) {\n listContainer.innerHTML = `\n <div class=\"ui-states-empty\" data-testid=\"widget-ui-states-empty\">\n <svg class=\"ui-states-empty-icon\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" aria-hidden=\"true\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/>\n <path d=\"M9 9h6M9 12h6M9 15h4\"/>\n </svg>\n <p class=\"ui-states-empty-text\">\n No captures yet.<br/>\n Click <strong>Capture</strong> to snapshot an element.\n </p>\n </div>\n `;\n return;\n }\n\n // Render memory items\n const itemsHtml = memories.map((m) => renderMemoryItem(m)).join(\"\");\n listContainer.insertAdjacentHTML(\"beforeend\", itemsHtml);\n\n // Wire view detail clicks\n listContainer\n .querySelectorAll('[data-testid=\"widget-ui-state-detail-btn\"]')\n .forEach((btn) => {\n const id = parseInt((btn as HTMLElement).dataset.stateId ?? \"-1\", 10);\n btn.addEventListener(\"click\", () => {\n if (!isNaN(id)) onViewMemoryDetail?.(id);\n });\n });\n\n // Load more button\n if (hasMore) {\n const loadMoreContainer = document.createElement(\"div\");\n loadMoreContainer.className = \"load-more-container\";\n loadMoreContainer.innerHTML = `\n <button class=\"load-more-btn\" data-testid=\"widget-ui-states-load-more\"\n data-page=\"${page + 1}\">\n Load more\n </button>\n `;\n loadMoreContainer\n .querySelector('[data-testid=\"widget-ui-states-load-more\"]')\n ?.addEventListener(\"click\", () => onOpenMemories?.());\n body.appendChild(loadMoreContainer);\n }\n }\n\n function renderMemoryItem(memory: ProductMemoryResponse): string {\n const timeAgo = formatTimeAgo(memory.updatedAt);\n const count = memory.entryCount;\n\n return `\n <div class=\"ui-state-item\" data-testid=\"widget-ui-state-item\" data-state-id=\"${memory.id}\">\n <div class=\"ui-state-url\" title=\"${escapeHtml(memory.title)}\">${escapeHtml(memory.title)}</div>\n <div class=\"ui-state-meta\">\n <span>${escapeHtml(timeAgo)}</span>\n <span class=\"ui-state-role-badge\">${count} ${count === 1 ? \"entry\" : \"entries\"}</span>\n </div>\n <div class=\"ui-state-actions\">\n <button class=\"view-detail-btn\"\n data-testid=\"widget-ui-state-detail-btn\"\n data-state-id=\"${memory.id}\">\n View Details\n </button>\n </div>\n </div>\n `;\n }\n\n // UI States: detail view\n\n function showMemoryDetail(memory: ProductMemoryDetailResponse): void {\n const entriesHtml = memory.entries\n .map((entry, idx) => {\n const timeAgo = formatTimeAgo(entry.capturedAt);\n const roleLabel = escapeHtml(entry.capturedByRole ?? \"\");\n return `\n <div class=\"pm-entry\" data-entry-id=\"${entry.id}\">\n <div class=\"detail-meta-section\">\n <div class=\"detail-meta-row\">\n <span>${escapeHtml(timeAgo)}</span>\n ${roleLabel ? `<span class=\"ui-state-role-badge\">${roleLabel}</span>` : \"\"}\n ${entry.capturedByName ? `<span>${escapeHtml(entry.capturedByName)}</span>` : \"\"}\n </div>\n </div>\n ${entry.snapshotHtml ? `<div class=\"ui-state-snapshot-preview\" data-testid=\"widget-ui-state-snapshot-preview-${entry.id}\"></div>` : \"\"}\n <div class=\"product-memory-section\" data-testid=\"widget-product-memory-section-${entry.id}\">\n <div class=\"product-memory-heading\">Entry ${idx + 1} · Explanation</div>\n ${\n entry.explanation\n ? `\n <div class=\"product-memory-read-mode\" data-testid=\"widget-product-memory-read\">\n <div class=\"product-memory-text\" data-testid=\"widget-product-memory-text\">${escapeHtml(entry.explanation)}</div>\n <div class=\"product-memory-actions\">\n <button class=\"product-memory-edit-btn\" data-testid=\"widget-product-memory-edit-btn\">Edit</button>\n <button class=\"product-memory-delete-entry-btn\" data-testid=\"widget-product-memory-delete-entry-btn\" data-entry-id=\"${entry.id}\" title=\"Delete Entry\">🗑</button>\n </div>\n </div>\n <div class=\"product-memory-write-mode\" data-testid=\"widget-product-memory-write\" style=\"display:none\">\n <textarea class=\"product-memory-textarea\" data-testid=\"widget-product-memory-textarea\"\n placeholder=\"Describe what this snapshot represents…\"\n maxlength=\"2000\">${escapeHtml(entry.explanation)}</textarea>\n <div class=\"product-memory-actions\">\n <button class=\"product-memory-cancel-btn\" data-testid=\"widget-product-memory-cancel-btn\">Cancel</button>\n <button class=\"product-memory-save-btn\" data-testid=\"widget-product-memory-save-btn\">Save</button>\n </div>\n </div>`\n : `\n <div class=\"product-memory-write-mode\" data-testid=\"widget-product-memory-write\">\n <textarea class=\"product-memory-textarea\" data-testid=\"widget-product-memory-textarea\"\n placeholder=\"Describe what this snapshot represents…\"\n maxlength=\"2000\"></textarea>\n <div class=\"product-memory-actions\">\n <button class=\"product-memory-save-btn\" data-testid=\"widget-product-memory-save-btn\">Add Explanation</button>\n </div>\n </div>`\n }\n </div>\n </div>\n `;\n })\n .join('<hr class=\"pm-entry-divider\">');\n\n body.innerHTML = `\n <div class=\"ui-state-detail-view\" data-testid=\"widget-ui-state-detail\">\n <div class=\"detail-back\">\n <button class=\"back-btn\" data-testid=\"widget-ui-state-back-btn\">← Captures</button>\n </div>\n <div class=\"detail-page-title\">${escapeHtml(memory.title)}</div>\n ${\n memory.entries.length === 0\n ? `<div class=\"ui-states-empty\" data-testid=\"widget-ui-states-empty\">\n <p class=\"ui-states-empty-text\">No entries yet. Capture an element to get started.</p>\n </div>`\n : entriesHtml\n }\n <div class=\"detail-actions\">\n <button class=\"detail-delete-btn\" data-testid=\"widget-delete-memory-btn\" data-memory-id=\"${memory.id}\">\n Delete Memory\n </button>\n <button class=\"detail-add-btn\" data-testid=\"widget-add-entry-btn\">\n + Add Entry\n </button>\n </div>\n </div>\n `;\n\n // Inject sanitized snapshot HTML for each entry\n memory.entries.forEach((entry) => {\n if (!entry.snapshotHtml) return;\n const preview = body.querySelector(\n `[data-testid=\"widget-ui-state-snapshot-preview-${entry.id}\"]`,\n ) as HTMLElement | null;\n if (preview) preview.innerHTML = entry.snapshotHtml;\n });\n\n // Wire back button → context-aware navigation (home or Show All list)\n body\n .querySelector('[data-testid=\"widget-ui-state-back-btn\"]')\n ?.addEventListener(\"click\", () => onBack?.());\n\n // Wire add-entry button → start a new capture targeting this memory\n body\n .querySelector('[data-testid=\"widget-add-entry-btn\"]')\n ?.addEventListener(\"click\", () => onAddEntryToMemory?.(memory.id));\n\n // Wire explanation edit/save per entry\n memory.entries.forEach((entry) => {\n const section = body.querySelector(\n `[data-testid=\"widget-product-memory-section-${entry.id}\"]`,\n ) as HTMLElement | null;\n if (!section) return;\n\n const readMode = section.querySelector(\n '[data-testid=\"widget-product-memory-read\"]',\n ) as HTMLElement | null;\n const writeMode = section.querySelector(\n '[data-testid=\"widget-product-memory-write\"]',\n ) as HTMLElement | null;\n const textarea = section.querySelector(\n '[data-testid=\"widget-product-memory-textarea\"]',\n ) as HTMLTextAreaElement | null;\n const saveBtn = section.querySelector(\n '[data-testid=\"widget-product-memory-save-btn\"]',\n ) as HTMLButtonElement | null;\n const editBtn = section.querySelector(\n '[data-testid=\"widget-product-memory-edit-btn\"]',\n ) as HTMLButtonElement | null;\n const cancelBtn = section.querySelector(\n '[data-testid=\"widget-product-memory-cancel-btn\"]',\n ) as HTMLButtonElement | null;\n\n editBtn?.addEventListener(\"click\", () => {\n if (readMode) readMode.style.display = \"none\";\n if (writeMode) writeMode.style.display = \"\";\n textarea?.focus();\n });\n\n cancelBtn?.addEventListener(\"click\", () => {\n if (writeMode) writeMode.style.display = \"none\";\n if (readMode) readMode.style.display = \"\";\n });\n\n saveBtn?.addEventListener(\"click\", () => {\n const explanation = textarea?.value.trim() ?? \"\";\n if (!explanation) return;\n if (saveBtn) {\n saveBtn.disabled = true;\n saveBtn.textContent = \"Saving…\";\n }\n onUpdateEntryExplanation?.(memory.id, entry.id, explanation);\n });\n });\n\n // Wire delete entry buttons\n memory.entries.forEach((entry) => {\n const deleteBtn = body.querySelector(\n `[data-testid=\"widget-product-memory-delete-entry-btn\"][data-entry-id=\"${entry.id}\"]`,\n ) as HTMLButtonElement | null;\n\n deleteBtn?.addEventListener(\"click\", (e) => {\n e.preventDefault();\n const confirmed = confirm(\n \"Are you sure you want to delete this entry? This action cannot be undone.\",\n );\n if (confirmed) {\n onDeleteEntry?.(memory.id, entry.id);\n }\n });\n });\n\n // Wire delete memory button\n const deleteMemoryBtn = body.querySelector(\n '[data-testid=\"widget-delete-memory-btn\"]',\n ) as HTMLButtonElement | null;\n\n deleteMemoryBtn?.addEventListener(\"click\", (e) => {\n e.preventDefault();\n const confirmed = confirm(\n `Are you sure you want to delete \"${memory.title}\"? This will delete all entries and cannot be undone.`,\n );\n if (confirmed) {\n onDeleteMemory?.(memory.id);\n }\n });\n }\n\n // ── Utility helpers ────────────────────────────────────────────────────────\n\n function formatTimeAgo(isoString: string): string {\n try {\n const diff = Math.floor(\n (Date.now() - new Date(isoString).getTime()) / 1000,\n );\n if (diff < 60) return \"just now\";\n if (diff < 3600) return `${Math.floor(diff / 60)}m ago`;\n if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`;\n if (diff < 604800) return `${Math.floor(diff / 86400)}d ago`;\n return new Date(isoString).toLocaleDateString();\n } catch {\n return \"unknown time\";\n }\n }\n\n function safeHostname(url: string): string {\n try {\n const u = new URL(url);\n return u.hostname + u.pathname;\n } catch {\n return url.slice(0, 60);\n }\n }\n\n // ── Capture form methods ─────────────────────────────────────────────\n\n function showNewMemoryForm(\n onPickElement: () => void,\n onCancelCapture: () => void,\n onSave: (\n title: string,\n explanation: string,\n watchForChanges: boolean,\n ) => void,\n onCancel: () => void,\n ): void {\n console.log(\"[unnoodle] showNewMemoryForm called\");\n\n // Use the body variable that's already available in this scope\n // instead of trying to query for it within host\n const bodyEl = body;\n console.log(\"[unnoodle] Using body element:\", bodyEl);\n\n if (!bodyEl) {\n console.log(\"[unnoodle] No body element available, returning early\");\n return;\n }\n\n console.log(\"[unnoodle] Creating capture form...\");\n const { element, controller } = createCaptureForm(\n { onPickElement, onCancelCapture, onSave, onCancel },\n { showTitle: true },\n );\n\n console.log(\"[unnoodle] Capture form created:\", element);\n activeFormController = controller;\n\n console.log(\"[unnoodle] Clearing bodyEl and appending form...\");\n bodyEl.innerHTML = \"\";\n bodyEl.appendChild(element);\n console.log(\n \"[unnoodle] Form appended successfully, bodyEl.innerHTML length is now:\",\n bodyEl.innerHTML.length,\n );\n }\n\n function showAddEntryForm(\n memoryTitle: string,\n onPickElement: () => void,\n onCancelCapture: () => void,\n onSave: (explanation: string) => void,\n onCancel: () => void,\n ): void {\n // Use the body variable that's already available in this scope\n const bodyEl = body;\n if (!bodyEl) return;\n\n const { element, controller } = createCaptureForm(\n {\n onPickElement,\n onCancelCapture,\n onSave: (_title: string, explanation: string) => {\n onSave(explanation);\n },\n onCancel: () => {\n onCancel();\n },\n },\n {\n showTitle: false,\n headerText: memoryTitle,\n subheaderText: \"Add new entry\",\n },\n );\n\n activeFormController = controller;\n bodyEl.innerHTML = \"\";\n bodyEl.appendChild(element);\n }\n\n function updateFormSnapshot(snapshot: ElementSnapshot): void {\n if (activeFormController) {\n activeFormController.setSnapshot(snapshot);\n }\n }\n\n function setFormPickingMode(picking: boolean): void {\n if (activeFormController) {\n activeFormController.setPickingMode(picking);\n }\n }\n\n function showStateChangeNotification(\n inferredMeaning: string | null,\n onSave: () => void,\n onDismiss: () => void,\n ): void {\n showStateChangeBanner(body, inferredMeaning, onSave, onDismiss);\n }\n\n function hideStateChangeNotification(): void {\n hideStateChangeBanner(body);\n }\n\n // ---- Ask view (LQ-12) ----------------------------------------------------\n // Rebuilt whenever the view is (re-)opened: `body.innerHTML` is replaced by\n // every other view, so a cached controller would hold detached nodes.\n let askView: AskViewControls | null = null;\n\n function ensureAskView(): AskViewControls {\n if (!askView) {\n askView = createAskView(\n body,\n {\n onAsk: (question: string) => onAsk?.(question),\n onOpenMemory: (memoryId: number) => onViewMemoryDetail?.(memoryId),\n onBack: () => onBack?.(),\n },\n escapeHtml,\n );\n }\n return askView;\n }\n\n function showAsk(status: AskStatus | null): void {\n currentViewMode = \"list\";\n ensureAskView().render(status);\n }\n\n function setAskLoading(): void {\n ensureAskView().setLoading();\n }\n\n function clearAskLoading(): void {\n ensureAskView().clearLoading();\n }\n\n function showAskAnswer(answer: AskAnswer): void {\n ensureAskView().showAnswer(answer);\n }\n\n function showAskError(message: string, retryable: boolean): void {\n ensureAskView().showError(message, retryable);\n }\n\n return {\n element: host,\n show,\n hide,\n showLogin,\n setLoginLoading,\n setLoginError,\n setLoading,\n showTerms,\n showSearchResults,\n setError,\n showTermDetail,\n showCommentForm,\n showEditForm,\n setCommentLoading,\n setCommentError,\n setEditLoading,\n setEditError,\n showSuggestedTerms,\n showAiModal,\n setAiModalLoading,\n showToast,\n setAuthenticated,\n showMemoriesList,\n showMemoryDetail,\n cleanup,\n popout,\n loadClarifications,\n showClarificationDetail,\n enterPickMode,\n showCaptureDescribe,\n setCaptureLoading,\n setCaptureError,\n exitCaptureMode,\n restoreHomeView,\n showHomeMemoryItems,\n showAllConcepts,\n showAllClarifications,\n showAllMemories,\n showNewMemoryForm,\n showAddEntryForm,\n updateFormSnapshot,\n setFormPickingMode,\n showStateChangeNotification,\n hideStateChangeNotification,\n showAsk,\n setAskLoading,\n clearAskLoading,\n showAskAnswer,\n showAskError,\n };\n\n // ---- Clarification detail view -------------------------------------------\n\n function showClarificationDetail(\n discussion: ContextDiscussion,\n canReply: boolean,\n ): void {\n currentClarification = discussion;\n renderClarificationDetailView(body, discussion, canReply, {\n onBack: () => onBack?.(),\n ...(onPostReply && { onPostReply }),\n });\n }\n\n // ---- Capture mode UI methods --------------------------------------------\n\n function getStripEl() {\n return body.querySelector<HTMLElement>(\n '[data-testid=\"widget-context-strip\"]',\n );\n }\n\n function enterPickMode(onCancel: () => void): void {\n const strip = getStripEl();\n if (!strip) return;\n enterPickModeView(strip, onCancel);\n }\n\n function showCaptureDescribe(\n snapshot: ElementSnapshot,\n onSave: (description: string) => void,\n onPickAgain: () => void,\n ): void {\n const strip = getStripEl();\n if (!strip) return;\n showCaptureDescribeView(strip, snapshot, onSave, onPickAgain);\n }\n\n function setCaptureLoading(loading: boolean): void {\n const strip = getStripEl();\n if (!strip) return;\n setCaptureLoadingState(strip, loading);\n }\n\n function setCaptureError(message: string): void {\n const strip = getStripEl();\n if (!strip) return;\n setCaptureErrorState(strip, message);\n }\n\n function exitCaptureMode(): void {\n const strip = getStripEl();\n if (!strip) return;\n exitCaptureModeView(strip);\n }\n\n function restoreHomeView(data: any): void {\n console.log(\"[unnoodle] restoreHomeView called with data:\", data);\n showTerms(data);\n }\n\n // ---- Home product-memory list -----------------------------------------\n\n function showHomeMemoryItems(memories: ProductMemoryResponse[]): void {\n const section = body.querySelector<HTMLElement>('[data-section=\"memory\"]');\n if (!section) return;\n\n // Remove previous items / empty-state / show-all button (keep header + helper divs)\n section\n .querySelectorAll(\n \".memory-item, .section-empty, .home-show-more-memories\",\n )\n .forEach((el) => el.remove());\n\n if (memories.length === 0) {\n const empty = document.createElement(\"div\");\n empty.className = \"section-empty\";\n empty.innerHTML = `\n <div class=\"section-empty-title\">No captures yet.</div>\n <div class=\"section-empty-text\">Capture elements on this screen so teammates can understand the interface faster.</div>\n <button class=\"section-empty-action\" data-testid=\"widget-add-ui-meaning-empty\">Add Capture</button>\n `;\n empty\n .querySelector('[data-testid=\"widget-add-ui-meaning-empty\"]')\n ?.addEventListener(\"click\", () => {\n onCaptureUiState?.();\n });\n section.appendChild(empty);\n return;\n }\n\n for (const m of memories.slice(0, MAX_HOME_ITEMS)) {\n // Limit to MAX_HOME_ITEMS on home view\n const item = document.createElement(\"div\");\n item.className = \"memory-item\";\n item.setAttribute(\"data-testid\", \"widget-memory-item\");\n item.setAttribute(\"data-ui-state-id\", String(m.id));\n const title = escapeHtml(m.title);\n const date = formatTimeAgo(m.updatedAt);\n const count = m.entryCount;\n item.innerHTML = `\n <div class=\"memory-item-content\">\n <div class=\"memory-item-title\">${title}</div>\n <div class=\"memory-item-meta\">${date} · ${count} ${count === 1 ? \"entry\" : \"entries\"}</div>\n </div>\n <span class=\"concept-chevron\"><svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><polyline points=\"9 18 15 12 9 6\"/></svg></span>\n `;\n item.addEventListener(\"click\", () => {\n onViewMemoryDetail?.(m.id);\n });\n section.appendChild(item);\n }\n\n if (memories.length > MAX_HOME_ITEMS) {\n const showAllBtn = document.createElement(\"a\");\n showAllBtn.className = \"home-show-more home-show-more-memories\";\n showAllBtn.setAttribute(\"data-testid\", \"widget-show-all-memories\");\n showAllBtn.setAttribute(\"href\", \"#\");\n showAllBtn.textContent = `Show all ${memories.length} memories →`;\n showAllBtn.addEventListener(\"click\", (e) => {\n e.preventDefault();\n onShowAllMemories?.();\n });\n section.appendChild(showAllBtn);\n }\n }\n}\n","// Unnoodle Rail CSS (exported as string)\nexport const railStyles = `\n:host {\n all: initial;\n}\n/* Rail shell — fixed to right edge, pushes body content like panel-shell */\n.rail-shell {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 34px;\n z-index: 2147483647;\n display: flex;\n flex-direction: column;\n padding: 3px;\n background: var(--unn-color-bg-secondary, #f5f5f7);\n border-left: 0.5px solid var(--unn-color-border-default, #e0e0e0);\n box-shadow: inset 6px 0 12px rgba(0,0,0,0.06), inset -4px 0 10px rgba(0,0,0,0.04), inset 0 6px 12px rgba(0,0,0,0.06), inset 0 -4px 10px rgba(0,0,0,0.04);\n transition: width 0.28s cubic-bezier(0.4,0,0.2,1);\n box-sizing: border-box;\n}\n.rail {\n flex: 1;\n width: 100%;\n background: linear-gradient(160deg, #2c3440 0%, #1a1f27 100%);\n box-shadow:\n 0 1px 2px rgba(0,0,0,0.30),\n 0 3px 8px rgba(0,0,0,0.38),\n 0 8px 20px rgba(0,0,0,0.22),\n 0 1px 0 rgba(255,255,255,0.06) inset;\n border-radius: 6px;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n box-sizing: border-box;\n overflow: hidden;\n}\n.rail-section {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding-top: 16px;\n padding-bottom: 16px;\n}\n.rail-identity {\n margin-bottom: 18px;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n.rail-avatar {\n width: 28px;\n height: 28px;\n border-radius: 50%;\n background: linear-gradient(160deg, #2c3440 0%, #1a1f27 100%);\n color: #fff;\n font-family: var(--unn-font-family, system-ui, sans-serif);\n font-size: 11px;\n font-weight: 700;\n letter-spacing: 0.5px;\n display: flex;\n align-items: center;\n justify-content: center;\n text-shadow: 0 1px 3px rgba(0,0,0,0.65), 0 -1px 0 rgba(255,255,255,0.10);\n user-select: none;\n}\n.rail-avatar--icon {\n background: none;\n width: auto;\n height: auto;\n}\n.rail-core {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 14px;\n}\n.rail-item {\n width: 100%;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: none;\n cursor: pointer;\n outline: none;\n padding: 0;\n position: relative;\n transition: background 120ms;\n}\n.rail-item.active {\n background: rgba(255,255,255,0.10);\n}\n.rail-item .icon {\n width: 18px;\n height: 18px;\n display: block;\n transition: transform 120ms, opacity 120ms;\n fill: #ffffff;\n opacity: 0.65;\n}\n.rail-item.active .icon {\n opacity: 1;\n}\n.rail-item:hover .icon {\n transform: scale(1.05);\n opacity: 1;\n}\n.rail-item .label {\n display: none !important;\n}\n\n/* Tooltip styles for rail icons */\n.rail-tooltip {\n position: absolute;\n left: 110%;\n top: 50%;\n transform: translateY(-50%);\n background: #222;\n color: #fff;\n font-size: 13px;\n font-family: var(--unn-font-family, system-ui, sans-serif);\n padding: 4px 10px;\n border-radius: 4px;\n white-space: nowrap;\n box-shadow: 0 2px 8px rgba(0,0,0,0.18);\n opacity: 0;\n pointer-events: none;\n z-index: 10;\n transition: opacity 0.08s;\n}\n.rail-item:hover .rail-tooltip {\n opacity: 1;\n pointer-events: auto;\n}\n.rail-auth-btn {\n position: relative;\n}\n.rail-auth-btn .rail-tooltip {\n position: absolute;\n left: 110%;\n top: 50%;\n transform: translateY(-50%);\n background: #222;\n color: #fff;\n font-size: 13px;\n font-family: var(--unn-font-family, system-ui, sans-serif);\n padding: 4px 10px;\n border-radius: 4px;\n white-space: nowrap;\n box-shadow: 0 2px 8px rgba(0,0,0,0.18);\n opacity: 0;\n pointer-events: none;\n z-index: 10;\n transition: opacity 0.08s;\n}\n.rail-auth-btn:hover .rail-tooltip {\n opacity: 1;\n pointer-events: auto;\n}\n .rail-glow {\n position: absolute;\n left: 2px;\n top: 50%;\n transform: translateY(-50%);\n width: 28px;\n height: 28px;\n border-radius: 50%;\n background: radial-gradient(circle, #fff 0%, #fff 80%, transparent 100%);\n opacity: 0.55;\n filter: blur(4px);\n z-index: 0;\n pointer-events: none;\n animation: rail-glow-pulse 2s infinite alternate;\n display: none;\n }\n .rail-glow.active {\n display: block;\n }\n@keyframes rail-glow-pulse {\n 0% { opacity: 0.35; }\n 100% { opacity: 0.6; }\n}\n\n.rail-auth {\n margin-bottom: 12px;\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n.rail-auth-btn {\n width: 100%;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: none;\n cursor: pointer;\n outline: none;\n padding: 0;\n font-family: var(--unn-font-family, system-ui, sans-serif);\n font-size: 14px;\n font-weight: 400;\n color: #222;\n transition: background 120ms;\n}\n .rail-auth-btn .icon {\n width: 18px;\n height: 18px;\n display: block;\n transition: transform 120ms;\n fill: #ffffff;\n }\n .rail-auth-btn:hover .icon {\n transform: scale(1.05);\n }\n .rail-auth-btn .label {\n opacity: 0;\n margin-left: 16px;\n font-size: 14px;\n font-weight: 400;\n color: #fff;\n white-space: nowrap;\n pointer-events: none;\n transition: opacity 150ms;\n }\n .rail:hover .rail-auth-btn .label {\n opacity: 1;\n pointer-events: auto;\n }\n`;\n","// Top section: user initials avatar (falls back to generic icon)\nexport function createRailIdentity(initials: string | null): HTMLElement {\n const root = document.createElement(\"div\");\n root.className = \"rail-identity rail-section\";\n\n if (initials) {\n const avatar = document.createElement(\"div\");\n avatar.className = \"rail-avatar\";\n avatar.textContent = initials;\n avatar.style.position = \"relative\";\n const tooltip = document.createElement(\"span\");\n tooltip.className = \"rail-tooltip\";\n tooltip.textContent = \"Profile\";\n avatar.appendChild(tooltip);\n root.appendChild(avatar);\n } else {\n const btn = document.createElement(\"button\");\n btn.className = \"rail-item\";\n btn.type = \"button\";\n btn.tabIndex = 0;\n btn.innerHTML = `<svg class=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" fill=\"#ffffff\" viewBox=\"0 0 256 256\"><path d=\"M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24ZM74.08,197.5a64,64,0,0,1,107.84,0,87.83,87.83,0,0,1-107.84,0ZM96,120a32,32,0,1,1,32,32A32,32,0,0,1,96,120Zm97.76,66.41a79.66,79.66,0,0,0-36.06-28.75,48,48,0,1,0-59.4,0,79.66,79.66,0,0,0-36.06,28.75,88,88,0,1,1,131.52,0Z\"></path></svg>`;\n const tooltip = document.createElement(\"span\");\n tooltip.className = \"rail-tooltip\";\n tooltip.textContent = \"Profile\";\n btn.appendChild(tooltip);\n root.appendChild(btn);\n }\n\n return root;\n}\n","// Middle section: Overview, Memory, Vocabulary, Clarifications\nexport interface RailCoreActionsCallbacks {\n onOverview: () => void;\n onMemory: () => void;\n onVocabulary: () => void;\n onClarifications: () => void;\n}\n\nexport function createRailCoreActions(\n state: { activeSection: string | null; hasMemoryGlow: boolean },\n cb: RailCoreActionsCallbacks,\n): HTMLElement {\n const root = document.createElement(\"div\");\n root.className = \"rail-core rail-section\";\n\n // Official Phosphor Regular SVGs (18×18, white fill)\n const icons = {\n house: `<svg class=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" fill=\"#ffffff\" viewBox=\"0 0 256 256\"><path d=\"M240,208H224V136l2.34,2.34A8,8,0,0,0,237.66,127L139.31,28.68a16,16,0,0,0-22.62,0L18.34,127a8,8,0,0,0,11.32,11.31L32,136v72H16a8,8,0,0,0,0,16H240a8,8,0,0,0,0-16ZM48,120l80-80,80,80v88H160V152a8,8,0,0,0-8-8H104a8,8,0,0,0-8,8v56H48Zm96,88H112V160h32Z\"></path></svg>`,\n brain: `<svg class=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" fill=\"#ffffff\" viewBox=\"0 0 256 256\"><path d=\"M248,124a56.11,56.11,0,0,0-32-50.61V72a48,48,0,0,0-88-26.49A48,48,0,0,0,40,72v1.39a56,56,0,0,0,0,101.2V176a48,48,0,0,0,88,26.49A48,48,0,0,0,216,176v-1.41A56.09,56.09,0,0,0,248,124ZM88,208a32,32,0,0,1-31.81-28.56A55.87,55.87,0,0,0,64,180h8a8,8,0,0,0,0-16H64A40,40,0,0,1,50.67,86.27,8,8,0,0,0,56,78.73V72a32,32,0,0,1,64,0v68.26A47.8,47.8,0,0,0,88,128a8,8,0,0,0,0,16,32,32,0,0,1,0,64Zm104-44h-8a8,8,0,0,0,0,16h8a55.87,55.87,0,0,0,7.81-.56A32,32,0,1,1,168,144a8,8,0,0,0,0-16,47.8,47.8,0,0,0-32,12.26V72a32,32,0,0,1,64,0v6.73a8,8,0,0,0,5.33,7.54A40,40,0,0,1,192,164Zm16-52a8,8,0,0,1-8,8h-4a36,36,0,0,1-36-36V80a8,8,0,0,1,16,0v4a20,20,0,0,0,20,20h4A8,8,0,0,1,208,112ZM60,120H56a8,8,0,0,1,0-16h4A20,20,0,0,0,80,84V80a8,8,0,0,1,16,0v4A36,36,0,0,1,60,120Z\"></path></svg>`,\n book: `<svg class=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" fill=\"#ffffff\" viewBox=\"0 0 256 256\"><path d=\"M232,48H160a40,40,0,0,0-32,16A40,40,0,0,0,96,48H24a8,8,0,0,0-8,8V200a8,8,0,0,0,8,8H96a24,24,0,0,1,24,24,8,8,0,0,0,16,0,24,24,0,0,1,24-24h72a8,8,0,0,0,8-8V56A8,8,0,0,0,232,48ZM96,192H32V64H96a24,24,0,0,1,24,24V200A39.81,39.81,0,0,0,96,192Zm128,0H160a39.81,39.81,0,0,0-24,8V88a24,24,0,0,1,24-24h64ZM160,88h40a8,8,0,0,1,0,16H160a8,8,0,0,1,0-16Zm48,40a8,8,0,0,1-8,8H160a8,8,0,0,1,0-16h40A8,8,0,0,1,208,128Zm0,32a8,8,0,0,1-8,8H160a8,8,0,0,1,0-16h40A8,8,0,0,1,208,160Z\"></path></svg>`,\n question: `<svg class=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" fill=\"#ffffff\" viewBox=\"0 0 256 256\"><path d=\"M225.86,102.82c-3.77-3.94-7.67-8-9.14-11.57-1.36-3.27-1.44-8.69-1.52-13.94-.15-9.76-.31-20.82-8-28.51s-18.75-7.85-28.51-8c-5.25-.08-10.67-.16-13.94-1.52-3.56-1.47-7.63-5.37-11.57-9.14C146.28,23.51,138.44,16,128,16s-18.27,7.51-25.18,14.14c-3.94,3.77-8,7.67-11.57,9.14C88,40.64,82.56,40.72,77.31,40.8c-9.76.15-20.82.31-28.51,8S41,67.55,40.8,77.31c-.08,5.25-.16,10.67-1.52,13.94-1.47,3.56-5.37,7.63-9.14,11.57C23.51,109.72,16,117.56,16,128s7.51,18.27,14.14,25.18c3.77,3.94,7.67,8,9.14,11.57,1.36,3.27,1.44,8.69,1.52,13.94.15,9.76.31,20.82,8,28.51s18.75,7.85,28.51,8c5.25.08,10.67.16,13.94,1.52,3.56,1.47,7.63,5.37,11.57,9.14C109.72,232.49,117.56,240,128,240s18.27-7.51,25.18-14.14c3.94-3.77,8-7.67,11.57-9.14,3.27-1.36,8.69-1.44,13.94-1.52,9.76-.15,20.82-.31,28.51-8s7.85-18.75,8-28.51c.08-5.25.16-10.67,1.52-13.94,1.47-3.56,5.37-7.63,9.14-11.57C232.49,146.28,240,138.44,240,128S232.49,109.73,225.86,102.82Zm-11.55,39.29c-4.79,5-9.75,10.17-12.38,16.52-2.52,6.1-2.63,13.07-2.73,19.82-.1,7-.21,14.33-3.32,17.43s-10.39,3.22-17.43,3.32c-6.75.1-13.72.21-19.82,2.73-6.35,2.63-11.52,7.59-16.52,12.38S132,224,128,224s-9.15-4.92-14.11-9.69-10.17-9.75-16.52-12.38c-6.1-2.52-13.07-2.63-19.82-2.73-7-.1-14.33-.21-17.43-3.32s-3.22-10.39-3.32-17.43c-.1-6.75-.21-13.72-2.73-19.82-2.63-6.35-7.59-11.52-12.38-16.52S32,132,32,128s4.92-9.15,9.69-14.11,9.75-10.17,12.38-16.52c2.52-6.1,2.63-13.07,2.73-19.82.1-7,.21-14.33,3.32-17.43S70.51,56.9,77.55,56.8c6.75-.1,13.72-.21,19.82-2.73,6.35-2.63,11.52-7.59,16.52-12.38S124,32,128,32s9.15,4.92,14.11,9.69,10.17,9.75,16.52,12.38c6.1,2.52,13.07,2.63,19.82,2.73,7,.1,14.33.21,17.43,3.32s3.22,10.39,3.32,17.43c.1,6.75.21,13.72,2.73,19.82,2.63,6.35,7.59,11.52,12.38,16.52S224,124,224,128,219.08,137.15,214.31,142.11ZM140,180a12,12,0,1,1-12-12A12,12,0,0,1,140,180Zm28-72c0,17.38-13.76,31.93-32,35.28V144a8,8,0,0,1-16,0v-8a8,8,0,0,1,8-8c13.23,0,24-9,24-20s-10.77-20-24-20-24,9-24,20v4a8,8,0,0,1-16,0v-4c0-19.85,17.94-36,40-36S168,88.15,168,108Z\"></path></svg>`,\n };\n\n const actions = [\n {\n key: \"overview\",\n icon: icons.house,\n label: \"Overview\",\n cb: cb.onOverview,\n },\n { key: \"memory\", icon: icons.brain, label: \"Memory\", cb: cb.onMemory },\n {\n key: \"vocabulary\",\n icon: icons.book,\n label: \"Vocabulary\",\n cb: cb.onVocabulary,\n },\n {\n key: \"clarifications\",\n icon: icons.question,\n label: \"Clarifications\",\n cb: cb.onClarifications,\n },\n ];\n\n actions.forEach((action) => {\n const btn = document.createElement(\"button\");\n btn.className =\n \"rail-item\" + (state.activeSection === action.key ? \" active\" : \"\");\n btn.type = \"button\";\n btn.tabIndex = 0;\n btn.innerHTML =\n (action.key === \"memory\"\n ? `<div class=\"rail-glow${state.hasMemoryGlow ? \" active\" : \"\"}\"></div>`\n : \"\") + action.icon;\n // Add custom tooltip\n const tooltip = document.createElement(\"span\");\n tooltip.className = \"rail-tooltip\";\n tooltip.textContent = action.label;\n btn.appendChild(tooltip);\n btn.addEventListener(\"click\", action.cb);\n root.appendChild(btn);\n });\n\n return root;\n}\n","// Bottom section: Login/Logout\nexport interface RailAuthCallbacks {\n onLogin: () => void;\n onLogout: () => void;\n}\n\nexport function createRailAuth(\n isLoggedIn: boolean,\n cb: RailAuthCallbacks,\n): HTMLElement {\n const root = document.createElement(\"div\");\n root.className = \"rail-auth rail-section\";\n const btn = document.createElement(\"button\");\n btn.className = \"rail-auth-btn\";\n btn.type = \"button\";\n btn.tabIndex = 0;\n let iconSVG, tooltipText;\n if (isLoggedIn) {\n iconSVG = `<svg class=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" fill=\"#ffffff\" viewBox=\"0 0 256 256\"><path d=\"M120,216a8,8,0,0,1-8,8H48a8,8,0,0,1-8-8V40a8,8,0,0,1,8-8h64a8,8,0,0,1,0,16H56V208h56A8,8,0,0,1,120,216Zm109.66-93.66-40-40a8,8,0,0,0-11.32,11.32L204.69,120H112a8,8,0,0,0,0,16h92.69l-26.35,26.34a8,8,0,0,0,11.32,11.32l40-40A8,8,0,0,0,229.66,122.34Z\"></path></svg>`;\n tooltipText = \"Logout\";\n btn.addEventListener(\"click\", cb.onLogout);\n } else {\n iconSVG = `<svg class=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" fill=\"#ffffff\" viewBox=\"0 0 256 256\"><path d=\"M141.66,133.66l-40,40a8,8,0,0,1-11.32-11.32L116.69,136H24a8,8,0,0,1,0-16h92.69L90.34,93.66a8,8,0,0,1,11.32-11.32l40,40A8,8,0,0,1,141.66,133.66ZM200,32H136a8,8,0,0,0,0,16h56V208H136a8,8,0,0,0,0,16h64a8,8,0,0,0,8-8V40A8,8,0,0,0,200,32Z\"></path></svg>`;\n tooltipText = \"Login\";\n btn.addEventListener(\"click\", cb.onLogin);\n }\n btn.innerHTML = iconSVG;\n // Add custom tooltip\n const tooltip = document.createElement(\"span\");\n tooltip.className = \"rail-tooltip\";\n tooltip.textContent = tooltipText;\n btn.appendChild(tooltip);\n root.appendChild(btn);\n return root;\n}\n","// Assembles the Unnoodle Rail from sections, manages state\nimport { railStyles } from \"./railStyles\";\nimport { createRailIdentity } from \"./railIdentity\";\nimport {\n createRailCoreActions,\n RailCoreActionsCallbacks,\n} from \"./railCoreActions\";\nimport { createRailAuth, RailAuthCallbacks } from \"./railAuth\";\n\nexport interface RailState {\n isLoggedIn: boolean;\n initials: string | null;\n activeSection: \"overview\" | \"memory\" | \"vocabulary\" | \"clarifications\" | null;\n hasMemoryGlow: boolean;\n}\n\nexport interface RailCallbacks\n extends RailCoreActionsCallbacks, RailAuthCallbacks {}\n\nexport function createRail(\n state: RailState,\n cb: RailCallbacks,\n): {\n element: HTMLElement;\n setState: (s: Partial<RailState>) => void;\n cleanup: () => void;\n} {\n const host = document.createElement(\"div\");\n host.id = \"unnoodle-rail-host\";\n const shadow = host.attachShadow({ mode: \"open\" });\n\n // Style\n const style = document.createElement(\"style\");\n style.textContent = railStyles;\n shadow.appendChild(style);\n\n // Sections\n let identity = createRailIdentity(state.initials);\n let core = createRailCoreActions(\n {\n activeSection: state.activeSection,\n hasMemoryGlow: state.hasMemoryGlow,\n },\n cb,\n );\n let auth = createRailAuth(state.isLoggedIn, cb);\n\n // Rail shell (fixed positioned wrapper, like panel-shell)\n const railShell = document.createElement(\"div\");\n railShell.className = \"rail-shell\";\n\n const rail = document.createElement(\"nav\");\n rail.className = \"rail\";\n rail.appendChild(identity);\n rail.appendChild(core);\n rail.appendChild(auth);\n\n railShell.appendChild(rail);\n shadow.appendChild(railShell);\n\n // Push body content so the rail doesn't overlay the page\n const RAIL_WIDTH = 34;\n document.body.style.transition =\n \"margin-right 0.28s cubic-bezier(0.4,0,0.2,1)\";\n document.body.style.marginRight = `${RAIL_WIDTH}px`;\n\n // State update\n function setState(s: Partial<RailState>) {\n // Remove old\n rail.removeChild(identity);\n rail.removeChild(core);\n rail.removeChild(auth);\n // New\n identity = createRailIdentity(s.initials ?? state.initials);\n core = createRailCoreActions(\n {\n activeSection: s.activeSection ?? state.activeSection,\n hasMemoryGlow: s.hasMemoryGlow ?? state.hasMemoryGlow,\n },\n cb,\n );\n auth = createRailAuth(s.isLoggedIn ?? state.isLoggedIn, cb);\n rail.appendChild(identity);\n rail.appendChild(core);\n rail.appendChild(auth);\n // Update state\n Object.assign(state, s);\n }\n\n // Cleanup\n function cleanup() {\n host.remove();\n document.body.style.marginRight = \"\";\n }\n\n return { element: host, setState, cleanup };\n}\n","import { createButton } from \"./button\";\nimport { createPanel, type PanelControls } from \"./panel\";\nimport type { GlossaryTerm, GlossaryTermUpdateRequest } from \"../types/config\";\nimport { createRail, RailState, RailCallbacks } from \"./rail/rail\";\n\nexport interface MountedUI {\n panel: PanelControls;\n /** Toggle the spinning progress ring or rail state. */\n setProgress: (active: boolean) => void;\n cleanup: () => void;\n}\n\nexport interface MountedRailUI {\n panel: PanelControls;\n setRailState: (s: Partial<RailState>) => void;\n cleanup: () => void;\n}\n\n/**\n * Mounts the button and panel host elements into the document body.\n * Both use Shadow DOM so they are fully isolated from host app styles.\n */\n/**\n * Mounts the button and panel host elements into the document body.\n * Both use Shadow DOM so they are fully isolated from host app styles.\n * This is the default (button) version.\n */\nexport function mountUI(\n onTrigger: () => void,\n onLogin: (email: string, password: string) => void,\n onSearch: (query: string) => void,\n workspaceUrl?: string,\n onClose?: () => void,\n onBack?: () => void,\n onAddComment?: (termId: number, body: string) => void,\n onEditTerm?: (termId: number, updates: GlossaryTermUpdateRequest) => void,\n onTermClick?: (term: GlossaryTerm) => void,\n onRequestEdit?: (termId: number) => void,\n onCaptureUiState?: () => void,\n onOpenMemories?: () => void,\n onViewMemoryDetail?: (id: number) => void,\n onUpdateEntryExplanation?: (\n memoryId: number,\n entryId: number,\n explanation: string,\n ) => void,\n onPopout?: () => void,\n onReattach?: () => void,\n onSsoLogin?: (provider: \"google\" | \"microsoft\") => void,\n shadowTokens?: string,\n onAskQuestion?: (contextId: number, body: string) => void,\n onRequireLogin?: () => void,\n onAddConcept?: (term: string, definition: string) => void,\n onOpenSearch?: () => void,\n onClarificationClick?: (\n discussion: import(\"../types/config\").ContextDiscussion,\n ) => void,\n onPostReply?: (contextId: number, questionId: number, body: string) => void,\n onAddEntryToMemory?: (memoryId: number) => void,\n onDeleteMemory?: (memoryId: number) => void,\n onDeleteEntry?: (memoryId: number, entryId: number) => void,\n onShowAllConcepts?: () => void,\n onShowAllClarifications?: () => void,\n onShowAllMemories?: () => void,\n /** LQ-12: user submitted a question in the Ask view. */\n onAsk?: (question: string) => void,\n /** LQ-12: user opened the Ask view from the home row. */\n onOpenAsk?: () => void,\n): MountedUI {\n const panel = createPanel(\n onLogin,\n onSearch,\n workspaceUrl,\n onClose,\n onBack,\n onAddComment,\n onEditTerm,\n onTermClick,\n onRequestEdit,\n onCaptureUiState,\n onOpenMemories,\n onViewMemoryDetail,\n onUpdateEntryExplanation,\n onPopout,\n onReattach,\n onSsoLogin,\n shadowTokens,\n onAskQuestion,\n onRequireLogin,\n onAddConcept,\n onOpenSearch,\n onClarificationClick,\n onPostReply,\n onAddEntryToMemory,\n onDeleteMemory,\n onDeleteEntry,\n onShowAllConcepts,\n onShowAllClarifications,\n onShowAllMemories,\n onAsk,\n onOpenAsk,\n );\n const button = createButton(onTrigger, shadowTokens);\n\n document.body.appendChild(panel.element);\n document.body.appendChild(button.element);\n\n const cleanup = () => {\n button.cleanup();\n panel.cleanup();\n };\n\n return { panel, setProgress: button.setProgress, cleanup };\n}\n\n/**\n * Mounts the Unnoodle Rail and panel host elements into the document body.\n * The rail is feature-flagged and state-driven.\n */\nexport function mountRailUI(\n railState: RailState,\n railCallbacks: RailCallbacks,\n panelCallbacks: Parameters<typeof createPanel>,\n): MountedRailUI {\n const panel = createPanel(...panelCallbacks);\n const rail = createRail(railState, railCallbacks);\n document.body.appendChild(panel.element);\n document.body.appendChild(rail.element);\n const cleanup = () => {\n rail.cleanup();\n panel.cleanup();\n };\n return {\n panel,\n setRailState: rail.setState,\n cleanup,\n };\n}\n","import type { GlossaryTerm } from \"../types/config\";\n\n/** Tags whose text content we never highlight */\nconst SKIP_TAGS = new Set([\n \"INPUT\",\n \"TEXTAREA\",\n \"SCRIPT\",\n \"STYLE\",\n \"CODE\",\n \"PRE\",\n \"KBD\",\n \"SAMP\",\n \"VAR\",\n \"NOSCRIPT\",\n \"BUTTON\",\n \"SELECT\",\n \"OPTION\",\n \"OPTGROUP\",\n]);\n\n/** Unnoodle shadow-host element IDs to exclude from DOM walking */\nconst SKIP_IDS = new Set([\"unnoodle-panel-host\", \"unnoodle-btn-host\"]);\n\nconst HIGHLIGHT_CLASS = \"unnoodle-highlight\";\n\nconst HIGHLIGHT_STYLE = [\n \"border-bottom: 1px dotted currentColor\",\n \"cursor: pointer\",\n \"opacity: 0.85\",\n \"text-decoration: none\",\n].join(\"; \");\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Scans the host page DOM and wraps glossary term occurrences in highlighted\n * spans. Call `apply()` when the panel opens and `remove()` when it closes.\n *\n * Safety rules:\n * - Skips script/style/code/pre and other non-prose tags\n * - Skips contenteditable regions\n * - Skips the unnoodle widget hosts (Shadow DOM)\n * - Skips DEPRECATED terms\n * - Whole-word matches only (word-boundary regex)\n * - Longer terms take priority over shorter ones (no partial collisions)\n * - Never double-wraps already-highlighted spans\n */\nexport class Highlighter {\n private onTermClick: (term: GlossaryTerm) => void;\n private highlights: HTMLElement[] = [];\n\n constructor(onTermClick: (term: GlossaryTerm) => void) {\n this.onTermClick = onTermClick;\n }\n\n /** Highlight all active terms in the current document. */\n apply(terms: GlossaryTerm[]): void {\n this.remove();\n const active = terms.filter((t) => t.status === \"ACTIVE\");\n if (active.length === 0) return;\n\n const { regex, termMap } = this.buildPattern(active);\n this.walkAndHighlight(document.body, regex, termMap);\n }\n\n /** Remove all highlights and restore original text nodes. */\n remove(): void {\n // Iterate in reverse to preserve sibling ordering during restoration\n for (let i = this.highlights.length - 1; i >= 0; i--) {\n const span = this.highlights[i]!;\n const parent = span.parentNode;\n if (!parent) continue;\n parent.replaceChild(\n document.createTextNode(span.textContent ?? \"\"),\n span,\n );\n parent.normalize();\n }\n this.highlights = [];\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Builds a single combined regex from all terms so that each text node is\n * processed in one pass. Terms are sorted longest-first so \"API Gateway\"\n * matches before a standalone \"API\".\n */\n private buildPattern(terms: GlossaryTerm[]): {\n regex: RegExp;\n termMap: Map<string, GlossaryTerm>;\n } {\n const termMap = new Map<string, GlossaryTerm>();\n const sorted = [...terms].sort((a, b) => b.term.length - a.term.length);\n const patterns: string[] = [];\n\n for (const term of sorted) {\n const key = term.term.toLowerCase();\n if (!termMap.has(key)) {\n termMap.set(key, term);\n patterns.push(escapeRegex(term.term));\n }\n if (term.abbreviation) {\n const abbrKey = term.abbreviation.toLowerCase();\n if (!termMap.has(abbrKey)) {\n termMap.set(abbrKey, term);\n patterns.push(escapeRegex(term.abbreviation));\n }\n }\n }\n\n if (patterns.length === 0) {\n return { regex: /(?!)/g, termMap };\n }\n\n const regex = new RegExp(`\\\\b(${patterns.join(\"|\")})\\\\b`, \"gi\");\n return { regex, termMap };\n }\n\n private walkAndHighlight(\n node: Node,\n regex: RegExp,\n termMap: Map<string, GlossaryTerm>,\n ): void {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const el = node as Element;\n\n // Skip unnoodle widget hosts (Shadow DOM)\n if (SKIP_IDS.has(el.id)) return;\n\n // Never re-highlight an existing span\n if (el.classList.contains(HIGHLIGHT_CLASS)) return;\n\n // Skip contenteditable regions\n if (el.getAttribute(\"contenteditable\") != null) return;\n\n // Skip non-prose tag types\n if (SKIP_TAGS.has(el.tagName)) return;\n\n // Snapshot childNodes before walking so mutations don't skew iteration\n for (const child of Array.from(el.childNodes)) {\n this.walkAndHighlight(child, regex, termMap);\n }\n } else if (node.nodeType === Node.TEXT_NODE) {\n this.highlightTextNode(node as Text, regex, termMap);\n }\n }\n\n private highlightTextNode(\n textNode: Text,\n regex: RegExp,\n termMap: Map<string, GlossaryTerm>,\n ): void {\n const text = textNode.textContent ?? \"\";\n if (!text.trim()) return;\n\n regex.lastIndex = 0;\n const fragments: (string | HTMLElement)[] = [];\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(text)) !== null) {\n const matched = match[0];\n const term = termMap.get(matched.toLowerCase());\n if (!term) continue;\n\n if (match.index > lastIndex) {\n fragments.push(text.slice(lastIndex, match.index));\n }\n\n const span = document.createElement(\"span\");\n span.className = HIGHLIGHT_CLASS;\n span.dataset.termId = String(term.id);\n span.textContent = matched;\n span.title =\n term.definition.length > 120\n ? `${term.definition.slice(0, 120)}…`\n : term.definition;\n span.style.cssText = HIGHLIGHT_STYLE;\n span.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.onTermClick(term);\n });\n\n fragments.push(span);\n this.highlights.push(span);\n lastIndex = match.index + matched.length;\n }\n\n if (fragments.length === 0) return;\n\n fragments.push(text.slice(lastIndex));\n\n const parent = textNode.parentNode;\n if (!parent) return;\n const anchor = textNode.nextSibling;\n parent.removeChild(textNode);\n\n for (const fragment of fragments) {\n if (typeof fragment === \"string\") {\n if (fragment) {\n parent.insertBefore(document.createTextNode(fragment), anchor);\n }\n } else {\n parent.insertBefore(fragment, anchor);\n }\n }\n }\n}\n","import type { GlossaryTerm, TermSuggestion } from \"../types/config\";\n\n/** Tags whose text content we never scan for candidate terms */\nconst SKIP_TAGS = new Set([\n \"INPUT\",\n \"TEXTAREA\",\n \"SCRIPT\",\n \"STYLE\",\n \"CODE\",\n \"PRE\",\n \"KBD\",\n \"SAMP\",\n \"VAR\",\n \"NOSCRIPT\",\n \"BUTTON\",\n \"SELECT\",\n \"OPTION\",\n \"OPTGROUP\",\n]);\n\n/** Unnoodle shadow-host element IDs — skip entirely */\nconst SKIP_IDS = new Set([\"unnoodle-panel-host\", \"unnoodle-btn-host\"]);\n\n/** Maximum number of suggestions to return */\nconst MAX_SUGGESTIONS = 5;\n\n/** Minimum number of occurrences for a candidate to qualify */\nconst MIN_FREQUENCY = 2;\n\n/**\n * Common English words that are capitalised purely due to sentence position —\n * these produce far too many false positives to be useful suggestions.\n */\nconst STOP_WORDS = new Set([\n \"The\",\n \"This\",\n \"These\",\n \"Those\",\n \"That\",\n \"Then\",\n \"There\",\n \"They\",\n \"Their\",\n \"When\",\n \"Where\",\n \"What\",\n \"Why\",\n \"How\",\n \"With\",\n \"From\",\n \"Into\",\n \"Has\",\n \"Have\",\n \"Was\",\n \"Were\",\n \"For\",\n \"But\",\n \"And\",\n \"Or\",\n \"In\",\n \"On\",\n \"At\",\n \"By\",\n \"Us\",\n \"We\",\n \"He\",\n \"She\",\n \"It\",\n \"Our\",\n \"Its\",\n \"You\",\n \"Your\",\n \"His\",\n \"Her\",\n \"An\",\n \"As\",\n \"Be\",\n \"Do\",\n \"To\",\n \"If\",\n \"Of\",\n \"So\",\n \"Up\",\n \"I\",\n]);\n\n/**\n * Scans the host-page DOM for candidate glossary terms: capitalized\n * phrases that appear multiple times and are not already in the glossary.\n *\n * Call `scan(glossary)` after the glossary loads.\n * Call `getPageContext(term)` to extract surrounding text for AI context.\n */\nexport class TermSuggester {\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n\n /**\n * Scans the current document and returns the top N candidate terms\n * sorted by frequency descending.\n *\n * Algorithm:\n * 1. Extract visible text, skipping code/script/input/unnoodle zones.\n * 2. Find all maximal runs of consecutive capitalised words.\n * 3. Within each run, enumerate every 1-, 2-, and 3-word sub-phrase that\n * starts at each position — this ensures \"Circuit Breaker\" is counted\n * even when preceded by \"Use\", rather than being consumed as part of the\n * longer phrase \"Use Circuit Breaker\".\n * 4. Aggregate frequency, filter by MIN_FREQUENCY, cap at MAX_SUGGESTIONS.\n */\n scan(existingTerms: GlossaryTerm[]): TermSuggestion[] {\n const glossarySet = this.buildGlossarySet(existingTerms);\n const text = this.extractText(document.body);\n\n const freq = new Map<string, number>();\n\n /**\n * Matches a maximal run of consecutive capitalised words (separated only\n * by whitespace). Each run is then split into individual words for the\n * n-gram enumeration below.\n */\n const RUN_RE = /[A-Z][a-zA-Z]*(?:\\s+[A-Z][a-zA-Z]*)*/g;\n let runMatch: RegExpExecArray | null;\n\n while ((runMatch = RUN_RE.exec(text)) !== null) {\n const words = runMatch[0].split(/\\s+/);\n\n for (let i = 0; i < words.length; i++) {\n // Skip if the first word of the candidate is a stop word\n if (STOP_WORDS.has(words[i]!)) continue;\n\n for (let len = 1; len <= Math.min(3, words.length - i); len++) {\n const phrase = words.slice(i, i + len).join(\" \");\n if (phrase.length < 2) continue;\n if (glossarySet.has(phrase.toLowerCase())) continue;\n freq.set(phrase, (freq.get(phrase) ?? 0) + 1);\n }\n }\n }\n\n return [...freq.entries()]\n .filter(([, count]) => count >= MIN_FREQUENCY)\n .sort((a, b) => b[1] - a[1])\n .slice(0, MAX_SUGGESTIONS)\n .map(([term, count]) => ({ term, count }));\n }\n\n /**\n * Returns the text of the paragraph/block element that contains the\n * first occurrence of `term` in the page. Used as AI context.\n */\n getPageContext(term: string): string {\n const lower = term.toLowerCase();\n const candidates = Array.from(\n document.body.querySelectorAll(\"p, li, blockquote, td, section, article\"),\n );\n\n for (const el of candidates) {\n if (SKIP_TAGS.has(el.tagName)) continue;\n if (SKIP_IDS.has(el.id)) continue;\n const text = el.textContent ?? \"\";\n if (text.toLowerCase().includes(lower)) {\n // Return truncated to 500 chars to keep prompt size sane\n return text.slice(0, 500).trim();\n }\n }\n\n return \"\";\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n private buildGlossarySet(terms: GlossaryTerm[]): Set<string> {\n const s = new Set<string>();\n for (const t of terms) {\n s.add(t.term.toLowerCase());\n if (t.abbreviation) s.add(t.abbreviation.toLowerCase());\n }\n return s;\n }\n\n private extractText(node: Node): string {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const el = node as Element;\n if (SKIP_IDS.has(el.id)) return \"\";\n if (SKIP_TAGS.has(el.tagName)) return \"\";\n if (el.getAttribute(\"contenteditable\") != null) return \"\";\n return Array.from(el.childNodes)\n .map((c) => this.extractText(c))\n .join(\" \");\n }\n if (node.nodeType === Node.TEXT_NODE) {\n return node.textContent ?? \"\";\n }\n return \"\";\n }\n}\n","import type {\n UnnoodleConfig,\n WidgetInitResponse,\n GlossaryTerm,\n ContextDiscussion,\n GlossaryTermUpdateRequest,\n ProductMemoryResponse,\n ProductMemoryDetailResponse,\n SsoProviders,\n} from \"../types/config\";\nimport Fuse, { type FuseResult } from \"fuse.js\";\nimport {\n initWidget,\n searchTerms,\n loginUser,\n fetchOAuthProviders,\n getDiscussions,\n postComment,\n updateTerm,\n generateAiDefinition,\n createSuggestedTerm,\n createProductMemory,\n listProductMemories,\n getProductMemory,\n updateProductMemoryEntry,\n fetchContextDiscussions,\n postContextDiscussion,\n postContextReply,\n deleteProductMemory,\n deleteProductMemoryEntry,\n createGlossaryTerm,\n ApiError,\n} from \"../core/apiClient\";\nimport {\n askQuestion,\n getAskStatus,\n AskBusyError,\n AskRateLimitedError,\n} from \"../api/ask\";\nimport {\n createCaptureModeController,\n type CaptureModeController,\n} from \"../features/memory/captureModeController\";\nimport { AddEntryOrchestrator } from \"../features/memory/captureOrchestrator\";\nimport { mountUI, mountRailUI, type MountedUI } from \"../ui/mount\";\nimport { Highlighter } from \"../ui/highlighter\";\nimport { TermSuggester } from \"../ui/termSuggester\";\n\nexport type WidgetView = \"login\" | \"terms\";\n\n/**\n * Controls the full widget lifecycle:\n *\n * 1. Mount floating button + panel (Shadow DOM)\n * 2. On open — load terms immediately using the API key alone (no login required)\n * 3. If a user JWT is already available (from sessionStorage), attach it so the\n * server can personalise results — but it is never required for reads.\n * 4. Write actions (Phase 2) will prompt inline login when needed.\n * 5. Terms panel shows searchable glossary list\n * 6. Keyboard shortcut Cmd/Ctrl+U toggles open/close\n */\n/** Shown when an MFA-enabled account signs in; the widget has no OTP step yet. */\nexport const MFA_NOT_SUPPORTED_MESSAGE =\n \"This account uses two-factor authentication, which this panel doesn't support yet. Sign in from your Unnoodle workspace instead.\";\n\nexport class WidgetController {\n constructor(config: UnnoodleConfig) {\n this.config = config;\n }\n private config!: UnnoodleConfig;\n /** LQ-12: the one in-flight question, aborted when the view closes. */\n private askInFlight: AbortController | null = null;\n private askRetryTimer: ReturnType<typeof setTimeout> | null = null;\n private ui: MountedUI | null = null;\n private rail: { setRailState?: (s: any) => void } | null = null;\n private isOpen = false;\n private isFetching = false;\n private keydownHandler: ((e: KeyboardEvent) => void) | null = null;\n private authToken: string | null = null;\n private tokenExpiryTimer: ReturnType<typeof setTimeout> | null = null;\n private cachedResponse: WidgetInitResponse | null = null;\n private cachedDiscussions: ContextDiscussion[] | null = null;\n private cachedHomeMemories: ProductMemoryResponse[] | null = null;\n private highlighter: Highlighter | null = null;\n private suggester: TermSuggester | null = null;\n private captureModeController: CaptureModeController | null = null;\n private activeSuggestion: any = null;\n private ssoProviders: SsoProviders | null = null;\n private ssoPopupCleanup: (() => void) | null = null;\n private fuseIndex: any = null;\n private currentTerm: GlossaryTerm | null = null;\n private currentDiscussion: ContextDiscussion | null = null;\n private currentMemory: ProductMemoryDetailResponse | null = null;\n private memories: ProductMemoryResponse[] = [];\n private memoriesPage: number = 0;\n private hasMoreMemories: boolean = false;\n private pendingAction: (() => void) | null = null;\n private sessionKey: string = \"unnoodle_jwt\";\n\n /**\n * Returns user initials for the rail avatar, using config or session info if available.\n */\n private getUserInitials(): string {\n let name = (this.config as any).userName as string | undefined;\n let email = (this.config as any).userEmail as string | undefined;\n if (!name && this.authToken) {\n try {\n const token = this.authToken;\n if (token) {\n const parts = token.split(\".\");\n if (parts.length === 3 && typeof parts[1] === \"string\") {\n const payload = JSON.parse(atob(parts[1]));\n name = payload.name;\n email = payload.email;\n }\n }\n } catch {}\n }\n if (name) {\n const parts = name.trim().split(\" \");\n if (parts.length === 1)\n return parts[0] && parts[0][0] ? parts[0][0].toUpperCase() : \"?\";\n const first = parts[0] && parts[0][0] ? parts[0][0] : \"\";\n const lastPart = parts[parts.length - 1];\n const last = lastPart && lastPart[0] ? lastPart[0] : \"\";\n return (first + last).toUpperCase() || \"?\";\n }\n if (email && email[0]) return email[0].toUpperCase();\n return \"?\";\n }\n\n init(): void {\n if (!this.config) {\n throw new Error(\"WidgetController: config is not set\");\n }\n const shadowTokens = this.config.theme?.shadowTokens;\n // Feature flag: useRail\n if ((this.config as any).useRail) {\n // Minimal state for demo: initials, login, active section, memory glow\n const isLoggedIn = !!this.resolveToken();\n const initials = isLoggedIn ? this.getUserInitials() : null;\n const railState = {\n isLoggedIn,\n initials,\n activeSection: \"overview\" as const,\n hasMemoryGlow: false,\n };\n const railCallbacks = {\n onOverview: () => this.open(),\n onMemory: () => {\n if (!this.isOpen) this.open();\n const token = !!this.resolveToken();\n if (this.cachedResponse?.productMemories) {\n this.ui?.panel.showAllMemories(\n this.cachedResponse.productMemories,\n token,\n );\n } else if (this.cachedHomeMemories) {\n this.ui?.panel.showAllMemories(this.cachedHomeMemories, token);\n } else {\n this.ui?.panel.showAllMemories?.([], token);\n }\n },\n onVocabulary: () => {\n if (!this.isOpen) this.open();\n if (this.cachedResponse) {\n this.ui?.panel.showAllConcepts(this.cachedResponse.glossary);\n } else {\n this.ui?.panel.showAllConcepts?.([]);\n }\n },\n onClarifications: () => {\n if (!this.isOpen) this.open();\n const token = !!this.resolveToken();\n if (this.cachedDiscussions) {\n this.ui?.panel.showAllClarifications(this.cachedDiscussions, token);\n } else {\n this.ui?.panel.showAllClarifications?.([], token);\n }\n },\n onLogin: () => {\n if (!this.isOpen) {\n this.isOpen = true;\n this.ui?.panel.show();\n }\n void this.showLoginWithProviders();\n },\n onLogout: () => {\n this.clearAuthToken();\n void this.showLoginWithProviders();\n },\n };\n const panelCallbacks = [\n (email: string, password: string) => this.handleLogin(email, password),\n (query: string) => this.handleSearch(query),\n this.config.workspaceUrl,\n () => {\n this.isOpen = false;\n this.highlighter?.remove();\n },\n () => this.handleBack(),\n (termId: number, body: string) => this.handleAddComment(termId, body),\n (termId: number, updates: GlossaryTermUpdateRequest) =>\n this.handleEditTerm(termId, updates),\n (term: GlossaryTerm) => this.handleTermClick(term),\n (termId: number) => this.handleRequestEdit(termId),\n () => {\n if (!this.resolveToken()) {\n void this.showLoginWithProviders();\n } else {\n this.captureModeController?.start();\n }\n },\n () => {\n void this.loadMemories(0, false);\n },\n (id: number) => {\n void this.handleViewMemoryDetail(id);\n },\n (memoryId: number, entryId: number, explanation: string) => {\n void this.handleUpdateEntryExplanation(\n memoryId,\n entryId,\n explanation,\n );\n },\n () => {\n this.isOpen = false;\n this.highlighter?.remove();\n },\n () => {\n this.isOpen = false;\n },\n (provider: \"google\" | \"microsoft\") => {\n this.handleSsoLogin(provider);\n },\n shadowTokens,\n (contextId: number, questionBody: string) => {\n void this.handleAskQuestion(contextId, questionBody);\n },\n () => {\n if (!this.resolveToken()) {\n void this.showLoginWithProviders();\n }\n },\n // onAddConcept: user submitted inline add-vocabulary form\n (term: string, definition: string) => {\n void this.handleCreateTerm(term, definition);\n },\n () => {\n if (this.cachedResponse) {\n this.ui?.panel.showSearchResults(this.cachedResponse.glossary, \"\");\n this.ui?.panel.setAuthenticated(!!this.resolveToken());\n }\n },\n (discussion: ContextDiscussion) => {\n this.handleClarificationClick(discussion);\n },\n (contextId: number, questionId: number, body: string) => {\n void this.handlePostReply(contextId, questionId, body);\n },\n (memoryId: number) => {\n this.handleAddEntryToMemory(memoryId);\n },\n (memoryId: number) => {\n void this.handleDeleteMemory(memoryId);\n },\n (memoryId: number, entryId: number) => {\n void this.handleDeleteEntry(memoryId, entryId);\n },\n () => {\n if (this.cachedResponse) {\n this.ui?.panel.showAllConcepts(this.cachedResponse.glossary);\n }\n },\n () => {\n if (this.cachedDiscussions) {\n this.ui?.panel.showAllClarifications(\n this.cachedDiscussions,\n !!this.resolveToken(),\n );\n }\n },\n () => {\n if (this.cachedResponse?.productMemories) {\n this.ui?.panel.showAllMemories(\n this.cachedResponse.productMemories,\n !!this.resolveToken(),\n );\n }\n },\n // onAsk (LQ-12): user submitted a question in the Ask view\n (question: string) => {\n void this.handleAsk(question);\n },\n // onOpenAsk (LQ-12): user clicked the Ask row on the home view\n () => {\n void this.handleOpenAsk();\n },\n ] as Parameters<typeof mountRailUI>[2];\n const railMount = mountRailUI(railState, railCallbacks, panelCallbacks);\n this.ui = {\n panel: railMount.panel,\n setProgress: () => {},\n cleanup: railMount.cleanup,\n };\n this.rail = railMount;\n } else {\n this.ui = mountUI(\n () => this.toggle(),\n (email, password) => this.handleLogin(email, password),\n (query) => this.handleSearch(query),\n this.config.workspaceUrl,\n () => {\n this.isOpen = false;\n this.highlighter?.remove();\n },\n () => this.handleBack(),\n (termId, body) => this.handleAddComment(termId, body),\n (termId, updates) => this.handleEditTerm(termId, updates),\n (term) => this.handleTermClick(term),\n (termId) => this.handleRequestEdit(termId),\n () => {\n console.log(\"[unnoodle] onCaptureUiState callback triggered\", {\n captureModeController: !!this.captureModeController,\n ui: !!this.ui,\n });\n if (!this.resolveToken()) {\n void this.showLoginWithProviders();\n } else {\n this.captureModeController?.start();\n }\n },\n () => {\n void this.loadMemories(0, false);\n },\n (id) => {\n void this.handleViewMemoryDetail(id);\n },\n (memoryId, entryId, explanation) => {\n void this.handleUpdateEntryExplanation(\n memoryId,\n entryId,\n explanation,\n );\n },\n // onPopout: panel leaves the main window — treat as closed so toggle() re-opens correctly\n () => {\n this.isOpen = false;\n this.highlighter?.remove();\n },\n // onReattach: panel returns to main window in closed state\n () => {\n this.isOpen = false;\n },\n // onSsoLogin: open popup for Google/Microsoft SSO from the login form\n (provider: \"google\" | \"microsoft\") => {\n this.handleSsoLogin(provider);\n },\n shadowTokens,\n // onAskQuestion: post a new clarification question on the context\n (contextId: number, questionBody: string) => {\n void this.handleAskQuestion(contextId, questionBody);\n },\n // onRequireLogin: unauthenticated user clicked a write-action button\n () => {\n if (!this.resolveToken()) {\n void this.showLoginWithProviders();\n }\n },\n // onAddConcept: user submitted inline add-vocabulary form\n (term: string, definition: string) => {\n void this.handleCreateTerm(term, definition);\n },\n // onOpenSearch: user clicked the search icon in home view → open terms/search view\n () => {\n if (this.cachedResponse) {\n this.ui?.panel.showSearchResults(this.cachedResponse.glossary, \"\");\n this.ui?.panel.setAuthenticated(!!this.resolveToken());\n }\n },\n // onClarificationClick: user clicked a clarification card → navigate to detail view\n (discussion: ContextDiscussion) => {\n this.handleClarificationClick(discussion);\n },\n // onPostReply: user submitted a reply in clarification detail view\n (contextId: number, questionId: number, body: string) => {\n void this.handlePostReply(contextId, questionId, body);\n },\n // onAddEntryToMemory: capture a new element and append it to an existing memory\n (memoryId: number) => {\n this.handleAddEntryToMemory(memoryId);\n },\n // onDeleteMemory: delete an entire product memory\n (memoryId: number) => {\n void this.handleDeleteMemory(memoryId);\n },\n // onDeleteEntry: delete an entry from a product memory\n (memoryId: number, entryId: number) => {\n void this.handleDeleteEntry(memoryId, entryId);\n },\n // onShowAllConcepts: user clicked \"Show All\" in Product Vocabulary section\n () => {\n console.log(\n \"DEBUG: onShowAllConcepts called, cachedResponse:\",\n !!this.cachedResponse,\n );\n if (this.cachedResponse) {\n console.log(\n \"DEBUG: Calling showAllConcepts with\",\n this.cachedResponse.glossary.length,\n \"terms\",\n );\n this.ui?.panel.showAllConcepts(this.cachedResponse.glossary);\n }\n },\n // onShowAllClarifications: user clicked \"Show All\" in Clarifications section\n () => {\n console.log(\n \"DEBUG: onShowAllClarifications called, cachedDiscussions:\",\n !!this.cachedDiscussions,\n );\n if (this.cachedDiscussions) {\n console.log(\n \"DEBUG: Calling showAllClarifications with\",\n this.cachedDiscussions.length,\n \"discussions\",\n );\n this.ui?.panel.showAllClarifications(\n this.cachedDiscussions,\n !!this.resolveToken(),\n );\n }\n },\n // onShowAllMemories: user clicked \"Show All\" in Product Memories section\n () => {\n console.log(\"DEBUG: onShowAllMemories called\", {\n hasCachedResponse: !!this.cachedResponse,\n hasResponseMemories: !!this.cachedResponse?.productMemories,\n hasCachedHomeMemories: !!this.cachedHomeMemories,\n });\n // Use cached data like other sections (consistent behavior)\n if (this.cachedResponse?.productMemories) {\n console.log(\n \"DEBUG: Using cached memories from main response\",\n this.cachedResponse.productMemories.length,\n );\n this.ui?.panel.showAllMemories(\n this.cachedResponse.productMemories,\n !!this.resolveToken(),\n );\n } else if (this.cachedHomeMemories) {\n console.log(\n \"DEBUG: Using cached memories from separate cache\",\n this.cachedHomeMemories.length,\n );\n this.ui?.panel.showAllMemories(\n this.cachedHomeMemories,\n !!this.resolveToken(),\n );\n } else {\n console.log(\"DEBUG: No cached memories, fetching via API\");\n void this.loadAllMemories();\n }\n },\n // onAsk (LQ-12): user submitted a question in the Ask view\n (question: string) => {\n void this.handleAsk(question);\n },\n // onOpenAsk (LQ-12): user clicked the Ask row on the home view\n () => {\n void this.handleOpenAsk();\n },\n );\n }\n\n this.captureModeController = createCaptureModeController(\n this.ui.panel,\n this.config,\n () => this.resolveToken(),\n () => this.cachedResponse?.glossary ?? [],\n () => void this.loadHomeMemoryItems(),\n );\n\n this.keydownHandler = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key === \"u\") {\n e.preventDefault();\n this.toggle();\n }\n };\n document.addEventListener(\"keydown\", this.keydownHandler);\n\n this.highlighter = new Highlighter((term) => this.handleTermClick(term));\n this.suggester = new TermSuggester();\n\n // Run onInit plugins\n if (this.config._plugins) {\n for (const plugin of this.config._plugins) {\n try {\n plugin.onInit?.(this.config);\n } catch {\n /* fail silently per plugin */\n }\n }\n }\n }\n\n open(): void {\n if (this.isOpen || !this.ui) return;\n this.isOpen = true;\n this.ui.panel.show();\n this.loadTerms();\n }\n\n close(): void {\n if (!this.isOpen || !this.ui) return;\n this.isOpen = false;\n this.abortAsk();\n this.highlighter?.remove();\n this.ui.panel.hide();\n }\n\n toggle(): void {\n this.isOpen ? this.close() : this.open();\n }\n\n /**\n * Show or hide the spinning progress ring on the trigger button.\n * Call `setProgress(true)` when a background task starts and\n * `setProgress(false)` when it completes.\n */\n setProgress(active: boolean): void {\n this.ui?.setProgress(active);\n }\n\n destroy(): void {\n if (this.keydownHandler) {\n document.removeEventListener(\"keydown\", this.keydownHandler);\n this.keydownHandler = null;\n }\n if (this.tokenExpiryTimer !== null) {\n clearTimeout(this.tokenExpiryTimer);\n this.tokenExpiryTimer = null;\n }\n this.abortAsk();\n this.highlighter?.remove();\n this.highlighter = null;\n this.suggester = null;\n this.captureModeController = null;\n this.activeSuggestion = null;\n this.ssoProviders = null;\n this.ssoPopupCleanup?.();\n this.ssoPopupCleanup = null;\n this.ui?.cleanup();\n this.ui = null;\n this.authToken = null;\n this.cachedResponse = null;\n this.cachedDiscussions = null;\n this.cachedHomeMemories = null;\n this.fuseIndex = null;\n this.currentTerm = null;\n this.pendingAction = null;\n try {\n sessionStorage.removeItem(this.sessionKey);\n } catch {\n /* ignore */\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n private resolveToken(): string | null {\n if (this.authToken) return this.authToken;\n return typeof this.config.getAuthToken === \"function\"\n ? (this.config.getAuthToken() ?? null)\n : null;\n }\n\n /**\n * Clear the stored auth token and remove it from sessionStorage.\n * Called when the JWT expiry timer fires.\n */\n private clearAuthToken(): void {\n this.authToken = null;\n try {\n sessionStorage.removeItem(this.sessionKey);\n } catch {\n /* ignore */\n }\n }\n\n /**\n * Schedule a timer that fires exactly when the JWT expires.\n * On expiry the token is cleared and, if the panel is open, a login panel\n * is shown — no outbound HTTP call is needed (cross-origin cookie restriction).\n */\n private scheduleTokenExpiry(jwt: string): void {\n if (this.tokenExpiryTimer !== null) {\n clearTimeout(this.tokenExpiryTimer);\n this.tokenExpiryTimer = null;\n }\n try {\n const parts = jwt.split(\".\");\n if (parts.length !== 3) return;\n const payloadB64 = parts[1];\n if (!payloadB64) return;\n const b64 = payloadB64.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const payload = JSON.parse(atob(b64)) as { exp?: unknown };\n if (typeof payload.exp !== \"number\") return;\n const expSeconds: number = payload.exp;\n\n const msUntilExpiry = expSeconds * 1000 - Date.now();\n if (msUntilExpiry <= 0) {\n // Already expired — clear immediately\n this.clearAuthToken();\n return;\n }\n\n this.tokenExpiryTimer = setTimeout(() => {\n this.tokenExpiryTimer = null;\n this.clearAuthToken();\n // If the panel is open prompt the user to sign in again\n if (this.isOpen && this.ui) {\n void this.showLoginWithProviders();\n }\n }, msUntilExpiry);\n } catch {\n /* malformed JWT payload — silently ignore */\n }\n }\n\n /**\n * Fetches SSO providers (once, cached) then shows the login form with the\n * correct SSO buttons for this tenant. Never throws — provider fetch errors\n * fall back to password-only login.\n */\n private async showLoginWithProviders(): Promise<void> {\n if (!this.ui) return;\n if (!this.ssoProviders) {\n this.ssoProviders = await fetchOAuthProviders(this.config);\n }\n // Guard again: component may have been destroyed while the fetch was in flight.\n if (!this.ui) return;\n this.ui.panel.showLogin(this.ssoProviders);\n }\n\n /**\n * Opens a popup window for Google or Microsoft OAuth.\n * Listens for a postMessage with type \"unnoodle-oauth-token\" from the popup,\n * stores the JWT, and loads the glossary (or runs any pending write-gate action).\n */\n private handleSsoLogin(provider: \"google\" | \"microsoft\"): void {\n if (!this.ui) return;\n\n const baseUrl =\n this.config.baseUrl?.replace(/\\/$/, \"\") ?? \"https://api.unnoodle.com\";\n const popupUrl = `${baseUrl}/api/auth/oauth/${provider}?widget=true`;\n\n const popup = window.open(\n popupUrl,\n \"unnoodle-sso\",\n \"width=500,height=650,scrollbars=yes,resizable=yes\",\n );\n\n // Remove any stale SSO listener from a previous attempt\n this.ssoPopupCleanup?.();\n this.ssoPopupCleanup = null;\n\n const cleanup = () => {\n clearInterval(closedPoll);\n window.removeEventListener(\"message\", onMessage);\n this.ssoPopupCleanup = null;\n };\n\n const onMessage = (event: MessageEvent) => {\n // Validate that the message originates from the configured API server\n try {\n const expectedOrigin = new URL(baseUrl).origin;\n if (event.origin !== expectedOrigin) return;\n } catch {\n // Malformed baseUrl — skip origin check (dev fallback)\n }\n\n if (\n !event.data ||\n typeof event.data !== \"object\" ||\n (event.data as Record<string, unknown>).type !==\n \"unnoodle-oauth-token\" ||\n typeof (event.data as Record<string, unknown>).token !== \"string\"\n ) {\n return;\n }\n\n cleanup();\n\n const token = (event.data as Record<string, string>).token;\n if (!token) return; // Safety check\n\n this.authToken = token;\n try {\n sessionStorage.setItem(this.sessionKey, token);\n } catch {\n /* ignore */\n }\n this.scheduleTokenExpiry(token);\n popup?.close();\n\n // Execute pending write-gate action if one was set, otherwise load terms\n if (this.pendingAction) {\n const action = this.pendingAction;\n this.pendingAction = null;\n action();\n } else {\n void this.fetchTerms(token);\n }\n };\n\n // Poll so we can clean up if the user closes the popup without completing\n const closedPoll = setInterval(() => {\n if (popup?.closed) cleanup();\n }, 500);\n\n this.ssoPopupCleanup = cleanup;\n window.addEventListener(\"message\", onMessage);\n }\n\n /**\n * Loads terms using the API key alone — no user login required.\n * If a JWT is present in sessionStorage it is forwarded so the server can\n * personalise results, but the read succeeds regardless.\n * Uses the cached response on subsequent opens to avoid redundant network calls.\n */\n private loadTerms(): void {\n if (this.cachedResponse) {\n this.ui?.panel.showTerms(this.cachedResponse);\n this.captureModeController?.setHomeData(this.cachedResponse);\n this.highlighter?.apply(this.cachedResponse.glossary);\n this.showSuggestions(this.cachedResponse.glossary);\n\n // Load clarifications: ALWAYS check main response cache first (like concepts)\n if (this.cachedResponse.clarifications !== undefined) {\n console.log(\n \"[DEBUG] Loading clarifications from main response cache\",\n this.cachedResponse.clarifications.length,\n );\n this.cachedDiscussions = this.cachedResponse.clarifications;\n this.ui?.panel.loadClarifications(\n this.cachedResponse.clarifications,\n !!this.resolveToken(),\n );\n } else if (this.cachedDiscussions) {\n this.ui?.panel.loadClarifications(\n this.cachedDiscussions,\n !!this.resolveToken(),\n );\n } else {\n void this.fetchDiscussions(this.cachedResponse.context.id);\n }\n\n // Load product memories: ALWAYS check main response cache first (like concepts)\n if (this.cachedResponse.productMemories !== undefined) {\n console.log(\n \"[DEBUG] Loading memories from main response cache\",\n this.cachedResponse.productMemories.length,\n );\n this.cachedHomeMemories = this.cachedResponse.productMemories;\n this.ui?.panel.showHomeMemoryItems(this.cachedResponse.productMemories);\n } else if (this.cachedHomeMemories) {\n console.log(\n \"[DEBUG] Using cached home memories from separate cache\",\n this.cachedHomeMemories.length,\n );\n this.ui?.panel.showHomeMemoryItems(this.cachedHomeMemories);\n } else {\n // Fallback: fetch product memories separately (same as initial load)\n void this.loadHomeMemoryItems();\n }\n return;\n }\n // Pass token if available (personalisation), but null is fine for reads.\n this.fetchTerms(this.resolveToken());\n }\n\n private async handleLogin(email: string, password: string): Promise<void> {\n if (!this.ui) return;\n this.ui.panel.setLoginLoading(true);\n\n try {\n const auth = await loginUser(this.config, { email, password });\n if (auth.mfaPending) {\n // The account has two-factor authentication (mandatory for admins).\n // auth.token is an MFA-PENDING token — only /api/auth/mfa/verify takes\n // it, so storing it as the session would leave every call failing.\n // This panel has no 6-digit step yet: refuse clearly, keep nothing,\n // and drop the gated action.\n this.pendingAction = null;\n this.ui.panel.setLoginError(MFA_NOT_SUPPORTED_MESSAGE);\n return;\n }\n this.authToken = auth.token;\n try {\n sessionStorage.setItem(this.sessionKey, auth.token);\n } catch {\n /* ignore */\n }\n this.scheduleTokenExpiry(auth.token);\n\n // Execute any pending write-gate action (e.g., show comment form or edit form)\n if (this.pendingAction) {\n const action = this.pendingAction;\n this.pendingAction = null;\n action();\n } else {\n await this.fetchTerms(auth.token);\n }\n } catch (err) {\n const message =\n err instanceof ApiError && err.status === 401\n ? \"Invalid email or password.\"\n : \"Login failed. Please try again.\";\n this.ui.panel.setLoginError(message);\n } finally {\n this.ui?.panel.setLoginLoading(false);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Phase 2: Term detail, comment, edit\n // ---------------------------------------------------------------------------\n\n private async handleTermClick(term: GlossaryTerm): Promise<void> {\n if (!this.ui) return;\n this.currentTerm = term;\n const token = this.resolveToken();\n\n this.ui.panel.setLoading();\n try {\n const discussions = await getDiscussions(\n this.config,\n term.id,\n token ?? undefined,\n );\n if (this.ui) {\n // Always show Edit button — login gate fires when clicked if no token\n this.ui.panel.showTermDetail(term, discussions, { showEdit: true });\n }\n } catch {\n // Show detail without discussions on error\n if (this.ui) {\n this.ui.panel.showTermDetail(term, [], { showEdit: true });\n }\n }\n }\n\n // ---------------------------------------------------------------------------\n // Ask (LQ-12)\n // ---------------------------------------------------------------------------\n\n /**\n * Open the Ask view. Unauthenticated users hit the login gate first — the\n * same gate every write action uses.\n *\n * `GET /api/ask/status` never 5xxes (E-Q13) and reports a disabled tenant as\n * a 200 with `enabled:false`, so a rejection here is transport or auth; the\n * view opens anyway with a null status rather than blocking on a failure the\n * user cannot act on (R4-15).\n */\n private async handleOpenAsk(): Promise<void> {\n if (!this.resolveToken()) {\n void this.showLoginWithProviders();\n return;\n }\n const status = await getAskStatus(this.config, this.resolveToken()).catch(\n () => null,\n );\n this.ui?.panel.showAsk(status);\n }\n\n /**\n * Ask one question (HLD §10.3). 503 is retried once after `Retry-After`;\n * 429 is terminal and names the limit; 401/403 re-open the login gate; an\n * abort (view closed / widget destroyed) is silent.\n */\n private async handleAsk(question: string): Promise<void> {\n if (this.askInFlight) return; // double-submit guard (R4-16)\n const ctrl = new AbortController();\n this.askInFlight = ctrl;\n this.ui?.panel.setAskLoading();\n try {\n for (let attempt = 0; ; attempt++) {\n try {\n const answer = await askQuestion(\n this.config,\n question,\n typeof location !== \"undefined\" ? location.href : \"\",\n this.resolveToken(),\n ctrl.signal,\n );\n this.ui?.panel.showAskAnswer(answer);\n return;\n } catch (e) {\n if (ctrl.signal.aborted) return; // view closed; say nothing\n if (e instanceof AskBusyError && attempt === 0) {\n await this.sleep((e.retryAfter || 2) * 1000);\n if (ctrl.signal.aborted) return;\n continue;\n }\n if (e instanceof AskBusyError) {\n this.ui?.panel.showAskError(\n \"Unnoodle is busy right now. Try again in a moment.\",\n true,\n );\n return;\n }\n if (e instanceof AskRateLimitedError) {\n this.ui?.panel.showAskError(this.rateLimitMessage(e), false);\n return;\n }\n if (e instanceof ApiError && (e.status === 401 || e.status === 403)) {\n void this.showLoginWithProviders();\n return;\n }\n this.ui?.panel.showAskError(\"Couldn't reach Unnoodle. Try again.\", true);\n return;\n }\n }\n } finally {\n if (this.askInFlight === ctrl) {\n this.askInFlight = null;\n this.ui?.panel.clearAskLoading();\n }\n }\n }\n\n /** 429 carries Retry-After; surface it rather than a bare \"try later\". */\n private rateLimitMessage(e: AskRateLimitedError): string {\n const seconds = Math.max(0, Math.round(e.retryAfter));\n if (seconds <= 0) {\n return \"You've reached today's question limit — try again later.\";\n }\n if (seconds < 90) {\n return `Too many questions just now — try again in ${seconds} second${seconds === 1 ? \"\" : \"s\"}.`;\n }\n const minutes = Math.round(seconds / 60);\n return `Too many questions just now — try again in ${minutes} minute${minutes === 1 ? \"\" : \"s\"}.`;\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => {\n this.askRetryTimer = setTimeout(resolve, ms);\n });\n }\n\n /** Abort any in-flight question — the view is gone, its answer is moot. */\n private abortAsk(): void {\n this.askInFlight?.abort();\n this.askInFlight = null;\n if (this.askRetryTimer !== null) {\n clearTimeout(this.askRetryTimer);\n this.askRetryTimer = null;\n }\n }\n\n private handleBack(): void {\n this.abortAsk();\n if (!this.ui || !this.cachedResponse) return;\n this.currentTerm = null;\n this.pendingAction = null;\n this.ui.panel.showTerms(this.cachedResponse);\n this.captureModeController?.setHomeData(this.cachedResponse);\n\n // Reload clarifications: ALWAYS check main response cache first (like concepts)\n if (this.cachedResponse.clarifications !== undefined) {\n this.cachedDiscussions = this.cachedResponse.clarifications;\n this.ui.panel.loadClarifications(\n this.cachedResponse.clarifications,\n !!this.resolveToken(),\n );\n } else if (this.cachedDiscussions) {\n this.ui.panel.loadClarifications(\n this.cachedDiscussions,\n !!this.resolveToken(),\n );\n }\n\n // Reload product memories: ALWAYS check main response cache first (like concepts)\n if (this.cachedResponse.productMemories !== undefined) {\n this.cachedHomeMemories = this.cachedResponse.productMemories;\n this.ui.panel.showHomeMemoryItems(this.cachedResponse.productMemories);\n } else if (this.cachedHomeMemories) {\n this.ui.panel.showHomeMemoryItems(this.cachedHomeMemories);\n } else {\n // Fallback: fetch product memories separately (same as initial load)\n void this.loadHomeMemoryItems();\n }\n }\n\n private handleAddComment(termId: number, body: string): void {\n if (!this.ui) return;\n\n if (!body) {\n // \"Show comment form\" request from the Add Comment button\n const token = this.resolveToken();\n if (!token) {\n // Write gate: login required\n this.pendingAction = () => this.ui?.panel.showCommentForm(termId);\n void this.showLoginWithProviders();\n } else {\n this.ui.panel.showCommentForm(termId);\n }\n } else {\n // Actual submission — post the comment (fire-and-forget for now)\n void this.submitComment(termId, body);\n }\n }\n\n private handleRequestEdit(termId: number): void {\n if (!this.ui) return;\n const term =\n this.currentTerm ??\n this.cachedResponse?.glossary.find((t) => t.id === termId) ??\n null;\n if (!term) return;\n\n const token = this.resolveToken();\n if (!token) {\n this.pendingAction = () => this.ui?.panel.showEditForm(term);\n void this.showLoginWithProviders();\n } else {\n this.ui.panel.showEditForm(term);\n }\n }\n\n private handleEditTerm(\n termId: number,\n updates: GlossaryTermUpdateRequest,\n ): void {\n // Fire-and-forget edit submission\n void this.submitEdit(termId, updates);\n }\n\n private async submitComment(termId: number, body: string): Promise<void> {\n const token = this.resolveToken();\n if (!token || !this.ui) return;\n this.ui.panel.setCommentLoading(true);\n try {\n await postComment(this.config, termId, body, token);\n // Reload discussions after posting\n const discussions = await getDiscussions(this.config, termId, token);\n if (this.ui && this.currentTerm) {\n this.ui.panel.showTermDetail(this.currentTerm, discussions, {\n showEdit: true,\n });\n }\n } catch (err) {\n const message =\n err instanceof ApiError\n ? err.message\n : \"Failed to post comment. Please try again.\";\n this.ui?.panel.setCommentError(message);\n } finally {\n this.ui?.panel.setCommentLoading(false);\n }\n }\n\n private async submitEdit(\n termId: number,\n updates: GlossaryTermUpdateRequest,\n ): Promise<void> {\n const token = this.resolveToken();\n if (!token || !this.ui) return;\n this.ui.panel.setEditLoading(true);\n try {\n await updateTerm(this.config, termId, updates, token);\n // Invalidate cache and reload\n this.cachedResponse = null;\n this.fuseIndex = null;\n await this.fetchTerms(token);\n } catch (err) {\n const message =\n err instanceof ApiError\n ? err.message\n : \"Failed to update term. Please try again.\";\n this.ui?.panel.setEditError(message);\n } finally {\n this.ui?.panel.setEditLoading(false);\n }\n }\n\n private async fetchTerms(token: string | null): Promise<void> {\n if (this.isFetching || !this.ui) return;\n this.isFetching = true;\n this.setProgress(true);\n this.ui.panel.setLoading();\n\n try {\n const response = await initWidget(this.config, token);\n this.cachedResponse = response;\n this.highlighter?.apply(response.glossary);\n\n // Notify plugins\n if (this.config._plugins) {\n for (const plugin of this.config._plugins) {\n try {\n plugin.onResponse?.(response);\n } catch {\n /* fail silently per plugin */\n }\n }\n }\n\n if (this.ui) {\n this.ui.panel.showTerms(response);\n this.captureModeController?.setHomeData(response);\n this.showSuggestions(response.glossary);\n // Signal authenticated state so action bar is shown for logged-in users\n this.ui.panel.setAuthenticated(!!this.resolveToken());\n\n // Load clarifications: use included data if available, otherwise fetch separately\n if (response.clarifications !== undefined) {\n // Use included clarifications from init response (apply 5-item limit)\n const limitedClarifications = response.clarifications.slice(0, 5);\n this.cachedDiscussions = limitedClarifications;\n // Ensure clarifications are in main response cache\n this.cachedResponse.clarifications = limitedClarifications;\n this.ui.panel.loadClarifications(\n limitedClarifications,\n !!this.resolveToken(),\n );\n } else {\n // Fallback: fetch context discussions separately for backward compatibility\n void this.fetchDiscussions(response.context.id);\n }\n\n // Load product memories: use included data if available, otherwise fetch separately\n if (response.productMemories !== undefined) {\n // Use included product memories from init response (apply 5-item limit)\n const limitedMemories = response.productMemories.slice(0, 5);\n this.cachedHomeMemories = limitedMemories;\n // Ensure memories are in main response cache\n this.cachedResponse.productMemories = limitedMemories;\n this.ui.panel.showHomeMemoryItems(limitedMemories);\n } else {\n // Fallback: fetch product memories separately for backward compatibility\n void this.loadHomeMemoryItems();\n }\n }\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n\n if (this.config._plugins) {\n for (const plugin of this.config._plugins) {\n try {\n plugin.onError?.(error);\n } catch {\n /* fail silently per plugin */\n }\n }\n }\n\n if (this.ui) {\n this.ui.panel.setError(\n \"Could not load terms. Please check your connection and try again.\",\n );\n }\n } finally {\n this.isFetching = false;\n this.setProgress(false);\n }\n }\n\n /**\n * Fetches context-level clarifications and pushes them to the panel.\n * Errors are swallowed so they don't affect the main glossary view.\n * Applies 5-item limit for consistency with unified init response.\n */\n private async fetchDiscussions(contextId: number): Promise<void> {\n if (!this.ui) return;\n try {\n const discussions = await fetchContextDiscussions(\n this.config,\n contextId,\n this.resolveToken(),\n );\n // Apply 5-item limit for consistency\n const limitedDiscussions = discussions.slice(0, 5);\n\n // Store in both separate cache AND main response cache for reliability\n this.cachedDiscussions = limitedDiscussions;\n if (this.cachedResponse) {\n this.cachedResponse.clarifications = limitedDiscussions;\n }\n\n this.ui.panel.loadClarifications(\n limitedDiscussions,\n !!this.resolveToken(),\n );\n } catch (err) {\n // Non-fatal: show empty state rather than leaving skeleton forever\n if (this.ui) {\n this.ui.panel.loadClarifications([], !!this.resolveToken());\n }\n }\n }\n\n /**\n * Posts a new clarification question and refreshes the Clarifications section.\n */\n private async handleCreateTerm(\n term: string,\n definition: string,\n ): Promise<void> {\n const token = this.resolveToken();\n if (!token || !this.ui || !this.cachedResponse) return;\n try {\n await createGlossaryTerm(\n this.config,\n this.cachedResponse.context.id,\n term,\n definition,\n token,\n );\n // Re-fetch so the new term appears in the list\n await this.fetchTerms(token);\n } catch (err) {\n const message =\n err instanceof ApiError\n ? err.message\n : \"Failed to add term. Please try again.\";\n this.ui.panel.showToast(message);\n }\n }\n\n private async handleAskQuestion(\n contextId: number,\n questionBody: string,\n ): Promise<void> {\n const token = this.resolveToken();\n if (!token || !this.ui) return;\n try {\n await postContextDiscussion(this.config, contextId, questionBody, token);\n // Re-fetch the full thread so replies are included\n await this.fetchDiscussions(contextId);\n } catch (err) {\n const message =\n err instanceof ApiError\n ? err.message\n : \"Failed to post question. Please try again.\";\n this.ui.panel.showToast(message);\n }\n }\n\n private handleClarificationClick(discussion: ContextDiscussion): void {\n if (!this.ui) return;\n this.currentDiscussion = discussion;\n const canReply = !!this.resolveToken();\n this.ui.panel.showClarificationDetail(discussion, canReply);\n }\n\n private async handlePostReply(\n contextId: number,\n questionId: number,\n body: string,\n ): Promise<void> {\n const token = this.resolveToken();\n if (!token || !this.ui) return;\n try {\n await postContextReply(this.config, contextId, questionId, body, token);\n // Re-fetch the full discussion thread to get updated replies\n const discussions = await fetchContextDiscussions(\n this.config,\n contextId,\n token,\n );\n this.cachedDiscussions = discussions;\n const updated = discussions.find((d) => d.id === questionId);\n if (updated) {\n this.currentDiscussion = updated;\n this.ui.panel.showClarificationDetail(updated, true);\n }\n this.ui.panel.loadClarifications(discussions, true);\n } catch (err) {\n const message =\n err instanceof ApiError\n ? err.message\n : \"Failed to post reply. Please try again.\";\n this.ui?.panel.showToast(message);\n }\n }\n\n private async handleSearch(query: string): Promise<void> {\n if (!this.ui || !this.cachedResponse) return;\n\n const trimmed = query.trim();\n\n if (!trimmed) {\n // Empty query — restore full cached list\n this.ui.panel.showTerms(this.cachedResponse);\n this.captureModeController?.setHomeData(this.cachedResponse);\n void this.loadHomeMemoryItems();\n return;\n }\n\n // Client-side fuzzy search via Fuse.js (instant, no network)\n if (!this.fuseIndex) {\n this.fuseIndex = this.buildFuseIndex(this.cachedResponse.glossary);\n }\n const fuseResults = this.fuseIndex.search(trimmed);\n const localResults: GlossaryTerm[] = fuseResults.map(\n (r: FuseResult<GlossaryTerm>) => r.item,\n );\n\n // Show local results instantly\n this.ui.panel.showSearchResults(localResults, trimmed);\n\n // Then do a server-side search for deeper/ranked results\n try {\n const token = this.resolveToken();\n const serverResults = await searchTerms(\n this.config,\n this.cachedResponse.context.id,\n trimmed,\n token,\n );\n // Only update if the search query is still the same (user hasn't typed more)\n if (this.ui) {\n this.ui.panel.showSearchResults(serverResults, trimmed);\n }\n } catch {\n // Already showing local results — server error is not fatal\n }\n }\n\n // ---------------------------------------------------------------------------\n // Phase 3: Suggested terms\n // ---------------------------------------------------------------------------\n\n /** Build a Fuse.js index over a glossary for fuzzy client-side search. */\n private buildFuseIndex(glossary: GlossaryTerm[]): Fuse<GlossaryTerm> {\n return new Fuse(glossary, {\n keys: [\n { name: \"term\", weight: 3 },\n { name: \"abbreviation\", weight: 2 },\n { name: \"definition\", weight: 1 },\n ],\n threshold: 0.35, // 0 = exact match, 1 = match anything\n includeScore: true,\n ignoreLocation: true,\n minMatchCharLength: 2,\n });\n }\n\n /**\n * Scans the host page for candidate terms and shows them below the glossary\n * list if at least one is found.\n */\n private showSuggestions(glossary: GlossaryTerm[]): void {\n if (!this.ui || !this.suggester) return;\n const suggestions = this.suggester.scan(glossary);\n if (suggestions.length === 0) return;\n this.ui.panel.showSuggestedTerms(suggestions, (termName) =>\n this.handleAddSuggestion(termName),\n );\n }\n\n /**\n * Called when the user clicks \"+ Add\" on a suggested term.\n * Login-gated: if no token, shows the login form and sets a pending action.\n * If token present: calls AI generate endpoint, then opens review modal.\n */\n private handleAddSuggestion(termName: string): void {\n if (!this.ui) return;\n this.activeSuggestion = termName;\n\n const token = this.resolveToken();\n if (!token) {\n this.pendingAction = () => this.openAiGenerateFlow(termName);\n void this.showLoginWithProviders();\n return;\n }\n void this.openAiGenerateFlow(termName);\n }\n\n private async openAiGenerateFlow(termName: string): Promise<void> {\n if (!this.ui) return;\n const token = this.resolveToken();\n if (!token) return;\n\n const pageContext = this.suggester?.getPageContext(termName) ?? \"\";\n const pageUrl = typeof window !== \"undefined\" ? window.location.href : \"\";\n\n this.ui.panel.setAiModalLoading(false); // reset if re-used\n\n try {\n const definition = await generateAiDefinition(\n this.config,\n termName,\n pageContext,\n pageUrl,\n token,\n );\n\n this.ui?.panel.showAiModal(\n termName,\n definition,\n (edited) => void this.submitSuggestedTerm(termName, edited),\n () => {\n // Cancel → return to terms list\n if (this.cachedResponse && this.ui) {\n this.ui.panel.showTerms(this.cachedResponse);\n this.captureModeController?.setHomeData(this.cachedResponse);\n this.showSuggestions(this.cachedResponse.glossary);\n void this.loadHomeMemoryItems();\n }\n },\n );\n } catch {\n // AI generate failed — fall back to empty definition modal\n this.ui?.panel.showAiModal(\n termName,\n \"\",\n (edited) => void this.submitSuggestedTerm(termName, edited),\n () => {\n if (this.cachedResponse && this.ui) {\n this.ui.panel.showTerms(this.cachedResponse);\n this.captureModeController?.setHomeData(this.cachedResponse);\n this.showSuggestions(this.cachedResponse.glossary);\n void this.loadHomeMemoryItems();\n }\n },\n );\n }\n }\n\n // ---------------------------------------------------------------------------\n // Product Memories\n // ---------------------------------------------------------------------------\n\n private async loadMemories(page: number, append = false): Promise<void> {\n if (!this.ui) return;\n const token = this.resolveToken();\n\n try {\n const pageResp = await listProductMemories(this.config, page, token);\n if (!append) this.memories = [];\n this.memories = [...this.memories, ...pageResp.content];\n this.memoriesPage = pageResp.number;\n this.hasMoreMemories = !pageResp.last;\n this.ui.panel.showMemoriesList(\n pageResp.content,\n pageResp.number,\n !pageResp.last,\n append,\n );\n } catch (err) {\n const message =\n err instanceof ApiError\n ? err.message\n : \"Could not load Product Memories.\";\n this.ui.panel.showToast(message);\n }\n }\n\n /**\n * Loads all product memories for the list view.\n */\n private async loadAllMemories(): Promise<void> {\n if (!this.ui) return;\n const token = this.resolveToken();\n\n try {\n // Load first page to get all memories for list view (20 per page is the API default)\n // For list view, first page should be sufficient for most use cases\n const pageResp = await listProductMemories(this.config, 0, token);\n this.ui?.panel.showAllMemories(pageResp.content, !!token);\n } catch (err) {\n console.error(\"[unnoodle] loadAllMemories failed:\", err);\n this.ui?.panel.showAllMemories([], false);\n }\n }\n\n /**\n * Loads product memories for the home page. Applies 5-item limit for consistency.\n * Fallback when product memories are not included in init response.\n */\n private async loadHomeMemoryItems(): Promise<void> {\n if (!this.ui) return;\n const token = this.resolveToken();\n\n try {\n const pageResp = await listProductMemories(this.config, 0, token);\n // Apply 5-item limit for consistency with unified init response\n const limitedMemories = pageResp.content.slice(0, 5);\n\n // Store in both separate cache AND main response cache for reliability\n this.cachedHomeMemories = limitedMemories;\n if (this.cachedResponse) {\n this.cachedResponse.productMemories = limitedMemories;\n }\n\n this.ui?.panel.showHomeMemoryItems(limitedMemories);\n } catch (err) {\n console.error(\"loadHomeMemoryItems failed:\", err);\n this.ui?.panel.showHomeMemoryItems([]);\n }\n }\n\n private async handleViewMemoryDetail(id: number): Promise<void> {\n if (!this.ui) return;\n const token = this.resolveToken();\n\n try {\n const memory = await getProductMemory(this.config, id, token);\n this.currentMemory = memory;\n this.ui.panel.showMemoryDetail(memory);\n } catch {\n this.ui.panel.showToast(\"Could not load memory details.\");\n }\n }\n\n private async handleUpdateEntryExplanation(\n memoryId: number,\n entryId: number,\n explanation: string,\n ): Promise<void> {\n if (!this.ui) return;\n const token = this.resolveToken();\n if (!token) return;\n\n try {\n const updated = await updateProductMemoryEntry(\n this.config,\n memoryId,\n entryId,\n { explanation },\n token,\n );\n this.currentMemory = updated;\n this.ui.panel.showMemoryDetail(updated);\n this.ui.panel.showToast(\"Explanation saved ✓\");\n } catch {\n this.ui.panel.showToast(\"Could not save explanation.\");\n }\n }\n\n /**\n * Show the \"add entry\" form for the currently viewed memory.\n * Uses the same CaptureModeController as new memories, but in \"add-entry\" mode.\n */\n private handleAddEntryToMemory(memoryId: number): void {\n if (!this.ui || !this.currentMemory) return;\n const token = this.resolveToken();\n if (!token) {\n void this.showLoginWithProviders();\n return;\n }\n const addController = createCaptureModeController(\n this.ui.panel,\n this.config,\n () => this.resolveToken(),\n () => this.cachedResponse?.glossary ?? [],\n // On save: navigate back to updated detail view\n () => void this.handleViewMemoryDetail(memoryId),\n new AddEntryOrchestrator(memoryId),\n { type: \"add-entry\", memoryTitle: this.currentMemory.title },\n );\n addController.start();\n }\n\n /**\n * Delete a product memory and navigate back to the memories list.\n */\n private async handleDeleteMemory(memoryId: number): Promise<void> {\n if (!this.ui) return;\n const token = this.resolveToken();\n if (!token) return;\n\n try {\n await deleteProductMemory(this.config, memoryId, token);\n this.ui.panel.showToast(\"Memory deleted ✓\");\n // Navigate back to memories list\n await this.loadMemories(0, false);\n } catch {\n this.ui.panel.showToast(\"Could not delete memory.\");\n }\n }\n\n /**\n * Delete an entry from a product memory and reload the detail view.\n */\n private async handleDeleteEntry(\n memoryId: number,\n entryId: number,\n ): Promise<void> {\n if (!this.ui) return;\n const token = this.resolveToken();\n if (!token) return;\n\n try {\n const updated = await deleteProductMemoryEntry(\n this.config,\n memoryId,\n entryId,\n token,\n );\n this.currentMemory = updated;\n this.ui.panel.showMemoryDetail(updated);\n this.ui.panel.showToast(\"Entry deleted ✓\");\n } catch {\n this.ui.panel.showToast(\"Could not delete entry.\");\n }\n }\n\n private async submitSuggestedTerm(\n termName: string,\n definition: string,\n ): Promise<void> {\n if (!this.ui || !this.cachedResponse) return;\n const token = this.resolveToken();\n if (!token) return;\n\n this.ui.panel.setAiModalLoading(true);\n try {\n await createSuggestedTerm(\n this.config,\n this.cachedResponse.context.id,\n termName,\n definition,\n token,\n );\n\n // Close modal, show toast, re-render terms\n this.ui.panel.showTerms(this.cachedResponse);\n this.captureModeController?.setHomeData(this.cachedResponse);\n this.showSuggestions(this.cachedResponse.glossary);\n void this.loadHomeMemoryItems();\n this.ui.panel.showToast(\"Term submitted for approval\");\n this.activeSuggestion = null;\n } catch (err) {\n this.ui.panel.setAiModalLoading(false);\n const message =\n err instanceof ApiError\n ? err.message\n : \"Failed to submit term. Please try again.\";\n // Re-show modal with error — simplest approach: just log for now\n void message; // consumed by crash-safe no-op for now\n }\n }\n}\n","/**\n * StateWatcher\n *\n * Single responsibility:\n * Observe a captured DOM element for meaningful state changes and report\n * them via a callback — enabling automatic new-state detection in the UI\n * memory timeline.\n *\n * Behaviour:\n * - watch(el, onStateChange): attaches a MutationObserver that listens for\n * text, attribute, and structural changes on the element and its subtree.\n * - Changes are debounced for 500ms so rapid successive mutations (e.g.\n * CSS class toggling during an animation) produce a single diff.\n * - Noise filter: style attribute mutations are ignored (too noisy).\n * - unwatch(): disconnects the observer and cancels pending callbacks.\n *\n * Change classification (StateDiff.type):\n * - \"text\" — visible text content changed (textContent assignment\n * fires a childList mutation with only text nodes, or a\n * characterData mutation on a text node directly).\n * - \"attribute\" — a non-style attribute changed (class, disabled,\n * aria-*, data-*, etc.).\n * - \"structure\" — child elements were added or removed.\n *\n * Design principles:\n * - No DOM mutation — observer only.\n * - No coupling to panel, API, or captureOrchestrator.\n * - before/after are always strings (attribute values, textContent, or\n * serialised child counts for structural diffs).\n */\n\n// ---------------------------------------------------------------------------\n// Public contracts\n// ---------------------------------------------------------------------------\n\nexport interface StateDiff {\n /** Category of the detected change. */\n type: \"text\" | \"attribute\" | \"structure\";\n /** Name of the changed attribute — only set when type === \"attribute\". */\n attribute?: string;\n /** State before the change. */\n before: string;\n /** State after the change. */\n after: string;\n}\n\nexport interface IStateWatcher {\n /**\n * Begin watching `el` for meaningful mutations.\n * Calls `onStateChange` (debounced 500ms) when a diff is detected.\n * Replaces any previous watch.\n */\n watch(el: Element, onStateChange: (diff: StateDiff) => void): void;\n /**\n * Stop watching. Cancels any pending debounced callback.\n * Safe to call when no watch is active.\n */\n unwatch(): void;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/** Lightweight snapshot of the element state taken at watch() / after each flush. */\ninterface ElementState {\n textContent: string;\n innerHTML: string;\n}\n\nfunction captureState(el: Element): ElementState {\n return {\n textContent: el.textContent ?? \"\",\n innerHTML: el.innerHTML,\n };\n}\n\nexport class StateWatcher implements IStateWatcher {\n private observer: MutationObserver | null = null;\n private timerId: ReturnType<typeof setTimeout> | null = null;\n private pendingMutations: MutationRecord[] = [];\n private watchedEl: Element | null = null;\n private callback: ((diff: StateDiff) => void) | null = null;\n /** Snapshot of watched element state at the start of the current quiet window. */\n private preBatchState: ElementState | null = null;\n\n watch(el: Element, onStateChange: (diff: StateDiff) => void): void {\n this.unwatch();\n this.watchedEl = el;\n this.callback = onStateChange;\n this.preBatchState = captureState(el);\n\n this.observer = new MutationObserver((mutations) => {\n for (const m of mutations) {\n this.pendingMutations.push(m);\n }\n this.scheduleFlush();\n });\n\n this.observer.observe(el, {\n childList: true,\n subtree: true,\n characterData: true,\n characterDataOldValue: true,\n attributes: true,\n attributeOldValue: true,\n });\n }\n\n unwatch(): void {\n if (this.timerId !== null) {\n clearTimeout(this.timerId);\n this.timerId = null;\n }\n this.observer?.disconnect();\n this.observer = null;\n this.pendingMutations = [];\n this.preBatchState = null;\n this.watchedEl = null;\n this.callback = null;\n }\n\n // ── Private ───────────────────────────────────────────────────────────────\n\n private scheduleFlush(): void {\n if (this.timerId !== null) clearTimeout(this.timerId);\n this.timerId = setTimeout(() => this.flush(), 500);\n }\n\n private flush(): void {\n this.timerId = null;\n\n const mutations = [...this.pendingMutations];\n this.pendingMutations = [];\n\n if (!this.watchedEl || !this.callback || !this.preBatchState) return;\n\n const diff = this.computeDiff(\n mutations,\n this.preBatchState,\n this.watchedEl,\n );\n\n if (diff) {\n this.preBatchState = captureState(this.watchedEl);\n this.callback(diff);\n } else {\n // No meaningful change — update pre-batch snapshot so we stay fresh\n this.preBatchState = captureState(this.watchedEl);\n }\n }\n\n private computeDiff(\n mutations: MutationRecord[],\n before: ElementState,\n el: Element,\n ): StateDiff | null {\n // Filter out style-only noise\n const meaningful = mutations.filter(\n (m) => !(m.type === \"attributes\" && m.attributeName === \"style\"),\n );\n\n if (meaningful.length === 0) return null;\n\n // Priority: attribute > characterData > childList\n const attrMutation = meaningful.find((m) => m.type === \"attributes\");\n if (attrMutation) {\n const attr = attrMutation.attributeName!;\n return {\n type: \"attribute\",\n attribute: attr,\n before: attrMutation.oldValue ?? \"\",\n after: el.getAttribute(attr) ?? \"\",\n };\n }\n\n const charMutation = meaningful.find((m) => m.type === \"characterData\");\n if (charMutation) {\n return {\n type: \"text\",\n before: charMutation.oldValue ?? \"\",\n after: (charMutation.target as CharacterData).data,\n };\n }\n\n // childList mutations — distinguish text-only from structural\n const childMutations = meaningful.filter((m) => m.type === \"childList\");\n if (childMutations.length > 0) {\n const allNodes: Node[] = [];\n for (const m of childMutations) {\n for (const n of Array.from(m.addedNodes)) allNodes.push(n);\n for (const n of Array.from(m.removedNodes)) allNodes.push(n);\n }\n\n const isTextOnly = allNodes.every((n) => n.nodeType === Node.TEXT_NODE);\n\n if (isTextOnly) {\n return {\n type: \"text\",\n before: before.textContent,\n after: el.textContent ?? \"\",\n };\n }\n\n return {\n type: \"structure\",\n before: before.innerHTML,\n after: el.innerHTML,\n };\n }\n\n return null;\n }\n}\n","/**\n * meaningInference\n *\n * Single responsibility:\n * Given a StateDiff and the current live element, produce a concise\n * human-readable string suggesting what UI state the change represents.\n * Returns null when no confident semantic meaning can be inferred.\n *\n * Rule-based approach (no ML, fully deterministic):\n *\n * Text changes — keyword scan of diff.after:\n * loading/spinner/submitting/saving → \"Loading state\"\n * error/failed/invalid/try again → \"Error state\"\n * success/saved/complete/done → \"Success state\"\n *\n * Attribute changes on \"class\":\n * Newly added class keyword scan (diff.after classes minus diff.before classes):\n * loading/spinner/pending → \"Loading state\"\n * disabled/inactive → \"Disabled state\"\n * error/invalid/danger → \"Error state\"\n * success/valid/done → \"Success state\"\n * active/selected/open → \"Active state\"\n * collapsed/closed/hidden → \"Collapsed state\"\n *\n * The \"disabled\" attribute:\n * Attribute present after change → \"Disabled state\"\n * Attribute absent after change → \"Enabled state\"\n *\n * ARIA attributes:\n * aria-expanded = \"true\" → \"Expanded state\"\n * aria-expanded = \"false\" → \"Collapsed state\"\n * aria-selected = \"true\" → \"Selected state\"\n * aria-busy = \"true\" → \"Loading state\"\n * aria-label changed → \"Label changed to: <value>\"\n *\n * Structure changes → null (caller decides context).\n *\n * Design principles:\n * - Pure function — no side effects, no DOM mutation.\n * - Returns null rather than guessing.\n * - Deterministic output for testability.\n */\n\nimport type { StateDiff } from \"./stateWatcher\";\n\n// ---------------------------------------------------------------------------\n// Keyword maps\n// ---------------------------------------------------------------------------\n\nconst TEXT_LOADING_RE = /\\b(loading|spinner|submitting|saving|please wait)\\b/i;\nconst TEXT_ERROR_RE =\n /\\b(error|failed|invalid|failure|try again|went wrong)\\b/i;\nconst TEXT_SUCCESS_RE = /\\b(success|saved|complete|done|submitted|finished)\\b/i;\n\nconst CLASS_RULES: Array<[RegExp, string]> = [\n [/\\b(loading|spinner|pending|busy)\\b/, \"Loading state\"],\n [/\\b(disabled|inactive|unavailable)\\b/, \"Disabled state\"],\n [/\\b(error|invalid|danger|fail)\\b/, \"Error state\"],\n [/\\b(success|valid|done|complete)\\b/, \"Success state\"],\n [/\\b(active|selected|open|checked|focused)\\b/, \"Active state\"],\n [/\\b(collapsed|closed|hidden)\\b/, \"Collapsed state\"],\n];\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction classSet(cls: string): Set<string> {\n return new Set(cls.split(/\\s+/).filter(Boolean));\n}\n\n/** Returns the classes present in `after` that were NOT in `before`. */\nfunction addedClasses(before: string, after: string): string {\n const beforeSet = classSet(before);\n return [...classSet(after)].filter((c) => !beforeSet.has(c)).join(\" \");\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Infer a human-readable state meaning from a StateDiff.\n *\n * @param diff The state change detected by StateWatcher.\n * @param el The live element after the change (used for attribute reads).\n * @returns A short description, or null if no meaning can be inferred.\n */\nexport function inferMeaning(diff: StateDiff, el: Element): string | null {\n // ── Text changes ──────────────────────────────────────────────────────────\n if (diff.type === \"text\") {\n const text = diff.after;\n if (TEXT_LOADING_RE.test(text)) return \"Loading state\";\n if (TEXT_ERROR_RE.test(text)) return \"Error state\";\n if (TEXT_SUCCESS_RE.test(text)) return \"Success state\";\n return null;\n }\n\n // ── Attribute changes ─────────────────────────────────────────────────────\n if (diff.type === \"attribute\") {\n const { attribute, after } = diff;\n\n // class — find newly added semantic classes\n if (attribute === \"class\") {\n const newClasses = addedClasses(diff.before, after);\n if (newClasses) {\n for (const [pattern, label] of CLASS_RULES) {\n if (pattern.test(newClasses)) return label;\n }\n }\n return null;\n }\n\n // disabled boolean attribute\n if (attribute === \"disabled\") {\n return el.hasAttribute(\"disabled\") ? \"Disabled state\" : \"Enabled state\";\n }\n\n // ARIA attributes\n if (attribute === \"aria-expanded\") {\n return after === \"true\" ? \"Expanded state\" : \"Collapsed state\";\n }\n if (attribute === \"aria-selected\") {\n return after === \"true\" ? \"Selected state\" : null;\n }\n if (attribute === \"aria-busy\") {\n return after === \"true\" ? \"Loading state\" : null;\n }\n if (attribute === \"aria-label\") {\n const trimmed = after.trim();\n return trimmed ? `Label changed to: ${trimmed}` : null;\n }\n\n return null;\n }\n\n // ── Structure changes — no semantic inference ─────────────────────────────\n return null;\n}\n","/**\n * LiveRenderer\n *\n * Single responsibility:\n * Highlight the DOM element that corresponds to a captured ProductMemory\n * entry — giving the viewer a live \"this is the element\" pointer.\n *\n * Behaviour:\n * - show(el): scrolls the element into view then draws a read-only highlight\n * ring (position:fixed) over the element's bounding rect.\n * - hide(): removes the ring from the DOM.\n * - Calling hide() before show() is safe (no-op).\n * - Calling show() a second time replaces the previous ring.\n *\n * Design principles:\n * - No click handlers — read-only visual indicator only.\n * - No coupling to panel, API, or state machine.\n * - Reuses the same visual language as ElementPicker (dashed Unnoodle violet\n * ring) but with a solid fill to distinguish \"live\" from \"pick\" mode.\n */\n\n// ---------------------------------------------------------------------------\n// Public contracts\n// ---------------------------------------------------------------------------\n\nexport interface ILiveRenderer {\n /** Scroll the element into view and draw the live highlight ring. */\n show(el: Element): void;\n /** Remove the highlight ring. Safe to call when ring is not shown. */\n hide(): void;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst LIVE_RING_ID = \"unnoodle-live-ring\";\n\nconst RING_CSS = `\n position: fixed;\n pointer-events: none;\n z-index: 2147483645;\n border: 2px solid #5C4EFA;\n border-radius: 4px;\n background: rgba(92, 78, 250, 0.10);\n box-shadow: 0 0 0 1px rgba(92, 78, 250, 0.35), 0 0 8px rgba(92, 78, 250, 0.25);\n`;\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\nexport class LiveRenderer implements ILiveRenderer {\n private ring: HTMLElement | null = null;\n\n show(el: Element): void {\n // Remove any previous ring first (idempotent)\n this.hide();\n\n // Scroll the element into view so the user can see it\n el.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n\n const rect = el.getBoundingClientRect();\n\n const ring = document.createElement(\"div\");\n ring.id = LIVE_RING_ID;\n ring.setAttribute(\"data-testid\", \"unnoodle-live-ring\");\n ring.style.cssText = RING_CSS;\n ring.style.top = `${rect.top}px`;\n ring.style.left = `${rect.left}px`;\n ring.style.width = `${rect.width}px`;\n ring.style.height = `${rect.height}px`;\n\n document.body.appendChild(ring);\n this.ring = ring;\n }\n\n hide(): void {\n this.ring?.remove();\n this.ring = null;\n }\n}\n","/**\n * MemoryDetailController\n *\n * Single responsibility:\n * After a ProductMemory is loaded, optionally start a StateWatcher on the\n * originally captured DOM element and surface its diffs via an onDiff\n * callback — enabling automatic new-state detection.\n *\n * Behaviour:\n * load(memory, onDiff):\n * 1. Unloads any prior watch.\n * 2. If memory.watchForChanges is false, does nothing more.\n * 3. Checks that the first entry's URL matches the current page URL\n * (origin + pathname only, ignoring query / hash).\n * 4. Uses TargetingEngine.resolve() to find the captured element.\n * 5. Starts StateWatcher.watch(el, onDiff).\n *\n * unload():\n * Stops any active StateWatcher. Safe to call when nothing is watching.\n *\n * Design principles:\n * - No DOM mutation.\n * - All dependencies are injected via interfaces for full testability.\n */\n\nimport type { ProductMemoryDetailResponse } from \"../../types/config\";\nimport type { IStateWatcher, StateDiff } from \"./stateWatcher\";\nimport type { ITargetingEngine, StoredTarget } from \"./targetingEngine\";\n\n// ---------------------------------------------------------------------------\n// Public interface\n// ---------------------------------------------------------------------------\n\nexport interface IMemoryDetailController {\n load(\n memory: ProductMemoryDetailResponse,\n onDiff: (diff: StateDiff) => void,\n ): void;\n unload(): void;\n}\n\n// ---------------------------------------------------------------------------\n// URL matching helper\n// ---------------------------------------------------------------------------\n\n/**\n * Returns true when stored origin+pathname matches the current page URL.\n * Query parameters and hash are intentionally ignored so navigating to\n * /form?step=2 still matches a memory captured at /form.\n */\nfunction urlsMatch(stored: string, current: string): boolean {\n try {\n const s = new URL(stored);\n const c = new URL(current);\n return s.origin === c.origin && s.pathname === c.pathname;\n } catch {\n return stored === current;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\nexport class MemoryDetailController implements IMemoryDetailController {\n constructor(\n private readonly stateWatcher: IStateWatcher,\n private readonly targetingEngine: ITargetingEngine,\n ) {}\n\n load(\n memory: ProductMemoryDetailResponse,\n onDiff: (diff: StateDiff) => void,\n ): void {\n this.unload();\n\n if (!memory.watchForChanges) return;\n\n const firstEntry = memory.entries[0];\n if (!firstEntry) return;\n\n if (!urlsMatch(firstEntry.url, window.location.href)) return;\n\n const meta = firstEntry.targetingMetadata;\n if (!meta) return;\n\n const target: StoredTarget = {\n ...(meta.id !== undefined && { id: meta.id }),\n ...(meta.dataTestId !== undefined && { dataTestId: meta.dataTestId }),\n tag: meta.tag,\n role: meta.role ?? null,\n text: meta.text ?? \"\",\n url: firstEntry.url,\n };\n\n const el = this.targetingEngine.resolve(target);\n if (!el) return;\n\n this.stateWatcher.watch(el, onDiff);\n }\n\n unload(): void {\n this.stateWatcher.unwatch();\n }\n}\n","import type { UnnoodleConfig } from \"./types/config\";\nimport { WidgetController } from \"./widget/widgetController\";\n\nexport type {\n UnnoodleConfig,\n UnnoodlePlugin,\n UnnoodleContext,\n UnnoodleApiResponse,\n UnnoodleAction,\n} from \"./types/config\";\n\n// Product-memory sub-system — publicly exported for SDK consumers and E2E use.\nexport { StateWatcher } from \"./features/memory/stateWatcher\";\nexport type {\n IStateWatcher,\n StateDiff,\n} from \"./features/memory/stateWatcher\";\nexport { inferMeaning } from \"./features/memory/meaningInference\";\nexport { LiveRenderer } from \"./features/memory/liveRenderer\";\nexport type { ILiveRenderer } from \"./features/memory/liveRenderer\";\nexport { MemoryDetailController } from \"./features/memory/memoryDetailController\";\nexport type { IMemoryDetailController } from \"./features/memory/memoryDetailController\";\n\nlet _controller: WidgetController | null = null;\n\n/**\n * Initializes the Unnoodle widget SDK.\n *\n * Call once when your application boots. Safe to call in SSR environments —\n * it will no-op if `document` is not available.\n *\n * @example\n * ```ts\n * import { initUnnoodle } from \"@unnoodle/browser\";\n *\n * initUnnoodle({ apiKey: \"pk_live_abc123\", context: \"engineering\" });\n * ```\n */\nexport function initUnnoodle(config: UnnoodleConfig): void {\n // SSR / non-browser guard\n if (typeof document === \"undefined\") {\n return;\n }\n\n if (!validateConfig(config)) {\n return;\n }\n\n // Destroy any existing instance before reinitializing.\n // Preserve the auth token so that framework lifecycles (e.g. React Strict\n // Mode's simulated unmount+remount) don't inadvertently log the user out.\n if (_controller) {\n const sessionKey = `unnoodle_token_${config.apiKey.slice(-8)}`;\n let savedToken: string | null = null;\n try {\n savedToken = sessionStorage.getItem(sessionKey);\n } catch {\n /* ignore — sessionStorage unavailable */\n }\n _controller.destroy();\n _controller = null;\n if (savedToken) {\n try {\n sessionStorage.setItem(sessionKey, savedToken);\n } catch {\n /* ignore */\n }\n }\n }\n\n _controller = new WidgetController(config);\n _controller.init();\n}\n\n/**\n * Programmatically open the Unnoodle panel.\n * No-op if the SDK has not been initialized.\n */\nexport function openUnnoodle(): void {\n _controller?.open();\n}\n\n/**\n * Programmatically close the Unnoodle panel.\n * No-op if the SDK has not been initialized.\n */\nexport function closeUnnoodle(): void {\n _controller?.close();\n}\n\n/**\n * Tear down the Unnoodle widget and remove all DOM elements and listeners.\n * Useful for single-page apps that need to clean up on route change.\n */\nexport function destroyUnnoodle(): void {\n _controller?.destroy();\n _controller = null;\n}\n\n/**\n * Namespace-style API — preferred for script-tag / CDN usage.\n *\n * @example\n * ```ts\n * import { Unnoodle } from \"@unnoodle/browser\";\n *\n * Unnoodle.init({ apiKey: \"pk_live_abc123\", context: \"engineering\" });\n * ```\n */\nexport const Unnoodle = {\n /** Initialize the Unnoodle widget SDK. Equivalent to `initUnnoodle()`. */\n init: initUnnoodle,\n /** Programmatically open the panel. */\n open: openUnnoodle,\n /** Programmatically close the panel. */\n close: closeUnnoodle,\n /** Tear down the widget and remove all DOM elements. */\n destroy: destroyUnnoodle,\n} as const;\n\nfunction validateConfig(config: UnnoodleConfig): boolean {\n if (!config || typeof config !== \"object\") {\n console.warn(\"[Unnoodle] initUnnoodle() requires a config object.\");\n return false;\n }\n\n if (\n !config.apiKey ||\n typeof config.apiKey !== \"string\" ||\n config.apiKey.trim() === \"\"\n ) {\n console.warn(\n \"[Unnoodle] initUnnoodle() requires a non-empty `apiKey` string (e.g. pk_live_xxx).\",\n );\n return false;\n }\n\n if (\n !config.context ||\n typeof config.context !== \"string\" ||\n config.context.trim() === \"\"\n ) {\n console.warn(\n \"[Unnoodle] initUnnoodle() requires a non-empty `context` string.\",\n );\n return false;\n }\n\n if (\n config.environment &&\n ![\"dev\", \"staging\", \"prod\"].includes(config.environment)\n ) {\n console.warn(\n `[Unnoodle] Invalid environment \"${config.environment}\". Must be \"dev\", \"staging\", or \"prod\". Defaulting to \"prod\".`,\n );\n }\n\n return true;\n}\n"]}